summaryrefslogtreecommitdiff
path: root/zebra/zebra_nhg.c
diff options
context:
space:
mode:
authorStephen Worley <sworley@cumulusnetworks.com>2019-07-25 13:27:59 -0400
committerStephen Worley <sworley@cumulusnetworks.com>2019-10-25 11:13:41 -0400
commit8dbc800f42797105b53fd385eb57ac30bc372d7d (patch)
tree8702bb8ef891fd054b4551f10211ecf933a0a5ab /zebra/zebra_nhg.c
parent4b87c90d58a04650d8bc4316115c3233236431a0 (diff)
zebra: Prevent duplication and overflow in nhe2grp
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>
Diffstat (limited to 'zebra/zebra_nhg.c')
-rw-r--r--zebra/zebra_nhg.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index 24eae603f2..870f4afb27 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -1444,13 +1444,16 @@ done:
}
/* 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;
/*
@@ -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;
}