From 2945b67b6b03db03b671a96ff4832909ff503148 Mon Sep 17 00:00:00 2001 From: Benjamin Poirier Date: Wed, 18 Oct 2023 16:40:44 -0400 Subject: [PATCH] bridge: Do not create untagged vlans on "external" vxlan ports vxlan interfaces with the external flag get the vni for a frame based on its vlan tag. If a frame is marked as untagged, the vxlan interface drops the frame because there's no way to transmit a vxlan frame without a vni. ifupdown2 configures the bridge pvid as an untagged vlan on single vxlan interfaces. (Note that bridge-pvid is inherited from bridge to port and it has a default value of 1.) This leads to the traffic being dropped for traffic on that vlan. Avoid that problem by not configuring any vlans as untagged on single vxlan interfaces. --- debian/changelog | 1 + ifupdown2/addons/bridge.py | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index eceaa53..81e657a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ ifupdown2 (3.2.1) unstable; urgency=medium * New: performance improvement: replace glob.glob with os.listdir + * New: bridge: Do not create untagged vlans on "external" vxlan ports * New: Attribute: "disable-ipv6" to control ipv6 on an interface * New: Policy: "default_loopback_scope" control loopback ip scope * Fix: keep link down after mac change if 'link-down yes' is specified diff --git a/ifupdown2/addons/bridge.py b/ifupdown2/addons/bridge.py index d31a225..4d6c091 100644 --- a/ifupdown2/addons/bridge.py +++ b/ifupdown2/addons/bridge.py @@ -897,7 +897,8 @@ class bridge(Bridge, moduleBase): c3 = self.syntax_check_learning_l2_vni_evpn(ifaceobj) c4 = self.syntax_check_bridge_arp_vni_vlan(ifaceobj, ifaceobj_getfunc) c5 = self.syntax_check_bridge_vni_svi_limit(ifaceobj, ifaceobj_getfunc) - return retval and c1 and c2 and c3 and c4 and c5 + c6 = self.check_bridge_single_vxlan(ifaceobj) + return retval and c1 and c2 and c3 and c4 and c5 and c6 def syntax_check_bridge_vni_svi_limit(self, ifaceobj, ifaceobj_getfunc): if self.bridge_vni_per_svi_limit > 0 and ifaceobj.link_kind & ifaceLinkKind.VXLAN: @@ -1024,6 +1025,14 @@ class bridge(Bridge, moduleBase): return False return True + def check_bridge_single_vxlan(self, ifaceobj): + if (ifaceobj.link_privflags & + (ifaceLinkPrivFlags.SINGLE_VXLAN | ifaceLinkPrivFlags.L3VXI) and + ifaceobj.get_attr_value_first('bridge-pvid')): + self.logger.warning("%s: bridge-pvid conflicts with single-vxlan device, bridge-pvid will be ignored" % ifaceobj.name) + return False + return True + def check_bridge_vlan_aware_port(self, ifaceobj, ifaceobj_getfunc): if ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE: ports = self._get_bridge_port_list(ifaceobj) @@ -1904,7 +1913,12 @@ class bridge(Bridge, moduleBase): elif bridge_vids: vids_final = bridge_vids - if allow_untagged == 'yes': + self.check_bridge_single_vxlan(bportifaceobj) + + vxlan_in_collect_metadata_mode = ( + bportifaceobj.link_privflags & + (ifaceLinkPrivFlags.SINGLE_VXLAN | ifaceLinkPrivFlags.L3VXI)) + if allow_untagged == 'yes' and not vxlan_in_collect_metadata_mode: if pvids: pvid_final = pvids[0] elif bridge_pvid: