nat: nat44-ed pool address allocation improvement
[vpp.git] / src / plugins / nat / nat44-ed / nat44_ed_cli.c
index 8ded7ee..9743ce6 100644 (file)
@@ -162,8 +162,8 @@ done:
 }
 
 static clib_error_t *
-nat_show_workers_commnad_fn (vlib_main_t * vm, unformat_input_t * input,
-                            vlib_cli_command_t * cmd)
+nat_show_workers_command_fn (vlib_main_t *vm, unformat_input_t *input,
+                            vlib_cli_command_t *cmd)
 {
   snat_main_t *sm = &snat_main;
   u32 *worker;
@@ -283,12 +283,7 @@ nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input,
   else if (unformat (input, "verbose"))
     verbose = 2;
 
-  vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->static_mapping_by_local,
-                  verbose);
-  vlib_cli_output (vm, "%U",
-                  format_bihash_8_8, &sm->static_mapping_by_external,
-                  verbose);
-      vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose);
+  vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose);
   vec_foreach_index (i, sm->per_thread_data)
   {
     vlib_cli_output (vm, "-------- thread %d %s --------\n",
@@ -296,8 +291,7 @@ nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input,
     vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose);
   }
 
-      vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash,
-                      verbose);
+  vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash, verbose);
 
   vlib_cli_output (vm, "-------- hash table parameters --------\n");
   vlib_cli_output (vm, "translation buckets: %u", sm->translation_buckets);
@@ -419,9 +413,13 @@ add_address_command_fn (vlib_main_t * vm,
   for (i = 0; i < count; i++)
     {
       if (is_add)
-       rv = snat_add_address (sm, &this_addr, vrf_id, twice_nat);
+       {
+         rv = nat44_ed_add_address (&this_addr, vrf_id, twice_nat);
+       }
       else
-       rv = snat_del_address (sm, this_addr, 0, twice_nat);
+       {
+         rv = nat44_ed_del_address (this_addr, 0, twice_nat);
+       }
 
       switch (rv)
        {
@@ -498,6 +496,7 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
   u32 udp_sessions = 0;
   u32 tcp_sessions = 0;
   u32 icmp_sessions = 0;
+  u32 other_sessions = 0;
 
   u32 timed_out = 0;
   u32 transitory = 0;
@@ -522,40 +521,42 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
             if (now >= sess_timeout_time)
               timed_out++;
 
-            switch (s->nat_proto)
-              {
-              case NAT_PROTOCOL_ICMP:
-                icmp_sessions++;
-                break;
-              case NAT_PROTOCOL_TCP:
-                tcp_sessions++;
-                if (s->state)
-                  {
-                    if (s->tcp_closed_timestamp)
-                      {
-                        if (now >= s->tcp_closed_timestamp)
-                          {
-                            ++transitory_closed;
-                          }
-                        else
-                          {
-                            ++transitory_wait_closed;
-                          }
-                      }
-                    transitory++;
-                  }
-                else
-                  established++;
-                break;
-              case NAT_PROTOCOL_UDP:
-              default:
-                udp_sessions++;
-                break;
-              }
-          }
-          nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
-          count += pool_elts (tsm->sessions);
-        }
+           switch (s->proto)
+             {
+             case IP_PROTOCOL_ICMP:
+               icmp_sessions++;
+               break;
+             case IP_PROTOCOL_TCP:
+               tcp_sessions++;
+               if (s->state)
+                 {
+                   if (s->tcp_closed_timestamp)
+                     {
+                       if (now >= s->tcp_closed_timestamp)
+                         {
+                           ++transitory_closed;
+                         }
+                       else
+                         {
+                           ++transitory_wait_closed;
+                         }
+                     }
+                   transitory++;
+                 }
+               else
+                 established++;
+               break;
+             case IP_PROTOCOL_UDP:
+               udp_sessions++;
+               break;
+             default:
+               ++other_sessions;
+               break;
+             }
+          }
+         nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
+         count += pool_elts (tsm->sessions);
+       }
     }
   else
     {
@@ -567,36 +568,38 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
         if (now >= sess_timeout_time)
           timed_out++;
 
-        switch (s->nat_proto)
-          {
-          case NAT_PROTOCOL_ICMP:
-            icmp_sessions++;
-            break;
-          case NAT_PROTOCOL_TCP:
-            tcp_sessions++;
-            if (s->state)
-              {
-                if (s->tcp_closed_timestamp)
-                  {
-                    if (now >= s->tcp_closed_timestamp)
-                      {
-                        ++transitory_closed;
-                      }
-                    else
-                      {
-                        ++transitory_wait_closed;
-                      }
-                  }
-                transitory++;
-              }
-            else
-              established++;
-            break;
-          case NAT_PROTOCOL_UDP:
-          default:
-            udp_sessions++;
-            break;
-          }
+       switch (s->proto)
+         {
+         case IP_PROTOCOL_ICMP:
+           icmp_sessions++;
+           break;
+         case IP_PROTOCOL_TCP:
+           tcp_sessions++;
+           if (s->state)
+             {
+               if (s->tcp_closed_timestamp)
+                 {
+                   if (now >= s->tcp_closed_timestamp)
+                     {
+                       ++transitory_closed;
+                     }
+                   else
+                     {
+                       ++transitory_wait_closed;
+                     }
+                 }
+               transitory++;
+             }
+           else
+             established++;
+           break;
+         case IP_PROTOCOL_UDP:
+           udp_sessions++;
+           break;
+         default:
+           ++other_sessions;
+           break;
+         }
       }
       nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
       count = pool_elts (tsm->sessions);
