2 * Copyright (c) 2020 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 NAT44 plugin API implementation
21 #include <vnet/ip/ip_types_api.h>
22 #include <vlibmemory/api.h>
24 #include <vnet/fib/fib_table.h>
26 #include <nat/lib/nat_inlines.h>
27 #include <nat/lib/ipfix_logging.h>
29 #include <nat/nat44-ed/nat44_ed.h>
31 #include <nat/nat44-ed/nat44_ed.api_enum.h>
32 #include <nat/nat44-ed/nat44_ed.api_types.h>
34 #include <nat/nat44-ed/nat44_ed_inlines.h>
36 #define REPLY_MSG_ID_BASE sm->msg_id_base
37 #include <vlibapi/api_helper_macros.h>
42 vl_api_nat44_ed_plugin_enable_disable_t_handler (
43 vl_api_nat44_ed_plugin_enable_disable_t *mp)
45 snat_main_t *sm = &snat_main;
46 nat44_config_t c = { 0 };
47 vl_api_nat44_ed_plugin_enable_disable_reply_t *rmp;
52 if ((mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY) ||
53 (mp->flags & NAT44_API_IS_CONNECTION_TRACKING))
55 rv = VNET_API_ERROR_UNSUPPORTED;
59 c.sessions = ntohl (mp->sessions);
60 c.inside_vrf = ntohl (mp->inside_vrf);
61 c.outside_vrf = ntohl (mp->outside_vrf);
63 rv = nat44_plugin_enable (c);
68 rv = nat44_plugin_disable ();
71 REPLY_MACRO (VL_API_NAT44_ED_PLUGIN_ENABLE_DISABLE_REPLY);
75 vl_api_nat44_ed_set_fq_options_t_handler (vl_api_nat44_ed_set_fq_options_t *mp)
77 snat_main_t *sm = &snat_main;
78 vl_api_nat44_ed_set_fq_options_reply_t *rmp;
80 u32 frame_queue_nelts = ntohl (mp->frame_queue_nelts);
81 rv = nat44_ed_set_frame_queue_nelts (frame_queue_nelts);
82 REPLY_MACRO (VL_API_NAT44_ED_SET_FQ_OPTIONS_REPLY);
86 vl_api_nat44_ed_show_fq_options_t_handler (
87 vl_api_nat44_ed_show_fq_options_t *mp)
89 snat_main_t *sm = &snat_main;
90 vl_api_nat44_ed_show_fq_options_reply_t *rmp;
92 /* clang-format off */
93 REPLY_MACRO2_ZERO (VL_API_NAT44_ED_SHOW_FQ_OPTIONS_REPLY,
95 rmp->frame_queue_nelts = htonl (sm->frame_queue_nelts);
100 /* Old API calls hold back because of deprecation
101 * nat44_ed replacement should be used */
104 vl_api_nat_set_workers_t_handler (vl_api_nat_set_workers_t * mp)
106 snat_main_t *sm = &snat_main;
107 vl_api_nat_set_workers_reply_t *rmp;
112 mask = clib_net_to_host_u64 (mp->worker_mask);
114 if (sm->num_workers < 2)
116 rv = VNET_API_ERROR_FEATURE_DISABLED;
120 bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
121 rv = snat_set_workers (bitmap);
122 clib_bitmap_free (bitmap);
125 REPLY_MACRO (VL_API_NAT_SET_WORKERS_REPLY);
129 send_nat_worker_details (u32 worker_index, vl_api_registration_t * reg,
132 vl_api_nat_worker_details_t *rmp;
133 snat_main_t *sm = &snat_main;
134 vlib_worker_thread_t *w =
135 vlib_worker_threads + worker_index + sm->first_worker_index;
137 rmp = vl_msg_api_alloc (sizeof (*rmp));
138 clib_memset (rmp, 0, sizeof (*rmp));
139 rmp->_vl_msg_id = ntohs (VL_API_NAT_WORKER_DETAILS + sm->msg_id_base);
140 rmp->context = context;
141 rmp->worker_index = htonl (worker_index);
142 rmp->lcore_id = htonl (w->cpu_id);
143 strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
145 vl_api_send_msg (reg, (u8 *) rmp);
149 vl_api_nat_worker_dump_t_handler (vl_api_nat_worker_dump_t * mp)
151 vl_api_registration_t *reg;
152 snat_main_t *sm = &snat_main;
155 reg = vl_api_client_index_to_registration (mp->client_index);
159 vec_foreach (worker_index, sm->workers)
161 send_nat_worker_details (*worker_index, reg, mp->context);
166 vl_api_nat44_set_session_limit_t_handler (vl_api_nat44_set_session_limit_t *
169 snat_main_t *sm = &snat_main;
170 vl_api_nat44_set_session_limit_reply_t *rmp;
173 rv = nat44_set_session_limit
174 (ntohl (mp->session_limit), ntohl (mp->vrf_id));
176 REPLY_MACRO (VL_API_NAT44_SET_SESSION_LIMIT_REPLY);
180 vl_api_nat_ipfix_enable_disable_t_handler (vl_api_nat_ipfix_enable_disable_t *
183 snat_main_t *sm = &snat_main;
184 vl_api_nat_ipfix_enable_disable_reply_t *rmp;
187 rv = nat_ipfix_logging_enable_disable (mp->enable,
190 clib_host_to_net_u16 (mp->src_port));
192 REPLY_MACRO (VL_API_NAT_IPFIX_ENABLE_DISABLE_REPLY);
196 vl_api_nat_set_timeouts_t_handler (vl_api_nat_set_timeouts_t * mp)
198 snat_main_t *sm = &snat_main;
199 vl_api_nat_set_timeouts_reply_t *rmp;
202 sm->timeouts.udp = ntohl (mp->udp);
203 sm->timeouts.tcp.established = ntohl (mp->tcp_established);
204 sm->timeouts.tcp.transitory = ntohl (mp->tcp_transitory);
205 sm->timeouts.icmp = ntohl (mp->icmp);
207 REPLY_MACRO (VL_API_NAT_SET_TIMEOUTS_REPLY);
211 vl_api_nat_set_mss_clamping_t_handler (vl_api_nat_set_mss_clamping_t * mp)
213 snat_main_t *sm = &snat_main;
214 vl_api_nat_set_mss_clamping_reply_t *rmp;
218 sm->mss_clamping = ntohs (mp->mss_value);
220 sm->mss_clamping = 0;
222 REPLY_MACRO (VL_API_NAT_SET_MSS_CLAMPING_REPLY);
226 vl_api_nat_get_mss_clamping_t_handler (vl_api_nat_get_mss_clamping_t * mp)
228 snat_main_t *sm = &snat_main;
229 vl_api_nat_get_mss_clamping_reply_t *rmp;
232 REPLY_MACRO2 (VL_API_NAT_GET_MSS_CLAMPING_REPLY,
234 rmp->enable = sm->mss_clamping ? 1 : 0;
235 rmp->mss_value = htons (sm->mss_clamping);
240 vl_api_nat44_add_del_address_range_t_handler
241 (vl_api_nat44_add_del_address_range_t * mp)
243 snat_main_t *sm = &snat_main;
244 vl_api_nat44_add_del_address_range_reply_t *rmp;
245 ip4_address_t this_addr;
246 u8 is_add, twice_nat;
247 u32 start_host_order, end_host_order;
254 twice_nat = mp->flags & NAT_API_IS_TWICE_NAT;
256 tmp = (u32 *) mp->first_ip_address;
257 start_host_order = clib_host_to_net_u32 (tmp[0]);
258 tmp = (u32 *) mp->last_ip_address;
259 end_host_order = clib_host_to_net_u32 (tmp[0]);
261 count = (end_host_order - start_host_order) + 1;
263 vrf_id = clib_host_to_net_u32 (mp->vrf_id);
266 nat_log_info ("%U - %U, %d addresses...",
267 format_ip4_address, mp->first_ip_address,
268 format_ip4_address, mp->last_ip_address, count);
270 memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
272 for (i = 0; i < count; i++)
276 rv = nat44_ed_add_address (&this_addr, vrf_id, twice_nat);
280 rv = nat44_ed_del_address (this_addr, twice_nat);
286 increment_v4_address (&this_addr);
290 REPLY_MACRO (VL_API_NAT44_ADD_DEL_ADDRESS_RANGE_REPLY);
294 send_nat44_address_details (snat_address_t * a,
295 vl_api_registration_t * reg, u32 context,
298 vl_api_nat44_address_details_t *rmp;
299 snat_main_t *sm = &snat_main;
301 rmp = vl_msg_api_alloc (sizeof (*rmp));
302 clib_memset (rmp, 0, sizeof (*rmp));
303 rmp->_vl_msg_id = ntohs (VL_API_NAT44_ADDRESS_DETAILS + sm->msg_id_base);
304 clib_memcpy (rmp->ip_address, &(a->addr), 4);
305 if (a->fib_index != ~0)
307 fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
308 rmp->vrf_id = ntohl (fib->ft_table_id);
313 rmp->flags |= NAT_API_IS_TWICE_NAT;
314 rmp->context = context;
316 vl_api_send_msg (reg, (u8 *) rmp);
320 vl_api_nat44_address_dump_t_handler (vl_api_nat44_address_dump_t * mp)
322 vl_api_registration_t *reg;
323 snat_main_t *sm = &snat_main;
326 reg = vl_api_client_index_to_registration (mp->client_index);
330 vec_foreach (a, sm->addresses)
331 send_nat44_address_details (a, reg, mp->context, 0);
332 vec_foreach (a, sm->twice_nat_addresses)
333 send_nat44_address_details (a, reg, mp->context, 1);
337 vl_api_nat44_interface_add_del_feature_t_handler
338 (vl_api_nat44_interface_add_del_feature_t * mp)
340 vl_api_nat44_interface_add_del_feature_reply_t *rmp;
341 snat_main_t *sm = &snat_main;
346 VALIDATE_SW_IF_INDEX (mp);
348 is_inside = mp->flags & NAT_API_IS_INSIDE;
349 sw_if_index = ntohl (mp->sw_if_index);
353 rv = nat44_ed_add_interface (sw_if_index, is_inside);
357 rv = nat44_ed_del_interface (sw_if_index, is_inside);
360 BAD_SW_IF_INDEX_LABEL;
361 REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_FEATURE_REPLY);
365 send_nat44_interface_details (snat_interface_t * i,
366 vl_api_registration_t * reg, u32 context)
368 vl_api_nat44_interface_details_t *rmp;
369 snat_main_t *sm = &snat_main;
371 rmp = vl_msg_api_alloc (sizeof (*rmp));
372 clib_memset (rmp, 0, sizeof (*rmp));
373 rmp->_vl_msg_id = ntohs (VL_API_NAT44_INTERFACE_DETAILS + sm->msg_id_base);
374 rmp->sw_if_index = ntohl (i->sw_if_index);
376 if (nat44_ed_is_interface_inside (i))
377 rmp->flags |= NAT_API_IS_INSIDE;
378 if (nat44_ed_is_interface_outside (i))
379 rmp->flags |= NAT_API_IS_OUTSIDE;
381 rmp->context = context;
383 vl_api_send_msg (reg, (u8 *) rmp);
387 vl_api_nat44_interface_dump_t_handler (vl_api_nat44_interface_dump_t * mp)
389 vl_api_registration_t *reg;
390 snat_main_t *sm = &snat_main;
393 reg = vl_api_client_index_to_registration (mp->client_index);
397 pool_foreach (i, sm->interfaces)
399 send_nat44_interface_details (i, reg, mp->context);
404 vl_api_nat44_ed_add_del_output_interface_t_handler (
405 vl_api_nat44_ed_add_del_output_interface_t *mp)
407 vl_api_nat44_ed_add_del_output_interface_reply_t *rmp;
408 snat_main_t *sm = &snat_main;
411 VALIDATE_SW_IF_INDEX_END (mp);
415 rv = nat44_ed_add_output_interface (mp->sw_if_index);
419 rv = nat44_ed_del_output_interface (mp->sw_if_index);
423 REPLY_MACRO_END (VL_API_NAT44_ED_ADD_DEL_OUTPUT_INTERFACE_REPLY);
427 #include <nat/nat44-ed/nat44_ed.api.h>
430 send_nat44_ed_output_interface_details (u32 index, vl_api_registration_t *rp,
433 snat_main_t *sm = &snat_main;
434 vl_api_nat44_ed_output_interface_details_t *rmp;
435 snat_interface_t *i =
436 pool_elt_at_index (sm->output_feature_interfaces, index);
438 /* Make sure every field is initiated (or don't skip the clib_memset()) */
439 REPLY_MACRO_DETAILS4 (
440 VL_API_NAT44_ED_OUTPUT_INTERFACE_DETAILS, rp, context, ({
441 rmp->sw_if_index = i->sw_if_index;
443 /* Endian hack until apigen registers _details
444 * endian functions */
445 vl_api_nat44_ed_output_interface_details_t_endian (rmp);
446 rmp->_vl_msg_id = htons (rmp->_vl_msg_id);
447 rmp->context = htonl (rmp->context);
452 vl_api_nat44_ed_output_interface_get_t_handler (
453 vl_api_nat44_ed_output_interface_get_t *mp)
455 vl_api_nat44_ed_output_interface_get_reply_t *rmp;
456 snat_main_t *sm = &snat_main;
459 if (pool_elts (sm->output_feature_interfaces) == 0)
461 REPLY_MACRO (VL_API_NAT44_ED_OUTPUT_INTERFACE_GET_REPLY);
465 REPLY_AND_DETAILS_MACRO (
466 VL_API_NAT44_ED_OUTPUT_INTERFACE_GET_REPLY, sm->output_feature_interfaces,
467 ({ send_nat44_ed_output_interface_details (cursor, rp, mp->context); }));
471 vl_api_nat44_add_del_static_mapping_t_handler
472 (vl_api_nat44_add_del_static_mapping_t * mp)
474 vl_api_nat44_add_del_static_mapping_reply_t *rmp;
476 snat_main_t *sm = &snat_main;
479 ip4_address_t l_addr, e_addr, pool_addr = { 0 };
480 u32 sw_if_index, flags = 0, vrf_id;
481 u16 l_port = 0, e_port = 0;
482 ip_protocol_t proto = 0;
485 memcpy (&l_addr.as_u8, mp->local_ip_address, 4);
487 if (mp->flags & NAT_API_IS_ADDR_ONLY)
489 flags |= NAT_SM_FLAG_ADDR_ONLY;
493 l_port = mp->local_port;
494 e_port = mp->external_port;
495 proto = mp->protocol;
498 if (mp->flags & NAT_API_IS_TWICE_NAT)
500 flags |= NAT_SM_FLAG_TWICE_NAT;
503 if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
505 flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
508 if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
510 flags |= NAT_SM_FLAG_OUT2IN_ONLY;
513 sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
514 if (sw_if_index != ~0)
516 flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
520 memcpy (&e_addr.as_u8, mp->external_ip_address, 4);
523 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
527 mp->tag[sizeof (mp->tag) - 1] = 0;
528 tag = format (0, "%s", mp->tag);
529 vec_terminate_c_string (tag);
531 rv = nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
532 vrf_id, sw_if_index, flags, pool_addr,
538 rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
539 vrf_id, sw_if_index, flags);
541 REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_REPLY);
545 vl_api_nat44_add_del_static_mapping_v2_t_handler
546 (vl_api_nat44_add_del_static_mapping_v2_t * mp)
548 vl_api_nat44_add_del_static_mapping_v2_reply_t *rmp;
550 snat_main_t *sm = &snat_main;
553 ip4_address_t l_addr, e_addr, pool_addr;
554 u32 sw_if_index, flags = 0, vrf_id;
555 u16 l_port = 0, e_port = 0;
559 memcpy (&l_addr.as_u8, mp->local_ip_address, 4);
560 memcpy (&pool_addr.as_u8, mp->pool_ip_address, 4);
562 if (pool_addr.as_u32 != 0)
564 flags |= NAT_SM_FLAG_EXACT_ADDRESS;
567 if (mp->flags & NAT_API_IS_ADDR_ONLY)
569 flags |= NAT_SM_FLAG_ADDR_ONLY;
573 l_port = mp->local_port;
574 e_port = mp->external_port;
577 if (mp->flags & NAT_API_IS_TWICE_NAT)
579 flags |= NAT_SM_FLAG_TWICE_NAT;
582 if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
584 flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
587 if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
589 flags |= NAT_SM_FLAG_OUT2IN_ONLY;
592 sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
593 if (sw_if_index != ~0)
595 flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
599 memcpy (&e_addr.as_u8, mp->external_ip_address, 4);
602 proto = mp->protocol;
603 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
607 mp->tag[sizeof (mp->tag) - 1] = 0;
608 tag = format (0, "%s", mp->tag);
609 vec_terminate_c_string (tag);
611 rv = nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
612 vrf_id, sw_if_index, flags, pool_addr,
618 rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
619 vrf_id, sw_if_index, flags);
621 REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_V2_REPLY);
625 send_nat44_static_mapping_details (snat_static_mapping_t * m,
626 vl_api_registration_t * reg, u32 context)
628 vl_api_nat44_static_mapping_details_t *rmp;
629 snat_main_t *sm = &snat_main;
630 u32 len = sizeof (*rmp);
632 rmp = vl_msg_api_alloc (len);
633 clib_memset (rmp, 0, len);
635 ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
637 clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
638 clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
639 rmp->external_sw_if_index = ~0;
640 rmp->vrf_id = htonl (m->vrf_id);
641 rmp->context = context;
643 // convert these in new api
645 if (is_sm_self_twice_nat (m->flags))
647 rmp->flags |= NAT_API_IS_SELF_TWICE_NAT;
650 if (is_sm_out2in_only (m->flags))
652 rmp->flags |= NAT_API_IS_OUT2IN_ONLY;
655 if (is_sm_twice_nat (m->flags))
657 rmp->flags |= NAT_API_IS_TWICE_NAT;
660 if (is_sm_addr_only (m->flags))
662 rmp->flags |= NAT_API_IS_ADDR_ONLY;
666 rmp->protocol = m->proto;
667 rmp->external_port = m->external_port;
668 rmp->local_port = m->local_port;
672 strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
674 vl_api_send_msg (reg, (u8 *) rmp);
678 send_nat44_static_map_resolve_details (snat_static_mapping_resolve_t *m,
679 vl_api_registration_t *reg, u32 context)
681 vl_api_nat44_static_mapping_details_t *rmp;
682 snat_main_t *sm = &snat_main;
684 rmp = vl_msg_api_alloc (sizeof (*rmp));
685 clib_memset (rmp, 0, sizeof (*rmp));
687 ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
688 clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
689 rmp->external_sw_if_index = htonl (m->sw_if_index);
690 rmp->vrf_id = htonl (m->vrf_id);
691 rmp->context = context;
693 if (is_sm_twice_nat (m->flags))
695 rmp->flags |= NAT_API_IS_TWICE_NAT;
698 if (is_sm_addr_only (m->flags))
700 rmp->flags |= NAT_API_IS_ADDR_ONLY;
704 rmp->protocol = m->proto;
705 rmp->external_port = m->e_port;
706 rmp->local_port = m->l_port;
710 strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
712 vl_api_send_msg (reg, (u8 *) rmp);
716 vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
719 vl_api_registration_t *reg;
720 snat_main_t *sm = &snat_main;
721 snat_static_mapping_t *m;
722 snat_static_mapping_resolve_t *rp;
725 reg = vl_api_client_index_to_registration (mp->client_index);
729 pool_foreach (m, sm->static_mappings)
731 if (!is_sm_identity_nat (m->flags) && !is_sm_lb (m->flags))
732 send_nat44_static_mapping_details (m, reg, mp->context);
735 for (j = 0; j < vec_len (sm->sm_to_resolve); j++)
737 rp = sm->sm_to_resolve + j;
738 if (!is_sm_identity_nat (rp->flags))
739 send_nat44_static_map_resolve_details (rp, reg, mp->context);
744 vl_api_nat44_add_del_identity_mapping_t_handler
745 (vl_api_nat44_add_del_identity_mapping_t * mp)
747 vl_api_nat44_add_del_identity_mapping_reply_t *rmp;
749 snat_main_t *sm = &snat_main;
752 ip4_address_t addr, pool_addr = { 0 };
753 u32 sw_if_index, flags, vrf_id;
754 ip_protocol_t proto = 0;
758 flags = NAT_SM_FLAG_IDENTITY_NAT;
760 if (mp->flags & NAT_API_IS_ADDR_ONLY)
762 flags |= NAT_SM_FLAG_ADDR_ONLY;
767 proto = mp->protocol;
770 sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
771 if (sw_if_index != ~0)
773 flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
777 memcpy (&addr.as_u8, mp->ip_address, 4);
780 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
784 mp->tag[sizeof (mp->tag) - 1] = 0;
785 tag = format (0, "%s", mp->tag);
786 vec_terminate_c_string (tag);
788 rv = nat44_ed_add_static_mapping (addr, addr, port, port, proto, vrf_id,
789 sw_if_index, flags, pool_addr, tag);
794 rv = nat44_ed_del_static_mapping (addr, addr, port, port, proto, vrf_id,
797 REPLY_MACRO (VL_API_NAT44_ADD_DEL_IDENTITY_MAPPING_REPLY);
801 send_nat44_identity_mapping_details (snat_static_mapping_t * m, int index,
802 vl_api_registration_t * reg, u32 context)
804 vl_api_nat44_identity_mapping_details_t *rmp;
805 snat_main_t *sm = &snat_main;
806 nat44_lb_addr_port_t *local = pool_elt_at_index (m->locals, index);
808 rmp = vl_msg_api_alloc (sizeof (*rmp));
809 clib_memset (rmp, 0, sizeof (*rmp));
811 ntohs (VL_API_NAT44_IDENTITY_MAPPING_DETAILS + sm->msg_id_base);
813 if (is_sm_addr_only (m->flags))
814 rmp->flags |= NAT_API_IS_ADDR_ONLY;
816 clib_memcpy (rmp->ip_address, &(m->local_addr), 4);
817 rmp->port = m->local_port;
818 rmp->sw_if_index = ~0;
819 rmp->vrf_id = htonl (local->vrf_id);
820 rmp->protocol = m->proto;
821 rmp->context = context;
823 strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
825 vl_api_send_msg (reg, (u8 *) rmp);
829 send_nat44_identity_map_resolve_details (snat_static_mapping_resolve_t *m,
830 vl_api_registration_t *reg,
833 vl_api_nat44_identity_mapping_details_t *rmp;
834 snat_main_t *sm = &snat_main;
836 rmp = vl_msg_api_alloc (sizeof (*rmp));
837 clib_memset (rmp, 0, sizeof (*rmp));
839 ntohs (VL_API_NAT44_IDENTITY_MAPPING_DETAILS + sm->msg_id_base);
841 if (is_sm_addr_only (m->flags))
842 rmp->flags = (vl_api_nat_config_flags_t) NAT_API_IS_ADDR_ONLY;
844 rmp->port = m->l_port;
845 rmp->sw_if_index = htonl (m->sw_if_index);
846 rmp->vrf_id = htonl (m->vrf_id);
847 rmp->protocol = m->proto;
848 rmp->context = context;
850 strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
852 vl_api_send_msg (reg, (u8 *) rmp);
856 vl_api_nat44_identity_mapping_dump_t_handler
857 (vl_api_nat44_identity_mapping_dump_t * mp)
859 vl_api_registration_t *reg;
860 snat_main_t *sm = &snat_main;
861 snat_static_mapping_t *m;
862 snat_static_mapping_resolve_t *rp;
865 reg = vl_api_client_index_to_registration (mp->client_index);
869 pool_foreach (m, sm->static_mappings)
871 if (is_sm_identity_nat (m->flags) && !is_sm_lb (m->flags))
873 pool_foreach_index (j, m->locals)
875 send_nat44_identity_mapping_details (m, j, reg, mp->context);
880 for (j = 0; j < vec_len (sm->sm_to_resolve); j++)
882 rp = sm->sm_to_resolve + j;
883 if (is_sm_identity_nat (rp->flags))
884 send_nat44_identity_map_resolve_details (rp, reg, mp->context);
889 vl_api_nat44_add_del_interface_addr_t_handler
890 (vl_api_nat44_add_del_interface_addr_t * mp)
892 snat_main_t *sm = &snat_main;
893 vl_api_nat44_add_del_interface_addr_reply_t *rmp;
894 u32 sw_if_index = ntohl (mp->sw_if_index);
898 VALIDATE_SW_IF_INDEX (mp);
900 twice_nat = mp->flags & NAT_API_IS_TWICE_NAT;
904 rv = nat44_ed_add_interface_address (sw_if_index, twice_nat);
908 rv = nat44_ed_del_interface_address (sw_if_index, twice_nat);
911 BAD_SW_IF_INDEX_LABEL;
913 REPLY_MACRO (VL_API_NAT44_ADD_DEL_INTERFACE_ADDR_REPLY);
917 send_nat44_interface_addr_details (u32 sw_if_index,
918 vl_api_registration_t * reg, u32 context,
921 vl_api_nat44_interface_addr_details_t *rmp;
922 snat_main_t *sm = &snat_main;
924 rmp = vl_msg_api_alloc (sizeof (*rmp));
925 clib_memset (rmp, 0, sizeof (*rmp));
927 ntohs (VL_API_NAT44_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
928 rmp->sw_if_index = ntohl (sw_if_index);
931 rmp->flags = (vl_api_nat_config_flags_t) NAT_API_IS_TWICE_NAT;
932 rmp->context = context;
934 vl_api_send_msg (reg, (u8 *) rmp);
938 vl_api_nat44_interface_addr_dump_t_handler (vl_api_nat44_interface_addr_dump_t
941 snat_main_t *sm = &snat_main;
942 vl_api_registration_t *reg;
943 snat_address_resolve_t *ap;
945 reg = vl_api_client_index_to_registration (mp->client_index);
949 vec_foreach (ap, sm->addr_to_resolve)
951 send_nat44_interface_addr_details (ap->sw_if_index, reg, mp->context,
956 static nat44_lb_addr_port_t *
957 unformat_nat44_lb_addr_port (vl_api_nat44_lb_addr_port_t *addr_port_pairs,
958 u32 addr_port_pair_num)
961 nat44_lb_addr_port_t *lb_addr_port_pairs = 0, lb_addr_port;
962 vl_api_nat44_lb_addr_port_t *ap;
964 for (i = 0; i < addr_port_pair_num; i++)
966 ap = &addr_port_pairs[i];
967 clib_memset (&lb_addr_port, 0, sizeof (lb_addr_port));
968 clib_memcpy (&lb_addr_port.addr, ap->addr, 4);
969 lb_addr_port.port = ap->port;
970 lb_addr_port.probability = ap->probability;
971 lb_addr_port.vrf_id = clib_net_to_host_u32 (ap->vrf_id);
972 vec_add1 (lb_addr_port_pairs, lb_addr_port);
975 return lb_addr_port_pairs;
979 vl_api_nat44_add_del_lb_static_mapping_t_handler (
980 vl_api_nat44_add_del_lb_static_mapping_t *mp)
982 snat_main_t *sm = &snat_main;
983 vl_api_nat44_add_del_lb_static_mapping_reply_t *rmp;
984 nat44_lb_addr_port_t *locals = 0;
985 ip4_address_t e_addr;
991 locals = unformat_nat44_lb_addr_port (mp->locals,
992 clib_net_to_host_u32 (mp->local_num));
993 clib_memcpy (&e_addr, mp->external_addr, 4);
994 proto = mp->protocol;
996 if (mp->flags & NAT_API_IS_TWICE_NAT)
998 flags |= NAT_SM_FLAG_TWICE_NAT;
1000 else if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
1002 flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
1005 if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
1007 flags |= NAT_SM_FLAG_OUT2IN_ONLY;
1012 mp->tag[sizeof (mp->tag) - 1] = 0;
1013 tag = format (0, "%s", mp->tag);
1014 vec_terminate_c_string (tag);
1016 rv = nat44_ed_add_lb_static_mapping (
1017 e_addr, mp->external_port, proto, locals, flags, tag,
1018 clib_net_to_host_u32 (mp->affinity));
1022 rv = nat44_ed_del_lb_static_mapping (e_addr, mp->external_port, proto,
1028 REPLY_MACRO (VL_API_NAT44_ADD_DEL_LB_STATIC_MAPPING_REPLY);
1032 vl_api_nat44_lb_static_mapping_add_del_local_t_handler (
1033 vl_api_nat44_lb_static_mapping_add_del_local_t *mp)
1035 snat_main_t *sm = &snat_main;
1036 vl_api_nat44_lb_static_mapping_add_del_local_reply_t *rmp;
1038 ip4_address_t e_addr, l_addr;
1039 ip_protocol_t proto;
1041 clib_memcpy (&e_addr, mp->external_addr, 4);
1042 clib_memcpy (&l_addr, mp->local.addr, 4);
1043 proto = mp->protocol;
1045 rv = nat44_ed_add_del_lb_static_mapping_local (
1046 e_addr, mp->external_port, l_addr, mp->local.port, proto,
1047 clib_net_to_host_u32 (mp->local.vrf_id), mp->local.probability,
1050 REPLY_MACRO (VL_API_NAT44_LB_STATIC_MAPPING_ADD_DEL_LOCAL_REPLY);
1054 send_nat44_lb_static_mapping_details (snat_static_mapping_t *m,
1055 vl_api_registration_t *reg, u32 context)
1057 vl_api_nat44_lb_static_mapping_details_t *rmp;
1058 snat_main_t *sm = &snat_main;
1059 nat44_lb_addr_port_t *ap;
1060 vl_api_nat44_lb_addr_port_t *locals;
1063 rmp = vl_msg_api_alloc (
1064 sizeof (*rmp) + (pool_elts (m->locals) * sizeof (nat44_lb_addr_port_t)));
1066 clib_memset (rmp, 0, sizeof (*rmp));
1068 ntohs (VL_API_NAT44_LB_STATIC_MAPPING_DETAILS + sm->msg_id_base);
1070 clib_memcpy (rmp->external_addr, &(m->external_addr), 4);
1071 rmp->external_port = m->external_port;
1072 rmp->protocol = m->proto;
1073 rmp->context = context;
1075 if (is_sm_self_twice_nat (m->flags))
1077 rmp->flags |= NAT_API_IS_SELF_TWICE_NAT;
1080 if (is_sm_out2in_only (m->flags))
1082 rmp->flags |= NAT_API_IS_OUT2IN_ONLY;
1085 if (is_sm_twice_nat (m->flags))
1087 rmp->flags |= NAT_API_IS_TWICE_NAT;
1091 strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
1093 locals = (vl_api_nat44_lb_addr_port_t *) rmp->locals;
1094 pool_foreach (ap, m->locals)
1096 clib_memcpy (locals->addr, &(ap->addr), 4);
1097 locals->port = ap->port;
1098 locals->probability = ap->probability;
1099 locals->vrf_id = ntohl (ap->vrf_id);
1103 rmp->local_num = ntohl (local_num);
1105 vl_api_send_msg (reg, (u8 *) rmp);
1109 vl_api_nat44_lb_static_mapping_dump_t_handler (
1110 vl_api_nat44_lb_static_mapping_dump_t *mp)
1112 vl_api_registration_t *reg;
1113 snat_main_t *sm = &snat_main;
1114 snat_static_mapping_t *m;
1116 reg = vl_api_client_index_to_registration (mp->client_index);
1120 pool_foreach (m, sm->static_mappings)
1122 if (is_sm_lb (m->flags))
1123 send_nat44_lb_static_mapping_details (m, reg, mp->context);
1128 vl_api_nat44_del_session_t_handler (vl_api_nat44_del_session_t *mp)
1130 snat_main_t *sm = &snat_main;
1131 vl_api_nat44_del_session_reply_t *rmp;
1132 ip4_address_t addr, eh_addr;
1138 memcpy (&addr.as_u8, mp->address, 4);
1140 vrf_id = clib_net_to_host_u32 (mp->vrf_id);
1141 memcpy (&eh_addr.as_u8, mp->ext_host_address, 4);
1142 eh_port = mp->ext_host_port;
1144 is_in = mp->flags & NAT_API_IS_INSIDE;
1146 rv = nat44_ed_del_session (sm, &addr, port, &eh_addr, eh_port, mp->protocol,
1149 REPLY_MACRO (VL_API_NAT44_DEL_SESSION_REPLY);
1153 vl_api_nat44_forwarding_enable_disable_t_handler (
1154 vl_api_nat44_forwarding_enable_disable_t *mp)
1156 vl_api_nat44_forwarding_enable_disable_reply_t *rmp;
1157 snat_main_t *sm = &snat_main;
1159 nat44_ed_forwarding_enable_disable (mp->enable);
1160 REPLY_MACRO (VL_API_NAT44_FORWARDING_ENABLE_DISABLE_REPLY);
1164 vl_api_nat44_show_running_config_t_handler (
1165 vl_api_nat44_show_running_config_t *mp)
1167 vl_api_nat44_show_running_config_reply_t *rmp;
1168 snat_main_t *sm = &snat_main;
1169 nat44_config_t *rc = &sm->rconfig;
1173 VL_API_NAT44_SHOW_RUNNING_CONFIG_REPLY, ({
1174 rmp->inside_vrf = htonl (rc->inside_vrf);
1175 rmp->outside_vrf = htonl (rc->outside_vrf);
1177 rmp->sessions = htonl (rc->sessions);
1178 rmp->translation_buckets = htonl (sm->translation_buckets);
1182 rmp->user_buckets = 0;
1183 rmp->user_sessions = 0;
1185 rmp->timeouts.udp = htonl (sm->timeouts.udp);
1186 rmp->timeouts.tcp_established = htonl (sm->timeouts.tcp.established);
1187 rmp->timeouts.tcp_transitory = htonl (sm->timeouts.tcp.transitory);
1188 rmp->timeouts.icmp = htonl (sm->timeouts.icmp);
1190 rmp->forwarding_enabled = sm->forwarding_enabled == 1;
1191 // consider how to split functionality between subplugins
1192 rmp->ipfix_logging_enabled = nat_ipfix_logging_enabled ();
1193 rmp->flags |= NAT44_IS_ENDPOINT_DEPENDENT;
1198 vl_api_nat44_ed_add_del_vrf_table_t_handler (
1199 vl_api_nat44_ed_add_del_vrf_table_t *mp)
1201 snat_main_t *sm = &snat_main;
1202 vl_api_nat44_ed_add_del_vrf_table_reply_t *rmp;
1203 int rv = nat44_ed_add_del_vrf_table (clib_net_to_host_u32 (mp->table_vrf_id),
1205 REPLY_MACRO (VL_API_NAT44_ED_ADD_DEL_VRF_TABLE_REPLY);
1209 vl_api_nat44_ed_add_del_vrf_route_t_handler (
1210 vl_api_nat44_ed_add_del_vrf_route_t *mp)
1212 snat_main_t *sm = &snat_main;
1213 vl_api_nat44_ed_add_del_vrf_route_reply_t *rmp;
1215 nat44_ed_add_del_vrf_route (clib_net_to_host_u32 (mp->table_vrf_id),
1216 clib_net_to_host_u32 (mp->vrf_id), mp->is_add);
1217 REPLY_MACRO (VL_API_NAT44_ED_ADD_DEL_VRF_ROUTE_REPLY);
1221 nat44_ed_vrf_tables_send_details (vl_api_registration_t *rp, u32 context,
1224 snat_main_t *sm = &snat_main;
1225 vl_api_nat44_ed_vrf_tables_details_t *mp;
1230 mp = vl_msg_api_alloc_zero (sizeof (*mp) +
1231 sizeof (mp->vrf_ids[0]) * vec_len (t->routes));
1233 ntohs (VL_API_NAT44_ED_VRF_TABLES_DETAILS + sm->msg_id_base);
1234 mp->context = context;
1235 mp->n_vrf_ids = clib_host_to_net_u32 (vec_len (t->routes));
1237 pool_foreach (r, t->routes)
1239 vec_add1 (vrf_ids, r->vrf_id);
1243 clib_memcpy (mp->vrf_ids, vrf_ids,
1244 sizeof (mp->vrf_ids[0]) * vec_len (t->routes));
1249 vl_api_send_msg (rp, (u8 *) mp);
1253 vl_api_nat44_ed_vrf_tables_dump_t_handler (
1254 vl_api_nat44_ed_vrf_tables_dump_t *mp)
1256 snat_main_t *sm = &snat_main;
1257 vl_api_registration_t *rp;
1260 rp = vl_api_client_index_to_registration (mp->client_index);
1264 pool_foreach (t, sm->vrf_tables)
1266 nat44_ed_vrf_tables_send_details (rp, mp->context, t);
1270 /* user (internal host) key */
1289 u32 nstaticsessions;
1296 clib_bihash_8_8_t user_hash;
1297 } user_create_helper_t;
1300 send_nat44_user_details (snat_user_t *u, vl_api_registration_t *reg,
1303 vl_api_nat44_user_details_t *rmp;
1304 snat_main_t *sm = &snat_main;
1305 ip4_main_t *im = &ip4_main;
1307 rmp = vl_msg_api_alloc (sizeof (*rmp));
1308 clib_memset (rmp, 0, sizeof (*rmp));
1309 rmp->_vl_msg_id = ntohs (VL_API_NAT44_USER_DETAILS + sm->msg_id_base);
1311 if (!pool_is_free_index (im->fibs, u->fib_index))
1313 fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
1314 rmp->vrf_id = ntohl (fib->ft_table_id);
1317 clib_memcpy (rmp->ip_address, &(u->addr), 4);
1318 rmp->nsessions = ntohl (u->nsessions);
1319 rmp->nstaticsessions = ntohl (u->nstaticsessions);
1320 rmp->context = context;
1322 vl_api_send_msg (reg, (u8 *) rmp);
1326 nat_ed_user_create_helper (user_create_helper_t *uch, snat_session_t *s)
1329 k.addr = s->in2out.addr;
1330 k.fib_index = s->in2out.fib_index;
1331 clib_bihash_kv_8_8_t key, value;
1335 if (clib_bihash_search_8_8 (&uch->user_hash, &key, &value))
1337 pool_get (uch->users, u);
1339 u->fib_index = k.fib_index;
1341 u->nstaticsessions = 0;
1342 key.value = u - uch->users;
1343 clib_bihash_add_del_8_8 (&uch->user_hash, &key, 1);
1347 u = pool_elt_at_index (uch->users, value.value);
1349 if (nat44_ed_is_session_static (s))
1351 ++u->nstaticsessions;
1360 format_user_kvp (u8 *s, va_list *args)
1362 clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
1365 s = format (s, "%U fib %d user-index %llu", format_ip4_address, &k.addr,
1366 k.fib_index, v->value);
1371 nat_ed_users_create (snat_main_per_thread_data_t *tsm,
1372 user_create_helper_t *uch)
1375 clib_bihash_init_8_8 (&uch->user_hash, "users", uch->user_buckets, 0);
1376 clib_bihash_set_kvp_format_fn_8_8 (&uch->user_hash, format_user_kvp);
1377 pool_foreach (s, tsm->sessions)
1379 nat_ed_user_create_helper (uch, s);
1384 nat_ed_users_destroy (user_create_helper_t *uch)
1386 pool_free (uch->users);
1387 clib_bihash_free_8_8 (&uch->user_hash);
1391 vl_api_nat44_user_dump_t_handler (vl_api_nat44_user_dump_t * mp)
1393 user_create_helper_t uch;
1394 vl_api_registration_t *reg;
1395 snat_main_t *sm = &snat_main;
1396 snat_main_per_thread_data_t *tsm;
1399 clib_memset (&uch, 0, sizeof (uch));
1401 uch.user_buckets = nat_calc_bihash_buckets (1024);
1403 reg = vl_api_client_index_to_registration (mp->client_index);
1407 vec_foreach (tsm, sm->per_thread_data)
1409 nat_ed_users_create (tsm, &uch);
1410 pool_foreach (u, uch.users)
1412 send_nat44_user_details (u, reg, mp->context);
1414 nat_ed_users_destroy (&uch);
1419 send_nat44_user_session_details (snat_session_t * s,
1420 vl_api_registration_t * reg, u32 context)
1422 vl_api_nat44_user_session_details_t *rmp;
1423 snat_main_t *sm = &snat_main;
1425 rmp = vl_msg_api_alloc (sizeof (*rmp));
1426 clib_memset (rmp, 0, sizeof (*rmp));
1428 ntohs (VL_API_NAT44_USER_SESSION_DETAILS + sm->msg_id_base);
1429 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
1430 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
1432 if (nat44_ed_is_session_static (s))
1433 rmp->flags |= NAT_API_IS_STATIC;
1435 if (nat44_ed_is_twice_nat_session (s))
1436 rmp->flags |= NAT_API_IS_TWICE_NAT;
1438 rmp->flags |= NAT_API_IS_EXT_HOST_VALID;
1440 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
1441 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
1442 rmp->total_pkts = ntohl (s->total_pkts);
1443 rmp->context = context;
1444 rmp->outside_port = s->out2in.port;
1445 rmp->inside_port = s->in2out.port;
1446 rmp->protocol = clib_host_to_net_u16 (s->proto);
1447 clib_memcpy (rmp->ext_host_address, &s->ext_host_addr, 4);
1448 rmp->ext_host_port = s->ext_host_port;
1449 if (nat44_ed_is_twice_nat_session (s))
1451 clib_memcpy (rmp->ext_host_nat_address, &s->ext_host_nat_addr, 4);
1452 rmp->ext_host_nat_port = s->ext_host_nat_port;
1455 vl_api_send_msg (reg, (u8 *) rmp);
1459 vl_api_nat44_user_session_dump_t_handler (vl_api_nat44_user_session_dump_t *
1462 snat_main_per_thread_data_t *tsm;
1463 snat_main_t *sm = &snat_main;
1464 vl_api_registration_t *reg;
1465 snat_user_key_t ukey;
1469 reg = vl_api_client_index_to_registration (mp->client_index);
1473 clib_memcpy (&ukey.addr, mp->ip_address, 4);
1474 ip.src_address.as_u32 = ukey.addr.as_u32;
1475 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
1476 if (sm->num_workers > 1)
1477 tsm = vec_elt_at_index (
1478 sm->per_thread_data,
1479 nat44_ed_get_in2out_worker_index (0, &ip, ukey.fib_index, 0));
1481 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
1483 pool_foreach (s, tsm->sessions) {
1484 if (s->in2out.addr.as_u32 == ukey.addr.as_u32)
1486 send_nat44_user_session_details (s, reg, mp->context);
1492 send_nat44_user_session_v2_details (snat_session_t *s,
1493 vl_api_registration_t *reg, u32 context)
1495 vl_api_nat44_user_session_v2_details_t *rmp;
1496 snat_main_t *sm = &snat_main;
1497 vnet_main_t *vnm = vnet_get_main ();
1498 u64 now = vlib_time_now (vnm->vlib_main);
1499 u64 sess_timeout_time = 0;
1501 rmp = vl_msg_api_alloc (sizeof (*rmp));
1502 clib_memset (rmp, 0, sizeof (*rmp));
1504 ntohs (VL_API_NAT44_USER_SESSION_V2_DETAILS + sm->msg_id_base);
1505 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
1506 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
1508 if (nat44_ed_is_session_static (s))
1509 rmp->flags |= NAT_API_IS_STATIC;
1511 if (nat44_ed_is_twice_nat_session (s))
1512 rmp->flags |= NAT_API_IS_TWICE_NAT;
1514 rmp->flags |= NAT_API_IS_EXT_HOST_VALID;
1516 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
1517 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
1518 rmp->total_pkts = ntohl (s->total_pkts);
1519 rmp->context = context;
1520 rmp->outside_port = s->out2in.port;
1521 rmp->inside_port = s->in2out.port;
1522 rmp->protocol = clib_host_to_net_u16 (s->proto);
1523 clib_memcpy (rmp->ext_host_address, &s->ext_host_addr, 4);
1524 rmp->ext_host_port = s->ext_host_port;
1525 if (nat44_ed_is_twice_nat_session (s))
1527 clib_memcpy (rmp->ext_host_nat_address, &s->ext_host_nat_addr, 4);
1528 rmp->ext_host_nat_port = s->ext_host_nat_port;
1531 sess_timeout_time = s->last_heard + nat44_session_get_timeout (sm, s);
1532 rmp->is_timed_out = (now >= sess_timeout_time);
1534 vl_api_send_msg (reg, (u8 *) rmp);
1538 send_nat44_user_session_v3_details (snat_session_t *s,
1539 vl_api_registration_t *reg, u32 context)
1541 vl_api_nat44_user_session_v3_details_t *rmp;
1542 snat_main_t *sm = &snat_main;
1543 u64 now = vlib_time_now (vlib_get_main ());
1544 u64 sess_timeout_time = 0;
1546 rmp = vl_msg_api_alloc (sizeof (*rmp));
1547 clib_memset (rmp, 0, sizeof (*rmp));
1549 ntohs (VL_API_NAT44_USER_SESSION_V3_DETAILS + sm->msg_id_base);
1550 clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
1551 clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
1553 if (nat44_ed_is_session_static (s))
1554 rmp->flags |= NAT_API_IS_STATIC;
1556 if (nat44_ed_is_twice_nat_session (s))
1557 rmp->flags |= NAT_API_IS_TWICE_NAT;
1559 rmp->flags |= NAT_API_IS_EXT_HOST_VALID;
1561 rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
1562 rmp->time_since_last_heard =
1563 clib_host_to_net_u64 ((u64) (now - s->last_heard));
1564 rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
1565 rmp->total_pkts = ntohl (s->total_pkts);
1566 rmp->context = context;
1567 rmp->outside_port = s->out2in.port;
1568 rmp->inside_port = s->in2out.port;
1569 rmp->protocol = clib_host_to_net_u16 (s->proto);
1570 clib_memcpy (rmp->ext_host_address, &s->ext_host_addr, 4);
1571 rmp->ext_host_port = s->ext_host_port;
1572 if (nat44_ed_is_twice_nat_session (s))
1574 clib_memcpy (rmp->ext_host_nat_address, &s->ext_host_nat_addr, 4);
1575 rmp->ext_host_nat_port = s->ext_host_nat_port;
1578 sess_timeout_time = s->last_heard + nat44_session_get_timeout (sm, s);
1579 rmp->is_timed_out = (now >= sess_timeout_time);
1581 vl_api_send_msg (reg, (u8 *) rmp);
1585 vl_api_nat44_user_session_v2_dump_t_handler (
1586 vl_api_nat44_user_session_v2_dump_t *mp)
1588 snat_main_per_thread_data_t *tsm;
1589 snat_main_t *sm = &snat_main;
1590 vl_api_registration_t *reg;
1591 snat_user_key_t ukey;
1595 reg = vl_api_client_index_to_registration (mp->client_index);
1599 clib_memcpy (&ukey.addr, mp->ip_address, 4);
1600 ip.src_address.as_u32 = ukey.addr.as_u32;
1601 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
1602 if (sm->num_workers > 1)
1603 tsm = vec_elt_at_index (
1604 sm->per_thread_data,
1605 nat44_ed_get_in2out_worker_index (0, &ip, ukey.fib_index, 0));
1607 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
1609 pool_foreach (s, tsm->sessions)
1611 if (s->in2out.addr.as_u32 == ukey.addr.as_u32)
1613 send_nat44_user_session_v2_details (s, reg, mp->context);
1619 vl_api_nat44_user_session_v3_dump_t_handler (
1620 vl_api_nat44_user_session_v3_dump_t *mp)
1622 snat_main_per_thread_data_t *tsm;
1623 snat_main_t *sm = &snat_main;
1624 vl_api_registration_t *reg;
1625 snat_user_key_t ukey;
1629 reg = vl_api_client_index_to_registration (mp->client_index);
1633 clib_memcpy (&ukey.addr, mp->ip_address, 4);
1634 ip.src_address.as_u32 = ukey.addr.as_u32;
1635 ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
1636 if (sm->num_workers > 1)
1637 tsm = vec_elt_at_index (
1638 sm->per_thread_data,
1639 nat44_ed_get_in2out_worker_index (0, &ip, ukey.fib_index, 0));
1641 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
1643 pool_foreach (s, tsm->sessions)
1645 if (s->in2out.addr.as_u32 == ukey.addr.as_u32)
1647 send_nat44_user_session_v3_details (s, reg, mp->context);
1652 /* API definitions */
1653 #include <vnet/format_fns.h>
1654 #include <nat/nat44-ed/nat44_ed.api.c>
1656 /* Set up the API message handling tables */
1658 nat44_api_hookup (vlib_main_t * vm)
1660 snat_main_t *sm = &snat_main;
1661 sm->msg_id_base = setup_message_id_table ();
1666 * fd.io coding-style-patch-verification: ON
1669 * eval: (c-set-style "gnu")