1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

minor fixes for ifquery and stp handling

Ticket: CM-3346
Reviewed By:
Testing Done: Tested ifupdown2 sanity
This commit is contained in:
Roopa Prabhu
2014-11-15 15:42:52 -08:00
parent 97382e8841
commit d8e3554dde
3 changed files with 119 additions and 28 deletions

View File

@@ -9,6 +9,7 @@ from ifupdown.iface import *
from ifupdownaddons.modulebase import moduleBase from ifupdownaddons.modulebase import moduleBase
from ifupdownaddons.bridgeutils import brctl from ifupdownaddons.bridgeutils import brctl
from ifupdownaddons.iproute2 import iproute2 from ifupdownaddons.iproute2 import iproute2
from collections import Counter
import ifupdown.rtnetlink_api as rtnetlink_api import ifupdown.rtnetlink_api as rtnetlink_api
import itertools import itertools
import re import re
@@ -493,6 +494,12 @@ class bridge(moduleBase):
stp = ifaceobj.get_attr_value_first('bridge-stp') stp = ifaceobj.get_attr_value_first('bridge-stp')
if stp: if stp:
self.brctlcmd.set_stp(ifaceobj.name, stp) self.brctlcmd.set_stp(ifaceobj.name, stp)
else:
# If stp not specified and running stp state on, set it to off
running_stp_state = self.read_file_oneline(
'/sys/class/net/%s/bridge/stp_state' %ifaceobj.name)
if running_stp_state and running_stp_state != '0':
self.brctlcmd.set_stp(ifaceobj.name, 'no')
# Use the brctlcmd bulk set method: first build a dictionary # Use the brctlcmd bulk set method: first build a dictionary
# and then call set # and then call set
bridgeattrs = { k:v for k,v in bridgeattrs = { k:v for k,v in
@@ -703,7 +710,7 @@ class bridge(moduleBase):
bridge_pvid = ifaceobj.get_attr_value_first('bridge-pvid') bridge_pvid = ifaceobj.get_attr_value_first('bridge-pvid')
if bridge_pvid: if bridge_pvid:
bridge_pvid = re.split(r'[\s\t]\s*', bridge_pvid) bridge_pvid = re.split(r'[\s\t]\s*', bridge_pvid)[0]
else: else:
bridge_pvid = None bridge_pvid = None
@@ -825,13 +832,66 @@ class bridge(moduleBase):
running_attrs['bridge-vids'] = ','.join(running_bridge_vids) running_attrs['bridge-vids'] = ','.join(running_bridge_vids)
return running_attrs return running_attrs
def _query_running_vidinfo(self, ifaceobjrunning): def _query_running_vidinfo(self, ifaceobjrunning, ifaceobj_getfunc,
bridgeports=None):
running_attrs = {} running_attrs = {}
running_vidinfo = self._get_running_vidinfo() running_vidinfo = self._get_running_vidinfo()
running_bridge_vids = running_vidinfo.get(ifaceobjrunning.name, if not running_vidinfo:
{}).get('vlan') return running_attrs
if running_bridge_vids:
running_attrs['bridge-vids'] = ','.join(running_bridge_vids) # 'bridge-vids' under the bridge is all about 'vids' on the port.
# so query the ports
running_bridgeport_vids = []
running_bridgeport_pvids = []
for bport in bridgeports:
vids = running_vidinfo.get(bport, {}).get('vlan')
if vids:
running_bridgeport_vids.append(' '.join(vids))
pvids = running_vidinfo.get(bport, {}).get('pvid')
if pvids:
running_bridgeport_pvids.append(pvids[0])
bridge_vids = None
if running_bridgeport_vids:
(vidval, freq) = Counter(running_bridgeport_vids).most_common()[0]
if freq == len(bridgeports):
running_attrs['bridge-vids'] = vidval
bridge_vids = vidval.split()
bridge_pvid = None
if running_bridgeport_pvids:
(vidval, freq) = Counter(running_bridgeport_pvids).most_common()[0]
if freq == len(bridgeports) and vidval != '1':
running_attrs['bridge-pvid'] = vidval
bridge_pvid = vidval.split()
# Go through all bridge ports and find their vids
for bport in bridgeports:
bportifaceobj = ifaceobj_getfunc(bport)
if not bportifaceobj:
continue
bport_vids = None
bport_pvids = None
vids = running_vidinfo.get(bport, {}).get('vlan')
if vids and vids != bridge_vids:
bport_vids = vids
pvids = running_vidinfo.get(bport, {}).get('pvid')
if pvids and pvids[0] != bridge_pvid:
bport_pvids = pvids
if not bport_vids and bport_pvids and bport_pvids[0] != '1':
bportifaceobj[0].replace_config('bridge-access', bport_pvids[0])
else:
if bport_pvids and bport_pvids[0] != '1':
bportifaceobj[0].replace_config('bridge-pvid', bport_pvids[0])
else:
# delete any stale bridge-vids under ports
bportifaceobj[0].delete_config('bridge-pvid')
if bport_vids:
bportifaceobj[0].replace_config('bridge-vids',
' '.join(bport_vids))
else:
# delete any stale bridge-vids under ports
bportifaceobj[0].delete_config('bridge-vids')
return running_attrs return running_attrs
def _query_running_mcqv4src(self, ifaceobjrunning): def _query_running_mcqv4src(self, ifaceobjrunning):
@@ -841,7 +901,8 @@ class bridge(moduleBase):
mcq = ' '.join(mcqs) mcq = ' '.join(mcqs)
return mcq return mcq
def _query_running_attrs(self, ifaceobjrunning, bridge_vlan_aware=False): def _query_running_attrs(self, ifaceobjrunning, ifaceobj_getfunc,
bridge_vlan_aware=False):
bridgeattrdict = {} bridgeattrdict = {}
userspace_stp = 0 userspace_stp = 0
ports = None ports = None
@@ -882,7 +943,9 @@ class bridge(moduleBase):
bridgeattrdict[attrname] = [v] bridgeattrdict[attrname] = [v]
if bridge_vlan_aware: if bridge_vlan_aware:
bridgevidinfo = self._query_running_vidinfo(ifaceobjrunning) bridgevidinfo = self._query_running_vidinfo(ifaceobjrunning,
ifaceobj_getfunc,
ports.keys())
else: else:
bridgevidinfo = self._query_running_vidinfo_compat(ifaceobjrunning, bridgevidinfo = self._query_running_vidinfo_compat(ifaceobjrunning,
ports) ports)
@@ -1237,15 +1300,16 @@ class bridge(moduleBase):
self._query_check_bridge_port(ifaceobj, ifaceobjcurr, self._query_check_bridge_port(ifaceobj, ifaceobjcurr,
ifaceobj_getfunc) ifaceobj_getfunc)
def _query_running_bridge(self, ifaceobjrunning): def _query_running_bridge(self, ifaceobjrunning, ifaceobj_getfunc):
if self.ipcmd.bridge_is_vlan_aware(ifaceobjrunning.name): if self.ipcmd.bridge_is_vlan_aware(ifaceobjrunning.name):
ifaceobjrunning.update_config('bridge-vlan-aware', 'yes') ifaceobjrunning.update_config('bridge-vlan-aware', 'yes')
ifaceobjrunning.update_config_dict(self._query_running_attrs( ifaceobjrunning.update_config_dict(self._query_running_attrs(
ifaceobjrunning, ifaceobjrunning,
ifaceobj_getfunc,
bridge_vlan_aware=True)) bridge_vlan_aware=True))
else: else:
ifaceobjrunning.update_config_dict(self._query_running_attrs( ifaceobjrunning.update_config_dict(self._query_running_attrs(
ifaceobjrunning)) ifaceobjrunning, None))
def _query_running_bridge_port_attrs(self, ifaceobjrunning, bridgename): def _query_running_bridge_port_attrs(self, ifaceobjrunning, bridgename):
if self.sysctl_get('net.bridge.bridge-stp-user-space') == '1': if self.sysctl_get('net.bridge.bridge-stp-user-space') == '1':
@@ -1263,6 +1327,8 @@ class bridge(moduleBase):
ifaceobj_getfunc=None): ifaceobj_getfunc=None):
bridgename = self.ipcmd.bridge_port_get_bridge_name( bridgename = self.ipcmd.bridge_port_get_bridge_name(
ifaceobjrunning.name) ifaceobjrunning.name)
bridge_vids = None
bridge_pvid = None
if not bridgename: if not bridgename:
self.logger.warn('%s: unable to find bridgename' self.logger.warn('%s: unable to find bridgename'
%ifaceobjrunning.name) %ifaceobjrunning.name)
@@ -1271,36 +1337,37 @@ class bridge(moduleBase):
return return
running_vidinfo = self._get_running_vidinfo() running_vidinfo = self._get_running_vidinfo()
# Check vidinfo
bridge_vids = running_vidinfo.get(bridgename, {}).get('vlan')
bridge_port_vids = running_vidinfo.get(ifaceobjrunning.name, bridge_port_vids = running_vidinfo.get(ifaceobjrunning.name,
{}).get('vlan') {}).get('vlan')
bridge_port_pvid = running_vidinfo.get(ifaceobjrunning.name, bridge_port_pvid = running_vidinfo.get(ifaceobjrunning.name,
{}).get('pvid') {}).get('pvid')
bridgeifaceobjlist = ifaceobj_getfunc(bridgename)
if bridgeifaceobjlist:
bridge_vids = bridgeifaceobjlist[0].get_attr_value('bridge-vids')
bridge_pvid = bridgeifaceobjlist[0].get_attr_value_first('bridge-pvid')
if not bridge_port_vids and bridge_port_pvid: if not bridge_port_vids and bridge_port_pvid:
# must be an access port # must be an access port
ifaceobjrunning.update_config('bridge-access', if bridge_port_pvid != '1':
ifaceobjrunning.update_config('bridge-access',
bridge_port_pvid) bridge_port_pvid)
else: else:
if bridge_port_vids: if bridge_port_vids:
if bridge_vids and bridge_port_vids != bridge_vids: if (not bridge_vids or bridge_port_vids != bridge_vids):
ifaceobjrunning.update_config('bridge-vids', ifaceobjrunning.update_config('bridge-vids',
' '.join(bridge_port_vids)) ' '.join(bridge_port_vids))
if bridge_port_pvid and bridge_port_pvid != '1': if bridge_port_pvid and bridge_port_pvid != '1':
ifaceobjrunning.update_config('bridge-pvid', if (not bridge_pvid or (bridge_port_pvid != bridge_pvid)):
ifaceobjrunning.update_config('bridge-pvid',
bridge_port_pvid) bridge_port_pvid)
self._query_running_bridge_port_attrs(ifaceobjrunning, bridgename) self._query_running_bridge_port_attrs(ifaceobjrunning, bridgename)
def _query_running(self, ifaceobjrunning, ifaceobj_getfunc=None):
def _query_running(self, ifaceobjrunning, **extra_args):
if self.brctlcmd.bridge_exists(ifaceobjrunning.name): if self.brctlcmd.bridge_exists(ifaceobjrunning.name):
self._query_running_bridge(ifaceobjrunning) self._query_running_bridge(ifaceobjrunning, ifaceobj_getfunc)
elif self.brctlcmd.is_bridge_port(ifaceobjrunning.name): elif self.brctlcmd.is_bridge_port(ifaceobjrunning.name):
self._query_running_bridge_port(ifaceobjrunning) self._query_running_bridge_port(ifaceobjrunning, ifaceobj_getfunc)
_run_ops = {'pre-up' : _up, _run_ops = {'pre-up' : _up,
'post-down' : _down, 'post-down' : _down,

View File

@@ -138,6 +138,7 @@ class mstpctl(moduleBase):
_port_attrs_map = {'mstpctl-portpathcost' : 'portpathcost', _port_attrs_map = {'mstpctl-portpathcost' : 'portpathcost',
'mstpctl-portadminedge' : 'portadminedge', 'mstpctl-portadminedge' : 'portadminedge',
'mstpctl-portautoedge' : 'portautoedge' ,
'mstpctl-portp2p' : 'portp2p', 'mstpctl-portp2p' : 'portp2p',
'mstpctl-portrestrrole' : 'portrestrrole', 'mstpctl-portrestrrole' : 'portrestrrole',
'mstpctl-portrestrtcn' : 'portrestrtcn', 'mstpctl-portrestrtcn' : 'portrestrtcn',
@@ -298,7 +299,8 @@ class mstpctl(moduleBase):
pass pass
def _apply_bridge_port_settings(self, ifaceobj, bridgename=None, def _apply_bridge_port_settings(self, ifaceobj, bridgename=None,
bridgeifaceobj=None): bridgeifaceobj=None, stp_on=True,
mstpd_running=True):
check = False if self.PERFMODE else True check = False if self.PERFMODE else True
if not bridgename and bridgeifaceobj: if not bridgename and bridgeifaceobj:
bridgename = bridgeifaceobj.name bridgename = bridgeifaceobj.name
@@ -315,6 +317,12 @@ class mstpctl(moduleBase):
# continue # continue
#else: #else:
continue continue
if not stp_on:
self.logger.warn('%s: cannot set %s (stp on bridge %s not on)\n'
%(ifaceobj.name, attrname, bridgename))
continue
if not mstpd_running:
continue
try: try:
self.mstpctlcmd.set_bridgeport_attr(bridgename, self.mstpctlcmd.set_bridgeport_attr(bridgename,
ifaceobj.name, dstattrname, attrval, check) ifaceobj.name, dstattrname, attrval, check)
@@ -348,9 +356,14 @@ class mstpctl(moduleBase):
# Check if bridge port # Check if bridge port
bridgename = self.ipcmd.bridge_port_get_bridge_name(ifaceobj.name) bridgename = self.ipcmd.bridge_port_get_bridge_name(ifaceobj.name)
if bridgename: if bridgename:
if self.mstpctlcmd.is_mstpd_running(): mstpd_running = (True if self.mstpctlcmd.is_mstpd_running()
self._apply_bridge_port_settings(ifaceobj, bridgename) else False)
ifaceobj.priv_flags |= self._BRIDGE_PORT_PROCESSED stp_on = (True if self.read_file_oneline(
'/sys/class/net/%s/bridge/stp_state'
%bridgename) == '2' else False)
self._apply_bridge_port_settings(ifaceobj, bridgename, None,
stp_on, mstpd_running)
ifaceobj.priv_flags |= self._BRIDGE_PORT_PROCESSED
return return
if not self._is_bridge(ifaceobj): if not self._is_bridge(ifaceobj):
return return

View File

@@ -324,6 +324,17 @@ class iface():
""" add attribute name and value to the interface config """ """ add attribute name and value to the interface config """
self.config.setdefault(attr_name, []).append(attr_value) self.config.setdefault(attr_name, []).append(attr_value)
def replace_config(self, attr_name, attr_value):
""" add attribute name and value to the interface config """
self.config[attr_name] = [attr_value]
def delete_config(self, attr_name):
""" add attribute name and value to the interface config """
try:
del self.config[attr_name]
except:
pass
def update_config_dict(self, attrdict): def update_config_dict(self, attrdict):
self.config.update(attrdict) self.config.update(attrdict)