Page MenuHomeVyOS Platform

No OneTemporary

Size
16 KB
Referenced Files
None
Subscribers
None
diff --git a/data/templates/frr/zebra.segment_routing.frr.j2 b/data/templates/frr/zebra.segment_routing.frr.j2
index 7b12fcdd0..718d47d8f 100644
--- a/data/templates/frr/zebra.segment_routing.frr.j2
+++ b/data/templates/frr/zebra.segment_routing.frr.j2
@@ -1,23 +1,26 @@
!
{% if srv6.locator is vyos_defined %}
segment-routing
srv6
locators
{% for locator, locator_config in srv6.locator.items() %}
locator {{ locator }}
{% if locator_config.prefix is vyos_defined %}
prefix {{ locator_config.prefix }} block-len {{ locator_config.block_len }} node-len {{ locator_config.node_len }} func-bits {{ locator_config.func_bits }}
{% endif %}
{% if locator_config.behavior_usid is vyos_defined %}
behavior usid
+{% endif %}
+{% if locator_config.format is vyos_defined %}
+ format {{ locator_config.format }}
{% endif %}
exit
!
{% endfor %}
exit
!
exit
!
exit
!
{% endif %}
diff --git a/interface-definitions/protocols_segment-routing.xml.in b/interface-definitions/protocols_segment-routing.xml.in
index c299f624e..688b253b6 100644
--- a/interface-definitions/protocols_segment-routing.xml.in
+++ b/interface-definitions/protocols_segment-routing.xml.in
@@ -1,137 +1,156 @@
<?xml version="1.0"?>
<interfaceDefinition>
<node name="protocols">
<children>
<node name="segment-routing" owner="${vyos_conf_scripts_dir}/protocols_segment-routing.py">
<properties>
<help>Segment Routing</help>
<priority>900</priority>
</properties>
<children>
<tagNode name="interface">
<properties>
<help>Interface specific Segment Routing options</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>
<children>
<node name="srv6">
<properties>
<help>Accept SR-enabled IPv6 packets on this interface</help>
</properties>
<children>
<leafNode name="hmac">
<properties>
<help>Define HMAC policy for ingress SR-enabled packets on this interface</help>
<completionHelp>
<list>accept drop ignore</list>
</completionHelp>
<valueHelp>
<format>accept</format>
<description>Accept packets without HMAC, validate packets with HMAC</description>
</valueHelp>
<valueHelp>
<format>drop</format>
<description>Drop packets without HMAC, validate packets with HMAC</description>
</valueHelp>
<valueHelp>
<format>ignore</format>
<description>Ignore HMAC field.</description>
</valueHelp>
<constraint>
<regex>(accept|drop|ignore)</regex>
</constraint>
</properties>
<defaultValue>accept</defaultValue>
</leafNode>
</children>
</node>
</children>
</tagNode>
<node name="srv6">
<properties>
<help>Segment-Routing SRv6 configuration</help>
</properties>
<children>
<tagNode name="locator">
<properties>
<help>Segment Routing SRv6 locator</help>
<constraint>
#include <include/constraint/alpha-numeric-hyphen-underscore.xml.i>
</constraint>
</properties>
<children>
<leafNode name="behavior-usid">
<properties>
<help>Set SRv6 behavior uSID</help>
<valueless/>
</properties>
</leafNode>
<leafNode name="prefix">
<properties>
<help>SRv6 locator prefix</help>
<valueHelp>
<format>ipv6net</format>
<description>SRv6 locator prefix</description>
</valueHelp>
<constraint>
<validator name="ipv6-prefix"/>
</constraint>
</properties>
</leafNode>
<leafNode name="block-len">
<properties>
<help>Configure SRv6 locator block length in bits</help>
<valueHelp>
<format>u32:16-64</format>
<description>Specify SRv6 locator block length in bits</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 16-64"/>
</constraint>
</properties>
<defaultValue>40</defaultValue>
</leafNode>
<leafNode name="func-bits">
<properties>
<help>Configure SRv6 locator function length in bits</help>
<valueHelp>
<format>u32:0-64</format>
<description>Specify SRv6 locator function length in bits</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-64"/>
</constraint>
</properties>
<defaultValue>16</defaultValue>
</leafNode>
<leafNode name="node-len">
<properties>
<help>Configure SRv6 locator node length in bits</help>
<valueHelp>
<format>u32:16-64</format>
<description>Configure SRv6 locator node length in bits</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 16-64"/>
</constraint>
</properties>
<defaultValue>24</defaultValue>
</leafNode>
+ <leafNode name="format">
+ <properties>
+ <help>SRv6 SID format</help>
+ <completionHelp>
+ <list>uncompressed-f4024 usid-f3216</list>
+ </completionHelp>
+ <valueHelp>
+ <format>uncompressed-f4024</format>
+ <description>Uncompressed f4024 format</description>
+ </valueHelp>
+ <valueHelp>
+ <format>usid-f3216</format>
+ <description>usid-f3216 format</description>
+ </valueHelp>
+ <constraint>
+ <regex>(uncompressed-f4024|usid-f3216)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
</children>
</tagNode>
</children>
</node>
</children>
</node>
</children>
</node>
</interfaceDefinition>
diff --git a/smoketest/scripts/cli/test_protocols_segment-routing.py b/smoketest/scripts/cli/test_protocols_segment-routing.py
index b1cac7483..af4ef2adf 100755
--- a/smoketest/scripts/cli/test_protocols_segment-routing.py
+++ b/smoketest/scripts/cli/test_protocols_segment-routing.py
@@ -1,110 +1,187 @@
#!/usr/bin/env python3
#
# 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
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Section
from vyos.frrender import zebra_daemon
from vyos.utils.process import process_named_running
from vyos.utils.system import sysctl_read
base_path = ['protocols', 'segment-routing']
+
class TestProtocolsSegmentRouting(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
# call base-classes classmethod
super(TestProtocolsSegmentRouting, cls).setUpClass()
# Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
cls.daemon_pid = process_named_running(zebra_daemon)
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
cls.cli_delete(cls, base_path)
def tearDown(self):
self.cli_delete(base_path)
self.cli_commit()
# check process health and continuity
self.assertEqual(self.daemon_pid, process_named_running(zebra_daemon))
def test_srv6(self):
interfaces = Section.interfaces('ethernet', vlan=False)
locators = {
- 'foo' : { 'prefix' : '2001:a::/64' },
- 'foo' : { 'prefix' : '2001:b::/64', 'usid' : {} },
+ 'foo1': {'prefix': '2001:a::/64'},
+ 'foo2': {'prefix': '2001:b::/64', 'usid': {}},
+ 'foo3': {'prefix': '2001:c::/64', 'format': 'uncompressed-f4024'},
+ 'foo4': {
+ 'prefix': '2001:d::/48',
+ 'block-len': '32',
+ 'node-len': '16',
+ 'func-bits': '16',
+ 'usid': {},
+ 'format': 'usid-f3216',
+ },
}
for locator, locator_config in locators.items():
- self.cli_set(base_path + ['srv6', 'locator', locator, 'prefix', locator_config['prefix']])
+ self.cli_set(
+ base_path
+ + ['srv6', 'locator', locator, 'prefix', locator_config['prefix']]
+ )
+ if 'block-len' in locator_config:
+ self.cli_set(
+ base_path
+ + [
+ 'srv6',
+ 'locator',
+ locator,
+ 'block-len',
+ locator_config['block-len'],
+ ]
+ )
+ if 'node-len' in locator_config:
+ self.cli_set(
+ base_path
+ + [
+ 'srv6',
+ 'locator',
+ locator,
+ 'node-len',
+ locator_config['node-len'],
+ ]
+ )
+ if 'func-bits' in locator_config:
+ self.cli_set(
+ base_path
+ + [
+ 'srv6',
+ 'locator',
+ locator,
+ 'func-bits',
+ locator_config['func-bits'],
+ ]
+ )
if 'usid' in locator_config:
self.cli_set(base_path + ['srv6', 'locator', locator, 'behavior-usid'])
+ if 'format' in locator_config:
+ self.cli_set(
+ base_path
+ + ['srv6', 'locator', locator, 'format', locator_config['format']]
+ )
# verify() - SRv6 should be enabled on at least one interface!
with self.assertRaises(ConfigSessionError):
self.cli_commit()
for interface in interfaces:
self.cli_set(base_path + ['interface', interface, 'srv6'])
self.cli_commit()
for interface in interfaces:
- self.assertEqual(sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1')
- self.assertEqual(sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '0') # default
-
- frrconfig = self.getFRRconfig(f'segment-routing', endsection='^exit')
- self.assertIn(f'segment-routing', frrconfig)
- self.assertIn(f' srv6', frrconfig)
- self.assertIn(f' locators', frrconfig)
+ self.assertEqual(
+ sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1'
+ )
+ self.assertEqual(
+ sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '0'
+ ) # default
+
+ frrconfig = self.getFRRconfig('segment-routing', endsection='^exit')
+ self.assertIn('segment-routing', frrconfig)
+ self.assertIn(' srv6', frrconfig)
+ self.assertIn(' locators', frrconfig)
for locator, locator_config in locators.items():
+ prefix = locator_config['prefix']
+ block_len = locator_config.get('block-len', '40')
+ node_len = locator_config.get('node-len', '24')
+ func_bits = locator_config.get('func-bits', '16')
+
self.assertIn(f' locator {locator}', frrconfig)
- self.assertIn(f' prefix {locator_config["prefix"]} block-len 40 node-len 24 func-bits 16', frrconfig)
+ self.assertIn(
+ f' prefix {prefix} block-len {block_len} node-len {node_len} func-bits {func_bits}',
+ frrconfig,
+ )
+
+ if 'format' in locator_config:
+ self.assertIn(f' format {locator_config["format"]}', frrconfig)
+ if 'usid' in locator_config:
+ self.assertIn(' behavior usid', frrconfig)
def test_srv6_sysctl(self):
interfaces = Section.interfaces('ethernet', vlan=False)
# HMAC accept
for interface in interfaces:
self.cli_set(base_path + ['interface', interface, 'srv6'])
self.cli_set(base_path + ['interface', interface, 'srv6', 'hmac', 'ignore'])
self.cli_commit()
for interface in interfaces:
- self.assertEqual(sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1')
- self.assertEqual(sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '-1') # ignore
+ self.assertEqual(
+ sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1'
+ )
+ self.assertEqual(
+ sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '-1'
+ ) # ignore
# HMAC drop
for interface in interfaces:
self.cli_set(base_path + ['interface', interface, 'srv6'])
self.cli_set(base_path + ['interface', interface, 'srv6', 'hmac', 'drop'])
self.cli_commit()
for interface in interfaces:
- self.assertEqual(sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1')
- self.assertEqual(sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '1') # drop
+ self.assertEqual(
+ sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1'
+ )
+ self.assertEqual(
+ sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '1'
+ ) # drop
# Disable SRv6 on first interface
first_if = interfaces[-1]
self.cli_delete(base_path + ['interface', first_if])
self.cli_commit()
self.assertEqual(sysctl_read(f'net.ipv6.conf.{first_if}.seg6_enabled'), '0')
+
if __name__ == '__main__':
unittest.main(verbosity=2)

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 6, 7:32 AM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4648134
Default Alt Text
(16 KB)

Event Timeline