@@ -613,6 +616,7 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
                   transitory_closed);
   vlib_cli_output (vm, "total udp sessions: %u", udp_sessions);
   vlib_cli_output (vm, "total icmp sessions: %u", icmp_sessions);
+  vlib_cli_output (vm, "total other sessions: %u", other_sessions);
   return 0;
 }
 
@@ -628,14 +632,14 @@ nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input,
     {
       vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
       if (ap->fib_index != ~0)
-          vlib_cli_output (vm, "  tenant VRF: %u",
-            fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
+       vlib_cli_output (
+         vm, "  tenant VRF: %u",
+         fib_table_get (ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
       else
         vlib_cli_output (vm, "  tenant VRF independent");
-    #define _(N, i, n, s) \
-      vlib_cli_output (vm, "  %d busy %s ports", ap->busy_##n##_ports, s);
-      foreach_nat_protocol
-    #undef _
+
+      if (ap->addr_len != ~0)
+       vlib_cli_output (vm, "  synced with interface address");
     }
   vlib_cli_output (vm, "NAT44 twice-nat pool addresses:");
   vec_foreach (ap, sm->twice_nat_addresses)
@@ -646,10 +650,9 @@ nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input,
             fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
       else
         vlib_cli_output (vm, "  tenant VRF independent");
-    #define _(N, i, n, s) \
-      vlib_cli_output (vm, "  %d busy %s ports", ap->busy_##n##_ports, s);
-      foreach_nat_protocol
-    #undef _
+
+      if (ap->addr_len != ~0)
+       vlib_cli_output (vm, "  synced with interface address");
     }
   return 0;
 }
@@ -665,8 +668,7 @@ snat_feature_command_fn (vlib_main_t * vm,
   u32 *inside_sw_if_indices = 0;
   u32 *outside_sw_if_indices = 0;
   u8 is_output_feature = 0;
-  int is_del = 0;
-  int i;
+  int i, rv, is_del = 0;
 
   sw_if_index = ~0;
 
@@ -701,8 +703,15 @@ snat_feature_command_fn (vlib_main_t * vm,
          sw_if_index = inside_sw_if_indices[i];
          if (is_output_feature)
            {
-             if (snat_interface_add_del_output_feature
-                 (sw_if_index, 1, is_del))
+             if (is_del)
+               {
+                 rv = nat44_ed_del_output_interface (sw_if_index);
+               }
+             else
+               {
+                 rv = nat44_ed_add_output_interface (sw_if_index);
+               }
+             if (rv)
                {
                  error = clib_error_return (0, "%s %U failed",
                                             is_del ? "del" : "add",
@@ -713,7 +722,15 @@ snat_feature_command_fn (vlib_main_t * vm,
            }
          else
            {
-             if (snat_interface_add_del (sw_if_index, 1, is_del))
+             if (is_del)
+               {
+                 rv = nat44_ed_del_interface (sw_if_index, 1);
+               }
+             else
+               {
+                 rv = nat44_ed_add_interface (sw_if_index, 1);
+               }
+             if (rv)
                {
                  error = clib_error_return (0, "%s %U failed",
                                             is_del ? "del" : "add",
@@ -732,8 +749,15 @@ snat_feature_command_fn (vlib_main_t * vm,
          sw_if_index = outside_sw_if_indices[i];
          if (is_output_feature)
            {
-             if (snat_interface_add_del_output_feature
-                 (sw_if_index, 0, is_del))
+             if (is_del)
+               {
+                 rv = nat44_ed_del_output_interface (sw_if_index);
+               }
+             else
+               {
+                 rv = nat44_ed_add_output_interface (sw_if_index);
+               }
+             if (rv)
                {
                  error = clib_error_return (0, "%s %U failed",
                                             is_del ? "del" : "add",
@@ -744,7 +768,15 @@ snat_feature_command_fn (vlib_main_t * vm,
            }
          else
            {
-             if (snat_interface_add_del (sw_if_index, 0, is_del))
+             if (is_del)
+               {
+                 rv = nat44_ed_del_interface (sw_if_index, 0);
+               }
+             else
+               {
+                 rv = nat44_ed_add_interface (sw_if_index, 0);
+               }
+             if (rv)
                {
                  error = clib_error_return (0, "%s %U failed",
                                             is_del ? "del" : "add",
@@ -775,21 +807,22 @@ nat44_show_interfaces_command_fn (vlib_main_t * vm, unformat_input_t * input,
   vlib_cli_output (vm, "NAT44 interfaces:");
   pool_foreach (i, sm->interfaces)
    {
-    vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
-                     i->sw_if_index,
-                     (nat_interface_is_inside(i) &&
-                      nat_interface_is_outside(i)) ? "in out" :
-                     (nat_interface_is_inside(i) ? "in" : "out"));
+     vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
+                     i->sw_if_index,
+                     (nat44_ed_is_interface_inside (i) &&
+                      nat44_ed_is_interface_outside (i)) ?
+                       "in out" :
+                       (nat44_ed_is_interface_inside (i) ? "in" : "out"));
   }
 
   pool_foreach (i, sm->output_feature_interfaces)
    {
-    vlib_cli_output (vm, " %U output-feature %s",
-                     format_vnet_sw_if_index_name, vnm,
-                     i->sw_if_index,
-                     (nat_interface_is_inside(i) &&
-                      nat_interface_is_outside(i)) ? "in out" :
-                     (nat_interface_is_inside(i) ? "in" : "out"));
+     vlib_cli_output (vm, " %U output-feature %s",
+                     format_vnet_sw_if_index_name, vnm, i->sw_if_index,
+                     (nat44_ed_is_interface_inside (i) &&
+                      nat44_ed_is_interface_outside (i)) ?
+                       "in out" :
+                       (nat44_ed_is_interface_inside (i) ? "in" : "out"));
   }
 
   return 0;
@@ -801,18 +834,16 @@ add_static_mapping_command_fn (vlib_main_t * vm,
                               vlib_cli_command_t * cmd)
 {
   unformat_input_t _line_input, *line_input = &_line_input;
+  vnet_main_t *vnm = vnet_get_main ();
   clib_error_t *error = 0;
-  ip4_address_t l_addr, e_addr, exact_addr;
+  ip4_address_t l_addr, e_addr, pool_addr;
   u32 l_port = 0, e_port = 0, vrf_id = ~0;
-  int is_add = 1, addr_only = 1, rv, exact = 0;
+  u8 l_port_set = 0, e_port_set = 0;
+  int is_add = 1, rv;
+  u32 flags = 0;
   u32 sw_if_index = ~0;
-  vnet_main_t *vnm = vnet_get_main ();
-  nat_protocol_t proto = NAT_PROTOCOL_OTHER;
-  u8 proto_set = 0;
-  twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
-  u8 out2in_only = 0;
+  ip_protocol_t proto = 0;
 
-  /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
@@ -820,38 +851,57 @@ add_static_mapping_command_fn (vlib_main_t * vm,
     {
       if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
                    &l_port))
-       addr_only = 0;
+       {
+         l_port_set = 1;
+       }
       else
        if (unformat (line_input, "local %U", unformat_ip4_address, &l_addr))
        ;
       else if (unformat (line_input, "external %U %u", unformat_ip4_address,
                         &e_addr, &e_port))
-       addr_only = 0;
+       {
+         e_port_set = 1;
+       }
       else if (unformat (line_input, "external %U", unformat_ip4_address,
                         &e_addr))
        ;
       else if (unformat (line_input, "external %U %u",
                         unformat_vnet_sw_interface, vnm, &sw_if_index,
                         &e_port))
-       addr_only = 0;
+       {
+         flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+         e_port_set = 1;
+       }
       else if (unformat (line_input, "external %U",
                         unformat_vnet_sw_interface, vnm, &sw_if_index))
-       ;
+       {
+         flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+       }
       else if (unformat (line_input, "exact %U", unformat_ip4_address,
-                        &exact_addr))
-       exact = 1;
+                        &pool_addr))
+       {
+         flags |= NAT_SM_FLAG_EXACT_ADDRESS;
+       }
       else if (unformat (line_input, "vrf %u", &vrf_id))
        ;
-      else if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
-       proto_set = 1;
-      else if (unformat (line_input, "twice-nat"))
-       twice_nat = TWICE_NAT;
+      else if (unformat (line_input, "%U", unformat_ip_protocol, &proto))
+       ;
       else if (unformat (line_input, "self-twice-nat"))
-       twice_nat = TWICE_NAT_SELF;
+       {
+         flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
+       }
+      else if (unformat (line_input, "twice-nat"))
+       {
+         flags |= NAT_SM_FLAG_TWICE_NAT;
+       }
       else if (unformat (line_input, "out2in-only"))
-       out2in_only = 1;
+       {
+         flags |= NAT_SM_FLAG_OUT2IN_ONLY;
+       }
       else if (unformat (line_input, "del"))
-       is_add = 0;
+       {
+         is_add = 0;
+       }
       else
        {
          error = clib_error_return (0, "unknown input: '%U'",
@@ -860,32 +910,37 @@ add_static_mapping_command_fn (vlib_main_t * vm,
        }
     }
 
-  if (twice_nat && addr_only)
+  if (l_port_set != e_port_set)
     {
-      error = clib_error_return (0, "twice NAT only for 1:1 NAPT");
+      error = clib_error_return (0, "Either both ports are set or none.");
       goto done;
     }
 
-  if (addr_only)
+  if (!l_port_set)
     {
-      if (proto_set)
-       {
-         error =
-           clib_error_return (0,
-                              "address only mapping doesn't support protocol");
-         goto done;
-       }
+      flags |= NAT_SM_FLAG_ADDR_ONLY;
     }
-  else if (!proto_set)
+  else
     {
-      error = clib_error_return (0, "protocol is required");
-      goto done;
+      l_port = clib_host_to_net_u16 (l_port);
+      e_port = clib_host_to_net_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, exact_addr, exact);
+  // TODO: specific pool_addr for both pool & twice nat pool ?
+
+  if (is_add)
+    {
+      rv =
+       nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
+                                    vrf_id, sw_if_index, flags, pool_addr, 0);
+    }
+  else
+    {
+      rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
+                                       vrf_id, sw_if_index, flags);
+    }
+
+  // TODO: fix returns
 
   switch (rv)
     {
@@ -914,23 +969,22 @@ done:
   return error;
 }
 
+// TODO: either delete this bullshit or update it
 static clib_error_t *
 add_identity_mapping_command_fn (vlib_main_t * vm,
                                 unformat_input_t * input,
                                 vlib_cli_command_t * cmd)
 {
   unformat_input_t _line_input, *line_input = &_line_input;
-  clib_error_t *error = 0;
-  ip4_address_t addr, pool_addr = { 0 };
-  u32 port = 0, vrf_id = ~0;
-  int is_add = 1;
-  int addr_only = 1;
-  u32 sw_if_index = ~0;
   vnet_main_t *vnm = vnet_get_main ();
-  int rv;
-  nat_protocol_t proto;
+  clib_error_t *error = 0;
+
+  int rv, is_add = 1, port_set = 0;
+  u32 sw_if_index, port, flags, vrf_id = ~0;
+  ip_protocol_t proto = 0;
+  ip4_address_t addr;
 
-  addr.as_u32 = 0;
+  flags = NAT_SM_FLAG_IDENTITY_NAT;
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
@@ -942,14 +996,20 @@ add_identity_mapping_command_fn (vlib_main_t * vm,
        ;
       else if (unformat (line_input, "external %U",
                         unformat_vnet_sw_interface, vnm, &sw_if_index))
-       ;
+       {
+         flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+       }
       else if (unformat (line_input, "vrf %u", &vrf_id))
        ;
-      else if (unformat (line_input, "%U %u", unformat_nat_protocol, &proto,
+      else if (unformat (line_input, "%U %u", unformat_ip_protocol, &proto,
                         &port))
-       addr_only = 0;
+       {
+         port_set = 1;
+       }
       else if (unformat (line_input, "del"))
-       is_add = 0;
+       {
+         is_add = 0;
+       }
       else
        {
          error = clib_error_return (0, "unknown input: '%U'",
@@ -958,9 +1018,28 @@ add_identity_mapping_command_fn (vlib_main_t * vm,
        }
     }
 
-  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, pool_addr, 0);
+  if (!port_set)
+    {
+      flags |= NAT_SM_FLAG_ADDR_ONLY;
+    }
+  else
+    {
+      port = clib_host_to_net_u16 (port);
+    }
+
+  if (is_add)
+    {
+
+      rv = nat44_ed_add_static_mapping (addr, addr, port, port, proto, vrf_id,
+                                       sw_if_index, flags, addr, 0);
+    }
+  else
+    {
+      rv = nat44_ed_del_static_mapping (addr, addr, port, port, proto, vrf_id,
+                                       sw_if_index, flags);
+    }
+
+  // TODO: fix returns
 
   switch (rv)
     {
@@ -998,13 +1077,11 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
   clib_error_t *error = 0;
   ip4_address_t l_addr, e_addr;
   u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0, affinity = 0;
-  int is_add = 1;
-  int rv;
-  nat_protocol_t proto;
   u8 proto_set = 0;
+  ip_protocol_t proto;
   nat44_lb_addr_port_t *locals = 0, local;
-  twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
-  u8 out2in_only = 0;
+  int rv, is_add = 1;
+  u32 flags = 0;
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
@@ -1035,17 +1112,27 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
       else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
                         &e_addr, &e_port))
        ;
-      else if (unformat (line_input, "protocol %U", unformat_nat_protocol,
+      else if (unformat (line_input, "protocol %U", unformat_ip_protocol,
                         &proto))
-       proto_set = 1;
+       {
+         proto_set = 1;
+       }
       else if (unformat (line_input, "twice-nat"))
-       twice_nat = TWICE_NAT;
+       {
+         flags |= NAT_SM_FLAG_TWICE_NAT;
+       }
       else if (unformat (line_input, "self-twice-nat"))
-       twice_nat = TWICE_NAT_SELF;
+       {
+         flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
+       }
       else if (unformat (line_input, "out2in-only"))
-       out2in_only = 1;
+       {
+         flags |= NAT_SM_FLAG_OUT2IN_ONLY;
+       }
       else if (unformat (line_input, "del"))
-       is_add = 0;
+       {
+         is_add = 0;
+       }
       else if (unformat (line_input, "affinity %u", &affinity))
        ;
       else
@@ -1068,9 +1155,15 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
       goto done;
     }
 
-  rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
-                                       is_add, twice_nat, out2in_only, 0,
-                                       affinity);
+  if (is_add)
+    {
+      rv = nat44_ed_add_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
+                                          flags, 0, affinity);
+    }
+  else
+    {
+      rv = nat44_ed_del_lb_static_mapping (e_addr, (u16) e_port, proto, flags);
+    }
 
   switch (rv)
     {
@@ -1107,7 +1200,7 @@ add_lb_backend_command_fn (vlib_main_t * vm,
   u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
   int is_add = 1;
   int rv;
-  nat_protocol_t proto;
+  ip_protocol_t proto;
   u8 proto_set = 0;
 
   /* Get a line of input. */
@@ -1126,7 +1219,7 @@ add_lb_backend_command_fn (vlib_main_t * vm,
       else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
                         &e_addr, &e_port))
        ;
-      else if (unformat (line_input, "protocol %U", unformat_nat_protocol,
+      else if (unformat (line_input, "protocol %U", unformat_ip_protocol,
                         &proto))
        proto_set = 1;
       else if (unformat (line_input, "del"))
@@ -1151,10 +1244,8 @@ add_lb_backend_command_fn (vlib_main_t * vm,
       goto done;
     }
 
-  rv =
-    nat44_lb_static_mapping_add_del_local (e_addr, (u16) e_port, l_addr,
-                                          l_port, proto, vrf_id, probability,
-                                          is_add);
+  rv = nat44_ed_add_del_lb_static_mapping_local (
+    e_addr, (u16) e_port, l_addr, l_port, proto, vrf_id, probability, is_add);
 
   switch (rv)
     {
@@ -1206,15 +1297,13 @@ snat_add_interface_address_command_fn (vlib_main_t * vm,
                                       unformat_input_t * input,
                                       vlib_cli_command_t * cmd)
 {
-  snat_main_t *sm = &snat_main;
   unformat_input_t _line_input, *line_input = &_line_input;
-  u32 sw_if_index;
-  int rv;
-  int is_del = 0;
+  snat_main_t *sm = &snat_main;
   clib_error_t *error = 0;
+  int rv, is_del = 0;
   u8 twice_nat = 0;
+  u32 sw_if_index;
 
-  /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
@@ -1224,9 +1313,13 @@ snat_add_interface_address_command_fn (vlib_main_t * vm,
                    sm->vnet_main, &sw_if_index))
        ;
       else if (unformat (line_input, "twice-nat"))
-       twice_nat = 1;
+       {
+         twice_nat = 1;
+       }
       else if (unformat (line_input, "del"))
-       is_del = 1;
+       {
+         is_del = 1;
+       }
       else
        {
          error = clib_error_return (0, "unknown input '%U'",
@@ -1235,17 +1328,21 @@ snat_add_interface_address_command_fn (vlib_main_t * vm,
        }
     }
 
-  rv = snat_add_interface_address (sm, sw_if_index, is_del, twice_nat);
-
-  switch (rv)
+  if (!is_del)
     {
-    case 0:
-      break;
-
-    default:
-      error = clib_error_return (0, "snat_add_interface_address returned %d",
-                                rv);
-      goto done;
+      rv = nat44_ed_add_interface_address (sw_if_index, twice_nat);
+      if (rv)
+       {
+         error = clib_error_return (0, "add address returned %d", rv);
+       }
+    }
+  else
+    {
+      rv = nat44_ed_del_interface_address (sw_if_index, twice_nat);
+      if (rv)
+       {
+         error = clib_error_return (0, "del address returned %d", rv);
+       }
     }
 
 done:
@@ -1287,22 +1384,61 @@ nat44_show_sessions_command_fn (vlib_main_t * vm, unformat_input_t * input,
   clib_error_t *error = 0;
   snat_main_per_thread_data_t *tsm;
   snat_main_t *sm = &snat_main;
-
-  int i = 0;
+  ip4_address_t i2o_sa, i2o_da, o2i_sa, o2i_da;
+  u8 filter_i2o_sa = 0, filter_i2o_da = 0;
+  u8 filter_o2i_sa = 0, filter_o2i_da = 0;
+  u16 i2o_sp, i2o_dp, o2i_sp, o2i_dp;
+  u8 filter_i2o_sp = 0, filter_i2o_dp = 0;
+  u8 filter_o2i_sp = 0, filter_o2i_dp = 0;
+  ip_protocol_t proto;
+  u8 filter_proto = 0;
+  u8 had_input = 1, filtering = 0;
+  int i = 0, showed_sessions;
 
   if (!unformat_user (input, unformat_line_input, line_input))
-    goto print;
+    {
+      had_input = 0;
+      goto print;
+    }
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
-      error = clib_error_return (0, "unknown input '%U'",
-                                format_unformat_error, line_input);
-      break;
+      if (unformat (line_input, "filter i2o saddr %U", unformat_ip4_address,
+                   &i2o_sa))
+       filter_i2o_sa = filtering = 1;
+      else if (unformat (line_input, "filter i2o daddr %U",
+                        unformat_ip4_address, &i2o_da))
+       filter_i2o_da = filtering = 1;
+      else if (unformat (line_input, "filter o2i saddr %U",
+                        unformat_ip4_address, &o2i_sa))
+       filter_o2i_sa = filtering = 1;
+      else if (unformat (line_input, "filter o2i daddr %U",
+                        unformat_ip4_address, &o2i_da))
+       filter_o2i_da = filtering = 1;
+      else if (unformat (line_input, "filter i2o sport %u", &i2o_sp))
+       filter_i2o_sp = filtering = 1;
+      else if (unformat (line_input, "filter i2o dport %u", &i2o_dp))
+       filter_i2o_dp = filtering = 1;
+      else if (unformat (line_input, "filter o2i sport %u", &o2i_sp))
+       filter_o2i_sp = filtering = 1;
+      else if (unformat (line_input, "filter o2i dport %u", &o2i_dp))
+       filter_o2i_dp = filtering = 1;
+      else if (unformat (line_input, "filter i2o proto %U",
+                        unformat_ip_protocol, &proto))
+       filter_proto = filtering = 1;
+      else if (unformat (line_input, "filter o2i proto %U",
+                        unformat_ip_protocol, &proto))
+       filter_proto = filtering = 1;
+      else
+       {
+         error = clib_error_return (0, "unknown input '%U'",
+                                    format_unformat_error, line_input);
+         goto done;
+       }
     }
-  unformat_free (line_input);
 
 print:
-    vlib_cli_output (vm, "NAT44 ED sessions:");
+  vlib_cli_output (vm, "NAT44 ED sessions:");
 
   vec_foreach_index (i, sm->per_thread_data)
     {
@@ -1312,12 +1448,52 @@ print:
                        i, vlib_worker_threads[i].name,
                        pool_elts (tsm->sessions));
 
-          snat_session_t *s;
-          pool_foreach (s, tsm->sessions)
-           {
-            vlib_cli_output (vm, "  %U\n", format_snat_session, tsm, s);
-          }
+      showed_sessions = 0;
+      snat_session_t *s;
+      pool_foreach (s, tsm->sessions)
+       {
+         if (filtering)
+           {
+             if (filter_i2o_sa && i2o_sa.as_u32 != s->i2o.match.saddr.as_u32)
+               continue;
+             if (filter_i2o_da && i2o_da.as_u32 != s->i2o.match.daddr.as_u32)
+               continue;
+             if (filter_o2i_sa && o2i_sa.as_u32 != s->o2i.match.saddr.as_u32)
+               continue;
+             if (filter_o2i_da && o2i_da.as_u32 != s->o2i.match.daddr.as_u32)
+               continue;
+             if (filter_i2o_sp &&
+                 i2o_sp != clib_net_to_host_u16 (s->i2o.match.sport))
+               continue;
+             if (filter_i2o_dp &&
+                 i2o_dp != clib_net_to_host_u16 (s->i2o.match.dport))
+               continue;
+             if (filter_o2i_sp &&
+                 o2i_sp != clib_net_to_host_u16 (s->o2i.match.sport))
+               continue;
+             if (filter_o2i_dp &&
+                 o2i_dp != clib_net_to_host_u16 (s->o2i.match.dport))
+               continue;
+             if (filter_proto && proto != s->proto)
+               continue;
+             showed_sessions++;
+           }
+         vlib_cli_output (vm, "  %U\n", format_snat_session, tsm, s);
+       }
+      if (filtering)
+       {
+         vlib_cli_output (vm,
+                          "Showed: %d, Filtered: %d of total %d "
+                          "sessions of thread %d\n\n",
+                          showed_sessions,
+                          pool_elts (tsm->sessions) - showed_sessions,
+                          pool_elts (tsm->sessions), i);
+       }
     }
+
+done:
+  if (had_input)
+    unformat_free (line_input);
   return error;
 }
 
@@ -1369,7 +1545,7 @@ nat44_del_session_command_fn (vlib_main_t * vm,
   u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
   clib_error_t *error = 0;
   ip4_address_t addr, eh_addr;
-  nat_protocol_t proto;
+  ip_protocol_t proto;
   int is_in = 0;
   int rv;
 
@@ -1378,9 +1554,8 @@ nat44_del_session_command_fn (vlib_main_t * vm,
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat
-         (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
-          unformat_nat_protocol, &proto))
+      if (unformat (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
+                   unformat_ip_protocol, &proto))
        ;
       else if (unformat (line_input, "in"))
        {
@@ -1405,10 +1580,9 @@ nat44_del_session_command_fn (vlib_main_t * vm,
        }
     }
 
-    rv =
-      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);
+  rv = nat44_ed_del_session (sm, &addr, clib_host_to_net_u16 (port), &eh_addr,
+                            clib_host_to_net_u16 (eh_port), proto, vrf_id,
+                            is_in);
 
   switch (rv)
     {
@@ -1545,7 +1719,7 @@ set_frame_queue_nelts_command_fn (vlib_main_t *vm, unformat_input_t *input,
       error = clib_error_return (0, "frame_queue_nelts cannot be zero");
       goto done;
     }
-  if (snat_set_frame_queue_nelts (frame_queue_nelts) != 0)
+  if (nat44_ed_set_frame_queue_nelts (frame_queue_nelts) != 0)
     {
       error = clib_error_return (0, "snat_set_frame_queue_nelts failed");
       goto done;
@@ -1603,7 +1777,7 @@ VLIB_CLI_COMMAND (set_workers_command, static) = {
 VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
   .path = "show nat workers",
   .short_help = "show nat workers",
-  .function = nat_show_workers_commnad_fn,
+  .function = nat_show_workers_command_fn,
 };
 
 /*?
@@ -1961,7 +2135,9 @@ VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = {
 ?*/
 VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = {
   .path = "show nat44 sessions",
-  .short_help = "show nat44 sessions",
+  .short_help = "show nat44 sessions [filter {i2o | o2i} {saddr <ip4-addr> "
+               "| sport <n> | daddr <ip4-addr> | dport <n> | proto <proto>} "
+               "[filter .. [..]]]",
   .function = nat44_show_sessions_command_fn,
 };