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);
-  snat_session_key_t key0, sm0;
   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 */
@@ -141,7 +137,13 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
                              &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
@@ -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)
 {
-  snat_session_key_t key0;
   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 */
-  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))
     {
@@ -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)
     {
-      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,
-                                          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->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,
-                  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,
-                                           &s->out2in);
+                                           &s->out2in.addr,
+                                           s->out2in.port, s->nat_proto);
 
       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,
+          ip4_address_t i2o_addr,
+          u16 i2o_port,
           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_key_t key1;
   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;
+  ip4_address_t sm_addr;
+  u16 sm_port;
+  u32 sm_fib_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;
     }
 
-  key1.protocol = key0->protocol;
-
   /* 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,
-                                              thread_index, &key1,
+                                              thread_index,
+                                              nat_proto,
+                                              &sm_addr, &sm_port,
                                               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);
-  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))
     {
@@ -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;
-  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");
 
-  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))
@@ -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,
-                                      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->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,
-              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
-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;
-  snat_session_key_t key0;
   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))
     {
-      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);
-      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);
-         key0.port = inner_echo0->identifier;
+         *port = inner_echo0->identifier;
          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;
        }
     }
-  *p_key0 = key0;
   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,
-                       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;
-  u32 rx_fib_index0;
-  snat_session_key_t key0;
   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 ();
+  *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);
+  *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;
     }
-  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 (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;
            }
        }
@@ -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,
-                                                rx_fib_index0,
-                                                thread_index)))
+                                                *fib_index, thread_index)))
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
@@ -527,15 +517,16 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
          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)
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
     }
@@ -558,12 +549,14 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 
 out:
-  *p_proto = key0.protocol;
   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)
-    *(snat_session_t **) d = s0;
+    *(snat_session_t **) (d) = s0;
   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,
-                       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 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;
+  *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);
+  *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 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
-      (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,
-                                                 rx_fib_index0)))
+                                                 *fib_index)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
 
@@ -647,10 +641,6 @@ icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 
 out:
-  *p_value = sm0;
-out2:
-  *p_proto = key0.protocol;
-  *p_dont_translate = dont_translate;
   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 ();
-  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;
@@ -683,9 +675,9 @@ icmp_in2out (snat_main_t * sm,
 
   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)
@@ -708,7 +700,7 @@ icmp_in2out (snat_main_t * sm,
     }
 
   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,
@@ -722,11 +714,11 @@ icmp_in2out (snat_main_t * sm,
 
       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;
-             new_id0 = sm0.port;
+             new_id0 = port;
              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;
-         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,
@@ -776,7 +768,7 @@ icmp_in2out (snat_main_t * sm,
              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;
@@ -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;
-             new_id0 = sm0.port;
+             new_id0 = port;
              ((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))
-       vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index;
+       vnet_buffer (b0)->sw_if_index[VLIB_TX] = fib_index;
     }
 
 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;
-  snat_session_key_t m_key;
   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;
 
@@ -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;
-         snat_session_key_t key0, key1;
          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,
@@ -1068,7 +1050,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                        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;
@@ -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,
@@ -1277,8 +1259,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                        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;
 
@@ -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;
-         snat_session_key_t key0;
          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))
@@ -1519,7 +1500,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
                        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))
@@ -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;
-         snat_session_key_t key0, sm0;
          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];
@@ -1854,21 +1842,18 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
              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;
            }
 
-         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;
 
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;
-  snat_session_key_t key;
   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
        {
-         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;
        }
-      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");
 
@@ -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,
-                                          s->in2out.protocol,
+                                          s->nat_proto,
                                           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->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,
-                  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++)
            {
-             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,
-                                                     &key);
+                                                     &s->ext_host_nat_addr,
+                                                     s->ext_host_nat_port,
+                                                     s->nat_proto);
                  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,
-                                         &s->out2in);
+                                         &s->out2in.addr, s->out2in.port,
+                                         s->nat_proto);
     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)
        {
-#define _(N, j, n, unused)                                                    \
+#define _(N, j, n, unused)                                                   \
   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;
@@ -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_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;
-  u32 tx_fib_index;
   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
-      (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)
@@ -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;
        }
+      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:
-         tx_fib_index = sm->outside_fib_index;
+         s->out2in.fib_index = sm->outside_fib_index;
          break;
        case 1:
-         tx_fib_index = sm->outside_fibs[0].fib_index;
+         s->out2in.fib_index = sm->outside_fibs[0].fib_index;
          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;
        }
 
-      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,
@@ -403,14 +404,14 @@ slow_path_ed (snat_main_t * sm,
          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))
        {
-         *sessionp = s;
+         *sessionp = NULL;
          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;
        }
+      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:
-         tx_fib_index = sm->outside_fib_index;
+         s->out2in.fib_index = sm->outside_fib_index;
          break;
        case 1:
-         tx_fib_index = sm->outside_fibs[0].fib_index;
+         s->out2in.fib_index = sm->outside_fibs[0].fib_index;
          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;
        }
 
-      s->out2in.fib_index = tx_fib_index;
       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))
@@ -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->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;
-  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,
@@ -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,
-                                      s->in2out.protocol,
+                                      s->nat_proto,
                                       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->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,
-              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;
 }
@@ -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;
-  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))
     {
-      key0.addr = ip->dst_address;
-      key0.port = udp->dst_port;
-      key0.protocol = proto;
-      key0.fib_index = sm->outside_fib_index;
       /* 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
@@ -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)
     {
-      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
     {
-      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))
@@ -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 */
-  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));
@@ -616,8 +617,8 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip,
     }
 
   /* 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));
@@ -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,
-                     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;
-  snat_session_t *s = 0;
-  u8 dont_translate = 0;
   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];
+  *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 =
-    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)
     {
@@ -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])))
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
@@ -692,7 +694,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
                                                     rx_fib_index,
                                                     thread_index)))
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
@@ -716,7 +718,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
 
       if (!s)
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          goto out;
        }
     }
@@ -742,10 +744,15 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 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)
-    *(snat_session_t **) d = s;
+    {
+      *(snat_session_t **) d = s;
+    }
   return next;
 }
 #endif
@@ -784,8 +791,8 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
     }
   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))
     {
@@ -807,7 +814,7 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
          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))
@@ -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;
 
-               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;
 
@@ -837,9 +843,8 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
 
          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 =
@@ -871,14 +876,14 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
        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");
 
-      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");
     }
@@ -1007,10 +1012,10 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm,
              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))
@@ -1295,11 +1300,10 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm,
              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));
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)
 {
-  snat_session_key_t key;
   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))
        {
-         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
        {
@@ -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;
-         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");
@@ -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,
-                            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;
@@ -247,12 +246,11 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
        }
       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;
        }
-      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;
@@ -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;
        }
-      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");
 
@@ -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->in2out.protocol, is_twice_nat_session (s));
+                              s->nat_proto, is_twice_nat_session (s));
     }
   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");
-      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");
 
@@ -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,
-                                s->in2out.protocol);
+                                s->nat_proto);
     }
 
   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,
-                                          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->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))
     {
-      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,
-                                         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,
-                                     &s->out2in);
+                                     &s->out2in.addr, s->out2in.port,
+                                     s->nat_proto);
 }
 
 int
@@ -352,7 +349,6 @@ void
 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;
@@ -371,7 +367,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
        }
       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;
        }
@@ -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;
-      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)))
@@ -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,
-                        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;
@@ -403,12 +398,11 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
     }
   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;
     }
-  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");
@@ -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;
     }
-  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");
@@ -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->in2out.protocol, is_twice_nat_session (s));
+                            s->nat_proto, is_twice_nat_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,
-                                          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->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))
     {
-      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,
-                                         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,
-                                     &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) ||
-                     (clib_net_to_host_u16 (s->out2in.port) != e_port))
+                     (s->out2in.port != e_port))
                    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) ||
-            (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;
       }
 
@@ -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_session_key_t m_key;
   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
@@ -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);
-             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;
            }
@@ -1017,11 +1002,8 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
 
       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;
@@ -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);
 
-      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);
 
-      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) */
@@ -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 (!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,
@@ -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);
 
