diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-03-26 17:05:52 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-04-06 19:22:43 +0200 |
commit | d61d5d888cc0e9f8526eff39de7e3aa4949fe322 (patch) | |
tree | a43575e3fcb34e83bf7ffabd6d59ffae6166ddf7 /zebra/zebra_rnh.c | |
parent | pbrd: Do not use vrf_frame for pbrms display (diff) | |
download | frr-d61d5d888cc0e9f8526eff39de7e3aa4949fe322.tar.xz frr-d61d5d888cc0e9f8526eff39de7e3aa4949fe322.zip |
zebra: Add code to notice nexthop changes for pbr tables
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>
Diffstat (limited to 'zebra/zebra_rnh.c')
-rw-r--r-- | zebra/zebra_rnh.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 65df4e15a..879da092f 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -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); } |