nat: more long read after short write optimization 00/27400/5
authorKlement Sekera <ksekera@cisco.com>
Tue, 19 May 2020 17:47:23 +0000 (17:47 +0000)
committerOle Trøan <otroan@employees.org>
Mon, 8 Jun 2020 13:46:35 +0000 (13:46 +0000)
Replace whitespread (mis)use of snat_session_key_t by proper function
arguments where applicable and inline functions to calculate hash keys
instead of using structs for that. Make all hash tables use same network
byte order port so that there is no longer a discrepancy between static
mappings using host byte order while in2out/out2in tables using network
byte order.

Type: improvement
Signed-off-by: Klement Sekera <ksekera@cisco.com>
Change-Id: I80786d2f947c67824c101a13bb608f1fe1080f34

15 files changed:
src/plugins/nat/in2out.c
src/plugins/nat/in2out_ed.c
src/plugins/nat/nat.c
src/plugins/nat/nat.h
src/plugins/nat/nat44_classify.c
src/plugins/nat/nat44_cli.c
src/plugins/nat/nat44_hairpinning.c
src/plugins/nat/nat64.c
src/plugins/nat/nat_api.c
src/plugins/nat/nat_det_in2out.c
src/plugins/nat/nat_det_out2in.c
src/plugins/nat/nat_format.c
src/plugins/nat/nat_inlines.h
src/plugins/nat/out2in.c
src/plugins/nat/out2in_ed.c

index 0c52e50..0d70271 100644 (file)
@@ -126,14 +126,10 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
                    u32 rx_fib_index0, u32 thread_index)
 {
   udp_header_t *udp0 = ip4_next_header (ip0);
                    u32 rx_fib_index0, u32 thread_index)
 {
   udp_header_t *udp0 = ip4_next_header (ip0);
-  snat_session_key_t key0, sm0;
   clib_bihash_kv_8_8_t kv0, value0;
 
   clib_bihash_kv_8_8_t kv0, value0;
 
-  key0.addr = ip0->dst_address;
-  key0.port = udp0->dst_port;
-  key0.protocol = proto0;
-  key0.fib_index = sm->outside_fib_index;
-  kv0.key = key0.as_u64;
+  init_nat_k (&kv0, ip0->dst_address, udp0->dst_port, sm->outside_fib_index,
+             proto0);
 
   /* NAT packet aimed at external address if */
   /* has active sessions */
 
   /* NAT packet aimed at external address if */
   /* has active sessions */
@@ -141,7 +137,13 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
                              &value0))
     {
       /* or is static mappings */
                              &value0))
     {
       /* or is static mappings */
-      if (!snat_static_mapping_match (sm, key0, &sm0, 1, 0, 0, 0, 0, 0))
+      ip4_address_t dummy_addr;
+      u16 dummy_port;
+      u32 dummy_fib_index;
+      if (!snat_static_mapping_match
+         (sm, ip0->dst_address, udp0->dst_port, sm->outside_fib_index,
+          proto0, &dummy_addr, &dummy_port, &dummy_fib_index, 1, 0, 0, 0, 0,
+          0))
        return 0;
     }
   else
        return 0;
     }
   else
@@ -159,26 +161,20 @@ nat_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip0,
                                  u32 proto0, u16 src_port, u16 dst_port,
                                  u32 thread_index, u32 sw_if_index)
 {
                                  u32 proto0, u16 src_port, u16 dst_port,
                                  u32 thread_index, u32 sw_if_index)
 {
-  snat_session_key_t key0;
   clib_bihash_kv_8_8_t kv0, value0;
   snat_interface_t *i;
 
   /* src NAT check */
   clib_bihash_kv_8_8_t kv0, value0;
   snat_interface_t *i;
 
   /* src NAT check */
-  key0.addr = ip0->src_address;
-  key0.port = src_port;
-  key0.protocol = proto0;
-  key0.fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
-  kv0.key = key0.as_u64;
+  init_nat_k (&kv0, ip0->src_address, src_port,
+             ip4_fib_table_get_index_for_sw_if_index (sw_if_index), proto0);
 
   if (!clib_bihash_search_8_8
       (&sm->per_thread_data[thread_index].out2in, &kv0, &value0))
     return 1;
 
   /* dst NAT check */
 
   if (!clib_bihash_search_8_8
       (&sm->per_thread_data[thread_index].out2in, &kv0, &value0))
     return 1;
 
   /* dst NAT check */
-  key0.addr = ip0->dst_address;
-  key0.port = dst_port;
-  key0.protocol = proto0;
-  kv0.key = key0.as_u64;
+  init_nat_k (&kv0, ip0->dst_address, dst_port,
+             ip4_fib_table_get_index_for_sw_if_index (sw_if_index), proto0);
   if (!clib_bihash_search_8_8
       (&sm->per_thread_data[thread_index].in2out, &kv0, &value0))
     {
   if (!clib_bihash_search_8_8
       (&sm->per_thread_data[thread_index].in2out, &kv0, &value0))
     {
@@ -212,30 +208,30 @@ nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
   sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s);
   if (ctx->now >= sess_timeout_time)
     {
   sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s);
   if (ctx->now >= sess_timeout_time)
     {
-      s_kv.key = s->out2in.as_u64;
+      init_nat_o2i_k (&s_kv, s);
       if (clib_bihash_add_del_8_8 (&tsm->out2in, &s_kv, 0))
        nat_elog_warn ("out2in key del failed");
 
       snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
       if (clib_bihash_add_del_8_8 (&tsm->out2in, &s_kv, 0))
        nat_elog_warn ("out2in key del failed");
 
       snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
-                                          s->in2out.protocol,
+                                          s->nat_proto,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
 
       nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
                               &s->in2out.addr, s->in2out.port,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
 
       nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
                               &s->in2out.addr, s->in2out.port,
-                              &s->out2in.addr, s->out2in.port,
-                              s->in2out.protocol);
+                              &s->out2in.addr, s->out2in.port, s->nat_proto);
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
-                  s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
+                  s->ext_host_port, s->nat_proto, s->out2in.fib_index,
                   ctx->thread_index);
 
       if (!snat_is_session_static (s))
        snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
                   ctx->thread_index);
 
       if (!snat_is_session_static (s))
        snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
-                                           &s->out2in);
+                                           &s->out2in.addr,
+                                           s->out2in.port, s->nat_proto);
 
       nat44_delete_session (sm, s, ctx->thread_index);
       return 1;
 
       nat44_delete_session (sm, s, ctx->thread_index);
       return 1;
@@ -248,15 +244,16 @@ nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
 static u32
 slow_path (snat_main_t * sm, vlib_buffer_t * b0,
           ip4_header_t * ip0,
 static u32
 slow_path (snat_main_t * sm, vlib_buffer_t * b0,
           ip4_header_t * ip0,
+          ip4_address_t i2o_addr,
+          u16 i2o_port,
           u32 rx_fib_index0,
           u32 rx_fib_index0,
-          snat_session_key_t * key0,
+          nat_protocol_t nat_proto,
           snat_session_t ** sessionp,
           vlib_node_runtime_t * node, u32 next0, u32 thread_index, f64 now)
 {
   snat_user_t *u;
   snat_session_t *s = 0;
   clib_bihash_kv_8_8_t kv0;
           snat_session_t ** sessionp,
           vlib_node_runtime_t * node, u32 next0, u32 thread_index, f64 now)
 {
   snat_user_t *u;
   snat_session_t *s = 0;
   clib_bihash_kv_8_8_t kv0;
-  snat_session_key_t key1;
   u8 is_sm = 0;
   nat_outside_fib_t *outside_fib;
   fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
   u8 is_sm = 0;
   nat_outside_fib_t *outside_fib;
   fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
@@ -269,6 +266,9 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
                },
   };
   nat44_is_idle_session_ctx_t ctx0;
                },
   };
   nat44_is_idle_session_ctx_t ctx0;
+  ip4_address_t sm_addr;
+  u16 sm_port;
+  u32 sm_fib_index;
 
   if (PREDICT_FALSE (nat44_maximum_sessions_exceeded (sm, thread_index)))
     {
 
   if (PREDICT_FALSE (nat44_maximum_sessions_exceeded (sm, thread_index)))
     {
@@ -278,15 +278,16 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
       return SNAT_IN2OUT_NEXT_DROP;
     }
 
       return SNAT_IN2OUT_NEXT_DROP;
     }
 
-  key1.protocol = key0->protocol;
-
   /* First try to match static mapping by local address and port */
   if (snat_static_mapping_match
   /* First try to match static mapping by local address and port */
   if (snat_static_mapping_match
-      (sm, *key0, &key1, 0, 0, 0, 0, 0, &identity_nat))
+      (sm, i2o_addr, i2o_port, rx_fib_index0, nat_proto, &sm_addr,
+       &sm_port, &sm_fib_index, 0, 0, 0, 0, 0, &identity_nat))
     {
       /* Try to create dynamic translation */
       if (snat_alloc_outside_address_and_port (sm->addresses, rx_fib_index0,
     {
       /* Try to create dynamic translation */
       if (snat_alloc_outside_address_and_port (sm->addresses, rx_fib_index0,
-                                              thread_index, &key1,
+                                              thread_index,
+                                              nat_proto,
+                                              &sm_addr, &sm_port,
                                               sm->port_per_thread,
                                               sm->per_thread_data
                                               [thread_index].snat_thread_index))
                                               sm->port_per_thread,
                                               sm->per_thread_data
                                               [thread_index].snat_thread_index))
@@ -325,9 +326,12 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
   if (is_sm)
     s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
   user_session_increment (sm, u, is_sm);
   if (is_sm)
     s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
   user_session_increment (sm, u, is_sm);
-  s->in2out = *key0;
-  s->out2in = key1;
-  s->out2in.protocol = key0->protocol;
+  s->in2out.addr = i2o_addr;
+  s->in2out.port = i2o_port;
+  s->in2out.fib_index = rx_fib_index0;
+  s->nat_proto = nat_proto;
+  s->out2in.addr = sm_addr;
+  s->out2in.port = sm_port;
   s->out2in.fib_index = sm->outside_fib_index;
   switch (vec_len (sm->outside_fibs))
     {
   s->out2in.fib_index = sm->outside_fib_index;
   switch (vec_len (sm->outside_fibs))
     {
@@ -361,16 +365,13 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
   /* Add to translation hashes */
   ctx0.now = now;
   ctx0.thread_index = thread_index;
   /* Add to translation hashes */
   ctx0.now = now;
   ctx0.thread_index = thread_index;
-  kv0.key = s->in2out.as_u64;
-  kv0.value = s - sm->per_thread_data[thread_index].sessions;
+  init_nat_i2o_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions);
   if (clib_bihash_add_or_overwrite_stale_8_8
       (&sm->per_thread_data[thread_index].in2out, &kv0,
        nat44_i2o_is_idle_session_cb, &ctx0))
     nat_elog_notice ("in2out key add failed");
 
   if (clib_bihash_add_or_overwrite_stale_8_8
       (&sm->per_thread_data[thread_index].in2out, &kv0,
        nat44_i2o_is_idle_session_cb, &ctx0))
     nat_elog_notice ("in2out key add failed");
 
-  kv0.key = s->out2in.as_u64;
-  kv0.value = s - sm->per_thread_data[thread_index].sessions;
-
+  init_nat_o2i_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions);
   if (clib_bihash_add_or_overwrite_stale_8_8
       (&sm->per_thread_data[thread_index].out2in, &kv0,
        nat44_o2i_is_idle_session_cb, &ctx0))
   if (clib_bihash_add_or_overwrite_stale_8_8
       (&sm->per_thread_data[thread_index].out2in, &kv0,
        nat44_o2i_is_idle_session_cb, &ctx0))
@@ -380,30 +381,28 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
-                                      s->in2out.protocol,
+                                      s->nat_proto,
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
 
   nat_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index,
                           &s->in2out.addr, s->in2out.port, &s->out2in.addr,
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
 
   nat_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index,
                           &s->in2out.addr, s->in2out.port, &s->out2in.addr,
-                          s->out2in.port, s->in2out.protocol);
+                          s->out2in.port, s->nat_proto);
 
   nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
               s->out2in.port, &s->ext_host_addr, s->ext_host_port,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
 
   nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
               s->out2in.port, &s->ext_host_addr, s->ext_host_port,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
-              s->in2out.protocol, s->in2out.fib_index, s->flags,
-              thread_index, 0);
+              s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0);
 
   return next0;
 }
 
 #ifndef CLIB_MARCH_VARIANT
 
   return next0;
 }
 
 #ifndef CLIB_MARCH_VARIANT
-static_always_inline
-  snat_in2out_error_t icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
-                                   snat_session_key_t * p_key0)
+static_always_inline snat_in2out_error_t
+icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
+             ip4_address_t * addr, u16 * port, nat_protocol_t * nat_proto)
 {
   icmp46_header_t *icmp0;
 {
   icmp46_header_t *icmp0;
-  snat_session_key_t key0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0 = 0;
   void *l4_header = 0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0 = 0;
   void *l4_header = 0;
@@ -415,32 +414,31 @@ static_always_inline
   if (!icmp_type_is_error_message
       (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
     {
   if (!icmp_type_is_error_message
       (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
     {
-      key0.protocol = NAT_PROTOCOL_ICMP;
-      key0.addr = ip0->src_address;
-      key0.port = vnet_buffer (b)->ip.reass.l4_src_port;
+      *nat_proto = NAT_PROTOCOL_ICMP;
+      *addr = ip0->src_address;
+      *port = vnet_buffer (b)->ip.reass.l4_src_port;
     }
   else
     {
       inner_ip0 = (ip4_header_t *) (echo0 + 1);
       l4_header = ip4_next_header (inner_ip0);
     }
   else
     {
       inner_ip0 = (ip4_header_t *) (echo0 + 1);
       l4_header = ip4_next_header (inner_ip0);
-      key0.protocol = ip_proto_to_nat_proto (inner_ip0->protocol);
-      key0.addr = inner_ip0->dst_address;
-      switch (key0.protocol)
+      *nat_proto = ip_proto_to_nat_proto (inner_ip0->protocol);
+      *addr = inner_ip0->dst_address;
+      switch (*nat_proto)
        {
        case NAT_PROTOCOL_ICMP:
          inner_icmp0 = (icmp46_header_t *) l4_header;
          inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
        {
        case NAT_PROTOCOL_ICMP:
          inner_icmp0 = (icmp46_header_t *) l4_header;
          inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
-         key0.port = inner_echo0->identifier;
+         *port = inner_echo0->identifier;
          break;
        case NAT_PROTOCOL_UDP:
        case NAT_PROTOCOL_TCP:
          break;
        case NAT_PROTOCOL_UDP:
        case NAT_PROTOCOL_TCP:
-         key0.port = ((tcp_udp_header_t *) l4_header)->dst_port;
+         *port = ((tcp_udp_header_t *) l4_header)->dst_port;
          break;
        default:
          return SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL;
        }
     }
          break;
        default:
          return SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL;
        }
     }
-  *p_key0 = key0;
   return -1;                   /* success */
 }
 
   return -1;                   /* success */
 }
 
@@ -462,47 +460,40 @@ static_always_inline
 u32
 icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
                        u32 thread_index, vlib_buffer_t * b0,
 u32
 icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
                        u32 thread_index, vlib_buffer_t * b0,
-                       ip4_header_t * ip0, u8 * p_proto,
-                       snat_session_key_t * p_value,
-                       u8 * p_dont_translate, void *d, void *e)
+                       ip4_header_t * ip0, ip4_address_t * addr, u16 * port,
+                       u32 * fib_index, nat_protocol_t * proto, void *d,
+                       void *e, u8 * dont_translate)
 {
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   u32 sw_if_index0;
 {
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   u32 sw_if_index0;
-  u32 rx_fib_index0;
-  snat_session_key_t key0;
   snat_session_t *s0 = 0;
   snat_session_t *s0 = 0;
-  u8 dont_translate = 0;
   clib_bihash_kv_8_8_t kv0, value0;
   u32 next0 = ~0;
   int err;
   vlib_main_t *vm = vlib_get_main ();
   clib_bihash_kv_8_8_t kv0, value0;
   u32 next0 = ~0;
   int err;
   vlib_main_t *vm = vlib_get_main ();
+  *dont_translate = 0;
 
   sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
 
   sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
-  rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
+  *fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
 
 
-  err = icmp_get_key (b0, ip0, &key0);
+  err = icmp_get_key (b0, ip0, addr, port, proto);
   if (err != -1)
     {
       b0->error = node->errors[err];
       next0 = SNAT_IN2OUT_NEXT_DROP;
       goto out;
     }
   if (err != -1)
     {
       b0->error = node->errors[err];
       next0 = SNAT_IN2OUT_NEXT_DROP;
       goto out;
     }
-  key0.fib_index = rx_fib_index0;
-
-  kv0.key = key0.as_u64;
 
 
+  init_nat_k (&kv0, *addr, *port, *fib_index, *proto);
   if (clib_bihash_search_8_8 (&tsm->in2out, &kv0, &value0))
     {
       if (vnet_buffer (b0)->sw_if_index[VLIB_TX] != ~0)
        {
   if (clib_bihash_search_8_8 (&tsm->in2out, &kv0, &value0))
     {
       if (vnet_buffer (b0)->sw_if_index[VLIB_TX] != ~0)
        {
-         if (PREDICT_FALSE (nat_not_translate_output_feature (sm, ip0,
-                                                              key0.protocol,
-                                                              key0.port,
-                                                              key0.port,
-                                                              thread_index,
-                                                              sw_if_index0)))
+         if (PREDICT_FALSE
+             (nat_not_translate_output_feature
+              (sm, ip0, *proto, *port, *port, thread_index, sw_if_index0)))
            {
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
              goto out;
            }
        }
@@ -510,10 +501,9 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
        {
          if (PREDICT_FALSE (snat_not_translate (sm, node, sw_if_index0,
                                                 ip0, NAT_PROTOCOL_ICMP,
        {
          if (PREDICT_FALSE (snat_not_translate (sm, node, sw_if_index0,
                                                 ip0, NAT_PROTOCOL_ICMP,
-                                                rx_fib_index0,
-                                                thread_index)))
+                                                *fib_index, thread_index)))
            {
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
              goto out;
            }
        }
@@ -527,15 +517,16 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
          goto out;
        }
 
          goto out;
        }
 
-      next0 = slow_path (sm, b0, ip0, rx_fib_index0, &key0, &s0, node, next0,
-                        thread_index, vlib_time_now (vm));
+      next0 =
+       slow_path (sm, b0, ip0, *addr, *port, *fib_index, *proto, &s0, node,
+                  next0, thread_index, vlib_time_now (vm));
 
       if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
        goto out;
 
       if (!s0)
        {
 
       if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
        goto out;
 
       if (!s0)
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
     }
          goto out;
        }
     }
@@ -558,12 +549,14 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 
 out:
     }
 
 out:
-  *p_proto = key0.protocol;
   if (s0)
   if (s0)
-    *p_value = s0->out2in;
-  *p_dont_translate = dont_translate;
+    {
+      *addr = s0->out2in.addr;
+      *port = s0->out2in.port;
+      *fib_index = s0->out2in.fib_index;
+    }
   if (d)
   if (d)
-    *(snat_session_t **) d = s0;
+    *(snat_session_t **) (d) = s0;
   return next0;
 }
 #endif
   return next0;
 }
 #endif
@@ -586,39 +579,40 @@ out:
 u32
 icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node,
                        u32 thread_index, vlib_buffer_t * b0,
 u32
 icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node,
                        u32 thread_index, vlib_buffer_t * b0,
-                       ip4_header_t * ip0, u8 * p_proto,
-                       snat_session_key_t * p_value,
-                       u8 * p_dont_translate, void *d, void *e)
+                       ip4_header_t * ip0, ip4_address_t * addr, u16 * port,
+                       u32 * fib_index, nat_protocol_t * proto, void *d,
+                       void *e, u8 * dont_translate)
 {
   u32 sw_if_index0;
 {
   u32 sw_if_index0;
-  u32 rx_fib_index0;
-  snat_session_key_t key0;
-  snat_session_key_t sm0;
-  u8 dont_translate = 0;
   u8 is_addr_only;
   u32 next0 = ~0;
   int err;
   u8 is_addr_only;
   u32 next0 = ~0;
   int err;
+  *dont_translate = 0;
 
   sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
 
   sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
-  rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
+  *fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
 
 
-  err = icmp_get_key (b0, ip0, &key0);
+  err = icmp_get_key (b0, ip0, addr, port, proto);
   if (err != -1)
     {
       b0->error = node->errors[err];
       next0 = SNAT_IN2OUT_NEXT_DROP;
   if (err != -1)
     {
       b0->error = node->errors[err];
       next0 = SNAT_IN2OUT_NEXT_DROP;
-      goto out2;
+      goto out;
     }
     }
-  key0.fib_index = rx_fib_index0;
+
+  ip4_address_t sm_addr;
+  u16 sm_port;
+  u32 sm_fib_index;
 
   if (snat_static_mapping_match
 
   if (snat_static_mapping_match
-      (sm, key0, &sm0, 0, &is_addr_only, 0, 0, 0, 0))
+      (sm, *addr, *port, *fib_index, *proto, &sm_addr, &sm_port,
+       &sm_fib_index, 0, &is_addr_only, 0, 0, 0, 0))
     {
       if (PREDICT_FALSE (snat_not_translate_fast (sm, node, sw_if_index0, ip0,
                                                  IP_PROTOCOL_ICMP,
     {
       if (PREDICT_FALSE (snat_not_translate_fast (sm, node, sw_if_index0, ip0,
                                                  IP_PROTOCOL_ICMP,
-                                                 rx_fib_index0)))
+                                                 *fib_index)))
        {
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
 
          goto out;
        }
 
@@ -647,10 +641,6 @@ icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 
 out:
     }
 
 out:
-  *p_value = sm0;
-out2:
-  *p_proto = key0.protocol;
-  *p_dont_translate = dont_translate;
   return next0;
 }
 #endif
   return next0;
 }
 #endif
@@ -667,8 +657,10 @@ icmp_in2out (snat_main_t * sm,
             u32 next0, u32 thread_index, void *d, void *e)
 {
   vlib_main_t *vm = vlib_get_main ();
             u32 next0, u32 thread_index, void *d, void *e)
 {
   vlib_main_t *vm = vlib_get_main ();
-  snat_session_key_t sm0;
-  u8 protocol;
+  ip4_address_t addr;
+  u16 port;
+  u32 fib_index;
+  nat_protocol_t protocol;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0;
   void *l4_header = 0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0;
   void *l4_header = 0;
@@ -683,9 +675,9 @@ icmp_in2out (snat_main_t * sm,
 
   echo0 = (icmp_echo_header_t *) (icmp0 + 1);
 
 
   echo0 = (icmp_echo_header_t *) (icmp0 + 1);
 
-  next0_tmp = sm->icmp_match_in2out_cb (sm, node, thread_index, b0, ip0,
-                                       &protocol, &sm0, &dont_translate, d,
-                                       e);
+  next0_tmp =
+    sm->icmp_match_in2out_cb (sm, node, thread_index, b0, ip0, &addr, &port,
+                             &fib_index, &protocol, d, e, &dont_translate);
   if (next0_tmp != ~0)
     next0 = next0_tmp;
   if (next0 == SNAT_IN2OUT_NEXT_DROP || dont_translate)
   if (next0_tmp != ~0)
     next0 = next0_tmp;
   if (next0 == SNAT_IN2OUT_NEXT_DROP || dont_translate)
@@ -708,7 +700,7 @@ icmp_in2out (snat_main_t * sm,
     }
 
   old_addr0 = ip0->src_address.as_u32;
     }
 
   old_addr0 = ip0->src_address.as_u32;
-  new_addr0 = ip0->src_address.as_u32 = sm0.addr.as_u32;
+  new_addr0 = ip0->src_address.as_u32 = addr.as_u32;
 
   sum0 = ip0->checksum;
   sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
 
   sum0 = ip0->checksum;
   sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
@@ -722,11 +714,11 @@ icmp_in2out (snat_main_t * sm,
 
       if (!icmp_type_is_error_message (icmp0->type))
        {
 
       if (!icmp_type_is_error_message (icmp0->type))
        {
-         new_id0 = sm0.port;
+         new_id0 = port;
          if (PREDICT_FALSE (new_id0 != echo0->identifier))
            {
              old_id0 = echo0->identifier;
          if (PREDICT_FALSE (new_id0 != echo0->identifier))
            {
              old_id0 = echo0->identifier;
-             new_id0 = sm0.port;
+             new_id0 = port;
              echo0->identifier = new_id0;
 
              sum0 = icmp0->checksum;
              echo0->identifier = new_id0;
 
              sum0 = icmp0->checksum;
@@ -749,7 +741,7 @@ icmp_in2out (snat_main_t * sm,
 
          /* update inner destination IP address */
          old_addr0 = inner_ip0->dst_address.as_u32;
 
          /* update inner destination IP address */
          old_addr0 = inner_ip0->dst_address.as_u32;
-         inner_ip0->dst_address = sm0.addr;
+         inner_ip0->dst_address = addr;
          new_addr0 = inner_ip0->dst_address.as_u32;
          sum0 = icmp0->checksum;
          sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
          new_addr0 = inner_ip0->dst_address.as_u32;
          sum0 = icmp0->checksum;
          sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
@@ -776,7 +768,7 @@ icmp_in2out (snat_main_t * sm,
              inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
 
              old_id0 = inner_echo0->identifier;
              inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
 
              old_id0 = inner_echo0->identifier;
-             new_id0 = sm0.port;
+             new_id0 = port;
              inner_echo0->identifier = new_id0;
 
              sum0 = icmp0->checksum;
              inner_echo0->identifier = new_id0;
 
              sum0 = icmp0->checksum;
@@ -788,7 +780,7 @@ icmp_in2out (snat_main_t * sm,
            case NAT_PROTOCOL_UDP:
            case NAT_PROTOCOL_TCP:
              old_id0 = ((tcp_udp_header_t *) l4_header)->dst_port;
            case NAT_PROTOCOL_UDP:
            case NAT_PROTOCOL_TCP:
              old_id0 = ((tcp_udp_header_t *) l4_header)->dst_port;
-             new_id0 = sm0.port;
+             new_id0 = port;
              ((tcp_udp_header_t *) l4_header)->dst_port = new_id0;
 
              sum0 = icmp0->checksum;
              ((tcp_udp_header_t *) l4_header)->dst_port = new_id0;
 
              sum0 = icmp0->checksum;
@@ -807,7 +799,7 @@ icmp_in2out (snat_main_t * sm,
       if (sm->deterministic ||
          0 != snat_icmp_hairpinning (sm, b0, ip0, icmp0,
                                      sm->endpoint_dependent))
       if (sm->deterministic ||
          0 != snat_icmp_hairpinning (sm, b0, ip0, icmp0,
                                      sm->endpoint_dependent))
-       vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index;
+       vnet_buffer (b0)->sw_if_index[VLIB_TX] = fib_index;
     }
 
 out:
     }
 
 out:
@@ -850,15 +842,10 @@ nat_in2out_sm_unknown_proto (snat_main_t * sm,
 {
   clib_bihash_kv_8_8_t kv, value;
   snat_static_mapping_t *m;
 {
   clib_bihash_kv_8_8_t kv, value;
   snat_static_mapping_t *m;
-  snat_session_key_t m_key;
   u32 old_addr, new_addr;
   ip_csum_t sum;
 
   u32 old_addr, new_addr;
   ip_csum_t sum;
 
-  m_key.addr = ip->src_address;
-  m_key.port = 0;
-  m_key.protocol = 0;
-  m_key.fib_index = rx_fib_index;
-  kv.key = m_key.as_u64;
+  init_nat_k (&kv, ip->src_address, 0, rx_fib_index, 0);
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value))
     return 1;
 
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value))
     return 1;
 
@@ -923,7 +910,6 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
          udp_header_t *udp0, *udp1;
          tcp_header_t *tcp0, *tcp1;
          icmp46_header_t *icmp0, *icmp1;
          udp_header_t *udp0, *udp1;
          tcp_header_t *tcp0, *tcp1;
          icmp46_header_t *icmp0, *icmp1;
-         snat_session_key_t key0, key1;
          u32 rx_fib_index0, rx_fib_index1;
          u32 proto0, proto1;
          snat_session_t *s0 = 0, *s1 = 0;
          u32 rx_fib_index0, rx_fib_index1;
          u32 proto0, proto1;
          snat_session_t *s0 = 0, *s1 = 0;
@@ -1023,13 +1009,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                }
            }
 
                }
            }
 
-         key0.addr = ip0->src_address;
-         key0.port = vnet_buffer (b0)->ip.reass.l4_src_port;
-         key0.protocol = proto0;
-         key0.fib_index = rx_fib_index0;
-
-         kv0.key = key0.as_u64;
-
+         init_nat_k (&kv0, ip0->src_address,
+                     vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0,
+                     proto0);
          if (PREDICT_FALSE
              (clib_bihash_search_8_8
               (&sm->per_thread_data[thread_index].in2out, &kv0,
          if (PREDICT_FALSE
              (clib_bihash_search_8_8
               (&sm->per_thread_data[thread_index].in2out, &kv0,
@@ -1068,7 +1050,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                        goto trace00;
                    }
 
                        goto trace00;
                    }
 
-                 next0 = slow_path (sm, b0, ip0, rx_fib_index0, &key0,
+                 next0 = slow_path (sm, b0, ip0,
+                                    ip0->src_address,
+                                    vnet_buffer (b0)->ip.reass.l4_src_port,
+                                    rx_fib_index0,
+                                    proto0,
                                     &s0, node, next0, thread_index, now);
                  if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
                    goto trace00;
                                     &s0, node, next0, thread_index, now);
                  if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
                    goto trace00;
@@ -1232,13 +1218,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                }
            }
 
                }
            }
 
-         key1.addr = ip1->src_address;
-         key1.port = vnet_buffer (b1)->ip.reass.l4_src_port;
-         key1.protocol = proto1;
-         key1.fib_index = rx_fib_index1;
-
-         kv1.key = key1.as_u64;
-
+         init_nat_k (&kv1, ip1->src_address,
+                     vnet_buffer (b1)->ip.reass.l4_src_port, rx_fib_index1,
+                     proto1);
          if (PREDICT_FALSE
              (clib_bihash_search_8_8
               (&sm->per_thread_data[thread_index].in2out, &kv1,
          if (PREDICT_FALSE
              (clib_bihash_search_8_8
               (&sm->per_thread_data[thread_index].in2out, &kv1,
@@ -1277,8 +1259,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                        goto trace01;
                    }
 
                        goto trace01;
                    }
 
-                 next1 = slow_path (sm, b1, ip1, rx_fib_index1, &key1,
-                                    &s1, node, next1, thread_index, now);
+                 next1 =
+                   slow_path (sm, b1, ip1, ip1->src_address,
+                              vnet_buffer (b1)->ip.reass.l4_src_port,
+                              rx_fib_index1, proto1, &s1, node, next1,
+                              thread_index, now);
                  if (PREDICT_FALSE (next1 == SNAT_IN2OUT_NEXT_DROP))
                    goto trace01;
 
                  if (PREDICT_FALSE (next1 == SNAT_IN2OUT_NEXT_DROP))
                    goto trace01;
 
@@ -1392,7 +1377,6 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
          udp_header_t *udp0;
          tcp_header_t *tcp0;
          icmp46_header_t *icmp0;
          udp_header_t *udp0;
          tcp_header_t *tcp0;
          icmp46_header_t *icmp0;
-         snat_session_key_t key0;
          u32 rx_fib_index0;
          u32 proto0;
          snat_session_t *s0 = 0;
          u32 rx_fib_index0;
          u32 proto0;
          snat_session_t *s0 = 0;
@@ -1476,12 +1460,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                }
            }
 
                }
            }
 
-         key0.addr = ip0->src_address;
-         key0.port = vnet_buffer (b0)->ip.reass.l4_src_port;
-         key0.protocol = proto0;
-         key0.fib_index = rx_fib_index0;
-
-         kv0.key = key0.as_u64;
+         init_nat_k (&kv0, ip0->src_address,
+                     vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0,
+                     proto0);
 
          if (clib_bihash_search_8_8
              (&sm->per_thread_data[thread_index].in2out, &kv0, &value0))
 
          if (clib_bihash_search_8_8
              (&sm->per_thread_data[thread_index].in2out, &kv0, &value0))
@@ -1519,7 +1500,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                        goto trace0;
                    }
 
                        goto trace0;
                    }
 
-                 next0 = slow_path (sm, b0, ip0, rx_fib_index0, &key0,
+                 next0 = slow_path (sm, b0, ip0,
+                                    ip0->src_address,
+                                    vnet_buffer (b0)->ip.reass.l4_src_port,
+                                    rx_fib_index0,
+                                    proto0,
                                     &s0, node, next0, thread_index, now);
 
                  if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
                                     &s0, node, next0, thread_index, now);
 
                  if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
@@ -1808,9 +1793,12 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
          udp_header_t *udp0;
          tcp_header_t *tcp0;
          icmp46_header_t *icmp0;
          udp_header_t *udp0;
          tcp_header_t *tcp0;
          icmp46_header_t *icmp0;
-         snat_session_key_t key0, sm0;
          u32 proto0;
          u32 rx_fib_index0;
          u32 proto0;
          u32 rx_fib_index0;
+         ip4_address_t sm0_addr;
+         u16 sm0_port;
+         u32 sm0_fib_index;
+
 
          /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
 
          /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
@@ -1854,21 +1842,18 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
              goto trace0;
            }
 
              goto trace0;
            }
 
