FD.io VPP  v18.01.2-1-g9b554f3
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;
230  clib_bihash_kv_16_8_t kv, value;
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] = reass->key.as_u64[0];
276  kv.key[1] = reass->key.as_u64[1];
277  if (!clib_bihash_search_16_8 (&srm->ip4_reass_hash, &kv, &value))
278  {
279  if (value.value == (reass - srm->ip4_reass_pool))
280  {
281  if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 0))
282  {
283  reass = 0;
284  goto unlock;
285  }
286  }
287  }
288 
289  nat_ip4_reass_get_frags_inline (reass, bi_to_drop);
290  }
291  else
292  {
293  pool_get (srm->ip4_reass_pool, reass);
294  pool_get (srm->ip4_reass_lru_list_pool, elt);
295  reass->lru_list_index = elt_index = elt - srm->ip4_reass_lru_list_pool;
296  clib_dlist_init (srm->ip4_reass_lru_list_pool, elt_index);
297  elt->value = reass - srm->ip4_reass_pool;
299  srm->ip4_reass_head_index, elt_index);
300  pool_get (srm->ip4_frags_list_pool, per_reass_list_head_elt);
301  reass->frags_per_reass_list_head_index =
302  per_reass_list_head_elt - srm->ip4_frags_list_pool;
304  reass->frags_per_reass_list_head_index);
305  srm->ip4_reass_n++;
306  }
307 
308  reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
309  reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
310  kv.value = reass - srm->ip4_reass_pool;
311  reass->sess_index = (u32) ~ 0;
312  reass->thread_index = (u32) ~ 0;
313  reass->last_heard = now;
314  reass->frag_n = 0;
315 
316  if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 1))
317  {
318  reass = 0;
319  goto unlock;
320  }
321 
322 unlock:
324  return reass;
325 }
326 
327 int
328 nat_ip4_reass_add_fragment (nat_reass_ip4_t * reass, u32 bi)
329 {
331  dlist_elt_t *elt;
332  u32 elt_index;
333 
334  if (reass->frag_n >= srm->ip4_max_frag)
335  return -1;
336 
338 
339  pool_get (srm->ip4_frags_list_pool, elt);
340  elt_index = elt - srm->ip4_frags_list_pool;
341  clib_dlist_init (srm->ip4_frags_list_pool, elt_index);
342  elt->value = bi;
344  reass->frags_per_reass_list_head_index, elt_index);
345  reass->frag_n++;
346 
348 
349  return 0;
350 }
351 
352 void
353 nat_ip4_reass_get_frags (nat_reass_ip4_t * reass, u32 ** bi)
354 {
356 
358 
359  nat_ip4_reass_get_frags_inline (reass, bi);
360 
362 }
363 
364 void
366 {
367  nat_reass_ip4_t *reass;
369  f64 now = vlib_time_now (srm->vlib_main);
370 
371  /* *INDENT-OFF* */
372  pool_foreach (reass, srm->ip4_reass_pool,
373  ({
374  if (now < reass->last_heard + (f64) srm->ip4_timeout)
375  {
376  if (fn (reass, ctx))
377  return;
378  }
379  }));
380  /* *INDENT-ON* */
381 }
382 
383 static_always_inline nat_reass_ip6_t *
385 {
387  clib_bihash_kv_48_8_t kv, value;
388  nat_reass_ip6_t *reass;
389 
390  k->unused = 0;
391  kv.key[0] = k->as_u64[0];
392  kv.key[1] = k->as_u64[1];
393  kv.key[2] = k->as_u64[2];
394  kv.key[3] = k->as_u64[3];
395  kv.key[4] = k->as_u64[4];
396  kv.key[5] = k->as_u64[5];
397 
398  if (clib_bihash_search_48_8 (&srm->ip6_reass_hash, &kv, &value))
399  return 0;
400 
401  reass = pool_elt_at_index (srm->ip6_reass_pool, value.value);
402  if (now < reass->last_heard + (f64) srm->ip6_timeout)
403  return reass;
404 
405  return 0;
406 }
407 
408 nat_reass_ip6_t *
410  u32 frag_id, u8 proto, u8 reset_timeout,
411  u32 ** bi_to_drop)
412 {
414  nat_reass_ip6_t *reass = 0;
416  f64 now = vlib_time_now (srm->vlib_main);
417  dlist_elt_t *oldest_elt, *elt;
418  dlist_elt_t *per_reass_list_head_elt;
419  u32 oldest_index, elt_index;
421 
422  k.src.as_u64[0] = src.as_u64[0];
423  k.src.as_u64[1] = src.as_u64[1];
424  k.dst.as_u64[0] = dst.as_u64[0];
425  k.dst.as_u64[1] = dst.as_u64[1];
426  k.frag_id = frag_id;
427  k.proto = proto;
428  k.unused = 0;
429 
431 
432  reass = nat_ip6_reass_lookup (&k, now);
433  if (reass)
434  {
435  if (reset_timeout)
436  {
437  reass->last_heard = now;
439  reass->lru_list_index);
442  reass->lru_list_index);
443  }
444  goto unlock;
445  }
446 
447  if (srm->ip6_reass_n >= srm->ip6_max_reass)
448  {
449  oldest_index =
451  srm->ip6_reass_head_index);
452  ASSERT (oldest_index != ~0);
453  oldest_elt =
454  pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
455  reass = pool_elt_at_index (srm->ip6_reass_pool, oldest_elt->value);
456  if (now < reass->last_heard + (f64) srm->ip6_timeout)
457  {
459  srm->ip6_reass_head_index, oldest_index);
460  clib_warning ("no free resassembly slot");
461  reass = 0;
462  goto unlock;
463  }
464 
466  srm->ip6_reass_head_index, oldest_index);
467 
468  kv.key[0] = k.as_u64[0];
469  kv.key[1] = k.as_u64[1];
470  kv.key[2] = k.as_u64[2];
471  kv.key[3] = k.as_u64[4];
472  kv.key[4] = k.as_u64[5];
473  if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 0))
474  {
475  reass = 0;
476  goto unlock;
477  }
478 
479  nat_ip6_reass_get_frags_inline (reass, bi_to_drop);
480  }
481  else
482  {
483  pool_get (srm->ip6_reass_pool, reass);
484  pool_get (srm->ip6_reass_lru_list_pool, elt);
485  reass->lru_list_index = elt_index = elt - srm->ip6_reass_lru_list_pool;
486  clib_dlist_init (srm->ip6_reass_lru_list_pool, elt_index);
487  elt->value = reass - srm->ip6_reass_pool;
489  srm->ip6_reass_head_index, elt_index);
490  pool_get (srm->ip6_frags_list_pool, per_reass_list_head_elt);
491  reass->frags_per_reass_list_head_index =
492  per_reass_list_head_elt - srm->ip6_frags_list_pool;
494  reass->frags_per_reass_list_head_index);
495  srm->ip6_reass_n++;
496  }
497 
498  reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
499  reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
500  reass->key.as_u64[2] = kv.key[2] = k.as_u64[2];
501  reass->key.as_u64[3] = kv.key[3] = k.as_u64[3];
502  reass->key.as_u64[4] = kv.key[4] = k.as_u64[4];
503  reass->key.as_u64[5] = kv.key[5] = k.as_u64[5];
504  kv.value = reass - srm->ip6_reass_pool;
505  reass->sess_index = (u32) ~ 0;
506  reass->last_heard = now;
507 
508  if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 1))
509  {
510  reass = 0;
511  goto unlock;
512  }
513 
514 unlock:
516  return reass;
517 }
518 
519 int
520 nat_ip6_reass_add_fragment (nat_reass_ip6_t * reass, u32 bi)
521 {
523  dlist_elt_t *elt;
524  u32 elt_index;
525 
526  if (reass->frag_n >= srm->ip6_max_frag)
527  return -1;
528 
530 
531  pool_get (srm->ip6_frags_list_pool, elt);
532  elt_index = elt - srm->ip6_frags_list_pool;
533  clib_dlist_init (srm->ip6_frags_list_pool, elt_index);
534  elt->value = bi;
536  reass->frags_per_reass_list_head_index, elt_index);
537  reass->frag_n++;
538 
540 
541  return 0;
542 }
543 
544 void
545 nat_ip6_reass_get_frags (nat_reass_ip6_t * reass, u32 ** bi)
546 {
548 
550 
551  nat_ip6_reass_get_frags_inline (reass, bi);
552 
554 }
555 
556 void
558 {
559  nat_reass_ip6_t *reass;
561  f64 now = vlib_time_now (srm->vlib_main);
562 
563  /* *INDENT-OFF* */
564  pool_foreach (reass, srm->ip6_reass_pool,
565  ({
566  if (now < reass->last_heard + (f64) srm->ip4_timeout)
567  {
568  if (fn (reass, ctx))
569  return;
570  }
571  }));
572  /* *INDENT-ON* */
573 }
574 
575 clib_error_t *
577 {
580  clib_error_t *error = 0;
581  dlist_elt_t *head;
582  u32 nbuckets, head_index;
583 
584  srm->vlib_main = vm;
585  srm->vnet_main = vnet_get_main ();
586 
587  /* IPv4 */
591  srm->ip4_drop_frag = 0;
592  srm->ip4_reass_n = 0;
593 
594  if (tm->n_vlib_mains > 1)
596 
598 
599  nbuckets = nat_reass_get_nbuckets (0);
600  clib_bihash_init_16_8 (&srm->ip4_reass_hash, "nat-ip4-reass", nbuckets,
601  nbuckets * 1024);
602 
603  pool_get (srm->ip4_reass_lru_list_pool, head);
604  srm->ip4_reass_head_index = head_index =
605  head - srm->ip4_reass_lru_list_pool;
606  clib_dlist_init (srm->ip4_reass_lru_list_pool, head_index);
607 
608  /* IPv6 */
612  srm->ip6_drop_frag = 0;
613  srm->ip6_reass_n = 0;
614 
615  if (tm->n_vlib_mains > 1)
617 
619 
620  nbuckets = nat_reass_get_nbuckets (1);
621  clib_bihash_init_48_8 (&srm->ip6_reass_hash, "nat-ip6-reass", nbuckets,
622  nbuckets * 1024);
623 
624  pool_get (srm->ip6_reass_lru_list_pool, head);
625  srm->ip6_reass_head_index = head_index =
626  head - srm->ip6_reass_lru_list_pool;
627  clib_dlist_init (srm->ip6_reass_lru_list_pool, head_index);
628 
629  return error;
630 }
631 
632 static clib_error_t *
634  vlib_cli_command_t * cmd)
635 {
636  clib_error_t *error = 0;
637  unformat_input_t _line_input, *line_input = &_line_input;
638  u32 timeout = 0, max_reass = 0, max_frag = 0;
639  u8 drop_frag = (u8) ~ 0, is_ip6 = 0;
640  int rv;
641 
642  /* Get a line of input. */
643  if (!unformat_user (input, unformat_line_input, line_input))
644  return 0;
645 
646  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
647  {
648  if (unformat (line_input, "max-reassemblies %u", &max_reass))
649  ;
650  else if (unformat (line_input, "max-fragments %u", &max_frag))
651  ;
652  else if (unformat (line_input, "timeout %u", &timeout))
653  ;
654  else if (unformat (line_input, "enable"))
655  drop_frag = 0;
656  else if (unformat (line_input, "disable"))
657  drop_frag = 1;
658  else if (unformat (line_input, "ip4"))
659  is_ip6 = 0;
660  else if (unformat (line_input, "ip6"))
661  is_ip6 = 1;
662  else
663  {
664  error = clib_error_return (0, "unknown input '%U'",
665  format_unformat_error, line_input);
666  goto done;
667  }
668  }
669 
670  if (!timeout)
671  timeout = nat_reass_get_timeout (is_ip6);
672  if (!max_reass)
673  max_reass = nat_reass_get_max_reass (is_ip6);
674  if (!max_frag)
675  max_frag = nat_reass_get_max_frag (is_ip6);
676  if (drop_frag == (u8) ~ 0)
677  drop_frag = nat_reass_is_drop_frag (is_ip6);
678 
679  rv =
680  nat_reass_set (timeout, (u16) max_reass, (u8) max_frag, drop_frag,
681  is_ip6);
682  if (rv)
683  {
684  error = clib_error_return (0, "nat_set_reass return %d", rv);
685  goto done;
686  }
687 
688 done:
689  unformat_free (line_input);
690 
691  return error;
692 }
693 
694 static int
695 nat_ip4_reass_walk_cli (nat_reass_ip4_t * reass, void *ctx)
696 {
697  vlib_main_t *vm = ctx;
698 
699  vlib_cli_output (vm, " src %U dst %U proto %u id 0x%04x cached %u",
700  format_ip4_address, &reass->key.src,
701  format_ip4_address, &reass->key.dst,
702  reass->key.proto,
703  clib_net_to_host_u16 (reass->key.frag_id), reass->frag_n);
704 
705  return 0;
706 }
707 
708 static int
709 nat_ip6_reass_walk_cli (nat_reass_ip6_t * reass, void *ctx)
710 {
711  vlib_main_t *vm = ctx;
712 
713  vlib_cli_output (vm, " src %U dst %U proto %u id 0x%08x cached %u",
714  format_ip6_address, &reass->key.src,
715  format_ip6_address, &reass->key.dst,
716  reass->key.proto,
717  clib_net_to_host_u32 (reass->key.frag_id), reass->frag_n);
718 
719  return 0;
720 }
721 
722 static clib_error_t *
724  vlib_cli_command_t * cmd)
725 {
726  vlib_cli_output (vm, "NAT IPv4 virtual fragmentation reassembly is %s",
727  nat_reass_is_drop_frag (0) ? "DISABLED" : "ENABLED");
728  vlib_cli_output (vm, " max-reasssemblies %u", nat_reass_get_max_reass (0));
729  vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (0));
730  vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (0));
731  vlib_cli_output (vm, " reassemblies:");
733 
734  vlib_cli_output (vm, "NAT IPv6 virtual fragmentation reassembly is %s",
735  nat_reass_is_drop_frag (1) ? "DISABLED" : "ENABLED");
736  vlib_cli_output (vm, " max-reasssemblies %u", nat_reass_get_max_reass (1));
737  vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (1));
738  vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (1));
739  vlib_cli_output (vm, " reassemblies:");
741 
742  return 0;
743 }
744 
745 /* *INDENT-OFF* */
746 VLIB_CLI_COMMAND (nat_reass_command, static) =
747 {
748  .path = "nat virtual-reassembly",
749  .short_help = "nat virtual-reassembly ip4|ip6 [max-reassemblies <n>] "
750  "[max-fragments <n>] [timeout <sec>] [enable|disable]",
751  .function = nat_reass_command_fn,
752 };
753 
754 VLIB_CLI_COMMAND (show_nat_reass_command, static) =
755 {
756  .path = "show nat virtual-reassembly",
757  .short_help = "show nat virtual-reassembly",
758  .function = show_nat_reass_command_fn,
759 };
760 /* *INDENT-ON* */
761 
762 /*
763  * fd.io coding-style-patch-verification: ON
764  *
765  * Local Variables:
766  * eval: (c-set-style "gnu")
767  * End:
768  */
int nat_ip6_reass_add_fragment(nat_reass_ip6_t *reass, u32 bi)
Cache fragment.
Definition: nat_reass.c:520
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:576
#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:328
static int nat_ip6_reass_walk_cli(nat_reass_ip6_t *reass, void *ctx)
Definition: nat_reass.c:709
void nat_ip6_reass_get_frags(nat_reass_ip6_t *reass, u32 **bi)
Get cached fragments.
Definition: nat_reass.c:545
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:365
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:633
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:695
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:723
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:384
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:409
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:557
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:353
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