L2-input/output: use feature enum type in flag update function
[vpp.git] / src / vnet / l2 / l2_input.c
index 7e41c88..85daba5 100644 (file)
@@ -82,7 +82,7 @@ format_l2_input_features (u8 * s, va_list * args)
   int i;
   for (i = L2INPUT_N_FEAT; i >= 0; i--)
     if (feature_bitmap & (1 << i))
-      s = format (s, "%10s (%s)\n", display_names[i], l2input_feat_names[i]);
+      s = format (s, "%17s (%s)\n", display_names[i], l2input_feat_names[i]);
   return s;
 }
 
@@ -177,7 +177,8 @@ classify_and_dispatch (l2input_main_t * msm, vlib_buffer_t * b0, u32 * next0)
 
       /* Disable bridge forwarding (flooding will execute instead if not xconnect) */
       feat_mask &= ~(L2INPUT_FEAT_FWD |
-                    L2INPUT_FEAT_UU_FLOOD | L2INPUT_FEAT_GBP_FWD);
+                    L2INPUT_FEAT_UU_FLOOD |
+                    L2INPUT_FEAT_UU_FWD | L2INPUT_FEAT_GBP_FWD);
 
       /* Disable ARP-term for non-ARP and non-ICMP6 packet */
       if (ethertype != ETHERNET_TYPE_ARP &&
@@ -517,7 +518,8 @@ l2input_intf_config (u32 sw_if_index)
 
 /** Enable (or disable) the feature in the bitmap for the given interface. */
 u32
-l2input_intf_bitmap_enable (u32 sw_if_index, u32 feature_bitmap, u32 enable)
+l2input_intf_bitmap_enable (u32 sw_if_index,
+                           l2input_feat_masks_t feature_bitmap, u32 enable)
 {
   l2_input_config_t *config = l2input_intf_config (sw_if_index);
 
@@ -573,7 +575,7 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /*           */
                 u32 mode,      /* One of L2 modes or back to L3 mode        */
                 u32 sw_if_index,       /* sw interface index                */
                 u32 bd_index,  /* for bridged interface                     */
-                u32 bvi,       /* the bridged interface is the BVI          */
+                l2_bd_port_type_t port_type,   /* port_type */
                 u32 shg,       /* the bridged interface split horizon group */
                 u32 xc_sw_if_index)    /* peer interface for xconnect       */
 {
@@ -613,6 +615,11 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main,        /*           */
          si = vnet_get_sw_interface (vnm, sw_if_index);
          si->flood_class = VNET_FLOOD_CLASS_NO_FLOOD;
        }
+      if (bd_config->uu_fwd_sw_if_index == sw_if_index)
+       {
+         bd_config->uu_fwd_sw_if_index = ~0;
+         bd_config->feature_bitmap &= ~L2INPUT_FEAT_UU_FWD;
+       }
 
       /* Clear MACs learned on the interface */
       if ((config->feature_bitmap & L2INPUT_FEAT_LEARN) ||
@@ -643,7 +650,7 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /*           */
 
       /* Clear L2 output config */
       out_config = l2output_intf_config (sw_if_index);
-      memset (out_config, 0, sizeof (l2_output_config_t));
+      clib_memset (out_config, 0, sizeof (l2_output_config_t));
 
       /* Make sure any L2-output packet to this interface now in L3 mode is
        * dropped. This may happen if L2 FIB MAC entry is stale */
@@ -657,6 +664,8 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /*           */
 
       if (mode == MODE_L2_BRIDGE)
        {
+         u8 member_flags;
+
          /*
           * Remove a check that the interface must be an Ethernet.
           * Specifically so we can bridge to L3 tunnel interfaces.
@@ -676,8 +685,12 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main,        /*           */
           * Enable forwarding, flooding, learning and ARP termination by default
           * (note that ARP term is disabled on BD feature bitmap by default)
           */
-         config->feature_bitmap |= L2INPUT_FEAT_FWD | L2INPUT_FEAT_UU_FLOOD |
-           L2INPUT_FEAT_FLOOD | L2INPUT_FEAT_LEARN | L2INPUT_FEAT_ARP_TERM;
+         config->feature_bitmap |= (L2INPUT_FEAT_FWD |
+                                    L2INPUT_FEAT_UU_FLOOD |
+                                    L2INPUT_FEAT_UU_FWD |
+                                    L2INPUT_FEAT_FLOOD |
+                                    L2INPUT_FEAT_LEARN |
+                                    L2INPUT_FEAT_ARP_TERM);
 
          /* Make sure last-chance drop is configured */
          config->feature_bitmap |= L2INPUT_FEAT_DROP;
@@ -692,7 +705,7 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /*           */
          /* TODO: think: add l2fib entry even for non-bvi interface? */
 
          /* Do BVI interface initializations */
-         if (bvi)
+         if (L2_BD_PORT_TYPE_BVI == port_type)
            {
              vnet_sw_interface_t *si;
 
@@ -715,16 +728,29 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main,       /*           */
              /* since this is a BVI interface we want to flood to it */
              si = vnet_get_sw_interface (vnm, sw_if_index);
              si->flood_class = VNET_FLOOD_CLASS_BVI;
+             member_flags = L2_FLOOD_MEMBER_BVI;
+           }
+         else if (L2_BD_PORT_TYPE_UU_FWD == port_type)
+           {
+             bd_config->uu_fwd_sw_if_index = sw_if_index;
+             bd_config->feature_bitmap |= L2INPUT_FEAT_UU_FWD;
+           }
+         else
+           {
+             member_flags = L2_FLOOD_MEMBER_NORMAL;
            }
 
-         /* Add interface to bridge-domain flood vector */
-         l2_flood_member_t member = {
-           .sw_if_index = sw_if_index,
-           .flags = bvi ? L2_FLOOD_MEMBER_BVI : L2_FLOOD_MEMBER_NORMAL,
-           .shg = shg,
-         };
-         bd_add_member (bd_config, &member);
-
+         if (L2_BD_PORT_TYPE_NORMAL == port_type ||
+             L2_BD_PORT_TYPE_BVI == port_type)
+           {
+             /* Add interface to bridge-domain flood vector */
+             l2_flood_member_t member = {
+               .sw_if_index = sw_if_index,
+               .flags = member_flags,
+               .shg = shg,
+             };
+             bd_add_member (bd_config, &member);
+           }
        }
       else if (mode == MODE_L2_XC)
        {
@@ -827,10 +853,10 @@ int_l2_bridge (vlib_main_t * vm,
               unformat_input_t * input, vlib_cli_command_t * cmd)
 {
   vnet_main_t *vnm = vnet_get_main ();
+  l2_bd_port_type_t port_type;
   clib_error_t *error = 0;
   u32 bd_index, bd_id;
   u32 sw_if_index;
-  u32 bvi;
   u32 rc;
   u32 shg;
 
@@ -857,7 +883,11 @@ int_l2_bridge (vlib_main_t * vm,
   bd_index = bd_find_or_add_bd_index (&bd_main, bd_id);
 
   /* optional bvi  */
-  bvi = unformat (input, "bvi");
+  port_type = L2_BD_PORT_TYPE_NORMAL;
+  if (unformat (input, "bvi"))
+    port_type = L2_BD_PORT_TYPE_BVI;
+  if (unformat (input, "uu-fwd"))
+    port_type = L2_BD_PORT_TYPE_UU_FWD;
 
   /* optional split horizon group */
   shg = 0;
@@ -865,8 +895,8 @@ int_l2_bridge (vlib_main_t * vm,
 
   /* set the interface mode */
   if ((rc =
-       set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE, sw_if_index, bd_index, bvi,
-                       shg, 0)))
+       set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE, sw_if_index, bd_index,
+                       port_type, shg, 0)))
     {
       if (rc == MODE_ERROR_ETH)
        {
@@ -920,7 +950,7 @@ done:
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (int_l2_bridge_cli, static) = {
   .path = "set interface l2 bridge",
-  .short_help = "set interface l2 bridge <interface> <bridge-domain-id> [bvi] [shg]",
+  .short_help = "set interface l2 bridge <interface> <bridge-domain-id> [bvi|uu-fwd] [shg]",
   .function = int_l2_bridge,
 };
 /* *INDENT-ON* */
@@ -956,7 +986,8 @@ int_l2_xc (vlib_main_t * vm,
 
   /* set the interface mode */
   if (set_int_l2_mode
-      (vm, vnm, MODE_L2_XC, sw_if_index, 0, 0, 0, xc_sw_if_index))
+      (vm, vnm, MODE_L2_XC, sw_if_index, 0, L2_BD_PORT_TYPE_NORMAL,
+       0, xc_sw_if_index))
     {
       error = clib_error_return (0, "invalid configuration for interface",
                                 format_unformat_error, input);
@@ -969,7 +1000,7 @@ done:
 
 /*?
  * Use this command put an interface into Layer 2 cross-connect mode.
- * Both interfaces must be in this mode for bi-directioal traffic. All
+ * Both interfaces must be in this mode for bi-directional traffic. All
  * packets received on one interface will be transmitted to the other.
  * To remove the Layer 2 cross-connect, put the interface in a different
  * mode, for example Layer 3 mode.
@@ -1010,7 +1041,8 @@ int_l3 (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
     }
 
   /* set the interface mode */
-  if (set_int_l2_mode (vm, vnm, MODE_L3, sw_if_index, 0, 0, 0, 0))
+  if (set_int_l2_mode (vm, vnm, MODE_L3, sw_if_index, 0,
+                      L2_BD_PORT_TYPE_NORMAL, 0, 0))
     {
       error = clib_error_return (0, "invalid configuration for interface",
                                 format_unformat_error, input);
@@ -1122,11 +1154,11 @@ done:
 }
 
 /*?
- * Show the packet processing mode (Layer2 xcross-onnect, Layer 2 bridge,
+ * Show the packet processing mode (Layer2 cross-connect, Layer 2 bridge,
  * Layer 3 routed) of all interfaces and sub-interfaces, or limit the
  * output to just the provided list of interfaces and sub-interfaces.
  * The output shows the mode, the interface, and if the interface is
- * a member of a bridge, the bridge-domain-id and the split horizen group (shg).
+ * a member of a bridge, the bridge-domain-id and the split horizon group (shg).
  *
  * @cliexpar
  * Example of displaying the mode of all interfaces:
@@ -1141,7 +1173,7 @@ done:
  * l2 xconnect GigabitEthernet0/8/0.300 GigabitEthernet0/9/0.300
  * l2 xconnect GigabitEthernet0/9/0.300 GigabitEthernet0/8/0.300
  * @cliexend
- * Example of displaying the mode of a seleted list of interfaces:
+ * Example of displaying the mode of a selected list of interfaces:
  * @cliexstart{show mode GigabitEthernet0/8/0 GigabitEthernet0/8/0.200}
  * l3 GigabitEthernet0/8/0
  * l2 bridge GigabitEthernet0/8/0.200 bd_id 200 shg 0