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

Bug fixes and some query support

Ticket: CM-3346
Reviewed By:
Testing Done: sanity testing and syntax testing for new bridge driver
This commit is contained in:
Roopa Prabhu
2014-10-28 16:10:00 -07:00
parent 1d591e73b5
commit e160136944
11 changed files with 563 additions and 214 deletions

View File

@@ -33,9 +33,24 @@ class addressvirtual(moduleBase):
return True
return False
def _apply_address_config(self, ifaceobj, realifacename, address_virtual_list):
def _add_addresses_to_bridge(self, ifaceobj, hwaddress):
if '.' in ifaceobj.name:
(bridgename, vlan) = ifaceobj.name.split('.')
if self.ipcmd.bridge_is_vlan_aware(bridgename):
[self.ipcmd.bridge_fdb_add(bridgename, addr,
vlan) for addr in hwaddress]
def _remove_addresses_from_bridge(self, ifaceobj, hwaddress):
if '.' in ifaceobj.name:
(bridgename, vlan) = ifaceobj.name.split('.')
if self.ipcmd.bridge_is_vlan_aware(bridgename):
[self.ipcmd.bridge_fdb_del(bridgename, addr,
vlan) for addr in hwaddress]
def _apply_address_config(self, ifaceobj, address_virtual_list):
purge_existing = False if self.PERFMODE else True
hwaddress = []
self.ipcmd.batch_start()
av_idx = 0
macvlan_prefix = '%s-virt' %ifaceobj.name.replace('.', '-')
@@ -52,50 +67,82 @@ class addressvirtual(moduleBase):
macvlan_ifacename = '%s-%d' %(macvlan_prefix, av_idx)
if not self.ipcmd.link_exists(macvlan_ifacename):
rtnetlink_api.rtnl_api.create_macvlan(macvlan_ifacename,
realifacename)
ifaceobj.name)
if av_attrs[0] != 'None':
self.ipcmd.link_set_hwaddress(macvlan_ifacename, av_attrs[0])
hwaddress.append(av_attrs[0])
self.ipcmd.addr_add_multiple(macvlan_ifacename, av_attrs[1:],
purge_existing)
av_idx += 1
self.ipcmd.batch_commit()
def _remove_address_config(self, ifaceobj, ifacename):
if not self.ipcmd.link_exists(ifacename):
return
self.ipcmd.batch_start()
macvlan_prefix = '%s-virt' %ifacename.replace('.', '-')
for macvlan_ifacename in glob.glob("/sys/class/net/%s-*" %macvlan_prefix):
self.ipcmd.link_delete(os.path.basename(macvlan_ifacename))
self.ipcmd.batch_commit()
# if ifaceobj is a bridge and bridge is a vlan aware bridge
# add the vid to the bridge
self._add_addresses_to_bridge(ifaceobj, hwaddress)
def _get_real_ifacename(self, ifaceobj):
realifacename = ifaceobj.name
if ifaceobj.type == ifaceType.BRIDGE_VLAN:
bridgename = ifaceobj.get_attr_value_first('bridge')
if bridgename:
realifacename = '%s.%s' %(bridgename, ifaceobj.priv_data)
return realifacename
def _remove_running_address_config(self, ifaceobj):
if not self.ipcmd.link_exists(ifaceobj.name):
return
hwaddress = []
self.ipcmd.batch_start()
macvlan_prefix = '%s-virt' %ifaceobj.name.replace('.', '-')
for macvlan_ifacename in glob.glob("/sys/class/net/%s-*" %macvlan_prefix):
macvlan_ifacename = os.path.basename(macvlan_ifacename)
if not self.ipcmd.link_exists(macvlan_ifacename):
continue
hwaddress.append(self.ipcmd.link_get_hwaddress(macvlan_ifacename))
self.ipcmd.link_delete(os.path.basename(macvlan_ifacename))
# XXX: Also delete any fdb addresses. This requires, checking mac address
# on individual macvlan interfaces and deleting the vlan from that.
self.ipcmd.batch_commit()
if any(hwaddress):
self._remove_addresses_from_bridge(ifaceobj, hwaddress)
def _remove_address_config(self, ifaceobj, address_virtual_list=None):
if not address_virtual_list:
self._remove_running_address_config(ifaceobj)
return
if not self.ipcmd.link_exists(ifaceobj.name):
return
hwaddress = []
self.ipcmd.batch_start()
av_idx = 0
macvlan_prefix = '%s-virt' %ifaceobj.name.replace('.', '-')
for av in address_virtual_list:
av_attrs = av.split()
if len(av_attrs) < 2:
self.logger.warn("%s: incorrect address-virtual attrs '%s'"
%(ifaceobj.name, av))
av_idx += 1
continue
# Delete the macvlan device on this device
macvlan_ifacename = '%s-%d' %(macvlan_prefix, av_idx)
self.ipcmd.link_delete(os.path.basename(macvlan_ifacename))
if av_attrs[0] != 'None':
hwaddress.append(av_attrs[0])
av_idx += 1
self.ipcmd.batch_commit()
self._remove_addresses_from_bridge(ifaceobj, hwaddress)
def _up(self, ifaceobj):
realifacename = self._get_real_ifacename(ifaceobj)
address_virtual_list = ifaceobj.get_attr_value('address-virtual')
if not address_virtual_list:
# XXX: address virtual is not present. In which case,
# delete stale any macvlan devices.
self._remove_address_config(ifaceobj, realifacename)
self._remove_address_config(ifaceobj, address_virtual_list)
return
if not self.ipcmd.link_exists(realifacename):
self.log_warn('%s: target link %s does not exist'
%(ifaceobj.name, realifacename))
if not self.ipcmd.link_exists(ifaceobj.name):
#self.log_warn('%s: interface does not exist'
# %ifaceobj.name)
return
self._apply_address_config(ifaceobj, realifacename, address_virtual_list)
self._apply_address_config(ifaceobj, address_virtual_list)
def _down(self, ifaceobj):
realifacename = self._get_real_ifacename(ifaceobj)
try:
self._remove_address_config(ifaceobj, realifacename)
self._remove_address_config(ifaceobj, ifaceobj.get_attr_value('address-virtual'))
except Exception, e:
self.log_warn(str(e))
@@ -103,9 +150,8 @@ class addressvirtual(moduleBase):
address_virtual_list = ifaceobj.get_attr_value('address-virtual')
if not address_virtual_list:
return
realifacename = self._get_real_ifacename(ifaceobj)
av_idx = 0
macvlan_prefix = '%s-virt' %realifacename.replace('.', '-')
macvlan_prefix = '%s-virt' %ifaceobj.name.replace('.', '-')
for address_virtual in address_virtual_list:
av_attrs = address_virtual.split()
if len(av_attrs) < 2:

