mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-25 22:30:52 +00:00
Merge pull request #4493 from sworleys/Pbr-NHT-Fix
zebra, pbrd: PBR handle nexthop tracking correctly
This commit is contained in:
commit
35aa470801
@ -66,6 +66,8 @@ static void *pbr_nhrc_hash_alloc(void *p)
|
|||||||
{
|
{
|
||||||
struct nhrc *nhrc = XCALLOC(MTYPE_PBR_NHG, sizeof(struct nhrc));
|
struct nhrc *nhrc = XCALLOC(MTYPE_PBR_NHG, sizeof(struct nhrc));
|
||||||
nhrc->nexthop = *(struct nexthop *)p;
|
nhrc->nexthop = *(struct nexthop *)p;
|
||||||
|
nhrc->nexthop.next = NULL;
|
||||||
|
nhrc->nexthop.prev = NULL;
|
||||||
return nhrc;
|
return nhrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,10 +714,30 @@ static void pbr_nht_individual_nexthop_update_lookup(struct hash_bucket *b,
|
|||||||
pnhi->valid += 1;
|
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)
|
static void pbr_nht_nexthop_update_lookup(struct hash_bucket *b, void *data)
|
||||||
{
|
{
|
||||||
struct pbr_nexthop_group_cache *pnhgc = b->data;
|
struct pbr_nexthop_group_cache *pnhgc = b->data;
|
||||||
struct pbr_nht_individual pnhi;
|
struct pbr_nht_individual pnhi;
|
||||||
|
struct nexthop_group nhg = {};
|
||||||
bool old_valid;
|
bool old_valid;
|
||||||
|
|
||||||
old_valid = pnhgc->valid;
|
old_valid = pnhgc->valid;
|
||||||
@ -730,6 +752,13 @@ static void pbr_nht_nexthop_update_lookup(struct hash_bucket *b, void *data)
|
|||||||
*/
|
*/
|
||||||
pnhgc->valid = !!pnhi.valid;
|
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)
|
if (old_valid != pnhgc->valid)
|
||||||
pbr_map_check_nh_group_change(pnhgc->name);
|
pbr_map_check_nh_group_change(pnhgc->name);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
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
|
* 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
|
* 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,
|
zebra_rnh_notify_protocol_clients(zvrf, afi, nrn, rnh, prn,
|
||||||
rnh->state);
|
rnh->state);
|
||||||
|
|
||||||
zebra_rnh_process_pbr_tables(afi, nrn, rnh, prn, rnh->state);
|
|
||||||
|
|
||||||
/* Process pseudowires attached to this nexthop */
|
/* Process pseudowires attached to this nexthop */
|
||||||
zebra_rnh_process_pseudowires(zvrf->vrf->vrf_id, rnh);
|
zebra_rnh_process_pseudowires(zvrf->vrf->vrf_id, rnh);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user