interface: Prevent bad inner-dot1q any exact-match configuration 77/24077/3
authorJon Loeliger <jdl@netgate.com>
Thu, 19 Dec 2019 15:03:52 +0000 (09:03 -0600)
committerJohn Lo <loj@cisco.com>
Thu, 19 Dec 2019 19:44:54 +0000 (19:44 +0000)
Someone much more knowledgeable than I wrote:

    For L3 IP forwarding, any VLAN tags on a packet must be exact
    match to a sub-interface which means both outer and inner VLAN
    tag IDs must be exact-matched to specific values defined of that
    sub-interface.  Without exact match on a L3 sub-interface, VPP
    has no mechanism to know what VLAN tags to use for packet output,
    such as ARP request packets or IP packets, on that sub-interface.

    Thus, sub-interface with "inner-dot1q any" is not an exact match
    sub-interface by definition since no match is present on inner
    tag.

While in the area, fix a memory leak that would ensue on poorly
configured interfaces.

Change-Id: I8d17a96dbca3e3724c297ecc935ca61764e6ce2e
Type: fix
Signed-off-by: Jon Loeliger <jdl@netgate.com>
src/vnet/interface.c
src/vnet/interface_cli.c

index b2166dc..5ee3a74 100644 (file)
@@ -582,6 +582,16 @@ vnet_create_sw_interface (vnet_main_t * vnm, vnet_sw_interface_t * template,
   vnet_hw_interface_t *hi;
   vnet_device_class_t *dev_class;
 
+  if (template->sub.eth.flags.two_tags == 1
+      && template->sub.eth.flags.exact_match == 1
+      && (template->sub.eth.flags.inner_vlan_id_any == 1
+         || template->sub.eth.flags.outer_vlan_id_any == 1))
+    {
+      error = clib_error_return (0,
+                                "inner-dot1q any exact-match is unsupported");
+      return error;
+    }
+
   hi = vnet_get_sup_hw_interface (vnm, template->sup_sw_if_index);
   dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
 
index 9de674a..1c0d8f5 100644 (file)
@@ -781,9 +781,6 @@ create_sub_interfaces (vlib_main_t * vm,
          continue;
        }
 
-      kp = clib_mem_alloc (sizeof (*kp));
-      *kp = sup_and_sub_key;
-
       template.type = VNET_SW_INTERFACE_TYPE_SUB;
       template.flood_class = VNET_FLOOD_CLASS_NORMAL;
       template.sup_sw_if_index = hi->sw_if_index;
@@ -795,6 +792,9 @@ create_sub_interfaces (vlib_main_t * vm,
       if (error)
        goto done;
 
+      kp = clib_mem_alloc (sizeof (*kp));
+      *kp = sup_and_sub_key;
+
       hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
       hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
       vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name,