diff options
| author | Daniil Baturin <daniil@vyos.io> | 2026-05-21 14:35:56 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-21 14:35:56 +0100 |
| commit | 097573dda926df118532f7479e1244b7d7a83e08 (patch) | |
| tree | ec8ade85127be6baa3372fc6fcd1b3c55295b69a /src | |
| parent | a367f7adc56ac01cd6ef7db93564d53b48bb2610 (diff) | |
| parent | fea16e41f9a3f4aef4251786b7d157e781368cb9 (diff) | |
| download | vyos-1x-097573dda926df118532f7479e1244b7d7a83e08.tar.gz vyos-1x-097573dda926df118532f7479e1244b7d7a83e08.zip | |
Merge pull request #5175 from natali-rs1985/T8509
wireguard: T8509: Add fwmark ip rules for VRF-bound interfaces
Diffstat (limited to 'src')
| -rwxr-xr-x | src/conf_mode/interfaces_wireguard.py | 34 | ||||
| -rwxr-xr-x | src/conf_mode/vrf.py | 6 |
2 files changed, 40 insertions, 0 deletions
diff --git a/src/conf_mode/interfaces_wireguard.py b/src/conf_mode/interfaces_wireguard.py index b430fa94a..92e3a239d 100755 --- a/src/conf_mode/interfaces_wireguard.py +++ b/src/conf_mode/interfaces_wireguard.py @@ -34,6 +34,7 @@ from vyos.configverify import verify_bond_bridge_member from vyos.ifconfig import WireGuardIf from vyos.utils.kernel import check_kmod from vyos.utils.network import check_port_availability +from vyos.utils.network import get_vrf_tableid from vyos.utils.network import is_wireguard_key_pair from vyos.utils.process import call from vyos import ConfigError @@ -75,6 +76,16 @@ def get_config(config=None): else: wireguard['is_source_interface'] = tmp + if is_node_changed(conf, base + [ifname, 'fwmark']) or is_node_changed( + conf, base + [ifname, 'vrf'] + ): + wireguard['fwmark_vrf_changed'] = {} + prev = conf.get_config_dict( + base + [ifname], effective=True, key_mangling=('-', '_'), get_first_key=True + ) + wireguard['prev_fwmark'] = prev.get('fwmark') + wireguard['prev_vrf'] = prev.get('vrf') + return wireguard @@ -154,6 +165,29 @@ def apply(wireguard): else: wg.update(wireguard) + # delete old fwmark-based ip rule if fwmark or VRF was changed + if 'fwmark_vrf_changed' in wireguard or 'deleted' in wireguard: + prev_fwmark = wireguard.get('prev_fwmark') + prev_vrf = wireguard.get('prev_vrf') + if prev_fwmark is not None and prev_vrf is not None: + table_id = get_vrf_tableid(prev_vrf) + if table_id is not None: + for afi in ['-4', '-6']: + call( + f'ip {afi} rule del pref 1998 fwmark {prev_fwmark} table {table_id}' + ) + + # Add ip rule to route fwmark-marked WireGuard tunnel packets into the + # correct VRF routing table. This is required for VRF-bound WireGuard + # interfaces with fwmark set, so that outgoing encapsulated packets use the + # proper VRF routes (otherwise, they may be unroutable or use the main table). + if wireguard.get('fwmark', '0') != '0' and 'vrf' in wireguard: + table_id = get_vrf_tableid(wireguard['vrf']) + for afi in ['-4', '-6']: + call( + f'ip {afi} rule add pref 1998 fwmark {wireguard["fwmark"]} table {table_id}' + ) + domain_resolver_usage = '/run/use-vyos-domain-resolver-interfaces-wireguard-' + wireguard['ifname'] ## DOMAIN RESOLVER diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py index 92bb956ed..c307ae27e 100755 --- a/src/conf_mode/vrf.py +++ b/src/conf_mode/vrf.py @@ -265,6 +265,12 @@ def apply(vrf): # Remove map element cmd(f'nft {nft_del_element}') + # Remove all ip rules pointing to this VRF table + table_id = get_vrf_tableid(tmp) + for afi in ['-4', '-6']: + while call(f'ip {afi} rule del table {table_id}') == 0: + pass + # Delete the VRF Kernel interface call(f'ip link delete dev {tmp}') |