-         key0.addr = ip0->src_address;
-         key0.protocol = proto0;
-         key0.port = udp0->src_port;
-         key0.fib_index = rx_fib_index0;
-
-         if (snat_static_mapping_match (sm, key0, &sm0, 0, 0, 0, 0, 0, 0))
+         if (snat_static_mapping_match
+             (sm, ip0->src_address, udp0->src_port, rx_fib_index0, proto0,
+              &sm0_addr, &sm0_port, &sm0_fib_index, 0, 0, 0, 0, 0, 0))
            {
              b0->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
              next0 = SNAT_IN2OUT_NEXT_DROP;
              goto trace0;
            }
 
            {
              b0->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
              next0 = SNAT_IN2OUT_NEXT_DROP;
              goto trace0;
            }
 
-         new_addr0 = sm0.addr.as_u32;
-         new_port0 = sm0.port;
-         vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index;
+         new_addr0 = sm0_addr.as_u32;
+         new_port0 = sm0_port;
+         vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0_fib_index;
          old_addr0 = ip0->src_address.as_u32;
          ip0->src_address.as_u32 = new_addr0;
 
          old_addr0 = ip0->src_address.as_u32;
          ip0->src_address.as_u32 = new_addr0;
 
index 54c866b..2e316f5 100644 (file)
@@ -81,7 +81,6 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
   clib_bihash_kv_16_8_t ed_kv;
   int i;
   snat_address_t *a;
   clib_bihash_kv_16_8_t ed_kv;
   int i;
   snat_address_t *a;
-  snat_session_key_t key;
   snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
                                                       ctx->thread_index);
 
   snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
                                                       ctx->thread_index);
 
@@ -104,12 +103,11 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
        }
       else
        {
        }
       else
        {
-         proto = nat_proto_to_ip_proto (s->in2out.protocol);
+         proto = nat_proto_to_ip_proto (s->nat_proto);
          l_port = s->out2in.port;
          r_port = s->ext_host_port;
        }
          l_port = s->out2in.port;
          r_port = s->ext_host_port;
        }
-      make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
-                 &ed_kv);
+      init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0))
        nat_elog_warn ("out2in_ed key del failed");
 
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0))
        nat_elog_warn ("out2in_ed key del failed");
 
@@ -119,7 +117,7 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
       snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
       snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
-                                          s->in2out.protocol,
+                                          s->nat_proto,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
@@ -129,24 +127,26 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
                             &s->ext_host_nat_addr, s->ext_host_nat_port,
                             &s->out2in.addr, s->out2in.port,
                             &s->ext_host_addr, s->ext_host_port,
                             &s->ext_host_nat_addr, s->ext_host_nat_port,
                             &s->out2in.addr, s->out2in.port,
                             &s->ext_host_addr, s->ext_host_port,
-                            s->in2out.protocol, is_twice_nat_session (s));
+                            s->nat_proto, is_twice_nat_session (s));
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
-                  s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
+                  s->ext_host_port, s->nat_proto, s->out2in.fib_index,
                   ctx->thread_index);
 
       if (is_twice_nat_session (s))
        {
          for (i = 0; i < vec_len (sm->twice_nat_addresses); i++)
            {
                   ctx->thread_index);
 
       if (is_twice_nat_session (s))
        {
          for (i = 0; i < vec_len (sm->twice_nat_addresses); i++)
            {
-             key.protocol = s->in2out.protocol;
-             key.port = s->ext_host_nat_port;
+             // TODO FIXME this is obviously broken - which address should be
+             // freed here?!
              a = sm->twice_nat_addresses + i;
              if (a->addr.as_u32 == s->ext_host_nat_addr.as_u32)
                {
                  snat_free_outside_address_and_port (sm->twice_nat_addresses,
                                                      ctx->thread_index,
              a = sm->twice_nat_addresses + i;
              if (a->addr.as_u32 == s->ext_host_nat_addr.as_u32)
                {
                  snat_free_outside_address_and_port (sm->twice_nat_addresses,
                                                      ctx->thread_index,
-                                                     &key);
+                                                     &s->ext_host_nat_addr,
+                                                     s->ext_host_nat_port,
+                                                     s->nat_proto);
                  break;
                }
            }
                  break;
                }
            }
@@ -156,7 +156,8 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
        goto delete;
 
       snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
        goto delete;
 
       snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
-                                         &s->out2in);
+                                         &s->out2in.addr, s->out2in.port,
+                                         s->nat_proto);
     delete:
       nat_ed_session_delete (sm, s, ctx->thread_index, 1);
       return 1;
     delete:
       nat_ed_session_delete (sm, s, ctx->thread_index, 1);
       return 1;
@@ -220,37 +221,38 @@ nat_ed_alloc_addr_and_port (snat_main_t * sm, u32 rx_fib_index,
       a = sm->addresses + i;
       switch (nat_proto)
        {
       a = sm->addresses + i;
       switch (nat_proto)
        {
-#define _(N, j, n, unused)                                                    \
+#define _(N, j, n, unused)                                                   \
   case NAT_PROTOCOL_##N:                                                     \
   case NAT_PROTOCOL_##N:                                                     \
-    if (a->fib_index == rx_fib_index)                                         \
-      {                                                                       \
-        u16 port = snat_random_port (1, port_per_thread);                     \
-        u16 attempts = port_per_thread;                                       \
-        while (attempts > 0)                                                  \
-          {                                                                   \
-            --attempts;                                                       \
-            portnum = port_thread_offset + port;                              \
-            make_ed_kv (&a->addr, &r_addr, proto, s->out2in.fib_index,        \
-                        clib_host_to_net_u16 (portnum), r_port, thread_index, \
-                        s - tsm->sessions, out2in_ed_kv);                     \
-            int rv = clib_bihash_add_del_16_8 (&sm->out2in_ed, out2in_ed_kv,  \
-                                               2 /* is_add */);               \
-            if (0 == rv)                                                      \
-              {                                                               \
-                ++a->busy_##n##_port_refcounts[portnum];                      \
-                a->busy_##n##_ports_per_thread[thread_index]++;               \
-                a->busy_##n##_ports++;                                        \
-                *allocated_addr = a->addr;                                    \
-                *allocated_port = clib_host_to_net_u16 (portnum);             \
-                return 0;                                                     \
-              }                                                               \
-            port = (port + 1) % port_per_thread;                              \
-          }                                                                   \
-      }                                                                       \
-    else if (a->fib_index == ~0)                                              \
-      {                                                                       \
-        ga = a;                                                               \
-      }                                                                       \
+    if (a->fib_index == rx_fib_index)                                        \
+      {                                                                      \
+        u16 port = snat_random_port (1, port_per_thread);                    \
+        u16 attempts = port_per_thread;                                      \
+        while (attempts > 0)                                                 \
+          {                                                                  \
+            --attempts;                                                      \
+            portnum = port_thread_offset + port;                             \
+            init_ed_kv (out2in_ed_kv, a->addr,                               \
+                        clib_host_to_net_u16 (portnum), r_addr, r_port,      \
+                        s->out2in.fib_index, proto, thread_index,            \
+                        s - tsm->sessions);                                  \
+            int rv = clib_bihash_add_del_16_8 (&sm->out2in_ed, out2in_ed_kv, \
+                                               2 /* is_add */);              \
+            if (0 == rv)                                                     \
+              {                                                              \
+                ++a->busy_##n##_port_refcounts[portnum];                     \
+                a->busy_##n##_ports_per_thread[thread_index]++;              \
+                a->busy_##n##_ports++;                                       \
+                *allocated_addr = a->addr;                                   \
+                *allocated_port = clib_host_to_net_u16 (portnum);            \
+                return 0;                                                    \
+              }                                                              \
+            port = (port + 1) % port_per_thread;                             \
+          }                                                                  \
+      }                                                                      \
+    else if (a->fib_index == ~0)                                             \
+      {                                                                      \
+        ga = a;                                                              \
+      }                                                                      \
     break;
 
          foreach_nat_protocol;
     break;
 
          foreach_nat_protocol;
@@ -321,14 +323,11 @@ slow_path_ed (snat_main_t * sm,
              snat_session_t ** sessionp,
              vlib_node_runtime_t * node, u32 next, u32 thread_index, f64 now)
 {
              snat_session_t ** sessionp,
              vlib_node_runtime_t * node, u32 next, u32 thread_index, f64 now)
 {
-
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   clib_bihash_kv_16_8_t out2in_ed_kv;
   nat44_is_idle_session_ctx_t ctx;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   clib_bihash_kv_16_8_t out2in_ed_kv;
   nat44_is_idle_session_ctx_t ctx;
-  snat_session_key_t key0, key1;
   ip4_address_t allocated_addr;
   u16 allocated_port;
   ip4_address_t allocated_addr;
   u16 allocated_port;
-  u32 tx_fib_index;
   u8 identity_nat;
 
   u32 nat_proto = ip_proto_to_nat_proto (proto);
   u8 identity_nat;
 
   u32 nat_proto = ip_proto_to_nat_proto (proto);
@@ -358,16 +357,13 @@ slow_path_ed (snat_main_t * sm,
        }
     }
 
        }
     }
 
-  key0.addr = l_addr;
-  key0.port = l_port;
-  key1.protocol = key0.protocol = nat_proto;
-  key0.fib_index = rx_fib_index;
-  key1.fib_index = sm->outside_fib_index;
-  tx_fib_index = sm->outside_fib_index;
-
+  ip4_address_t sm_addr;
+  u16 sm_port;
+  u32 sm_fib_index;
   /* First try to match static mapping by local address and port */
   if (snat_static_mapping_match
   /* First try to match static mapping by local address and port */
   if (snat_static_mapping_match
-      (sm, key0, &key1, 0, 0, 0, &lb, 0, &identity_nat))
+      (sm, l_addr, l_port, rx_fib_index, nat_proto, &sm_addr, &sm_port,
+       &sm_fib_index, 0, 0, 0, &lb, 0, &identity_nat))
     {
       s = nat_ed_session_alloc (sm, thread_index, now, proto);
       if (!s)
     {
       s = nat_ed_session_alloc (sm, thread_index, now, proto);
       if (!s)
@@ -376,20 +372,25 @@ slow_path_ed (snat_main_t * sm,
          b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED];
          return NAT_NEXT_DROP;
        }
          b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED];
          return NAT_NEXT_DROP;
        }
+      s->in2out.addr = l_addr;
+      s->in2out.port = l_port;
+      s->nat_proto = nat_proto;
+      s->in2out.fib_index = rx_fib_index;
+      s->out2in.fib_index = sm->outside_fib_index;
+
       switch (vec_len (sm->outside_fibs))
        {
        case 0:
       switch (vec_len (sm->outside_fibs))
        {
        case 0:
-         tx_fib_index = sm->outside_fib_index;
+         s->out2in.fib_index = sm->outside_fib_index;
          break;
        case 1:
          break;
        case 1:
-         tx_fib_index = sm->outside_fibs[0].fib_index;
+         s->out2in.fib_index = sm->outside_fibs[0].fib_index;
          break;
        default:
          break;
        default:
-         tx_fib_index = nat_outside_fib_index_lookup (sm, r_addr);
+         s->out2in.fib_index = nat_outside_fib_index_lookup (sm, r_addr);
          break;
        }
 
          break;
        }
 
-      s->out2in.fib_index = tx_fib_index;
       /* Try to create dynamic translation */
       if (nat_ed_alloc_addr_and_port (sm, rx_fib_index, nat_proto,
                                      thread_index, r_addr, r_port, proto,
       /* Try to create dynamic translation */
       if (nat_ed_alloc_addr_and_port (sm, rx_fib_index, nat_proto,
                                      thread_index, r_addr, r_port, proto,
@@ -403,14 +404,14 @@ slow_path_ed (snat_main_t * sm,
          nat_ed_session_delete (sm, s, thread_index, 1);
          return NAT_NEXT_DROP;
        }
          nat_ed_session_delete (sm, s, thread_index, 1);
          return NAT_NEXT_DROP;
        }
-      key1.addr = allocated_addr;
-      key1.port = allocated_port;
+      s->out2in.addr = allocated_addr;
+      s->out2in.port = allocated_port;
     }
   else
     {
       if (PREDICT_FALSE (identity_nat))
        {
     }
   else
     {
       if (PREDICT_FALSE (identity_nat))
        {
-         *sessionp = s;
+         *sessionp = NULL;
          return next;
        }
       s = nat_ed_session_alloc (sm, thread_index, now, proto);
          return next;
        }
       s = nat_ed_session_alloc (sm, thread_index, now, proto);
@@ -420,25 +421,31 @@ slow_path_ed (snat_main_t * sm,
          b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED];
          return NAT_NEXT_DROP;
        }
          b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED];
          return NAT_NEXT_DROP;
        }
+      s->out2in.addr = sm_addr;
+      s->out2in.port = sm_port;
+      s->in2out.addr = l_addr;
+      s->in2out.port = l_port;
+      s->nat_proto = nat_proto;
+      s->in2out.fib_index = rx_fib_index;
+      s->out2in.fib_index = sm->outside_fib_index;
       switch (vec_len (sm->outside_fibs))
        {
        case 0:
       switch (vec_len (sm->outside_fibs))
        {
        case 0:
-         tx_fib_index = sm->outside_fib_index;
+         s->out2in.fib_index = sm->outside_fib_index;
          break;
        case 1:
          break;
        case 1:
-         tx_fib_index = sm->outside_fibs[0].fib_index;
+         s->out2in.fib_index = sm->outside_fibs[0].fib_index;
          break;
        default:
          break;
        default:
-         tx_fib_index = nat_outside_fib_index_lookup (sm, r_addr);
+         s->out2in.fib_index = nat_outside_fib_index_lookup (sm, r_addr);
          break;
        }
 
          break;
        }
 
-      s->out2in.fib_index = tx_fib_index;
       s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
 
       s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
 
-      make_ed_kv (&key1.addr, &r_addr, proto,
-                 s->out2in.fib_index, key1.port, r_port, thread_index,
-                 s - tsm->sessions, &out2in_ed_kv);
+      init_ed_kv (&out2in_ed_kv, sm_addr, sm_port, r_addr, r_port,
+                 s->out2in.fib_index, proto, thread_index,
+                 s - tsm->sessions);
       if (clib_bihash_add_or_overwrite_stale_16_8
          (&sm->out2in_ed, &out2in_ed_kv, nat44_o2i_ed_is_idle_session_cb,
           &ctx))
       if (clib_bihash_add_or_overwrite_stale_16_8
          (&sm->out2in_ed, &out2in_ed_kv, nat44_o2i_ed_is_idle_session_cb,
           &ctx))
@@ -450,14 +457,10 @@ slow_path_ed (snat_main_t * sm,
   s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
   s->ext_host_addr = r_addr;
   s->ext_host_port = r_port;
   s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
   s->ext_host_addr = r_addr;
   s->ext_host_port = r_port;
-  s->in2out = key0;
-  s->out2in = key1;
-  s->out2in.fib_index = tx_fib_index;
-  s->out2in.protocol = key0.protocol;
 
   clib_bihash_kv_16_8_t in2out_ed_kv;
 
   clib_bihash_kv_16_8_t in2out_ed_kv;
-  make_ed_kv (&l_addr, &r_addr, proto, rx_fib_index, l_port, r_port,
-             thread_index, s - tsm->sessions, &in2out_ed_kv);
+  init_ed_kv (&in2out_ed_kv, l_addr, l_port, r_addr, r_port, rx_fib_index,
+             proto, thread_index, s - tsm->sessions);
   ctx.now = now;
   ctx.thread_index = thread_index;
   if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &in2out_ed_kv,
   ctx.now = now;
   ctx.thread_index = thread_index;
   if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &in2out_ed_kv,
@@ -471,7 +474,7 @@ slow_path_ed (snat_main_t * sm,
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
-                                      s->in2out.protocol,
+                                      s->nat_proto,
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
 
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
 
@@ -479,14 +482,13 @@ slow_path_ed (snat_main_t * sm,
                         &s->in2out.addr, s->in2out.port,
                         &s->ext_host_nat_addr, s->ext_host_nat_port,
                         &s->out2in.addr, s->out2in.port,
                         &s->in2out.addr, s->in2out.port,
                         &s->ext_host_nat_addr, s->ext_host_nat_port,
                         &s->out2in.addr, s->out2in.port,
-                        &s->ext_host_addr, s->ext_host_port,
-                        s->in2out.protocol, 0);
+                        &s->ext_host_addr, s->ext_host_port, s->nat_proto,
+                        0);
 
   nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
               s->out2in.port, &s->ext_host_addr, s->ext_host_port,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
 
   nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
               s->out2in.port, &s->ext_host_addr, s->ext_host_port,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
-              s->in2out.protocol, s->in2out.fib_index, s->flags,
-              thread_index, 0);
+              s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0);
 
   return next;
 }
 
   return next;
 }
@@ -498,21 +500,20 @@ nat44_ed_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
 {
   udp_header_t *udp = ip4_next_header (ip);
   clib_bihash_kv_16_8_t kv, value;
 {
   udp_header_t *udp = ip4_next_header (ip);
   clib_bihash_kv_16_8_t kv, value;
-  snat_session_key_t key0, key1;
 
 
-  make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
-             sm->outside_fib_index, udp->dst_port, udp->src_port, ~0, ~0,
-             &kv);
+  init_ed_k (&kv, ip->dst_address, udp->dst_port, ip->src_address,
+            udp->src_port, sm->outside_fib_index, ip->protocol);
 
   /* NAT packet aimed at external address if has active sessions */
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     {
 
   /* NAT packet aimed at external address if has active sessions */
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     {
-      key0.addr = ip->dst_address;
-      key0.port = udp->dst_port;
-      key0.protocol = proto;
-      key0.fib_index = sm->outside_fib_index;
       /* or is static mappings */
       /* or is static mappings */
-      if (!snat_static_mapping_match (sm, key0, &key1, 1, 0, 0, 0, 0, 0))
+      ip4_address_t dummy_addr;
+      u16 dummy_port;
+      u32 dummy_fib_index;
+      if (!snat_static_mapping_match
+         (sm, ip->dst_address, udp->dst_port, sm->outside_fib_index, proto,
+          &dummy_addr, &dummy_port, &dummy_fib_index, 1, 0, 0, 0, 0, 0))
        return 0;
     }
   else
        return 0;
     }
   else
@@ -544,14 +545,14 @@ nat_not_translate_output_feature_fwd (snat_main_t * sm, ip4_header_t * ip,
     }
   else if (ip->protocol == IP_PROTOCOL_UDP || ip->protocol == IP_PROTOCOL_TCP)
     {
     }
   else if (ip->protocol == IP_PROTOCOL_UDP || ip->protocol == IP_PROTOCOL_TCP)
     {
-      make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, 0,
-                 vnet_buffer (b)->ip.reass.l4_src_port,
-                 vnet_buffer (b)->ip.reass.l4_dst_port, ~0, ~0, &kv);
+      init_ed_k (&kv, ip->src_address, vnet_buffer (b)->ip.reass.l4_src_port,
+                ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port, 0,
+                ip->protocol);
     }
   else
     {
     }
   else
     {
-      make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, 0, 0,
-                 0, ~0, ~0, &kv);
+      init_ed_k (&kv, ip->src_address, 0, ip->dst_address, 0, 0,
+                ip->protocol);
     }
 
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
     }
 
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
@@ -597,8 +598,8 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip,
   u32 tx_fib_index = ip4_fib_table_get_index_for_sw_if_index (tx_sw_if_index);
 
   /* src NAT check */
   u32 tx_fib_index = ip4_fib_table_get_index_for_sw_if_index (tx_sw_if_index);
 
   /* src NAT check */
-  make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol,
-             tx_fib_index, src_port, dst_port, ~0, ~0, &kv);
+  init_ed_k (&kv, ip->src_address, src_port, ip->dst_address, dst_port,
+            tx_fib_index, ip->protocol);
   if (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     {
       ASSERT (thread_index == ed_value_get_thread_index (&value));
   if (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     {
       ASSERT (thread_index == ed_value_get_thread_index (&value));
@@ -616,8 +617,8 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip,
     }
 
   /* dst NAT check */
     }
 
   /* dst NAT check */
-  make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
-             rx_fib_index, dst_port, src_port, ~0, ~0, &kv);
+  init_ed_k (&kv, ip->dst_address, dst_port, ip->src_address, src_port,
+            rx_fib_index, ip->protocol);
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
     {
       ASSERT (thread_index == ed_value_get_thread_index (&value));
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
     {
       ASSERT (thread_index == ed_value_get_thread_index (&value));
@@ -644,26 +645,27 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip,
 #ifndef CLIB_MARCH_VARIANT
 u32
 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
 #ifndef CLIB_MARCH_VARIANT
 u32
 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
-                     u32 thread_index, vlib_buffer_t * b, ip4_header_t * ip,
-                     u8 * p_proto, snat_session_key_t * p_value,
-                     u8 * p_dont_translate, void *d, void *e)
+                     u32 thread_index, vlib_buffer_t * b,
+                     ip4_header_t * ip, ip4_address_t * addr,
+                     u16 * port, u32 * fib_index, nat_protocol_t * proto,
+                     void *d, void *e, u8 * dont_translate)
 {
   u32 sw_if_index;
   u32 rx_fib_index;
 {
   u32 sw_if_index;
   u32 rx_fib_index;
-  snat_session_t *s = 0;
-  u8 dont_translate = 0;
   clib_bihash_kv_16_8_t kv, value;
   u32 next = ~0;
   int err;
   clib_bihash_kv_16_8_t kv, value;
   u32 next = ~0;
   int err;
+  snat_session_t *s = NULL;
   u16 l_port = 0, r_port = 0;  // initialize to workaround gcc warning
   vlib_main_t *vm = vlib_get_main ();
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   u16 l_port = 0, r_port = 0;  // initialize to workaround gcc warning
   vlib_main_t *vm = vlib_get_main ();
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+  *dont_translate = 0;
 
   sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
   rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
 
   err =
 
   sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
   rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
 
   err =
-    get_icmp_i2o_ed_key (b, ip, rx_fib_index, ~0, ~0, p_proto, &l_port,
+    get_icmp_i2o_ed_key (b, ip, rx_fib_index, ~0, ~0, proto, &l_port,
                         &r_port, &kv);
   if (err != 0)
     {
                         &r_port, &kv);
   if (err != 0)
     {
@@ -681,7 +683,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
               (sm, ip, l_port, r_port, thread_index,
                sw_if_index, vnet_buffer (b)->sw_if_index[VLIB_TX])))
            {
               (sm, ip, l_port, r_port, thread_index,
                sw_if_index, vnet_buffer (b)->sw_if_index[VLIB_TX])))
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
              goto out;
            }
        }
@@ -692,7 +694,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
                                                     rx_fib_index,
                                                     thread_index)))
            {
                                                     rx_fib_index,
                                                     thread_index)))
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
              goto out;
            }
        }
@@ -716,7 +718,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
 
       if (!s)
        {
 
       if (!s)
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
     }
          goto out;
        }
     }
@@ -742,10 +744,15 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 out:
   if (s)
     }
 out:
   if (s)
-    *p_value = s->out2in;
-  *p_dont_translate = dont_translate;
+    {
+      *addr = s->out2in.addr;
+      *port = s->out2in.port;
+      *fib_index = s->out2in.fib_index;
+    }
   if (d)
   if (d)
-    *(snat_session_t **) d = s;
+    {
+      *(snat_session_t **) d = s;
+    }
   return next;
 }
 #endif
   return next;
 }
 #endif
@@ -784,8 +791,8 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
     }
   old_addr = ip->src_address.as_u32;
 
     }
   old_addr = ip->src_address.as_u32;
 
-  make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol,
-             rx_fib_index, 0, 0, ~0, ~0, &s_kv);
+  init_ed_k (&s_kv, ip->src_address, 0, ip->dst_address, 0, rx_fib_index,
+            ip->protocol);
 
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &s_kv, &s_value))
     {
 
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &s_kv, &s_value))
     {
@@ -807,7 +814,7 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
          return 0;
        }
 
          return 0;
        }
 
-      make_sm_kv (&kv, &ip->src_address, 0, rx_fib_index, 0);
+      init_nat_k (&kv, ip->src_address, 0, rx_fib_index, 0);
 
       /* Try to find static mapping first */
       if (!clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value))
 
       /* Try to find static mapping first */
       if (!clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value))
@@ -825,8 +832,7 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
              {
                new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32;
 
              {
                new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32;
 
-               make_ed_kv (&s->out2in.addr, &ip->dst_address, ip->protocol,
-                           outside_fib_index, 0, 0, ~0, ~0, &s_kv);
+               init_ed_k(&s_kv, s->out2in.addr, 0, ip->dst_address, 0, outside_fib_index, ip->protocol);
                if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
                  goto create_ses;
 
                if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
                  goto create_ses;
 
@@ -837,9 +843,8 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
 
          for (i = 0; i < vec_len (sm->addresses); i++)
            {
 
          for (i = 0; i < vec_len (sm->addresses); i++)
            {
-             make_ed_kv (&sm->addresses[i].addr, &ip->dst_address,
-                         ip->protocol, outside_fib_index, 0, 0, ~0, ~0,
-                         &s_kv);
+             init_ed_k (&s_kv, sm->addresses[i].addr, 0, ip->dst_address, 0,
+                        outside_fib_index, ip->protocol);
              if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
                {
                  new_addr = ip->src_address.as_u32 =
              if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
                {
                  new_addr = ip->src_address.as_u32 =
@@ -871,14 +876,14 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
        s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
 
       /* Add to lookup tables */
        s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
 
       /* Add to lookup tables */
-      make_ed_kv (&s->in2out.addr, &ip->dst_address, ip->protocol,
-                 rx_fib_index, 0, 0, thread_index, s - tsm->sessions, &s_kv);
+      init_ed_kv (&s_kv, s->in2out.addr, 0, ip->dst_address, 0, rx_fib_index,
+                 ip->protocol, thread_index, s - tsm->sessions);
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1))
        nat_elog_notice ("in2out key add failed");
 
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1))
        nat_elog_notice ("in2out key add failed");
 
-      make_ed_kv (&s->out2in.addr, &ip->dst_address, ip->protocol,
-                 outside_fib_index, 0, 0, thread_index, s - tsm->sessions,
-                 &s_kv);
+      init_ed_kv (&s_kv, s->out2in.addr, 0, ip->dst_address, 0,
+                 outside_fib_index, ip->protocol, thread_index,
+                 s - tsm->sessions);
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1))
        nat_elog_notice ("out2in key add failed");
     }
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1))
        nat_elog_notice ("out2in key add failed");
     }
@@ -1007,10 +1012,10 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm,
              goto trace0;
            }
 
              goto trace0;
            }
 
-         make_ed_kv (&ip0->src_address, &ip0->dst_address,
-                     ip0->protocol, rx_fib_index0,
-                     vnet_buffer (b0)->ip.reass.l4_src_port,
-                     vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0, &kv0);
+         init_ed_k (&kv0, ip0->src_address,
+                    vnet_buffer (b0)->ip.reass.l4_src_port, ip0->dst_address,
+                    vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
+                    ip0->protocol);
 
          // lookup for session
          if (clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0))
 
          // lookup for session
          if (clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0))
@@ -1295,11 +1300,10 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm,
              goto trace0;
            }
 
              goto trace0;
            }
 
-         make_ed_kv (&ip0->src_address, &ip0->dst_address,
-                     ip0->protocol, rx_fib_index0,
-                     vnet_buffer (b0)->ip.reass.l4_src_port,
-                     vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0, &kv0);
-
+         init_ed_k (&kv0, ip0->src_address,
+                    vnet_buffer (b0)->ip.reass.l4_src_port, ip0->dst_address,
+                    vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
+                    ip0->protocol);
          if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0))
            {
              ASSERT (thread_index == ed_value_get_thread_index (&value0));
          if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0))
            {
              ASSERT (thread_index == ed_value_get_thread_index (&value0));
index 5566456..ed01bb4 100644 (file)
@@ -198,7 +198,6 @@ void
 nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
                       u8 is_ha)
 {
 nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
                       u8 is_ha)
 {
-  snat_session_key_t key;
   clib_bihash_kv_8_8_t kv;
   u8 proto;
   u16 r_port, l_port;
   clib_bihash_kv_8_8_t kv;
   u8 proto;
   u16 r_port, l_port;
@@ -212,8 +211,8 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
     {
       if (snat_is_unk_proto_session (s))
        {
     {
       if (snat_is_unk_proto_session (s))
        {
-         make_ed_kv (&s->in2out.addr, &s->ext_host_addr, s->in2out.port, 0,
-                     0, 0, ~0, ~0, &ed_kv);
+         init_ed_k (&ed_kv, s->in2out.addr, 0, s->ext_host_addr, 0, 0,
+                    s->in2out.port);
        }
       else
        {
        }
       else
        {
@@ -221,9 +220,9 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
          r_port = s->ext_host_port;
          l_addr = &s->in2out.addr;
          r_addr = &s->ext_host_addr;
          r_port = s->ext_host_port;
          l_addr = &s->in2out.addr;
          r_addr = &s->ext_host_addr;
-         proto = nat_proto_to_ip_proto (s->in2out.protocol);
-         make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0,
-                     ~0, &ed_kv);
+         proto = nat_proto_to_ip_proto (s->nat_proto);
+         init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index,
+                    proto);
        }
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
        nat_elog_warn ("in2out_ed key del failed");
        }
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
        nat_elog_warn ("in2out_ed key del failed");
@@ -235,7 +234,7 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
     {
       if (is_affinity_sessions (s))
        nat_affinity_unlock (s->ext_host_addr, s->out2in.addr,
     {
       if (is_affinity_sessions (s))
        nat_affinity_unlock (s->ext_host_addr, s->out2in.addr,
-                            s->in2out.protocol, s->out2in.port);
+                            s->nat_proto, s->out2in.port);
       l_addr = &s->out2in.addr;
       r_addr = &s->ext_host_addr;
       fib_index = s->out2in.fib_index;
       l_addr = &s->out2in.addr;
       r_addr = &s->ext_host_addr;
       fib_index = s->out2in.fib_index;
@@ -247,12 +246,11 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
        }
       else
        {
        }
       else
        {
-         proto = nat_proto_to_ip_proto (s->in2out.protocol);
+         proto = nat_proto_to_ip_proto (s->nat_proto);
          l_port = s->out2in.port;
          r_port = s->ext_host_port;
        }
          l_port = s->out2in.port;
          r_port = s->ext_host_port;
        }
-      make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
-                 &ed_kv);
+      init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0))
        nat_elog_warn ("out2in_ed key del failed");
       l_addr = &s->in2out.addr;
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0))
        nat_elog_warn ("out2in_ed key del failed");
       l_addr = &s->in2out.addr;
@@ -264,8 +262,7 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
          r_addr = &s->ext_host_nat_addr;
          r_port = s->ext_host_nat_port;
        }
          r_addr = &s->ext_host_nat_addr;
          r_port = s->ext_host_nat_port;
        }
-      make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
-                 &ed_kv);
+      init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
        nat_elog_warn ("in2out_ed key del failed");
 
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
        nat_elog_warn ("in2out_ed key del failed");
 
@@ -275,14 +272,14 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
                               &s->ext_host_nat_addr, s->ext_host_nat_port,
                               &s->out2in.addr, s->out2in.port,
                               &s->ext_host_addr, s->ext_host_port,
                               &s->ext_host_nat_addr, s->ext_host_nat_port,
                               &s->out2in.addr, s->out2in.port,
                               &s->ext_host_addr, s->ext_host_port,
-                              s->in2out.protocol, is_twice_nat_session (s));
+                              s->nat_proto, is_twice_nat_session (s));
     }
   else
     {
     }
   else
     {
-      kv.key = s->in2out.as_u64;
+      init_nat_i2o_k (&kv, s);
       if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 0))
        nat_elog_warn ("in2out key del failed");
       if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 0))
        nat_elog_warn ("in2out key del failed");
-      kv.key = s->out2in.as_u64;
+      init_nat_o2i_k (&kv, s);
       if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 0))
        nat_elog_warn ("out2in key del failed");
 
       if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 0))
        nat_elog_warn ("out2in key del failed");
 
@@ -290,7 +287,7 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
        nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
                                 &s->in2out.addr, s->in2out.port,
                                 &s->out2in.addr, s->out2in.port,
        nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
                                 &s->in2out.addr, s->in2out.port,
                                 &s->out2in.addr, s->out2in.port,
-                                s->in2out.protocol);
+                                s->nat_proto);
     }
 
   if (snat_is_unk_proto_session (s))
     }
 
   if (snat_is_unk_proto_session (s))
@@ -302,31 +299,31 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
       snat_ipfix_logging_nat44_ses_delete (thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
       snat_ipfix_logging_nat44_ses_delete (thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
-                                          s->in2out.protocol,
+                                          s->nat_proto,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
-                  s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
+                  s->ext_host_port, s->nat_proto, s->out2in.fib_index,
                   thread_index);
     }
 
   /* Twice NAT address and port for external host */
   if (is_twice_nat_session (s))
     {
                   thread_index);
     }
 
   /* Twice NAT address and port for external host */
   if (is_twice_nat_session (s))
     {
-      key.protocol = s->in2out.protocol;
-      key.port = s->ext_host_nat_port;
-      key.addr.as_u32 = s->ext_host_nat_addr.as_u32;
       snat_free_outside_address_and_port (sm->twice_nat_addresses,
       snat_free_outside_address_and_port (sm->twice_nat_addresses,
-                                         thread_index, &key);
+                                         thread_index,
+                                         &s->ext_host_nat_addr,
+                                         s->ext_host_nat_port, s->nat_proto);
     }
 
   if (snat_is_session_static (s))
     return;
 
   snat_free_outside_address_and_port (sm->addresses, thread_index,
     }
 
   if (snat_is_session_static (s))
     return;
 
   snat_free_outside_address_and_port (sm->addresses, thread_index,
-                                     &s->out2in);
+                                     &s->out2in.addr, s->out2in.port,
+                                     s->nat_proto);
 }
 
 int
 }
 
 int
@@ -352,7 +349,6 @@ void
 nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
                         u32 thread_index, u8 is_ha)
 {
 nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
                         u32 thread_index, u8 is_ha)
 {
-  snat_session_key_t key;
   u8 proto;
   u16 r_port, l_port;
   ip4_address_t *l_addr, *r_addr;
   u8 proto;
   u16 r_port, l_port;
   ip4_address_t *l_addr, *r_addr;
@@ -371,7 +367,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
        }
       else
        {
        }
       else
        {
-         proto = nat_proto_to_ip_proto (s->in2out.protocol);
+         proto = nat_proto_to_ip_proto (s->nat_proto);
          l_port = s->in2out.port;
          r_port = s->ext_host_port;
        }
          l_port = s->in2out.port;
          r_port = s->ext_host_port;
        }
@@ -379,8 +375,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
       l_addr = &s->in2out.addr;
       r_addr = &s->ext_host_addr;
       fib_index = 0;
       l_addr = &s->in2out.addr;
       r_addr = &s->ext_host_addr;
       fib_index = 0;
-      make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
-                 &ed_kv);
+      init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
 
       if (PREDICT_FALSE
          (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0)))
 
       if (PREDICT_FALSE
          (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0)))
@@ -391,7 +386,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
   /* session lookup tables */
   if (is_affinity_sessions (s))
     nat_affinity_unlock (s->ext_host_addr, s->out2in.addr,
   /* session lookup tables */
   if (is_affinity_sessions (s))
     nat_affinity_unlock (s->ext_host_addr, s->out2in.addr,
-                        s->in2out.protocol, s->out2in.port);
+                        s->nat_proto, s->out2in.port);
   l_addr = &s->out2in.addr;
   r_addr = &s->ext_host_addr;
   fib_index = s->out2in.fib_index;
   l_addr = &s->out2in.addr;
   r_addr = &s->ext_host_addr;
   fib_index = s->out2in.fib_index;
@@ -403,12 +398,11 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
     }
   else
     {
     }
   else
     {
-      proto = nat_proto_to_ip_proto (s->in2out.protocol);
+      proto = nat_proto_to_ip_proto (s->nat_proto);
       l_port = s->out2in.port;
       r_port = s->ext_host_port;
     }
       l_port = s->out2in.port;
       r_port = s->ext_host_port;
     }
-  make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
-             &ed_kv);
+  init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
 
   if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0)))
     nat_elog_warn ("out2in_ed key del failed");
 
   if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0)))
     nat_elog_warn ("out2in_ed key del failed");
@@ -424,8 +418,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
       r_addr = &s->ext_host_nat_addr;
       r_port = s->ext_host_nat_port;
     }
       r_addr = &s->ext_host_nat_addr;
       r_port = s->ext_host_nat_port;
     }
-  make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
-             &ed_kv);
+  init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
 
   if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0)))
     nat_elog_warn ("in2out_ed key del failed");
 
   if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0)))
     nat_elog_warn ("in2out_ed key del failed");
@@ -437,7 +430,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
                             &s->ext_host_nat_addr, s->ext_host_nat_port,
                             &s->out2in.addr, s->out2in.port,
                             &s->ext_host_addr, s->ext_host_port,
                             &s->ext_host_nat_addr, s->ext_host_nat_port,
                             &s->out2in.addr, s->out2in.port,
                             &s->ext_host_addr, s->ext_host_port,
-                            s->in2out.protocol, is_twice_nat_session (s));
+                            s->nat_proto, is_twice_nat_session (s));
     }
 
   if (snat_is_unk_proto_session (s))
     }
 
   if (snat_is_unk_proto_session (s))
@@ -448,30 +441,30 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
       snat_ipfix_logging_nat44_ses_delete (thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
       snat_ipfix_logging_nat44_ses_delete (thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
-                                          s->in2out.protocol,
+                                          s->nat_proto,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
-                  s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
+                  s->ext_host_port, s->nat_proto, s->out2in.fib_index,
                   thread_index);
     }
 
   /* Twice NAT address and port for external host */
   if (is_twice_nat_session (s))
     {
                   thread_index);
     }
 
   /* Twice NAT address and port for external host */
   if (is_twice_nat_session (s))
     {
-      key.protocol = s->in2out.protocol;
-      key.port = s->ext_host_nat_port;
-      key.addr.as_u32 = s->ext_host_nat_addr.as_u32;
       snat_free_outside_address_and_port (sm->twice_nat_addresses,
       snat_free_outside_address_and_port (sm->twice_nat_addresses,
-                                         thread_index, &key);
+                                         thread_index,
+                                         &s->ext_host_nat_addr,
+                                         s->ext_host_nat_port, s->nat_proto);
     }
 
   if (snat_is_session_static (s))
     return;
 
   snat_free_outside_address_and_port (sm->addresses, thread_index,
     }
 
   if (snat_is_session_static (s))
     return;
 
   snat_free_outside_address_and_port (sm->addresses, thread_index,
-                                     &s->out2in);
+                                     &s->out2in.addr, s->out2in.port,
+                                     s->nat_proto);
 }
 
 
 }
 
 
@@ -790,7 +783,7 @@ snat_static_mapping_del_sessions (snat_main_t * sm,
              if (!addr_only)
                {
                  if ((s->out2in.addr.as_u32 != e_addr.as_u32) ||
              if (!addr_only)
                {
                  if ((s->out2in.addr.as_u32 != e_addr.as_u32) ||
-                     (clib_net_to_host_u16 (s->out2in.port) != e_port))
+                     (s->out2in.port != e_port))
                    continue;
                }
 
                    continue;
                }
 
@@ -831,9 +824,9 @@ snat_ed_static_mapping_del_sessions (snat_main_t * sm,
     if (!addr_only)
       {
         if ((s->out2in.addr.as_u32 != e_addr.as_u32) ||
     if (!addr_only)
       {
         if ((s->out2in.addr.as_u32 != e_addr.as_u32) ||
-            (clib_net_to_host_u16 (s->out2in.port) != e_port) ||
-            clib_net_to_host_u16 (s->in2out.port) != l_port ||
-            s->in2out.protocol != protocol)
+            s->out2in.port != e_port ||
+            s->in2out.port != l_port ||
+            s->nat_proto != protocol)
           continue;
       }
 
           continue;
       }
 
@@ -865,7 +858,6 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
 {
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m;
 {
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m;
-  snat_session_key_t m_key;
   clib_bihash_kv_8_8_t kv, value;
   snat_address_t *a = 0;
   u32 fib_index = ~0;
   clib_bihash_kv_8_8_t kv, value;
   snat_address_t *a = 0;
   u32 fib_index = ~0;
@@ -958,11 +950,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
        }
     }
 
        }
     }
 
-  m_key.addr = e_addr;
-  m_key.port = addr_only ? 0 : e_port;
-  m_key.protocol = addr_only ? 0 : proto;
-  m_key.fib_index = 0;
-  kv.key = m_key.as_u64;
+  init_nat_k (&kv, e_addr, addr_only ? 0 : e_port, 0, addr_only ? 0 : proto);
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = 0;
   else
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = 0;
   else
@@ -986,12 +974,9 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
              local->fib_index =
                fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
                                                   nat_fib_src_low);
              local->fib_index =
                fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
                                                   nat_fib_src_low);
-             m_key.addr = m->local_addr;
-             m_key.port = m->local_port;
-             m_key.protocol = m->proto;
-             m_key.fib_index = local->fib_index;
-             kv.key = m_key.as_u64;
-             kv.value = m - sm->static_mappings;
+             init_nat_kv (&kv, m->local_addr, m->local_port,
+                          local->fib_index, m->proto,
+                          m - sm->static_mappings);
              clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
              return 0;
            }
              clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
              return 0;
            }
@@ -1017,11 +1002,8 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
 
       if (!(out2in_only || identity_nat))
        {
 
       if (!(out2in_only || identity_nat))
        {
-         m_key.addr = l_addr;
-         m_key.port = addr_only ? 0 : l_port;
-         m_key.protocol = addr_only ? 0 : proto;
-         m_key.fib_index = fib_index;
-         kv.key = m_key.as_u64;
+         init_nat_k (&kv, l_addr, addr_only ? 0 : l_port, fib_index,
+                     addr_only ? 0 : proto);
          if (!clib_bihash_search_8_8
              (&sm->static_mapping_by_local, &kv, &value))
            return VNET_API_ERROR_VALUE_EXIST;
          if (!clib_bihash_search_8_8
              (&sm->static_mapping_by_local, &kv, &value))
            return VNET_API_ERROR_VALUE_EXIST;
@@ -1123,20 +1105,13 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
       else
        tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
 
       else
        tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
 
-      m_key.addr = m->local_addr;
-      m_key.port = m->local_port;
-      m_key.protocol = m->proto;
-      m_key.fib_index = fib_index;
-      kv.key = m_key.as_u64;
-      kv.value = m - sm->static_mappings;
+      init_nat_kv (&kv, m->local_addr, m->local_port, fib_index, m->proto,
+                  m - sm->static_mappings);
       if (!out2in_only)
        clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
 
       if (!out2in_only)
        clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
 
-      m_key.addr = m->external_addr;
-      m_key.port = m->external_port;
-      m_key.fib_index = 0;
-      kv.key = m_key.as_u64;
-      kv.value = m - sm->static_mappings;
+      init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto,
+                  m - sm->static_mappings);
       clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1);
 
       /* Delete dynamic sessions matching local address (+ local port) */
       clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1);
 
       /* Delete dynamic sessions matching local address (+ local port) */
@@ -1165,9 +1140,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
                      if (snat_is_session_static (s))
                        continue;
 
                      if (snat_is_session_static (s))
                        continue;
 
-                     if (!addr_only
-                         && (clib_net_to_host_u16 (s->in2out.port) !=
-                             m->local_port))
+                     if (!addr_only && s->in2out.port != m->local_port)
                        continue;
 
                      nat_free_session_data (sm, s,
                        continue;
 
                      nat_free_session_data (sm, s,
@@ -1248,11 +1221,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
       else
        tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
 
       else
        tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
 
-      m_key.addr = m->local_addr;
-      m_key.port = m->local_port;
-      m_key.protocol = m->proto;
-      m_key.fib_index = fib_index;
-      kv.key = m_key.as_u64;
+      init_nat_k (&kv, m->local_addr, m->local_port, fib_index, m->proto);
       if (!out2in_only)
        clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0);
 
       if (!out2in_only)
        clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0);
 
@@ -1281,10 +1250,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
       if (pool_elts (m->locals))
        return 0;
 
       if (pool_elts (m->locals))
        return 0;
 
-      m_key.addr = m->external_addr;
-      m_key.port = m->external_port;
-      m_key.fib_index = 0;
-      kv.key = m_key.as_u64;
+      init_nat_k (&kv, m->external_addr, m->external_port, 0, m->proto);
       clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0);
 
       vec_free (m->tag);
       clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0);
 
       vec_free (m->tag);
@@ -1328,7 +1294,6 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
 {
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m;
 {
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m;
-  snat_session_key_t m_key;
   clib_bihash_kv_8_8_t kv, value;
   snat_address_t *a = 0;
   int i;
   clib_bihash_kv_8_8_t kv, value;
   snat_address_t *a = 0;
   int i;
@@ -1340,11 +1305,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
   if (!sm->endpoint_dependent)
     return VNET_API_ERROR_FEATURE_DISABLED;
 
   if (!sm->endpoint_dependent)
     return VNET_API_ERROR_FEATURE_DISABLED;
 
-  m_key.addr = e_addr;
-  m_key.port = e_port;
-  m_key.protocol = proto;
-  m_key.fib_index = 0;
-  kv.key = m_key.as_u64;
+  init_nat_k (&kv, e_addr, e_port, 0, proto);
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = 0;
   else
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = 0;
   else
@@ -1413,32 +1374,25 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
       else
        m->affinity_per_service_list_head_index = ~0;
 
       else
        m->affinity_per_service_list_head_index = ~0;
 
-      m_key.addr = m->external_addr;
-      m_key.port = m->external_port;
-      m_key.protocol = m->proto;
-      m_key.fib_index = 0;
-      kv.key = m_key.as_u64;
-      kv.value = m - sm->static_mappings;
+      init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto,
+                  m - sm->static_mappings);
       if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1))
        {
          nat_elog_err ("static_mapping_by_external key add failed");
          return VNET_API_ERROR_UNSPECIFIED;
        }
 
       if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1))
        {
          nat_elog_err ("static_mapping_by_external key add failed");
          return VNET_API_ERROR_UNSPECIFIED;
        }
 
-      m_key.fib_index = m->fib_index;
       for (i = 0; i < vec_len (locals); i++)
        {
          locals[i].fib_index =
            fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
                                               locals[i].vrf_id,
                                               nat_fib_src_low);
       for (i = 0; i < vec_len (locals); i++)
        {
          locals[i].fib_index =
            fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
                                               locals[i].vrf_id,
                                               nat_fib_src_low);
-         m_key.addr = locals[i].addr;
-         m_key.fib_index = locals[i].fib_index;
          if (!out2in_only)
            {
          if (!out2in_only)
            {
-             m_key.port = locals[i].port;
-             kv.key = m_key.as_u64;
-             kv.value = m - sm->static_mappings;
+             init_nat_kv (&kv, locals[i].addr, locals[i].port,
+                          locals[i].fib_index, m->proto,
+                          m - sm->static_mappings);
              clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
            }
          locals[i].prefix = (i == 0) ? locals[i].probability :
              clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
            }
          locals[i].prefix = (i == 0) ? locals[i].probability :
@@ -1506,11 +1460,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
            }
        }
 
            }
        }
 
-      m_key.addr = m->external_addr;
-      m_key.port = m->external_port;
-      m_key.protocol = m->proto;
-      m_key.fib_index = 0;
-      kv.key = m_key.as_u64;
+      init_nat_k (&kv, m->external_addr, m->external_port, 0, m->proto);
       if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0))
        {
          nat_elog_err ("static_mapping_by_external key del failed");
       if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0))
        {
          nat_elog_err ("static_mapping_by_external key del failed");
@@ -1522,12 +1472,9 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
       ({
           fib_table_unlock (local->fib_index, FIB_PROTOCOL_IP4,
                             nat_fib_src_low);
       ({
           fib_table_unlock (local->fib_index, FIB_PROTOCOL_IP4,
                             nat_fib_src_low);
-          m_key.addr = local->addr;
           if (!out2in_only)
             {
           if (!out2in_only)
             {
-              m_key.port = local->port;
-              m_key.fib_index = local->fib_index;
-              kv.key = m_key.as_u64;
+init_nat_k(&              kv, local->addr, local->port, local->fib_index, m->proto);
               if (clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0))
                 {
                   nat_elog_err ("static_mapping_by_local key del failed");
               if (clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0))
                 {
                   nat_elog_err ("static_mapping_by_local key del failed");
@@ -1552,7 +1499,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
               continue;
 
             if ((s->in2out.addr.as_u32 != local->addr.as_u32) ||
               continue;
 
             if ((s->in2out.addr.as_u32 != local->addr.as_u32) ||
-                (clib_net_to_host_u16 (s->in2out.port) != local->port))
+                s->in2out.port != local->port)
               continue;
 
             nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
               continue;
 
             nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
@@ -1580,7 +1527,6 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
 {
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m = 0;
 {
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m = 0;
-  snat_session_key_t m_key;
   clib_bihash_kv_8_8_t kv, value;
   nat44_lb_addr_port_t *local, *prev_local, *match_local = 0;
   snat_main_per_thread_data_t *tsm;
   clib_bihash_kv_8_8_t kv, value;
   nat44_lb_addr_port_t *local, *prev_local, *match_local = 0;
   snat_main_per_thread_data_t *tsm;
@@ -1592,11 +1538,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
   if (!sm->endpoint_dependent)
     return VNET_API_ERROR_FEATURE_DISABLED;
 
   if (!sm->endpoint_dependent)
     return VNET_API_ERROR_FEATURE_DISABLED;
 
-  m_key.addr = e_addr;
-  m_key.port = e_port;
-  m_key.protocol = proto;
-  m_key.fib_index = 0;
-  kv.key = m_key.as_u64;
+  init_nat_k (&kv, e_addr, e_port, 0, proto);
   if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = pool_elt_at_index (sm->static_mappings, value.value);
 
   if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = pool_elt_at_index (sm->static_mappings, value.value);
 
@@ -1635,11 +1577,8 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
 
       if (!is_out2in_only_static_mapping (m))
        {
 
       if (!is_out2in_only_static_mapping (m))
        {
-         m_key.addr = l_addr;
-         m_key.port = l_port;
-         m_key.fib_index = local->fib_index;
-         kv.key = m_key.as_u64;
-         kv.value = m - sm->static_mappings;
+         init_nat_kv (&kv, l_addr, l_port, local->fib_index, proto,
+                      m - sm->static_mappings);
          if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1))
            nat_elog_err ("static_mapping_by_local key add failed");
        }
          if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1))
            nat_elog_err ("static_mapping_by_local key add failed");
        }
@@ -1657,10 +1596,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
 
       if (!is_out2in_only_static_mapping (m))
        {
 
       if (!is_out2in_only_static_mapping (m))
        {
-         m_key.addr = l_addr;
-         m_key.port = l_port;
-         m_key.fib_index = match_local->fib_index;
-         kv.key = m_key.as_u64;
+         init_nat_k (&kv, l_addr, l_port, match_local->fib_index, proto);
          if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0))
            nat_elog_err ("static_mapping_by_local key del failed");
        }
          if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0))
            nat_elog_err ("static_mapping_by_local key del failed");
        }
@@ -1684,7 +1620,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
           continue;
 
         if ((s->in2out.addr.as_u32 != match_local->addr.as_u32) ||
           continue;
 
         if ((s->in2out.addr.as_u32 != match_local->addr.as_u32) ||
-            (clib_net_to_host_u16 (s->in2out.port) != match_local->port))
+            s->in2out.port != match_local->port)
           continue;
 
         nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
           continue;
 
         nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
@@ -2441,14 +2377,13 @@ nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im,
                                 u32 if_address_index, u32 is_delete);
 
 static int
                                 u32 if_address_index, u32 is_delete);
 
 static int
-nat_alloc_addr_and_port_default (snat_address_t * addresses,
-                                u32 fib_index,
-                                u32 thread_index,
-                                snat_session_key_t * k,
+nat_alloc_addr_and_port_default (snat_address_t * addresses, u32 fib_index,
+                                u32 thread_index, nat_protocol_t proto,
+                                ip4_address_t * addr, u16 * port,
                                 u16 port_per_thread, u32 snat_thread_index);
 
 void
                                 u16 port_per_thread, u32 snat_thread_index);
 
 void
-test_ed_make_split ()
+test_key_calc_split ()
 {
   ip4_address_t l_addr;
   l_addr.as_u8[0] = 1;
 {
   ip4_address_t l_addr;
   l_addr.as_u8[0] = 1;
@@ -2467,8 +2402,8 @@ test_ed_make_split ()
   u32 thread_index = 3000000001;
   u32 session_index = 3000000221;
   clib_bihash_kv_16_8_t kv;
   u32 thread_index = 3000000001;
   u32 session_index = 3000000221;
   clib_bihash_kv_16_8_t kv;
-  make_ed_kv (&l_addr, &r_addr, proto, fib_index, l_port, r_port,
-             thread_index, session_index, &kv);
+  init_ed_kv (&kv, l_addr, l_port, r_addr, r_port, fib_index, proto,
+             thread_index, session_index);
   ip4_address_t l_addr2;
   ip4_address_t r_addr2;
   clib_memset (&l_addr2, 0, sizeof (l_addr2));
   ip4_address_t l_addr2;
   ip4_address_t r_addr2;
   clib_memset (&l_addr2, 0, sizeof (l_addr2));
@@ -2487,6 +2422,16 @@ test_ed_make_split ()
   ASSERT (fib_index == fib_index2);
   ASSERT (thread_index == ed_value_get_thread_index (&kv));
   ASSERT (session_index == ed_value_get_session_index (&kv));
   ASSERT (fib_index == fib_index2);
   ASSERT (thread_index == ed_value_get_thread_index (&kv));
   ASSERT (session_index == ed_value_get_session_index (&kv));
+
+  fib_index = 7001;
+  proto = 5;
+  nat_protocol_t proto3 = ~0;
+  u64 key = calc_nat_key (l_addr, l_port, fib_index, proto);
+  split_nat_key (key, &l_addr2, &l_port2, &fib_index2, &proto3);
+  ASSERT (l_addr.as_u32 == l_addr2.as_u32);
+  ASSERT (l_port == l_port2);
+  ASSERT (proto == proto3);
+  ASSERT (fib_index == fib_index2);
 }
 
 static clib_error_t *
 }
 
 static clib_error_t *
@@ -2656,7 +2601,7 @@ snat_init (vlib_main_t * vm)
                                         FIB_SOURCE_PRIORITY_LOW,
                                         FIB_SOURCE_BH_SIMPLE);
 
                                         FIB_SOURCE_PRIORITY_LOW,
                                         FIB_SOURCE_BH_SIMPLE);
 
-  test_ed_make_split ();
+  test_key_calc_split ();
   return error;
 }
 
   return error;
 }
 
