NAT44 segv on unknown proto on inside interface
[vpp.git] / src / plugins / nat / in2out.c
index 7d9d6c3..3ec65e8 100755 (executable)
@@ -1217,34 +1217,37 @@ snat_in2out_unknown_proto (snat_main_t *sm,
       else
         {
           /* Choose same out address as for TCP/UDP session to same destination */
-          if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
+          head_index = u->sessions_per_user_list_head_index;
+          head = pool_elt_at_index (tsm->list_pool, head_index);
+          elt_index = head->next;
+         if (PREDICT_FALSE (elt_index == ~0))
+           ses_index = ~0;
+         else
+           {
+             elt = pool_elt_at_index (tsm->list_pool, elt_index);
+             ses_index = elt->value;
+           }
+
+          while (ses_index != ~0)
             {
-              head_index = u->sessions_per_user_list_head_index;
-              head = pool_elt_at_index (tsm->list_pool, head_index);
-              elt_index = head->next;
+              s =  pool_elt_at_index (tsm->sessions, ses_index);
+              elt_index = elt->next;
               elt = pool_elt_at_index (tsm->list_pool, elt_index);
               ses_index = elt->value;
-              while (ses_index != ~0)
-                {
-                  s =  pool_elt_at_index (tsm->sessions, ses_index);
-                  elt_index = elt->next;
-                  elt = pool_elt_at_index (tsm->list_pool, elt_index);
-                  ses_index = elt->value;
 
-                  if (s->ext_host_addr.as_u32 == ip->dst_address.as_u32)
-                    {
-                      new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32;
-                      address_index = s->outside_address_index;
+              if (s->ext_host_addr.as_u32 == ip->dst_address.as_u32)
+                {
+                  new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32;
+                  address_index = s->outside_address_index;
 
-                      key.fib_index = sm->outside_fib_index;
-                      key.l_addr.as_u32 = new_addr;
-                      s_kv.key[0] = key.as_u64[0];
-                      s_kv.key[1] = key.as_u64[1];
-                      if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
-                        break;
+                  key.fib_index = sm->outside_fib_index;
+                  key.l_addr.as_u32 = new_addr;
+                  s_kv.key[0] = key.as_u64[0];
+                  s_kv.key[1] = key.as_u64[1];
+                  if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
+                    break;
 
-                      goto create_ses;
-                    }
+                  goto create_ses;
                 }
             }
           key.fib_index = sm->outside_fib_index;
@@ -1273,6 +1276,7 @@ create_ses:
 
       s->ext_host_addr.as_u32 = ip->dst_address.as_u32;
       s->flags |= SNAT_SESSION_FLAG_UNKNOWN_PROTO;
+      s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
       s->outside_address_index = address_index;
       s->out2in.addr.as_u32 = new_addr;
       s->out2in.fib_index = sm->outside_fib_index;
@@ -1402,6 +1406,7 @@ snat_in2out_lb (snat_main_t *sm,
       s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
       if (lb)
         s->flags |= SNAT_SESSION_FLAG_LOAD_BALANCING;
+      s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
       s->outside_address_index = ~0;
       s->in2out = l_key;
       s->out2in = e_key;