diff options
Diffstat (limited to 'staticd/static_routes.c')
-rw-r--r-- | staticd/static_routes.c | 201 |
1 files changed, 51 insertions, 150 deletions
diff --git a/staticd/static_routes.c b/staticd/static_routes.c index 1fbbf7e..cba3818 100644 --- a/staticd/static_routes.c +++ b/staticd/static_routes.c @@ -87,11 +87,6 @@ void zebra_stable_node_cleanup(struct route_table *table, /* Install static path into rib. */ void static_install_path(struct static_path *pn) { - struct static_nexthop *nh; - - frr_each(static_nexthop_list, &pn->nexthop_list, nh) - static_zebra_nht_register(nh, true); - if (static_nexthop_list_count(&pn->nexthop_list)) static_zebra_route_add(pn, true); } @@ -245,21 +240,20 @@ void static_del_path(struct static_path *pn) XFREE(MTYPE_STATIC_PATH, pn); } -struct static_nexthop *static_add_nexthop(struct static_path *pn, - enum static_nh_type type, - struct ipaddr *ipaddr, - const char *ifname, - const char *nh_vrf, uint32_t color) +struct static_nexthop * +static_add_nexthop(struct static_path *pn, enum static_nh_type type, + struct ipaddr *ipaddr, const char *ifname, + const char *nh_vrfname, uint32_t color) { struct route_node *rn = pn->rn; struct static_nexthop *nh; - struct static_vrf *nh_svrf; + struct vrf *nh_vrf; struct interface *ifp; struct static_nexthop *cp; route_lock_node(rn); - nh_svrf = static_vrf_lookup_by_name(nh_vrf); + nh_vrf = vrf_lookup_by_name(nh_vrfname); /* Make new static route structure. */ nh = XCALLOC(MTYPE_STATIC_NEXTHOP, sizeof(struct static_nexthop)); @@ -274,8 +268,8 @@ struct static_nexthop *static_add_nexthop(struct static_path *pn, if (nh->type == STATIC_BLACKHOLE) nh->bh_type = STATIC_BLACKHOLE_NULL; - nh->nh_vrf_id = nh_svrf ? nh_svrf->vrf->vrf_id : VRF_UNKNOWN; - strlcpy(nh->nh_vrfname, nh_vrf, sizeof(nh->nh_vrfname)); + nh->nh_vrf_id = nh_vrf ? nh_vrf->vrf_id : VRF_UNKNOWN; + strlcpy(nh->nh_vrfname, nh_vrfname, sizeof(nh->nh_vrfname)); if (ifname) strlcpy(nh->ifname, ifname, sizeof(nh->ifname)); @@ -378,6 +372,17 @@ void static_install_nexthop(struct static_nexthop *nh) } } +void static_uninstall_nexthop(struct static_nexthop *nh) +{ + struct static_path *pn = nh->pn; + + if (nh->nh_vrf_id == VRF_UNKNOWN) + return; + + static_zebra_nht_register(nh, false); + static_uninstall_path(pn); +} + void static_delete_nexthop(struct static_nexthop *nh) { struct static_path *pn = nh->pn; @@ -387,17 +392,8 @@ void static_delete_nexthop(struct static_nexthop *nh) /* Remove BFD session/configuration if any. */ bfd_sess_free(&nh->bsp); - if (nh->nh_vrf_id == VRF_UNKNOWN) - goto EXIT; - - static_zebra_nht_register(nh, false); - /* - * If we have other si nodes then route replace - * else delete the route - */ - static_uninstall_path(pn); + static_uninstall_nexthop(nh); -EXIT: route_unlock_node(rn); /* Free static route configuration. */ XFREE(MTYPE_STATIC_NEXTHOP, nh); @@ -437,14 +433,10 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi, struct route_node *rn; struct static_nexthop *nh; struct static_path *pn; - struct vrf *vrf; + struct static_vrf *svrf; struct static_route_info *si; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - struct static_vrf *svrf; - - svrf = vrf->info; - + RB_FOREACH (svrf, svrf_name_head, &svrfs) { stable = static_vrf_static_table(afi, safi, svrf); if (!stable) continue; @@ -476,8 +468,8 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi, * afi -> The afi to look at * safi -> the safi to look at */ -static void static_fixup_vrf(struct static_vrf *svrf, - struct route_table *stable, afi_t afi, safi_t safi) +static void static_fixup_vrf(struct vrf *vrf, struct route_table *stable, + afi_t afi, safi_t safi) { struct route_node *rn; struct static_nexthop *nh; @@ -491,13 +483,11 @@ static void static_fixup_vrf(struct static_vrf *svrf, continue; frr_each(static_path_list, &si->path_list, pn) { frr_each(static_nexthop_list, &pn->nexthop_list, nh) { - if (strcmp(svrf->vrf->name, nh->nh_vrfname) - != 0) + if (strcmp(vrf->name, nh->nh_vrfname) != 0) continue; - nh->nh_vrf_id = svrf->vrf->vrf_id; - nh->nh_registered = false; - if (nh->ifindex) { + nh->nh_vrf_id = vrf->vrf_id; + if (nh->ifname[0]) { ifp = if_lookup_by_name(nh->ifname, nh->nh_vrf_id); if (ifp) @@ -506,7 +496,7 @@ static void static_fixup_vrf(struct static_vrf *svrf, continue; } - static_install_path(pn); + static_install_nexthop(nh); } } } @@ -521,13 +511,9 @@ static void static_fixup_vrf(struct static_vrf *svrf, * afi -> the afi in question * safi -> the safi in question */ -static void static_enable_vrf(struct static_vrf *svrf, - struct route_table *stable, afi_t afi, - safi_t safi) +static void static_enable_vrf(struct route_table *stable, afi_t afi, safi_t safi) { struct route_node *rn; - struct static_nexthop *nh; - struct interface *ifp; struct static_path *pn; struct static_route_info *si; @@ -535,21 +521,8 @@ static void static_enable_vrf(struct static_vrf *svrf, si = static_route_info_from_rnode(rn); if (!si) continue; - frr_each(static_path_list, &si->path_list, pn) { - frr_each(static_nexthop_list, &pn->nexthop_list, nh) { - if (nh->ifindex) { - ifp = if_lookup_by_name(nh->ifname, - nh->nh_vrf_id); - if (ifp) - nh->ifindex = ifp->ifindex; - else - continue; - } - if (nh->nh_vrf_id == VRF_UNKNOWN) - continue; - static_install_path(pn); - } - } + frr_each(static_path_list, &si->path_list, pn) + static_install_path(pn); } } @@ -560,27 +533,26 @@ static void static_enable_vrf(struct static_vrf *svrf, * * enable_svrf -> the vrf being enabled */ -void static_fixup_vrf_ids(struct static_vrf *enable_svrf) +void static_fixup_vrf_ids(struct vrf *vrf) { struct route_table *stable; - struct vrf *vrf; + struct static_vrf *svrf, *enable_svrf; afi_t afi; safi_t safi; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - struct static_vrf *svrf; + enable_svrf = vrf->info; - svrf = vrf->info; + RB_FOREACH (svrf, svrf_name_head, &svrfs) { /* Install any static routes configured for this VRF. */ FOREACH_AFI_SAFI (afi, safi) { stable = svrf->stable[afi][safi]; if (!stable) continue; - static_fixup_vrf(enable_svrf, stable, afi, safi); + static_fixup_vrf(vrf, stable, afi, safi); if (enable_svrf == svrf) - static_enable_vrf(svrf, stable, afi, safi); + static_enable_vrf(stable, afi, safi); } } } @@ -595,8 +567,7 @@ void static_fixup_vrf_ids(struct static_vrf *enable_svrf) * afi -> the afi in question * safi -> the safi in question */ -static void static_cleanup_vrf(struct static_vrf *svrf, - struct route_table *stable, +static void static_cleanup_vrf(struct vrf *vrf, struct route_table *stable, afi_t afi, safi_t safi) { struct route_node *rn; @@ -610,11 +581,13 @@ static void static_cleanup_vrf(struct static_vrf *svrf, continue; frr_each(static_path_list, &si->path_list, pn) { frr_each(static_nexthop_list, &pn->nexthop_list, nh) { - if (strcmp(svrf->vrf->name, nh->nh_vrfname) - != 0) + if (strcmp(vrf->name, nh->nh_vrfname) != 0) continue; - static_uninstall_path(pn); + static_uninstall_nexthop(nh); + + nh->nh_vrf_id = VRF_UNKNOWN; + nh->ifindex = IFINDEX_INTERNAL; } } } @@ -632,7 +605,6 @@ static void static_disable_vrf(struct route_table *stable, afi_t afi, safi_t safi) { struct route_node *rn; - struct static_nexthop *nh; struct static_path *pn; struct static_route_info *si; @@ -640,11 +612,8 @@ static void static_disable_vrf(struct route_table *stable, si = static_route_info_from_rnode(rn); if (!si) continue; - frr_each(static_path_list, &si->path_list, pn) { - frr_each(static_nexthop_list, &pn->nexthop_list, nh) { - static_uninstall_path(pn); - } - } + frr_each(static_path_list, &si->path_list, pn) + static_uninstall_path(pn); } } @@ -656,26 +625,23 @@ static void static_disable_vrf(struct route_table *stable, * * disable_svrf - The vrf being disabled */ -void static_cleanup_vrf_ids(struct static_vrf *disable_svrf) +void static_cleanup_vrf_ids(struct vrf *vrf) { - struct vrf *vrf; + struct route_table *stable; + struct static_vrf *svrf, *disable_svrf; afi_t afi; safi_t safi; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - struct static_vrf *svrf; - - svrf = vrf->info; + disable_svrf = vrf->info; + RB_FOREACH (svrf, svrf_name_head, &svrfs) { /* Uninstall any static routes configured for this VRF. */ FOREACH_AFI_SAFI (afi, safi) { - struct route_table *stable; - stable = svrf->stable[afi][safi]; if (!stable) continue; - static_cleanup_vrf(disable_svrf, stable, afi, safi); + static_cleanup_vrf(vrf, stable, afi, safi); if (disable_svrf == svrf) static_disable_vrf(stable, afi, safi); @@ -683,71 +649,6 @@ 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. - * - * 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_nexthop *nh; - struct static_path *pn; - struct static_route_info *si; - - for (rn = route_top(stable); rn; rn = route_next(rn)) { - si = static_route_info_from_rnode(rn); - if (!si) - continue; - frr_each(static_path_list, &si->path_list, pn) { - frr_each(static_nexthop_list, &pn->nexthop_list, nh) { - if (nh->nh_vrf_id != ifp->vrf->vrf_id) - continue; - - if (nh->ifindex != ifp->ifindex) - continue; - - static_install_path(pn); - } - } - } -} - -/* - * 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->vrf_id) - continue; - - /* Install any static routes configured for this interface. */ - FOREACH_AFI_SAFI (afi, 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) { |