From 71349e0358634c099b1c2b3d63a5dca3ad103578 Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Sat, 19 Aug 2017 17:28:58 -0700 Subject: [PATCH] zebra: lookup link by ifindex Frr has an assumption that when interface A links to B, we already know about B. But that might be true always. It is probably purely depends on the configuration and how the interfaces are hashed in Kernel. FRR seems to sometimes get "A is linked to B" before it knows about B, in that case, the linkage between the data structure for A & B won't be proper. Ticket: CM-17679 Review: ccr-6628 Testing: Manual Signed-off-by: Mitesh Kanjariya --- zebra/interface.c | 6 ++++-- zebra/rt_netlink.c | 3 ++- zebra/zebra_vxlan.c | 39 +++++++++++++++++++++++++++++++++------ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/zebra/interface.c b/zebra/interface.c index c4d0363994..8456984330 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -874,7 +874,8 @@ void if_up(struct interface *ifp) link_if = ifp; zebra_vxlan_svi_up(ifp, link_if); } else if (IS_ZEBRA_IF_VLAN(ifp)) { - link_if = zif->link; + link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + zif->link_ifindex); if (link_if) zebra_vxlan_svi_up(ifp, link_if); } @@ -902,7 +903,8 @@ void if_down(struct interface *ifp) link_if = ifp; zebra_vxlan_svi_down(ifp, link_if); } else if (IS_ZEBRA_IF_VLAN(ifp)) { - link_if = zif->link; + link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + zif->link_ifindex); if (link_if) zebra_vxlan_svi_down(ifp, link_if); } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index e28fe5630a..6763a9a82e 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2005,7 +2005,8 @@ static int netlink_ipneigh_change(struct sockaddr_nl *snl, struct nlmsghdr *h, * itself */ if (IS_ZEBRA_IF_VLAN(ifp)) { - link_if = zif->link; + link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + zif->link_ifindex); if (!link_if) return 0; } else if (IS_ZEBRA_IF_BRIDGE(ifp)) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 86c3ce1d00..32c0e20a91 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1777,6 +1777,9 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if) vlanid_t vid = 0; zebra_vni_t *zvni; + if (!br_if) + return NULL; + /* Make sure the linked interface is a bridge. */ if (!IS_ZEBRA_IF_BRIDGE(br_if)) return NULL; @@ -3886,7 +3889,11 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, if (!ifp_zif) return -1; - svi_if = ifp_zif->link; + /* + * for a MACVLAN interface the link represents the svi_if + */ + svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + ifp_zif->link_ifindex); if (!svi_if) { zlog_err("%u:MACVLAN %s(%u) without link information", ifp->vrf_id, ifp->name, ifp->ifindex); @@ -3894,19 +3901,39 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, } if (IS_ZEBRA_IF_VLAN(svi_if)) { + /* + * If it is a vlan aware bridge then the link gives the + * bridge information + */ + struct interface *svi_if_link = NULL; + svi_if_zif = svi_if->info; - if (svi_if_zif) - zvni = zvni_map_svi(svi_if, svi_if_zif->link); + if (svi_if_zif) { + svi_if_link = if_lookup_by_index_per_ns( + zebra_ns_lookup( + NS_DEFAULT), + svi_if_zif->link_ifindex); + zvni = zvni_map_svi(svi_if, svi_if_link); + } } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) { + /* + * If it is a vlan unaware bridge then svi is the bridge + * itself + */ zvni = zvni_map_svi(svi_if, svi_if); } } else if (IS_ZEBRA_IF_VLAN(ifp)) { struct zebra_if *svi_if_zif = - NULL; /* Zebra daemon specific info for SVI*/ + NULL; /* Zebra daemon specific info for SVI */ + struct interface *svi_if_link = + NULL; /* link info for the SVI = bridge info */ svi_if_zif = ifp->info; - if (svi_if_zif) - zvni = zvni_map_svi(ifp, svi_if_zif->link); + svi_if_link = + if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + svi_if_zif->link_ifindex); + if (svi_if_zif && svi_if_link) + zvni = zvni_map_svi(ifp, svi_if_link); } else if (IS_ZEBRA_IF_BRIDGE(ifp)) { zvni = zvni_map_svi(ifp, ifp); } -- 2.39.5