From b822b93a356c200202b7e7f90cbadd7068837c2b Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Mon, 10 Jun 2019 00:39:40 -0400 Subject: zebra,pbrd: Update pbrd to handle NHT properly Update pbrd to properly handle nexthop tracking. When we get a notification that a change happened on a nexthop, re-install it if its still valid. Before, we were running over all routes and re-queueing them if they were PBR routes. This commit removes that and puts all the processing in PBR instead. Signed-off-by: Stephen Worley --- pbrd/pbr_nht.c | 27 +++++++++++++++++++++++++++ zebra/zebra_rnh.c | 50 -------------------------------------------------- 2 files changed, 27 insertions(+), 50 deletions(-) diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c index a6ee8bf01..22dd6f1a3 100644 --- a/pbrd/pbr_nht.c +++ b/pbrd/pbr_nht.c @@ -714,10 +714,30 @@ static void pbr_nht_individual_nexthop_update_lookup(struct hash_bucket *b, pnhi->valid += 1; } +static void pbr_nexthop_group_cache_iterate_to_group(struct hash_bucket *b, + void *data) +{ + struct pbr_nexthop_cache *pnhc = b->data; + struct nexthop_group *nhg = data; + struct nexthop *nh = NULL; + + copy_nexthops(&nh, pnhc->nexthop, NULL); + + nexthop_add(&nhg->nexthop, nh); +} + +static void +pbr_nexthop_group_cache_to_nexthop_group(struct nexthop_group *nhg, + struct pbr_nexthop_group_cache *pnhgc) +{ + hash_iterate(pnhgc->nhh, pbr_nexthop_group_cache_iterate_to_group, nhg); +} + static void pbr_nht_nexthop_update_lookup(struct hash_bucket *b, void *data) { struct pbr_nexthop_group_cache *pnhgc = b->data; struct pbr_nht_individual pnhi; + struct nexthop_group nhg = {}; bool old_valid; old_valid = pnhgc->valid; @@ -732,6 +752,13 @@ static void pbr_nht_nexthop_update_lookup(struct hash_bucket *b, void *data) */ pnhgc->valid = !!pnhi.valid; + if (pnhgc->valid) { + pbr_nexthop_group_cache_to_nexthop_group(&nhg, pnhgc); + pbr_nht_install_nexthop_group(pnhgc, nhg); + /* Don't need copied nexthops anymore */ + nexthops_free(nhg.nexthop); + } + if (old_valid != pnhgc->valid) pbr_map_check_nh_group_change(pnhgc->name); } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index a63d01571..1024f3a05 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -592,54 +592,6 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi, zebra_rnh_clear_nexthop_rnh_filters(re); } -static void zebra_rnh_process_pbr_tables(afi_t afi, struct route_node *nrn, - struct rnh *rnh, - struct route_node *prn, - struct route_entry *re) -{ - struct zebra_router_table *zrt; - struct route_entry *o_re; - struct route_node *o_rn; - struct listnode *node; - struct zserv *client; - - /* - * We are only concerned about nexthops that change for - * anyone using PBR - */ - for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) { - if (client->proto == ZEBRA_ROUTE_PBR) - break; - } - - if (!client) - return; - - RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) { - if (afi != zrt->afi) - continue; - - for (o_rn = route_top(zrt->table); o_rn; - o_rn = srcdest_route_next(o_rn)) { - RNODE_FOREACH_RE (o_rn, o_re) { - if (o_re->type == ZEBRA_ROUTE_PBR) - break; - - } - - /* - * If we have a PBR route and a nexthop changes - * just rethink it. Yes this is a hammer, but - * a small one - */ - if (o_re) { - SET_FLAG(o_re->status, ROUTE_ENTRY_CHANGED); - rib_queue_add(o_rn); - } - } - } -} - /* * Utility to determine whether a candidate nexthop is useable. We make this * check in a couple of places, so this is a single home for the logic we @@ -834,8 +786,6 @@ static void zebra_rnh_eval_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi, zebra_rnh_notify_protocol_clients(zvrf, afi, nrn, rnh, prn, rnh->state); - zebra_rnh_process_pbr_tables(afi, nrn, rnh, prn, rnh->state); - /* Process pseudowires attached to this nexthop */ zebra_rnh_process_pseudowires(zvrf->vrf->vrf_id, rnh); } -- cgit v1.2.3