-      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);
 
@@ -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;
 
-      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);
@@ -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_session_key_t m_key;
   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;
 
-  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
@@ -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;
 
-      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;
        }
 
-      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);
-         m_key.addr = locals[i].addr;
-         m_key.fib_index = locals[i].fib_index;
          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 :
@@ -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");
@@ -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);
-          m_key.addr = local->addr;
           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");
@@ -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) ||
-                (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);
@@ -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_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;
@@ -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;
 
-  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);
 
@@ -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))
        {
-         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");
        }
@@ -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))
        {
-         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");
        }
@@ -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) ||
-            (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);
@@ -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
-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
-test_ed_make_split ()
+test_key_calc_split ()
 {
   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;
-  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));
@@ -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));
+
+  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 *
@@ -2656,7 +2601,7 @@ snat_init (vlib_main_t * vm)
                                         FIB_SOURCE_PRIORITY_LOW,
                                         FIB_SOURCE_BH_SIMPLE);
 
-  test_ed_make_split ();
+  test_key_calc_split ();
   return error;
 }
 
@@ -2664,16 +2609,18 @@ VLIB_INIT_FUNCTION (snat_init);
 
 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;
-  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++)
     {
-      if (addresses[address_index].addr.as_u32 == k->addr.as_u32)
+      if (addresses[address_index].addr.as_u32 == addr->as_u32)
        break;
     }
 
