]> git.proxmox.com Git - mirror_ifupdown2.git/commitdiff
addons: bridge: support for bridge-learning attribute
authorRoopa Prabhu <roopa@cumulusnetworks.com>
Mon, 6 Feb 2017 00:27:02 +0000 (16:27 -0800)
committerRoopa Prabhu <roopa@cumulusnetworks.com>
Mon, 6 Feb 2017 18:32:25 +0000 (10:32 -0800)
Ticket: CM-14683
Reviewed By: julien, mallik, anita, vivek, balki, wkok
Testing Done: tested with bridge-learning on off

- support for bridge-learning attribute on bridge ports.
  (currently uses sysfs, must move to netlink soon)
- Additional feature for vxlan bridge ports: sync learning
flag to vxlan bridge ports. No ifquery check for this auto
sync feature.

example config for vxlan ports:
auto vxlan1000
iface vxlan1000
        vxlan-id 1000
        bridge-learning off
        bridge-access 100

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
addons/bridge.py
ifupdownaddons/iproute2.py

index 1085145a7ffc7e7a1dd835e10492b89f1d8d23ab..fda4fbcb1096125746f29765ccc2e2bf777da78f 100644 (file)
@@ -17,7 +17,6 @@ import ifupdown.ifupdownflags as ifupdownflags
 import itertools
 import re
 import time
-import pdb
 
 class bridgeFlags:
     PORT_PROCESSED = 0x1
@@ -247,6 +246,11 @@ class bridge(moduleBase):
                         { 'help' : 'bridge port vlans',
                           'compat': True,
                           'example' : ['bridge-port-pvids bond0=100 bond1=200']},
+                    'bridge-learning' :
+                        { 'help' : 'bridge port learning flag',
+                          'validvals': ['on', 'off'],
+                          'default': 'on',
+                          'example' : ['bridge-learning off']},
                      }}
 
     def __init__(self, *args, **kargs):
@@ -1143,6 +1147,36 @@ class bridge(moduleBase):
         except Exception, e:
             self.log_error(str(e), bportifaceobj)
 
+        # special handling for learning:
+        # bridge ports may have learning capability, in which case
+        # we need to keep the bridge ports internal learning in sync
+        # with bridge learning capability. This is true for vxlan ports
+        # hence special case this for vxlan ports.
+        try:
+            config_learn = bportifaceobj.get_attr_value_first('bridge-learning')
+            if not config_learn:
+                config_learn = self.get_mod_subattr('bridge-learning', 'default')
+            config_learn = utils.get_onoff_bool(config_learn)
+            running_learn = self.ipcmd.get_brport_learning(bportifaceobj.name)
+            if config_learn != running_learn:
+                self.ipcmd.set_brport_learning(bportifaceobj.name, config_learn)
+        except Exception, e:
+            self.log_error(str(e), bportifaceobj)
+
+        if not (bportifaceobj.link_kind & ifaceLinkKind.VXLAN):
+            return
+        try:
+            vxlan_learn = self.ipcmd.get_vxlandev_learning(bportifaceobj.name)
+            if vxlan_learn:
+                vxlan_learn = utils.get_onoff_bool(vxlan_learn)
+            else:
+                vxlan_learn = 'on'
+            if vxlan_learn != config_learn:
+                self.ipcmd.set_vxlandev_learning(bportifaceobj.name, config_learn)
+        except Exception, e:
+            self.log_warn('%s: unable to propagate learning to vxlan dev (%s)'
+                          %(bportifaceobj.name, str(e)))
+
     def _apply_bridge_port_settings_all(self, ifaceobj,
                                         ifaceobj_getfunc=None,
                                         bridge_vlan_aware=False):
@@ -1896,6 +1930,22 @@ class bridge(moduleBase):
             except Exception, e:
                 self.log_warn('%s: %s' %(ifaceobj.name, str(e)))
 
+            try:
+                config_learn = ifaceobj.get_attr_value_first('bridge-learning')
+                if not config_learn:
+                    return
+                config_learn = utils.get_onoff_bool(config_learn)
+                running_learn = self.ipcmd.get_brport_learning(ifaceobj.name)
+                if config_learn == running_learn:
+                    ifaceobjcurr.update_config_with_status('bridge-learning',
+                                                            running_learn, 0)
+                else:
+                    ifaceobjcurr.update_config_with_status('bridge-learning',
+                                                            running_learn, 1)
+                
+            except Exception, e:
+                self.log_warn('%s: %s' %(ifaceobj.name, str(e)))
+
     def _query_check(self, ifaceobj, ifaceobjcurr, ifaceobj_getfunc=None):
         if self._is_bridge(ifaceobj):
             self._query_check_bridge(ifaceobj, ifaceobjcurr)
index 72eda662f994577835224e08c7290b9978b7d7a7..7018b3e9e465fca5fdd8a75748b19c5845c7556b 100644 (file)
@@ -660,6 +660,17 @@ class iproute2(utilsBase):
     def get_vxlandev_attrs(self, ifacename):
         return self._cache_get('link', [ifacename, 'linkinfo'])
 
+    def get_vxlandev_learning(self, ifacename):
+        return self._cache_get('link', [ifacename, 'linkinfo', 'learning'])
+
+    def set_vxlandev_learning(self, ifacename, learn):
+        if learn == 'on':
+            utils.exec_command('ip link set dev %s type vxlan learning' %ifacename)
+            self._cache_update([ifacename, 'linkinfo', 'learning'], 'on')
+        else:
+            utils.exec_command('ip link set dev %s type vxlan nolearning' %ifacename)
+            self._cache_update([ifacename, 'linkinfo', 'learning'], 'off')
+
     def link_get_linkinfo_attrs(self, ifacename):
         return self._cache_get('link', [ifacename, 'linkinfo'])
 
@@ -944,3 +955,19 @@ class iproute2(utilsBase):
     def link_get_vrfs(self):
         self._fill_cache()
         return linkCache.vrfs
+
+    def get_brport_learning(self, ifacename):
+        learn = self.read_file_oneline('/sys/class/net/%s/brport/learning'
+                                       %ifacename)
+        if learn and learn == '1':
+            return 'on'
+        else:
+            return 'off'
+
+    def set_brport_learning(self, ifacename, learn):
+        if learn == 'off':
+            return self.write_file('/sys/class/net/%s/brport/learning'
+                                    %ifacename, '0')
+        else:
+            return self.write_file('/sys/class/net/%s/brport/learning'
+                                    %ifacename, '1')