summaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/nat_reass.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/nat/nat_reass.c')
-rwxr-xr-xsrc/plugins/nat/nat_reass.c893
1 files changed, 0 insertions, 893 deletions
diff --git a/src/plugins/nat/nat_reass.c b/src/plugins/nat/nat_reass.c
deleted file mode 100755
index b518c0cb916..00000000000
--- a/src/plugins/nat/nat_reass.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/*
- * Copyright (c) 2017 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @file
- * @brief NAT plugin virtual fragmentation reassembly
- */
-
-#include <vnet/vnet.h>
-#include <nat/nat_reass.h>
-#include <nat/nat_ipfix_logging.h>
-
-nat_reass_main_t nat_reass_main;
-
-static u32
-nat_reass_get_nbuckets (u8 is_ip6)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- u32 nbuckets;
- u8 i;
-
- if (is_ip6)
- nbuckets = (u32) (srm->ip6_max_reass / NAT_REASS_HT_LOAD_FACTOR);
- else
- nbuckets = (u32) (srm->ip4_max_reass / NAT_REASS_HT_LOAD_FACTOR);
-
- for (i = 0; i < 31; i++)
- if ((1 << i) >= nbuckets)
- break;
- nbuckets = 1 << i;
-
- return nbuckets;
-}
-
-static_always_inline void
-nat_ip4_reass_get_frags_inline (nat_reass_ip4_t * reass, u32 ** bi)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- u32 elt_index;
- dlist_elt_t *elt;
-
- while ((elt_index =
- clib_dlist_remove_head (srm->ip4_frags_list_pool,
- reass->frags_per_reass_list_head_index)) !=
- ~0)
- {
- elt = pool_elt_at_index (srm->ip4_frags_list_pool, elt_index);
- vec_add1 (*bi, elt->value);
- reass->frag_n--;
- pool_put_index (srm->ip4_frags_list_pool, elt_index);
- }
-}
-
-static_always_inline void
-nat_ip6_reass_get_frags_inline (nat_reass_ip6_t * reass, u32 ** bi)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- u32 elt_index;
- dlist_elt_t *elt;
-
- while ((elt_index =
- clib_dlist_remove_head (srm->ip6_frags_list_pool,
- reass->frags_per_reass_list_head_index)) !=
- ~0)
- {
- elt = pool_elt_at_index (srm->ip6_frags_list_pool, elt_index);
- vec_add1 (*bi, elt->value);
- reass->frag_n--;
- pool_put_index (srm->ip6_frags_list_pool, elt_index);
- }
-}
-
-int
-nat_reass_set (u32 timeout, u16 max_reass, u8 max_frag, u8 drop_frag,
- u8 is_ip6)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- u32 nbuckets;
-
- if (is_ip6)
- {
- if (srm->ip6_max_reass != max_reass)
- {
- clib_spinlock_lock_if_init (&srm->ip6_reass_lock);
-
- srm->ip6_max_reass = max_reass;
- pool_free (srm->ip6_reass_pool);
- pool_alloc (srm->ip6_reass_pool, srm->ip4_max_reass);
- nbuckets = nat_reass_get_nbuckets (0);
- clib_bihash_free_48_8 (&srm->ip6_reass_hash);
- clib_bihash_init_48_8 (&srm->ip6_reass_hash, "nat-ip6-reass",
- nbuckets, nbuckets * 1024);
-
- clib_spinlock_unlock_if_init (&srm->ip6_reass_lock);
- }
- srm->ip6_timeout = timeout;
- srm->ip6_max_frag = max_frag;
- srm->ip6_drop_frag = drop_frag;
- }
- else
- {
- if (srm->ip4_max_reass != max_reass)
- {
- clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
-
- srm->ip4_max_reass = max_reass;
- pool_free (srm->ip4_reass_pool);
- pool_alloc (srm->ip4_reass_pool, srm->ip4_max_reass);
- nbuckets = nat_reass_get_nbuckets (0);
- clib_bihash_free_16_8 (&srm->ip4_reass_hash);
- clib_bihash_init_16_8 (&srm->ip4_reass_hash, "nat-ip4-reass",
- nbuckets, nbuckets * 1024);
- clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
- }
- srm->ip4_timeout = timeout;
- srm->ip4_max_frag = max_frag;
- srm->ip4_drop_frag = drop_frag;
- }
-
- return 0;
-}
-
-u32
-nat_reass_get_timeout (u8 is_ip6)
-{
- nat_reass_main_t *srm = &nat_reass_main;
-
- if (is_ip6)
- return srm->ip6_timeout;
-
- return srm->ip4_timeout;
-}
-
-u16
-nat_reass_get_max_reass (u8 is_ip6)
-{
- nat_reass_main_t *srm = &nat_reass_main;
-
- if (is_ip6)
- return srm->ip6_max_reass;
-
- return srm->ip4_max_reass;
-}
-
-u8
-nat_reass_get_max_frag (u8 is_ip6)
-{
- nat_reass_main_t *srm = &nat_reass_main;
-
- if (is_ip6)
- return srm->ip6_max_frag;
-
- return srm->ip4_max_frag;
-}
-
-u8
-nat_reass_is_drop_frag (u8 is_ip6)
-{
- nat_reass_main_t *srm = &nat_reass_main;
-
- if (is_ip6)
- return srm->ip6_drop_frag;
-
- return srm->ip4_drop_frag;
-}
-
-static_always_inline nat_reass_ip4_t *
-nat_ip4_reass_lookup (nat_reass_ip4_key_t * k, f64 now)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- clib_bihash_kv_16_8_t kv, value;
- nat_reass_ip4_t *reass;
-
- kv.key[0] = k->as_u64[0];
- kv.key[1] = k->as_u64[1];
-
- if (clib_bihash_search_16_8 (&srm->ip4_reass_hash, &kv, &value))
- return 0;
-
- reass = pool_elt_at_index (srm->ip4_reass_pool, value.value);
- if (now < reass->last_heard + (f64) srm->ip4_timeout)
- return reass;
-
- return 0;
-}
-
-nat_reass_ip4_t *
-nat_ip4_reass_find (ip4_address_t src, ip4_address_t dst, u16 frag_id,
- u8 proto)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- nat_reass_ip4_t *reass = 0;
- nat_reass_ip4_key_t k;
- f64 now = vlib_time_now (srm->vlib_main);
-
- k.src.as_u32 = src.as_u32;
- k.dst.as_u32 = dst.as_u32;
- k.frag_id = frag_id;
- k.proto = proto;
-
- clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
- reass = nat_ip4_reass_lookup (&k, now);
- clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
-
- return reass;
-}
-
-nat_reass_ip4_t *
-nat_ip4_reass_create (ip4_address_t src, ip4_address_t dst, u16 frag_id,
- u8 proto)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- nat_reass_ip4_t *reass = 0;
- dlist_elt_t *elt, *per_reass_list_head_elt;
- u32 elt_index;
- f64 now = vlib_time_now (srm->vlib_main);
- nat_reass_ip4_key_t k;
- clib_bihash_kv_16_8_t kv;
-
- clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
-
- if (srm->ip4_reass_n >= srm->ip4_max_reass)
- {
- nat_elog_warn ("no free resassembly slot");
- goto unlock;
- }
-
- pool_get (srm->ip4_reass_pool, reass);
- pool_get (srm->ip4_reass_lru_list_pool, elt);
- reass->lru_list_index = elt_index = elt - srm->ip4_reass_lru_list_pool;
- clib_dlist_init (srm->ip4_reass_lru_list_pool, elt_index);
- elt->value = reass - srm->ip4_reass_pool;
- clib_dlist_addtail (srm->ip4_reass_lru_list_pool,
- srm->ip4_reass_head_index, elt_index);
- pool_get (srm->ip4_frags_list_pool, per_reass_list_head_elt);
- reass->frags_per_reass_list_head_index =
- per_reass_list_head_elt - srm->ip4_frags_list_pool;
- clib_dlist_init (srm->ip4_frags_list_pool,
- reass->frags_per_reass_list_head_index);
- srm->ip4_reass_n++;
- k.src.as_u32 = src.as_u32;
- k.dst.as_u32 = dst.as_u32;
- k.frag_id = frag_id;
- k.proto = proto;
- reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
- reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
- kv.value = reass - srm->ip4_reass_pool;
- reass->sess_index = (u32) ~ 0;
- reass->thread_index = (u32) ~ 0;
- reass->last_heard = now;
- reass->frag_n = 0;
- reass->flags = 0;
- reass->classify_next = NAT_REASS_IP4_CLASSIFY_NONE;
- if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 1))
- nat_elog_warn ("ip4_reass_hash add key failed");
-
-unlock:
- clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
- return reass;
-}
-
-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)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- nat_reass_ip4_t *reass = 0;
- nat_reass_ip4_key_t k;
- f64 now = vlib_time_now (srm->vlib_main);
- dlist_elt_t *oldest_elt, *elt;
- dlist_elt_t *per_reass_list_head_elt;
- u32 oldest_index, elt_index;
- clib_bihash_kv_16_8_t kv, value;
-
- k.src.as_u32 = src.as_u32;
- k.dst.as_u32 = dst.as_u32;
- k.frag_id = frag_id;
- k.proto = proto;
-
- clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
-
- reass = nat_ip4_reass_lookup (&k, now);
- if (reass)
- {
- if (reset_timeout)
- {
- reass->last_heard = now;
- clib_dlist_remove (srm->ip4_reass_lru_list_pool,
- reass->lru_list_index);
- clib_dlist_addtail (srm->ip4_reass_lru_list_pool,
- srm->ip4_reass_head_index,
- reass->lru_list_index);
- }
-
- if (reass->flags & NAT_REASS_FLAG_MAX_FRAG_DROP)
- {
- reass = 0;
- goto unlock;
- }
-
- goto unlock;
- }
-
- if (srm->ip4_reass_n >= srm->ip4_max_reass)
- {
- oldest_index =
- clib_dlist_remove_head (srm->ip4_reass_lru_list_pool,
- srm->ip4_reass_head_index);
- ASSERT (oldest_index != ~0);
- oldest_elt =
- pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
- reass = pool_elt_at_index (srm->ip4_reass_pool, oldest_elt->value);
- if (now < reass->last_heard + (f64) srm->ip4_timeout)
- {
- clib_dlist_addhead (srm->ip4_reass_lru_list_pool,
- srm->ip4_reass_head_index, oldest_index);
- nat_elog_warn ("no free resassembly slot");
- reass = 0;
- goto unlock;
- }
-
- clib_dlist_addtail (srm->ip4_reass_lru_list_pool,
- srm->ip4_reass_head_index, oldest_index);
-
- kv.key[0] = reass->key.as_u64[0];
- kv.key[1] = reass->key.as_u64[1];
- if (!clib_bihash_search_16_8 (&srm->ip4_reass_hash, &kv, &value))
- {
- if (value.value == (reass - srm->ip4_reass_pool))
- {
- if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 0))
- {
- reass = 0;
- goto unlock;
- }
- }
- }
-
- nat_ip4_reass_get_frags_inline (reass, bi_to_drop);
- }
- else
- {
- pool_get (srm->ip4_reass_pool, reass);
- pool_get (srm->ip4_reass_lru_list_pool, elt);
- reass->lru_list_index = elt_index = elt - srm->ip4_reass_lru_list_pool;
- clib_dlist_init (srm->ip4_reass_lru_list_pool, elt_index);
- elt->value = reass - srm->ip4_reass_pool;
- clib_dlist_addtail (srm->ip4_reass_lru_list_pool,
- srm->ip4_reass_head_index, elt_index);
- pool_get (srm->ip4_frags_list_pool, per_reass_list_head_elt);
- reass->frags_per_reass_list_head_index =
- per_reass_list_head_elt - srm->ip4_frags_list_pool;
- clib_dlist_init (srm->ip4_frags_list_pool,
- reass->frags_per_reass_list_head_index);
- srm->ip4_reass_n++;
- }
-
- reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
- reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
- kv.value = reass - srm->ip4_reass_pool;
- reass->sess_index = (u32) ~ 0;
- reass->thread_index = (u32) ~ 0;
- reass->last_heard = now;
- reass->frag_n = 0;
- reass->flags = 0;
- reass->classify_next = NAT_REASS_IP4_CLASSIFY_NONE;
-
- if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 1))
- {
- reass = 0;
- goto unlock;
- }
-
-unlock:
- clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
- return reass;
-}
-
-int
-nat_ip4_reass_add_fragment (u32 thread_index, nat_reass_ip4_t * reass,
- u32 bi, u32 ** bi_to_drop)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- dlist_elt_t *elt;
- u32 elt_index;
-
- if (reass->frag_n >= srm->ip4_max_frag)
- {
- nat_ipfix_logging_max_fragments_ip4 (thread_index, srm->ip4_max_frag,
- &reass->key.src);
- reass->flags |= NAT_REASS_FLAG_MAX_FRAG_DROP;
- nat_ip4_reass_get_frags_inline (reass, bi_to_drop);
- return -1;
- }
-
- clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
-
- pool_get (srm->ip4_frags_list_pool, elt);
- elt_index = elt - srm->ip4_frags_list_pool;
- clib_dlist_init (srm->ip4_frags_list_pool, elt_index);
- elt->value = bi;
- clib_dlist_addtail (srm->ip4_frags_list_pool,
- reass->frags_per_reass_list_head_index, elt_index);
- reass->frag_n++;
-
- clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
-
- return 0;
-}
-
-void
-nat_ip4_reass_get_frags (nat_reass_ip4_t * reass, u32 ** bi)
-{
- nat_reass_main_t *srm = &nat_reass_main;
-
- clib_spinlock_lock_if_init (&srm->ip4_reass_lock);
-
- nat_ip4_reass_get_frags_inline (reass, bi);
-
- clib_spinlock_unlock_if_init (&srm->ip4_reass_lock);
-}
-
-void
-nat_ip4_reass_walk (nat_ip4_reass_walk_fn_t fn, void *ctx)
-{
- nat_reass_ip4_t *reass;
- nat_reass_main_t *srm = &nat_reass_main;
- f64 now = vlib_time_now (srm->vlib_main);
-
- /* *INDENT-OFF* */
- pool_foreach (reass, srm->ip4_reass_pool,
- ({
- if (now < reass->last_heard + (f64) srm->ip4_timeout)
- {
- if (fn (reass, ctx))
- return;
- }
- }));
- /* *INDENT-ON* */
-}
-
-static_always_inline nat_reass_ip6_t *
-nat_ip6_reass_lookup (nat_reass_ip6_key_t * k, f64 now)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- clib_bihash_kv_48_8_t kv, value;
- nat_reass_ip6_t *reass;
-
- k->unused = 0;
- kv.key[0] = k->as_u64[0];
- kv.key[1] = k->as_u64[1];
- kv.key[2] = k->as_u64[2];
- kv.key[3] = k->as_u64[3];
- kv.key[4] = k->as_u64[4];
- kv.key[5] = k->as_u64[5];
-
- if (clib_bihash_search_48_8 (&srm->ip6_reass_hash, &kv, &value))
- return 0;
-
- reass = pool_elt_at_index (srm->ip6_reass_pool, value.value);
- if (now < reass->last_heard + (f64) srm->ip6_timeout)
- return reass;
-
- return 0;
-}
-
-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)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- nat_reass_ip6_t *reass = 0;
- nat_reass_ip6_key_t k;
- f64 now = vlib_time_now (srm->vlib_main);
- dlist_elt_t *oldest_elt, *elt;
- dlist_elt_t *per_reass_list_head_elt;
- u32 oldest_index, elt_index;
- clib_bihash_kv_48_8_t kv;
-
- k.src.as_u64[0] = src.as_u64[0];
- k.src.as_u64[1] = src.as_u64[1];
- k.dst.as_u64[0] = dst.as_u64[0];
- k.dst.as_u64[1] = dst.as_u64[1];
- k.frag_id = frag_id;
- k.proto = proto;
- k.unused = 0;
-
- clib_spinlock_lock_if_init (&srm->ip6_reass_lock);
-
- reass = nat_ip6_reass_lookup (&k, now);
- if (reass)
- {
- if (reset_timeout)
- {
- reass->last_heard = now;
- clib_dlist_remove (srm->ip6_reass_lru_list_pool,
- reass->lru_list_index);
- clib_dlist_addtail (srm->ip6_reass_lru_list_pool,
- srm->ip6_reass_head_index,
- reass->lru_list_index);
- }
-
- if (reass->flags & NAT_REASS_FLAG_MAX_FRAG_DROP)
- {
- reass = 0;
- goto unlock;
- }
-
- goto unlock;
- }
-
- if (srm->ip6_reass_n >= srm->ip6_max_reass)
- {
- oldest_index =
- clib_dlist_remove_head (srm->ip6_reass_lru_list_pool,
- srm->ip6_reass_head_index);
- ASSERT (oldest_index != ~0);
- oldest_elt =
- pool_elt_at_index (srm->ip4_reass_lru_list_pool, oldest_index);
- reass = pool_elt_at_index (srm->ip6_reass_pool, oldest_elt->value);
- if (now < reass->last_heard + (f64) srm->ip6_timeout)
- {
- clib_dlist_addhead (srm->ip6_reass_lru_list_pool,
- srm->ip6_reass_head_index, oldest_index);
- nat_elog_warn ("no free resassembly slot");
- reass = 0;
- goto unlock;
- }
-
- clib_dlist_addtail (srm->ip6_reass_lru_list_pool,
- srm->ip6_reass_head_index, oldest_index);
-
- kv.key[0] = k.as_u64[0];
- kv.key[1] = k.as_u64[1];
- kv.key[2] = k.as_u64[2];
- kv.key[3] = k.as_u64[3];
- kv.key[4] = k.as_u64[4];
- kv.key[5] = k.as_u64[5];
- if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 0))
- {
- reass = 0;
- goto unlock;
- }
-
- nat_ip6_reass_get_frags_inline (reass, bi_to_drop);
- }
- else
- {
- pool_get (srm->ip6_reass_pool, reass);
- pool_get (srm->ip6_reass_lru_list_pool, elt);
- reass->lru_list_index = elt_index = elt - srm->ip6_reass_lru_list_pool;
- clib_dlist_init (srm->ip6_reass_lru_list_pool, elt_index);
- elt->value = reass - srm->ip6_reass_pool;
- clib_dlist_addtail (srm->ip6_reass_lru_list_pool,
- srm->ip6_reass_head_index, elt_index);
- pool_get (srm->ip6_frags_list_pool, per_reass_list_head_elt);
- reass->frags_per_reass_list_head_index =
- per_reass_list_head_elt - srm->ip6_frags_list_pool;
- clib_dlist_init (srm->ip6_frags_list_pool,
- reass->frags_per_reass_list_head_index);
- srm->ip6_reass_n++;
- }
-
- reass->key.as_u64[0] = kv.key[0] = k.as_u64[0];
- reass->key.as_u64[1] = kv.key[1] = k.as_u64[1];
- reass->key.as_u64[2] = kv.key[2] = k.as_u64[2];
- reass->key.as_u64[3] = kv.key[3] = k.as_u64[3];
- reass->key.as_u64[4] = kv.key[4] = k.as_u64[4];
- reass->key.as_u64[5] = kv.key[5] = k.as_u64[5];
- kv.value = reass - srm->ip6_reass_pool;
- reass->sess_index = (u32) ~ 0;
- reass->last_heard = now;
-
- if (clib_bihash_add_del_48_8 (&srm->ip6_reass_hash, &kv, 1))
- {
- reass = 0;
- goto unlock;
- }
-
-unlock:
- clib_spinlock_unlock_if_init (&srm->ip6_reass_lock);
- return reass;
-}
-
-int
-nat_ip6_reass_add_fragment (u32 thread_index, nat_reass_ip6_t * reass,
- u32 bi, u32 ** bi_to_drop)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- dlist_elt_t *elt;
- u32 elt_index;
-
- if (reass->frag_n >= srm->ip6_max_frag)
- {
- nat_ipfix_logging_max_fragments_ip6 (thread_index, srm->ip6_max_frag,
- &reass->key.src);
- reass->flags |= NAT_REASS_FLAG_MAX_FRAG_DROP;
- nat_ip6_reass_get_frags_inline (reass, bi_to_drop);
- return -1;
- }
-
- clib_spinlock_lock_if_init (&srm->ip6_reass_lock);
-
- pool_get (srm->ip6_frags_list_pool, elt);
- elt_index = elt - srm->ip6_frags_list_pool;
- clib_dlist_init (srm->ip6_frags_list_pool, elt_index);
- elt->value = bi;
- clib_dlist_addtail (srm->ip6_frags_list_pool,
- reass->frags_per_reass_list_head_index, elt_index);
- reass->frag_n++;
-
- clib_spinlock_unlock_if_init (&srm->ip6_reass_lock);
-
- return 0;
-}
-
-void
-nat_ip6_reass_get_frags (nat_reass_ip6_t * reass, u32 ** bi)
-{
- nat_reass_main_t *srm = &nat_reass_main;
-
- clib_spinlock_lock_if_init (&srm->ip6_reass_lock);
-
- nat_ip6_reass_get_frags_inline (reass, bi);
-
- clib_spinlock_unlock_if_init (&srm->ip6_reass_lock);
-}
-
-void
-nat_ip6_reass_walk (nat_ip6_reass_walk_fn_t fn, void *ctx)
-{
- nat_reass_ip6_t *reass;
- nat_reass_main_t *srm = &nat_reass_main;
- f64 now = vlib_time_now (srm->vlib_main);
-
- /* *INDENT-OFF* */
- pool_foreach (reass, srm->ip6_reass_pool,
- ({
- if (now < reass->last_heard + (f64) srm->ip4_timeout)
- {
- if (fn (reass, ctx))
- return;
- }
- }));
- /* *INDENT-ON* */
-}
-
-clib_error_t *
-nat_reass_init (vlib_main_t * vm)
-{
- nat_reass_main_t *srm = &nat_reass_main;
- vlib_thread_main_t *tm = vlib_get_thread_main ();
- clib_error_t *error = 0;
- dlist_elt_t *head;
- u32 nbuckets, head_index;
-
- srm->vlib_main = vm;
- srm->vnet_main = vnet_get_main ();
-
- /* IPv4 */
- srm->ip4_timeout = NAT_REASS_TIMEOUT_DEFAULT;
- srm->ip4_max_reass = NAT_MAX_REASS_DEAFULT;
- srm->ip4_max_frag = NAT_MAX_FRAG_DEFAULT;
- srm->ip4_drop_frag = 0;
- srm->ip4_reass_n = 0;
-
- if (tm->n_vlib_mains > 1)
- clib_spinlock_init (&srm->ip4_reass_lock);
-
- pool_alloc (srm->ip4_reass_pool, srm->ip4_max_reass);
-
- nbuckets = nat_reass_get_nbuckets (0);
- clib_bihash_init_16_8 (&srm->ip4_reass_hash, "nat-ip4-reass", nbuckets,
- nbuckets * 1024);
-
- pool_get (srm->ip4_reass_lru_list_pool, head);
- srm->ip4_reass_head_index = head_index =
- head - srm->ip4_reass_lru_list_pool;
- clib_dlist_init (srm->ip4_reass_lru_list_pool, head_index);
-
- /* IPv6 */
- srm->ip6_timeout = NAT_REASS_TIMEOUT_DEFAULT;
- srm->ip6_max_reass = NAT_MAX_REASS_DEAFULT;
- srm->ip6_max_frag = NAT_MAX_FRAG_DEFAULT;
- srm->ip6_drop_frag = 0;
- srm->ip6_reass_n = 0;
-
- if (tm->n_vlib_mains > 1)
- clib_spinlock_init (&srm->ip6_reass_lock);
-
- pool_alloc (srm->ip6_reass_pool, srm->ip6_max_reass);
-
- nbuckets = nat_reass_get_nbuckets (1);
- clib_bihash_init_48_8 (&srm->ip6_reass_hash, "nat-ip6-reass", nbuckets,
- nbuckets * 1024);
-
- pool_get (srm->ip6_reass_lru_list_pool, head);
- srm->ip6_reass_head_index = head_index =
- head - srm->ip6_reass_lru_list_pool;
- clib_dlist_init (srm->ip6_reass_lru_list_pool, head_index);
-
- return error;
-}
-
-static clib_error_t *
-nat_reass_command_fn (vlib_main_t * vm, unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- clib_error_t *error = 0;
- unformat_input_t _line_input, *line_input = &_line_input;
- u32 timeout = 0, max_reass = 0, max_frag = 0;
- u8 drop_frag = (u8) ~ 0, is_ip6 = 0;
- int rv;
-
- /* Get a line of input. */
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "max-reassemblies %u", &max_reass))
- ;
- else if (unformat (line_input, "max-fragments %u", &max_frag))
- ;
- else if (unformat (line_input, "timeout %u", &timeout))
- ;
- else if (unformat (line_input, "enable"))
- drop_frag = 0;
- else if (unformat (line_input, "disable"))
- drop_frag = 1;
- else if (unformat (line_input, "ip4"))
- is_ip6 = 0;
- else if (unformat (line_input, "ip6"))
- is_ip6 = 1;
- else
- {
- error = clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
-
- if (!timeout)
- timeout = nat_reass_get_timeout (is_ip6);
- if (!max_reass)
- max_reass = nat_reass_get_max_reass (is_ip6);
- if (!max_frag)
- max_frag = nat_reass_get_max_frag (is_ip6);
- if (drop_frag == (u8) ~ 0)
- drop_frag = nat_reass_is_drop_frag (is_ip6);
-
- rv =
- nat_reass_set (timeout, (u16) max_reass, (u8) max_frag, drop_frag,
- is_ip6);
- if (rv)
- {
- error = clib_error_return (0, "nat_set_reass return %d", rv);
- goto done;
- }
-
-done:
- unformat_free (line_input);
-
- return error;
-}
-
-static int
-nat_ip4_reass_walk_cli (nat_reass_ip4_t * reass, void *ctx)
-{
- vlib_main_t *vm = ctx;
- u8 *flags_str = 0;
- const char *classify_next_str;
-
- if (reass->flags & NAT_REASS_FLAG_MAX_FRAG_DROP)
- flags_str = format (flags_str, "MAX_FRAG_DROP");
- if (reass->flags & NAT_REASS_FLAG_CLASSIFY_ED_CONTINUE)
- {
- if (flags_str)
- flags_str = format (flags_str, " | ");
- flags_str = format (flags_str, "CLASSIFY_ED_CONTINUE");
- }
- if (reass->flags & NAT_REASS_FLAG_ED_DONT_TRANSLATE)
- {
- if (flags_str)
- flags_str = format (flags_str, " | ");
- flags_str = format (flags_str, "CLASSIFY_ED_DONT_TRANSLATE");
- }
- if (!flags_str)
- flags_str = format (flags_str, "0");
- flags_str = format (flags_str, "%c", 0);
-
- switch (reass->classify_next)
- {
- case NAT_REASS_IP4_CLASSIFY_NONE:
- classify_next_str = "NONE";
- break;
- case NAT_REASS_IP4_CLASSIFY_NEXT_IN2OUT:
- classify_next_str = "IN2OUT";
- break;
- case NAT_REASS_IP4_CLASSIFY_NEXT_OUT2IN:
- classify_next_str = "OUT2IN";
- break;
- default:
- classify_next_str = "invalid value";
- }
-
- vlib_cli_output (vm, " src %U dst %U proto %u id 0x%04x cached %u "
- "flags %s classify_next %s",
- format_ip4_address, &reass->key.src,
- format_ip4_address, &reass->key.dst,
- reass->key.proto,
- clib_net_to_host_u16 (reass->key.frag_id), reass->frag_n,
- flags_str, classify_next_str);
-
- vec_free (flags_str);
-
- return 0;
-}
-
-static int
-nat_ip6_reass_walk_cli (nat_reass_ip6_t * reass, void *ctx)
-{
- vlib_main_t *vm = ctx;
-
- vlib_cli_output (vm, " src %U dst %U proto %u id 0x%08x cached %u",
- format_ip6_address, &reass->key.src,
- format_ip6_address, &reass->key.dst,
- reass->key.proto,
- clib_net_to_host_u32 (reass->key.frag_id), reass->frag_n);
-
- return 0;
-}
-
-static clib_error_t *
-show_nat_reass_command_fn (vlib_main_t * vm, unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- vlib_cli_output (vm, "NAT IPv4 virtual fragmentation reassembly is %s",
- nat_reass_is_drop_frag (0) ? "DISABLED" : "ENABLED");
- vlib_cli_output (vm, " max-reassemblies %u", nat_reass_get_max_reass (0));
- vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (0));
- vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (0));
- vlib_cli_output (vm, " reassemblies:");
- nat_ip4_reass_walk (nat_ip4_reass_walk_cli, vm);
-
- vlib_cli_output (vm, "NAT IPv6 virtual fragmentation reassembly is %s",
- nat_reass_is_drop_frag (1) ? "DISABLED" : "ENABLED");
- vlib_cli_output (vm, " max-reassemblies %u", nat_reass_get_max_reass (1));
- vlib_cli_output (vm, " max-fragments %u", nat_reass_get_max_frag (1));
- vlib_cli_output (vm, " timeout %usec", nat_reass_get_timeout (1));
- vlib_cli_output (vm, " reassemblies:");
- nat_ip6_reass_walk (nat_ip6_reass_walk_cli, vm);
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (nat_reass_command, static) =
-{
- .path = "nat virtual-reassembly",
- .short_help = "nat virtual-reassembly ip4|ip6 [max-reassemblies <n>] "
- "[max-fragments <n>] [timeout <sec>] [enable|disable]",
- .function = nat_reass_command_fn,
-};
-
-VLIB_CLI_COMMAND (show_nat_reass_command, static) =
-{
- .path = "show nat virtual-reassembly",
- .short_help = "show nat virtual-reassembly",
- .function = show_nat_reass_command_fn,
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */