1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00
Roopa Prabhu fc5e1735c0 ifupdown: add new ifupdownflags class to carry ifupdown flags
Ticket: cleanup
Reviewed By:
Testing Done: Tested ifupdown sanity

This gets rid of some ugly previous flag handling which was
passed through modules. This creates a global instance of
flags that all addon modules and helper modules can use.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2016-04-14 22:30:53 -07:00

870 lines
31 KiB
Python

#!/usr/bin/python
#
# Copyright 2014 Cumulus Networks, Inc. All rights reserved.
# Author: Roopa Prabhu, roopa@cumulusnetworks.com
#
import os
import glob
import shlex
import signal
from ifupdown.utils import utils
from collections import OrderedDict
from utilsbase import *
from systemutils import *
from cache import *
import ifupdown.ifupdownflags as ifupdownflags
VXLAN_UDP_PORT = 4789
class iproute2(utilsBase):
""" This class contains helper methods to cache and interact with the
commands in the iproute2 package """
_cache_fill_done = False
ipbatchbuf = ''
ipbatch = False
ipbatch_pause = False
def __init__(self, *args, **kargs):
utilsBase.__init__(self, *args, **kargs)
if ifupdownflags.flags.CACHE:
self._fill_cache()
def _fill_cache(self):
if not iproute2._cache_fill_done:
self._link_fill()
self._addr_fill()
iproute2._cache_fill_done = True
return True
return False
def _link_fill(self, ifacename=None, refresh=False):
""" fills cache with link information
if ifacename argument given, fill cache for ifacename, else
fill cache for all interfaces in the system
"""
linkout = {}
if iproute2._cache_fill_done and not refresh: return
try:
# if ifacename already present, return
if (ifacename and not refresh and
linkCache.get_attr([ifacename, 'ifflag'])):
return
except:
pass
cmdout = self.link_show(ifacename=ifacename)
if not cmdout:
return
for c in cmdout.splitlines():
citems = c.split()
ifnamenlink = citems[1].split('@')
if len(ifnamenlink) > 1:
ifname = ifnamenlink[0]
iflink = ifnamenlink[1].strip(':')
else:
ifname = ifnamenlink[0].strip(':')
iflink = None
linkattrs = {}
linkattrs['link'] = iflink
linkattrs['ifindex'] = citems[0].strip(':')
flags = citems[2].strip('<>').split(',')
linkattrs['flags'] = flags
linkattrs['ifflag'] = 'UP' if 'UP' in flags else 'DOWN'
for i in range(0, len(citems)):
if citems[i] == 'mtu': linkattrs['mtu'] = citems[i+1]
elif citems[i] == 'state': linkattrs['state'] = citems[i+1]
elif citems[i] == 'link/ether': linkattrs['hwaddress'] = citems[i+1]
elif citems[i] == 'vlan':
vidx = citems.index('id')
linkattrs['linkinfo'] = {'vlanid' : citems[vidx+1]}
linkattrs['kind'] = 'vlan'
elif citems[i] == 'dummy':
linkattrs['kind'] = 'dummy'
elif citems[i] == 'vxlan' and citems[i+1] == 'id':
linkattrs['kind'] = 'vxlan'
vattrs = {'vxlanid' : citems[i+2],
'svcnode' : None,
'remote' : [],
'ageing' : citems[i+2],
'learning': 'on'}
for j in range(i+2, len(citems)):
if citems[j] == 'local':
vattrs['local'] = citems[j+1]
elif citems[j] == 'remote':
vattrs['svcnode'] = citems[j+1]
elif citems[j] == 'ageing':
vattrs['ageing'] = citems[j+1]
elif citems[j] == 'nolearning':
vattrs['learning'] = 'off'
# get vxlan peer nodes
peers = self.get_vxlan_peers(ifname, vattrs['svcnode'])
if peers:
vattrs['remote'] = peers
linkattrs['linkinfo'] = vattrs
break
elif citems[i] == 'vrf' and citems[i+1] == 'table':
vattrs = {'table' : citems[i+2]}
linkattrs['linkinfo'] = vattrs
linkattrs['kind'] = 'vrf'
linkCache.vrfs[ifname] = vattrs
break
elif citems[i] == 'vrf_slave':
linkattrs['kind'] = 'vrf_slave'
break
#linkattrs['alias'] = self.read_file_oneline(
# '/sys/class/net/%s/ifalias' %ifname)
linkout[ifname] = linkattrs
[linkCache.update_attrdict([ifname], linkattrs)
for ifname, linkattrs in linkout.items()]
def _addr_filter(self, ifname, addr, scope=None):
default_addrs = ['127.0.0.1/8', '::1/128' , '0.0.0.0']
if ifname == 'lo' and addr in default_addrs:
return True
if scope and scope == 'link':
return True
return False
def _addr_fill(self, ifacename=None, refresh=False):
""" fills cache with address information
if ifacename argument given, fill cache for ifacename, else
fill cache for all interfaces in the system
"""
linkout = {}
if iproute2._cache_fill_done and not refresh: return
try:
# Check if ifacename is already full, in which case, return
if ifacename and not refresh:
linkCache.get_attr([ifacename, 'addrs'])
return
except:
pass
cmdout = self.addr_show(ifacename=ifacename)
if not cmdout:
return
for c in cmdout.splitlines():
citems = c.split()
ifnamenlink = citems[1].split('@')
if len(ifnamenlink) > 1:
ifname = ifnamenlink[0]
else:
ifname = ifnamenlink[0].strip(':')
if not linkout.get(ifname):
linkattrs = {}
linkattrs['addrs'] = OrderedDict({})
try:
linkout[ifname].update(linkattrs)
except KeyError:
linkout[ifname] = linkattrs
if citems[2] == 'inet':
if self._addr_filter(ifname, citems[3], scope=citems[5]):
continue
addrattrs = {}
addrattrs['scope'] = citems[5]
addrattrs['type'] = 'inet'
linkout[ifname]['addrs'][citems[3]] = addrattrs
elif citems[2] == 'inet6':
if self._addr_filter(ifname, citems[3], scope=citems[5]):
continue
if citems[5] == 'link': continue #skip 'link' addresses
addrattrs = {}
addrattrs['scope'] = citems[5]
addrattrs['type'] = 'inet6'
linkout[ifname]['addrs'][citems[3]] = addrattrs
[linkCache.update_attrdict([ifname], linkattrs)
for ifname, linkattrs in linkout.items()]
def _cache_get(self, type, attrlist, refresh=False):
try:
if ifupdownflags.flags.DRYRUN:
return False
if ifupdownflags.flags.CACHE:
if self._fill_cache():
# if we filled the cache, return new data
return linkCache.get_attr(attrlist)
if not refresh:
return linkCache.get_attr(attrlist)
if type == 'link':
self._link_fill(attrlist[0], refresh)
elif type == 'addr':
self._addr_fill(attrlist[0], refresh)
else:
self._link_fill(attrlist[0], refresh)
self._addr_fill(attrlist[0], refresh)
return linkCache.get_attr(attrlist)
except Exception, e:
self.logger.debug('_cache_get(%s) : [%s]'
%(str(attrlist), str(e)))
pass
return None
def _cache_check(self, type, attrlist, value, refresh=False):
try:
attrvalue = self._cache_get(type, attrlist, refresh)
if attrvalue and attrvalue == value:
return True
except Exception, e:
self.logger.debug('_cache_check(%s) : [%s]'
%(str(attrlist), str(e)))
pass
return False
def _cache_update(self, attrlist, value):
if ifupdownflags.flags.DRYRUN: return
try:
linkCache.add_attr(attrlist, value)
except:
pass
def _cache_delete(self, attrlist):
if ifupdownflags.flags.DRYRUN: return
try:
linkCache.del_attr(attrlist)
except:
pass
def _cache_invalidate(self):
linkCache.invalidate()
iproute2._cache_fill_done = False
def batch_start(self):
self.ipbatcbuf = ''
self.ipbatch = True
self.ipbatch_pause = False
def add_to_batch(self, cmd):
self.ipbatchbuf += cmd + '\n'
def batch_pause(self):
self.ipbatch_pause = True
def batch_resume(self):
self.ipbatch_pause = False
def batch_commit(self):
if not self.ipbatchbuf:
self.ipbatchbuf = ''
self.ipbatch = False
self.ipbatch_pause = False
return
try:
self.exec_command_talk_stdin('ip -force -batch -',
stdinbuf=self.ipbatchbuf)
except Exception:
raise
finally:
self.ipbatchbuf = ''
self.ipbatch = False
self.ipbatch_pause = False
def addr_show(self, ifacename=None):
if ifacename:
if not self.link_exists(ifacename):
return
return self.exec_commandl(['ip','-o', 'addr', 'show', 'dev',
'%s' %ifacename])
else:
return self.exec_commandl(['ip', '-o', 'addr', 'show'])
def link_show(self, ifacename=None):
if ifacename:
return self.exec_commandl(['ip', '-o', '-d', 'link',
'show', 'dev', '%s' %ifacename])
else:
return self.exec_commandl(['ip', '-o', '-d', 'link', 'show'])
def addr_add(self, ifacename, address, broadcast=None,
peer=None, scope=None, preferred_lifetime=None):
if not address:
return
cmd = 'addr add %s' %address
if broadcast:
cmd += ' broadcast %s' %broadcast
if peer:
cmd += ' peer %s' %peer
if scope:
cmd += ' scope %s' %scope
if preferred_lifetime:
cmd += ' preferred_lft %s' %preferred_lifetime
cmd += ' dev %s' %ifacename
if self.ipbatch and not self.ipbatch_pause:
self.add_to_batch(cmd)
else:
self.exec_command('ip ' + cmd)
self._cache_update([ifacename, 'addrs', address], {})
def addr_del(self, ifacename, address, broadcast=None,
peer=None, scope=None):
""" Delete ipv4 address """
if not address:
return
if not self._cache_get('addr', [ifacename, 'addrs', address]):
return
cmd = 'addr del %s' %address
if broadcast:
cmd += 'broadcast %s' %broadcast
if peer:
cmd += 'peer %s' %peer
if scope:
cmd += 'scope %s' %scope
cmd += ' dev %s' %ifacename
self.exec_command('ip ' + cmd)
self._cache_delete([ifacename, 'addrs', address])
def addr_flush(self, ifacename):
cmd = 'addr flush dev %s' %ifacename
if self.ipbatch and not self.ipbatch_pause:
self.add_to_batch(cmd)
else:
self.exec_command('ip ' + cmd)
self._cache_delete([ifacename, 'addrs'])
def del_addr_all(self, ifacename, skip_addrs=[]):
if not skip_addrs: skip_addrs = []
runningaddrsdict = self.addr_get(ifacename)
try:
# XXX: ignore errors. Fix this to delete secondary addresses
# first
[self.addr_del(ifacename, a) for a in
set(runningaddrsdict.keys()).difference(skip_addrs)]
except:
# ignore errors
pass
def addr_get(self, ifacename, details=True, refresh=False):
addrs = self._cache_get('addr', [ifacename, 'addrs'],
refresh=refresh)
if not addrs:
return None
if details:
return addrs
return addrs.keys()
def addr_add_multiple(self, ifacename, addrs, purge_existing=False):
# purges address
if purge_existing:
# if perfmode is not set and also if iface has no sibling
# objects, purge addresses that are not present in the new
# config
runningaddrs = self.addr_get(ifacename, details=False)
if addrs == runningaddrs:
return
try:
# if primary address is not same, there is no need to keep any.
# reset all addresses
if (addrs and runningaddrs and
(addrs[0] != runningaddrs[0])):
self.del_addr_all(ifacename)
else:
self.del_addr_all(ifacename, addrs)
except Exception, e:
self.log_warn(str(e))
for a in addrs:
try:
self.addr_add(ifacename, a)
except Exception, e:
self.logger.error(str(e))
def _link_set_ifflag(self, ifacename, value):
# Dont look at the cache, the cache may have stale value
# because link status can be changed by external
# entity (One such entity is ifupdown main program)
cmd = 'link set dev %s %s' %(ifacename, value.lower())
if self.ipbatch:
self.add_to_batch(cmd)
else:
self.exec_command('ip ' + cmd)
def link_up(self, ifacename):
self._link_set_ifflag(ifacename, 'UP')
def link_down(self, ifacename):
self._link_set_ifflag(ifacename, 'DOWN')
def link_set(self, ifacename, key, value=None, force=False, type=None):
if not force:
if (key not in ['master', 'nomaster'] and
self._cache_check('link', [ifacename, key], value)):
return
cmd = 'link set dev %s' %ifacename
if type:
cmd += ' type %s' %type
cmd += ' %s' %key
if value:
cmd += ' %s' %value
if self.ipbatch:
self.add_to_batch(cmd)
else:
self.exec_command('ip ' + cmd)
if key not in ['master', 'nomaster']:
self._cache_update([ifacename, key], value)
def link_set_hwaddress(self, ifacename, hwaddress, force=False):
if not force:
if self._cache_check('link', [ifacename, 'hwaddress'], hwaddress):
return
self.link_down(ifacename)
cmd = 'link set dev %s address %s' %(ifacename, hwaddress)
if self.ipbatch:
self.add_to_batch(cmd)
else:
self.exec_command('ip ' + cmd)
self.link_up(ifacename)
self._cache_update([ifacename, 'hwaddress'], hwaddress)
def link_set_alias(self, ifacename, alias):
self.exec_commandl(['ip', 'link', 'set', 'dev',
ifacename, 'alias', alias])
def link_get_alias(self, ifacename):
return self.read_file_oneline('/sys/class/net/%s/ifalias'
%ifacename)
def link_isloopback(self, ifacename):
flags = self._cache_get('link', [ifacename, 'flags'])
if not flags:
return
if 'LOOPBACK' in flags:
return True
return False
def link_get_status(self, ifacename):
return self._cache_get('link', [ifacename, 'ifflag'], refresh=True)
def route_add_gateway(self, ifacename, gateway, metric=None):
if not gateway:
return
cmd = 'ip route add default via %s' %gateway
# Add metric
if metric:
cmd += 'metric %s' %metric
cmd += ' dev %s' %ifacename
self.exec_command(cmd)
def route_del_gateway(self, ifacename, gateway, metric=None):
# delete default gw
if not gateway:
return
cmd = 'ip route del default via %s' %gateway
if metric:
cmd += ' metric %s' %metric
cmd += ' dev %s' %ifacename
self.exec_command(cmd)
def route6_add_gateway(self, ifacename, gateway):
if not gateway:
return
return self.exec_command('ip -6 route add default via %s' %gateway +
' dev %s' %ifacename)
def route6_del_gateway(self, ifacename, gateway):
if not gateway:
return
return self.exec_command('ip -6 route del default via %s' %gateway +
'dev %s' %ifacename)
def link_create_vlan(self, vlan_device_name, vlan_raw_device, vlanid):
if self.link_exists(vlan_device_name):
return
self.exec_command('ip link add link %s' %vlan_raw_device +
' name %s' %vlan_device_name +
' type vlan id %d' %vlanid)
self._cache_update([vlan_device_name], {})
def link_create_vlan_from_name(self, vlan_device_name):
v = vlan_device_name.split('.')
if len(v) != 2:
self.logger.warn('invalid vlan device name %s' %vlan_device_name)
return
self.link_create_vlan(vlan_device_name, v[0], v[1])
def link_create_macvlan(self, name, linkdev, mode='private'):
if self.link_exists(name):
return
cmd = ('link add link %s' %linkdev +
' name %s' %name +
' type macvlan mode %s' %mode)
if self.ipbatch and not self.ipbatch_pause:
self.add_to_batch(cmd)
else:
self.exec_command('ip %s' %cmd)
self._cache_update([name], {})
def get_vxlan_peers(self, dev, svcnodeip):
cmd = 'bridge fdb show brport %s' % dev
cur_peers = []
try:
ps = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, close_fds=True)
utils.enable_subprocess_signal_forwarding(ps, signal.SIGINT)
output = subprocess.check_output(('grep', '00:00:00:00:00:00'), stdin=ps.stdout)
ps.wait()
utils.disable_subprocess_signal_forwarding(signal.SIGINT)
try:
ppat = re.compile('\s+dst\s+(\d+.\d+.\d+.\d+)\s+')
for l in output.split('\n'):
m = ppat.search(l)
if m and m.group(1) != svcnodeip:
cur_peers.append(m.group(1))
except:
self.logger.warn('error parsing ip link output')
pass
except subprocess.CalledProcessError as e:
if e.returncode != 1:
self.logger.error(str(e))
finally:
utils.disable_subprocess_signal_forwarding(signal.SIGINT)
return cur_peers
def link_create_vxlan(self, name, vxlanid,
localtunnelip=None,
svcnodeip=None,
remoteips=None,
learning='on',
ageing=None,
anycastip=None):
if svcnodeip and remoteips:
raise Exception("svcnodeip and remoteip is mutually exclusive")
args = ''
if svcnodeip:
args += ' remote %s' %svcnodeip
if ageing:
args += ' ageing %s' %ageing
if learning == 'off':
args += ' nolearning'
if self.link_exists(name):
cmd = 'link set dev %s type vxlan dstport %d' %(name, VXLAN_UDP_PORT)
vxlanattrs = self.get_vxlandev_attrs(name)
# on ifreload do not overwrite anycast_ip to individual ip if clagd
# has modified
if vxlanattrs:
running_localtunnelip = vxlanattrs.get('local')
if anycastip and running_localtunnelip and anycastip == running_localtunnelip:
localtunnelip = running_localtunnelip
running_svcnode = vxlanattrs.get('svcnode')
if running_svcnode and not svcnodeip:
args += ' noremote'
else:
cmd = 'link add dev %s type vxlan id %s dstport %d' %(name, vxlanid, VXLAN_UDP_PORT)
if localtunnelip:
args += ' local %s' %localtunnelip
cmd += args
if self.ipbatch and not self.ipbatch_pause:
self.add_to_batch(cmd)
else:
self.exec_command('ip %s' %cmd)
if not systemUtils.is_service_running(None, '/var/run/vxrd.pid'):
#figure out the diff for remotes and do the bridge fdb updates
#only if provisioned by user and not by vxrd
cur_peers = set(self.get_vxlan_peers(name, svcnodeip))
if remoteips:
new_peers = set(remoteips)
del_list = cur_peers.difference(new_peers)
add_list = new_peers.difference(cur_peers)
else:
del_list = cur_peers
add_list = []
try:
for addr in del_list:
self.bridge_fdb_del(name, '00:00:00:00:00:00', None, True, addr)
except:
pass
try:
for addr in add_list:
self.bridge_fdb_append(name, '00:00:00:00:00:00', None, True, addr)
except:
pass
# XXX: update linkinfo correctly
self._cache_update([name], {})
def link_exists(self, ifacename):
if ifupdownflags.flags.DRYRUN:
return True
return os.path.exists('/sys/class/net/%s' %ifacename)
def is_vlan_device_by_name(self, ifacename):
if re.search(r'\.', ifacename):
return True
return False
def route_add(self, route):
self.exec_command('ip route add ' + route)
def route6_add(self, route):
self.exec_command('ip -6 route add ' + route)
def get_vlandev_attrs(self, ifacename):
return (self._cache_get('link', [ifacename, 'link']),
self._cache_get('link', [ifacename, 'linkinfo', 'vlanid']))
def get_vxlandev_attrs(self, ifacename):
return self._cache_get('link', [ifacename, 'linkinfo'])
def link_get_linkinfo_attrs(self, ifacename):
return self._cache_get('link', [ifacename, 'linkinfo'])
def link_get_mtu(self, ifacename):
return self._cache_get('link', [ifacename, 'mtu'])
def link_get_kind(self, ifacename):
return self._cache_get('link', [ifacename, 'kind'])
def link_get_hwaddress(self, ifacename):
address = self._cache_get('link', [ifacename, 'hwaddress'])
# newly created logical interface addresses dont end up in the cache
# read hwaddress from sysfs file for these interfaces
if not address:
address = self.read_file_oneline('/sys/class/net/%s/address'
%ifacename)
return address
def link_create(self, ifacename, type, attrs={}):
""" generic link_create function """
if self.link_exists(ifacename):
return
cmd = 'link add'
cmd += ' name %s type %s' %(ifacename, type)
if attrs:
for k, v in attrs.iteritems():
cmd += ' %s' %k
if v:
cmd += ' %s' %v
if self.ipbatch and not self.ipbatch_pause:
self.add_to_batch(cmd)
else:
self.exec_command('ip %s' %cmd)
self._cache_update([ifacename], {})
def link_delete(self, ifacename):
if not self.link_exists(ifacename):
return
cmd = 'link del %s' %ifacename
if self.ipbatch and not self.ipbatch_pause:
self.add_to_batch(cmd)
else:
self.exec_command('ip %s' %cmd)
self._cache_invalidate()
def link_get_master(self, ifacename):
sysfs_master_path = '/sys/class/net/%s/master' %ifacename
if os.path.exists(sysfs_master_path):
link_path = os.readlink(sysfs_master_path)
if link_path:
return os.path.basename(link_path)
else:
return None
else:
return self._cache_get('link', [ifacename, 'master'])
def bridge_port_vids_add(self, bridgeportname, vids):
[self.exec_command('bridge vlan add vid %s dev %s'
%(v, bridgeportname)) for v in vids]
def bridge_port_vids_del(self, bridgeportname, vids):
if not vids:
return
[self.exec_command('bridge vlan del vid %s dev %s'
%(v, bridgeportname)) for v in vids]
def bridge_port_vids_flush(self, bridgeportname):
self.exec_command('bridge vlan del vid %s dev %s'
%(vid, bridgeportname))
def bridge_port_vids_get(self, bridgeportname):
self.exec_command('/sbin/bridge vlan show %s' %bridgeportname)
bridgeout = self.exec_command('/sbin/bridge vlan show dev %s'
%bridgeportname)
if not bridgeout: return []
brvlanlines = bridgeout.readlines()[2:]
vids = [l.strip() for l in brvlanlines]
return [vid for v in vids if vid]
def bridge_port_vids_get_all(self):
brvlaninfo = {}
bridgeout = self.exec_command('/sbin/bridge -c vlan show')
if not bridgeout: return brvlaninfo
brvlanlines = bridgeout.splitlines()
brportname=None
for l in brvlanlines[1:]:
if l and l[0] not in [' ', '\t']:
brportname = None
l=l.strip()
if not l:
brportname=None
continue
if 'PVID' in l:
attrs = l.split()
brportname = attrs[0]
brvlaninfo[brportname] = {'pvid' : attrs[1],
'vlan' : []}
elif brportname:
if 'Egress Untagged' not in l:
brvlaninfo[brportname]['vlan'].append(l)
elif not brportname:
attrs = l.split()
if attrs[1] == 'None' or 'Egress Untagged' in attrs[1]:
continue
brportname = attrs[0]
brvlaninfo[brportname] = {'vlan' : [attrs[1]]}
return brvlaninfo
def bridge_port_pvid_add(self, bridgeportname, pvid):
self.exec_command('bridge vlan add vid %s untagged pvid dev %s'
%(pvid, bridgeportname))
def bridge_port_pvid_del(self, bridgeportname, pvid):
self.exec_command('bridge vlan del vid %s untagged pvid dev %s'
%(pvid, bridgeportname))
def bridge_port_pvids_get(self, bridgeportname):
return self.read_file_oneline('/sys/class/net/%s/brport/pvid'
%bridgeportname)
def bridge_vids_add(self, bridgeportname, vids, bridge=True):
target = 'self' if bridge else ''
[self.exec_command('bridge vlan add vid %s dev %s %s'
%(v, bridgeportname, target)) for v in vids]
def bridge_vids_del(self, bridgeportname, vids, bridge=True):
target = 'self' if bridge else ''
[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=None, bridge=True, remote=None):
target = 'self' if bridge else ''
vlan_str = ''
if vlan:
vlan_str = 'vlan %s ' % vlan
dst_str = ''
if remote:
dst_str = 'dst %s ' % remote
self.exec_command('bridge fdb replace %s dev %s %s %s %s'
%(address, dev, vlan_str, target, dst_str))
def bridge_fdb_append(self, dev, address, vlan=None, bridge=True, remote=None):
target = 'self' if bridge else ''
vlan_str = ''
if vlan:
vlan_str = 'vlan %s ' % vlan
dst_str = ''
if remote:
dst_str = 'dst %s ' % remote
self.exec_command('bridge fdb append %s dev %s %s %s %s'
%(address, dev, vlan_str, target, dst_str))
def bridge_fdb_del(self, dev, address, vlan=None, bridge=True, remote=None):
target = 'self' if bridge else ''
vlan_str = ''
if vlan:
vlan_str = 'vlan %s ' % vlan
dst_str = ''
if remote:
dst_str = 'dst %s ' % remote
self.exec_command('bridge fdb del %s dev %s %s %s %s'
%(address, dev, vlan_str, target, dst_str))
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
def bridge_fdb_show_dev(self, dev):
try:
fdbs = {}
output = self.exec_command('bridge fdb show dev %s' %dev)
if output:
for fdb_entry in output.splitlines():
try:
entries = fdb_entry.split()
fdbs.setdefault(entries[2], []).append(entries[0])
except:
self.logger.debug('%s: invalid fdb line \'%s\''
%(dev, fdb_entry))
pass
return fdbs
except Exception:
return None
def is_bridge(self, bridge):
return os.path.exists('/sys/class/net/%s/bridge' %bridge)
def is_link_up(self, ifacename):
ret = False
try:
flags = self.read_file_oneline('/sys/class/net/%s/flags' %ifacename)
iflags = int(flags, 16)
if (iflags & 0x0001):
ret = True
except:
ret = False
pass
return ret
def ip_route_get_dev(self, prefix):
try:
output = self.exec_command('ip route get %s' %prefix)
if output:
rline = output.splitlines()[0]
if rline:
rattrs = rline.split()
return rattrs[rattrs.index('dev') + 1]
except Exception, e:
self.logger.debug('ip_route_get_dev: failed .. %s' %str(e))
pass
return None
def link_get_lowers(self, ifacename):
try:
lowers = glob.glob("/sys/class/net/%s/lower_*" %ifacename)
if not lowers:
return []
return [os.path.basename(l)[6:] for l in lowers]
except:
return []
def link_get_upper(self, ifacename):
try:
upper = glob.glob("/sys/class/net/%s/upper_*" %ifacename)
if not upper:
return None
return os.path.basename(upper[0])[6:]
except:
return None
def link_get_vrfs(self):
self._fill_cache()
return linkCache.vrfs