summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2019-02-28 15:11:41 +0100
committerDonald Sharp <sharpd@cumulusnetworks.com>2019-03-01 22:30:31 +0100
commitbd4fb6158ddafa10b86a3a382934ed7a8c6e7afc (patch)
treecda82bf20b05620dd5db61112eb7700aba596aa1 /zebra
parentsharpd: Add code to allow nexthops to be watched from non-default vrf (diff)
downloadfrr-bd4fb6158ddafa10b86a3a382934ed7a8c6e7afc.tar.xz
frr-bd4fb6158ddafa10b86a3a382934ed7a8c6e7afc.zip
zebra: Upon vrf deletion, actually release this data.
When a vrf is deleted we need to tell the zebra_router that we have finished using the tables we are keeping track of. This will allow us to properly cleanup the data structures associated with them. This fixes this valgrind error found: ==8579== Invalid read of size 8 ==8579== at 0x430034: zvrf_id (zebra_vrf.h:167) ==8579== by 0x432366: rib_process (zebra_rib.c:1580) ==8579== by 0x432366: process_subq (zebra_rib.c:2092) ==8579== by 0x432366: meta_queue_process (zebra_rib.c:2188) ==8579== by 0x48C99FE: work_queue_run (workqueue.c:291) ==8579== by 0x48C3788: thread_call (thread.c:1607) ==8579== by 0x48A2E9E: frr_run (libfrr.c:1011) ==8579== by 0x41316A: main (main.c:473) ==8579== Address 0x5aeb750 is 0 bytes inside a block of size 4,424 free'd ==8579== at 0x4839A0C: free (vg_replace_malloc.c:540) ==8579== by 0x438914: zebra_vrf_delete (zebra_vrf.c:279) ==8579== by 0x48C4225: vrf_delete (vrf.c:243) ==8579== by 0x48C4225: vrf_delete (vrf.c:217) ==8579== by 0x4151CE: netlink_vrf_change (if_netlink.c:364) ==8579== by 0x416810: netlink_link_change (if_netlink.c:1189) ==8579== by 0x41C1FC: netlink_parse_info (kernel_netlink.c:904) ==8579== by 0x41C2D3: kernel_read (kernel_netlink.c:389) ==8579== by 0x48C3788: thread_call (thread.c:1607) ==8579== by 0x48A2E9E: frr_run (libfrr.c:1011) ==8579== by 0x41316A: main (main.c:473) ==8579== Block was alloc'd at ==8579== at 0x483AB1A: calloc (vg_replace_malloc.c:762) ==8579== by 0x48A6030: qcalloc (memory.c:110) ==8579== by 0x4389EF: zebra_vrf_alloc (zebra_vrf.c:382) ==8579== by 0x438A42: zebra_vrf_new (zebra_vrf.c:93) ==8579== by 0x48C40AD: vrf_get (vrf.c:209) ==8579== by 0x415144: netlink_vrf_change (if_netlink.c:319) ==8579== by 0x415E90: netlink_interface (if_netlink.c:653) ==8579== by 0x41C1FC: netlink_parse_info (kernel_netlink.c:904) ==8579== by 0x4163E8: interface_lookup_netlink (if_netlink.c:760) ==8579== by 0x42BB37: zebra_ns_enable (zebra_ns.c:130) ==8579== by 0x42BC5E: zebra_ns_init (zebra_ns.c:208) ==8579== by 0x4130F4: main (main.c:401) This can be found by: `ip link del <VRF DEVICE NAME>` then `ip link add <NAME> type vrf table X` again and then attempting to use the vrf. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'zebra')
-rw-r--r--zebra/zebra_router.c21
-rw-r--r--zebra/zebra_router.h2
-rw-r--r--zebra/zebra_vrf.c13
3 files changed, 30 insertions, 6 deletions
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index c3b861c24..cabc8be8d 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -168,10 +168,31 @@ static void zebra_router_free_table(struct zebra_router_table *zrt)
table_info = route_table_get_info(zrt->table);
route_table_finish(zrt->table);
+ RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
+
XFREE(MTYPE_RIB_TABLE_INFO, table_info);
XFREE(MTYPE_ZEBRA_NS, zrt);
}
+void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
+ afi_t afi, safi_t safi)
+{
+ struct zebra_router_table finder;
+ struct zebra_router_table *zrt;
+
+ memset(&finder, 0, sizeof(finder));
+ finder.afi = afi;
+ finder.safi = safi;
+ finder.tableid = tableid;
+ finder.ns_id = zvrf->zns->ns_id;
+ zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
+
+ if (!zrt)
+ return;
+
+ zebra_router_free_table(zrt);
+}
+
uint32_t zebra_router_get_next_sequence(void)
{
return 1
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index fb2849591..e5043f38a 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -117,6 +117,8 @@ extern struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf,
extern struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
uint32_t tableid, afi_t afi,
safi_t safi);
+extern void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
+ afi_t afi, safi_t safi);
extern int zebra_router_config_write(struct vty *vty);
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index d18305495..390c01dc6 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -208,8 +208,11 @@ static int zebra_vrf_disable(struct vrf *vrf)
* table, see rib_close_table above
* we no-longer need this pointer.
*/
- for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
+ for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
+ zebra_router_release_table(zvrf, zvrf->table_id, afi,
+ safi);
zvrf->table[afi][safi] = NULL;
+ }
route_table_finish(zvrf->rnh_table[afi]);
zvrf->rnh_table[afi] = NULL;
@@ -256,14 +259,12 @@ static int zebra_vrf_delete(struct vrf *vrf)
/* release allocated memory */
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
- void *table_info;
-
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
table = zvrf->table[afi][safi];
if (table) {
- table_info = route_table_get_info(table);
- route_table_finish(table);
- XFREE(MTYPE_RIB_TABLE_INFO, table_info);
+ zebra_router_release_table(zvrf, zvrf->table_id,
+ afi, safi);
+ zvrf->table[afi][safi] = NULL;
}
}