@@ -2664,16 +2609,18 @@ VLIB_INIT_FUNCTION (snat_init);
 
 void
 snat_free_outside_address_and_port (snat_address_t * addresses,
 
 void
 snat_free_outside_address_and_port (snat_address_t * addresses,
-                                   u32 thread_index, snat_session_key_t * k)
+                                   u32 thread_index,
+                                   ip4_address_t * addr,
+                                   u16 port, nat_protocol_t protocol)
 {
   snat_address_t *a;
   u32 address_index;
 {
   snat_address_t *a;
   u32 address_index;
-  u16 port_host_byte_order = clib_net_to_host_u16 (k->port);
+  u16 port_host_byte_order = clib_net_to_host_u16 (port);
 
   for (address_index = 0; address_index < vec_len (addresses);
        address_index++)
     {
 
   for (address_index = 0; address_index < vec_len (addresses);
        address_index++)
     {
-      if (addresses[address_index].addr.as_u32 == k->addr.as_u32)
+      if (addresses[address_index].addr.as_u32 == addr->as_u32)
        break;
     }
 
        break;
     }
 
@@ -2681,7 +2628,7 @@ snat_free_outside_address_and_port (snat_address_t * addresses,
 
   a = addresses + address_index;
 
 
   a = addresses + address_index;
 
-  switch (k->protocol)
+  switch (protocol)
     {
 #define _(N, i, n, s) \
     case NAT_PROTOCOL_##N: \
     {
 #define _(N, i, n, s) \
     case NAT_PROTOCOL_##N: \
@@ -2700,20 +2647,21 @@ snat_free_outside_address_and_port (snat_address_t * addresses,
 
 static int
 nat_set_outside_address_and_port (snat_address_t * addresses,
 
 static int
 nat_set_outside_address_and_port (snat_address_t * addresses,
-                                 u32 thread_index, snat_session_key_t * k)
+                                 u32 thread_index, ip4_address_t addr,
+                                 u16 port, nat_protocol_t protocol)
 {
   snat_address_t *a = 0;
   u32 address_index;
 {
   snat_address_t *a = 0;
   u32 address_index;
-  u16 port_host_byte_order = clib_net_to_host_u16 (k->port);
+  u16 port_host_byte_order = clib_net_to_host_u16 (port);
 
   for (address_index = 0; address_index < vec_len (addresses);
        address_index++)
     {
 
   for (address_index = 0; address_index < vec_len (addresses);
        address_index++)
     {
-      if (addresses[address_index].addr.as_u32 != k->addr.as_u32)
+      if (addresses[address_index].addr.as_u32 != addr.as_u32)
        continue;
 
       a = addresses + address_index;
        continue;
 
       a = addresses + address_index;
-      switch (k->protocol)
+      switch (protocol)
        {
 #define _(N, j, n, s) \
         case NAT_PROTOCOL_##N: \
        {
 #define _(N, j, n, s) \
         case NAT_PROTOCOL_##N: \
@@ -2736,8 +2684,13 @@ nat_set_outside_address_and_port (snat_address_t * addresses,
 
 int
 snat_static_mapping_match (snat_main_t * sm,
 
 int
 snat_static_mapping_match (snat_main_t * sm,
-                          snat_session_key_t match,
-                          snat_session_key_t * mapping,
+                          ip4_address_t match_addr,
+                          u16 match_port,
+                          u32 match_fib_index,
+                          nat_protocol_t match_protocol,
+                          ip4_address_t * mapping_addr,
+                          u16 * mapping_port,
+                          u32 * mapping_fib_index,
                           u8 by_external,
                           u8 * is_addr_only,
                           twice_nat_type_t * twice_nat,
                           u8 by_external,
                           u8 * is_addr_only,
                           twice_nat_type_t * twice_nat,
@@ -2746,33 +2699,36 @@ snat_static_mapping_match (snat_main_t * sm,
 {
   clib_bihash_kv_8_8_t kv, value;
   snat_static_mapping_t *m;
 {
   clib_bihash_kv_8_8_t kv, value;
   snat_static_mapping_t *m;
-  snat_session_key_t m_key;
   clib_bihash_8_8_t *mapping_hash = &sm->static_mapping_by_local;
   u32 rand, lo = 0, hi, mid, *tmp = 0, i;
   u8 backend_index;
   nat44_lb_addr_port_t *local;
 
   clib_bihash_8_8_t *mapping_hash = &sm->static_mapping_by_local;
   u32 rand, lo = 0, hi, mid, *tmp = 0, i;
   u8 backend_index;
   nat44_lb_addr_port_t *local;
 
-  m_key.fib_index = match.fib_index;
   if (by_external)
     {
       mapping_hash = &sm->static_mapping_by_external;
   if (by_external)
     {
       mapping_hash = &sm->static_mapping_by_external;
-      m_key.fib_index = 0;
-    }
-
-  m_key.addr = match.addr;
-  m_key.port = clib_net_to_host_u16 (match.port);
-  m_key.protocol = match.protocol;
-
-  kv.key = m_key.as_u64;
+      init_nat_k (&kv, match_addr, match_port, 0, match_protocol);
+      if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
+       {
+         /* Try address only mapping */
+         init_nat_k (&kv, match_addr, 0, 0, 0);
+         if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
+           return 1;
+       }
 
 
-  if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
+    }
+  else
     {
     {
-      /* Try address only mapping */
-      m_key.port = 0;
-      m_key.protocol = 0;
-      kv.key = m_key.as_u64;
+      init_nat_k (&kv, match_addr, match_port, match_fib_index,
+                 match_protocol);
       if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
       if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
-       return 1;
+       {
+         /* Try address only mapping */
+         init_nat_k (&kv, match_addr, 0, match_fib_index, 0);
+         if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
+           return 1;
+       }
+
     }
 
   m = pool_elt_at_index (sm->static_mappings, value.value);
     }
 
   m = pool_elt_at_index (sm->static_mappings, value.value);
@@ -2784,15 +2740,15 @@ snat_static_mapping_match (snat_main_t * sm,
          if (PREDICT_FALSE (lb != 0))
            *lb = m->affinity ? AFFINITY_LB_NAT : LB_NAT;
          if (m->affinity && !nat_affinity_find_and_lock (ext_host_addr[0],
          if (PREDICT_FALSE (lb != 0))
            *lb = m->affinity ? AFFINITY_LB_NAT : LB_NAT;
          if (m->affinity && !nat_affinity_find_and_lock (ext_host_addr[0],
-                                                         match.addr,
-                                                         match.protocol,
-                                                         match.port,
+                                                         match_addr,
+                                                         match_protocol,
+                                                         match_port,
                                                          &backend_index))
            {
              local = pool_elt_at_index (m->locals, backend_index);
                                                          &backend_index))
            {
              local = pool_elt_at_index (m->locals, backend_index);
-             mapping->addr = local->addr;
-             mapping->port = clib_host_to_net_u16 (local->port);
-             mapping->fib_index = local->fib_index;
+             *mapping_addr = local->addr;
+             *mapping_port = local->port;
+             *mapping_fib_index = local->fib_index;
              goto end;
            }
          // pick locals matching this worker
              goto end;
            }
          // pick locals matching this worker
@@ -2838,13 +2794,13 @@ snat_static_mapping_match (snat_main_t * sm,
          local = pool_elt_at_index (m->locals, tmp[lo]);
          if (!(local->prefix >= rand))
            return 1;
          local = pool_elt_at_index (m->locals, tmp[lo]);
          if (!(local->prefix >= rand))
            return 1;
-         mapping->addr = local->addr;
-         mapping->port = clib_host_to_net_u16 (local->port);
-         mapping->fib_index = local->fib_index;
+         *mapping_addr = local->addr;
+         *mapping_port = local->port;
+         *mapping_fib_index = local->fib_index;
          if (m->affinity)
            {
          if (m->affinity)
            {
-             if (nat_affinity_create_and_lock (ext_host_addr[0], match.addr,
-                                               match.protocol, match.port,
+             if (nat_affinity_create_and_lock (ext_host_addr[0], match_addr,
+                                               match_protocol, match_port,
                                                tmp[lo], m->affinity,
                                                m->affinity_per_service_list_head_index))
                nat_elog_info ("create affinity record failed");
                                                tmp[lo], m->affinity,
                                                m->affinity_per_service_list_head_index))
                nat_elog_info ("create affinity record failed");
@@ -2855,21 +2811,20 @@ snat_static_mapping_match (snat_main_t * sm,
        {
          if (PREDICT_FALSE (lb != 0))
            *lb = NO_LB_NAT;
        {
          if (PREDICT_FALSE (lb != 0))
            *lb = NO_LB_NAT;
-         mapping->fib_index = m->fib_index;
-         mapping->addr = m->local_addr;
+         *mapping_fib_index = m->fib_index;
+         *mapping_addr = m->local_addr;
          /* Address only mapping doesn't change port */
          /* Address only mapping doesn't change port */
-         mapping->port = is_addr_only_static_mapping (m) ? match.port
-           : clib_host_to_net_u16 (m->local_port);
+         *mapping_port = is_addr_only_static_mapping (m) ? match_port
+           : m->local_port;
        }
        }
-      mapping->protocol = m->proto;
     }
   else
     {
     }
   else
     {
-      mapping->addr = m->external_addr;
+      *mapping_addr = m->external_addr;
       /* Address only mapping doesn't change port */
       /* Address only mapping doesn't change port */
-      mapping->port = is_addr_only_static_mapping (m) ? match.port
-       : clib_host_to_net_u16 (m->external_port);
-      mapping->fib_index = sm->outside_fib_index;
+      *mapping_port = is_addr_only_static_mapping (m) ? match_port
+       : m->external_port;
+      *mapping_fib_index = sm->outside_fib_index;
     }
 
 end:
     }
 
 end:
@@ -2897,21 +2852,26 @@ int
 snat_alloc_outside_address_and_port (snat_address_t * addresses,
                                     u32 fib_index,
                                     u32 thread_index,
 snat_alloc_outside_address_and_port (snat_address_t * addresses,
                                     u32 fib_index,
                                     u32 thread_index,
-                                    snat_session_key_t * k,
+                                    nat_protocol_t proto,
+                                    ip4_address_t * addr,
+                                    u16 * port,
                                     u16 port_per_thread,
                                     u32 snat_thread_index)
 {
   snat_main_t *sm = &snat_main;
 
                                     u16 port_per_thread,
                                     u32 snat_thread_index)
 {
   snat_main_t *sm = &snat_main;
 
-  return sm->alloc_addr_and_port (addresses, fib_index, thread_index, k,
-                                 port_per_thread, snat_thread_index);
+  return sm->alloc_addr_and_port (addresses, fib_index, thread_index, proto,
+                                 addr, port, port_per_thread,
+                                 snat_thread_index);
 }
 
 static int
 nat_alloc_addr_and_port_default (snat_address_t * addresses,
                                 u32 fib_index,
                                 u32 thread_index,
 }
 
 static int
 nat_alloc_addr_and_port_default (snat_address_t * addresses,
                                 u32 fib_index,
                                 u32 thread_index,
-                                snat_session_key_t * k,
+                                nat_protocol_t proto,
+                                ip4_address_t * addr,
+                                u16 * port,
                                 u16 port_per_thread, u32 snat_thread_index)
 {
   int i;
                                 u16 port_per_thread, u32 snat_thread_index)
 {
   int i;
@@ -2921,7 +2881,7 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses,
   for (i = 0; i < vec_len (addresses); i++)
     {
       a = addresses + i;
   for (i = 0; i < vec_len (addresses); i++)
     {
       a = addresses + i;
-      switch (k->protocol)
+      switch (proto)
        {
 #define _(N, j, n, s) \
         case NAT_PROTOCOL_##N: \
        {
 #define _(N, j, n, s) \
         case NAT_PROTOCOL_##N: \
@@ -2939,8 +2899,8 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses,
                      --a->busy_##n##_port_refcounts[portnum]; \
                       a->busy_##n##_ports_per_thread[thread_index]++; \
                       a->busy_##n##_ports++; \
                      --a->busy_##n##_port_refcounts[portnum]; \
                       a->busy_##n##_ports_per_thread[thread_index]++; \
                       a->busy_##n##_ports++; \
-                      k->addr = a->addr; \
-                      k->port = clib_host_to_net_u16(portnum); \
+                      *addr = a->addr; \
+                      *port = clib_host_to_net_u16(portnum); \
                       return 0; \
                     } \
                 } \
                       return 0; \
                     } \
                 } \
@@ -2962,7 +2922,7 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses,
   if (ga)
     {
       a = ga;
   if (ga)
     {
       a = ga;
-      switch (k->protocol)
+      switch (proto)
        {
 #define _(N, j, n, s) \
         case NAT_PROTOCOL_##N: \
        {
 #define _(N, j, n, s) \
         case NAT_PROTOCOL_##N: \
@@ -2976,8 +2936,8 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses,
              ++a->busy_##n##_port_refcounts[portnum]; \
               a->busy_##n##_ports_per_thread[thread_index]++; \
               a->busy_##n##_ports++; \
              ++a->busy_##n##_port_refcounts[portnum]; \
               a->busy_##n##_ports_per_thread[thread_index]++; \
               a->busy_##n##_ports++; \
-              k->addr = a->addr; \
-              k->port = clib_host_to_net_u16(portnum); \
+              *addr = a->addr; \
+              *port = clib_host_to_net_u16(portnum); \
               return 0; \
             }
          break;
               return 0; \
             }
          break;
@@ -2995,10 +2955,9 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses,
 }
 
 static int
 }
 
 static int
-nat_alloc_addr_and_port_mape (snat_address_t * addresses,
-                             u32 fib_index,
-                             u32 thread_index,
-                             snat_session_key_t * k,
+nat_alloc_addr_and_port_mape (snat_address_t * addresses, u32 fib_index,
+                             u32 thread_index, nat_protocol_t proto,
+                             ip4_address_t * addr, u16 * port,
                              u16 port_per_thread, u32 snat_thread_index)
 {
   snat_main_t *sm = &snat_main;
                              u16 port_per_thread, u32 snat_thread_index)
 {
   snat_main_t *sm = &snat_main;
@@ -3010,7 +2969,7 @@ nat_alloc_addr_and_port_mape (snat_address_t * addresses,
   if (!vec_len (addresses))
     goto exhausted;
 
   if (!vec_len (addresses))
     goto exhausted;
 
-  switch (k->protocol)
+  switch (proto)
     {
 #define _(N, i, n, s) \
     case NAT_PROTOCOL_##N: \
     {
 #define _(N, i, n, s) \
     case NAT_PROTOCOL_##N: \
@@ -3025,8 +2984,8 @@ nat_alloc_addr_and_port_mape (snat_address_t * addresses,
                 continue; \
              ++a->busy_##n##_port_refcounts[portnum]; \
               a->busy_##n##_ports++; \
                 continue; \
              ++a->busy_##n##_port_refcounts[portnum]; \
               a->busy_##n##_ports++; \
-              k->addr = a->addr; \
-              k->port = clib_host_to_net_u16 (portnum); \
+              *addr = a->addr; \
+              *port = clib_host_to_net_u16 (portnum); \
               return 0; \
             } \
         } \
               return 0; \
             } \
         } \
@@ -3045,10 +3004,9 @@ exhausted:
 }
 
 static int
 }
 
 static int
-nat_alloc_addr_and_port_range (snat_address_t * addresses,
-                              u32 fib_index,
-                              u32 thread_index,
-                              snat_session_key_t * k,
+nat_alloc_addr_and_port_range (snat_address_t * addresses, u32 fib_index,
+                              u32 thread_index, nat_protocol_t proto,
+                              ip4_address_t * addr, u16 * port,
                               u16 port_per_thread, u32 snat_thread_index)
 {
   snat_main_t *sm = &snat_main;
                               u16 port_per_thread, u32 snat_thread_index)
 {
   snat_main_t *sm = &snat_main;
@@ -3060,7 +3018,7 @@ nat_alloc_addr_and_port_range (snat_address_t * addresses,
   if (!vec_len (addresses))
     goto exhausted;
 
   if (!vec_len (addresses))
     goto exhausted;
 
-  switch (k->protocol)
+  switch (proto)
     {
 #define _(N, i, n, s) \
     case NAT_PROTOCOL_##N: \
     {
 #define _(N, i, n, s) \
     case NAT_PROTOCOL_##N: \
@@ -3073,8 +3031,8 @@ nat_alloc_addr_and_port_range (snat_address_t * addresses,
                 continue; \
              ++a->busy_##n##_port_refcounts[portnum]; \
               a->busy_##n##_ports++; \
                 continue; \
              ++a->busy_##n##_port_refcounts[portnum]; \
               a->busy_##n##_ports++; \
-              k->addr = a->addr; \
-              k->port = clib_host_to_net_u16 (portnum); \
+              *addr = a->addr; \
+              *port = clib_host_to_net_u16 (portnum); \
               return 0; \
             } \
         } \
               return 0; \
             } \
         } \
@@ -3119,11 +3077,8 @@ u8 *
 format_session_kvp (u8 * s, va_list * args)
 {
   clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
 format_session_kvp (u8 * s, va_list * args)
 {
   clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
-  snat_session_key_t k;
 
 
-  k.as_u64 = v->key;
-
-  s = format (s, "%U session-index %llu", format_snat_key, &k, v->value);
+  s = format (s, "%U session-index %llu", format_snat_key, v->key, v->value);
 
   return s;
 }
 
   return s;
 }
@@ -3132,12 +3087,9 @@ u8 *
 format_static_mapping_kvp (u8 * s, va_list * args)
 {
   clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
 format_static_mapping_kvp (u8 * s, va_list * args)
 {
   clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
-  snat_session_key_t k;
-
-  k.as_u64 = v->key;
 
   s = format (s, "%U static-mapping-index %llu",
 
   s = format (s, "%U static-mapping-index %llu",
-             format_static_mapping_key, &k, v->value);
+             format_snat_key, v->key, v->value);
 
   return s;
 }
 
   return s;
 }
@@ -3205,7 +3157,6 @@ snat_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip0,
   snat_main_t *sm = &snat_main;
   udp_header_t *udp;
   u16 port;
   snat_main_t *sm = &snat_main;
   udp_header_t *udp;
   u16 port;
-  snat_session_key_t m_key;
   clib_bihash_kv_8_8_t kv, value;
   snat_static_mapping_t *m;
   u32 proto;
   clib_bihash_kv_8_8_t kv, value;
   snat_static_mapping_t *m;
   u32 proto;
@@ -3214,11 +3165,7 @@ snat_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip0,
   /* first try static mappings without port */
   if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
     {
   /* first try static mappings without port */
   if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
     {
-      m_key.addr = ip0->dst_address;
-      m_key.port = 0;
-      m_key.protocol = 0;
-      m_key.fib_index = rx_fib_index0;
-      kv.key = m_key.as_u64;
+      init_nat_k (&kv, ip0->dst_address, 0, rx_fib_index0, 0);
       if (!clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
       if (!clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
@@ -3271,11 +3218,7 @@ snat_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip0,
   /* try static mappings with port */
   if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
     {
   /* try static mappings with port */
   if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
     {
-      m_key.addr = ip0->dst_address;
-      m_key.port = clib_net_to_host_u16 (port);
-      m_key.protocol = proto;
-      m_key.fib_index = rx_fib_index0;
-      kv.key = m_key.as_u64;
+      init_nat_k (&kv, ip0->dst_address, port, rx_fib_index0, proto);
       if (!clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
       if (!clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
@@ -3345,9 +3288,8 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t * ip, u32 rx_fib_index,
          break;
        }
 
          break;
        }
 
-      make_ed_kv (&ip->src_address, &ip->dst_address,
-                 ip->protocol, fib_index, udp->src_port, udp->dst_port,
-                 ~0, ~0, &kv16);
+      init_ed_k (&kv16, ip->src_address, udp->src_port, ip->dst_address,
+                udp->dst_port, fib_index, ip->protocol);
 
       if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed,
                                                  &kv16, &value16)))
 
       if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed,
                                                  &kv16, &value16)))
@@ -3415,9 +3357,8 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
     {
       udp = ip4_next_header (ip);
 
     {
       udp = ip4_next_header (ip);
 
-      make_ed_kv (&ip->dst_address, &ip->src_address,
-                 ip->protocol, rx_fib_index, udp->dst_port, udp->src_port,
-                 ~0, ~0, &kv16);
+      init_ed_k (&kv16, ip->dst_address, udp->dst_port, ip->src_address,
+                udp->src_port, rx_fib_index, ip->protocol);
 
       if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed,
                                                  &kv16, &value16)))
 
       if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed,
                                                  &kv16, &value16)))
@@ -3462,7 +3403,7 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
   /* first try static mappings without port */
   if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
     {
   /* first try static mappings without port */
   if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
     {
-      make_sm_kv (&kv, &ip->dst_address, 0, 0, 0);
+      init_nat_k (&kv, ip->dst_address, 0, 0, 0);
       if (!clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
       if (!clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
@@ -3517,8 +3458,7 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
   /* try static mappings with port */
   if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
     {
   /* try static mappings with port */
   if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
     {
-      make_sm_kv (&kv, &ip->dst_address, proto, 0,
-                 clib_net_to_host_u16 (port));
+      init_nat_k (&kv, ip->dst_address, proto, 0, port);
       if (!clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
       if (!clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
@@ -3562,7 +3502,6 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
 {
   snat_main_t *sm = &snat_main;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
 {
   snat_main_t *sm = &snat_main;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
-  snat_session_key_t key;
   snat_user_t *u;
   snat_session_t *s;
   clib_bihash_kv_8_8_t kv;
   snat_user_t *u;
   snat_session_t *s;
   clib_bihash_kv_8_8_t kv;
@@ -3578,14 +3517,10 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
                },
   };
 
                },
   };
 
-  key.addr.as_u32 = out_addr->as_u32;
-  key.port = out_port;
-  key.protocol = proto;
-
   if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING))
     {
       if (nat_set_outside_address_and_port
   if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING))
     {
       if (nat_set_outside_address_and_port
-         (sm->addresses, thread_index, &key))
+         (sm->addresses, thread_index, *out_addr, out_port, proto))
        return;
     }
 
        return;
     }
 
@@ -3599,9 +3534,12 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
 
   if (sm->endpoint_dependent)
     {
 
   if (sm->endpoint_dependent)
     {
-      nat_ed_lru_insert (tsm, s, now, proto);
+      nat_ed_lru_insert (tsm, s, now, nat_proto_to_ip_proto (proto));
     }
 
     }
 
+  s->out2in.addr.as_u32 = out_addr->as_u32;
+  s->out2in.port = out_port;
+  s->nat_proto = proto;
   s->last_heard = now;
   s->flags = flags;
   s->ext_host_addr.as_u32 = eh_addr->as_u32;
   s->last_heard = now;
   s->flags = flags;
   s->ext_host_addr.as_u32 = eh_addr->as_u32;
@@ -3610,10 +3548,10 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
   switch (vec_len (sm->outside_fibs))
     {
     case 0:
   switch (vec_len (sm->outside_fibs))
     {
     case 0:
-      key.fib_index = sm->outside_fib_index;
+      s->out2in.fib_index = sm->outside_fib_index;
       break;
     case 1:
       break;
     case 1:
-      key.fib_index = sm->outside_fibs[0].fib_index;
+      s->out2in.fib_index = sm->outside_fibs[0].fib_index;
       break;
     default:
       /* *INDENT-OFF* */
       break;
     default:
       /* *INDENT-OFF* */
@@ -3624,7 +3562,7 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
             {
               if (fib_entry_get_resolving_interface (fei) != ~0)
                 {
             {
               if (fib_entry_get_resolving_interface (fei) != ~0)
                 {
-                  key.fib_index = outside_fib->fib_index;
+                  s->out2in.fib_index = outside_fib->fib_index;
                   break;
                 }
             }
                   break;
                 }
             }
@@ -3632,17 +3570,14 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
       /* *INDENT-ON* */
       break;
     }
       /* *INDENT-ON* */
       break;
     }
-  s->out2in = key;
-  kv.key = key.as_u64;
-  kv.value = s - tsm->sessions;
+  init_nat_o2i_kv (&kv, s, s - tsm->sessions);
   if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 1))
     nat_elog_warn ("out2in key add failed");
 
   if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 1))
     nat_elog_warn ("out2in key add failed");
 
-  key.addr.as_u32 = in_addr->as_u32;
-  key.port = in_port;
-  key.fib_index = fib_index;
-  s->in2out = key;
-  kv.key = key.as_u64;
+  s->in2out.addr.as_u32 = in_addr->as_u32;
+  s->in2out.port = in_port;
+  s->in2out.fib_index = fib_index;
+  init_nat_i2o_kv (&kv, s, s - tsm->sessions);
   if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 1))
     nat_elog_warn ("in2out key add failed");
 }
   if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 1))
     nat_elog_warn ("in2out key add failed");
 }
@@ -3653,7 +3588,6 @@ nat_ha_sdel_cb (ip4_address_t * out_addr, u16 out_port,
                u32 ti)
 {
   snat_main_t *sm = &snat_main;
                u32 ti)
 {
   snat_main_t *sm = &snat_main;
-  snat_session_key_t key;
   clib_bihash_kv_8_8_t kv, value;
   u32 thread_index;
   snat_session_t *s;
   clib_bihash_kv_8_8_t kv, value;
   u32 thread_index;
   snat_session_t *s;
@@ -3668,11 +3602,7 @@ nat_ha_sdel_cb (ip4_address_t * out_addr, u16 out_port,
     thread_index = sm->num_workers;
   tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
 
     thread_index = sm->num_workers;
   tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
 
-  key.addr.as_u32 = out_addr->as_u32;
-  key.port = out_port;
-  key.protocol = proto;
-  key.fib_index = fib_index;
-  kv.key = key.as_u64;
+  init_nat_k (&kv, *out_addr, out_port, fib_index, proto);
   if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value))
     return;
 
   if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value))
     return;
 
@@ -3687,18 +3617,13 @@ nat_ha_sref_cb (ip4_address_t * out_addr, u16 out_port,
                u32 total_pkts, u64 total_bytes, u32 thread_index)
 {
   snat_main_t *sm = &snat_main;
                u32 total_pkts, u64 total_bytes, u32 thread_index)
 {
   snat_main_t *sm = &snat_main;
-  snat_session_key_t key;
   clib_bihash_kv_8_8_t kv, value;
   snat_session_t *s;
   snat_main_per_thread_data_t *tsm;
 
   tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
 
   clib_bihash_kv_8_8_t kv, value;
   snat_session_t *s;
   snat_main_per_thread_data_t *tsm;
 
   tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
 
-  key.addr.as_u32 = out_addr->as_u32;
-  key.port = out_port;
-  key.protocol = proto;
-  key.fib_index = fib_index;
-  kv.key = key.as_u64;
+  init_nat_k (&kv, *out_addr, out_port, fib_index, proto);
   if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value))
     return;
 
   if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value))
     return;
 
@@ -3716,7 +3641,6 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port,
 {
   snat_main_t *sm = &snat_main;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
 {
   snat_main_t *sm = &snat_main;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
-  snat_session_key_t key;
   snat_session_t *s;
   clib_bihash_kv_16_8_t kv;
   vlib_main_t *vm = vlib_get_main ();
   snat_session_t *s;
   clib_bihash_kv_16_8_t kv;
   vlib_main_t *vm = vlib_get_main ();
@@ -3731,23 +3655,18 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port,
                },
   };
 
                },
   };
 
-  key.addr.as_u32 = out_addr->as_u32;
-  key.port = out_port;
-  key.protocol = proto;
 
   if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING))
     {
       if (nat_set_outside_address_and_port
 
   if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING))
     {
       if (nat_set_outside_address_and_port
-         (sm->addresses, thread_index, &key))
+         (sm->addresses, thread_index, *out_addr, out_port, proto))
        return;
     }
 
        return;
     }
 
-  key.addr.as_u32 = ehn_addr->as_u32;
-  key.port = ehn_port;
   if (flags & SNAT_SESSION_FLAG_TWICE_NAT)
     {
       if (nat_set_outside_address_and_port
   if (flags & SNAT_SESSION_FLAG_TWICE_NAT)
     {
       if (nat_set_outside_address_and_port
-         (sm->twice_nat_addresses, thread_index, &key))
+         (sm->addresses, thread_index, *ehn_addr, ehn_port, proto))
        return;
     }
 
        return;
     }
 
@@ -3767,10 +3686,10 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port,
   switch (vec_len (sm->outside_fibs))
     {
     case 0:
   switch (vec_len (sm->outside_fibs))
     {
     case 0:
-      key.fib_index = sm->outside_fib_index;
+      s->out2in.fib_index = sm->outside_fib_index;
       break;
     case 1:
       break;
     case 1:
-      key.fib_index = sm->outside_fibs[0].fib_index;
+      s->out2in.fib_index = sm->outside_fibs[0].fib_index;
       break;
     default:
       /* *INDENT-OFF* */
       break;
     default:
       /* *INDENT-OFF* */
@@ -3781,7 +3700,7 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port,
             {
               if (fib_entry_get_resolving_interface (fei) != ~0)
                 {
             {
               if (fib_entry_get_resolving_interface (fei) != ~0)
                 {
-                  key.fib_index = outside_fib->fib_index;
+                  s->out2in.fib_index = outside_fib->fib_index;
                   break;
                 }
             }
                   break;
                 }
             }
@@ -3789,25 +3708,23 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port,
       /* *INDENT-ON* */
       break;
     }
       /* *INDENT-ON* */
       break;
     }
-  key.addr.as_u32 = out_addr->as_u32;
-  key.port = out_port;
-  s->out2in = key;
-  kv.value = s - tsm->sessions;
-
-  key.addr.as_u32 = in_addr->as_u32;
-  key.port = in_port;
-  key.fib_index = fib_index;
-  s->in2out = key;
-
-  make_ed_kv (in_addr, &s->ext_host_nat_addr,
-             nat_proto_to_ip_proto (proto), fib_index, in_port,
-             s->ext_host_nat_port, thread_index, s - tsm->sessions, &kv);
+  s->nat_proto = proto;
+  s->out2in.addr.as_u32 = out_addr->as_u32;
+  s->out2in.port = out_port;
+
+  s->in2out.addr.as_u32 = in_addr->as_u32;
+  s->in2out.port = in_port;
+  s->in2out.fib_index = fib_index;
+
+  init_ed_kv (&kv, *in_addr, in_port, s->ext_host_nat_addr,
+             s->ext_host_nat_port, fib_index, nat_proto_to_ip_proto (proto),
+             thread_index, s - tsm->sessions);
   if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1))
     nat_elog_warn ("in2out key add failed");
 
   if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1))
     nat_elog_warn ("in2out key add failed");
 
