From 52645d4339efe63b335f62932f8212f0a7232c56 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 12 Oct 2022 21:21:00 +0200 Subject: [PATCH] zebra: crash when deleting a vrf with a l3vni inside The following crash happens when deleting a vrf with a L3VNI vxlan interface associated to that vrf: Thread 1 (Thread 0x7fc2eb121e40 (LWP 11516)): #0 raise (sig=) at ../sysdeps/unix/sysv/linux/raise.c:50 #1 0x00007fc2eb774a04 in core_handler (signo=11, siginfo=0x7fff26102830, context=0x7fff26102700) at /build/tools-build-framework/output/_packages/cp-routing/src/lib/sigevent.c:262 #2 #3 0x00007fc2eb716ffb in hash_get (hash=0x55af78ece860, data=0x7fff26102be0, alloc_func=0x55af76f52f60 ) at /build/tools-build-framework/output/_packages/cp-routing/src/lib/hash.c:157 #4 0x000055af76f530f8 in zebra_evpn_add (vni=101) at /build/tools-build-framework/output/_packages/cp-routing/src/zebra/zebra_evpn.c:1023 #5 0x000055af76fb64c5 in zebra_vxlan_handle_vni_transition (zvrf=0x55af78ed0220, vni=101, add=0) at /build/tools-build-framework/output/_packages/cp-routing/src/zebra/zebra_vxlan.c:2080 #6 0x000055af76fbd94f in zebra_vxlan_vrf_delete (zvrf=0x55af78ed0220) at /build/tools-build-framework/output/_packages/cp-routing/src/zebra/zebra_vxlan.c:5364 zl3vni = 0x55af78fffb20 vni = 101 #7 0x000055af76fa13bb in zebra_vrf_delete (vrf=0x55af78ed0140) at /build/tools-build-framework/output/_packages/cp-routing/src/zebra/zebra_vrf.c:312 #8 0x00007fc2eb791330 in vrf_delete (vrf=0x55af78ed0140) at /build/tools-build-framework/output/_packages/cp-routing/src/lib/vrf.c:295 #9 0x00007fc2eb791b55 in vrf_terminate_single (vrf=0x55af78ed0140) at /build/tools-build-framework/output/_packages/cp-routing/src/lib/vrf.c:597 #10 0x00007fc2eb791c41 in vrf_terminate () at /build/tools-build-framework/output/_packages/cp-routing/src/lib/vrf.c:624 #11 0x000055af76f1c8a6 in sigint () at /build/tools-build-framework/output/_packages/cp-routing/src/zebra/main.c:191 #12 0x00007fc2eb774757 in quagga_sigevent_process () at /build/tools-build-framework/output/_packages/cp-routing/src/lib/sigevent.c:130 #13 0x00007fc2eb78cf9b in thread_fetch (m=0x55af78ccc3f0, fetch=0x7fff26102f20) at /build/tools-build-framework/output/_packages/cp-routing/src/lib/thread.c:1631 #14 0x00007fc2eb728e8c in frr_run (master=0x55af78ccc3f0) at /build/tools-build-framework/output/_packages/cp-routing/src/lib/libfrr.c:1154 #15 0x000055af76f1ce36 in main (argc=6, argv=0x7fff261031e8) at /build/tools-build-framework/output/_packages/cp-routing/src/zebra/main.c:487 Because vrf_disable is called first, zvrf->evpn_table may be freed. But because we call vrf_delete, we may still want to handle VNI transition to L2. And we dont check the evpn_table pointer. Do the check. Signed-off-by: Philippe Guibert --- zebra/zebra_evpn.c | 2 ++ zebra/zebra_vxlan.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index f207477445d3..cbe093d3b45b 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -1017,6 +1017,8 @@ struct zebra_evpn *zebra_evpn_add(vni_t vni) struct zebra_evpn *zevpn = NULL; zvrf = zebra_vrf_get_evpn(); + if (!zvrf->evpn_table) + return NULL; memset(&tmp_zevpn, 0, sizeof(tmp_zevpn)); tmp_zevpn.vni = vni; zevpn = hash_get(zvrf->evpn_table, &tmp_zevpn, zebra_evpn_alloc); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 7e86d15b4b43..3333db1b1fb8 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -2176,6 +2176,8 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, return 0; zevpn = zebra_evpn_add(vni); + if (!zevpn) + return -1; /* Find bridge interface for the VNI */ vlan_if = zvni_map_to_svi(vxl->access_vlan, @@ -5913,6 +5915,7 @@ void zebra_vxlan_close_tables(struct zebra_vrf *zvrf) return; hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf); hash_free(zvrf->evpn_table); + zvrf->evpn_table = NULL; if (zvrf->vxlan_sg_table) { zebra_vxlan_cleanup_sg_table(zvrf); hash_free(zvrf->vxlan_sg_table);