X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fnat%2Fnat_reass.c;h=8fd370de2fce987752a387508837307f106f85c3;hb=a7f8b228ff505acc052a77101b12e714ead26536;hp=239bc70d8360ce5d7cedf5185094c57b68cd76de;hpb=efcd1e9e1d7dda4e4ea3db5750925cd8f6894f4d;p=vpp.git diff --git a/src/plugins/nat/nat_reass.c b/src/plugins/nat/nat_reass.c old mode 100644 new mode 100755 index 239bc70d836..8fd370de2fc --- a/src/plugins/nat/nat_reass.c +++ b/src/plugins/nat/nat_reass.c @@ -19,6 +19,7 @@ #include #include +#include nat_reass_main_t nat_reass_main; @@ -194,6 +195,27 @@ nat_ip4_reass_lookup (nat_reass_ip4_key_t * k, f64 now) 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_find_or_create (ip4_address_t src, ip4_address_t dst, u16 frag_id, u8 proto, u8 reset_timeout, @@ -206,7 +228,7 @@ nat_ip4_reass_find_or_create (ip4_address_t src, ip4_address_t dst, 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; + clib_bihash_kv_16_8_t kv, value; k.src.as_u32 = src.as_u32; k.dst.as_u32 = dst.as_u32; @@ -227,6 +249,13 @@ nat_ip4_reass_find_or_create (ip4_address_t src, ip4_address_t dst, srm->ip4_reass_head_index, reass->lru_list_index); } + + if (reass->flags && NAT_REASS_FLAG_MAX_FRAG_DROP) + { + reass = 0; + goto unlock; + } + goto unlock; } @@ -251,12 +280,18 @@ nat_ip4_reass_find_or_create (ip4_address_t src, ip4_address_t dst, clib_dlist_addtail (srm->ip4_reass_lru_list_pool, srm->ip4_reass_head_index, oldest_index); - kv.key[0] = k.as_u64[0]; - kv.key[1] = k.as_u64[1]; - if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 0)) + 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)) { - reass = 0; - goto unlock; + 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); @@ -282,7 +317,9 @@ nat_ip4_reass_find_or_create (ip4_address_t src, ip4_address_t dst, 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; if (clib_bihash_add_del_16_8 (&srm->ip4_reass_hash, &kv, 1)) { @@ -296,14 +333,21 @@ unlock: } int -nat_ip4_reass_add_fragment (nat_reass_ip4_t * reass, u32 bi) +nat_ip4_reass_add_fragment (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) - return -1; + { + nat_ipfix_logging_max_fragments_ip4 (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); @@ -412,6 +456,13 @@ nat_ip6_reass_find_or_create (ip6_address_t src, ip6_address_t dst, srm->ip6_reass_head_index, reass->lru_list_index); } + + if (reass->flags && NAT_REASS_FLAG_MAX_FRAG_DROP) + { + reass = 0; + goto unlock; + } + goto unlock; } @@ -488,14 +539,21 @@ unlock: } int -nat_ip6_reass_add_fragment (nat_reass_ip6_t * reass, u32 bi) +nat_ip6_reass_add_fragment (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) - return -1; + { + nat_ipfix_logging_max_fragments_ip6 (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); @@ -696,7 +754,7 @@ show_nat_reass_command_fn (vlib_main_t * vm, unformat_input_t * input, { vlib_cli_output (vm, "NAT IPv4 virtual fragmentation reassembly is %s", nat_reass_is_drop_frag (0) ? "DISABLED" : "ENABLED"); - vlib_cli_output (vm, " max-reasssemblies %u", nat_reass_get_max_reass (0)); + 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:"); @@ -704,7 +762,7 @@ show_nat_reass_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_output (vm, "NAT IPv6 virtual fragmentation reassembly is %s", nat_reass_is_drop_frag (1) ? "DISABLED" : "ENABLED"); - vlib_cli_output (vm, " max-reasssemblies %u", nat_reass_get_max_reass (1)); + 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:");