vppinfra: Improve code portability
[vpp.git] / src / vnet / span / span.c
index 6ecd178..bf5e20f 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <vnet/span/span.h>
 
+span_main_t span_main;
+
 typedef enum
 {
   SPAN_DISABLE = 0,
@@ -32,8 +34,15 @@ typedef enum
 static_always_inline u32
 span_dst_set (span_mirror_t * sm, u32 dst_sw_if_index, int enable)
 {
-  sm->mirror_ports =
-    clib_bitmap_set (sm->mirror_ports, dst_sw_if_index, enable);
+  if (dst_sw_if_index == ~0)
+    {
+      ASSERT (enable == 0);
+      clib_bitmap_zero (sm->mirror_ports);
+    }
+  else
+    sm->mirror_ports =
+      clib_bitmap_set (sm->mirror_ports, dst_sw_if_index, enable);
+
   u32 last = sm->num_mirror_ports;
   sm->num_mirror_ports = clib_bitmap_count_set_bits (sm->mirror_ports);
   return last;
@@ -68,9 +77,9 @@ span_add_delete_entry (vlib_main_t * vm,
   u32 last_tx_ports_count = span_dst_set (txm, dst_sw_if_index, tx);
 
   int enable_rx = last_rx_ports_count == 0 && rxm->num_mirror_ports == 1;
-  int disable_rx = last_rx_ports_count == 1 && rxm->num_mirror_ports == 0;
+  int disable_rx = last_rx_ports_count > 0 && rxm->num_mirror_ports == 0;
   int enable_tx = last_tx_ports_count == 0 && txm->num_mirror_ports == 1;
-  int disable_tx = last_tx_ports_count == 1 && txm->num_mirror_ports == 0;
+  int disable_tx = last_tx_ports_count > 0 && txm->num_mirror_ports == 0;
 
   switch (sf)
     {
@@ -78,6 +87,9 @@ span_add_delete_entry (vlib_main_t * vm,
       if (enable_rx || disable_rx)
        vnet_feature_enable_disable ("device-input", "span-input",
                                     src_sw_if_index, rx, 0, 0);
+      if (enable_rx || disable_rx)
+       vnet_feature_enable_disable ("port-rx-eth", "span-input",
+                                    src_sw_if_index, rx, 0, 0);
       if (enable_tx || disable_tx)
        vnet_feature_enable_disable ("interface-output", "span-output",
                                     src_sw_if_index, tx, 0, 0);
@@ -92,12 +104,29 @@ span_add_delete_entry (vlib_main_t * vm,
       return VNET_API_ERROR_UNIMPLEMENTED;
     }
 
-  if (dst_sw_if_index > sm->max_sw_if_index)
+  if (dst_sw_if_index != ~0 && dst_sw_if_index > sm->max_sw_if_index)
     sm->max_sw_if_index = dst_sw_if_index;
 
   return 0;
 }
 
+static uword
+unformat_span_state (unformat_input_t * input, va_list * args)
+{
+  span_state_t *state = va_arg (*args, span_state_t *);
+  if (unformat (input, "disable"))
+    *state = SPAN_DISABLE;
+  else if (unformat (input, "rx"))
+    *state = SPAN_RX;
+  else if (unformat (input, "tx"))
+    *state = SPAN_TX;
+  else if (unformat (input, "both"))
+    *state = SPAN_BOTH;
+  else
+    return 0;
+  return 1;
+}
+
 static clib_error_t *
 set_interface_span_command_fn (vlib_main_t * vm,
                               unformat_input_t * input,
@@ -106,8 +135,9 @@ set_interface_span_command_fn (vlib_main_t * vm,
   span_main_t *sm = &span_main;
   u32 src_sw_if_index = ~0;
   u32 dst_sw_if_index = ~0;
-  u8 state = SPAN_BOTH;
   span_feat_t sf = SPAN_FEAT_DEVICE;
+  span_state_t state = SPAN_BOTH;
+  int state_set = 0;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
@@ -117,18 +147,16 @@ set_interface_span_command_fn (vlib_main_t * vm,
       else if (unformat (input, "destination %U", unformat_vnet_sw_interface,
                         sm->vnet_main, &dst_sw_if_index))
        ;
-      else if (unformat (input, "disable"))
-       state = SPAN_DISABLE;
-      else if (unformat (input, "rx"))
-       state = SPAN_RX;
-      else if (unformat (input, "tx"))
-       state = SPAN_TX;
-      else if (unformat (input, "both"))
-       state = SPAN_BOTH;
+      else if (unformat (input, "%U", unformat_span_state, &state))
+       {
+         if (state_set)
+           return clib_error_return (0, "Multiple mirror states in input");
+         state_set = 1;
+       }
       else if (unformat (input, "l2"))
        sf = SPAN_FEAT_L2;
       else
-       break;
+       return clib_error_return (0, "Invalid input");
     }
 
   int rv =
@@ -138,13 +166,11 @@ set_interface_span_command_fn (vlib_main_t * vm,
   return 0;
 }
 
-/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_interface_span_command, static) = {
   .path = "set interface span",
   .short_help = "set interface span <if-name> [l2] {disable | destination <if-name> [both|rx|tx]}",
   .function = set_interface_span_command_fn,
 };
-/* *INDENT-ON* */
 
 static clib_error_t *
 show_interfaces_span_command_fn (vlib_main_t * vm,
@@ -155,10 +181,14 @@ show_interfaces_span_command_fn (vlib_main_t * vm,
   span_interface_t *si;
   vnet_main_t *vnm = &vnet_main;
   u8 header = 1;
-  char *states[] = { "none", "rx", "tx", "both" };
+  static const char *states[] = {
+    [SPAN_DISABLE] = "none",
+    [SPAN_RX] = "rx",
+    [SPAN_TX] = "tx",
+    [SPAN_BOTH] = "both"
+  };
   u8 *s = 0;
 
-  /* *INDENT-OFF* */
   vec_foreach (si, sm->interfaces)
   {
   span_mirror_t * drxm = &si->mirror_rxtx[SPAN_FEAT_DEVICE][VLIB_RX];
@@ -176,41 +206,38 @@ show_interfaces_span_command_fn (vlib_main_t * vm,
        clib_bitmap_t *b = clib_bitmap_dup_or (d, l);
        if (header)
          {
-           vlib_cli_output (vm, "%-20s %-20s  %6s   %6s", "Source", "Destination",
+           vlib_cli_output (vm, "%-32s %-32s  %6s   %6s", "Source", "Destination",
                             "Device", "L2");
            header = 0;
          }
        s = format (s, "%U", format_vnet_sw_if_index_name, vnm,
                    si - sm->interfaces);
-       clib_bitmap_foreach (i, b, (
+       clib_bitmap_foreach (i, b)
          {
            int device = (clib_bitmap_get (drxm->mirror_ports, i) +
                         clib_bitmap_get (dtxm->mirror_ports, i) * 2);
            int l2 = (clib_bitmap_get (lrxm->mirror_ports, i) +
                      clib_bitmap_get (ltxm->mirror_ports, i) * 2);
 
-           vlib_cli_output (vm, "%-20v %-20U (%6s) (%6s)", s,
+           vlib_cli_output (vm, "%-32v %-32U (%6s) (%6s)", s,
                             format_vnet_sw_if_index_name, vnm, i,
                             states[device], states[l2]);
            vec_reset_length (s);
-         }));
+         }
        clib_bitmap_free (b);
        clib_bitmap_free (l);
        clib_bitmap_free (d);
       }
       }
-  /* *INDENT-ON* */
   vec_free (s);
   return 0;
 }
 
-/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_interfaces_span_command, static) = {
   .path = "show interface span",
   .short_help = "Shows SPAN mirror table",
   .function = show_interfaces_span_command_fn,
 };
-/* *INDENT-ON* */
 
 /*
  * fd.io coding-style-patch-verification: ON