]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: use ifindex vs ifp to avoid use-after-free on shutdown
authorChristian Hopps <chopps@labn.net>
Tue, 30 May 2023 00:29:33 +0000 (20:29 -0400)
committerChristian Hopps <chopps@labn.net>
Tue, 30 May 2023 08:09:29 +0000 (04:09 -0400)
Signed-off-by: Christian Hopps <chopps@labn.net>
zebra/zebra_evpn_mh.c
zebra/zebra_evpn_mh.h

index 49120c2877cce3608d3d1c18e35f1d76d8ecdd67..a5092c629ac7d32d29b1a6f10d0afcb71ba6aedb 100644 (file)
@@ -535,19 +535,26 @@ static bool zebra_evpn_acc_vl_cmp(const void *p1, const void *p2)
 }
 
 /* Lookup VLAN based broadcast domain */
-struct zebra_evpn_access_bd *zebra_evpn_acc_vl_find(vlanid_t vid,
-                                                   struct interface *br_if)
+struct zebra_evpn_access_bd *
+zebra_evpn_acc_vl_find_index(vlanid_t vid, ifindex_t bridge_ifindex)
 {
        struct zebra_evpn_access_bd *acc_bd;
        struct zebra_evpn_access_bd tmp;
 
        tmp.vid = vid;
-       tmp.bridge_ifindex = br_if->ifindex;
+       tmp.bridge_ifindex = bridge_ifindex;
        acc_bd = hash_lookup(zmh_info->evpn_vlan_table, &tmp);
 
        return acc_bd;
 }
 
+/* Lookup VLAN based broadcast domain */
+struct zebra_evpn_access_bd *zebra_evpn_acc_vl_find(vlanid_t vid,
+                                                   struct interface *br_if)
+{
+       return zebra_evpn_acc_vl_find_index(vid, br_if->ifindex);
+}
+
 /* A new broadcast domain can be created when a VLAN member or VLAN<=>VxLAN_IF
  * mapping is added.
  */
@@ -842,9 +849,9 @@ void zebra_evpn_access_bd_bridge_cleanup(vlanid_t vid, struct interface *br_if,
 void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, struct zebra_evpn *zevpn,
                             bool set)
 {
-       struct interface *br_if;
        struct zebra_vxlan_vni *vni;
        struct zebra_evpn_access_bd *acc_bd;
+       ifindex_t br_ifindex;
 
        if (!zif)
                return;
@@ -854,11 +861,12 @@ void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, struct zebra_evpn *zevpn,
        if (!vni)
                return;
 
-       br_if = zif->brslave_info.br_if;
-       if (!br_if)
+       /* Use the index as the pointer can be stale (deleted) */
+       br_ifindex = zif->brslave_info.bridge_ifindex;
+       if (!zif->brslave_info.br_if || br_ifindex == IFINDEX_INTERNAL)
                return;
 
-       acc_bd = zebra_evpn_acc_vl_find(vni->access_vlan, br_if);
+       acc_bd = zebra_evpn_acc_vl_find_index(vni->access_vlan, br_ifindex);
        if (!acc_bd)
                return;
 
index 6dda30a57fefb033b4a8f91558f35bcc972f2e7d..59a41d06069984f11078cc3d41d0b632a1781c1f 100644 (file)
@@ -344,6 +344,8 @@ extern void zebra_evpn_if_es_print(struct vty *vty, json_object *json,
                                   struct zebra_if *zif);
 extern struct zebra_evpn_access_bd *
 zebra_evpn_acc_vl_find(vlanid_t vid, struct interface *br_if);
+struct zebra_evpn_access_bd *
+zebra_evpn_acc_vl_find_index(vlanid_t vid, ifindex_t bridge_ifindex);
 extern void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid,
                                       struct interface *br_if);
 extern void zebra_evpn_es_cleanup(void);