diff options
author | Donald Sharp <sharpd@nvidia.com> | 2020-12-10 16:18:00 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@nvidia.com> | 2020-12-12 02:45:39 +0100 |
commit | 89527adde7e5046ecb97d0c94b10760dd30f3276 (patch) | |
tree | cf256a6661ba8cf3e053ff5b72c5aac4de46ac82 /pbrd/pbr_nht.c | |
parent | Merge pull request #7711 from volta-networks/fix_ldpsync_client_close_callback (diff) | |
download | frr-89527adde7e5046ecb97d0c94b10760dd30f3276.tar.xz frr-89527adde7e5046ecb97d0c94b10760dd30f3276.zip |
pbrd: Pay attention to interface up/down events with nht
When an interface goes up/down we need to pay attention to this
in PBR. In the past we were relying *only* on the nht events
but this is not sufficient for cases where an interface is flapping
up and down. If this is happening it could be happening fast enough
that zebra is not sending nht events because they are consolidated
into a single event from it's perspective and that is the right thing
to do. This commit will allow us to back out commit:
0aaa722883245c2109d9856ca0656749860fc579
As that commit introduced extra processing in zebra that is actually
causing issues in other places. The problem that commit was trying
to solve should have always been handled in pbrd instead of making
zebra do work that is unnatural to it's actual flow.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'pbrd/pbr_nht.c')
-rw-r--r-- | pbrd/pbr_nht.c | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c index ce7780ed4..8fd7ac9e3 100644 --- a/pbrd/pbr_nht.c +++ b/pbrd/pbr_nht.c @@ -719,8 +719,51 @@ pbr_nht_individual_nexthop_gw_update(struct pbr_nexthop_cache *pnhc, { bool is_valid = pnhc->valid; - if (!pnhi->nhr) /* It doesn't care about non-nexthop updates */ + /* + * If we have an interface down event, let's note that + * it is happening and find all the nexthops that depend + * on that interface. As that if we have an interface + * flapping fast enough it means that zebra might turn + * those nexthop tracking events into a no-update + * So let's search and do the right thing on the + * interface event. + */ + if (!pnhi->nhr && pnhi->ifp) { + struct connected *connected; + struct listnode *node; + struct prefix p; + + switch (pnhc->nexthop.type) { + case NEXTHOP_TYPE_BLACKHOLE: + goto done; + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_IPV6_IFINDEX: + is_valid = if_is_up(pnhi->ifp); + goto done; + break; + case NEXTHOP_TYPE_IPV4: + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + p.u.prefix4 = pnhc->nexthop.gate.ipv4; + break; + case NEXTHOP_TYPE_IPV6: + p.family = AF_INET6; + p.prefixlen = IPV6_MAX_BITLEN; + memcpy(&p.u.prefix6, &pnhc->nexthop.gate.ipv6, + sizeof(struct in6_addr)); + break; + } + + FOR_ALL_INTERFACES_ADDRESSES (pnhi->ifp, connected, node) { + if (prefix_match(connected->address, &p)) { + is_valid = if_is_up(pnhi->ifp); + break; + } + } goto done; + } switch (pnhi->nhr->prefix.family) { case AF_INET: @@ -983,7 +1026,6 @@ static void pbr_nht_nexthop_vrf_handle(struct hash_bucket *b, void *data) struct pbr_vrf *pbr_vrf = data; struct pbr_nht_individual pnhi = {}; - zlog_debug("pnhgc iterating"); hash_iterate(pnhgc->nhh, pbr_nht_clear_looked_at, NULL); memset(&pnhi, 0, sizeof(pnhi)); pnhi.pbr_vrf = pbr_vrf; @@ -1097,6 +1139,7 @@ static void pbr_nht_nexthop_interface_update_lookup(struct hash_bucket *b, { struct pbr_nexthop_group_cache *pnhgc = b->data; struct pbr_nht_individual pnhi = {}; + struct nexthop_group nhg = {}; bool old_valid; old_valid = pnhgc->valid; @@ -1111,6 +1154,15 @@ static void pbr_nht_nexthop_interface_update_lookup(struct hash_bucket *b, */ pnhgc->valid = pnhi.valid; + pbr_nexthop_group_cache_to_nexthop_group(&nhg, pnhgc); + + if (pnhgc->valid) + pbr_nht_install_nexthop_group(pnhgc, nhg); + else + pbr_nht_uninstall_nexthop_group(pnhgc, nhg, 0); + + nexthops_free(nhg.nexthop); + if (old_valid != pnhgc->valid) pbr_map_check_nh_group_change(pnhgc->name); } |