summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2024-03-20 20:53:47 +0100
committerChristian Breunig <christian@breunig.cc>2024-03-20 21:00:46 +0100
commit9eb018c4935235d292d7c693ac15da5761be064a (patch)
treeb2c39197432cb0216b6d3c0ee032266d2cd47cdc
parenta33aacf8ab67bab183f2ec84be49966a4c939c3d (diff)
downloadvyos-1x-9eb018c4935235d292d7c693ac15da5761be064a.tar.gz
vyos-1x-9eb018c4935235d292d7c693ac15da5761be064a.zip
vti: T6085: interface is always down and only enabled by IPSec daemon
When a VTI interface is just created, it is in ADMIN UP state by default, even if an IPSec peer is not connected. After the peer is disconnected the interface goes to DOWN state as expected. This breaks routing logic - for example, static routes through VTI interfaces will be active even if a peer is not connected. This changes to logic so ADMIN UP/DOWN state can only be changed by the vti-up-down helper script. Error was introduced during the Perl -> Python migration and move to the generic vyos.ifconfig abstraction during the 1.4 development cycle.
-rw-r--r--python/vyos/ifconfig/vti.py8
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_vti.py19
-rwxr-xr-xsrc/etc/ipsec.d/vti-up-down4
3 files changed, 28 insertions, 3 deletions
diff --git a/python/vyos/ifconfig/vti.py b/python/vyos/ifconfig/vti.py
index 9ebbeb9ed..9511386f4 100644
--- a/python/vyos/ifconfig/vti.py
+++ b/python/vyos/ifconfig/vti.py
@@ -1,4 +1,4 @@
-# Copyright 2021-2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -52,8 +52,14 @@ class VTIIf(Interface):
cmd += f' {iproute2_key} {tmp}'
self._cmd(cmd.format(**self.config))
+
+ # interface is always A/D down. It needs to be enabled explicitly
self.set_interface('admin_state', 'down')
+ def set_admin_state(self, state):
+ """ Handled outside by /etc/ipsec.d/vti-up-down """
+ pass
+
def get_mac(self):
""" Get a synthetic MAC address. """
return self.get_mac_synthetic()
diff --git a/smoketest/scripts/cli/test_interfaces_vti.py b/smoketest/scripts/cli/test_interfaces_vti.py
index 7f13575a3..871ac650b 100755
--- a/smoketest/scripts/cli/test_interfaces_vti.py
+++ b/smoketest/scripts/cli/test_interfaces_vti.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# Copyright (C) 2023-2024 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -18,6 +18,9 @@ import unittest
from base_interfaces_test import BasicInterfaceTest
+from vyos.ifconfig import Interface
+from vyos.utils.network import is_intf_addr_assigned
+
class VTIInterfaceTest(BasicInterfaceTest.TestCase):
@classmethod
def setUpClass(cls):
@@ -27,5 +30,19 @@ class VTIInterfaceTest(BasicInterfaceTest.TestCase):
# call base-classes classmethod
super(VTIInterfaceTest, cls).setUpClass()
+ def test_add_single_ip_address(self):
+ addr = '192.0.2.0/31'
+ for intf in self._interfaces:
+ self.cli_set(self._base_path + [intf, 'address', addr])
+ for option in self._options.get(intf, []):
+ self.cli_set(self._base_path + [intf] + option.split())
+
+ self.cli_commit()
+
+ # VTI interface are always down and only brought up by IPSec
+ for intf in self._interfaces:
+ self.assertTrue(is_intf_addr_assigned(intf, addr))
+ self.assertEqual(Interface(intf).get_admin_state(), 'down')
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/etc/ipsec.d/vti-up-down b/src/etc/ipsec.d/vti-up-down
index 441b316c2..01e9543c9 100755
--- a/src/etc/ipsec.d/vti-up-down
+++ b/src/etc/ipsec.d/vti-up-down
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-2024 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -57,7 +57,9 @@ if __name__ == '__main__':
if 'disable' not in vti:
tmp = VTIIf(interface)
tmp.update(vti)
+ call(f'sudo ip link set {interface} up')
else:
+ call(f'sudo ip link set {interface} down')
syslog(f'Interface {interface} is admin down ...')
elif verb in ['down-client', 'down-host']:
if vti_link_up: