nat: NAT44 ED & EI session filtering CLI 41/33741/3
authorJúlius Milan <julius.milan@pantheon.tech>
Fri, 10 Sep 2021 07:43:31 +0000 (09:43 +0200)
committerAndrew Yourtchenko <ayourtch@gmail.com>
Tue, 28 Sep 2021 13:38:36 +0000 (13:38 +0000)
Improving session filtering capabilities of
show nat44 sessions CLI command for EI and ED NAT
plugins. Adding filtering options: saddr, sport,
daddr, dport, proto for both i2o and o2i flows.

Type: improvement

Change-Id: I70bc94a2e922cddf9451eb7dcbf4a7be21ebf0df
Signed-off-by: Filip Varga <fivarga@cisco.com>
src/plugins/nat/nat44-ed/nat44_ed_cli.c
src/plugins/nat/nat44-ei/nat44_ei_cli.c

index e9be7eb..1eedb27 100644 (file)
@@ -1386,22 +1386,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;
+  nat_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_nat_protocol, &proto))
+       filter_proto = filtering = 1;
+      else if (unformat (line_input, "filter o2i proto %U",
+                        unformat_nat_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)
     {
@@ -1411,12 +1450,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->nat_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;
 }
 
@@ -2059,7 +2138,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,
 };
 
index a009f02..9ee117e 100644 (file)
@@ -1252,6 +1252,8 @@ nat44_ei_show_sessions_command_fn (vlib_main_t *vm, unformat_input_t *input,
 {
   unformat_input_t _line_input, *line_input = &_line_input;
   clib_error_t *error = 0;
+  ip4_address_t saddr;
+  u8 filter_saddr = 0;
 
   nat44_ei_main_per_thread_data_t *tnm;
   nat44_ei_main_t *nm = &nat44_ei_main;
@@ -1266,6 +1268,9 @@ nat44_ei_show_sessions_command_fn (vlib_main_t *vm, unformat_input_t *input,
     {
       if (unformat (line_input, "detail"))
        detail = 1;
+      else if (unformat (line_input, "filter saddr %U", unformat_ip4_address,
+                        &saddr))
+       filter_saddr = 1;
       else
        {
          error = clib_error_return (0, "unknown input '%U'",
@@ -1288,6 +1293,8 @@ print:
       nat44_ei_user_t *u;
       pool_foreach (u, tnm->users)
        {
+         if (filter_saddr && saddr.as_u32 != u->addr.as_u32)
+           continue;
          vlib_cli_output (vm, "  %U", format_nat44_ei_user, tnm, u, detail);
        }
     }
@@ -1930,7 +1937,7 @@ VLIB_CLI_COMMAND (nat44_ei_show_interface_address_command, static) = {
 ?*/
 VLIB_CLI_COMMAND (nat44_ei_show_sessions_command, static) = {
   .path = "show nat44 ei sessions",
-  .short_help = "show nat44 ei sessions [detail]",
+  .short_help = "show nat44 ei sessions [detail] [filter saddr <ip>]",
   .function = nat44_ei_show_sessions_command_fn,
 };