diff options
author | Jon Loeliger <jdl@netgate.com> | 2019-12-19 09:03:52 -0600 |
---|---|---|
committer | Dave Wallace <dwallacelf@gmail.com> | 2020-08-12 14:33:06 +0000 |
commit | 62c6e93d1095ddbc6d86efbd4db18d51cc1fd9bb (patch) | |
tree | 94c554f504546bc55a073836e83476081ef72f2f | |
parent | 74331c935fd68d01757ff3af34c03cc8ca87faa0 (diff) |
interface: Prevent bad inner-dot1q any exact-match configuration
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>
(cherry picked from commit b22e1f06bbebc48ec72ce8effa529e69ffbb12ca)
-rw-r--r-- | src/vnet/interface.c | 10 | ||||
-rw-r--r-- | src/vnet/interface_cli.c | 6 |
2 files changed, 13 insertions, 3 deletions
diff --git a/src/vnet/interface.c b/src/vnet/interface.c index 0f6b8aeab07..c827f1901a3 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -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); diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index 46c5d5e8389..65783b6e7d4 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -757,9 +757,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; @@ -771,6 +768,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, |