2 * Copyright (c) 2017 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @brief NAT plugin API implementation
22 #include <nat/nat_det.h>
23 #include <nat/nat64.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
27 #include <nat/nat_msg_enum.h>
28 #include <vnet/fib/fib_table.h>
30 #define vl_api_nat44_lb_addr_port_t_endian vl_noop_handler
31 #define vl_api_nat44_add_del_lb_static_mapping_t_endian vl_noop_handler
32 #define vl_api_nat44_nat44_lb_static_mapping_details_t_endian vl_noop_handler
34 /* define message structures */
36 #include <nat/nat_all_api_h.h>
39 /* define generated endian-swappers */
41 #include <nat/nat_all_api_h.h>
44 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
46 #define REPLY_MSG_ID_BASE sm->msg_id_base
47 #include <vlibapi/api_helper_macros.h>
49 /* Get the API version number */
50 #define vl_api_version(n,v) static u32 api_version=(v);
51 #include <nat/nat_all_api_h.h>
54 /* Macro to finish up custom dump fns */
57 vl_print (handle, (char *)s); \
62 vl_api_snat_add_address_range_t_handler
63 (vl_api_snat_add_address_range_t * mp)
65 snat_main_t *sm = &snat_main;
66 vl_api_snat_add_address_range_reply_t *rmp;
67 ip4_address_t this_addr;
68 u32 start_host_order, end_host_order;
76 rv = VNET_API_ERROR_UNIMPLEMENTED;
80 if (sm->static_mapping_only)
82 rv = VNET_API_ERROR_FEATURE_DISABLED;
86 tmp = (u32 *) mp->first_ip_address;
87 start_host_order = clib_host_to_net_u32 (tmp[0]);
88 tmp = (u32 *) mp->last_ip_address;
89 end_host_order = clib_host_to_net_u32 (tmp[0]);
91 count = (end_host_order - start_host_order) + 1;
93 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
96 clib_warning ("%U - %U, %d addresses...",
97 format_ip4_address, mp->first_ip_address,
98 format_ip4_address, mp->last_ip_address, count);
100 memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
102 for (i = 0; i < count; i++)
105 snat_add_address (sm, &this_addr, vrf_id);
107 rv = snat_del_address (sm, this_addr, 0);
112 increment_v4_address (&this_addr);
116 REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
119 static void *vl_api_snat_add_address_range_t_print
120 (vl_api_snat_add_address_range_t * mp, void *handle)
124 s = format (0, "SCRIPT: snat_add_address_range ");
125 s = format (s, "%U ", format_ip4_address, mp->first_ip_address);
126 if (memcmp (mp->first_ip_address, mp->last_ip_address, 4))
128 s = format (s, " - %U ", format_ip4_address, mp->last_ip_address);
134 send_snat_address_details
135 (snat_address_t * a, unix_shared_memory_queue_t * q, u32 context)
137 vl_api_snat_address_details_t *rmp;
138 snat_main_t *sm = &snat_main;
140 rmp = vl_msg_api_alloc (sizeof (*rmp));
141 memset (rmp, 0, sizeof (*rmp));
142 rmp->_vl_msg_id = ntohs (VL_API_SNAT_ADDRESS_DETAILS + sm->msg_id_base);
144 clib_memcpy (rmp->ip_address, &(a->addr), 4);
145 if (a->fib_index != ~0)
147 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
148 rmp->vrf_id = ntohl (fib->ft_table_id);
152 rmp->context = context;
154 vl_msg_api_send_shmem (q, (u8 *) & rmp);
158 vl_api_snat_address_dump_t_handler (vl_api_snat_address_dump_t * mp)
160 unix_shared_memory_queue_t *q;
161 snat_main_t *sm = &snat_main;
164 q = vl_api_client_index_to_input_queue (mp->client_index);
169 vec_foreach (a, sm->addresses)
170 send_snat_address_details (a, q, mp->context);
174 static void *vl_api_snat_address_dump_t_print
175 (vl_api_snat_address_dump_t * mp, void *handle)
179 s = format (0, "SCRIPT: snat_address_dump ");
185 vl_api_snat_interface_add_del_feature_t_handler
186 (vl_api_snat_interface_add_del_feature_t * mp)
188 snat_main_t *sm = &snat_main;
189 vl_api_snat_interface_add_del_feature_reply_t *rmp;
190 u8 is_del = mp->is_add == 0;
191 u32 sw_if_index = ntohl (mp->sw_if_index);
194 VALIDATE_SW_IF_INDEX (mp);
196 rv = snat_interface_add_del (sw_if_index, mp->is_inside, is_del);
198 BAD_SW_IF_INDEX_LABEL;
200 REPLY_MACRO (VL_API_SNAT_INTERFACE_ADD_DEL_FEATURE_REPLY);
203 static void *vl_api_snat_interface_add_del_feature_t_print
204 (vl_api_snat_interface_add_del_feature_t * mp, void *handle)
208 s = format (0, "SCRIPT: snat_interface_add_del_feature ");
209 s = format (s, "sw_if_index %d %s %s",
210 clib_host_to_net_u32 (mp->sw_if_index),
211 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
217 send_snat_interface_details
218 (snat_interface_t * i, unix_shared_memory_queue_t * q, u32 context)
220 vl_api_snat_interface_details_t *rmp;
221 snat_main_t *sm = &snat_main;
223 rmp = vl_msg_api_alloc (sizeof (*rmp));
224 memset (rmp, 0, sizeof (*rmp));
225 rmp->_vl_msg_id = ntohs (VL_API_SNAT_INTERFACE_DETAILS + sm->msg_id_base);
226 rmp->sw_if_index = ntohl (i->sw_if_index);
227 rmp->is_inside = nat_interface_is_inside (i);
228 rmp->context = context;
230 vl_msg_api_send_shmem (q, (u8 *) & rmp);
234 vl_api_snat_interface_dump_t_handler (vl_api_snat_interface_dump_t * mp)
236 unix_shared_memory_queue_t *q;
237 snat_main_t *sm = &snat_main;
240 q = vl_api_client_index_to_input_queue (mp->client_index);
245 pool_foreach (i, sm->interfaces,
247 send_snat_interface_details(i, q, mp->context);
252 static void *vl_api_snat_interface_dump_t_print
253 (vl_api_snat_interface_dump_t * mp, void *handle)
257 s = format (0, "SCRIPT: snat_interface_dump ");
263 vl_api_snat_interface_add_del_output_feature_t_handler
264 (vl_api_snat_interface_add_del_output_feature_t * mp)
266 snat_main_t *sm = &snat_main;
267 vl_api_snat_interface_add_del_output_feature_reply_t *rmp;
268 u8 is_del = mp->is_add == 0;
269 u32 sw_if_index = ntohl (mp->sw_if_index);
272 VALIDATE_SW_IF_INDEX (mp);
274 rv = snat_interface_add_del_output_feature (sw_if_index, mp->is_inside,
277 BAD_SW_IF_INDEX_LABEL;
279 REPLY_MACRO (VL_API_SNAT_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY);
282 static void *vl_api_snat_interface_add_del_output_feature_t_print
283 (vl_api_snat_interface_add_del_output_feature_t * mp, void *handle)
287 s = format (0, "SCRIPT: snat_interface_add_del_output_feature ");
288 s = format (s, "sw_if_index %d %s %s",
289 clib_host_to_net_u32 (mp->sw_if_index),
290 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
296 send_snat_interface_output_feature_details (snat_interface_t * i,
297 unix_shared_memory_queue_t * q,
300 vl_api_snat_interface_output_feature_details_t *rmp;
301 snat_main_t *sm = &snat_main;
303 rmp = vl_msg_api_alloc (sizeof (*rmp));
304 memset (rmp, 0, sizeof (*rmp));
306 ntohs (VL_API_SNAT_INTERFACE_OUTPUT_FEATURE_DETAILS + sm->msg_id_base);
307 rmp->sw_if_index = ntohl (i->sw_if_index);
308 rmp->context = context;
309 rmp->is_inside = nat_interface_is_inside (i);
311 vl_msg_api_send_shmem (q, (u8 *) & rmp);
315 vl_api_snat_interface_output_feature_dump_t_handler
316 (vl_api_snat_interface_output_feature_dump_t * mp)
318 unix_shared_memory_queue_t *q;
319 snat_main_t *sm = &snat_main;
322 q = vl_api_client_index_to_input_queue (mp->client_index);
327 pool_foreach (i, sm->output_feature_interfaces,
329 send_snat_interface_output_feature_details(i, q, mp->context);
334 static void *vl_api_snat_interface_output_feature_dump_t_print
335 (vl_api_snat_interface_output_feature_dump_t * mp, void *handle)
339 s = format (0, "SCRIPT: snat_interface_output_feature_dump ");
345 vl_api_snat_add_static_mapping_t_handler
346 (vl_api_snat_add_static_mapping_t * mp)
348 snat_main_t *sm = &snat_main;
349 vl_api_snat_add_static_mapping_reply_t *rmp;
350 ip4_address_t local_addr, external_addr;
351 u16 local_port = 0, external_port = 0;
352 u32 vrf_id, external_sw_if_index;
354 snat_protocol_t proto;
358 rv = VNET_API_ERROR_UNIMPLEMENTED;
362 memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
363 memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
364 if (mp->addr_only == 0)
366 local_port = clib_net_to_host_u16 (mp->local_port);
367 external_port = clib_net_to_host_u16 (mp->external_port);
369 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
370 external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
371 proto = ip_proto_to_snat_proto (mp->protocol);
373 rv = snat_add_static_mapping (local_addr, external_addr, local_port,
374 external_port, vrf_id, mp->addr_only,
375 external_sw_if_index, proto, mp->is_add);
378 REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
381 static void *vl_api_snat_add_static_mapping_t_print
382 (vl_api_snat_add_static_mapping_t * mp, void *handle)
386 s = format (0, "SCRIPT: snat_add_static_mapping ");
387 s = format (s, "protocol %d local_addr %U external_addr %U ",
389 format_ip4_address, mp->local_ip_address,
390 format_ip4_address, mp->external_ip_address);
392 if (mp->addr_only == 0)
393 s = format (s, "local_port %d external_port %d ",
394 clib_net_to_host_u16 (mp->local_port),
395 clib_net_to_host_u16 (mp->external_port));
397 if (mp->vrf_id != ~0)
398 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
400 if (mp->external_sw_if_index != ~0)
401 s = format (s, "external_sw_if_index %d",
402 clib_net_to_host_u32 (mp->external_sw_if_index));
407 send_snat_static_mapping_details
408 (snat_static_mapping_t * m, unix_shared_memory_queue_t * q, u32 context)
410 vl_api_snat_static_mapping_details_t *rmp;
411 snat_main_t *sm = &snat_main;
413 rmp = vl_msg_api_alloc (sizeof (*rmp));
414 memset (rmp, 0, sizeof (*rmp));
416 ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS + sm->msg_id_base);
418 rmp->addr_only = m->addr_only;
419 clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
420 clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
421 rmp->local_port = htons (m->local_port);
422 rmp->external_port = htons (m->external_port);
423 rmp->external_sw_if_index = ~0;
424 rmp->vrf_id = htonl (m->vrf_id);
425 rmp->protocol = snat_proto_to_ip_proto (m->proto);
426 rmp->context = context;
428 vl_msg_api_send_shmem (q, (u8 *) & rmp);
432 send_snat_static_map_resolve_details
433 (snat_static_map_resolve_t * m, unix_shared_memory_queue_t * q, u32 context)
435 vl_api_snat_static_mapping_details_t *rmp;
436 snat_main_t *sm = &snat_main;
438 rmp = vl_msg_api_alloc (sizeof (*rmp));
439 memset (rmp, 0, sizeof (*rmp));
441 ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS + sm->msg_id_base);
443 rmp->addr_only = m->addr_only;
444 clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
445 rmp->local_port = htons (m->l_port);
446 rmp->external_port = htons (m->e_port);
447 rmp->external_sw_if_index = htonl (m->sw_if_index);
448 rmp->vrf_id = htonl (m->vrf_id);
449 rmp->protocol = snat_proto_to_ip_proto (m->proto);
450 rmp->context = context;
452 vl_msg_api_send_shmem (q, (u8 *) & rmp);
456 vl_api_snat_static_mapping_dump_t_handler
457 (vl_api_snat_static_mapping_dump_t * mp)
459 unix_shared_memory_queue_t *q;
460 snat_main_t *sm = &snat_main;
461 snat_static_mapping_t *m;
462 snat_static_map_resolve_t *rp;
465 q = vl_api_client_index_to_input_queue (mp->client_index);
470 pool_foreach (m, sm->static_mappings,
472 if (!vec_len(m->locals))
473 send_snat_static_mapping_details (m, q, mp->context);
477 for (j = 0; j < vec_len (sm->to_resolve); j++)
479 rp = sm->to_resolve + j;
480 send_snat_static_map_resolve_details (rp, q, mp->context);
484 static void *vl_api_snat_static_mapping_dump_t_print
485 (vl_api_snat_static_mapping_dump_t * mp, void *handle)
489 s = format (0, "SCRIPT: snat_static_mapping_dump ");
495 vl_api_snat_control_ping_t_handler (vl_api_snat_control_ping_t * mp)
497 vl_api_snat_control_ping_reply_t *rmp;
498 snat_main_t *sm = &snat_main;
502 REPLY_MACRO2 (VL_API_SNAT_CONTROL_PING_REPLY,
504 rmp->vpe_pid = ntohl (getpid ());
509 static void *vl_api_snat_control_ping_t_print
510 (vl_api_snat_control_ping_t * mp, void *handle)
514 s = format (0, "SCRIPT: snat_control_ping ");
520 vl_api_snat_show_config_t_handler (vl_api_snat_show_config_t * mp)
522 vl_api_snat_show_config_reply_t *rmp;
523 snat_main_t *sm = &snat_main;
527 REPLY_MACRO2 (VL_API_SNAT_SHOW_CONFIG_REPLY,
529 rmp->translation_buckets = htonl (sm->translation_buckets);
530 rmp->translation_memory_size = htonl (sm->translation_memory_size);
531 rmp->user_buckets = htonl (sm->user_buckets);
532 rmp->user_memory_size = htonl (sm->user_memory_size);
533 rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
534 rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
535 rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
536 rmp->static_mapping_only = sm->static_mapping_only;
537 rmp->static_mapping_connection_tracking =
538 sm->static_mapping_connection_tracking;
539 rmp->deterministic = sm->deterministic;
544 static void *vl_api_snat_show_config_t_print
545 (vl_api_snat_show_config_t * mp, void *handle)
549 s = format (0, "SCRIPT: snat_show_config ");
555 vl_api_snat_set_workers_t_handler (vl_api_snat_set_workers_t * mp)
557 snat_main_t *sm = &snat_main;
558 vl_api_snat_set_workers_reply_t *rmp;
561 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
563 if (sm->num_workers < 2)
565 rv = VNET_API_ERROR_FEATURE_DISABLED;
569 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
570 rv = snat_set_workers (bitmap);
571 clib_bitmap_free (bitmap);
574 REPLY_MACRO (VL_API_SNAT_SET_WORKERS_REPLY);
577 static void *vl_api_snat_set_workers_t_print
578 (vl_api_snat_set_workers_t * mp, void *handle)
584 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
586 s = format (0, "SCRIPT: snat_set_workers ");
587 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
589 clib_bitmap_foreach (i, bitmap,
592 s = format (s, "%d", i);
594 s = format (s, ",%d", i);
598 clib_bitmap_free (bitmap);
603 send_snat_worker_details
604 (u32 worker_index, unix_shared_memory_queue_t * q, u32 context)
606 vl_api_snat_worker_details_t *rmp;
607 snat_main_t *sm = &snat_main;
608 vlib_worker_thread_t *w =
609 vlib_worker_threads + worker_index + sm->first_worker_index;
611 rmp = vl_msg_api_alloc (sizeof (*rmp));
612 memset (rmp, 0, sizeof (*rmp));
613 rmp->_vl_msg_id = ntohs (VL_API_SNAT_WORKER_DETAILS + sm->msg_id_base);
614 rmp->context = context;
615 rmp->worker_index = htonl (worker_index);
616 rmp->lcore_id = htonl (w->lcore_id);
617 strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
619 vl_msg_api_send_shmem (q, (u8 *) & rmp);
623 vl_api_snat_worker_dump_t_handler (vl_api_snat_worker_dump_t * mp)
625 unix_shared_memory_queue_t *q;
626 snat_main_t *sm = &snat_main;
629 q = vl_api_client_index_to_input_queue (mp->client_index);
634 vec_foreach (worker_index, sm->workers)
635 send_snat_worker_details(*worker_index, q, mp->context);
639 static void *vl_api_snat_worker_dump_t_print
640 (vl_api_snat_worker_dump_t * mp, void *handle)
644 s = format (0, "SCRIPT: snat_worker_dump ");
650 vl_api_snat_add_del_interface_addr_t_handler
651 (vl_api_snat_add_del_interface_addr_t * mp)
653 snat_main_t *sm = &snat_main;
654 vl_api_snat_add_del_interface_addr_reply_t *rmp;
655 u8 is_del = mp->is_add == 0;
656 u32 sw_if_index = ntohl (mp->sw_if_index);
659 VALIDATE_SW_IF_INDEX (mp);
661 rv = snat_add_interface_address (sm, sw_if_index, is_del);
663 BAD_SW_IF_INDEX_LABEL;
665 REPLY_MACRO (VL_API_SNAT_ADD_DEL_INTERFACE_ADDR_REPLY);
668 static void *vl_api_snat_add_del_interface_addr_t_print
669 (vl_api_snat_add_del_interface_addr_t * mp, void *handle)
673 s = format (0, "SCRIPT: snat_add_del_interface_addr ");
674 s = format (s, "sw_if_index %d %s",
675 clib_host_to_net_u32 (mp->sw_if_index),
676 mp->is_add ? "" : "del");
682 send_snat_interface_addr_details
683 (u32 sw_if_index, unix_shared_memory_queue_t * q, u32 context)
685 vl_api_snat_interface_addr_details_t *rmp;
686 snat_main_t *sm = &snat_main;
688 rmp = vl_msg_api_alloc (sizeof (*rmp));
689 memset (rmp, 0, sizeof (*rmp));
691 ntohs (VL_API_SNAT_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
692 rmp->sw_if_index = ntohl (sw_if_index);
693 rmp->context = context;
695 vl_msg_api_send_shmem (q, (u8 *) & rmp);
699 vl_api_snat_interface_addr_dump_t_handler
700 (vl_api_snat_interface_addr_dump_t * mp)
702 unix_shared_memory_queue_t *q;
703 snat_main_t *sm = &snat_main;
706 q = vl_api_client_index_to_input_queue (mp->client_index);
711 vec_foreach (i, sm->auto_add_sw_if_indices)
712 send_snat_interface_addr_details(*i, q, mp->context);
716 static void *vl_api_snat_interface_addr_dump_t_print
717 (vl_api_snat_interface_addr_dump_t * mp, void *handle)
721 s = format (0, "SCRIPT: snat_interface_addr_dump ");
727 vl_api_snat_ipfix_enable_disable_t_handler
728 (vl_api_snat_ipfix_enable_disable_t * mp)
730 snat_main_t *sm = &snat_main;
731 vl_api_snat_ipfix_enable_disable_reply_t *rmp;
734 rv = snat_ipfix_logging_enable_disable (mp->enable,
740 REPLY_MACRO (VL_API_SNAT_IPFIX_ENABLE_DISABLE_REPLY);
743 static void *vl_api_snat_ipfix_enable_disable_t_print
744 (vl_api_snat_ipfix_enable_disable_t * mp, void *handle)
748 s = format (0, "SCRIPT: snat_ipfix_enable_disable ");
750 s = format (s, "domain %d ", clib_net_to_host_u32 (mp->domain_id));
752 s = format (s, "src_port %d ", clib_net_to_host_u16 (mp->src_port));
754 s = format (s, "disable ");
760 send_snat_user_details
761 (snat_user_t * u, unix_shared_memory_queue_t * q, u32 context)
763 vl_api_snat_user_details_t *rmp;
764 snat_main_t *sm = &snat_main;
765 fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
767 rmp = vl_msg_api_alloc (sizeof (*rmp));
768 memset (rmp, 0, sizeof (*rmp));
769 rmp->_vl_msg_id = ntohs (VL_API_SNAT_USER_DETAILS + sm->msg_id_base);
771 rmp->vrf_id = ntohl (fib->ft_table_id);
774 clib_memcpy (rmp->ip_address, &(u->addr), 4);
775 rmp->nsessions = ntohl (u->nsessions);
776 rmp->nstaticsessions = ntohl (u->nstaticsessions);
777 rmp->context = context;
779 vl_msg_api_send_shmem (q, (u8 *) & rmp);
783 vl_api_snat_user_dump_t_handler (vl_api_snat_user_dump_t * mp)
785 unix_shared_memory_queue_t *q;
786 snat_main_t *sm = &snat_main;
787 snat_main_per_thread_data_t *tsm;
790 q = vl_api_client_index_to_input_queue (mp->client_index);
795 vec_foreach (tsm, sm->per_thread_data)
796 vec_foreach (u, tsm->users)
797 send_snat_user_details (u, q, mp->context);
801 static void *vl_api_snat_user_dump_t_print
802 (vl_api_snat_user_dump_t * mp, void *handle)
806 s = format (0, "SCRIPT: snat_user_dump ");
812 send_snat_user_session_details
813 (snat_session_t * s, unix_shared_memory_queue_t * q, u32 context)
815 vl_api_snat_user_session_details_t *rmp;
816 snat_main_t *sm = &snat_main;
818 rmp = vl_msg_api_alloc (sizeof (*rmp));
819 memset (rmp, 0, sizeof (*rmp));
821 ntohs (VL_API_SNAT_USER_SESSION_DETAILS + sm->msg_id_base);
823 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
824 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
825 rmp->is_static = s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING ? 1 : 0;
826 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
827 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
828 rmp->total_pkts = ntohl (s->total_pkts);
829 rmp->context = context;
830 if (snat_is_unk_proto_session (s))
832 rmp->outside_port = 0;
833 rmp->inside_port = 0;
834 rmp->protocol = ntohs (s->in2out.port);
838 rmp->outside_port = s->out2in.port;
839 rmp->inside_port = s->in2out.port;
840 rmp->protocol = ntohs (snat_proto_to_ip_proto (s->in2out.protocol));
843 vl_msg_api_send_shmem (q, (u8 *) & rmp);
847 vl_api_snat_user_session_dump_t_handler
848 (vl_api_snat_user_session_dump_t * mp)
850 unix_shared_memory_queue_t *q;
851 snat_main_t *sm = &snat_main;
852 snat_main_per_thread_data_t *tsm;
854 clib_bihash_kv_8_8_t key, value;
855 snat_user_key_t ukey;
857 u32 session_index, head_index, elt_index;
858 dlist_elt_t *head, *elt;
861 q = vl_api_client_index_to_input_queue (mp->client_index);
867 clib_memcpy (&ukey.addr, mp->ip_address, 4);
868 ip.src_address.as_u32 = ukey.addr.as_u32;
869 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
870 key.key = ukey.as_u64;
873 vec_elt_at_index (sm->per_thread_data,
874 sm->worker_in2out_cb (&ip, ukey.fib_index));
876 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
877 if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
879 u = pool_elt_at_index (tsm->users, value.value);
880 if (!u->nsessions && !u->nstaticsessions)
883 head_index = u->sessions_per_user_list_head_index;
884 head = pool_elt_at_index (tsm->list_pool, head_index);
885 elt_index = head->next;
886 elt = pool_elt_at_index (tsm->list_pool, elt_index);
887 session_index = elt->value;
888 while (session_index != ~0)
890 s = pool_elt_at_index (tsm->sessions, session_index);
892 send_snat_user_session_details (s, q, mp->context);
894 elt_index = elt->next;
895 elt = pool_elt_at_index (tsm->list_pool, elt_index);
896 session_index = elt->value;
900 static void *vl_api_snat_user_session_dump_t_print
901 (vl_api_snat_user_session_dump_t * mp, void *handle)
905 s = format (0, "SCRIPT: snat_user_session_dump ");
906 s = format (s, "ip_address %U vrf_id %d\n",
907 format_ip4_address, mp->ip_address,
908 clib_net_to_host_u32 (mp->vrf_id));
913 /******************************************************************/
914 /*** detrministic NAT/CGN (old, will be deprecated after 17.10) ***/
915 /******************************************************************/
918 vl_api_snat_add_det_map_t_handler (vl_api_snat_add_det_map_t * mp)
920 snat_main_t *sm = &snat_main;
921 vl_api_snat_add_det_map_reply_t *rmp;
923 ip4_address_t in_addr, out_addr;
925 clib_memcpy (&in_addr, mp->in_addr, 4);
926 clib_memcpy (&out_addr, mp->out_addr, 4);
927 rv = snat_det_add_map (sm, &in_addr, mp->in_plen, &out_addr,
928 mp->out_plen, mp->is_add);
930 REPLY_MACRO (VL_API_SNAT_ADD_DET_MAP_REPLY);
933 static void *vl_api_snat_add_det_map_t_print
934 (vl_api_snat_add_det_map_t * mp, void *handle)
938 s = format (0, "SCRIPT: snat_add_det_map ");
939 s = format (s, "inside address %U/%d outside address %U/%d\n",
940 format_ip4_address, mp->in_addr, mp->in_plen,
941 format_ip4_address, mp->out_addr, mp->out_plen);
947 vl_api_snat_det_forward_t_handler (vl_api_snat_det_forward_t * mp)
949 snat_main_t *sm = &snat_main;
950 vl_api_snat_det_forward_reply_t *rmp;
952 u16 lo_port = 0, hi_port = 0;
954 ip4_address_t in_addr, out_addr;
957 clib_memcpy (&in_addr, mp->in_addr, 4);
958 dm = snat_det_map_by_user (sm, &in_addr);
961 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
965 snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
966 hi_port = lo_port + dm->ports_per_host - 1;
970 REPLY_MACRO2 (VL_API_SNAT_DET_FORWARD_REPLY,
972 rmp->out_port_lo = ntohs (lo_port);
973 rmp->out_port_hi = ntohs (hi_port);
975 memset (rmp->out_addr, 0, 16);
976 clib_memcpy (rmp->out_addr, &out_addr, 4);
981 static void *vl_api_snat_det_forward_t_print
982 (vl_api_snat_det_forward_t * mp, void *handle)
986 s = format (0, "SCRIPT: smat_det_forward_t");
987 s = format (s, "inside ip address %U\n", format_ip4_address, mp->in_addr);
993 vl_api_snat_det_reverse_t_handler (vl_api_snat_det_reverse_t * mp)
995 snat_main_t *sm = &snat_main;
996 vl_api_snat_det_reverse_reply_t *rmp;
998 ip4_address_t out_addr, in_addr;
1002 clib_memcpy (&out_addr, mp->out_addr, 4);
1003 dm = snat_det_map_by_out (sm, &out_addr);
1006 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1010 snat_det_reverse (dm, &out_addr, htons (mp->out_port), &in_addr);
1014 REPLY_MACRO2 (VL_API_SNAT_DET_REVERSE_REPLY,
1017 memset (rmp->in_addr, 0, 16);
1018 clib_memcpy (rmp->in_addr, &in_addr, 4);
1023 static void *vl_api_snat_det_reverse_t_print
1024 (vl_api_snat_det_reverse_t * mp, void *handle)
1028 s = format (0, "SCRIPT: smat_det_reverse_t");
1029 s = format (s, "outside ip address %U outside port %d",
1030 format_ip4_address, mp->out_addr, ntohs (mp->out_port));
1036 sent_snat_det_map_details
1037 (snat_det_map_t * m, unix_shared_memory_queue_t * q, u32 context)
1039 vl_api_snat_det_map_details_t *rmp;
1040 snat_main_t *sm = &snat_main;
1042 rmp = vl_msg_api_alloc (sizeof (*rmp));
1043 memset (rmp, 0, sizeof (*rmp));
1044 rmp->_vl_msg_id = ntohs (VL_API_SNAT_DET_MAP_DETAILS + sm->msg_id_base);
1046 clib_memcpy (rmp->in_addr, &m->in_addr, 4);
1047 rmp->in_plen = m->in_plen;
1048 clib_memcpy (rmp->out_addr, &m->out_addr, 4);
1049 rmp->out_plen = m->out_plen;
1050 rmp->sharing_ratio = htonl (m->sharing_ratio);
1051 rmp->ports_per_host = htons (m->ports_per_host);
1052 rmp->ses_num = htonl (m->ses_num);
1053 rmp->context = context;
1055 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1059 vl_api_snat_det_map_dump_t_handler (vl_api_snat_det_map_dump_t * mp)
1061 unix_shared_memory_queue_t *q;
1062 snat_main_t *sm = &snat_main;
1065 q = vl_api_client_index_to_input_queue (mp->client_index);
1070 vec_foreach(m, sm->det_maps)
1071 sent_snat_det_map_details(m, q, mp->context);
1075 static void *vl_api_snat_det_map_dump_t_print
1076 (vl_api_snat_det_map_dump_t * mp, void *handle)
1080 s = format (0, "SCRIPT: snat_det_map_dump ");
1086 vl_api_snat_det_set_timeouts_t_handler (vl_api_snat_det_set_timeouts_t * mp)
1088 snat_main_t *sm = &snat_main;
1089 vl_api_snat_det_set_timeouts_reply_t *rmp;
1092 sm->udp_timeout = ntohl (mp->udp);
1093 sm->tcp_established_timeout = ntohl (mp->tcp_established);
1094 sm->tcp_transitory_timeout = ntohl (mp->tcp_transitory);
1095 sm->icmp_timeout = ntohl (mp->icmp);
1097 REPLY_MACRO (VL_API_SNAT_DET_SET_TIMEOUTS_REPLY);
1100 static void *vl_api_snat_det_set_timeouts_t_print
1101 (vl_api_snat_det_set_timeouts_t * mp, void *handle)
1105 s = format (0, "SCRIPT: snat_det_set_timeouts ");
1106 s = format (s, "udp %d tcp_established %d tcp_transitory %d icmp %d\n",
1108 ntohl (mp->tcp_established),
1109 ntohl (mp->tcp_transitory), ntohl (mp->icmp));
1115 vl_api_snat_det_get_timeouts_t_handler (vl_api_snat_det_get_timeouts_t * mp)
1117 snat_main_t *sm = &snat_main;
1118 vl_api_snat_det_get_timeouts_reply_t *rmp;
1122 REPLY_MACRO2 (VL_API_SNAT_DET_GET_TIMEOUTS_REPLY,
1124 rmp->udp = htonl (sm->udp_timeout);
1125 rmp->tcp_established = htonl (sm->tcp_established_timeout);
1126 rmp->tcp_transitory = htonl (sm->tcp_transitory_timeout);
1127 rmp->icmp = htonl (sm->icmp_timeout);
1132 static void *vl_api_snat_det_get_timeouts_t_print
1133 (vl_api_snat_det_get_timeouts_t * mp, void *handle)
1137 s = format (0, "SCRIPT: snat_det_get_timeouts");
1143 vl_api_snat_det_close_session_out_t_handler
1144 (vl_api_snat_det_close_session_out_t * mp)
1146 snat_main_t *sm = &snat_main;
1147 vl_api_snat_det_close_session_out_reply_t *rmp;
1148 ip4_address_t out_addr, ext_addr, in_addr;
1149 snat_det_out_key_t key;
1151 snat_det_session_t *ses;
1154 clib_memcpy (&out_addr, mp->out_addr, 4);
1155 clib_memcpy (&ext_addr, mp->ext_addr, 4);
1157 dm = snat_det_map_by_out (sm, &out_addr);
1160 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1163 snat_det_reverse (dm, &ext_addr, ntohs (mp->out_port), &in_addr);
1164 key.ext_host_addr = ext_addr;
1165 key.ext_host_port = mp->ext_port;
1166 key.out_port = mp->out_port;
1167 ses = snat_det_get_ses_by_out (dm, &in_addr, key.as_u64);
1170 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1173 snat_det_ses_close (dm, ses);
1176 REPLY_MACRO (VL_API_SNAT_DET_CLOSE_SESSION_OUT_REPLY);
1179 static void *vl_api_snat_det_close_session_out_t_print
1180 (vl_api_snat_det_close_session_out_t * mp, void *handle)
1184 s = format (0, "SCRIPT: snat_det_close_session_out ");
1185 s = format (s, "out_addr %U out_port %d "
1186 "ext_addr %U ext_port %d\n",
1187 format_ip4_address, mp->out_addr, ntohs (mp->out_port),
1188 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
1194 vl_api_snat_det_close_session_in_t_handler
1195 (vl_api_snat_det_close_session_in_t * mp)
1197 snat_main_t *sm = &snat_main;
1198 vl_api_snat_det_close_session_in_reply_t *rmp;
1199 ip4_address_t in_addr, ext_addr;
1200 snat_det_out_key_t key;
1202 snat_det_session_t *ses;
1205 clib_memcpy (&in_addr, mp->in_addr, 4);
1206 clib_memcpy (&ext_addr, mp->ext_addr, 4);
1208 dm = snat_det_map_by_user (sm, &in_addr);
1211 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1214 key.ext_host_addr = ext_addr;
1215 key.ext_host_port = mp->ext_port;
1216 ses = snat_det_find_ses_by_in (dm, &in_addr, mp->in_port, key);
1219 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1222 snat_det_ses_close (dm, ses);
1225 REPLY_MACRO (VL_API_SNAT_DET_CLOSE_SESSION_OUT_REPLY);
1228 static void *vl_api_snat_det_close_session_in_t_print
1229 (vl_api_snat_det_close_session_in_t * mp, void *handle)
1232 s = format (0, "SCRIPT: snat_det_close_session_in ");
1233 s = format (s, "in_addr %U in_port %d "
1234 "ext_addr %U ext_port %d\n",
1235 format_ip4_address, mp->in_addr, ntohs (mp->in_port),
1236 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
1242 send_snat_det_session_details
1243 (snat_det_session_t * s, unix_shared_memory_queue_t * q, u32 context)
1245 vl_api_snat_det_session_details_t *rmp;
1246 snat_main_t *sm = &snat_main;
1248 rmp = vl_msg_api_alloc (sizeof (*rmp));
1249 memset (rmp, 0, sizeof (*rmp));
1250 rmp->_vl_msg_id = ntohs (VL_API_SNAT_DET_SESSION_DETAILS + sm->msg_id_base);
1252 rmp->in_port = s->in_port;
1253 clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
1254 rmp->ext_port = s->out.ext_host_port;
1255 rmp->out_port = s->out.out_port;
1256 rmp->state = s->state;
1257 rmp->expire = ntohl (s->expire);
1258 rmp->context = context;
1260 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1264 vl_api_snat_det_session_dump_t_handler (vl_api_snat_det_session_dump_t * mp)
1266 unix_shared_memory_queue_t *q;
1267 snat_main_t *sm = &snat_main;
1268 ip4_address_t user_addr;
1270 snat_det_session_t *s, empty_ses;
1273 q = vl_api_client_index_to_input_queue (mp->client_index);
1279 memset (&empty_ses, 0, sizeof (empty_ses));
1280 clib_memcpy (&user_addr, mp->user_addr, 4);
1281 dm = snat_det_map_by_user (sm, &user_addr);
1285 s = dm->sessions + snat_det_user_ses_offset (&user_addr, dm->in_plen);
1286 for (i = 0; i < SNAT_DET_SES_PER_USER; i++)
1289 send_snat_det_session_details (s, q, mp->context);
1294 static void *vl_api_snat_det_session_dump_t_print
1295 (vl_api_snat_det_session_dump_t * mp, void *handle)
1299 s = format (0, "SCRIPT: snat_det_session_dump ");
1300 s = format (s, "user_addr %U\n", format_ip4_address, mp->user_addr);
1305 /******************************/
1306 /*** Common NAT plugin APIs ***/
1307 /******************************/
1310 vl_api_nat_control_ping_t_handler (vl_api_nat_control_ping_t * mp)
1312 vl_api_nat_control_ping_reply_t *rmp;
1313 snat_main_t *sm = &snat_main;
1317 REPLY_MACRO2 (VL_API_NAT_CONTROL_PING_REPLY,
1319 rmp->vpe_pid = ntohl (getpid ());
1325 vl_api_nat_control_ping_t_print (vl_api_nat_control_ping_t * mp, void *handle)
1329 s = format (0, "SCRIPT: nat_control_ping ");
1335 vl_api_nat_show_config_t_handler (vl_api_nat_show_config_t * mp)
1337 vl_api_nat_show_config_reply_t *rmp;
1338 snat_main_t *sm = &snat_main;
1342 REPLY_MACRO2 (VL_API_NAT_SHOW_CONFIG_REPLY,
1344 rmp->translation_buckets = htonl (sm->translation_buckets);
1345 rmp->translation_memory_size = htonl (sm->translation_memory_size);
1346 rmp->user_buckets = htonl (sm->user_buckets);
1347 rmp->user_memory_size = htonl (sm->user_memory_size);
1348 rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
1349 rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
1350 rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
1351 rmp->static_mapping_only = sm->static_mapping_only;
1352 rmp->static_mapping_connection_tracking =
1353 sm->static_mapping_connection_tracking;
1354 rmp->deterministic = sm->deterministic;
1360 vl_api_nat_show_config_t_print (vl_api_nat_show_config_t * mp, void *handle)
1364 s = format (0, "SCRIPT: nat_show_config ");
1370 vl_api_nat_set_workers_t_handler (vl_api_nat_set_workers_t * mp)
1372 snat_main_t *sm = &snat_main;
1373 vl_api_snat_set_workers_reply_t *rmp;
1376 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
1378 if (sm->num_workers < 2)
1380 rv = VNET_API_ERROR_FEATURE_DISABLED;
1384 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
1385 rv = snat_set_workers (bitmap);
1386 clib_bitmap_free (bitmap);
1389 REPLY_MACRO (VL_API_NAT_SET_WORKERS_REPLY);
1393 vl_api_nat_set_workers_t_print (vl_api_nat_set_workers_t * mp, void *handle)
1399 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
1401 s = format (0, "SCRIPT: nat_set_workers ");
1402 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
1404 clib_bitmap_foreach (i, bitmap,
1407 s = format (s, "%d", i);
1409 s = format (s, ",%d", i);
1413 clib_bitmap_free (bitmap);
1418 send_nat_worker_details (u32 worker_index, unix_shared_memory_queue_t * q,
1421 vl_api_nat_worker_details_t *rmp;
1422 snat_main_t *sm = &snat_main;
1423 vlib_worker_thread_t *w =
1424 vlib_worker_threads + worker_index + sm->first_worker_index;
1426 rmp = vl_msg_api_alloc (sizeof (*rmp));
1427 memset (rmp, 0, sizeof (*rmp));
1428 rmp->_vl_msg_id = ntohs (VL_API_NAT_WORKER_DETAILS + sm->msg_id_base);
1429 rmp->context = context;
1430 rmp->worker_index = htonl (worker_index);
1431 rmp->lcore_id = htonl (w->lcore_id);
1432 strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
1434 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1438 vl_api_nat_worker_dump_t_handler (vl_api_nat_worker_dump_t * mp)
1440 unix_shared_memory_queue_t *q;
1441 snat_main_t *sm = &snat_main;
1444 q = vl_api_client_index_to_input_queue (mp->client_index);
1449 vec_foreach (worker_index, sm->workers)
1450 send_nat_worker_details(*worker_index, q, mp->context);
1455 vl_api_nat_worker_dump_t_print (vl_api_nat_worker_dump_t * mp, void *handle)
1459 s = format (0, "SCRIPT: nat_worker_dump ");
1465 vl_api_nat_ipfix_enable_disable_t_handler (vl_api_nat_ipfix_enable_disable_t *
1468 snat_main_t *sm = &snat_main;
1469 vl_api_nat_ipfix_enable_disable_reply_t *rmp;
1472 rv = snat_ipfix_logging_enable_disable (mp->enable,
1473 clib_host_to_net_u32
1475 clib_host_to_net_u16
1478 REPLY_MACRO (VL_API_NAT_IPFIX_ENABLE_DISABLE_REPLY);
1482 vl_api_nat_ipfix_enable_disable_t_print (vl_api_nat_ipfix_enable_disable_t *
1487 s = format (0, "SCRIPT: nat_ipfix_enable_disable ");
1489 s = format (s, "domain %d ", clib_net_to_host_u32 (mp->domain_id));
1491 s = format (s, "src_port %d ", clib_net_to_host_u16 (mp->src_port));
1493 s = format (s, "disable ");
1502 vl_api_nat44_add_del_address_range_t_handler
1503 (vl_api_nat44_add_del_address_range_t * mp)
1505 snat_main_t *sm = &snat_main;
1506 vl_api_nat44_add_del_address_range_reply_t *rmp;
1507 ip4_address_t this_addr;
1508 u32 start_host_order, end_host_order;
1514 if (sm->static_mapping_only)
1516 rv = VNET_API_ERROR_FEATURE_DISABLED;
1520 tmp = (u32 *) mp->first_ip_address;
1521 start_host_order = clib_host_to_net_u32 (tmp[0]);
1522 tmp = (u32 *) mp->last_ip_address;
1523 end_host_order = clib_host_to_net_u32 (tmp[0]);
1525 count = (end_host_order - start_host_order) + 1;
1527 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
1530 clib_warning ("%U - %U, %d addresses...",
1531 format_ip4_address, mp->first_ip_address,
1532 format_ip4_address, mp->last_ip_address, count);
1534 memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
1536 for (i = 0; i < count; i++)
1539 snat_add_address (sm, &this_addr, vrf_id);
1541 rv = snat_del_address (sm, this_addr, 0);
1546 increment_v4_address (&this_addr);
1550 REPLY_MACRO (VL_API_NAT44_ADD_DEL_ADDRESS_RANGE_REPLY);
1553 static void *vl_api_nat44_add_del_address_range_t_print
1554 (vl_api_nat44_add_del_address_range_t * mp, void *handle)
1558 s = format (0, "SCRIPT: nat44_add_address_range ");
1559 s = format (s, "%U ", format_ip4_address, mp->first_ip_address);
1560 if (memcmp (mp->first_ip_address, mp->last_ip_address, 4))
1562 s = format (s, " - %U ", format_ip4_address, mp->last_ip_address);
1568 send_nat44_address_details (snat_address_t * a,
1569 unix_shared_memory_queue_t * q, u32 context)
1571 vl_api_nat44_address_details_t *rmp;
1572 snat_main_t *sm = &snat_main;
1574 rmp = vl_msg_api_alloc (sizeof (*rmp));
1575 memset (rmp, 0, sizeof (*rmp));
1576 rmp->_vl_msg_id = ntohs (VL_API_NAT44_ADDRESS_DETAILS + sm->msg_id_base);
1577 clib_memcpy (rmp->ip_address, &(a->addr), 4);
1578 if (a->fib_index != ~0)
1580 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
1581 rmp->vrf_id = ntohl (fib->ft_table_id);
1585 rmp->context = context;
1587 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1591 vl_api_nat44_address_dump_t_handler (vl_api_nat44_address_dump_t * mp)
1593 unix_shared_memory_queue_t *q;
1594 snat_main_t *sm = &snat_main;
1597 q = vl_api_client_index_to_input_queue (mp->client_index);
1602 vec_foreach (a, sm->addresses)
1603 send_nat44_address_details (a, q, mp->context);
1608 vl_api_nat44_address_dump_t_print (vl_api_nat44_address_dump_t * mp,
1613 s = format (0, "SCRIPT: nat44_address_dump ");
1619 vl_api_nat44_interface_add_del_feature_t_handler
1620 (vl_api_nat44_interface_add_del_feature_t * mp)
1622 snat_main_t *sm = &snat_main;
1623 vl_api_nat44_interface_add_del_feature_reply_t *rmp;
1624 u8 is_del = mp->is_add == 0;
1625 u32 sw_if_index = ntohl (mp->sw_if_index);
1628 VALIDATE_SW_IF_INDEX (mp);
1630 rv = snat_interface_add_del (sw_if_index, mp->is_inside, is_del);
1632 BAD_SW_IF_INDEX_LABEL;
1634 REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_FEATURE_REPLY);
1637 static void *vl_api_nat44_interface_add_del_feature_t_print
1638 (vl_api_nat44_interface_add_del_feature_t * mp, void *handle)
1642 s = format (0, "SCRIPT: nat44_interface_add_del_feature ");
1643 s = format (s, "sw_if_index %d %s %s",
1644 clib_host_to_net_u32 (mp->sw_if_index),
1645 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
1651 send_nat44_interface_details (snat_interface_t * i,
1652 unix_shared_memory_queue_t * q, u32 context)
1654 vl_api_nat44_interface_details_t *rmp;
1655 snat_main_t *sm = &snat_main;
1657 rmp = vl_msg_api_alloc (sizeof (*rmp));
1658 memset (rmp, 0, sizeof (*rmp));
1659 rmp->_vl_msg_id = ntohs (VL_API_NAT44_INTERFACE_DETAILS + sm->msg_id_base);
1660 rmp->sw_if_index = ntohl (i->sw_if_index);
1661 rmp->is_inside = (nat_interface_is_inside (i)
1662 && nat_interface_is_outside (i)) ? 2 :
1663 nat_interface_is_inside (i);
1664 rmp->context = context;
1666 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1670 vl_api_nat44_interface_dump_t_handler (vl_api_nat44_interface_dump_t * mp)
1672 unix_shared_memory_queue_t *q;
1673 snat_main_t *sm = &snat_main;
1674 snat_interface_t *i;
1676 q = vl_api_client_index_to_input_queue (mp->client_index);
1681 pool_foreach (i, sm->interfaces,
1683 send_nat44_interface_details(i, q, mp->context);
1689 vl_api_nat44_interface_dump_t_print (vl_api_nat44_interface_dump_t * mp,
1694 s = format (0, "SCRIPT: nat44_interface_dump ");
1700 vl_api_nat44_interface_add_del_output_feature_t_handler
1701 (vl_api_nat44_interface_add_del_output_feature_t * mp)
1703 snat_main_t *sm = &snat_main;
1704 vl_api_nat44_interface_add_del_output_feature_reply_t *rmp;
1705 u8 is_del = mp->is_add == 0;
1706 u32 sw_if_index = ntohl (mp->sw_if_index);
1709 VALIDATE_SW_IF_INDEX (mp);
1711 rv = snat_interface_add_del_output_feature (sw_if_index, mp->is_inside,
1714 BAD_SW_IF_INDEX_LABEL;
1716 REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY);
1719 static void *vl_api_nat44_interface_add_del_output_feature_t_print
1720 (vl_api_nat44_interface_add_del_output_feature_t * mp, void *handle)
1724 s = format (0, "SCRIPT: nat44_interface_add_del_output_feature ");
1725 s = format (s, "sw_if_index %d %s %s",
1726 clib_host_to_net_u32 (mp->sw_if_index),
1727 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
1733 send_nat44_interface_output_feature_details (snat_interface_t * i,
1734 unix_shared_memory_queue_t * q,
1737 vl_api_nat44_interface_output_feature_details_t *rmp;
1738 snat_main_t *sm = &snat_main;
1740 rmp = vl_msg_api_alloc (sizeof (*rmp));
1741 memset (rmp, 0, sizeof (*rmp));
1743 ntohs (VL_API_NAT44_INTERFACE_OUTPUT_FEATURE_DETAILS + sm->msg_id_base);
1744 rmp->sw_if_index = ntohl (i->sw_if_index);
1745 rmp->context = context;
1746 rmp->is_inside = nat_interface_is_inside (i);
1748 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1752 vl_api_nat44_interface_output_feature_dump_t_handler
1753 (vl_api_nat44_interface_output_feature_dump_t * mp)
1755 unix_shared_memory_queue_t *q;
1756 snat_main_t *sm = &snat_main;
1757 snat_interface_t *i;
1759 q = vl_api_client_index_to_input_queue (mp->client_index);
1764 pool_foreach (i, sm->output_feature_interfaces,
1766 send_nat44_interface_output_feature_details(i, q, mp->context);
1771 static void *vl_api_nat44_interface_output_feature_dump_t_print
1772 (vl_api_nat44_interface_output_feature_dump_t * mp, void *handle)
1776 s = format (0, "SCRIPT: nat44_interface_output_feature_dump ");
1782 vl_api_nat44_add_del_static_mapping_t_handler
1783 (vl_api_nat44_add_del_static_mapping_t * mp)
1785 snat_main_t *sm = &snat_main;
1786 vl_api_nat44_add_del_static_mapping_reply_t *rmp;
1787 ip4_address_t local_addr, external_addr;
1788 u16 local_port = 0, external_port = 0;
1789 u32 vrf_id, external_sw_if_index;
1791 snat_protocol_t proto;
1793 memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
1794 memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
1795 if (mp->addr_only == 0)
1797 local_port = clib_net_to_host_u16 (mp->local_port);
1798 external_port = clib_net_to_host_u16 (mp->external_port);
1800 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
1801 external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
1802 proto = ip_proto_to_snat_proto (mp->protocol);
1804 rv = snat_add_static_mapping (local_addr, external_addr, local_port,
1805 external_port, vrf_id, mp->addr_only,
1806 external_sw_if_index, proto, mp->is_add);
1808 REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_REPLY);
1811 static void *vl_api_nat44_add_del_static_mapping_t_print
1812 (vl_api_nat44_add_del_static_mapping_t * mp, void *handle)
1816 s = format (0, "SCRIPT: nat44_add_del_static_mapping ");
1817 s = format (s, "protocol %d local_addr %U external_addr %U ",
1819 format_ip4_address, mp->local_ip_address,
1820 format_ip4_address, mp->external_ip_address);
1822 if (mp->addr_only == 0)
1823 s = format (s, "local_port %d external_port %d ",
1824 clib_net_to_host_u16 (mp->local_port),
1825 clib_net_to_host_u16 (mp->external_port));
1827 if (mp->vrf_id != ~0)
1828 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
1830 if (mp->external_sw_if_index != ~0)
1831 s = format (s, "external_sw_if_index %d",
1832 clib_net_to_host_u32 (mp->external_sw_if_index));
1837 send_nat44_static_mapping_details (snat_static_mapping_t * m,
1838 unix_shared_memory_queue_t * q,
1841 vl_api_nat44_static_mapping_details_t *rmp;
1842 snat_main_t *sm = &snat_main;
1844 rmp = vl_msg_api_alloc (sizeof (*rmp));
1845 memset (rmp, 0, sizeof (*rmp));
1847 ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
1848 rmp->addr_only = m->addr_only;
1849 clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
1850 clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
1851 rmp->local_port = htons (m->local_port);
1852 rmp->external_port = htons (m->external_port);
1853 rmp->external_sw_if_index = ~0;
1854 rmp->vrf_id = htonl (m->vrf_id);
1855 rmp->protocol = snat_proto_to_ip_proto (m->proto);
1856 rmp->context = context;
1858 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1862 send_nat44_static_map_resolve_details (snat_static_map_resolve_t * m,
1863 unix_shared_memory_queue_t * q,
1866 vl_api_nat44_static_mapping_details_t *rmp;
1867 snat_main_t *sm = &snat_main;
1869 rmp = vl_msg_api_alloc (sizeof (*rmp));
1870 memset (rmp, 0, sizeof (*rmp));
1872 ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
1873 rmp->addr_only = m->addr_only;
1874 clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
1875 rmp->local_port = htons (m->l_port);
1876 rmp->external_port = htons (m->e_port);
1877 rmp->external_sw_if_index = htonl (m->sw_if_index);
1878 rmp->vrf_id = htonl (m->vrf_id);
1879 rmp->protocol = snat_proto_to_ip_proto (m->proto);
1880 rmp->context = context;
1882 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1886 vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
1889 unix_shared_memory_queue_t *q;
1890 snat_main_t *sm = &snat_main;
1891 snat_static_mapping_t *m;
1892 snat_static_map_resolve_t *rp;
1895 q = vl_api_client_index_to_input_queue (mp->client_index);
1900 pool_foreach (m, sm->static_mappings,
1902 if (!vec_len(m->locals))
1903 send_nat44_static_mapping_details (m, q, mp->context);
1907 for (j = 0; j < vec_len (sm->to_resolve); j++)
1909 rp = sm->to_resolve + j;
1910 send_nat44_static_map_resolve_details (rp, q, mp->context);
1915 vl_api_nat44_static_mapping_dump_t_print (vl_api_nat44_static_mapping_dump_t *
1920 s = format (0, "SCRIPT: nat44_static_mapping_dump ");
1926 vl_api_nat44_add_del_interface_addr_t_handler
1927 (vl_api_nat44_add_del_interface_addr_t * mp)
1929 snat_main_t *sm = &snat_main;
1930 vl_api_nat44_add_del_interface_addr_reply_t *rmp;
1931 u8 is_del = mp->is_add == 0;
1932 u32 sw_if_index = ntohl (mp->sw_if_index);
1935 VALIDATE_SW_IF_INDEX (mp);
1937 rv = snat_add_interface_address (sm, sw_if_index, is_del);
1939 BAD_SW_IF_INDEX_LABEL;
1941 REPLY_MACRO (VL_API_NAT44_ADD_DEL_INTERFACE_ADDR_REPLY);
1944 static void *vl_api_nat44_add_del_interface_addr_t_print
1945 (vl_api_nat44_add_del_interface_addr_t * mp, void *handle)
1949 s = format (0, "SCRIPT: nat44_add_del_interface_addr ");
1950 s = format (s, "sw_if_index %d %s",
1951 clib_host_to_net_u32 (mp->sw_if_index),
1952 mp->is_add ? "" : "del");
1958 send_nat44_interface_addr_details (u32 sw_if_index,
1959 unix_shared_memory_queue_t * q,
1962 vl_api_nat44_interface_addr_details_t *rmp;
1963 snat_main_t *sm = &snat_main;
1965 rmp = vl_msg_api_alloc (sizeof (*rmp));
1966 memset (rmp, 0, sizeof (*rmp));
1968 ntohs (VL_API_NAT44_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
1969 rmp->sw_if_index = ntohl (sw_if_index);
1970 rmp->context = context;
1972 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1976 vl_api_nat44_interface_addr_dump_t_handler (vl_api_nat44_interface_addr_dump_t
1979 unix_shared_memory_queue_t *q;
1980 snat_main_t *sm = &snat_main;
1983 q = vl_api_client_index_to_input_queue (mp->client_index);
1988 vec_foreach (i, sm->auto_add_sw_if_indices)
1989 send_nat44_interface_addr_details(*i, q, mp->context);
1994 vl_api_nat44_interface_addr_dump_t_print (vl_api_nat44_interface_addr_dump_t *
1999 s = format (0, "SCRIPT: nat44_interface_addr_dump ");
2005 send_nat44_user_details (snat_user_t * u, unix_shared_memory_queue_t * q,
2008 vl_api_nat44_user_details_t *rmp;
2009 snat_main_t *sm = &snat_main;
2010 fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
2012 rmp = vl_msg_api_alloc (sizeof (*rmp));
2013 memset (rmp, 0, sizeof (*rmp));
2014 rmp->_vl_msg_id = ntohs (VL_API_NAT44_USER_DETAILS + sm->msg_id_base);
2016 rmp->vrf_id = ntohl (fib->ft_table_id);
2018 clib_memcpy (rmp->ip_address, &(u->addr), 4);
2019 rmp->nsessions = ntohl (u->nsessions);
2020 rmp->nstaticsessions = ntohl (u->nstaticsessions);
2021 rmp->context = context;
2023 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2027 vl_api_nat44_user_dump_t_handler (vl_api_nat44_user_dump_t * mp)
2029 unix_shared_memory_queue_t *q;
2030 snat_main_t *sm = &snat_main;
2031 snat_main_per_thread_data_t *tsm;
2034 q = vl_api_client_index_to_input_queue (mp->client_index);
2039 vec_foreach (tsm, sm->per_thread_data)
2040 vec_foreach (u, tsm->users)
2041 send_nat44_user_details (u, q, mp->context);
2046 vl_api_nat44_user_dump_t_print (vl_api_nat44_user_dump_t * mp, void *handle)
2050 s = format (0, "SCRIPT: nat44_user_dump ");
2056 send_nat44_user_session_details (snat_session_t * s,
2057 unix_shared_memory_queue_t * q, u32 context)
2059 vl_api_nat44_user_session_details_t *rmp;
2060 snat_main_t *sm = &snat_main;
2062 rmp = vl_msg_api_alloc (sizeof (*rmp));
2063 memset (rmp, 0, sizeof (*rmp));
2065 ntohs (VL_API_NAT44_USER_SESSION_DETAILS + sm->msg_id_base);
2066 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
2067 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
2068 rmp->is_static = s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING ? 1 : 0;
2069 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
2070 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
2071 rmp->total_pkts = ntohl (s->total_pkts);
2072 rmp->context = context;
2073 if (snat_is_unk_proto_session (s))
2075 rmp->outside_port = 0;
2076 rmp->inside_port = 0;
2077 rmp->protocol = ntohs (s->in2out.port);
2081 rmp->outside_port = s->out2in.port;
2082 rmp->inside_port = s->in2out.port;
2083 rmp->protocol = ntohs (snat_proto_to_ip_proto (s->in2out.protocol));
2086 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2090 vl_api_nat44_user_session_dump_t_handler (vl_api_nat44_user_session_dump_t *
2093 unix_shared_memory_queue_t *q;
2094 snat_main_t *sm = &snat_main;
2095 snat_main_per_thread_data_t *tsm;
2097 clib_bihash_kv_8_8_t key, value;
2098 snat_user_key_t ukey;
2100 u32 session_index, head_index, elt_index;
2101 dlist_elt_t *head, *elt;
2104 q = vl_api_client_index_to_input_queue (mp->client_index);
2108 clib_memcpy (&ukey.addr, mp->ip_address, 4);
2109 ip.src_address.as_u32 = ukey.addr.as_u32;
2110 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
2111 key.key = ukey.as_u64;
2112 if (sm->num_workers)
2114 vec_elt_at_index (sm->per_thread_data,
2115 sm->worker_in2out_cb (&ip, ukey.fib_index));
2117 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
2118 if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
2120 u = pool_elt_at_index (tsm->users, value.value);
2121 if (!u->nsessions && !u->nstaticsessions)
2124 head_index = u->sessions_per_user_list_head_index;
2125 head = pool_elt_at_index (tsm->list_pool, head_index);
2126 elt_index = head->next;
2127 elt = pool_elt_at_index (tsm->list_pool, elt_index);
2128 session_index = elt->value;
2129 while (session_index != ~0)
2131 s = pool_elt_at_index (tsm->sessions, session_index);
2133 send_nat44_user_session_details (s, q, mp->context);
2135 elt_index = elt->next;
2136 elt = pool_elt_at_index (tsm->list_pool, elt_index);
2137 session_index = elt->value;
2142 vl_api_nat44_user_session_dump_t_print (vl_api_nat44_user_session_dump_t * mp,
2147 s = format (0, "SCRIPT: nat44_user_session_dump ");
2148 s = format (s, "ip_address %U vrf_id %d\n",
2149 format_ip4_address, mp->ip_address,
2150 clib_net_to_host_u32 (mp->vrf_id));
2155 static nat44_lb_addr_port_t *
2156 unformat_nat44_lb_addr_port (vl_api_nat44_lb_addr_port_t * addr_port_pairs,
2157 u8 addr_port_pair_num)
2160 nat44_lb_addr_port_t *lb_addr_port_pairs = 0, lb_addr_port;
2161 vl_api_nat44_lb_addr_port_t *ap;
2163 for (i = 0; i < addr_port_pair_num; i++)
2165 ap = &addr_port_pairs[i];
2166 memset (&lb_addr_port, 0, sizeof (lb_addr_port));
2167 clib_memcpy (&lb_addr_port.addr, ap->addr, 4);
2168 lb_addr_port.port = clib_net_to_host_u16 (ap->port);
2169 lb_addr_port.probability = ap->probability;
2170 vec_add1 (lb_addr_port_pairs, lb_addr_port);
2173 return lb_addr_port_pairs;
2177 vl_api_nat44_add_del_lb_static_mapping_t_handler
2178 (vl_api_nat44_add_del_lb_static_mapping_t * mp)
2180 snat_main_t *sm = &snat_main;
2181 vl_api_nat44_add_del_lb_static_mapping_reply_t *rmp;
2183 nat44_lb_addr_port_t *locals = 0;
2184 ip4_address_t e_addr;
2185 snat_protocol_t proto;
2187 locals = unformat_nat44_lb_addr_port (mp->locals, mp->local_num);
2188 clib_memcpy (&e_addr, mp->external_addr, 4);
2189 proto = ip_proto_to_snat_proto (mp->protocol);
2192 nat44_add_del_lb_static_mapping (e_addr,
2193 clib_net_to_host_u16 (mp->external_port),
2194 proto, clib_net_to_host_u32 (mp->vrf_id),
2195 locals, mp->is_add);
2199 REPLY_MACRO (VL_API_NAT44_ADD_DEL_LB_STATIC_MAPPING_REPLY);
2202 static void *vl_api_nat44_add_del_lb_static_mapping_t_print
2203 (vl_api_nat44_add_del_lb_static_mapping_t * mp, void *handle)
2207 s = format (0, "SCRIPT: nat44_add_del_lb_static_mapping ");
2208 s = format (s, "is_add %d\n", mp->is_add);
2214 send_nat44_lb_static_mapping_details (snat_static_mapping_t * m,
2215 unix_shared_memory_queue_t * q,
2218 vl_api_nat44_lb_static_mapping_details_t *rmp;
2219 snat_main_t *sm = &snat_main;
2220 nat44_lb_addr_port_t *ap;
2221 vl_api_nat44_lb_addr_port_t *locals;
2224 vl_msg_api_alloc (sizeof (*rmp) +
2225 (vec_len (m->locals) * sizeof (nat44_lb_addr_port_t)));
2226 memset (rmp, 0, sizeof (*rmp));
2228 ntohs (VL_API_NAT44_LB_STATIC_MAPPING_DETAILS + sm->msg_id_base);
2230 clib_memcpy (rmp->external_addr, &(m->external_addr), 4);
2231 rmp->external_port = ntohs (m->external_port);
2232 rmp->protocol = snat_proto_to_ip_proto (m->proto);
2233 rmp->vrf_id = ntohl (m->vrf_id);
2234 rmp->context = context;
2236 locals = (vl_api_nat44_lb_addr_port_t *) rmp->locals;
2237 vec_foreach (ap, m->locals)
2239 clib_memcpy (locals->addr, &(ap->addr), 4);
2240 locals->port = htons (ap->port);
2241 locals->probability = ap->probability;
2246 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2250 vl_api_nat44_lb_static_mapping_dump_t_handler
2251 (vl_api_nat44_lb_static_mapping_dump_t * mp)
2253 unix_shared_memory_queue_t *q;
2254 snat_main_t *sm = &snat_main;
2255 snat_static_mapping_t *m;
2257 q = vl_api_client_index_to_input_queue (mp->client_index);
2262 pool_foreach (m, sm->static_mappings,
2264 if (vec_len(m->locals))
2265 send_nat44_lb_static_mapping_details (m, q, mp->context);
2270 static void *vl_api_nat44_lb_static_mapping_dump_t_print
2271 (vl_api_nat44_lb_static_mapping_dump_t * mp, void *handle)
2275 s = format (0, "SCRIPT: nat44_lb_static_mapping_dump ");
2281 vl_api_nat44_del_session_t_handler (vl_api_nat44_del_session_t * mp)
2283 snat_main_t *sm = &snat_main;
2284 vl_api_nat44_del_session_reply_t *rmp;
2289 snat_protocol_t proto;
2291 memcpy (&addr.as_u8, mp->address, 4);
2292 port = clib_net_to_host_u16 (mp->port);
2293 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
2294 proto = ip_proto_to_snat_proto (mp->protocol);
2296 rv = nat44_del_session (sm, &addr, port, proto, vrf_id, mp->is_in);
2298 REPLY_MACRO (VL_API_NAT44_DEL_SESSION_REPLY);
2302 vl_api_nat44_del_session_t_print (vl_api_nat44_del_session_t * mp,
2307 s = format (0, "SCRIPT: nat44_add_del_static_mapping ");
2308 s = format (s, "addr %U port %d protocol %d vrf_id %d is_in %d",
2309 format_ip4_address, mp->address,
2310 clib_net_to_host_u16 (mp->port),
2311 mp->protocol, clib_net_to_host_u32 (mp->vrf_id), mp->is_in);
2316 /*******************************/
2317 /*** Deterministic NAT (CGN) ***/
2318 /*******************************/
2321 vl_api_nat_det_add_del_map_t_handler (vl_api_nat_det_add_del_map_t * mp)
2323 snat_main_t *sm = &snat_main;
2324 vl_api_nat_det_add_del_map_reply_t *rmp;
2326 ip4_address_t in_addr, out_addr;
2330 rv = VNET_API_ERROR_UNIMPLEMENTED;
2334 clib_memcpy (&in_addr, mp->in_addr, 4);
2335 clib_memcpy (&out_addr, mp->out_addr, 4);
2336 rv = snat_det_add_map (sm, &in_addr, mp->in_plen, &out_addr,
2337 mp->out_plen, mp->is_add);
2340 REPLY_MACRO (VL_API_NAT_DET_ADD_DEL_MAP_REPLY);
2344 vl_api_nat_det_add_del_map_t_print (vl_api_nat_det_add_del_map_t * mp,
2349 s = format (0, "SCRIPT: nat_det_add_del_map ");
2350 s = format (s, "inside address %U/%d outside address %U/%d\n",
2351 format_ip4_address, mp->in_addr, mp->in_plen,
2352 format_ip4_address, mp->out_addr, mp->out_plen);
2358 vl_api_nat_det_forward_t_handler (vl_api_nat_det_forward_t * mp)
2360 snat_main_t *sm = &snat_main;
2361 vl_api_nat_det_forward_reply_t *rmp;
2363 u16 lo_port = 0, hi_port = 0;
2365 ip4_address_t in_addr, out_addr;
2369 out_addr.as_u32 = 0;
2370 rv = VNET_API_ERROR_UNIMPLEMENTED;
2374 out_addr.as_u32 = 0;
2375 clib_memcpy (&in_addr, mp->in_addr, 4);
2376 dm = snat_det_map_by_user (sm, &in_addr);
2379 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2383 snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
2384 hi_port = lo_port + dm->ports_per_host - 1;
2388 REPLY_MACRO2 (VL_API_NAT_DET_FORWARD_REPLY,
2390 rmp->out_port_lo = ntohs (lo_port);
2391 rmp->out_port_hi = ntohs (hi_port);
2392 clib_memcpy (rmp->out_addr, &out_addr, 4);
2398 vl_api_nat_det_forward_t_print (vl_api_nat_det_forward_t * mp, void *handle)
2402 s = format (0, "SCRIPT: nat_det_forward");
2403 s = format (s, "inside ip address %U\n", format_ip4_address, mp->in_addr);
2409 vl_api_nat_det_reverse_t_handler (vl_api_nat_det_reverse_t * mp)
2411 snat_main_t *sm = &snat_main;
2412 vl_api_nat_det_reverse_reply_t *rmp;
2414 ip4_address_t out_addr, in_addr;
2418 clib_memcpy (&out_addr, mp->out_addr, 4);
2419 dm = snat_det_map_by_out (sm, &out_addr);
2422 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2426 snat_det_reverse (dm, &out_addr, htons (mp->out_port), &in_addr);
2430 REPLY_MACRO2 (VL_API_NAT_DET_REVERSE_REPLY,
2433 memset (rmp->in_addr, 0, 16);
2434 clib_memcpy (rmp->in_addr, &in_addr, 4);
2440 vl_api_nat_det_reverse_t_print (vl_api_nat_det_reverse_t * mp, void *handle)
2444 s = format (0, "SCRIPT: nat_det_reverse");
2445 s = format (s, "outside ip address %U outside port %d",
2446 format_ip4_address, mp->out_addr, ntohs (mp->out_port));
2452 sent_nat_det_map_details (snat_det_map_t * m, unix_shared_memory_queue_t * q,
2455 vl_api_nat_det_map_details_t *rmp;
2456 snat_main_t *sm = &snat_main;
2458 rmp = vl_msg_api_alloc (sizeof (*rmp));
2459 memset (rmp, 0, sizeof (*rmp));
2460 rmp->_vl_msg_id = ntohs (VL_API_NAT_DET_MAP_DETAILS + sm->msg_id_base);
2462 clib_memcpy (rmp->in_addr, &m->in_addr, 4);
2463 rmp->in_plen = m->in_plen;
2464 clib_memcpy (rmp->out_addr, &m->out_addr, 4);
2465 rmp->out_plen = m->out_plen;
2466 rmp->sharing_ratio = htonl (m->sharing_ratio);
2467 rmp->ports_per_host = htons (m->ports_per_host);
2468 rmp->ses_num = htonl (m->ses_num);
2469 rmp->context = context;
2471 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2475 vl_api_nat_det_map_dump_t_handler (vl_api_nat_det_map_dump_t * mp)
2477 unix_shared_memory_queue_t *q;
2478 snat_main_t *sm = &snat_main;
2481 q = vl_api_client_index_to_input_queue (mp->client_index);
2486 vec_foreach(m, sm->det_maps)
2487 sent_nat_det_map_details(m, q, mp->context);
2492 vl_api_nat_det_map_dump_t_print (vl_api_nat_det_map_dump_t * mp, void *handle)
2496 s = format (0, "SCRIPT: nat_det_map_dump ");
2502 vl_api_nat_det_set_timeouts_t_handler (vl_api_nat_det_set_timeouts_t * mp)
2504 snat_main_t *sm = &snat_main;
2505 vl_api_nat_det_set_timeouts_reply_t *rmp;
2508 sm->udp_timeout = ntohl (mp->udp);
2509 sm->tcp_established_timeout = ntohl (mp->tcp_established);
2510 sm->tcp_transitory_timeout = ntohl (mp->tcp_transitory);
2511 sm->icmp_timeout = ntohl (mp->icmp);
2513 REPLY_MACRO (VL_API_NAT_DET_SET_TIMEOUTS_REPLY);
2517 vl_api_nat_det_set_timeouts_t_print (vl_api_nat_det_set_timeouts_t * mp,
2522 s = format (0, "SCRIPT: nat_det_set_timeouts ");
2523 s = format (s, "udp %d tcp_established %d tcp_transitory %d icmp %d\n",
2525 ntohl (mp->tcp_established),
2526 ntohl (mp->tcp_transitory), ntohl (mp->icmp));
2532 vl_api_nat_det_get_timeouts_t_handler (vl_api_nat_det_get_timeouts_t * mp)
2534 snat_main_t *sm = &snat_main;
2535 vl_api_nat_det_get_timeouts_reply_t *rmp;
2539 REPLY_MACRO2 (VL_API_NAT_DET_GET_TIMEOUTS_REPLY,
2541 rmp->udp = htonl (sm->udp_timeout);
2542 rmp->tcp_established = htonl (sm->tcp_established_timeout);
2543 rmp->tcp_transitory = htonl (sm->tcp_transitory_timeout);
2544 rmp->icmp = htonl (sm->icmp_timeout);
2550 vl_api_nat_det_get_timeouts_t_print (vl_api_nat_det_get_timeouts_t * mp,
2555 s = format (0, "SCRIPT: nat_det_get_timeouts");
2561 vl_api_nat_det_close_session_out_t_handler (vl_api_nat_det_close_session_out_t
2564 snat_main_t *sm = &snat_main;
2565 vl_api_nat_det_close_session_out_reply_t *rmp;
2566 ip4_address_t out_addr, ext_addr, in_addr;
2567 snat_det_out_key_t key;
2569 snat_det_session_t *ses;
2572 clib_memcpy (&out_addr, mp->out_addr, 4);
2573 clib_memcpy (&ext_addr, mp->ext_addr, 4);
2575 dm = snat_det_map_by_out (sm, &out_addr);
2578 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2581 snat_det_reverse (dm, &ext_addr, ntohs (mp->out_port), &in_addr);
2582 key.ext_host_addr = ext_addr;
2583 key.ext_host_port = mp->ext_port;
2584 key.out_port = mp->out_port;
2585 ses = snat_det_get_ses_by_out (dm, &in_addr, key.as_u64);
2588 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2591 snat_det_ses_close (dm, ses);
2594 REPLY_MACRO (VL_API_NAT_DET_CLOSE_SESSION_OUT_REPLY);
2598 vl_api_nat_det_close_session_out_t_print (vl_api_nat_det_close_session_out_t *
2603 s = format (0, "SCRIPT: nat_det_close_session_out ");
2604 s = format (s, "out_addr %U out_port %d "
2605 "ext_addr %U ext_port %d\n",
2606 format_ip4_address, mp->out_addr, ntohs (mp->out_port),
2607 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
2613 vl_api_nat_det_close_session_in_t_handler (vl_api_nat_det_close_session_in_t *
2616 snat_main_t *sm = &snat_main;
2617 vl_api_nat_det_close_session_in_reply_t *rmp;
2618 ip4_address_t in_addr, ext_addr;
2619 snat_det_out_key_t key;
2621 snat_det_session_t *ses;
2626 rv = VNET_API_ERROR_UNIMPLEMENTED;
2630 clib_memcpy (&in_addr, mp->in_addr, 4);
2631 clib_memcpy (&ext_addr, mp->ext_addr, 4);
2633 dm = snat_det_map_by_user (sm, &in_addr);
2636 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2639 key.ext_host_addr = ext_addr;
2640 key.ext_host_port = mp->ext_port;
2641 ses = snat_det_find_ses_by_in (dm, &in_addr, mp->in_port, key);
2644 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2647 snat_det_ses_close (dm, ses);
2650 REPLY_MACRO (VL_API_NAT_DET_CLOSE_SESSION_OUT_REPLY);
2654 vl_api_nat_det_close_session_in_t_print (vl_api_nat_det_close_session_in_t *
2658 s = format (0, "SCRIPT: nat_det_close_session_in ");
2659 s = format (s, "in_addr %U in_port %d ext_addr %U ext_port %d\n",
2660 format_ip4_address, mp->in_addr, ntohs (mp->in_port),
2661 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
2667 send_nat_det_session_details (snat_det_session_t * s,
2668 unix_shared_memory_queue_t * q, u32 context)
2670 vl_api_nat_det_session_details_t *rmp;
2671 snat_main_t *sm = &snat_main;
2673 rmp = vl_msg_api_alloc (sizeof (*rmp));
2674 memset (rmp, 0, sizeof (*rmp));
2675 rmp->_vl_msg_id = ntohs (VL_API_NAT_DET_SESSION_DETAILS + sm->msg_id_base);
2676 rmp->in_port = s->in_port;
2677 clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
2678 rmp->ext_port = s->out.ext_host_port;
2679 rmp->out_port = s->out.out_port;
2680 rmp->state = s->state;
2681 rmp->expire = ntohl (s->expire);
2682 rmp->context = context;
2684 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2688 vl_api_nat_det_session_dump_t_handler (vl_api_nat_det_session_dump_t * mp)
2690 unix_shared_memory_queue_t *q;
2691 snat_main_t *sm = &snat_main;
2692 ip4_address_t user_addr;
2694 snat_det_session_t *s, empty_ses;
2697 q = vl_api_client_index_to_input_queue (mp->client_index);
2703 memset (&empty_ses, 0, sizeof (empty_ses));
2704 clib_memcpy (&user_addr, mp->user_addr, 4);
2705 dm = snat_det_map_by_user (sm, &user_addr);
2709 s = dm->sessions + snat_det_user_ses_offset (&user_addr, dm->in_plen);
2710 for (i = 0; i < SNAT_DET_SES_PER_USER; i++)
2713 send_nat_det_session_details (s, q, mp->context);
2719 vl_api_nat_det_session_dump_t_print (vl_api_nat_det_session_dump_t * mp,
2724 s = format (0, "SCRIPT: nat_det_session_dump ");
2725 s = format (s, "user_addr %U\n", format_ip4_address, mp->user_addr);
2735 vl_api_nat64_add_del_pool_addr_range_t_handler
2736 (vl_api_nat64_add_del_pool_addr_range_t * mp)
2738 vl_api_nat64_add_del_pool_addr_range_reply_t *rmp;
2739 snat_main_t *sm = &snat_main;
2740 nat64_main_t *nm = &nat64_main;
2742 ip4_address_t this_addr;
2743 u32 start_host_order, end_host_order;
2748 if (nm->is_disabled)
2750 rv = VNET_API_ERROR_FEATURE_DISABLED;
2754 tmp = (u32 *) mp->start_addr;
2755 start_host_order = clib_host_to_net_u32 (tmp[0]);
2756 tmp = (u32 *) mp->end_addr;
2757 end_host_order = clib_host_to_net_u32 (tmp[0]);
2759 count = (end_host_order - start_host_order) + 1;
2761 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
2763 memcpy (&this_addr.as_u8, mp->start_addr, 4);
2765 for (i = 0; i < count; i++)
2767 if ((rv = nat64_add_del_pool_addr (&this_addr, vrf_id, mp->is_add)))
2770 increment_v4_address (&this_addr);
2774 REPLY_MACRO (VL_API_NAT64_ADD_DEL_POOL_ADDR_RANGE_REPLY);
2777 static void *vl_api_nat64_add_del_pool_addr_range_t_print
2778 (vl_api_nat64_add_del_pool_addr_range_t * mp, void *handle)
2782 s = format (0, "SCRIPT: nat64_add_del_pool_addr_range ");
2783 s = format (s, "%U - %U vrf_id %u %s\n",
2784 format_ip4_address, mp->start_addr,
2785 format_ip4_address, mp->end_addr,
2786 ntohl (mp->vrf_id), mp->is_add ? "" : "del");
2791 typedef struct nat64_api_walk_ctx_t_
2793 unix_shared_memory_queue_t *q;
2795 } nat64_api_walk_ctx_t;
2798 nat64_api_pool_walk (snat_address_t * a, void *arg)
2800 vl_api_nat64_pool_addr_details_t *rmp;
2801 snat_main_t *sm = &snat_main;
2802 nat64_api_walk_ctx_t *ctx = arg;
2804 rmp = vl_msg_api_alloc (sizeof (*rmp));
2805 memset (rmp, 0, sizeof (*rmp));
2806 rmp->_vl_msg_id = ntohs (VL_API_NAT64_POOL_ADDR_DETAILS + sm->msg_id_base);
2807 clib_memcpy (rmp->address, &(a->addr), 4);
2808 if (a->fib_index != ~0)
2810 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP6);
2813 rmp->vrf_id = ntohl (fib->ft_table_id);
2817 rmp->context = ctx->context;
2819 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
2825 vl_api_nat64_pool_addr_dump_t_handler (vl_api_nat64_pool_addr_dump_t * mp)
2827 unix_shared_memory_queue_t *q;
2828 nat64_main_t *nm = &nat64_main;
2830 if (nm->is_disabled)
2833 q = vl_api_client_index_to_input_queue (mp->client_index);
2837 nat64_api_walk_ctx_t ctx = {
2839 .context = mp->context,
2842 nat64_pool_addr_walk (nat64_api_pool_walk, &ctx);
2846 vl_api_nat64_pool_addr_dump_t_print (vl_api_nat64_pool_addr_dump_t * mp,
2851 s = format (0, "SCRIPT: nat64_pool_addr_dump\n");
2857 vl_api_nat64_add_del_interface_t_handler (vl_api_nat64_add_del_interface_t *
2860 snat_main_t *sm = &snat_main;
2861 nat64_main_t *nm = &nat64_main;
2862 vl_api_nat64_add_del_interface_reply_t *rmp;
2865 if (nm->is_disabled)
2867 rv = VNET_API_ERROR_FEATURE_DISABLED;
2871 VALIDATE_SW_IF_INDEX (mp);
2874 nat64_add_del_interface (ntohl (mp->sw_if_index), mp->is_inside,
2877 BAD_SW_IF_INDEX_LABEL;
2880 REPLY_MACRO (VL_API_NAT64_ADD_DEL_INTERFACE_REPLY);
2884 vl_api_nat64_add_del_interface_t_print (vl_api_nat64_add_del_interface_t * mp,
2889 s = format (0, "SCRIPT: nat64_add_del_interface ");
2890 s = format (s, "sw_if_index %d %s %s",
2891 clib_host_to_net_u32 (mp->sw_if_index),
2892 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
2898 nat64_api_interface_walk (snat_interface_t * i, void *arg)
2900 vl_api_nat64_interface_details_t *rmp;
2901 snat_main_t *sm = &snat_main;
2902 nat64_api_walk_ctx_t *ctx = arg;
2904 rmp = vl_msg_api_alloc (sizeof (*rmp));
2905 memset (rmp, 0, sizeof (*rmp));
2906 rmp->_vl_msg_id = ntohs (VL_API_NAT64_INTERFACE_DETAILS + sm->msg_id_base);
2907 rmp->sw_if_index = ntohl (i->sw_if_index);
2908 rmp->is_inside = (nat_interface_is_inside (i)
2909 && nat_interface_is_outside (i)) ? 2 :
2910 nat_interface_is_inside (i);
2911 rmp->context = ctx->context;
2913 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
2919 vl_api_nat64_interface_dump_t_handler (vl_api_nat64_interface_dump_t * mp)
2921 unix_shared_memory_queue_t *q;
2922 nat64_main_t *nm = &nat64_main;
2924 if (nm->is_disabled)
2927 q = vl_api_client_index_to_input_queue (mp->client_index);
2931 nat64_api_walk_ctx_t ctx = {
2933 .context = mp->context,
2936 nat64_interfaces_walk (nat64_api_interface_walk, &ctx);
2940 vl_api_nat64_interface_dump_t_print (vl_api_nat64_interface_dump_t * mp,
2945 s = format (0, "SCRIPT: snat_interface_dump ");
2951 vl_api_nat64_add_del_static_bib_t_handler
2952 (vl_api_nat64_add_del_static_bib_t * mp)
2954 snat_main_t *sm = &snat_main;
2955 nat64_main_t *nm = &nat64_main;
2956 vl_api_nat64_add_del_static_bib_reply_t *rmp;
2957 ip6_address_t in_addr;
2958 ip4_address_t out_addr;
2961 if (nm->is_disabled)
2963 rv = VNET_API_ERROR_FEATURE_DISABLED;
2967 memcpy (&in_addr.as_u8, mp->i_addr, 16);
2968 memcpy (&out_addr.as_u8, mp->o_addr, 4);
2971 nat64_add_del_static_bib_entry (&in_addr, &out_addr,
2972 clib_net_to_host_u16 (mp->i_port),
2973 clib_net_to_host_u16 (mp->o_port),
2975 clib_net_to_host_u32 (mp->vrf_id),
2979 REPLY_MACRO (VL_API_NAT64_ADD_DEL_STATIC_BIB_REPLY);
2982 static void *vl_api_nat64_add_del_static_bib_t_print
2983 (vl_api_nat64_add_del_static_bib_t * mp, void *handle)
2987 s = format (0, "SCRIPT: nat64_add_del_static_bib ");
2988 s = format (s, "protocol %d i_addr %U o_addr %U ",
2990 format_ip6_address, mp->i_addr, format_ip4_address, mp->o_addr);
2992 if (mp->vrf_id != ~0)
2993 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
2999 nat64_api_bib_walk (nat64_db_bib_entry_t * bibe, void *arg)
3001 vl_api_nat64_bib_details_t *rmp;
3002 snat_main_t *sm = &snat_main;
3003 nat64_api_walk_ctx_t *ctx = arg;
3006 fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
3010 rmp = vl_msg_api_alloc (sizeof (*rmp));
3011 memset (rmp, 0, sizeof (*rmp));
3012 rmp->_vl_msg_id = ntohs (VL_API_NAT64_BIB_DETAILS + sm->msg_id_base);
3013 rmp->context = ctx->context;
3014 clib_memcpy (rmp->i_addr, &(bibe->in_addr), 16);
3015 clib_memcpy (rmp->o_addr, &(bibe->out_addr), 4);
3016 rmp->i_port = bibe->in_port;
3017 rmp->o_port = bibe->out_port;
3018 rmp->vrf_id = ntohl (fib->ft_table_id);
3019 rmp->proto = bibe->proto;
3020 rmp->is_static = bibe->is_static;
3021 rmp->ses_num = ntohl (bibe->ses_num);
3023 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3029 vl_api_nat64_bib_dump_t_handler (vl_api_nat64_bib_dump_t * mp)
3031 unix_shared_memory_queue_t *q;
3032 nat64_main_t *nm = &nat64_main;
3034 if (nm->is_disabled)
3037 q = vl_api_client_index_to_input_queue (mp->client_index);
3041 nat64_api_walk_ctx_t ctx = {
3043 .context = mp->context,
3046 nat64_db_bib_walk (&nm->db, mp->proto, nat64_api_bib_walk, &ctx);
3050 vl_api_nat64_bib_dump_t_print (vl_api_nat64_bib_dump_t * mp, void *handle)
3054 s = format (0, "SCRIPT: snat_bib_dump protocol %d", mp->proto);
3060 vl_api_nat64_set_timeouts_t_handler (vl_api_nat64_set_timeouts_t * mp)
3062 snat_main_t *sm = &snat_main;
3063 nat64_main_t *nm = &nat64_main;
3064 vl_api_nat64_set_timeouts_reply_t *rmp;
3067 if (nm->is_disabled)
3069 rv = VNET_API_ERROR_FEATURE_DISABLED;
3073 rv = nat64_set_icmp_timeout (ntohl (mp->icmp));
3076 rv = nat64_set_udp_timeout (ntohl (mp->udp));
3080 nat64_set_tcp_timeouts (ntohl (mp->tcp_trans), ntohl (mp->tcp_est),
3081 ntohl (mp->tcp_incoming_syn));
3084 REPLY_MACRO (VL_API_NAT64_SET_TIMEOUTS_REPLY);
3087 static void *vl_api_nat64_set_timeouts_t_print
3088 (vl_api_nat64_set_timeouts_t * mp, void *handle)
3092 s = format (0, "SCRIPT: nat64_set_timeouts ");
3095 "udp %d icmp %d, tcp_trans %d, tcp_est %d, tcp_incoming_syn %d\n",
3096 ntohl (mp->udp), ntohl (mp->icmp), ntohl (mp->tcp_trans),
3097 ntohl (mp->tcp_est), ntohl (mp->tcp_incoming_syn));
3103 vl_api_nat64_get_timeouts_t_handler (vl_api_nat64_get_timeouts_t * mp)
3105 snat_main_t *sm = &snat_main;
3106 nat64_main_t *nm = &nat64_main;
3107 vl_api_nat64_get_timeouts_reply_t *rmp;
3110 if (nm->is_disabled)
3114 REPLY_MACRO2 (VL_API_NAT64_GET_TIMEOUTS_REPLY,
3116 rmp->udp = htonl (nat64_get_udp_timeout());
3117 rmp->icmp = htonl (nat64_get_icmp_timeout());
3118 rmp->tcp_trans = htonl (nat64_get_tcp_trans_timeout());
3119 rmp->tcp_est = htonl (nat64_get_tcp_est_timeout());
3120 rmp->tcp_incoming_syn = htonl (nat64_get_tcp_incoming_syn_timeout());
3125 static void *vl_api_nat64_get_timeouts_t_print
3126 (vl_api_nat64_get_timeouts_t * mp, void *handle)
3130 s = format (0, "SCRIPT: nat64_get_timeouts");
3136 nat64_api_st_walk (nat64_db_st_entry_t * ste, void *arg)
3138 vl_api_nat64_st_details_t *rmp;
3139 snat_main_t *sm = &snat_main;
3140 nat64_api_walk_ctx_t *ctx = arg;
3141 nat64_main_t *nm = &nat64_main;
3142 nat64_db_bib_entry_t *bibe;
3145 bibe = nat64_db_bib_entry_by_index (&nm->db, ste->proto, ste->bibe_index);
3149 fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
3153 rmp = vl_msg_api_alloc (sizeof (*rmp));
3154 memset (rmp, 0, sizeof (*rmp));
3155 rmp->_vl_msg_id = ntohs (VL_API_NAT64_ST_DETAILS + sm->msg_id_base);
3156 rmp->context = ctx->context;
3157 clib_memcpy (rmp->il_addr, &(bibe->in_addr), 16);
3158 clib_memcpy (rmp->ol_addr, &(bibe->out_addr), 4);
3159 rmp->il_port = bibe->in_port;
3160 rmp->ol_port = bibe->out_port;
3161 clib_memcpy (rmp->ir_addr, &(ste->in_r_addr), 16);
3162 clib_memcpy (rmp->or_addr, &(ste->out_r_addr), 4);
3163 rmp->il_port = ste->r_port;
3164 rmp->vrf_id = ntohl (fib->ft_table_id);
3165 rmp->proto = ste->proto;
3167 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3173 vl_api_nat64_st_dump_t_handler (vl_api_nat64_st_dump_t * mp)
3175 unix_shared_memory_queue_t *q;
3176 nat64_main_t *nm = &nat64_main;
3178 if (nm->is_disabled)
3181 q = vl_api_client_index_to_input_queue (mp->client_index);
3185 nat64_api_walk_ctx_t ctx = {
3187 .context = mp->context,
3190 nat64_db_st_walk (&nm->db, mp->proto, nat64_api_st_walk, &ctx);
3194 vl_api_nat64_st_dump_t_print (vl_api_nat64_st_dump_t * mp, void *handle)
3198 s = format (0, "SCRIPT: snat_st_dump protocol %d", mp->proto);
3204 vl_api_nat64_add_del_prefix_t_handler (vl_api_nat64_add_del_prefix_t * mp)
3206 vl_api_nat64_add_del_prefix_reply_t *rmp;
3207 snat_main_t *sm = &snat_main;
3208 nat64_main_t *nm = &nat64_main;
3209 ip6_address_t prefix;
3212 if (nm->is_disabled)
3214 rv = VNET_API_ERROR_FEATURE_DISABLED;
3218 memcpy (&prefix.as_u8, mp->prefix, 16);
3221 nat64_add_del_prefix (&prefix, mp->prefix_len,
3222 clib_net_to_host_u32 (mp->vrf_id), mp->is_add);
3224 REPLY_MACRO (VL_API_NAT64_ADD_DEL_PREFIX_REPLY);
3228 vl_api_nat64_add_del_prefix_t_print (vl_api_nat64_add_del_prefix_t * mp,
3233 s = format (0, "SCRIPT: nat64_add_del_prefix %U/%u vrf_id %u %s\n",
3234 format_ip6_address, mp->prefix, mp->prefix_len,
3235 ntohl (mp->vrf_id), mp->is_add ? "" : "del");
3241 nat64_api_prefix_walk (nat64_prefix_t * p, void *arg)
3243 vl_api_nat64_prefix_details_t *rmp;
3244 snat_main_t *sm = &snat_main;
3245 nat64_api_walk_ctx_t *ctx = arg;
3247 rmp = vl_msg_api_alloc (sizeof (*rmp));
3248 memset (rmp, 0, sizeof (*rmp));
3249 rmp->_vl_msg_id = ntohs (VL_API_NAT64_PREFIX_DETAILS + sm->msg_id_base);
3250 clib_memcpy (rmp->prefix, &(p->prefix), 16);
3251 rmp->prefix_len = p->plen;
3252 rmp->vrf_id = ntohl (p->vrf_id);
3253 rmp->context = ctx->context;
3255 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3261 vl_api_nat64_prefix_dump_t_handler (vl_api_nat64_prefix_dump_t * mp)
3263 unix_shared_memory_queue_t *q;
3264 nat64_main_t *nm = &nat64_main;
3266 if (nm->is_disabled)
3269 q = vl_api_client_index_to_input_queue (mp->client_index);
3273 nat64_api_walk_ctx_t ctx = {
3275 .context = mp->context,
3278 nat64_prefix_walk (nat64_api_prefix_walk, &ctx);
3282 vl_api_nat64_prefix_dump_t_print (vl_api_nat64_prefix_dump_t * mp,
3287 s = format (0, "SCRIPT: nat64_prefix_dump\n");
3292 /* List of message types that this plugin understands */
3293 #define foreach_snat_plugin_api_msg \
3294 _(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range) \
3295 _(SNAT_INTERFACE_ADD_DEL_FEATURE, snat_interface_add_del_feature) \
3296 _(SNAT_ADD_STATIC_MAPPING, snat_add_static_mapping) \
3297 _(SNAT_CONTROL_PING, snat_control_ping) \
3298 _(SNAT_STATIC_MAPPING_DUMP, snat_static_mapping_dump) \
3299 _(SNAT_SHOW_CONFIG, snat_show_config) \
3300 _(SNAT_ADDRESS_DUMP, snat_address_dump) \
3301 _(SNAT_INTERFACE_DUMP, snat_interface_dump) \
3302 _(SNAT_SET_WORKERS, snat_set_workers) \
3303 _(SNAT_WORKER_DUMP, snat_worker_dump) \
3304 _(SNAT_ADD_DEL_INTERFACE_ADDR, snat_add_del_interface_addr) \
3305 _(SNAT_INTERFACE_ADDR_DUMP, snat_interface_addr_dump) \
3306 _(SNAT_IPFIX_ENABLE_DISABLE, snat_ipfix_enable_disable) \
3307 _(SNAT_USER_DUMP, snat_user_dump) \
3308 _(SNAT_USER_SESSION_DUMP, snat_user_session_dump) \
3309 _(SNAT_INTERFACE_ADD_DEL_OUTPUT_FEATURE, \
3310 snat_interface_add_del_output_feature) \
3311 _(SNAT_INTERFACE_OUTPUT_FEATURE_DUMP, \
3312 snat_interface_output_feature_dump) \
3313 _(SNAT_ADD_DET_MAP, snat_add_det_map) \
3314 _(SNAT_DET_FORWARD, snat_det_forward) \
3315 _(SNAT_DET_REVERSE, snat_det_reverse) \
3316 _(SNAT_DET_MAP_DUMP, snat_det_map_dump) \
3317 _(SNAT_DET_SET_TIMEOUTS, snat_det_set_timeouts) \
3318 _(SNAT_DET_GET_TIMEOUTS, snat_det_get_timeouts) \
3319 _(SNAT_DET_CLOSE_SESSION_OUT, snat_det_close_session_out) \
3320 _(SNAT_DET_CLOSE_SESSION_IN, snat_det_close_session_in) \
3321 _(SNAT_DET_SESSION_DUMP, snat_det_session_dump) \
3322 _(NAT_CONTROL_PING, nat_control_ping) \
3323 _(NAT_SHOW_CONFIG, nat_show_config) \
3324 _(NAT_SET_WORKERS, nat_set_workers) \
3325 _(NAT_WORKER_DUMP, nat_worker_dump) \
3326 _(NAT_IPFIX_ENABLE_DISABLE, nat_ipfix_enable_disable) \
3327 _(NAT44_ADD_DEL_ADDRESS_RANGE, nat44_add_del_address_range) \
3328 _(NAT44_INTERFACE_ADD_DEL_FEATURE, nat44_interface_add_del_feature) \
3329 _(NAT44_ADD_DEL_STATIC_MAPPING, nat44_add_del_static_mapping) \
3330 _(NAT44_STATIC_MAPPING_DUMP, nat44_static_mapping_dump) \
3331 _(NAT44_ADDRESS_DUMP, nat44_address_dump) \
3332 _(NAT44_INTERFACE_DUMP, nat44_interface_dump) \
3333 _(NAT44_ADD_DEL_INTERFACE_ADDR, nat44_add_del_interface_addr) \
3334 _(NAT44_INTERFACE_ADDR_DUMP, nat44_interface_addr_dump) \
3335 _(NAT44_USER_DUMP, nat44_user_dump) \
3336 _(NAT44_USER_SESSION_DUMP, nat44_user_session_dump) \
3337 _(NAT44_INTERFACE_ADD_DEL_OUTPUT_FEATURE, \
3338 nat44_interface_add_del_output_feature) \
3339 _(NAT44_INTERFACE_OUTPUT_FEATURE_DUMP, \
3340 nat44_interface_output_feature_dump) \
3341 _(NAT44_ADD_DEL_LB_STATIC_MAPPING, nat44_add_del_lb_static_mapping) \
3342 _(NAT44_LB_STATIC_MAPPING_DUMP, nat44_lb_static_mapping_dump) \
3343 _(NAT44_DEL_SESSION, nat44_del_session) \
3344 _(NAT_DET_ADD_DEL_MAP, nat_det_add_del_map) \
3345 _(NAT_DET_FORWARD, nat_det_forward) \
3346 _(NAT_DET_REVERSE, nat_det_reverse) \
3347 _(NAT_DET_MAP_DUMP, nat_det_map_dump) \
3348 _(NAT_DET_SET_TIMEOUTS, nat_det_set_timeouts) \
3349 _(NAT_DET_GET_TIMEOUTS, nat_det_get_timeouts) \
3350 _(NAT_DET_CLOSE_SESSION_OUT, nat_det_close_session_out) \
3351 _(NAT_DET_CLOSE_SESSION_IN, nat_det_close_session_in) \
3352 _(NAT_DET_SESSION_DUMP, nat_det_session_dump) \
3353 _(NAT64_ADD_DEL_POOL_ADDR_RANGE, nat64_add_del_pool_addr_range) \
3354 _(NAT64_POOL_ADDR_DUMP, nat64_pool_addr_dump) \
3355 _(NAT64_ADD_DEL_INTERFACE, nat64_add_del_interface) \
3356 _(NAT64_INTERFACE_DUMP, nat64_interface_dump) \
3357 _(NAT64_ADD_DEL_STATIC_BIB, nat64_add_del_static_bib) \
3358 _(NAT64_BIB_DUMP, nat64_bib_dump) \
3359 _(NAT64_SET_TIMEOUTS, nat64_set_timeouts) \
3360 _(NAT64_GET_TIMEOUTS, nat64_get_timeouts) \
3361 _(NAT64_ST_DUMP, nat64_st_dump) \
3362 _(NAT64_ADD_DEL_PREFIX, nat64_add_del_prefix) \
3363 _(NAT64_PREFIX_DUMP, nat64_prefix_dump)
3365 /* Set up the API message handling tables */
3366 static clib_error_t *
3367 snat_plugin_api_hookup (vlib_main_t * vm)
3369 snat_main_t *sm __attribute__ ((unused)) = &snat_main;
3371 vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
3373 vl_api_##n##_t_handler, \
3375 vl_api_##n##_t_endian, \
3376 vl_api_##n##_t_print, \
3377 sizeof(vl_api_##n##_t), 1);
3378 foreach_snat_plugin_api_msg;
3384 #define vl_msg_name_crc_list
3385 #include <nat/nat_all_api_h.h>
3386 #undef vl_msg_name_crc_list
3389 setup_message_id_table (snat_main_t * sm, api_main_t * am)
3391 #define _(id,n,crc) \
3392 vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base);
3393 foreach_vl_msg_name_crc_nat;
3398 plugin_custom_dump_configure (snat_main_t * sm)
3400 #define _(n,f) sm->api_main->msg_print_handlers \
3401 [VL_API_##n + sm->msg_id_base] \
3402 = (void *) vl_api_##f##_t_print;
3403 foreach_snat_plugin_api_msg;
3408 snat_api_init (vlib_main_t * vm, snat_main_t * sm)
3411 clib_error_t *error = 0;
3413 name = format (0, "snat_%08x%c", api_version, 0);
3415 /* Ask for a correctly-sized block of API message decode slots */
3417 vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE);
3419 error = snat_plugin_api_hookup (vm);
3421 /* Add our API messages to the global name_crc hash table */
3422 setup_message_id_table (sm, sm->api_main);
3424 plugin_custom_dump_configure (sm);
3432 * fd.io coding-style-patch-verification: ON
3435 * eval: (c-set-style "gnu")