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 <nat/dslite.h>
25 #include <nat/nat_reass.h>
26 #include <vlibapi/api.h>
27 #include <vlibmemory/api.h>
29 #include <nat/nat_msg_enum.h>
30 #include <vnet/fib/fib_table.h>
32 #define vl_api_nat44_lb_addr_port_t_endian vl_noop_handler
33 #define vl_api_nat44_add_del_lb_static_mapping_t_endian vl_noop_handler
34 #define vl_api_nat44_nat44_lb_static_mapping_details_t_endian vl_noop_handler
36 /* define message structures */
38 #include <nat/nat_all_api_h.h>
41 /* define generated endian-swappers */
43 #include <nat/nat_all_api_h.h>
46 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
48 #define REPLY_MSG_ID_BASE sm->msg_id_base
49 #include <vlibapi/api_helper_macros.h>
51 /* Get the API version number */
52 #define vl_api_version(n,v) static u32 api_version=(v);
53 #include <nat/nat_all_api_h.h>
56 /* Macro to finish up custom dump fns */
59 vl_print (handle, (char *)s); \
64 vl_api_snat_add_address_range_t_handler
65 (vl_api_snat_add_address_range_t * mp)
67 snat_main_t *sm = &snat_main;
68 vl_api_snat_add_address_range_reply_t *rmp;
69 ip4_address_t this_addr;
70 u32 start_host_order, end_host_order;
78 rv = VNET_API_ERROR_UNIMPLEMENTED;
82 if (sm->static_mapping_only)
84 rv = VNET_API_ERROR_FEATURE_DISABLED;
88 tmp = (u32 *) mp->first_ip_address;
89 start_host_order = clib_host_to_net_u32 (tmp[0]);
90 tmp = (u32 *) mp->last_ip_address;
91 end_host_order = clib_host_to_net_u32 (tmp[0]);
93 count = (end_host_order - start_host_order) + 1;
95 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
98 clib_warning ("%U - %U, %d addresses...",
99 format_ip4_address, mp->first_ip_address,
100 format_ip4_address, mp->last_ip_address, count);
102 memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
104 for (i = 0; i < count; i++)
107 snat_add_address (sm, &this_addr, vrf_id);
109 rv = snat_del_address (sm, this_addr, 0);
114 increment_v4_address (&this_addr);
118 REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
121 static void *vl_api_snat_add_address_range_t_print
122 (vl_api_snat_add_address_range_t * mp, void *handle)
126 s = format (0, "SCRIPT: snat_add_address_range ");
127 s = format (s, "%U ", format_ip4_address, mp->first_ip_address);
128 if (memcmp (mp->first_ip_address, mp->last_ip_address, 4))
130 s = format (s, " - %U ", format_ip4_address, mp->last_ip_address);
136 send_snat_address_details
137 (snat_address_t * a, unix_shared_memory_queue_t * q, u32 context)
139 vl_api_snat_address_details_t *rmp;
140 snat_main_t *sm = &snat_main;
142 rmp = vl_msg_api_alloc (sizeof (*rmp));
143 memset (rmp, 0, sizeof (*rmp));
144 rmp->_vl_msg_id = ntohs (VL_API_SNAT_ADDRESS_DETAILS + sm->msg_id_base);
146 clib_memcpy (rmp->ip_address, &(a->addr), 4);
147 if (a->fib_index != ~0)
149 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
150 rmp->vrf_id = ntohl (fib->ft_table_id);
154 rmp->context = context;
156 vl_msg_api_send_shmem (q, (u8 *) & rmp);
160 vl_api_snat_address_dump_t_handler (vl_api_snat_address_dump_t * mp)
162 unix_shared_memory_queue_t *q;
163 snat_main_t *sm = &snat_main;
166 q = vl_api_client_index_to_input_queue (mp->client_index);
171 vec_foreach (a, sm->addresses)
172 send_snat_address_details (a, q, mp->context);
176 static void *vl_api_snat_address_dump_t_print
177 (vl_api_snat_address_dump_t * mp, void *handle)
181 s = format (0, "SCRIPT: snat_address_dump ");
187 vl_api_snat_interface_add_del_feature_t_handler
188 (vl_api_snat_interface_add_del_feature_t * mp)
190 snat_main_t *sm = &snat_main;
191 vl_api_snat_interface_add_del_feature_reply_t *rmp;
192 u8 is_del = mp->is_add == 0;
193 u32 sw_if_index = ntohl (mp->sw_if_index);
196 VALIDATE_SW_IF_INDEX (mp);
198 rv = snat_interface_add_del (sw_if_index, mp->is_inside, is_del);
200 BAD_SW_IF_INDEX_LABEL;
202 REPLY_MACRO (VL_API_SNAT_INTERFACE_ADD_DEL_FEATURE_REPLY);
205 static void *vl_api_snat_interface_add_del_feature_t_print
206 (vl_api_snat_interface_add_del_feature_t * mp, void *handle)
210 s = format (0, "SCRIPT: snat_interface_add_del_feature ");
211 s = format (s, "sw_if_index %d %s %s",
212 clib_host_to_net_u32 (mp->sw_if_index),
213 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
219 send_snat_interface_details
220 (snat_interface_t * i, unix_shared_memory_queue_t * q, u32 context)
222 vl_api_snat_interface_details_t *rmp;
223 snat_main_t *sm = &snat_main;
225 rmp = vl_msg_api_alloc (sizeof (*rmp));
226 memset (rmp, 0, sizeof (*rmp));
227 rmp->_vl_msg_id = ntohs (VL_API_SNAT_INTERFACE_DETAILS + sm->msg_id_base);
228 rmp->sw_if_index = ntohl (i->sw_if_index);
229 rmp->is_inside = nat_interface_is_inside (i);
230 rmp->context = context;
232 vl_msg_api_send_shmem (q, (u8 *) & rmp);
236 vl_api_snat_interface_dump_t_handler (vl_api_snat_interface_dump_t * mp)
238 unix_shared_memory_queue_t *q;
239 snat_main_t *sm = &snat_main;
242 q = vl_api_client_index_to_input_queue (mp->client_index);
247 pool_foreach (i, sm->interfaces,
249 send_snat_interface_details(i, q, mp->context);
254 static void *vl_api_snat_interface_dump_t_print
255 (vl_api_snat_interface_dump_t * mp, void *handle)
259 s = format (0, "SCRIPT: snat_interface_dump ");
265 vl_api_snat_interface_add_del_output_feature_t_handler
266 (vl_api_snat_interface_add_del_output_feature_t * mp)
268 snat_main_t *sm = &snat_main;
269 vl_api_snat_interface_add_del_output_feature_reply_t *rmp;
270 u8 is_del = mp->is_add == 0;
271 u32 sw_if_index = ntohl (mp->sw_if_index);
274 VALIDATE_SW_IF_INDEX (mp);
276 rv = snat_interface_add_del_output_feature (sw_if_index, mp->is_inside,
279 BAD_SW_IF_INDEX_LABEL;
281 REPLY_MACRO (VL_API_SNAT_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY);
284 static void *vl_api_snat_interface_add_del_output_feature_t_print
285 (vl_api_snat_interface_add_del_output_feature_t * mp, void *handle)
289 s = format (0, "SCRIPT: snat_interface_add_del_output_feature ");
290 s = format (s, "sw_if_index %d %s %s",
291 clib_host_to_net_u32 (mp->sw_if_index),
292 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
298 send_snat_interface_output_feature_details (snat_interface_t * i,
299 unix_shared_memory_queue_t * q,
302 vl_api_snat_interface_output_feature_details_t *rmp;
303 snat_main_t *sm = &snat_main;
305 rmp = vl_msg_api_alloc (sizeof (*rmp));
306 memset (rmp, 0, sizeof (*rmp));
308 ntohs (VL_API_SNAT_INTERFACE_OUTPUT_FEATURE_DETAILS + sm->msg_id_base);
309 rmp->sw_if_index = ntohl (i->sw_if_index);
310 rmp->context = context;
311 rmp->is_inside = nat_interface_is_inside (i);
313 vl_msg_api_send_shmem (q, (u8 *) & rmp);
317 vl_api_snat_interface_output_feature_dump_t_handler
318 (vl_api_snat_interface_output_feature_dump_t * mp)
320 unix_shared_memory_queue_t *q;
321 snat_main_t *sm = &snat_main;
324 q = vl_api_client_index_to_input_queue (mp->client_index);
329 pool_foreach (i, sm->output_feature_interfaces,
331 send_snat_interface_output_feature_details(i, q, mp->context);
336 static void *vl_api_snat_interface_output_feature_dump_t_print
337 (vl_api_snat_interface_output_feature_dump_t * mp, void *handle)
341 s = format (0, "SCRIPT: snat_interface_output_feature_dump ");
347 vl_api_snat_add_static_mapping_t_handler
348 (vl_api_snat_add_static_mapping_t * mp)
350 snat_main_t *sm = &snat_main;
351 vl_api_snat_add_static_mapping_reply_t *rmp;
352 ip4_address_t local_addr, external_addr;
353 u16 local_port = 0, external_port = 0;
354 u32 vrf_id, external_sw_if_index;
356 snat_protocol_t proto;
360 rv = VNET_API_ERROR_UNIMPLEMENTED;
364 memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
365 memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
366 if (mp->addr_only == 0)
368 local_port = clib_net_to_host_u16 (mp->local_port);
369 external_port = clib_net_to_host_u16 (mp->external_port);
371 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
372 external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
373 proto = ip_proto_to_snat_proto (mp->protocol);
375 rv = snat_add_static_mapping (local_addr, external_addr, local_port,
376 external_port, vrf_id, mp->addr_only,
377 external_sw_if_index, proto, mp->is_add);
380 REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
383 static void *vl_api_snat_add_static_mapping_t_print
384 (vl_api_snat_add_static_mapping_t * mp, void *handle)
388 s = format (0, "SCRIPT: snat_add_static_mapping ");
389 s = format (s, "protocol %d local_addr %U external_addr %U ",
391 format_ip4_address, mp->local_ip_address,
392 format_ip4_address, mp->external_ip_address);
394 if (mp->addr_only == 0)
395 s = format (s, "local_port %d external_port %d ",
396 clib_net_to_host_u16 (mp->local_port),
397 clib_net_to_host_u16 (mp->external_port));
399 if (mp->vrf_id != ~0)
400 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
402 if (mp->external_sw_if_index != ~0)
403 s = format (s, "external_sw_if_index %d",
404 clib_net_to_host_u32 (mp->external_sw_if_index));
409 send_snat_static_mapping_details
410 (snat_static_mapping_t * m, unix_shared_memory_queue_t * q, u32 context)
412 vl_api_snat_static_mapping_details_t *rmp;
413 snat_main_t *sm = &snat_main;
415 rmp = vl_msg_api_alloc (sizeof (*rmp));
416 memset (rmp, 0, sizeof (*rmp));
418 ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS + sm->msg_id_base);
420 rmp->addr_only = m->addr_only;
421 clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
422 clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
423 rmp->local_port = htons (m->local_port);
424 rmp->external_port = htons (m->external_port);
425 rmp->external_sw_if_index = ~0;
426 rmp->vrf_id = htonl (m->vrf_id);
427 rmp->protocol = snat_proto_to_ip_proto (m->proto);
428 rmp->context = context;
430 vl_msg_api_send_shmem (q, (u8 *) & rmp);
434 send_snat_static_map_resolve_details
435 (snat_static_map_resolve_t * m, unix_shared_memory_queue_t * q, u32 context)
437 vl_api_snat_static_mapping_details_t *rmp;
438 snat_main_t *sm = &snat_main;
440 rmp = vl_msg_api_alloc (sizeof (*rmp));
441 memset (rmp, 0, sizeof (*rmp));
443 ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS + sm->msg_id_base);
445 rmp->addr_only = m->addr_only;
446 clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
447 rmp->local_port = htons (m->l_port);
448 rmp->external_port = htons (m->e_port);
449 rmp->external_sw_if_index = htonl (m->sw_if_index);
450 rmp->vrf_id = htonl (m->vrf_id);
451 rmp->protocol = snat_proto_to_ip_proto (m->proto);
452 rmp->context = context;
454 vl_msg_api_send_shmem (q, (u8 *) & rmp);
458 vl_api_snat_static_mapping_dump_t_handler
459 (vl_api_snat_static_mapping_dump_t * mp)
461 unix_shared_memory_queue_t *q;
462 snat_main_t *sm = &snat_main;
463 snat_static_mapping_t *m;
464 snat_static_map_resolve_t *rp;
467 q = vl_api_client_index_to_input_queue (mp->client_index);
472 pool_foreach (m, sm->static_mappings,
474 if (!vec_len(m->locals))
475 send_snat_static_mapping_details (m, q, mp->context);
479 for (j = 0; j < vec_len (sm->to_resolve); j++)
481 rp = sm->to_resolve + j;
482 send_snat_static_map_resolve_details (rp, q, mp->context);
486 static void *vl_api_snat_static_mapping_dump_t_print
487 (vl_api_snat_static_mapping_dump_t * mp, void *handle)
491 s = format (0, "SCRIPT: snat_static_mapping_dump ");
497 vl_api_snat_control_ping_t_handler (vl_api_snat_control_ping_t * mp)
499 vl_api_snat_control_ping_reply_t *rmp;
500 snat_main_t *sm = &snat_main;
504 REPLY_MACRO2 (VL_API_SNAT_CONTROL_PING_REPLY,
506 rmp->vpe_pid = ntohl (getpid ());
511 static void *vl_api_snat_control_ping_t_print
512 (vl_api_snat_control_ping_t * mp, void *handle)
516 s = format (0, "SCRIPT: snat_control_ping ");
522 vl_api_snat_show_config_t_handler (vl_api_snat_show_config_t * mp)
524 vl_api_snat_show_config_reply_t *rmp;
525 snat_main_t *sm = &snat_main;
529 REPLY_MACRO2 (VL_API_SNAT_SHOW_CONFIG_REPLY,
531 rmp->translation_buckets = htonl (sm->translation_buckets);
532 rmp->translation_memory_size = htonl (sm->translation_memory_size);
533 rmp->user_buckets = htonl (sm->user_buckets);
534 rmp->user_memory_size = htonl (sm->user_memory_size);
535 rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
536 rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
537 rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
538 rmp->static_mapping_only = sm->static_mapping_only;
539 rmp->static_mapping_connection_tracking =
540 sm->static_mapping_connection_tracking;
541 rmp->deterministic = sm->deterministic;
546 static void *vl_api_snat_show_config_t_print
547 (vl_api_snat_show_config_t * mp, void *handle)
551 s = format (0, "SCRIPT: snat_show_config ");
557 vl_api_snat_set_workers_t_handler (vl_api_snat_set_workers_t * mp)
559 snat_main_t *sm = &snat_main;
560 vl_api_snat_set_workers_reply_t *rmp;
563 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
565 if (sm->num_workers < 2)
567 rv = VNET_API_ERROR_FEATURE_DISABLED;
571 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
572 rv = snat_set_workers (bitmap);
573 clib_bitmap_free (bitmap);
576 REPLY_MACRO (VL_API_SNAT_SET_WORKERS_REPLY);
579 static void *vl_api_snat_set_workers_t_print
580 (vl_api_snat_set_workers_t * mp, void *handle)
586 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
588 s = format (0, "SCRIPT: snat_set_workers ");
589 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
591 clib_bitmap_foreach (i, bitmap,
594 s = format (s, "%d", i);
596 s = format (s, ",%d", i);
600 clib_bitmap_free (bitmap);
605 send_snat_worker_details
606 (u32 worker_index, unix_shared_memory_queue_t * q, u32 context)
608 vl_api_snat_worker_details_t *rmp;
609 snat_main_t *sm = &snat_main;
610 vlib_worker_thread_t *w =
611 vlib_worker_threads + worker_index + sm->first_worker_index;
613 rmp = vl_msg_api_alloc (sizeof (*rmp));
614 memset (rmp, 0, sizeof (*rmp));
615 rmp->_vl_msg_id = ntohs (VL_API_SNAT_WORKER_DETAILS + sm->msg_id_base);
616 rmp->context = context;
617 rmp->worker_index = htonl (worker_index);
618 rmp->lcore_id = htonl (w->lcore_id);
619 strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
621 vl_msg_api_send_shmem (q, (u8 *) & rmp);
625 vl_api_snat_worker_dump_t_handler (vl_api_snat_worker_dump_t * mp)
627 unix_shared_memory_queue_t *q;
628 snat_main_t *sm = &snat_main;
631 q = vl_api_client_index_to_input_queue (mp->client_index);
636 vec_foreach (worker_index, sm->workers)
637 send_snat_worker_details(*worker_index, q, mp->context);
641 static void *vl_api_snat_worker_dump_t_print
642 (vl_api_snat_worker_dump_t * mp, void *handle)
646 s = format (0, "SCRIPT: snat_worker_dump ");
652 vl_api_snat_add_del_interface_addr_t_handler
653 (vl_api_snat_add_del_interface_addr_t * mp)
655 snat_main_t *sm = &snat_main;
656 vl_api_snat_add_del_interface_addr_reply_t *rmp;
657 u8 is_del = mp->is_add == 0;
658 u32 sw_if_index = ntohl (mp->sw_if_index);
661 VALIDATE_SW_IF_INDEX (mp);
663 rv = snat_add_interface_address (sm, sw_if_index, is_del);
665 BAD_SW_IF_INDEX_LABEL;
667 REPLY_MACRO (VL_API_SNAT_ADD_DEL_INTERFACE_ADDR_REPLY);
670 static void *vl_api_snat_add_del_interface_addr_t_print
671 (vl_api_snat_add_del_interface_addr_t * mp, void *handle)
675 s = format (0, "SCRIPT: snat_add_del_interface_addr ");
676 s = format (s, "sw_if_index %d %s",
677 clib_host_to_net_u32 (mp->sw_if_index),
678 mp->is_add ? "" : "del");
684 send_snat_interface_addr_details
685 (u32 sw_if_index, unix_shared_memory_queue_t * q, u32 context)
687 vl_api_snat_interface_addr_details_t *rmp;
688 snat_main_t *sm = &snat_main;
690 rmp = vl_msg_api_alloc (sizeof (*rmp));
691 memset (rmp, 0, sizeof (*rmp));
693 ntohs (VL_API_SNAT_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
694 rmp->sw_if_index = ntohl (sw_if_index);
695 rmp->context = context;
697 vl_msg_api_send_shmem (q, (u8 *) & rmp);
701 vl_api_snat_interface_addr_dump_t_handler
702 (vl_api_snat_interface_addr_dump_t * mp)
704 unix_shared_memory_queue_t *q;
705 snat_main_t *sm = &snat_main;
708 q = vl_api_client_index_to_input_queue (mp->client_index);
713 vec_foreach (i, sm->auto_add_sw_if_indices)
714 send_snat_interface_addr_details(*i, q, mp->context);
718 static void *vl_api_snat_interface_addr_dump_t_print
719 (vl_api_snat_interface_addr_dump_t * mp, void *handle)
723 s = format (0, "SCRIPT: snat_interface_addr_dump ");
729 vl_api_snat_ipfix_enable_disable_t_handler
730 (vl_api_snat_ipfix_enable_disable_t * mp)
732 snat_main_t *sm = &snat_main;
733 vl_api_snat_ipfix_enable_disable_reply_t *rmp;
736 rv = snat_ipfix_logging_enable_disable (mp->enable,
742 REPLY_MACRO (VL_API_SNAT_IPFIX_ENABLE_DISABLE_REPLY);
745 static void *vl_api_snat_ipfix_enable_disable_t_print
746 (vl_api_snat_ipfix_enable_disable_t * mp, void *handle)
750 s = format (0, "SCRIPT: snat_ipfix_enable_disable ");
752 s = format (s, "domain %d ", clib_net_to_host_u32 (mp->domain_id));
754 s = format (s, "src_port %d ", clib_net_to_host_u16 (mp->src_port));
756 s = format (s, "disable ");
762 send_snat_user_details
763 (snat_user_t * u, unix_shared_memory_queue_t * q, u32 context)
765 vl_api_snat_user_details_t *rmp;
766 snat_main_t *sm = &snat_main;
767 fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
769 rmp = vl_msg_api_alloc (sizeof (*rmp));
770 memset (rmp, 0, sizeof (*rmp));
771 rmp->_vl_msg_id = ntohs (VL_API_SNAT_USER_DETAILS + sm->msg_id_base);
773 rmp->vrf_id = ntohl (fib->ft_table_id);
776 clib_memcpy (rmp->ip_address, &(u->addr), 4);
777 rmp->nsessions = ntohl (u->nsessions);
778 rmp->nstaticsessions = ntohl (u->nstaticsessions);
779 rmp->context = context;
781 vl_msg_api_send_shmem (q, (u8 *) & rmp);
785 vl_api_snat_user_dump_t_handler (vl_api_snat_user_dump_t * mp)
787 unix_shared_memory_queue_t *q;
788 snat_main_t *sm = &snat_main;
789 snat_main_per_thread_data_t *tsm;
792 q = vl_api_client_index_to_input_queue (mp->client_index);
797 vec_foreach (tsm, sm->per_thread_data)
798 vec_foreach (u, tsm->users)
799 send_snat_user_details (u, q, mp->context);
803 static void *vl_api_snat_user_dump_t_print
804 (vl_api_snat_user_dump_t * mp, void *handle)
808 s = format (0, "SCRIPT: snat_user_dump ");
814 send_snat_user_session_details
815 (snat_session_t * s, unix_shared_memory_queue_t * q, u32 context)
817 vl_api_snat_user_session_details_t *rmp;
818 snat_main_t *sm = &snat_main;
820 rmp = vl_msg_api_alloc (sizeof (*rmp));
821 memset (rmp, 0, sizeof (*rmp));
823 ntohs (VL_API_SNAT_USER_SESSION_DETAILS + sm->msg_id_base);
825 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
826 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
827 rmp->is_static = s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING ? 1 : 0;
828 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
829 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
830 rmp->total_pkts = ntohl (s->total_pkts);
831 rmp->context = context;
832 if (snat_is_unk_proto_session (s))
834 rmp->outside_port = 0;
835 rmp->inside_port = 0;
836 rmp->protocol = ntohs (s->in2out.port);
840 rmp->outside_port = s->out2in.port;
841 rmp->inside_port = s->in2out.port;
842 rmp->protocol = ntohs (snat_proto_to_ip_proto (s->in2out.protocol));
845 vl_msg_api_send_shmem (q, (u8 *) & rmp);
849 vl_api_snat_user_session_dump_t_handler
850 (vl_api_snat_user_session_dump_t * mp)
852 unix_shared_memory_queue_t *q;
853 snat_main_t *sm = &snat_main;
854 snat_main_per_thread_data_t *tsm;
856 clib_bihash_kv_8_8_t key, value;
857 snat_user_key_t ukey;
859 u32 session_index, head_index, elt_index;
860 dlist_elt_t *head, *elt;
863 q = vl_api_client_index_to_input_queue (mp->client_index);
869 clib_memcpy (&ukey.addr, mp->ip_address, 4);
870 ip.src_address.as_u32 = ukey.addr.as_u32;
871 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
872 key.key = ukey.as_u64;
875 vec_elt_at_index (sm->per_thread_data,
876 sm->worker_in2out_cb (&ip, ukey.fib_index));
878 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
879 if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
881 u = pool_elt_at_index (tsm->users, value.value);
882 if (!u->nsessions && !u->nstaticsessions)
885 head_index = u->sessions_per_user_list_head_index;
886 head = pool_elt_at_index (tsm->list_pool, head_index);
887 elt_index = head->next;
888 elt = pool_elt_at_index (tsm->list_pool, elt_index);
889 session_index = elt->value;
890 while (session_index != ~0)
892 s = pool_elt_at_index (tsm->sessions, session_index);
894 send_snat_user_session_details (s, q, mp->context);
896 elt_index = elt->next;
897 elt = pool_elt_at_index (tsm->list_pool, elt_index);
898 session_index = elt->value;
902 static void *vl_api_snat_user_session_dump_t_print
903 (vl_api_snat_user_session_dump_t * mp, void *handle)
907 s = format (0, "SCRIPT: snat_user_session_dump ");
908 s = format (s, "ip_address %U vrf_id %d\n",
909 format_ip4_address, mp->ip_address,
910 clib_net_to_host_u32 (mp->vrf_id));
915 /******************************************************************/
916 /*** detrministic NAT/CGN (old, will be deprecated after 17.10) ***/
917 /******************************************************************/
920 vl_api_snat_add_det_map_t_handler (vl_api_snat_add_det_map_t * mp)
922 snat_main_t *sm = &snat_main;
923 vl_api_snat_add_det_map_reply_t *rmp;
925 ip4_address_t in_addr, out_addr;
927 clib_memcpy (&in_addr, mp->in_addr, 4);
928 clib_memcpy (&out_addr, mp->out_addr, 4);
929 rv = snat_det_add_map (sm, &in_addr, mp->in_plen, &out_addr,
930 mp->out_plen, mp->is_add);
932 REPLY_MACRO (VL_API_SNAT_ADD_DET_MAP_REPLY);
935 static void *vl_api_snat_add_det_map_t_print
936 (vl_api_snat_add_det_map_t * mp, void *handle)
940 s = format (0, "SCRIPT: snat_add_det_map ");
941 s = format (s, "inside address %U/%d outside address %U/%d\n",
942 format_ip4_address, mp->in_addr, mp->in_plen,
943 format_ip4_address, mp->out_addr, mp->out_plen);
949 vl_api_snat_det_forward_t_handler (vl_api_snat_det_forward_t * mp)
951 snat_main_t *sm = &snat_main;
952 vl_api_snat_det_forward_reply_t *rmp;
954 u16 lo_port = 0, hi_port = 0;
956 ip4_address_t in_addr, out_addr;
959 clib_memcpy (&in_addr, mp->in_addr, 4);
960 dm = snat_det_map_by_user (sm, &in_addr);
963 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
967 snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
968 hi_port = lo_port + dm->ports_per_host - 1;
972 REPLY_MACRO2 (VL_API_SNAT_DET_FORWARD_REPLY,
974 rmp->out_port_lo = ntohs (lo_port);
975 rmp->out_port_hi = ntohs (hi_port);
977 memset (rmp->out_addr, 0, 16);
978 clib_memcpy (rmp->out_addr, &out_addr, 4);
983 static void *vl_api_snat_det_forward_t_print
984 (vl_api_snat_det_forward_t * mp, void *handle)
988 s = format (0, "SCRIPT: smat_det_forward_t");
989 s = format (s, "inside ip address %U\n", format_ip4_address, mp->in_addr);
995 vl_api_snat_det_reverse_t_handler (vl_api_snat_det_reverse_t * mp)
997 snat_main_t *sm = &snat_main;
998 vl_api_snat_det_reverse_reply_t *rmp;
1000 ip4_address_t out_addr, in_addr;
1004 clib_memcpy (&out_addr, mp->out_addr, 4);
1005 dm = snat_det_map_by_out (sm, &out_addr);
1008 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1012 snat_det_reverse (dm, &out_addr, htons (mp->out_port), &in_addr);
1016 REPLY_MACRO2 (VL_API_SNAT_DET_REVERSE_REPLY,
1019 memset (rmp->in_addr, 0, 16);
1020 clib_memcpy (rmp->in_addr, &in_addr, 4);
1025 static void *vl_api_snat_det_reverse_t_print
1026 (vl_api_snat_det_reverse_t * mp, void *handle)
1030 s = format (0, "SCRIPT: smat_det_reverse_t");
1031 s = format (s, "outside ip address %U outside port %d",
1032 format_ip4_address, mp->out_addr, ntohs (mp->out_port));
1038 sent_snat_det_map_details
1039 (snat_det_map_t * m, unix_shared_memory_queue_t * q, u32 context)
1041 vl_api_snat_det_map_details_t *rmp;
1042 snat_main_t *sm = &snat_main;
1044 rmp = vl_msg_api_alloc (sizeof (*rmp));
1045 memset (rmp, 0, sizeof (*rmp));
1046 rmp->_vl_msg_id = ntohs (VL_API_SNAT_DET_MAP_DETAILS + sm->msg_id_base);
1048 clib_memcpy (rmp->in_addr, &m->in_addr, 4);
1049 rmp->in_plen = m->in_plen;
1050 clib_memcpy (rmp->out_addr, &m->out_addr, 4);
1051 rmp->out_plen = m->out_plen;
1052 rmp->sharing_ratio = htonl (m->sharing_ratio);
1053 rmp->ports_per_host = htons (m->ports_per_host);
1054 rmp->ses_num = htonl (m->ses_num);
1055 rmp->context = context;
1057 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1061 vl_api_snat_det_map_dump_t_handler (vl_api_snat_det_map_dump_t * mp)
1063 unix_shared_memory_queue_t *q;
1064 snat_main_t *sm = &snat_main;
1067 q = vl_api_client_index_to_input_queue (mp->client_index);
1072 vec_foreach(m, sm->det_maps)
1073 sent_snat_det_map_details(m, q, mp->context);
1077 static void *vl_api_snat_det_map_dump_t_print
1078 (vl_api_snat_det_map_dump_t * mp, void *handle)
1082 s = format (0, "SCRIPT: snat_det_map_dump ");
1088 vl_api_snat_det_set_timeouts_t_handler (vl_api_snat_det_set_timeouts_t * mp)
1090 snat_main_t *sm = &snat_main;
1091 vl_api_snat_det_set_timeouts_reply_t *rmp;
1094 sm->udp_timeout = ntohl (mp->udp);
1095 sm->tcp_established_timeout = ntohl (mp->tcp_established);
1096 sm->tcp_transitory_timeout = ntohl (mp->tcp_transitory);
1097 sm->icmp_timeout = ntohl (mp->icmp);
1099 REPLY_MACRO (VL_API_SNAT_DET_SET_TIMEOUTS_REPLY);
1102 static void *vl_api_snat_det_set_timeouts_t_print
1103 (vl_api_snat_det_set_timeouts_t * mp, void *handle)
1107 s = format (0, "SCRIPT: snat_det_set_timeouts ");
1108 s = format (s, "udp %d tcp_established %d tcp_transitory %d icmp %d\n",
1110 ntohl (mp->tcp_established),
1111 ntohl (mp->tcp_transitory), ntohl (mp->icmp));
1117 vl_api_snat_det_get_timeouts_t_handler (vl_api_snat_det_get_timeouts_t * mp)
1119 snat_main_t *sm = &snat_main;
1120 vl_api_snat_det_get_timeouts_reply_t *rmp;
1124 REPLY_MACRO2 (VL_API_SNAT_DET_GET_TIMEOUTS_REPLY,
1126 rmp->udp = htonl (sm->udp_timeout);
1127 rmp->tcp_established = htonl (sm->tcp_established_timeout);
1128 rmp->tcp_transitory = htonl (sm->tcp_transitory_timeout);
1129 rmp->icmp = htonl (sm->icmp_timeout);
1134 static void *vl_api_snat_det_get_timeouts_t_print
1135 (vl_api_snat_det_get_timeouts_t * mp, void *handle)
1139 s = format (0, "SCRIPT: snat_det_get_timeouts");
1145 vl_api_snat_det_close_session_out_t_handler
1146 (vl_api_snat_det_close_session_out_t * mp)
1148 snat_main_t *sm = &snat_main;
1149 vl_api_snat_det_close_session_out_reply_t *rmp;
1150 ip4_address_t out_addr, ext_addr, in_addr;
1151 snat_det_out_key_t key;
1153 snat_det_session_t *ses;
1156 clib_memcpy (&out_addr, mp->out_addr, 4);
1157 clib_memcpy (&ext_addr, mp->ext_addr, 4);
1159 dm = snat_det_map_by_out (sm, &out_addr);
1162 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1165 snat_det_reverse (dm, &ext_addr, ntohs (mp->out_port), &in_addr);
1166 key.ext_host_addr = ext_addr;
1167 key.ext_host_port = mp->ext_port;
1168 key.out_port = mp->out_port;
1169 ses = snat_det_get_ses_by_out (dm, &in_addr, key.as_u64);
1172 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1175 snat_det_ses_close (dm, ses);
1178 REPLY_MACRO (VL_API_SNAT_DET_CLOSE_SESSION_OUT_REPLY);
1181 static void *vl_api_snat_det_close_session_out_t_print
1182 (vl_api_snat_det_close_session_out_t * mp, void *handle)
1186 s = format (0, "SCRIPT: snat_det_close_session_out ");
1187 s = format (s, "out_addr %U out_port %d "
1188 "ext_addr %U ext_port %d\n",
1189 format_ip4_address, mp->out_addr, ntohs (mp->out_port),
1190 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
1196 vl_api_snat_det_close_session_in_t_handler
1197 (vl_api_snat_det_close_session_in_t * mp)
1199 snat_main_t *sm = &snat_main;
1200 vl_api_snat_det_close_session_in_reply_t *rmp;
1201 ip4_address_t in_addr, ext_addr;
1202 snat_det_out_key_t key;
1204 snat_det_session_t *ses;
1207 clib_memcpy (&in_addr, mp->in_addr, 4);
1208 clib_memcpy (&ext_addr, mp->ext_addr, 4);
1210 dm = snat_det_map_by_user (sm, &in_addr);
1213 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1216 key.ext_host_addr = ext_addr;
1217 key.ext_host_port = mp->ext_port;
1218 ses = snat_det_find_ses_by_in (dm, &in_addr, mp->in_port, key);
1221 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1224 snat_det_ses_close (dm, ses);
1227 REPLY_MACRO (VL_API_SNAT_DET_CLOSE_SESSION_OUT_REPLY);
1230 static void *vl_api_snat_det_close_session_in_t_print
1231 (vl_api_snat_det_close_session_in_t * mp, void *handle)
1234 s = format (0, "SCRIPT: snat_det_close_session_in ");
1235 s = format (s, "in_addr %U in_port %d "
1236 "ext_addr %U ext_port %d\n",
1237 format_ip4_address, mp->in_addr, ntohs (mp->in_port),
1238 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
1244 send_snat_det_session_details
1245 (snat_det_session_t * s, unix_shared_memory_queue_t * q, u32 context)
1247 vl_api_snat_det_session_details_t *rmp;
1248 snat_main_t *sm = &snat_main;
1250 rmp = vl_msg_api_alloc (sizeof (*rmp));
1251 memset (rmp, 0, sizeof (*rmp));
1252 rmp->_vl_msg_id = ntohs (VL_API_SNAT_DET_SESSION_DETAILS + sm->msg_id_base);
1254 rmp->in_port = s->in_port;
1255 clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
1256 rmp->ext_port = s->out.ext_host_port;
1257 rmp->out_port = s->out.out_port;
1258 rmp->state = s->state;
1259 rmp->expire = ntohl (s->expire);
1260 rmp->context = context;
1262 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1266 vl_api_snat_det_session_dump_t_handler (vl_api_snat_det_session_dump_t * mp)
1268 unix_shared_memory_queue_t *q;
1269 snat_main_t *sm = &snat_main;
1270 ip4_address_t user_addr;
1272 snat_det_session_t *s, empty_ses;
1275 q = vl_api_client_index_to_input_queue (mp->client_index);
1281 memset (&empty_ses, 0, sizeof (empty_ses));
1282 clib_memcpy (&user_addr, mp->user_addr, 4);
1283 dm = snat_det_map_by_user (sm, &user_addr);
1287 s = dm->sessions + snat_det_user_ses_offset (&user_addr, dm->in_plen);
1288 for (i = 0; i < SNAT_DET_SES_PER_USER; i++)
1291 send_snat_det_session_details (s, q, mp->context);
1296 static void *vl_api_snat_det_session_dump_t_print
1297 (vl_api_snat_det_session_dump_t * mp, void *handle)
1301 s = format (0, "SCRIPT: snat_det_session_dump ");
1302 s = format (s, "user_addr %U\n", format_ip4_address, mp->user_addr);
1307 /******************************/
1308 /*** Common NAT plugin APIs ***/
1309 /******************************/
1312 vl_api_nat_control_ping_t_handler (vl_api_nat_control_ping_t * mp)
1314 vl_api_nat_control_ping_reply_t *rmp;
1315 snat_main_t *sm = &snat_main;
1319 REPLY_MACRO2 (VL_API_NAT_CONTROL_PING_REPLY,
1321 rmp->vpe_pid = ntohl (getpid ());
1327 vl_api_nat_control_ping_t_print (vl_api_nat_control_ping_t * mp, void *handle)
1331 s = format (0, "SCRIPT: nat_control_ping ");
1337 vl_api_nat_show_config_t_handler (vl_api_nat_show_config_t * mp)
1339 vl_api_nat_show_config_reply_t *rmp;
1340 snat_main_t *sm = &snat_main;
1344 REPLY_MACRO2 (VL_API_NAT_SHOW_CONFIG_REPLY,
1346 rmp->translation_buckets = htonl (sm->translation_buckets);
1347 rmp->translation_memory_size = htonl (sm->translation_memory_size);
1348 rmp->user_buckets = htonl (sm->user_buckets);
1349 rmp->user_memory_size = htonl (sm->user_memory_size);
1350 rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
1351 rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
1352 rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
1353 rmp->static_mapping_only = sm->static_mapping_only;
1354 rmp->static_mapping_connection_tracking =
1355 sm->static_mapping_connection_tracking;
1356 rmp->deterministic = sm->deterministic;
1362 vl_api_nat_show_config_t_print (vl_api_nat_show_config_t * mp, void *handle)
1366 s = format (0, "SCRIPT: nat_show_config ");
1372 vl_api_nat_set_workers_t_handler (vl_api_nat_set_workers_t * mp)
1374 snat_main_t *sm = &snat_main;
1375 vl_api_snat_set_workers_reply_t *rmp;
1378 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
1380 if (sm->num_workers < 2)
1382 rv = VNET_API_ERROR_FEATURE_DISABLED;
1386 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
1387 rv = snat_set_workers (bitmap);
1388 clib_bitmap_free (bitmap);
1391 REPLY_MACRO (VL_API_NAT_SET_WORKERS_REPLY);
1395 vl_api_nat_set_workers_t_print (vl_api_nat_set_workers_t * mp, void *handle)
1401 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
1403 s = format (0, "SCRIPT: nat_set_workers ");
1404 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
1406 clib_bitmap_foreach (i, bitmap,
1409 s = format (s, "%d", i);
1411 s = format (s, ",%d", i);
1415 clib_bitmap_free (bitmap);
1420 send_nat_worker_details (u32 worker_index, unix_shared_memory_queue_t * q,
1423 vl_api_nat_worker_details_t *rmp;
1424 snat_main_t *sm = &snat_main;
1425 vlib_worker_thread_t *w =
1426 vlib_worker_threads + worker_index + sm->first_worker_index;
1428 rmp = vl_msg_api_alloc (sizeof (*rmp));
1429 memset (rmp, 0, sizeof (*rmp));
1430 rmp->_vl_msg_id = ntohs (VL_API_NAT_WORKER_DETAILS + sm->msg_id_base);
1431 rmp->context = context;
1432 rmp->worker_index = htonl (worker_index);
1433 rmp->lcore_id = htonl (w->lcore_id);
1434 strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
1436 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1440 vl_api_nat_worker_dump_t_handler (vl_api_nat_worker_dump_t * mp)
1442 unix_shared_memory_queue_t *q;
1443 snat_main_t *sm = &snat_main;
1446 q = vl_api_client_index_to_input_queue (mp->client_index);
1451 vec_foreach (worker_index, sm->workers)
1452 send_nat_worker_details(*worker_index, q, mp->context);
1457 vl_api_nat_worker_dump_t_print (vl_api_nat_worker_dump_t * mp, void *handle)
1461 s = format (0, "SCRIPT: nat_worker_dump ");
1467 vl_api_nat_ipfix_enable_disable_t_handler (vl_api_nat_ipfix_enable_disable_t *
1470 snat_main_t *sm = &snat_main;
1471 vl_api_nat_ipfix_enable_disable_reply_t *rmp;
1474 rv = snat_ipfix_logging_enable_disable (mp->enable,
1475 clib_host_to_net_u32
1477 clib_host_to_net_u16
1480 REPLY_MACRO (VL_API_NAT_IPFIX_ENABLE_DISABLE_REPLY);
1484 vl_api_nat_ipfix_enable_disable_t_print (vl_api_nat_ipfix_enable_disable_t *
1489 s = format (0, "SCRIPT: nat_ipfix_enable_disable ");
1491 s = format (s, "domain %d ", clib_net_to_host_u32 (mp->domain_id));
1493 s = format (s, "src_port %d ", clib_net_to_host_u16 (mp->src_port));
1495 s = format (s, "disable ");
1501 vl_api_nat_set_reass_t_handler (vl_api_nat_set_reass_t * mp)
1503 snat_main_t *sm = &snat_main;
1504 vl_api_nat_set_reass_reply_t *rmp;
1508 nat_reass_set (ntohl (mp->timeout), ntohs (mp->max_reass), mp->max_frag,
1509 mp->drop_frag, mp->is_ip6);
1511 REPLY_MACRO (VL_API_NAT_SET_REASS_REPLY);
1515 vl_api_nat_set_reass_t_print (vl_api_nat_set_reass_t * mp, void *handle)
1519 s = format (0, "SCRIPT: nat_set_reass ");
1520 s = format (s, "timeout %d max_reass %d max_frag %d drop_frag %d is_ip6 %d",
1521 clib_host_to_net_u32 (mp->timeout),
1522 clib_host_to_net_u16 (mp->max_reass),
1523 mp->max_frag, mp->drop_frag, mp->is_ip6);
1529 vl_api_nat_get_reass_t_handler (vl_api_nat_get_reass_t * mp)
1531 snat_main_t *sm = &snat_main;
1532 vl_api_nat_get_reass_reply_t *rmp;
1536 REPLY_MACRO2 (VL_API_NAT_GET_REASS_REPLY,
1538 rmp->ip4_timeout = htonl (nat_reass_get_timeout(0));
1539 rmp->ip4_max_reass = htons (nat_reass_get_max_reass(0));
1540 rmp->ip4_max_frag = nat_reass_get_max_frag(0);
1541 rmp->ip4_drop_frag = nat_reass_is_drop_frag(0);
1542 rmp->ip6_timeout = htonl (nat_reass_get_timeout(1));
1543 rmp->ip6_max_reass = htons (nat_reass_get_max_reass(1));
1544 rmp->ip6_max_frag = nat_reass_get_max_frag(1);
1545 rmp->ip6_drop_frag = nat_reass_is_drop_frag(1);
1551 vl_api_nat_get_reass_t_print (vl_api_nat_get_reass_t * mp, void *handle)
1555 s = format (0, "SCRIPT: nat_get_reass");
1560 typedef struct nat_api_walk_ctx_t_
1562 unix_shared_memory_queue_t *q;
1564 } nat_api_walk_ctx_t;
1567 nat_ip4_reass_walk_api (nat_reass_ip4_t * reass, void *arg)
1569 vl_api_nat_reass_details_t *rmp;
1570 snat_main_t *sm = &snat_main;
1571 nat_api_walk_ctx_t *ctx = arg;
1573 rmp = vl_msg_api_alloc (sizeof (*rmp));
1574 memset (rmp, 0, sizeof (*rmp));
1575 rmp->_vl_msg_id = ntohs (VL_API_NAT_REASS_DETAILS + sm->msg_id_base);
1576 rmp->context = ctx->context;
1577 clib_memcpy (rmp->src_addr, &(reass->key.src), 4);
1578 clib_memcpy (rmp->dst_addr, &(reass->key.dst), 4);
1579 rmp->proto = reass->key.proto;
1580 rmp->frag_id = ntohl (reass->key.frag_id);
1581 rmp->frag_n = reass->frag_n;
1584 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
1590 nat_ip6_reass_walk_api (nat_reass_ip6_t * reass, void *arg)
1592 vl_api_nat_reass_details_t *rmp;
1593 snat_main_t *sm = &snat_main;
1594 nat_api_walk_ctx_t *ctx = arg;
1596 rmp = vl_msg_api_alloc (sizeof (*rmp));
1597 memset (rmp, 0, sizeof (*rmp));
1598 rmp->_vl_msg_id = ntohs (VL_API_NAT_REASS_DETAILS + sm->msg_id_base);
1599 rmp->context = ctx->context;
1600 clib_memcpy (rmp->src_addr, &(reass->key.src), 16);
1601 clib_memcpy (rmp->dst_addr, &(reass->key.dst), 16);
1602 rmp->proto = reass->key.proto;
1603 rmp->frag_id = ntohl (reass->key.frag_id);
1604 rmp->frag_n = reass->frag_n;
1607 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
1613 vl_api_nat_reass_dump_t_handler (vl_api_nat_reass_dump_t * mp)
1615 unix_shared_memory_queue_t *q;
1617 q = vl_api_client_index_to_input_queue (mp->client_index);
1621 nat_api_walk_ctx_t ctx = {
1623 .context = mp->context,
1626 nat_ip4_reass_walk (nat_ip4_reass_walk_api, &ctx);
1627 nat_ip6_reass_walk (nat_ip6_reass_walk_api, &ctx);
1631 vl_api_nat_reass_dump_t_print (vl_api_nat_reass_dump_t * mp, void *handle)
1635 s = format (0, "SCRIPT: nat_reass_dump");
1644 vl_api_nat44_add_del_address_range_t_handler
1645 (vl_api_nat44_add_del_address_range_t * mp)
1647 snat_main_t *sm = &snat_main;
1648 vl_api_nat44_add_del_address_range_reply_t *rmp;
1649 ip4_address_t this_addr;
1650 u32 start_host_order, end_host_order;
1656 if (sm->static_mapping_only)
1658 rv = VNET_API_ERROR_FEATURE_DISABLED;
1662 tmp = (u32 *) mp->first_ip_address;
1663 start_host_order = clib_host_to_net_u32 (tmp[0]);
1664 tmp = (u32 *) mp->last_ip_address;
1665 end_host_order = clib_host_to_net_u32 (tmp[0]);
1667 count = (end_host_order - start_host_order) + 1;
1669 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
1672 clib_warning ("%U - %U, %d addresses...",
1673 format_ip4_address, mp->first_ip_address,
1674 format_ip4_address, mp->last_ip_address, count);
1676 memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
1678 for (i = 0; i < count; i++)
1681 snat_add_address (sm, &this_addr, vrf_id);
1683 rv = snat_del_address (sm, this_addr, 0);
1688 increment_v4_address (&this_addr);
1692 REPLY_MACRO (VL_API_NAT44_ADD_DEL_ADDRESS_RANGE_REPLY);
1695 static void *vl_api_nat44_add_del_address_range_t_print
1696 (vl_api_nat44_add_del_address_range_t * mp, void *handle)
1700 s = format (0, "SCRIPT: nat44_add_address_range ");
1701 s = format (s, "%U ", format_ip4_address, mp->first_ip_address);
1702 if (memcmp (mp->first_ip_address, mp->last_ip_address, 4))
1704 s = format (s, " - %U ", format_ip4_address, mp->last_ip_address);
1710 send_nat44_address_details (snat_address_t * a,
1711 unix_shared_memory_queue_t * q, u32 context)
1713 vl_api_nat44_address_details_t *rmp;
1714 snat_main_t *sm = &snat_main;
1716 rmp = vl_msg_api_alloc (sizeof (*rmp));
1717 memset (rmp, 0, sizeof (*rmp));
1718 rmp->_vl_msg_id = ntohs (VL_API_NAT44_ADDRESS_DETAILS + sm->msg_id_base);
1719 clib_memcpy (rmp->ip_address, &(a->addr), 4);
1720 if (a->fib_index != ~0)
1722 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
1723 rmp->vrf_id = ntohl (fib->ft_table_id);
1727 rmp->context = context;
1729 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1733 vl_api_nat44_address_dump_t_handler (vl_api_nat44_address_dump_t * mp)
1735 unix_shared_memory_queue_t *q;
1736 snat_main_t *sm = &snat_main;
1739 q = vl_api_client_index_to_input_queue (mp->client_index);
1744 vec_foreach (a, sm->addresses)
1745 send_nat44_address_details (a, q, mp->context);
1750 vl_api_nat44_address_dump_t_print (vl_api_nat44_address_dump_t * mp,
1755 s = format (0, "SCRIPT: nat44_address_dump ");
1761 vl_api_nat44_interface_add_del_feature_t_handler
1762 (vl_api_nat44_interface_add_del_feature_t * mp)
1764 snat_main_t *sm = &snat_main;
1765 vl_api_nat44_interface_add_del_feature_reply_t *rmp;
1766 u8 is_del = mp->is_add == 0;
1767 u32 sw_if_index = ntohl (mp->sw_if_index);
1770 VALIDATE_SW_IF_INDEX (mp);
1772 rv = snat_interface_add_del (sw_if_index, mp->is_inside, is_del);
1774 BAD_SW_IF_INDEX_LABEL;
1776 REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_FEATURE_REPLY);
1779 static void *vl_api_nat44_interface_add_del_feature_t_print
1780 (vl_api_nat44_interface_add_del_feature_t * mp, void *handle)
1784 s = format (0, "SCRIPT: nat44_interface_add_del_feature ");
1785 s = format (s, "sw_if_index %d %s %s",
1786 clib_host_to_net_u32 (mp->sw_if_index),
1787 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
1793 send_nat44_interface_details (snat_interface_t * i,
1794 unix_shared_memory_queue_t * q, u32 context)
1796 vl_api_nat44_interface_details_t *rmp;
1797 snat_main_t *sm = &snat_main;
1799 rmp = vl_msg_api_alloc (sizeof (*rmp));
1800 memset (rmp, 0, sizeof (*rmp));
1801 rmp->_vl_msg_id = ntohs (VL_API_NAT44_INTERFACE_DETAILS + sm->msg_id_base);
1802 rmp->sw_if_index = ntohl (i->sw_if_index);
1803 rmp->is_inside = (nat_interface_is_inside (i)
1804 && nat_interface_is_outside (i)) ? 2 :
1805 nat_interface_is_inside (i);
1806 rmp->context = context;
1808 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1812 vl_api_nat44_interface_dump_t_handler (vl_api_nat44_interface_dump_t * mp)
1814 unix_shared_memory_queue_t *q;
1815 snat_main_t *sm = &snat_main;
1816 snat_interface_t *i;
1818 q = vl_api_client_index_to_input_queue (mp->client_index);
1823 pool_foreach (i, sm->interfaces,
1825 send_nat44_interface_details(i, q, mp->context);
1831 vl_api_nat44_interface_dump_t_print (vl_api_nat44_interface_dump_t * mp,
1836 s = format (0, "SCRIPT: nat44_interface_dump ");
1842 vl_api_nat44_interface_add_del_output_feature_t_handler
1843 (vl_api_nat44_interface_add_del_output_feature_t * mp)
1845 snat_main_t *sm = &snat_main;
1846 vl_api_nat44_interface_add_del_output_feature_reply_t *rmp;
1847 u8 is_del = mp->is_add == 0;
1848 u32 sw_if_index = ntohl (mp->sw_if_index);
1851 VALIDATE_SW_IF_INDEX (mp);
1853 rv = snat_interface_add_del_output_feature (sw_if_index, mp->is_inside,
1856 BAD_SW_IF_INDEX_LABEL;
1858 REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY);
1861 static void *vl_api_nat44_interface_add_del_output_feature_t_print
1862 (vl_api_nat44_interface_add_del_output_feature_t * mp, void *handle)
1866 s = format (0, "SCRIPT: nat44_interface_add_del_output_feature ");
1867 s = format (s, "sw_if_index %d %s %s",
1868 clib_host_to_net_u32 (mp->sw_if_index),
1869 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
1875 send_nat44_interface_output_feature_details (snat_interface_t * i,
1876 unix_shared_memory_queue_t * q,
1879 vl_api_nat44_interface_output_feature_details_t *rmp;
1880 snat_main_t *sm = &snat_main;
1882 rmp = vl_msg_api_alloc (sizeof (*rmp));
1883 memset (rmp, 0, sizeof (*rmp));
1885 ntohs (VL_API_NAT44_INTERFACE_OUTPUT_FEATURE_DETAILS + sm->msg_id_base);
1886 rmp->sw_if_index = ntohl (i->sw_if_index);
1887 rmp->context = context;
1888 rmp->is_inside = nat_interface_is_inside (i);
1890 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1894 vl_api_nat44_interface_output_feature_dump_t_handler
1895 (vl_api_nat44_interface_output_feature_dump_t * mp)
1897 unix_shared_memory_queue_t *q;
1898 snat_main_t *sm = &snat_main;
1899 snat_interface_t *i;
1901 q = vl_api_client_index_to_input_queue (mp->client_index);
1906 pool_foreach (i, sm->output_feature_interfaces,
1908 send_nat44_interface_output_feature_details(i, q, mp->context);
1913 static void *vl_api_nat44_interface_output_feature_dump_t_print
1914 (vl_api_nat44_interface_output_feature_dump_t * mp, void *handle)
1918 s = format (0, "SCRIPT: nat44_interface_output_feature_dump ");
1924 vl_api_nat44_add_del_static_mapping_t_handler
1925 (vl_api_nat44_add_del_static_mapping_t * mp)
1927 snat_main_t *sm = &snat_main;
1928 vl_api_nat44_add_del_static_mapping_reply_t *rmp;
1929 ip4_address_t local_addr, external_addr;
1930 u16 local_port = 0, external_port = 0;
1931 u32 vrf_id, external_sw_if_index;
1933 snat_protocol_t proto;
1935 memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
1936 memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
1937 if (mp->addr_only == 0)
1939 local_port = clib_net_to_host_u16 (mp->local_port);
1940 external_port = clib_net_to_host_u16 (mp->external_port);
1942 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
1943 external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
1944 proto = ip_proto_to_snat_proto (mp->protocol);
1946 rv = snat_add_static_mapping (local_addr, external_addr, local_port,
1947 external_port, vrf_id, mp->addr_only,
1948 external_sw_if_index, proto, mp->is_add);
1950 REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_REPLY);
1953 static void *vl_api_nat44_add_del_static_mapping_t_print
1954 (vl_api_nat44_add_del_static_mapping_t * mp, void *handle)
1958 s = format (0, "SCRIPT: nat44_add_del_static_mapping ");
1959 s = format (s, "protocol %d local_addr %U external_addr %U ",
1961 format_ip4_address, mp->local_ip_address,
1962 format_ip4_address, mp->external_ip_address);
1964 if (mp->addr_only == 0)
1965 s = format (s, "local_port %d external_port %d ",
1966 clib_net_to_host_u16 (mp->local_port),
1967 clib_net_to_host_u16 (mp->external_port));
1969 if (mp->vrf_id != ~0)
1970 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
1972 if (mp->external_sw_if_index != ~0)
1973 s = format (s, "external_sw_if_index %d",
1974 clib_net_to_host_u32 (mp->external_sw_if_index));
1979 send_nat44_static_mapping_details (snat_static_mapping_t * m,
1980 unix_shared_memory_queue_t * q,
1983 vl_api_nat44_static_mapping_details_t *rmp;
1984 snat_main_t *sm = &snat_main;
1986 rmp = vl_msg_api_alloc (sizeof (*rmp));
1987 memset (rmp, 0, sizeof (*rmp));
1989 ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
1990 rmp->addr_only = m->addr_only;
1991 clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
1992 clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
1993 rmp->local_port = htons (m->local_port);
1994 rmp->external_port = htons (m->external_port);
1995 rmp->external_sw_if_index = ~0;
1996 rmp->vrf_id = htonl (m->vrf_id);
1997 rmp->protocol = snat_proto_to_ip_proto (m->proto);
1998 rmp->context = context;
2000 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2004 send_nat44_static_map_resolve_details (snat_static_map_resolve_t * m,
2005 unix_shared_memory_queue_t * q,
2008 vl_api_nat44_static_mapping_details_t *rmp;
2009 snat_main_t *sm = &snat_main;
2011 rmp = vl_msg_api_alloc (sizeof (*rmp));
2012 memset (rmp, 0, sizeof (*rmp));
2014 ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
2015 rmp->addr_only = m->addr_only;
2016 clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
2017 rmp->local_port = htons (m->l_port);
2018 rmp->external_port = htons (m->e_port);
2019 rmp->external_sw_if_index = htonl (m->sw_if_index);
2020 rmp->vrf_id = htonl (m->vrf_id);
2021 rmp->protocol = snat_proto_to_ip_proto (m->proto);
2022 rmp->context = context;
2024 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2028 vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
2031 unix_shared_memory_queue_t *q;
2032 snat_main_t *sm = &snat_main;
2033 snat_static_mapping_t *m;
2034 snat_static_map_resolve_t *rp;
2037 q = vl_api_client_index_to_input_queue (mp->client_index);
2042 pool_foreach (m, sm->static_mappings,
2044 if (!vec_len(m->locals))
2045 send_nat44_static_mapping_details (m, q, mp->context);
2049 for (j = 0; j < vec_len (sm->to_resolve); j++)
2051 rp = sm->to_resolve + j;
2052 send_nat44_static_map_resolve_details (rp, q, mp->context);
2057 vl_api_nat44_static_mapping_dump_t_print (vl_api_nat44_static_mapping_dump_t *
2062 s = format (0, "SCRIPT: nat44_static_mapping_dump ");
2068 vl_api_nat44_add_del_interface_addr_t_handler
2069 (vl_api_nat44_add_del_interface_addr_t * mp)
2071 snat_main_t *sm = &snat_main;
2072 vl_api_nat44_add_del_interface_addr_reply_t *rmp;
2073 u8 is_del = mp->is_add == 0;
2074 u32 sw_if_index = ntohl (mp->sw_if_index);
2077 VALIDATE_SW_IF_INDEX (mp);
2079 rv = snat_add_interface_address (sm, sw_if_index, is_del);
2081 BAD_SW_IF_INDEX_LABEL;
2083 REPLY_MACRO (VL_API_NAT44_ADD_DEL_INTERFACE_ADDR_REPLY);
2086 static void *vl_api_nat44_add_del_interface_addr_t_print
2087 (vl_api_nat44_add_del_interface_addr_t * mp, void *handle)
2091 s = format (0, "SCRIPT: nat44_add_del_interface_addr ");
2092 s = format (s, "sw_if_index %d %s",
2093 clib_host_to_net_u32 (mp->sw_if_index),
2094 mp->is_add ? "" : "del");
2100 send_nat44_interface_addr_details (u32 sw_if_index,
2101 unix_shared_memory_queue_t * q,
2104 vl_api_nat44_interface_addr_details_t *rmp;
2105 snat_main_t *sm = &snat_main;
2107 rmp = vl_msg_api_alloc (sizeof (*rmp));
2108 memset (rmp, 0, sizeof (*rmp));
2110 ntohs (VL_API_NAT44_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
2111 rmp->sw_if_index = ntohl (sw_if_index);
2112 rmp->context = context;
2114 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2118 vl_api_nat44_interface_addr_dump_t_handler (vl_api_nat44_interface_addr_dump_t
2121 unix_shared_memory_queue_t *q;
2122 snat_main_t *sm = &snat_main;
2125 q = vl_api_client_index_to_input_queue (mp->client_index);
2130 vec_foreach (i, sm->auto_add_sw_if_indices)
2131 send_nat44_interface_addr_details(*i, q, mp->context);
2136 vl_api_nat44_interface_addr_dump_t_print (vl_api_nat44_interface_addr_dump_t *
2141 s = format (0, "SCRIPT: nat44_interface_addr_dump ");
2147 send_nat44_user_details (snat_user_t * u, unix_shared_memory_queue_t * q,
2150 vl_api_nat44_user_details_t *rmp;
2151 snat_main_t *sm = &snat_main;
2152 fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
2154 rmp = vl_msg_api_alloc (sizeof (*rmp));
2155 memset (rmp, 0, sizeof (*rmp));
2156 rmp->_vl_msg_id = ntohs (VL_API_NAT44_USER_DETAILS + sm->msg_id_base);
2158 rmp->vrf_id = ntohl (fib->ft_table_id);
2160 clib_memcpy (rmp->ip_address, &(u->addr), 4);
2161 rmp->nsessions = ntohl (u->nsessions);
2162 rmp->nstaticsessions = ntohl (u->nstaticsessions);
2163 rmp->context = context;
2165 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2169 vl_api_nat44_user_dump_t_handler (vl_api_nat44_user_dump_t * mp)
2171 unix_shared_memory_queue_t *q;
2172 snat_main_t *sm = &snat_main;
2173 snat_main_per_thread_data_t *tsm;
2176 q = vl_api_client_index_to_input_queue (mp->client_index);
2181 vec_foreach (tsm, sm->per_thread_data)
2182 vec_foreach (u, tsm->users)
2183 send_nat44_user_details (u, q, mp->context);
2188 vl_api_nat44_user_dump_t_print (vl_api_nat44_user_dump_t * mp, void *handle)
2192 s = format (0, "SCRIPT: nat44_user_dump ");
2198 send_nat44_user_session_details (snat_session_t * s,
2199 unix_shared_memory_queue_t * q, u32 context)
2201 vl_api_nat44_user_session_details_t *rmp;
2202 snat_main_t *sm = &snat_main;
2204 rmp = vl_msg_api_alloc (sizeof (*rmp));
2205 memset (rmp, 0, sizeof (*rmp));
2207 ntohs (VL_API_NAT44_USER_SESSION_DETAILS + sm->msg_id_base);
2208 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
2209 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
2210 rmp->is_static = s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING ? 1 : 0;
2211 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
2212 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
2213 rmp->total_pkts = ntohl (s->total_pkts);
2214 rmp->context = context;
2215 if (snat_is_unk_proto_session (s))
2217 rmp->outside_port = 0;
2218 rmp->inside_port = 0;
2219 rmp->protocol = ntohs (s->in2out.port);
2223 rmp->outside_port = s->out2in.port;
2224 rmp->inside_port = s->in2out.port;
2225 rmp->protocol = ntohs (snat_proto_to_ip_proto (s->in2out.protocol));
2228 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2232 vl_api_nat44_user_session_dump_t_handler (vl_api_nat44_user_session_dump_t *
2235 unix_shared_memory_queue_t *q;
2236 snat_main_t *sm = &snat_main;
2237 snat_main_per_thread_data_t *tsm;
2239 clib_bihash_kv_8_8_t key, value;
2240 snat_user_key_t ukey;
2242 u32 session_index, head_index, elt_index;
2243 dlist_elt_t *head, *elt;
2246 q = vl_api_client_index_to_input_queue (mp->client_index);
2250 clib_memcpy (&ukey.addr, mp->ip_address, 4);
2251 ip.src_address.as_u32 = ukey.addr.as_u32;
2252 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
2253 key.key = ukey.as_u64;
2254 if (sm->num_workers)
2256 vec_elt_at_index (sm->per_thread_data,
2257 sm->worker_in2out_cb (&ip, ukey.fib_index));
2259 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
2260 if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
2262 u = pool_elt_at_index (tsm->users, value.value);
2263 if (!u->nsessions && !u->nstaticsessions)
2266 head_index = u->sessions_per_user_list_head_index;
2267 head = pool_elt_at_index (tsm->list_pool, head_index);
2268 elt_index = head->next;
2269 elt = pool_elt_at_index (tsm->list_pool, elt_index);
2270 session_index = elt->value;
2271 while (session_index != ~0)
2273 s = pool_elt_at_index (tsm->sessions, session_index);
2275 send_nat44_user_session_details (s, q, mp->context);
2277 elt_index = elt->next;
2278 elt = pool_elt_at_index (tsm->list_pool, elt_index);
2279 session_index = elt->value;
2284 vl_api_nat44_user_session_dump_t_print (vl_api_nat44_user_session_dump_t * mp,
2289 s = format (0, "SCRIPT: nat44_user_session_dump ");
2290 s = format (s, "ip_address %U vrf_id %d\n",
2291 format_ip4_address, mp->ip_address,
2292 clib_net_to_host_u32 (mp->vrf_id));
2297 static nat44_lb_addr_port_t *
2298 unformat_nat44_lb_addr_port (vl_api_nat44_lb_addr_port_t * addr_port_pairs,
2299 u8 addr_port_pair_num)
2302 nat44_lb_addr_port_t *lb_addr_port_pairs = 0, lb_addr_port;
2303 vl_api_nat44_lb_addr_port_t *ap;
2305 for (i = 0; i < addr_port_pair_num; i++)
2307 ap = &addr_port_pairs[i];
2308 memset (&lb_addr_port, 0, sizeof (lb_addr_port));
2309 clib_memcpy (&lb_addr_port.addr, ap->addr, 4);
2310 lb_addr_port.port = clib_net_to_host_u16 (ap->port);
2311 lb_addr_port.probability = ap->probability;
2312 vec_add1 (lb_addr_port_pairs, lb_addr_port);
2315 return lb_addr_port_pairs;
2319 vl_api_nat44_add_del_lb_static_mapping_t_handler
2320 (vl_api_nat44_add_del_lb_static_mapping_t * mp)
2322 snat_main_t *sm = &snat_main;
2323 vl_api_nat44_add_del_lb_static_mapping_reply_t *rmp;
2325 nat44_lb_addr_port_t *locals = 0;
2326 ip4_address_t e_addr;
2327 snat_protocol_t proto;
2329 locals = unformat_nat44_lb_addr_port (mp->locals, mp->local_num);
2330 clib_memcpy (&e_addr, mp->external_addr, 4);
2331 proto = ip_proto_to_snat_proto (mp->protocol);
2334 nat44_add_del_lb_static_mapping (e_addr,
2335 clib_net_to_host_u16 (mp->external_port),
2336 proto, clib_net_to_host_u32 (mp->vrf_id),
2337 locals, mp->is_add);
2341 REPLY_MACRO (VL_API_NAT44_ADD_DEL_LB_STATIC_MAPPING_REPLY);
2344 static void *vl_api_nat44_add_del_lb_static_mapping_t_print
2345 (vl_api_nat44_add_del_lb_static_mapping_t * mp, void *handle)
2349 s = format (0, "SCRIPT: nat44_add_del_lb_static_mapping ");
2350 s = format (s, "is_add %d\n", mp->is_add);
2356 send_nat44_lb_static_mapping_details (snat_static_mapping_t * m,
2357 unix_shared_memory_queue_t * q,
2360 vl_api_nat44_lb_static_mapping_details_t *rmp;
2361 snat_main_t *sm = &snat_main;
2362 nat44_lb_addr_port_t *ap;
2363 vl_api_nat44_lb_addr_port_t *locals;
2366 vl_msg_api_alloc (sizeof (*rmp) +
2367 (vec_len (m->locals) * sizeof (nat44_lb_addr_port_t)));
2368 memset (rmp, 0, sizeof (*rmp));
2370 ntohs (VL_API_NAT44_LB_STATIC_MAPPING_DETAILS + sm->msg_id_base);
2372 clib_memcpy (rmp->external_addr, &(m->external_addr), 4);
2373 rmp->external_port = ntohs (m->external_port);
2374 rmp->protocol = snat_proto_to_ip_proto (m->proto);
2375 rmp->vrf_id = ntohl (m->vrf_id);
2376 rmp->context = context;
2378 locals = (vl_api_nat44_lb_addr_port_t *) rmp->locals;
2379 vec_foreach (ap, m->locals)
2381 clib_memcpy (locals->addr, &(ap->addr), 4);
2382 locals->port = htons (ap->port);
2383 locals->probability = ap->probability;
2388 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2392 vl_api_nat44_lb_static_mapping_dump_t_handler
2393 (vl_api_nat44_lb_static_mapping_dump_t * mp)
2395 unix_shared_memory_queue_t *q;
2396 snat_main_t *sm = &snat_main;
2397 snat_static_mapping_t *m;
2399 q = vl_api_client_index_to_input_queue (mp->client_index);
2404 pool_foreach (m, sm->static_mappings,
2406 if (vec_len(m->locals))
2407 send_nat44_lb_static_mapping_details (m, q, mp->context);
2412 static void *vl_api_nat44_lb_static_mapping_dump_t_print
2413 (vl_api_nat44_lb_static_mapping_dump_t * mp, void *handle)
2417 s = format (0, "SCRIPT: nat44_lb_static_mapping_dump ");
2423 vl_api_nat44_del_session_t_handler (vl_api_nat44_del_session_t * mp)
2425 snat_main_t *sm = &snat_main;
2426 vl_api_nat44_del_session_reply_t *rmp;
2431 snat_protocol_t proto;
2433 memcpy (&addr.as_u8, mp->address, 4);
2434 port = clib_net_to_host_u16 (mp->port);
2435 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
2436 proto = ip_proto_to_snat_proto (mp->protocol);
2438 rv = nat44_del_session (sm, &addr, port, proto, vrf_id, mp->is_in);
2440 REPLY_MACRO (VL_API_NAT44_DEL_SESSION_REPLY);
2444 vl_api_nat44_del_session_t_print (vl_api_nat44_del_session_t * mp,
2449 s = format (0, "SCRIPT: nat44_add_del_static_mapping ");
2450 s = format (s, "addr %U port %d protocol %d vrf_id %d is_in %d",
2451 format_ip4_address, mp->address,
2452 clib_net_to_host_u16 (mp->port),
2453 mp->protocol, clib_net_to_host_u32 (mp->vrf_id), mp->is_in);
2458 /*******************************/
2459 /*** Deterministic NAT (CGN) ***/
2460 /*******************************/
2463 vl_api_nat_det_add_del_map_t_handler (vl_api_nat_det_add_del_map_t * mp)
2465 snat_main_t *sm = &snat_main;
2466 vl_api_nat_det_add_del_map_reply_t *rmp;
2468 ip4_address_t in_addr, out_addr;
2472 rv = VNET_API_ERROR_UNIMPLEMENTED;
2476 clib_memcpy (&in_addr, mp->in_addr, 4);
2477 clib_memcpy (&out_addr, mp->out_addr, 4);
2478 rv = snat_det_add_map (sm, &in_addr, mp->in_plen, &out_addr,
2479 mp->out_plen, mp->is_add);
2482 REPLY_MACRO (VL_API_NAT_DET_ADD_DEL_MAP_REPLY);
2486 vl_api_nat_det_add_del_map_t_print (vl_api_nat_det_add_del_map_t * mp,
2491 s = format (0, "SCRIPT: nat_det_add_del_map ");
2492 s = format (s, "inside address %U/%d outside address %U/%d\n",
2493 format_ip4_address, mp->in_addr, mp->in_plen,
2494 format_ip4_address, mp->out_addr, mp->out_plen);
2500 vl_api_nat_det_forward_t_handler (vl_api_nat_det_forward_t * mp)
2502 snat_main_t *sm = &snat_main;
2503 vl_api_nat_det_forward_reply_t *rmp;
2505 u16 lo_port = 0, hi_port = 0;
2507 ip4_address_t in_addr, out_addr;
2511 out_addr.as_u32 = 0;
2512 rv = VNET_API_ERROR_UNIMPLEMENTED;
2516 out_addr.as_u32 = 0;
2517 clib_memcpy (&in_addr, mp->in_addr, 4);
2518 dm = snat_det_map_by_user (sm, &in_addr);
2521 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2525 snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
2526 hi_port = lo_port + dm->ports_per_host - 1;
2530 REPLY_MACRO2 (VL_API_NAT_DET_FORWARD_REPLY,
2532 rmp->out_port_lo = ntohs (lo_port);
2533 rmp->out_port_hi = ntohs (hi_port);
2534 clib_memcpy (rmp->out_addr, &out_addr, 4);
2540 vl_api_nat_det_forward_t_print (vl_api_nat_det_forward_t * mp, void *handle)
2544 s = format (0, "SCRIPT: nat_det_forward");
2545 s = format (s, "inside ip address %U\n", format_ip4_address, mp->in_addr);
2551 vl_api_nat_det_reverse_t_handler (vl_api_nat_det_reverse_t * mp)
2553 snat_main_t *sm = &snat_main;
2554 vl_api_nat_det_reverse_reply_t *rmp;
2556 ip4_address_t out_addr, in_addr;
2560 clib_memcpy (&out_addr, mp->out_addr, 4);
2561 dm = snat_det_map_by_out (sm, &out_addr);
2564 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2568 snat_det_reverse (dm, &out_addr, htons (mp->out_port), &in_addr);
2572 REPLY_MACRO2 (VL_API_NAT_DET_REVERSE_REPLY,
2575 memset (rmp->in_addr, 0, 16);
2576 clib_memcpy (rmp->in_addr, &in_addr, 4);
2582 vl_api_nat_det_reverse_t_print (vl_api_nat_det_reverse_t * mp, void *handle)
2586 s = format (0, "SCRIPT: nat_det_reverse");
2587 s = format (s, "outside ip address %U outside port %d",
2588 format_ip4_address, mp->out_addr, ntohs (mp->out_port));
2594 sent_nat_det_map_details (snat_det_map_t * m, unix_shared_memory_queue_t * q,
2597 vl_api_nat_det_map_details_t *rmp;
2598 snat_main_t *sm = &snat_main;
2600 rmp = vl_msg_api_alloc (sizeof (*rmp));
2601 memset (rmp, 0, sizeof (*rmp));
2602 rmp->_vl_msg_id = ntohs (VL_API_NAT_DET_MAP_DETAILS + sm->msg_id_base);
2604 clib_memcpy (rmp->in_addr, &m->in_addr, 4);
2605 rmp->in_plen = m->in_plen;
2606 clib_memcpy (rmp->out_addr, &m->out_addr, 4);
2607 rmp->out_plen = m->out_plen;
2608 rmp->sharing_ratio = htonl (m->sharing_ratio);
2609 rmp->ports_per_host = htons (m->ports_per_host);
2610 rmp->ses_num = htonl (m->ses_num);
2611 rmp->context = context;
2613 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2617 vl_api_nat_det_map_dump_t_handler (vl_api_nat_det_map_dump_t * mp)
2619 unix_shared_memory_queue_t *q;
2620 snat_main_t *sm = &snat_main;
2623 q = vl_api_client_index_to_input_queue (mp->client_index);
2628 vec_foreach(m, sm->det_maps)
2629 sent_nat_det_map_details(m, q, mp->context);
2634 vl_api_nat_det_map_dump_t_print (vl_api_nat_det_map_dump_t * mp, void *handle)
2638 s = format (0, "SCRIPT: nat_det_map_dump ");
2644 vl_api_nat_det_set_timeouts_t_handler (vl_api_nat_det_set_timeouts_t * mp)
2646 snat_main_t *sm = &snat_main;
2647 vl_api_nat_det_set_timeouts_reply_t *rmp;
2650 sm->udp_timeout = ntohl (mp->udp);
2651 sm->tcp_established_timeout = ntohl (mp->tcp_established);
2652 sm->tcp_transitory_timeout = ntohl (mp->tcp_transitory);
2653 sm->icmp_timeout = ntohl (mp->icmp);
2655 REPLY_MACRO (VL_API_NAT_DET_SET_TIMEOUTS_REPLY);
2659 vl_api_nat_det_set_timeouts_t_print (vl_api_nat_det_set_timeouts_t * mp,
2664 s = format (0, "SCRIPT: nat_det_set_timeouts ");
2665 s = format (s, "udp %d tcp_established %d tcp_transitory %d icmp %d\n",
2667 ntohl (mp->tcp_established),
2668 ntohl (mp->tcp_transitory), ntohl (mp->icmp));
2674 vl_api_nat_det_get_timeouts_t_handler (vl_api_nat_det_get_timeouts_t * mp)
2676 snat_main_t *sm = &snat_main;
2677 vl_api_nat_det_get_timeouts_reply_t *rmp;
2681 REPLY_MACRO2 (VL_API_NAT_DET_GET_TIMEOUTS_REPLY,
2683 rmp->udp = htonl (sm->udp_timeout);
2684 rmp->tcp_established = htonl (sm->tcp_established_timeout);
2685 rmp->tcp_transitory = htonl (sm->tcp_transitory_timeout);
2686 rmp->icmp = htonl (sm->icmp_timeout);
2692 vl_api_nat_det_get_timeouts_t_print (vl_api_nat_det_get_timeouts_t * mp,
2697 s = format (0, "SCRIPT: nat_det_get_timeouts");
2703 vl_api_nat_det_close_session_out_t_handler (vl_api_nat_det_close_session_out_t
2706 snat_main_t *sm = &snat_main;
2707 vl_api_nat_det_close_session_out_reply_t *rmp;
2708 ip4_address_t out_addr, ext_addr, in_addr;
2709 snat_det_out_key_t key;
2711 snat_det_session_t *ses;
2714 clib_memcpy (&out_addr, mp->out_addr, 4);
2715 clib_memcpy (&ext_addr, mp->ext_addr, 4);
2717 dm = snat_det_map_by_out (sm, &out_addr);
2720 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2723 snat_det_reverse (dm, &ext_addr, ntohs (mp->out_port), &in_addr);
2724 key.ext_host_addr = ext_addr;
2725 key.ext_host_port = mp->ext_port;
2726 key.out_port = mp->out_port;
2727 ses = snat_det_get_ses_by_out (dm, &in_addr, key.as_u64);
2730 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2733 snat_det_ses_close (dm, ses);
2736 REPLY_MACRO (VL_API_NAT_DET_CLOSE_SESSION_OUT_REPLY);
2740 vl_api_nat_det_close_session_out_t_print (vl_api_nat_det_close_session_out_t *
2745 s = format (0, "SCRIPT: nat_det_close_session_out ");
2746 s = format (s, "out_addr %U out_port %d "
2747 "ext_addr %U ext_port %d\n",
2748 format_ip4_address, mp->out_addr, ntohs (mp->out_port),
2749 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
2755 vl_api_nat_det_close_session_in_t_handler (vl_api_nat_det_close_session_in_t *
2758 snat_main_t *sm = &snat_main;
2759 vl_api_nat_det_close_session_in_reply_t *rmp;
2760 ip4_address_t in_addr, ext_addr;
2761 snat_det_out_key_t key;
2763 snat_det_session_t *ses;
2768 rv = VNET_API_ERROR_UNIMPLEMENTED;
2772 clib_memcpy (&in_addr, mp->in_addr, 4);
2773 clib_memcpy (&ext_addr, mp->ext_addr, 4);
2775 dm = snat_det_map_by_user (sm, &in_addr);
2778 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2781 key.ext_host_addr = ext_addr;
2782 key.ext_host_port = mp->ext_port;
2783 ses = snat_det_find_ses_by_in (dm, &in_addr, mp->in_port, key);
2786 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2789 snat_det_ses_close (dm, ses);
2792 REPLY_MACRO (VL_API_NAT_DET_CLOSE_SESSION_OUT_REPLY);
2796 vl_api_nat_det_close_session_in_t_print (vl_api_nat_det_close_session_in_t *
2800 s = format (0, "SCRIPT: nat_det_close_session_in ");
2801 s = format (s, "in_addr %U in_port %d ext_addr %U ext_port %d\n",
2802 format_ip4_address, mp->in_addr, ntohs (mp->in_port),
2803 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
2809 send_nat_det_session_details (snat_det_session_t * s,
2810 unix_shared_memory_queue_t * q, u32 context)
2812 vl_api_nat_det_session_details_t *rmp;
2813 snat_main_t *sm = &snat_main;
2815 rmp = vl_msg_api_alloc (sizeof (*rmp));
2816 memset (rmp, 0, sizeof (*rmp));
2817 rmp->_vl_msg_id = ntohs (VL_API_NAT_DET_SESSION_DETAILS + sm->msg_id_base);
2818 rmp->in_port = s->in_port;
2819 clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
2820 rmp->ext_port = s->out.ext_host_port;
2821 rmp->out_port = s->out.out_port;
2822 rmp->state = s->state;
2823 rmp->expire = ntohl (s->expire);
2824 rmp->context = context;
2826 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2830 vl_api_nat_det_session_dump_t_handler (vl_api_nat_det_session_dump_t * mp)
2832 unix_shared_memory_queue_t *q;
2833 snat_main_t *sm = &snat_main;
2834 ip4_address_t user_addr;
2836 snat_det_session_t *s, empty_ses;
2839 q = vl_api_client_index_to_input_queue (mp->client_index);
2845 memset (&empty_ses, 0, sizeof (empty_ses));
2846 clib_memcpy (&user_addr, mp->user_addr, 4);
2847 dm = snat_det_map_by_user (sm, &user_addr);
2851 s = dm->sessions + snat_det_user_ses_offset (&user_addr, dm->in_plen);
2852 for (i = 0; i < SNAT_DET_SES_PER_USER; i++)
2855 send_nat_det_session_details (s, q, mp->context);
2861 vl_api_nat_det_session_dump_t_print (vl_api_nat_det_session_dump_t * mp,
2866 s = format (0, "SCRIPT: nat_det_session_dump ");
2867 s = format (s, "user_addr %U\n", format_ip4_address, mp->user_addr);
2877 vl_api_nat64_add_del_pool_addr_range_t_handler
2878 (vl_api_nat64_add_del_pool_addr_range_t * mp)
2880 vl_api_nat64_add_del_pool_addr_range_reply_t *rmp;
2881 snat_main_t *sm = &snat_main;
2882 nat64_main_t *nm = &nat64_main;
2884 ip4_address_t this_addr;
2885 u32 start_host_order, end_host_order;
2890 if (nm->is_disabled)
2892 rv = VNET_API_ERROR_FEATURE_DISABLED;
2896 tmp = (u32 *) mp->start_addr;
2897 start_host_order = clib_host_to_net_u32 (tmp[0]);
2898 tmp = (u32 *) mp->end_addr;
2899 end_host_order = clib_host_to_net_u32 (tmp[0]);
2901 count = (end_host_order - start_host_order) + 1;
2903 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
2905 memcpy (&this_addr.as_u8, mp->start_addr, 4);
2907 for (i = 0; i < count; i++)
2909 if ((rv = nat64_add_del_pool_addr (&this_addr, vrf_id, mp->is_add)))
2912 increment_v4_address (&this_addr);
2916 REPLY_MACRO (VL_API_NAT64_ADD_DEL_POOL_ADDR_RANGE_REPLY);
2919 static void *vl_api_nat64_add_del_pool_addr_range_t_print
2920 (vl_api_nat64_add_del_pool_addr_range_t * mp, void *handle)
2924 s = format (0, "SCRIPT: nat64_add_del_pool_addr_range ");
2925 s = format (s, "%U - %U vrf_id %u %s\n",
2926 format_ip4_address, mp->start_addr,
2927 format_ip4_address, mp->end_addr,
2928 ntohl (mp->vrf_id), mp->is_add ? "" : "del");
2933 typedef struct nat64_api_walk_ctx_t_
2935 unix_shared_memory_queue_t *q;
2937 } nat64_api_walk_ctx_t;
2940 nat64_api_pool_walk (snat_address_t * a, void *arg)
2942 vl_api_nat64_pool_addr_details_t *rmp;
2943 snat_main_t *sm = &snat_main;
2944 nat64_api_walk_ctx_t *ctx = arg;
2946 rmp = vl_msg_api_alloc (sizeof (*rmp));
2947 memset (rmp, 0, sizeof (*rmp));
2948 rmp->_vl_msg_id = ntohs (VL_API_NAT64_POOL_ADDR_DETAILS + sm->msg_id_base);
2949 clib_memcpy (rmp->address, &(a->addr), 4);
2950 if (a->fib_index != ~0)
2952 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP6);
2955 rmp->vrf_id = ntohl (fib->ft_table_id);
2959 rmp->context = ctx->context;
2961 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
2967 vl_api_nat64_pool_addr_dump_t_handler (vl_api_nat64_pool_addr_dump_t * mp)
2969 unix_shared_memory_queue_t *q;
2970 nat64_main_t *nm = &nat64_main;
2972 if (nm->is_disabled)
2975 q = vl_api_client_index_to_input_queue (mp->client_index);
2979 nat64_api_walk_ctx_t ctx = {
2981 .context = mp->context,
2984 nat64_pool_addr_walk (nat64_api_pool_walk, &ctx);
2988 vl_api_nat64_pool_addr_dump_t_print (vl_api_nat64_pool_addr_dump_t * mp,
2993 s = format (0, "SCRIPT: nat64_pool_addr_dump\n");
2999 vl_api_nat64_add_del_interface_t_handler (vl_api_nat64_add_del_interface_t *
3002 snat_main_t *sm = &snat_main;
3003 nat64_main_t *nm = &nat64_main;
3004 vl_api_nat64_add_del_interface_reply_t *rmp;
3007 if (nm->is_disabled)
3009 rv = VNET_API_ERROR_FEATURE_DISABLED;
3013 VALIDATE_SW_IF_INDEX (mp);
3016 nat64_add_del_interface (ntohl (mp->sw_if_index), mp->is_inside,
3019 BAD_SW_IF_INDEX_LABEL;
3022 REPLY_MACRO (VL_API_NAT64_ADD_DEL_INTERFACE_REPLY);
3026 vl_api_nat64_add_del_interface_t_print (vl_api_nat64_add_del_interface_t * mp,
3031 s = format (0, "SCRIPT: nat64_add_del_interface ");
3032 s = format (s, "sw_if_index %d %s %s",
3033 clib_host_to_net_u32 (mp->sw_if_index),
3034 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
3040 nat64_api_interface_walk (snat_interface_t * i, void *arg)
3042 vl_api_nat64_interface_details_t *rmp;
3043 snat_main_t *sm = &snat_main;
3044 nat64_api_walk_ctx_t *ctx = arg;
3046 rmp = vl_msg_api_alloc (sizeof (*rmp));
3047 memset (rmp, 0, sizeof (*rmp));
3048 rmp->_vl_msg_id = ntohs (VL_API_NAT64_INTERFACE_DETAILS + sm->msg_id_base);
3049 rmp->sw_if_index = ntohl (i->sw_if_index);
3050 rmp->is_inside = (nat_interface_is_inside (i)
3051 && nat_interface_is_outside (i)) ? 2 :
3052 nat_interface_is_inside (i);
3053 rmp->context = ctx->context;
3055 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3061 vl_api_nat64_interface_dump_t_handler (vl_api_nat64_interface_dump_t * mp)
3063 unix_shared_memory_queue_t *q;
3064 nat64_main_t *nm = &nat64_main;
3066 if (nm->is_disabled)
3069 q = vl_api_client_index_to_input_queue (mp->client_index);
3073 nat64_api_walk_ctx_t ctx = {
3075 .context = mp->context,
3078 nat64_interfaces_walk (nat64_api_interface_walk, &ctx);
3082 vl_api_nat64_interface_dump_t_print (vl_api_nat64_interface_dump_t * mp,
3087 s = format (0, "SCRIPT: snat_interface_dump ");
3093 vl_api_nat64_add_del_static_bib_t_handler
3094 (vl_api_nat64_add_del_static_bib_t * mp)
3096 snat_main_t *sm = &snat_main;
3097 nat64_main_t *nm = &nat64_main;
3098 vl_api_nat64_add_del_static_bib_reply_t *rmp;
3099 ip6_address_t in_addr;
3100 ip4_address_t out_addr;
3103 if (nm->is_disabled)
3105 rv = VNET_API_ERROR_FEATURE_DISABLED;
3109 memcpy (&in_addr.as_u8, mp->i_addr, 16);
3110 memcpy (&out_addr.as_u8, mp->o_addr, 4);
3113 nat64_add_del_static_bib_entry (&in_addr, &out_addr,
3114 clib_net_to_host_u16 (mp->i_port),
3115 clib_net_to_host_u16 (mp->o_port),
3117 clib_net_to_host_u32 (mp->vrf_id),
3121 REPLY_MACRO (VL_API_NAT64_ADD_DEL_STATIC_BIB_REPLY);
3124 static void *vl_api_nat64_add_del_static_bib_t_print
3125 (vl_api_nat64_add_del_static_bib_t * mp, void *handle)
3129 s = format (0, "SCRIPT: nat64_add_del_static_bib ");
3130 s = format (s, "protocol %d i_addr %U o_addr %U ",
3132 format_ip6_address, mp->i_addr, format_ip4_address, mp->o_addr);
3134 if (mp->vrf_id != ~0)
3135 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
3141 nat64_api_bib_walk (nat64_db_bib_entry_t * bibe, void *arg)
3143 vl_api_nat64_bib_details_t *rmp;
3144 snat_main_t *sm = &snat_main;
3145 nat64_api_walk_ctx_t *ctx = arg;
3148 fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
3152 rmp = vl_msg_api_alloc (sizeof (*rmp));
3153 memset (rmp, 0, sizeof (*rmp));
3154 rmp->_vl_msg_id = ntohs (VL_API_NAT64_BIB_DETAILS + sm->msg_id_base);
3155 rmp->context = ctx->context;
3156 clib_memcpy (rmp->i_addr, &(bibe->in_addr), 16);
3157 clib_memcpy (rmp->o_addr, &(bibe->out_addr), 4);
3158 rmp->i_port = bibe->in_port;
3159 rmp->o_port = bibe->out_port;
3160 rmp->vrf_id = ntohl (fib->ft_table_id);
3161 rmp->proto = bibe->proto;
3162 rmp->is_static = bibe->is_static;
3163 rmp->ses_num = ntohl (bibe->ses_num);
3165 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3171 vl_api_nat64_bib_dump_t_handler (vl_api_nat64_bib_dump_t * mp)
3173 unix_shared_memory_queue_t *q;
3174 nat64_main_t *nm = &nat64_main;
3176 if (nm->is_disabled)
3179 q = vl_api_client_index_to_input_queue (mp->client_index);
3183 nat64_api_walk_ctx_t ctx = {
3185 .context = mp->context,
3188 nat64_db_bib_walk (&nm->db, mp->proto, nat64_api_bib_walk, &ctx);
3192 vl_api_nat64_bib_dump_t_print (vl_api_nat64_bib_dump_t * mp, void *handle)
3196 s = format (0, "SCRIPT: snat_bib_dump protocol %d", mp->proto);
3202 vl_api_nat64_set_timeouts_t_handler (vl_api_nat64_set_timeouts_t * mp)
3204 snat_main_t *sm = &snat_main;
3205 nat64_main_t *nm = &nat64_main;
3206 vl_api_nat64_set_timeouts_reply_t *rmp;
3209 if (nm->is_disabled)
3211 rv = VNET_API_ERROR_FEATURE_DISABLED;
3215 rv = nat64_set_icmp_timeout (ntohl (mp->icmp));
3218 rv = nat64_set_udp_timeout (ntohl (mp->udp));
3222 nat64_set_tcp_timeouts (ntohl (mp->tcp_trans), ntohl (mp->tcp_est),
3223 ntohl (mp->tcp_incoming_syn));
3226 REPLY_MACRO (VL_API_NAT64_SET_TIMEOUTS_REPLY);
3229 static void *vl_api_nat64_set_timeouts_t_print
3230 (vl_api_nat64_set_timeouts_t * mp, void *handle)
3234 s = format (0, "SCRIPT: nat64_set_timeouts ");
3237 "udp %d icmp %d, tcp_trans %d, tcp_est %d, tcp_incoming_syn %d\n",
3238 ntohl (mp->udp), ntohl (mp->icmp), ntohl (mp->tcp_trans),
3239 ntohl (mp->tcp_est), ntohl (mp->tcp_incoming_syn));
3245 vl_api_nat64_get_timeouts_t_handler (vl_api_nat64_get_timeouts_t * mp)
3247 snat_main_t *sm = &snat_main;
3248 nat64_main_t *nm = &nat64_main;
3249 vl_api_nat64_get_timeouts_reply_t *rmp;
3252 if (nm->is_disabled)
3256 REPLY_MACRO2 (VL_API_NAT64_GET_TIMEOUTS_REPLY,
3258 rmp->udp = htonl (nat64_get_udp_timeout());
3259 rmp->icmp = htonl (nat64_get_icmp_timeout());
3260 rmp->tcp_trans = htonl (nat64_get_tcp_trans_timeout());
3261 rmp->tcp_est = htonl (nat64_get_tcp_est_timeout());
3262 rmp->tcp_incoming_syn = htonl (nat64_get_tcp_incoming_syn_timeout());
3267 static void *vl_api_nat64_get_timeouts_t_print
3268 (vl_api_nat64_get_timeouts_t * mp, void *handle)
3272 s = format (0, "SCRIPT: nat64_get_timeouts");
3278 nat64_api_st_walk (nat64_db_st_entry_t * ste, void *arg)
3280 vl_api_nat64_st_details_t *rmp;
3281 snat_main_t *sm = &snat_main;
3282 nat64_api_walk_ctx_t *ctx = arg;
3283 nat64_main_t *nm = &nat64_main;
3284 nat64_db_bib_entry_t *bibe;
3287 bibe = nat64_db_bib_entry_by_index (&nm->db, ste->proto, ste->bibe_index);
3291 fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
3295 rmp = vl_msg_api_alloc (sizeof (*rmp));
3296 memset (rmp, 0, sizeof (*rmp));
3297 rmp->_vl_msg_id = ntohs (VL_API_NAT64_ST_DETAILS + sm->msg_id_base);
3298 rmp->context = ctx->context;
3299 clib_memcpy (rmp->il_addr, &(bibe->in_addr), 16);
3300 clib_memcpy (rmp->ol_addr, &(bibe->out_addr), 4);
3301 rmp->il_port = bibe->in_port;
3302 rmp->ol_port = bibe->out_port;
3303 clib_memcpy (rmp->ir_addr, &(ste->in_r_addr), 16);
3304 clib_memcpy (rmp->or_addr, &(ste->out_r_addr), 4);
3305 rmp->il_port = ste->r_port;
3306 rmp->vrf_id = ntohl (fib->ft_table_id);
3307 rmp->proto = ste->proto;
3309 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3315 vl_api_nat64_st_dump_t_handler (vl_api_nat64_st_dump_t * mp)
3317 unix_shared_memory_queue_t *q;
3318 nat64_main_t *nm = &nat64_main;
3320 if (nm->is_disabled)
3323 q = vl_api_client_index_to_input_queue (mp->client_index);
3327 nat64_api_walk_ctx_t ctx = {
3329 .context = mp->context,
3332 nat64_db_st_walk (&nm->db, mp->proto, nat64_api_st_walk, &ctx);
3336 vl_api_nat64_st_dump_t_print (vl_api_nat64_st_dump_t * mp, void *handle)
3340 s = format (0, "SCRIPT: snat_st_dump protocol %d", mp->proto);
3346 vl_api_nat64_add_del_prefix_t_handler (vl_api_nat64_add_del_prefix_t * mp)
3348 vl_api_nat64_add_del_prefix_reply_t *rmp;
3349 snat_main_t *sm = &snat_main;
3350 nat64_main_t *nm = &nat64_main;
3351 ip6_address_t prefix;
3354 if (nm->is_disabled)
3356 rv = VNET_API_ERROR_FEATURE_DISABLED;
3360 memcpy (&prefix.as_u8, mp->prefix, 16);
3363 nat64_add_del_prefix (&prefix, mp->prefix_len,
3364 clib_net_to_host_u32 (mp->vrf_id), mp->is_add);
3366 REPLY_MACRO (VL_API_NAT64_ADD_DEL_PREFIX_REPLY);
3370 vl_api_nat64_add_del_prefix_t_print (vl_api_nat64_add_del_prefix_t * mp,
3375 s = format (0, "SCRIPT: nat64_add_del_prefix %U/%u vrf_id %u %s\n",
3376 format_ip6_address, mp->prefix, mp->prefix_len,
3377 ntohl (mp->vrf_id), mp->is_add ? "" : "del");
3383 nat64_api_prefix_walk (nat64_prefix_t * p, void *arg)
3385 vl_api_nat64_prefix_details_t *rmp;
3386 snat_main_t *sm = &snat_main;
3387 nat64_api_walk_ctx_t *ctx = arg;
3389 rmp = vl_msg_api_alloc (sizeof (*rmp));
3390 memset (rmp, 0, sizeof (*rmp));
3391 rmp->_vl_msg_id = ntohs (VL_API_NAT64_PREFIX_DETAILS + sm->msg_id_base);
3392 clib_memcpy (rmp->prefix, &(p->prefix), 16);
3393 rmp->prefix_len = p->plen;
3394 rmp->vrf_id = ntohl (p->vrf_id);
3395 rmp->context = ctx->context;
3397 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3403 vl_api_nat64_prefix_dump_t_handler (vl_api_nat64_prefix_dump_t * mp)
3405 unix_shared_memory_queue_t *q;
3406 nat64_main_t *nm = &nat64_main;
3408 if (nm->is_disabled)
3411 q = vl_api_client_index_to_input_queue (mp->client_index);
3415 nat64_api_walk_ctx_t ctx = {
3417 .context = mp->context,
3420 nat64_prefix_walk (nat64_api_prefix_walk, &ctx);
3424 vl_api_nat64_prefix_dump_t_print (vl_api_nat64_prefix_dump_t * mp,
3429 s = format (0, "SCRIPT: nat64_prefix_dump\n");
3439 vl_api_dslite_set_aftr_addr_t_handler (vl_api_dslite_set_aftr_addr_t * mp)
3441 vl_api_dslite_set_aftr_addr_reply_t *rmp;
3442 snat_main_t *sm = &snat_main;
3443 dslite_main_t *dm = &dslite_main;
3445 ip6_address_t ip6_addr;
3447 memcpy (&ip6_addr.as_u8, mp->ip6_addr, 16);
3449 rv = dslite_set_aftr_ip6_addr (dm, &ip6_addr);
3451 REPLY_MACRO (VL_API_DSLITE_SET_AFTR_ADDR_REPLY);
3455 vl_api_dslite_set_aftr_addr_t_print (vl_api_dslite_set_aftr_addr_t * mp,
3460 s = format (0, "SCRIPT: dslite_set_aftr_addr ");
3461 s = format (s, "ip6_addr %U ip4_addr %U\n",
3462 format_ip6_address, mp->ip6_addr,
3463 format_ip4_address, mp->ip4_addr);
3469 vl_api_dslite_add_del_pool_addr_range_t_handler
3470 (vl_api_dslite_add_del_pool_addr_range_t * mp)
3472 vl_api_dslite_add_del_pool_addr_range_reply_t *rmp;
3473 snat_main_t *sm = &snat_main;
3474 dslite_main_t *dm = &dslite_main;
3476 ip4_address_t this_addr;
3477 u32 start_host_order, end_host_order;
3481 tmp = (u32 *) mp->start_addr;
3482 start_host_order = clib_host_to_net_u32 (tmp[0]);
3483 tmp = (u32 *) mp->end_addr;
3484 end_host_order = clib_host_to_net_u32 (tmp[0]);
3486 count = (end_host_order - start_host_order) + 1;
3487 memcpy (&this_addr.as_u8, mp->start_addr, 4);
3489 for (i = 0; i < count; i++)
3491 if ((rv = dslite_add_del_pool_addr (dm, &this_addr, mp->is_add)))
3494 increment_v4_address (&this_addr);
3498 REPLY_MACRO (VL_API_DSLITE_ADD_DEL_POOL_ADDR_RANGE_REPLY);
3501 static void *vl_api_dslite_add_del_pool_addr_range_t_print
3502 (vl_api_dslite_add_del_pool_addr_range_t * mp, void *handle)
3506 s = format (0, "SCRIPT: dslite_add_del_pool_addr_range ");
3507 s = format (s, "%U - %U\n",
3508 format_ip4_address, mp->start_addr,
3509 format_ip4_address, mp->end_addr);
3515 /* List of message types that this plugin understands */
3516 #define foreach_snat_plugin_api_msg \
3517 _(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range) \
3518 _(SNAT_INTERFACE_ADD_DEL_FEATURE, snat_interface_add_del_feature) \
3519 _(SNAT_ADD_STATIC_MAPPING, snat_add_static_mapping) \
3520 _(SNAT_CONTROL_PING, snat_control_ping) \
3521 _(SNAT_STATIC_MAPPING_DUMP, snat_static_mapping_dump) \
3522 _(SNAT_SHOW_CONFIG, snat_show_config) \
3523 _(SNAT_ADDRESS_DUMP, snat_address_dump) \
3524 _(SNAT_INTERFACE_DUMP, snat_interface_dump) \
3525 _(SNAT_SET_WORKERS, snat_set_workers) \
3526 _(SNAT_WORKER_DUMP, snat_worker_dump) \
3527 _(SNAT_ADD_DEL_INTERFACE_ADDR, snat_add_del_interface_addr) \
3528 _(SNAT_INTERFACE_ADDR_DUMP, snat_interface_addr_dump) \
3529 _(SNAT_IPFIX_ENABLE_DISABLE, snat_ipfix_enable_disable) \
3530 _(SNAT_USER_DUMP, snat_user_dump) \
3531 _(SNAT_USER_SESSION_DUMP, snat_user_session_dump) \
3532 _(SNAT_INTERFACE_ADD_DEL_OUTPUT_FEATURE, \
3533 snat_interface_add_del_output_feature) \
3534 _(SNAT_INTERFACE_OUTPUT_FEATURE_DUMP, \
3535 snat_interface_output_feature_dump) \
3536 _(SNAT_ADD_DET_MAP, snat_add_det_map) \
3537 _(SNAT_DET_FORWARD, snat_det_forward) \
3538 _(SNAT_DET_REVERSE, snat_det_reverse) \
3539 _(SNAT_DET_MAP_DUMP, snat_det_map_dump) \
3540 _(SNAT_DET_SET_TIMEOUTS, snat_det_set_timeouts) \
3541 _(SNAT_DET_GET_TIMEOUTS, snat_det_get_timeouts) \
3542 _(SNAT_DET_CLOSE_SESSION_OUT, snat_det_close_session_out) \
3543 _(SNAT_DET_CLOSE_SESSION_IN, snat_det_close_session_in) \
3544 _(SNAT_DET_SESSION_DUMP, snat_det_session_dump) \
3545 _(NAT_CONTROL_PING, nat_control_ping) \
3546 _(NAT_SHOW_CONFIG, nat_show_config) \
3547 _(NAT_SET_WORKERS, nat_set_workers) \
3548 _(NAT_WORKER_DUMP, nat_worker_dump) \
3549 _(NAT_IPFIX_ENABLE_DISABLE, nat_ipfix_enable_disable) \
3550 _(NAT_SET_REASS, nat_set_reass) \
3551 _(NAT_GET_REASS, nat_get_reass) \
3552 _(NAT_REASS_DUMP, nat_reass_dump) \
3553 _(NAT44_ADD_DEL_ADDRESS_RANGE, nat44_add_del_address_range) \
3554 _(NAT44_INTERFACE_ADD_DEL_FEATURE, nat44_interface_add_del_feature) \
3555 _(NAT44_ADD_DEL_STATIC_MAPPING, nat44_add_del_static_mapping) \
3556 _(NAT44_STATIC_MAPPING_DUMP, nat44_static_mapping_dump) \
3557 _(NAT44_ADDRESS_DUMP, nat44_address_dump) \
3558 _(NAT44_INTERFACE_DUMP, nat44_interface_dump) \
3559 _(NAT44_ADD_DEL_INTERFACE_ADDR, nat44_add_del_interface_addr) \
3560 _(NAT44_INTERFACE_ADDR_DUMP, nat44_interface_addr_dump) \
3561 _(NAT44_USER_DUMP, nat44_user_dump) \
3562 _(NAT44_USER_SESSION_DUMP, nat44_user_session_dump) \
3563 _(NAT44_INTERFACE_ADD_DEL_OUTPUT_FEATURE, \
3564 nat44_interface_add_del_output_feature) \
3565 _(NAT44_INTERFACE_OUTPUT_FEATURE_DUMP, \
3566 nat44_interface_output_feature_dump) \
3567 _(NAT44_ADD_DEL_LB_STATIC_MAPPING, nat44_add_del_lb_static_mapping) \
3568 _(NAT44_LB_STATIC_MAPPING_DUMP, nat44_lb_static_mapping_dump) \
3569 _(NAT44_DEL_SESSION, nat44_del_session) \
3570 _(NAT_DET_ADD_DEL_MAP, nat_det_add_del_map) \
3571 _(NAT_DET_FORWARD, nat_det_forward) \
3572 _(NAT_DET_REVERSE, nat_det_reverse) \
3573 _(NAT_DET_MAP_DUMP, nat_det_map_dump) \
3574 _(NAT_DET_SET_TIMEOUTS, nat_det_set_timeouts) \
3575 _(NAT_DET_GET_TIMEOUTS, nat_det_get_timeouts) \
3576 _(NAT_DET_CLOSE_SESSION_OUT, nat_det_close_session_out) \
3577 _(NAT_DET_CLOSE_SESSION_IN, nat_det_close_session_in) \
3578 _(NAT_DET_SESSION_DUMP, nat_det_session_dump) \
3579 _(NAT64_ADD_DEL_POOL_ADDR_RANGE, nat64_add_del_pool_addr_range) \
3580 _(NAT64_POOL_ADDR_DUMP, nat64_pool_addr_dump) \
3581 _(NAT64_ADD_DEL_INTERFACE, nat64_add_del_interface) \
3582 _(NAT64_INTERFACE_DUMP, nat64_interface_dump) \
3583 _(NAT64_ADD_DEL_STATIC_BIB, nat64_add_del_static_bib) \
3584 _(NAT64_BIB_DUMP, nat64_bib_dump) \
3585 _(NAT64_SET_TIMEOUTS, nat64_set_timeouts) \
3586 _(NAT64_GET_TIMEOUTS, nat64_get_timeouts) \
3587 _(NAT64_ST_DUMP, nat64_st_dump) \
3588 _(NAT64_ADD_DEL_PREFIX, nat64_add_del_prefix) \
3589 _(NAT64_PREFIX_DUMP, nat64_prefix_dump) \
3590 _(DSLITE_ADD_DEL_POOL_ADDR_RANGE, dslite_add_del_pool_addr_range) \
3591 _(DSLITE_SET_AFTR_ADDR, dslite_set_aftr_addr)
3593 /* Set up the API message handling tables */
3594 static clib_error_t *
3595 snat_plugin_api_hookup (vlib_main_t * vm)
3597 snat_main_t *sm __attribute__ ((unused)) = &snat_main;
3599 vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
3601 vl_api_##n##_t_handler, \
3603 vl_api_##n##_t_endian, \
3604 vl_api_##n##_t_print, \
3605 sizeof(vl_api_##n##_t), 1);
3606 foreach_snat_plugin_api_msg;
3612 #define vl_msg_name_crc_list
3613 #include <nat/nat_all_api_h.h>
3614 #undef vl_msg_name_crc_list
3617 setup_message_id_table (snat_main_t * sm, api_main_t * am)
3619 #define _(id,n,crc) \
3620 vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base);
3621 foreach_vl_msg_name_crc_nat;
3626 plugin_custom_dump_configure (snat_main_t * sm)
3628 #define _(n,f) sm->api_main->msg_print_handlers \
3629 [VL_API_##n + sm->msg_id_base] \
3630 = (void *) vl_api_##f##_t_print;
3631 foreach_snat_plugin_api_msg;
3636 snat_api_init (vlib_main_t * vm, snat_main_t * sm)
3639 clib_error_t *error = 0;
3641 name = format (0, "snat_%08x%c", api_version, 0);
3643 /* Ask for a correctly-sized block of API message decode slots */
3645 vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE);
3647 error = snat_plugin_api_hookup (vm);
3649 /* Add our API messages to the global name_crc hash table */
3650 setup_message_id_table (sm, sm->api_main);
3652 plugin_custom_dump_configure (sm);
3660 * fd.io coding-style-patch-verification: ON
3663 * eval: (c-set-style "gnu")