From efcb94561737cd1077db303c244ddaed6b74aea0 Mon Sep 17 00:00:00 2001 From: "Anand H. Krishnan" Date: Tue, 19 Jul 2016 14:10:13 +0530 Subject: [PATCH] In case of ECMP calculation, update the ECMP index in the forwaring metadata ECMP index in the forwarding metadata is used by datapath to derive various information at various stages of the path. If vRouter was computing the ECMP index, it was not updating the ECMP index in the forwarding metadata, leading to problems such as wrong/invalid label in the packet. Change-Id: Ic86b15c3d6c8f83af11caf74ea1d69cc8ce841ea Closes-BUG: #1603963 --- dp-core/vr_nexthop.c | 26 +++++++++++++++++++++----- include/vr_nexthop.h | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/dp-core/vr_nexthop.c b/dp-core/vr_nexthop.c index 29c5c83a8..5587a4cef 100644 --- a/dp-core/vr_nexthop.c +++ b/dp-core/vr_nexthop.c @@ -612,14 +612,13 @@ static struct vr_nexthop * nh_composite_ecmp_select_nh(struct vr_packet *pkt, struct vr_nexthop *nh, struct vr_forwarding_md *fmd) { - int ret; + int ret, ecmp_index; unsigned int hash, hash_ecmp, count; struct vr_flow flow; struct vr_ip6 *ip6; struct vr_nexthop *cnh = NULL; struct vr_component_nh *cnhp = nh->nh_component_nh; - struct vr_component_nh *cnhp_ecmp = nh->nh_component_ecmp; if (!(count = nh->nh_component_cnt)) return NULL; @@ -640,12 +639,20 @@ nh_composite_ecmp_select_nh(struct vr_packet *pkt, struct vr_nexthop *nh, hash = hash_ecmp = vr_hash(&flow, flow.flow_key_len, 0); hash %= count; + ecmp_index = cnhp[hash].cnh_ecmp_index; cnh = cnhp[hash].cnh; - if (!cnh && nh->nh_component_ecmp_cnt) { - hash_ecmp %= nh->nh_component_ecmp_cnt; - cnh = cnhp_ecmp[hash_ecmp].cnh; + if (!cnh) { + if (nh->nh_component_ecmp_cnt) { + cnhp = nh->nh_component_ecmp; + hash_ecmp %= nh->nh_component_ecmp_cnt; + ecmp_index = cnhp[hash_ecmp].cnh_ecmp_index; + cnh = cnhp[hash_ecmp].cnh; + } } + if (cnh) + fmd->fmd_ecmp_nh_index = ecmp_index; + return cnh; } @@ -2300,7 +2307,14 @@ nh_composite_add(struct vr_nexthop *nh, vr_nexthop_req *req) nh->nh_component_nh[i].cnh_label = req->nhr_label_list[i]; if (nh->nh_component_nh[i].cnh) active++; + + if (req->nhr_flags & NH_FLAG_COMPOSITE_ECMP) { + nh->nh_component_nh[i].cnh_ecmp_index = i; + } else { + nh->nh_component_nh[i].cnh_ecmp_index = -1; + } } + nh->nh_component_cnt = req->nhr_nh_list_size; if (nh_composite_mcast_validate(nh, req)) @@ -2324,6 +2338,8 @@ nh_composite_add(struct vr_nexthop *nh, vr_nexthop_req *req) if (nh->nh_component_nh[i].cnh) { memcpy(&nh->nh_component_ecmp[j++], &nh->nh_component_nh[i], sizeof(struct vr_component_nh)); + /* this happens implicitly */ + /* nh->nh_component_ecmp[j++].cnh_ecmp_index = i */ } } nh->nh_component_ecmp_cnt = j; diff --git a/include/vr_nexthop.h b/include/vr_nexthop.h index 6f379e247..494a06c1f 100644 --- a/include/vr_nexthop.h +++ b/include/vr_nexthop.h @@ -70,6 +70,7 @@ struct vr_forwarding_md; struct vr_component_nh { int cnh_label; + int cnh_ecmp_index; struct vr_nexthop *cnh; };