diff --git a/addons/vxlan.py b/addons/vxlan.py index 954e931..00e8735 100644 --- a/addons/vxlan.py +++ b/addons/vxlan.py @@ -32,6 +32,9 @@ class vxlan(moduleBase): {'help' : 'vxlan remote ip', 'validvals' : ['', ''], 'example': ['vxlan-remoteip 172.16.22.127']}, + 'vxlan-physdev' : + {'help' : 'vxlan physical device', + 'example': ['vxlan-physdev eth1']}, 'vxlan-learning' : {'help' : 'vxlan learning yes/no', 'validvals' : ['yes', 'no', 'on', 'off'], @@ -59,6 +62,14 @@ class vxlan(moduleBase): self.log_warn('%s: multiple clagd-vxlan-anycast-ip lines, using first one' % (ifaceobj.name,)) vxlan._clagd_vxlan_anycast_ip = clagd_vxlan_list[0] + + + # If we should use a specific underlay device for the VXLAN + # tunnel make sure this device is set up before the VXLAN iface. + physdev = ifaceobj.get_attr_value_first('vxlan-physdev') + if physdev: + return [ physdev ] + return None def _is_vxlan_device(self, ifaceobj): @@ -72,6 +83,7 @@ class vxlan(moduleBase): anycastip = self._clagd_vxlan_anycast_ip group = ifaceobj.get_attr_value_first('vxlan-svcnodeip') local = ifaceobj.get_attr_value_first('vxlan-local-tunnelip') + physdev = ifaceobj.get_attr_value_first('vxlan-physdev') ageing = ifaceobj.get_attr_value_first('vxlan-ageing') learning = utils.get_onoff_bool(ifaceobj.get_attr_value_first('vxlan-learning')) @@ -89,7 +101,8 @@ class vxlan(moduleBase): local=local, learning=learning, ageing=ageing, - group=group) + group=group, + physdev=physdev) remoteips = ifaceobj.get_attr_value('vxlan-remoteip') if not systemUtils.is_service_running(None, '/var/run/vxrd.pid'): @@ -207,6 +220,11 @@ class vxlan(moduleBase): self._query_check_n_update(ifaceobj, ifaceobjcurr, 'vxlan-ageing', ageing, vxlanattrs.get('ageing')) + physdev = ifaceobj.get_attr_value_first('vxlan-physdev') + if physdev: + self._query_check_n_update(ifaceobj, ifaceobjcurr, 'vxlan-physdev', + physdev, vxlanattrs.get('physdev')) + def _query_running(self, ifaceobjrunning): vxlanattrs = self.ipcmd.get_vxlandev_attrs(ifaceobjrunning.name) if not vxlanattrs: diff --git a/ifupdown/netlink.py b/ifupdown/netlink.py index 3a7e7b2..49f4ae4 100644 --- a/ifupdown/netlink.py +++ b/ifupdown/netlink.py @@ -94,24 +94,30 @@ class Netlink(utilsBase): % (ifacename, vlanid, str(e))) def link_add_vxlan(self, ifacename, vxlanid, local=None, dstport=VXLAN_UDP_PORT, - group=None, learning='on', ageing=None): + group=None, learning='on', ageing=None, physdev=None): cmd = 'ip link add %s type vxlan id %s dstport %s' % (ifacename, vxlanid, dstport) + + cmd += ' local %s' % local if local else '' cmd += ' ageing %s' % ageing if ageing else '' cmd += ' remote %s' % group if group else ' noremote' cmd += ' nolearning' if learning == 'off' else '' + cmd += ' dev %s' % physdev if physdev else '' self.logger.info('%s: netlink: %s' % (ifacename, cmd)) if ifupdownflags.flags.DRYRUN: return try: + if physdev: + physdev = self.get_iface_index (physdev) return self._nlmanager_api.link_add_vxlan(ifacename, vxlanid, dstport=dstport, local=local, group=group, learning=learning, - ageing=ageing) + ageing=ageing, + physdev=physdev) except Exception as e: raise Exception('netlink: %s: cannot create vxlan %s: %s' % (ifacename, vxlanid, str(e))) diff --git a/ifupdownaddons/iproute2.py b/ifupdownaddons/iproute2.py index 7c150b8..1212133 100644 --- a/ifupdownaddons/iproute2.py +++ b/ifupdownaddons/iproute2.py @@ -114,6 +114,7 @@ class iproute2(utilsBase): linkattrs['kind'] = 'vxlan' vattrs = {'vxlanid': citems[i + 2], 'svcnode': None, + 'physdev': None, 'remote': [], 'ageing': citems[i + 2], 'learning': 'on'} @@ -126,6 +127,8 @@ class iproute2(utilsBase): vattrs['ageing'] = citems[j + 1] elif citems[j] == 'nolearning': vattrs['learning'] = 'off' + elif citems[j] == 'dev': + vattrs['physdev'] = citems[j + 1] # get vxlan peer nodes if provisioned by user and not by vxrd if not vxrd_running: peers = self.get_vxlan_peers(ifname, vattrs['svcnode']) diff --git a/nlmanager/nlmanager.py b/nlmanager/nlmanager.py index 6406677..11c3b1b 100644 --- a/nlmanager/nlmanager.py +++ b/nlmanager/nlmanager.py @@ -643,7 +643,7 @@ class NetlinkManager(object): return self.tx_nlpacket_get_response(nbr) def link_add_vxlan(self, ifname, vxlanid, dstport=None, local=None, - group=None, learning='on', ageing=None): + group=None, learning='on', ageing=None, physdev=None): debug = RTM_NEWLINK in self.debug @@ -654,6 +654,8 @@ class NetlinkManager(object): info_data[Link.IFLA_VXLAN_LOCAL] = local if group: info_data[Link.IFLA_VXLAN_GROUP] = group + if physdev: + info_data[Link.IFLA_VXLAN_LINK] = int (physdev) learning = 0 if learning == 'off' else 1 info_data[Link.IFLA_VXLAN_LEARNING] = learning