summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2026-05-21 14:35:56 +0100
committerGitHub <noreply@github.com>2026-05-21 14:35:56 +0100
commit097573dda926df118532f7479e1244b7d7a83e08 (patch)
treeec8ade85127be6baa3372fc6fcd1b3c55295b69a /src
parenta367f7adc56ac01cd6ef7db93564d53b48bb2610 (diff)
parentfea16e41f9a3f4aef4251786b7d157e781368cb9 (diff)
downloadvyos-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-xsrc/conf_mode/interfaces_wireguard.py34
-rwxr-xr-xsrc/conf_mode/vrf.py6
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}')