summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2023-04-08 22:09:04 +0200
committerChristian Breunig <christian@breunig.cc>2023-04-13 09:01:31 +0200
commit3f4de1390d6459cdd17dd1b6f22b1a3aec002671 (patch)
tree5091149b640ff7b064b87f2e1391f931ba5a7677 /src
parent8993298bc2c9d3e796d658dc71ba6ae6afedc4c3 (diff)
downloadvyos-1x-3f4de1390d6459cdd17dd1b6f22b1a3aec002671.tar.gz
vyos-1x-3f4de1390d6459cdd17dd1b6f22b1a3aec002671.zip
T5150: initial implementation of new Kernel/Zebra route-map support
It is possible to install a route-map which filters the routes between routing daemons and the OS kernel (zebra) As of now this can be done by e.g. * set protocols ospf route-map foo * set protocols ospfv3 route-map foo * set protocols bgp route-map foo Which in turn will install the following lines into FRR * ip protocol ospf route-map foo * ipv6 protocol ospf6 route-map foo * ip protocol bgp route-map foo The current state of the VyOS CLI is incomplete as there is no way to: * Install a filter for BGP IPv6 routes * Install a filter for static routes * Install a filter for connected routes Thus the CLI should be redesigned to close match what FRR does for both the default and any other VRF * set system ip protocol ospf route-map foo * set system ipv6 protocol ospfv3 route-map foo * set system ip protocol bgp route-map foo * set system ipv6 protocol bgp route-map foo The configuration can be migrated accordingly. This commit does not come with the migrator, it will be comitted later.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/protocols_static.py7
-rwxr-xr-xsrc/conf_mode/system-ip.py38
-rwxr-xr-xsrc/conf_mode/system-ipv6.py38
3 files changed, 70 insertions, 13 deletions
diff --git a/src/conf_mode/protocols_static.py b/src/conf_mode/protocols_static.py
index 3e5ebb805..3eabf24bc 100755
--- a/src/conf_mode/protocols_static.py
+++ b/src/conf_mode/protocols_static.py
@@ -105,17 +105,10 @@ def generate(static):
def apply(static):
static_daemon = 'staticd'
- zebra_daemon = 'zebra'
# Save original configuration prior to starting any commit actions
frr_cfg = frr.FRRConfig()
- # The route-map used for the FIB (zebra) is part of the zebra daemon
- frr_cfg.load_configuration(zebra_daemon)
- frr_cfg.modify_section(r'^ip protocol static route-map [-a-zA-Z0-9.]+', '')
- frr_cfg.commit_configuration(zebra_daemon)
- frr_cfg.load_configuration(static_daemon)
-
if 'vrf' in static:
vrf = static['vrf']
frr_cfg.modify_section(f'^vrf {vrf}', stop_pattern='^exit', remove_stop_mark=True)
diff --git a/src/conf_mode/system-ip.py b/src/conf_mode/system-ip.py
index 0c5063ed3..95865c690 100755
--- a/src/conf_mode/system-ip.py
+++ b/src/conf_mode/system-ip.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2022 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 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,12 +18,15 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.configverify import verify_route_map
+from vyos.template import render_to_string
from vyos.util import call
from vyos.util import dict_search
from vyos.util import sysctl_write
from vyos.util import write_file
from vyos.xml import defaults
from vyos import ConfigError
+from vyos import frr
from vyos import airbag
airbag.enable()
@@ -40,13 +43,30 @@ def get_config(config=None):
default_values = defaults(base)
opt = dict_merge(default_values, opt)
+ # When working with FRR we need to know the corresponding address-family
+ opt['afi'] = 'ip'
+
+ # We also need the route-map information from the config
+ #
+ # XXX: one MUST always call this without the key_mangling() option! See
+ # vyos.configverify.verify_common_route_maps() for more information.
+ tmp = {'policy' : {'route-map' : conf.get_config_dict(['policy', 'route-map'],
+ get_first_key=True)}}
+ # Merge policy dict into "regular" config dict
+ opt = dict_merge(tmp, opt)
return opt
def verify(opt):
- pass
+ if 'protocol' in opt:
+ for protocol, protocol_options in opt['protocol'].items():
+ if 'route_map' in protocol_options:
+ verify_route_map(protocol_options['route_map'], opt)
+ return
def generate(opt):
- pass
+ if 'protocol' in opt:
+ opt['frr_zebra_config'] = render_to_string('frr/zebra.route-map.frr.j2', opt)
+ return
def apply(opt):
# Apply ARP threshold values
@@ -78,6 +98,18 @@ def apply(opt):
value = '1' if (tmp != None) else '0'
sysctl_write('net.ipv4.fib_multipath_hash_policy', value)
+ if 'protocol' in opt:
+ zebra_daemon = 'zebra'
+ # Save original configuration prior to starting any commit actions
+ frr_cfg = frr.FRRConfig()
+
+ # The route-map used for the FIB (zebra) is part of the zebra daemon
+ frr_cfg.load_configuration(zebra_daemon)
+ frr_cfg.modify_section(r'ip protocol \w+ route-map [-a-zA-Z0-9.]+', stop_pattern='(\s|!)')
+ if 'frr_zebra_config' in opt:
+ frr_cfg.add_before(frr.default_add_before, opt['frr_zebra_config'])
+ frr_cfg.commit_configuration(zebra_daemon)
+
if __name__ == '__main__':
try:
c = get_config()
diff --git a/src/conf_mode/system-ipv6.py b/src/conf_mode/system-ipv6.py
index 26aacf46b..b6d3a79c3 100755
--- a/src/conf_mode/system-ipv6.py
+++ b/src/conf_mode/system-ipv6.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2022 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 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
@@ -19,11 +19,14 @@ import os
from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.configverify import verify_route_map
+from vyos.template import render_to_string
from vyos.util import dict_search
from vyos.util import sysctl_write
from vyos.util import write_file
from vyos.xml import defaults
from vyos import ConfigError
+from vyos import frr
from vyos import airbag
airbag.enable()
@@ -41,13 +44,30 @@ def get_config(config=None):
default_values = defaults(base)
opt = dict_merge(default_values, opt)
+ # When working with FRR we need to know the corresponding address-family
+ opt['afi'] = 'ipv6'
+
+ # We also need the route-map information from the config
+ #
+ # XXX: one MUST always call this without the key_mangling() option! See
+ # vyos.configverify.verify_common_route_maps() for more information.
+ tmp = {'policy' : {'route-map' : conf.get_config_dict(['policy', 'route-map'],
+ get_first_key=True)}}
+ # Merge policy dict into "regular" config dict
+ opt = dict_merge(tmp, opt)
return opt
def verify(opt):
- pass
+ if 'protocol' in opt:
+ for protocol, protocol_options in opt['protocol'].items():
+ if 'route_map' in protocol_options:
+ verify_route_map(protocol_options['route_map'], opt)
+ return
def generate(opt):
- pass
+ if 'protocol' in opt:
+ opt['frr_zebra_config'] = render_to_string('frr/zebra.route-map.frr.j2', opt)
+ return
def apply(opt):
# configure multipath
@@ -78,6 +98,18 @@ def apply(opt):
if name == 'accept_dad':
write_file(os.path.join(root, name), value)
+ if 'protocol' in opt:
+ zebra_daemon = 'zebra'
+ # Save original configuration prior to starting any commit actions
+ frr_cfg = frr.FRRConfig()
+
+ # The route-map used for the FIB (zebra) is part of the zebra daemon
+ frr_cfg.load_configuration(zebra_daemon)
+ frr_cfg.modify_section(r'ipv6 protocol \w+ route-map [-a-zA-Z0-9.]+', stop_pattern='(\s|!)')
+ if 'frr_zebra_config' in opt:
+ frr_cfg.add_before(frr.default_add_before, opt['frr_zebra_config'])
+ frr_cfg.commit_configuration(zebra_daemon)
+
if __name__ == '__main__':
try:
c = get_config()