diff options
Diffstat (limited to 'src/conf_mode/protocols_ospfv3.py')
-rwxr-xr-x | src/conf_mode/protocols_ospfv3.py | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py index f1e490f48..d0460b830 100755 --- a/src/conf_mode/protocols_ospfv3.py +++ b/src/conf_mode/protocols_ospfv3.py @@ -17,6 +17,7 @@ import os from sys import exit +from sys import argv from vyos.config import Config from vyos.configdict import dict_merge @@ -24,6 +25,7 @@ from vyos.configdict import node_changed from vyos.configverify import verify_common_route_maps from vyos.template import render_to_string from vyos.ifconfig import Interface +from vyos.util import get_interface_config from vyos.xml import defaults from vyos import ConfigError from vyos import frr @@ -35,9 +37,22 @@ def get_config(config=None): conf = config else: conf = Config() - base = ['protocols', 'ospfv3'] + + vrf = None + if len(argv) > 1: + vrf = argv[1] + + base_path = ['protocols', 'ospfv3'] + + # eqivalent of the C foo ? 'a' : 'b' statement + base = vrf and ['vrf', 'name', vrf, 'protocols', 'ospfv3'] or base_path ospfv3 = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) + # Assign the name of our VRF context. This MUST be done before the return + # statement below, else on deletion we will delete the default instance + # instead of the VRF instance. + if vrf: ospfv3['vrf'] = vrf + # 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 @@ -69,12 +84,22 @@ def verify(ospfv3): verify_common_route_maps(ospfv3) if 'interface' in ospfv3: - for ifname, if_config in ospfv3['interface'].items(): - if 'ifmtu' in if_config: - mtu = Interface(ifname).get_mtu() - if int(if_config['ifmtu']) > int(mtu): + for interface, interface_config in ospfv3['interface'].items(): + if 'ifmtu' in interface_config: + mtu = Interface(interface).get_mtu() + if int(interface_config['ifmtu']) > int(mtu): raise ConfigError(f'OSPFv3 ifmtu can not exceed physical MTU of "{mtu}"') + # If interface specific options are set, we must ensure that the + # interface is bound to our requesting VRF. Due to the VyOS + # priorities the interface is bound to the VRF after creation of + # the VRF itself, and before any routing protocol is configured. + if 'vrf' in ospfv3: + vrf = ospfv3['vrf'] + tmp = get_interface_config(interface) + if 'master' not in tmp or tmp['master'] != vrf: + raise ConfigError(f'Interface {interface} is not a member of VRF {vrf}!') + return None def generate(ospfv3): @@ -89,14 +114,21 @@ def apply(ospfv3): # Save original configuration prior to starting any commit actions frr_cfg = frr.FRRConfig() + + # Generate empty helper string which can be ammended to FRR commands, it + # will be either empty (default VRF) or contain the "vrf <name" statement + vrf = '' + if 'vrf' in ospfv3: + vrf = ' vrf ' + ospfv3['vrf'] + frr_cfg.load_configuration(ospf6_daemon) - frr_cfg.modify_section('^router ospf6', stop_pattern='^exit', remove_stop_mark=True) + frr_cfg.modify_section(f'^router ospf6{vrf}', stop_pattern='^exit', remove_stop_mark=True) for key in ['interface', 'interface_removed']: if key not in ospfv3: continue for interface in ospfv3[key]: - frr_cfg.modify_section(f'^interface {interface}', stop_pattern='^exit', remove_stop_mark=True) + frr_cfg.modify_section(f'^interface {interface}{vrf}', stop_pattern='^exit', remove_stop_mark=True) if 'new_frr_config' in ospfv3: frr_cfg.add_before(frr.default_add_before, ospfv3['new_frr_config']) |