Merge pull request #4165 from dslicenc/rnh-invalid-nexthops

zebra: stop sending invalid nexthops to clients
This commit is contained in:
Mark Stapp 2019-04-19 14:11:22 -04:00 committed by GitHub
commit c02a40c14f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 5 deletions

View File

@ -82,6 +82,7 @@ struct nexthop {
#define NEXTHOP_FLAG_ONLINK (1 << 3) /* Nexthop should be installed onlink. */ #define NEXTHOP_FLAG_ONLINK (1 << 3) /* Nexthop should be installed onlink. */
#define NEXTHOP_FLAG_MATCHED (1 << 4) /* Already matched vs a nexthop */ #define NEXTHOP_FLAG_MATCHED (1 << 4) /* Already matched vs a nexthop */
#define NEXTHOP_FLAG_DUPLICATE (1 << 5) /* nexthop duplicates another active one */ #define NEXTHOP_FLAG_DUPLICATE (1 << 5) /* nexthop duplicates another active one */
#define NEXTHOP_FLAG_RNH_FILTERED (1 << 6) /* rmap filtered, used by rnh */
#define NEXTHOP_IS_ACTIVE(flags) \ #define NEXTHOP_IS_ACTIVE(flags) \
(CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE) \ (CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE) \
&& !CHECK_FLAG(flags, NEXTHOP_FLAG_DUPLICATE)) && !CHECK_FLAG(flags, NEXTHOP_FLAG_DUPLICATE))

View File

@ -377,6 +377,20 @@ void zebra_deregister_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw)
zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE); zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE);
} }
/* Clear the NEXTHOP_FLAG_RNH_FILTERED flags on all nexthops
*/
static void zebra_rnh_clear_nexthop_rnh_filters(struct route_entry *re)
{
struct nexthop *nexthop;
if (re) {
for (nexthop = re->ng.nexthop; nexthop;
nexthop = nexthop->next) {
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RNH_FILTERED);
}
}
}
/* Apply the NHT route-map for a client to the route (and nexthops) /* Apply the NHT route-map for a client to the route (and nexthops)
* resolving a NH. * resolving a NH.
*/ */
@ -393,11 +407,11 @@ static int zebra_rnh_apply_nht_rmap(afi_t afi, struct zebra_vrf *zvrf,
nexthop = nexthop->next) { nexthop = nexthop->next) {
ret = zebra_nht_route_map_check( ret = zebra_nht_route_map_check(
afi, proto, &prn->p, zvrf, re, nexthop); afi, proto, &prn->p, zvrf, re, nexthop);
if (ret != RMAP_DENYMATCH) { if (ret != RMAP_DENYMATCH)
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
at_least_one++; /* at least one valid NH */ at_least_one++; /* at least one valid NH */
} else { else {
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); SET_FLAG(nexthop->flags,
NEXTHOP_FLAG_RNH_FILTERED);
} }
} }
} }
@ -546,6 +560,7 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
* this * this
* nexthop to see if it is filtered or not. * nexthop to see if it is filtered or not.
*/ */
zebra_rnh_clear_nexthop_rnh_filters(re);
num_resolving_nh = zebra_rnh_apply_nht_rmap( num_resolving_nh = zebra_rnh_apply_nht_rmap(
afi, zvrf, prn, re, client->proto); afi, zvrf, prn, re, client->proto);
if (num_resolving_nh) if (num_resolving_nh)
@ -572,6 +587,9 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
send_client(rnh, client, RNH_NEXTHOP_TYPE, zvrf->vrf->vrf_id); send_client(rnh, client, RNH_NEXTHOP_TYPE, zvrf->vrf->vrf_id);
} }
if (re)
zebra_rnh_clear_nexthop_rnh_filters(re);
} }
static void zebra_rnh_process_pbr_tables(afi_t afi, struct route_node *nrn, static void zebra_rnh_process_pbr_tables(afi_t afi, struct route_node *nrn,
@ -631,7 +649,10 @@ static bool rnh_nexthop_valid(const struct route_entry *re,
const struct nexthop *nh) const struct nexthop *nh)
{ {
return (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED) return (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)
&& CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)); && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)
&& !CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)
&& !CHECK_FLAG(nh->flags, NEXTHOP_FLAG_DUPLICATE)
&& !CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RNH_FILTERED));
} }
/* /*