@@ -2681,7 +2628,7 @@ snat_free_outside_address_and_port (snat_address_t * addresses,
 
   a = addresses + address_index;
 
-  switch (k->protocol)
+  switch (protocol)
     {
 #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,
-                                 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;
-  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++)
     {
-      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;
-      switch (k->protocol)
+      switch (protocol)
        {
 #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,
-                          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,
@@ -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;
-  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;
 
-  m_key.fib_index = match.fib_index;
   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))
-       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);
@@ -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],
-                                                         match.addr,
-                                                         match.protocol,
-                                                         match.port,
+                                                         match_addr,
+                                                         match_protocol,
+                                                         match_port,
                                                          &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
@@ -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;
-         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 (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");
@@ -2855,21 +2811,20 @@ snat_static_mapping_match (snat_main_t * sm,
        {
          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 */
-         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
     {
-      mapping->addr = m->external_addr;
+      *mapping_addr = m->external_addr;
       /* 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:
@@ -2897,21 +2852,26 @@ 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)
 {
   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,
-                                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;
@@ -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;
-      switch (k->protocol)
+      switch (proto)
        {
 #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++; \
-                      k->addr = a->addr; \
-                      k->port = clib_host_to_net_u16(portnum); \
+                      *addr = a->addr; \
+                      *port = clib_host_to_net_u16(portnum); \
                       return 0; \
                     } \
                 } \
@@ -2962,7 +2922,7 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses,
   if (ga)
     {
       a = ga;
-      switch (k->protocol)
+      switch (proto)
        {
 #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++; \
-              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;
@@ -2995,10 +2955,9 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses,
 }
 
 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;
@@ -3010,7 +2969,7 @@ nat_alloc_addr_and_port_mape (snat_address_t * addresses,
   if (!vec_len (addresses))
     goto exhausted;
 
-  switch (k->protocol)
+  switch (proto)
     {
 #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++; \
-              k->addr = a->addr; \
-              k->port = clib_host_to_net_u16 (portnum); \
+              *addr = a->addr; \
+              *port = clib_host_to_net_u16 (portnum); \
               return 0; \
             } \
         } \
@@ -3045,10 +3004,9 @@ exhausted:
 }
 
 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;
@@ -3060,7 +3018,7 @@ nat_alloc_addr_and_port_range (snat_address_t * addresses,
   if (!vec_len (addresses))
     goto exhausted;
 
-  switch (k->protocol)
+  switch (proto)
     {
 #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++; \
-              k->addr = a->addr; \
-              k->port = clib_host_to_net_u16 (portnum); \
+              *addr = a->addr; \
+              *port = clib_host_to_net_u16 (portnum); \
               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 *);
-  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;
 }
@@ -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 *);
-  snat_session_key_t k;
-
-  k.as_u64 = v->key;
 
   s = format (s, "%U static-mapping-index %llu",
-             format_static_mapping_key, &k, v->value);
+             format_snat_key, v->key, v->value);
 
   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_session_key_t m_key;
   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)))
     {
-      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))
        {
@@ -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)))
     {
-      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))
        {
@@ -3345,9 +3288,8 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t * ip, u32 rx_fib_index,
          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)))
@@ -3415,9 +3357,8 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * 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)))
@@ -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)))
     {
-      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))
        {
@@ -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)))
     {
-      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))
        {
@@ -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_session_key_t key;
   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
-         (sm->addresses, thread_index, &key))
+         (sm->addresses, thread_index, *out_addr, out_port, proto))
        return;
     }
 
@@ -3599,9 +3534,12 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
 
   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;
@@ -3610,10 +3548,10 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
   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:
-      key.fib_index = sm->outside_fibs[0].fib_index;
+      s->out2in.fib_index = sm->outside_fibs[0].fib_index;
       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)
                 {
-                  key.fib_index = outside_fib->fib_index;
+                  s->out2in.fib_index = outside_fib->fib_index;
                   break;
                 }
             }
@@ -3632,17 +3570,14 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
       /* *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");
 
-  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");
 }
@@ -3653,7 +3588,6 @@ nat_ha_sdel_cb (ip4_address_t * out_addr, u16 out_port,
                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;
@@ -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);
 
-  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;
 
@@ -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;
-  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);
 
-  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;
 
@@ -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_session_key_t key;
   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
-         (sm->addresses, thread_index, &key))
+         (sm->addresses, thread_index, *out_addr, out_port, proto))
        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
-         (sm->twice_nat_addresses, thread_index, &key))
+         (sm->addresses, thread_index, *ehn_addr, ehn_port, proto))
        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:
-      key.fib_index = sm->outside_fib_index;
+      s->out2in.fib_index = sm->outside_fib_index;
       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* */
@@ -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)
                 {
-                  key.fib_index = outside_fib->fib_index;
+                  s->out2in.fib_index = outside_fib->fib_index;
                   break;
                 }
             }
@@ -3789,25 +3708,23 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port,
       /* *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");
 
-  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");
 }
@@ -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);
 
-  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;
 
@@ -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);
 
-  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;
 
@@ -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_session_key_t m_key;
   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:
-  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
@@ -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);
-  snat_session_key_t key;
   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);
 
-  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))
     {
@@ -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;
-  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;
index fbf2105..8b04e18 100644 (file)
@@ -68,21 +68,6 @@ typedef struct
   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
 {
@@ -251,11 +236,23 @@ typedef enum
 /* *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;
@@ -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,
-                                         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,
@@ -511,7 +511,9 @@ typedef int (nat_alloc_out_addr_and_port_function_t) (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);
 
@@ -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,
-                           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,
-                           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,
-                           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,
-                           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,
-                          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,
-                          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,
-                         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,
-                         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,
@@ -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 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
@@ -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 k                 allocated address and port pair
  * @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,
-                                        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.
  *
- * @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
@@ -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,
-                              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,
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;
-         snat_session_key_t m_key0;
          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)))
            {
-             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))
@@ -145,10 +140,9 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                    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))
                {
@@ -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;
-         snat_session_key_t m_key0;
          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)))
            {
-             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))
@@ -262,10 +251,9 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
                    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))
                {
@@ -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;
-         snat_session_key_t m_key0;
          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);
-             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))
@@ -391,11 +378,7 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
 
          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))
@@ -405,10 +388,9 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
                    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))
                {
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++;
 
-            switch (s->in2out.protocol)
+            switch (s->nat_proto)
               {
               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++;
 
-        switch (s->in2out.protocol)
+        switch (s->nat_proto)
           {
           case NAT_PROTOCOL_ICMP:
             icmp_sessions++;
@@ -1071,7 +1071,8 @@ add_static_mapping_command_fn (vlib_main_t * vm,
       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);
 
@@ -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)
     {
@@ -1730,10 +1732,13 @@ nat44_del_session_command_fn (vlib_main_t * vm,
 
   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
-    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)
     {
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_session_key_t m_key;
 
   /* *INDENT-OFF* */
   vec_foreach (ap, sm->addresses)
@@ -103,11 +102,7 @@ is_hairpinning (snat_main_t * sm, ip4_address_t * dst_addr)
     }
   /* *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;
 
@@ -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)
 {
-  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;
-
-  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 */
-  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
@@ -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;
-         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_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)
@@ -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)
 {
-  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;
@@ -277,10 +272,9 @@ snat_icmp_hairpinning (snat_main_t * sm,
       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));
