diff options
Diffstat (limited to 'staticd/static_nht.c')
| -rw-r--r-- | staticd/static_nht.c | 122 |
1 files changed, 75 insertions, 47 deletions
diff --git a/staticd/static_nht.c b/staticd/static_nht.c index 1a2ddd7f05..feb6e0f993 100644 --- a/staticd/static_nht.c +++ b/staticd/static_nht.c @@ -30,33 +30,33 @@ #include "static_zebra.h" #include "static_nht.h" -static void static_nht_update_rn(struct route_node *rn, - struct prefix *nhp, uint32_t nh_num, - vrf_id_t nh_vrf_id, struct vrf *vrf, - safi_t safi) +static void static_nht_update_path(struct route_node *rn, + struct static_path *pn, struct prefix *nhp, + uint32_t nh_num, vrf_id_t nh_vrf_id, + struct vrf *vrf, safi_t safi) { - struct static_route *si; + struct static_nexthop *nh; - for (si = rn->info; si; si = si->next) { - if (si->nh_vrf_id != nh_vrf_id) + frr_each(static_nexthop_list, &pn->nexthop_list, nh) { + if (nh->nh_vrf_id != nh_vrf_id) continue; - if (si->type != STATIC_IPV4_GATEWAY - && si->type != STATIC_IPV4_GATEWAY_IFNAME - && si->type != STATIC_IPV6_GATEWAY - && si->type != STATIC_IPV6_GATEWAY_IFNAME) + if (nh->type != STATIC_IPV4_GATEWAY + && nh->type != STATIC_IPV4_GATEWAY_IFNAME + && nh->type != STATIC_IPV6_GATEWAY + && nh->type != STATIC_IPV6_GATEWAY_IFNAME) continue; if (nhp->family == AF_INET - && nhp->u.prefix4.s_addr == si->addr.ipv4.s_addr) - si->nh_valid = !!nh_num; + && nhp->u.prefix4.s_addr == nh->addr.ipv4.s_addr) + nh->nh_valid = !!nh_num; if (nhp->family == AF_INET6 - && memcmp(&nhp->u.prefix6, &si->addr.ipv6, 16) == 0) - si->nh_valid = !!nh_num; + && memcmp(&nhp->u.prefix6, &nh->addr.ipv6, 16) == 0) + nh->nh_valid = !!nh_num; - if (si->state == STATIC_START) - static_zebra_route_add(rn, si, vrf->vrf_id, safi, true); + if (nh->state == STATIC_START) + static_zebra_route_add(rn, pn, safi, true); } } @@ -67,6 +67,8 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp, struct route_table *stable; struct static_vrf *svrf; struct route_node *rn; + struct static_path *pn; + struct static_route_info *si; svrf = vrf->info; if (!svrf) @@ -78,17 +80,26 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp, if (sp) { rn = srcdest_rnode_lookup(stable, sp, NULL); - if (rn) { - static_nht_update_rn(rn, nhp, nh_num, nh_vrf_id, - vrf, safi); + if (rn && rn->info) { + si = static_route_info_from_rnode(rn); + frr_each(static_path_list, &si->path_list, pn) { + static_nht_update_path(rn, pn, nhp, nh_num, + nh_vrf_id, vrf, safi); + } route_unlock_node(rn); } return; } - for (rn = route_top(stable); rn; rn = route_next(rn)) - static_nht_update_rn(rn, nhp, nh_num, nh_vrf_id, vrf, safi); - + 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) { + static_nht_update_path(rn, pn, nhp, nh_num, nh_vrf_id, + vrf, safi); + } + } } void static_nht_update(struct prefix *sp, struct prefix *nhp, @@ -111,8 +122,10 @@ static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi, { struct static_vrf *svrf; struct route_table *stable; - struct static_route *si; + struct static_nexthop *nh; + struct static_path *pn; struct route_node *rn; + struct static_route_info *si; svrf = vrf->info; if (!svrf) @@ -123,25 +136,33 @@ static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi, return; for (rn = route_top(stable); rn; rn = route_next(rn)) { - for (si = rn->info; si; si = si->next) { - if (si->nh_vrf_id != nh_vrf_id) - continue; - - if (nhp->family == AF_INET - && nhp->u.prefix4.s_addr != si->addr.ipv4.s_addr) - continue; - - if (nhp->family == AF_INET6 - && memcmp(&nhp->u.prefix6, &si->addr.ipv6, 16) != 0) - continue; - - /* - * We've been told that a nexthop we depend - * on has changed in some manner, so reset - * the state machine to allow us to start - * over. - */ - si->state = STATIC_START; + 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 != nh_vrf_id) + continue; + + if (nhp->family == AF_INET + && nhp->u.prefix4.s_addr + != nh->addr.ipv4.s_addr) + continue; + + if (nhp->family == AF_INET6 + && memcmp(&nhp->u.prefix6, &nh->addr.ipv6, + 16) + != 0) + continue; + + /* + * We've been told that a nexthop we + * depend on has changed in some manner, + * so reset the state machine to allow + * us to start over. + */ + nh->state = STATIC_START; + } } } } @@ -164,8 +185,10 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi, { struct static_vrf *svrf; struct route_table *stable; - struct static_route *si; struct route_node *rn; + struct static_nexthop *nh; + struct static_path *pn; + struct static_route_info *si; svrf = vrf->info; if (!svrf) @@ -178,9 +201,14 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi, rn = srcdest_rnode_lookup(stable, sp, NULL); if (!rn) return; - - for (si = rn->info; si; si = si->next) - si->state = state; + si = rn->info; + if (si) { + frr_each(static_path_list, &si->path_list, pn) { + frr_each(static_nexthop_list, &pn->nexthop_list, nh) { + nh->state = state; + } + } + } route_unlock_node(rn); } |
