]> git.proxmox.com Git - mirror_ifupdown2.git/blobdiff - ifupdown2/addons/bridge.py
addons: when comparing mac addresses use integer representation
[mirror_ifupdown2.git] / ifupdown2 / addons / bridge.py
index e51d2b411c2afdab9d3ac468db70d6c71edb5640..a157dd6063e9683eb3d9c4e1b03e5853238800bd 100644 (file)
@@ -25,6 +25,8 @@ try:
     from ifupdown2.ifupdownaddons.cache import *
     from ifupdown2.ifupdownaddons.LinkUtils import LinkUtils
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
+
+    import ifupdown2.ifupdown.ifupdownconfig as ifupdownconfig
 except ImportError:
     import ifupdown.exceptions as exceptions
     import ifupdown.policymanager as policymanager
@@ -40,6 +42,8 @@ except ImportError:
     from ifupdownaddons.LinkUtils import LinkUtils
     from ifupdownaddons.modulebase import moduleBase
 
+    import ifupdown.ifupdownconfig as ifupdownconfig
+
 
 class bridgeFlags:
     PORT_PROCESSED = 0x1
@@ -643,6 +647,14 @@ class bridge(moduleBase):
             )
         )
 
+        self.vxlan_bridge_igmp_snooping_enable_port_mcrouter = utils.get_boolean_from_string(
+            policymanager.policymanager_api.get_module_globals(
+                module_name=self.__class__.__name__,
+                attr="vxlan_bridge_igmp_snooping_enable_port_mcrouter"
+            ),
+            default=True
+        )
+
         self.l2protocol_tunnel_callback = {
             'all': self._l2protocol_tunnel_set_all,
             'stp': self._l2protocol_tunnel_set_stp,
@@ -931,7 +943,7 @@ class bridge(moduleBase):
     def handle_ipv6(self, ports, state, ifaceobj=None):
         if (ifaceobj and
                 (ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VXLAN) and
-                not ifaceobj.get_attr_value('address')):
+                not ifaceobj.get_attr_value('address') and not ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE):
             self._enable_disable_ipv6(ifaceobj.name, state)
         for p in ports:
             self._enable_disable_ipv6(p, state)
@@ -1222,9 +1234,15 @@ class bridge(moduleBase):
 
     def get_bridge_mcsnoop_value(self, ifaceobj):
         mcsnoop = ifaceobj.get_attr_value_first('bridge-mcsnoop')
-        if not mcsnoop and ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VXLAN:
-            return self._vxlan_bridge_default_igmp_snooping
-        return mcsnoop
+
+        if mcsnoop:
+            return mcsnoop
+
+        if ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VXLAN:
+            if self._vxlan_bridge_default_igmp_snooping is not None:
+                return self._vxlan_bridge_default_igmp_snooping
+
+        return self.get_attr_default_value("bridge-mcsnoop")
 
     def fill_ifla_info_data_with_ifla_br_attribute(self,
                                                    ifla_info_data,
@@ -1249,7 +1267,7 @@ class bridge(moduleBase):
             old_cache_key = self._ifla_br_attributes_old_cache_key_map.get(nl_attr)
             if old_cache_key and not link_just_created:
                 cached_value = self.brctlcmd.link_cache_get([ifname, 'linkinfo', old_cache_key])
-                if not cached_value:
+                if not cached_value or cached_value == "None":
                     # the link already exists but we don't have any value
                     # cached for this attr, it probably means that the
                     # capability is not available on this system (i.e old kernel)
@@ -1944,6 +1962,18 @@ class bridge(moduleBase):
                                                                                      brport_name,
                                                                                      brport_ifla_info_slave_data,
                                                                                      bridge_ports_learning.get(brport_name))