@@ -288,13 +282,10 @@ snat_icmp_hairpinning (snat_main_t * sm,
        }
       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;
        }
@@ -334,12 +325,7 @@ snat_icmp_hairpinning (snat_main_t * sm,
     }
   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))
        {
@@ -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;
-             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) -
@@ -412,7 +395,7 @@ nat_hairpinning_sm_unknown_proto (snat_main_t * sm,
   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;
 
@@ -447,11 +430,11 @@ nat44_ed_hairpinning_unknown_proto (snat_main_t * sm,
     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))
     {
-      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;
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;
-  snat_session_key_t k;
   u32 worker_index = 0;
   int rv;
 
-  k.protocol = proto;
-
   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;
 }
index abd1d86..9d1ed1b 100644 (file)
@@ -1110,8 +1110,8 @@ static void
 
   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);
@@ -1201,8 +1201,8 @@ send_nat44_static_mapping_details (snat_static_mapping_t * m,
   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)
@@ -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);
-      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));
@@ -1312,7 +1312,7 @@ static void
 
   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);
@@ -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->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);
@@ -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;
 
-  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);
@@ -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->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))
     {
@@ -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);
-      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);
@@ -1875,7 +1875,7 @@ static void
 
   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,
@@ -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);
-  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;
 
@@ -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);
-    locals->port = htons (ap->port);
+    locals->port = ap->port;
     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);
-  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);
-  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;
 
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,
-                      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;
-  u8 protocol;
+  nat_protocol_t 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;
@@ -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;
+  *dont_translate = 0;
 
   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)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          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)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          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:
-  *p_proto = protocol;
+  *proto = protocol;
   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)
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,
-                      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;
-  u8 dont_translate = 0;
   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;
+  *dont_translate = 0;
 
   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)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          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)))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          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:
-  *p_proto = protocol;
+  *proto = protocol;
   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)
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)
 {
-  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",
-             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;
 }
 
index 7c28919..76dd9a7 100644 (file)
 #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,
@@ -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)
 {
-  switch (s->in2out.protocol)
+  switch (s->nat_proto)
     {
     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->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);
 }
@@ -444,13 +521,20 @@ nat44_session_update_lru (snat_main_t * sm, snat_session_t * s,
 }
 
 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;
+}
+
+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;
 }
 
@@ -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,
-                    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;
@@ -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;
        }
     }
-  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);
@@ -589,11 +664,11 @@ get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
   return 0;
 }
 
-
 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;
@@ -640,8 +715,8 @@ get_icmp_o2i_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
          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);
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)
     {
-      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,
-                                          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->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,
-                  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,
-                                           &s->out2in);
+                                           &s->out2in.addr, s->out2in.port,
+                                           s->nat_proto);
 
       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,
-                                  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)
 {
@@ -198,8 +203,7 @@ create_session_for_static_mapping (snat_main_t * sm,
   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");
@@ -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->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;
-  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");
 
-  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))
@@ -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,
-                                      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->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,
-              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
-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;
-  snat_session_key_t key0;
   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))
     {
-      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);
-      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);
-         key0.port = inner_echo0->identifier;
+         *port = inner_echo0->identifier;
          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;
        }
     }
-  *p_key0 = key0;
   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,
-                       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;
-  u32 rx_fib_index0;
-  snat_session_key_t key0;
-  snat_session_key_t sm0;
   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 ();
+  *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);
+  *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;
     }
-  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
-         (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)
            {
@@ -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)))
                {
-                 dont_translate = 1;
+                 *dont_translate = 1;
                  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
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              goto out;
            }
        }
@@ -399,13 +404,15 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
 
       if (PREDICT_FALSE (identity_nat))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          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)
        {
@@ -432,10 +439,12 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 
 out:
-  *p_proto = key0.protocol;
   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;
@@ -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,
-                       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;
-  snat_session_key_t key0;
-  snat_session_key_t sm0;
-  u8 dont_translate = 0;
   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);
 
