]> git.proxmox.com Git - mirror_ifupdown2.git/commitdiff
Misc fixes + ifreload new option + cleanups + more ifquery support etc
authorRoopa Prabhu <roopa@cumulusnetworks.com>
Wed, 12 Nov 2014 05:58:12 +0000 (21:58 -0800)
committerRoopa Prabhu <roopa@cumulusnetworks.com>
Wed, 12 Nov 2014 05:58:12 +0000 (21:58 -0800)
Ticket: CM-3346, CM-3784, CM-3841
Reviewed By:
Testing Done: various ifupdown2 tests

addons/bridge.py
addons/bridgevlanaware.py [deleted file]
addons/ifenslave.py
addons/vlan.py
config/ifupdown2.conf
ifupdown/iface.py
ifupdown/ifupdownmain.py
ifupdown/networkinterfaces.py
ifupdown/scheduler.py
ifupdownaddons/modulebase.py
sbin/ifupdown

index 94a8069e506ff214e40687d1b1e2b1e0381c6caf..9c21d58e8255a07d5995c615aaa8c249afc07153 100644 (file)
@@ -168,7 +168,8 @@ class bridge(moduleBase):
                                    'If specified under the bridge the ports ' +
                                    'inherit it unless overridden by a ' +
                                    'bridge-vids attribuet under the port',
-                          'example' : ['bridge-vids 4000']},
+                          'example' : ['bridge-vids 4000',
+                                       'bridge-vids 2000 2200-3000']},
                     'bridge-pvid' :
                         { 'help' : 'bridge port pvid. Must be specified under' +
                                    ' the bridge port',
@@ -198,6 +199,9 @@ class bridge(moduleBase):
         self.brctlcmd = None
         self._running_vidinfo = {}
         self._running_vidinfo_valid = False
+        self._resv_vlan_range =  self._get_reserved_vlan_range()
+        self.logger.debug('%s: using reserved vlan range %s'
+                  %(self.__class__.__name__, str(self._resv_vlan_range)))
 
     def _is_bridge(self, ifaceobj):
         if ifaceobj.get_attr_value_first('bridge-ports'):
@@ -605,7 +609,8 @@ class bridge(moduleBase):
                           %(bportifaceobj.name, pvid, str(e)))
 
     def _apply_bridge_vlan_aware_port_settings_all(self, bportifaceobj,
-                                                   bridge_vids=None):
+                                                   bridge_vids=None,
+                                                   bridge_pvid=None):
         running_vidinfo = self._get_running_vidinfo()
         vids = None
         pvids = None
@@ -613,22 +618,27 @@ class bridge(moduleBase):
         if bport_access:
             vids = re.split(r'[\s\t]\s*', bport_access)
             pvids = vids
+        else:
+            bport_vids = bportifaceobj.get_attr_value_first('bridge-vids')
+            if bport_vids:
+                vids = re.split(r'[\s\t,]\s*', bport_vids)
 
-        bport_vids = bportifaceobj.get_attr_value_first('bridge-vids')
-        if bport_vids:
-            vids = re.split(r'[\s\t]\s*', bport_vids)
-
-        bport_pvids = bportifaceobj.get_attr_value_first('bridge-pvid')
-        if bport_pvids:
-            pvids = re.split(r'[\s\t]\s*', bport_pvids)
+            bport_pvids = bportifaceobj.get_attr_value_first('bridge-pvid')
+            if bport_pvids:
+                pvids = re.split(r'[\s\t]\s*', bport_pvids)
 
         if pvids:
             self._apply_bridge_port_pvids(bportifaceobj, pvids[0],
                     running_vidinfo.get(bportifaceobj.name, {}).get('pvid'))
-        else:
+        elif bridge_pvid:
             self._apply_bridge_port_pvids(bportifaceobj,
-                    '1', running_vidinfo.get(bportifaceobj.name,
+                    bridge_pvid, running_vidinfo.get(bportifaceobj.name,
                     {}).get('pvid'))
+        # XXX: default pvid is already one
+        #else:
+        #    self._apply_bridge_port_pvids(bportifaceobj,
+        #            '1', running_vidinfo.get(bportifaceobj.name,
+        #            {}).get('pvid'))
 
         if vids:
             self._apply_bridge_vids(bportifaceobj, vids,
@@ -686,10 +696,16 @@ class bridge(moduleBase):
 
         bridge_vids = ifaceobj.get_attr_value_first('bridge-vids')
         if bridge_vids:
-           bridge_vids = re.split(r'[\s\t]\s*', bridge_vids)
+           bridge_vids = re.split(r'[\s\t,]\s*', bridge_vids)
         else:
            bridge_vids = None
 
+        bridge_pvid = ifaceobj.get_attr_value_first('bridge-pvid')
+        if bridge_pvid:
+           bridge_pvid = re.split(r'[\s\t]\s*', bridge_pvid)
+        else:
+           bridge_pvid = None
+
         bridgeports = self._get_bridge_port_list(ifaceobj)
         for bport in bridgeports:
             # Use the brctlcmd bulk set method: first build a dictionary
@@ -711,7 +727,7 @@ class bridge(moduleBase):
                 # Add attributes specific to the vlan aware bridge
                 if bridge_vlan_aware:
                    self._apply_bridge_vlan_aware_port_settings_all(
-                                bportifaceobj, bridge_vids)
+                                bportifaceobj, bridge_vids, bridge_pvid)
                 self._apply_bridge_port_settings(bportifaceobj,
                                                  bridgeifaceobj=ifaceobj)
 
@@ -722,8 +738,11 @@ class bridge(moduleBase):
            if self.ipcmd.bridge_is_vlan_aware(bridgename):
               bridge_vids = self._get_bridge_vids(bridgename,
                                                   ifaceobj_getfunc)
+              bridge_pvid = self._get_bridge_pvid(bridgename,
+                                                   ifaceobj_getfunc)
               self._apply_bridge_vlan_aware_port_settings_all(ifaceobj,
-                                                              bridge_vids)
+                                                              bridge_vids,
+                                                              bridge_pvid)
            self._apply_bridge_port_settings(ifaceobj, bridgename=bridgename)
            ifaceobj.priv_flags |= self._BRIDGE_PORT_PROCESSED
            return
@@ -1096,9 +1115,16 @@ class bridge(moduleBase):
         ifaceobjs = ifaceobj_getfunc(bridgename)
         for ifaceobj in ifaceobjs:
             vids = ifaceobj.get_attr_value_first('bridge-vids')
-            if vids: return re.split(r'[\s\t]\s*', vids)
+            if vids: return re.split(r'[\s\t,]\s*', vids)
         return None
 
+    def _get_bridge_pvid(self, bridgename, ifaceobj_getfunc):
+        ifaceobjs = ifaceobj_getfunc(bridgename)
+        pvid = None
+        for ifaceobj in ifaceobjs:
+            pvid = ifaceobj.get_attr_value_first('bridge-pvid')
+        return pvid
+
     def _get_bridge_name(self, ifaceobj):
         return self.ipcmd.bridge_port_get_bridge_name(ifaceobj.name)
 
diff --git a/addons/bridgevlanaware.py b/addons/bridgevlanaware.py
deleted file mode 100644 (file)
index 532fb30..0000000
+++ /dev/null
@@ -1,863 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2014 Cumulus Networks, Inc. All rights reserved.
-# Author: Roopa Prabhu, roopa@cumulusnetworks.com
-#
-
-from sets import Set
-from ifupdown.iface import *
-from ifupdownaddons.modulebase import moduleBase
-from ifupdownaddons.bridgeutils import brctl
-from ifupdownaddons.iproute2 import iproute2
-import itertools
-import re
-import os
-
-class bridgevlanaware(moduleBase):
-    """  ifupdown2 addon module to configure linux bridges """
-
-    _modinfo = { 'mhelp' : 'bridge configuration module',
-                 'attrs' : {
-                   'bridge' :
-                        {'help': 'bridge this interface is part of',
-                         'example' : ['bridge br0']},
-                   'bridge-vlan-aware' :
-                        {'help': 'Is this a vlan aware bridge ?',
-                         'default' : 'no',
-                         'required' : False,
-                         'example' : ['bridge-vlan-aware yes']},
-                   'type' :
-                        {'help': 'type of interface this module supports',
-                         'example' : ['type bridge']},
-                   'bridge-stp' :
-                        {'help': 'bridge-stp yes/no',
-                         'example' : ['bridge-stp no'],
-                         'validvals' : ['yes', 'on', 'off', 'no'],
-                         'default' : 'no'},
-                   'bridge-bridgeprio' :
-                        {'help': 'bridge priority',
-                         'example' : ['bridge-bridgeprio 32768'],
-                         'default' : '32768'},
-                   'bridge-ageing' :
-                       {'help': 'bridge ageing',
-                         'example' : ['bridge-ageing 300'],
-                         'default' : '300'},
-                   'bridge-fd' :
-                        { 'help' : 'bridge forward delay',
-                          'example' : ['bridge-fd 15'],
-                          'default' : '15'},
-                   'bridge-gcint' :
-                        # XXX: recheck values
-                        { 'help' : 'bridge garbage collection interval in secs',
-                          'example' : ['bridge-gcint 4'],
-                          'default' : '4'},
-                   'bridge-hello' :
-                        { 'help' : 'bridge set hello time',
-                          'example' : ['bridge-hello 2'],
-                          'default' : '2'},
-                   'bridge-maxage' :
-                        { 'help' : 'bridge set maxage',
-                          'example' : ['bridge-maxage 20'],
-                          'default' : '20'},
-                   'bridge-pathcosts' :
-                        { 'help' : 'bridge set port path costs',
-                          'example' : ['bridge-pathcosts swp1=100 swp2=100'],
-                          'default' : '100'},
-                   'bridge-priority' :
-                        { 'help' : 'bridge port priority',
-                          'example' : ['bridge-priority 32'],
-                          'default' : '32'},
-                   'bridge-mclmc' :
-                        { 'help' : 'set multicast last member count',
-                          'example' : ['bridge-mclmc 2'],
-                          'default' : '2'},
-                    'bridge-mcrouter' :
-                        { 'help' : 'set multicast router',
-                          'default' : '1',
-                          'example' : ['bridge-mcrouter 1']},
-                    'bridge-mcsnoop' :
-                        { 'help' : 'set multicast snooping',
-                          'default' : '1',
-                          'example' : ['bridge-mcsnoop 1']},
-                    'bridge-mcsqc' :
-                        { 'help' : 'set multicast startup query count',
-                          'default' : '2',
-                          'example' : ['bridge-mcsqc 2']},
-                    'bridge-mcqifaddr' :
-                        { 'help' : 'set multicast query to use ifaddr',
-                          'default' : '0',
-                          'example' : ['bridge-mcqifaddr 0']},
-                    'bridge-mcquerier' :
-                        { 'help' : 'set multicast querier',
-                          'default' : '0',
-                          'example' : ['bridge-mcquerier 0']},
-                    'bridge-hashel' :
-                        { 'help' : 'set hash elasticity',
-                          'default' : '4096',
-                          'example' : ['bridge-hashel 4096']},
-                    'bridge-hashmax' :
-                        { 'help' : 'set hash max',
-                          'default' : '4096',
-                          'example' : ['bridge-hashmax 4096']},
-                    'bridge-mclmi' :
-                        { 'help' : 'set multicast last member interval (in secs)',
-                          'default' : '1',
-                          'example' : ['bridge-mclmi 1']},
-                    'bridge-mcmi' :
-                        { 'help' : 'set multicast membership interval (in secs)',
-                          'default' : '260',
-                          'example' : ['bridge-mcmi 260']},
-                    'bridge-mcqpi' :
-                        { 'help' : 'set multicast querier interval (in secs)',
-                          'default' : '255',
-                          'example' : ['bridge-mcqpi 255']},
-                    'bridge-mcqi' :
-                        { 'help' : 'set multicast query interval (in secs)',
-                          'default' : '125',
-                          'example' : ['bridge-mcqi 125']},
-                    'bridge-mcqri' :
-                        { 'help' : 'set multicast query response interval (in secs)',
-                          'default' : '10',
-                          'example' : ['bridge-mcqri 10']},
-                    'bridge-mcsqi' :
-                        { 'help' : 'set multicast startup query interval (in secs)',
-                          'default' : '31',
-                          'example' : ['bridge-mcsqi 31']},
-                    'bridge-mcqv4src' :
-                        { 'help' : 'set per VLAN v4 multicast querier source address',
-                          'compat' : True,
-                          'example' : ['bridge-mcqv4src 172.16.100.1']},
-                    'bridge-igmp-querier-src' :
-                        { 'help' : 'set per VLAN v4 multicast querier source address',
-                          'example' : ['bridge-igmp-querier-src 172.16.100.1']},
-                    'bridge-mcfl' :
-                        { 'help' : 'port multicast fast leave',
-                          'default' : '0',
-                          'example' : ['bridge-mcfl 0']},
-                    'bridge-waitport' :
-                        { 'help' : 'wait for a max of time secs for the' +
-                                ' specified ports to become available,' +
-                                'if no ports are specified then those' +
-                                ' specified on bridge-ports will be' +
-                                ' used here. Specifying no ports here ' +
-                                'should not be used if we are using ' +
-                                'regex or \"all\" on bridge_ports,' +
-                                'as it wouldnt work.',
-                          'default' : '0',
-                          'example' : ['bridge-waitport 4 swp1 swp2']},
-                    'bridge-maxwait' :
-                        { 'help' : 'forces to time seconds the maximum time ' +
-                                'that the Debian bridge setup  scripts will ' +
-                                'wait for the bridge ports to get to the ' +
-                                'forwarding status, doesn\'t allow factional ' +
-                                'part. If it is equal to 0 then no waiting' +
-                                ' is done',
-                          'default' : '0',
-                          'example' : ['bridge-maxwait 3']},
-                    'bridge-vlan' :
-                        { 'help' : 'bridge vlans',
-                          'example' : ['bridge-vlan 4000']},
-                    'bridge-vlan-native' :
-                        { 'compat' : True,
-                          'help' : 'bridge port vlan',
-                          'example' : ['bridge-vlan-native 1']},
-                        }}
-
-    def __init__(self, *args, **kargs):
-        moduleBase.__init__(self, *args, **kargs)
-        self.ipcmd = None
-        self.brctlcmd = None
-
-    def _is_bridge_port(self, ifaceobj):
-        if ifaceobj.get_attr_value_first('bridge'):
-            return True
-        return False
-
-    def _is_bridge(self, ifaceobj):
-        if ifaceobj.type == ifaceType.BRIDGE:
-            return True
-        return False
-
-    def _is_bridge_vlan(self, ifaceobj):
-        if ifaceobj.type & ifaceType.BRIDGE_VLAN:
-            return True
-        return False
-
-    def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None):
-        bridge = ifaceobj.get_attr_value_first('bridge')
-        if bridge:
-            match = re.match("^%s-([\d]+)" %bridge, ifaceobj.name)
-            if match:
-                ifaceobj.priv_data = int(match.groups()[0], 10)
-                # XXX: mark this iface as a bridge_vlan iface
-                ifaceobj.type = ifaceType.BRIDGE_VLAN
-            return [bridge]
-        elif ifaceobj.get_attr_value_first('type') == 'bridge':
-            ifaceobj.type = ifaceType.BRIDGE
-        return None
-
-    def get_dependent_ifacenames_running(self, ifaceobj):
-        self._init_command_handlers()
-        if not self.brctlcmd.bridge_exists(ifaceobj.name):
-            return None
-        return self.brctlcmd.get_bridge_ports(ifaceobj.name)
-
-    def _process_bridge_waitport(self, ifaceobj, portlist):
-        waitport_value = ifaceobj.get_attr_value_first('bridge-waitport')
-        if not waitport_value: return
-        try:
-            waitportvals = re.split(r'[\s\t]\s*', waitport_value, 1)
-            if not waitportvals: return
-            try:
-                waitporttime = int(waitportvals[0])
-            except:
-                self.log_warn('%s: invalid waitport value \'%s\''
-                        %(ifaceobj.name, waitporttime))
-                return
-            if waitporttime <= 0: return
-            try:
-                waitportlist = self.parse_port_list(waitportvals[1])
-            except IndexError, e:
-                # ignore error and use all bridge ports
-                waitportlist = portlist
-                pass
-            if not waitportlist: return
-            self.logger.info('%s: waiting for ports %s to exist ...'
-                    %(ifaceobj.name, str(waitportlist)))
-            starttime = time.time()
-            while ((time.time() - starttime) < waitporttime):
-                if all([False for p in waitportlist
-                        if not self.ipcmd.link_exists(p)]):
-                    break;
-                time.sleep(1)
-        except Exception, e:
-            self.log_warn('%s: unable to process waitport: %s'
-                    %(ifaceobj.name, str(e)))
-
-    def _add_ports(self, ifaceobj):
-        bridgeports = self._get_bridge_port_list(ifaceobj)
-        runningbridgeports = []
-
-        self._process_bridge_waitport(ifaceobj, bridgeports)
-        # Delete active ports not in the new port list
-        if not self.PERFMODE:
-            runningbridgeports = self.brctlcmd.get_bridge_ports(ifaceobj.name)
-            if runningbridgeports:
-                [self.ipcmd.link_set(bport, 'nomaster')
-                    for bport in runningbridgeports
-                        if not bridgeports or bport not in bridgeports]
-            else:
-                runningbridgeports = []
-        if not bridgeports:
-            return
-        err = 0
-        for bridgeport in Set(bridgeports).difference(Set(runningbridgeports)):
-            try:
-                if not self.DRYRUN and not self.ipcmd.link_exists(bridgeport):
-                    self.log_warn('%s: bridge port %s does not exist'
-                                   %(ifaceobj.name, bridgeport))
-                    err += 1
-                    continue
-                self.ipcmd.link_set(bridgeport, 'master', ifaceobj.name)
-                self.write_file('/proc/sys/net/ipv6/conf/%s' %bridgeport +
-                                '/disable_ipv6', '1')
-                self.ipcmd.addr_flush(bridgeport)
-            except Exception, e:
-                self.log_error(str(e))
-        if err:
-            self.log_error('bridge configuration failed (missing ports)')
-
-    def _process_bridge_maxwait(self, ifaceobj, portlist):
-        maxwait = ifaceobj.get_attr_value_first('bridge-maxwait')
-        if not maxwait: return
-        try:
-            maxwait = int(maxwait)
-        except:
-            self.log_warn('%s: invalid maxwait value \'%s\'' %(ifaceobj.name,
-                    maxwait))
-            return
-        if not maxwait: return
-        self.logger.info('%s: waiting for ports to go to fowarding state ..'
-                %ifaceobj.name)
-        try:
-            starttime = time.time()
-            while ((time.time() - starttime) < maxwait):
-                if all([False for p in portlist
-                    if self.read_file_oneline(
-                            '/sys/class/net/%s/brif/%s/state'
-                            %(ifaceobj.name, p)) != '3']):
-                    break;
-                time.sleep(1)
-        except Exception, e:
-            self.log_warn('%s: unable to process maxwait: %s'
-                    %(ifaceobj.name, str(e)))
-
-    def _ints_to_ranges(self, ints):
-        for a, b in itertools.groupby(enumerate(ints), lambda (x, y): y - x):
-            b = list(b)
-            yield b[0][1], b[-1][1]
-
-    def _ranges_to_ints(self, rangelist):
-        """ returns expanded list of integers given set of string ranges
-        example: ['1', '2-4', '6'] returns [1, 2, 3, 4, 6]
-        """
-        result = []
-        for part in rangelist:
-            if '-' in part:
-                a, b = part.split('-')
-                a, b = int(a), int(b)
-                result.extend(range(a, b + 1))
-            else:
-                a = int(part)
-                result.append(a)
-        return result
-
-    def _diff_vids(self, vids1, vids2):
-        vids_to_add = None
-        vids_to_del = None
-
-        vids1_ints = self._ranges_to_ints(vids1)
-        vids2_ints = self._ranges_to_ints(vids2)
-        vids1_diff = Set(vids1_ints).difference(vids2_ints)
-        vids2_diff = Set(vids2_ints).difference(vids1_ints)
-        if vids1_diff:
-            vids_to_add = ['%d' %start if start == end else '%d-%d' %(start, end)
-                        for start, end in self._ints_to_ranges(vids1_diff)]
-        if vids2_diff:
-            vids_to_del = ['%d' %start if start == end else '%d-%d' %(start, end)
-                        for start, end in self._ints_to_ranges(vids2_diff)]
-        return (vids_to_del, vids_to_add)
-
-    def _compare_vids(self, vids1, vids2):
-        """ Returns true if the vids are same else return false """
-
-        vids1_ints = self._ranges_to_ints(vids1)
-        vids2_ints = self._ranges_to_ints(vids2)
-        if Set(vids1_ints).symmetric_difference(vids2_ints):
-            return False
-        else:
-            return True
-
-    def _set_bridge_mcqv4src(self, ifaceobj):
-        attrval = ifaceobj.get_attr_value_first('bridge-mcqv4src')
-        if attrval:
-            running_mcqv4src = {}
-            if not self.PERFMODE:
-                running_mcqv4src = self.brctlcmd.get_mcqv4src(ifaceobj.name)
-            mcqs = {}
-            srclist = attrval.split()
-            for s in srclist:
-                k, v = s.split('=')
-                mcqs[k] = v
-
-            k_to_del = Set(running_mcqv4src.keys()).difference(mcqs.keys())
-            for v in k_to_del:
-                self.brctlcmd.del_mcqv4src(ifaceobj.name, int(v, 10))
-            for v in mcqs.keys():
-                self.brctlcmd.set_mcqv4src(ifaceobj.name, int(v, 10), mcqs[v])
-
-    def _set_bridge_vidinfo(self, ifaceobj, isbridge=True):
-        # Handle bridge vlan attrs
-        running_vidinfo = {}
-        if not self.PERFMODE:
-            running_vidinfo = self.ipcmd.bridge_port_vids_get_all()
-        attrval = ifaceobj.get_attr_value_first('bridge-vlan')
-        if attrval:
-            vids = re.split(r'[\s\t]\s*', attrval)
-            #vids = attrval.split(',')
-            try:
-                if running_vidinfo.get(ifaceobj.name):
-                    (vids_to_del, vids_to_add) = \
-                    self._diff_vids(vids,
-                            running_vidinfo.get(ifaceobj.name, {}).get('vlan'))
-                    if vids_to_del:
-                        self.ipcmd.bridge_vids_del(ifaceobj.name,
-                                                   vids_to_del, isbridge)
-                    if vids_to_add:
-                        self.ipcmd.bridge_vids_add(ifaceobj.name,
-                                                        vids_to_add, isbridge)
-                else:
-                    self.ipcmd.bridge_vids_add(ifaceobj.name, vids,
-                                                    isbridge)
-            except Exception, e:
-                self.log_warn('%s: failed to set vid `%s` (%s)'
-                        %(ifaceobj.name, str(vids), str(e)))
-        else:
-            running_vids = running_vidinfo.get(ifaceobj.name, {}).get('vlan')
-            if running_vids:
-                self.ipcmd.bridge_vids_del(ifaceobj.name, running_vids)
-
-        # Install pvids
-        pvid = ifaceobj.get_attr_value_first('bridge-vlan-native')
-        if pvid:
-            try:
-                running_pvid = running_vidinfo.get(ifaceobj.name,
-                                                   {}).get('pvid')
-                if running_pvid:
-                    if running_pvid != pvid:
-                        self.ipcmd.bridge_port_pvid_del(ifaceobj.name,
-                                                        running_pvid)
-                        self.ipcmd.bridge_port_pvid_add(ifaceobj.name, pvid)
-                else:
-                    self.ipcmd.bridge_port_pvid_add(ifaceobj.name, pvid)
-            except Exception, e:
-                self.log_warn('%s: failed to set pvid `%s` (%s)'
-                            %(ifaceobj.name, pvid, str(e)))
-
-    def _apply_bridge_settings(self, ifaceobj):
-        try:
-            stp = ifaceobj.get_attr_value_first('bridge-stp')
-            if stp:
-                self.brctlcmd.set_stp(ifaceobj.name, stp)
-            # Use the brctlcmd bulk set method: first build a dictionary
-            # and then call set
-            bridgeattrs = { k:v for k,v in
-                             {'ageing' :
-                                ifaceobj.get_attr_value_first('bridge-ageing'),
-                              'bridgeprio' :
-                                ifaceobj.get_attr_value_first(
-                                                        'bridge-bridgeprio'),
-                              'fd' :
-                                ifaceobj.get_attr_value_first('bridge-fd'),
-                              'gcint' :
-                                ifaceobj.get_attr_value_first('bridge-gcint'),
-                              'hello' :
-                                ifaceobj.get_attr_value_first('bridge-hello'),
-                              'maxage' :
-                                ifaceobj.get_attr_value_first('bridge-maxage'),
-                              'mclmc' :
-                                ifaceobj.get_attr_value_first('bridge-mclmc'),
-                              'mcrouter' :
-                                ifaceobj.get_attr_value_first(
-                                                            'bridge-mcrouter'),
-                              'mcsnoop' :
-                                ifaceobj.get_attr_value_first('bridge-mcsnoop'),
-                              'mcsqc' :
-                                ifaceobj.get_attr_value_first('bridge-mcsqc'),
-                              'mcqifaddr' :
-                                ifaceobj.get_attr_value_first(
-                                                            'bridge-mcqifaddr'),
-                              'mcquerier' :
-                                ifaceobj.get_attr_value_first(
-                                                            'bridge-mcquerier'),
-                              'hashel' :
-                                ifaceobj.get_attr_value_first('bridge-hashel'),
-                              'hashmax' :
-                                ifaceobj.get_attr_value_first('bridge-hashmax'),
-                              'mclmi' :
-                                ifaceobj.get_attr_value_first('bridge-mclmi'),
-                              'mcmi' :
-                                ifaceobj.get_attr_value_first('bridge-mcmi'),
-                              'mcqpi' :
-                                ifaceobj.get_attr_value_first('bridge-mcqpi'),
-                              'mcqi' :
-                                ifaceobj.get_attr_value_first('bridge-mcqi'),
-                              'mcqri' :
-                                ifaceobj.get_attr_value_first('bridge-mcqri'),
-                              'mcsqi' :
-                                ifaceobj.get_attr_value_first('bridge-mcsqi')
-                               }.items()
-                            if v }
-            if bridgeattrs:
-                self.brctlcmd.set_bridge_attrs(ifaceobj.name, bridgeattrs)
-            self._set_bridge_vidinfo(ifaceobj)
-
-            self._set_bridge_mcqv4src(ifaceobj)
-
-            #self._process_bridge_maxwait(ifaceobj,
-            #        self._get_bridge_port_list(ifaceobj))
-        except Exception, e:
-            self.log_warn(str(e))
-
-    def _apply_bridge_port_settings(self, ifaceobj, bridge):
-        try:
-            # Use the brctlcmd bulk set method: first build a dictionary
-            # and then call set
-            portattrs = {}
-            for attrname, dstattrname in {'bridge-pathcost' : 'pathcost',
-                                'bridge-prio' : 'portprio',
-                                'bridge-mcrouter' : 'portmcrouter',
-                                'bridge-mcfl' : 'portmcfl'}.items():
-                attrval = ifaceobj.get_attr_value_first(attrname)
-                if not attrval:
-                    continue
-                portattrs[ifaceobj.name] = attrval
-            self.brctlcmd.set_bridgeport_attrs(bridge, ifaceobj.name, portattrs)
-            self._set_bridge_vidinfo(ifaceobj, isbridge=False)
-        except Exception, e:
-            self.log_warn(str(e))
-
-    def _apply_bridge_vlan_settings(self, ifaceobj, bridge):
-        mcq = ifaceobj.get_attrs_value_first(['bridge-mcqv4src',
-                                    'bridge-igmp-querier-src'])
-        if mcq:
-            running_mcq = None
-            if not self.PERFMODE:
-                running_mcq = self.brctlcmd.get_mcqv4src(bridge,
-                                            vlan=ifaceobj.priv_data)
-            if running_mcq != mcq:
-                self.brctlcmd.set_mcqv4src(bridge, ifaceobj.priv_data, mcq)
-
-        self.ipcmd.bridge_vids_add(bridge, [ifaceobj.priv_data], True)
-
-    def _delete_bridge_vlan_settings(self, ifaceobj, bridge):
-        # delete vlan from bridge
-        self.ipcmd.bridge_vids_del(bridge, [ifaceobj.priv_data], True)
-
-        mcq = ifaceobj.get_attr_value_first('bridge-mcqv4src')
-        if mcq:
-            self.brctlcmd.del_mcqv4src(bridge, ifaceobj.name)
-
-    def _up_bridge(self, ifaceobj):
-        try:
-            if not self.PERFMODE:
-                if not self.ipcmd.link_exists(ifaceobj.name):
-                    self.ipcmd.link_create(ifaceobj.name, 'bridge')
-            else:
-                self.ipcmd.link_create(ifaceobj.name, 'bridge')
-            self._apply_bridge_settings(ifaceobj)
-        except Exception, e:
-            self.log_error(str(e))
-
-    def _up_bridge_port(self, ifaceobj, bridge):
-        try:
-           self.ipcmd.link_set(ifaceobj.name, 'master', bridge)
-           self._apply_bridge_port_settings(ifaceobj, bridge)
-        except Exception, e:
-            self.log_error(str(e))
-
-    def _up_bridge_vlan(self, ifaceobj, bridge):
-        purge_existing = False if self.PERFMODE else True
-        try:
-            address = ifaceobj.get_attr_value('address')
-            if address:
-                # Create a vlan device, 
-                ifacename  = '%s.%s' %(bridge, ifaceobj.priv_data)
-                if not self.ipcmd.link_exists(ifacename):
-                    self.ipcmd.link_create_vlan(ifacename, bridge,
-                            ifaceobj.priv_data)
-                    purge_existing = False
-                hwaddress = ifaceobj.get_attr_value_first('hwaddress')
-                if hwaddress:
-                    self.ipcmd.link_set_hwaddress(ifacename, hwaddress)
-                self.ipcmd.addr_add_multiple(ifacename, address, purge_existing)
-            self._apply_bridge_vlan_settings(ifaceobj, bridge)
-        except Exception, e:
-            self.log_error(str(e))
-
-    def _up(self, ifaceobj):
-        bridge = ifaceobj.get_attr_value_first('bridge')
-        if ifaceobj.type == ifaceType.BRIDGE_VLAN:
-            self._up_bridge_vlan(ifaceobj, bridge)
-        elif bridge:
-            self._up_bridge_port(ifaceobj, bridge)
-        elif self._is_bridge(ifaceobj):
-            self._up_bridge(ifaceobj)
-        else:
-            # Was this interface part of the bridge at some point and now
-            # got removed ?. If we attached it to the bridge last time
-            # we should release it
-            if os.path.exists('/sys/class/net/%s/brport' %ifaceobj.name):
-                bridgelink = os.readlink('/sys/class/net/%s/brport/bridge'
-                                         %ifaceobj.name)
-                if bridgelink:
-                    bridge = os.path.basename(bridgelink)
-                    if (not ifaceobj.upperifaces or 
-                            bridge not in ifaceobj.upperifaces):
-                        # set nomaster
-                        self.ipcmd.link_set(ifaceobj.name, 'nomaster')
-
-    def _down_bridge(self, ifaceobj):
-        try:
-            self.brctlcmd.delete_bridge(ifaceobj.name)
-        except Exception, e:
-            self.log_error(str(e))
-
-    def _down_bridge_port(self, ifaceobj):
-        self.ipcmd.link_set(ifaceobj.name, 'nomaster')
-
-    def _down_bridge_vlan(self, ifaceobj, bridge):
-        try:
-            address = ifaceobj.get_attr_value('address')
-            if address:
-                # Create a vlan device, 
-                ifacename  = '%s.%s' %(bridge, ifaceobj.priv_data)
-                self.ipcmd.link_delete(ifacename)
-            self._delete_bridge_vlan_settings(ifaceobj, bridge)
-        except Exception, e:
-            self.log_error(str(e))
-
-    def _down(self, ifaceobj):
-        bridge = ifaceobj.get_attr_value_first('bridge')
-        if ifaceobj.type == ifaceType.BRIDGE_VLAN:
-            self._down_bridge_vlan(ifaceobj, bridge)
-        elif bridge:
-            self._down_bridge_port(ifaceobj)
-        elif self._is_bridge(ifaceobj):
-            self._down_bridge(ifaceobj)
-
-    def _query_running_vidinfo(self, ifaceobjrunning, ports):
-        running_attrs = {}
-        running_vidinfo = self.ipcmd.bridge_port_vids_get_all()
-
-        if ports:
-            running_bridge_port_vids = ''
-            for p in ports:
-                try:
-                    running_vids = running_vidinfo.get(p, {}).get('vlan')
-                    if running_vids:
-                        running_bridge_port_vids += ' %s=%s' %(p,
-                                                      ','.join(running_vids))
-                except Exception:
-                    pass
-            running_attrs['bridge-port-vids'] = running_bridge_port_vids
-
-            running_bridge_port_pvids = ''
-            for p in ports:
-                try:
-                    running_pvids = running_vidinfo.get(p, {}).get('pvid')
-                    if running_pvids:
-                        running_bridge_port_pvids += ' %s=%s' %(p,
-                                                        running_pvids)
-                except Exception:
-                    pass
-            running_attrs['bridge-port-pvids'] = running_bridge_port_pvids
-
-        running_bridge_vids = running_vidinfo.get(ifaceobjrunning.name, {}).get('vlan')
-        if running_bridge_vids:
-            running_attrs['bridge-vids'] = ','.join(running_bridge_vids)
-        return running_attrs
-
-    def _query_running_mcqv4src(self, ifaceobjrunning):
-        running_mcqv4src = self.brctlcmd.get_mcqv4src(ifaceobjrunning.name)
-        mcqs = ['%s=%s' %(v, i) for v, i in running_mcqv4src.items()]
-        mcqs.sort()
-        mcq = ' '.join(mcqs)
-        return mcq
-
-    def _query_running_attrs(self, ifaceobjrunning):
-        bridgeattrdict = {}
-        userspace_stp = 0
-        ports = None
-        skip_kernel_stp_attrs = 0
-
-        if self.sysctl_get('net.bridge.bridge-stp-user-space') == '1':
-            userspace_stp = 1
-
-        tmpbridgeattrdict = self.brctlcmd.get_bridge_attrs(ifaceobjrunning.name)
-        if not tmpbridgeattrdict:
-            self.logger.warn('%s: unable to get bridge attrs'
-                    %ifaceobjrunning.name)
-            return bridgeattrdict
-
-        # Fill bridge_ports and bridge stp attributes first
-        ports = tmpbridgeattrdict.get('ports')
-        if ports:
-            bridgeattrdict['bridge-ports'] = [' '.join(ports.keys())]
-        stp = tmpbridgeattrdict.get('stp', 'no')
-        if stp != self.get_mod_subattr('bridge-stp', 'default'):
-            bridgeattrdict['bridge-stp'] = [stp]
-
-        if  stp == 'yes' and userspace_stp:
-            skip_kernel_stp_attrs = 1
-
-        # pick all other attributes
-        for k,v in tmpbridgeattrdict.items():
-            if not v:
-                continue
-            if k == 'ports' or k == 'stp':
-                continue
-
-            if skip_kernel_stp_attrs and k[:2] != 'mc':
-                # only include igmp attributes if kernel stp is off
-                continue
-            attrname = 'bridge-' + k
-            if v != self.get_mod_subattr(attrname, 'default'):
-                bridgeattrdict[attrname] = [v]
-
-        bridgevidinfo = self._query_running_vidinfo(ifaceobjrunning, ports)
-        if bridgevidinfo:
-            bridgeattrdict.update({k : [v] for k, v in bridgevidinfo.items()
-                                    if v})
-
-        mcq = self._query_running_mcqv4src(ifaceobjrunning)
-        if mcq:
-            bridgeattrdict['bridge-mcqv4src'] = [mcq]
-
-        if skip_kernel_stp_attrs:
-            return bridgeattrdict
-
-        if ports:
-            portconfig = {'bridge-pathcosts' : '',
-                          'bridge-portprios' : ''}
-            for p, v in ports.items():
-                v = self.brctlcmd.get_pathcost(ifaceobjrunning.name, p)
-                if v and v != self.get_mod_subattr('bridge-pathcosts',
-                                                   'default'):
-                    portconfig['bridge-pathcosts'] += ' %s=%s' %(p, v)
-
-                v = self.brctlcmd.get_portprio(ifaceobjrunning.name, p)
-                if v and v != self.get_mod_subattr('bridge-portprios',
-                                                   'default'):
-                    portconfig['bridge-portprios'] += ' %s=%s' %(p, v)
-
-            bridgeattrdict.update({k : [v] for k, v in portconfig.items()
-                                    if v})
-
-        return bridgeattrdict
-
-    def _query_check_mcqv4src(self, ifaceobj, ifaceobjcurr):
-        running_mcqs = self._query_running_mcqv4src(ifaceobj)
-        attrval = ifaceobj.get_attr_value_first('bridge-mcqv4src')
-        if attrval:
-            mcqs = attrval.split()
-            mcqs.sort()
-            mcqsout = ' '.join(mcqs)
-            ifaceobjcurr.update_config_with_status('bridge-mcqv4src',
-                         running_mcqs, 1 if running_mcqs != mcqsout else 0)
-
-    def _query_check_vidinfo(self, ifaceobj, ifaceobjcurr):
-
-        err = 0
-        running_vidinfo = self.ipcmd.bridge_port_vids_get_all()
-        attrval = ifaceobj.get_attr_value_first('bridge-port-vids')
-        if attrval:
-            running_bridge_port_vids = ''
-            portlist = self.parse_port_list(attrval)
-            if not portlist:
-                self.log_warn('%s: could not parse \'%s %s\''
-                          %(ifaceobj.name, attrname, attrval))
-                return
-            err = 0
-            for p in portlist:
-                try:
-                    (port, val) = p.split('=')
-                    vids = val.split(',')
-                    running_vids = running_vidinfo.get(port, {}).get('vlan')
-                    if running_vids:
-                        if not self._compare_vids(vids, running_vids):
-                            err += 1
-                            running_bridge_port_vids += ' %s=%s' %(port,
-                                                      ','.join(running_vids))
-                        else:
-                            running_bridge_port_vids += ' %s' %p
-                    else:
-                        err += 1
-                except Exception, e:
-                    self.log_warn('%s: failure checking vid %s (%s)'
-                        %(ifaceobj.name, p, str(e)))
-            if err:
-                ifaceobjcurr.update_config_with_status('bridge-port-vids',
-                                                 running_bridge_port_vids, 1)
-            else:
-                ifaceobjcurr.update_config_with_status('bridge-port-vids',
-                                                 attrval, 0)
-
-        # Install pvids
-        attrval = ifaceobj.get_attr_value_first('bridge-port-pvids')
-        if attrval:
-            portlist = self.parse_port_list(attrval)
-            if not portlist:
-                self.log_warn('%s: could not parse \'%s %s\''
-                              %(ifaceobj.name, attrname, attrval))
-                return
-            running_bridge_port_pvids = ''
-            err = 0
-            for p in portlist:
-                try:
-                    (port, pvid) = p.split('=')
-                    running_pvid = running_vidinfo.get(port, {}).get('pvid')
-                    if running_pvid and running_pvid == pvid:
-                        running_bridge_port_pvids += ' %s' %p
-                    else:
-                        err += 1
-                        running_bridge_port_pvids += ' %s=%s' %(port,
-                                                            running_pvid)
-                except Exception, e:
-                    self.log_warn('%s: failure checking pvid %s (%s)'
-                            %(ifaceobj.name, pvid, str(e)))
-            if err:
-                ifaceobjcurr.update_config_with_status('bridge-port-pvids',
-                                                 running_bridge_port_pvids, 1)
-            else:
-                ifaceobjcurr.update_config_with_status('bridge-port-pvids',
-                                                 running_bridge_port_pvids, 0)
-
-        attrval = ifaceobj.get_attr_value_first('bridge-vids')
-        if attrval:
-            vids = re.split(r'[\s\t]\s*', attrval)
-            running_vids = running_vidinfo.get(ifaceobj.name, {}).get('vlan')
-            if running_vids:
-                if self._compare_vids(vids, running_vids):
-                    ifaceobjcurr.update_config_with_status('bridge-vids',
-                                                           attrval, 0)
-                else:
-                    ifaceobjcurr.update_config_with_status('bridge-vids',
-                                                ','.join(running_vids), 1)
-            else:
-                ifaceobjcurr.update_config_with_status('bridge-vids', attrval,
-                                                       1)
-
-    def _query_check_bridge(self, ifaceobj, ifaceobjcurr):
-        return
-
-    def _query_check_bridge_port(self, ifaceobj, bridge, ifaceobjcurr):
-        return
-
-    def _query_check_bridge_vlan(self, ifaceobj, bridge, ifaceobjcurr):
-        return
-
-    def _query_check(self, ifaceobj, ifaceobjcurr):
-        bridge = ifaceobj.get_attr_value_first('bridge')
-        if ifaceobj.type == ifaceType.BRIDGE_VLAN:
-            self._query_check_bridge_vlan(ifaceobj, bridge, ifaceobjcurr)
-        elif bridge:
-            self._query_check_bridge_port(ifaceobj, bridge, ifaceobjcurr)
-        elif self._is_bridge(ifaceobj):
-            self._query_check_bridge(ifaceobj, ifaceobjcurr)
-
-    def _query_running(self, ifaceobjrunning):
-        return
-
-    _run_ops = {'pre-up' : _up,
-               'post-down' : _down,
-               'query-checkcurr' : _query_check,
-               'query-running' : _query_running}
-
-    def get_ops(self):
-        """ returns list of ops supported by this module """
-        return self._run_ops.keys()
-
-    def _init_command_handlers(self):
-        flags = self.get_flags()
-        if not self.ipcmd:
-            self.ipcmd = iproute2(**flags)
-        if not self.brctlcmd:
-            self.brctlcmd = brctl(**flags)
-
-    def run(self, ifaceobj, operation, query_ifaceobj=None):
-        """ run bridge configuration on the interface object passed as
-            argument. Can create bridge interfaces if they dont exist already
-
-        Args:
-            **ifaceobj** (object): iface object
-
-            **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
-                                 'query-running'
-
-        Kwargs:
-            **query_ifaceobj** (object): query check ifaceobject. This is only
-                valid when op is 'query-checkcurr'. It is an object same as
-                ifaceobj, but contains running attribute values and its config
-                status. The modules can use it to return queried running state
-                of interfaces. status is success if the running state is same
-                as user required state in ifaceobj. error otherwise.
-        """
-        op_handler = self._run_ops.get(operation)
-        if not op_handler:
-           return
-        self._init_command_handlers()
-        if operation == 'query-checkcurr':
-            op_handler(self, ifaceobj, query_ifaceobj)
-        else:
-            op_handler(self, ifaceobj)
index b344e2ab5d33f05b18267562f43d56937fd6024a..aa89c2e5658a1d4d084a6bf0f8e9fe2381c3cf9e 100644 (file)
@@ -321,6 +321,7 @@ class ifenslave(moduleBase):
                             self.ifenslavecmd.get_lacp_fallback_period(bondname),
                      'bond-lacp-fallback-priority' :
                             self.ifenslavecmd.get_lacp_fallback_priority(bondname)}
+
         slaves = self.ifenslavecmd.get_slaves(bondname)
         if slaves:
             bondattrs['bond-slaves'] = slaves
index feb16c9b2f785f67fc4f45be16b5eb563ae18070..2467a2f456b093f75e7363919297b6aa614e23c1 100644 (file)
@@ -30,6 +30,9 @@ class vlan(moduleBase):
         moduleBase.__init__(self, *args, **kargs)
         self.ipcmd = None
         self._bridge_vids_query_cache = {}
+        self._resv_vlan_range =  self._get_reserved_vlan_range()
+        self.logger.debug('%s: using reserved vlan range %s'
+                  %(self.__class__.__name__, str(self._resv_vlan_range)))
 
     def _is_vlan_device(self, ifaceobj):
         vlan_raw_device = ifaceobj.get_attr_value_first('vlan-raw-device')
@@ -197,6 +200,7 @@ class vlan(moduleBase):
     def _init_command_handlers(self):
         if not self.ipcmd:
             self.ipcmd = iproute2(**self.get_flags())
+        
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         """ run vlan configuration on the interface object passed as argument
index d450e1352e97c2715414b5ed76226d9a43687231..cd210d88c3de6b40c99756cedd98b00e664551d1 100644 (file)
@@ -13,12 +13,21 @@ template_lookuppath=/etc/network/ifupdown2/templates
 # Support /etc/network/if-*/ scripts
 addon_scripts_support=0
 
+# By defauly ifupdown2 only supports a single vlan filtering bridge
+# on the system. Set this flag to 1 to support multiple vlan
+# filtering bridges
+multiple_vlan_aware_bridge_support=0
+
 # ifquery check status strings.
 # By default `ifquery --check` prints the check and
 # cross marks against interface attributes.
 # Use the below strings to modify the default behaviour.
+#
+# ifquery_check_success_str=
+# ifquery_check_error_str=(x)
+#
 
-# check_success_str=
-# check_error_str=(x)
+# This attribute controls iface/vlan range expansions
+# in ifquery default output.
+ifquery_ifacename_expand_range=0
 
-multiple_vlan_aware_bridge_support=0
index 8e53415953aeda00796e60b656ea386edea1ea94..6f5b895841276ee0b6c4d09be71b49c6cbd6c061 100644 (file)
@@ -18,10 +18,9 @@ import logging
 import json
 
 class ifaceType():
-    UNKNOWN = 0x1
-    GENERIC = 0x2
-    BRIDGE = 0x3
-    BRIDGE_VLAN = 0x4
+    UNKNOWN = 0x0
+    IFACE = 0x1
+    BRIDGE_VLAN = 0x2
 
 class ifaceStatus():
     """Enumerates iface status """
@@ -180,6 +179,8 @@ class iface():
     # flag to indicate that the object was created from pickled state
     _PICKLED = 0x1
     HAS_SIBLINGS = 0x2
+    IFACERANGE_ENTRY = 0x3
+    IFACERANGE_START = 0x4
 
     version = '0.1'
 
@@ -214,7 +215,7 @@ class iface():
         self.type = ifaceType.UNKNOWN
         """interface type"""
         self.priv_data = None
-        self.real_name = None
+        self.realname = None
 
     def _set_attrs_from_dict(self, attrdict):
         self.auto = attrdict.get('auto', False)
@@ -436,15 +437,20 @@ class iface():
         logger.info('}')
 
     def dump_pretty(self, with_status=False,
-                    successstr='success', errorstr='error'):
+                    successstr='success', errorstr='error',
+                    use_realname=False):
         indent = '\t'
         outbuf = ''
+        if use_realname:
+            name = self.realname
+        else:
+            name = self.name
         if self.auto:
-            outbuf += 'auto %s\n' %self.name
+            outbuf += 'auto %s\n' %name
         if self.type == ifaceType.BRIDGE_VLAN:
-            outbuf += 'vlan %s' %self.name
+            outbuf += 'vlan %s' %name
         else:
-            outbuf += 'iface %s' %self.name
+            outbuf += 'iface %s' %name
         if self.addr_family:
             outbuf += ' %s' %self.addr_family
         if self.addr_method:
index c7a8751494d394e247858b2a0de31a1bbc9f1482..8a724c3f94c861ef7795b8e3b8357dc6a6cbd220 100644 (file)
@@ -165,6 +165,8 @@ class ifupdownMain(ifupdownBase):
         self.config = config
         self.logger.debug(self.config)
 
+        self.type = ifaceType.UNKNOWN
+
         # Can be used to provide hints for caching
         self.CACHE_FLAGS = 0x0
         self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG = False
@@ -348,7 +350,7 @@ class ifupdownMain(ifupdownBase):
         for d in del_list:
             dlist.remove(d)
 
-    def query_dependents(self, ifaceobj, ops, ifacenames):
+    def query_dependents(self, ifaceobj, ops, ifacenames, type=None):
         """ Gets iface dependents by calling into respective modules """
         ret_dlist = []
 
@@ -742,8 +744,17 @@ class ifupdownMain(ifupdownBase):
                 traceback.print_tb(t)
                 self.logger.warning('error saving state (%s)' %str(e))
 
+    def set_type(self, type):
+        if type == 'iface':
+            self.type = ifaceType.IFACE
+        elif type == 'vlan':
+            self.type = ifaceType.BRIDGE_VLAN
+        else:
+            self.type = ifaceType.UNKNOWN
+
     def up(self, ops, auto=False, allow_classes=None, ifacenames=None,
-           excludepats=None, printdependency=None, syntaxcheck=False):
+           excludepats=None, printdependency=None, syntaxcheck=False,
+           type=None):
         """This brings the interface(s) up
         
         Args:
@@ -758,6 +769,8 @@ class ifupdownMain(ifupdownBase):
             syntaxcheck (bool): only perform syntax check
         """
 
+        self.set_type(type)
+
         if allow_classes:
             self.IFACE_CLASS = True
         if not self.ADDONS_ENABLE: self.STATEMANAGER_UPDATE = False
@@ -800,9 +813,12 @@ class ifupdownMain(ifupdownBase):
                 self._save_state()
 
     def down(self, ops, auto=False, allow_classes=None, ifacenames=None,
-             excludepats=None, printdependency=None, usecurrentconfig=False):
+             excludepats=None, printdependency=None, usecurrentconfig=False,
+             type=None):
         """ down an interface """
 
+        self.set_type(type)
+
         if allow_classes:
             self.IFACE_CLASS = True
         if not self.ADDONS_ENABLE: self.STATEMANAGER_UPDATE = False
@@ -858,9 +874,11 @@ class ifupdownMain(ifupdownBase):
 
     def query(self, ops, auto=False, allow_classes=None, ifacenames=None,
               excludepats=None, printdependency=None,
-              format='native'):
+              format='native', type=None):
         """ query an interface """
 
+        self.set_type(type)
+
         if allow_classes:
             self.IFACE_CLASS = True
         if self.STATEMANAGER_ENABLE and ops[0] == 'query-savedstate':
@@ -902,8 +920,6 @@ class ifupdownMain(ifupdownBase):
                 raise Exception('no ifaces found matching ' +
                         'given allow lists')
 
-        # Roopa
-        #self.populate_dependency_info(ops, filtered_ifacenames)
         self.populate_dependency_info(ops)
         if ops[0] == 'query-dependency' and printdependency:
             self.print_dependency(filtered_ifacenames, printdependency)
@@ -925,16 +941,87 @@ class ifupdownMain(ifupdownBase):
             self.print_ifaceobjsrunning_pretty(filtered_ifacenames, format)
             return
 
-    def reload(self, upops, downops, auto=False, allow=None,
-            ifacenames=None, excludepats=None, usecurrentconfig=False):
-        """ reload interface config """
+    def _reload_currentlyup(self, upops, downops, auto=True, allow=None,
+            ifacenames=None, excludepats=None, usecurrentconfig=False,
+            **extra_args):
+        """ reload currently up interfaces """
         allow_classes = []
         new_ifaceobjdict = {}
 
-        self.logger.debug('reloading interface config ..')
-        if auto:
-            self.ALL = True
-            self.WITH_DEPENDS = True
+        # Override auto to true
+        auto = True
+
+        try:
+            self.read_iface_config()
+        except:
+            raise
+
+        if not self.ifaceobjdict:
+            self.logger.warn("nothing to reload ..exiting.")
+            return
+
+        already_up_ifacenames = []
+        # generate dependency graph of interfaces
+        self.populate_dependency_info(upops)
+        if (not usecurrentconfig and self.STATEMANAGER_ENABLE
+                and self.statemanager.ifaceobjdict):
+            already_up_ifacenames = self.statemanager.ifaceobjdict.keys()
+
+        if not ifacenames: ifacenames = self.ifaceobjdict.keys()
+        filtered_ifacenames = [i for i in ifacenames
+                               if self._iface_whitelisted(auto, allow_classes,
+                               excludepats, i)]
+        
+        # Get already up interfaces that still exist in the interfaces file
+        already_up_ifacenames_not_present = Set(
+                        already_up_ifacenames).difference(ifacenames)
+        already_up_ifacenames_still_present = Set(
+                        already_up_ifacenames).difference(
+                        already_up_ifacenames_not_present)
+        interfaces_to_up = Set(already_up_ifacenames_still_present).union(
+                                            filtered_ifacenames)
+
+        if (already_up_ifacenames_not_present and
+                self.config.get('ifreload_currentlyup_down_notpresent') == '1'):
+           self.logger.info('reload: schedule down on interfaces: %s'
+                            %str(already_up_ifacenames_not_present))
+
+           # Save a copy of new iface objects and dependency_graph
+           new_ifaceobjdict = dict(self.ifaceobjdict)
+           new_dependency_graph = dict(self.dependency_graph)
+
+           # old interface config is read into self.ifaceobjdict
+           self.read_old_iface_config()
+
+           # reinitialize dependency graph 
+           self.dependency_graph = OrderedDict({})
+           self.populate_dependency_info(downops,
+                                         already_up_ifacenames_not_present)
+           self._sched_ifaces(already_up_ifacenames_not_present, downops)
+        else:
+           self.logger.debug('no interfaces to down ..')
+
+        # Now, run 'up' with new config dict
+        # reset statemanager update flag to default
+        if new_ifaceobjdict:
+            self.ifaceobjdict = new_ifaceobjdict
+            self.dependency_graph = new_dependency_graph
+
+        if not self.ifaceobjdict:
+           return
+        self.logger.info('reload: scheduling up on interfaces: %s'
+                         %str(interfaces_to_up))
+        self._sched_ifaces(interfaces_to_up, upops)
+        if self.DRYRUN:
+            return
+        self._save_state()
+
+    def _reload_default(self, upops, downops, auto=False, allow=None,
+            ifacenames=None, excludepats=None, usecurrentconfig=False,
+            **extra_args):
+        """ reload interface config """
+        allow_classes = []
+        new_ifaceobjdict = {}
 
         try:
             self.read_iface_config()
@@ -975,7 +1062,8 @@ class ifupdownMain(ifupdownBase):
             #     config
             #
             ifacedownlist = []
-            for ifname, lastifaceobjlist in self.ifaceobjdict.items():
+            for ifname in filtered_ifacenames:
+                lastifaceobjlist = self.ifaceobjdict.get(ifname)
                 objidx = 0
                 # If interface is not present in the new file
                 # append it to the down list
@@ -997,7 +1085,7 @@ class ifupdownMain(ifupdownBase):
                         continue
 
             if ifacedownlist:
-                self.logger.info('Executing down on interfaces: %s'
+                self.logger.info('reload: scheduling down on interfaces: %s'
                                   %str(ifacedownlist))
                 # reinitialize dependency graph 
                 self.dependency_graph = OrderedDict({})
@@ -1018,13 +1106,25 @@ class ifupdownMain(ifupdownBase):
                                if self._iface_whitelisted(auto, allow_classes,
                                excludepats, i)]
 
-        self.logger.info('Scheduling up on interfaces: %s'
-                                  %str(filtered_ifacenames))
+        self.logger.info('reload: scheduling up on interfaces: %s'
+                         %str(filtered_ifacenames))
         self._sched_ifaces(filtered_ifacenames, upops)
         if self.DRYRUN:
             return
         self._save_state()
 
+    def reload(self, *args, **kargs):
+        """ reload interface config """
+        if kargs.get('auto', False):
+            self.ALL = True
+            self.WITH_DEPENDS = True
+
+        self.logger.debug('reloading interface config ..')
+        if kargs.get('currentlyup', False):
+            self._reload_currentlyup(*args, **kargs)
+        else:
+            self._reload_default(*args, **kargs)
+
     def _pretty_print_ordered_dict(self, prefix, argdict):
         outbuf = prefix + ' {\n'
         for k, vlist in argdict.items():
@@ -1085,7 +1185,14 @@ class ifupdownMain(ifupdownBase):
             print json.dumps(ifaceobjs, cls=ifaceJsonEncoder,
                              indent=4, separators=(',', ': '))
         else:
-            map(lambda i: i.dump_pretty(), ifaceobjs)
+            expand = int(self.config.get('ifquery_ifacename_expand_range', '0'))
+            for i in ifaceobjs:
+                if not expand and (i.flags & iface.IFACERANGE_ENTRY):
+                    # print only the first one
+                    if i.flags & iface.IFACERANGE_START:
+                       i.dump_pretty(use_realname=True)
+                else:
+                    i.dump_pretty()
 
     def _get_ifaceobjscurr_pretty(self, ifacenames, ifaceobjs):
         ret = 0
@@ -1122,9 +1229,9 @@ class ifupdownMain(ifupdownBase):
                        separators=(',', ': '))
         else:
             map(lambda i: i.dump_pretty(with_status=True,
-                    successstr=self.config.get('check_success_str',
+                    successstr=self.config.get('ifquery_check_success_str',
                                                _success_sym),
-                    errorstr=self.config.get('check_error_str', _error_sym)),
+                    errorstr=self.config.get('ifquery_check_error_str', _error_sym)),
                                 ifaceobjs)
         return ret
 
index 5ba14b3b2af87879b111df565625dd573b3c8451..561654df4c11d49d8c1508845f400652fa040114 100644 (file)
@@ -266,8 +266,11 @@ class networkInterfaces():
         if range_val:
            for v in range(range_val[1], range_val[2]):
                 ifaceobj_new = copy.deepcopy(ifaceobj)
-                ifaceobj_new.real_name = ifaceobj.name
+                ifaceobj_new.realname = ifaceobj.name
                 ifaceobj_new.name = "%s%d" %(range_val[0], v)
+                ifaceobj_new.flags |= iface.IFACERANGE_ENTRY
+                if v == range_val[1]:
+                    ifaceobj_new.flags |= iface.IFACERANGE_START
                 self.callbacks.get('iface_found')(ifaceobj_new)
         else:
             self.callbacks.get('iface_found')(ifaceobj)
@@ -282,9 +285,12 @@ class networkInterfaces():
         if range_val:
            for v in range(range_val[1], range_val[2]):
                 ifaceobj_new = copy.deepcopy(ifaceobj)
-                ifaceobj_new.real_name = ifaceobj.name
+                ifaceobj_new.realname = ifaceobj.name
                 ifaceobj_new.name = "%s%d" %(range_val[0], v)
                 ifaceobj_new.type = ifaceType.BRIDGE_VLAN
+                ifaceobj_new.flags |= iface.IFACERANGE_ENTRY
+                if v == range_val[1]:
+                    ifaceobj_new.flags |= iface.IFACERANGE_START
                 self.callbacks.get('iface_found')(ifaceobj_new)
         else:
             ifaceobj.type = ifaceType.BRIDGE_VLAN
index fc01022e0530b35cfa991bfcfe78f2acf830e9b8..5c13d4ab840dbad9dec33127f962e17c4e0023e5 100644 (file)
@@ -43,6 +43,9 @@ class ifaceScheduler():
         """ Runs sub operation on an interface """
         ifacename = ifaceobj.name
 
+        if ifupdownobj.type and ifupdownobj.type != ifaceobj.Type:
+            return
+
         if (cls._STATE_CHECK and
             (ifaceobj.state >= ifaceState.from_str(op))):
             ifupdownobj.logger.debug('%s: already in state %s' %(ifacename, op))
@@ -151,27 +154,6 @@ class ifaceScheduler():
                 not ifupdownobj.ALL)):
             return True
 
-        if ifaceobj.type == ifaceType.BRIDGE:
-            #
-            # XXX: This function's job is to return True for
-            # logical devices when any of the upperifaces are still around.
-            # In the new model, where bridge is represented as a dependency
-            # for a bridge port, bridge becomes a lowerdevice of a bridge port,
-            # which is not really true. To handle this case, add a special
-            # check for bridge device. Will figure out a better way to handle
-            # this.
-            # Long term this function should be replaced by
-            # walking the sysfs links to upper and lower device available in
-            # latest kernels.
-            try:
-                if os.listdir('/sys/class/net/%s/brif' %ifaceobj.name):
-                    return False
-                else:
-                    return True
-            except Exception:
-                pass
-                return True
-
         ulist = ifaceobj.upperifaces
         if not ulist:
             return True
index 8f8d8749043393881e80c8b25ae9e35efcf113ed..7d42cd2facacf080b285208fd204353a874d11fb 100644 (file)
@@ -320,3 +320,13 @@ class moduleBase(object):
         return dict(force=self.FORCE, dryrun=self.DRYRUN, nowait=self.NOWAIT,
                     perfmode=self.PERFMODE, cache=self.CACHE,
                     cacheflags=self.CACHE_FLAGS)
+
+    def _get_reserved_vlan_range(self):
+        start = end = 0
+        get_resvvlan = '/usr/share/python-ifupdown2/get_reserved_vlan_range.sh'
+        try:
+            (start, end) = self.exec_command(get_resvvlan).split('-')
+        except:
+            # ignore errors
+            pass
+        return (start, end)
index 4b8ffca3e12d0869be66f72e6accee504e43b633..b8f211f616eae4ded62a38146cbe4f40b0050ea3 100755 (executable)
@@ -51,13 +51,13 @@ def run_up(args):
             ifupdown_handle.up(['up'], args.all, args.CLASS, iflist,
                                excludepats=args.excludepats,
                                printdependency=args.printdependency,
-                               syntaxcheck=args.syntaxcheck)
+                               syntaxcheck=args.syntaxcheck, type=args.type)
         else:
             ifupdown_handle.up(['pre-up', 'up', 'post-up'],
                                args.all, args.CLASS, iflist,
                                excludepats=args.excludepats,
                                printdependency=args.printdependency,
-                               syntaxcheck=args.syntaxcheck)
+                               syntaxcheck=args.syntaxcheck, type=args.type)
     except:
         raise
 
@@ -81,7 +81,8 @@ def run_down(args):
                              args.all, args.CLASS, iflist,
                              excludepats=args.excludepats,
                              printdependency=args.printdependency,
-                             usecurrentconfig=args.usecurrentconfig)
+                             usecurrentconfig=args.usecurrentconfig,
+                             type=args.type)
     except:
         raise
 
@@ -123,7 +124,7 @@ def run_query(args):
         ifupdown_handle.query([qop], args.all, args.CLASS, iflist,
                               excludepats=args.excludepats,
                               printdependency=args.printdependency,
-                              format=args.format)
+                              format=args.format, type=args.type)
     except:
         raise
 
@@ -139,7 +140,8 @@ def run_reload(args):
                                ['pre-down', 'down', 'post-down'],
                                args.all, None, None,
                                excludepats=args.excludepats,
-                               usecurrentconfig=args.usecurrentconfig)
+                               usecurrentconfig=args.usecurrentconfig,
+                               currentlyup=args.currentlyup)
     except:
         raise
 
@@ -226,6 +228,13 @@ def update_argparser(argparser):
                 default='native',
                 choices=['native', 'json'],
                 help='interfaces file format')
+    argparser.add_argument('-T', '--type',
+                dest='type',
+                default=None,
+                choices=['iface', 'vlan'],
+                help='type of interface entry (iface or vlan).' +
+                     'This option can be used in case of ambiguity between ' +
+                     'a vlan interface and an iface interface of the same name')
 
 def update_ifupdown_argparser(argparser):
     """ common arg parser for ifup and ifdown """
@@ -294,8 +303,13 @@ def update_ifquery_argparser(argparser):
 
 def update_ifreload_argparser(argparser):
     """ parser for ifreload """
-    argparser.add_argument('-a', '--all', action='store_true', required=True,
+    group = argparser.add_mutually_exclusive_group(required=True)
+    group.add_argument('-a', '--all', action='store_true',
                 help='process all interfaces marked \"auto\"')
+    group.add_argument('-c', '--currently-up', dest='currentlyup',
+                action='store_true',
+                help='only reload auto and other interfaces that are ' +
+                'currently up')
     argparser.add_argument('iflist', metavar='IFACE',
                 nargs='*', help=argparse.SUPPRESS)
     argparser.add_argument('-n', '--no-act', dest='noact',
@@ -367,8 +381,8 @@ def validate_args(op, args):
     if op == 'query' and args.syntaxhelp:
         return True
     if op == 'reload':
-        if not args.all:
-            print '\'-a\' option is required'
+        if not args.all and not args.currentlyup:
+            print '\'-a\' or \'-c\' option is required'
             return False
     elif (not args.iflist and
             not args.all and not args.CLASS):