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:
@@ -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:
|
||||
|
322
addons/bridge.py
322
addons/bridge.py
@@ -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,
|
||||
|
@@ -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')
|
||||
|
@@ -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:
|
||||
|
@@ -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,
|
||||
|
@@ -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)
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user