summaryrefslogtreecommitdiff
path: root/pbrd/pbr_nht.c
diff options
context:
space:
mode:
Diffstat (limited to 'pbrd/pbr_nht.c')
-rw-r--r--pbrd/pbr_nht.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c
index fc78b8ed1f..22dd6f1a38 100644
--- a/pbrd/pbr_nht.c
+++ b/pbrd/pbr_nht.c
@@ -66,6 +66,8 @@ static void *pbr_nhrc_hash_alloc(void *p)
{
struct nhrc *nhrc = XCALLOC(MTYPE_PBR_NHG, sizeof(struct nhrc));
nhrc->nexthop = *(struct nexthop *)p;
+ nhrc->nexthop.next = NULL;
+ nhrc->nexthop.prev = NULL;
return nhrc;
}
@@ -712,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;
@@ -730,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);
}