]> git.proxmox.com Git - mirror_frr.git/commitdiff
staticd: install static routes in a vrf when next-hop interface comes up
authorDon Slice <dslice@cumulusnetworks.com>
Thu, 8 Nov 2018 19:47:27 +0000 (19:47 +0000)
committerDon Slice <dslice@cumulusnetworks.com>
Mon, 12 Nov 2018 15:08:11 +0000 (15:08 +0000)
Problem reported with cross-vrf static routes that the routes weren't
installed when the target interface is bounced.  Determined that we did
not initiate re-install of the statics in that particular case, so added
it. Test case previously failing now passes.

Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
staticd/static_routes.c
staticd/static_routes.h
staticd/static_zebra.c

index cd0330ed82065a17fa5a45af0a425103fb49b95e..7fbeb178527563d2f15adecfa98e21ab08d40254 100644 (file)
@@ -497,6 +497,67 @@ void static_cleanup_vrf_ids(struct static_vrf *disable_svrf)
        }
 }
 
+/*
+ * This function enables static routes when an interface it relies
+ * on in a different vrf is coming up.
+ *
+ * svrf -> The svrf that ifp is being brought up
+ * stable -> The stable we are looking at.
+ * ifp -> interface coming up
+ * afi -> the afi in question
+ * safi -> the safi in question
+ */
+static void static_fixup_intf_nh(struct route_table *stable,
+                                struct interface *ifp,
+                                afi_t afi, safi_t safi)
+{
+       struct route_node *rn;
+       struct static_route *si;
+
+       for (rn = route_top(stable); rn; rn = route_next(rn)) {
+               for (si = rn->info; si; si = si->next) {
+                       if (si->nh_vrf_id != ifp->vrf_id)
+                               continue;
+
+                       if (si->ifindex != ifp->ifindex)
+                               continue;
+
+                       static_install_route(rn, si, safi);
+               }
+       }
+}
+
+/*
+ * This function enables static routes that rely on an interface in
+ * a different vrf when that interface comes up.
+ */
+void static_install_intf_nh(struct interface *ifp)
+{
+       struct route_table *stable;
+       struct vrf *vrf;
+       afi_t afi;
+       safi_t safi;
+
+       RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
+               struct static_vrf *svrf = vrf->info;
+
+               /* Not needed if same vrf since happens naturally */
+               if (vrf->vrf_id == ifp->vrf_id)
+                       continue;
+
+               /* Install any static routes configured for this interface. */
+               for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+                       for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
+                               stable = svrf->stable[afi][safi];
+                               if (!stable)
+                                       continue;
+
+                               static_fixup_intf_nh(stable, ifp, afi, safi);
+                       }
+               }
+       }
+}
+
 /* called from if_{add,delete}_update, i.e. when ifindex becomes [in]valid */
 void static_ifindex_update(struct interface *ifp, bool up)
 {
index 916ddcd7eb024145e49f5e81296e1e8ac660397d..6036bfe396970df625915b759ee4e68f5e909233 100644 (file)
@@ -113,5 +113,7 @@ extern int static_delete_route(afi_t afi, safi_t safi, uint8_t type,
 
 extern void static_cleanup_vrf_ids(struct static_vrf *disable_svrf);
 
+extern void static_install_intf_nh(struct interface *ifp);
+
 extern void static_ifindex_update(struct interface *ifp, bool up);
 #endif
index 4e168e142cc09ef1d5658b3c33b01b5124786eda..b228611de708a7689c7e9483cdf92d7dc74dc2af 100644 (file)
@@ -122,11 +122,17 @@ static int interface_state_up(int command, struct zclient *zclient,
 
        ifp = zebra_interface_if_lookup(zclient->ibuf);
 
-       if (ifp && if_is_vrf(ifp)) {
-               struct static_vrf *svrf = static_vrf_lookup_by_id(vrf_id);
+       if (ifp) {
+               if (if_is_vrf(ifp)) {
+                       struct static_vrf *svrf =
+                                       static_vrf_lookup_by_id(vrf_id);
 
-               static_fixup_vrf_ids(svrf);
-               static_config_install_delayed_routes(svrf);
+                       static_fixup_vrf_ids(svrf);
+                       static_config_install_delayed_routes(svrf);
+               }
+
+               /* Install any static reliant on this interface coming up */
+               static_install_intf_nh(ifp);
        }
 
        return 0;