-  make_ed_kv (out_addr, eh_addr, nat_proto_to_ip_proto (proto),
-             s->out2in.fib_index, out_port, eh_port, thread_index,
-             s - tsm->sessions, &kv);
+  init_ed_kv (&kv, *out_addr, out_port, *eh_addr, eh_port,
+             s->out2in.fib_index, nat_proto_to_ip_proto (proto),
+             thread_index, s - tsm->sessions);
   if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &kv, 1))
     nat_elog_warn ("out2in key add failed");
 }
   if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &kv, 1))
     nat_elog_warn ("out2in key add failed");
 }
@@ -3832,8 +3749,7 @@ nat_ha_sdel_ed_cb (ip4_address_t * out_addr, u16 out_port,
     thread_index = sm->num_workers;
   tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
 
     thread_index = sm->num_workers;
   tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
 
-  make_ed_kv (out_addr, eh_addr, proto, fib_index, out_port, eh_port, ~0, ~0,
-             &kv);
+  init_ed_k (&kv, *out_addr, out_port, *eh_addr, eh_port, fib_index, proto);
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     return;
 
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     return;
 
@@ -3855,8 +3771,7 @@ nat_ha_sref_ed_cb (ip4_address_t * out_addr, u16 out_port,
 
   tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
 
 
   tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
 
-  make_ed_kv (out_addr, eh_addr, proto, fib_index, out_port, eh_port, ~0, ~0,
-             &kv);
+  init_ed_k (&kv, *out_addr, out_port, *eh_addr, eh_port, fib_index, proto);
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     return;
 
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     return;
 
@@ -4210,7 +4125,6 @@ nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im,
   snat_main_t *sm = &snat_main;
   snat_static_map_resolve_t *rp;
   snat_static_mapping_t *m;
   snat_main_t *sm = &snat_main;
   snat_static_map_resolve_t *rp;
   snat_static_mapping_t *m;
-  snat_session_key_t m_key;
   clib_bihash_kv_8_8_t kv, value;
   int i, rv;
   ip4_address_t l_addr;
   clib_bihash_kv_8_8_t kv, value;
   int i, rv;
   ip4_address_t l_addr;
@@ -4227,11 +4141,8 @@ nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im,
   return;
 
 match:
   return;
 
 match:
-  m_key.addr.as_u32 = address->as_u32;
-  m_key.port = rp->addr_only ? 0 : rp->e_port;
-  m_key.protocol = rp->addr_only ? 0 : rp->proto;
-  m_key.fib_index = sm->outside_fib_index;
-  kv.key = m_key.as_u64;
+  init_nat_k (&kv, *address, rp->addr_only ? 0 : rp->e_port,
+             sm->outside_fib_index, rp->addr_only ? 0 : rp->proto);
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = 0;
   else
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = 0;
   else
@@ -4425,7 +4336,6 @@ nat44_del_session (snat_main_t * sm, ip4_address_t * addr, u16 port,
   clib_bihash_kv_8_8_t kv, value;
   ip4_header_t ip;
   u32 fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id);
   clib_bihash_kv_8_8_t kv, value;
   ip4_header_t ip;
   u32 fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id);
-  snat_session_key_t key;
   snat_session_t *s;
   clib_bihash_8_8_t *t;
 
   snat_session_t *s;
   clib_bihash_8_8_t *t;
 
@@ -4440,11 +4350,7 @@ nat44_del_session (snat_main_t * sm, ip4_address_t * addr, u16 port,
   else
     tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
 
   else
     tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
 
-  key.addr.as_u32 = addr->as_u32;
-  key.port = clib_host_to_net_u16 (port);
-  key.protocol = proto;
-  key.fib_index = fib_index;
-  kv.key = key.as_u64;
+  init_nat_k (&kv, *addr, port, fib_index, proto);
   t = is_in ? &tsm->in2out : &tsm->out2in;
   if (!clib_bihash_search_8_8 (t, &kv, &value))
     {
   t = is_in ? &tsm->in2out : &tsm->out2in;
   if (!clib_bihash_search_8_8 (t, &kv, &value))
     {
@@ -4484,8 +4390,7 @@ nat44_del_ed_session (snat_main_t * sm, ip4_address_t * addr, u16 port,
     tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
 
   t = is_in ? &tsm->in2out_ed : &sm->out2in_ed;
     tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
 
   t = is_in ? &tsm->in2out_ed : &sm->out2in_ed;
-  make_ed_kv (addr, eh_addr, proto, fib_index, clib_host_to_net_u16 (port),
-             clib_host_to_net_u16 (eh_port), ~0, ~0, &kv);
+  init_ed_k (&kv, *addr, port, *eh_addr, eh_port, fib_index, proto);
   if (clib_bihash_search_16_8 (t, &kv, &value))
     {
       return VNET_API_ERROR_NO_SUCH_ENTRY;
   if (clib_bihash_search_16_8 (t, &kv, &value))
     {
       return VNET_API_ERROR_NO_SUCH_ENTRY;
index fbf2105..8b04e18 100644 (file)
@@ -68,21 +68,6 @@ typedef struct
   u32 arc_next_index;
 } nat_pre_trace_t;
 
   u32 arc_next_index;
 } nat_pre_trace_t;
 
-/* session key (4-tuple) */
-typedef struct
-{
-  union
-  {
-    struct
-    {
-      ip4_address_t addr;
-      u16 port;
-      u16 protocol:3, fib_index:13;
-    };
-    u64 as_u64;
-  };
-} snat_session_key_t;
-
 /* deterministic session outside key */
 typedef struct
 {
 /* deterministic session outside key */
 typedef struct
 {
@@ -251,11 +236,23 @@ typedef enum
 /* *INDENT-OFF* */
 typedef CLIB_PACKED(struct
 {
 /* *INDENT-OFF* */
 typedef CLIB_PACKED(struct
 {
-  /* Outside network key */
-  snat_session_key_t out2in;
+  /* Outside network tuple */
+  struct
+  {
+    ip4_address_t addr;
+    u32 fib_index;
+    u16 port;
+  } out2in;
 
 
-  /* Inside network key */
-  snat_session_key_t in2out;
+  /* Inside network tuple */
+  struct
+  {
+    ip4_address_t addr;
+    u32 fib_index;
+    u16 port;
+  } in2out;
+
+  nat_protocol_t nat_proto;
 
   /* Flags */
   u32 flags;
 
   /* Flags */
   u32 flags;
@@ -491,10 +488,13 @@ typedef u32 (snat_icmp_match_function_t) (struct snat_main_s * sm,
                                          vlib_node_runtime_t * node,
                                          u32 thread_index,
                                          vlib_buffer_t * b0,
                                          vlib_node_runtime_t * node,
                                          u32 thread_index,
                                          vlib_buffer_t * b0,
-                                         ip4_header_t * ip0, u8 * p_proto,
-                                         snat_session_key_t * p_value,
-                                         u8 * p_dont_translate, void *d,
-                                         void *e);
+                                         ip4_header_t * ip0,
+                                         ip4_address_t * addr,
+                                         u16 * port,
+                                         u32 * fib_index,
+                                         nat_protocol_t * proto,
+                                         void *d, void *e,
+                                         u8 * dont_translate);
 
 /* Return worker thread index for given packet */
 typedef u32 (snat_get_worker_in2out_function_t) (ip4_header_t * ip,
 
 /* Return worker thread index for given packet */
 typedef u32 (snat_get_worker_in2out_function_t) (ip4_header_t * ip,
@@ -511,7 +511,9 @@ typedef int (nat_alloc_out_addr_and_port_function_t) (snat_address_t *
                                                      addresses,
                                                      u32 fib_index,
                                                      u32 thread_index,
                                                      addresses,
                                                      u32 fib_index,
                                                      u32 thread_index,
-                                                     snat_session_key_t * k,
+                                                     nat_protocol_t proto,
+                                                     ip4_address_t * addr,
+                                                     u16 * port,
                                                      u16 port_per_thread,
                                                      u32 snat_thread_index);
 
                                                      u16 port_per_thread,
                                                      u32 snat_thread_index);
 
@@ -1008,48 +1010,54 @@ do                                                        \
 /* ICMP session match functions */
 u32 icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node,
                            u32 thread_index, vlib_buffer_t * b0,
 /* ICMP session match functions */
 u32 icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node,
                            u32 thread_index, vlib_buffer_t * b0,
-                           ip4_header_t * ip0, u8 * p_proto,
-                           snat_session_key_t * p_value,
-                           u8 * p_dont_translate, void *d, void *e);
+                           ip4_header_t * ip0, ip4_address_t * addr,
+                           u16 * port, u32 * fib_index,
+                           nat_protocol_t * proto, void *d, void *e,
+                           u8 * dont_translate);
 u32 icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
                            u32 thread_index, vlib_buffer_t * b0,
 u32 icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
                            u32 thread_index, vlib_buffer_t * b0,
-                           ip4_header_t * ip0, u8 * p_proto,
-                           snat_session_key_t * p_value,
-                           u8 * p_dont_translate, void *d, void *e);
+                           ip4_header_t * ip0, ip4_address_t * addr,
+                           u16 * port, u32 * fib_index,
+                           nat_protocol_t * proto, void *d, void *e,
+                           u8 * dont_translate);
 u32 icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node,
                            u32 thread_index, vlib_buffer_t * b0,
 u32 icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node,
                            u32 thread_index, vlib_buffer_t * b0,
-                           ip4_header_t * ip0, u8 * p_proto,
-                           snat_session_key_t * p_value,
-                           u8 * p_dont_translate, void *d, void *e);
+                           ip4_header_t * ip0, ip4_address_t * addr,
+                           u16 * port, u32 * fib_index,
+                           nat_protocol_t * proto, void *d, void *e,
+                           u8 * dont_translate);
 u32 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
                            u32 thread_index, vlib_buffer_t * b0,
 u32 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
                            u32 thread_index, vlib_buffer_t * b0,
-                           ip4_header_t * ip0, u8 * p_proto,
-                           snat_session_key_t * p_value,
-                           u8 * p_dont_translate, void *d, void *e);
+                           ip4_header_t * ip0, ip4_address_t * addr,
+                           u16 * port, u32 * fib_index,
+                           nat_protocol_t * proto, void *d, void *e,
+                           u8 * dont_translate);
 
 /* ICMP deterministic NAT session match functions */
 u32 icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
                           u32 thread_index, vlib_buffer_t * b0,
 
 /* ICMP deterministic NAT session match functions */
 u32 icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
                           u32 thread_index, vlib_buffer_t * b0,
-                          ip4_header_t * ip0, u8 * p_proto,
-                          snat_session_key_t * p_value,
-                          u8 * p_dont_translate, void *d, void *e);
+                          ip4_header_t * ip0, ip4_address_t * addr,
+                          u16 * port, u32 * fib_index,
+                          nat_protocol_t * proto, void *d, void *e,
+                          u8 * dont_translate);
 u32 icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
                           u32 thread_index, vlib_buffer_t * b0,
 u32 icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
                           u32 thread_index, vlib_buffer_t * b0,
-                          ip4_header_t * ip0, u8 * p_proto,
-                          snat_session_key_t * p_value,
-                          u8 * p_dont_translate, void *d, void *e);
+                          ip4_header_t * ip0, ip4_address_t * addr,
+                          u16 * port, u32 * fib_index,
+                          nat_protocol_t * proto, void *d, void *e,
+                          u8 * dont_translate);
 
 /* ICMP endpoint-dependent session match functions */
 u32 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
                          u32 thread_index, vlib_buffer_t * b0,
 
 /* ICMP endpoint-dependent session match functions */
 u32 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
                          u32 thread_index, vlib_buffer_t * b0,
-                         ip4_header_t * ip0, u8 * p_proto,
-                         snat_session_key_t * p_value,
-                         u8 * p_dont_translate, void *d, void *e);
+                         ip4_header_t * ip0, ip4_address_t * addr,
+                         u16 * port, u32 * fib_index, nat_protocol_t * proto,
+                         void *d, void *e, u8 * dont_translate);
 u32 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
                          u32 thread_index, vlib_buffer_t * b0,
 u32 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
                          u32 thread_index, vlib_buffer_t * b0,
-                         ip4_header_t * ip0, u8 * p_proto,
-                         snat_session_key_t * p_value,
-                         u8 * p_dont_translate, void *d, void *e);
+                         ip4_header_t * ip0, ip4_address_t * addr,
+                         u16 * port, u32 * fib_index, nat_protocol_t * proto,
+                         void *d, void *e, u8 * dont_translate);
 
 u32 icmp_in2out (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0,
                 icmp46_header_t * icmp0, u32 sw_if_index0, u32 rx_fib_index0,
 
 u32 icmp_in2out (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0,
                 icmp46_header_t * icmp0, u32 sw_if_index0, u32 rx_fib_index0,
@@ -1348,11 +1356,13 @@ void nat_set_alloc_addr_and_port_default (void);
  *
  * @param addresses    vector of outside addresses
  * @param thread_index thread index
  *
  * @param addresses    vector of outside addresses
  * @param thread_index thread index
- * @param k            address, port and protocol
+ * @param key          address, port and protocol
  */
  */
-void snat_free_outside_address_and_port (snat_address_t * addresses,
-                                        u32 thread_index,
-                                        snat_session_key_t * k);
+void
+snat_free_outside_address_and_port (snat_address_t * addresses,
+                                   u32 thread_index,
+                                   ip4_address_t * addr,
+                                   u16 port, nat_protocol_t protocol);
 
 /**
  * @brief Alloc outside address and port
 
 /**
  * @brief Alloc outside address and port
@@ -1360,7 +1370,6 @@ void snat_free_outside_address_and_port (snat_address_t * addresses,
  * @param addresses         vector of outside addresses
  * @param fib_index         FIB table index
  * @param thread_index      thread index
  * @param addresses         vector of outside addresses
  * @param fib_index         FIB table index
  * @param thread_index      thread index
- * @param k                 allocated address and port pair
  * @param port_per_thread   number of ports per thread
  * @param snat_thread_index NAT thread index
  *
  * @param port_per_thread   number of ports per thread
  * @param snat_thread_index NAT thread index
  *
@@ -1369,15 +1378,19 @@ void snat_free_outside_address_and_port (snat_address_t * addresses,
 int snat_alloc_outside_address_and_port (snat_address_t * addresses,
                                         u32 fib_index,
                                         u32 thread_index,
 int snat_alloc_outside_address_and_port (snat_address_t * addresses,
                                         u32 fib_index,
                                         u32 thread_index,
-                                        snat_session_key_t * k,
+                                        nat_protocol_t proto,
+                                        ip4_address_t * addr,
+                                        u16 * port,
                                         u16 port_per_thread,
                                         u32 snat_thread_index);
 
 /**
  * @brief Match NAT44 static mapping.
  *
                                         u16 port_per_thread,
                                         u32 snat_thread_index);
 
 /**
  * @brief Match NAT44 static mapping.
  *
- * @param match         address and port to match
- * @param mapping       external/local address and port of the matched mapping
+ * @param key           address and port to match
+ * @param addr          external/local address of the matched mapping
+ * @param port          port of the matched mapping
+ * @param fib_index     fib index of the matched mapping
  * @param by_external   if 0 match by local address otherwise match by external
  *                      address
  * @param is_addr_only  1 if matched mapping is address only
  * @param by_external   if 0 match by local address otherwise match by external
  *                      address
  * @param is_addr_only  1 if matched mapping is address only
@@ -1388,8 +1401,13 @@ int snat_alloc_outside_address_and_port (snat_address_t * addresses,
  * @returns 0 if match found otherwise 1.
  */
 int snat_static_mapping_match (snat_main_t * sm,
  * @returns 0 if match found otherwise 1.
  */
 int snat_static_mapping_match (snat_main_t * sm,
-                              snat_session_key_t match,
-                              snat_session_key_t * mapping,
+                              ip4_address_t match_addr,
+                              u16 match_port,
+                              u32 match_fib_index,
+                              nat_protocol_t match_protocol,
+                              ip4_address_t * mapping_addr,
+                              u16 * mapping_port,
+                              u32 * mapping_fib_index,
                               u8 by_external,
                               u8 * is_addr_only,
                               twice_nat_type_t * twice_nat,
                               u8 by_external,
                               u8 * is_addr_only,
                               twice_nat_type_t * twice_nat,
index bb3584e..54c52e3 100644 (file)
@@ -104,7 +104,6 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
          u32 next0 = NAT44_CLASSIFY_NEXT_IN2OUT;
          ip4_header_t *ip0;
          snat_address_t *ap;
          u32 next0 = NAT44_CLASSIFY_NEXT_IN2OUT;
          ip4_header_t *ip0;
          snat_address_t *ap;
-         snat_session_key_t m_key0;
          clib_bihash_kv_8_8_t kv0, value0;
 
          /* speculatively enqueue b0 to the current next frame */
          clib_bihash_kv_8_8_t kv0, value0;
 
          /* speculatively enqueue b0 to the current next frame */
@@ -131,11 +130,7 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
-             m_key0.addr = ip0->dst_address;
-             m_key0.port = 0;
-             m_key0.protocol = 0;
-             m_key0.fib_index = 0;
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
@@ -145,10 +140,9 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                    next0 = NAT44_CLASSIFY_NEXT_OUT2IN;
                  goto enqueue0;
                }
                    next0 = NAT44_CLASSIFY_NEXT_OUT2IN;
                  goto enqueue0;
                }
-             m_key0.port =
-               clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port);
-             m_key0.protocol = ip_proto_to_nat_proto (ip0->protocol);
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address,
+                         vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
+                         ip_proto_to_nat_proto (ip0->protocol));
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
@@ -221,7 +215,6 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
          u32 next0 = NAT_NEXT_IN2OUT_CLASSIFY;
          ip4_header_t *ip0;
          snat_address_t *ap;
          u32 next0 = NAT_NEXT_IN2OUT_CLASSIFY;
          ip4_header_t *ip0;
          snat_address_t *ap;
-         snat_session_key_t m_key0;
          clib_bihash_kv_8_8_t kv0, value0;
 
          /* speculatively enqueue b0 to the current next frame */
          clib_bihash_kv_8_8_t kv0, value0;
 
          /* speculatively enqueue b0 to the current next frame */
@@ -248,11 +241,7 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
-             m_key0.addr = ip0->dst_address;
-             m_key0.port = 0;
-             m_key0.protocol = 0;
-             m_key0.fib_index = 0;
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
@@ -262,10 +251,9 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
                    next0 = NAT_NEXT_OUT2IN_CLASSIFY;
                  goto enqueue0;
                }
                    next0 = NAT_NEXT_OUT2IN_CLASSIFY;
                  goto enqueue0;
                }
-             m_key0.port =
-               clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port);
-             m_key0.protocol = ip_proto_to_nat_proto (ip0->protocol);
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address,
+                         vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
+                         ip_proto_to_nat_proto (ip0->protocol));
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
@@ -340,7 +328,6 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
          u32 sw_if_index0, rx_fib_index0;
          ip4_header_t *ip0;
          snat_address_t *ap;
          u32 sw_if_index0, rx_fib_index0;
          ip4_header_t *ip0;
          snat_address_t *ap;
-         snat_session_key_t m_key0;
          clib_bihash_kv_8_8_t kv0, value0;
          clib_bihash_kv_16_8_t ed_kv0, ed_value0;
 
          clib_bihash_kv_8_8_t kv0, value0;
          clib_bihash_kv_16_8_t ed_kv0, ed_value0;
 
@@ -366,11 +353,11 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
              rx_fib_index0 =
                fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
                                                     sw_if_index0);
              rx_fib_index0 =
                fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
                                                     sw_if_index0);
-             make_ed_kv (&ip0->src_address, &ip0->dst_address,
-                         ip0->protocol, rx_fib_index0,
-                         vnet_buffer (b0)->ip.reass.l4_src_port,
-                         vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0,
-                         &ed_kv0);
+             init_ed_k (&ed_kv0, ip0->src_address,
+                        vnet_buffer (b0)->ip.reass.l4_src_port,
+                        ip0->dst_address,
+                        vnet_buffer (b0)->ip.reass.l4_dst_port,
+                        rx_fib_index0, ip0->protocol);
              /* process whole packet */
              if (!clib_bihash_search_16_8
                  (&tsm->in2out_ed, &ed_kv0, &ed_value0))
              /* process whole packet */
              if (!clib_bihash_search_16_8
                  (&tsm->in2out_ed, &ed_kv0, &ed_value0))
@@ -391,11 +378,7 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
-             m_key0.addr = ip0->dst_address;
-             m_key0.port = 0;
-             m_key0.protocol = 0;
-             m_key0.fib_index = 0;
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
@@ -405,10 +388,9 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
                    next0 = NAT_NEXT_OUT2IN_ED_FAST_PATH;
                  goto enqueue0;
                }
                    next0 = NAT_NEXT_OUT2IN_ED_FAST_PATH;
                  goto enqueue0;
                }
-             m_key0.port =
-               clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port);
-             m_key0.protocol = ip_proto_to_nat_proto (ip0->protocol);
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address,
+                         vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
+                         ip_proto_to_nat_proto (ip0->protocol));
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
index 68ed0cb..ffc5fd4 100644 (file)
@@ -674,7 +674,7 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
             if (now >= sess_timeout_time)
               timed_out++;
 
             if (now >= sess_timeout_time)
               timed_out++;
 
-            switch (s->in2out.protocol)
+            switch (s->nat_proto)
               {
               case NAT_PROTOCOL_ICMP:
                 icmp_sessions++;
               {
               case NAT_PROTOCOL_ICMP:
                 icmp_sessions++;
@@ -720,7 +720,7 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
         if (now >= sess_timeout_time)
           timed_out++;
 
         if (now >= sess_timeout_time)
           timed_out++;
 
-        switch (s->in2out.protocol)
+        switch (s->nat_proto)
           {
           case NAT_PROTOCOL_ICMP:
             icmp_sessions++;
           {
           case NAT_PROTOCOL_ICMP:
             icmp_sessions++;
@@ -1071,7 +1071,8 @@ add_static_mapping_command_fn (vlib_main_t * vm,
       goto done;
     }
 
       goto done;
     }
 
-  rv = snat_add_static_mapping (l_addr, e_addr, (u16) l_port, (u16) e_port,
+  rv = snat_add_static_mapping (l_addr, e_addr, clib_host_to_net_u16 (l_port),
+                               clib_host_to_net_u16 (e_port),
                                vrf_id, addr_only, sw_if_index, proto, is_add,
                                twice_nat, out2in_only, 0, 0);
 
                                vrf_id, addr_only, sw_if_index, proto, is_add,
                                twice_nat, out2in_only, 0, 0);
 
@@ -1155,9 +1156,10 @@ add_identity_mapping_command_fn (vlib_main_t * vm,
        }
     }
 
        }
     }
 
