Skip to content

Commit

Permalink
zebra: Prevent duplication and overflow in nhe2grp
Browse files Browse the repository at this point in the history
The kernel does not allow duplicate IDs in the same group, but
we are perfectly find with it internally if two different
nexthops resolve the the same nexthop (default route for instance).
So, we have to handle this when we get ready to install.

Further, pass the max group size in the arguments to ensure we
don't overflow. Don't actually think this is possible due to
multipath checking in nexthop_active_update() but better to be
safe.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
  • Loading branch information
sworleys committed Oct 25, 2019
1 parent 4b87c90 commit 8dbc800
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 9 deletions.
4 changes: 2 additions & 2 deletions zebra/zebra_dplane.c
Original file line number Diff line number Diff line change
Expand Up @@ -1589,8 +1589,8 @@ static int dplane_ctx_nexthop_init(struct zebra_dplane_ctx *ctx,
/* If its a group, convert it to a grp array of ids */
if (!zebra_nhg_depends_is_empty(nhe)
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE))
ctx->u.rinfo.nhe.nh_grp_count =
zebra_nhg_nhe2grp(ctx->u.rinfo.nhe.nh_grp, nhe);
ctx->u.rinfo.nhe.nh_grp_count = zebra_nhg_nhe2grp(
ctx->u.rinfo.nhe.nh_grp, nhe, MULTIPATH_NUM);

zns = ((struct zebra_vrf *)vrf_info_lookup(nhe->vrf_id))->zns;

Expand Down
26 changes: 21 additions & 5 deletions zebra/zebra_nhg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1444,13 +1444,16 @@ int zebra_nhg_re_update_ref(struct route_entry *re, struct nhg_hash_entry *new)
}

/* Convert a nhe into a group array */
uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe)
uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
int max_num)
{
struct nhg_connected *rb_node_dep = NULL;
struct nhg_hash_entry *depend = NULL;
uint8_t i = 0;

frr_each (nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
bool duplicate = false;

depend = rb_node_dep->nhe;

/*
Expand All @@ -1467,11 +1470,24 @@ uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe)
}
}

grp[i].id = depend->id;
/* We aren't using weights for anything right now */
grp[i].weight = 0;
i++;
/* Check for duplicate IDs, kernel doesn't like that */
for (int j = 0; j < i; j++) {
if (depend->id == grp[j].id)
duplicate = true;
}

if (!duplicate) {
grp[i].id = depend->id;
/* We aren't using weights for anything right now */
grp[i].weight = 0;
i++;
}

if (i >= max_num)
goto done;
}

done:
return i;
}

Expand Down
4 changes: 2 additions & 2 deletions zebra/zebra_nhg.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ extern int nexthop_active_update(struct route_node *rn, struct route_entry *re);
extern int zebra_nhg_re_update_ref(struct route_entry *re,
struct nhg_hash_entry *nhe);

extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp,
struct nhg_hash_entry *nhe);
extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
int size);

void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe);
void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe);
Expand Down

0 comments on commit 8dbc800

Please sign in to comment.