summaryrefslogtreecommitdiff
path: root/zebra/zapi_msg.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2023-09-28 12:27:31 -0400
committerDonald Sharp <sharpd@nvidia.com>2023-10-12 13:34:43 -0400
commit35718a2aeaeacdf2fec3eca50f614337219244ff (patch)
tree96b598b04531ec38742028b0156b4856092ffd4c /zebra/zapi_msg.c
parent9bc4d9eaec92589deda092bd867054e25e64be3f (diff)
zebra: Score weighted values of ecmp to a number between 1-255
Currently underlying asics get into a bit of trouble when the nexthop weight passed down varies wildly between the different numbers. Let's normalize the weight values between 1 and 255 Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'zebra/zapi_msg.c')
-rw-r--r--zebra/zapi_msg.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 6754238ce5..2aeb1b97e9 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -1679,10 +1679,14 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
struct nexthop_group **png,
struct nhg_backup_info **pbnhg)
{
+ struct zapi_nexthop *znh;
struct nexthop_group *ng = NULL;
struct nhg_backup_info *bnhg = NULL;
uint16_t i;
struct nexthop *last_nh = NULL;
+ bool same_weight = true;
+ uint64_t max_weight = 0;
+ uint64_t tmp;
assert(!(png && pbnhg));
@@ -1697,6 +1701,40 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
bnhg = zebra_nhg_backup_alloc();
}
+ for (i = 0; i < nexthop_num; i++) {
+ znh = &nhops[i];
+
+ if (max_weight < znh->weight) {
+ if (i != 0 || znh->weight != 1)
+ same_weight = false;
+
+ max_weight = znh->weight;
+ }
+ }
+
+ /*
+ * Let's convert the weights to a scaled value
+ * between 1 and zrouter.nexthop_weight_scale_value
+ * This is a simple application of a ratio:
+ * scaled_weight/zrouter.nexthop_weight_scale_value =
+ * weight/max_weight
+ * This translates to:
+ * scaled_weight = weight * zrouter.nexthop_weight_scale_value
+ * -------------------------------------------
+ * max_weight
+ *
+ * This same formula is applied to both the nexthops
+ * and the backup nexthops
+ */
+ if (!same_weight) {
+ for (i = 0; i < nexthop_num; i++) {
+ znh = &nhops[i];
+
+ tmp = (uint64_t)znh->weight * 255;
+ znh->weight = MAX(1, ((uint32_t)(tmp / max_weight)));
+ }
+ }
+
/*
* TBD should _all_ of the nexthop add operations use
* api_nh->vrf_id instead of re->vrf_id ? I only changed