summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNataliia Solomko <natalirs1985@gmail.com>2026-07-16 15:16:02 +0300
committerNataliia Solomko <natalirs1985@gmail.com>2026-07-20 12:02:54 +0300
commite72de7eb3e4a6ef67a6836367f43ef363bf77e40 (patch)
treed991699275715c7014524d06d7f4ae4369303173 /src
parentfb6f19f186296f42057cd1685d6f3bb63a5dae39 (diff)
downloadvyos-1x-e72de7eb3e4a6ef67a6836367f43ef363bf77e40.tar.gz
vyos-1x-e72de7eb3e4a6ef67a6836367f43ef363bf77e40.zip
vpp: T8367: Fix identical default MAC on bridged loopback interfaces
VPP assigns loopback interfaces a default MAC address derived only from the interface instance number (de:ad:00:00:00:<instance>), with no host-specific entropy. Two independent VPP nodes configuring the same loopback instance (e.g. as a bridge BVI over VXLAN) therefore end up with an identical MAC address. When that MAC arrives from a peer over the shared L2 segment, VPP's L2 learning logic rejects it as a `mac move violation` - it's statically pinned to the local BVI and cannot legitimately appear on another port. This silently drops ARP traffic between the loopbacks while ordinary bridged client traffic (unique MACs) is unaffected, breaking loopback-to-loopback connectivity. Add a mac-address option to the VPP loopback interface, and fall back to a deterministic, host-unique MAC (derived from host UUID/hostname, same scheme already used for container interfaces) whenever none is configured, so the collision can no longer occur by default. Also fix a related bug found while reproducing the above: a loopback is fully deleted and recreated in VPP on every apply, receiving a new `sw_if_index` each time. The loopback conf_mode script never registered the bridge it's a BVI member of as a dependent, so the bridge kept its L2 membership bound to the stale, deleted index instead of reattaching the current one. Register the bridge dependency and reuse the existing `verify_vpp_remove_bridge_interface()` check to block deleting a loopback still in use as a BVI.
Diffstat (limited to 'src')
-rw-r--r--src/conf_mode/vpp_interfaces_loopback.py10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/conf_mode/vpp_interfaces_loopback.py b/src/conf_mode/vpp_interfaces_loopback.py
index 2f7b59354..c1046fdca 100644
--- a/src/conf_mode/vpp_interfaces_loopback.py
+++ b/src/conf_mode/vpp_interfaces_loopback.py
@@ -24,6 +24,8 @@ from vyos.configdep import set_dependents, call_dependents
from vyos.utils.process import is_systemd_service_active
from vyos.ifconfig.vpp import VPPLoopbackInterface
+from vyos.vpp.config_deps import deps_bridge_dict
+from vyos.vpp.config_verify import verify_vpp_remove_bridge_interface
def get_config(config=None) -> dict:
@@ -55,6 +57,12 @@ def get_config(config=None) -> dict:
no_tag_node_value_mangle=True,
)
+ # Bridge dependency - reattach as BVI after this loopback is recreated
+ config['bridge_members'] = deps_bridge_dict(conf)
+ if ifname in config['bridge_members']:
+ for bridge_iface in config['bridge_members'][ifname]:
+ set_dependents('vpp_interfaces_bridge', conf, bridge_iface)
+
# NAT dependency
if conf.exists(['vpp', 'nat', 'nat44']):
set_dependents('vpp_nat_nat44', conf)
@@ -73,6 +81,8 @@ def verify(config):
if 'remove_vpp' in config:
return None
+ verify_vpp_remove_bridge_interface(config)
+
if not is_systemd_service_active('vpp.service'):
raise ConfigError(
'Cannot configure VPP loopback interface: vpp.service is not running'