summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/vyos/ifconfig/vti.py32
-rwxr-xr-xsrc/conf_mode/interfaces-vti.py23
-rwxr-xr-xsrc/conf_mode/vpn_ipsec.py39
3 files changed, 57 insertions, 37 deletions
diff --git a/python/vyos/ifconfig/vti.py b/python/vyos/ifconfig/vti.py
index e2090c889..9eafcd11b 100644
--- a/python/vyos/ifconfig/vti.py
+++ b/python/vyos/ifconfig/vti.py
@@ -14,6 +14,7 @@
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
from vyos.ifconfig.interface import Interface
+from vyos.util import dict_search
@Interface.register
class VTIIf(Interface):
@@ -25,3 +26,34 @@ class VTIIf(Interface):
'prefixes': ['vti', ],
},
}
+
+ def _create(self):
+ # This table represents a mapping from VyOS internal config dict to
+ # arguments used by iproute2. For more information please refer to:
+ # - https://man7.org/linux/man-pages/man8/ip-link.8.html
+ # - https://man7.org/linux/man-pages/man8/ip-tunnel.8.html
+ mapping = {
+ 'source_address' : 'local',
+ 'source_interface' : 'dev',
+ 'remote' : 'remote',
+ 'key' : 'key',
+ }
+
+ cmd = 'ip link add {ifname} type vti'
+ for vyos_key, iproute2_key in mapping.items():
+ # dict_search will return an empty dict "{}" for valueless nodes like
+ # "parameters.nolearning" - thus we need to test the nodes existence
+ # by using isinstance()
+ tmp = dict_search(vyos_key, self.config)
+ if isinstance(tmp, dict):
+ cmd += f' {iproute2_key}'
+ elif tmp != None:
+ cmd += f' {iproute2_key} {tmp}'
+
+ self._cmd(cmd.format(**self.config))
+ self.set_interface('admin_state', 'down')
+
+ def set_admin_state(self, state):
+ # function is not implemented for VTI interfaces as this is entirely
+ # handled by the ipsec up/down scripts
+ pass
diff --git a/src/conf_mode/interfaces-vti.py b/src/conf_mode/interfaces-vti.py
index 432d113e8..acd4a9790 100755
--- a/src/conf_mode/interfaces-vti.py
+++ b/src/conf_mode/interfaces-vti.py
@@ -19,6 +19,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.ifconfig import VTIIf
+from vyos.util import dict_search
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -34,6 +35,23 @@ def get_config(config=None):
conf = Config()
base = ['interfaces', 'vti']
vti = get_interface_dict(conf, base)
+
+ # VTI is more then an interface - we retrieve the "real" configuration from
+ # the IPsec peer configuration which binds this VTI
+ conf.set_level([])
+ tmp = conf.get_config_dict(['vpn', 'ipsec', 'site-to-site', 'peer'],
+ key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ for peer, peer_config in tmp.items():
+ if dict_search('vti.bind', peer_config) == vti['ifname']:
+ vti['remote'] = peer
+ if 'local_address' in peer_config:
+ vti['source_address'] = peer_config['local_address']
+ # we also need to "calculate" a per vti individual key
+ base = 0x900000
+ vti['key'] = base + int(vti['ifname'].lstrip('vti'))
+
return vti
def verify(vti):
@@ -46,6 +64,11 @@ def generate(vti):
return None
def apply(vti):
+ tmp = VTIIf(**vti)
+ tmp.remove()
+ if 'deleted' not in vti:
+ tmp.update(vti)
+
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py
index a1c36ea3b..ccbcd7f44 100755
--- a/src/conf_mode/vpn_ipsec.py
+++ b/src/conf_mode/vpn_ipsec.py
@@ -132,7 +132,7 @@ def get_config(config=None):
if pfs == 'enable':
pfs = default_ike_pfs
-
+
if 'proposal' in esp_conf:
ciphers = []
for i in esp_conf['proposal']:
@@ -360,9 +360,7 @@ def apply(ipsec):
should_start = ('profile' in ipsec or ('site_to_site' in ipsec and 'peer' in ipsec['site_to_site']))
- if should_start:
- apply_vti_interfaces(ipsec)
- else:
+ if not should_start:
cleanup_vti_interfaces()
if not process_named_running('charon'):
@@ -388,39 +386,6 @@ def apply(ipsec):
resync_l2tp(conf)
resync_nhrp(conf)
-def apply_vti_interfaces(ipsec):
- # While vyatta-vti-config.pl is still active, this interface will get deleted by cleanupVtiNotConfigured()
- if 'site_to_site' in ipsec and 'peer' in ipsec['site_to_site']:
- for peer, peer_conf in ipsec['site_to_site']['peer'].items():
- if 'vti' in peer_conf and 'bind' in peer_conf['vti']:
- vti_interface = peer_conf['vti']['bind']
- vti_conf = get_vti_interface(vti_interface)
- if not vti_conf:
- continue
- vti_mtu = vti_conf['mtu'] if 'mtu' in vti_conf else 1500
- mark = get_mark(vti_interface)
-
- local_ip = ''
- if 'local_address' in peer_conf:
- local_ip = peer_conf['local_address']
- elif 'dhcp_interface' in peer_conf:
- local_ip = get_dhcp_address(peer_conf['dhcp_interface'])
-
- call(f'sudo /usr/sbin/ip link delete {vti_interface} type vti', stderr=DEVNULL)
- call(f'sudo /usr/sbin/ip link add {vti_interface} type vti local {local_ip} remote {peer} okey {mark} ikey {mark}')
- call(f'sudo /usr/sbin/ip link set {vti_interface} mtu {vti_mtu}')
- if 'address' in vti_conf:
- address = vti_conf['address']
- if isinstance(address, list):
- for addr in address:
- call(f'sudo /usr/sbin/ip addr add {addr} dev {vti_interface}')
- else:
- call(f'sudo /usr/sbin/ip addr add {address} dev {vti_interface}')
-
- if 'description' in vti_conf:
- description = vti_conf['description']
- call(f'sudo echo "{description}" > /sys/class/net/{vti_interface}/ifalias')
-
def get_vti_interface(vti_interface):
global conf
section = conf.get_config_dict(['interfaces', 'vti'], get_first_key=True)