View File

@@ -167,18 +167,6 @@ class bridge(moduleBase):
'bridge-port-pvids' :
{ 'help' : 'bridge port vlans',
'example' : ['bridge-port-pvids bond0=100 bond1=200']},
'bridge-pathcost' :
{ 'help' : 'bridge port path cost',
'example' : ['bridge-pathcost 10']},
'bridge-priority' :
{ 'help' : 'bridge port priority',
'example' : ['bridge-priority 10']},
'bridge-multicast-router' :
{ 'help' : 'bridge multicast router',
'example' : ['bridge-multicast-router 1']},
'bridge-multicast-fast-leave' :
{ 'help' : 'bridge multicast fast leave',
'example' : ['bridge-multicast-fast-leave 1']},
'bridge-igmp-querier-src' :
{ 'help' : 'bridge igmp querier src',
'example' : ['bridge-igmp-querier-src 172.16.101.1']},
@@ -455,23 +443,25 @@ class bridge(moduleBase):
%(ifaceobj.name, p, str(e)))
# install vids
attrval = ifaceobj.get_attr_value_first('bridge-vids')
if attrval:
vids = re.split(r'[\s\t]\s*', attrval)
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)
if vids_to_add:
self.ipcmd.bridge_vids_add(ifaceobj.name, vids_to_add)
else:
self.ipcmd.bridge_vids_add(ifaceobj.name, vids)
else:
running_vids = running_vidinfo.get(ifaceobj.name)
if running_vids:
self.ipcmd.bridge_vids_del(ifaceobj.name, running_vids)
# XXX: Commenting out this code for now because it was decided
# that this is not needed
#attrval = ifaceobj.get_attr_value_first('bridge-vids')
#if attrval:
# vids = re.split(r'[\s\t]\s*', attrval)
# 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)
# if vids_to_add:
# self.ipcmd.bridge_vids_add(ifaceobj.name, vids_to_add)
# else:
# self.ipcmd.bridge_vids_add(ifaceobj.name, vids)
#else:
# running_vids = running_vidinfo.get(ifaceobj.name)
# if running_vids:
# self.ipcmd.bridge_vids_del(ifaceobj.name, running_vids)
def _apply_bridge_settings(self, ifaceobj):
try:
@@ -588,6 +578,8 @@ class bridge(moduleBase):
self.ipcmd.bridge_port_pvid_del(bportifaceobj.name,
running_pvid)
self.ipcmd.bridge_port_pvid_add(bportifaceobj.name, pvid)
else:
self.ipcmd.bridge_port_pvid_add(bportifaceobj.name, pvid)
except Exception, e:
self.log_warn('%s: failed to set pvid `%s` (%s)'
%(bportifaceobj.name, pvid, str(e)))
@@ -635,13 +627,10 @@ class bridge(moduleBase):
# Set other stp and igmp attributes
portattrs = {}
for attrname, dstattrname in {
'bridge-pathcost' : 'pathcost',
'bridge-prio' : 'portprio',
'bridge-priority' : 'portprio',
'bridge-mcrouter' : 'portmcrouter',
'bridge-multicast-router' : 'portmcrouter',
'bridge-mcfl' : 'portmcfl',
'bridge-multicast-fast-leave' : 'portmcfl'}.items():
'bridge-pathcosts' : 'pathcost',
'bridge-portprios' : 'portprio',
'bridge-portmcrouter' : 'portmcrouter',
'bridge-portmcfl' : 'portmcfl'}.items():
attrval = bportifaceobj.get_attr_value_first(attrname)
if not attrval:
# Check if bridge has that attribute
@@ -685,6 +674,10 @@ class bridge(moduleBase):
for bport in bridgeports:
# Use the brctlcmd bulk set method: first build a dictionary
# and then call set
if not self.ipcmd.bridge_port_exists(ifaceobj.name, bport):
self.logger.info('%s: skipping bridge config' %ifaceobj.name +
' for port %s (missing port)' %bport)
continue
self.logger.info('%s: processing bridge config for port %s'
%(ifaceobj.name, bport))
bportifaceobjlist = ifaceobj_getfunc(bport)
@@ -701,17 +694,18 @@ class bridge(moduleBase):
def _up(self, ifaceobj, ifaceobj_getfunc=None):
# Check if bridge port
if self._is_bridge_port(ifaceobj):
bridgename = ifaceobj.upperifaces[0]
bridgename = self._get_bridge_name(ifaceobj)
if not bridgename:
self.logger.warn('%s: unable to determine bridge name'
%ifaceobj.name)
return
if self.ipcmd.bridge_is_vlan_aware(bridgename):
self._apply_bridge_vlan_aware_port_settings_all(
ifaceobj)
bridge_vids = self._get_bridge_vids(bridgename,
ifaceobj_getfunc)
self._apply_bridge_vlan_aware_port_settings_all(ifaceobj,
bridge_vids)
self._apply_bridge_port_settings(ifaceobj, bridgename=bridgename)
return
if not self._is_bridge(ifaceobj):
return
try:
@@ -753,7 +747,7 @@ class bridge(moduleBase):
except Exception, e:
self.log_error(str(e))
def _query_running_vidinfo(self, ifaceobjrunning, ports):
def _query_running_vidinfo_compat(self, ifaceobjrunning, ports):
running_attrs = {}
running_vidinfo = self._get_running_vidinfo()
if ports:
@@ -785,6 +779,15 @@ class bridge(moduleBase):
running_attrs['bridge-vids'] = ','.join(running_bridge_vids)
return running_attrs
def _query_running_vidinfo(self, ifaceobjrunning):
running_attrs = {}
running_vidinfo = self._get_running_vidinfo()
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()]
@@ -792,7 +795,7 @@ class bridge(moduleBase):
mcq = ' '.join(mcqs)
return mcq
def _query_running_attrs(self, ifaceobjrunning):
def _query_running_attrs(self, ifaceobjrunning, bridge_vlan_aware=False):
bridgeattrdict = {}
userspace_stp = 0
ports = None
@@ -832,7 +835,11 @@ class bridge(moduleBase):
if v != self.get_mod_subattr(attrname, 'default'):
bridgeattrdict[attrname] = [v]
bridgevidinfo = self._query_running_vidinfo(ifaceobjrunning, ports)
if bridge_vlan_aware:
bridgevidinfo = self._query_running_vidinfo(ifaceobjrunning)
else:
bridgevidinfo = self._query_running_vidinfo_compat(ifaceobjrunning,
ports)
if bridgevidinfo:
bridgeattrdict.update({k : [v] for k, v in bridgevidinfo.items()
if v})
@@ -873,10 +880,9 @@ class bridge(moduleBase):
ifaceobjcurr.update_config_with_status('bridge-mcqv4src',
running_mcqs, 1 if running_mcqs != mcqsout else 0)
def _query_check_vidinfo(self, ifaceobj, ifaceobjcurr):
def _query_check_bridge_vidinfo(self, ifaceobj, ifaceobjcurr):
err = 0
running_vidinfo = self.ipcmd.bridge_port_vids_get_all()
running_vidinfo = self._get_running_vidinfo()
attrval = ifaceobj.get_attr_value_first('bridge-port-vids')
if attrval:
running_bridge_port_vids = ''
@@ -910,7 +916,6 @@ class bridge(moduleBase):
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)
@@ -940,28 +945,35 @@ class bridge(moduleBase):
ifaceobjcurr.update_config_with_status('bridge-port-pvids',
running_bridge_port_pvids, 0)
# XXX: No need to check for bridge-vids on the bridge
# This is used by the ports. The vids on the bridge
# come from the vlan interfaces on the bridge.
#
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)
#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)
ifaceobjcurr.update_config_with_status('bridge-vids', attrval, -1)
def _query_check(self, ifaceobj, ifaceobjcurr, ifaceobj_getfunc=None):
def _query_check_bridge(self, ifaceobj, ifaceobjcurr,
ifaceobj_getfunc=None):
if not self._is_bridge(ifaceobj):
return
if not self.brctlcmd.bridge_exists(ifaceobj.name):
self.logger.info('%s: bridge: does not exist' %(ifaceobj.name))
ifaceobjcurr.status = ifaceStatus.NOTFOUND
return
ifaceattrs = self.dict_key_subset(ifaceobj.config,
self.get_mod_attrs())
if not ifaceattrs:
@@ -985,7 +997,14 @@ class bridge(moduleBase):
rv = runningattrs.get(k[7:])
if k == 'bridge-mcqv4src':
continue
if k == 'bridge-stp':
if k == 'bridge-vlan-aware' and v == 'yes':
if self.ipcmd.bridge_is_vlan_aware(ifaceobj.name):
ifaceobjcurr.update_config_with_status('bridge-vlan-aware',
v, 0)
else:
ifaceobjcurr.update_config_with_status('bridge-vlan-aware',
v, 1)
elif k == 'bridge-stp':
# special case stp compare because it may
# contain more than one valid values
stp_on_vals = ['on', 'yes']
@@ -1047,16 +1066,189 @@ class bridge(moduleBase):
else:
ifaceobjcurr.update_config_with_status(k, rv, 0)
self._query_check_vidinfo(ifaceobj, ifaceobjcurr)
self._query_check_bridge_vidinfo(ifaceobj, ifaceobjcurr)
self._query_check_mcqv4src(ifaceobj, ifaceobjcurr)
def _query_running(self, ifaceobjrunning, ifaceobj_getfunc=None):
if not self.brctlcmd.bridge_exists(ifaceobjrunning.name):
def _get_bridge_vids(self, bridgename, ifaceobj_getfunc):
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)
return None
def _get_bridge_name(self, ifaceobj):
return self.ipcmd.bridge_port_get_bridge_name(ifaceobj.name)
def _query_check_bridge_port_vidinfo(self, ifaceobj, ifaceobjcurr,
ifaceobj_getfunc, bridgename):
running_vidinfo = self._get_running_vidinfo()
attr_name = 'bridge-access'
vids = ifaceobj.get_attr_value_first(attr_name)
if vids:
running_pvids = running_vidinfo.get(ifaceobj.name,
{}).get('pvid')
running_vids = running_vidinfo.get(ifaceobj.name,
{}).get('vlan')
if (not running_pvids or running_pvids != vids or
running_vids):
ifaceobjcurr.update_config_with_status(attr_name,
running_pvids, 1)
else:
ifaceobjcurr.update_config_with_status(attr_name, vids, 0)
return
attr_name = 'bridge-vids'
vids = ifaceobj.get_attr_value_first(attr_name)
if vids:
vids = re.split(r'[\s\t]\s*', vids)
running_vids = running_vidinfo.get(ifaceobj.name,
{}).get('vlan')
if not running_vids or not self._compare_vids(vids, running_vids):
ifaceobjcurr.update_config_with_status(attr_name,
' '.join(running_vids), 1)
else:
ifaceobjcurr.update_config_with_status(attr_name,
' '.join(running_vids), 0)
else:
# check if it matches the bridge vids
bridge_vids = self._get_bridge_vids(bridgename, ifaceobj_getfunc)
running_vids = running_vidinfo.get(ifaceobj.name,
{}).get('vlan')
if (bridge_vids and (not running_vids or
not self._compare_vids(bridge_vids, running_vids))):
ifaceobjcurr.status = ifaceStatus.ERROR
ifaceobjcurr.status_str = 'bridge vid error'
running_pvid = running_vidinfo.get(ifaceobj.name,
{}).get('pvid')
attr_name = 'bridge-pvid'
pvid = ifaceobj.get_attr_value_first(attr_name)
if pvid:
if running_pvid and runing_pvid == pvid:
ifaceobjcurr.update_config_with_status(attr_name,
running_pvid, 0)
else:
ifaceobjcurr.update_config_with_status(attr_name,
running_pvid, 1)
elif not running_pvid or running_pvid != '1':
ifaceobjcurr.status = ifaceStatus.ERROR
ifaceobjcurr.status_str = 'bridge pvid error'
def _query_check_bridge_port(self, ifaceobj, ifaceobjcurr,
ifaceobj_getfunc):
if not self._is_bridge_port(ifaceobj):
# Mark all bridge attributes as failed
ifaceobj.check_n_update_config_with_status_many(
['bridge-vids', 'bridge-pvid', 'bridge-access',
'bridge-pathcosts', 'bridge-portprios',
'bridge-portmcrouter',
'bridge-portmcfl',
'bridge-igmp-querier-src'], 0)
return
bridgename = self._get_bridge_name(ifaceobj)
if not bridgename:
self.logger.warn('%s: unable to determine bridge name'
%ifaceobj.name)
return
if self.ipcmd.bridge_is_vlan_aware(bridgename):
self._query_check_bridge_port_vidinfo(ifaceobj, ifaceobjcurr,
ifaceobj_getfunc,
bridgename)
for attr, dstattr in {'bridge-pathcosts' : 'pathcost',
'bridge-portprios' : 'priority',
'bridge-portmcrouter' : 'mcrouter',
'bridge-portmcfl' : 'mcfl' }.items():
attrval = ifaceobj.get_attr_value_first(attr)
if not attrval:
continue
try:
running_attrval = self.brctlcmd.get_bridgeport_attr(
bridgename, ifaceobj.name, dstattr)
if running_attrval != attrval:
ifaceobjcurr.update_config_with_status(attr,
running_attrval, 1)
else:
ifaceobjcurr.update_config_with_status(attr,
running_attrval, 0)
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)
else:
self._query_check_bridge_port(ifaceobj, ifaceobjcurr,
ifaceobj_getfunc)
def _query_running_bridge(self, ifaceobjrunning):
if self.ipcmd.bridge_is_vlan_aware(ifaceobjrunning.name):
ifaceobjrunning.update_config('bridge-vlan-aware', 'yes')
ifaceobjrunning.update_config_dict(self._query_running_attrs(
ifaceobjrunning,
bridge_vlan_aware=True))
else:
ifaceobjrunning.update_config_dict(self._query_running_attrs(
ifaceobjrunning))
def _query_running_bridge_port_attrs(self, ifaceobjrunning, bridgename):
if self.sysctl_get('net.bridge.bridge-stp-user-space') == '1':
return
v = self.brctlcmd.get_pathcost(bridgename, ifaceobjrunning.name)
if v and v != self.get_mod_subattr('bridge-pathcosts', 'default'):
ifaceobjrunning.update_config('bridge-pathcosts', v)
v = self.brctlcmd.get_pathcost(bridgename, ifaceobjrunning.name)
if v and v != self.get_mod_subattr('bridge-portprios', 'default'):
ifaceobjrunning.update_config('bridge-portprios', v)
def _query_running_bridge_port(self, ifaceobjrunning,
ifaceobj_getfunc=None):
bridgename = self.ipcmd.bridge_port_get_bridge_name(
ifaceobjrunning.name)
if not bridgename:
self.logger.warn('%s: unable to find bridgename'
%ifaceobjrunning.name)
return
if not self.ipcmd.bridge_is_vlan_aware(bridgename):
return
running_vidinfo = self._get_running_vidinfo()
# Check vidinfo
bridge_vids = running_vidinfo.get(bridgename, {}).get('vlan')
bridge_port_vids = running_vidinfo.get(ifaceobjrunning.name,
{}).get('vlan')
bridge_port_pvid = running_vidinfo.get(ifaceobjrunning.name,
{}).get('pvid')
if not bridge_port_vids and bridge_port_pvid:
# must be an access port
ifaceobjrunning.update_config('bridge-access',
bridge_port_pvid)
else:
if bridge_port_vids:
if bridge_vids and bridge_port_vids != bridge_vids:
ifaceobjrunning.update_config('bridge-vids',
' '.join(bridge_port_vids))
if bridge_port_pvid and bridge_port_pvid != '1':
ifaceobjrunning.update_config('bridge-pvid',
bridge_port_pvid)
self._query_running_bridge_port_attrs(ifaceobjrunning, bridgename)
def _query_running(self, ifaceobjrunning, **extra_args):
if self.brctlcmd.bridge_exists(ifaceobjrunning.name):
self._query_running_bridge(ifaceobjrunning)
elif self.brctlcmd.is_bridge_port(ifaceobjrunning.name):
self._query_running_bridge_port(ifaceobjrunning)
_run_ops = {'pre-up' : _up,
'post-down' : _down,
'query-checkcurr' : _query_check,

View File

@@ -60,8 +60,8 @@ class bridgevlan(moduleBase):
raise
if not self.ipcmd.link_exists(bridgename):
self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
bridgename))
#self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
# bridgename))
return
running_mcqv4src = {}
@@ -93,8 +93,8 @@ class bridgevlan(moduleBase):
raise
if not self.ipcmd.link_exists(bridgename):
self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
bridgename))
#self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
# bridgename))
return
mcqv4src = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')