-  rv = snat_add_static_mapping (addr, addr, (u16) port, (u16) port,
-                               vrf_id, addr_only, sw_if_index, proto, is_add,
-                               0, 0, 0, 1);
+  rv =
+    snat_add_static_mapping (addr, addr, clib_host_to_net_u16 (port),
+                            clib_host_to_net_u16 (port), vrf_id, addr_only,
+                            sw_if_index, proto, is_add, 0, 0, 0, 1);
 
   switch (rv)
     {
 
   switch (rv)
     {
@@ -1730,10 +1732,13 @@ nat44_del_session_command_fn (vlib_main_t * vm,
 
   if (is_ed)
     rv =
 
   if (is_ed)
     rv =
-      nat44_del_ed_session (sm, &addr, port, &eh_addr, eh_port,
+      nat44_del_ed_session (sm, &addr, clib_host_to_net_u16 (port), &eh_addr,
+                           clib_host_to_net_u16 (eh_port),
                            nat_proto_to_ip_proto (proto), vrf_id, is_in);
   else
                            nat_proto_to_ip_proto (proto), vrf_id, is_in);
   else
-    rv = nat44_del_session (sm, &addr, port, proto, vrf_id, is_in);
+    rv =
+      nat44_del_session (sm, &addr, clib_host_to_net_u16 (port), proto,
+                        vrf_id, is_in);
 
   switch (rv)
     {
 
   switch (rv)
     {
index 1c91bd7..f15de95 100644 (file)
@@ -93,7 +93,6 @@ is_hairpinning (snat_main_t * sm, ip4_address_t * dst_addr)
 {
   snat_address_t *ap;
   clib_bihash_kv_8_8_t kv, value;
 {
   snat_address_t *ap;
   clib_bihash_kv_8_8_t kv, value;
-  snat_session_key_t m_key;
 
   /* *INDENT-OFF* */
   vec_foreach (ap, sm->addresses)
 
   /* *INDENT-OFF* */
   vec_foreach (ap, sm->addresses)
@@ -103,11 +102,7 @@ is_hairpinning (snat_main_t * sm, ip4_address_t * dst_addr)
     }
   /* *INDENT-ON* */
 
     }
   /* *INDENT-ON* */
 
-  m_key.addr.as_u32 = dst_addr->as_u32;
-  m_key.fib_index = 0;
-  m_key.port = 0;
-  m_key.protocol = 0;
-  kv.key = m_key.as_u64;
+  init_nat_k (&kv, *dst_addr, 0, 0, 0);
   if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     return 1;
 
   if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     return 1;
 
@@ -121,26 +116,23 @@ snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node,
                  udp_header_t * udp0, tcp_header_t * tcp0, u32 proto0,
                  int is_ed, int do_trace)
 {
                  udp_header_t * udp0, tcp_header_t * tcp0, u32 proto0,
                  int is_ed, int do_trace)
 {
-  snat_session_key_t key0, sm0;
   snat_session_t *s0 = NULL;
   clib_bihash_kv_8_8_t kv0, value0;
   ip_csum_t sum0;
   u32 new_dst_addr0 = 0, old_dst_addr0, ti = 0, si = ~0;
   u16 new_dst_port0 = ~0, old_dst_port0;
   int rv;
   snat_session_t *s0 = NULL;
   clib_bihash_kv_8_8_t kv0, value0;
   ip_csum_t sum0;
   u32 new_dst_addr0 = 0, old_dst_addr0, ti = 0, si = ~0;
   u16 new_dst_port0 = ~0, old_dst_port0;
   int rv;
-
-  key0.addr = ip0->dst_address;
-  key0.port = udp0->dst_port;
-  key0.protocol = proto0;
-  key0.fib_index = sm->outside_fib_index;
-  kv0.key = key0.as_u64;
-
+  ip4_address_t sm0_addr;
+  u16 sm0_port;
+  u32 sm0_fib_index;
   /* Check if destination is static mappings */
   /* Check if destination is static mappings */
-  if (!snat_static_mapping_match (sm, key0, &sm0, 1, 0, 0, 0, 0, 0))
+  if (!snat_static_mapping_match
+      (sm, ip0->dst_address, udp0->dst_port, sm->outside_fib_index, proto0,
+       &sm0_addr, &sm0_port, &sm0_fib_index, 1, 0, 0, 0, 0, 0))
     {
     {
-      new_dst_addr0 = sm0.addr.as_u32;
-      new_dst_port0 = sm0.port;
-      vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index;
+      new_dst_addr0 = sm0_addr.as_u32;
+      new_dst_port0 = sm0_port;
+      vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0_fib_index;
     }
   /* or active session */
   else
     }
   /* or active session */
   else
@@ -155,17 +147,21 @@ snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node,
       if (is_ed)
        {
          clib_bihash_kv_16_8_t ed_kv, ed_value;
       if (is_ed)
        {
          clib_bihash_kv_16_8_t ed_kv, ed_value;
-         make_ed_kv (&ip0->dst_address, &ip0->src_address,
-                     ip0->protocol, sm->outside_fib_index, udp0->dst_port,
-                     udp0->src_port, ~0, ~0, &ed_kv);
+         init_ed_k (&ed_kv, ip0->dst_address, udp0->dst_port,
+                    ip0->src_address, udp0->src_port, sm->outside_fib_index,
+                    ip0->protocol);
          rv = clib_bihash_search_16_8 (&sm->out2in_ed, &ed_kv, &ed_value);
          ASSERT (ti == ed_value_get_thread_index (&ed_value));
          si = ed_value_get_session_index (&ed_value);
        }
       else
        {
          rv = clib_bihash_search_16_8 (&sm->out2in_ed, &ed_kv, &ed_value);
          ASSERT (ti == ed_value_get_thread_index (&ed_value));
          si = ed_value_get_session_index (&ed_value);
        }
       else
        {
-         rv = clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0,
-                                      &value0);
+
+         init_nat_k (&kv0, ip0->dst_address, udp0->dst_port,
+                     sm->outside_fib_index, proto0);
+         rv =
+           clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0,
+                                   &value0);
          si = value0.value;
        }
       if (rv)
          si = value0.value;
        }
       if (rv)
@@ -250,7 +246,6 @@ snat_icmp_hairpinning (snat_main_t * sm,
                       vlib_buffer_t * b0,
                       ip4_header_t * ip0, icmp46_header_t * icmp0, int is_ed)
 {
                       vlib_buffer_t * b0,
                       ip4_header_t * ip0, icmp46_header_t * icmp0, int is_ed)
 {
-  snat_session_key_t key0;
   clib_bihash_kv_8_8_t kv0, value0;
   u32 old_dst_addr0, new_dst_addr0;
   u32 old_addr0, new_addr0;
   clib_bihash_kv_8_8_t kv0, value0;
   u32 old_dst_addr0, new_dst_addr0;
   u32 old_addr0, new_addr0;
@@ -277,10 +272,9 @@ snat_icmp_hairpinning (snat_main_t * sm,
       if (is_ed)
        {
          clib_bihash_kv_16_8_t ed_kv, ed_value;
       if (is_ed)
        {
          clib_bihash_kv_16_8_t ed_kv, ed_value;
-         make_ed_kv (&ip0->dst_address, &ip0->src_address,
-                     inner_ip0->protocol, sm->outside_fib_index,
-                     l4_header->src_port, l4_header->dst_port, ~0, ~0,
-                     &ed_kv);
+         init_ed_k (&ed_kv, ip0->dst_address, l4_header->src_port,
+                    ip0->src_address, l4_header->dst_port,
+                    sm->outside_fib_index, inner_ip0->protocol);
          if (clib_bihash_search_16_8 (&sm->out2in_ed, &ed_kv, &ed_value))
            return 1;
          ASSERT (ti == ed_value_get_thread_index (&ed_value));
          if (clib_bihash_search_16_8 (&sm->out2in_ed, &ed_kv, &ed_value))
            return 1;
          ASSERT (ti == ed_value_get_thread_index (&ed_value));
@@ -288,13 +282,10 @@ snat_icmp_hairpinning (snat_main_t * sm,
        }
       else
        {
        }
       else
        {
-         key0.addr = ip0->dst_address;
-         key0.port = l4_header->src_port;
-         key0.protocol = protocol;
-         key0.fib_index = sm->outside_fib_index;
-         kv0.key = key0.as_u64;
-         if (clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0,
-                                     &value0))
+         init_nat_k (&kv0, ip0->dst_address, l4_header->src_port,
+                     sm->outside_fib_index, protocol);
+         if (clib_bihash_search_8_8
+             (&sm->per_thread_data[ti].out2in, &kv0, &value0))
            return 1;
          si = value0.value;
        }
            return 1;
          si = value0.value;
        }
@@ -334,12 +325,7 @@ snat_icmp_hairpinning (snat_main_t * sm,
     }
   else
     {
     }
   else
     {
-      key0.addr = ip0->dst_address;
-      key0.port = 0;
-      key0.protocol = 0;
-      key0.fib_index = sm->outside_fib_index;
-      kv0.key = key0.as_u64;
-
+      init_nat_k (&kv0, ip0->dst_address, 0, sm->outside_fib_index, 0);
       if (clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv0, &value0))
        {
       if (clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv0, &value0))
        {
@@ -347,11 +333,8 @@ snat_icmp_hairpinning (snat_main_t * sm,
            {
              icmp_echo_header_t *echo0 = (icmp_echo_header_t *) (icmp0 + 1);
              u16 icmp_id0 = echo0->identifier;
            {
              icmp_echo_header_t *echo0 = (icmp_echo_header_t *) (icmp0 + 1);
              u16 icmp_id0 = echo0->identifier;
-             key0.addr = ip0->dst_address;
-             key0.port = icmp_id0;
-             key0.protocol = NAT_PROTOCOL_ICMP;
-             key0.fib_index = sm->outside_fib_index;
-             kv0.key = key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address, icmp_id0,
+                         sm->outside_fib_index, NAT_PROTOCOL_ICMP);
              if (sm->num_workers > 1)
                ti =
                  (clib_net_to_host_u16 (icmp_id0) -
              if (sm->num_workers > 1)
                ti =
                  (clib_net_to_host_u16 (icmp_id0) -
@@ -412,7 +395,7 @@ nat_hairpinning_sm_unknown_proto (snat_main_t * sm,
   u32 old_addr, new_addr;
   ip_csum_t sum;
 
   u32 old_addr, new_addr;
   ip_csum_t sum;
 
-  make_sm_kv (&kv, &ip->dst_address, 0, 0, 0);
+  init_nat_k (&kv, ip->dst_address, 0, 0, 0);
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     return;
 
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     return;
 
@@ -447,11 +430,11 @@ nat44_ed_hairpinning_unknown_proto (snat_main_t * sm,
     ti = sm->num_workers;
 
   old_addr = ip->dst_address.as_u32;
     ti = sm->num_workers;
 
   old_addr = ip->dst_address.as_u32;
-  make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
-             sm->outside_fib_index, 0, 0, ~0, ~0, &s_kv);
+  init_ed_k (&s_kv, ip->dst_address, 0, ip->src_address, 0,
+            sm->outside_fib_index, ip->protocol);
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
     {
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
     {
-      make_sm_kv (&kv, &ip->dst_address, 0, 0, 0);
+      init_nat_k (&kv, ip->dst_address, 0, 0, 0);
       if (clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        return;
       if (clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        return;
index 6c5bfc1..9fc3344 100644 (file)
@@ -530,24 +530,16 @@ nat64_alloc_out_addr_and_port (u32 fib_index, nat_protocol_t proto,
 {
   nat64_main_t *nm = &nat64_main;
   snat_main_t *sm = nm->sm;
 {
   nat64_main_t *nm = &nat64_main;
   snat_main_t *sm = nm->sm;
-  snat_session_key_t k;
   u32 worker_index = 0;
   int rv;
 
   u32 worker_index = 0;
   int rv;
 
-  k.protocol = proto;
-
   if (sm->num_workers > 1)
     worker_index = thread_index - sm->first_worker_index;
 
   rv =
   if (sm->num_workers > 1)
     worker_index = thread_index - sm->first_worker_index;
 
   rv =
-    sm->alloc_addr_and_port (nm->addr_pool, fib_index, thread_index, &k,
-                            sm->port_per_thread, worker_index);
-
-  if (!rv)
-    {
-      *port = k.port;
-      addr->as_u32 = k.addr.as_u32;
-    }
+    sm->alloc_addr_and_port (nm->addr_pool, fib_index, thread_index,
+                            proto, addr, port, sm->port_per_thread,
+                            worker_index);
 
   return rv;
 }
 
   return rv;
 }
index abd1d86..9d1ed1b 100644 (file)
@@ -1110,8 +1110,8 @@ static void
 
   if (!(mp->flags & NAT_API_IS_ADDR_ONLY))
     {
 
   if (!(mp->flags & NAT_API_IS_ADDR_ONLY))
     {
-      local_port = clib_net_to_host_u16 (mp->local_port);
-      external_port = clib_net_to_host_u16 (mp->external_port);
+      local_port = mp->local_port;
+      external_port = mp->external_port;
     }
 
   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
     }
 
   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
@@ -1201,8 +1201,8 @@ send_nat44_static_mapping_details (snat_static_mapping_t * m,
   else
     {
       rmp->protocol = nat_proto_to_ip_proto (m->proto);
   else
     {
       rmp->protocol = nat_proto_to_ip_proto (m->proto);
-      rmp->external_port = htons (m->external_port);
-      rmp->local_port = htons (m->local_port);
+      rmp->external_port = m->external_port;
+      rmp->local_port = m->local_port;
     }
 
   if (m->tag)
     }
 
   if (m->tag)
@@ -1238,8 +1238,8 @@ send_nat44_static_map_resolve_details (snat_static_map_resolve_t * m,
   else
     {
       rmp->protocol = nat_proto_to_ip_proto (m->proto);
   else
     {
       rmp->protocol = nat_proto_to_ip_proto (m->proto);
-      rmp->external_port = htons (m->e_port);
-      rmp->local_port = htons (m->l_port);
+      rmp->external_port = m->e_port;
+      rmp->local_port = m->l_port;
     }
   if (m->tag)
     strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
     }
   if (m->tag)
     strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
@@ -1312,7 +1312,7 @@ static void
 
   if (!(mp->flags & NAT_API_IS_ADDR_ONLY))
     {
 
   if (!(mp->flags & NAT_API_IS_ADDR_ONLY))
     {
-      port = clib_net_to_host_u16 (mp->port);
+      port = mp->port;
       proto = ip_proto_to_nat_proto (mp->protocol);
     }
   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
       proto = ip_proto_to_nat_proto (mp->protocol);
     }
   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
@@ -1374,7 +1374,7 @@ send_nat44_identity_mapping_details (snat_static_mapping_t * m, int index,
     rmp->flags |= NAT_API_IS_ADDR_ONLY;
 
   clib_memcpy (rmp->ip_address, &(m->local_addr), 4);
     rmp->flags |= NAT_API_IS_ADDR_ONLY;
 
   clib_memcpy (rmp->ip_address, &(m->local_addr), 4);
-  rmp->port = htons (m->local_port);
+  rmp->port = m->local_port;
   rmp->sw_if_index = ~0;
   rmp->vrf_id = htonl (local->vrf_id);
   rmp->protocol = nat_proto_to_ip_proto (m->proto);
   rmp->sw_if_index = ~0;
   rmp->vrf_id = htonl (local->vrf_id);
   rmp->protocol = nat_proto_to_ip_proto (m->proto);
@@ -1401,7 +1401,7 @@ send_nat44_identity_map_resolve_details (snat_static_map_resolve_t * m,
   if (m->addr_only)
     rmp->flags = (vl_api_nat_config_flags_t) NAT_API_IS_ADDR_ONLY;
 
   if (m->addr_only)
     rmp->flags = (vl_api_nat_config_flags_t) NAT_API_IS_ADDR_ONLY;
 
-  rmp->port = htons (m->l_port);
+  rmp->port = m->l_port;
   rmp->sw_if_index = htonl (m->sw_if_index);
   rmp->vrf_id = htonl (m->vrf_id);
   rmp->protocol = nat_proto_to_ip_proto (m->proto);
   rmp->sw_if_index = htonl (m->sw_if_index);
   rmp->vrf_id = htonl (m->vrf_id);
   rmp->protocol = nat_proto_to_ip_proto (m->proto);
@@ -1719,7 +1719,7 @@ send_nat44_user_session_details (snat_session_t * s,
     {
       rmp->outside_port = s->out2in.port;
       rmp->inside_port = s->in2out.port;
     {
       rmp->outside_port = s->out2in.port;
       rmp->inside_port = s->in2out.port;
-      rmp->protocol = ntohs (nat_proto_to_ip_proto (s->in2out.protocol));
+      rmp->protocol = ntohs (nat_proto_to_ip_proto (s->nat_proto));
     }
   if (is_ed_session (s) || is_fwd_bypass_session (s))
     {
     }
   if (is_ed_session (s) || is_fwd_bypass_session (s))
     {
@@ -1831,7 +1831,7 @@ unformat_nat44_lb_addr_port (vl_api_nat44_lb_addr_port_t * addr_port_pairs,
       ap = &addr_port_pairs[i];
       clib_memset (&lb_addr_port, 0, sizeof (lb_addr_port));
       clib_memcpy (&lb_addr_port.addr, ap->addr, 4);
       ap = &addr_port_pairs[i];
       clib_memset (&lb_addr_port, 0, sizeof (lb_addr_port));
       clib_memcpy (&lb_addr_port.addr, ap->addr, 4);
-      lb_addr_port.port = clib_net_to_host_u16 (ap->port);
+      lb_addr_port.port = ap->port;
       lb_addr_port.probability = ap->probability;
       lb_addr_port.vrf_id = clib_net_to_host_u32 (ap->vrf_id);
       vec_add1 (lb_addr_port_pairs, lb_addr_port);
       lb_addr_port.probability = ap->probability;
       lb_addr_port.vrf_id = clib_net_to_host_u32 (ap->vrf_id);
       vec_add1 (lb_addr_port_pairs, lb_addr_port);
@@ -1875,7 +1875,7 @@ static void
 
   rv =
     nat44_add_del_lb_static_mapping (e_addr,
 
   rv =
     nat44_add_del_lb_static_mapping (e_addr,
-                                    clib_net_to_host_u16 (mp->external_port),
+                                    mp->external_port,
                                     proto, locals, mp->is_add,
                                     twice_nat,
                                     mp->flags & NAT_API_IS_OUT2IN_ONLY, tag,
                                     proto, locals, mp->is_add,
                                     twice_nat,
                                     mp->flags & NAT_API_IS_OUT2IN_ONLY, tag,
@@ -1968,7 +1968,7 @@ send_nat44_lb_static_mapping_details (snat_static_mapping_t * m,
     ntohs (VL_API_NAT44_LB_STATIC_MAPPING_DETAILS + sm->msg_id_base);
 
   clib_memcpy (rmp->external_addr, &(m->external_addr), 4);
     ntohs (VL_API_NAT44_LB_STATIC_MAPPING_DETAILS + sm->msg_id_base);
 
   clib_memcpy (rmp->external_addr, &(m->external_addr), 4);
-  rmp->external_port = ntohs (m->external_port);
+  rmp->external_port = m->external_port;
   rmp->protocol = nat_proto_to_ip_proto (m->proto);
   rmp->context = context;
 
   rmp->protocol = nat_proto_to_ip_proto (m->proto);
   rmp->context = context;
 
@@ -1986,7 +1986,7 @@ send_nat44_lb_static_mapping_details (snat_static_mapping_t * m,
   pool_foreach (ap, m->locals,
   ({
     clib_memcpy (locals->addr, &(ap->addr), 4);
   pool_foreach (ap, m->locals,
   ({
     clib_memcpy (locals->addr, &(ap->addr), 4);
-    locals->port = htons (ap->port);
+    locals->port = ap->port;
     locals->probability = ap->probability;
     locals->vrf_id = ntohl (ap->vrf_id);
     locals++;
     locals->probability = ap->probability;
     locals->vrf_id = ntohl (ap->vrf_id);
     locals++;
@@ -2051,11 +2051,11 @@ vl_api_nat44_del_session_t_handler (vl_api_nat44_del_session_t * mp)
     }
 
   memcpy (&addr.as_u8, mp->address, 4);
     }
 
   memcpy (&addr.as_u8, mp->address, 4);
-  port = clib_net_to_host_u16 (mp->port);
+  port = mp->port;
   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
   proto = ip_proto_to_nat_proto (mp->protocol);
   memcpy (&eh_addr.as_u8, mp->ext_host_address, 4);
   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
   proto = ip_proto_to_nat_proto (mp->protocol);
   memcpy (&eh_addr.as_u8, mp->ext_host_address, 4);
-  eh_port = clib_net_to_host_u16 (mp->ext_host_port);
+  eh_port = mp->ext_host_port;
 
   is_in = mp->flags & NAT_API_IS_INSIDE;
 
 
   is_in = mp->flags & NAT_API_IS_INSIDE;
 
index 8628fcc..b9b9405 100644 (file)
@@ -96,17 +96,17 @@ format_nat_det_in2out_trace (u8 * s, va_list * args)
 u32
 icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
                       u32 thread_index, vlib_buffer_t * b0,
 u32
 icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
                       u32 thread_index, vlib_buffer_t * b0,
-                      ip4_header_t * ip0, u8 * p_proto,
-                      snat_session_key_t * p_value, u8 * p_dont_translate,
-                      void *d, void *e)
+                      ip4_header_t * ip0, ip4_address_t * addr,
+                      u16 * port, u32 * fib_index,
+                      nat_protocol_t * proto, void *d, void *e,
+                      u8 * dont_translate)
 {
   vlib_main_t *vm = vlib_get_main ();
   icmp46_header_t *icmp0;
   u32 sw_if_index0;
   u32 rx_fib_index0;
 {
   vlib_main_t *vm = vlib_get_main ();
   icmp46_header_t *icmp0;
   u32 sw_if_index0;
   u32 rx_fib_index0;
-  u8 protocol;
+  nat_protocol_t protocol;
   snat_det_out_key_t key0;
   snat_det_out_key_t key0;
-  u8 dont_translate = 0;
   u32 next0 = ~0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0;
   u32 next0 = ~0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0;
@@ -118,6 +118,7 @@ icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
   snat_det_session_t *ses0 = 0;
   ip4_address_t in_addr;
   u16 in_port;
   snat_det_session_t *ses0 = 0;
   ip4_address_t in_addr;
   u16 in_port;
+  *dont_translate = 0;
 
   icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
   echo0 = (icmp_echo_header_t *) (icmp0 + 1);
 
   icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
   echo0 = (icmp_echo_header_t *) (icmp0 + 1);
@@ -165,7 +166,7 @@ icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
                                                  IP_PROTOCOL_ICMP,
                                                  rx_fib_index0)))
        {
                                                  IP_PROTOCOL_ICMP,
                                                  rx_fib_index0)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
       next0 = NAT_DET_IN2OUT_NEXT_DROP;
          goto out;
        }
       next0 = NAT_DET_IN2OUT_NEXT_DROP;
@@ -185,7 +186,7 @@ icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
                                                  IP_PROTOCOL_ICMP,
                                                  rx_fib_index0)))
        {
                                                  IP_PROTOCOL_ICMP,
                                                  rx_fib_index0)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
       if (icmp0->type != ICMP4_echo_request)
          goto out;
        }
       if (icmp0->type != ICMP4_echo_request)
@@ -234,14 +235,13 @@ icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
   ses0->expire = now + sm->icmp_timeout;
 
 out:
   ses0->expire = now + sm->icmp_timeout;
 
 out:
-  *p_proto = protocol;
+  *proto = protocol;
   if (ses0)
     {
   if (ses0)
     {
-      p_value->addr = new_addr0;
-      p_value->fib_index = sm->outside_fib_index;
-      p_value->port = ses0->out.out_port;
+      *addr = new_addr0;
+      *fib_index = sm->outside_fib_index;
+      *port = ses0->out.out_port;
     }
     }
-  *p_dont_translate = dont_translate;
   if (d)
     *(snat_det_session_t **) d = ses0;
   if (e)
   if (d)
     *(snat_det_session_t **) d = ses0;
   if (e)
index 80d9b39..5ca2afb 100644 (file)
@@ -95,15 +95,15 @@ format_nat_det_out2in_trace (u8 * s, va_list * args)
 u32
 icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
                       u32 thread_index, vlib_buffer_t * b0,
 u32
 icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
                       u32 thread_index, vlib_buffer_t * b0,
-                      ip4_header_t * ip0, u8 * p_proto,
-                      snat_session_key_t * p_value,
-                      u8 * p_dont_translate, void *d, void *e)
+                      ip4_header_t * ip0, ip4_address_t * addr,
+                      u16 * port, u32 * fib_index,
+                      nat_protocol_t * proto, void *d, void *e,
+                      u8 * dont_translate)
 {
   icmp46_header_t *icmp0;
   u32 sw_if_index0;
   u8 protocol;
   snat_det_out_key_t key0;
 {
   icmp46_header_t *icmp0;
   u32 sw_if_index0;
   u8 protocol;
   snat_det_out_key_t key0;
-  u8 dont_translate = 0;
   u32 next0 = ~0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0;
   u32 next0 = ~0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0;
@@ -113,6 +113,7 @@ icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
   ip4_address_t new_addr0 = { {0} };
   snat_det_session_t *ses0 = 0;
   ip4_address_t out_addr;
   ip4_address_t new_addr0 = { {0} };
   snat_det_session_t *ses0 = 0;
   ip4_address_t out_addr;
+  *dont_translate = 0;
 
   icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
   echo0 = (icmp_echo_header_t *) (icmp0 + 1);
 
   icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
   echo0 = (icmp_echo_header_t *) (icmp0 + 1);
@@ -162,7 +163,7 @@ icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
       if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
                                            ip0->dst_address.as_u32)))
        {
       if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
                                            ip0->dst_address.as_u32)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
       nat_log_info ("unknown dst address:  %U",
          goto out;
        }
       nat_log_info ("unknown dst address:  %U",
@@ -180,7 +181,7 @@ icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
       if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
                                            ip0->dst_address.as_u32)))
        {
       if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
                                            ip0->dst_address.as_u32)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
       nat_log_info ("no match src %U:%d dst %U:%d for user %U",
          goto out;
        }
       nat_log_info ("no match src %U:%d dst %U:%d for user %U",
@@ -207,14 +208,13 @@ icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
   goto out;
 
 out:
   goto out;
 
 out:
-  *p_proto = protocol;
+  *proto = protocol;
   if (ses0)
     {
   if (ses0)
     {
-      p_value->addr = new_addr0;
-      p_value->fib_index = sm->inside_fib_index;
-      p_value->port = ses0->in_port;
+      *addr = new_addr0;
+      *fib_index = sm->inside_fib_index;
+      *port = ses0->in_port;
     }
     }
-  *p_dont_translate = dont_translate;
   if (d)
     *(snat_det_session_t **) d = ses0;
   if (e)
   if (d)
     *(snat_det_session_t **) d = ses0;
   if (e)
index 33e9655..8287968 100644 (file)
@@ -76,23 +76,19 @@ format_nat_addr_and_port_alloc_alg (u8 * s, va_list * args)
 u8 *
 format_snat_key (u8 * s, va_list * args)
 {
 u8 *
 format_snat_key (u8 * s, va_list * args)
 {
-  snat_session_key_t *key = va_arg (*args, snat_session_key_t *);
+  u64 key = va_arg (*args, u64);
 
 
-  s = format (s, "%U proto %U port %d fib %d",
-             format_ip4_address, &key->addr,
-             format_nat_protocol, key->protocol,
-             clib_net_to_host_u16 (key->port), key->fib_index);
-  return s;
-}
+  ip4_address_t addr;
+  u16 port;
+  nat_protocol_t protocol;
+  u32 fib_index;
 
 
-u8 *
-format_static_mapping_key (u8 * s, va_list * args)
-{
-  snat_session_key_t *key = va_arg (*args, snat_session_key_t *);
+  split_nat_key (key, &addr, &port, &fib_index, &protocol);
 
   s = format (s, "%U proto %U port %d fib %d",
 
   s = format (s, "%U proto %U port %d fib %d",
-             format_ip4_address, &key->addr,
-             format_nat_protocol, key->protocol, key->port, key->fib_index);
+             format_ip4_address, &addr,
+             format_nat_protocol, protocol,
+             clib_net_to_host_u16 (port), fib_index);
   return s;
 }
 
   return s;
 }
 
index 7c28919..76dd9a7 100644 (file)
 #include <nat/nat.h>
 #include <nat/nat_ha.h>
 
 #include <nat/nat.h>
 #include <nat/nat_ha.h>
 
+always_inline u64
+calc_nat_key (ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
+{
+  ASSERT (fib_index <= (1 << 14) - 1);
+  ASSERT (proto <= (1 << 3) - 1);
+  return (u64) addr.as_u32 << 32 | (u64) port << 16 | fib_index << 3 |
+    (proto & 0x7);
+}
+
+always_inline void
+split_nat_key (u64 key, ip4_address_t * addr, u16 * port,
+              u32 * fib_index, nat_protocol_t * proto)
+{
+  if (addr)
+    {
+      addr->as_u32 = key >> 32;
+    }
+  if (port)
+    {
+      *port = (key >> 16) & (u16) ~ 0;
+    }
+  if (fib_index)
+    {
+      *fib_index = key >> 3 & ((1 << 13) - 1);
+    }
+  if (proto)
+    {
+      *proto = key & 0x7;
+    }
+}
+
+always_inline void
+init_nat_k (clib_bihash_kv_8_8_t * kv, ip4_address_t addr, u16 port,
+           u32 fib_index, nat_protocol_t proto)
+{
+  kv->key = calc_nat_key (addr, port, fib_index, proto);
+  kv->value = ~0ULL;
+}
+
+always_inline void
+init_nat_kv (clib_bihash_kv_8_8_t * kv, ip4_address_t addr, u16 port,
+            u32 fib_index, nat_protocol_t proto, u64 value)
+{
+  init_nat_k (kv, addr, port, fib_index, proto);
+  kv->value = value;
+}
+
+always_inline void
+init_nat_i2o_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s)
+{
+  return init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
+                    s->nat_proto);
+}
+
+always_inline void
+init_nat_i2o_kv (clib_bihash_kv_8_8_t * kv, snat_session_t * s, u64 value)
+{
+  init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
+             s->nat_proto);
+  kv->value = value;
+}
+
+always_inline void
+init_nat_o2i_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s)
+{
+  return init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
+                    s->nat_proto);
+}
+
+always_inline void
+init_nat_o2i_kv (clib_bihash_kv_8_8_t * kv, snat_session_t * s, u64 value)
+{
+  init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
+             s->nat_proto);
+  kv->value = value;
+}
+
 static inline uword
 nat_pre_node_fn_inline (vlib_main_t * vm,
                        vlib_node_runtime_t * node,
 static inline uword
 nat_pre_node_fn_inline (vlib_main_t * vm,
                        vlib_node_runtime_t * node,
@@ -384,7 +461,7 @@ nat44_set_tcp_session_state_o2i (snat_main_t * sm, f64 now,
 always_inline u32
 nat44_session_get_timeout (snat_main_t * sm, snat_session_t * s)
 {
 always_inline u32
 nat44_session_get_timeout (snat_main_t * sm, snat_session_t * s)
 {
-  switch (s->in2out.protocol)
+  switch (s->nat_proto)
     {
     case NAT_PROTOCOL_ICMP:
       return sm->icmp_timeout;
     {
     case NAT_PROTOCOL_ICMP:
       return sm->icmp_timeout;
@@ -412,7 +489,7 @@ nat44_session_update_counters (snat_session_t * s, f64 now, uword bytes,
   s->total_pkts++;
   s->total_bytes += bytes;
   nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
   s->total_pkts++;
   s->total_bytes += bytes;
   nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
-              s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
+              s->ext_host_port, s->nat_proto, s->out2in.fib_index,
               s->total_pkts, s->total_bytes, thread_index,
               &s->ha_last_refreshed, now);
 }
               s->total_pkts, s->total_bytes, thread_index,
               &s->ha_last_refreshed, now);
 }
@@ -444,13 +521,20 @@ nat44_session_update_lru (snat_main_t * sm, snat_session_t * s,
 }
 
 always_inline void
 }
 
 always_inline void
-make_ed_kv (ip4_address_t * l_addr, ip4_address_t * r_addr, u8 proto,
-           u32 fib_index, u16 l_port, u16 r_port, u32 thread_index,
-           u32 session_index, clib_bihash_kv_16_8_t * kv)
+init_ed_k (clib_bihash_kv_16_8_t * kv, ip4_address_t l_addr, u16 l_port,
+          ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto)
 {
 {
-  kv->key[0] = (u64) r_addr->as_u32 << 32 | l_addr->as_u32;
+  kv->key[0] = (u64) r_addr.as_u32 << 32 | l_addr.as_u32;
   kv->key[1] =
     (u64) r_port << 48 | (u64) l_port << 32 | fib_index << 8 | proto;
   kv->key[1] =
     (u64) r_port << 48 | (u64) l_port << 32 | fib_index << 8 | proto;
+}
+
+always_inline void
+init_ed_kv (clib_bihash_kv_16_8_t * kv, ip4_address_t l_addr, u16 l_port,
+           ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto,
+           u32 thread_index, u32 session_index)
+{
+  init_ed_k (kv, l_addr, l_port, r_addr, r_port, fib_index, proto);
   kv->value = (u64) thread_index << 32 | session_index;
 }
 
   kv->value = (u64) thread_index << 32 | session_index;
 }
 
@@ -511,20 +595,11 @@ split_ed_kv (clib_bihash_kv_16_8_t * kv,
     }
 }
 
     }
 }
 
-always_inline void
-make_sm_kv (clib_bihash_kv_8_8_t * kv, ip4_address_t * addr, u8 proto,
-           u32 fib_index, u16 port)
-{
-  kv->key = (u64) fib_index << 51 | (u64) proto << 48 | (u64) port << 32 |
-    addr->as_u32;
-
-  kv->value = ~0ULL;
-}
-
 static_always_inline int
 get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
 static_always_inline int
 get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
-                    u32 thread_index, u32 session_index, u8 * nat_proto,
-                    u16 * l_port, u16 * r_port, clib_bihash_kv_16_8_t * kv)
+                    u32 thread_index, u32 session_index,
+                    nat_protocol_t * nat_proto, u16 * l_port, u16 * r_port,
+                    clib_bihash_kv_16_8_t * kv)
 {
   u8 proto;
   u16 _l_port, _r_port;
 {
   u8 proto;
   u16 _l_port, _r_port;
@@ -572,8 +647,8 @@ get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
          return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
        }
     }
          return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
        }
     }
-  make_ed_kv (l_addr, r_addr, proto, rx_fib_index, _l_port, _r_port,
-             thread_index, session_index, kv);
+  init_ed_kv (kv, *l_addr, _l_port, *r_addr, _r_port, rx_fib_index, proto,
+             thread_index, session_index);
   if (nat_proto)
     {
       *nat_proto = ip_proto_to_nat_proto (proto);
   if (nat_proto)
     {
       *nat_proto = ip_proto_to_nat_proto (proto);
@@ -589,11 +664,11 @@ get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
   return 0;
 }
 
   return 0;
 }
 
-
 static_always_inline int
 get_icmp_o2i_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
 static_always_inline int
 get_icmp_o2i_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
-                    u32 thread_index, u32 session_index, u8 * nat_proto,
-                    u16 * l_port, u16 * r_port, clib_bihash_kv_16_8_t * kv)
+                    u32 thread_index, u32 session_index,
+                    nat_protocol_t * nat_proto, u16 * l_port, u16 * r_port,
+                    clib_bihash_kv_16_8_t * kv)
 {
   icmp46_header_t *icmp0;
   u8 proto;
 {
   icmp46_header_t *icmp0;
   u8 proto;
@@ -640,8 +715,8 @@ get_icmp_o2i_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
          return -1;
        }
     }
          return -1;
        }
     }
-  make_ed_kv (l_addr, r_addr, proto, rx_fib_index, _l_port, _r_port,
-             thread_index, session_index, kv);
+  init_ed_kv (kv, *l_addr, _l_port, *r_addr, _r_port, rx_fib_index, proto,
+             thread_index, session_index);
   if (nat_proto)
     {
       *nat_proto = ip_proto_to_nat_proto (proto);
   if (nat_proto)
     {
       *nat_proto = ip_proto_to_nat_proto (proto);
index 44f7dcf..faf5d73 100644 (file)
@@ -126,30 +126,30 @@ nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
   sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s);
   if (ctx->now >= sess_timeout_time)
     {
   sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s);
   if (ctx->now >= sess_timeout_time)
     {
-      s_kv.key = s->in2out.as_u64;
+      init_nat_i2o_k (&s_kv, s);
       if (clib_bihash_add_del_8_8 (&tsm->in2out, &s_kv, 0))
        nat_elog_warn ("out2in key del failed");
 
       snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
       if (clib_bihash_add_del_8_8 (&tsm->in2out, &s_kv, 0))
        nat_elog_warn ("out2in key del failed");
 
       snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
-                                          s->in2out.protocol,
+                                          s->nat_proto,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
 
       nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
                               &s->in2out.addr, s->in2out.port,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
 
       nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
                               &s->in2out.addr, s->in2out.port,
-                              &s->out2in.addr, s->out2in.port,
-                              s->in2out.protocol);
+                              &s->out2in.addr, s->out2in.port, s->nat_proto);
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
-                  s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
+                  s->ext_host_port, s->nat_proto, s->out2in.fib_index,
                   ctx->thread_index);
 
       if (!snat_is_session_static (s))
        snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
                   ctx->thread_index);
 
       if (!snat_is_session_static (s))
        snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
-                                           &s->out2in);
+                                           &s->out2in.addr, s->out2in.port,
+                                           s->nat_proto);
 
       nat44_delete_session (sm, s, ctx->thread_index);
       return 1;
 
       nat44_delete_session (sm, s, ctx->thread_index);
       return 1;
@@ -176,8 +176,13 @@ nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
 static inline snat_session_t *
 create_session_for_static_mapping (snat_main_t * sm,
                                   vlib_buffer_t * b0,
 static inline snat_session_t *
 create_session_for_static_mapping (snat_main_t * sm,
                                   vlib_buffer_t * b0,
-                                  snat_session_key_t in2out,
-                                  snat_session_key_t out2in,
+                                  ip4_address_t i2o_addr,
+                                  u16 i2o_port,
+                                  u32 i2o_fib_index,
+                                  ip4_address_t o2i_addr,
+                                  u16 o2i_port,
+                                  u32 o2i_fib_index,
+                                  nat_protocol_t proto,
                                   vlib_node_runtime_t * node,
                                   u32 thread_index, f64 now)
 {
                                   vlib_node_runtime_t * node,
                                   u32 thread_index, f64 now)
 {
@@ -198,8 +203,7 @@ create_session_for_static_mapping (snat_main_t * sm,
   ip0 = vlib_buffer_get_current (b0);
   udp0 = ip4_next_header (ip0);
 
   ip0 = vlib_buffer_get_current (b0);
   udp0 = ip4_next_header (ip0);
 
-  u =
-    nat_user_get_or_create (sm, &in2out.addr, in2out.fib_index, thread_index);
+  u = nat_user_get_or_create (sm, &i2o_addr, i2o_fib_index, thread_index);
   if (!u)
     {
       nat_elog_warn ("create NAT user failed");
   if (!u)
     {
       nat_elog_warn ("create NAT user failed");
@@ -218,22 +222,24 @@ create_session_for_static_mapping (snat_main_t * sm,
   s->ext_host_addr.as_u32 = ip0->src_address.as_u32;
   s->ext_host_port = udp0->src_port;
   user_session_increment (sm, u, 1 /* static */ );
   s->ext_host_addr.as_u32 = ip0->src_address.as_u32;
   s->ext_host_port = udp0->src_port;
   user_session_increment (sm, u, 1 /* static */ );
-  s->in2out = in2out;
-  s->out2in = out2in;
-  s->in2out.protocol = out2in.protocol;
+  s->in2out.addr = i2o_addr;
+  s->in2out.port = i2o_port;
+  s->in2out.fib_index = i2o_fib_index;
+  s->out2in.addr = o2i_addr;
+  s->out2in.port = o2i_port;
+  s->out2in.fib_index = o2i_fib_index;
+  s->nat_proto = proto;
 
   /* Add to translation hashes */
   ctx0.now = now;
   ctx0.thread_index = thread_index;
 
   /* Add to translation hashes */
   ctx0.now = now;
   ctx0.thread_index = thread_index;
-  kv0.key = s->in2out.as_u64;
-  kv0.value = s - sm->per_thread_data[thread_index].sessions;
+  init_nat_i2o_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions);
   if (clib_bihash_add_or_overwrite_stale_8_8
       (&sm->per_thread_data[thread_index].in2out, &kv0,
        nat44_i2o_is_idle_session_cb, &ctx0))
     nat_elog_notice ("in2out key add failed");
 
   if (clib_bihash_add_or_overwrite_stale_8_8
       (&sm->per_thread_data[thread_index].in2out, &kv0,
        nat44_i2o_is_idle_session_cb, &ctx0))
     nat_elog_notice ("in2out key add failed");
 
-  kv0.key = s->out2in.as_u64;
-
+  init_nat_o2i_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions);
   if (clib_bihash_add_or_overwrite_stale_8_8
       (&sm->per_thread_data[thread_index].out2in, &kv0,
        nat44_o2i_is_idle_session_cb, &ctx0))
   if (clib_bihash_add_or_overwrite_stale_8_8
       (&sm->per_thread_data[thread_index].out2in, &kv0,
        nat44_o2i_is_idle_session_cb, &ctx0))
@@ -243,30 +249,28 @@ create_session_for_static_mapping (snat_main_t * sm,
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
-                                      s->in2out.protocol,
+                                      s->nat_proto,
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
 
   nat_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index,
                           &s->in2out.addr, s->in2out.port, &s->out2in.addr,
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
 
   nat_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index,
                           &s->in2out.addr, s->in2out.port, &s->out2in.addr,
-                          s->out2in.port, s->in2out.protocol);
+                          s->out2in.port, s->nat_proto);
 
   nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
               s->out2in.port, &s->ext_host_addr, s->ext_host_port,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
 
   nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
               s->out2in.port, &s->ext_host_addr, s->ext_host_port,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
-              s->in2out.protocol, s->in2out.fib_index, s->flags,
-              thread_index, 0);
+              s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0);
 
   return s;
 }
 
 #ifndef CLIB_MARCH_VARIANT
 
   return s;
 }
 
 #ifndef CLIB_MARCH_VARIANT
-static_always_inline
-  snat_out2in_error_t icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
-                                   snat_session_key_t * p_key0)
+static_always_inline snat_out2in_error_t
+icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
+             ip4_address_t * addr, u16 * port, nat_protocol_t * nat_proto)
 {
   icmp46_header_t *icmp0;
 {
   icmp46_header_t *icmp0;
-  snat_session_key_t key0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0;
   void *l4_header = 0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0;
   void *l4_header = 0;
@@ -278,32 +282,31 @@ static_always_inline
   if (!icmp_type_is_error_message
       (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
     {
   if (!icmp_type_is_error_message
       (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
     {
-      key0.protocol = NAT_PROTOCOL_ICMP;
-      key0.addr = ip0->dst_address;
-      key0.port = vnet_buffer (b)->ip.reass.l4_src_port;
+      *nat_proto = NAT_PROTOCOL_ICMP;
+      *addr = ip0->dst_address;
+      *port = vnet_buffer (b)->ip.reass.l4_src_port;
     }
   else
     {
       inner_ip0 = (ip4_header_t *) (echo0 + 1);
       l4_header = ip4_next_header (inner_ip0);
     }
   else
     {
       inner_ip0 = (ip4_header_t *) (echo0 + 1);
       l4_header = ip4_next_header (inner_ip0);
-      key0.protocol = ip_proto_to_nat_proto (inner_ip0->protocol);
-      key0.addr = inner_ip0->src_address;
-      switch (key0.protocol)
+      *nat_proto = ip_proto_to_nat_proto (inner_ip0->protocol);
+      *addr = inner_ip0->src_address;
+      switch (*nat_proto)
        {
        case NAT_PROTOCOL_ICMP:
          inner_icmp0 = (icmp46_header_t *) l4_header;
          inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
        {
        case NAT_PROTOCOL_ICMP:
          inner_icmp0 = (icmp46_header_t *) l4_header;
          inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
-         key0.port = inner_echo0->identifier;
+         *port = inner_echo0->identifier;
          break;
        case NAT_PROTOCOL_UDP:
        case NAT_PROTOCOL_TCP:
          break;
        case NAT_PROTOCOL_UDP:
        case NAT_PROTOCOL_TCP:
-         key0.port = ((tcp_udp_header_t *) l4_header)->src_port;
+         *port = ((tcp_udp_header_t *) l4_header)->src_port;
          break;
        default:
          return SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL;
        }
     }
          break;
        default:
          return SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL;
        }
     }
-  *p_key0 = key0;
   return -1;                   /* success */
 }
 
   return -1;                   /* success */
 }
 
@@ -325,46 +328,48 @@ static_always_inline
 u32
 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
                        u32 thread_index, vlib_buffer_t * b0,
 u32
 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
                        u32 thread_index, vlib_buffer_t * b0,
-                       ip4_header_t * ip0, u8 * p_proto,
-                       snat_session_key_t * p_value,
-                       u8 * p_dont_translate, void *d, void *e)
+                       ip4_header_t * ip0, ip4_address_t * addr,
+                       u16 * port, u32 * fib_index,
+                       nat_protocol_t * proto, void *d, void *e,
+                       u8 * dont_translate)
 {
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   u32 sw_if_index0;
 {
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   u32 sw_if_index0;
-  u32 rx_fib_index0;
-  snat_session_key_t key0;
-  snat_session_key_t sm0;
   snat_session_t *s0 = 0;
   snat_session_t *s0 = 0;
-  u8 dont_translate = 0;
   clib_bihash_kv_8_8_t kv0, value0;
   u8 is_addr_only;
   u32 next0 = ~0;
   int err;
   u8 identity_nat;
   vlib_main_t *vm = vlib_get_main ();
   clib_bihash_kv_8_8_t kv0, value0;
   u8 is_addr_only;
   u32 next0 = ~0;
   int err;
   u8 identity_nat;
   vlib_main_t *vm = vlib_get_main ();
+  *dont_translate = 0;
 
   sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
 
   sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
-  rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
+  *fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
 
 
-  key0.protocol = 0;
+  *proto = 0;
 
 
-  err = icmp_get_key (b0, ip0, &key0);
+  err = icmp_get_key (b0, ip0, addr, port, proto);
   if (err != -1)
     {
       b0->error = node->errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
       next0 = SNAT_OUT2IN_NEXT_DROP;
       goto out;
     }
   if (err != -1)
     {
       b0->error = node->errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
       next0 = SNAT_OUT2IN_NEXT_DROP;
       goto out;
     }
-  key0.fib_index = rx_fib_index0;
 
 
-  kv0.key = key0.as_u64;
+  ip4_address_t mapping_addr;
+  u16 mapping_port;
+  u32 mapping_fib_index;
 
 
+  init_nat_k (&kv0, *addr, *port, *fib_index, *proto);
   if (clib_bihash_search_8_8 (&tsm->out2in, &kv0, &value0))
     {
       /* Try to match static mapping by external address and port,
          destination address and port in packet */
       if (snat_static_mapping_match
   if (clib_bihash_search_8_8 (&tsm->out2in, &kv0, &value0))
     {
       /* Try to match static mapping by external address and port,
          destination address and port in packet */
       if (snat_static_mapping_match
-         (sm, key0, &sm0, 1, &is_addr_only, 0, 0, 0, &identity_nat))
+         (sm, *addr, *port, *fib_index, *proto,
+          &mapping_addr, &mapping_port, &mapping_fib_index, 1, &is_addr_only,
+          0, 0, 0, &identity_nat))
        {
          if (!sm->forwarding_enabled)
            {
        {
          if (!sm->forwarding_enabled)
            {
@@ -372,7 +377,7 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
              if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
                                                    ip0->dst_address.as_u32)))
                {
              if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
                                                    ip0->dst_address.as_u32)))
                {
-                 dont_translate = 1;
+                 *dont_translate = 1;
                  goto out;
                }
              b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
                  goto out;
                }
              b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
@@ -381,7 +386,7 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
            }
          else
            {
            }
          else
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
              goto out;
            }
        }
@@ -399,13 +404,15 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
 
       if (PREDICT_FALSE (identity_nat))
        {
 
       if (PREDICT_FALSE (identity_nat))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
       /* Create session initiated by host from external network */
          goto out;
        }
       /* Create session initiated by host from external network */
-      s0 = create_session_for_static_mapping (sm, b0, sm0, key0,
-                                             node, thread_index,
-                                             vlib_time_now (vm));
+      s0 =
+       create_session_for_static_mapping (sm, b0, mapping_addr, mapping_port,
+                                          mapping_fib_index, *addr, *port,
+                                          *fib_index, *proto, node,
+                                          thread_index, vlib_time_now (vm));
 
       if (!s0)
        {
 
       if (!s0)
        {
@@ -432,10 +439,12 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 
 out:
     }
 
 out:
-  *p_proto = key0.protocol;
   if (s0)
   if (s0)
-    *p_value = s0->in2out;
-  *p_dont_translate = dont_translate;
+    {
+      *addr = s0->in2out.addr;
+      *port = s0->in2out.port;
+      *fib_index = s0->in2out.fib_index;
+    }
   if (d)
     *(snat_session_t **) d = s0;
   return next0;
   if (d)
     *(snat_session_t **) d = s0;
   return next0;
@@ -460,38 +469,38 @@ out:
 u32
 icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node,
                        u32 thread_index, vlib_buffer_t * b0,
 u32
 icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node,
                        u32 thread_index, vlib_buffer_t * b0,
-                       ip4_header_t * ip0, u8 * p_proto,
-                       snat_session_key_t * p_value,
-                       u8 * p_dont_translate, void *d, void *e)
+                       ip4_header_t * ip0, ip4_address_t * mapping_addr,
+                       u16 * mapping_port, u32 * mapping_fib_index,
+                       nat_protocol_t * proto, void *d, void *e,
+                       u8 * dont_translate)
 {
   u32 sw_if_index0;
   u32 rx_fib_index0;
 {
   u32 sw_if_index0;
   u32 rx_fib_index0;
-  snat_session_key_t key0;
-  snat_session_key_t sm0;
-  u8 dont_translate = 0;
   u8 is_addr_only;
   u32 next0 = ~0;
   int err;
   u8 is_addr_only;
   u32 next0 = ~0;
   int err;
+  ip4_address_t addr;
+  u16 port;
+  *dont_translate = 0;
 
   sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
   rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
 
 
   sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
   rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
 
-  err = icmp_get_key (b0, ip0, &key0);
+  err = icmp_get_key (b0, ip0, &addr, &port, proto);
   if (err != -1)
     {
       b0->error = node->errors[err];
       next0 = SNAT_OUT2IN_NEXT_DROP;
   if (err != -1)
     {
       b0->error = node->errors[err];
       next0 = SNAT_OUT2IN_NEXT_DROP;
-      goto out2;
+      goto out;
     }
     }
-  key0.fib_index = rx_fib_index0;
-
   if (snat_static_mapping_match
   if (snat_static_mapping_match
-      (sm, key0, &sm0, 1, &is_addr_only, 0, 0, 0, 0))
+      (sm, addr, port, rx_fib_index0, *proto, mapping_addr, mapping_port,
+       mapping_fib_index, 1, &is_addr_only, 0, 0, 0, 0))
     {
       /* Don't NAT packet aimed at the intfc address */
       if (is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32))
        {
     {
       /* Don't NAT packet aimed at the intfc address */
       if (is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
       b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
          goto out;
        }
       b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
@@ -512,10 +521,6 @@ icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 
 out:
     }
 
 out:
-  *p_value = sm0;
-out2:
-  *p_proto = key0.protocol;
-  *p_dont_translate = dont_translate;
   return next0;
 }
 #endif
   return next0;
 }
 #endif
@@ -531,8 +536,6 @@ icmp_out2in (snat_main_t * sm,
             vlib_node_runtime_t * node,
             u32 next0, u32 thread_index, void *d, void *e)
 {
             vlib_node_runtime_t * node,
             u32 next0, u32 thread_index, void *d, void *e)
 {
-  snat_session_key_t sm0;
-  u8 protocol;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0 = 0;
   void *l4_header = 0;
   icmp_echo_header_t *echo0, *inner_echo0 = 0;
   ip4_header_t *inner_ip0 = 0;
   void *l4_header = 0;
@@ -544,12 +547,16 @@ icmp_out2in (snat_main_t * sm,
   u16 checksum0;
   u32 next0_tmp;
   vlib_main_t *vm = vlib_get_main ();
   u16 checksum0;
   u32 next0_tmp;
   vlib_main_t *vm = vlib_get_main ();
+  ip4_address_t addr;
+  u16 port;
+  u32 fib_index;
+  nat_protocol_t proto;
 
   echo0 = (icmp_echo_header_t *) (icmp0 + 1);
 
   next0_tmp = sm->icmp_match_out2in_cb (sm, node, thread_index, b0, ip0,
 
   echo0 = (icmp_echo_header_t *) (icmp0 + 1);
 
   next0_tmp = sm->icmp_match_out2in_cb (sm, node, thread_index, b0, ip0,
-                                       &protocol, &sm0, &dont_translate, d,
-                                       e);
+                                       &addr, &port, &fib_index, &proto,
+                                       d, e, &dont_translate);
   if (next0_tmp != ~0)
     next0 = next0_tmp;
   if (next0 == SNAT_OUT2IN_NEXT_DROP || dont_translate)
   if (next0_tmp != ~0)
     next0 = next0_tmp;
   if (next0 == SNAT_OUT2IN_NEXT_DROP || dont_translate)
@@ -572,8 +579,8 @@ icmp_out2in (snat_main_t * sm,
     }
 
   old_addr0 = ip0->dst_address.as_u32;
     }
 
   old_addr0 = ip0->dst_address.as_u32;
-  new_addr0 = ip0->dst_address.as_u32 = sm0.addr.as_u32;
-  vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index;
+  new_addr0 = ip0->dst_address.as_u32 = addr.as_u32;
+  vnet_buffer (b0)->sw_if_index[VLIB_TX] = fib_index;
 
   sum0 = ip0->checksum;
   sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
 
   sum0 = ip0->checksum;
   sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
@@ -588,11 +595,11 @@ icmp_out2in (snat_main_t * sm,
 
       if (!icmp_type_is_error_message (icmp0->type))
        {
 
       if (!icmp_type_is_error_message (icmp0->type))
        {
-         new_id0 = sm0.port;
+         new_id0 = port;
          if (PREDICT_FALSE (new_id0 != echo0->identifier))
            {
              old_id0 = echo0->identifier;
          if (PREDICT_FALSE (new_id0 != echo0->identifier))
            {
              old_id0 = echo0->identifier;
-             new_id0 = sm0.port;
+             new_id0 = port;
              echo0->identifier = new_id0;
 
              sum0 = icmp0->checksum;
              echo0->identifier = new_id0;
 
              sum0 = icmp0->checksum;
@@ -614,7 +621,7 @@ icmp_out2in (snat_main_t * sm,
            }
 
          old_addr0 = inner_ip0->src_address.as_u32;
            }
 
          old_addr0 = inner_ip0->src_address.as_u32;
-         inner_ip0->src_address = sm0.addr;
+         inner_ip0->src_address = addr;
          new_addr0 = inner_ip0->src_address.as_u32;
 
          sum0 = icmp0->checksum;
          new_addr0 = inner_ip0->src_address.as_u32;
 
          sum0 = icmp0->checksum;
@@ -622,14 +629,14 @@ icmp_out2in (snat_main_t * sm,
                                 src_address /* changed member */ );
          icmp0->checksum = ip_csum_fold (sum0);
 
                                 src_address /* changed member */ );
          icmp0->checksum = ip_csum_fold (sum0);
 
-         switch (protocol)
+         switch (proto)
            {
            case NAT_PROTOCOL_ICMP:
              inner_icmp0 = (icmp46_header_t *) l4_header;
              inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
 
              old_id0 = inner_echo0->identifier;
            {
            case NAT_PROTOCOL_ICMP:
              inner_icmp0 = (icmp46_header_t *) l4_header;
              inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
 
              old_id0 = inner_echo0->identifier;
-             new_id0 = sm0.port;
+             new_id0 = port;
              inner_echo0->identifier = new_id0;
 
              sum0 = icmp0->checksum;
              inner_echo0->identifier = new_id0;
 
              sum0 = icmp0->checksum;
@@ -641,7 +648,7 @@ icmp_out2in (snat_main_t * sm,
            case NAT_PROTOCOL_UDP:
            case NAT_PROTOCOL_TCP:
              old_id0 = ((tcp_udp_header_t *) l4_header)->src_port;
            case NAT_PROTOCOL_UDP:
            case NAT_PROTOCOL_TCP:
              old_id0 = ((tcp_udp_header_t *) l4_header)->src_port;
-             new_id0 = sm0.port;
+             new_id0 = port;
              ((tcp_udp_header_t *) l4_header)->src_port = new_id0;
 
              sum0 = icmp0->checksum;
              ((tcp_udp_header_t *) l4_header)->src_port = new_id0;
 
              sum0 = icmp0->checksum;
@@ -695,15 +702,10 @@ nat_out2in_sm_unknown_proto (snat_main_t * sm,
 {
   clib_bihash_kv_8_8_t kv, value;
   snat_static_mapping_t *m;
 {
   clib_bihash_kv_8_8_t kv, value;
   snat_static_mapping_t *m;
-  snat_session_key_t m_key;
   u32 old_addr, new_addr;
   ip_csum_t sum;
 
   u32 old_addr, new_addr;
   ip_csum_t sum;
 
-  m_key.addr = ip->dst_address;
-  m_key.port = 0;
-  m_key.protocol = 0;
-  m_key.fib_index = 0;
-  kv.key = m_key.as_u64;
+  init_nat_k (&kv, ip->dst_address, 0, 0, 0);
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     return 1;
 
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     return 1;
 
@@ -759,12 +761,14 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
          udp_header_t *udp0, *udp1;
          tcp_header_t *tcp0, *tcp1;
          icmp46_header_t *icmp0, *icmp1;
          udp_header_t *udp0, *udp1;
          tcp_header_t *tcp0, *tcp1;
          icmp46_header_t *icmp0, *icmp1;
-         snat_session_key_t key0, key1, sm0, sm1;
          u32 rx_fib_index0, rx_fib_index1;
          u32 proto0, proto1;
          snat_session_t *s0 = 0, *s1 = 0;
          clib_bihash_kv_8_8_t kv0, kv1, value0, value1;
          u8 identity_nat0, identity_nat1;
          u32 rx_fib_index0, rx_fib_index1;
          u32 proto0, proto1;
          snat_session_t *s0 = 0, *s1 = 0;
          clib_bihash_kv_8_8_t kv0, kv1, value0, value1;
          u8 identity_nat0, identity_nat1;
+         ip4_address_t sm_addr0, sm_addr1;
+         u16 sm_port0, sm_port1;
+         u32 sm_fib_index0, sm_fib_index1;
 
          /* Prefetch next iteration. */
          {
 
          /* Prefetch next iteration. */
          {
@@ -839,20 +843,19 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
              goto trace0;
            }
 
              goto trace0;
            }
 
-         key0.addr = ip0->dst_address;
-         key0.port = vnet_buffer (b0)->ip.reass.l4_dst_port;
-         key0.protocol = proto0;
-         key0.fib_index = rx_fib_index0;
-
-         kv0.key = key0.as_u64;
-
+         init_nat_k (&kv0, ip0->dst_address,
+                     vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
+                     proto0);
          if (clib_bihash_search_8_8
              (&sm->per_thread_data[thread_index].out2in, &kv0, &value0))
            {
              /* Try to match static mapping by external address and port,
                 destination address and port in packet */
              if (snat_static_mapping_match
          if (clib_bihash_search_8_8
              (&sm->per_thread_data[thread_index].out2in, &kv0, &value0))
            {
              /* Try to match static mapping by external address and port,
                 destination address and port in packet */
              if (snat_static_mapping_match
-                 (sm, key0, &sm0, 1, 0, 0, 0, 0, &identity_nat0))
+                 (sm, ip0->dst_address,
+                  vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
+                  proto0, &sm_addr0, &sm_port0, &sm_fib_index0, 1, 0, 0, 0,
+                  0, &identity_nat0))
                {
                  /*
                   * Send DHCP packets to the ipv4 stack, or we won't
                {
                  /*
                   * Send DHCP packets to the ipv4 stack, or we won't
@@ -881,8 +884,15 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
                goto trace0;
 
              /* Create session initiated by host from external network */
                goto trace0;
 
              /* Create session initiated by host from external network */
-             s0 = create_session_for_static_mapping (sm, b0, sm0, key0, node,
-                                                     thread_index, now);
+             s0 = create_session_for_static_mapping (sm, b0,
+                                                     sm_addr0, sm_port0,
+                                                     sm_fib_index0,
+                                                     ip0->dst_address,
+                                                     vnet_buffer (b0)->
+                                                     ip.reass.l4_dst_port,
+                                                     rx_fib_index0, proto0,
+                                                     node, thread_index,
+                                                     now);
              if (!s0)
                {
                  next0 = SNAT_OUT2IN_NEXT_DROP;
              if (!s0)
                {
                  next0 = SNAT_OUT2IN_NEXT_DROP;
@@ -1011,12 +1021,9 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
              goto trace1;
            }
 
              goto trace1;
            }
 
-         key1.addr = ip1->dst_address;
-         key1.port = vnet_buffer (b1)->ip.reass.l4_dst_port;
-         key1.protocol = proto1;
-         key1.fib_index = rx_fib_index1;
-
-         kv1.key = key1.as_u64;
+         init_nat_k (&kv1, ip1->dst_address,
+                     vnet_buffer (b1)->ip.reass.l4_dst_port, rx_fib_index1,
+                     proto1);
 
          if (clib_bihash_search_8_8
              (&sm->per_thread_data[thread_index].out2in, &kv1, &value1))
 
          if (clib_bihash_search_8_8
              (&sm->per_thread_data[thread_index].out2in, &kv1, &value1))
@@ -1024,7 +1031,10 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
              /* Try to match static mapping by external address and port,
                 destination address and port in packet */
              if (snat_static_mapping_match
              /* Try to match static mapping by external address and port,
                 destination address and port in packet */
              if (snat_static_mapping_match
-                 (sm, key1, &sm1, 1, 0, 0, 0, 0, &identity_nat1))
+                 (sm, ip1->dst_address,
+                  vnet_buffer (b1)->ip.reass.l4_dst_port, proto1,
+                  rx_fib_index1, &sm_addr1, &sm_port1, &sm_fib_index1, 1, 0,
+                  0, 0, 0, &identity_nat1))
                {
                  /*
                   * Send DHCP packets to the ipv4 stack, or we won't
                {
                  /*
                   * Send DHCP packets to the ipv4 stack, or we won't
@@ -1053,8 +1063,14 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
                goto trace1;
 
              /* Create session initiated by host from external network */
                goto trace1;
 
              /* Create session initiated by host from external network */
-             s1 = create_session_for_static_mapping (sm, b1, sm1, key1, node,
-                                                     thread_index, now);
+             s1 =
+               create_session_for_static_mapping (sm, b1, sm_addr1, sm_port1,
+                                                  sm_fib_index1,
+                                                  ip1->dst_address,
+                                                  vnet_buffer (b1)->ip.
+                                                  reass.l4_dst_port,
+                                                  rx_fib_index1, proto1,
+                                                  node, thread_index, now);
              if (!s1)
                {
                  next1 = SNAT_OUT2IN_NEXT_DROP;
              if (!s1)
                {
                  next1 = SNAT_OUT2IN_NEXT_DROP;
@@ -1162,12 +1178,14 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
          udp_header_t *udp0;
          tcp_header_t *tcp0;
          icmp46_header_t *icmp0;
          udp_header_t *udp0;
          tcp_header_t *tcp0;
          icmp46_header_t *icmp0;
-         snat_session_key_t key0, sm0;
          u32 rx_fib_index0;
          u32 proto0;
          snat_session_t *s0 = 0;
          clib_bihash_kv_8_8_t kv0, value0;
          u8 identity_nat0;
          u32 rx_fib_index0;
          u32 proto0;
          snat_session_t *s0 = 0;
          clib_bihash_kv_8_8_t kv0, value0;
          u8 identity_nat0;
+         ip4_address_t sm_addr0;
+         u16 sm_port0;
+         u32 sm_fib_index0;
 
          /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
 
          /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
@@ -1226,12 +1244,9 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
              goto trace00;
            }
 
              goto trace00;
            }
 
-         key0.addr = ip0->dst_address;
-         key0.port = vnet_buffer (b0)->ip.reass.l4_dst_port;
-         key0.protocol = proto0;
-         key0.fib_index = rx_fib_index0;
-
-         kv0.key = key0.as_u64;
+         init_nat_k (&kv0, ip0->dst_address,
+                     vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
+                     proto0);
 
          if (clib_bihash_search_8_8
              (&sm->per_thread_data[thread_index].out2in, &kv0, &value0))
 
          if (clib_bihash_search_8_8
              (&sm->per_thread_data[thread_index].out2in, &kv0, &value0))
@@ -1239,7 +1254,10 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
              /* Try to match static mapping by external address and port,
                 destination address and port in packet */
              if (snat_static_mapping_match
              /* Try to match static mapping by external address and port,
                 destination address and port in packet */
              if (snat_static_mapping_match
-                 (sm, key0, &sm0, 1, 0, 0, 0, 0, &identity_nat0))
+                 (sm, ip0->dst_address,
+                  vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
+                  proto0, &sm_addr0, &sm_port0, &sm_fib_index0, 1, 0, 0, 0,
+                  0, &identity_nat0))
                {
                  /*
                   * Send DHCP packets to the ipv4 stack, or we won't
                {
                  /*
                   * Send DHCP packets to the ipv4 stack, or we won't
@@ -1268,8 +1286,15 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
                goto trace00;
 
              /* Create session initiated by host from external network */
                goto trace00;
 
              /* Create session initiated by host from external network */
-             s0 = create_session_for_static_mapping (sm, b0, sm0, key0, node,
-                                                     thread_index, now);
+             s0 = create_session_for_static_mapping (sm, b0,
+                                                     sm_addr0, sm_port0,
+                                                     sm_fib_index0,
+                                                     ip0->dst_address,
+                                                     vnet_buffer (b0)->
+                                                     ip.reass.l4_dst_port,
+                                                     rx_fib_index0, proto0,
+                                                     node, thread_index,
+                                                     now);
              if (!s0)
                {
                  next0 = SNAT_OUT2IN_NEXT_DROP;
              if (!s0)
                {
                  next0 = SNAT_OUT2IN_NEXT_DROP;
@@ -1437,9 +1462,11 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
          udp_header_t *udp0;
          tcp_header_t *tcp0;
          icmp46_header_t *icmp0;
          udp_header_t *udp0;
          tcp_header_t *tcp0;
          icmp46_header_t *icmp0;
-         snat_session_key_t key0, sm0;
          u32 proto0;
          u32 rx_fib_index0;
          u32 proto0;
          u32 rx_fib_index0;
+         ip4_address_t sm_addr0;
+         u16 sm_port0;
+         u32 sm_fib_index0;
 
          /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
 
          /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
@@ -1484,19 +1511,17 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
              goto trace00;
            }
 
              goto trace00;
            }
 
-         key0.addr = ip0->dst_address;
-         key0.port = udp0->dst_port;
-         key0.fib_index = rx_fib_index0;
-
-         if (snat_static_mapping_match (sm, key0, &sm0, 1, 0, 0, 0, 0, 0))
+         if (snat_static_mapping_match
+             (sm, ip0->dst_address, udp0->dst_port, rx_fib_index0, proto0,
+              &sm_addr0, &sm_port0, &sm_fib_index0, 1, 0, 0, 0, 0, 0))
            {
              b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
              goto trace00;
            }
 
            {
              b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
              goto trace00;
            }
 
-         new_addr0 = sm0.addr.as_u32;
-         new_port0 = sm0.port;
-         vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index;
+         new_addr0 = sm_addr0.as_u32;
+         new_port0 = sm_port0;
+         vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm_fib_index0;
          old_addr0 = ip0->dst_address.as_u32;
          ip0->dst_address.as_u32 = new_addr0;
 
          old_addr0 = ip0->dst_address.as_u32;
          ip0->dst_address.as_u32 = new_addr0;
 
index 5d759fb..3d081e1 100644 (file)
@@ -103,8 +103,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
   u32 fib_index;
   clib_bihash_kv_16_8_t ed_kv;
   int i;
   u32 fib_index;
   clib_bihash_kv_16_8_t ed_kv;
   int i;
-  snat_address_t *a;
-  snat_session_key_t key;
+  //snat_address_t *a;
   snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
                                                       ctx->thread_index);
 
   snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
                                                       ctx->thread_index);
 
@@ -123,7 +122,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
        }
       else
        {
        }
       else
        {
-         proto = nat_proto_to_ip_proto (s->in2out.protocol);
+         proto = nat_proto_to_ip_proto (s->nat_proto);
          l_port = s->in2out.port;
          r_port = s->ext_host_port;
        }
          l_port = s->in2out.port;
          r_port = s->ext_host_port;
        }
@@ -132,8 +131,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
          r_addr = &s->ext_host_nat_addr;
          r_port = s->ext_host_nat_port;
        }
          r_addr = &s->ext_host_nat_addr;
          r_port = s->ext_host_nat_port;
        }
-      make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
-                 &ed_kv);
+      init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
        nat_elog_warn ("in2out_ed key del failed");
 
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
        nat_elog_warn ("in2out_ed key del failed");
 
@@ -143,7 +141,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
       snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
       snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
                                           s->in2out.addr.as_u32,
                                           s->out2in.addr.as_u32,
-                                          s->in2out.protocol,
+                                          s->nat_proto,
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
                                           s->in2out.port,
                                           s->out2in.port,
                                           s->in2out.fib_index);
@@ -153,26 +151,27 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
                             &s->ext_host_nat_addr, s->ext_host_nat_port,
                             &s->out2in.addr, s->out2in.port,
                             &s->ext_host_addr, s->ext_host_port,
                             &s->ext_host_nat_addr, s->ext_host_nat_port,
                             &s->out2in.addr, s->out2in.port,
                             &s->ext_host_addr, s->ext_host_port,
-                            s->in2out.protocol, is_twice_nat_session (s));
+                            s->nat_proto, is_twice_nat_session (s));
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
 
       nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
-                  s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
+                  s->ext_host_port, s->nat_proto, s->out2in.fib_index,
                   ctx->thread_index);
 
       if (is_twice_nat_session (s))
        {
          for (i = 0; i < vec_len (sm->twice_nat_addresses); i++)
            {
                   ctx->thread_index);
 
       if (is_twice_nat_session (s))
        {
          for (i = 0; i < vec_len (sm->twice_nat_addresses); i++)
            {
-             key.protocol = s->in2out.protocol;
-             key.port = s->ext_host_nat_port;
-             a = sm->twice_nat_addresses + i;
-             if (a->addr.as_u32 == s->ext_host_nat_addr.as_u32)
-               {
-                 snat_free_outside_address_and_port (sm->twice_nat_addresses,
-                                                     ctx->thread_index,
-                                                     &key);
-                 break;
-               }
+             // FIXME TODO this is obviously wrong code ... needs fix!
+             //       key.protocol = s->nat_proto;
+             //       key.port = s->ext_host_nat_port;
+             //       a = sm->twice_nat_addresses + i;
+             //       if (a->addr.as_u32 == s->ext_host_nat_addr.as_u32)
+             //      {
+             //        snat_free_outside_address_and_port (sm->twice_nat_addresses,
+             //                                            ctx->thread_index,
+             //                                            &key);
+             //        break;
+             //      }
            }
        }
 
            }
        }
 
@@ -180,7 +179,8 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
        goto delete;
 
       snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
        goto delete;
 
       snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
-                                         &s->out2in);
+                                         &s->out2in.addr, s->out2in.port,
+                                         s->nat_proto);
     delete:
       nat_ed_session_delete (sm, s, ctx->thread_index, 1);
       return 1;
     delete:
       nat_ed_session_delete (sm, s, ctx->thread_index, 1);
       return 1;
@@ -193,8 +193,13 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
 static snat_session_t *
 create_session_for_static_mapping_ed (snat_main_t * sm,
                                      vlib_buffer_t * b,
 static snat_session_t *
 create_session_for_static_mapping_ed (snat_main_t * sm,
                                      vlib_buffer_t * b,
-                                     snat_session_key_t l_key,
-                                     snat_session_key_t e_key,
+                                     ip4_address_t i2o_addr,
+                                     u16 i2o_port,
+                                     u32 i2o_fib_index,
+                                     ip4_address_t o2i_addr,
+                                     u16 o2i_port,
+                                     u32 o2i_fib_index,
+                                     nat_protocol_t nat_proto,
                                      vlib_node_runtime_t * node,
                                      u32 rx_fib_index,
                                      u32 thread_index,
                                      vlib_node_runtime_t * node,
                                      u32 rx_fib_index,
                                      u32 thread_index,
@@ -206,7 +211,6 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
   udp_header_t *udp;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   clib_bihash_kv_16_8_t kv;
   udp_header_t *udp;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   clib_bihash_kv_16_8_t kv;
-  snat_session_key_t eh_key;
   nat44_is_idle_session_ctx_t ctx;
 
   if (PREDICT_FALSE
   nat44_is_idle_session_ctx_t ctx;
 
   if (PREDICT_FALSE
@@ -217,7 +221,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
       return 0;
     }
 
       return 0;
     }
 
-  s = nat_ed_session_alloc (sm, thread_index, now, e_key.protocol);
+  s = nat_ed_session_alloc (sm, thread_index, now, nat_proto);
   if (!s)
     {
       b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_USER_SESS_EXCEEDED];
   if (!s)
     {
       b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_USER_SESS_EXCEEDED];
@@ -229,21 +233,24 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
   udp = ip4_next_header (ip);
 
   s->ext_host_addr.as_u32 = ip->src_address.as_u32;
   udp = ip4_next_header (ip);
 
   s->ext_host_addr.as_u32 = ip->src_address.as_u32;
-  s->ext_host_port = e_key.protocol == NAT_PROTOCOL_ICMP ? 0 : udp->src_port;
+  s->ext_host_port = nat_proto == NAT_PROTOCOL_ICMP ? 0 : udp->src_port;
   s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
   if (lb_nat)
     s->flags |= SNAT_SESSION_FLAG_LOAD_BALANCING;
   if (lb_nat == AFFINITY_LB_NAT)
     s->flags |= SNAT_SESSION_FLAG_AFFINITY;
   s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
   s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
   if (lb_nat)
     s->flags |= SNAT_SESSION_FLAG_LOAD_BALANCING;
   if (lb_nat == AFFINITY_LB_NAT)
     s->flags |= SNAT_SESSION_FLAG_AFFINITY;
   s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
-  s->out2in = e_key;
-  s->in2out = l_key;
-  s->in2out.protocol = s->out2in.protocol;
+  s->out2in.addr = o2i_addr;
+  s->out2in.port = o2i_port;
+  s->out2in.fib_index = o2i_fib_index;
+  s->in2out.addr = i2o_addr;
+  s->in2out.port = i2o_port;
+  s->in2out.fib_index = i2o_fib_index;
+  s->nat_proto = nat_proto;
 
   /* Add to lookup tables */
 
   /* Add to lookup tables */
-  make_ed_kv (&e_key.addr, &s->ext_host_addr, ip->protocol,
-             e_key.fib_index, e_key.port, s->ext_host_port, thread_index,
-             s - tsm->sessions, &kv);
+  init_ed_kv (&kv, o2i_addr, o2i_port, s->ext_host_addr, s->ext_host_port,
+             o2i_fib_index, ip->protocol, thread_index, s - tsm->sessions);
   ctx.now = now;
   ctx.thread_index = thread_index;
   if (clib_bihash_add_or_overwrite_stale_16_8 (&sm->out2in_ed, &kv,
   ctx.now = now;
   ctx.thread_index = thread_index;
   if (clib_bihash_add_or_overwrite_stale_16_8 (&sm->out2in_ed, &kv,
@@ -252,11 +259,13 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
     nat_elog_notice ("out2in-ed key add failed");
 
   if (twice_nat == TWICE_NAT || (twice_nat == TWICE_NAT_SELF &&
     nat_elog_notice ("out2in-ed key add failed");
 
   if (twice_nat == TWICE_NAT || (twice_nat == TWICE_NAT_SELF &&
-                                ip->src_address.as_u32 == l_key.addr.as_u32))
+                                ip->src_address.as_u32 == i2o_addr.as_u32))
     {
     {
-      eh_key.protocol = e_key.protocol;
       if (snat_alloc_outside_address_and_port (sm->twice_nat_addresses, 0,
       if (snat_alloc_outside_address_and_port (sm->twice_nat_addresses, 0,
-                                              thread_index, &eh_key,
+                                              thread_index,
+                                              nat_proto,
+                                              &s->ext_host_nat_addr,
+                                              &s->ext_host_nat_port,
                                               sm->port_per_thread,
                                               tsm->snat_thread_index))
        {
                                               sm->port_per_thread,
                                               tsm->snat_thread_index))
        {
@@ -266,18 +275,16 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
            nat_elog_notice ("out2in-ed key del failed");
          return 0;
        }
            nat_elog_notice ("out2in-ed key del failed");
          return 0;
        }
-      s->ext_host_nat_addr.as_u32 = eh_key.addr.as_u32;
-      s->ext_host_nat_port = eh_key.port;
       s->flags |= SNAT_SESSION_FLAG_TWICE_NAT;
       s->flags |= SNAT_SESSION_FLAG_TWICE_NAT;
-      make_ed_kv (&l_key.addr, &s->ext_host_nat_addr, ip->protocol,
-                 l_key.fib_index, l_key.port, s->ext_host_nat_port,
-                 thread_index, s - tsm->sessions, &kv);
+      init_ed_kv (&kv, i2o_addr, i2o_port, s->ext_host_nat_addr,
+                 s->ext_host_nat_port, i2o_fib_index, ip->protocol,
+                 thread_index, s - tsm->sessions);
     }
   else
     {
     }
   else
     {
-      make_ed_kv (&l_key.addr, &s->ext_host_addr, ip->protocol,
-                 l_key.fib_index, l_key.port, s->ext_host_port, thread_index,
-                 s - tsm->sessions, &kv);
+      init_ed_kv (&kv, i2o_addr, i2o_port, s->ext_host_addr,
+                 s->ext_host_port, i2o_fib_index, ip->protocol,
+                 thread_index, s - tsm->sessions);
     }
   if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &kv,
                                               nat44_i2o_ed_is_idle_session_cb,
     }
   if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &kv,
                                               nat44_i2o_ed_is_idle_session_cb,
@@ -287,7 +294,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
-                                      s->in2out.protocol,
+                                      s->nat_proto,
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
 
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
 
@@ -296,13 +303,12 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
                         &s->ext_host_nat_addr, s->ext_host_nat_port,
                         &s->out2in.addr, s->out2in.port,
                         &s->ext_host_addr, s->ext_host_port,
                         &s->ext_host_nat_addr, s->ext_host_nat_port,
                         &s->out2in.addr, s->out2in.port,
                         &s->ext_host_addr, s->ext_host_port,
-                        s->in2out.protocol, is_twice_nat_session (s));
+                        s->nat_proto, is_twice_nat_session (s));
 
   nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
               s->out2in.port, &s->ext_host_addr, s->ext_host_port,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
 
   nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
               s->out2in.port, &s->ext_host_addr, s->ext_host_port,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
-              s->in2out.protocol, s->in2out.fib_index, s->flags,
-              thread_index, 0);
+              s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0);
 
   return s;
 }
 
   return s;
 }
@@ -314,8 +320,8 @@ next_src_nat (snat_main_t * sm, ip4_header_t * ip, u16 src_port,
   clib_bihash_kv_16_8_t kv, value;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
 
   clib_bihash_kv_16_8_t kv, value;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
 
-  make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol,
-             rx_fib_index, src_port, dst_port, ~0, ~0, &kv);
+  init_ed_k (&kv, ip->src_address, src_port, ip->dst_address, dst_port,
+            rx_fib_index, ip->protocol);
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
     return 1;
 
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
     return 1;
 
@@ -353,8 +359,8 @@ create_bypass_for_fwd (snat_main_t * sm, vlib_buffer_t * b, ip4_header_t * ip,
          l_port = 0;
          r_port = 0;
        }
          l_port = 0;
          r_port = 0;
        }
-      make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
-                 rx_fib_index, l_port, r_port, ~0, ~0, &kv);
+      init_ed_k (&kv, ip->dst_address, l_port, ip->src_address, r_port,
+                rx_fib_index, ip->protocol);
     }
 
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
     }
 
   if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
