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

Modified ifupdown support for vxlan head end replication

Ticket: CM-5637
Reviewed By: CCR-2755
Testing Done:

Replaced vxlan-peernodeip attribute with vxlan-remoteip.  Updated
the vxlan and iproute2 modules to configure head end replication
using bridge fdb commands.
This commit is contained in:
Wilson Kok
2015-04-15 09:48:12 -07:00
parent 1cda1e437b
commit 44533c7298
2 changed files with 100 additions and 31 deletions

View File

@@ -9,6 +9,8 @@ from collections import OrderedDict
from utilsbase import *
from cache import *
VXLAN_UDP_PORT = 4789
class iproute2(utilsBase):
""" This class contains helper methods to cache and interact with the
commands in the iproute2 package """
@@ -68,16 +70,19 @@ class iproute2(utilsBase):
elif citems[i] == 'vxlan' and citems[i+1] == 'id':
vattrs = {'vxlanid' : citems[i+2],
'svcnode' : [],
'remote' : [],
'learning': 'on'}
for j in range(i+2, len(citems)):
if citems[j] == 'local':
vattrs['local'] = citems[j+1]
elif citems[j] == 'svcnode':
vattrs['svcnode'].append(citems[j+1])
elif citems[j] == 'peernode':
vattrs['peernode'].append(citems[j+1])
elif citems[j] == 'nolearning':
vattrs['learning'] = 'off'
# get vxlan peer nodes
peers = self.get_vxlan_peers(ifname)
if peers:
vattrs['remote'] = peers
linkattrs['linkinfo'] = vattrs
break
#linkattrs['alias'] = self.read_file_oneline(
@@ -456,35 +461,77 @@ class iproute2(utilsBase):
self.exec_command('ip %s' %cmd)
self._cache_update([name], {})
def get_vxlan_peers(self, dev):
cmd = 'bridge fdb show brport %s' % dev
cur_peers = []
try:
ps = subprocess.Popen((cmd).split(), stdout=subprocess.PIPE, close_fds=True)
output = subprocess.check_output(('grep', '00:00:00:00:00:00'), stdin=ps.stdout)
ps.wait()
try:
ppat = re.compile('\s+dst\s+(\d+.\d+.\d+.\d+)\s+')
for l in output.split('\n'):
m = ppat.search(l)
if m:
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))
return cur_peers
def link_create_vxlan(self, name, vxlanid,
localtunnelip=None,
svcnodeips=None,
peernodeips=None,
remoteips=None,
learning='on'):
if svcnodeips and peernodeips:
raise Exception("svcnodeip and peernodeip is mutually exclusive")
if svcnodeips and remoteips:
raise Exception("svcnodeip and remoteip is mutually exclusive")
args = ''
if localtunnelip:
args += ' local %s' %localtunnelip
if svcnodeips:
for s in svcnodeips:
args += ' svcnode %s' %s
if peernodeips:
for s in peernodeips:
args += ' peernode %s' %s
if learning == 'off':
args += ' nolearning'
if self.link_exists(name):
cmd = 'link set dev %s type vxlan ' %(name)
cmd = 'link set dev %s type vxlan dstport %d' %(name, VXLAN_UDP_PORT)
else:
cmd = 'link add dev %s type vxlan id %s' %(name, vxlanid)
cmd = 'link add dev %s type vxlan id %s dstport %d' %(name, vxlanid, VXLAN_UDP_PORT)
cmd += args
if self.ipbatch and not self.ipbatch_pause:
self.add_to_batch(cmd)
else:
self.exec_command('ip %s' %cmd)
# figure out the diff for remotes and do the bridge fdb updates
cur_peers = set(self.get_vxlan_peers(name))
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], {})
@@ -620,23 +667,43 @@ 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=None, bridge=True):
def bridge_fdb_add(self, dev, address, vlan=None, bridge=True, remote=None):
target = 'self' if bridge else ''
vlan_str = ''
if vlan:
self.exec_command('bridge fdb replace %s dev %s vlan %s %s'
%(address, dev, vlan, target))
else:
self.exec_command('bridge fdb replace %s dev %s %s'
%(address, dev, target))
vlan_str = 'vlan %s ' % vlan
def bridge_fdb_del(self, dev, address, vlan=None, bridge=True):
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:
self.exec_command('bridge fdb del %s dev %s vlan %s %s'
%(address, dev, vlan, target))
else:
self.exec_command('bridge fdb del %s dev %s %s'
%(address, dev, target))
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