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:
committed by
Julien Fortin
parent
db65511035
commit
2e2adb0e84
151
addons/tunnel.py
Normal file
151
addons/tunnel.py
Normal 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)
|
Reference in New Issue
Block a user