From 2355e4973365b0ea3f14737f894636973e656b16 Mon Sep 17 00:00:00 2001 From: Alexander Chernavin Date: Fri, 19 May 2023 15:43:06 +0000 Subject: linux-cp: update adjs for subifs too when mac changes The plugin creates and manages adjacencies for the physical interface in each interface pair (they are part of the x-connect feature). When a link update notification is received from the host system, MAC address of the corresponding physical interface is updated (as needed) as well as previously created adjacencies for it (because a new rewrite string needs to be generated). Subinterfaces inherit MAC address from the parent interface. When MAC address of the parent interface changes, it also implies MAC address change for its subinterfaces. The problem is that this is currently not considered in the plugin. After MAC address update on the parent interface, packets sent from subinterfaces might have wrong source MAC address. For example, IPv6 Neighbor Solicitation messages will be sent with the wrong (previous) MAC address and neighbor discovery will fail. With this fix, when the plugin updates adjacencies for a physical interface, it will also update adjacencies for the subinterfaces with existing interface pair. Type: fix Change-Id: Ia5f617197e33cb79b9b025c02c2c126c31a551ec Signed-off-by: Alexander Chernavin --- src/plugins/linux-cp/lcp_router.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/plugins/linux-cp/lcp_router.c b/src/plugins/linux-cp/lcp_router.c index c5846cfca3c..ad701c5ceda 100644 --- a/src/plugins/linux-cp/lcp_router.c +++ b/src/plugins/linux-cp/lcp_router.c @@ -272,6 +272,25 @@ lcp_router_link_mtu (struct rtnl_link *rl, u32 sw_if_index) vnet_sw_interface_set_mtu (vnm, sw->sw_if_index, mtu); } +static walk_rc_t +lcp_router_link_addr_adj_upd_cb (vnet_main_t *vnm, u32 sw_if_index, void *arg) +{ + lcp_itf_pair_t *lip; + + lip = lcp_itf_pair_get (lcp_itf_pair_find_by_phy (sw_if_index)); + if (!lip) + { + return WALK_CONTINUE; + } + + vnet_update_adjacency_for_sw_interface (vnm, lip->lip_phy_sw_if_index, + lip->lip_phy_adjs.adj_index[AF_IP4]); + vnet_update_adjacency_for_sw_interface (vnm, lip->lip_phy_sw_if_index, + lip->lip_phy_adjs.adj_index[AF_IP6]); + + return WALK_CONTINUE; +} + static void lcp_router_link_addr (struct rtnl_link *rl, lcp_itf_pair_t *lip) { @@ -301,10 +320,8 @@ lcp_router_link_addr (struct rtnl_link *rl, lcp_itf_pair_t *lip) mac_addr_bytes); /* mcast adjacencies need to be updated */ - vnet_update_adjacency_for_sw_interface (vnm, lip->lip_phy_sw_if_index, - lip->lip_phy_adjs.adj_index[AF_IP4]); - vnet_update_adjacency_for_sw_interface (vnm, lip->lip_phy_sw_if_index, - lip->lip_phy_adjs.adj_index[AF_IP6]); + vnet_hw_interface_walk_sw (vnm, hw->hw_if_index, + lcp_router_link_addr_adj_upd_cb, NULL); } static void lcp_router_table_flush (lcp_router_table_t *nlt, -- cgit 1.2.3-korg