diff options
author | Christian Breunig <christian@breunig.cc> | 2023-12-20 22:38:52 +0100 |
---|---|---|
committer | Christian Breunig <christian@breunig.cc> | 2023-12-20 22:38:52 +0100 |
commit | 774cc97eda61eb0b91df820797fb3c705d0073d5 (patch) | |
tree | 84d94d5132b3f184bcc62f34541c05f0c4652745 /src | |
parent | 10701108fecb36f7be7eb7ef5f1e54e63da5fb4e (diff) | |
download | vyos-1x-774cc97eda61eb0b91df820797fb3c705d0073d5.tar.gz vyos-1x-774cc97eda61eb0b91df820797fb3c705d0073d5.zip |
srv6: T591: enable SR enabled packet processing on defined interfaces
The Linux Kernel needs to be told if IPv6 SR enabled packets whether should be
processed or not. This is done using
/proc/sys/net/conf/<iface>/seg6_* variables:
seg6_enabled - BOOL
Accept or drop SR-enabled IPv6 packets on this interface.
Relevant packets are those with SRH present and DA = local.
0 - disabled (default)
not 0 - enabled
Or the VyOS CLI command:
* set protocols segment-routing interface eth0 srv6
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/protocols_segment_routing.py | 66 | ||||
-rw-r--r-- | src/etc/sysctl.d/30-vyos-router.conf | 3 |
2 files changed, 58 insertions, 11 deletions
diff --git a/src/conf_mode/protocols_segment_routing.py b/src/conf_mode/protocols_segment_routing.py index eb1653212..d865c2ac0 100755 --- a/src/conf_mode/protocols_segment_routing.py +++ b/src/conf_mode/protocols_segment_routing.py @@ -19,7 +19,10 @@ import os from sys import exit from vyos.config import Config +from vyos.configdict import node_changed from vyos.template import render_to_string +from vyos.utils.dict import dict_search +from vyos.utils.system import sysctl_write from vyos import ConfigError from vyos import frr from vyos import airbag @@ -32,33 +35,74 @@ def get_config(config=None): conf = Config() base = ['protocols', 'segment-routing'] - sr = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True) + sr = conf.get_config_dict(base, key_mangling=('-', '_'), + get_first_key=True, + no_tag_node_value_mangle=True, + with_recursive_defaults=True) - # We have gathered the dict representation of the CLI, but there are default - # options which we need to update into the dictionary retrived. - sr = conf.merge_defaults(sr, recursive=True) + # FRR has VRF support for different routing daemons. As interfaces belong + # to VRFs - or the global VRF, we need to check for changed interfaces so + # that they will be properly rendered for the FRR config. Also this eases + # removal of interfaces from the running configuration. + interfaces_removed = node_changed(conf, base + ['interface']) + if interfaces_removed: + sr['interface_removed'] = list(interfaces_removed) + import pprint + pprint.pprint(sr) return sr -def verify(static): +def verify(sr): + if 'srv6' in sr: + srv6_enable = False + if 'interface' in sr: + for interface, interface_config in sr['interface'].items(): + if 'srv6' in interface_config: + srv6_enable = True + break + if not srv6_enable: + raise ConfigError('SRv6 should be enabled on at least one interface!') return None -def generate(static): - if not static: +def generate(sr): + if not sr: return None - static['new_frr_config'] = render_to_string('frr/zebra.segment_routing.frr.j2', static) + sr['new_frr_config'] = render_to_string('frr/zebra.segment_routing.frr.j2', sr) return None -def apply(static): +def apply(sr): zebra_daemon = 'zebra' + if 'interface_removed' in sr: + for interface in sr['interface_removed']: + # Disable processing of IPv6-SR packets + sysctl_write(f'net.ipv6.conf.{interface}.seg6_enabled', '0') + + if 'interface' in sr: + for interface, interface_config in sr['interface'].items(): + # Accept or drop SR-enabled IPv6 packets on this interface + if 'srv6' in interface_config: + sysctl_write(f'net.ipv6.conf.{interface}.seg6_enabled', '1') + # Define HMAC policy for ingress SR-enabled packets on this interface + # It's a redundant check as HMAC has a default value - but better safe + # then sorry + tmp = dict_search('srv6.hmac', interface_config) + if tmp == 'accept': + sysctl_write(f'net.ipv6.conf.{interface}.seg6_require_hmac', '0') + elif tmp == 'drop': + sysctl_write(f'net.ipv6.conf.{interface}.seg6_require_hmac', '1') + elif tmp == 'ignore': + sysctl_write(f'net.ipv6.conf.{interface}.seg6_require_hmac', '-1') + else: + sysctl_write(f'net.ipv6.conf.{interface}.seg6_enabled', '0') + # Save original configuration prior to starting any commit actions frr_cfg = frr.FRRConfig() frr_cfg.load_configuration(zebra_daemon) frr_cfg.modify_section(r'^segment-routing') - if 'new_frr_config' in static: - frr_cfg.add_before(frr.default_add_before, static['new_frr_config']) + if 'new_frr_config' in sr: + frr_cfg.add_before(frr.default_add_before, sr['new_frr_config']) frr_cfg.commit_configuration(zebra_daemon) return None diff --git a/src/etc/sysctl.d/30-vyos-router.conf b/src/etc/sysctl.d/30-vyos-router.conf index 1c9b8999f..6291be5f0 100644 --- a/src/etc/sysctl.d/30-vyos-router.conf +++ b/src/etc/sysctl.d/30-vyos-router.conf @@ -105,3 +105,6 @@ net.core.rps_sock_flow_entries = 32768 net.core.default_qdisc=fq_codel net.ipv4.tcp_congestion_control=bbr +# Disable IPv6 Segment Routing packets by default +net.ipv6.conf.all.seg6_enabled = 0 +net.ipv6.conf.default.seg6_enabled = 0 |