nat: nat44-ed disable protection for api/cli
[vpp.git] / src / plugins / nat / nat44-ed / nat44_ed_cli.c
index fd4b1ec..9b3480c 100644 (file)
 #include <nat/nat44-ed/nat44_ed_inlines.h>
 #include <nat/nat44-ed/nat44_ed_affinity.h>
 
+#define NAT44_ED_EXPECTED_ARGUMENT "expected required argument(s)"
+
 static clib_error_t *
-nat44_enable_command_fn (vlib_main_t * vm,
-                        unformat_input_t * input, vlib_cli_command_t * cmd)
+nat44_ed_enable_disable_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;
   clib_error_t *error = 0;
 
   nat44_config_t c = { 0 };
-  u8 mode_set = 0;
-
-  if (sm->enabled)
-    return clib_error_return (0, "nat44 already enabled");
+  u8 enable_set = 0, enable = 0, mode_set = 0;
 
-  /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    {
-      if (nat44_plugin_enable (c) != 0)
-       return clib_error_return (0, "nat44 enable failed");
-      return 0;
-    }
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -63,6 +57,14 @@ nat44_enable_command_fn (vlib_main_t * vm,
       else if (unformat (line_input, "inside-vrf %u", &c.inside_vrf));
       else if (unformat (line_input, "outside-vrf %u", &c.outside_vrf));
       else if (unformat (line_input, "sessions %u", &c.sessions));
+      else if (!enable_set)
+       {
+         enable_set = 1;
+         if (unformat (line_input, "disable"))
+           ;
+         else if (unformat (line_input, "enable"))
+           enable = 1;
+       }
       else
        {
          error = clib_error_return (0, "unknown input '%U'",
@@ -71,32 +73,37 @@ nat44_enable_command_fn (vlib_main_t * vm,
        }
     }
 
-  if (!c.sessions)
+  if (!enable_set)
     {
-      error = clib_error_return (0, "number of sessions is required");
+      error = clib_error_return (0, "expected enable | disable");
       goto done;
     }
 
-  if (nat44_plugin_enable (c) != 0)
-    error = clib_error_return (0, "nat44 enable failed");
-done:
-  unformat_free (line_input);
-  return error;
-}
-
-static clib_error_t *
-nat44_disable_command_fn (vlib_main_t * vm,
-                         unformat_input_t * input, vlib_cli_command_t * cmd)
-{
-  snat_main_t *sm = &snat_main;
-  clib_error_t *error = 0;
+  if (enable)
+    {
+      if (sm->enabled)
+       {
+         error = clib_error_return (0, "already enabled");
+         goto done;
+       }
 
-  if (!sm->enabled)
-    return clib_error_return (0, "nat44 already disabled");
+      if (nat44_plugin_enable (c) != 0)
+       error = clib_error_return (0, "enable failed");
+    }
+  else
+    {
+      if (!sm->enabled)
+       {
+         error = clib_error_return (0, "already disabled");
+         goto done;
+       }
 
-  if (nat44_plugin_disable () != 0)
-    error = clib_error_return (0, "nat44 disable failed");
+      if (nat44_plugin_disable () != 0)
+       error = clib_error_return (0, "disable failed");
+    }
 
+done:
+  unformat_free (line_input);
   return error;
 }
 
@@ -111,7 +118,7 @@ set_workers_command_fn (vlib_main_t * vm,
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -187,7 +194,7 @@ snat_set_log_level_command_fn (vlib_main_t * vm,
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   if (!unformat (line_input, "%d", &log_level))
     {
@@ -214,21 +221,13 @@ snat_ipfix_logging_enable_disable_command_fn (vlib_main_t * vm,
                                              vlib_cli_command_t * cmd)
 {
   unformat_input_t _line_input, *line_input = &_line_input;
-  u32 domain_id = 0;
-  u32 src_port = 0;
-  u8 enable = 1;
-  int rv = 0;
   clib_error_t *error = 0;
 
-  /* Get a line of input. */
+  u32 domain_id = 0, src_port = 0;
+  u8 enable_set = 0, enable = 0;
+
   if (!unformat_user (input, unformat_line_input, line_input))
-    {
-      rv = nat_ipfix_logging_enable_disable (enable, domain_id,
-                                            (u16) src_port);
-      if (rv)
-       return clib_error_return (0, "ipfix logging enable failed");
-      return 0;
-    }
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -236,8 +235,14 @@ snat_ipfix_logging_enable_disable_command_fn (vlib_main_t * vm,
        ;
       else if (unformat (line_input, "src-port %d", &src_port))
        ;
-      else if (unformat (line_input, "disable"))
-       enable = 0;
+      else if (!enable_set)
+       {
+         enable_set = 1;
+         if (unformat (line_input, "disable"))
+           ;
+         else if (unformat (line_input, "enable"))
+           enable = 1;
+       }
       else
        {
          error = clib_error_return (0, "unknown input '%U'",
@@ -246,9 +251,13 @@ snat_ipfix_logging_enable_disable_command_fn (vlib_main_t * vm,
        }
     }
 
-  rv = nat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
+  if (!enable_set)
+    {
+      error = clib_error_return (0, "expected enable | disable");
+      goto done;
+    }
 
-  if (rv)
+  if (nat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port))
     {
       error = clib_error_return (0, "ipfix logging enable failed");
       goto done;
@@ -306,7 +315,7 @@ nat_set_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input,
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -359,7 +368,7 @@ add_address_command_fn (vlib_main_t * vm,
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -656,14 +665,13 @@ 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;
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -692,8 +700,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",
@@ -704,7 +719,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",
@@ -723,8 +746,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",
@@ -735,7 +765,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",
@@ -792,57 +830,75 @@ add_static_mapping_command_fn (vlib_main_t * vm,
                               vlib_cli_command_t * cmd)
 {
   unformat_input_t _line_input, *line_input = &_line_input;
-  clib_error_t *error = 0;
-  ip4_address_t l_addr, e_addr, exact_addr;
-  u32 l_port = 0, e_port = 0, vrf_id = ~0;
-  int is_add = 1, addr_only = 1, rv, exact = 0;
-  u32 sw_if_index = ~0;
   vnet_main_t *vnm = vnet_get_main ();
+  clib_error_t *error = 0;
+  int rv;
+
   nat_protocol_t proto = NAT_PROTOCOL_OTHER;
-  u8 proto_set = 0;
-  twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
-  u8 out2in_only = 0;
+  ip4_address_t l_addr, e_addr, pool_addr;
+  u32 l_port = 0, e_port = 0, vrf_id = ~0;
+  u8 l_port_set = 0, e_port_set = 0;
+  u32 sw_if_index, flags = 0;
+  int is_add = 1;
 
-  /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
       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, "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'",
@@ -851,32 +907,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)
     {
@@ -905,27 +966,26 @@ 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;
+  clib_error_t *error = 0;
+
+  int rv, is_add = 1, port_set = 0;
+  u32 sw_if_index, port, flags, vrf_id = ~0;
   nat_protocol_t proto;
+  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))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -933,14 +993,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,
                         &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'",
@@ -949,9 +1015,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)
     {
@@ -989,17 +1074,15 @@ 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;
+  nat_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))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -1028,15 +1111,25 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
        ;
       else if (unformat (line_input, "protocol %U", unformat_nat_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
@@ -1059,9 +1152,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)
     {
@@ -1103,7 +1202,7 @@ add_lb_backend_command_fn (vlib_main_t * vm,
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -1142,10 +1241,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)
     {
@@ -1207,7 +1304,7 @@ snat_add_interface_address_command_fn (vlib_main_t * vm,
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -1322,9 +1419,8 @@ nat44_set_session_limit_command_fn (vlib_main_t * vm,
 
   u32 session_limit = 0, vrf_id = 0;
 
-  /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -1365,9 +1461,8 @@ nat44_del_session_command_fn (vlib_main_t * vm,
   int is_in = 0;
   int rv;
 
-  /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -1398,10 +1493,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),
+                            nat_proto_to_ip_proto (proto), vrf_id, is_in);
 
   switch (rv)
     {
@@ -1426,25 +1520,22 @@ snat_forwarding_set_command_fn (vlib_main_t * vm,
 {
   snat_main_t *sm = &snat_main;
   unformat_input_t _line_input, *line_input = &_line_input;
-  u8 forwarding_enable;
-  u8 forwarding_enable_set = 0;
   clib_error_t *error = 0;
 
-  /* Get a line of input. */
+  u8 enable_set = 0, enable = 0;
+
   if (!unformat_user (input, unformat_line_input, line_input))
-    return clib_error_return (0, "'enable' or 'disable' expected");
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
-      if (!forwarding_enable_set && unformat (line_input, "enable"))
-       {
-         forwarding_enable = 1;
-         forwarding_enable_set = 1;
-       }
-      else if (!forwarding_enable_set && unformat (line_input, "disable"))
+      if (!enable_set)
        {
-         forwarding_enable = 0;
-         forwarding_enable_set = 1;
+         enable_set = 1;
+         if (unformat (line_input, "disable"))
+           ;
+         else if (unformat (line_input, "enable"))
+           enable = 1;
        }
       else
        {
@@ -1454,17 +1545,13 @@ snat_forwarding_set_command_fn (vlib_main_t * vm,
        }
     }
 
-  if (!forwarding_enable_set)
-    {
-      error = clib_error_return (0, "'enable' or 'disable' expected");
-      goto done;
-    }
-
-  sm->forwarding_enabled = forwarding_enable;
+  if (!enable_set)
+    error = clib_error_return (0, "expected enable | disable");
+  else
+    sm->forwarding_enabled = enable;
 
 done:
   unformat_free (line_input);
-
   return error;
 }
 
@@ -1476,9 +1563,8 @@ set_timeout_command_fn (vlib_main_t * vm,
   unformat_input_t _line_input, *line_input = &_line_input;
   clib_error_t *error = 0;
 
-  /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -1526,9 +1612,10 @@ set_frame_queue_nelts_command_fn (vlib_main_t *vm, unformat_input_t *input,
   unformat_input_t _line_input, *line_input = &_line_input;
   clib_error_t *error = 0;
   u32 frame_queue_nelts = 0;
-  /* Get a line of input. */
+
   if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
+    return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
+
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
       if (unformat (line_input, "%u", &frame_queue_nelts))
@@ -1545,7 +1632,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;
@@ -1557,38 +1644,24 @@ done:
 
 /*?
  * @cliexpar
- * @cliexstart{nat44 enable}
+ * @cliexstart{nat44}
  * Enable nat44 plugin
- * To enable nat44, use:
- *  vpp# nat44 enable sessions <n>
- * To enable nat44 static mapping only, use:
- *  vpp# nat44 enable sessions <n> static-mapping
- * To enable nat44 static mapping with connection tracking, use:
- *  vpp# nat44 enable sessions <n> static-mapping connection-tracking
- * To set inside-vrf outside-vrf, use:
- *  vpp# nat44 enable sessions <n> inside-vrf <id> outside-vrf <id>
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat44_enable_command, static) = {
-  .path = "nat44 enable",
-  .short_help =
-    "nat44 enable sessions <max-number> [static-mappig-only "
-    "[connection-tracking]] [inside-vrf <vrf-id>] [outside-vrf <vrf-id>]",
-  .function = nat44_enable_command_fn,
-};
-
-/*?
- * @cliexpar
- * @cliexstart{nat44 disable}
- * Disable nat44 plugin
- * To disable nat44, use:
+ * To enable nat44-ed, use:
+ *  vpp# nat44 enable
+ * To disable nat44-ed, use:
  *  vpp# nat44 disable
+ * To enable nat44-ed static mapping with connection tracking, use:
+ *  vpp# nat44-ed enable static-mapping connection-tracking
+ * To set inside-vrf outside-vrf, use:
+ *  vpp# nat44 enable inside-vrf <id> outside-vrf <id>
  * @cliexend
 ?*/
-VLIB_CLI_COMMAND (nat44_disable_command, static) = {
-  .path = "nat44 disable",
-  .short_help = "nat44 disable",
-  .function = nat44_disable_command_fn,
+VLIB_CLI_COMMAND (nat44_ed_enable_disable_command, static) = {
+  .path = "nat44",
+  .short_help = "nat44 <enable [sessions <max-number>] [static-mapping-only "
+               "connection-tracking] [inside-vrf <vrf-id>] "
+               "[outside-vrf <vrf-id>]>|disable",
+  .function = nat44_ed_enable_disable_command_fn,
 };
 
 /*?
@@ -1691,7 +1764,8 @@ VLIB_CLI_COMMAND (snat_set_log_level_command, static) = {
 VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
   .path = "nat ipfix logging",
   .function = snat_ipfix_logging_enable_disable_command_fn,
-  .short_help = "nat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
+  .short_help = "nat ipfix logging disable|<enable [domain <domain-id>] "
+               "[src-port <port>]>",
 };
 
 /*?