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 <vlibapi/api.h>
26 #include <vlibmemory/api.h>
28 #include <nat/nat_msg_enum.h>
29 #include <vnet/fib/fib_table.h>
31 #define vl_api_nat44_lb_addr_port_t_endian vl_noop_handler
32 #define vl_api_nat44_add_del_lb_static_mapping_t_endian vl_noop_handler
33 #define vl_api_nat44_nat44_lb_static_mapping_details_t_endian vl_noop_handler
35 /* define message structures */
37 #include <nat/nat_all_api_h.h>
40 /* define generated endian-swappers */
42 #include <nat/nat_all_api_h.h>
45 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
47 #define REPLY_MSG_ID_BASE sm->msg_id_base
48 #include <vlibapi/api_helper_macros.h>
50 /* Get the API version number */
51 #define vl_api_version(n,v) static u32 api_version=(v);
52 #include <nat/nat_all_api_h.h>
55 /* Macro to finish up custom dump fns */
58 vl_print (handle, (char *)s); \
63 vl_api_snat_add_address_range_t_handler
64 (vl_api_snat_add_address_range_t * mp)
66 snat_main_t *sm = &snat_main;
67 vl_api_snat_add_address_range_reply_t *rmp;
68 ip4_address_t this_addr;
69 u32 start_host_order, end_host_order;
77 rv = VNET_API_ERROR_UNIMPLEMENTED;
81 if (sm->static_mapping_only)
83 rv = VNET_API_ERROR_FEATURE_DISABLED;
87 tmp = (u32 *) mp->first_ip_address;
88 start_host_order = clib_host_to_net_u32 (tmp[0]);
89 tmp = (u32 *) mp->last_ip_address;
90 end_host_order = clib_host_to_net_u32 (tmp[0]);
92 count = (end_host_order - start_host_order) + 1;
94 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
97 clib_warning ("%U - %U, %d addresses...",
98 format_ip4_address, mp->first_ip_address,
99 format_ip4_address, mp->last_ip_address, count);
101 memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
103 for (i = 0; i < count; i++)
106 snat_add_address (sm, &this_addr, vrf_id);
108 rv = snat_del_address (sm, this_addr, 0);
113 increment_v4_address (&this_addr);
117 REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
120 static void *vl_api_snat_add_address_range_t_print
121 (vl_api_snat_add_address_range_t * mp, void *handle)
125 s = format (0, "SCRIPT: snat_add_address_range ");
126 s = format (s, "%U ", format_ip4_address, mp->first_ip_address);
127 if (memcmp (mp->first_ip_address, mp->last_ip_address, 4))
129 s = format (s, " - %U ", format_ip4_address, mp->last_ip_address);
135 send_snat_address_details
136 (snat_address_t * a, unix_shared_memory_queue_t * q, u32 context)
138 vl_api_snat_address_details_t *rmp;
139 snat_main_t *sm = &snat_main;
141 rmp = vl_msg_api_alloc (sizeof (*rmp));
142 memset (rmp, 0, sizeof (*rmp));
143 rmp->_vl_msg_id = ntohs (VL_API_SNAT_ADDRESS_DETAILS + sm->msg_id_base);
145 clib_memcpy (rmp->ip_address, &(a->addr), 4);
146 if (a->fib_index != ~0)
148 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
149 rmp->vrf_id = ntohl (fib->ft_table_id);
153 rmp->context = context;
155 vl_msg_api_send_shmem (q, (u8 *) & rmp);
159 vl_api_snat_address_dump_t_handler (vl_api_snat_address_dump_t * mp)
161 unix_shared_memory_queue_t *q;
162 snat_main_t *sm = &snat_main;
165 q = vl_api_client_index_to_input_queue (mp->client_index);
170 vec_foreach (a, sm->addresses)
171 send_snat_address_details (a, q, mp->context);
175 static void *vl_api_snat_address_dump_t_print
176 (vl_api_snat_address_dump_t * mp, void *handle)
180 s = format (0, "SCRIPT: snat_address_dump ");
186 vl_api_snat_interface_add_del_feature_t_handler
187 (vl_api_snat_interface_add_del_feature_t * mp)
189 snat_main_t *sm = &snat_main;
190 vl_api_snat_interface_add_del_feature_reply_t *rmp;
191 u8 is_del = mp->is_add == 0;
192 u32 sw_if_index = ntohl (mp->sw_if_index);
195 VALIDATE_SW_IF_INDEX (mp);
197 rv = snat_interface_add_del (sw_if_index, mp->is_inside, is_del);
199 BAD_SW_IF_INDEX_LABEL;
201 REPLY_MACRO (VL_API_SNAT_INTERFACE_ADD_DEL_FEATURE_REPLY);
204 static void *vl_api_snat_interface_add_del_feature_t_print
205 (vl_api_snat_interface_add_del_feature_t * mp, void *handle)
209 s = format (0, "SCRIPT: snat_interface_add_del_feature ");
210 s = format (s, "sw_if_index %d %s %s",
211 clib_host_to_net_u32 (mp->sw_if_index),
212 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
218 send_snat_interface_details
219 (snat_interface_t * i, unix_shared_memory_queue_t * q, u32 context)
221 vl_api_snat_interface_details_t *rmp;
222 snat_main_t *sm = &snat_main;
224 rmp = vl_msg_api_alloc (sizeof (*rmp));
225 memset (rmp, 0, sizeof (*rmp));
226 rmp->_vl_msg_id = ntohs (VL_API_SNAT_INTERFACE_DETAILS + sm->msg_id_base);
227 rmp->sw_if_index = ntohl (i->sw_if_index);
228 rmp->is_inside = nat_interface_is_inside (i);
229 rmp->context = context;
231 vl_msg_api_send_shmem (q, (u8 *) & rmp);
235 vl_api_snat_interface_dump_t_handler (vl_api_snat_interface_dump_t * mp)
237 unix_shared_memory_queue_t *q;
238 snat_main_t *sm = &snat_main;
241 q = vl_api_client_index_to_input_queue (mp->client_index);
246 pool_foreach (i, sm->interfaces,
248 send_snat_interface_details(i, q, mp->context);
253 static void *vl_api_snat_interface_dump_t_print
254 (vl_api_snat_interface_dump_t * mp, void *handle)
258 s = format (0, "SCRIPT: snat_interface_dump ");
264 vl_api_snat_interface_add_del_output_feature_t_handler
265 (vl_api_snat_interface_add_del_output_feature_t * mp)
267 snat_main_t *sm = &snat_main;
268 vl_api_snat_interface_add_del_output_feature_reply_t *rmp;
269 u8 is_del = mp->is_add == 0;
270 u32 sw_if_index = ntohl (mp->sw_if_index);
273 VALIDATE_SW_IF_INDEX (mp);
275 rv = snat_interface_add_del_output_feature (sw_if_index, mp->is_inside,
278 BAD_SW_IF_INDEX_LABEL;
280 REPLY_MACRO (VL_API_SNAT_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY);
283 static void *vl_api_snat_interface_add_del_output_feature_t_print
284 (vl_api_snat_interface_add_del_output_feature_t * mp, void *handle)
288 s = format (0, "SCRIPT: snat_interface_add_del_output_feature ");
289 s = format (s, "sw_if_index %d %s %s",
290 clib_host_to_net_u32 (mp->sw_if_index),
291 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
297 send_snat_interface_output_feature_details (snat_interface_t * i,
298 unix_shared_memory_queue_t * q,
301 vl_api_snat_interface_output_feature_details_t *rmp;
302 snat_main_t *sm = &snat_main;
304 rmp = vl_msg_api_alloc (sizeof (*rmp));
305 memset (rmp, 0, sizeof (*rmp));
307 ntohs (VL_API_SNAT_INTERFACE_OUTPUT_FEATURE_DETAILS + sm->msg_id_base);
308 rmp->sw_if_index = ntohl (i->sw_if_index);
309 rmp->context = context;
310 rmp->is_inside = nat_interface_is_inside (i);
312 vl_msg_api_send_shmem (q, (u8 *) & rmp);
316 vl_api_snat_interface_output_feature_dump_t_handler
317 (vl_api_snat_interface_output_feature_dump_t * mp)
319 unix_shared_memory_queue_t *q;
320 snat_main_t *sm = &snat_main;
323 q = vl_api_client_index_to_input_queue (mp->client_index);
328 pool_foreach (i, sm->output_feature_interfaces,
330 send_snat_interface_output_feature_details(i, q, mp->context);
335 static void *vl_api_snat_interface_output_feature_dump_t_print
336 (vl_api_snat_interface_output_feature_dump_t * mp, void *handle)
340 s = format (0, "SCRIPT: snat_interface_output_feature_dump ");
346 vl_api_snat_add_static_mapping_t_handler
347 (vl_api_snat_add_static_mapping_t * mp)
349 snat_main_t *sm = &snat_main;
350 vl_api_snat_add_static_mapping_reply_t *rmp;
351 ip4_address_t local_addr, external_addr;
352 u16 local_port = 0, external_port = 0;
353 u32 vrf_id, external_sw_if_index;
355 snat_protocol_t proto;
359 rv = VNET_API_ERROR_UNIMPLEMENTED;
363 memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
364 memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
365 if (mp->addr_only == 0)
367 local_port = clib_net_to_host_u16 (mp->local_port);
368 external_port = clib_net_to_host_u16 (mp->external_port);
370 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
371 external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
372 proto = ip_proto_to_snat_proto (mp->protocol);
374 rv = snat_add_static_mapping (local_addr, external_addr, local_port,
375 external_port, vrf_id, mp->addr_only,
376 external_sw_if_index, proto, mp->is_add);
379 REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
382 static void *vl_api_snat_add_static_mapping_t_print
383 (vl_api_snat_add_static_mapping_t * mp, void *handle)
387 s = format (0, "SCRIPT: snat_add_static_mapping ");
388 s = format (s, "protocol %d local_addr %U external_addr %U ",
390 format_ip4_address, mp->local_ip_address,
391 format_ip4_address, mp->external_ip_address);
393 if (mp->addr_only == 0)
394 s = format (s, "local_port %d external_port %d ",
395 clib_net_to_host_u16 (mp->local_port),
396 clib_net_to_host_u16 (mp->external_port));
398 if (mp->vrf_id != ~0)
399 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
401 if (mp->external_sw_if_index != ~0)
402 s = format (s, "external_sw_if_index %d",
403 clib_net_to_host_u32 (mp->external_sw_if_index));
408 send_snat_static_mapping_details
409 (snat_static_mapping_t * m, unix_shared_memory_queue_t * q, u32 context)
411 vl_api_snat_static_mapping_details_t *rmp;
412 snat_main_t *sm = &snat_main;
414 rmp = vl_msg_api_alloc (sizeof (*rmp));
415 memset (rmp, 0, sizeof (*rmp));
417 ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS + sm->msg_id_base);
419 rmp->addr_only = m->addr_only;
420 clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
421 clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
422 rmp->local_port = htons (m->local_port);
423 rmp->external_port = htons (m->external_port);
424 rmp->external_sw_if_index = ~0;
425 rmp->vrf_id = htonl (m->vrf_id);
426 rmp->protocol = snat_proto_to_ip_proto (m->proto);
427 rmp->context = context;
429 vl_msg_api_send_shmem (q, (u8 *) & rmp);
433 send_snat_static_map_resolve_details
434 (snat_static_map_resolve_t * m, unix_shared_memory_queue_t * q, u32 context)
436 vl_api_snat_static_mapping_details_t *rmp;
437 snat_main_t *sm = &snat_main;
439 rmp = vl_msg_api_alloc (sizeof (*rmp));
440 memset (rmp, 0, sizeof (*rmp));
442 ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS + sm->msg_id_base);
444 rmp->addr_only = m->addr_only;
445 clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
446 rmp->local_port = htons (m->l_port);
447 rmp->external_port = htons (m->e_port);
448 rmp->external_sw_if_index = htonl (m->sw_if_index);
449 rmp->vrf_id = htonl (m->vrf_id);
450 rmp->protocol = snat_proto_to_ip_proto (m->proto);
451 rmp->context = context;
453 vl_msg_api_send_shmem (q, (u8 *) & rmp);
457 vl_api_snat_static_mapping_dump_t_handler
458 (vl_api_snat_static_mapping_dump_t * mp)
460 unix_shared_memory_queue_t *q;
461 snat_main_t *sm = &snat_main;
462 snat_static_mapping_t *m;
463 snat_static_map_resolve_t *rp;
466 q = vl_api_client_index_to_input_queue (mp->client_index);
471 pool_foreach (m, sm->static_mappings,
473 if (!vec_len(m->locals))
474 send_snat_static_mapping_details (m, q, mp->context);
478 for (j = 0; j < vec_len (sm->to_resolve); j++)
480 rp = sm->to_resolve + j;
481 send_snat_static_map_resolve_details (rp, q, mp->context);
485 static void *vl_api_snat_static_mapping_dump_t_print
486 (vl_api_snat_static_mapping_dump_t * mp, void *handle)
490 s = format (0, "SCRIPT: snat_static_mapping_dump ");
496 vl_api_snat_control_ping_t_handler (vl_api_snat_control_ping_t * mp)
498 vl_api_snat_control_ping_reply_t *rmp;
499 snat_main_t *sm = &snat_main;
503 REPLY_MACRO2 (VL_API_SNAT_CONTROL_PING_REPLY,
505 rmp->vpe_pid = ntohl (getpid ());
510 static void *vl_api_snat_control_ping_t_print
511 (vl_api_snat_control_ping_t * mp, void *handle)
515 s = format (0, "SCRIPT: snat_control_ping ");
521 vl_api_snat_show_config_t_handler (vl_api_snat_show_config_t * mp)
523 vl_api_snat_show_config_reply_t *rmp;
524 snat_main_t *sm = &snat_main;
528 REPLY_MACRO2 (VL_API_SNAT_SHOW_CONFIG_REPLY,
530 rmp->translation_buckets = htonl (sm->translation_buckets);
531 rmp->translation_memory_size = htonl (sm->translation_memory_size);
532 rmp->user_buckets = htonl (sm->user_buckets);
533 rmp->user_memory_size = htonl (sm->user_memory_size);
534 rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
535 rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
536 rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
537 rmp->static_mapping_only = sm->static_mapping_only;
538 rmp->static_mapping_connection_tracking =
539 sm->static_mapping_connection_tracking;
540 rmp->deterministic = sm->deterministic;
545 static void *vl_api_snat_show_config_t_print
546 (vl_api_snat_show_config_t * mp, void *handle)
550 s = format (0, "SCRIPT: snat_show_config ");
556 vl_api_snat_set_workers_t_handler (vl_api_snat_set_workers_t * mp)
558 snat_main_t *sm = &snat_main;
559 vl_api_snat_set_workers_reply_t *rmp;
562 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
564 if (sm->num_workers < 2)
566 rv = VNET_API_ERROR_FEATURE_DISABLED;
570 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
571 rv = snat_set_workers (bitmap);
572 clib_bitmap_free (bitmap);
575 REPLY_MACRO (VL_API_SNAT_SET_WORKERS_REPLY);
578 static void *vl_api_snat_set_workers_t_print
579 (vl_api_snat_set_workers_t * mp, void *handle)
585 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
587 s = format (0, "SCRIPT: snat_set_workers ");
588 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
590 clib_bitmap_foreach (i, bitmap,
593 s = format (s, "%d", i);
595 s = format (s, ",%d", i);
599 clib_bitmap_free (bitmap);
604 send_snat_worker_details
605 (u32 worker_index, unix_shared_memory_queue_t * q, u32 context)
607 vl_api_snat_worker_details_t *rmp;
608 snat_main_t *sm = &snat_main;
609 vlib_worker_thread_t *w =
610 vlib_worker_threads + worker_index + sm->first_worker_index;
612 rmp = vl_msg_api_alloc (sizeof (*rmp));
613 memset (rmp, 0, sizeof (*rmp));
614 rmp->_vl_msg_id = ntohs (VL_API_SNAT_WORKER_DETAILS + sm->msg_id_base);
615 rmp->context = context;
616 rmp->worker_index = htonl (worker_index);
617 rmp->lcore_id = htonl (w->lcore_id);
618 strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
620 vl_msg_api_send_shmem (q, (u8 *) & rmp);
624 vl_api_snat_worker_dump_t_handler (vl_api_snat_worker_dump_t * mp)
626 unix_shared_memory_queue_t *q;
627 snat_main_t *sm = &snat_main;
630 q = vl_api_client_index_to_input_queue (mp->client_index);
635 vec_foreach (worker_index, sm->workers)
636 send_snat_worker_details(*worker_index, q, mp->context);
640 static void *vl_api_snat_worker_dump_t_print
641 (vl_api_snat_worker_dump_t * mp, void *handle)
645 s = format (0, "SCRIPT: snat_worker_dump ");
651 vl_api_snat_add_del_interface_addr_t_handler
652 (vl_api_snat_add_del_interface_addr_t * mp)
654 snat_main_t *sm = &snat_main;
655 vl_api_snat_add_del_interface_addr_reply_t *rmp;
656 u8 is_del = mp->is_add == 0;
657 u32 sw_if_index = ntohl (mp->sw_if_index);
660 VALIDATE_SW_IF_INDEX (mp);
662 rv = snat_add_interface_address (sm, sw_if_index, is_del);
664 BAD_SW_IF_INDEX_LABEL;
666 REPLY_MACRO (VL_API_SNAT_ADD_DEL_INTERFACE_ADDR_REPLY);
669 static void *vl_api_snat_add_del_interface_addr_t_print
670 (vl_api_snat_add_del_interface_addr_t * mp, void *handle)
674 s = format (0, "SCRIPT: snat_add_del_interface_addr ");
675 s = format (s, "sw_if_index %d %s",
676 clib_host_to_net_u32 (mp->sw_if_index),
677 mp->is_add ? "" : "del");
683 send_snat_interface_addr_details
684 (u32 sw_if_index, unix_shared_memory_queue_t * q, u32 context)
686 vl_api_snat_interface_addr_details_t *rmp;
687 snat_main_t *sm = &snat_main;
689 rmp = vl_msg_api_alloc (sizeof (*rmp));
690 memset (rmp, 0, sizeof (*rmp));
692 ntohs (VL_API_SNAT_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
693 rmp->sw_if_index = ntohl (sw_if_index);
694 rmp->context = context;
696 vl_msg_api_send_shmem (q, (u8 *) & rmp);
700 vl_api_snat_interface_addr_dump_t_handler
701 (vl_api_snat_interface_addr_dump_t * mp)
703 unix_shared_memory_queue_t *q;
704 snat_main_t *sm = &snat_main;
707 q = vl_api_client_index_to_input_queue (mp->client_index);
712 vec_foreach (i, sm->auto_add_sw_if_indices)
713 send_snat_interface_addr_details(*i, q, mp->context);
717 static void *vl_api_snat_interface_addr_dump_t_print
718 (vl_api_snat_interface_addr_dump_t * mp, void *handle)
722 s = format (0, "SCRIPT: snat_interface_addr_dump ");
728 vl_api_snat_ipfix_enable_disable_t_handler
729 (vl_api_snat_ipfix_enable_disable_t * mp)
731 snat_main_t *sm = &snat_main;
732 vl_api_snat_ipfix_enable_disable_reply_t *rmp;
735 rv = snat_ipfix_logging_enable_disable (mp->enable,
741 REPLY_MACRO (VL_API_SNAT_IPFIX_ENABLE_DISABLE_REPLY);
744 static void *vl_api_snat_ipfix_enable_disable_t_print
745 (vl_api_snat_ipfix_enable_disable_t * mp, void *handle)
749 s = format (0, "SCRIPT: snat_ipfix_enable_disable ");
751 s = format (s, "domain %d ", clib_net_to_host_u32 (mp->domain_id));
753 s = format (s, "src_port %d ", clib_net_to_host_u16 (mp->src_port));
755 s = format (s, "disable ");
761 send_snat_user_details
762 (snat_user_t * u, unix_shared_memory_queue_t * q, u32 context)
764 vl_api_snat_user_details_t *rmp;
765 snat_main_t *sm = &snat_main;
766 fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
768 rmp = vl_msg_api_alloc (sizeof (*rmp));
769 memset (rmp, 0, sizeof (*rmp));
770 rmp->_vl_msg_id = ntohs (VL_API_SNAT_USER_DETAILS + sm->msg_id_base);
772 rmp->vrf_id = ntohl (fib->ft_table_id);
775 clib_memcpy (rmp->ip_address, &(u->addr), 4);
776 rmp->nsessions = ntohl (u->nsessions);
777 rmp->nstaticsessions = ntohl (u->nstaticsessions);
778 rmp->context = context;
780 vl_msg_api_send_shmem (q, (u8 *) & rmp);
784 vl_api_snat_user_dump_t_handler (vl_api_snat_user_dump_t * mp)
786 unix_shared_memory_queue_t *q;
787 snat_main_t *sm = &snat_main;
788 snat_main_per_thread_data_t *tsm;
791 q = vl_api_client_index_to_input_queue (mp->client_index);
796 vec_foreach (tsm, sm->per_thread_data)
797 vec_foreach (u, tsm->users)
798 send_snat_user_details (u, q, mp->context);
802 static void *vl_api_snat_user_dump_t_print
803 (vl_api_snat_user_dump_t * mp, void *handle)
807 s = format (0, "SCRIPT: snat_user_dump ");
813 send_snat_user_session_details
814 (snat_session_t * s, unix_shared_memory_queue_t * q, u32 context)
816 vl_api_snat_user_session_details_t *rmp;
817 snat_main_t *sm = &snat_main;
819 rmp = vl_msg_api_alloc (sizeof (*rmp));
820 memset (rmp, 0, sizeof (*rmp));
822 ntohs (VL_API_SNAT_USER_SESSION_DETAILS + sm->msg_id_base);
824 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
825 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
826 rmp->is_static = s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING ? 1 : 0;
827 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
828 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
829 rmp->total_pkts = ntohl (s->total_pkts);
830 rmp->context = context;
831 if (snat_is_unk_proto_session (s))
833 rmp->outside_port = 0;
834 rmp->inside_port = 0;
835 rmp->protocol = ntohs (s->in2out.port);
839 rmp->outside_port = s->out2in.port;
840 rmp->inside_port = s->in2out.port;
841 rmp->protocol = ntohs (snat_proto_to_ip_proto (s->in2out.protocol));
844 vl_msg_api_send_shmem (q, (u8 *) & rmp);
848 vl_api_snat_user_session_dump_t_handler
849 (vl_api_snat_user_session_dump_t * mp)
851 unix_shared_memory_queue_t *q;
852 snat_main_t *sm = &snat_main;
853 snat_main_per_thread_data_t *tsm;
855 clib_bihash_kv_8_8_t key, value;
856 snat_user_key_t ukey;
858 u32 session_index, head_index, elt_index;
859 dlist_elt_t *head, *elt;
862 q = vl_api_client_index_to_input_queue (mp->client_index);
868 clib_memcpy (&ukey.addr, mp->ip_address, 4);
869 ip.src_address.as_u32 = ukey.addr.as_u32;
870 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
871 key.key = ukey.as_u64;
874 vec_elt_at_index (sm->per_thread_data,
875 sm->worker_in2out_cb (&ip, ukey.fib_index));
877 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
878 if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
880 u = pool_elt_at_index (tsm->users, value.value);
881 if (!u->nsessions && !u->nstaticsessions)
884 head_index = u->sessions_per_user_list_head_index;
885 head = pool_elt_at_index (tsm->list_pool, head_index);
886 elt_index = head->next;
887 elt = pool_elt_at_index (tsm->list_pool, elt_index);
888 session_index = elt->value;
889 while (session_index != ~0)
891 s = pool_elt_at_index (tsm->sessions, session_index);
893 send_snat_user_session_details (s, q, mp->context);
895 elt_index = elt->next;
896 elt = pool_elt_at_index (tsm->list_pool, elt_index);
897 session_index = elt->value;
901 static void *vl_api_snat_user_session_dump_t_print
902 (vl_api_snat_user_session_dump_t * mp, void *handle)
906 s = format (0, "SCRIPT: snat_user_session_dump ");
907 s = format (s, "ip_address %U vrf_id %d\n",
908 format_ip4_address, mp->ip_address,
909 clib_net_to_host_u32 (mp->vrf_id));
914 /******************************************************************/
915 /*** detrministic NAT/CGN (old, will be deprecated after 17.10) ***/
916 /******************************************************************/
919 vl_api_snat_add_det_map_t_handler (vl_api_snat_add_det_map_t * mp)
921 snat_main_t *sm = &snat_main;
922 vl_api_snat_add_det_map_reply_t *rmp;
924 ip4_address_t in_addr, out_addr;
926 clib_memcpy (&in_addr, mp->in_addr, 4);
927 clib_memcpy (&out_addr, mp->out_addr, 4);
928 rv = snat_det_add_map (sm, &in_addr, mp->in_plen, &out_addr,
929 mp->out_plen, mp->is_add);
931 REPLY_MACRO (VL_API_SNAT_ADD_DET_MAP_REPLY);
934 static void *vl_api_snat_add_det_map_t_print
935 (vl_api_snat_add_det_map_t * mp, void *handle)
939 s = format (0, "SCRIPT: snat_add_det_map ");
940 s = format (s, "inside address %U/%d outside address %U/%d\n",
941 format_ip4_address, mp->in_addr, mp->in_plen,
942 format_ip4_address, mp->out_addr, mp->out_plen);
948 vl_api_snat_det_forward_t_handler (vl_api_snat_det_forward_t * mp)
950 snat_main_t *sm = &snat_main;
951 vl_api_snat_det_forward_reply_t *rmp;
953 u16 lo_port = 0, hi_port = 0;
955 ip4_address_t in_addr, out_addr;
958 clib_memcpy (&in_addr, mp->in_addr, 4);
959 dm = snat_det_map_by_user (sm, &in_addr);
962 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
966 snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
967 hi_port = lo_port + dm->ports_per_host - 1;
971 REPLY_MACRO2 (VL_API_SNAT_DET_FORWARD_REPLY,
973 rmp->out_port_lo = ntohs (lo_port);
974 rmp->out_port_hi = ntohs (hi_port);
976 memset (rmp->out_addr, 0, 16);
977 clib_memcpy (rmp->out_addr, &out_addr, 4);
982 static void *vl_api_snat_det_forward_t_print
983 (vl_api_snat_det_forward_t * mp, void *handle)
987 s = format (0, "SCRIPT: smat_det_forward_t");
988 s = format (s, "inside ip address %U\n", format_ip4_address, mp->in_addr);
994 vl_api_snat_det_reverse_t_handler (vl_api_snat_det_reverse_t * mp)
996 snat_main_t *sm = &snat_main;
997 vl_api_snat_det_reverse_reply_t *rmp;
999 ip4_address_t out_addr, in_addr;
1003 clib_memcpy (&out_addr, mp->out_addr, 4);
1004 dm = snat_det_map_by_out (sm, &out_addr);
1007 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1011 snat_det_reverse (dm, &out_addr, htons (mp->out_port), &in_addr);
1015 REPLY_MACRO2 (VL_API_SNAT_DET_REVERSE_REPLY,
1018 memset (rmp->in_addr, 0, 16);
1019 clib_memcpy (rmp->in_addr, &in_addr, 4);
1024 static void *vl_api_snat_det_reverse_t_print
1025 (vl_api_snat_det_reverse_t * mp, void *handle)
1029 s = format (0, "SCRIPT: smat_det_reverse_t");
1030 s = format (s, "outside ip address %U outside port %d",
1031 format_ip4_address, mp->out_addr, ntohs (mp->out_port));
1037 sent_snat_det_map_details
1038 (snat_det_map_t * m, unix_shared_memory_queue_t * q, u32 context)
1040 vl_api_snat_det_map_details_t *rmp;
1041 snat_main_t *sm = &snat_main;
1043 rmp = vl_msg_api_alloc (sizeof (*rmp));
1044 memset (rmp, 0, sizeof (*rmp));
1045 rmp->_vl_msg_id = ntohs (VL_API_SNAT_DET_MAP_DETAILS + sm->msg_id_base);
1047 clib_memcpy (rmp->in_addr, &m->in_addr, 4);
1048 rmp->in_plen = m->in_plen;
1049 clib_memcpy (rmp->out_addr, &m->out_addr, 4);
1050 rmp->out_plen = m->out_plen;
1051 rmp->sharing_ratio = htonl (m->sharing_ratio);
1052 rmp->ports_per_host = htons (m->ports_per_host);
1053 rmp->ses_num = htonl (m->ses_num);
1054 rmp->context = context;
1056 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1060 vl_api_snat_det_map_dump_t_handler (vl_api_snat_det_map_dump_t * mp)
1062 unix_shared_memory_queue_t *q;
1063 snat_main_t *sm = &snat_main;
1066 q = vl_api_client_index_to_input_queue (mp->client_index);
1071 vec_foreach(m, sm->det_maps)
1072 sent_snat_det_map_details(m, q, mp->context);
1076 static void *vl_api_snat_det_map_dump_t_print
1077 (vl_api_snat_det_map_dump_t * mp, void *handle)
1081 s = format (0, "SCRIPT: snat_det_map_dump ");
1087 vl_api_snat_det_set_timeouts_t_handler (vl_api_snat_det_set_timeouts_t * mp)
1089 snat_main_t *sm = &snat_main;
1090 vl_api_snat_det_set_timeouts_reply_t *rmp;
1093 sm->udp_timeout = ntohl (mp->udp);
1094 sm->tcp_established_timeout = ntohl (mp->tcp_established);
1095 sm->tcp_transitory_timeout = ntohl (mp->tcp_transitory);
1096 sm->icmp_timeout = ntohl (mp->icmp);
1098 REPLY_MACRO (VL_API_SNAT_DET_SET_TIMEOUTS_REPLY);
1101 static void *vl_api_snat_det_set_timeouts_t_print
1102 (vl_api_snat_det_set_timeouts_t * mp, void *handle)
1106 s = format (0, "SCRIPT: snat_det_set_timeouts ");
1107 s = format (s, "udp %d tcp_established %d tcp_transitory %d icmp %d\n",
1109 ntohl (mp->tcp_established),
1110 ntohl (mp->tcp_transitory), ntohl (mp->icmp));
1116 vl_api_snat_det_get_timeouts_t_handler (vl_api_snat_det_get_timeouts_t * mp)
1118 snat_main_t *sm = &snat_main;
1119 vl_api_snat_det_get_timeouts_reply_t *rmp;
1123 REPLY_MACRO2 (VL_API_SNAT_DET_GET_TIMEOUTS_REPLY,
1125 rmp->udp = htonl (sm->udp_timeout);
1126 rmp->tcp_established = htonl (sm->tcp_established_timeout);
1127 rmp->tcp_transitory = htonl (sm->tcp_transitory_timeout);
1128 rmp->icmp = htonl (sm->icmp_timeout);
1133 static void *vl_api_snat_det_get_timeouts_t_print
1134 (vl_api_snat_det_get_timeouts_t * mp, void *handle)
1138 s = format (0, "SCRIPT: snat_det_get_timeouts");
1144 vl_api_snat_det_close_session_out_t_handler
1145 (vl_api_snat_det_close_session_out_t * mp)
1147 snat_main_t *sm = &snat_main;
1148 vl_api_snat_det_close_session_out_reply_t *rmp;
1149 ip4_address_t out_addr, ext_addr, in_addr;
1150 snat_det_out_key_t key;
1152 snat_det_session_t *ses;
1155 clib_memcpy (&out_addr, mp->out_addr, 4);
1156 clib_memcpy (&ext_addr, mp->ext_addr, 4);
1158 dm = snat_det_map_by_out (sm, &out_addr);
1161 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1164 snat_det_reverse (dm, &ext_addr, ntohs (mp->out_port), &in_addr);
1165 key.ext_host_addr = ext_addr;
1166 key.ext_host_port = mp->ext_port;
1167 key.out_port = mp->out_port;
1168 ses = snat_det_get_ses_by_out (dm, &in_addr, key.as_u64);
1171 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1174 snat_det_ses_close (dm, ses);
1177 REPLY_MACRO (VL_API_SNAT_DET_CLOSE_SESSION_OUT_REPLY);
1180 static void *vl_api_snat_det_close_session_out_t_print
1181 (vl_api_snat_det_close_session_out_t * mp, void *handle)
1185 s = format (0, "SCRIPT: snat_det_close_session_out ");
1186 s = format (s, "out_addr %U out_port %d "
1187 "ext_addr %U ext_port %d\n",
1188 format_ip4_address, mp->out_addr, ntohs (mp->out_port),
1189 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
1195 vl_api_snat_det_close_session_in_t_handler
1196 (vl_api_snat_det_close_session_in_t * mp)
1198 snat_main_t *sm = &snat_main;
1199 vl_api_snat_det_close_session_in_reply_t *rmp;
1200 ip4_address_t in_addr, ext_addr;
1201 snat_det_out_key_t key;
1203 snat_det_session_t *ses;
1206 clib_memcpy (&in_addr, mp->in_addr, 4);
1207 clib_memcpy (&ext_addr, mp->ext_addr, 4);
1209 dm = snat_det_map_by_user (sm, &in_addr);
1212 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1215 key.ext_host_addr = ext_addr;
1216 key.ext_host_port = mp->ext_port;
1217 ses = snat_det_find_ses_by_in (dm, &in_addr, mp->in_port, key);
1220 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1223 snat_det_ses_close (dm, ses);
1226 REPLY_MACRO (VL_API_SNAT_DET_CLOSE_SESSION_OUT_REPLY);
1229 static void *vl_api_snat_det_close_session_in_t_print
1230 (vl_api_snat_det_close_session_in_t * mp, void *handle)
1233 s = format (0, "SCRIPT: snat_det_close_session_in ");
1234 s = format (s, "in_addr %U in_port %d "
1235 "ext_addr %U ext_port %d\n",
1236 format_ip4_address, mp->in_addr, ntohs (mp->in_port),
1237 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
1243 send_snat_det_session_details
1244 (snat_det_session_t * s, unix_shared_memory_queue_t * q, u32 context)
1246 vl_api_snat_det_session_details_t *rmp;
1247 snat_main_t *sm = &snat_main;
1249 rmp = vl_msg_api_alloc (sizeof (*rmp));
1250 memset (rmp, 0, sizeof (*rmp));
1251 rmp->_vl_msg_id = ntohs (VL_API_SNAT_DET_SESSION_DETAILS + sm->msg_id_base);
1253 rmp->in_port = s->in_port;
1254 clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
1255 rmp->ext_port = s->out.ext_host_port;
1256 rmp->out_port = s->out.out_port;
1257 rmp->state = s->state;
1258 rmp->expire = ntohl (s->expire);
1259 rmp->context = context;
1261 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1265 vl_api_snat_det_session_dump_t_handler (vl_api_snat_det_session_dump_t * mp)
1267 unix_shared_memory_queue_t *q;
1268 snat_main_t *sm = &snat_main;
1269 ip4_address_t user_addr;
1271 snat_det_session_t *s, empty_ses;
1274 q = vl_api_client_index_to_input_queue (mp->client_index);
1280 memset (&empty_ses, 0, sizeof (empty_ses));
1281 clib_memcpy (&user_addr, mp->user_addr, 4);
1282 dm = snat_det_map_by_user (sm, &user_addr);
1286 s = dm->sessions + snat_det_user_ses_offset (&user_addr, dm->in_plen);
1287 for (i = 0; i < SNAT_DET_SES_PER_USER; i++)
1290 send_snat_det_session_details (s, q, mp->context);
1295 static void *vl_api_snat_det_session_dump_t_print
1296 (vl_api_snat_det_session_dump_t * mp, void *handle)
1300 s = format (0, "SCRIPT: snat_det_session_dump ");
1301 s = format (s, "user_addr %U\n", format_ip4_address, mp->user_addr);
1306 /******************************/
1307 /*** Common NAT plugin APIs ***/
1308 /******************************/
1311 vl_api_nat_control_ping_t_handler (vl_api_nat_control_ping_t * mp)
1313 vl_api_nat_control_ping_reply_t *rmp;
1314 snat_main_t *sm = &snat_main;
1318 REPLY_MACRO2 (VL_API_NAT_CONTROL_PING_REPLY,
1320 rmp->vpe_pid = ntohl (getpid ());
1326 vl_api_nat_control_ping_t_print (vl_api_nat_control_ping_t * mp, void *handle)
1330 s = format (0, "SCRIPT: nat_control_ping ");
1336 vl_api_nat_show_config_t_handler (vl_api_nat_show_config_t * mp)
1338 vl_api_nat_show_config_reply_t *rmp;
1339 snat_main_t *sm = &snat_main;
1343 REPLY_MACRO2 (VL_API_NAT_SHOW_CONFIG_REPLY,
1345 rmp->translation_buckets = htonl (sm->translation_buckets);
1346 rmp->translation_memory_size = htonl (sm->translation_memory_size);
1347 rmp->user_buckets = htonl (sm->user_buckets);
1348 rmp->user_memory_size = htonl (sm->user_memory_size);
1349 rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
1350 rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
1351 rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
1352 rmp->static_mapping_only = sm->static_mapping_only;
1353 rmp->static_mapping_connection_tracking =
1354 sm->static_mapping_connection_tracking;
1355 rmp->deterministic = sm->deterministic;
1361 vl_api_nat_show_config_t_print (vl_api_nat_show_config_t * mp, void *handle)
1365 s = format (0, "SCRIPT: nat_show_config ");
1371 vl_api_nat_set_workers_t_handler (vl_api_nat_set_workers_t * mp)
1373 snat_main_t *sm = &snat_main;
1374 vl_api_snat_set_workers_reply_t *rmp;
1377 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
1379 if (sm->num_workers < 2)
1381 rv = VNET_API_ERROR_FEATURE_DISABLED;
1385 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
1386 rv = snat_set_workers (bitmap);
1387 clib_bitmap_free (bitmap);
1390 REPLY_MACRO (VL_API_NAT_SET_WORKERS_REPLY);
1394 vl_api_nat_set_workers_t_print (vl_api_nat_set_workers_t * mp, void *handle)
1400 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
1402 s = format (0, "SCRIPT: nat_set_workers ");
1403 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
1405 clib_bitmap_foreach (i, bitmap,
1408 s = format (s, "%d", i);
1410 s = format (s, ",%d", i);
1414 clib_bitmap_free (bitmap);
1419 send_nat_worker_details (u32 worker_index, unix_shared_memory_queue_t * q,
1422 vl_api_nat_worker_details_t *rmp;
1423 snat_main_t *sm = &snat_main;
1424 vlib_worker_thread_t *w =
1425 vlib_worker_threads + worker_index + sm->first_worker_index;
1427 rmp = vl_msg_api_alloc (sizeof (*rmp));
1428 memset (rmp, 0, sizeof (*rmp));
1429 rmp->_vl_msg_id = ntohs (VL_API_NAT_WORKER_DETAILS + sm->msg_id_base);
1430 rmp->context = context;
1431 rmp->worker_index = htonl (worker_index);
1432 rmp->lcore_id = htonl (w->lcore_id);
1433 strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
1435 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1439 vl_api_nat_worker_dump_t_handler (vl_api_nat_worker_dump_t * mp)
1441 unix_shared_memory_queue_t *q;
1442 snat_main_t *sm = &snat_main;
1445 q = vl_api_client_index_to_input_queue (mp->client_index);
1450 vec_foreach (worker_index, sm->workers)
1451 send_nat_worker_details(*worker_index, q, mp->context);
1456 vl_api_nat_worker_dump_t_print (vl_api_nat_worker_dump_t * mp, void *handle)
1460 s = format (0, "SCRIPT: nat_worker_dump ");
1466 vl_api_nat_ipfix_enable_disable_t_handler (vl_api_nat_ipfix_enable_disable_t *
1469 snat_main_t *sm = &snat_main;
1470 vl_api_nat_ipfix_enable_disable_reply_t *rmp;
1473 rv = snat_ipfix_logging_enable_disable (mp->enable,
1474 clib_host_to_net_u32
1476 clib_host_to_net_u16
1479 REPLY_MACRO (VL_API_NAT_IPFIX_ENABLE_DISABLE_REPLY);
1483 vl_api_nat_ipfix_enable_disable_t_print (vl_api_nat_ipfix_enable_disable_t *
1488 s = format (0, "SCRIPT: nat_ipfix_enable_disable ");
1490 s = format (s, "domain %d ", clib_net_to_host_u32 (mp->domain_id));
1492 s = format (s, "src_port %d ", clib_net_to_host_u16 (mp->src_port));
1494 s = format (s, "disable ");
1503 vl_api_nat44_add_del_address_range_t_handler
1504 (vl_api_nat44_add_del_address_range_t * mp)
1506 snat_main_t *sm = &snat_main;
1507 vl_api_nat44_add_del_address_range_reply_t *rmp;
1508 ip4_address_t this_addr;
1509 u32 start_host_order, end_host_order;
1515 if (sm->static_mapping_only)
1517 rv = VNET_API_ERROR_FEATURE_DISABLED;
1521 tmp = (u32 *) mp->first_ip_address;
1522 start_host_order = clib_host_to_net_u32 (tmp[0]);
1523 tmp = (u32 *) mp->last_ip_address;
1524 end_host_order = clib_host_to_net_u32 (tmp[0]);
1526 count = (end_host_order - start_host_order) + 1;
1528 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
1531 clib_warning ("%U - %U, %d addresses...",
1532 format_ip4_address, mp->first_ip_address,
1533 format_ip4_address, mp->last_ip_address, count);
1535 memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
1537 for (i = 0; i < count; i++)
1540 snat_add_address (sm, &this_addr, vrf_id);
1542 rv = snat_del_address (sm, this_addr, 0);
1547 increment_v4_address (&this_addr);
1551 REPLY_MACRO (VL_API_NAT44_ADD_DEL_ADDRESS_RANGE_REPLY);
1554 static void *vl_api_nat44_add_del_address_range_t_print
1555 (vl_api_nat44_add_del_address_range_t * mp, void *handle)
1559 s = format (0, "SCRIPT: nat44_add_address_range ");
1560 s = format (s, "%U ", format_ip4_address, mp->first_ip_address);
1561 if (memcmp (mp->first_ip_address, mp->last_ip_address, 4))
1563 s = format (s, " - %U ", format_ip4_address, mp->last_ip_address);
1569 send_nat44_address_details (snat_address_t * a,
1570 unix_shared_memory_queue_t * q, u32 context)
1572 vl_api_nat44_address_details_t *rmp;
1573 snat_main_t *sm = &snat_main;
1575 rmp = vl_msg_api_alloc (sizeof (*rmp));
1576 memset (rmp, 0, sizeof (*rmp));
1577 rmp->_vl_msg_id = ntohs (VL_API_NAT44_ADDRESS_DETAILS + sm->msg_id_base);
1578 clib_memcpy (rmp->ip_address, &(a->addr), 4);
1579 if (a->fib_index != ~0)
1581 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
1582 rmp->vrf_id = ntohl (fib->ft_table_id);
1586 rmp->context = context;
1588 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1592 vl_api_nat44_address_dump_t_handler (vl_api_nat44_address_dump_t * mp)
1594 unix_shared_memory_queue_t *q;
1595 snat_main_t *sm = &snat_main;
1598 q = vl_api_client_index_to_input_queue (mp->client_index);
1603 vec_foreach (a, sm->addresses)
1604 send_nat44_address_details (a, q, mp->context);
1609 vl_api_nat44_address_dump_t_print (vl_api_nat44_address_dump_t * mp,
1614 s = format (0, "SCRIPT: nat44_address_dump ");
1620 vl_api_nat44_interface_add_del_feature_t_handler
1621 (vl_api_nat44_interface_add_del_feature_t * mp)
1623 snat_main_t *sm = &snat_main;
1624 vl_api_nat44_interface_add_del_feature_reply_t *rmp;
1625 u8 is_del = mp->is_add == 0;
1626 u32 sw_if_index = ntohl (mp->sw_if_index);
1629 VALIDATE_SW_IF_INDEX (mp);
1631 rv = snat_interface_add_del (sw_if_index, mp->is_inside, is_del);
1633 BAD_SW_IF_INDEX_LABEL;
1635 REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_FEATURE_REPLY);
1638 static void *vl_api_nat44_interface_add_del_feature_t_print
1639 (vl_api_nat44_interface_add_del_feature_t * mp, void *handle)
1643 s = format (0, "SCRIPT: nat44_interface_add_del_feature ");
1644 s = format (s, "sw_if_index %d %s %s",
1645 clib_host_to_net_u32 (mp->sw_if_index),
1646 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
1652 send_nat44_interface_details (snat_interface_t * i,
1653 unix_shared_memory_queue_t * q, u32 context)
1655 vl_api_nat44_interface_details_t *rmp;
1656 snat_main_t *sm = &snat_main;
1658 rmp = vl_msg_api_alloc (sizeof (*rmp));
1659 memset (rmp, 0, sizeof (*rmp));
1660 rmp->_vl_msg_id = ntohs (VL_API_NAT44_INTERFACE_DETAILS + sm->msg_id_base);
1661 rmp->sw_if_index = ntohl (i->sw_if_index);
1662 rmp->is_inside = (nat_interface_is_inside (i)
1663 && nat_interface_is_outside (i)) ? 2 :
1664 nat_interface_is_inside (i);
1665 rmp->context = context;
1667 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1671 vl_api_nat44_interface_dump_t_handler (vl_api_nat44_interface_dump_t * mp)
1673 unix_shared_memory_queue_t *q;
1674 snat_main_t *sm = &snat_main;
1675 snat_interface_t *i;
1677 q = vl_api_client_index_to_input_queue (mp->client_index);
1682 pool_foreach (i, sm->interfaces,
1684 send_nat44_interface_details(i, q, mp->context);
1690 vl_api_nat44_interface_dump_t_print (vl_api_nat44_interface_dump_t * mp,
1695 s = format (0, "SCRIPT: nat44_interface_dump ");
1701 vl_api_nat44_interface_add_del_output_feature_t_handler
1702 (vl_api_nat44_interface_add_del_output_feature_t * mp)
1704 snat_main_t *sm = &snat_main;
1705 vl_api_nat44_interface_add_del_output_feature_reply_t *rmp;
1706 u8 is_del = mp->is_add == 0;
1707 u32 sw_if_index = ntohl (mp->sw_if_index);
1710 VALIDATE_SW_IF_INDEX (mp);
1712 rv = snat_interface_add_del_output_feature (sw_if_index, mp->is_inside,
1715 BAD_SW_IF_INDEX_LABEL;
1717 REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY);
1720 static void *vl_api_nat44_interface_add_del_output_feature_t_print
1721 (vl_api_nat44_interface_add_del_output_feature_t * mp, void *handle)
1725 s = format (0, "SCRIPT: nat44_interface_add_del_output_feature ");
1726 s = format (s, "sw_if_index %d %s %s",
1727 clib_host_to_net_u32 (mp->sw_if_index),
1728 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
1734 send_nat44_interface_output_feature_details (snat_interface_t * i,
1735 unix_shared_memory_queue_t * q,
1738 vl_api_nat44_interface_output_feature_details_t *rmp;
1739 snat_main_t *sm = &snat_main;
1741 rmp = vl_msg_api_alloc (sizeof (*rmp));
1742 memset (rmp, 0, sizeof (*rmp));
1744 ntohs (VL_API_NAT44_INTERFACE_OUTPUT_FEATURE_DETAILS + sm->msg_id_base);
1745 rmp->sw_if_index = ntohl (i->sw_if_index);
1746 rmp->context = context;
1747 rmp->is_inside = nat_interface_is_inside (i);
1749 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1753 vl_api_nat44_interface_output_feature_dump_t_handler
1754 (vl_api_nat44_interface_output_feature_dump_t * mp)
1756 unix_shared_memory_queue_t *q;
1757 snat_main_t *sm = &snat_main;
1758 snat_interface_t *i;
1760 q = vl_api_client_index_to_input_queue (mp->client_index);
1765 pool_foreach (i, sm->output_feature_interfaces,
1767 send_nat44_interface_output_feature_details(i, q, mp->context);
1772 static void *vl_api_nat44_interface_output_feature_dump_t_print
1773 (vl_api_nat44_interface_output_feature_dump_t * mp, void *handle)
1777 s = format (0, "SCRIPT: nat44_interface_output_feature_dump ");
1783 vl_api_nat44_add_del_static_mapping_t_handler
1784 (vl_api_nat44_add_del_static_mapping_t * mp)
1786 snat_main_t *sm = &snat_main;
1787 vl_api_nat44_add_del_static_mapping_reply_t *rmp;
1788 ip4_address_t local_addr, external_addr;
1789 u16 local_port = 0, external_port = 0;
1790 u32 vrf_id, external_sw_if_index;
1792 snat_protocol_t proto;
1794 memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
1795 memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
1796 if (mp->addr_only == 0)
1798 local_port = clib_net_to_host_u16 (mp->local_port);
1799 external_port = clib_net_to_host_u16 (mp->external_port);
1801 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
1802 external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
1803 proto = ip_proto_to_snat_proto (mp->protocol);
1805 rv = snat_add_static_mapping (local_addr, external_addr, local_port,
1806 external_port, vrf_id, mp->addr_only,
1807 external_sw_if_index, proto, mp->is_add);
1809 REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_REPLY);
1812 static void *vl_api_nat44_add_del_static_mapping_t_print
1813 (vl_api_nat44_add_del_static_mapping_t * mp, void *handle)
1817 s = format (0, "SCRIPT: nat44_add_del_static_mapping ");
1818 s = format (s, "protocol %d local_addr %U external_addr %U ",
1820 format_ip4_address, mp->local_ip_address,
1821 format_ip4_address, mp->external_ip_address);
1823 if (mp->addr_only == 0)
1824 s = format (s, "local_port %d external_port %d ",
1825 clib_net_to_host_u16 (mp->local_port),
1826 clib_net_to_host_u16 (mp->external_port));
1828 if (mp->vrf_id != ~0)
1829 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
1831 if (mp->external_sw_if_index != ~0)
1832 s = format (s, "external_sw_if_index %d",
1833 clib_net_to_host_u32 (mp->external_sw_if_index));
1838 send_nat44_static_mapping_details (snat_static_mapping_t * m,
1839 unix_shared_memory_queue_t * q,
1842 vl_api_nat44_static_mapping_details_t *rmp;
1843 snat_main_t *sm = &snat_main;
1845 rmp = vl_msg_api_alloc (sizeof (*rmp));
1846 memset (rmp, 0, sizeof (*rmp));
1848 ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
1849 rmp->addr_only = m->addr_only;
1850 clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
1851 clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
1852 rmp->local_port = htons (m->local_port);
1853 rmp->external_port = htons (m->external_port);
1854 rmp->external_sw_if_index = ~0;
1855 rmp->vrf_id = htonl (m->vrf_id);
1856 rmp->protocol = snat_proto_to_ip_proto (m->proto);
1857 rmp->context = context;
1859 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1863 send_nat44_static_map_resolve_details (snat_static_map_resolve_t * m,
1864 unix_shared_memory_queue_t * q,
1867 vl_api_nat44_static_mapping_details_t *rmp;
1868 snat_main_t *sm = &snat_main;
1870 rmp = vl_msg_api_alloc (sizeof (*rmp));
1871 memset (rmp, 0, sizeof (*rmp));
1873 ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
1874 rmp->addr_only = m->addr_only;
1875 clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
1876 rmp->local_port = htons (m->l_port);
1877 rmp->external_port = htons (m->e_port);
1878 rmp->external_sw_if_index = htonl (m->sw_if_index);
1879 rmp->vrf_id = htonl (m->vrf_id);
1880 rmp->protocol = snat_proto_to_ip_proto (m->proto);
1881 rmp->context = context;
1883 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1887 vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
1890 unix_shared_memory_queue_t *q;
1891 snat_main_t *sm = &snat_main;
1892 snat_static_mapping_t *m;
1893 snat_static_map_resolve_t *rp;
1896 q = vl_api_client_index_to_input_queue (mp->client_index);
1901 pool_foreach (m, sm->static_mappings,
1903 if (!vec_len(m->locals))
1904 send_nat44_static_mapping_details (m, q, mp->context);
1908 for (j = 0; j < vec_len (sm->to_resolve); j++)
1910 rp = sm->to_resolve + j;
1911 send_nat44_static_map_resolve_details (rp, q, mp->context);
1916 vl_api_nat44_static_mapping_dump_t_print (vl_api_nat44_static_mapping_dump_t *
1921 s = format (0, "SCRIPT: nat44_static_mapping_dump ");
1927 vl_api_nat44_add_del_interface_addr_t_handler
1928 (vl_api_nat44_add_del_interface_addr_t * mp)
1930 snat_main_t *sm = &snat_main;
1931 vl_api_nat44_add_del_interface_addr_reply_t *rmp;
1932 u8 is_del = mp->is_add == 0;
1933 u32 sw_if_index = ntohl (mp->sw_if_index);
1936 VALIDATE_SW_IF_INDEX (mp);
1938 rv = snat_add_interface_address (sm, sw_if_index, is_del);
1940 BAD_SW_IF_INDEX_LABEL;
1942 REPLY_MACRO (VL_API_NAT44_ADD_DEL_INTERFACE_ADDR_REPLY);
1945 static void *vl_api_nat44_add_del_interface_addr_t_print
1946 (vl_api_nat44_add_del_interface_addr_t * mp, void *handle)
1950 s = format (0, "SCRIPT: nat44_add_del_interface_addr ");
1951 s = format (s, "sw_if_index %d %s",
1952 clib_host_to_net_u32 (mp->sw_if_index),
1953 mp->is_add ? "" : "del");
1959 send_nat44_interface_addr_details (u32 sw_if_index,
1960 unix_shared_memory_queue_t * q,
1963 vl_api_nat44_interface_addr_details_t *rmp;
1964 snat_main_t *sm = &snat_main;
1966 rmp = vl_msg_api_alloc (sizeof (*rmp));
1967 memset (rmp, 0, sizeof (*rmp));
1969 ntohs (VL_API_NAT44_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
1970 rmp->sw_if_index = ntohl (sw_if_index);
1971 rmp->context = context;
1973 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1977 vl_api_nat44_interface_addr_dump_t_handler (vl_api_nat44_interface_addr_dump_t
1980 unix_shared_memory_queue_t *q;
1981 snat_main_t *sm = &snat_main;
1984 q = vl_api_client_index_to_input_queue (mp->client_index);
1989 vec_foreach (i, sm->auto_add_sw_if_indices)
1990 send_nat44_interface_addr_details(*i, q, mp->context);
1995 vl_api_nat44_interface_addr_dump_t_print (vl_api_nat44_interface_addr_dump_t *
2000 s = format (0, "SCRIPT: nat44_interface_addr_dump ");
2006 send_nat44_user_details (snat_user_t * u, unix_shared_memory_queue_t * q,
2009 vl_api_nat44_user_details_t *rmp;
2010 snat_main_t *sm = &snat_main;
2011 fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
2013 rmp = vl_msg_api_alloc (sizeof (*rmp));
2014 memset (rmp, 0, sizeof (*rmp));
2015 rmp->_vl_msg_id = ntohs (VL_API_NAT44_USER_DETAILS + sm->msg_id_base);
2017 rmp->vrf_id = ntohl (fib->ft_table_id);
2019 clib_memcpy (rmp->ip_address, &(u->addr), 4);
2020 rmp->nsessions = ntohl (u->nsessions);
2021 rmp->nstaticsessions = ntohl (u->nstaticsessions);
2022 rmp->context = context;
2024 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2028 vl_api_nat44_user_dump_t_handler (vl_api_nat44_user_dump_t * mp)
2030 unix_shared_memory_queue_t *q;
2031 snat_main_t *sm = &snat_main;
2032 snat_main_per_thread_data_t *tsm;
2035 q = vl_api_client_index_to_input_queue (mp->client_index);
2040 vec_foreach (tsm, sm->per_thread_data)
2041 vec_foreach (u, tsm->users)
2042 send_nat44_user_details (u, q, mp->context);
2047 vl_api_nat44_user_dump_t_print (vl_api_nat44_user_dump_t * mp, void *handle)
2051 s = format (0, "SCRIPT: nat44_user_dump ");
2057 send_nat44_user_session_details (snat_session_t * s,
2058 unix_shared_memory_queue_t * q, u32 context)
2060 vl_api_nat44_user_session_details_t *rmp;
2061 snat_main_t *sm = &snat_main;
2063 rmp = vl_msg_api_alloc (sizeof (*rmp));
2064 memset (rmp, 0, sizeof (*rmp));
2066 ntohs (VL_API_NAT44_USER_SESSION_DETAILS + sm->msg_id_base);
2067 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
2068 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
2069 rmp->is_static = s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING ? 1 : 0;
2070 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
2071 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
2072 rmp->total_pkts = ntohl (s->total_pkts);
2073 rmp->context = context;
2074 if (snat_is_unk_proto_session (s))
2076 rmp->outside_port = 0;
2077 rmp->inside_port = 0;
2078 rmp->protocol = ntohs (s->in2out.port);
2082 rmp->outside_port = s->out2in.port;
2083 rmp->inside_port = s->in2out.port;
2084 rmp->protocol = ntohs (snat_proto_to_ip_proto (s->in2out.protocol));
2087 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2091 vl_api_nat44_user_session_dump_t_handler (vl_api_nat44_user_session_dump_t *
2094 unix_shared_memory_queue_t *q;
2095 snat_main_t *sm = &snat_main;
2096 snat_main_per_thread_data_t *tsm;
2098 clib_bihash_kv_8_8_t key, value;
2099 snat_user_key_t ukey;
2101 u32 session_index, head_index, elt_index;
2102 dlist_elt_t *head, *elt;
2105 q = vl_api_client_index_to_input_queue (mp->client_index);
2109 clib_memcpy (&ukey.addr, mp->ip_address, 4);
2110 ip.src_address.as_u32 = ukey.addr.as_u32;
2111 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
2112 key.key = ukey.as_u64;
2113 if (sm->num_workers)
2115 vec_elt_at_index (sm->per_thread_data,
2116 sm->worker_in2out_cb (&ip, ukey.fib_index));
2118 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
2119 if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
2121 u = pool_elt_at_index (tsm->users, value.value);
2122 if (!u->nsessions && !u->nstaticsessions)
2125 head_index = u->sessions_per_user_list_head_index;
2126 head = pool_elt_at_index (tsm->list_pool, head_index);
2127 elt_index = head->next;
2128 elt = pool_elt_at_index (tsm->list_pool, elt_index);
2129 session_index = elt->value;
2130 while (session_index != ~0)
2132 s = pool_elt_at_index (tsm->sessions, session_index);
2134 send_nat44_user_session_details (s, q, mp->context);
2136 elt_index = elt->next;
2137 elt = pool_elt_at_index (tsm->list_pool, elt_index);
2138 session_index = elt->value;
2143 vl_api_nat44_user_session_dump_t_print (vl_api_nat44_user_session_dump_t * mp,
2148 s = format (0, "SCRIPT: nat44_user_session_dump ");
2149 s = format (s, "ip_address %U vrf_id %d\n",
2150 format_ip4_address, mp->ip_address,
2151 clib_net_to_host_u32 (mp->vrf_id));
2156 static nat44_lb_addr_port_t *
2157 unformat_nat44_lb_addr_port (vl_api_nat44_lb_addr_port_t * addr_port_pairs,
2158 u8 addr_port_pair_num)
2161 nat44_lb_addr_port_t *lb_addr_port_pairs = 0, lb_addr_port;
2162 vl_api_nat44_lb_addr_port_t *ap;
2164 for (i = 0; i < addr_port_pair_num; i++)
2166 ap = &addr_port_pairs[i];
2167 memset (&lb_addr_port, 0, sizeof (lb_addr_port));
2168 clib_memcpy (&lb_addr_port.addr, ap->addr, 4);
2169 lb_addr_port.port = clib_net_to_host_u16 (ap->port);
2170 lb_addr_port.probability = ap->probability;
2171 vec_add1 (lb_addr_port_pairs, lb_addr_port);
2174 return lb_addr_port_pairs;
2178 vl_api_nat44_add_del_lb_static_mapping_t_handler
2179 (vl_api_nat44_add_del_lb_static_mapping_t * mp)
2181 snat_main_t *sm = &snat_main;
2182 vl_api_nat44_add_del_lb_static_mapping_reply_t *rmp;
2184 nat44_lb_addr_port_t *locals = 0;
2185 ip4_address_t e_addr;
2186 snat_protocol_t proto;
2188 locals = unformat_nat44_lb_addr_port (mp->locals, mp->local_num);
2189 clib_memcpy (&e_addr, mp->external_addr, 4);
2190 proto = ip_proto_to_snat_proto (mp->protocol);
2193 nat44_add_del_lb_static_mapping (e_addr,
2194 clib_net_to_host_u16 (mp->external_port),
2195 proto, clib_net_to_host_u32 (mp->vrf_id),
2196 locals, mp->is_add);
2200 REPLY_MACRO (VL_API_NAT44_ADD_DEL_LB_STATIC_MAPPING_REPLY);
2203 static void *vl_api_nat44_add_del_lb_static_mapping_t_print
2204 (vl_api_nat44_add_del_lb_static_mapping_t * mp, void *handle)
2208 s = format (0, "SCRIPT: nat44_add_del_lb_static_mapping ");
2209 s = format (s, "is_add %d\n", mp->is_add);
2215 send_nat44_lb_static_mapping_details (snat_static_mapping_t * m,
2216 unix_shared_memory_queue_t * q,
2219 vl_api_nat44_lb_static_mapping_details_t *rmp;
2220 snat_main_t *sm = &snat_main;
2221 nat44_lb_addr_port_t *ap;
2222 vl_api_nat44_lb_addr_port_t *locals;
2225 vl_msg_api_alloc (sizeof (*rmp) +
2226 (vec_len (m->locals) * sizeof (nat44_lb_addr_port_t)));
2227 memset (rmp, 0, sizeof (*rmp));
2229 ntohs (VL_API_NAT44_LB_STATIC_MAPPING_DETAILS + sm->msg_id_base);
2231 clib_memcpy (rmp->external_addr, &(m->external_addr), 4);
2232 rmp->external_port = ntohs (m->external_port);
2233 rmp->protocol = snat_proto_to_ip_proto (m->proto);
2234 rmp->vrf_id = ntohl (m->vrf_id);
2235 rmp->context = context;
2237 locals = (vl_api_nat44_lb_addr_port_t *) rmp->locals;
2238 vec_foreach (ap, m->locals)
2240 clib_memcpy (locals->addr, &(ap->addr), 4);
2241 locals->port = htons (ap->port);
2242 locals->probability = ap->probability;
2247 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2251 vl_api_nat44_lb_static_mapping_dump_t_handler
2252 (vl_api_nat44_lb_static_mapping_dump_t * mp)
2254 unix_shared_memory_queue_t *q;
2255 snat_main_t *sm = &snat_main;
2256 snat_static_mapping_t *m;
2258 q = vl_api_client_index_to_input_queue (mp->client_index);
2263 pool_foreach (m, sm->static_mappings,
2265 if (vec_len(m->locals))
2266 send_nat44_lb_static_mapping_details (m, q, mp->context);
2271 static void *vl_api_nat44_lb_static_mapping_dump_t_print
2272 (vl_api_nat44_lb_static_mapping_dump_t * mp, void *handle)
2276 s = format (0, "SCRIPT: nat44_lb_static_mapping_dump ");
2282 vl_api_nat44_del_session_t_handler (vl_api_nat44_del_session_t * mp)
2284 snat_main_t *sm = &snat_main;
2285 vl_api_nat44_del_session_reply_t *rmp;
2290 snat_protocol_t proto;
2292 memcpy (&addr.as_u8, mp->address, 4);
2293 port = clib_net_to_host_u16 (mp->port);
2294 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
2295 proto = ip_proto_to_snat_proto (mp->protocol);
2297 rv = nat44_del_session (sm, &addr, port, proto, vrf_id, mp->is_in);
2299 REPLY_MACRO (VL_API_NAT44_DEL_SESSION_REPLY);
2303 vl_api_nat44_del_session_t_print (vl_api_nat44_del_session_t * mp,
2308 s = format (0, "SCRIPT: nat44_add_del_static_mapping ");
2309 s = format (s, "addr %U port %d protocol %d vrf_id %d is_in %d",
2310 format_ip4_address, mp->address,
2311 clib_net_to_host_u16 (mp->port),
2312 mp->protocol, clib_net_to_host_u32 (mp->vrf_id), mp->is_in);
2317 /*******************************/
2318 /*** Deterministic NAT (CGN) ***/
2319 /*******************************/
2322 vl_api_nat_det_add_del_map_t_handler (vl_api_nat_det_add_del_map_t * mp)
2324 snat_main_t *sm = &snat_main;
2325 vl_api_nat_det_add_del_map_reply_t *rmp;
2327 ip4_address_t in_addr, out_addr;
2331 rv = VNET_API_ERROR_UNIMPLEMENTED;
2335 clib_memcpy (&in_addr, mp->in_addr, 4);
2336 clib_memcpy (&out_addr, mp->out_addr, 4);
2337 rv = snat_det_add_map (sm, &in_addr, mp->in_plen, &out_addr,
2338 mp->out_plen, mp->is_add);
2341 REPLY_MACRO (VL_API_NAT_DET_ADD_DEL_MAP_REPLY);
2345 vl_api_nat_det_add_del_map_t_print (vl_api_nat_det_add_del_map_t * mp,
2350 s = format (0, "SCRIPT: nat_det_add_del_map ");
2351 s = format (s, "inside address %U/%d outside address %U/%d\n",
2352 format_ip4_address, mp->in_addr, mp->in_plen,
2353 format_ip4_address, mp->out_addr, mp->out_plen);
2359 vl_api_nat_det_forward_t_handler (vl_api_nat_det_forward_t * mp)
2361 snat_main_t *sm = &snat_main;
2362 vl_api_nat_det_forward_reply_t *rmp;
2364 u16 lo_port = 0, hi_port = 0;
2366 ip4_address_t in_addr, out_addr;
2370 out_addr.as_u32 = 0;
2371 rv = VNET_API_ERROR_UNIMPLEMENTED;
2375 out_addr.as_u32 = 0;
2376 clib_memcpy (&in_addr, mp->in_addr, 4);
2377 dm = snat_det_map_by_user (sm, &in_addr);
2380 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2384 snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
2385 hi_port = lo_port + dm->ports_per_host - 1;
2389 REPLY_MACRO2 (VL_API_NAT_DET_FORWARD_REPLY,
2391 rmp->out_port_lo = ntohs (lo_port);
2392 rmp->out_port_hi = ntohs (hi_port);
2393 clib_memcpy (rmp->out_addr, &out_addr, 4);
2399 vl_api_nat_det_forward_t_print (vl_api_nat_det_forward_t * mp, void *handle)
2403 s = format (0, "SCRIPT: nat_det_forward");
2404 s = format (s, "inside ip address %U\n", format_ip4_address, mp->in_addr);
2410 vl_api_nat_det_reverse_t_handler (vl_api_nat_det_reverse_t * mp)
2412 snat_main_t *sm = &snat_main;
2413 vl_api_nat_det_reverse_reply_t *rmp;
2415 ip4_address_t out_addr, in_addr;
2419 clib_memcpy (&out_addr, mp->out_addr, 4);
2420 dm = snat_det_map_by_out (sm, &out_addr);
2423 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2427 snat_det_reverse (dm, &out_addr, htons (mp->out_port), &in_addr);
2431 REPLY_MACRO2 (VL_API_NAT_DET_REVERSE_REPLY,
2434 memset (rmp->in_addr, 0, 16);
2435 clib_memcpy (rmp->in_addr, &in_addr, 4);
2441 vl_api_nat_det_reverse_t_print (vl_api_nat_det_reverse_t * mp, void *handle)
2445 s = format (0, "SCRIPT: nat_det_reverse");
2446 s = format (s, "outside ip address %U outside port %d",
2447 format_ip4_address, mp->out_addr, ntohs (mp->out_port));
2453 sent_nat_det_map_details (snat_det_map_t * m, unix_shared_memory_queue_t * q,
2456 vl_api_nat_det_map_details_t *rmp;
2457 snat_main_t *sm = &snat_main;
2459 rmp = vl_msg_api_alloc (sizeof (*rmp));
2460 memset (rmp, 0, sizeof (*rmp));
2461 rmp->_vl_msg_id = ntohs (VL_API_NAT_DET_MAP_DETAILS + sm->msg_id_base);
2463 clib_memcpy (rmp->in_addr, &m->in_addr, 4);
2464 rmp->in_plen = m->in_plen;
2465 clib_memcpy (rmp->out_addr, &m->out_addr, 4);
2466 rmp->out_plen = m->out_plen;
2467 rmp->sharing_ratio = htonl (m->sharing_ratio);
2468 rmp->ports_per_host = htons (m->ports_per_host);
2469 rmp->ses_num = htonl (m->ses_num);
2470 rmp->context = context;
2472 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2476 vl_api_nat_det_map_dump_t_handler (vl_api_nat_det_map_dump_t * mp)
2478 unix_shared_memory_queue_t *q;
2479 snat_main_t *sm = &snat_main;
2482 q = vl_api_client_index_to_input_queue (mp->client_index);
2487 vec_foreach(m, sm->det_maps)
2488 sent_nat_det_map_details(m, q, mp->context);
2493 vl_api_nat_det_map_dump_t_print (vl_api_nat_det_map_dump_t * mp, void *handle)
2497 s = format (0, "SCRIPT: nat_det_map_dump ");
2503 vl_api_nat_det_set_timeouts_t_handler (vl_api_nat_det_set_timeouts_t * mp)
2505 snat_main_t *sm = &snat_main;
2506 vl_api_nat_det_set_timeouts_reply_t *rmp;
2509 sm->udp_timeout = ntohl (mp->udp);
2510 sm->tcp_established_timeout = ntohl (mp->tcp_established);
2511 sm->tcp_transitory_timeout = ntohl (mp->tcp_transitory);
2512 sm->icmp_timeout = ntohl (mp->icmp);
2514 REPLY_MACRO (VL_API_NAT_DET_SET_TIMEOUTS_REPLY);
2518 vl_api_nat_det_set_timeouts_t_print (vl_api_nat_det_set_timeouts_t * mp,
2523 s = format (0, "SCRIPT: nat_det_set_timeouts ");
2524 s = format (s, "udp %d tcp_established %d tcp_transitory %d icmp %d\n",
2526 ntohl (mp->tcp_established),
2527 ntohl (mp->tcp_transitory), ntohl (mp->icmp));
2533 vl_api_nat_det_get_timeouts_t_handler (vl_api_nat_det_get_timeouts_t * mp)
2535 snat_main_t *sm = &snat_main;
2536 vl_api_nat_det_get_timeouts_reply_t *rmp;
2540 REPLY_MACRO2 (VL_API_NAT_DET_GET_TIMEOUTS_REPLY,
2542 rmp->udp = htonl (sm->udp_timeout);
2543 rmp->tcp_established = htonl (sm->tcp_established_timeout);
2544 rmp->tcp_transitory = htonl (sm->tcp_transitory_timeout);
2545 rmp->icmp = htonl (sm->icmp_timeout);
2551 vl_api_nat_det_get_timeouts_t_print (vl_api_nat_det_get_timeouts_t * mp,
2556 s = format (0, "SCRIPT: nat_det_get_timeouts");
2562 vl_api_nat_det_close_session_out_t_handler (vl_api_nat_det_close_session_out_t
2565 snat_main_t *sm = &snat_main;
2566 vl_api_nat_det_close_session_out_reply_t *rmp;
2567 ip4_address_t out_addr, ext_addr, in_addr;
2568 snat_det_out_key_t key;
2570 snat_det_session_t *ses;
2573 clib_memcpy (&out_addr, mp->out_addr, 4);
2574 clib_memcpy (&ext_addr, mp->ext_addr, 4);
2576 dm = snat_det_map_by_out (sm, &out_addr);
2579 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2582 snat_det_reverse (dm, &ext_addr, ntohs (mp->out_port), &in_addr);
2583 key.ext_host_addr = ext_addr;
2584 key.ext_host_port = mp->ext_port;
2585 key.out_port = mp->out_port;
2586 ses = snat_det_get_ses_by_out (dm, &in_addr, key.as_u64);
2589 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2592 snat_det_ses_close (dm, ses);
2595 REPLY_MACRO (VL_API_NAT_DET_CLOSE_SESSION_OUT_REPLY);
2599 vl_api_nat_det_close_session_out_t_print (vl_api_nat_det_close_session_out_t *
2604 s = format (0, "SCRIPT: nat_det_close_session_out ");
2605 s = format (s, "out_addr %U out_port %d "
2606 "ext_addr %U ext_port %d\n",
2607 format_ip4_address, mp->out_addr, ntohs (mp->out_port),
2608 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
2614 vl_api_nat_det_close_session_in_t_handler (vl_api_nat_det_close_session_in_t *
2617 snat_main_t *sm = &snat_main;
2618 vl_api_nat_det_close_session_in_reply_t *rmp;
2619 ip4_address_t in_addr, ext_addr;
2620 snat_det_out_key_t key;
2622 snat_det_session_t *ses;
2627 rv = VNET_API_ERROR_UNIMPLEMENTED;
2631 clib_memcpy (&in_addr, mp->in_addr, 4);
2632 clib_memcpy (&ext_addr, mp->ext_addr, 4);
2634 dm = snat_det_map_by_user (sm, &in_addr);
2637 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2640 key.ext_host_addr = ext_addr;
2641 key.ext_host_port = mp->ext_port;
2642 ses = snat_det_find_ses_by_in (dm, &in_addr, mp->in_port, key);
2645 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2648 snat_det_ses_close (dm, ses);
2651 REPLY_MACRO (VL_API_NAT_DET_CLOSE_SESSION_OUT_REPLY);
2655 vl_api_nat_det_close_session_in_t_print (vl_api_nat_det_close_session_in_t *
2659 s = format (0, "SCRIPT: nat_det_close_session_in ");
2660 s = format (s, "in_addr %U in_port %d ext_addr %U ext_port %d\n",
2661 format_ip4_address, mp->in_addr, ntohs (mp->in_port),
2662 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
2668 send_nat_det_session_details (snat_det_session_t * s,
2669 unix_shared_memory_queue_t * q, u32 context)
2671 vl_api_nat_det_session_details_t *rmp;
2672 snat_main_t *sm = &snat_main;
2674 rmp = vl_msg_api_alloc (sizeof (*rmp));
2675 memset (rmp, 0, sizeof (*rmp));
2676 rmp->_vl_msg_id = ntohs (VL_API_NAT_DET_SESSION_DETAILS + sm->msg_id_base);
2677 rmp->in_port = s->in_port;
2678 clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
2679 rmp->ext_port = s->out.ext_host_port;
2680 rmp->out_port = s->out.out_port;
2681 rmp->state = s->state;
2682 rmp->expire = ntohl (s->expire);
2683 rmp->context = context;
2685 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2689 vl_api_nat_det_session_dump_t_handler (vl_api_nat_det_session_dump_t * mp)
2691 unix_shared_memory_queue_t *q;
2692 snat_main_t *sm = &snat_main;
2693 ip4_address_t user_addr;
2695 snat_det_session_t *s, empty_ses;
2698 q = vl_api_client_index_to_input_queue (mp->client_index);
2704 memset (&empty_ses, 0, sizeof (empty_ses));
2705 clib_memcpy (&user_addr, mp->user_addr, 4);
2706 dm = snat_det_map_by_user (sm, &user_addr);
2710 s = dm->sessions + snat_det_user_ses_offset (&user_addr, dm->in_plen);
2711 for (i = 0; i < SNAT_DET_SES_PER_USER; i++)
2714 send_nat_det_session_details (s, q, mp->context);
2720 vl_api_nat_det_session_dump_t_print (vl_api_nat_det_session_dump_t * mp,
2725 s = format (0, "SCRIPT: nat_det_session_dump ");
2726 s = format (s, "user_addr %U\n", format_ip4_address, mp->user_addr);
2736 vl_api_nat64_add_del_pool_addr_range_t_handler
2737 (vl_api_nat64_add_del_pool_addr_range_t * mp)
2739 vl_api_nat64_add_del_pool_addr_range_reply_t *rmp;
2740 snat_main_t *sm = &snat_main;
2741 nat64_main_t *nm = &nat64_main;
2743 ip4_address_t this_addr;
2744 u32 start_host_order, end_host_order;
2749 if (nm->is_disabled)
2751 rv = VNET_API_ERROR_FEATURE_DISABLED;
2755 tmp = (u32 *) mp->start_addr;
2756 start_host_order = clib_host_to_net_u32 (tmp[0]);
2757 tmp = (u32 *) mp->end_addr;
2758 end_host_order = clib_host_to_net_u32 (tmp[0]);
2760 count = (end_host_order - start_host_order) + 1;
2762 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
2764 memcpy (&this_addr.as_u8, mp->start_addr, 4);
2766 for (i = 0; i < count; i++)
2768 if ((rv = nat64_add_del_pool_addr (&this_addr, vrf_id, mp->is_add)))
2771 increment_v4_address (&this_addr);
2775 REPLY_MACRO (VL_API_NAT64_ADD_DEL_POOL_ADDR_RANGE_REPLY);
2778 static void *vl_api_nat64_add_del_pool_addr_range_t_print
2779 (vl_api_nat64_add_del_pool_addr_range_t * mp, void *handle)
2783 s = format (0, "SCRIPT: nat64_add_del_pool_addr_range ");
2784 s = format (s, "%U - %U vrf_id %u %s\n",
2785 format_ip4_address, mp->start_addr,
2786 format_ip4_address, mp->end_addr,
2787 ntohl (mp->vrf_id), mp->is_add ? "" : "del");
2792 typedef struct nat64_api_walk_ctx_t_
2794 unix_shared_memory_queue_t *q;
2796 } nat64_api_walk_ctx_t;
2799 nat64_api_pool_walk (snat_address_t * a, void *arg)
2801 vl_api_nat64_pool_addr_details_t *rmp;
2802 snat_main_t *sm = &snat_main;
2803 nat64_api_walk_ctx_t *ctx = arg;
2805 rmp = vl_msg_api_alloc (sizeof (*rmp));
2806 memset (rmp, 0, sizeof (*rmp));
2807 rmp->_vl_msg_id = ntohs (VL_API_NAT64_POOL_ADDR_DETAILS + sm->msg_id_base);
2808 clib_memcpy (rmp->address, &(a->addr), 4);
2809 if (a->fib_index != ~0)
2811 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP6);
2814 rmp->vrf_id = ntohl (fib->ft_table_id);
2818 rmp->context = ctx->context;
2820 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
2826 vl_api_nat64_pool_addr_dump_t_handler (vl_api_nat64_pool_addr_dump_t * mp)
2828 unix_shared_memory_queue_t *q;
2829 nat64_main_t *nm = &nat64_main;
2831 if (nm->is_disabled)
2834 q = vl_api_client_index_to_input_queue (mp->client_index);
2838 nat64_api_walk_ctx_t ctx = {
2840 .context = mp->context,
2843 nat64_pool_addr_walk (nat64_api_pool_walk, &ctx);
2847 vl_api_nat64_pool_addr_dump_t_print (vl_api_nat64_pool_addr_dump_t * mp,
2852 s = format (0, "SCRIPT: nat64_pool_addr_dump\n");
2858 vl_api_nat64_add_del_interface_t_handler (vl_api_nat64_add_del_interface_t *
2861 snat_main_t *sm = &snat_main;
2862 nat64_main_t *nm = &nat64_main;
2863 vl_api_nat64_add_del_interface_reply_t *rmp;
2866 if (nm->is_disabled)
2868 rv = VNET_API_ERROR_FEATURE_DISABLED;
2872 VALIDATE_SW_IF_INDEX (mp);
2875 nat64_add_del_interface (ntohl (mp->sw_if_index), mp->is_inside,
2878 BAD_SW_IF_INDEX_LABEL;
2881 REPLY_MACRO (VL_API_NAT64_ADD_DEL_INTERFACE_REPLY);
2885 vl_api_nat64_add_del_interface_t_print (vl_api_nat64_add_del_interface_t * mp,
2890 s = format (0, "SCRIPT: nat64_add_del_interface ");
2891 s = format (s, "sw_if_index %d %s %s",
2892 clib_host_to_net_u32 (mp->sw_if_index),
2893 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
2899 nat64_api_interface_walk (snat_interface_t * i, void *arg)
2901 vl_api_nat64_interface_details_t *rmp;
2902 snat_main_t *sm = &snat_main;
2903 nat64_api_walk_ctx_t *ctx = arg;
2905 rmp = vl_msg_api_alloc (sizeof (*rmp));
2906 memset (rmp, 0, sizeof (*rmp));
2907 rmp->_vl_msg_id = ntohs (VL_API_NAT64_INTERFACE_DETAILS + sm->msg_id_base);
2908 rmp->sw_if_index = ntohl (i->sw_if_index);
2909 rmp->is_inside = (nat_interface_is_inside (i)
2910 && nat_interface_is_outside (i)) ? 2 :
2911 nat_interface_is_inside (i);
2912 rmp->context = ctx->context;
2914 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
2920 vl_api_nat64_interface_dump_t_handler (vl_api_nat64_interface_dump_t * mp)
2922 unix_shared_memory_queue_t *q;
2923 nat64_main_t *nm = &nat64_main;
2925 if (nm->is_disabled)
2928 q = vl_api_client_index_to_input_queue (mp->client_index);
2932 nat64_api_walk_ctx_t ctx = {
2934 .context = mp->context,
2937 nat64_interfaces_walk (nat64_api_interface_walk, &ctx);
2941 vl_api_nat64_interface_dump_t_print (vl_api_nat64_interface_dump_t * mp,
2946 s = format (0, "SCRIPT: snat_interface_dump ");
2952 vl_api_nat64_add_del_static_bib_t_handler
2953 (vl_api_nat64_add_del_static_bib_t * mp)
2955 snat_main_t *sm = &snat_main;
2956 nat64_main_t *nm = &nat64_main;
2957 vl_api_nat64_add_del_static_bib_reply_t *rmp;
2958 ip6_address_t in_addr;
2959 ip4_address_t out_addr;
2962 if (nm->is_disabled)
2964 rv = VNET_API_ERROR_FEATURE_DISABLED;
2968 memcpy (&in_addr.as_u8, mp->i_addr, 16);
2969 memcpy (&out_addr.as_u8, mp->o_addr, 4);
2972 nat64_add_del_static_bib_entry (&in_addr, &out_addr,
2973 clib_net_to_host_u16 (mp->i_port),
2974 clib_net_to_host_u16 (mp->o_port),
2976 clib_net_to_host_u32 (mp->vrf_id),
2980 REPLY_MACRO (VL_API_NAT64_ADD_DEL_STATIC_BIB_REPLY);
2983 static void *vl_api_nat64_add_del_static_bib_t_print
2984 (vl_api_nat64_add_del_static_bib_t * mp, void *handle)
2988 s = format (0, "SCRIPT: nat64_add_del_static_bib ");
2989 s = format (s, "protocol %d i_addr %U o_addr %U ",
2991 format_ip6_address, mp->i_addr, format_ip4_address, mp->o_addr);
2993 if (mp->vrf_id != ~0)
2994 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
3000 nat64_api_bib_walk (nat64_db_bib_entry_t * bibe, void *arg)
3002 vl_api_nat64_bib_details_t *rmp;
3003 snat_main_t *sm = &snat_main;
3004 nat64_api_walk_ctx_t *ctx = arg;
3007 fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
3011 rmp = vl_msg_api_alloc (sizeof (*rmp));
3012 memset (rmp, 0, sizeof (*rmp));
3013 rmp->_vl_msg_id = ntohs (VL_API_NAT64_BIB_DETAILS + sm->msg_id_base);
3014 rmp->context = ctx->context;
3015 clib_memcpy (rmp->i_addr, &(bibe->in_addr), 16);
3016 clib_memcpy (rmp->o_addr, &(bibe->out_addr), 4);
3017 rmp->i_port = bibe->in_port;
3018 rmp->o_port = bibe->out_port;
3019 rmp->vrf_id = ntohl (fib->ft_table_id);
3020 rmp->proto = bibe->proto;
3021 rmp->is_static = bibe->is_static;
3022 rmp->ses_num = ntohl (bibe->ses_num);
3024 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3030 vl_api_nat64_bib_dump_t_handler (vl_api_nat64_bib_dump_t * mp)
3032 unix_shared_memory_queue_t *q;
3033 nat64_main_t *nm = &nat64_main;
3035 if (nm->is_disabled)
3038 q = vl_api_client_index_to_input_queue (mp->client_index);
3042 nat64_api_walk_ctx_t ctx = {
3044 .context = mp->context,
3047 nat64_db_bib_walk (&nm->db, mp->proto, nat64_api_bib_walk, &ctx);
3051 vl_api_nat64_bib_dump_t_print (vl_api_nat64_bib_dump_t * mp, void *handle)
3055 s = format (0, "SCRIPT: snat_bib_dump protocol %d", mp->proto);
3061 vl_api_nat64_set_timeouts_t_handler (vl_api_nat64_set_timeouts_t * mp)
3063 snat_main_t *sm = &snat_main;
3064 nat64_main_t *nm = &nat64_main;
3065 vl_api_nat64_set_timeouts_reply_t *rmp;
3068 if (nm->is_disabled)
3070 rv = VNET_API_ERROR_FEATURE_DISABLED;
3074 rv = nat64_set_icmp_timeout (ntohl (mp->icmp));
3077 rv = nat64_set_udp_timeout (ntohl (mp->udp));
3081 nat64_set_tcp_timeouts (ntohl (mp->tcp_trans), ntohl (mp->tcp_est),
3082 ntohl (mp->tcp_incoming_syn));
3085 REPLY_MACRO (VL_API_NAT64_SET_TIMEOUTS_REPLY);
3088 static void *vl_api_nat64_set_timeouts_t_print
3089 (vl_api_nat64_set_timeouts_t * mp, void *handle)
3093 s = format (0, "SCRIPT: nat64_set_timeouts ");
3096 "udp %d icmp %d, tcp_trans %d, tcp_est %d, tcp_incoming_syn %d\n",
3097 ntohl (mp->udp), ntohl (mp->icmp), ntohl (mp->tcp_trans),
3098 ntohl (mp->tcp_est), ntohl (mp->tcp_incoming_syn));
3104 vl_api_nat64_get_timeouts_t_handler (vl_api_nat64_get_timeouts_t * mp)
3106 snat_main_t *sm = &snat_main;
3107 nat64_main_t *nm = &nat64_main;
3108 vl_api_nat64_get_timeouts_reply_t *rmp;
3111 if (nm->is_disabled)
3115 REPLY_MACRO2 (VL_API_NAT64_GET_TIMEOUTS_REPLY,
3117 rmp->udp = htonl (nat64_get_udp_timeout());
3118 rmp->icmp = htonl (nat64_get_icmp_timeout());
3119 rmp->tcp_trans = htonl (nat64_get_tcp_trans_timeout());
3120 rmp->tcp_est = htonl (nat64_get_tcp_est_timeout());
3121 rmp->tcp_incoming_syn = htonl (nat64_get_tcp_incoming_syn_timeout());
3126 static void *vl_api_nat64_get_timeouts_t_print
3127 (vl_api_nat64_get_timeouts_t * mp, void *handle)
3131 s = format (0, "SCRIPT: nat64_get_timeouts");
3137 nat64_api_st_walk (nat64_db_st_entry_t * ste, void *arg)
3139 vl_api_nat64_st_details_t *rmp;
3140 snat_main_t *sm = &snat_main;
3141 nat64_api_walk_ctx_t *ctx = arg;
3142 nat64_main_t *nm = &nat64_main;
3143 nat64_db_bib_entry_t *bibe;
3146 bibe = nat64_db_bib_entry_by_index (&nm->db, ste->proto, ste->bibe_index);
3150 fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
3154 rmp = vl_msg_api_alloc (sizeof (*rmp));
3155 memset (rmp, 0, sizeof (*rmp));
3156 rmp->_vl_msg_id = ntohs (VL_API_NAT64_ST_DETAILS + sm->msg_id_base);
3157 rmp->context = ctx->context;
3158 clib_memcpy (rmp->il_addr, &(bibe->in_addr), 16);
3159 clib_memcpy (rmp->ol_addr, &(bibe->out_addr), 4);
3160 rmp->il_port = bibe->in_port;
3161 rmp->ol_port = bibe->out_port;
3162 clib_memcpy (rmp->ir_addr, &(ste->in_r_addr), 16);
3163 clib_memcpy (rmp->or_addr, &(ste->out_r_addr), 4);
3164 rmp->il_port = ste->r_port;
3165 rmp->vrf_id = ntohl (fib->ft_table_id);
3166 rmp->proto = ste->proto;
3168 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3174 vl_api_nat64_st_dump_t_handler (vl_api_nat64_st_dump_t * mp)
3176 unix_shared_memory_queue_t *q;
3177 nat64_main_t *nm = &nat64_main;
3179 if (nm->is_disabled)
3182 q = vl_api_client_index_to_input_queue (mp->client_index);
3186 nat64_api_walk_ctx_t ctx = {
3188 .context = mp->context,
3191 nat64_db_st_walk (&nm->db, mp->proto, nat64_api_st_walk, &ctx);
3195 vl_api_nat64_st_dump_t_print (vl_api_nat64_st_dump_t * mp, void *handle)
3199 s = format (0, "SCRIPT: snat_st_dump protocol %d", mp->proto);
3205 vl_api_nat64_add_del_prefix_t_handler (vl_api_nat64_add_del_prefix_t * mp)
3207 vl_api_nat64_add_del_prefix_reply_t *rmp;
3208 snat_main_t *sm = &snat_main;
3209 nat64_main_t *nm = &nat64_main;
3210 ip6_address_t prefix;
3213 if (nm->is_disabled)
3215 rv = VNET_API_ERROR_FEATURE_DISABLED;
3219 memcpy (&prefix.as_u8, mp->prefix, 16);
3222 nat64_add_del_prefix (&prefix, mp->prefix_len,
3223 clib_net_to_host_u32 (mp->vrf_id), mp->is_add);
3225 REPLY_MACRO (VL_API_NAT64_ADD_DEL_PREFIX_REPLY);
3229 vl_api_nat64_add_del_prefix_t_print (vl_api_nat64_add_del_prefix_t * mp,
3234 s = format (0, "SCRIPT: nat64_add_del_prefix %U/%u vrf_id %u %s\n",
3235 format_ip6_address, mp->prefix, mp->prefix_len,
3236 ntohl (mp->vrf_id), mp->is_add ? "" : "del");
3242 nat64_api_prefix_walk (nat64_prefix_t * p, void *arg)
3244 vl_api_nat64_prefix_details_t *rmp;
3245 snat_main_t *sm = &snat_main;
3246 nat64_api_walk_ctx_t *ctx = arg;
3248 rmp = vl_msg_api_alloc (sizeof (*rmp));
3249 memset (rmp, 0, sizeof (*rmp));
3250 rmp->_vl_msg_id = ntohs (VL_API_NAT64_PREFIX_DETAILS + sm->msg_id_base);
3251 clib_memcpy (rmp->prefix, &(p->prefix), 16);
3252 rmp->prefix_len = p->plen;
3253 rmp->vrf_id = ntohl (p->vrf_id);
3254 rmp->context = ctx->context;
3256 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
3262 vl_api_nat64_prefix_dump_t_handler (vl_api_nat64_prefix_dump_t * mp)
3264 unix_shared_memory_queue_t *q;
3265 nat64_main_t *nm = &nat64_main;
3267 if (nm->is_disabled)
3270 q = vl_api_client_index_to_input_queue (mp->client_index);
3274 nat64_api_walk_ctx_t ctx = {
3276 .context = mp->context,
3279 nat64_prefix_walk (nat64_api_prefix_walk, &ctx);
3283 vl_api_nat64_prefix_dump_t_print (vl_api_nat64_prefix_dump_t * mp,
3288 s = format (0, "SCRIPT: nat64_prefix_dump\n");
3298 vl_api_dslite_set_aftr_addr_t_handler (vl_api_dslite_set_aftr_addr_t * mp)
3300 vl_api_dslite_set_aftr_addr_reply_t *rmp;
3301 snat_main_t *sm = &snat_main;
3302 dslite_main_t *dm = &dslite_main;
3304 ip6_address_t ip6_addr;
3306 memcpy (&ip6_addr.as_u8, mp->ip6_addr, 16);
3308 rv = dslite_set_aftr_ip6_addr (dm, &ip6_addr);
3310 REPLY_MACRO (VL_API_DSLITE_SET_AFTR_ADDR_REPLY);
3314 vl_api_dslite_set_aftr_addr_t_print (vl_api_dslite_set_aftr_addr_t * mp,
3319 s = format (0, "SCRIPT: dslite_set_aftr_addr ");
3320 s = format (s, "ip6_addr %U ip4_addr %U\n",
3321 format_ip6_address, mp->ip6_addr,
3322 format_ip4_address, mp->ip4_addr);
3328 vl_api_dslite_add_del_pool_addr_range_t_handler
3329 (vl_api_dslite_add_del_pool_addr_range_t * mp)
3331 vl_api_dslite_add_del_pool_addr_range_reply_t *rmp;
3332 snat_main_t *sm = &snat_main;
3333 dslite_main_t *dm = &dslite_main;
3335 ip4_address_t this_addr;
3336 u32 start_host_order, end_host_order;
3340 tmp = (u32 *) mp->start_addr;
3341 start_host_order = clib_host_to_net_u32 (tmp[0]);
3342 tmp = (u32 *) mp->end_addr;
3343 end_host_order = clib_host_to_net_u32 (tmp[0]);
3345 count = (end_host_order - start_host_order) + 1;
3346 memcpy (&this_addr.as_u8, mp->start_addr, 4);
3348 for (i = 0; i < count; i++)
3350 if ((rv = dslite_add_del_pool_addr (dm, &this_addr, mp->is_add)))
3353 increment_v4_address (&this_addr);
3357 REPLY_MACRO (VL_API_DSLITE_ADD_DEL_POOL_ADDR_RANGE_REPLY);
3360 static void *vl_api_dslite_add_del_pool_addr_range_t_print
3361 (vl_api_dslite_add_del_pool_addr_range_t * mp, void *handle)
3365 s = format (0, "SCRIPT: dslite_add_del_pool_addr_range ");
3366 s = format (s, "%U - %U\n",
3367 format_ip4_address, mp->start_addr,
3368 format_ip4_address, mp->end_addr);
3374 /* List of message types that this plugin understands */
3375 #define foreach_snat_plugin_api_msg \
3376 _(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range) \
3377 _(SNAT_INTERFACE_ADD_DEL_FEATURE, snat_interface_add_del_feature) \
3378 _(SNAT_ADD_STATIC_MAPPING, snat_add_static_mapping) \
3379 _(SNAT_CONTROL_PING, snat_control_ping) \
3380 _(SNAT_STATIC_MAPPING_DUMP, snat_static_mapping_dump) \
3381 _(SNAT_SHOW_CONFIG, snat_show_config) \
3382 _(SNAT_ADDRESS_DUMP, snat_address_dump) \
3383 _(SNAT_INTERFACE_DUMP, snat_interface_dump) \
3384 _(SNAT_SET_WORKERS, snat_set_workers) \
3385 _(SNAT_WORKER_DUMP, snat_worker_dump) \
3386 _(SNAT_ADD_DEL_INTERFACE_ADDR, snat_add_del_interface_addr) \
3387 _(SNAT_INTERFACE_ADDR_DUMP, snat_interface_addr_dump) \
3388 _(SNAT_IPFIX_ENABLE_DISABLE, snat_ipfix_enable_disable) \
3389 _(SNAT_USER_DUMP, snat_user_dump) \
3390 _(SNAT_USER_SESSION_DUMP, snat_user_session_dump) \
3391 _(SNAT_INTERFACE_ADD_DEL_OUTPUT_FEATURE, \
3392 snat_interface_add_del_output_feature) \
3393 _(SNAT_INTERFACE_OUTPUT_FEATURE_DUMP, \
3394 snat_interface_output_feature_dump) \
3395 _(SNAT_ADD_DET_MAP, snat_add_det_map) \
3396 _(SNAT_DET_FORWARD, snat_det_forward) \
3397 _(SNAT_DET_REVERSE, snat_det_reverse) \
3398 _(SNAT_DET_MAP_DUMP, snat_det_map_dump) \
3399 _(SNAT_DET_SET_TIMEOUTS, snat_det_set_timeouts) \
3400 _(SNAT_DET_GET_TIMEOUTS, snat_det_get_timeouts) \
3401 _(SNAT_DET_CLOSE_SESSION_OUT, snat_det_close_session_out) \
3402 _(SNAT_DET_CLOSE_SESSION_IN, snat_det_close_session_in) \
3403 _(SNAT_DET_SESSION_DUMP, snat_det_session_dump) \
3404 _(NAT_CONTROL_PING, nat_control_ping) \
3405 _(NAT_SHOW_CONFIG, nat_show_config) \
3406 _(NAT_SET_WORKERS, nat_set_workers) \
3407 _(NAT_WORKER_DUMP, nat_worker_dump) \
3408 _(NAT_IPFIX_ENABLE_DISABLE, nat_ipfix_enable_disable) \
3409 _(NAT44_ADD_DEL_ADDRESS_RANGE, nat44_add_del_address_range) \
3410 _(NAT44_INTERFACE_ADD_DEL_FEATURE, nat44_interface_add_del_feature) \
3411 _(NAT44_ADD_DEL_STATIC_MAPPING, nat44_add_del_static_mapping) \
3412 _(NAT44_STATIC_MAPPING_DUMP, nat44_static_mapping_dump) \
3413 _(NAT44_ADDRESS_DUMP, nat44_address_dump) \
3414 _(NAT44_INTERFACE_DUMP, nat44_interface_dump) \
3415 _(NAT44_ADD_DEL_INTERFACE_ADDR, nat44_add_del_interface_addr) \
3416 _(NAT44_INTERFACE_ADDR_DUMP, nat44_interface_addr_dump) \
3417 _(NAT44_USER_DUMP, nat44_user_dump) \
3418 _(NAT44_USER_SESSION_DUMP, nat44_user_session_dump) \
3419 _(NAT44_INTERFACE_ADD_DEL_OUTPUT_FEATURE, \
3420 nat44_interface_add_del_output_feature) \
3421 _(NAT44_INTERFACE_OUTPUT_FEATURE_DUMP, \
3422 nat44_interface_output_feature_dump) \
3423 _(NAT44_ADD_DEL_LB_STATIC_MAPPING, nat44_add_del_lb_static_mapping) \
3424 _(NAT44_LB_STATIC_MAPPING_DUMP, nat44_lb_static_mapping_dump) \
3425 _(NAT44_DEL_SESSION, nat44_del_session) \
3426 _(NAT_DET_ADD_DEL_MAP, nat_det_add_del_map) \
3427 _(NAT_DET_FORWARD, nat_det_forward) \
3428 _(NAT_DET_REVERSE, nat_det_reverse) \
3429 _(NAT_DET_MAP_DUMP, nat_det_map_dump) \
3430 _(NAT_DET_SET_TIMEOUTS, nat_det_set_timeouts) \
3431 _(NAT_DET_GET_TIMEOUTS, nat_det_get_timeouts) \
3432 _(NAT_DET_CLOSE_SESSION_OUT, nat_det_close_session_out) \
3433 _(NAT_DET_CLOSE_SESSION_IN, nat_det_close_session_in) \
3434 _(NAT_DET_SESSION_DUMP, nat_det_session_dump) \
3435 _(NAT64_ADD_DEL_POOL_ADDR_RANGE, nat64_add_del_pool_addr_range) \
3436 _(NAT64_POOL_ADDR_DUMP, nat64_pool_addr_dump) \
3437 _(NAT64_ADD_DEL_INTERFACE, nat64_add_del_interface) \
3438 _(NAT64_INTERFACE_DUMP, nat64_interface_dump) \
3439 _(NAT64_ADD_DEL_STATIC_BIB, nat64_add_del_static_bib) \
3440 _(NAT64_BIB_DUMP, nat64_bib_dump) \
3441 _(NAT64_SET_TIMEOUTS, nat64_set_timeouts) \
3442 _(NAT64_GET_TIMEOUTS, nat64_get_timeouts) \
3443 _(NAT64_ST_DUMP, nat64_st_dump) \
3444 _(NAT64_ADD_DEL_PREFIX, nat64_add_del_prefix) \
3445 _(NAT64_PREFIX_DUMP, nat64_prefix_dump) \
3446 _(DSLITE_ADD_DEL_POOL_ADDR_RANGE, dslite_add_del_pool_addr_range) \
3447 _(DSLITE_SET_AFTR_ADDR, dslite_set_aftr_addr)
3449 /* Set up the API message handling tables */
3450 static clib_error_t *
3451 snat_plugin_api_hookup (vlib_main_t * vm)
3453 snat_main_t *sm __attribute__ ((unused)) = &snat_main;
3455 vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
3457 vl_api_##n##_t_handler, \
3459 vl_api_##n##_t_endian, \
3460 vl_api_##n##_t_print, \
3461 sizeof(vl_api_##n##_t), 1);
3462 foreach_snat_plugin_api_msg;
3468 #define vl_msg_name_crc_list
3469 #include <nat/nat_all_api_h.h>
3470 #undef vl_msg_name_crc_list
3473 setup_message_id_table (snat_main_t * sm, api_main_t * am)
3475 #define _(id,n,crc) \
3476 vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base);
3477 foreach_vl_msg_name_crc_nat;
3482 plugin_custom_dump_configure (snat_main_t * sm)
3484 #define _(n,f) sm->api_main->msg_print_handlers \
3485 [VL_API_##n + sm->msg_id_base] \
3486 = (void *) vl_api_##f##_t_print;
3487 foreach_snat_plugin_api_msg;
3492 snat_api_init (vlib_main_t * vm, snat_main_t * sm)
3495 clib_error_t *error = 0;
3497 name = format (0, "snat_%08x%c", api_version, 0);
3499 /* Ask for a correctly-sized block of API message decode slots */
3501 vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE);
3503 error = snat_plugin_api_hookup (vm);
3505 /* Add our API messages to the global name_crc hash table */
3506 setup_message_id_table (sm, sm->api_main);
3508 plugin_custom_dump_configure (sm);
3516 * fd.io coding-style-patch-verification: ON
3519 * eval: (c-set-style "gnu")