Line data Source code
1 : /*
2 : * Copyright (c) 2020 Cisco and/or its affiliates.
3 : *
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:
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
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.
15 : */
16 : /**
17 : * @file
18 : * @brief NAT44 plugin API implementation
19 : */
20 :
21 : #include <vnet/ip/ip_types_api.h>
22 : #include <vlibmemory/api.h>
23 :
24 : #include <vnet/fib/fib_table.h>
25 :
26 : #include <nat/lib/nat_inlines.h>
27 : #include <nat/lib/ipfix_logging.h>
28 :
29 : #include <nat/nat44-ed/nat44_ed.h>
30 :
31 : #include <nat/nat44-ed/nat44_ed.api_enum.h>
32 : #include <nat/nat44-ed/nat44_ed.api_types.h>
33 :
34 : #include <nat/nat44-ed/nat44_ed_inlines.h>
35 :
36 : #define REPLY_MSG_ID_BASE sm->msg_id_base
37 : #include <vlibapi/api_helper_macros.h>
38 :
39 : /* New API calls */
40 :
41 : static void
42 174 : vl_api_nat44_ed_plugin_enable_disable_t_handler (
43 : vl_api_nat44_ed_plugin_enable_disable_t *mp)
44 : {
45 174 : snat_main_t *sm = &snat_main;
46 174 : nat44_config_t c = { 0 };
47 : vl_api_nat44_ed_plugin_enable_disable_reply_t *rmp;
48 174 : int rv = 0;
49 :
50 174 : if (mp->enable)
51 : {
52 87 : if ((mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY) ||
53 87 : (mp->flags & NAT44_API_IS_CONNECTION_TRACKING))
54 : {
55 0 : rv = VNET_API_ERROR_UNSUPPORTED;
56 : }
57 : else
58 : {
59 87 : c.sessions = ntohl (mp->sessions);
60 87 : c.inside_vrf = ntohl (mp->inside_vrf);
61 87 : c.outside_vrf = ntohl (mp->outside_vrf);
62 :
63 87 : rv = nat44_plugin_enable (c);
64 : }
65 : }
66 : else
67 : {
68 87 : rv = nat44_plugin_disable ();
69 : }
70 :
71 174 : REPLY_MACRO (VL_API_NAT44_ED_PLUGIN_ENABLE_DISABLE_REPLY);
72 : }
73 :
74 : static void
75 0 : vl_api_nat44_ed_set_fq_options_t_handler (vl_api_nat44_ed_set_fq_options_t *mp)
76 : {
77 0 : snat_main_t *sm = &snat_main;
78 : vl_api_nat44_ed_set_fq_options_reply_t *rmp;
79 0 : int rv = 0;
80 0 : u32 frame_queue_nelts = ntohl (mp->frame_queue_nelts);
81 0 : rv = nat44_ed_set_frame_queue_nelts (frame_queue_nelts);
82 0 : REPLY_MACRO (VL_API_NAT44_ED_SET_FQ_OPTIONS_REPLY);
83 : }
84 :
85 : static void
86 0 : vl_api_nat44_ed_show_fq_options_t_handler (
87 : vl_api_nat44_ed_show_fq_options_t *mp)
88 : {
89 0 : snat_main_t *sm = &snat_main;
90 : vl_api_nat44_ed_show_fq_options_reply_t *rmp;
91 0 : int rv = 0;
92 : /* clang-format off */
93 0 : REPLY_MACRO2_ZERO (VL_API_NAT44_ED_SHOW_FQ_OPTIONS_REPLY,
94 : ({
95 : rmp->frame_queue_nelts = htonl (sm->frame_queue_nelts);
96 : }));
97 : /* clang-format on */
98 : }
99 :
100 : /* Old API calls hold back because of deprecation
101 : * nat44_ed replacement should be used */
102 :
103 : static void
104 0 : vl_api_nat_set_workers_t_handler (vl_api_nat_set_workers_t * mp)
105 : {
106 0 : snat_main_t *sm = &snat_main;
107 : vl_api_nat_set_workers_reply_t *rmp;
108 0 : int rv = 0;
109 0 : uword *bitmap = 0;
110 : u64 mask;
111 :
112 0 : mask = clib_net_to_host_u64 (mp->worker_mask);
113 :
114 0 : if (sm->num_workers < 2)
115 : {
116 0 : rv = VNET_API_ERROR_FEATURE_DISABLED;
117 0 : goto send_reply;
118 : }
119 :
120 0 : bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
121 0 : rv = snat_set_workers (bitmap);
122 0 : clib_bitmap_free (bitmap);
123 :
124 0 : send_reply:
125 0 : REPLY_MACRO (VL_API_NAT_SET_WORKERS_REPLY);
126 : }
127 :
128 : static void
129 0 : send_nat_worker_details (u32 worker_index, vl_api_registration_t * reg,
130 : u32 context)
131 : {
132 : vl_api_nat_worker_details_t *rmp;
133 0 : snat_main_t *sm = &snat_main;
134 0 : vlib_worker_thread_t *w =
135 0 : vlib_worker_threads + worker_index + sm->first_worker_index;
136 :
137 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
138 0 : clib_memset (rmp, 0, sizeof (*rmp));
139 0 : rmp->_vl_msg_id = ntohs (VL_API_NAT_WORKER_DETAILS + sm->msg_id_base);
140 0 : rmp->context = context;
141 0 : rmp->worker_index = htonl (worker_index);
142 0 : rmp->lcore_id = htonl (w->cpu_id);
143 0 : strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
144 :
145 0 : vl_api_send_msg (reg, (u8 *) rmp);
146 0 : }
147 :
148 : static void
149 0 : vl_api_nat_worker_dump_t_handler (vl_api_nat_worker_dump_t * mp)
150 : {
151 : vl_api_registration_t *reg;
152 0 : snat_main_t *sm = &snat_main;
153 : u32 *worker_index;
154 :
155 0 : reg = vl_api_client_index_to_registration (mp->client_index);
156 0 : if (!reg)
157 0 : return;
158 :
159 0 : vec_foreach (worker_index, sm->workers)
160 : {
161 0 : send_nat_worker_details (*worker_index, reg, mp->context);
162 : }
163 : }
164 :
165 : static void
166 1 : vl_api_nat44_set_session_limit_t_handler (vl_api_nat44_set_session_limit_t *
167 : mp)
168 : {
169 1 : snat_main_t *sm = &snat_main;
170 : vl_api_nat44_set_session_limit_reply_t *rmp;
171 1 : int rv = 0;
172 :
173 1 : rv = nat44_set_session_limit
174 : (ntohl (mp->session_limit), ntohl (mp->vrf_id));
175 :
176 1 : REPLY_MACRO (VL_API_NAT44_SET_SESSION_LIMIT_REPLY);
177 : }
178 :
179 : static void
180 1 : vl_api_nat_ipfix_enable_disable_t_handler (vl_api_nat_ipfix_enable_disable_t *
181 : mp)
182 : {
183 1 : snat_main_t *sm = &snat_main;
184 : vl_api_nat_ipfix_enable_disable_reply_t *rmp;
185 1 : int rv = 0;
186 :
187 1 : rv = nat_ipfix_logging_enable_disable (mp->enable,
188 : clib_host_to_net_u32
189 : (mp->domain_id),
190 1 : clib_host_to_net_u16 (mp->src_port));
191 :
192 1 : REPLY_MACRO (VL_API_NAT_IPFIX_ENABLE_DISABLE_REPLY);
193 : }
194 :
195 : static void
196 14 : vl_api_nat_set_timeouts_t_handler (vl_api_nat_set_timeouts_t * mp)
197 : {
198 14 : snat_main_t *sm = &snat_main;
199 : vl_api_nat_set_timeouts_reply_t *rmp;
200 14 : int rv = 0;
201 :
202 14 : sm->timeouts.udp = ntohl (mp->udp);
203 14 : sm->timeouts.tcp.established = ntohl (mp->tcp_established);
204 14 : sm->timeouts.tcp.transitory = ntohl (mp->tcp_transitory);
205 14 : sm->timeouts.icmp = ntohl (mp->icmp);
206 :
207 14 : REPLY_MACRO (VL_API_NAT_SET_TIMEOUTS_REPLY);
208 : }
209 :
210 : static void
211 0 : vl_api_nat_set_mss_clamping_t_handler (vl_api_nat_set_mss_clamping_t * mp)
212 : {
213 0 : snat_main_t *sm = &snat_main;
214 : vl_api_nat_set_mss_clamping_reply_t *rmp;
215 0 : int rv = 0;
216 :
217 0 : if (mp->enable)
218 0 : sm->mss_clamping = ntohs (mp->mss_value);
219 : else
220 0 : sm->mss_clamping = 0;
221 :
222 0 : REPLY_MACRO (VL_API_NAT_SET_MSS_CLAMPING_REPLY);
223 : }
224 :
225 : static void
226 0 : vl_api_nat_get_mss_clamping_t_handler (vl_api_nat_get_mss_clamping_t * mp)
227 : {
228 0 : snat_main_t *sm = &snat_main;
229 : vl_api_nat_get_mss_clamping_reply_t *rmp;
230 0 : int rv = 0;
231 :
232 0 : REPLY_MACRO2 (VL_API_NAT_GET_MSS_CLAMPING_REPLY,
233 : ({
234 : rmp->enable = sm->mss_clamping ? 1 : 0;
235 : rmp->mss_value = htons (sm->mss_clamping);
236 : }))
237 : }
238 :
239 : static void
240 79 : vl_api_nat44_add_del_address_range_t_handler
241 : (vl_api_nat44_add_del_address_range_t * mp)
242 : {
243 79 : 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;
248 : u32 vrf_id;
249 : int i, count;
250 79 : int rv = 0;
251 : u32 *tmp;
252 :
253 79 : is_add = mp->is_add;
254 79 : twice_nat = mp->flags & NAT_API_IS_TWICE_NAT;
255 :
256 79 : tmp = (u32 *) mp->first_ip_address;
257 79 : start_host_order = clib_host_to_net_u32 (tmp[0]);
258 79 : tmp = (u32 *) mp->last_ip_address;
259 79 : end_host_order = clib_host_to_net_u32 (tmp[0]);
260 :
261 79 : count = (end_host_order - start_host_order) + 1;
262 :
263 79 : vrf_id = clib_host_to_net_u32 (mp->vrf_id);
264 :
265 79 : if (count > 1024)
266 0 : nat_log_info ("%U - %U, %d addresses...",
267 : format_ip4_address, mp->first_ip_address,
268 : format_ip4_address, mp->last_ip_address, count);
269 :
270 79 : memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
271 :
272 354 : for (i = 0; i < count; i++)
273 : {
274 275 : if (is_add)
275 : {
276 274 : rv = nat44_ed_add_address (&this_addr, vrf_id, twice_nat);
277 : }
278 : else
279 : {
280 1 : rv = nat44_ed_del_address (this_addr, twice_nat);
281 : }
282 :
283 275 : if (rv)
284 0 : goto send_reply;
285 :
286 275 : increment_v4_address (&this_addr);
287 : }
288 :
289 79 : send_reply:
290 79 : REPLY_MACRO (VL_API_NAT44_ADD_DEL_ADDRESS_RANGE_REPLY);
291 : }
292 :
293 : static void
294 1 : send_nat44_address_details (snat_address_t * a,
295 : vl_api_registration_t * reg, u32 context,
296 : u8 twice_nat)
297 : {
298 : vl_api_nat44_address_details_t *rmp;
299 1 : snat_main_t *sm = &snat_main;
300 :
301 1 : rmp = vl_msg_api_alloc (sizeof (*rmp));
302 1 : clib_memset (rmp, 0, sizeof (*rmp));
303 1 : rmp->_vl_msg_id = ntohs (VL_API_NAT44_ADDRESS_DETAILS + sm->msg_id_base);
304 1 : clib_memcpy (rmp->ip_address, &(a->addr), 4);
305 1 : if (a->fib_index != ~0)
306 : {
307 0 : fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
308 0 : rmp->vrf_id = ntohl (fib->ft_table_id);
309 : }
310 : else
311 1 : rmp->vrf_id = ~0;
312 1 : if (twice_nat)
313 1 : rmp->flags |= NAT_API_IS_TWICE_NAT;
314 1 : rmp->context = context;
315 :
316 1 : vl_api_send_msg (reg, (u8 *) rmp);
317 1 : }
318 :
319 : static void
320 4 : vl_api_nat44_address_dump_t_handler (vl_api_nat44_address_dump_t * mp)
321 : {
322 : vl_api_registration_t *reg;
323 4 : snat_main_t *sm = &snat_main;
324 : snat_address_t *a;
325 :
326 4 : reg = vl_api_client_index_to_registration (mp->client_index);
327 4 : if (!reg)
328 0 : return;
329 :
330 4 : vec_foreach (a, sm->addresses)
331 0 : send_nat44_address_details (a, reg, mp->context, 0);
332 5 : vec_foreach (a, sm->twice_nat_addresses)
333 1 : send_nat44_address_details (a, reg, mp->context, 1);
334 : }
335 :
336 : static void
337 180 : vl_api_nat44_interface_add_del_feature_t_handler
338 : (vl_api_nat44_interface_add_del_feature_t * mp)
339 : {
340 : vl_api_nat44_interface_add_del_feature_reply_t *rmp;
341 180 : snat_main_t *sm = &snat_main;
342 : u32 sw_if_index;
343 : u8 is_inside;
344 180 : int rv = 0;
345 :
346 180 : VALIDATE_SW_IF_INDEX (mp);
347 :
348 180 : is_inside = mp->flags & NAT_API_IS_INSIDE;
349 180 : sw_if_index = ntohl (mp->sw_if_index);
350 :
351 180 : if (mp->is_add)
352 : {
353 180 : rv = nat44_ed_add_interface (sw_if_index, is_inside);
354 : }
355 : else
356 : {
357 0 : rv = nat44_ed_del_interface (sw_if_index, is_inside);
358 : }
359 :
360 180 : BAD_SW_IF_INDEX_LABEL;
361 180 : REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_FEATURE_REPLY);
362 : }
363 :
364 : static void
365 12 : send_nat44_interface_details (snat_interface_t * i,
366 : vl_api_registration_t * reg, u32 context)
367 : {
368 : vl_api_nat44_interface_details_t *rmp;
369 12 : snat_main_t *sm = &snat_main;
370 :
371 12 : rmp = vl_msg_api_alloc (sizeof (*rmp));
372 12 : clib_memset (rmp, 0, sizeof (*rmp));
373 12 : rmp->_vl_msg_id = ntohs (VL_API_NAT44_INTERFACE_DETAILS + sm->msg_id_base);
374 12 : rmp->sw_if_index = ntohl (i->sw_if_index);
375 :
376 12 : if (nat44_ed_is_interface_inside (i))
377 10 : rmp->flags |= NAT_API_IS_INSIDE;
378 12 : if (nat44_ed_is_interface_outside (i))
379 8 : rmp->flags |= NAT_API_IS_OUTSIDE;
380 :
381 12 : rmp->context = context;
382 :
383 12 : vl_api_send_msg (reg, (u8 *) rmp);
384 12 : }
385 :
386 : static void
387 10 : vl_api_nat44_interface_dump_t_handler (vl_api_nat44_interface_dump_t * mp)
388 : {
389 : vl_api_registration_t *reg;
390 10 : snat_main_t *sm = &snat_main;
391 : snat_interface_t *i;
392 :
393 10 : reg = vl_api_client_index_to_registration (mp->client_index);
394 10 : if (!reg)
395 0 : return;
396 :
397 22 : pool_foreach (i, sm->interfaces)
398 : {
399 12 : send_nat44_interface_details (i, reg, mp->context);
400 : }
401 : }
402 :
403 : static void
404 14 : vl_api_nat44_ed_add_del_output_interface_t_handler (
405 : vl_api_nat44_ed_add_del_output_interface_t *mp)
406 : {
407 : vl_api_nat44_ed_add_del_output_interface_reply_t *rmp;
408 14 : snat_main_t *sm = &snat_main;
409 14 : int rv = 0;
410 :
411 14 : VALIDATE_SW_IF_INDEX_END (mp);
412 :
413 14 : if (mp->is_add)
414 : {
415 14 : rv = nat44_ed_add_output_interface (mp->sw_if_index);
416 : }
417 : else
418 : {
419 0 : rv = nat44_ed_del_output_interface (mp->sw_if_index);
420 : }
421 :
422 14 : bad_sw_if_index:
423 14 : REPLY_MACRO_END (VL_API_NAT44_ED_ADD_DEL_OUTPUT_INTERFACE_REPLY);
424 : }
425 :
426 : #define vl_endianfun
427 : #include <nat/nat44-ed/nat44_ed.api.h>
428 : #undef vl_endianfun
429 : static void
430 8 : send_nat44_ed_output_interface_details (u32 index, vl_api_registration_t *rp,
431 : u32 context)
432 : {
433 8 : snat_main_t *sm = &snat_main;
434 : vl_api_nat44_ed_output_interface_details_t *rmp;
435 8 : snat_interface_t *i =
436 8 : pool_elt_at_index (sm->output_feature_interfaces, index);
437 :
438 : /* Make sure every field is initiated (or don't skip the clib_memset()) */
439 8 : REPLY_MACRO_DETAILS4 (
440 : VL_API_NAT44_ED_OUTPUT_INTERFACE_DETAILS, rp, context, ({
441 : rmp->sw_if_index = i->sw_if_index;
442 :
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);
448 : }));
449 8 : }
450 :
451 : static void
452 10 : vl_api_nat44_ed_output_interface_get_t_handler (
453 : vl_api_nat44_ed_output_interface_get_t *mp)
454 : {
455 : vl_api_nat44_ed_output_interface_get_reply_t *rmp;
456 10 : snat_main_t *sm = &snat_main;
457 10 : i32 rv = 0;
458 :
459 10 : if (pool_elts (sm->output_feature_interfaces) == 0)
460 : {
461 2 : REPLY_MACRO (VL_API_NAT44_ED_OUTPUT_INTERFACE_GET_REPLY);
462 2 : return;
463 : }
464 :
465 16 : 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); }));
468 : }
469 :
470 : static void
471 47 : vl_api_nat44_add_del_static_mapping_t_handler
472 : (vl_api_nat44_add_del_static_mapping_t * mp)
473 : {
474 : vl_api_nat44_add_del_static_mapping_reply_t *rmp;
475 :
476 47 : snat_main_t *sm = &snat_main;
477 47 : int rv = 0;
478 :
479 47 : ip4_address_t l_addr, e_addr, pool_addr = { 0 };
480 47 : u32 sw_if_index, flags = 0, vrf_id;
481 47 : u16 l_port = 0, e_port = 0;
482 47 : ip_protocol_t proto = 0;
483 47 : u8 *tag = 0;
484 :
485 47 : memcpy (&l_addr.as_u8, mp->local_ip_address, 4);
486 :
487 47 : if (mp->flags & NAT_API_IS_ADDR_ONLY)
488 : {
489 10 : flags |= NAT_SM_FLAG_ADDR_ONLY;
490 : }
491 : else
492 : {
493 37 : l_port = mp->local_port;
494 37 : e_port = mp->external_port;
495 37 : proto = mp->protocol;
496 : }
497 :
498 47 : if (mp->flags & NAT_API_IS_TWICE_NAT)
499 : {
500 10 : flags |= NAT_SM_FLAG_TWICE_NAT;
501 : }
502 :
503 47 : if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
504 : {
505 4 : flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
506 : }
507 :
508 47 : if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
509 : {
510 20 : flags |= NAT_SM_FLAG_OUT2IN_ONLY;
511 : }
512 :
513 47 : sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
514 47 : if (sw_if_index != ~0)
515 : {
516 4 : flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
517 : }
518 : else
519 : {
520 43 : memcpy (&e_addr.as_u8, mp->external_ip_address, 4);
521 : }
522 :
523 47 : vrf_id = clib_net_to_host_u32 (mp->vrf_id);
524 :
525 47 : if (mp->is_add)
526 : {
527 45 : mp->tag[sizeof (mp->tag) - 1] = 0;
528 45 : tag = format (0, "%s", mp->tag);
529 45 : vec_terminate_c_string (tag);
530 :
531 45 : rv = nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
532 : vrf_id, sw_if_index, flags, pool_addr,
533 : tag);
534 45 : vec_free (tag);
535 : }
536 : else
537 : {
538 2 : rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
539 : vrf_id, sw_if_index, flags);
540 : }
541 47 : REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_REPLY);
542 : }
543 :
544 : static void
545 0 : vl_api_nat44_add_del_static_mapping_v2_t_handler
546 : (vl_api_nat44_add_del_static_mapping_v2_t * mp)
547 : {
548 : vl_api_nat44_add_del_static_mapping_v2_reply_t *rmp;
549 :
550 0 : snat_main_t *sm = &snat_main;
551 0 : int rv = 0;
552 :
553 : ip4_address_t l_addr, e_addr, pool_addr;
554 0 : u32 sw_if_index, flags = 0, vrf_id;
555 0 : u16 l_port = 0, e_port = 0;
556 : ip_protocol_t proto;
557 0 : u8 *tag = 0;
558 :
559 0 : memcpy (&l_addr.as_u8, mp->local_ip_address, 4);
560 0 : memcpy (&pool_addr.as_u8, mp->pool_ip_address, 4);
561 :
562 0 : if (pool_addr.as_u32 != 0)
563 : {
564 0 : flags |= NAT_SM_FLAG_EXACT_ADDRESS;
565 : }
566 :
567 0 : if (mp->flags & NAT_API_IS_ADDR_ONLY)
568 : {
569 0 : flags |= NAT_SM_FLAG_ADDR_ONLY;
570 : }
571 : else
572 : {
573 0 : l_port = mp->local_port;
574 0 : e_port = mp->external_port;
575 : }
576 :
577 0 : if (mp->flags & NAT_API_IS_TWICE_NAT)
578 : {
579 0 : flags |= NAT_SM_FLAG_TWICE_NAT;
580 : }
581 :
582 0 : if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
583 : {
584 0 : flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
585 : }
586 :
587 0 : if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
588 : {
589 0 : flags |= NAT_SM_FLAG_OUT2IN_ONLY;
590 : }
591 :
592 0 : sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
593 0 : if (sw_if_index != ~0)
594 : {
595 0 : flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
596 : }
597 : else
598 : {
599 0 : memcpy (&e_addr.as_u8, mp->external_ip_address, 4);
600 : }
601 :
602 0 : proto = mp->protocol;
603 0 : vrf_id = clib_net_to_host_u32 (mp->vrf_id);
604 :
605 0 : if (mp->is_add)
606 : {
607 0 : mp->tag[sizeof (mp->tag) - 1] = 0;
608 0 : tag = format (0, "%s", mp->tag);
609 0 : vec_terminate_c_string (tag);
610 :
611 0 : rv = nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
612 : vrf_id, sw_if_index, flags, pool_addr,
613 : tag);
614 0 : vec_free (tag);
615 : }
616 : else
617 : {
618 0 : rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
619 : vrf_id, sw_if_index, flags);
620 : }
621 0 : REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_V2_REPLY);
622 : }
623 :
624 : static void
625 0 : send_nat44_static_mapping_details (snat_static_mapping_t * m,
626 : vl_api_registration_t * reg, u32 context)
627 : {
628 : vl_api_nat44_static_mapping_details_t *rmp;
629 0 : snat_main_t *sm = &snat_main;
630 0 : u32 len = sizeof (*rmp);
631 :
632 0 : rmp = vl_msg_api_alloc (len);
633 0 : clib_memset (rmp, 0, len);
634 0 : rmp->_vl_msg_id =
635 0 : ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
636 :
637 0 : clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
638 0 : clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
639 0 : rmp->external_sw_if_index = ~0;
640 0 : rmp->vrf_id = htonl (m->vrf_id);
641 0 : rmp->context = context;
642 :
643 : // convert these in new api
644 :
645 0 : if (is_sm_self_twice_nat (m->flags))
646 : {
647 0 : rmp->flags |= NAT_API_IS_SELF_TWICE_NAT;
648 : }
649 :
650 0 : if (is_sm_out2in_only (m->flags))
651 : {
652 0 : rmp->flags |= NAT_API_IS_OUT2IN_ONLY;
653 : }
654 :
655 0 : if (is_sm_twice_nat (m->flags))
656 : {
657 0 : rmp->flags |= NAT_API_IS_TWICE_NAT;
658 : }
659 :
660 0 : if (is_sm_addr_only (m->flags))
661 : {
662 0 : rmp->flags |= NAT_API_IS_ADDR_ONLY;
663 : }
664 : else
665 : {
666 0 : rmp->protocol = m->proto;
667 0 : rmp->external_port = m->external_port;
668 0 : rmp->local_port = m->local_port;
669 : }
670 :
671 0 : if (m->tag)
672 0 : strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
673 :
674 0 : vl_api_send_msg (reg, (u8 *) rmp);
675 0 : }
676 :
677 : static void
678 0 : send_nat44_static_map_resolve_details (snat_static_mapping_resolve_t *m,
679 : vl_api_registration_t *reg, u32 context)
680 : {
681 : vl_api_nat44_static_mapping_details_t *rmp;
682 0 : snat_main_t *sm = &snat_main;
683 :
684 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
685 0 : clib_memset (rmp, 0, sizeof (*rmp));
686 0 : rmp->_vl_msg_id =
687 0 : ntohs (VL_API_NAT44_STATIC_MAPPING_DETAILS + sm->msg_id_base);
688 0 : clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
689 0 : rmp->external_sw_if_index = htonl (m->sw_if_index);
690 0 : rmp->vrf_id = htonl (m->vrf_id);
691 0 : rmp->context = context;
692 :
693 0 : if (is_sm_twice_nat (m->flags))
694 : {
695 0 : rmp->flags |= NAT_API_IS_TWICE_NAT;
696 : }
697 :
698 0 : if (is_sm_addr_only (m->flags))
699 : {
700 0 : rmp->flags |= NAT_API_IS_ADDR_ONLY;
701 : }
702 : else
703 : {
704 0 : rmp->protocol = m->proto;
705 0 : rmp->external_port = m->e_port;
706 0 : rmp->local_port = m->l_port;
707 : }
708 :
709 0 : if (m->tag)
710 0 : strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
711 :
712 0 : vl_api_send_msg (reg, (u8 *) rmp);
713 0 : }
714 :
715 : static void
716 0 : vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
717 : * mp)
718 : {
719 : vl_api_registration_t *reg;
720 0 : snat_main_t *sm = &snat_main;
721 : snat_static_mapping_t *m;
722 : snat_static_mapping_resolve_t *rp;
723 : int j;
724 :
725 0 : reg = vl_api_client_index_to_registration (mp->client_index);
726 0 : if (!reg)
727 0 : return;
728 :
729 0 : pool_foreach (m, sm->static_mappings)
730 : {
731 0 : if (!is_sm_identity_nat (m->flags) && !is_sm_lb (m->flags))
732 0 : send_nat44_static_mapping_details (m, reg, mp->context);
733 : }
734 :
735 0 : for (j = 0; j < vec_len (sm->sm_to_resolve); j++)
736 : {
737 0 : rp = sm->sm_to_resolve + j;
738 0 : if (!is_sm_identity_nat (rp->flags))
739 0 : send_nat44_static_map_resolve_details (rp, reg, mp->context);
740 : }
741 : }
742 :
743 : static void
744 1 : vl_api_nat44_add_del_identity_mapping_t_handler
745 : (vl_api_nat44_add_del_identity_mapping_t * mp)
746 : {
747 : vl_api_nat44_add_del_identity_mapping_reply_t *rmp;
748 :
749 1 : snat_main_t *sm = &snat_main;
750 1 : int rv = 0;
751 :
752 1 : ip4_address_t addr, pool_addr = { 0 };
753 : u32 sw_if_index, flags, vrf_id;
754 1 : ip_protocol_t proto = 0;
755 1 : u16 port = 0;
756 1 : u8 *tag = 0;
757 :
758 1 : flags = NAT_SM_FLAG_IDENTITY_NAT;
759 :
760 1 : if (mp->flags & NAT_API_IS_ADDR_ONLY)
761 : {
762 1 : flags |= NAT_SM_FLAG_ADDR_ONLY;
763 : }
764 : else
765 : {
766 0 : port = mp->port;
767 0 : proto = mp->protocol;
768 : }
769 :
770 1 : sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
771 1 : if (sw_if_index != ~0)
772 : {
773 0 : flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
774 : }
775 : else
776 : {
777 1 : memcpy (&addr.as_u8, mp->ip_address, 4);
778 : }
779 :
780 1 : vrf_id = clib_net_to_host_u32 (mp->vrf_id);
781 :
782 1 : if (mp->is_add)
783 : {
784 1 : mp->tag[sizeof (mp->tag) - 1] = 0;
785 1 : tag = format (0, "%s", mp->tag);
786 1 : vec_terminate_c_string (tag);
787 :
788 1 : rv = nat44_ed_add_static_mapping (addr, addr, port, port, proto, vrf_id,
789 : sw_if_index, flags, pool_addr, tag);
790 1 : vec_free (tag);
791 : }
792 : else
793 : {
794 0 : rv = nat44_ed_del_static_mapping (addr, addr, port, port, proto, vrf_id,
795 : sw_if_index, flags);
796 : }
797 1 : REPLY_MACRO (VL_API_NAT44_ADD_DEL_IDENTITY_MAPPING_REPLY);
798 : }
799 :
800 : static void
801 0 : send_nat44_identity_mapping_details (snat_static_mapping_t * m, int index,
802 : vl_api_registration_t * reg, u32 context)
803 : {
804 : vl_api_nat44_identity_mapping_details_t *rmp;
805 0 : snat_main_t *sm = &snat_main;
806 0 : nat44_lb_addr_port_t *local = pool_elt_at_index (m->locals, index);
807 :
808 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
809 0 : clib_memset (rmp, 0, sizeof (*rmp));
810 0 : rmp->_vl_msg_id =
811 0 : ntohs (VL_API_NAT44_IDENTITY_MAPPING_DETAILS + sm->msg_id_base);
812 :
813 0 : if (is_sm_addr_only (m->flags))
814 0 : rmp->flags |= NAT_API_IS_ADDR_ONLY;
815 :
816 0 : clib_memcpy (rmp->ip_address, &(m->local_addr), 4);
817 0 : rmp->port = m->local_port;
818 0 : rmp->sw_if_index = ~0;
819 0 : rmp->vrf_id = htonl (local->vrf_id);
820 0 : rmp->protocol = m->proto;
821 0 : rmp->context = context;
822 0 : if (m->tag)
823 0 : strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
824 :
825 0 : vl_api_send_msg (reg, (u8 *) rmp);
826 0 : }
827 :
828 : static void
829 0 : send_nat44_identity_map_resolve_details (snat_static_mapping_resolve_t *m,
830 : vl_api_registration_t *reg,
831 : u32 context)
832 : {
833 : vl_api_nat44_identity_mapping_details_t *rmp;
834 0 : snat_main_t *sm = &snat_main;
835 :
836 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
837 0 : clib_memset (rmp, 0, sizeof (*rmp));
838 0 : rmp->_vl_msg_id =
839 0 : ntohs (VL_API_NAT44_IDENTITY_MAPPING_DETAILS + sm->msg_id_base);
840 :
841 0 : if (is_sm_addr_only (m->flags))
842 0 : rmp->flags = (vl_api_nat_config_flags_t) NAT_API_IS_ADDR_ONLY;
843 :
844 0 : rmp->port = m->l_port;
845 0 : rmp->sw_if_index = htonl (m->sw_if_index);
846 0 : rmp->vrf_id = htonl (m->vrf_id);
847 0 : rmp->protocol = m->proto;
848 0 : rmp->context = context;
849 0 : if (m->tag)
850 0 : strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
851 :
852 0 : vl_api_send_msg (reg, (u8 *) rmp);
853 0 : }
854 :
855 : static void
856 0 : vl_api_nat44_identity_mapping_dump_t_handler
857 : (vl_api_nat44_identity_mapping_dump_t * mp)
858 : {
859 : vl_api_registration_t *reg;
860 0 : snat_main_t *sm = &snat_main;
861 : snat_static_mapping_t *m;
862 : snat_static_mapping_resolve_t *rp;
863 : int j;
864 :
865 0 : reg = vl_api_client_index_to_registration (mp->client_index);
866 0 : if (!reg)
867 0 : return;
868 :
869 0 : pool_foreach (m, sm->static_mappings)
870 : {
871 0 : if (is_sm_identity_nat (m->flags) && !is_sm_lb (m->flags))
872 : {
873 0 : pool_foreach_index (j, m->locals)
874 : {
875 0 : send_nat44_identity_mapping_details (m, j, reg, mp->context);
876 : }
877 : }
878 : }
879 :
880 0 : for (j = 0; j < vec_len (sm->sm_to_resolve); j++)
881 : {
882 0 : rp = sm->sm_to_resolve + j;
883 0 : if (is_sm_identity_nat (rp->flags))
884 0 : send_nat44_identity_map_resolve_details (rp, reg, mp->context);
885 : }
886 : }
887 :
888 : static void
889 2 : vl_api_nat44_add_del_interface_addr_t_handler
890 : (vl_api_nat44_add_del_interface_addr_t * mp)
891 : {
892 2 : snat_main_t *sm = &snat_main;
893 : vl_api_nat44_add_del_interface_addr_reply_t *rmp;
894 2 : u32 sw_if_index = ntohl (mp->sw_if_index);
895 : u8 twice_nat;
896 2 : int rv = 0;
897 :
898 2 : VALIDATE_SW_IF_INDEX (mp);
899 :
900 2 : twice_nat = mp->flags & NAT_API_IS_TWICE_NAT;
901 :
902 2 : if (mp->is_add)
903 : {
904 2 : rv = nat44_ed_add_interface_address (sw_if_index, twice_nat);
905 : }
906 : else
907 : {
908 0 : rv = nat44_ed_del_interface_address (sw_if_index, twice_nat);
909 : }
910 :
911 2 : BAD_SW_IF_INDEX_LABEL;
912 :
913 2 : REPLY_MACRO (VL_API_NAT44_ADD_DEL_INTERFACE_ADDR_REPLY);
914 : }
915 :
916 : static void
917 0 : send_nat44_interface_addr_details (u32 sw_if_index,
918 : vl_api_registration_t * reg, u32 context,
919 : u8 twice_nat)
920 : {
921 : vl_api_nat44_interface_addr_details_t *rmp;
922 0 : snat_main_t *sm = &snat_main;
923 :
924 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
925 0 : clib_memset (rmp, 0, sizeof (*rmp));
926 0 : rmp->_vl_msg_id =
927 0 : ntohs (VL_API_NAT44_INTERFACE_ADDR_DETAILS + sm->msg_id_base);
928 0 : rmp->sw_if_index = ntohl (sw_if_index);
929 :
930 0 : if (twice_nat)
931 0 : rmp->flags = (vl_api_nat_config_flags_t) NAT_API_IS_TWICE_NAT;
932 0 : rmp->context = context;
933 :
934 0 : vl_api_send_msg (reg, (u8 *) rmp);
935 0 : }
936 :
937 : static void
938 0 : vl_api_nat44_interface_addr_dump_t_handler (vl_api_nat44_interface_addr_dump_t
939 : * mp)
940 : {
941 0 : snat_main_t *sm = &snat_main;
942 : vl_api_registration_t *reg;
943 : snat_address_resolve_t *ap;
944 :
945 0 : reg = vl_api_client_index_to_registration (mp->client_index);
946 0 : if (!reg)
947 0 : return;
948 :
949 0 : vec_foreach (ap, sm->addr_to_resolve)
950 : {
951 0 : send_nat44_interface_addr_details (ap->sw_if_index, reg, mp->context,
952 0 : ap->is_twice_nat);
953 : }
954 : }
955 :
956 : static nat44_lb_addr_port_t *
957 12 : unformat_nat44_lb_addr_port (vl_api_nat44_lb_addr_port_t *addr_port_pairs,
958 : u32 addr_port_pair_num)
959 : {
960 : u8 i;
961 12 : nat44_lb_addr_port_t *lb_addr_port_pairs = 0, lb_addr_port;
962 : vl_api_nat44_lb_addr_port_t *ap;
963 :
964 36 : for (i = 0; i < addr_port_pair_num; i++)
965 : {
966 24 : ap = &addr_port_pairs[i];
967 24 : clib_memset (&lb_addr_port, 0, sizeof (lb_addr_port));
968 24 : clib_memcpy (&lb_addr_port.addr, ap->addr, 4);
969 24 : lb_addr_port.port = ap->port;
970 24 : lb_addr_port.probability = ap->probability;
971 24 : lb_addr_port.vrf_id = clib_net_to_host_u32 (ap->vrf_id);
972 24 : vec_add1 (lb_addr_port_pairs, lb_addr_port);
973 : }
974 :
975 12 : return lb_addr_port_pairs;
976 : }
977 :
978 : static void
979 12 : vl_api_nat44_add_del_lb_static_mapping_t_handler (
980 : vl_api_nat44_add_del_lb_static_mapping_t *mp)
981 : {
982 12 : snat_main_t *sm = &snat_main;
983 : vl_api_nat44_add_del_lb_static_mapping_reply_t *rmp;
984 12 : nat44_lb_addr_port_t *locals = 0;
985 : ip4_address_t e_addr;
986 : ip_protocol_t proto;
987 12 : u32 flags = 0;
988 12 : u8 *tag = 0;
989 12 : int rv = 0;
990 :
991 12 : locals = unformat_nat44_lb_addr_port (mp->locals,
992 : clib_net_to_host_u32 (mp->local_num));
993 12 : clib_memcpy (&e_addr, mp->external_addr, 4);
994 12 : proto = mp->protocol;
995 :
996 12 : if (mp->flags & NAT_API_IS_TWICE_NAT)
997 : {
998 2 : flags |= NAT_SM_FLAG_TWICE_NAT;
999 : }
1000 10 : else if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
1001 : {
1002 3 : flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
1003 : }
1004 :
1005 12 : if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
1006 : {
1007 2 : flags |= NAT_SM_FLAG_OUT2IN_ONLY;
1008 : }
1009 :
1010 12 : if (mp->is_add)
1011 : {
1012 12 : mp->tag[sizeof (mp->tag) - 1] = 0;
1013 12 : tag = format (0, "%s", mp->tag);
1014 12 : vec_terminate_c_string (tag);
1015 :
1016 12 : rv = nat44_ed_add_lb_static_mapping (
1017 12 : e_addr, mp->external_port, proto, locals, flags, tag,
1018 : clib_net_to_host_u32 (mp->affinity));
1019 : }
1020 : else
1021 : {
1022 0 : rv = nat44_ed_del_lb_static_mapping (e_addr, mp->external_port, proto,
1023 : flags);
1024 : }
1025 :
1026 12 : vec_free (locals);
1027 12 : vec_free (tag);
1028 12 : REPLY_MACRO (VL_API_NAT44_ADD_DEL_LB_STATIC_MAPPING_REPLY);
1029 : }
1030 :
1031 : static void
1032 2 : vl_api_nat44_lb_static_mapping_add_del_local_t_handler (
1033 : vl_api_nat44_lb_static_mapping_add_del_local_t *mp)
1034 : {
1035 2 : snat_main_t *sm = &snat_main;
1036 : vl_api_nat44_lb_static_mapping_add_del_local_reply_t *rmp;
1037 2 : int rv = 0;
1038 : ip4_address_t e_addr, l_addr;
1039 : ip_protocol_t proto;
1040 :
1041 2 : clib_memcpy (&e_addr, mp->external_addr, 4);
1042 2 : clib_memcpy (&l_addr, mp->local.addr, 4);
1043 2 : proto = mp->protocol;
1044 :
1045 4 : rv = nat44_ed_add_del_lb_static_mapping_local (
1046 2 : e_addr, mp->external_port, l_addr, mp->local.port, proto,
1047 2 : clib_net_to_host_u32 (mp->local.vrf_id), mp->local.probability,
1048 2 : mp->is_add);
1049 :
1050 2 : REPLY_MACRO (VL_API_NAT44_LB_STATIC_MAPPING_ADD_DEL_LOCAL_REPLY);
1051 : }
1052 :
1053 : static void
1054 0 : send_nat44_lb_static_mapping_details (snat_static_mapping_t *m,
1055 : vl_api_registration_t *reg, u32 context)
1056 : {
1057 : vl_api_nat44_lb_static_mapping_details_t *rmp;
1058 0 : snat_main_t *sm = &snat_main;
1059 : nat44_lb_addr_port_t *ap;
1060 : vl_api_nat44_lb_addr_port_t *locals;
1061 0 : u32 local_num = 0;
1062 :
1063 0 : rmp = vl_msg_api_alloc (
1064 0 : sizeof (*rmp) + (pool_elts (m->locals) * sizeof (nat44_lb_addr_port_t)));
1065 :
1066 0 : clib_memset (rmp, 0, sizeof (*rmp));
1067 0 : rmp->_vl_msg_id =
1068 0 : ntohs (VL_API_NAT44_LB_STATIC_MAPPING_DETAILS + sm->msg_id_base);
1069 :
1070 0 : clib_memcpy (rmp->external_addr, &(m->external_addr), 4);
1071 0 : rmp->external_port = m->external_port;
1072 0 : rmp->protocol = m->proto;
1073 0 : rmp->context = context;
1074 :
1075 0 : if (is_sm_self_twice_nat (m->flags))
1076 : {
1077 0 : rmp->flags |= NAT_API_IS_SELF_TWICE_NAT;
1078 : }
1079 :
1080 0 : if (is_sm_out2in_only (m->flags))
1081 : {
1082 0 : rmp->flags |= NAT_API_IS_OUT2IN_ONLY;
1083 : }
1084 :
1085 0 : if (is_sm_twice_nat (m->flags))
1086 : {
1087 0 : rmp->flags |= NAT_API_IS_TWICE_NAT;
1088 : }
1089 :
1090 0 : if (m->tag)
1091 0 : strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
1092 :
1093 0 : locals = (vl_api_nat44_lb_addr_port_t *) rmp->locals;
1094 0 : pool_foreach (ap, m->locals)
1095 : {
1096 0 : clib_memcpy (locals->addr, &(ap->addr), 4);
1097 0 : locals->port = ap->port;
1098 0 : locals->probability = ap->probability;
1099 0 : locals->vrf_id = ntohl (ap->vrf_id);
1100 0 : locals++;
1101 0 : local_num++;
1102 : }
1103 0 : rmp->local_num = ntohl (local_num);
1104 :
1105 0 : vl_api_send_msg (reg, (u8 *) rmp);
1106 0 : }
1107 :
1108 : static void
1109 0 : vl_api_nat44_lb_static_mapping_dump_t_handler (
1110 : vl_api_nat44_lb_static_mapping_dump_t *mp)
1111 : {
1112 : vl_api_registration_t *reg;
1113 0 : snat_main_t *sm = &snat_main;
1114 : snat_static_mapping_t *m;
1115 :
1116 0 : reg = vl_api_client_index_to_registration (mp->client_index);
1117 0 : if (!reg)
1118 0 : return;
1119 :
1120 0 : pool_foreach (m, sm->static_mappings)
1121 : {
1122 0 : if (is_sm_lb (m->flags))
1123 0 : send_nat44_lb_static_mapping_details (m, reg, mp->context);
1124 : }
1125 : }
1126 :
1127 : static void
1128 14 : vl_api_nat44_del_session_t_handler (vl_api_nat44_del_session_t *mp)
1129 : {
1130 14 : snat_main_t *sm = &snat_main;
1131 : vl_api_nat44_del_session_reply_t *rmp;
1132 : ip4_address_t addr, eh_addr;
1133 : u16 port, eh_port;
1134 : u32 vrf_id;
1135 14 : int rv = 0;
1136 : u8 is_in;
1137 :
1138 14 : memcpy (&addr.as_u8, mp->address, 4);
1139 14 : port = mp->port;
1140 14 : vrf_id = clib_net_to_host_u32 (mp->vrf_id);
1141 14 : memcpy (&eh_addr.as_u8, mp->ext_host_address, 4);
1142 14 : eh_port = mp->ext_host_port;
1143 :
1144 14 : is_in = mp->flags & NAT_API_IS_INSIDE;
1145 :
1146 14 : rv = nat44_ed_del_session (sm, &addr, port, &eh_addr, eh_port, mp->protocol,
1147 : vrf_id, is_in);
1148 :
1149 14 : REPLY_MACRO (VL_API_NAT44_DEL_SESSION_REPLY);
1150 : }
1151 :
1152 : static void
1153 25 : vl_api_nat44_forwarding_enable_disable_t_handler (
1154 : vl_api_nat44_forwarding_enable_disable_t *mp)
1155 : {
1156 : vl_api_nat44_forwarding_enable_disable_reply_t *rmp;
1157 25 : snat_main_t *sm = &snat_main;
1158 25 : int rv = 0;
1159 25 : nat44_ed_forwarding_enable_disable (mp->enable);
1160 25 : REPLY_MACRO (VL_API_NAT44_FORWARDING_ENABLE_DISABLE_REPLY);
1161 : }
1162 :
1163 : static void
1164 4 : vl_api_nat44_show_running_config_t_handler (
1165 : vl_api_nat44_show_running_config_t *mp)
1166 : {
1167 : vl_api_nat44_show_running_config_reply_t *rmp;
1168 4 : snat_main_t *sm = &snat_main;
1169 4 : nat44_config_t *rc = &sm->rconfig;
1170 4 : int rv = 0;
1171 :
1172 4 : REPLY_MACRO2_ZERO (
1173 : VL_API_NAT44_SHOW_RUNNING_CONFIG_REPLY, ({
1174 : rmp->inside_vrf = htonl (rc->inside_vrf);
1175 : rmp->outside_vrf = htonl (rc->outside_vrf);
1176 :
1177 : rmp->sessions = htonl (rc->sessions);
1178 : rmp->translation_buckets = htonl (sm->translation_buckets);
1179 :
1180 : // OBSOLETE
1181 : rmp->users = 0;
1182 : rmp->user_buckets = 0;
1183 : rmp->user_sessions = 0;
1184 :
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);
1189 :
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;
1194 : }));
1195 : }
1196 :
1197 : static void
1198 0 : vl_api_nat44_ed_add_del_vrf_table_t_handler (
1199 : vl_api_nat44_ed_add_del_vrf_table_t *mp)
1200 : {
1201 0 : snat_main_t *sm = &snat_main;
1202 : vl_api_nat44_ed_add_del_vrf_table_reply_t *rmp;
1203 0 : int rv = nat44_ed_add_del_vrf_table (clib_net_to_host_u32 (mp->table_vrf_id),
1204 0 : mp->is_add);
1205 0 : REPLY_MACRO (VL_API_NAT44_ED_ADD_DEL_VRF_TABLE_REPLY);
1206 : }
1207 :
1208 : static void
1209 0 : vl_api_nat44_ed_add_del_vrf_route_t_handler (
1210 : vl_api_nat44_ed_add_del_vrf_route_t *mp)
1211 : {
1212 0 : snat_main_t *sm = &snat_main;
1213 : vl_api_nat44_ed_add_del_vrf_route_reply_t *rmp;
1214 : int rv =
1215 0 : nat44_ed_add_del_vrf_route (clib_net_to_host_u32 (mp->table_vrf_id),
1216 0 : clib_net_to_host_u32 (mp->vrf_id), mp->is_add);
1217 0 : REPLY_MACRO (VL_API_NAT44_ED_ADD_DEL_VRF_ROUTE_REPLY);
1218 : }
1219 :
1220 : static void
1221 0 : nat44_ed_vrf_tables_send_details (vl_api_registration_t *rp, u32 context,
1222 : vrf_table_t *t)
1223 : {
1224 0 : snat_main_t *sm = &snat_main;
1225 : vl_api_nat44_ed_vrf_tables_details_t *mp;
1226 :
1227 0 : u32 *vrf_ids = 0;
1228 : vrf_route_t *r;
1229 :
1230 0 : mp = vl_msg_api_alloc_zero (sizeof (*mp) +
1231 0 : sizeof (mp->vrf_ids[0]) * vec_len (t->routes));
1232 0 : mp->_vl_msg_id =
1233 0 : ntohs (VL_API_NAT44_ED_VRF_TABLES_DETAILS + sm->msg_id_base);
1234 0 : mp->context = context;
1235 0 : mp->n_vrf_ids = clib_host_to_net_u32 (vec_len (t->routes));
1236 :
1237 0 : pool_foreach (r, t->routes)
1238 : {
1239 0 : vec_add1 (vrf_ids, r->vrf_id);
1240 : }
1241 :
1242 : // copy the records
1243 0 : clib_memcpy (mp->vrf_ids, vrf_ids,
1244 : sizeof (mp->vrf_ids[0]) * vec_len (t->routes));
1245 :
1246 0 : vec_free (vrf_ids);
1247 :
1248 : // send the message
1249 0 : vl_api_send_msg (rp, (u8 *) mp);
1250 0 : }
1251 :
1252 : static void
1253 0 : nat44_ed_vrf_tables_send_details_v2 (vl_api_registration_t *rp, u32 context,
1254 : vrf_table_t *t)
1255 : {
1256 0 : snat_main_t *sm = &snat_main;
1257 : vl_api_nat44_ed_vrf_tables_v2_details_t *mp;
1258 :
1259 0 : u32 *vrf_ids = 0;
1260 : vrf_route_t *r;
1261 :
1262 0 : mp = vl_msg_api_alloc_zero (sizeof (*mp) +
1263 0 : sizeof (mp->vrf_ids[0]) * vec_len (t->routes));
1264 0 : mp->_vl_msg_id = clib_net_to_host_u16 (VL_API_NAT44_ED_VRF_TABLES_DETAILS +
1265 0 : sm->msg_id_base);
1266 0 : mp->context = context;
1267 0 : mp->n_vrf_ids = clib_net_to_host_u32 (vec_len (t->routes));
1268 0 : mp->table_vrf_id = clib_net_to_host_u32 (t->table_vrf_id);
1269 0 : pool_foreach (r, t->routes)
1270 : {
1271 0 : vec_add1 (vrf_ids, clib_net_to_host_u32 (r->vrf_id));
1272 : }
1273 :
1274 : // copy the records
1275 0 : clib_memcpy (mp->vrf_ids, vrf_ids,
1276 : sizeof (mp->vrf_ids[0]) * vec_len (t->routes));
1277 :
1278 0 : vec_free (vrf_ids);
1279 :
1280 : // send the message
1281 0 : vl_api_send_msg (rp, (u8 *) mp);
1282 0 : }
1283 :
1284 : static void
1285 0 : vl_api_nat44_ed_vrf_tables_dump_t_handler (
1286 : vl_api_nat44_ed_vrf_tables_dump_t *mp)
1287 : {
1288 0 : snat_main_t *sm = &snat_main;
1289 : vl_api_registration_t *rp;
1290 : vrf_table_t *t;
1291 :
1292 0 : rp = vl_api_client_index_to_registration (mp->client_index);
1293 0 : if (rp == 0)
1294 0 : return;
1295 :
1296 0 : pool_foreach (t, sm->vrf_tables)
1297 : {
1298 0 : nat44_ed_vrf_tables_send_details (rp, mp->context, t);
1299 : }
1300 : }
1301 :
1302 : static void
1303 0 : vl_api_nat44_ed_vrf_tables_v2_dump_t_handler (
1304 : vl_api_nat44_ed_vrf_tables_v2_dump_t *mp)
1305 : {
1306 0 : snat_main_t *sm = &snat_main;
1307 : vl_api_registration_t *rp;
1308 : vrf_table_t *t;
1309 :
1310 0 : rp = vl_api_client_index_to_registration (mp->client_index);
1311 0 : if (rp == 0)
1312 0 : return;
1313 :
1314 0 : pool_foreach (t, sm->vrf_tables)
1315 : {
1316 0 : nat44_ed_vrf_tables_send_details_v2 (rp, mp->context, t);
1317 : }
1318 : }
1319 :
1320 : /* user (internal host) key */
1321 : typedef struct
1322 : {
1323 : union
1324 : {
1325 : struct
1326 : {
1327 : ip4_address_t addr;
1328 : u32 fib_index;
1329 : };
1330 : u64 as_u64;
1331 : };
1332 : } snat_user_key_t;
1333 :
1334 : typedef struct
1335 : {
1336 : ip4_address_t addr;
1337 : u32 fib_index;
1338 : u32 nsessions;
1339 : u32 nstaticsessions;
1340 : } snat_user_t;
1341 :
1342 : typedef struct
1343 : {
1344 : u32 user_buckets;
1345 : snat_user_t *users;
1346 : clib_bihash_8_8_t user_hash;
1347 : } user_create_helper_t;
1348 :
1349 : static void
1350 10 : send_nat44_user_details (snat_user_t *u, vl_api_registration_t *reg,
1351 : u32 context)
1352 : {
1353 : vl_api_nat44_user_details_t *rmp;
1354 10 : snat_main_t *sm = &snat_main;
1355 10 : ip4_main_t *im = &ip4_main;
1356 :
1357 10 : rmp = vl_msg_api_alloc (sizeof (*rmp));
1358 10 : clib_memset (rmp, 0, sizeof (*rmp));
1359 10 : rmp->_vl_msg_id = ntohs (VL_API_NAT44_USER_DETAILS + sm->msg_id_base);
1360 :
1361 10 : if (!pool_is_free_index (im->fibs, u->fib_index))
1362 : {
1363 10 : fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
1364 10 : rmp->vrf_id = ntohl (fib->ft_table_id);
1365 : }
1366 :
1367 10 : clib_memcpy (rmp->ip_address, &(u->addr), 4);
1368 10 : rmp->nsessions = ntohl (u->nsessions);
1369 10 : rmp->nstaticsessions = ntohl (u->nstaticsessions);
1370 10 : rmp->context = context;
1371 :
1372 10 : vl_api_send_msg (reg, (u8 *) rmp);
1373 10 : }
1374 :
1375 : static void
1376 30 : nat_ed_user_create_helper (user_create_helper_t *uch, snat_session_t *s)
1377 : {
1378 : snat_user_key_t k;
1379 30 : k.addr = s->in2out.addr;
1380 30 : k.fib_index = s->in2out.fib_index;
1381 : clib_bihash_kv_8_8_t key, value;
1382 30 : key.key = k.as_u64;
1383 : snat_user_t *u;
1384 :
1385 30 : if (clib_bihash_search_8_8 (&uch->user_hash, &key, &value))
1386 : {
1387 10 : pool_get (uch->users, u);
1388 10 : u->addr = k.addr;
1389 10 : u->fib_index = k.fib_index;
1390 10 : u->nsessions = 0;
1391 10 : u->nstaticsessions = 0;
1392 10 : key.value = u - uch->users;
1393 10 : clib_bihash_add_del_8_8 (&uch->user_hash, &key, 1);
1394 : }
1395 : else
1396 : {
1397 20 : u = pool_elt_at_index (uch->users, value.value);
1398 : }
1399 30 : if (nat44_ed_is_session_static (s))
1400 : {
1401 18 : ++u->nstaticsessions;
1402 : }
1403 : else
1404 : {
1405 12 : ++u->nsessions;
1406 : }
1407 30 : }
1408 :
1409 : u8 *
1410 0 : format_user_kvp (u8 *s, va_list *args)
1411 : {
1412 0 : clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
1413 : snat_user_key_t k;
1414 0 : k.as_u64 = v->key;
1415 0 : s = format (s, "%U fib %d user-index %llu", format_ip4_address, &k.addr,
1416 : k.fib_index, v->value);
1417 0 : return s;
1418 : }
1419 :
1420 : static void
1421 24 : nat_ed_users_create (snat_main_per_thread_data_t *tsm,
1422 : user_create_helper_t *uch)
1423 : {
1424 : snat_session_t *s;
1425 24 : clib_bihash_init_8_8 (&uch->user_hash, "users", uch->user_buckets, 0);
1426 24 : clib_bihash_set_kvp_format_fn_8_8 (&uch->user_hash, format_user_kvp);
1427 54 : pool_foreach (s, tsm->sessions)
1428 : {
1429 30 : nat_ed_user_create_helper (uch, s);
1430 : }
1431 24 : }
1432 :
1433 : static void
1434 24 : nat_ed_users_destroy (user_create_helper_t *uch)
1435 : {
1436 24 : pool_free (uch->users);
1437 24 : clib_bihash_free_8_8 (&uch->user_hash);
1438 24 : }
1439 :
1440 : static void
1441 8 : vl_api_nat44_user_dump_t_handler (vl_api_nat44_user_dump_t * mp)
1442 : {
1443 : user_create_helper_t uch;
1444 : vl_api_registration_t *reg;
1445 8 : snat_main_t *sm = &snat_main;
1446 : snat_main_per_thread_data_t *tsm;
1447 : snat_user_t *u;
1448 :
1449 8 : clib_memset (&uch, 0, sizeof (uch));
1450 :
1451 8 : uch.user_buckets = nat_calc_bihash_buckets (1024);
1452 :
1453 8 : reg = vl_api_client_index_to_registration (mp->client_index);
1454 8 : if (!reg)
1455 0 : return;
1456 :
1457 32 : vec_foreach (tsm, sm->per_thread_data)
1458 : {
1459 24 : nat_ed_users_create (tsm, &uch);
1460 34 : pool_foreach (u, uch.users)
1461 : {
1462 10 : send_nat44_user_details (u, reg, mp->context);
1463 : }
1464 24 : nat_ed_users_destroy (&uch);
1465 : }
1466 : }
1467 :
1468 : static void
1469 34 : send_nat44_user_session_details (snat_session_t * s,
1470 : vl_api_registration_t * reg, u32 context)
1471 : {
1472 : vl_api_nat44_user_session_details_t *rmp;
1473 34 : snat_main_t *sm = &snat_main;
1474 :
1475 34 : rmp = vl_msg_api_alloc (sizeof (*rmp));
1476 34 : clib_memset (rmp, 0, sizeof (*rmp));
1477 34 : rmp->_vl_msg_id =
1478 34 : ntohs (VL_API_NAT44_USER_SESSION_DETAILS + sm->msg_id_base);
1479 34 : clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
1480 34 : clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
1481 :
1482 34 : if (nat44_ed_is_session_static (s))
1483 21 : rmp->flags |= NAT_API_IS_STATIC;
1484 :
1485 34 : if (nat44_ed_is_twice_nat_session (s))
1486 9 : rmp->flags |= NAT_API_IS_TWICE_NAT;
1487 :
1488 34 : rmp->flags |= NAT_API_IS_EXT_HOST_VALID;
1489 :
1490 34 : rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
1491 34 : rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
1492 34 : rmp->total_pkts = ntohl (s->total_pkts);
1493 34 : rmp->context = context;
1494 34 : rmp->outside_port = s->out2in.port;
1495 34 : rmp->inside_port = s->in2out.port;
1496 34 : rmp->protocol = clib_host_to_net_u16 (s->proto);
1497 34 : clib_memcpy (rmp->ext_host_address, &s->ext_host_addr, 4);
1498 34 : rmp->ext_host_port = s->ext_host_port;
1499 34 : if (nat44_ed_is_twice_nat_session (s))
1500 : {
1501 9 : clib_memcpy (rmp->ext_host_nat_address, &s->ext_host_nat_addr, 4);
1502 9 : rmp->ext_host_nat_port = s->ext_host_nat_port;
1503 : }
1504 :
1505 34 : vl_api_send_msg (reg, (u8 *) rmp);
1506 34 : }
1507 :
1508 : static void
1509 51 : vl_api_nat44_user_session_dump_t_handler (vl_api_nat44_user_session_dump_t *
1510 : mp)
1511 : {
1512 : snat_main_per_thread_data_t *tsm;
1513 51 : snat_main_t *sm = &snat_main;
1514 : vl_api_registration_t *reg;
1515 : snat_user_key_t ukey;
1516 : snat_session_t *s;
1517 : ip4_header_t ip;
1518 :
1519 51 : reg = vl_api_client_index_to_registration (mp->client_index);
1520 51 : if (!reg)
1521 0 : return;
1522 :
1523 51 : clib_memcpy (&ukey.addr, mp->ip_address, 4);
1524 51 : ip.src_address.as_u32 = ukey.addr.as_u32;
1525 51 : ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
1526 51 : if (sm->num_workers > 1)
1527 34 : tsm = vec_elt_at_index (
1528 : sm->per_thread_data,
1529 : nat44_ed_get_in2out_worker_index (0, &ip, ukey.fib_index, 0));
1530 : else
1531 17 : tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
1532 :
1533 97 : pool_foreach (s, tsm->sessions) {
1534 46 : if (s->in2out.addr.as_u32 == ukey.addr.as_u32)
1535 : {
1536 34 : send_nat44_user_session_details (s, reg, mp->context);
1537 : }
1538 : }
1539 : }
1540 :
1541 : static void
1542 0 : send_nat44_user_session_v2_details (snat_session_t *s,
1543 : vl_api_registration_t *reg, u32 context)
1544 : {
1545 : vl_api_nat44_user_session_v2_details_t *rmp;
1546 0 : snat_main_t *sm = &snat_main;
1547 0 : vnet_main_t *vnm = vnet_get_main ();
1548 0 : u64 now = vlib_time_now (vnm->vlib_main);
1549 0 : u64 sess_timeout_time = 0;
1550 :
1551 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
1552 0 : clib_memset (rmp, 0, sizeof (*rmp));
1553 0 : rmp->_vl_msg_id =
1554 0 : ntohs (VL_API_NAT44_USER_SESSION_V2_DETAILS + sm->msg_id_base);
1555 0 : clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
1556 0 : clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
1557 :
1558 0 : if (nat44_ed_is_session_static (s))
1559 0 : rmp->flags |= NAT_API_IS_STATIC;
1560 :
1561 0 : if (nat44_ed_is_twice_nat_session (s))
1562 0 : rmp->flags |= NAT_API_IS_TWICE_NAT;
1563 :
1564 0 : rmp->flags |= NAT_API_IS_EXT_HOST_VALID;
1565 :
1566 0 : rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
1567 0 : rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
1568 0 : rmp->total_pkts = ntohl (s->total_pkts);
1569 0 : rmp->context = context;
1570 0 : rmp->outside_port = s->out2in.port;
1571 0 : rmp->inside_port = s->in2out.port;
1572 0 : rmp->protocol = clib_host_to_net_u16 (s->proto);
1573 0 : clib_memcpy (rmp->ext_host_address, &s->ext_host_addr, 4);
1574 0 : rmp->ext_host_port = s->ext_host_port;
1575 0 : if (nat44_ed_is_twice_nat_session (s))
1576 : {
1577 0 : clib_memcpy (rmp->ext_host_nat_address, &s->ext_host_nat_addr, 4);
1578 0 : rmp->ext_host_nat_port = s->ext_host_nat_port;
1579 : }
1580 :
1581 0 : sess_timeout_time = s->last_heard + nat44_session_get_timeout (sm, s);
1582 0 : rmp->is_timed_out = (now >= sess_timeout_time);
1583 :
1584 0 : vl_api_send_msg (reg, (u8 *) rmp);
1585 0 : }
1586 :
1587 : static void
1588 0 : send_nat44_user_session_v3_details (snat_session_t *s,
1589 : vl_api_registration_t *reg, u32 context)
1590 : {
1591 : vl_api_nat44_user_session_v3_details_t *rmp;
1592 0 : snat_main_t *sm = &snat_main;
1593 0 : u64 now = vlib_time_now (vlib_get_main ());
1594 0 : u64 sess_timeout_time = 0;
1595 :
1596 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
1597 0 : clib_memset (rmp, 0, sizeof (*rmp));
1598 0 : rmp->_vl_msg_id =
1599 0 : ntohs (VL_API_NAT44_USER_SESSION_V3_DETAILS + sm->msg_id_base);
1600 0 : clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
1601 0 : clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
1602 :
1603 0 : if (nat44_ed_is_session_static (s))
1604 0 : rmp->flags |= NAT_API_IS_STATIC;
1605 :
1606 0 : if (nat44_ed_is_twice_nat_session (s))
1607 0 : rmp->flags |= NAT_API_IS_TWICE_NAT;
1608 :
1609 0 : rmp->flags |= NAT_API_IS_EXT_HOST_VALID;
1610 :
1611 0 : rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
1612 0 : rmp->time_since_last_heard =
1613 0 : clib_host_to_net_u64 ((u64) (now - s->last_heard));
1614 0 : rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
1615 0 : rmp->total_pkts = ntohl (s->total_pkts);
1616 0 : rmp->context = context;
1617 0 : rmp->outside_port = s->out2in.port;
1618 0 : rmp->inside_port = s->in2out.port;
1619 0 : rmp->protocol = clib_host_to_net_u16 (s->proto);
1620 0 : clib_memcpy (rmp->ext_host_address, &s->ext_host_addr, 4);
1621 0 : rmp->ext_host_port = s->ext_host_port;
1622 0 : if (nat44_ed_is_twice_nat_session (s))
1623 : {
1624 0 : clib_memcpy (rmp->ext_host_nat_address, &s->ext_host_nat_addr, 4);
1625 0 : rmp->ext_host_nat_port = s->ext_host_nat_port;
1626 : }
1627 :
1628 0 : sess_timeout_time = s->last_heard + nat44_session_get_timeout (sm, s);
1629 0 : rmp->is_timed_out = (now >= sess_timeout_time);
1630 :
1631 0 : vl_api_send_msg (reg, (u8 *) rmp);
1632 0 : }
1633 :
1634 : static void
1635 0 : vl_api_nat44_user_session_v2_dump_t_handler (
1636 : vl_api_nat44_user_session_v2_dump_t *mp)
1637 : {
1638 : snat_main_per_thread_data_t *tsm;
1639 0 : snat_main_t *sm = &snat_main;
1640 : vl_api_registration_t *reg;
1641 : snat_user_key_t ukey;
1642 : snat_session_t *s;
1643 : ip4_header_t ip;
1644 :
1645 0 : reg = vl_api_client_index_to_registration (mp->client_index);
1646 0 : if (!reg)
1647 0 : return;
1648 :
1649 0 : clib_memcpy (&ukey.addr, mp->ip_address, 4);
1650 0 : ip.src_address.as_u32 = ukey.addr.as_u32;
1651 0 : ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
1652 0 : if (sm->num_workers > 1)
1653 0 : tsm = vec_elt_at_index (
1654 : sm->per_thread_data,
1655 : nat44_ed_get_in2out_worker_index (0, &ip, ukey.fib_index, 0));
1656 : else
1657 0 : tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
1658 :
1659 0 : pool_foreach (s, tsm->sessions)
1660 : {
1661 0 : if (s->in2out.addr.as_u32 == ukey.addr.as_u32)
1662 : {
1663 0 : send_nat44_user_session_v2_details (s, reg, mp->context);
1664 : }
1665 : }
1666 : }
1667 :
1668 : static void
1669 0 : vl_api_nat44_user_session_v3_dump_t_handler (
1670 : vl_api_nat44_user_session_v3_dump_t *mp)
1671 : {
1672 : snat_main_per_thread_data_t *tsm;
1673 0 : snat_main_t *sm = &snat_main;
1674 : vl_api_registration_t *reg;
1675 : snat_user_key_t ukey;
1676 : snat_session_t *s;
1677 : ip4_header_t ip;
1678 :
1679 0 : reg = vl_api_client_index_to_registration (mp->client_index);
1680 0 : if (!reg)
1681 0 : return;
1682 :
1683 0 : clib_memcpy (&ukey.addr, mp->ip_address, 4);
1684 0 : ip.src_address.as_u32 = ukey.addr.as_u32;
1685 0 : ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
1686 0 : if (sm->num_workers > 1)
1687 0 : tsm = vec_elt_at_index (
1688 : sm->per_thread_data,
1689 : nat44_ed_get_in2out_worker_index (0, &ip, ukey.fib_index, 0));
1690 : else
1691 0 : tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
1692 :
1693 0 : pool_foreach (s, tsm->sessions)
1694 : {
1695 0 : if (s->in2out.addr.as_u32 == ukey.addr.as_u32)
1696 : {
1697 0 : send_nat44_user_session_v3_details (s, reg, mp->context);
1698 : }
1699 : }
1700 : }
1701 :
1702 : /* API definitions */
1703 : #include <vnet/format_fns.h>
1704 : #include <nat/nat44-ed/nat44_ed.api.c>
1705 :
1706 : /* Set up the API message handling tables */
1707 : clib_error_t *
1708 559 : nat44_api_hookup (vlib_main_t * vm)
1709 : {
1710 559 : snat_main_t *sm = &snat_main;
1711 559 : sm->msg_id_base = setup_message_id_table ();
1712 559 : return 0;
1713 : }
1714 :
1715 : /*
1716 : * fd.io coding-style-patch-verification: ON
1717 : *
1718 : * Local Variables:
1719 : * eval: (c-set-style "gnu")
1720 : * End:
1721 : */
|