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 SNAT plugin API implementation
21 #include <snat/snat.h>
22 #include <snat/snat_det.h>
23 #include <snat/nat64.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vlibsocket/api.h>
27 #include <snat/snat_msg_enum.h>
28 #include <vnet/fib/fib_table.h>
30 /* define message structures */
32 #include <snat/snat_all_api_h.h>
35 /* define generated endian-swappers */
37 #include <snat/snat_all_api_h.h>
40 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
42 #define REPLY_MSG_ID_BASE sm->msg_id_base
43 #include <vlibapi/api_helper_macros.h>
45 /* Get the API version number */
46 #define vl_api_version(n,v) static u32 api_version=(v);
47 #include <snat/snat_all_api_h.h>
50 /* Macro to finish up custom dump fns */
53 vl_print (handle, (char *)s); \
58 vl_api_snat_add_address_range_t_handler
59 (vl_api_snat_add_address_range_t * mp)
61 snat_main_t *sm = &snat_main;
62 vl_api_snat_add_address_range_reply_t *rmp;
63 ip4_address_t this_addr;
64 u32 start_host_order, end_host_order;
72 rv = VNET_API_ERROR_UNIMPLEMENTED;
76 if (sm->static_mapping_only)
78 rv = VNET_API_ERROR_FEATURE_DISABLED;
82 tmp = (u32 *) mp->first_ip_address;
83 start_host_order = clib_host_to_net_u32 (tmp[0]);
84 tmp = (u32 *) mp->last_ip_address;
85 end_host_order = clib_host_to_net_u32 (tmp[0]);
87 count = (end_host_order - start_host_order) + 1;
89 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
92 clib_warning ("%U - %U, %d addresses...",
93 format_ip4_address, mp->first_ip_address,
94 format_ip4_address, mp->last_ip_address, count);
96 memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
98 for (i = 0; i < count; i++)
101 snat_add_address (sm, &this_addr, vrf_id);
103 rv = snat_del_address (sm, this_addr, 0);
108 increment_v4_address (&this_addr);
112 REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
115 static void *vl_api_snat_add_address_range_t_print
116 (vl_api_snat_add_address_range_t * mp, void *handle)
120 s = format (0, "SCRIPT: snat_add_address_range ");
121 s = format (s, "%U ", format_ip4_address, mp->first_ip_address);
122 if (memcmp (mp->first_ip_address, mp->last_ip_address, 4))
124 s = format (s, " - %U ", format_ip4_address, mp->last_ip_address);
130 send_snat_address_details
131 (snat_address_t * a, unix_shared_memory_queue_t * q, u32 context)
133 vl_api_snat_address_details_t *rmp;
134 snat_main_t *sm = &snat_main;
136 rmp = vl_msg_api_alloc (sizeof (*rmp));
137 memset (rmp, 0, sizeof (*rmp));
138 rmp->_vl_msg_id = ntohs (VL_API_SNAT_ADDRESS_DETAILS + sm->msg_id_base);
140 clib_memcpy (rmp->ip_address, &(a->addr), 4);
141 if (a->fib_index != ~0)
143 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
144 rmp->vrf_id = ntohl (fib->ft_table_id);
148 rmp->context = context;
150 vl_msg_api_send_shmem (q, (u8 *) & rmp);
154 vl_api_snat_address_dump_t_handler (vl_api_snat_address_dump_t * mp)
156 unix_shared_memory_queue_t *q;
157 snat_main_t *sm = &snat_main;
160 q = vl_api_client_index_to_input_queue (mp->client_index);
165 vec_foreach (a, sm->addresses)
166 send_snat_address_details (a, q, mp->context);
170 static void *vl_api_snat_address_dump_t_print
171 (vl_api_snat_address_dump_t * mp, void *handle)
175 s = format (0, "SCRIPT: snat_address_dump ");
181 vl_api_snat_interface_add_del_feature_t_handler
182 (vl_api_snat_interface_add_del_feature_t * mp)
184 snat_main_t *sm = &snat_main;
185 vl_api_snat_interface_add_del_feature_reply_t *rmp;
186 u8 is_del = mp->is_add == 0;
187 u32 sw_if_index = ntohl (mp->sw_if_index);
190 VALIDATE_SW_IF_INDEX (mp);
192 rv = snat_interface_add_del (sw_if_index, mp->is_inside, is_del);
194 BAD_SW_IF_INDEX_LABEL;
196 REPLY_MACRO (VL_API_SNAT_INTERFACE_ADD_DEL_FEATURE_REPLY);
199 static void *vl_api_snat_interface_add_del_feature_t_print
200 (vl_api_snat_interface_add_del_feature_t * mp, void *handle)
204 s = format (0, "SCRIPT: snat_interface_add_del_feature ");
205 s = format (s, "sw_if_index %d %s %s",
206 clib_host_to_net_u32 (mp->sw_if_index),
207 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
213 send_snat_interface_details
214 (snat_interface_t * i, unix_shared_memory_queue_t * q, u32 context)
216 vl_api_snat_interface_details_t *rmp;
217 snat_main_t *sm = &snat_main;
219 rmp = vl_msg_api_alloc (sizeof (*rmp));
220 memset (rmp, 0, sizeof (*rmp));
221 rmp->_vl_msg_id = ntohs (VL_API_SNAT_INTERFACE_DETAILS + sm->msg_id_base);
222 rmp->sw_if_index = ntohl (i->sw_if_index);
223 rmp->is_inside = i->is_inside;
224 rmp->context = context;
226 vl_msg_api_send_shmem (q, (u8 *) & rmp);
230 vl_api_snat_interface_dump_t_handler (vl_api_snat_interface_dump_t * mp)
232 unix_shared_memory_queue_t *q;
233 snat_main_t *sm = &snat_main;
236 q = vl_api_client_index_to_input_queue (mp->client_index);
241 pool_foreach (i, sm->interfaces,
243 send_snat_interface_details(i, q, mp->context);
248 static void *vl_api_snat_interface_dump_t_print
249 (vl_api_snat_interface_dump_t * mp, void *handle)
253 s = format (0, "SCRIPT: snat_interface_dump ");
257 vl_api_snat_add_static_mapping_t_handler
258 (vl_api_snat_add_static_mapping_t * mp)
260 snat_main_t *sm = &snat_main;
261 vl_api_snat_add_static_mapping_reply_t *rmp;
262 ip4_address_t local_addr, external_addr;
263 u16 local_port = 0, external_port = 0;
264 u32 vrf_id, external_sw_if_index;
266 snat_protocol_t proto;
270 rv = VNET_API_ERROR_UNIMPLEMENTED;
274 memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
275 memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
276 if (mp->addr_only == 0)
278 local_port = clib_net_to_host_u16 (mp->local_port);
279 external_port = clib_net_to_host_u16 (mp->external_port);
281 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
282 external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
283 proto = ip_proto_to_snat_proto (mp->protocol);
285 rv = snat_add_static_mapping (local_addr, external_addr, local_port,
286 external_port, vrf_id, mp->addr_only,
287 external_sw_if_index, proto, mp->is_add);
290 REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
293 static void *vl_api_snat_add_static_mapping_t_print
294 (vl_api_snat_add_static_mapping_t * mp, void *handle)
298 s = format (0, "SCRIPT: snat_add_static_mapping ");
299 s = format (s, "protocol %d local_addr %U external_addr %U ",
301 format_ip4_address, mp->local_ip_address,
302 format_ip4_address, mp->external_ip_address);
304 if (mp->addr_only == 0)
305 s = format (s, "local_port %d external_port %d ",
306 clib_net_to_host_u16 (mp->local_port),
307 clib_net_to_host_u16 (mp->external_port));
309 if (mp->vrf_id != ~0)
310 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
312 if (mp->external_sw_if_index != ~0)
313 s = format (s, "external_sw_if_index %d",
314 clib_net_to_host_u32 (mp->external_sw_if_index));
319 send_snat_static_mapping_details
320 (snat_static_mapping_t * m, unix_shared_memory_queue_t * q, u32 context)
322 vl_api_snat_static_mapping_details_t *rmp;
323 snat_main_t *sm = &snat_main;
325 rmp = vl_msg_api_alloc (sizeof (*rmp));
326 memset (rmp, 0, sizeof (*rmp));
328 ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS + sm->msg_id_base);
330 rmp->addr_only = m->addr_only;
331 clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
332 clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
333 rmp->local_port = htons (m->local_port);
334 rmp->external_port = htons (m->external_port);
335 rmp->external_sw_if_index = ~0;
336 rmp->vrf_id = htonl (m->vrf_id);
337 rmp->protocol = snat_proto_to_ip_proto (m->proto);
338 rmp->context = context;
340 vl_msg_api_send_shmem (q, (u8 *) & rmp);
344 send_snat_static_map_resolve_details
345 (snat_static_map_resolve_t * m, unix_shared_memory_queue_t * q, u32 context)
347 vl_api_snat_static_mapping_details_t *rmp;
348 snat_main_t *sm = &snat_main;
350 rmp = vl_msg_api_alloc (sizeof (*rmp));
351 memset (rmp, 0, sizeof (*rmp));
353 ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS + sm->msg_id_base);
355 rmp->addr_only = m->addr_only;
356 clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
357 rmp->local_port = htons (m->l_port);
358 rmp->external_port = htons (m->e_port);
359 rmp->external_sw_if_index = htonl (m->sw_if_index);
360 rmp->vrf_id = htonl (m->vrf_id);
361 rmp->protocol = snat_proto_to_ip_proto (m->proto);
362 rmp->context = context;
364 vl_msg_api_send_shmem (q, (u8 *) & rmp);
368 vl_api_snat_static_mapping_dump_t_handler
369 (vl_api_snat_static_mapping_dump_t * mp)
371 unix_shared_memory_queue_t *q;
372 snat_main_t *sm = &snat_main;
373 snat_static_mapping_t *m;
374 snat_static_map_resolve_t *rp;
377 q = vl_api_client_index_to_input_queue (mp->client_index);
382 pool_foreach (m, sm->static_mappings,
384 send_snat_static_mapping_details (m, q, mp->context);
388 for (j = 0; j < vec_len (sm->to_resolve); j++)
390 rp = sm->to_resolve + j;
391 send_snat_static_map_resolve_details (rp, q, mp->context);
395 static void *vl_api_snat_static_mapping_dump_t_print
396 (vl_api_snat_static_mapping_dump_t * mp, void *handle)
400 s = format (0, "SCRIPT: snat_static_mapping_dump ");
406 vl_api_snat_control_ping_t_handler (vl_api_snat_control_ping_t * mp)
408 vl_api_snat_control_ping_reply_t *rmp;
409 snat_main_t *sm = &snat_main;
413 REPLY_MACRO2 (VL_API_SNAT_CONTROL_PING_REPLY,
415 rmp->vpe_pid = ntohl (getpid ());
420 static void *vl_api_snat_control_ping_t_print
421 (vl_api_snat_control_ping_t * mp, void *handle)
425 s = format (0, "SCRIPT: snat_control_ping ");
431 vl_api_snat_show_config_t_handler (vl_api_snat_show_config_t * mp)
433 vl_api_snat_show_config_reply_t *rmp;
434 snat_main_t *sm = &snat_main;
438 REPLY_MACRO2 (VL_API_SNAT_SHOW_CONFIG_REPLY,
440 rmp->translation_buckets = htonl (sm->translation_buckets);
441 rmp->translation_memory_size = htonl (sm->translation_memory_size);
442 rmp->user_buckets = htonl (sm->user_buckets);
443 rmp->user_memory_size = htonl (sm->user_memory_size);
444 rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
445 rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
446 rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
447 rmp->static_mapping_only = sm->static_mapping_only;
448 rmp->static_mapping_connection_tracking =
449 sm->static_mapping_connection_tracking;
450 rmp->deterministic = sm->deterministic;
455 static void *vl_api_snat_show_config_t_print
456 (vl_api_snat_show_config_t * mp, void *handle)
460 s = format (0, "SCRIPT: snat_show_config ");
466 vl_api_snat_set_workers_t_handler (vl_api_snat_set_workers_t * mp)
468 snat_main_t *sm = &snat_main;
469 vl_api_snat_set_workers_reply_t *rmp;
472 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
474 if (sm->num_workers < 2)
476 rv = VNET_API_ERROR_FEATURE_DISABLED;
480 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
481 rv = snat_set_workers (bitmap);
482 clib_bitmap_free (bitmap);
485 REPLY_MACRO (VL_API_SNAT_SET_WORKERS_REPLY);
488 static void *vl_api_snat_set_workers_t_print
489 (vl_api_snat_set_workers_t * mp, void *handle)
495 u64 mask = clib_net_to_host_u64 (mp->worker_mask);
497 s = format (0, "SCRIPT: snat_set_workers ");
498 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
500 clib_bitmap_foreach (i, bitmap,
503 s = format (s, "%d", i);
505 s = format (s, ",%d", i);
509 clib_bitmap_free (bitmap);
514 send_snat_worker_details
515 (u32 worker_index, unix_shared_memory_queue_t * q, u32 context)
517 vl_api_snat_worker_details_t *rmp;
518 snat_main_t *sm = &snat_main;
519 vlib_worker_thread_t *w =
520 vlib_worker_threads + worker_index + sm->first_worker_index;
522 rmp = vl_msg_api_alloc (sizeof (*rmp));
523 memset (rmp, 0, sizeof (*rmp));
524 rmp->_vl_msg_id = ntohs (VL_API_SNAT_WORKER_DETAILS + sm->msg_id_base);
525 rmp->context = context;
526 rmp->worker_index = htonl (worker_index);
527 rmp->lcore_id = htonl (w->lcore_id);
528 strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
530 vl_msg_api_send_shmem (q, (u8 *) & rmp);
534 vl_api_snat_worker_dump_t_handler (vl_api_snat_worker_dump_t * mp)
536 unix_shared_memory_queue_t *q;
537 snat_main_t *sm = &snat_main;
540 q = vl_api_client_index_to_input_queue (mp->client_index);
545 vec_foreach (worker_index, sm->workers)
546 send_snat_worker_details(*worker_index, q, mp->context);
550 static void *vl_api_snat_worker_dump_t_print
551 (vl_api_snat_worker_dump_t * mp, void *handle)
555 s = format (0, "SCRIPT: snat_worker_dump ");
561 vl_api_snat_add_del_interface_addr_t_handler
562 (vl_api_snat_add_del_interface_addr_t * mp)
564 snat_main_t *sm = &snat_main;
565 vl_api_snat_add_del_interface_addr_reply_t *rmp;
566 u8 is_del = mp->is_add == 0;
567 u32 sw_if_index = ntohl (mp->sw_if_index);
570 VALIDATE_SW_IF_INDEX (mp);
572 rv = snat_add_interface_address (sm, sw_if_index, is_del);
574 BAD_SW_IF_INDEX_LABEL;
576 REPLY_MACRO (VL_API_SNAT_ADD_DEL_INTERFACE_ADDR_REPLY);
579 static void *vl_api_snat_add_del_interface_addr_t_print
580 (vl_api_snat_add_del_interface_addr_t * mp, void *handle)
584 s = format (0, "SCRIPT: snat_add_del_interface_addr ");
585 s = format (s, "sw_if_index %d %s",
586 clib_host_to_net_u32 (mp->sw_if_index),
587 mp->is_add ? "" : "del");
593 send_snat_interface_addr_details
594 (u32 sw_if_index, unix_shared_memory_queue_t * q, u32 context)
596 vl_api_snat_interface_addr_details_t *rmp;
597 snat_main_t *sm = &snat_main;
599 rmp = vl_msg_api_alloc (sizeof (*rmp));
600 memset (rmp, 0, sizeof (*rmp));
602 ntohs (VL_API_SNAT_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
603 rmp->sw_if_index = ntohl (sw_if_index);
604 rmp->context = context;
606 vl_msg_api_send_shmem (q, (u8 *) & rmp);
610 vl_api_snat_interface_addr_dump_t_handler
611 (vl_api_snat_interface_addr_dump_t * mp)
613 unix_shared_memory_queue_t *q;
614 snat_main_t *sm = &snat_main;
617 q = vl_api_client_index_to_input_queue (mp->client_index);
622 vec_foreach (i, sm->auto_add_sw_if_indices)
623 send_snat_interface_addr_details(*i, q, mp->context);
627 static void *vl_api_snat_interface_addr_dump_t_print
628 (vl_api_snat_interface_addr_dump_t * mp, void *handle)
632 s = format (0, "SCRIPT: snat_interface_addr_dump ");
638 vl_api_snat_ipfix_enable_disable_t_handler
639 (vl_api_snat_ipfix_enable_disable_t * mp)
641 snat_main_t *sm = &snat_main;
642 vl_api_snat_ipfix_enable_disable_reply_t *rmp;
645 rv = snat_ipfix_logging_enable_disable (mp->enable,
651 REPLY_MACRO (VL_API_SNAT_IPFIX_ENABLE_DISABLE_REPLY);
654 static void *vl_api_snat_ipfix_enable_disable_t_print
655 (vl_api_snat_ipfix_enable_disable_t * mp, void *handle)
659 s = format (0, "SCRIPT: snat_ipfix_enable_disable ");
661 s = format (s, "domain %d ", clib_net_to_host_u32 (mp->domain_id));
663 s = format (s, "src_port %d ", clib_net_to_host_u16 (mp->src_port));
665 s = format (s, "disable ");
671 send_snat_user_details
672 (snat_user_t * u, unix_shared_memory_queue_t * q, u32 context)
674 vl_api_snat_user_details_t *rmp;
675 snat_main_t *sm = &snat_main;
676 fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
678 rmp = vl_msg_api_alloc (sizeof (*rmp));
679 memset (rmp, 0, sizeof (*rmp));
680 rmp->_vl_msg_id = ntohs (VL_API_SNAT_USER_DETAILS + sm->msg_id_base);
682 rmp->vrf_id = ntohl (fib->ft_table_id);
685 clib_memcpy (rmp->ip_address, &(u->addr), 4);
686 rmp->nsessions = ntohl (u->nsessions);
687 rmp->nstaticsessions = ntohl (u->nstaticsessions);
688 rmp->context = context;
690 vl_msg_api_send_shmem (q, (u8 *) & rmp);
694 vl_api_snat_user_dump_t_handler (vl_api_snat_user_dump_t * mp)
696 unix_shared_memory_queue_t *q;
697 snat_main_t *sm = &snat_main;
698 snat_main_per_thread_data_t *tsm;
701 q = vl_api_client_index_to_input_queue (mp->client_index);
706 vec_foreach (tsm, sm->per_thread_data)
707 vec_foreach (u, tsm->users)
708 send_snat_user_details (u, q, mp->context);
712 static void *vl_api_snat_user_dump_t_print
713 (vl_api_snat_user_dump_t * mp, void *handle)
717 s = format (0, "SCRIPT: snat_user_dump ");
723 send_snat_user_session_details
724 (snat_session_t * s, unix_shared_memory_queue_t * q, u32 context)
726 vl_api_snat_user_session_details_t *rmp;
727 snat_main_t *sm = &snat_main;
729 rmp = vl_msg_api_alloc (sizeof (*rmp));
730 memset (rmp, 0, sizeof (*rmp));
732 ntohs (VL_API_SNAT_USER_SESSION_DETAILS + sm->msg_id_base);
734 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
735 rmp->outside_port = s->out2in.port;
736 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
737 rmp->inside_port = s->in2out.port;
738 rmp->protocol = ntohs (snat_proto_to_ip_proto (s->in2out.protocol));
739 rmp->is_static = s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING ? 1 : 0;
740 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
741 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
742 rmp->total_pkts = ntohl (s->total_pkts);
743 rmp->context = context;
745 vl_msg_api_send_shmem (q, (u8 *) & rmp);
749 vl_api_snat_user_session_dump_t_handler
750 (vl_api_snat_user_session_dump_t * mp)
752 unix_shared_memory_queue_t *q;
753 snat_main_t *sm = &snat_main;
754 snat_main_per_thread_data_t *tsm;
756 clib_bihash_kv_8_8_t key, value;
757 snat_user_key_t ukey;
759 u32 session_index, head_index, elt_index;
760 dlist_elt_t *head, *elt;
762 q = vl_api_client_index_to_input_queue (mp->client_index);
768 clib_memcpy (&ukey.addr, mp->ip_address, 4);
769 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
770 key.key = ukey.as_u64;
771 if (!clib_bihash_search_8_8 (&sm->worker_by_in, &key, &value))
772 tsm = vec_elt_at_index (sm->per_thread_data, value.value);
774 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
775 if (clib_bihash_search_8_8 (&sm->user_hash, &key, &value))
777 u = pool_elt_at_index (tsm->users, value.value);
778 if (!u->nsessions && !u->nstaticsessions)
781 head_index = u->sessions_per_user_list_head_index;
782 head = pool_elt_at_index (tsm->list_pool, head_index);
783 elt_index = head->next;
784 elt = pool_elt_at_index (tsm->list_pool, elt_index);
785 session_index = elt->value;
786 while (session_index != ~0)
788 s = pool_elt_at_index (tsm->sessions, session_index);
790 send_snat_user_session_details (s, q, mp->context);
792 elt_index = elt->next;
793 elt = pool_elt_at_index (tsm->list_pool, elt_index);
794 session_index = elt->value;
798 static void *vl_api_snat_user_session_dump_t_print
799 (vl_api_snat_user_session_dump_t * mp, void *handle)
803 s = format (0, "SCRIPT: snat_user_session_dump ");
804 s = format (s, "ip_address %U vrf_id %d\n",
805 format_ip4_address, mp->ip_address,
806 clib_net_to_host_u32 (mp->vrf_id));
811 /****************************/
812 /*** detrministic NAT/CGN ***/
813 /****************************/
816 vl_api_snat_add_det_map_t_handler (vl_api_snat_add_det_map_t * mp)
818 snat_main_t *sm = &snat_main;
819 vl_api_snat_add_det_map_reply_t *rmp;
821 ip4_address_t in_addr, out_addr;
823 clib_memcpy (&in_addr, mp->in_addr, 4);
824 clib_memcpy (&out_addr, mp->out_addr, 4);
825 rv = snat_det_add_map (sm, &in_addr, mp->in_plen, &out_addr,
826 mp->out_plen, mp->is_add);
828 REPLY_MACRO (VL_API_SNAT_ADD_DET_MAP_REPLY);
831 static void *vl_api_snat_add_det_map_t_print
832 (vl_api_snat_add_det_map_t * mp, void *handle)
836 s = format (0, "SCRIPT: snat_add_det_map ");
837 s = format (s, "inside address %U/%d outside address %U/%d\n",
838 format_ip4_address, mp->in_addr, mp->in_plen,
839 format_ip4_address, mp->out_addr, mp->out_plen);
845 vl_api_snat_det_forward_t_handler (vl_api_snat_det_forward_t * mp)
847 snat_main_t *sm = &snat_main;
848 vl_api_snat_det_forward_reply_t *rmp;
850 u16 lo_port = 0, hi_port = 0;
852 ip4_address_t in_addr, out_addr;
855 clib_memcpy (&in_addr, mp->in_addr, 4);
856 dm = snat_det_map_by_user (sm, &in_addr);
859 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
863 snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
864 hi_port = lo_port + dm->ports_per_host - 1;
868 REPLY_MACRO2 (VL_API_SNAT_DET_FORWARD_REPLY,
870 rmp->out_port_lo = ntohs (lo_port);
871 rmp->out_port_hi = ntohs (hi_port);
873 memset (rmp->out_addr, 0, 16);
874 clib_memcpy (rmp->out_addr, &out_addr, 4);
879 static void *vl_api_snat_det_forward_t_print
880 (vl_api_snat_det_forward_t * mp, void *handle)
884 s = format (0, "SCRIPT: smat_det_forward_t");
885 s = format (s, "inside ip address %U\n", format_ip4_address, mp->in_addr);
891 vl_api_snat_det_reverse_t_handler (vl_api_snat_det_reverse_t * mp)
893 snat_main_t *sm = &snat_main;
894 vl_api_snat_det_reverse_reply_t *rmp;
896 ip4_address_t out_addr, in_addr;
900 clib_memcpy (&out_addr, mp->out_addr, 4);
901 dm = snat_det_map_by_out (sm, &out_addr);
904 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
908 snat_det_reverse (dm, &out_addr, htons (mp->out_port), &in_addr);
912 REPLY_MACRO2 (VL_API_SNAT_DET_REVERSE_REPLY,
915 memset (rmp->in_addr, 0, 16);
916 clib_memcpy (rmp->in_addr, &in_addr, 4);
921 static void *vl_api_snat_det_reverse_t_print
922 (vl_api_snat_det_reverse_t * mp, void *handle)
926 s = format (0, "SCRIPT: smat_det_reverse_t");
927 s = format (s, "outside ip address %U outside port %d",
928 format_ip4_address, mp->out_addr, ntohs (mp->out_port));
934 sent_snat_det_map_details
935 (snat_det_map_t * m, unix_shared_memory_queue_t * q, u32 context)
937 vl_api_snat_det_map_details_t *rmp;
938 snat_main_t *sm = &snat_main;
940 rmp = vl_msg_api_alloc (sizeof (*rmp));
941 memset (rmp, 0, sizeof (*rmp));
942 rmp->_vl_msg_id = ntohs (VL_API_SNAT_DET_MAP_DETAILS + sm->msg_id_base);
944 clib_memcpy (rmp->in_addr, &m->in_addr, 4);
945 rmp->in_plen = m->in_plen;
946 clib_memcpy (rmp->out_addr, &m->out_addr, 4);
947 rmp->out_plen = m->out_plen;
948 rmp->sharing_ratio = htonl (m->sharing_ratio);
949 rmp->ports_per_host = htons (m->ports_per_host);
950 rmp->ses_num = htonl (m->ses_num);
951 rmp->context = context;
953 vl_msg_api_send_shmem (q, (u8 *) & rmp);
957 vl_api_snat_det_map_dump_t_handler (vl_api_snat_det_map_dump_t * mp)
959 unix_shared_memory_queue_t *q;
960 snat_main_t *sm = &snat_main;
963 q = vl_api_client_index_to_input_queue (mp->client_index);
968 vec_foreach(m, sm->det_maps)
969 sent_snat_det_map_details(m, q, mp->context);
973 static void *vl_api_snat_det_map_dump_t_print
974 (vl_api_snat_det_map_dump_t * mp, void *handle)
978 s = format (0, "SCRIPT: snat_det_map_dump ");
984 vl_api_snat_det_set_timeouts_t_handler (vl_api_snat_det_set_timeouts_t * mp)
986 snat_main_t *sm = &snat_main;
987 vl_api_snat_det_set_timeouts_reply_t *rmp;
990 sm->udp_timeout = ntohl (mp->udp);
991 sm->tcp_established_timeout = ntohl (mp->tcp_established);
992 sm->tcp_transitory_timeout = ntohl (mp->tcp_transitory);
993 sm->icmp_timeout = ntohl (mp->icmp);
995 REPLY_MACRO (VL_API_SNAT_DET_SET_TIMEOUTS_REPLY);
998 static void *vl_api_snat_det_set_timeouts_t_print
999 (vl_api_snat_det_set_timeouts_t * mp, void *handle)
1003 s = format (0, "SCRIPT: snat_det_set_timeouts ");
1004 s = format (s, "udp %d tcp_established %d tcp_transitory %d icmp %d\n",
1006 ntohl (mp->tcp_established),
1007 ntohl (mp->tcp_transitory), ntohl (mp->icmp));
1013 vl_api_snat_det_get_timeouts_t_handler (vl_api_snat_det_get_timeouts_t * mp)
1015 snat_main_t *sm = &snat_main;
1016 vl_api_snat_det_get_timeouts_reply_t *rmp;
1020 REPLY_MACRO2 (VL_API_SNAT_DET_GET_TIMEOUTS_REPLY,
1022 rmp->udp = htonl (sm->udp_timeout);
1023 rmp->tcp_established = htonl (sm->tcp_established_timeout);
1024 rmp->tcp_transitory = htonl (sm->tcp_transitory_timeout);
1025 rmp->icmp = htonl (sm->icmp_timeout);
1030 static void *vl_api_snat_det_get_timeouts_t_print
1031 (vl_api_snat_det_get_timeouts_t * mp, void *handle)
1035 s = format (0, "SCRIPT: snat_det_get_timeouts");
1041 vl_api_snat_det_close_session_out_t_handler
1042 (vl_api_snat_det_close_session_out_t * mp)
1044 snat_main_t *sm = &snat_main;
1045 vl_api_snat_det_close_session_out_reply_t *rmp;
1046 ip4_address_t out_addr, ext_addr, in_addr;
1047 snat_det_out_key_t key;
1049 snat_det_session_t *ses;
1052 clib_memcpy (&out_addr, mp->out_addr, 4);
1053 clib_memcpy (&ext_addr, mp->ext_addr, 4);
1055 dm = snat_det_map_by_out (sm, &out_addr);
1058 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1061 snat_det_reverse (dm, &ext_addr, ntohs (mp->out_port), &in_addr);
1062 key.ext_host_addr = ext_addr;
1063 key.ext_host_port = mp->ext_port;
1064 key.out_port = mp->out_port;
1065 ses = snat_det_get_ses_by_out (dm, &in_addr, key.as_u64);
1068 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1071 snat_det_ses_close (dm, ses);
1074 REPLY_MACRO (VL_API_SNAT_DET_CLOSE_SESSION_OUT_REPLY);
1077 static void *vl_api_snat_det_close_session_out_t_print
1078 (vl_api_snat_det_close_session_out_t * mp, void *handle)
1082 s = format (0, "SCRIPT: snat_det_close_session_out ");
1083 s = format (s, "out_addr %U out_port %d "
1084 "ext_addr %U ext_port %d\n",
1085 format_ip4_address, mp->out_addr, ntohs (mp->out_port),
1086 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
1092 vl_api_snat_det_close_session_in_t_handler
1093 (vl_api_snat_det_close_session_in_t * mp)
1095 snat_main_t *sm = &snat_main;
1096 vl_api_snat_det_close_session_in_reply_t *rmp;
1097 ip4_address_t in_addr, ext_addr;
1098 snat_det_out_key_t key;
1100 snat_det_session_t *ses;
1103 clib_memcpy (&in_addr, mp->in_addr, 4);
1104 clib_memcpy (&ext_addr, mp->ext_addr, 4);
1106 dm = snat_det_map_by_user (sm, &in_addr);
1109 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1112 key.ext_host_addr = ext_addr;
1113 key.ext_host_port = mp->ext_port;
1114 ses = snat_det_find_ses_by_in (dm, &in_addr, mp->in_port, key);
1117 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1120 snat_det_ses_close (dm, ses);
1123 REPLY_MACRO (VL_API_SNAT_DET_CLOSE_SESSION_OUT_REPLY);
1126 static void *vl_api_snat_det_close_session_in_t_print
1127 (vl_api_snat_det_close_session_in_t * mp, void *handle)
1130 s = format (0, "SCRIPT: snat_det_close_session_in ");
1131 s = format (s, "in_addr %U in_port %d "
1132 "ext_addr %U ext_port %d\n",
1133 format_ip4_address, mp->in_addr, ntohs (mp->in_port),
1134 format_ip4_address, mp->ext_addr, ntohs (mp->ext_port));
1140 send_snat_det_session_details
1141 (snat_det_session_t * s, unix_shared_memory_queue_t * q, u32 context)
1143 vl_api_snat_det_session_details_t *rmp;
1144 snat_main_t *sm = &snat_main;
1146 rmp = vl_msg_api_alloc (sizeof (*rmp));
1147 memset (rmp, 0, sizeof (*rmp));
1148 rmp->_vl_msg_id = ntohs (VL_API_SNAT_DET_SESSION_DETAILS + sm->msg_id_base);
1150 rmp->in_port = s->in_port;
1151 clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
1152 rmp->ext_port = s->out.ext_host_port;
1153 rmp->out_port = s->out.out_port;
1154 rmp->state = s->state;
1155 rmp->expire = ntohl (s->expire);
1156 rmp->context = context;
1158 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1162 vl_api_snat_det_session_dump_t_handler (vl_api_snat_det_session_dump_t * mp)
1164 unix_shared_memory_queue_t *q;
1165 snat_main_t *sm = &snat_main;
1166 ip4_address_t user_addr;
1168 snat_det_session_t *s, empty_ses;
1171 q = vl_api_client_index_to_input_queue (mp->client_index);
1177 memset (&empty_ses, 0, sizeof (empty_ses));
1178 clib_memcpy (&user_addr, mp->user_addr, 4);
1179 dm = snat_det_map_by_user (sm, &user_addr);
1183 s = dm->sessions + snat_det_user_ses_offset (&user_addr, dm->in_plen);
1184 for (i = 0; i < SNAT_DET_SES_PER_USER; i++)
1187 send_snat_det_session_details (s, q, mp->context);
1192 static void *vl_api_snat_det_session_dump_t_print
1193 (vl_api_snat_det_session_dump_t * mp, void *handle)
1197 s = format (0, "SCRIPT: snat_det_session_dump ");
1198 s = format (s, "user_addr %U\n", format_ip4_address, mp->user_addr);
1208 vl_api_nat64_add_del_pool_addr_range_t_handler
1209 (vl_api_nat64_add_del_pool_addr_range_t * mp)
1211 vl_api_nat64_add_del_pool_addr_range_reply_t *rmp;
1212 snat_main_t *sm = &snat_main;
1213 nat64_main_t *nm = &nat64_main;
1215 ip4_address_t this_addr;
1216 u32 start_host_order, end_host_order;
1221 if (nm->is_disabled)
1223 rv = VNET_API_ERROR_FEATURE_DISABLED;
1227 tmp = (u32 *) mp->start_addr;
1228 start_host_order = clib_host_to_net_u32 (tmp[0]);
1229 tmp = (u32 *) mp->end_addr;
1230 end_host_order = clib_host_to_net_u32 (tmp[0]);
1232 count = (end_host_order - start_host_order) + 1;
1234 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
1236 memcpy (&this_addr.as_u8, mp->start_addr, 4);
1238 for (i = 0; i < count; i++)
1240 if ((rv = nat64_add_del_pool_addr (&this_addr, vrf_id, mp->is_add)))
1243 increment_v4_address (&this_addr);
1247 REPLY_MACRO (VL_API_NAT64_ADD_DEL_POOL_ADDR_RANGE_REPLY);
1250 static void *vl_api_nat64_add_del_pool_addr_range_t_print
1251 (vl_api_nat64_add_del_pool_addr_range_t * mp, void *handle)
1255 s = format (0, "SCRIPT: nat64_add_del_pool_addr_range ");
1256 s = format (s, "%U - %U vrf_id %u %s\n",
1257 format_ip4_address, mp->start_addr,
1258 format_ip4_address, mp->end_addr,
1259 ntohl (mp->vrf_id), mp->is_add ? "" : "del");
1264 typedef struct nat64_api_walk_ctx_t_
1266 unix_shared_memory_queue_t *q;
1268 } nat64_api_walk_ctx_t;
1271 nat64_api_pool_walk (snat_address_t * a, void *arg)
1273 vl_api_nat64_pool_addr_details_t *rmp;
1274 snat_main_t *sm = &snat_main;
1275 nat64_api_walk_ctx_t *ctx = arg;
1277 rmp = vl_msg_api_alloc (sizeof (*rmp));
1278 memset (rmp, 0, sizeof (*rmp));
1279 rmp->_vl_msg_id = ntohs (VL_API_NAT64_POOL_ADDR_DETAILS + sm->msg_id_base);
1280 clib_memcpy (rmp->address, &(a->addr), 4);
1281 if (a->fib_index != ~0)
1283 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP6);
1286 rmp->vrf_id = ntohl (fib->ft_table_id);
1290 rmp->context = ctx->context;
1292 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
1298 vl_api_nat64_pool_addr_dump_t_handler (vl_api_nat64_pool_addr_dump_t * mp)
1300 unix_shared_memory_queue_t *q;
1301 nat64_main_t *nm = &nat64_main;
1303 if (nm->is_disabled)
1306 q = vl_api_client_index_to_input_queue (mp->client_index);
1310 nat64_api_walk_ctx_t ctx = {
1312 .context = mp->context,
1315 nat64_pool_addr_walk (nat64_api_pool_walk, &ctx);
1319 vl_api_nat64_pool_addr_dump_t_print (vl_api_nat64_pool_addr_dump_t * mp,
1324 s = format (0, "SCRIPT: nat64_pool_addr_dump\n");
1330 vl_api_nat64_add_del_interface_t_handler (vl_api_nat64_add_del_interface_t *
1333 snat_main_t *sm = &snat_main;
1334 nat64_main_t *nm = &nat64_main;
1335 vl_api_nat64_add_del_interface_reply_t *rmp;
1338 if (nm->is_disabled)
1340 rv = VNET_API_ERROR_FEATURE_DISABLED;
1344 VALIDATE_SW_IF_INDEX (mp);
1347 nat64_add_del_interface (ntohl (mp->sw_if_index), mp->is_inside,
1350 BAD_SW_IF_INDEX_LABEL;
1353 REPLY_MACRO (VL_API_NAT64_ADD_DEL_INTERFACE_REPLY);
1357 vl_api_nat64_add_del_interface_t_print (vl_api_nat64_add_del_interface_t * mp,
1362 s = format (0, "SCRIPT: nat64_add_del_interface ");
1363 s = format (s, "sw_if_index %d %s %s",
1364 clib_host_to_net_u32 (mp->sw_if_index),
1365 mp->is_inside ? "in" : "out", mp->is_add ? "" : "del");
1371 nat64_api_interface_walk (snat_interface_t * i, void *arg)
1373 vl_api_nat64_interface_details_t *rmp;
1374 snat_main_t *sm = &snat_main;
1375 nat64_api_walk_ctx_t *ctx = arg;
1377 rmp = vl_msg_api_alloc (sizeof (*rmp));
1378 memset (rmp, 0, sizeof (*rmp));
1379 rmp->_vl_msg_id = ntohs (VL_API_NAT64_INTERFACE_DETAILS + sm->msg_id_base);
1380 rmp->sw_if_index = ntohl (i->sw_if_index);
1381 rmp->is_inside = i->is_inside;
1382 rmp->context = ctx->context;
1384 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
1390 vl_api_nat64_interface_dump_t_handler (vl_api_nat64_interface_dump_t * mp)
1392 unix_shared_memory_queue_t *q;
1393 nat64_main_t *nm = &nat64_main;
1395 if (nm->is_disabled)
1398 q = vl_api_client_index_to_input_queue (mp->client_index);
1402 nat64_api_walk_ctx_t ctx = {
1404 .context = mp->context,
1407 nat64_interfaces_walk (nat64_api_interface_walk, &ctx);
1411 vl_api_nat64_interface_dump_t_print (vl_api_nat64_interface_dump_t * mp,
1416 s = format (0, "SCRIPT: snat_interface_dump ");
1422 vl_api_nat64_add_del_static_bib_t_handler
1423 (vl_api_nat64_add_del_static_bib_t * mp)
1425 snat_main_t *sm = &snat_main;
1426 nat64_main_t *nm = &nat64_main;
1427 vl_api_nat64_add_del_static_bib_reply_t *rmp;
1428 ip6_address_t in_addr;
1429 ip4_address_t out_addr;
1432 if (nm->is_disabled)
1434 rv = VNET_API_ERROR_FEATURE_DISABLED;
1438 memcpy (&in_addr.as_u8, mp->i_addr, 16);
1439 memcpy (&out_addr.as_u8, mp->o_addr, 4);
1442 nat64_add_del_static_bib_entry (&in_addr, &out_addr,
1443 clib_net_to_host_u16 (mp->i_port),
1444 clib_net_to_host_u16 (mp->o_port),
1446 clib_net_to_host_u32 (mp->vrf_id),
1450 REPLY_MACRO (VL_API_NAT64_ADD_DEL_STATIC_BIB_REPLY);
1453 static void *vl_api_nat64_add_del_static_bib_t_print
1454 (vl_api_nat64_add_del_static_bib_t * mp, void *handle)
1458 s = format (0, "SCRIPT: nat64_add_del_static_bib ");
1459 s = format (s, "protocol %d i_addr %U o_addr %U ",
1461 format_ip6_address, mp->i_addr, format_ip4_address, mp->o_addr);
1463 if (mp->vrf_id != ~0)
1464 s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
1470 nat64_api_bib_walk (nat64_db_bib_entry_t * bibe, void *arg)
1472 vl_api_nat64_bib_details_t *rmp;
1473 snat_main_t *sm = &snat_main;
1474 nat64_api_walk_ctx_t *ctx = arg;
1477 fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
1481 rmp = vl_msg_api_alloc (sizeof (*rmp));
1482 memset (rmp, 0, sizeof (*rmp));
1483 rmp->_vl_msg_id = ntohs (VL_API_NAT64_BIB_DETAILS + sm->msg_id_base);
1484 rmp->context = ctx->context;
1485 clib_memcpy (rmp->i_addr, &(bibe->in_addr), 16);
1486 clib_memcpy (rmp->o_addr, &(bibe->out_addr), 4);
1487 rmp->i_port = bibe->in_port;
1488 rmp->o_port = bibe->out_port;
1489 rmp->vrf_id = ntohl (fib->ft_table_id);
1490 rmp->proto = snat_proto_to_ip_proto (bibe->proto);
1491 rmp->is_static = bibe->is_static;
1492 rmp->ses_num = ntohl (bibe->ses_num);
1494 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
1500 vl_api_nat64_bib_dump_t_handler (vl_api_nat64_bib_dump_t * mp)
1502 unix_shared_memory_queue_t *q;
1503 nat64_main_t *nm = &nat64_main;
1504 snat_protocol_t proto;
1506 if (nm->is_disabled)
1509 q = vl_api_client_index_to_input_queue (mp->client_index);
1513 nat64_api_walk_ctx_t ctx = {
1515 .context = mp->context,
1518 proto = ip_proto_to_snat_proto (mp->proto);
1520 nat64_db_bib_walk (&nm->db, proto, nat64_api_bib_walk, &ctx);
1524 vl_api_nat64_bib_dump_t_print (vl_api_nat64_bib_dump_t * mp, void *handle)
1528 s = format (0, "SCRIPT: snat_bib_dump protocol %d", mp->proto);
1534 vl_api_nat64_set_timeouts_t_handler (vl_api_nat64_set_timeouts_t * mp)
1536 snat_main_t *sm = &snat_main;
1537 nat64_main_t *nm = &nat64_main;
1538 vl_api_nat64_set_timeouts_reply_t *rmp;
1541 if (nm->is_disabled)
1543 rv = VNET_API_ERROR_FEATURE_DISABLED;
1547 rv = nat64_set_icmp_timeout (ntohl (mp->icmp));
1550 rv = nat64_set_udp_timeout (ntohl (mp->udp));
1554 nat64_set_tcp_timeouts (ntohl (mp->tcp_trans), ntohl (mp->tcp_est),
1555 ntohl (mp->tcp_incoming_syn));
1558 REPLY_MACRO (VL_API_NAT64_SET_TIMEOUTS_REPLY);
1561 static void *vl_api_nat64_set_timeouts_t_print
1562 (vl_api_nat64_set_timeouts_t * mp, void *handle)
1566 s = format (0, "SCRIPT: nat64_set_timeouts ");
1569 "udp %d icmp %d, tcp_trans %d, tcp_est %d, tcp_incoming_syn %d\n",
1570 ntohl (mp->udp), ntohl (mp->icmp), ntohl (mp->tcp_trans),
1571 ntohl (mp->tcp_est), ntohl (mp->tcp_incoming_syn));
1577 vl_api_nat64_get_timeouts_t_handler (vl_api_nat64_get_timeouts_t * mp)
1579 snat_main_t *sm = &snat_main;
1580 nat64_main_t *nm = &nat64_main;
1581 vl_api_nat64_get_timeouts_reply_t *rmp;
1584 if (nm->is_disabled)
1588 REPLY_MACRO2 (VL_API_NAT64_GET_TIMEOUTS_REPLY,
1590 rmp->udp = htonl (nat64_get_udp_timeout());
1591 rmp->icmp = htonl (nat64_get_icmp_timeout());
1592 rmp->tcp_trans = htonl (nat64_get_tcp_trans_timeout());
1593 rmp->tcp_est = htonl (nat64_get_tcp_est_timeout());
1594 rmp->tcp_incoming_syn = htonl (nat64_get_tcp_incoming_syn_timeout());
1599 static void *vl_api_nat64_get_timeouts_t_print
1600 (vl_api_nat64_get_timeouts_t * mp, void *handle)
1604 s = format (0, "SCRIPT: nat64_get_timeouts");
1610 nat64_api_st_walk (nat64_db_st_entry_t * ste, void *arg)
1612 vl_api_nat64_st_details_t *rmp;
1613 snat_main_t *sm = &snat_main;
1614 nat64_api_walk_ctx_t *ctx = arg;
1615 nat64_main_t *nm = &nat64_main;
1616 nat64_db_bib_entry_t *bibe;
1619 bibe = nat64_db_bib_entry_by_index (&nm->db, ste->proto, ste->bibe_index);
1623 fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
1627 rmp = vl_msg_api_alloc (sizeof (*rmp));
1628 memset (rmp, 0, sizeof (*rmp));
1629 rmp->_vl_msg_id = ntohs (VL_API_NAT64_ST_DETAILS + sm->msg_id_base);
1630 rmp->context = ctx->context;
1631 clib_memcpy (rmp->il_addr, &(bibe->in_addr), 16);
1632 clib_memcpy (rmp->ol_addr, &(bibe->out_addr), 4);
1633 rmp->il_port = bibe->in_port;
1634 rmp->ol_port = bibe->out_port;
1635 clib_memcpy (rmp->ir_addr, &(ste->in_r_addr), 16);
1636 clib_memcpy (rmp->or_addr, &(ste->out_r_addr), 4);
1637 rmp->il_port = ste->r_port;
1638 rmp->vrf_id = ntohl (fib->ft_table_id);
1639 rmp->proto = snat_proto_to_ip_proto (ste->proto);
1641 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
1647 vl_api_nat64_st_dump_t_handler (vl_api_nat64_st_dump_t * mp)
1649 unix_shared_memory_queue_t *q;
1650 nat64_main_t *nm = &nat64_main;
1651 snat_protocol_t proto;
1653 if (nm->is_disabled)
1656 q = vl_api_client_index_to_input_queue (mp->client_index);
1660 nat64_api_walk_ctx_t ctx = {
1662 .context = mp->context,
1665 proto = ip_proto_to_snat_proto (mp->proto);
1667 nat64_db_st_walk (&nm->db, proto, nat64_api_st_walk, &ctx);
1671 vl_api_nat64_st_dump_t_print (vl_api_nat64_st_dump_t * mp, void *handle)
1675 s = format (0, "SCRIPT: snat_st_dump protocol %d", mp->proto);
1681 vl_api_nat64_add_del_prefix_t_handler (vl_api_nat64_add_del_prefix_t * mp)
1683 vl_api_nat64_add_del_prefix_reply_t *rmp;
1684 snat_main_t *sm = &snat_main;
1685 nat64_main_t *nm = &nat64_main;
1686 ip6_address_t prefix;
1689 if (nm->is_disabled)
1691 rv = VNET_API_ERROR_FEATURE_DISABLED;
1695 memcpy (&prefix.as_u8, mp->prefix, 16);
1698 nat64_add_del_prefix (&prefix, mp->prefix_len,
1699 clib_net_to_host_u32 (mp->vrf_id), mp->is_add);
1701 REPLY_MACRO (VL_API_NAT64_ADD_DEL_PREFIX_REPLY);
1705 vl_api_nat64_add_del_prefix_t_print (vl_api_nat64_add_del_prefix_t * mp,
1710 s = format (0, "SCRIPT: nat64_add_del_prefix %U/%u vrf_id %u %s\n",
1711 format_ip6_address, mp->prefix, mp->prefix_len,
1712 ntohl (mp->vrf_id), mp->is_add ? "" : "del");
1718 nat64_api_prefix_walk (nat64_prefix_t * p, void *arg)
1720 vl_api_nat64_prefix_details_t *rmp;
1721 snat_main_t *sm = &snat_main;
1722 nat64_api_walk_ctx_t *ctx = arg;
1724 rmp = vl_msg_api_alloc (sizeof (*rmp));
1725 memset (rmp, 0, sizeof (*rmp));
1726 rmp->_vl_msg_id = ntohs (VL_API_NAT64_PREFIX_DETAILS + sm->msg_id_base);
1727 clib_memcpy (rmp->prefix, &(p->prefix), 16);
1728 rmp->prefix_len = p->plen;
1729 rmp->vrf_id = ntohl (p->vrf_id);
1730 rmp->context = ctx->context;
1732 vl_msg_api_send_shmem (ctx->q, (u8 *) & rmp);
1738 vl_api_nat64_prefix_dump_t_handler (vl_api_nat64_prefix_dump_t * mp)
1740 unix_shared_memory_queue_t *q;
1741 nat64_main_t *nm = &nat64_main;
1743 if (nm->is_disabled)
1746 q = vl_api_client_index_to_input_queue (mp->client_index);
1750 nat64_api_walk_ctx_t ctx = {
1752 .context = mp->context,
1755 nat64_prefix_walk (nat64_api_prefix_walk, &ctx);
1759 vl_api_nat64_prefix_dump_t_print (vl_api_nat64_prefix_dump_t * mp,
1764 s = format (0, "SCRIPT: nat64_prefix_dump\n");
1769 /* List of message types that this plugin understands */
1770 #define foreach_snat_plugin_api_msg \
1771 _(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range) \
1772 _(SNAT_INTERFACE_ADD_DEL_FEATURE, snat_interface_add_del_feature) \
1773 _(SNAT_ADD_STATIC_MAPPING, snat_add_static_mapping) \
1774 _(SNAT_CONTROL_PING, snat_control_ping) \
1775 _(SNAT_STATIC_MAPPING_DUMP, snat_static_mapping_dump) \
1776 _(SNAT_SHOW_CONFIG, snat_show_config) \
1777 _(SNAT_ADDRESS_DUMP, snat_address_dump) \
1778 _(SNAT_INTERFACE_DUMP, snat_interface_dump) \
1779 _(SNAT_SET_WORKERS, snat_set_workers) \
1780 _(SNAT_WORKER_DUMP, snat_worker_dump) \
1781 _(SNAT_ADD_DEL_INTERFACE_ADDR, snat_add_del_interface_addr) \
1782 _(SNAT_INTERFACE_ADDR_DUMP, snat_interface_addr_dump) \
1783 _(SNAT_IPFIX_ENABLE_DISABLE, snat_ipfix_enable_disable) \
1784 _(SNAT_USER_DUMP, snat_user_dump) \
1785 _(SNAT_USER_SESSION_DUMP, snat_user_session_dump) \
1786 _(SNAT_ADD_DET_MAP, snat_add_det_map) \
1787 _(SNAT_DET_FORWARD, snat_det_forward) \
1788 _(SNAT_DET_REVERSE, snat_det_reverse) \
1789 _(SNAT_DET_MAP_DUMP, snat_det_map_dump) \
1790 _(SNAT_DET_SET_TIMEOUTS, snat_det_set_timeouts) \
1791 _(SNAT_DET_GET_TIMEOUTS, snat_det_get_timeouts) \
1792 _(SNAT_DET_CLOSE_SESSION_OUT, snat_det_close_session_out) \
1793 _(SNAT_DET_CLOSE_SESSION_IN, snat_det_close_session_in) \
1794 _(SNAT_DET_SESSION_DUMP, snat_det_session_dump) \
1795 _(NAT64_ADD_DEL_POOL_ADDR_RANGE, nat64_add_del_pool_addr_range) \
1796 _(NAT64_POOL_ADDR_DUMP, nat64_pool_addr_dump) \
1797 _(NAT64_ADD_DEL_INTERFACE, nat64_add_del_interface) \
1798 _(NAT64_INTERFACE_DUMP, nat64_interface_dump) \
1799 _(NAT64_ADD_DEL_STATIC_BIB, nat64_add_del_static_bib) \
1800 _(NAT64_BIB_DUMP, nat64_bib_dump) \
1801 _(NAT64_SET_TIMEOUTS, nat64_set_timeouts) \
1802 _(NAT64_GET_TIMEOUTS, nat64_get_timeouts) \
1803 _(NAT64_ST_DUMP, nat64_st_dump) \
1804 _(NAT64_ADD_DEL_PREFIX, nat64_add_del_prefix) \
1805 _(NAT64_PREFIX_DUMP, nat64_prefix_dump)
1807 /* Set up the API message handling tables */
1808 static clib_error_t *
1809 snat_plugin_api_hookup (vlib_main_t * vm)
1811 snat_main_t *sm __attribute__ ((unused)) = &snat_main;
1813 vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
1815 vl_api_##n##_t_handler, \
1817 vl_api_##n##_t_endian, \
1818 vl_api_##n##_t_print, \
1819 sizeof(vl_api_##n##_t), 1);
1820 foreach_snat_plugin_api_msg;
1826 #define vl_msg_name_crc_list
1827 #include <snat/snat_all_api_h.h>
1828 #undef vl_msg_name_crc_list
1831 setup_message_id_table (snat_main_t * sm, api_main_t * am)
1833 #define _(id,n,crc) \
1834 vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base);
1835 foreach_vl_msg_name_crc_snat;
1840 plugin_custom_dump_configure (snat_main_t * sm)
1842 #define _(n,f) sm->api_main->msg_print_handlers \
1843 [VL_API_##n + sm->msg_id_base] \
1844 = (void *) vl_api_##f##_t_print;
1845 foreach_snat_plugin_api_msg;
1850 snat_api_init (vlib_main_t * vm, snat_main_t * sm)
1853 clib_error_t *error = 0;
1855 name = format (0, "snat_%08x%c", api_version, 0);
1857 /* Ask for a correctly-sized block of API message decode slots */
1859 vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE);
1861 error = snat_plugin_api_hookup (vm);
1863 /* Add our API messages to the global name_crc hash table */
1864 setup_message_id_table (sm, sm->api_main);
1866 plugin_custom_dump_configure (sm);
1874 * fd.io coding-style-patch-verification: ON
1877 * eval: (c-set-style "gnu")