FD.io VPP  v18.01-8-g0eacf49
Vector Packet Processing
nat_reass.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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  * @file
17  * @brief NAT plugin virtual fragmentation reassembly
18  */
19 
20 #include <vnet/vnet.h>
21 #include <nat/nat_reass.h>
22 
24 
25 static u32
27 {
29  u32 nbuckets;
30  u8 i;
31 
32  if (is_ip6)
33  nbuckets = (u32) (srm->ip6_max_reass / NAT_REASS_HT_LOAD_FACTOR);
34  else
35  nbuckets = (u32) (srm->ip4_max_reass / NAT_REASS_HT_LOAD_FACTOR);
36 
37  for (i = 0; i < 31; i++)
38  if ((1 << i) >= nbuckets)
39  break;
40  nbuckets = 1 << i;
41 
42  return nbuckets;
43 }
44 
46 nat_ip4_reass_get_frags_inline (nat_reass_ip4_t * reass, u32 ** bi)
47 {
49  u32 elt_index;
50  dlist_elt_t *elt;
51 
52  while ((elt_index =
54  reass->frags_per_reass_list_head_index)) !=
55  ~0)
56  {
57  elt = pool_elt_at_index (srm->ip4_frags_list_pool, elt_index);
58  vec_add1 (*bi, elt->value);
59  reass->frag_n--;
60  pool_put_index (srm->ip4_frags_list_pool, elt_index);
61  }
62 }
63 
65 nat_ip6_reass_get_frags_inline (nat_reass_ip6_t * reass, u32 ** bi)
66 {
68  u32 elt_index;
69  dlist_elt_t *elt;
70 
71  while ((elt_index =
73  reass->frags_per_reass_list_head_index)) !=
74  ~0)
75  {
76  elt = pool_elt_at_index (srm->ip6_frags_list_pool, elt_index);
77  vec_add1 (*bi, elt->value);
78  reass->frag_n--;
79  pool_put_index (srm->ip6_frags_list_pool, elt_index);
80  }
81 }
82 
83 int
84 nat_reass_set (u32 timeout, u16 max_reass, u8 max_frag, u8 drop_frag,
85  u8 is_ip6)
86 {
88  u32 nbuckets;
89 
90  if (is_ip6)
91  {
92  if (srm->ip6_max_reass != max_reass)
93  {
95 
96  srm->ip6_max_reass = max_reass;
99  nbuckets = nat_reass_get_nbuckets (0);
100  clib_bihash_free_48_8 (&srm->ip6_reass_hash);
101  clib_bihash_init_48_8 (&srm->ip6_reass_hash, "nat-ip6-reass",
102  nbuckets, nbuckets * 1024);
103 
105  }
106  srm->ip6_timeout = timeout;
107  srm->ip6_max_frag = max_frag;
108  srm->ip6_drop_frag = drop_frag;
109  }
110  else
111  {
112  if (srm->ip4_max_reass != max_reass)
113  {
115 
116  srm->ip4_max_reass = max_reass;
117  pool_free (srm->ip4_reass_pool);
119  nbuckets = nat_reass_get_nbuckets (0);
120  clib_bihash_free_16_8 (&srm->ip4_reass_hash);
121  clib_bihash_init_16_8 (&srm->ip4_reass_hash, "nat-ip4-reass",
122  nbuckets, nbuckets * 1024);
124  }
125  srm->ip4_timeout = timeout;
126  srm->ip4_max_frag = max_frag;
127  srm->ip4_drop_frag = drop_frag;
128  }
129 
130  return 0;
131 }
132 
133 u32
135 {
137 
138  if (is_ip6)
139  return srm->ip6_timeout;
140 
141  return srm->ip4_timeout;
142 }
143 
144 u16
146 {
148 
149  if (is_ip6)
150  return srm->ip6_max_reass;
151 
152  return srm->ip4_max_reass;
153 }
154 
155 u8
157 {
159 
160  if (is_ip6)
161  return srm->ip6_max_frag;
162 
163  return srm->ip4_max_frag;
164 }
165 
166 u8
168 {
170 
171  if (is_ip6)
172  return srm->ip6_drop_frag;
173 
174  return srm->ip4_drop_frag;
175 }
176 
177 static_always_inline nat_reass_ip4_t *
179 {
181  clib_bihash_kv_16_8_t kv, value;
182  nat_reass_ip4_t *reass;
183 
184  kv.key[0] = k->as_u64[0];
185  kv.key[1] = k->as_u64[1];
186 
187  if (clib_bihash_search_16_8 (&srm->ip4_reass_hash, &kv, &value))
188  return 0;
189 
190  reass = pool_elt_at_index (srm->ip4_reass_pool, value.value);
191  if (now < reass->last_heard + (f64) srm->ip4_timeout)
192  return reass;
193 
194  return 0;
195 }
196 
197 nat_reass_ip4_t *
199  u8 proto)
200 {
202  nat_reass_ip4_t *reass = 0;
204  f64 now = vlib_time_now (srm->vlib_main);
205 
206  k.src.as_u32 = src.as_u32;
207  k.dst.as_u32 = dst.as_u32;
208  k.frag_id = frag_id;
209  k.proto = proto;
210 
212  reass = nat_ip4_reass_lookup (&k, now);
214 
215  return reass;
216 }
217 
218 nat_reass_ip4_t *
220  u16 frag_id, u8 proto, u8 reset_timeout,
221  u32 ** bi_to_drop)
222 {
224  nat_reass_ip4_t *reass = 0;
226  f64 now = vlib_time_now (srm->vlib_main);
227  dlist_elt_t *oldest_elt, *elt;
228  dlist_elt_t *per_reass_list_head_elt;
229  u32 oldest_index, elt_index;
231 
232  k.src.as_u32 = src.as_u32;
233  k.dst.as_u32 = dst.as_u32;
234  k.frag_id = frag_id;
235  k.proto = proto;
236 
238 
239  reass = nat_ip4_reass_lookup (&k, now);
240  if (reass)
241  {
242  if (reset_timeout)
243  {
244  reass->last_heard = now;
246  reass->lru_list_index);
249  reass->lru_list_index);
250  }
251  goto unlock;
252  }
253 
254  if (srm->ip4_reass_n >= srm->ip4_max_reass)
255  {
256  oldest_index =
258  srm->ip4_reass_head_index);
259  ASSERT (oldest_index != ~0);
260  oldest_elt =
261  pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
262  reass = pool_elt_at_index (srm->ip4_reass_pool, oldest_elt->value);
263  if (now < reass->last_heard + (f64) srm->ip4_timeout)
264  {
266  srm->ip4_reass_head_index, oldest_index);
267  clib_warning ("no free resassembly slot");
268  reass = 0;
269  goto unlock;
270  }
271 
273  srm->ip4_reass_head_index, oldest_index);
274 
275  kv.key[0] = k.as_u64[0];
276  kv.key[1] = k.as_u64[1];
277  if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 0))
278  {
279  reass = 0;
280  goto unlock;
281  }
282 
283  nat_ip4_reass_get_frags_inline (reass, bi_to_drop);
284  }
285  else
286  {
287  pool_get (srm->ip4_reass_pool, reass);
288  pool_get (srm->ip4_reass_lru_list_pool, elt);
289  reass->lru_list_index = elt_index = elt - srm->ip4_reass_lru_list_pool;
290  clib_dlist_init (srm->ip4_reass_lru_list_pool, elt_index);
291  elt->value = reass - srm->ip4_reass_pool;
293  srm->ip4_reass_head_index, elt_index);
294  pool_get (srm->ip4_frags_list_pool, per_reass_list_head_elt);
295  reass->frags_per_reass_list_head_index =
296  per_reass_list_head_elt - srm->ip4_frags_list_pool;
298  reass->frags_per_reass_list_head_index);
299  srm->ip4_reass_n++;
300  }
301 
302  reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
303  reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
304  kv.value = reass - srm->ip4_reass_pool;
305  reass->sess_index = (u32) ~ 0;
306  reass->thread_index = (u32) ~ 0;
307  reass->last_heard = now;
308 
309  if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 1))
310  {
311  reass = 0;
312  goto unlock;
313  }
314 
315 unlock:
317  return reass;
318 }
319 
320 int
321 nat_ip4_reass_add_fragment (nat_reass_ip4_t * reass, u32 bi)
322 {
324  dlist_elt_t *elt;
325  u32 elt_index;
326 
327  if (reass->frag_n >= srm->ip4_max_frag)
328  return -1;
329 
331 
332  pool_get (srm->ip4_frags_list_pool, elt);
333  elt_index = elt - srm->ip4_frags_list_pool;
334  clib_dlist_init (srm->ip4_frags_list_pool, elt_index);
335  elt->value = bi;
337  reass->frags_per_reass_list_head_index, elt_index);
338  reass->frag_n++;
339 
341 
342  return 0;
343 }
344 
345 void
346 nat_ip4_reass_get_frags (nat_reass_ip4_t * reass, u32 ** bi)
347 {
349 
351 
352  nat_ip4_reass_get_frags_inline (reass, bi);
353 
355 }
356 
357 void
359 {
360  nat_reass_ip4_t *reass;
362  f64 now = vlib_time_now (srm->vlib_main);
363 
364  /* *INDENT-OFF* */
365  pool_foreach (reass, srm->ip4_reass_pool,
366  ({
367  if (now < reass->last_heard + (f64) srm->ip4_timeout)
368  {
369  if (fn (reass, ctx))
370  return;
371  }
372  }));
373  /* *INDENT-ON* */
374 }
375 
376 static_always_inline nat_reass_ip6_t *
378 {
380  clib_bihash_kv_48_8_t kv, value;
381  nat_reass_ip6_t *reass;
382 
383  k->unused = 0;
384  kv.key[0] = k->as_u64[0];
385  kv.key[1] = k->as_u64[1];
386  kv.key[2] = k->as_u64[2];
387  kv.key[3] = k->as_u64[3];
388  kv.key[4] = k->as_u64[4];
389  kv.key[5] = k->as_u64[5];
390 
391  if (clib_bihash_search_48_8 (&srm->ip6_reass_hash, &kv, &value))
392  return 0;
393 
394  reass = pool_elt_at_index (srm->ip6_reass_pool, value.value);
395  if (now < reass->last_heard + (f64) srm->ip6_timeout)
396  return reass;
397 
398  return 0;
399 }
400 
401 nat_reass_ip6_t *
403  u32 frag_id, u8 proto, u8 reset_timeout,
404  u32 ** bi_to_drop)
405 {
407  nat_reass_ip6_t *reass = 0;
409  f64 now = vlib_time_now (srm->vlib_main);
410  dlist_elt_t *oldest_elt, *elt;
411  dlist_elt_t *per_reass_list_head_elt;
412  u32 oldest_index, elt_index;
414 
415  k.src.as_u64[0] = src.as_u64[0];
416  k.src.as_u64[1] = src.as_u64[1];
417  k.dst.as_u64[0] = dst.as_u64[0];
418  k.dst.as_u64[1] = dst.as_u64[1];
419  k.frag_id = frag_id;
420  k.proto = proto;
421  k.unused = 0;
422 
424 
425  reass = nat_ip6_reass_lookup (&k, now);
426  if (reass)
427  {
428  if (reset_timeout)
429  {
430  reass->last_heard = now;
432  reass->lru_list_index);
435  reass->lru_list_index);
436  }
437  goto unlock;
438  }
439 
440  if (srm->ip6_reass_n >= srm->ip6_max_reass)
441  {
442  oldest_index =
444  srm->ip6_reass_head_index);
445  ASSERT (oldest_index != ~0);
446  oldest_elt =
447  pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
448  reass = pool_elt_at_index (srm->ip6_reass_pool, oldest_elt->value);
449  if (now < reass->last_heard + (f64) srm->ip6_timeout)
450  {
452  srm->ip6_reass_head_index, oldest_index);
453  clib_warning ("no free resassembly slot");
454  reass = 0;
455  goto unlock;
456  }
457 
459  srm->ip6_reass_head_index, oldest_index);
460 
461  kv.key[0] = k.as_u64[0];
462  kv.key[1] = k.as_u64[1];
463  kv.key[2] = k.as_u64[2];
464  kv.key[3] = k.as_u64[4];
465  kv.key[4] = k.as_u64[5];
466  if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 0))
467  {
468  reass = 0;
469  goto unlock;
470  }
471 
472  nat_ip6_reass_get_frags_inline (reass, bi_to_drop);
473  }
474  else
475  {
476  pool_get (srm->ip6_reass_pool, reass);
477  pool_get (srm->ip6_reass_lru_list_pool, elt);
478  reass->lru_list_index = elt_index = elt - srm->ip6_reass_lru_list_pool;
479  clib_dlist_init (srm->ip6_reass_lru_list_pool, elt_index);
480  elt->value = reass - srm->ip6_reass_pool;
482  srm->ip6_reass_head_index, elt_index);
483  pool_get (srm->ip6_frags_list_pool, per_reass_list_head_elt);
484  reass->frags_per_reass_list_head_index =
485  per_reass_list_head_elt - srm->ip6_frags_list_pool;
487  reass->frags_per_reass_list_head_index);
488  srm->ip6_reass_n++;
489  }
490 
491  reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
492  reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
493  reass->key.as_u64[2] = kv.key[2] = k.as_u64[2];
494  reass->key.as_u64[3] = kv.key[3] = k.as_u64[3];
495  reass->key.as_u64[4] = kv.key[4] = k.as_u64[4];
496  reass->key.as_u64[5] = kv.key[5] = k.as_u64[5];
497  kv.value = reass - srm->ip6_reass_pool;
498  reass->sess_index = (u32) ~ 0;
499  reass->last_heard = now;
500 
501  if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 1))
502  {
503  reass = 0;
504  goto unlock;
505  }
506 
507 unlock:
509  return reass;
510 }
511 
512 int
513 nat_ip6_reass_add_fragment (nat_reass_ip6_t * reass, u32 bi)
514 {
516  dlist_elt_t *elt;
517  u32 elt_index;
518 
519  if (reass->frag_n >= srm->ip6_max_frag)
520  return -1;
521 
523 
524  pool_get (srm->ip6_frags_list_pool, elt);
525  elt_index = elt - srm->ip6_frags_list_pool;
526  clib_dlist_init (srm->ip6_frags_list_pool, elt_index);
527  elt->value = bi;
529  reass->frags_per_reass_list_head_index, elt_index);
530  reass->frag_n++;
531 
533 
534  return 0;
535 }
536 
537 void
538 nat_ip6_reass_get_frags (nat_reass_ip6_t * reass, u32 ** bi)
539 {
541 
543 
544  nat_ip6_reass_get_frags_inline (reass, bi);
545 
547 }
548 
549 void
551 {
552  nat_reass_ip6_t *reass;
554  f64 now = vlib_time_now (srm->vlib_main);
555 
556  /* *INDENT-OFF* */
557  pool_foreach (reass, srm->ip6_reass_pool,
558  ({
559  if (now < reass->last_heard + (f64) srm->ip4_timeout)
560  {
561  if (fn (reass, ctx))
562  return;
563  }
564  }));
565  /* *INDENT-ON* */
566 }
567 
568 clib_error_t *
570 {
573  clib_error_t *error = 0;
574  dlist_elt_t *head;
575  u32 nbuckets, head_index;
576 
577  srm->vlib_main = vm;
578  srm->vnet_main = vnet_get_main ();
579 
580  /* IPv4 */
584  srm->ip4_drop_frag = 0;
585  srm->ip4_reass_n = 0;
586 
587  if (tm->n_vlib_mains > 1)
589 
591 
592  nbuckets = nat_reass_get_nbuckets (0);
593  clib_bihash_init_16_8 (&srm->ip4_reass_hash, "nat-ip4-reass", nbuckets,
594  nbuckets * 1024);
595 
596  pool_get (srm->ip4_reass_lru_list_pool, head);
597  srm->ip4_reass_head_index = head_index =
598  head - srm->ip4_reass_lru_list_pool;
599  clib_dlist_init (srm->ip4_reass_lru_list_pool, head_index);
600 
601  /* IPv6 */
605  srm->ip6_drop_frag = 0;
606  srm->ip6_reass_n = 0;
607 
608  if (tm->n_vlib_mains > 1)
610 
612 
613  nbuckets = nat_reass_get_nbuckets (1);
614  clib_bihash_init_48_8 (&srm->ip6_reass_hash, "nat-ip6-reass", nbuckets,
615  nbuckets * 1024);
616 
617  pool_get (srm->ip6_reass_lru_list_pool, head);
618  srm->ip6_reass_head_index = head_index =
619  head - srm->ip6_reass_lru_list_pool;
620  clib_dlist_init (srm->ip6_reass_lru_list_pool, head_index);
621 
622  return error;
623 }
624 
625 static clib_error_t *
627  vlib_cli_command_t * cmd)
628 {
629  clib_error_t *error = 0;
630  unformat_input_t _line_input, *line_input = &_line_input;
631  u32 timeout = 0, max_reass = 0, max_frag = 0;
632  u8 drop_frag = (u8) ~ 0, is_ip6 = 0;
633  int rv;
634 
635  /* Get a line of input. */
636  if (!unformat_user (input, unformat_line_input, line_input))
637  return 0;
638 
639  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
640  {
641  if (unformat (line_input, "max-reassemblies %u", &max_reass))
642  ;
643  else if (unformat (line_input, "max-fragments %u", &max_frag))
644  ;
645  else if (unformat (line_input, "timeout %u", &timeout))
646  ;
647  else if (unformat (line_input, "enable"))
648  drop_frag = 0;
649  else if (unformat (line_input, "disable"))
650  drop_frag = 1;
651  else if (unformat (line_input, "ip4"))
652  is_ip6 = 0;
653  else if (unformat (line_input, "ip6"))
654  is_ip6 = 1;
655  else
656  {
657  error = clib_error_return (0, "unknown input '%U'",
658  format_unformat_error, line_input);
659  goto done;
660  }
661  }
662 
663  if (!timeout)
664  timeout = nat_reass_get_timeout (is_ip6);
665  if (!max_reass)
666  max_reass = nat_reass_get_max_reass (is_ip6);
667  if (!max_frag)
668  max_frag = nat_reass_get_max_frag (is_ip6);
669  if (drop_frag == (u8) ~ 0)
670  drop_frag = nat_reass_is_drop_frag (is_ip6);
671 
672  rv =
673  nat_reass_set (timeout, (u16) max_reass, (u8) max_frag, drop_frag,
674  is_ip6);
675  if (rv)
676  {
677  error = clib_error_return (0, "nat_set_reass return %d", rv);
678  goto done;
679  }
680 
681 done:
682  unformat_free (line_input);
683 
684  return error;
685 }
686 
687 static int
688 nat_ip4_reass_walk_cli (nat_reass_ip4_t * reass, void *ctx)
689 {
690  vlib_main_t *vm = ctx;
691 
692  vlib_cli_output (vm, " src %U dst %U proto %u id 0x%04x cached %u",
693  format_ip4_address, &reass->key.src,
694  format_ip4_address, &reass->key.dst,
695  reass->key.proto,
696  clib_net_to_host_u16 (reass->key.frag_id), reass->frag_n);
697 
698  return 0;
699 }
700 
701 static int
702 nat_ip6_reass_walk_cli (nat_reass_ip6_t * reass, void *ctx)
703 {
704  vlib_main_t *vm = ctx;
705 
706  vlib_cli_output (vm, " src %U dst %U proto %u id 0x%08x cached %u",
707  format_ip6_address, &reass->key.src,
708  format_ip6_address, &reass->key.dst,
709  reass->key.proto,
710  clib_net_to_host_u32 (reass->key.frag_id), reass->frag_n);
711 
712  return 0;
713 }
714 
715 static clib_error_t *
717  vlib_cli_command_t * cmd)
718 {
719  vlib_cli_output (vm, "NAT IPv4 virtual fragmentation reassembly is %s",
720  nat_reass_is_drop_frag (0) ? "DISABLED" : "ENABLED");
721  vlib_cli_output (vm, " max-reasssemblies %u", nat_reass_get_max_reass (0));
722  vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (0));
723  vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (0));
724  vlib_cli_output (vm, " reassemblies:");
726 
727  vlib_cli_output (vm, "NAT IPv6 virtual fragmentation reassembly is %s",
728  nat_reass_is_drop_frag (1) ? "DISABLED" : "ENABLED");
729  vlib_cli_output (vm, " max-reasssemblies %u", nat_reass_get_max_reass (1));
730  vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (1));
731  vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (1));
732  vlib_cli_output (vm, " reassemblies:");
734 
735  return 0;
736 }
737 
738 /* *INDENT-OFF* */
739 VLIB_CLI_COMMAND (nat_reass_command, static) =
740 {
741  .path = "nat virtual-reassembly",
742  .short_help = "nat virtual-reassembly ip4|ip6 [max-reassemblies <n>] "
743  "[max-fragments <n>] [timeout <sec>] [enable|disable]",
744  .function = nat_reass_command_fn,
745 };
746 
747 VLIB_CLI_COMMAND (show_nat_reass_command, static) =
748 {
749  .path = "show nat virtual-reassembly",
750  .short_help = "show nat virtual-reassembly",
751  .function = show_nat_reass_command_fn,
752 };
753 /* *INDENT-ON* */
754 
755 /*
756  * fd.io coding-style-patch-verification: ON
757  *
758  * Local Variables:
759  * eval: (c-set-style "gnu")
760  * End:
761  */
int nat_ip6_reass_add_fragment(nat_reass_ip6_t *reass, u32 bi)
Cache fragment.
Definition: nat_reass.c:513
u32 nat_reass_get_timeout(u8 is_ip6)
Get reassembly timeout.
Definition: nat_reass.c:134
ip4_address_t src
Definition: nat_reass.h:39
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
static void clib_dlist_init(dlist_elt_t *pool, u32 index)
Definition: dlist.h:36
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
clib_error_t * nat_reass_init(vlib_main_t *vm)
Initialize NAT virtual fragmentation reassembly.
Definition: nat_reass.c:569
#define pool_alloc(P, N)
Allocate N more free elements to pool (unspecified alignment).
Definition: pool.h:324
u64 as_u64[2]
Definition: ip6_packet.h:51
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:224
int nat_ip4_reass_add_fragment(nat_reass_ip4_t *reass, u32 bi)
Cache fragment.
Definition: nat_reass.c:321
static int nat_ip6_reass_walk_cli(nat_reass_ip6_t *reass, void *ctx)
Definition: nat_reass.c:702
void nat_ip6_reass_get_frags(nat_reass_ip6_t *reass, u32 **bi)
Get cached fragments.
Definition: nat_reass.c:538
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:85
nat_reass_ip4_t * nat_ip4_reass_find(ip4_address_t src, ip4_address_t dst, u16 frag_id, u8 proto)
Find reassembly.
Definition: nat_reass.c:198
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
int(* nat_ip6_reass_walk_fn_t)(nat_reass_ip6_t *reass, void *ctx)
Call back function when walking IPv6 reassemblies, non-zero return value stop walk.
Definition: nat_reass.h:291
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:225
void nat_ip4_reass_walk(nat_ip4_reass_walk_fn_t fn, void *ctx)
Walk IPv4 reassemblies.
Definition: nat_reass.c:358
static clib_error_t * nat_reass_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat_reass.c:626
u32 ip6_reass_head_index
Definition: nat_reass.h:120
format_function_t format_ip4_address
Definition: format.h:79
#define static_always_inline
Definition: clib.h:93
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:438
dlist_elt_t * ip4_frags_list_pool
Definition: nat_reass.h:110
dlist_elt_t * ip6_reass_lru_list_pool
Definition: nat_reass.h:118
static_always_inline void nat_ip6_reass_get_frags_inline(nat_reass_ip6_t *reass, u32 **bi)
Definition: nat_reass.c:65
#define NAT_MAX_REASS_DEAFULT
Definition: nat_reass.h:29
#define clib_error_return(e, args...)
Definition: error.h:99
nat_reass_ip6_t * ip6_reass_pool
Definition: nat_reass.h:116
vnet_main_t * vnet_main
Definition: nat_reass.h:126
unformat_function_t unformat_line_input
Definition: format.h:281
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:33
#define NAT_MAX_FRAG_DEFAULT
Definition: nat_reass.h:30
u8 nat_reass_get_max_frag(u8 is_ip6)
Get maximum number of fragmets per reassembly.
Definition: nat_reass.c:156
vlib_main_t * vlib_main
Definition: nat_reass.h:125
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:459
static int nat_ip4_reass_walk_cli(nat_reass_ip4_t *reass, void *ctx)
Definition: nat_reass.c:688
dlist_elt_t * ip4_reass_lru_list_pool
Definition: nat_reass.h:109
static_always_inline void nat_ip4_reass_get_frags_inline(nat_reass_ip4_t *reass, u32 **bi)
Definition: nat_reass.c:46
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
Definition: dlist.h:43
struct _unformat_input_t unformat_input_t
#define NAT_REASS_TIMEOUT_DEFAULT
Definition: nat_reass.h:28
static clib_error_t * show_nat_reass_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat_reass.c:716
int(* nat_ip4_reass_walk_fn_t)(nat_reass_ip4_t *reass, void *ctx)
Call back function when walking IPv4 reassemblies, non-zero return value stop walk.
Definition: nat_reass.h:242
#define pool_free(p)
Free a pool.
Definition: pool.h:352
u16 nat_reass_get_max_reass(u8 is_ip6)
Get maximum number of concurrent reassemblies.
Definition: nat_reass.c:145
u32 ip4_reass_head_index
Definition: nat_reass.h:111
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static void clib_dlist_addhead(dlist_elt_t *pool, u32 head_index, u32 new_index)
Definition: dlist.h:71
int nat_reass_set(u32 timeout, u16 max_reass, u8 max_frag, u8 drop_frag, u8 is_ip6)
Set NAT virtual fragmentation reassembly configuration.
Definition: nat_reass.c:84
format_function_t format_ip6_address
Definition: format.h:95
u8 nat_reass_is_drop_frag(u8 is_ip6)
Get status of virtual fragmentation reassembly.
Definition: nat_reass.c:167
vlib_main_t * vm
Definition: buffer.c:283
static u32 nat_reass_get_nbuckets(u8 is_ip6)
Definition: nat_reass.c:26
#define clib_warning(format, args...)
Definition: error.h:59
nat_reass_ip4_t * ip4_reass_pool
Definition: nat_reass.h:107
dlist_elt_t * ip6_frags_list_pool
Definition: nat_reass.h:119
ip6_address_t dst
Definition: nat_reass.h:70
clib_bihash_16_8_t ip4_reass_hash
Definition: nat_reass.h:108
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
static_always_inline nat_reass_ip4_t * nat_ip4_reass_lookup(nat_reass_ip4_key_t *k, f64 now)
Definition: nat_reass.c:178
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:294
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
long ctx[MAX_CONNS]
Definition: main.c:122
nat_reass_main_t nat_reass_main
Definition: nat_reass.c:23
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
Definition: dlist.h:99
u32 value
Definition: dlist.h:32
static_always_inline nat_reass_ip6_t * nat_ip6_reass_lookup(nat_reass_ip6_key_t *k, f64 now)
Definition: nat_reass.c:377
unsigned short u16
Definition: types.h:57
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
ip6_address_t src
Definition: nat_reass.h:69
nat_reass_ip6_t * nat_ip6_reass_find_or_create(ip6_address_t src, ip6_address_t dst, u32 frag_id, u8 proto, u8 reset_timeout, u32 **bi_to_drop)
Find or create reassembly.
Definition: nat_reass.c:402
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
void nat_ip6_reass_walk(nat_ip6_reass_walk_fn_t fn, void *ctx)
Walk IPv6 reassemblies.
Definition: nat_reass.c:550
nat_reass_ip4_t * nat_ip4_reass_find_or_create(ip4_address_t src, ip4_address_t dst, u16 frag_id, u8 proto, u8 reset_timeout, u32 **bi_to_drop)
Find or create reassembly.
Definition: nat_reass.c:219
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#define NAT_REASS_HT_LOAD_FACTOR
Definition: nat_reass.h:31
void nat_ip4_reass_get_frags(nat_reass_ip4_t *reass, u32 **bi)
Get cached fragments.
Definition: nat_reass.c:346
NAT plugin virtual fragmentation reassembly.
clib_bihash_48_8_t ip6_reass_hash
Definition: nat_reass.h:117
ip4_address_t dst
Definition: nat_reass.h:40
clib_spinlock_t ip6_reass_lock
Definition: nat_reass.h:122
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:65
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
clib_spinlock_t ip4_reass_lock
Definition: nat_reass.h:113
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
static u32 clib_dlist_remove_head(dlist_elt_t *pool, u32 head_index)
Definition: dlist.h:117