]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: zvni_from_svi() adaptation for other network namespaces
authorPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 27 Sep 2019 09:17:20 +0000 (11:17 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 21 Sep 2020 07:17:09 +0000 (09:17 +0200)
other network namespaces are parsed because bridge interface can be
bridged with vxlan interfaces with a link in the default vrf that hosts
l2vpn.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
zebra/zebra_evpn.c

index 73df93258e440dd84cb3cb181b425b9f58cdc11f..b704c32c5c4490e28c1211ed2fa2afb33a605cc6 100644 (file)
@@ -675,51 +675,35 @@ zebra_evpn_t *zebra_evpn_map_vlan(struct interface *ifp,
        return zevpn;
 }
 
-/*
- * Map SVI and associated bridge to an EVPN. This is invoked upon getting
- * neighbor notifications, to see if they are of interest.
- */
-zebra_evpn_t *zebra_evpn_from_svi(struct interface *ifp,
-                                 struct interface *br_if)
+struct zevpn_from_svi_param {
+       struct interface *br_if;
+       struct zebra_if *zif;
+       uint8_t bridge_vlan_aware;
+       vlanid_t vid;
+};
+
+static int zebra_evpn_from_svi_zns(struct zebra_ns *zns,
+                                  void *_in_param,
+                                  void **_p_zevpn)
 {
-       struct zebra_ns *zns;
        struct route_node *rn;
+       struct interface *br_if;
+       zebra_evpn_t **p_zevpn = (zebra_evpn_t **)_p_zevpn;
+       zebra_evpn_t *zevpn;
        struct interface *tmp_if = NULL;
        struct zebra_if *zif;
-       struct zebra_l2info_bridge *br;
        struct zebra_l2info_vxlan *vxl = NULL;
-       uint8_t bridge_vlan_aware;
-       vlanid_t vid = 0;
-       zebra_evpn_t *zevpn;
+       struct zevpn_from_svi_param *in_param =
+               (struct zevpn_from_svi_param *)_in_param;
        int found = 0;
 
-       if (!br_if)
-               return NULL;
-
-       /* Make sure the linked interface is a bridge. */
-       if (!IS_ZEBRA_IF_BRIDGE(br_if))
-               return NULL;
-
-       /* Determine if bridge is VLAN-aware or not */
-       zif = br_if->info;
+       if (!in_param)
+               return ZNS_WALK_STOP;
+       br_if = in_param->br_if;
+       zif = in_param->zif;
        assert(zif);
-       br = &zif->l2info.br;
-       bridge_vlan_aware = br->vlan_aware;
-       if (bridge_vlan_aware) {
-               struct zebra_l2info_vlan *vl;
 
-               if (!IS_ZEBRA_IF_VLAN(ifp))
-                       return NULL;
-
-               zif = ifp->info;
-               assert(zif);
-               vl = &zif->l2info.vl;
-               vid = vl->vid;
-       }
-
-       /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
        /* TODO: Optimize with a hash. */
-       zns = zebra_ns_lookup(NS_DEFAULT);
        for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
                tmp_if = (struct interface *)rn->info;
                if (!tmp_if)
@@ -734,16 +718,67 @@ zebra_evpn_t *zebra_evpn_from_svi(struct interface *ifp,
                if (zif->brslave_info.br_if != br_if)
                        continue;
 
-               if (!bridge_vlan_aware || vxl->access_vlan == vid) {
+               if (!in_param->bridge_vlan_aware
+                   || vxl->access_vlan == in_param->vid) {
                        found = 1;
                        break;
                }
        }
 
        if (!found)
-               return NULL;
+               return ZNS_WALK_CONTINUE;
 
        zevpn = zebra_evpn_lookup(vxl->vni);
+       if (p_zevpn)
+               *p_zevpn = zevpn;
+       return ZNS_WALK_STOP;
+}
+
+/*
+ * Map SVI and associated bridge to an EVPN. This is invoked upon getting
+ * neighbor notifications, to see if they are of interest.
+ */
+zebra_evpn_t *zebra_evpn_from_svi(struct interface *ifp,
+                                 struct interface *br_if)
+{
+       struct zebra_l2info_bridge *br;
+       zebra_evpn_t *zevpn = NULL;
+       zebra_evpn_t **p_zevpn;
+       struct zebra_if *zif;
+       struct zevpn_from_svi_param in_param;
+
+       if (!br_if)
+               return NULL;
+
+       /* Make sure the linked interface is a bridge. */
+       if (!IS_ZEBRA_IF_BRIDGE(br_if))
+               return NULL;
+
+       /* Determine if bridge is VLAN-aware or not */
+       zif = br_if->info;
+       assert(zif);
+       br = &zif->l2info.br;
+       in_param.bridge_vlan_aware = br->vlan_aware;
+       in_param.vid = 0;
+
+       if (in_param.bridge_vlan_aware) {
+               struct zebra_l2info_vlan *vl;
+
+               if (!IS_ZEBRA_IF_VLAN(ifp))
+                       return NULL;
+
+               zif = ifp->info;
+               assert(zif);
+               vl = &zif->l2info.vl;
+               in_param.vid = vl->vid;
+       }
+
+       in_param.br_if = br_if;
+       in_param.zif = zif;
+       p_zevpn = &zevpn;
+       /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
+       zebra_ns_list_walk(zebra_evpn_from_svi_zns, (void *)&in_param,
+                          (void **)p_zevpn);
        return zevpn;
 }