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

Add support GRE/SIT tunnels. (#20)

This commit adds support for configuring GRE/IPIP/SIT tunnel interfaces as know
from previous versions of ifupdown. Currently only configuration checks for GRE
and SIT tunnels are implemented.

A tunnel interface configuration could look like this:

auto gre42
iface gre42 inet tunnel
        mode     gre
        local    198.51.100.1
        endpoint 203.0.113.2
	#
	# optional tunnel attributes
        ttl      64
        mtu      1400
	tunnel-physdev eth0
        #
        address  192.0.2.42/31
        address  2001:db8:d0c:23::42/64

auto he-ipv6
iface he-ipv6 inet tunnel
	mode sit
	endpoint 203.0.113.6
	local    198.51.100.66
	#
	# optional tunnel attributes
	ttl 255
	mtu 1466
	tunnel-physdev vrf_external
	#
	address 2001:db8:666::2/64

Signed-off-by: Maximilian Wilhelm <max@rfc2324.org>
This commit is contained in:
Maximilian Wilhelm
2017-01-28 23:54:43 +01:00
committed by Julien Fortin
parent db65511035
commit 2e2adb0e84
5 changed files with 174 additions and 3 deletions

151
addons/tunnel.py Normal file
View File

@@ -0,0 +1,151 @@
#!/usr/bin/python
#
# Maximilian Wilhelm <max@rfc2324.org>
# -- Mon 10 Oct 2016 10:53:13 PM CEST
#
from ifupdown.iface import *
from ifupdownaddons.modulebase import moduleBase
from ifupdownaddons.iproute2 import iproute2
import ifupdown.ifupdownflags as ifupdownflags
import logging
#
# TODO: Add checks for ipip tunnels.
#
class tunnel (moduleBase):
_modinfo = { 'mhelp' : 'create/configure GRE/IPIP/SIT tunnel interfaces',
'attrs' : {
'mode' :
{ 'help' : 'type of tunnel as in \'ip link\' command.',
'validvals' : ['gre' 'ipip', 'sit'],
'required' : True,
'example' : ['mode gre']},
'local' :
{ 'help' : 'IP of local tunnel endpoint',
'validvals' : ['<ipv4>', '<ipv6>'],
'required' : True,
'example' : ['local 192.2.0.42']},
'endpoint' :
{ 'help' : 'IP of remote tunnel endpoint',
'validvals' : ['<ipv4>', '<ipv6>'],
'required' : True,
'example' : ['endpoint 192.2.0.23']},
'ttl' :
{ 'help' : 'TTL for tunnel packets',
'validvals' : ['<number>'],
'required' : False,
'example' : ['ttl 64']},
'tunnel-physdev' :
{ 'help' : 'Physical underlay device to use for tunnel packets',
'validvals' : ['<interface>'],
'required' : False,
'example' : ['tunnel-physdev eth1']},
}
}
def __init__ (self, *args, **kargs):
moduleBase.__init__ (self, *args, **kargs)
self.ipcmd = None
def _is_my_interface (self, ifaceobj):
if ifaceobj.addr_method == "tunnel" and ifaceobj.get_attr_value_first ('mode'):
return True
return False
def _up (self, ifaceobj):
attr_map = {
# attr_name -> ip route param name
'local' : 'local',
'endpoint' : 'remote',
'ttl' : 'ttl',
'tunnel-physdev' : 'dev',
}
mode = ifaceobj.get_attr_value_first ('mode')
attrs = {}
# Only include attributes which have been set and map ifupdown2 names
# to attribute names expected by iproute
for attr, iproute_attr in attr_map.items ():
attr_val = ifaceobj.get_attr_value_first (attr)
if attr_val != None:
attrs[iproute_attr] = attr_val
self.ipcmd.link_create (ifaceobj.name, mode, attrs)
def _down (self, ifaceobj):
if not ifupdownflags.flags.PERFMODE and not self.ipcmd.link_exists (ifaceobj.name):
return
try:
self.ipcmd.link_delete (ifaceobj.name)
except Exception, e:
self.log_warn (str (e))
def _query_check_n_update (self, ifaceobj, ifaceobjcurr, attrname, attrval,
running_attrval):
if not ifaceobj.get_attr_value_first (attrname):
return
if running_attrval and attrval == running_attrval:
ifaceobjcurr.update_config_with_status (attrname, attrval, 0)
else:
ifaceobjcurr.update_config_with_status (attrname, running_attrval, 1)
def _query_check (self, ifaceobj, ifaceobjcurr):
if not self.ipcmd.link_exists (ifaceobj.name):
return
tunattrs = self.ipcmd.link_get_linkinfo_attrs (ifaceobj.name)
if not tunattrs:
ifaceobjcurr.check_n_update_config_with_status_many (ifaceobj, self.get_mod_attrs (), -1)
return
for attr in self.get_mod_attrs ():
if not ifaceobj.get_attr_value_first (attr):
continue
# Validate all interface attributes set in the config.
# Remote any leading 'tunnel-' prefix in front of the attr name
# when accessing tunattrs parsed from 'ip -d link'.
self._query_check_n_update (ifaceobj, ifaceobjcurr, attr,
ifaceobj.get_attr_value_first (attr),
tunattrs.get (attr.replace ("tunnel-", "")))
# Operations supported by this addon (yet).
_run_ops = {
'pre-up' : _up,
'post-down' : _down,
'query-checkcurr' : _query_check
}
def get_ops (self):
return self._run_ops.keys()
def _init_command_handlers (self):
if not self.ipcmd:
self.ipcmd = iproute2 ()
def run (self, ifaceobj, operation, query_ifaceobj = None, **extra_args):
op_handler = self._run_ops.get (operation)
if not op_handler:
return
if operation != 'query-running' and not self._is_my_interface (ifaceobj):
return
self._init_command_handlers ()
if operation == 'query-checkcurr':
op_handler (self, ifaceobj, query_ifaceobj)
else:
op_handler (self, ifaceobj)

View File

@@ -1,4 +1,5 @@
pre-up,link
pre-up,tunnel
pre-up,bond
pre-up,batman_adv
pre-up,vlan
@@ -35,3 +36,4 @@ post-down,bond
post-down,batman_adv
post-down,usercmds
post-down,link
post-down,tunnel

View File

@@ -27,8 +27,8 @@ class networkInterfaces():
callbacks = {}
auto_all = False
_addrfams = {'inet' : ['static', 'manual', 'loopback', 'dhcp', 'dhcp6'],
'inet6' : ['static', 'manual', 'loopback', 'dhcp', 'dhcp6']}
_addrfams = {'inet' : ['static', 'manual', 'loopback', 'dhcp', 'dhcp6', 'tunnel'],
'inet6' : ['static', 'manual', 'loopback', 'dhcp', 'dhcp6', 'tunnel']}
def __init__(self, interfacesfile='/etc/network/interfaces',
interfacesfileiobuf=None, interfacesfileformat='native',

View File

@@ -103,6 +103,24 @@ class iproute2(utilsBase):
linkattrs['state'] = citems[i + 1]
elif citems[i] == 'link/ether':
linkattrs['hwaddress'] = citems[i + 1]
elif citems[i] in [ 'link/gre', 'link/sit' ]:
linkattrs['kind'] = 'tunnel'
tunattrs = {'mode' : citems[i].split ('/')[1],
'endpoint' : None,
'local' : None,
'ttl' : None,
'physdev' : None}
for j in range(i + 2, len(citems)):
if citems[j] == 'local':
tunattrs['local'] = citems[j + 1]
elif citems[j] == 'remote':
tunattrs['endpoint'] = citems[j + 1]
elif citems[j] == 'ttl':
tunattrs['ttl'] = citems[j + 1]
elif citems[j] == 'dev':
tunattrs['physdev'] = citems[j + 1]
linkattrs['linkinfo'] = tunattrs
break
elif citems[i] == 'vlan':
vlanid = self._get_vland_id(citems, i, warn)
if vlanid:

View File

@@ -16,7 +16,7 @@ setup(name='ifupdown2',
'addons/dhcp.py', 'addons/usercmds.py',
'addons/ethtool.py',
'addons/addressvirtual.py', 'addons/vxlan.py',
'addons/link.py', 'addons/vrf.py',
'addons/link.py', 'addons/tunnel.py', 'addons/vrf.py',
'addons/bridgevlan.py', 'addons/batman_adv.py']),
('/usr/share/ifupdown2/nlmanager/',
['nlmanager/nllistener.py',