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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @brief NAT plugin virtual fragmentation reassembly
20 #include <vnet/vnet.h>
21 #include <nat/nat_reass.h>
22 #include <nat/nat_ipfix_logging.h>
24 nat_reass_main_t nat_reass_main;
27 nat_reass_get_nbuckets (u8 is_ip6)
29 nat_reass_main_t *srm = &nat_reass_main;
34 nbuckets = (u32) (srm->ip6_max_reass / NAT_REASS_HT_LOAD_FACTOR);
36 nbuckets = (u32) (srm->ip4_max_reass / NAT_REASS_HT_LOAD_FACTOR);
38 for (i = 0; i < 31; i++)
39 if ((1 << i) >= nbuckets)
46 static_always_inline void
47 nat_ip4_reass_get_frags_inline (nat_reass_ip4_t * reass, u32 ** bi)
49 nat_reass_main_t *srm = &nat_reass_main;
54 clib_dlist_remove_head (srm->ip4_frags_list_pool,
55 reass->frags_per_reass_list_head_index)) !=
58 elt = pool_elt_at_index (srm->ip4_frags_list_pool, elt_index);
59 vec_add1 (*bi, elt->value);
61 pool_put_index (srm->ip4_frags_list_pool, elt_index);
65 static_always_inline void
66 nat_ip6_reass_get_frags_inline (nat_reass_ip6_t * reass, u32 ** bi)
68 nat_reass_main_t *srm = &nat_reass_main;
73 clib_dlist_remove_head (srm->ip6_frags_list_pool,
74 reass->frags_per_reass_list_head_index)) !=
77 elt = pool_elt_at_index (srm->ip6_frags_list_pool, elt_index);
78 vec_add1 (*bi, elt->value);
80 pool_put_index (srm->ip6_frags_list_pool, elt_index);
85 nat_reass_set (u32 timeout, u16 max_reass, u8 max_frag, u8 drop_frag,
88 nat_reass_main_t *srm = &nat_reass_main;
93 if (srm->ip6_max_reass != max_reass)
95 clib_spinlock_lock_if_init (&srm->ip6_reass_lock);
97 srm->ip6_max_reass = max_reass;
98 pool_free (srm->ip6_reass_pool);
99 pool_alloc (srm->ip6_reass_pool, srm->ip4_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);
105 clib_spinlock_unlock_if_init (&srm->ip6_reass_lock);
107 srm->ip6_timeout = timeout;
108 srm->ip6_max_frag = max_frag;
109 srm->ip6_drop_frag = drop_frag;
113 if (srm->ip4_max_reass != max_reass)
115 clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
117 srm->ip4_max_reass = max_reass;
118 pool_free (srm->ip4_reass_pool);
119 pool_alloc (srm->ip4_reass_pool, srm->ip4_max_reass);
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);
124 clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
126 srm->ip4_timeout = timeout;
127 srm->ip4_max_frag = max_frag;
128 srm->ip4_drop_frag = drop_frag;
135 nat_reass_get_timeout (u8 is_ip6)
137 nat_reass_main_t *srm = &nat_reass_main;
140 return srm->ip6_timeout;
142 return srm->ip4_timeout;
146 nat_reass_get_max_reass (u8 is_ip6)
148 nat_reass_main_t *srm = &nat_reass_main;
151 return srm->ip6_max_reass;
153 return srm->ip4_max_reass;
157 nat_reass_get_max_frag (u8 is_ip6)
159 nat_reass_main_t *srm = &nat_reass_main;
162 return srm->ip6_max_frag;
164 return srm->ip4_max_frag;
168 nat_reass_is_drop_frag (u8 is_ip6)
170 nat_reass_main_t *srm = &nat_reass_main;
173 return srm->ip6_drop_frag;
175 return srm->ip4_drop_frag;
178 static_always_inline nat_reass_ip4_t *
179 nat_ip4_reass_lookup (nat_reass_ip4_key_t * k, f64 now)
181 nat_reass_main_t *srm = &nat_reass_main;
182 clib_bihash_kv_16_8_t kv, value;
183 nat_reass_ip4_t *reass;
185 kv.key[0] = k->as_u64[0];
186 kv.key[1] = k->as_u64[1];
188 if (clib_bihash_search_16_8 (&srm->ip4_reass_hash, &kv, &value))
191 reass = pool_elt_at_index (srm->ip4_reass_pool, value.value);
192 if (now < reass->last_heard + (f64) srm->ip4_timeout)
199 nat_ip4_reass_find (ip4_address_t src, ip4_address_t dst, u16 frag_id,
202 nat_reass_main_t *srm = &nat_reass_main;
203 nat_reass_ip4_t *reass = 0;
204 nat_reass_ip4_key_t k;
205 f64 now = vlib_time_now (srm->vlib_main);
207 k.src.as_u32 = src.as_u32;
208 k.dst.as_u32 = dst.as_u32;
212 clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
213 reass = nat_ip4_reass_lookup (&k, now);
214 clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
220 nat_ip4_reass_create (ip4_address_t src, ip4_address_t dst, u16 frag_id,
223 nat_reass_main_t *srm = &nat_reass_main;
224 nat_reass_ip4_t *reass = 0;
225 dlist_elt_t *elt, *per_reass_list_head_elt;
227 f64 now = vlib_time_now (srm->vlib_main);
228 nat_reass_ip4_key_t k;
229 clib_bihash_kv_16_8_t kv;
231 clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
233 if (srm->ip4_reass_n >= srm->ip4_max_reass)
235 nat_elog_warn ("no free resassembly slot");
239 pool_get (srm->ip4_reass_pool, reass);
240 pool_get (srm->ip4_reass_lru_list_pool, elt);
241 reass->lru_list_index = elt_index = elt - srm->ip4_reass_lru_list_pool;
242 clib_dlist_init (srm->ip4_reass_lru_list_pool, elt_index);
243 elt->value = reass - srm->ip4_reass_pool;
244 clib_dlist_addtail (srm->ip4_reass_lru_list_pool,
245 srm->ip4_reass_head_index, elt_index);
246 pool_get (srm->ip4_frags_list_pool, per_reass_list_head_elt);
247 reass->frags_per_reass_list_head_index =
248 per_reass_list_head_elt - srm->ip4_frags_list_pool;
249 clib_dlist_init (srm->ip4_frags_list_pool,
250 reass->frags_per_reass_list_head_index);
252 k.src.as_u32 = src.as_u32;
253 k.dst.as_u32 = dst.as_u32;
256 reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
257 reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
258 kv.value = reass - srm->ip4_reass_pool;
259 reass->sess_index = (u32) ~ 0;
260 reass->thread_index = (u32) ~ 0;
261 reass->last_heard = now;
264 reass->classify_next = NAT_REASS_IP4_CLASSIFY_NONE;
265 if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 1))
266 nat_elog_warn ("ip4_reass_hash add key failed");
269 clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
274 nat_ip4_reass_find_or_create (ip4_address_t src, ip4_address_t dst,
275 u16 frag_id, u8 proto, u8 reset_timeout,
278 nat_reass_main_t *srm = &nat_reass_main;
279 nat_reass_ip4_t *reass = 0;
280 nat_reass_ip4_key_t k;
281 f64 now = vlib_time_now (srm->vlib_main);
282 dlist_elt_t *oldest_elt, *elt;
283 dlist_elt_t *per_reass_list_head_elt;
284 u32 oldest_index, elt_index;
285 clib_bihash_kv_16_8_t kv, value;
287 k.src.as_u32 = src.as_u32;
288 k.dst.as_u32 = dst.as_u32;
292 clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
294 reass = nat_ip4_reass_lookup (&k, now);
299 reass->last_heard = now;
300 clib_dlist_remove (srm->ip4_reass_lru_list_pool,
301 reass->lru_list_index);
302 clib_dlist_addtail (srm->ip4_reass_lru_list_pool,
303 srm->ip4_reass_head_index,
304 reass->lru_list_index);
307 if (reass->flags & NAT_REASS_FLAG_MAX_FRAG_DROP)
316 if (srm->ip4_reass_n >= srm->ip4_max_reass)
319 clib_dlist_remove_head (srm->ip4_reass_lru_list_pool,
320 srm->ip4_reass_head_index);
321 ASSERT (oldest_index != ~0);
323 pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
324 reass = pool_elt_at_index (srm->ip4_reass_pool, oldest_elt->value);
325 if (now < reass->last_heard + (f64) srm->ip4_timeout)
327 clib_dlist_addhead (srm->ip4_reass_lru_list_pool,
328 srm->ip4_reass_head_index, oldest_index);
329 nat_elog_warn ("no free resassembly slot");
334 clib_dlist_addtail (srm->ip4_reass_lru_list_pool,
335 srm->ip4_reass_head_index, oldest_index);
337 kv.key[0] = reass->key.as_u64[0];
338 kv.key[1] = reass->key.as_u64[1];
339 if (!clib_bihash_search_16_8 (&srm->ip4_reass_hash, &kv, &value))
341 if (value.value == (reass - srm->ip4_reass_pool))
343 if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 0))
351 nat_ip4_reass_get_frags_inline (reass, bi_to_drop);
355 pool_get (srm->ip4_reass_pool, reass);
356 pool_get (srm->ip4_reass_lru_list_pool, elt);
357 reass->lru_list_index = elt_index = elt - srm->ip4_reass_lru_list_pool;
358 clib_dlist_init (srm->ip4_reass_lru_list_pool, elt_index);
359 elt->value = reass - srm->ip4_reass_pool;
360 clib_dlist_addtail (srm->ip4_reass_lru_list_pool,
361 srm->ip4_reass_head_index, elt_index);
362 pool_get (srm->ip4_frags_list_pool, per_reass_list_head_elt);
363 reass->frags_per_reass_list_head_index =
364 per_reass_list_head_elt - srm->ip4_frags_list_pool;
365 clib_dlist_init (srm->ip4_frags_list_pool,
366 reass->frags_per_reass_list_head_index);
370 reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
371 reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
372 kv.value = reass - srm->ip4_reass_pool;
373 reass->sess_index = (u32) ~ 0;
374 reass->thread_index = (u32) ~ 0;
375 reass->last_heard = now;
378 reass->classify_next = NAT_REASS_IP4_CLASSIFY_NONE;
380 if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 1))
387 clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
392 nat_ip4_reass_add_fragment (u32 thread_index, nat_reass_ip4_t * reass,
393 u32 bi, u32 ** bi_to_drop)
395 nat_reass_main_t *srm = &nat_reass_main;
399 if (reass->frag_n >= srm->ip4_max_frag)
401 nat_ipfix_logging_max_fragments_ip4 (thread_index, srm->ip4_max_frag,
403 reass->flags |= NAT_REASS_FLAG_MAX_FRAG_DROP;
404 nat_ip4_reass_get_frags_inline (reass, bi_to_drop);
408 clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
410 pool_get (srm->ip4_frags_list_pool, elt);
411 elt_index = elt - srm->ip4_frags_list_pool;
412 clib_dlist_init (srm->ip4_frags_list_pool, elt_index);
414 clib_dlist_addtail (srm->ip4_frags_list_pool,
415 reass->frags_per_reass_list_head_index, elt_index);
418 clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
424 nat_ip4_reass_get_frags (nat_reass_ip4_t * reass, u32 ** bi)
426 nat_reass_main_t *srm = &nat_reass_main;
428 clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
430 nat_ip4_reass_get_frags_inline (reass, bi);
432 clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
436 nat_ip4_reass_walk (nat_ip4_reass_walk_fn_t fn, void *ctx)
438 nat_reass_ip4_t *reass;
439 nat_reass_main_t *srm = &nat_reass_main;
440 f64 now = vlib_time_now (srm->vlib_main);
443 pool_foreach (reass, srm->ip4_reass_pool,
445 if (now < reass->last_heard + (f64) srm->ip4_timeout)
454 static_always_inline nat_reass_ip6_t *
455 nat_ip6_reass_lookup (nat_reass_ip6_key_t * k, f64 now)
457 nat_reass_main_t *srm = &nat_reass_main;
458 clib_bihash_kv_48_8_t kv, value;
459 nat_reass_ip6_t *reass;
462 kv.key[0] = k->as_u64[0];
463 kv.key[1] = k->as_u64[1];
464 kv.key[2] = k->as_u64[2];
465 kv.key[3] = k->as_u64[3];
466 kv.key[4] = k->as_u64[4];
467 kv.key[5] = k->as_u64[5];
469 if (clib_bihash_search_48_8 (&srm->ip6_reass_hash, &kv, &value))
472 reass = pool_elt_at_index (srm->ip6_reass_pool, value.value);
473 if (now < reass->last_heard + (f64) srm->ip6_timeout)
480 nat_ip6_reass_find_or_create (ip6_address_t src, ip6_address_t dst,
481 u32 frag_id, u8 proto, u8 reset_timeout,
484 nat_reass_main_t *srm = &nat_reass_main;
485 nat_reass_ip6_t *reass = 0;
486 nat_reass_ip6_key_t k;
487 f64 now = vlib_time_now (srm->vlib_main);
488 dlist_elt_t *oldest_elt, *elt;
489 dlist_elt_t *per_reass_list_head_elt;
490 u32 oldest_index, elt_index;
491 clib_bihash_kv_48_8_t kv;
493 k.src.as_u64[0] = src.as_u64[0];
494 k.src.as_u64[1] = src.as_u64[1];
495 k.dst.as_u64[0] = dst.as_u64[0];
496 k.dst.as_u64[1] = dst.as_u64[1];
501 clib_spinlock_lock_if_init (&srm->ip6_reass_lock);
503 reass = nat_ip6_reass_lookup (&k, now);
508 reass->last_heard = now;
509 clib_dlist_remove (srm->ip6_reass_lru_list_pool,
510 reass->lru_list_index);
511 clib_dlist_addtail (srm->ip6_reass_lru_list_pool,
512 srm->ip6_reass_head_index,
513 reass->lru_list_index);
516 if (reass->flags & NAT_REASS_FLAG_MAX_FRAG_DROP)
525 if (srm->ip6_reass_n >= srm->ip6_max_reass)
528 clib_dlist_remove_head (srm->ip6_reass_lru_list_pool,
529 srm->ip6_reass_head_index);
530 ASSERT (oldest_index != ~0);
532 pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
533 reass = pool_elt_at_index (srm->ip6_reass_pool, oldest_elt->value);
534 if (now < reass->last_heard + (f64) srm->ip6_timeout)
536 clib_dlist_addhead (srm->ip6_reass_lru_list_pool,
537 srm->ip6_reass_head_index, oldest_index);
538 nat_elog_warn ("no free resassembly slot");
543 clib_dlist_addtail (srm->ip6_reass_lru_list_pool,
544 srm->ip6_reass_head_index, oldest_index);
546 kv.key[0] = k.as_u64[0];
547 kv.key[1] = k.as_u64[1];
548 kv.key[2] = k.as_u64[2];
549 kv.key[3] = k.as_u64[3];
550 kv.key[4] = k.as_u64[4];
551 kv.key[5] = k.as_u64[5];
552 if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 0))
558 nat_ip6_reass_get_frags_inline (reass, bi_to_drop);
562 pool_get (srm->ip6_reass_pool, reass);
563 pool_get (srm->ip6_reass_lru_list_pool, elt);
564 reass->lru_list_index = elt_index = elt - srm->ip6_reass_lru_list_pool;
565 clib_dlist_init (srm->ip6_reass_lru_list_pool, elt_index);
566 elt->value = reass - srm->ip6_reass_pool;
567 clib_dlist_addtail (srm->ip6_reass_lru_list_pool,
568 srm->ip6_reass_head_index, elt_index);
569 pool_get (srm->ip6_frags_list_pool, per_reass_list_head_elt);
570 reass->frags_per_reass_list_head_index =
571 per_reass_list_head_elt - srm->ip6_frags_list_pool;
572 clib_dlist_init (srm->ip6_frags_list_pool,
573 reass->frags_per_reass_list_head_index);
577 reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
578 reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
579 reass->key.as_u64[2] = kv.key[2] = k.as_u64[2];
580 reass->key.as_u64[3] = kv.key[3] = k.as_u64[3];
581 reass->key.as_u64[4] = kv.key[4] = k.as_u64[4];
582 reass->key.as_u64[5] = kv.key[5] = k.as_u64[5];
583 kv.value = reass - srm->ip6_reass_pool;
584 reass->sess_index = (u32) ~ 0;
585 reass->last_heard = now;
587 if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 1))
594 clib_spinlock_unlock_if_init (&srm->ip6_reass_lock);
599 nat_ip6_reass_add_fragment (u32 thread_index, nat_reass_ip6_t * reass,
600 u32 bi, u32 ** bi_to_drop)
602 nat_reass_main_t *srm = &nat_reass_main;
606 if (reass->frag_n >= srm->ip6_max_frag)
608 nat_ipfix_logging_max_fragments_ip6 (thread_index, srm->ip6_max_frag,
610 reass->flags |= NAT_REASS_FLAG_MAX_FRAG_DROP;
611 nat_ip6_reass_get_frags_inline (reass, bi_to_drop);
615 clib_spinlock_lock_if_init (&srm->ip6_reass_lock);
617 pool_get (srm->ip6_frags_list_pool, elt);
618 elt_index = elt - srm->ip6_frags_list_pool;
619 clib_dlist_init (srm->ip6_frags_list_pool, elt_index);
621 clib_dlist_addtail (srm->ip6_frags_list_pool,
622 reass->frags_per_reass_list_head_index, elt_index);
625 clib_spinlock_unlock_if_init (&srm->ip6_reass_lock);
631 nat_ip6_reass_get_frags (nat_reass_ip6_t * reass, u32 ** bi)
633 nat_reass_main_t *srm = &nat_reass_main;
635 clib_spinlock_lock_if_init (&srm->ip6_reass_lock);
637 nat_ip6_reass_get_frags_inline (reass, bi);
639 clib_spinlock_unlock_if_init (&srm->ip6_reass_lock);
643 nat_ip6_reass_walk (nat_ip6_reass_walk_fn_t fn, void *ctx)
645 nat_reass_ip6_t *reass;
646 nat_reass_main_t *srm = &nat_reass_main;
647 f64 now = vlib_time_now (srm->vlib_main);
650 pool_foreach (reass, srm->ip6_reass_pool,
652 if (now < reass->last_heard + (f64) srm->ip4_timeout)
662 nat_reass_init (vlib_main_t * vm)
664 nat_reass_main_t *srm = &nat_reass_main;
665 vlib_thread_main_t *tm = vlib_get_thread_main ();
666 clib_error_t *error = 0;
668 u32 nbuckets, head_index;
671 srm->vnet_main = vnet_get_main ();
674 srm->ip4_timeout = NAT_REASS_TIMEOUT_DEFAULT;
675 srm->ip4_max_reass = NAT_MAX_REASS_DEAFULT;
676 srm->ip4_max_frag = NAT_MAX_FRAG_DEFAULT;
677 srm->ip4_drop_frag = 0;
678 srm->ip4_reass_n = 0;
680 if (tm->n_vlib_mains > 1)
681 clib_spinlock_init (&srm->ip4_reass_lock);
683 pool_alloc (srm->ip4_reass_pool, srm->ip4_max_reass);
685 nbuckets = nat_reass_get_nbuckets (0);
686 clib_bihash_init_16_8 (&srm->ip4_reass_hash, "nat-ip4-reass", nbuckets,
689 pool_get (srm->ip4_reass_lru_list_pool, head);
690 srm->ip4_reass_head_index = head_index =
691 head - srm->ip4_reass_lru_list_pool;
692 clib_dlist_init (srm->ip4_reass_lru_list_pool, head_index);
695 srm->ip6_timeout = NAT_REASS_TIMEOUT_DEFAULT;
696 srm->ip6_max_reass = NAT_MAX_REASS_DEAFULT;
697 srm->ip6_max_frag = NAT_MAX_FRAG_DEFAULT;
698 srm->ip6_drop_frag = 0;
699 srm->ip6_reass_n = 0;
701 if (tm->n_vlib_mains > 1)
702 clib_spinlock_init (&srm->ip6_reass_lock);
704 pool_alloc (srm->ip6_reass_pool, srm->ip6_max_reass);
706 nbuckets = nat_reass_get_nbuckets (1);
707 clib_bihash_init_48_8 (&srm->ip6_reass_hash, "nat-ip6-reass", nbuckets,
710 pool_get (srm->ip6_reass_lru_list_pool, head);
711 srm->ip6_reass_head_index = head_index =
712 head - srm->ip6_reass_lru_list_pool;
713 clib_dlist_init (srm->ip6_reass_lru_list_pool, head_index);
718 static clib_error_t *
719 nat_reass_command_fn (vlib_main_t * vm, unformat_input_t * input,
720 vlib_cli_command_t * cmd)
722 clib_error_t *error = 0;
723 unformat_input_t _line_input, *line_input = &_line_input;
724 u32 timeout = 0, max_reass = 0, max_frag = 0;
725 u8 drop_frag = (u8) ~ 0, is_ip6 = 0;
728 /* Get a line of input. */
729 if (!unformat_user (input, unformat_line_input, line_input))
732 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
734 if (unformat (line_input, "max-reassemblies %u", &max_reass))
736 else if (unformat (line_input, "max-fragments %u", &max_frag))
738 else if (unformat (line_input, "timeout %u", &timeout))
740 else if (unformat (line_input, "enable"))
742 else if (unformat (line_input, "disable"))
744 else if (unformat (line_input, "ip4"))
746 else if (unformat (line_input, "ip6"))
750 error = clib_error_return (0, "unknown input '%U'",
751 format_unformat_error, line_input);
757 timeout = nat_reass_get_timeout (is_ip6);
759 max_reass = nat_reass_get_max_reass (is_ip6);
761 max_frag = nat_reass_get_max_frag (is_ip6);
762 if (drop_frag == (u8) ~ 0)
763 drop_frag = nat_reass_is_drop_frag (is_ip6);
766 nat_reass_set (timeout, (u16) max_reass, (u8) max_frag, drop_frag,
770 error = clib_error_return (0, "nat_set_reass return %d", rv);
775 unformat_free (line_input);
781 nat_ip4_reass_walk_cli (nat_reass_ip4_t * reass, void *ctx)
783 vlib_main_t *vm = ctx;
785 const char *classify_next_str;
787 if (reass->flags & NAT_REASS_FLAG_MAX_FRAG_DROP)
788 flags_str = format (flags_str, "MAX_FRAG_DROP");
789 if (reass->flags & NAT_REASS_FLAG_CLASSIFY_ED_CONTINUE)
792 flags_str = format (flags_str, " | ");
793 flags_str = format (flags_str, "CLASSIFY_ED_CONTINUE");
795 if (reass->flags & NAT_REASS_FLAG_ED_DONT_TRANSLATE)
798 flags_str = format (flags_str, " | ");
799 flags_str = format (flags_str, "CLASSIFY_ED_DONT_TRANSLATE");
802 flags_str = format (flags_str, "0");
803 flags_str = format (flags_str, "%c", 0);
805 switch (reass->classify_next)
807 case NAT_REASS_IP4_CLASSIFY_NONE:
808 classify_next_str = "NONE";
810 case NAT_REASS_IP4_CLASSIFY_NEXT_IN2OUT:
811 classify_next_str = "IN2OUT";
813 case NAT_REASS_IP4_CLASSIFY_NEXT_OUT2IN:
814 classify_next_str = "OUT2IN";
817 classify_next_str = "invalid value";
820 vlib_cli_output (vm, " src %U dst %U proto %u id 0x%04x cached %u "
821 "flags %s classify_next %s",
822 format_ip4_address, &reass->key.src,
823 format_ip4_address, &reass->key.dst,
825 clib_net_to_host_u16 (reass->key.frag_id), reass->frag_n,
826 flags_str, classify_next_str);
828 vec_free (flags_str);
834 nat_ip6_reass_walk_cli (nat_reass_ip6_t * reass, void *ctx)
836 vlib_main_t *vm = ctx;
838 vlib_cli_output (vm, " src %U dst %U proto %u id 0x%08x cached %u",
839 format_ip6_address, &reass->key.src,
840 format_ip6_address, &reass->key.dst,
842 clib_net_to_host_u32 (reass->key.frag_id), reass->frag_n);
847 static clib_error_t *
848 show_nat_reass_command_fn (vlib_main_t * vm, unformat_input_t * input,
849 vlib_cli_command_t * cmd)
851 vlib_cli_output (vm, "NAT IPv4 virtual fragmentation reassembly is %s",
852 nat_reass_is_drop_frag (0) ? "DISABLED" : "ENABLED");
853 vlib_cli_output (vm, " max-reassemblies %u", nat_reass_get_max_reass (0));
854 vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (0));
855 vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (0));
856 vlib_cli_output (vm, " reassemblies:");
857 nat_ip4_reass_walk (nat_ip4_reass_walk_cli, vm);
859 vlib_cli_output (vm, "NAT IPv6 virtual fragmentation reassembly is %s",
860 nat_reass_is_drop_frag (1) ? "DISABLED" : "ENABLED");
861 vlib_cli_output (vm, " max-reassemblies %u", nat_reass_get_max_reass (1));
862 vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (1));
863 vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (1));
864 vlib_cli_output (vm, " reassemblies:");
865 nat_ip6_reass_walk (nat_ip6_reass_walk_cli, vm);
871 VLIB_CLI_COMMAND (nat_reass_command, static) =
873 .path = "nat virtual-reassembly",
874 .short_help = "nat virtual-reassembly ip4|ip6 [max-reassemblies <n>] "
875 "[max-fragments <n>] [timeout <sec>] [enable|disable]",
876 .function = nat_reass_command_fn,
879 VLIB_CLI_COMMAND (show_nat_reass_command, static) =
881 .path = "show nat virtual-reassembly",
882 .short_help = "show nat virtual-reassembly",
883 .function = show_nat_reass_command_fn,
888 * fd.io coding-style-patch-verification: ON
891 * eval: (c-set-style "gnu")