summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Worley <sworley@cumulusnetworks.com>2019-06-10 06:39:40 +0200
committerStephen Worley <sworley@cumulusnetworks.com>2019-06-10 20:36:30 +0200
commitb822b93a356c200202b7e7f90cbadd7068837c2b (patch)
treeb43e4102bf3fa737fade5f537b1e0db3c4066400
parentpbrd: Set next/prev to NULL on cached nexthops (diff)
downloadfrr-b822b93a356c200202b7e7f90cbadd7068837c2b.tar.xz
frr-b822b93a356c200202b7e7f90cbadd7068837c2b.zip
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 <sworley@cumulusnetworks.com>
-rw-r--r--pbrd/pbr_nht.c27
-rw-r--r--zebra/zebra_rnh.c50
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);
}