abf: add feature.yaml
[vpp.git] / src / plugins / nat / nat_reass.c
index 8fd370d..b518c0c 100755 (executable)
@@ -216,6 +216,60 @@ nat_ip4_reass_find (ip4_address_t src, ip4_address_t dst, u16 frag_id,
   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,
@@ -250,7 +304,7 @@ nat_ip4_reass_find_or_create (ip4_address_t src, ip4_address_t dst,
                              reass->lru_list_index);
        }
 
-      if (reass->flags && NAT_REASS_FLAG_MAX_FRAG_DROP)
+      if (reass->flags & NAT_REASS_FLAG_MAX_FRAG_DROP)
        {
          reass = 0;
          goto unlock;
@@ -272,7 +326,7 @@ nat_ip4_reass_find_or_create (ip4_address_t src, ip4_address_t dst,
        {
          clib_dlist_addhead (srm->ip4_reass_lru_list_pool,
                              srm->ip4_reass_head_index, oldest_index);
-         clib_warning ("no free resassembly slot");
+         nat_elog_warn ("no free resassembly slot");
          reass = 0;
          goto unlock;
        }
@@ -320,6 +374,8 @@ nat_ip4_reass_find_or_create (ip4_address_t src, ip4_address_t dst,
   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))
     {
@@ -333,8 +389,8 @@ unlock:
 }
 
 int
-nat_ip4_reass_add_fragment (nat_reass_ip4_t * reass, u32 bi,
-                           u32 ** bi_to_drop)
+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;
@@ -342,7 +398,7 @@ nat_ip4_reass_add_fragment (nat_reass_ip4_t * reass, u32 bi,
 
   if (reass->frag_n >= srm->ip4_max_frag)
     {
-      nat_ipfix_logging_max_fragments_ip4 (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);
@@ -457,7 +513,7 @@ nat_ip6_reass_find_or_create (ip6_address_t src, ip6_address_t dst,
                              reass->lru_list_index);
        }
 
-      if (reass->flags && NAT_REASS_FLAG_MAX_FRAG_DROP)
+      if (reass->flags & NAT_REASS_FLAG_MAX_FRAG_DROP)
        {
          reass = 0;
          goto unlock;
@@ -479,7 +535,7 @@ nat_ip6_reass_find_or_create (ip6_address_t src, ip6_address_t dst,
        {
          clib_dlist_addhead (srm->ip6_reass_lru_list_pool,
                              srm->ip6_reass_head_index, oldest_index);
-         clib_warning ("no free resassembly slot");
+         nat_elog_warn ("no free resassembly slot");
          reass = 0;
          goto unlock;
        }
@@ -490,8 +546,9 @@ nat_ip6_reass_find_or_create (ip6_address_t src, ip6_address_t dst,
       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[4];
-      kv.key[4] = k.as_u64[5];
+      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;
@@ -539,8 +596,8 @@ unlock:
 }
 
 int
-nat_ip6_reass_add_fragment (nat_reass_ip6_t * reass, u32 bi,
-                           u32 ** bi_to_drop)
+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;
@@ -548,7 +605,7 @@ nat_ip6_reass_add_fragment (nat_reass_ip6_t * reass, u32 bi,
 
   if (reass->frag_n >= srm->ip6_max_frag)
     {
-      nat_ipfix_logging_max_fragments_ip6 (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);
@@ -724,12 +781,51 @@ 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);
 
-  vlib_cli_output (vm, "  src %U dst %U proto %u id 0x%04x cached %u",
+  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);
+                  clib_net_to_host_u16 (reass->key.frag_id), reass->frag_n,
+                  flags_str, classify_next_str);
+
+  vec_free (flags_str);
 
   return 0;
 }