diff options
author | zsdc <taras@vyos.io> | 2021-07-12 22:59:48 +0300 |
---|---|---|
committer | zsdc <taras@vyos.io> | 2021-07-17 22:36:39 +0300 |
commit | 22791e26f444766dc9f9e1729b72893208f58079 (patch) | |
tree | e412fd0e8247c3fc11b9f90d33646aafaf29247c /python/vyos | |
parent | 83721c1ce672b76d40c710f38b0ab05c370a2191 (diff) | |
download | vyos-1x-22791e26f444766dc9f9e1729b72893208f58079.tar.gz vyos-1x-22791e26f444766dc9f9e1729b72893208f58079.zip |
VRF: T3655: proper connection tracking for VRFs
Currently, all VRFs share the same connection tracking table, which can
lead to problems:
- traffic leaks to a wrong VRF
- improper NAT rules handling when multiple VRFs contain the same IP
networks
- stateful firewall rules issues
The commit implements connection tracking zones support. Each VRF
utilizes its own zone, so connections will never mix up.
It also adds some restrictions to VRF names and assigned table numbers,
because of nftables and conntrack requirements:
- VRF name should always start from a letter (interfaces that start from
numbers are not supported in nftables rules)
- table number must be in the 100-65535 range because conntrack supports
only 65535 zones
Diffstat (limited to 'python/vyos')
-rwxr-xr-x[-rw-r--r--] | python/vyos/ifconfig/interface.py | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 08b7af90b..a1928ba51 100644..100755 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -311,6 +311,28 @@ class Interface(Control): cmd = 'ip link del dev {ifname}'.format(**self.config) return self._cmd(cmd) + def _set_vrf_ct_zone(self, vrf): + """ + Add/Remove rules in nftables to associate traffic in VRF to an + individual conntack zone + """ + if vrf: + # Get routing table ID for VRF + vrf_table_id = get_interface_config(vrf).get('linkinfo', {}).get( + 'info_data', {}).get('table') + # Add map element with interface and zone ID + if vrf_table_id: + self._cmd( + f'nft add element inet vrf_zones ct_iface_map {{ "{self.ifname}" : {vrf_table_id} }}' + ) + else: + nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{self.ifname}" }}' + # Check if deleting is possible first to avoid raising errors + _, err = self._popen(f'nft -c {nft_del_element}') + if not err: + # Remove map element + self._cmd(f'nft {nft_del_element}') + def get_min_mtu(self): """ Get hardware minimum supported MTU @@ -401,6 +423,7 @@ class Interface(Control): >>> Interface('eth0').set_vrf() """ self.set_interface('vrf', vrf) + self._set_vrf_ct_zone(vrf) def set_arp_cache_tmo(self, tmo): """ |