-  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;
-      goto out2;
+      goto out;
     }
-  key0.fib_index = rx_fib_index0;
-
   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))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          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:
-  *p_value = sm0;
-out2:
-  *p_proto = key0.protocol;
-  *p_dont_translate = dont_translate;
   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)
 {
-  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;
@@ -544,12 +547,16 @@ icmp_out2in (snat_main_t * sm,
   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,
-                                       &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)
@@ -572,8 +579,8 @@ icmp_out2in (snat_main_t * sm,
     }
 
   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,
@@ -588,11 +595,11 @@ icmp_out2in (snat_main_t * sm,
 
       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;
-             new_id0 = sm0.port;
+             new_id0 = port;
              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;
-         inner_ip0->src_address = sm0.addr;
+         inner_ip0->src_address = addr;
          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);
 
-         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;
-             new_id0 = sm0.port;
+             new_id0 = port;
              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;
-             new_id0 = sm0.port;
+             new_id0 = port;
              ((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;
-  snat_session_key_t m_key;
   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;
 
@@ -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;
-         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;
+         ip4_address_t sm_addr0, sm_addr1;
+         u16 sm_port0, sm_port1;
+         u32 sm_fib_index0, sm_fib_index1;
 
          /* Prefetch next iteration. */
          {
@@ -839,20 +843,19 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
              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
-                 (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
@@ -881,8 +884,15 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
                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;
@@ -1011,12 +1021,9 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
              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))
@@ -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
-                 (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
@@ -1053,8 +1063,14 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
                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;
@@ -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;
-         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;
+         ip4_address_t sm_addr0;
+         u16 sm_port0;
+         u32 sm_fib_index0;
 
          /* 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;
            }
 
-         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))
@@ -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
-                 (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
@@ -1268,8 +1286,15 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
                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;
@@ -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;
-         snat_session_key_t key0, sm0;
          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];
@@ -1484,19 +1511,17 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
              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;
            }
 
-         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;
 
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;
-  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);
 
@@ -123,7 +122,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
        }
       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;
        }
@@ -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;
        }
-      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");
 
@@ -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,
-                                          s->in2out.protocol,
+                                          s->nat_proto,
                                           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->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,
-                  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++)
            {
-             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,
-                                         &s->out2in);
+                                         &s->out2in.addr, s->out2in.port,
+                                         s->nat_proto);
     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,
-                                     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,
@@ -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;
-  snat_session_key_t eh_key;
   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;
     }
 
-  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];
@@ -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;
-  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->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 */
-  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,
@@ -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 &&
-                                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,
-                                              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))
        {
@@ -266,18 +275,16 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
            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;
-      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
     {
-      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,
@@ -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,
-                                      s->in2out.protocol,
+                                      s->nat_proto,
                                       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->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,
-              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;
 }
@@ -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];
 
-  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;
 
@@ -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;
        }
-      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))
@@ -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->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;
-      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))
@@ -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,
-                     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;
-  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 ();
+  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
-      (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;
@@ -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 */
-      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
-         (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)
            {
@@ -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)))
                {
-                 dont_translate = 1;
+                 *dont_translate = 1;
                  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
            {
-             dont_translate = 1;
+             *dont_translate = 1;
              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))
        {
-         dont_translate = 1;
+         *dont_translate = 1;
          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)
        {
@@ -545,8 +559,11 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
     }
 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;
@@ -572,8 +589,8 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
 
   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))
     {
@@ -594,7 +611,7 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
          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))
        {
@@ -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");
 
-      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");
     }
@@ -738,10 +755,10 @@ nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm,
              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 */
@@ -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.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 ==
@@ -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_key_t e_key0, l_key0;
          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];
@@ -1053,10 +1071,10 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
              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))
@@ -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 */
-             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
@@ -1140,12 +1155,18 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
                }
 
              /* 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,
-                                                        twice_nat0,
-                                                        lb_nat0, now);
+                                                        twice_nat0, lb_nat0,
+                                                        now);
              if (!s0)
                {
                  next0 = NAT_NEXT_DROP;