@@ -387,14 +393,16 @@ create_bypass_for_fwd (snat_main_t * sm, vlib_buffer_t * b, ip4_header_t * ip,
       s->flags |= SNAT_SESSION_FLAG_FWD_BYPASS;
       s->out2in.addr = ip->dst_address;
       s->out2in.port = l_port;
       s->flags |= SNAT_SESSION_FLAG_FWD_BYPASS;
       s->out2in.addr = ip->dst_address;
       s->out2in.port = l_port;
-      s->out2in.protocol = proto;
+      s->nat_proto = proto;
       if (proto == NAT_PROTOCOL_OTHER)
        {
          s->flags |= SNAT_SESSION_FLAG_UNKNOWN_PROTO;
          s->out2in.port = ip->protocol;
        }
       s->out2in.fib_index = 0;
       if (proto == NAT_PROTOCOL_OTHER)
        {
          s->flags |= SNAT_SESSION_FLAG_UNKNOWN_PROTO;
          s->out2in.port = ip->protocol;
        }
       s->out2in.fib_index = 0;
-      s->in2out = s->out2in;
+      s->in2out.addr = s->out2in.addr;
+      s->in2out.port = s->out2in.port;
+      s->in2out.fib_index = s->out2in.fib_index;
 
       kv.value = s - tsm->sessions;
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1))
 
       kv.value = s - tsm->sessions;
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1))
@@ -431,24 +439,28 @@ create_bypass_for_fwd_worker (snat_main_t * sm, vlib_buffer_t * b,
 #ifndef CLIB_MARCH_VARIANT
 u32
 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
 #ifndef CLIB_MARCH_VARIANT
 u32
 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
-                     u32 thread_index, vlib_buffer_t * b, ip4_header_t * ip,
-                     u8 * p_proto, snat_session_key_t * p_value,
-                     u8 * p_dont_translate, void *d, void *e)
+                     u32 thread_index, vlib_buffer_t * b,
+                     ip4_header_t * ip, ip4_address_t * addr,
+                     u16 * port, u32 * fib_index, nat_protocol_t * proto,
+                     void *d, void *e, u8 * dont_translate)
 {
   u32 next = ~0, sw_if_index, rx_fib_index;
   clib_bihash_kv_16_8_t kv, value;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   snat_session_t *s = 0;
 {
   u32 next = ~0, sw_if_index, rx_fib_index;
   clib_bihash_kv_16_8_t kv, value;
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   snat_session_t *s = 0;
-  u8 dont_translate = 0, is_addr_only, identity_nat;
-  snat_session_key_t e_key, l_key;
+  u8 is_addr_only, identity_nat;
   u16 l_port, r_port;
   vlib_main_t *vm = vlib_get_main ();
   u16 l_port, r_port;
   vlib_main_t *vm = vlib_get_main ();
+  ip4_address_t sm_addr;
+  u16 sm_port;
+  u32 sm_fib_index;
+  *dont_translate = 0;
 
   sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
   rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
 
   if (get_icmp_o2i_ed_key
 
   sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
   rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
 
   if (get_icmp_o2i_ed_key
-      (b, ip, rx_fib_index, ~0, ~0, p_proto, &l_port, &r_port, &kv))
+      (b, ip, rx_fib_index, ~0, ~0, proto, &l_port, &r_port, &kv))
     {
       b->error = node->errors[NAT_OUT2IN_ED_ERROR_UNSUPPORTED_PROTOCOL];
       next = NAT_NEXT_DROP;
     {
       b->error = node->errors[NAT_OUT2IN_ED_ERROR_UNSUPPORTED_PROTOCOL];
       next = NAT_NEXT_DROP;
@@ -458,12 +470,10 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     {
       /* Try to match static mapping */
   if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
     {
       /* Try to match static mapping */
-      e_key.addr = ip->dst_address;
-      e_key.port = l_port;
-      e_key.protocol = ip_proto_to_nat_proto (ip->protocol);
-      e_key.fib_index = rx_fib_index;
       if (snat_static_mapping_match
       if (snat_static_mapping_match
-         (sm, e_key, &l_key, 1, &is_addr_only, 0, 0, 0, &identity_nat))
+         (sm, ip->dst_address, l_port, rx_fib_index,
+          ip_proto_to_nat_proto (ip->protocol), &sm_addr, &sm_port,
+          &sm_fib_index, 1, &is_addr_only, 0, 0, 0, &identity_nat))
        {
          if (!sm->forwarding_enabled)
            {
        {
          if (!sm->forwarding_enabled)
            {
@@ -471,7 +481,7 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
              if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index,
                                                    ip->dst_address.as_u32)))
                {
              if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index,
                                                    ip->dst_address.as_u32)))
                {
-                 dont_translate = 1;
+                 *dont_translate = 1;
                  goto out;
                }
              b->error = node->errors[NAT_OUT2IN_ED_ERROR_NO_TRANSLATION];
                  goto out;
                }
              b->error = node->errors[NAT_OUT2IN_ED_ERROR_NO_TRANSLATION];
@@ -480,7 +490,7 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
            }
          else
            {
            }
          else
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              if (next_src_nat (sm, ip, l_port, r_port,
                                thread_index, rx_fib_index))
                {
              if (next_src_nat (sm, ip, l_port, r_port,
                                thread_index, rx_fib_index))
                {
@@ -508,14 +518,18 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
 
       if (PREDICT_FALSE (identity_nat))
        {
 
       if (PREDICT_FALSE (identity_nat))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
 
       /* Create session initiated by host from external network */
          goto out;
        }
 
       /* Create session initiated by host from external network */
-      s = create_session_for_static_mapping_ed (sm, b, l_key, e_key, node,
-                                               rx_fib_index, thread_index, 0,
-                                               0, vlib_time_now (vm));
+      s =
+       create_session_for_static_mapping_ed (sm, b, sm_addr, sm_port,
+                                             sm_fib_index, ip->dst_address,
+                                             l_port, rx_fib_index, *proto,
+                                             node, rx_fib_index,
+                                             thread_index, 0, 0,
+                                             vlib_time_now (vm));
 
       if (!s)
        {
 
       if (!s)
        {
@@ -545,8 +559,11 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 out:
   if (s)
     }
 out:
   if (s)
-    *p_value = s->in2out;
-  *p_dont_translate = dont_translate;
+    {
+      *addr = s->in2out.addr;
+      *port = s->in2out.port;
+      *fib_index = s->in2out.fib_index;
+    }
   if (d)
     *(snat_session_t **) d = s;
   return next;
   if (d)
     *(snat_session_t **) d = s;
   return next;
@@ -572,8 +589,8 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
 
   old_addr = ip->dst_address.as_u32;
 
 
   old_addr = ip->dst_address.as_u32;
 
-  make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol, rx_fib_index,
-             0, 0, ~0, ~0, &s_kv);
+  init_ed_k (&s_kv, ip->dst_address, 0, ip->src_address, 0, rx_fib_index,
+            ip->protocol);
 
   if (!clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
     {
 
   if (!clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
     {
@@ -594,7 +611,7 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
          return 0;
        }
 
          return 0;
        }
 
-      make_sm_kv (&kv, &ip->dst_address, 0, 0, 0);
+      init_nat_k (&kv, ip->dst_address, 0, 0, 0);
       if (clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
       if (clib_bihash_search_8_8
          (&sm->static_mapping_by_external, &kv, &value))
        {
@@ -630,8 +647,8 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1))
        nat_elog_notice ("out2in key add failed");
 
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1))
        nat_elog_notice ("out2in key add failed");
 
-      make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
-                 m->fib_index, 0, 0, thread_index, s - tsm->sessions, &s_kv);
+      init_ed_kv (&s_kv, ip->dst_address, 0, ip->src_address, 0, m->fib_index,
+                 ip->protocol, thread_index, s - tsm->sessions);
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1))
        nat_elog_notice ("in2out key add failed");
     }
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1))
        nat_elog_notice ("in2out key add failed");
     }
