]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: remove vrf route entries at vrf disabling
authorLouis Scalbert <louis.scalbert@6wind.com>
Thu, 22 Aug 2024 09:12:29 +0000 (11:12 +0200)
committerLouis Scalbert <louis.scalbert@6wind.com>
Mon, 10 Mar 2025 08:54:18 +0000 (09:54 +0100)
This is the continuation of the previous commit.

When a VRF is deleted, the kernel retains only its own routing entries
in the former VRF table and removes all others.

This change ensures that routing entries created by FRR daemons are also
removed from the former zebra VRF table when the VRF is disabled.

To test:

> echo "100 my_table" | tee -a /etc/iproute2/rt_tables
> ip l add du0 type dummy
> ifconfig du0 192.168.0.1/24 up
> ip route add blackhole default table 100
> ip route show table 100
> ip l add red type vrf table 100
> ip l set du0 master red
> vtysh -c 'configure' -c 'vrf red' -c 'ip route 10.0.0.0/24 192.168.0.254'
> vtysh -c 'show ip route table 100'
> sleep 0.1
> ip l del red
> sleep 0.1
> vtysh -c 'show ip route table 100'
> ip l add red type vrf table 100
> ip l set du0 master red
> vtysh -c 'configure' -c 'vrf red' -c 'ip route 10.0.0.0/24 192.168.0.254'
> vtysh -c 'show ip route table 100'
> sleep 0.1
> ip l del red
> sleep 0.1
> vtysh -c 'show ip route table 100'

Fixes: d8612e6 ("zebra: Track tables allocated by vrf and cleanup")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
zebra/zebra_rib.c
zebra/zebra_vrf.c
zebra/zebra_vrf.h

index 8cea605f41b69a647c110fb6969e888a6ccb2dc2..e7ab7a47c569287fa4b94473e8d0a9b77c507ffb 100644 (file)
@@ -903,6 +903,11 @@ void zebra_rtable_node_cleanup(struct route_table *table,
                rib_unlink(node, re);
        }
 
+       zebra_node_info_cleanup(node);
+}
+
+void zebra_node_info_cleanup(struct route_node *node)
+{
        if (node->info) {
                rib_dest_t *dest = node->info;
 
index 7f300671978f75cfcdb7e3294b8ca4bf23ebde9c..7e53a2e8043519ccd0d508de3127482cbb4addf6 100644 (file)
@@ -166,9 +166,10 @@ static int zebra_vrf_enable(struct vrf *vrf)
 static void zebra_vrf_disable_update_vrfid(struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
 {
        struct rib_table_info *info;
-       struct route_entry *re;
-       struct route_node *rn;
+       struct route_entry *re, *nre;
+       struct route_node *rn, *nrn;
        bool empty_table = true;
+       bool rn_delete;
 
        /* Assign the table to the default VRF.
         * Although the table is not technically owned by the default VRF,
@@ -187,13 +188,30 @@ static void zebra_vrf_disable_update_vrfid(struct zebra_vrf *zvrf, afi_t afi, sa
                        continue;
                }
 
-               /* Assign the route entries to the default VRF,
+               /* Assign the kernel route entries to the default VRF,
                 * even though they are not actually owned by it.
+                *
+                * Remove route nodes that have been created by FRR daemons.
+                * They are not needed if the VRF is disabled.
                 */
-               RNODE_FOREACH_RE (rn, re)
-                       nexthop_vrf_update(rn, re, VRF_DEFAULT);
-
-               rn = route_next(rn);
+               rn_delete = true;
+               RNODE_FOREACH_RE_SAFE (rn, re, nre) {
+                       if (re->type == ZEBRA_ROUTE_KERNEL) {
+                               nexthop_vrf_update(rn, re, VRF_DEFAULT);
+                               rn_delete = false;
+                       } else
+                               rib_unlink(rn, re);
+               }
+               if (rn_delete) {
+                       nrn = route_next(rn);
+                       zebra_node_info_cleanup(rn);
+                       rn->info = NULL;
+                       route_unlock_node(rn);
+                       rn = nrn;
+               } else {
+                       empty_table = false;
+                       rn = route_next(rn);
+               }
        }
 
        if (empty_table)
index 334bb93684ab97faf4687f9f766ac001927b88a6..289a8fcc4790c70e5f5199e02128452404075fb8 100644 (file)
@@ -263,6 +263,8 @@ extern void zebra_vrf_init(void);
 
 extern void zebra_rtable_node_cleanup(struct route_table *table,
                                      struct route_node *node);
+extern void zebra_node_info_cleanup(struct route_node *node);
+
 
 #ifdef __cplusplus
 }