FD.io VPP  v18.07-rc0-415-g6c78436
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 #include <nat/nat_ipfix_logging.h>
23 
25 
26 static u32
28 {
30  u32 nbuckets;
31  u8 i;
32 
33  if (is_ip6)
34  nbuckets = (u32) (srm->ip6_max_reass / NAT_REASS_HT_LOAD_FACTOR);
35  else
36  nbuckets = (u32) (srm->ip4_max_reass / NAT_REASS_HT_LOAD_FACTOR);
37 
38  for (i = 0; i < 31; i++)
39  if ((1 << i) >= nbuckets)
40  break;
41  nbuckets = 1 << i;
42 
43  return nbuckets;
44 }
45 
47 nat_ip4_reass_get_frags_inline (nat_reass_ip4_t * reass, u32 ** bi)
48 {
50  u32 elt_index;
51  dlist_elt_t *elt;
52 
53  while ((elt_index =
55  reass->frags_per_reass_list_head_index)) !=
56  ~0)
57  {
58  elt = pool_elt_at_index (srm->ip4_frags_list_pool, elt_index);
59  vec_add1 (*bi, elt->value);
60  reass->frag_n--;
61  pool_put_index (srm->ip4_frags_list_pool, elt_index);
62  }
63 }
64 
66 nat_ip6_reass_get_frags_inline (nat_reass_ip6_t * reass, u32 ** bi)
67 {
69  u32 elt_index;
70  dlist_elt_t *elt;
71 
72  while ((elt_index =
74  reass->frags_per_reass_list_head_index)) !=
75  ~0)
76  {
77  elt = pool_elt_at_index (srm->ip6_frags_list_pool, elt_index);
78  vec_add1 (*bi, elt->value);
79  reass->frag_n--;
80  pool_put_index (srm->ip6_frags_list_pool, elt_index);
81  }
82 }
83 
84 int
85 nat_reass_set (u32 timeout, u16 max_reass, u8 max_frag, u8 drop_frag,
86  u8 is_ip6)
87 {
89  u32 nbuckets;
90 
91  if (is_ip6)
92  {
93  if (srm->ip6_max_reass != max_reass)
94  {
96 
97  srm->ip6_max_reass = max_reass;
100  nbuckets = nat_reass_get_nbuckets (0);
101  clib_bihash_free_48_8 (&srm->ip6_reass_hash);
102  clib_bihash_init_48_8 (&srm->ip6_reass_hash, "nat-ip6-reass",
103  nbuckets, nbuckets * 1024);
104 
106  }
107  srm->ip6_timeout = timeout;
108  srm->ip6_max_frag = max_frag;
109  srm->ip6_drop_frag = drop_frag;
110  }
111  else
112  {
113  if (srm->ip4_max_reass != max_reass)
114  {
116 
117  srm->ip4_max_reass = max_reass;
118  pool_free (srm->ip4_reass_pool);
120  nbuckets = nat_reass_get_nbuckets (0);
121  clib_bihash_free_16_8 (&srm->ip4_reass_hash);
122  clib_bihash_init_16_8 (&srm->ip4_reass_hash, "nat-ip4-reass",
123  nbuckets, nbuckets * 1024);
125  }
126  srm->ip4_timeout = timeout;
127  srm->ip4_max_frag = max_frag;
128  srm->ip4_drop_frag = drop_frag;
129  }
130 
131  return 0;
132 }
133 
134 u32
136 {
138 
139  if (is_ip6)
140  return srm->ip6_timeout;
141 
142  return srm->ip4_timeout;
143 }
144 
145 u16
147 {
149 
150  if (is_ip6)
151  return srm->ip6_max_reass;
152 
153  return srm->ip4_max_reass;
154 }
155 
156 u8
158 {
160 
161  if (is_ip6)
162  return srm->ip6_max_frag;
163 
164  return srm->ip4_max_frag;
165 }
166 
167 u8
169 {
171 
172  if (is_ip6)
173  return srm->ip6_drop_frag;
174 
175  return srm->ip4_drop_frag;
176 }
177 
178 static_always_inline nat_reass_ip4_t *
180 {
182  clib_bihash_kv_16_8_t kv, value;
183  nat_reass_ip4_t *reass;
184 
185  kv.key[0] = k->as_u64[0];
186  kv.key[1] = k->as_u64[1];
187 
188  if (clib_bihash_search_16_8 (&srm->ip4_reass_hash, &kv, &value))
189  return 0;
190 
191  reass = pool_elt_at_index (srm->ip4_reass_pool, value.value);
192  if (now < reass->last_heard + (f64) srm->ip4_timeout)
193  return reass;
194 
195  return 0;
196 }
197 
198 nat_reass_ip4_t *
200  u8 proto)
201 {
203  nat_reass_ip4_t *reass = 0;
205  f64 now = vlib_time_now (srm->vlib_main);
206 
207  k.src.as_u32 = src.as_u32;
208  k.dst.as_u32 = dst.as_u32;
209  k.frag_id = frag_id;
210  k.proto = proto;
211 
213  reass = nat_ip4_reass_lookup (&k, now);
215 
216  return reass;
217 }
218 
219 nat_reass_ip4_t *
221  u16 frag_id, u8 proto, u8 reset_timeout,
222  u32 ** bi_to_drop)
223 {
225  nat_reass_ip4_t *reass = 0;
227  f64 now = vlib_time_now (srm->vlib_main);
228  dlist_elt_t *oldest_elt, *elt;
229  dlist_elt_t *per_reass_list_head_elt;
230  u32 oldest_index, elt_index;
231  clib_bihash_kv_16_8_t kv, value;
232 
233  k.src.as_u32 = src.as_u32;
234  k.dst.as_u32 = dst.as_u32;
235  k.frag_id = frag_id;
236  k.proto = proto;
237 
239 
240  reass = nat_ip4_reass_lookup (&k, now);
241  if (reass)
242  {
243  if (reset_timeout)
244  {
245  reass->last_heard = now;
247  reass->lru_list_index);
250  reass->lru_list_index);
251  }
252  goto unlock;
253  }
254 
255  if (srm->ip4_reass_n >= srm->ip4_max_reass)
256  {
257  oldest_index =
259  srm->ip4_reass_head_index);
260  ASSERT (oldest_index != ~0);
261  oldest_elt =
262  pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
263  reass = pool_elt_at_index (srm->ip4_reass_pool, oldest_elt->value);
264  if (now < reass->last_heard + (f64) srm->ip4_timeout)
265  {
267  srm->ip4_reass_head_index, oldest_index);
268  clib_warning ("no free resassembly slot");
269  reass = 0;
270  goto unlock;
271  }
272 
274  srm->ip4_reass_head_index, oldest_index);
275 
276  kv.key[0] = reass->key.as_u64[0];
277  kv.key[1] = reass->key.as_u64[1];
278  if (!clib_bihash_search_16_8 (&srm->ip4_reass_hash, &kv, &value))
279  {
280  if (value.value == (reass - srm->ip4_reass_pool))
281  {
282  if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 0))
283  {
284  reass = 0;
285  goto unlock;
286  }
287  }
288  }
289 
290  nat_ip4_reass_get_frags_inline (reass, bi_to_drop);
291  }
292  else
293  {
294  pool_get (srm->ip4_reass_pool, reass);
295  pool_get (srm->ip4_reass_lru_list_pool, elt);
296  reass->lru_list_index = elt_index = elt - srm->ip4_reass_lru_list_pool;
297  clib_dlist_init (srm->ip4_reass_lru_list_pool, elt_index);
298  elt->value = reass - srm->ip4_reass_pool;
300  srm->ip4_reass_head_index, elt_index);
301  pool_get (srm->ip4_frags_list_pool, per_reass_list_head_elt);
302  reass->frags_per_reass_list_head_index =
303  per_reass_list_head_elt - srm->ip4_frags_list_pool;
305  reass->frags_per_reass_list_head_index);
306  srm->ip4_reass_n++;
307  }
308 
309  reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
310  reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
311  kv.value = reass - srm->ip4_reass_pool;
312  reass->sess_index = (u32) ~ 0;
313  reass->thread_index = (u32) ~ 0;
314  reass->last_heard = now;
315  reass->frag_n = 0;
316 
317  if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 1))
318  {
319  reass = 0;
320  goto unlock;
321  }
322 
323 unlock:
325  return reass;
326 }
327 
328 int
329 nat_ip4_reass_add_fragment (nat_reass_ip4_t * reass, u32 bi)
330 {
332  dlist_elt_t *elt;
333  u32 elt_index;
334 
335  if (reass->frag_n >= srm->ip4_max_frag)
336  {
338  &reass->key.src);
339  return -1;
340  }
341 
343 
344  pool_get (srm->ip4_frags_list_pool, elt);
345  elt_index = elt - srm->ip4_frags_list_pool;
346  clib_dlist_init (srm->ip4_frags_list_pool, elt_index);
347  elt->value = bi;
349  reass->frags_per_reass_list_head_index, elt_index);
350  reass->frag_n++;
351 
353 
354  return 0;
355 }
356 
357 void
358 nat_ip4_reass_get_frags (nat_reass_ip4_t * reass, u32 ** bi)
359 {
361 
363 
364  nat_ip4_reass_get_frags_inline (reass, bi);
365 
367 }
368 
369 void
371 {
372  nat_reass_ip4_t *reass;
374  f64 now = vlib_time_now (srm->vlib_main);
375 
376  /* *INDENT-OFF* */
377  pool_foreach (reass, srm->ip4_reass_pool,
378  ({
379  if (now < reass->last_heard + (f64) srm->ip4_timeout)
380  {
381  if (fn (reass, ctx))
382  return;
383  }
384  }));
385  /* *INDENT-ON* */
386 }
387 
388 static_always_inline nat_reass_ip6_t *
390 {
392  clib_bihash_kv_48_8_t kv, value;
393  nat_reass_ip6_t *reass;
394 
395  k->unused = 0;
396  kv.key[0] = k->as_u64[0];
397  kv.key[1] = k->as_u64[1];
398  kv.key[2] = k->as_u64[2];
399  kv.key[3] = k->as_u64[3];
400  kv.key[4] = k->as_u64[4];
401  kv.key[5] = k->as_u64[5];
402 
403  if (clib_bihash_search_48_8 (&srm->ip6_reass_hash, &kv, &value))
404  return 0;
405 
406  reass = pool_elt_at_index (srm->ip6_reass_pool, value.value);
407  if (now < reass->last_heard + (f64) srm->ip6_timeout)
408  return reass;
409 
410  return 0;
411 }
412 
413 nat_reass_ip6_t *
415  u32 frag_id, u8 proto, u8 reset_timeout,
416  u32 ** bi_to_drop)
417 {
419  nat_reass_ip6_t *reass = 0;
421  f64 now = vlib_time_now (srm->vlib_main);
422  dlist_elt_t *oldest_elt, *elt;
423  dlist_elt_t *per_reass_list_head_elt;
424  u32 oldest_index, elt_index;
426 
427  k.src.as_u64[0] = src.as_u64[0];
428  k.src.as_u64[1] = src.as_u64[1];
429  k.dst.as_u64[0] = dst.as_u64[0];
430  k.dst.as_u64[1] = dst.as_u64[1];
431  k.frag_id = frag_id;
432  k.proto = proto;
433  k.unused = 0;
434 
436 
437  reass = nat_ip6_reass_lookup (&k, now);
438  if (reass)
439  {
440  if (reset_timeout)
441  {
442  reass->last_heard = now;
444  reass->lru_list_index);
447  reass->lru_list_index);
448  }
449  goto unlock;
450  }
451 
452  if (srm->ip6_reass_n >= srm->ip6_max_reass)
453  {
454  oldest_index =
456  srm->ip6_reass_head_index);
457  ASSERT (oldest_index != ~0);
458  oldest_elt =
459  pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
460  reass = pool_elt_at_index (srm->ip6_reass_pool, oldest_elt->value);
461  if (now < reass->last_heard + (f64) srm->ip6_timeout)
462  {
464  srm->ip6_reass_head_index, oldest_index);
465  clib_warning ("no free resassembly slot");
466  reass = 0;
467  goto unlock;
468  }
469 
471  srm->ip6_reass_head_index, oldest_index);
472 
473  kv.key[0] = k.as_u64[0];
474  kv.key[1] = k.as_u64[1];
475  kv.key[2] = k.as_u64[2];
476  kv.key[3] = k.as_u64[4];
477  kv.key[4] = k.as_u64[5];
478  if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 0))
479  {
480  reass = 0;
481  goto unlock;
482  }
483 
484  nat_ip6_reass_get_frags_inline (reass, bi_to_drop);
485  }
486  else
487  {
488  pool_get (srm->ip6_reass_pool, reass);
489  pool_get (srm->ip6_reass_lru_list_pool, elt);
490  reass->lru_list_index = elt_index = elt - srm->ip6_reass_lru_list_pool;
491  clib_dlist_init (srm->ip6_reass_lru_list_pool, elt_index);
492  elt->value = reass - srm->ip6_reass_pool;
494  srm->ip6_reass_head_index, elt_index);
495  pool_get (srm->ip6_frags_list_pool, per_reass_list_head_elt);
496  reass->frags_per_reass_list_head_index =
497  per_reass_list_head_elt - srm->ip6_frags_list_pool;
499  reass->frags_per_reass_list_head_index);
500  srm->ip6_reass_n++;
501  }
502 
503  reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
504  reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
505  reass->key.as_u64[2] = kv.key[2] = k.as_u64[2];
506  reass->key.as_u64[3] = kv.key[3] = k.as_u64[3];
507  reass->key.as_u64[4] = kv.key[4] = k.as_u64[4];
508  reass->key.as_u64[5] = kv.key[5] = k.as_u64[5];
509  kv.value = reass - srm->ip6_reass_pool;
510  reass->sess_index = (u32) ~ 0;
511  reass->last_heard = now;
512 
513  if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 1))
514  {
515  reass = 0;
516  goto unlock;
517  }
518 
519 unlock:
521  return reass;
522 }
523 
524 int
525 nat_ip6_reass_add_fragment (nat_reass_ip6_t * reass, u32 bi)
526 {
528  dlist_elt_t *elt;
529  u32 elt_index;
530 
531  if (reass->frag_n >= srm->ip6_max_frag)
532  {
534  &reass->key.src);
535  return -1;
536  }
537 
539 
540  pool_get (srm->ip6_frags_list_pool, elt);
541  elt_index = elt - srm->ip6_frags_list_pool;
542  clib_dlist_init (srm->ip6_frags_list_pool, elt_index);
543  elt->value = bi;
545  reass->frags_per_reass_list_head_index, elt_index);
546  reass->frag_n++;
547 
549 
550  return 0;
551 }
552 
553 void
554 nat_ip6_reass_get_frags (nat_reass_ip6_t * reass, u32 ** bi)
555 {
557 
559 
560  nat_ip6_reass_get_frags_inline (reass, bi);
561 
563 }
564 
565 void
567 {
568  nat_reass_ip6_t *reass;
570  f64 now = vlib_time_now (srm->vlib_main);
571 
572  /* *INDENT-OFF* */
573  pool_foreach (reass, srm->ip6_reass_pool,
574  ({
575  if (now < reass->last_heard + (f64) srm->ip4_timeout)
576  {
577  if (fn (reass, ctx))
578  return;
579  }
580  }));
581  /* *INDENT-ON* */
582 }
583 
584 clib_error_t *
586 {
589  clib_error_t *error = 0;
590  dlist_elt_t *head;
591  u32 nbuckets, head_index;
592 
593  srm->vlib_main = vm;
594  srm->vnet_main = vnet_get_main ();
595 
596  /* IPv4 */
600  srm->ip4_drop_frag = 0;
601  srm->ip4_reass_n = 0;
602 
603  if (tm->n_vlib_mains > 1)
605 
607 
608  nbuckets = nat_reass_get_nbuckets (0);
609  clib_bihash_init_16_8 (&srm->ip4_reass_hash, "nat-ip4-reass", nbuckets,
610  nbuckets * 1024);
611 
612  pool_get (srm->ip4_reass_lru_list_pool, head);
613  srm->ip4_reass_head_index = head_index =
614  head - srm->ip4_reass_lru_list_pool;
615  clib_dlist_init (srm->ip4_reass_lru_list_pool, head_index);
616 
617  /* IPv6 */
621  srm->ip6_drop_frag = 0;
622  srm->ip6_reass_n = 0;
623 
624  if (tm->n_vlib_mains > 1)
626 
628 
629  nbuckets = nat_reass_get_nbuckets (1);
630  clib_bihash_init_48_8 (&srm->ip6_reass_hash, "nat-ip6-reass", nbuckets,
631  nbuckets * 1024);
632 
633  pool_get (srm->ip6_reass_lru_list_pool, head);
634  srm->ip6_reass_head_index = head_index =
635  head - srm->ip6_reass_lru_list_pool;
636  clib_dlist_init (srm->ip6_reass_lru_list_pool, head_index);
637 
638  return error;
639 }
640 
641 static clib_error_t *
643  vlib_cli_command_t * cmd)
644 {
645  clib_error_t *error = 0;
646  unformat_input_t _line_input, *line_input = &_line_input;
647  u32 timeout = 0, max_reass = 0, max_frag = 0;
648  u8 drop_frag = (u8) ~ 0, is_ip6 = 0;
649  int rv;
650 
651  /* Get a line of input. */
652  if (!unformat_user (input, unformat_line_input, line_input))
653  return 0;
654 
655  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
656  {
657  if (unformat (line_input, "max-reassemblies %u", &max_reass))
658  ;
659  else if (unformat (line_input, "max-fragments %u", &max_frag))
660  ;
661  else if (unformat (line_input, "timeout %u", &timeout))
662  ;
663  else if (unformat (line_input, "enable"))
664  drop_frag = 0;
665  else if (unformat (line_input, "disable"))
666  drop_frag = 1;
667  else if (unformat (line_input, "ip4"))
668  is_ip6 = 0;
669  else if (unformat (line_input, "ip6"))
670  is_ip6 = 1;
671  else
672  {
673  error = clib_error_return (0, "unknown input '%U'",
674  format_unformat_error, line_input);
675  goto done;
676  }
677  }
678 
679  if (!timeout)
680  timeout = nat_reass_get_timeout (is_ip6);
681  if (!max_reass)
682  max_reass = nat_reass_get_max_reass (is_ip6);
683  if (!max_frag)
684  max_frag = nat_reass_get_max_frag (is_ip6);
685  if (drop_frag == (u8) ~ 0)
686  drop_frag = nat_reass_is_drop_frag (is_ip6);
687 
688  rv =
689  nat_reass_set (timeout, (u16) max_reass, (u8) max_frag, drop_frag,
690  is_ip6);
691  if (rv)
692  {
693  error = clib_error_return (0, "nat_set_reass return %d", rv);
694  goto done;
695  }
696 
697 done:
698  unformat_free (line_input);
699 
700  return error;
701 }
702 
703 static int
704 nat_ip4_reass_walk_cli (nat_reass_ip4_t * reass, void *ctx)
705 {
706  vlib_main_t *vm = ctx;
707 
708  vlib_cli_output (vm, " src %U dst %U proto %u id 0x%04x cached %u",
709  format_ip4_address, &reass->key.src,
710  format_ip4_address, &reass->key.dst,
711  reass->key.proto,
712  clib_net_to_host_u16 (reass->key.frag_id), reass->frag_n);
713 
714  return 0;
715 }
716 
717 static int
718 nat_ip6_reass_walk_cli (nat_reass_ip6_t * reass, void *ctx)
719 {
720  vlib_main_t *vm = ctx;
721 
722  vlib_cli_output (vm, " src %U dst %U proto %u id 0x%08x cached %u",
723  format_ip6_address, &reass->key.src,
724  format_ip6_address, &reass->key.dst,
725  reass->key.proto,
726  clib_net_to_host_u32 (reass->key.frag_id), reass->frag_n);
727 
728  return 0;
729 }
730 
731 static clib_error_t *
733  vlib_cli_command_t * cmd)
734 {
735  vlib_cli_output (vm, "NAT IPv4 virtual fragmentation reassembly is %s",
736  nat_reass_is_drop_frag (0) ? "DISABLED" : "ENABLED");
737  vlib_cli_output (vm, " max-reassemblies %u", nat_reass_get_max_reass (0));
738  vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (0));
739  vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (0));
740  vlib_cli_output (vm, " reassemblies:");
742 
743  vlib_cli_output (vm, "NAT IPv6 virtual fragmentation reassembly is %s",
744  nat_reass_is_drop_frag (1) ? "DISABLED" : "ENABLED");
745  vlib_cli_output (vm, " max-reassemblies %u", nat_reass_get_max_reass (1));
746  vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (1));
747  vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (1));
748  vlib_cli_output (vm, " reassemblies:");
750 
751  return 0;
752 }
753 
754 /* *INDENT-OFF* */
755 VLIB_CLI_COMMAND (nat_reass_command, static) =
756 {
757  .path = "nat virtual-reassembly",
758  .short_help = "nat virtual-reassembly ip4|ip6 [max-reassemblies <n>] "
759  "[max-fragments <n>] [timeout <sec>] [enable|disable]",
760  .function = nat_reass_command_fn,
761 };
762 
763 VLIB_CLI_COMMAND (show_nat_reass_command, static) =
764 {
765  .path = "show nat virtual-reassembly",
766  .short_help = "show nat virtual-reassembly",
767  .function = show_nat_reass_command_fn,
768 };
769 /* *INDENT-ON* */
770 
771 /*
772  * fd.io coding-style-patch-verification: ON
773  *
774  * Local Variables:
775  * eval: (c-set-style "gnu")
776  * End:
777  */
int nat_ip6_reass_add_fragment(nat_reass_ip6_t *reass, u32 bi)
Cache fragment.
Definition: nat_reass.c:525
u32 nat_reass_get_timeout(u8 is_ip6)
Get reassembly timeout.
Definition: nat_reass.c:135
ip4_address_t src
Definition: nat_reass.h:39
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:585
#define pool_alloc(P, N)
Allocate N more free elements to pool (unspecified alignment).
Definition: pool.h:326
u64 as_u64[2]
Definition: ip6_packet.h:51
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:225
int nat_ip4_reass_add_fragment(nat_reass_ip4_t *reass, u32 bi)
Cache fragment.
Definition: nat_reass.c:329
static int nat_ip6_reass_walk_cli(nat_reass_ip6_t *reass, void *ctx)
Definition: nat_reass.c:718
void nat_ip6_reass_get_frags(nat_reass_ip6_t *reass, u32 **bi)
Get cached fragments.
Definition: nat_reass.c:554
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:98
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:199
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
int i
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
void nat_ipfix_logging_max_fragments_ip6(u32 limit, ip6_address_t *src)
Generate maximum IPv6 fragments pending reassembly exceeded event.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
unsigned char u8
Definition: types.h:56
void nat_ip4_reass_walk(nat_ip4_reass_walk_fn_t fn, void *ctx)
Walk IPv4 reassemblies.
Definition: nat_reass.c:370
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:642
double f64
Definition: types.h:142
u32 ip6_reass_head_index
Definition: nat_reass.h:120
format_function_t format_ip4_address
Definition: format.h:81
#define static_always_inline
Definition: clib.h:93
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
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:66
#define NAT_MAX_REASS_DEAFULT
Definition: nat_reass.h:29
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
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:57
#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:157
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:461
static int nat_ip4_reass_walk_cli(nat_reass_ip4_t *reass, void *ctx)
Definition: nat_reass.c:704
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:47
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
unsigned short u16
Definition: types.h:57
#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:732
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:354
u16 nat_reass_get_max_reass(u8 is_ip6)
Get maximum number of concurrent reassemblies.
Definition: nat_reass.c:146
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:85
format_function_t format_ip6_address
Definition: format.h:99
u8 nat_reass_is_drop_frag(u8 is_ip6)
Get status of virtual fragmentation reassembly.
Definition: nat_reass.c:168
vlib_main_t * vm
Definition: buffer.c:294
static u32 nat_reass_get_nbuckets(u8 is_ip6)
Definition: nat_reass.c:27
#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:179
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:296
void nat_ipfix_logging_max_fragments_ip4(u32 limit, ip4_address_t *src)
Generate maximum IPv4 fragments pending reassembly exceeded event.
#define ASSERT(truth)
long ctx[MAX_CONNS]
Definition: main.c:126
nat_reass_main_t nat_reass_main
Definition: nat_reass.c:24
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:389
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:414
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:566
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:220
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:358
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:681
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:82
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