Skip to content
Permalink
Browse files

staticd: install static routes in a vrf when next-hop interface comes up

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>
  • Loading branch information...
dslicenc committed Nov 8, 2018
1 parent 6987aac commit a9be49bcbc95f2a4098cec7692a9d8dfef52b0f5
Showing with 73 additions and 4 deletions.
  1. +61 −0 staticd/static_routes.c
  2. +2 −0 staticd/static_routes.h
  3. +10 −4 staticd/static_zebra.c
@@ -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)
{
@@ -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
@@ -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;

0 comments on commit a9be49b

Please sign in to comment.
You can’t perform that action at this time.