@@ -738,10 +755,10 @@ nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm,
              goto trace0;
            }
 
              goto trace0;
            }
 
-         make_ed_kv (&ip0->dst_address, &ip0->src_address,
-                     ip0->protocol, rx_fib_index0,
-                     vnet_buffer (b0)->ip.reass.l4_dst_port,
-                     vnet_buffer (b0)->ip.reass.l4_src_port, ~0, ~0, &kv0);
+         init_ed_k (&kv0, ip0->dst_address,
+                    vnet_buffer (b0)->ip.reass.l4_dst_port, ip0->src_address,
+                    vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0,
+                    ip0->protocol);
 
          /* there is a stashed index in vnet_buffer2 from handoff node,
           * see if we can use it */
 
          /* there is a stashed index in vnet_buffer2 from handoff node,
           * see if we can use it */
@@ -757,8 +774,7 @@ nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm,
                  (s0->out2in.addr.as_u32 == ip0->dst_address.as_u32
                   && s0->out2in.port ==
                   vnet_buffer (b0)->ip.reass.l4_dst_port
                  (s0->out2in.addr.as_u32 == ip0->dst_address.as_u32
                   && s0->out2in.port ==
                   vnet_buffer (b0)->ip.reass.l4_dst_port
-                  && s0->out2in.protocol ==
-                  ip_proto_to_nat_proto (ip0->protocol)
+                  && s0->nat_proto == ip_proto_to_nat_proto (ip0->protocol)
                   && s0->out2in.fib_index == rx_fib_index0
                   && s0->ext_host_addr.as_u32 == ip0->src_address.as_u32
                   && s0->ext_host_port ==
                   && s0->out2in.fib_index == rx_fib_index0
                   && s0->ext_host_addr.as_u32 == ip0->src_address.as_u32
                   && s0->ext_host_port ==
@@ -991,10 +1007,12 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
          snat_session_t *s0 = 0;
          clib_bihash_kv_16_8_t kv0, value0;
          ip_csum_t sum0;
          snat_session_t *s0 = 0;
          clib_bihash_kv_16_8_t kv0, value0;
          ip_csum_t sum0;
-         snat_session_key_t e_key0, l_key0;
          lb_nat_type_t lb_nat0;
          twice_nat_type_t twice_nat0;
          u8 identity_nat0;
          lb_nat_type_t lb_nat0;
          twice_nat_type_t twice_nat0;
          u8 identity_nat0;
+         ip4_address_t sm_addr;
+         u16 sm_port;
+         u32 sm_fib_index;
 
          /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
 
          /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
@@ -1053,10 +1071,10 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
              goto trace0;
            }
 
              goto trace0;
            }
 
-         make_ed_kv (&ip0->dst_address, &ip0->src_address,
-                     ip0->protocol, rx_fib_index0,
-                     vnet_buffer (b0)->ip.reass.l4_dst_port,
-                     vnet_buffer (b0)->ip.reass.l4_src_port, ~0, ~0, &kv0);
+         init_ed_k (&kv0, ip0->dst_address,
+                    vnet_buffer (b0)->ip.reass.l4_dst_port, ip0->src_address,
+                    vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0,
+                    ip0->protocol);
 
          s0 = NULL;
          if (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv0, &value0))
 
          s0 = NULL;
          if (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv0, &value0))
@@ -1078,15 +1096,12 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
            {
              /* Try to match static mapping by external address and port,
                 destination address and port in packet */
            {
              /* Try to match static mapping by external address and port,
                 destination address and port in packet */
-             e_key0.addr = ip0->dst_address;
-             e_key0.port = vnet_buffer (b0)->ip.reass.l4_dst_port;
-             e_key0.protocol = proto0;
-             e_key0.fib_index = rx_fib_index0;
-
-             if (snat_static_mapping_match (sm, e_key0, &l_key0, 1, 0,
-                                            &twice_nat0, &lb_nat0,
-                                            &ip0->src_address,
-                                            &identity_nat0))
+
+             if (snat_static_mapping_match
+                 (sm, ip0->dst_address,
+                  vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
+                  proto0, &sm_addr, &sm_port, &sm_fib_index, 1, 0,
+                  &twice_nat0, &lb_nat0, &ip0->src_address, &identity_nat0))
                {
                  /*
                   * Send DHCP packets to the ipv4 stack, or we won't
                {
                  /*
                   * Send DHCP packets to the ipv4 stack, or we won't
@@ -1140,12 +1155,18 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
                }
 
              /* Create session initiated by host from external network */
                }
 
              /* Create session initiated by host from external network */
-             s0 = create_session_for_static_mapping_ed (sm, b0, l_key0,
-                                                        e_key0, node,
+             s0 = create_session_for_static_mapping_ed (sm, b0,
+                                                        sm_addr, sm_port,
+                                                        sm_fib_index,
+                                                        ip0->dst_address,
+                                                        vnet_buffer (b0)->
+                                                        ip.reass.l4_dst_port,
+                                                        rx_fib_index0,
+                                                        proto0, node,
                                                         rx_fib_index0,
                                                         thread_index,
                                                         rx_fib_index0,
                                                         thread_index,
-                                                        twice_nat0,
-                                                        lb_nat0, now);
+                                                        twice_nat0, lb_nat0,
+                                                        now);
              if (!s0)
                {
                  next0 = NAT_NEXT_DROP;
              if (!s0)
                {
                  next0 = NAT_NEXT_DROP;