summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiaosen Wang <secretandanon@gmail.com>2026-02-23 23:31:26 -0800
committerMiaosen Wang <secretandanon@gmail.com>2026-02-24 00:43:34 -0800
commit7f6545b188b7ad00a2ba4bf2dc7281bca93f05bf (patch)
treede3cd4ad1498eb95d26c9d8a017fff6819aec7e0
parent662b45c159393aa9451c93b168da415021949857 (diff)
downloadvyos-1x-7f6545b188b7ad00a2ba4bf2dc7281bca93f05bf.tar.gz
vyos-1x-7f6545b188b7ad00a2ba4bf2dc7281bca93f05bf.zip
T8302: This PR adds Router Advertisement (RA) base-interface support for IPv6 wildcard prefix derivation and includes validation and smoketests.
Included changes: - Add `base-interface` under: - `service router-advert interface <lan-if> prefix ::/64 base-interface <wan-if>` - Render `Base6Interface <wan-if>;` in `radvd.conf` when configured. - Add validation guard: - `base-interface` is only allowed with wildcard prefix `::/64`. - Extend smoketests: - Positive case: `::/64` + `base-interface` commits and renders correctly. - Negative case: non-`::/64` prefix with `base-interface` fails commit.
-rw-r--r--data/templates/router-advert/radvd.conf.j23
-rw-r--r--interface-definitions/service_router-advert.xml.in15
-rwxr-xr-xsmoketest/scripts/cli/test_service_router-advert.py14
-rwxr-xr-xsrc/conf_mode/service_router-advert.py3
4 files changed, 35 insertions, 0 deletions
diff --git a/data/templates/router-advert/radvd.conf.j2 b/data/templates/router-advert/radvd.conf.j2
index 15febd0dd..3da405688 100644
--- a/data/templates/router-advert/radvd.conf.j2
+++ b/data/templates/router-advert/radvd.conf.j2
@@ -84,6 +84,9 @@ interface {{ iface }} {
AdvPreferredLifetime {{ prefix_options.preferred_lifetime }};
DeprecatePrefix {{ 'on' if prefix_options.deprecate_prefix is vyos_defined else 'off' }};
DecrementLifetimes {{ 'on' if prefix_options.decrement_lifetime is vyos_defined else 'off' }};
+{% if prefix_options.base_interface is vyos_defined %}
+ Base6Interface {{ prefix_options.base_interface }};
+{% endif %}
};
{% endfor %}
{% endif %}
diff --git a/interface-definitions/service_router-advert.xml.in b/interface-definitions/service_router-advert.xml.in
index dc7164abc..878b53e78 100644
--- a/interface-definitions/service_router-advert.xml.in
+++ b/interface-definitions/service_router-advert.xml.in
@@ -305,6 +305,21 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="base-interface">
+ <properties>
+ <help>Prefix will be combined with IPv6 address of specified interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces</script>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface name</description>
+ </valueHelp>
+ <constraint>
+ #include <include/constraint/interface-name.xml.i>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="preferred-lifetime">
<properties>
<help>Time in seconds that the prefix will remain preferred</help>
diff --git a/smoketest/scripts/cli/test_service_router-advert.py b/smoketest/scripts/cli/test_service_router-advert.py
index 54133b5c7..52f0db4ab 100755
--- a/smoketest/scripts/cli/test_service_router-advert.py
+++ b/smoketest/scripts/cli/test_service_router-advert.py
@@ -376,5 +376,19 @@ class TestServiceRADVD(VyOSUnitTestSHIM.TestCase):
tmp = f'autoignoreprefixes' + ' {'
self.assertNotIn(tmp, config)
+ def test_base_interface(self):
+ self.cli_set(base_path + ['prefix', '::/64'])
+ self.cli_set(base_path + ['prefix', '::/64', 'base-interface', 'eth0'])
+ self.cli_commit()
+
+ config = read_file(RADVD_CONF)
+ self.assertIn('Base6Interface eth0;', config)
+
+ self.cli_set(base_path + ['prefix', '2001:db8:1234::/64'])
+ self.cli_set(
+ base_path + ['prefix', '2001:db8:1234::/64', 'base-interface', 'eth0']
+ )
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
if __name__ == '__main__':
unittest.main(verbosity=2, failfast=VyOSUnitTestSHIM.TestCase.debug_on())
diff --git a/src/conf_mode/service_router-advert.py b/src/conf_mode/service_router-advert.py
index 4345bea1d..86b0f8dd5 100755
--- a/src/conf_mode/service_router-advert.py
+++ b/src/conf_mode/service_router-advert.py
@@ -64,6 +64,9 @@ def verify(rtradv):
if not (int(valid_lifetime) >= int(preferred_lifetime)):
raise ConfigError('Prefix valid-lifetime must be greater then or equal to preferred-lifetime')
+ if 'base_interface' in prefix_config and prefix != '::/64':
+ raise ConfigError('Prefix base-interface can only be used together with the wildcard prefix "::/64"')
+
if 'nat64prefix' in interface_config:
nat64_supported_lengths = [32, 40, 48, 56, 64, 96]
for prefix, prefix_config in interface_config['nat64prefix'].items():