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>
This commit is contained in:
Donald Sharp 2018-03-26 11:05:52 -04:00
parent 5e44f18ff1
commit d61d5d888c

View 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);
}