Line data Source code
1 : /*
2 : * Copyright (c) 2020 Cisco and/or its affiliates.
3 : * * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 :
16 : /**
17 : * @file
18 : * @brief Deterministic NAT (CGN) plugin API implementation
19 : */
20 :
21 : #include <vnet/ip/ip_types_api.h>
22 : #include <nat/det44/det44.h>
23 : #include <nat/det44/det44.api_enum.h>
24 : #include <nat/det44/det44.api_types.h>
25 : #include <vnet/fib/fib_table.h>
26 : #include <vnet/ip/ip.h>
27 :
28 : #include <vlibmemory/api.h>
29 :
30 : #define REPLY_MSG_ID_BASE dm->msg_id_base
31 : #include <vlibapi/api_helper_macros.h>
32 :
33 : static void
34 6 : vl_api_det44_add_del_map_t_handler (vl_api_det44_add_del_map_t * mp)
35 : {
36 6 : det44_main_t *dm = &det44_main;
37 : vl_api_det44_add_del_map_reply_t *rmp;
38 6 : int rv = 0;
39 : ip4_address_t in_addr, out_addr;
40 6 : clib_memcpy (&in_addr, mp->in_addr, 4);
41 6 : clib_memcpy (&out_addr, mp->out_addr, 4);
42 6 : rv = snat_det_add_map (&in_addr, mp->in_plen, &out_addr,
43 6 : mp->out_plen, mp->is_add);
44 6 : REPLY_MACRO (VL_API_DET44_ADD_DEL_MAP_REPLY);
45 : }
46 :
47 : static void
48 1 : vl_api_det44_forward_t_handler (vl_api_det44_forward_t * mp)
49 : {
50 1 : det44_main_t *dm = &det44_main;
51 : vl_api_det44_forward_reply_t *rmp;
52 1 : int rv = 0;
53 1 : u16 lo_port = 0, hi_port = 0;
54 : snat_det_map_t *m;
55 : ip4_address_t in_addr, out_addr;
56 :
57 1 : out_addr.as_u32 = 0;
58 1 : clib_memcpy (&in_addr, mp->in_addr, 4);
59 1 : m = snat_det_map_by_user (&in_addr);
60 1 : if (!m)
61 : {
62 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
63 0 : goto send_reply;
64 : }
65 :
66 1 : snat_det_forward (m, &in_addr, &out_addr, &lo_port);
67 1 : hi_port = lo_port + m->ports_per_host - 1;
68 :
69 1 : send_reply:
70 : /* *INDENT-OFF* */
71 1 : REPLY_MACRO2 (VL_API_DET44_FORWARD_REPLY,
72 : ({
73 : rmp->out_port_lo = ntohs (lo_port);
74 : rmp->out_port_hi = ntohs (hi_port);
75 : clib_memcpy (rmp->out_addr, &out_addr, 4);
76 : }))
77 : /* *INDENT-ON* */
78 : }
79 :
80 : static void
81 1 : vl_api_det44_reverse_t_handler (vl_api_det44_reverse_t * mp)
82 : {
83 1 : det44_main_t *dm = &det44_main;
84 : vl_api_det44_reverse_reply_t *rmp;
85 1 : int rv = 0;
86 : ip4_address_t out_addr, in_addr;
87 : snat_det_map_t *m;
88 :
89 1 : in_addr.as_u32 = 0;
90 1 : clib_memcpy (&out_addr, mp->out_addr, 4);
91 1 : m = snat_det_map_by_out (&out_addr);
92 1 : if (!m)
93 : {
94 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
95 0 : goto send_reply;
96 : }
97 :
98 1 : snat_det_reverse (m, &out_addr, htons (mp->out_port), &in_addr);
99 :
100 1 : send_reply:
101 : /* *INDENT-OFF* */
102 1 : REPLY_MACRO2 (VL_API_DET44_REVERSE_REPLY,
103 : ({
104 : clib_memcpy (rmp->in_addr, &in_addr, 4);
105 : }))
106 : /* *INDENT-ON* */
107 : }
108 :
109 : static void
110 7 : sent_det44_map_details (snat_det_map_t * m, vl_api_registration_t * reg,
111 : u32 context)
112 : {
113 7 : det44_main_t *dm = &det44_main;
114 : vl_api_det44_map_details_t *rmp;
115 :
116 7 : rmp = vl_msg_api_alloc (sizeof (*rmp));
117 7 : clib_memset (rmp, 0, sizeof (*rmp));
118 7 : rmp->_vl_msg_id = ntohs (VL_API_DET44_MAP_DETAILS + dm->msg_id_base);
119 7 : clib_memcpy (rmp->in_addr, &m->in_addr, 4);
120 7 : rmp->in_plen = m->in_plen;
121 7 : clib_memcpy (rmp->out_addr, &m->out_addr, 4);
122 7 : rmp->out_plen = m->out_plen;
123 7 : rmp->sharing_ratio = htonl (m->sharing_ratio);
124 7 : rmp->ports_per_host = htons (m->ports_per_host);
125 7 : rmp->ses_num = htonl (m->ses_num);
126 7 : rmp->context = context;
127 :
128 7 : vl_api_send_msg (reg, (u8 *) rmp);
129 7 : }
130 :
131 : static void
132 7 : vl_api_det44_map_dump_t_handler (vl_api_det44_map_dump_t * mp)
133 : {
134 7 : det44_main_t *dm = &det44_main;
135 : vl_api_registration_t *reg;
136 : snat_det_map_t *m;
137 :
138 7 : reg = vl_api_client_index_to_registration (mp->client_index);
139 7 : if (!reg)
140 0 : return;
141 :
142 : /* *INDENT-OFF* */
143 14 : vec_foreach(m, dm->det_maps)
144 7 : sent_det44_map_details(m, reg, mp->context);
145 : /* *INDENT-ON* */
146 : }
147 :
148 : static void
149 1 : vl_api_det44_close_session_out_t_handler (vl_api_det44_close_session_out_t
150 : * mp)
151 : {
152 1 : det44_main_t *dm = &det44_main;
153 : vl_api_det44_close_session_out_reply_t *rmp;
154 : ip4_address_t out_addr, ext_addr, in_addr;
155 : snat_det_out_key_t key;
156 : snat_det_map_t *m;
157 : snat_det_session_t *ses;
158 1 : int rv = 0;
159 :
160 1 : clib_memcpy (&out_addr, mp->out_addr, 4);
161 1 : clib_memcpy (&ext_addr, mp->ext_addr, 4);
162 :
163 1 : m = snat_det_map_by_out (&out_addr);
164 1 : if (!m)
165 : {
166 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
167 0 : goto send_reply;
168 : }
169 1 : snat_det_reverse (m, &ext_addr, ntohs (mp->out_port), &in_addr);
170 1 : key.ext_host_addr = ext_addr;
171 1 : key.ext_host_port = mp->ext_port;
172 1 : key.out_port = mp->out_port;
173 1 : ses = snat_det_get_ses_by_out (m, &in_addr, key.as_u64);
174 1 : if (!ses)
175 : {
176 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
177 0 : goto send_reply;
178 : }
179 1 : snat_det_ses_close (m, ses);
180 :
181 1 : send_reply:
182 1 : REPLY_MACRO (VL_API_DET44_CLOSE_SESSION_OUT_REPLY);
183 : }
184 :
185 : static void
186 1 : vl_api_det44_close_session_in_t_handler (vl_api_det44_close_session_in_t * mp)
187 : {
188 1 : det44_main_t *dm = &det44_main;
189 : vl_api_det44_close_session_in_reply_t *rmp;
190 : ip4_address_t in_addr, ext_addr;
191 : snat_det_out_key_t key;
192 : snat_det_map_t *m;
193 : snat_det_session_t *ses;
194 1 : int rv = 0;
195 :
196 1 : clib_memcpy (&in_addr, mp->in_addr, 4);
197 1 : clib_memcpy (&ext_addr, mp->ext_addr, 4);
198 :
199 1 : m = snat_det_map_by_user (&in_addr);
200 1 : if (!m)
201 : {
202 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
203 0 : goto send_reply;
204 : }
205 1 : key.ext_host_addr = ext_addr;
206 1 : key.ext_host_port = mp->ext_port;
207 1 : ses = snat_det_find_ses_by_in (m, &in_addr, mp->in_port, key);
208 1 : if (!ses)
209 : {
210 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
211 0 : goto send_reply;
212 : }
213 1 : snat_det_ses_close (m, ses);
214 :
215 1 : send_reply:
216 1 : REPLY_MACRO (VL_API_DET44_CLOSE_SESSION_OUT_REPLY);
217 : }
218 :
219 : static void
220 3 : send_det44_session_details (snat_det_session_t * s,
221 : vl_api_registration_t * reg, u32 context)
222 : {
223 3 : det44_main_t *dm = &det44_main;
224 : vl_api_det44_session_details_t *rmp;
225 :
226 3 : rmp = vl_msg_api_alloc (sizeof (*rmp));
227 3 : clib_memset (rmp, 0, sizeof (*rmp));
228 3 : rmp->_vl_msg_id = ntohs (VL_API_DET44_SESSION_DETAILS + dm->msg_id_base);
229 3 : rmp->in_port = s->in_port;
230 3 : clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
231 3 : rmp->ext_port = s->out.ext_host_port;
232 3 : rmp->out_port = s->out.out_port;
233 3 : rmp->state = s->state;
234 3 : rmp->expire = ntohl (s->expire);
235 3 : rmp->context = context;
236 :
237 3 : vl_api_send_msg (reg, (u8 *) rmp);
238 3 : }
239 :
240 : static void
241 1 : vl_api_det44_session_dump_t_handler (vl_api_det44_session_dump_t * mp)
242 : {
243 : vl_api_registration_t *reg;
244 : ip4_address_t user_addr;
245 : snat_det_map_t *m;
246 : snat_det_session_t *s, empty_ses;
247 : u16 i;
248 :
249 1 : reg = vl_api_client_index_to_registration (mp->client_index);
250 1 : if (!reg)
251 0 : return;
252 :
253 1 : clib_memset (&empty_ses, 0, sizeof (empty_ses));
254 1 : clib_memcpy (&user_addr, mp->user_addr, 4);
255 1 : m = snat_det_map_by_user (&user_addr);
256 1 : if (!m)
257 0 : return;
258 :
259 1 : s = m->sessions + snat_det_user_ses_offset (&user_addr, m->in_plen);
260 1001 : for (i = 0; i < DET44_SES_PER_USER; i++)
261 : {
262 1000 : if (s->out.as_u64)
263 3 : send_det44_session_details (s, reg, mp->context);
264 1000 : s++;
265 : }
266 : }
267 :
268 : static void
269 14 : vl_api_det44_plugin_enable_disable_t_handler
270 : (vl_api_det44_plugin_enable_disable_t * mp)
271 : {
272 14 : det44_main_t *dm = &det44_main;
273 : vl_api_det44_plugin_enable_disable_reply_t *rmp;
274 14 : det44_config_t c = { 0 };
275 14 : int rv = 0;
276 14 : if (mp->enable)
277 : {
278 7 : c.outside_vrf_id = ntohl (mp->outside_vrf);
279 7 : c.inside_vrf_id = ntohl (mp->inside_vrf);
280 7 : rv = det44_plugin_enable (c);
281 : }
282 : else
283 : {
284 7 : rv = det44_plugin_disable ();
285 : }
286 14 : REPLY_MACRO (VL_API_DET44_PLUGIN_ENABLE_DISABLE_REPLY);
287 : }
288 :
289 : static void
290 10 : vl_api_det44_interface_add_del_feature_t_handler
291 : (vl_api_det44_interface_add_del_feature_t * mp)
292 : {
293 10 : det44_main_t *dm = &det44_main;
294 : vl_api_det44_interface_add_del_feature_reply_t *rmp;
295 10 : u32 sw_if_index = ntohl (mp->sw_if_index);
296 10 : int rv = 0;
297 10 : VALIDATE_SW_IF_INDEX (mp);
298 10 : rv = det44_interface_add_del (sw_if_index, mp->is_inside, !mp->is_add);
299 10 : BAD_SW_IF_INDEX_LABEL;
300 10 : REPLY_MACRO (VL_API_DET44_INTERFACE_ADD_DEL_FEATURE_REPLY);
301 : }
302 :
303 : static void
304 0 : det44_send_interface_details (det44_interface_t * i,
305 : vl_api_registration_t * reg, u32 context)
306 : {
307 0 : det44_main_t *dm = &det44_main;
308 : vl_api_det44_interface_details_t *rmp;
309 :
310 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
311 0 : clib_memset (rmp, 0, sizeof (*rmp));
312 0 : rmp->_vl_msg_id = ntohs (VL_API_DET44_INTERFACE_DETAILS + dm->msg_id_base);
313 0 : rmp->sw_if_index = ntohl (i->sw_if_index);
314 0 : rmp->is_outside = det44_interface_is_outside (i);
315 0 : rmp->is_inside = det44_interface_is_inside (i);
316 0 : rmp->context = context;
317 0 : vl_api_send_msg (reg, (u8 *) rmp);
318 0 : }
319 :
320 : static void
321 0 : vl_api_det44_interface_dump_t_handler (vl_api_det44_interface_dump_t * mp)
322 : {
323 0 : det44_main_t *dm = &det44_main;
324 : vl_api_registration_t *reg;
325 : det44_interface_t *i;
326 :
327 0 : reg = vl_api_client_index_to_registration (mp->client_index);
328 0 : if (!reg)
329 0 : return;
330 :
331 : /* *INDENT-OFF* */
332 0 : pool_foreach (i, dm->interfaces)
333 : {
334 0 : det44_send_interface_details(i, reg, mp->context);
335 : }
336 : /* *INDENT-ON* */
337 : }
338 :
339 : static void
340 2 : vl_api_det44_set_timeouts_t_handler (vl_api_det44_set_timeouts_t * mp)
341 : {
342 2 : det44_main_t *dm = &det44_main;
343 : vl_api_det44_set_timeouts_reply_t *rmp;
344 : nat_timeouts_t timeouts;
345 2 : int rv = 0;
346 2 : timeouts.udp = ntohl (mp->udp);
347 2 : timeouts.tcp.established = ntohl (mp->tcp_established);
348 2 : timeouts.tcp.transitory = ntohl (mp->tcp_transitory);
349 2 : timeouts.icmp = ntohl (mp->icmp);
350 2 : rv = det44_set_timeouts (&timeouts);
351 2 : REPLY_MACRO (VL_API_DET44_SET_TIMEOUTS_REPLY);
352 : }
353 :
354 : static void
355 2 : vl_api_det44_get_timeouts_t_handler (vl_api_det44_get_timeouts_t * mp)
356 : {
357 2 : det44_main_t *dm = &det44_main;
358 : vl_api_det44_get_timeouts_reply_t *rmp;
359 : nat_timeouts_t timeouts;
360 2 : int rv = 0;
361 2 : timeouts = det44_get_timeouts ();
362 : /* *INDENT-OFF* */
363 2 : REPLY_MACRO2 (VL_API_DET44_GET_TIMEOUTS_REPLY,
364 : ({
365 : rmp->udp = htonl (timeouts.udp);
366 : rmp->tcp_established = htonl (timeouts.tcp.established);
367 : rmp->tcp_transitory = htonl (timeouts.tcp.transitory);
368 : rmp->icmp = htonl (timeouts.icmp);
369 : }))
370 : /* *INDENT-ON* */
371 : }
372 :
373 : /*
374 : * Obsolete deterministic API to be removed
375 : */
376 :
377 : static void
378 0 : vl_api_nat_det_add_del_map_t_handler (vl_api_nat_det_add_del_map_t * mp)
379 : {
380 0 : det44_main_t *dm = &det44_main;
381 : vl_api_nat_det_add_del_map_reply_t *rmp;
382 0 : int rv = 0;
383 : ip4_address_t in_addr, out_addr;
384 :
385 0 : clib_memcpy (&in_addr, mp->in_addr, 4);
386 0 : clib_memcpy (&out_addr, mp->out_addr, 4);
387 0 : rv = snat_det_add_map (&in_addr, mp->in_plen, &out_addr,
388 0 : mp->out_plen, mp->is_add);
389 0 : REPLY_MACRO (VL_API_NAT_DET_ADD_DEL_MAP_REPLY);
390 : }
391 :
392 : static void
393 0 : vl_api_nat_det_forward_t_handler (vl_api_nat_det_forward_t * mp)
394 : {
395 0 : det44_main_t *dm = &det44_main;
396 : vl_api_nat_det_forward_reply_t *rmp;
397 0 : int rv = 0;
398 0 : u16 lo_port = 0, hi_port = 0;
399 : snat_det_map_t *m;
400 : ip4_address_t in_addr, out_addr;
401 :
402 0 : out_addr.as_u32 = 0;
403 0 : clib_memcpy (&in_addr, mp->in_addr, 4);
404 0 : m = snat_det_map_by_user (&in_addr);
405 0 : if (!m)
406 : {
407 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
408 0 : goto send_reply;
409 : }
410 :
411 0 : snat_det_forward (m, &in_addr, &out_addr, &lo_port);
412 0 : hi_port = lo_port + m->ports_per_host - 1;
413 :
414 0 : send_reply:
415 : /* *INDENT-OFF* */
416 0 : REPLY_MACRO2 (VL_API_NAT_DET_FORWARD_REPLY,
417 : ({
418 : rmp->out_port_lo = ntohs (lo_port);
419 : rmp->out_port_hi = ntohs (hi_port);
420 : clib_memcpy (rmp->out_addr, &out_addr, 4);
421 : }))
422 : /* *INDENT-ON* */
423 : }
424 :
425 : static void
426 0 : vl_api_nat_det_reverse_t_handler (vl_api_nat_det_reverse_t * mp)
427 : {
428 0 : det44_main_t *dm = &det44_main;
429 : vl_api_nat_det_reverse_reply_t *rmp;
430 0 : int rv = 0;
431 : ip4_address_t out_addr, in_addr;
432 : snat_det_map_t *m;
433 :
434 0 : in_addr.as_u32 = 0;
435 0 : clib_memcpy (&out_addr, mp->out_addr, 4);
436 0 : m = snat_det_map_by_out (&out_addr);
437 0 : if (!m)
438 : {
439 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
440 0 : goto send_reply;
441 : }
442 :
443 0 : snat_det_reverse (m, &out_addr, htons (mp->out_port), &in_addr);
444 :
445 0 : send_reply:
446 : /* *INDENT-OFF* */
447 0 : REPLY_MACRO2 (VL_API_NAT_DET_REVERSE_REPLY,
448 : ({
449 : clib_memcpy (rmp->in_addr, &in_addr, 4);
450 : }))
451 : /* *INDENT-ON* */
452 : }
453 :
454 : static void
455 0 : sent_nat_det_map_details (snat_det_map_t * m, vl_api_registration_t * reg,
456 : u32 context)
457 : {
458 0 : det44_main_t *dm = &det44_main;
459 : vl_api_nat_det_map_details_t *rmp;
460 :
461 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
462 0 : clib_memset (rmp, 0, sizeof (*rmp));
463 0 : rmp->_vl_msg_id = ntohs (VL_API_NAT_DET_MAP_DETAILS + dm->msg_id_base);
464 0 : clib_memcpy (rmp->in_addr, &m->in_addr, 4);
465 0 : rmp->in_plen = m->in_plen;
466 0 : clib_memcpy (rmp->out_addr, &m->out_addr, 4);
467 0 : rmp->out_plen = m->out_plen;
468 0 : rmp->sharing_ratio = htonl (m->sharing_ratio);
469 0 : rmp->ports_per_host = htons (m->ports_per_host);
470 0 : rmp->ses_num = htonl (m->ses_num);
471 0 : rmp->context = context;
472 :
473 0 : vl_api_send_msg (reg, (u8 *) rmp);
474 0 : }
475 :
476 : static void
477 0 : vl_api_nat_det_map_dump_t_handler (vl_api_nat_det_map_dump_t * mp)
478 : {
479 0 : det44_main_t *dm = &det44_main;
480 : vl_api_registration_t *reg;
481 : snat_det_map_t *m;
482 :
483 0 : reg = vl_api_client_index_to_registration (mp->client_index);
484 0 : if (!reg)
485 0 : return;
486 :
487 : /* *INDENT-OFF* */
488 0 : vec_foreach(m, dm->det_maps)
489 0 : sent_nat_det_map_details(m, reg, mp->context);
490 : /* *INDENT-ON* */
491 : }
492 :
493 : static void
494 0 : vl_api_nat_det_close_session_out_t_handler (vl_api_nat_det_close_session_out_t
495 : * mp)
496 : {
497 0 : det44_main_t *dm = &det44_main;
498 : vl_api_nat_det_close_session_out_reply_t *rmp;
499 : ip4_address_t out_addr, ext_addr, in_addr;
500 : snat_det_out_key_t key;
501 : snat_det_map_t *m;
502 : snat_det_session_t *ses;
503 0 : int rv = 0;
504 :
505 0 : clib_memcpy (&out_addr, mp->out_addr, 4);
506 0 : clib_memcpy (&ext_addr, mp->ext_addr, 4);
507 :
508 0 : m = snat_det_map_by_out (&out_addr);
509 0 : if (!m)
510 : {
511 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
512 0 : goto send_reply;
513 : }
514 0 : snat_det_reverse (m, &ext_addr, ntohs (mp->out_port), &in_addr);
515 0 : key.ext_host_addr = ext_addr;
516 0 : key.ext_host_port = mp->ext_port;
517 0 : key.out_port = mp->out_port;
518 0 : ses = snat_det_get_ses_by_out (m, &in_addr, key.as_u64);
519 0 : if (!ses)
520 : {
521 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
522 0 : goto send_reply;
523 : }
524 0 : snat_det_ses_close (m, ses);
525 :
526 0 : send_reply:
527 0 : REPLY_MACRO (VL_API_NAT_DET_CLOSE_SESSION_OUT_REPLY);
528 : }
529 :
530 : static void
531 0 : vl_api_nat_det_close_session_in_t_handler (vl_api_nat_det_close_session_in_t *
532 : mp)
533 : {
534 0 : det44_main_t *dm = &det44_main;
535 : vl_api_nat_det_close_session_in_reply_t *rmp;
536 : ip4_address_t in_addr, ext_addr;
537 : snat_det_out_key_t key;
538 : snat_det_map_t *m;
539 : snat_det_session_t *ses;
540 0 : int rv = 0;
541 :
542 0 : clib_memcpy (&in_addr, mp->in_addr, 4);
543 0 : clib_memcpy (&ext_addr, mp->ext_addr, 4);
544 :
545 0 : m = snat_det_map_by_user (&in_addr);
546 0 : if (!m)
547 : {
548 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
549 0 : goto send_reply;
550 : }
551 0 : key.ext_host_addr = ext_addr;
552 0 : key.ext_host_port = mp->ext_port;
553 0 : ses = snat_det_find_ses_by_in (m, &in_addr, mp->in_port, key);
554 0 : if (!ses)
555 : {
556 0 : rv = VNET_API_ERROR_NO_SUCH_ENTRY;
557 0 : goto send_reply;
558 : }
559 0 : snat_det_ses_close (m, ses);
560 :
561 0 : send_reply:
562 0 : REPLY_MACRO (VL_API_NAT_DET_CLOSE_SESSION_OUT_REPLY);
563 : }
564 :
565 : static void
566 0 : send_nat_det_session_details (snat_det_session_t * s,
567 : vl_api_registration_t * reg, u32 context)
568 : {
569 0 : det44_main_t *dm = &det44_main;
570 : vl_api_nat_det_session_details_t *rmp;
571 :
572 0 : rmp = vl_msg_api_alloc (sizeof (*rmp));
573 0 : clib_memset (rmp, 0, sizeof (*rmp));
574 0 : rmp->_vl_msg_id = ntohs (VL_API_NAT_DET_SESSION_DETAILS + dm->msg_id_base);
575 0 : rmp->in_port = s->in_port;
576 0 : clib_memcpy (rmp->ext_addr, &s->out.ext_host_addr, 4);
577 0 : rmp->ext_port = s->out.ext_host_port;
578 0 : rmp->out_port = s->out.out_port;
579 0 : rmp->state = s->state;
580 0 : rmp->expire = ntohl (s->expire);
581 0 : rmp->context = context;
582 :
583 0 : vl_api_send_msg (reg, (u8 *) rmp);
584 0 : }
585 :
586 : static void
587 0 : vl_api_nat_det_session_dump_t_handler (vl_api_nat_det_session_dump_t * mp)
588 : {
589 : vl_api_registration_t *reg;
590 : ip4_address_t user_addr;
591 : snat_det_map_t *m;
592 : snat_det_session_t *s, empty_ses;
593 : u16 i;
594 :
595 0 : reg = vl_api_client_index_to_registration (mp->client_index);
596 0 : if (!reg)
597 0 : return;
598 :
599 0 : clib_memset (&empty_ses, 0, sizeof (empty_ses));
600 0 : clib_memcpy (&user_addr, mp->user_addr, 4);
601 0 : m = snat_det_map_by_user (&user_addr);
602 0 : if (!m)
603 0 : return;
604 :
605 0 : s = m->sessions + snat_det_user_ses_offset (&user_addr, m->in_plen);
606 0 : for (i = 0; i < DET44_SES_PER_USER; i++)
607 : {
608 0 : if (s->out.as_u64)
609 0 : send_nat_det_session_details (s, reg, mp->context);
610 0 : s++;
611 : }
612 : }
613 :
614 : /* API definitions */
615 : #include <vnet/format_fns.h>
616 : #include <nat/det44/det44.api.c>
617 :
618 : /* Set up the API message handling tables */
619 : clib_error_t *
620 559 : det44_api_hookup (vlib_main_t * vm)
621 : {
622 559 : det44_main_t *dm = &det44_main;
623 559 : dm->msg_id_base = setup_message_id_table ();
624 559 : return 0;
625 : }
626 :
627 : /*
628 : * fd.io coding-style-patch-verification: ON
629 : *
630 : * Local Variables:
631 : * eval: (c-set-style "gnu")
632 : * End:
633 : */
|