]> git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/addons/tunnel.py
addons: tunnel: Add support for GRETAP tunnels. (#34)
[mirror_ifupdown2.git] / ifupdown2 / addons / tunnel.py
1 #!/usr/bin/python
2 #
3 # Maximilian Wilhelm <max@rfc2324.org>
4 # -- Mon 10 Oct 2016 10:53:13 PM CEST
5 #
6
7 from ifupdown.iface import *
8 from ifupdownaddons.modulebase import moduleBase
9 from ifupdownaddons.iproute2 import iproute2
10 import ifupdown.ifupdownflags as ifupdownflags
11 import logging
12
13 #
14 # TODO: Add checks for ipip tunnels.
15 #
16 class tunnel (moduleBase):
17 _modinfo = { 'mhelp' : 'create/configure GRE/IPIP/SIT and GRETAP tunnel interfaces',
18 'attrs' : {
19 'mode' :
20 { 'help' : 'type of tunnel as in \'ip link\' command.',
21 'validvals' : ['gre', 'gretap', 'ipip', 'sit'],
22 'required' : True,
23 'example' : ['mode gre']},
24 'local' :
25 { 'help' : 'IP of local tunnel endpoint',
26 'validvals' : ['<ipv4>', '<ipv6>'],
27 'required' : True,
28 'example' : ['local 192.2.0.42']},
29 'endpoint' :
30 { 'help' : 'IP of remote tunnel endpoint',
31 'validvals' : ['<ipv4>', '<ipv6>'],
32 'required' : True,
33 'example' : ['endpoint 192.2.0.23']},
34 'ttl' :
35 { 'help' : 'TTL for tunnel packets',
36 'validvals' : ['<number>'],
37 'required' : False,
38 'example' : ['ttl 64']},
39 'tunnel-physdev' :
40 { 'help' : 'Physical underlay device to use for tunnel packets',
41 'validvals' : ['<interface>'],
42 'required' : False,
43 'example' : ['tunnel-physdev eth1']},
44 }
45 }
46
47
48 def __init__ (self, *args, **kargs):
49 moduleBase.__init__ (self, *args, **kargs)
50 self.ipcmd = None
51
52
53 def _is_my_interface (self, ifaceobj):
54 if ifaceobj.addr_method == "tunnel" and ifaceobj.get_attr_value_first ('mode'):
55 return True
56 return False
57
58
59 def _up (self, ifaceobj):
60 attr_map = {
61 # attr_name -> ip route param name
62 'local' : 'local',
63 'endpoint' : 'remote',
64 'ttl' : 'ttl',
65 'tunnel-physdev' : 'dev',
66 }
67
68 mode = ifaceobj.get_attr_value_first ('mode')
69 attrs = {}
70
71 # Only include attributes which have been set and map ifupdown2 names
72 # to attribute names expected by iproute
73 for attr, iproute_attr in attr_map.items ():
74 attr_val = ifaceobj.get_attr_value_first (attr)
75 if attr_val != None:
76 attrs[iproute_attr] = attr_val
77
78 self.ipcmd.link_create (ifaceobj.name, mode, attrs)
79
80
81 def _down (self, ifaceobj):
82 if not ifupdownflags.flags.PERFMODE and not self.ipcmd.link_exists (ifaceobj.name):
83 return
84 try:
85 self.ipcmd.link_delete (ifaceobj.name)
86 except Exception, e:
87 self.log_warn (str (e))
88
89
90 def _query_check_n_update (self, ifaceobj, ifaceobjcurr, attrname, attrval,
91 running_attrval):
92 if not ifaceobj.get_attr_value_first (attrname):
93 return
94
95 if running_attrval and attrval == running_attrval:
96 ifaceobjcurr.update_config_with_status (attrname, attrval, 0)
97 else:
98 ifaceobjcurr.update_config_with_status (attrname, running_attrval, 1)
99
100
101 def _query_check (self, ifaceobj, ifaceobjcurr):
102 if not self.ipcmd.link_exists (ifaceobj.name):
103 return
104
105 tunattrs = self.ipcmd.link_get_linkinfo_attrs (ifaceobj.name)
106 if not tunattrs:
107 ifaceobjcurr.check_n_update_config_with_status_many (ifaceobj, self.get_mod_attrs (), -1)
108 return
109
110 for attr in self.get_mod_attrs ():
111 if not ifaceobj.get_attr_value_first (attr):
112 continue
113
114 # Validate all interface attributes set in the config.
115 # Remote any leading 'tunnel-' prefix in front of the attr name
116 # when accessing tunattrs parsed from 'ip -d link'.
117 self._query_check_n_update (ifaceobj, ifaceobjcurr, attr,
118 ifaceobj.get_attr_value_first (attr),
119 tunattrs.get (attr.replace ("tunnel-", "")))
120
121
122 # Operations supported by this addon (yet).
123 _run_ops = {
124 'pre-up' : _up,
125 'post-down' : _down,
126 'query-checkcurr' : _query_check
127 }
128
129
130 def get_ops (self):
131 return self._run_ops.keys()
132
133
134 def _init_command_handlers (self):
135 if not self.ipcmd:
136 self.ipcmd = iproute2 ()
137
138
139 def run (self, ifaceobj, operation, query_ifaceobj = None, **extra_args):
140 op_handler = self._run_ops.get (operation)
141 if not op_handler:
142 return
143
144 if operation != 'query-running' and not self._is_my_interface (ifaceobj):
145 return
146
147 self._init_command_handlers ()
148 if operation == 'query-checkcurr':
149 op_handler (self, ifaceobj, query_ifaceobj)
150 else:
151 op_handler (self, ifaceobj)