+
+                    cached_bridge_mcsnoop = self.brctlcmd.link_cache_get([ifname, 'linkinfo', Link.IFLA_BR_MCAST_SNOOPING])
+
+                    if (self.vxlan_bridge_igmp_snooping_enable_port_mcrouter and utils.get_boolean_from_string(
+                            self.get_bridge_mcsnoop_value(ifaceobj)
+                    )) or cached_bridge_mcsnoop:
+                        # if policy "vxlan_bridge_igmp_snooping_enable_port_mcrouter"
+                        # is on and mcsnoop is on (or mcsnoop is already enabled on the
+                        # bridge, set 'bridge-portmcrouter 2' on vxlan ports (if not set by the user)
+                        if not brport_ifla_info_slave_data.get(Link.IFLA_BRPORT_MULTICAST_ROUTER):
+                            brport_ifla_info_slave_data[Link.IFLA_BRPORT_MULTICAST_ROUTER] = 2
+                            self.logger.info("%s: %s: vxlan bridge igmp snooping: enable port multicast router" % (ifname, brport_name))
                 else:
                     kind = None
                     ifla_info_data = {}
@@ -2013,6 +2043,24 @@ class bridge(moduleBase):
                 self.logger.debug('(cache %s)' % cached_ifla_brport_group_fwd_maskhi)
             brports_ifla_info_slave_data[brport_name][Link.IFLA_BRPORT_GROUP_FWD_MASKHI] = ifla_brport_group_fwd_maskhi
 
+    def get_bridge_mtu(self, ifaceobj):
+        user_config_mtu = ifaceobj.get_attr_value_first("mtu")
+
+        if not user_config_mtu:
+            user_config_mtu = policymanager.policymanager_api.get_attr_default(
+                module_name=self.__class__.__name__,
+                attr="mtu"
+            )
+
+        try:
+            if user_config_mtu:
+                mtu = int(user_config_mtu)
+                self.logger.info("%s: set bridge mtu %s" % (ifaceobj.name, mtu))
+                return mtu
+        except Exception as e:
+            self.logger.warning("%s: invalid bridge mtu %s: %s" % (ifaceobj.name, user_config_mtu, str(e)))
+        return 0
+
     def up_bridge(self, ifaceobj, ifaceobj_getfunc):
         ifname = ifaceobj.name
 
@@ -2024,7 +2072,7 @@ class bridge(moduleBase):
             link_just_created = not link_exists
 
         if not link_exists:
-            netlink.link_add_bridge(ifname)
+            netlink.link_add_bridge(ifname, self.get_bridge_mtu(ifaceobj))
         else:
             self.logger.info('%s: bridge already exists' % ifname)
 
@@ -2055,8 +2103,8 @@ class bridge(moduleBase):
         finally:
             if ifaceobj.link_type != ifaceLinkType.LINK_NA:
                 for p in running_ports:
-                    if (ifaceobj_getfunc(p)[0].link_privflags &
-                            ifaceLinkPrivFlags.KEEP_LINK_DOWN):
+                    ifaceobj_list = ifaceobj_getfunc(p)
+                    if (ifaceobj_list and ifaceobj_list[0].link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN):
                         netlink.link_set_updown(p, "down")
                         continue
                     try:
@@ -2157,7 +2205,7 @@ class bridge(moduleBase):
             # and compare the ints, it will increase perfs and be safer.
             cached_value = self.ipcmd.cache_get('link', [ifname, 'hwaddress'])
             self.logger.debug('%s: cached hwaddress value: %s' % (ifname, cached_value))
-            if cached_value and cached_value == bridge_mac:
+            if cached_value and self.ipcmd.mac_str_to_int(cached_value) == self.ipcmd.mac_str_to_int(bridge_mac):
                 # the bridge mac is already set to the bridge_mac_intf's mac
                 return
 
@@ -2201,6 +2249,14 @@ class bridge(moduleBase):
             self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj)
         try:
             netlink.link_del(ifname)
+
+            if utils.get_boolean_from_string(ifupdownconfig.config.get("ifreload_down_changed")):
+                self.ipcmd.del_cache_entry(ifname)
+                for upper in ifaceobj.upperifaces or []:
+                    try:
+                        self.ipcmd.del_cache_entry(upper)
+                    except:
+                        pass
         except Exception as e:
             ifaceobj.set_status(ifaceStatus.ERROR)
             self.logger.error(str(e))