View File

@@ -48,7 +48,7 @@ class ifenslave(moduleBase):
'default' : 'balance-rr',
'example' : ['bond-mode 802.3ad']},
'bond-lacp-rate':
{'help' : 'bond use carrier',
{'help' : 'bond lacp rate',
'validvals' : ['0', '1'],
'default' : '0',
'example' : ['bond-lacp-rate 0']},
@@ -268,7 +268,8 @@ class ifenslave(moduleBase):
if not v:
continue
if k == 'bond-slaves':
slaves = v.split()
slaves = self._get_slave_list(ifaceobj)
#slaves = v.split()
continue
rv = runningattrs.get(k)
if not rv:

View File

@@ -131,77 +131,18 @@ class mstpctl(moduleBase):
'default' : 'no',
'required' : False,
'example' : ['mstpctl-portbpdufilter swp1=no swp2=no']},
'mstpctl-pathcost' :
{ 'help' : 'port path cost',
'default' : '0',
'required' : False,
'example' : ['mstpctl-pathcost 1']},
'mstpctl-p2p' :
{ 'help' : 'bridge port p2p detection mode',
'default' : 'no',
'validvals' : ['yes', 'no'],
'required' : False,
'example' : ['mstpctl-p2p yes']},
'mstpctl-restrrole' :
{ 'help' :
'enable/disable port ability to take root role of the port',
'default' : 'no',
'validvals' : ['yes', 'no'],
'required' : False,
'example' : ['mstpctl-restrrole yes']},
'mstpctl-restrtcn' :
{ 'help' :
'enable/disable port ability to propagate received topology change notification of the port',
'default' : 'no',
'validvals' : ['yes', 'no'],
'required' : False,
'example' : ['mstpctl-restrtcn yes']},
'mstpctl-treeprio' :
{ 'help' :
'port priority for MSTI instance',
'default' : '128',
'validrange' : ['0', '240'],
'required' : False,
'example' : ['mstpctl-treeprio 128']},
'mstpctl-network' :
{ 'help' : 'enable/disable bridge assurance capability for a port',
'validvals' : ['yes', 'no'],
'default' : 'no',
'required' : False,
'example' : ['mstpctl-network no']},
'mstpctl-adminedge' :
{ 'help' : 'enable/disable initial edge state of the port',
'validvals' : ['yes', 'no'],
'default' : 'no',
'required' : False,
'example' : ['mstpctl-adminedge no']},
'mstpctl-autoedge' :
{ 'help' : 'enable/disable auto transition to/from edge state of the port',
'validvals' : ['yes', 'no'],
'default' : 'no',
'required' : False,
'example' : ['mstpctl-autoedge yes']},
'mstpctl-treecost' :
{ 'help' : 'port tree cost',
'required' : False},
'mstpctl-bpdufilter' :
{ 'help' : 'enable/disable bpdu filter on a port',
'validvals' : ['yes', 'no'],
'default' : 'no',
'required' : False,
'example' : ['mstpctl-bpdufilter yes']},
}}
_port_attrs_map = {'mstpctl-pathcost' : 'portpathcost',
'mstpctl-adminedge' : 'portadminedge',
'mstpctl-p2p' : 'portp2p',
'mstpctl-restrrole' : 'portrestrrole',
'mstpctl-restrtcn' : 'portrestrtcn',
_port_attrs_map = {'mstpctl-portpathcost' : 'portpathcost',
'mstpctl-portadminedge' : 'portadminedge',
'mstpctl-portp2p' : 'portp2p',
'mstpctl-portrestrrole' : 'portrestrrole',
'mstpctl-portrestrtcn' : 'portrestrtcn',
'mstpctl-bpduguard' : 'bpduguard',
'mstpctl-treeprio' : 'treeportprio',
'mstpctl-treecost' : 'treeportcost',
'mstpctl-network' : 'portnetwork',
'mstpctl-bpdufilter' : 'portbpdufilter'}
'mstpctl-treeportprio' : 'treeportprio',
'mstpctl-treeportcost' : 'treeportcost',
'mstpctl-portnetwork' : 'portnetwork',
'mstpctl-portbpdufilter' : 'portbpdufilter'}
def __init__(self, *args, **kargs):
moduleBase.__init__(self, *args, **kargs)
@@ -636,14 +577,20 @@ class mstpctl(moduleBase):
ifaceobjcurr.update_config_with_status(k, rv, 0)
def _query_check_bridge_port(self, ifaceobj, ifaceobjcurr):
bridge = ifaceobj.upperifaces[0]
# list of attributes that are not supported currently
blacklistedattrs = ['mstpctl-pathcost',
'mstpctl-treeprio', 'mstpctl-treecost']
if not self.ipcmd.link_exists():
self.logger.debug('bridge port %s does not exist' %ifaceobj.name)
ifaceobjcurr.status = ifaceStatus.NOTFOUND
return
# Check if this is a bridge port
if not self._is_bridge_port(ifaceobj.name):
# mark all the bridge attributes as error
ifaceobj.check_n_update_config_with_status_many(
self._port_attrs_map.keys(), 0)
return
bridgename = self._get_bridge_name(ifaceobj)
# list of attributes that are not supported currently
blacklistedattrs = ['mstpctl-pathcost',
'mstpctl-treeprio', 'mstpctl-treecost']
ifaceattrs = self.dict_key_subset(ifaceobj.config,
self._port_attrs_map.keys())
if not ifaceattrs:
@@ -653,14 +600,14 @@ class mstpctl(moduleBase):
runningattrs = {}
for k in ifaceattrs:
# for all mstpctl options
if k in blacklistedattrs:
continue
# get the corresponding ifaceobj attr
v = ifaceobj.get_attr_value_first(k)
if not v:
ifaceobjcurr.update_config_with_status(k, v, -1)
continue
currv = self.mstpctlcmd.get_bridgeport_attr(bridge,
if k in blacklistedattrs:
continue
currv = self.mstpctlcmd.get_bridgeport_attr(bridgename,
ifaceobj.name, self._port_attrs_map.get(k))
if currv:
if currv != v:
@@ -671,15 +618,75 @@ class mstpctl(moduleBase):
ifaceobjcurr.update_config_with_status(k, None, 1)
def _query_check(self, ifaceobj, ifaceobjcurr, ifaceobj_getfunc=None):
# Check if bridge port
if self._is_bridge_port(ifaceobj):
self._query_check_bridge_port(ifaceobj, ifaceobjcurr)
elif self._is_bridge(ifaceobj):
if self._is_bridge(ifaceobj):
self._query_check_bridge(ifaceobj, ifaceobjcurr)
else:
self._query_check_bridge_port(ifaceobj, ifaceobjcurr)
def _query_running(self, ifaceobjrunning, ifaceobj_getfunc=None):
if not self.brctlcmd.bridge_exists(ifaceobjrunning.name):
def _query_running_bridge_port(self, ifaceobjrunning):
bridgename = self.ipcmd.bridge_port_get_bridge_name(
ifaceobjrunning.name)
if not bridgename:
self.logger.warn('%s: unable to determine bridgename'
%ifaceobjrunning.name)
return
if self.brctlcmd.get_stp(bridgename) == 'no':
# This bridge does not run stp, return
return
# if userspace stp not set, return
if self.sysctl_get('net.bridge.bridge-stp-user-space') != '1':
return
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
ifaceobjrunning.name,
'portnetwork')
if v and v != 'no':
ifaceobjrunning.update_config('mstpctl-network', v)
# XXX: Can we really get path cost of a port ???
#v = self.mstpctlcmd.get_portpathcost(ifaceobjrunning.name, p)
#if v and v != self.get_mod_subattr('mstpctl-pathcost',
# 'default'):
# ifaceobjrunning.update_config('mstpctl-network', v)
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
ifaceobjrunning.name, 'portadminedge')
if v and v != 'no':
ifaceobjrunning.update_config('mstpctl-adminedge', v)
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
ifaceobjrunning.name,'portp2p')
if v and v != 'no':
ifaceobjrunning.update_config('mstpctl-p2p', v)
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
ifaceobjrunning.name, 'portrestrrole')
if v and v != 'no':
ifaceobjrunning.update_config('mstpctl-restrrole', v)
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
ifaceobjrunning.name, 'restrtcn')
if v and v != 'no':
ifaceobjrunning.update_config('mstpctl-restrtcn', v)
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
ifaceobjrunning.name, 'bpduguard')
if v and v != 'no':
ifaceobjrunning.update_config('mstpctl-bpduguard', v)
# XXX: Can we really get path cost of a port ???
#v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
# p, 'treeprio')
#if v and v != self.get_mod_subattr('mstpctl-treeportprio',
# 'default'):
# portconfig['mstpctl-treeportprio'] += ' %s=%s' %(p, v)
#v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
# p, 'treecost')
#if v and v != self.get_mod_subattr('mstpctl-treeportcost',
# 'default'):
# portconfig['mstpctl-treeportcost'] += ' %s=%s' %(p, v)
def _query_running_bridge(self, ifaceobjrunning):
if self.brctlcmd.get_stp(ifaceobjrunning.name) == 'no':
# This bridge does not run stp, return
return
@@ -692,6 +699,12 @@ class mstpctl(moduleBase):
ifaceobjrunning.update_config_dict(self._query_running_attrs(
ifaceobjrunning))
def _query_running(self, ifaceobjrunning, **extra_args):
if self.brctlcmd.bridge_exists(ifaceobjrunning.name):
self._query_running_bridge(ifaceobjrunning)
elif self.brctlcmd.is_bridge_port(ifaceobjrunning.name):
self._query_running_bridge_port(ifaceobjrunning)
_run_ops = {'pre-up' : _up,
'post-down' : _down,
'query-checkcurr' : _query_check,

View File

@@ -9,6 +9,7 @@ from ifupdownaddons.modulebase import moduleBase
from ifupdownaddons.iproute2 import iproute2
import ifupdown.rtnetlink_api as rtnetlink_api
import logging
import re
class vlan(moduleBase):
""" ifupdown2 addon module to configure vlans """
@@ -91,7 +92,27 @@ class vlan(moduleBase):
return None
return [self._get_vlan_raw_device(ifaceobj)]
def _up(self, ifaceobj):
def _get_bridge_vids(self, bridgename, ifaceobj_getfunc):
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)
return None
def _bridge_vid_add_del(self, ifaceobj, bridgename, vlanid,
ifaceobj_getfunc, add=True):
if self.ipcmd.bridge_is_vlan_aware(bridgename):
# Check if the bridge vids has the vlanid
vids = self._get_bridge_vids(bridgename, ifaceobj_getfunc)
if vids and vlanid in vids:
return
else:
if add:
self.ipcmd.bridge_vids_add(bridgename, [vlanid])
else:
self.ipcmd.bridge_vids_del(bridgename, [vlanid])
def _up(self, ifaceobj, ifaceobj_getfunc=None):
vlanid = self._get_vlan_id(ifaceobj)
if vlanid == -1:
raise Exception('could not determine vlanid')
@@ -102,25 +123,31 @@ class vlan(moduleBase):
if not self.ipcmd.link_exists(vlanrawdevice):
raise Exception('rawdevice %s not present' %vlanrawdevice)
if self.ipcmd.link_exists(ifaceobj.name):
self._bridge_vid_add_del(ifaceobj, vlanrawdevice, vlanid,
ifaceobj_getfunc)
return
rtnetlink_api.rtnl_api.create_vlan(vlanrawdevice,
ifaceobj.name, vlanid)
self._bridge_vid_add_del(ifaceobj, vlanrawdevice, vlanid,
ifaceobj_getfunc)
def _down(self, ifaceobj):
def _down(self, ifaceobj, ifaceobj_getfunc=None):
vlanid = self._get_vlan_id(ifaceobj)
if vlanid == -1:
raise Exception('could not determine vlanid')
vlan_raw_device = self._get_vlan_raw_device(ifaceobj)
if not vlan_raw_device:
vlanrawdevice = self._get_vlan_raw_device(ifaceobj)
if not vlanrawdevice:
raise Exception('could not determine vlan raw device')
if not self.PERFMODE and not self.ipcmd.link_exists(ifaceobj.name):
return
try:
self.ipcmd.link_delete(ifaceobj.name)
self._bridge_vid_add_del(ifaceobj, vlanrawdevice, vlanid,
ifaceobj_getfunc, add=False)
except Exception, e:
self.log_warn(str(e))
def _query_check(self, ifaceobj, ifaceobjcurr):
def _query_check(self, ifaceobj, ifaceobjcurr, ifaceobj_getfunc=None):
if not self.ipcmd.link_exists(ifaceobj.name):
ifaceobjcurr.status = ifaceStatus.NOTFOUND
return
@@ -139,7 +166,7 @@ class vlan(moduleBase):
ifaceobjcurr.update_config_with_status('vlan-id',
vlanid, 0)
def _query_running(self, ifaceobjrunning):
def _query_running(self, ifaceobjrunning, ifaceobj_getfunc=None):
if not self.ipcmd.link_exists(ifaceobjrunning.name):
if self._is_vlan_by_name(ifaceobjrunning.name):
ifaceobjcurr.status = ifaceStatus.NOTFOUND
@@ -168,7 +195,8 @@ class vlan(moduleBase):
if not self.ipcmd:
self.ipcmd = iproute2(**self.get_flags())
def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
def run(self, ifaceobj, operation, query_ifaceobj=None,
ifaceobj_getfunc=None, **extra_args):
""" run vlan configuration on the interface object passed as argument
Args:
@@ -194,6 +222,6 @@ class vlan(moduleBase):
return
self._init_command_handlers()
if operation == 'query-checkcurr':
op_handler(self, ifaceobj, query_ifaceobj)
op_handler(self, ifaceobj, query_ifaceobj, ifaceobj_getfunc)
else:
op_handler(self, ifaceobj)
op_handler(self, ifaceobj, ifaceobj_getfunc)

View File

@@ -191,6 +191,8 @@ class iface():
"""iface state (of type ifaceState) """
self.status = ifaceStatus.UNKNOWN
"""iface status (of type ifaceStatus) """
self.status_str = None
"""iface status str (string representing the status) """
self.flags = 0x0
"""iface flags """
self.priv_flags = 0x0
@@ -331,14 +333,23 @@ class iface():
attr_value = ''
self.config.setdefault(attr_name, []).append(attr_value)
self._config_status.setdefault(attr_name, []).append(attr_status)
# set global iface state
if attr_status:
if attr_status == 1:
self.status = ifaceStatus.ERROR
elif self.status != ifaceStatus.ERROR:
# Not already error, mark success
self.status = ifaceStatus.SUCCESS
def check_n_update_config_with_status_many(self, attr_names,
attr_status=0):
# set multiple attribute status to zero
# also updates status only if the attribute is present
for attr_name in attr_names:
if not self.get_attr_value_first(attr_name):
return
self.config.setdefault(attr_name, []).append('')
self._config_status.setdefault(attr_name, []).append(attr_status)
def get_config_attr_status(self, attr_name, idx=0):
""" get status of a attribute config on this interface.
@@ -362,6 +373,7 @@ class iface():
if v != dstiface.config.get(k)): return False
return True
def __getstate__(self):
odict = self.__dict__.copy()
del odict['state']
@@ -435,13 +447,14 @@ class iface():
if self.addr_method:
outbuf += ' %s' %self.addr_method
if with_status:
if (self.status == ifaceStatus.NOTFOUND or
self.status == ifaceStatus.ERROR):
if (self.status == ifaceStatus.ERROR or
self.status == ifaceStatus.NOTFOUND):
if self.status_str:
outbuf += ' [%s]' %self.status_str
outbuf += ' %s' %errorstr
elif self.status == ifaceStatus.SUCCESS:
outbuf += ' %s' %successstr
if self.status == ifaceStatus.NOTFOUND:
if with_status:
outbuf = (outbuf.encode('utf8')
if isinstance(outbuf, unicode) else outbuf)
print outbuf + '\n'
@@ -452,10 +465,12 @@ class iface():
for cname, cvaluelist in config.items():
idx = 0
for cv in cvaluelist:
if not cv: continue
if with_status:
s = self.get_config_attr_status(cname, idx)
if s:
if s == -1:
outbuf += (indent + '%s %s\n'
%(cname, cv))
elif s == 1:
outbuf += (indent + '%s %s %s\n'
%(cname, cv, errorstr))
elif s == 0:

View File

@@ -371,7 +371,7 @@ class ifupdownMain(ifupdownBase):
if dlist: ret_dlist.extend(dlist)
return list(set(ret_dlist))
def populate_dependency_info(self, ops, ifacenames=None):
def populate_dependency_info_old(self, ops, ifacenames=None):
""" recursive function to generate iface dependency info """
if not ifacenames:
@@ -395,6 +395,33 @@ class ifupdownMain(ifupdownBase):
else:
self.dependency_graph[i] = dlist
def populate_dependency_info(self, ops, ifacenames=None):
""" recursive function to generate iface dependency info """
if not ifacenames:
ifacenames = self.ifaceobjdict.keys()
iqueue = deque(ifacenames)
while iqueue:
i = iqueue.popleft()
# Go through all modules and find dependent ifaces
dlist = None
ifaceobj = self.get_ifaceobj_first(i)
if not ifaceobj:
continue
dlist = ifaceobj.lowerifaces
if not dlist:
dlist = self.query_dependents(ifaceobj, ops, ifacenames)
else:
continue
if dlist:
self.preprocess_dependency_list(ifaceobj.name,
dlist, ops)
ifaceobj.lowerifaces = dlist
[iqueue.append(d) for d in dlist]
if not self.dependency_graph.get(i):
self.dependency_graph[i] = dlist
def _add_ifaceobj(self, ifaceobj):
currentifaceobjlist = self.ifaceobjdict.get(ifaceobj.name)
if not currentifaceobjlist:
@@ -865,7 +892,9 @@ class ifupdownMain(ifupdownBase):
raise Exception('no ifaces found matching ' +
'given allow lists')
self.populate_dependency_info(ops, filtered_ifacenames)
# 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)
return

