]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: Add code to notice nexthop changes for pbr tables
authorDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 26 Mar 2018 15:05:52 +0000 (11:05 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 6 Apr 2018 17:22:43 +0000 (13:22 -0400)
When we have a PBR installed as a table, we need to notice
when a nexthop changes and rethink the routes for the pbr
tables.

Add code to nexthop tracking to notice the pbr watched
nexthop has changed in some manner.  If it is a pbr route
that depends on the nexthop then just enqueue it for
rethinking.

This is a bit of a hammer, we know that only pbr routes
are going to be installing routes in weird non-standard
tables as such we need to only handle nexthop changes
for nexthops that are actually changing that we care
about and to only requeue for route nodes we have
route entries for from PBR

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/zebra_rnh.c

index 65df4e15aa2be782323f41f480bcc8a09b1ab0b5..879da092f0e199f92dce93f19f4af4ebe067f4c4 100644 (file)
@@ -514,6 +514,59 @@ static void zebra_rnh_notify_protocol_clients(vrf_id_t vrfid, int family,
        }
 }
 
+static void zebra_rnh_process_pbr_tables(int family,
+                                        struct route_node *nrn,
+                                        struct rnh *rnh,
+                                        struct route_node *prn,
+                                        struct route_entry *re)
+{
+       struct zebra_ns_table *znst;
+       struct route_entry *o_re;
+       struct route_node *o_rn;
+       struct listnode *node;
+       struct zserv *client;
+       struct zebra_ns *zns;
+       afi_t afi = AFI_IP;
+
+       if (family == AF_INET6)
+               afi = AFI_IP6;
+
+       /*
+        * 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;
+
+       zns = zebra_ns_lookup(NS_DEFAULT);
+       RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) {
+               if (afi != znst->afi)
+                       continue;
+
+               for (o_rn = route_top(znst->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)
+                               rib_queue_add(o_rn);
+               }
+       }
+}
+
 static void zebra_rnh_process_static_routes(vrf_id_t vrfid, int family,
                                            struct route_node *nrn,
                                            struct rnh *rnh,
@@ -752,6 +805,9 @@ static void zebra_rnh_eval_nexthop_entry(vrf_id_t vrfid, int family, int force,
                zebra_rnh_process_static_routes(vrfid, family, nrn, rnh, prn,
                                                rnh->state);
 
+               zebra_rnh_process_pbr_tables(family, nrn, rnh, prn,
+                                            rnh->state);
+
                /* Process pseudowires attached to this nexthop */
                zebra_rnh_process_pseudowires(vrfid, rnh);
        }