]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra,pbrd: Update pbrd to handle NHT properly
authorStephen Worley <sworley@cumulusnetworks.com>
Mon, 10 Jun 2019 04:39:40 +0000 (00:39 -0400)
committerStephen Worley <sworley@cumulusnetworks.com>
Mon, 10 Jun 2019 18:36:30 +0000 (14:36 -0400)
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>
pbrd/pbr_nht.c
zebra/zebra_rnh.c

index a6ee8bf01e8977a97e2e128b039448a878640e87..22dd6f1a38337cd91018153e8441dd8329cc6591 100644 (file)
@@ -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);
 }
index a63d015716030bfa308406daf06a78ac9aa9225b..1024f3a0525c425bbeb2d37f383f3d5d759ab7b0 100644 (file)
@@ -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);
        }