View File

@@ -62,7 +62,8 @@ class ifaceScheduler():
if (ifaceobj.priv_flags & ifupdownobj.NOCONFIG):
continue
ifupdownobj.logger.debug(msg)
m.run(ifaceobj, op, query_ifaceobj)
m.run(ifaceobj, op, query_ifaceobj,
ifaceobj_getfunc=ifupdownobj.get_ifaceobjs)
else:
ifupdownobj.logger.debug(msg)
m.run(ifaceobj, op, ifaceobj_getfunc=ifupdownobj.get_ifaceobjs)

View File

@@ -489,8 +489,8 @@ class brctl(utilsBase):
def bridge_port_exists(self, bridge, bridgeportname):
try:
return bridgeportname in os.listdir('/sys/class/net/%s/brif'
%bridge)
return os.path.exists('/sys/class/net/%s/brif/%s'
%(bridge, bridgeportname))
except Exception:
return False

View File

@@ -608,8 +608,32 @@ class iproute2(utilsBase):
[self.exec_command('bridge vlan del vid %s dev %s %s'
%(v, bridgeportname, target)) for v in vids]
def bridge_fdb_add(self, dev, address, vlan, bridge=True):
target = 'self' if bridge else ''
self.exec_command('bridge fdb add %s dev %s vlan %s %s'
%(address, dev, vlan, target))
def bridge_fdb_del(self, dev, address, vlan, bridge=True):
target = 'self' if bridge else ''
self.exec_command('bridge fdb del %s dev %s vlan %s %s'
%(address, dev, vlan, target))
def bridge_is_vlan_aware(self, bridgename):
filename = '/sys/class/net/%s/bridge/vlan_filtering' %bridgename
if os.path.exists(filename) and self.read_file_oneline(filename) == '1':
return True
return False
def bridge_port_get_bridge_name(self, bridgeport):
filename = '/sys/class/net/%s/brport/bridge' %bridgeport
try:
return os.path.basename(os.readlink(filename))
except:
return None
def bridge_port_exists(self, bridge, bridgeportname):
try:
return os.path.exists('/sys/class/net/%s/brif/%s'
%(bridge, bridgeportname))
except Exception:
return False