Skip to content

Commit a44e651

Browse files
[nhg]: Add support for weight in nexthop group member. (sonic-net#1752)
* Add support for weight in nexthop group member. 1. In fpmsyncd, parse weight field in nlmsg, set APP_DB if weight is set. 2. In routeorch, collect weight and pass weight attribute to next hop group memeber object. Signed-off-by: Zhenghui Cai <[email protected]>
1 parent 5c625b2 commit a44e651

File tree

6 files changed

+95
-5
lines changed

6 files changed

+95
-5
lines changed

fpmsyncd/routesync.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@ void RouteSync::onRouteMsg(int nlmsg_type, struct nl_object *obj, char *vrf)
700700
/* Get nexthop lists */
701701
string nexthops = getNextHopGw(route_obj);
702702
string ifnames = getNextHopIf(route_obj);
703+
string weights = getNextHopWt(route_obj);
703704

704705
vector<string> alsv = tokenize(ifnames, ',');
705706
for (auto alias : alsv)
@@ -722,6 +723,11 @@ void RouteSync::onRouteMsg(int nlmsg_type, struct nl_object *obj, char *vrf)
722723

723724
fvVector.push_back(nh);
724725
fvVector.push_back(idx);
726+
if (!weights.empty())
727+
{
728+
FieldValueTuple wt("weight", weights);
729+
fvVector.push_back(wt);
730+
}
725731

726732
if (!warmRestartInProgress)
727733
{
@@ -962,3 +968,36 @@ string RouteSync::getNextHopIf(struct rtnl_route *route_obj)
962968

963969
return result;
964970
}
971+
972+
/*
973+
* Get next hop weights
974+
* @arg route_obj route object
975+
*
976+
* Return concatenation of interface names: wt0 + "," + wt1 + .... + "," + wtN
977+
*/
978+
string RouteSync::getNextHopWt(struct rtnl_route *route_obj)
979+
{
980+
string result = "";
981+
982+
for (int i = 0; i < rtnl_route_get_nnexthops(route_obj); i++)
983+
{
984+
struct rtnl_nexthop *nexthop = rtnl_route_nexthop_n(route_obj, i);
985+
/* Get the weight of next hop */
986+
uint8_t weight = rtnl_route_nh_get_weight(nexthop);
987+
if (weight)
988+
{
989+
result += to_string(weight + 1);
990+
}
991+
else
992+
{
993+
return "";
994+
}
995+
996+
if (i + 1 < rtnl_route_get_nnexthops(route_obj))
997+
{
998+
result += string(",");
999+
}
1000+
}
1001+
1002+
return result;
1003+
}

fpmsyncd/routesync.h

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ class RouteSync : public NetMsg
7575

7676
/* Get next hop interfaces */
7777
string getNextHopIf(struct rtnl_route *route_obj);
78+
79+
/* Get next hop weights*/
80+
string getNextHopWt(struct rtnl_route *route_obj);
7881
};
7982

8083
}

orchagent/nexthopgroupkey.h

+15
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ class NextHopGroupKey
3131
}
3232
}
3333

34+
NextHopGroupKey(const std::string &nexthops, const std::string &weights)
35+
{
36+
std::vector<std::string> nhv = tokenize(nexthops, NHG_DELIMITER);
37+
std::vector<std::string> wtv = tokenize(weights, NHG_DELIMITER);
38+
for (uint32_t i = 0; i < nhv.size(); i++)
39+
{
40+
NextHopKey nh(nhv[i]);
41+
if (i < wtv.size())
42+
{
43+
nh.weight = (uint32_t)std::stoi(wtv[i]);
44+
}
45+
m_nexthops.insert(nh);
46+
}
47+
}
48+
3449
inline const std::set<NextHopKey> &getNextHops() const
3550
{
3651
return m_nexthops;

orchagent/nexthopkey.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ struct NextHopKey
1515
string alias; // incoming interface alias
1616
uint32_t vni; // Encap VNI overlay nexthop
1717
MacAddress mac_address; // Overlay Nexthop MAC.
18+
uint32_t weight; // NH weight for NHGs
1819

19-
NextHopKey() = default;
20-
NextHopKey(const std::string &ipstr, const std::string &alias) : ip_address(ipstr), alias(alias), vni(0), mac_address() {}
21-
NextHopKey(const IpAddress &ip, const std::string &alias) : ip_address(ip), alias(alias), vni(0), mac_address() {}
20+
21+
NextHopKey() : weight(0) {}
22+
NextHopKey(const std::string &ipstr, const std::string &alias) : ip_address(ipstr), alias(alias), vni(0), mac_address(), weight(0) {}
23+
NextHopKey(const IpAddress &ip, const std::string &alias) : ip_address(ip), alias(alias), vni(0), mac_address(), weight(0) {}
2224
NextHopKey(const std::string &str)
2325
{
2426
if (str.find(NHG_DELIMITER) != string::npos)

orchagent/routeorch.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,13 @@ bool RouteOrch::validnexthopinNextHopGroup(const NextHopKey &nexthop, uint32_t&
325325
nhgm_attr.value.oid = m_neighOrch->getNextHopId(nexthop);
326326
nhgm_attrs.push_back(nhgm_attr);
327327

328+
if (nexthop.weight)
329+
{
330+
nhgm_attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_WEIGHT;
331+
nhgm_attr.value.s32 = nexthop.weight;
332+
nhgm_attrs.push_back(nhgm_attr);
333+
}
334+
328335
status = sai_next_hop_group_api->create_next_hop_group_member(&nexthop_id, gSwitchId,
329336
(uint32_t)nhgm_attrs.size(),
330337
nhgm_attrs.data());
@@ -513,6 +520,7 @@ void RouteOrch::doTask(Consumer& consumer)
513520
string aliases;
514521
string vni_labels;
515522
string remote_macs;
523+
string weights;
516524
bool& excp_intfs_flag = ctx.excp_intfs_flag;
517525
bool overlay_nh = false;
518526
bool blackhole = false;
@@ -535,6 +543,9 @@ void RouteOrch::doTask(Consumer& consumer)
535543

536544
if (fvField(i) == "blackhole")
537545
blackhole = fvValue(i) == "true";
546+
547+
if (fvField(i) == "weight")
548+
weights = fvValue(i);
538549
}
539550

540551
vector<string>& ipv = ctx.ipv;
@@ -624,7 +635,7 @@ void RouteOrch::doTask(Consumer& consumer)
624635
nhg_str += NHG_DELIMITER + ipv[i] + NH_DELIMITER + alsv[i];
625636
}
626637

627-
nhg = NextHopGroupKey(nhg_str);
638+
nhg = NextHopGroupKey(nhg_str, weights);
628639

629640
}
630641
else
@@ -1102,6 +1113,7 @@ bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops)
11021113
for (size_t i = 0; i < npid_count; i++)
11031114
{
11041115
auto nhid = next_hop_ids[i];
1116+
auto weight = nhopgroup_members_set[nhid].weight;
11051117

11061118
// Create a next hop group member
11071119
vector<sai_attribute_t> nhgm_attrs;
@@ -1115,6 +1127,13 @@ bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops)
11151127
nhgm_attr.value.oid = nhid;
11161128
nhgm_attrs.push_back(nhgm_attr);
11171129

1130+
if (weight)
1131+
{
1132+
nhgm_attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_WEIGHT;
1133+
nhgm_attr.value.s32 = weight;
1134+
nhgm_attrs.push_back(nhgm_attr);
1135+
}
1136+
11181137
gNextHopGroupMemberBulker.create_entry(&nhgm_ids[i],
11191138
(uint32_t)nhgm_attrs.size(),
11201139
nhgm_attrs.data());

tests/test_nhg.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ def test_route_nhg(self, dvs, dvs_route, testlog):
4444

4545
dvs_route.check_asicdb_deleted_route_entries([rtprefix])
4646

47-
fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.1,10.0.0.3,10.0.0.5"), ("ifname", "Ethernet0,Ethernet4,Ethernet8")])
47+
fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.1,10.0.0.3,10.0.0.5"),
48+
("ifname", "Ethernet0,Ethernet4,Ethernet8"),
49+
("weight", "10,30,50")])
4850
ps.set(rtprefix, fvs)
4951

5052
# check if route was propagated to ASIC DB
@@ -68,6 +70,16 @@ def test_route_nhg(self, dvs, dvs_route, testlog):
6870

6971
assert fvs["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID"] == nhgid
7072

73+
# verify weight attributes in asic db
74+
nhid = fvs["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID"]
75+
weight = fvs["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_WEIGHT"]
76+
77+
fvs = asic_db.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP", nhid)
78+
nhip = fvs["SAI_NEXT_HOP_ATTR_IP"].split('.')
79+
expected_weight = int(nhip[3]) * 10
80+
81+
assert int(weight) == expected_weight
82+
7183
# bring links down one-by-one
7284
for i in [0, 1, 2]:
7385
dvs.servers[i].runcmd("ip link set down dev eth0") == 0

0 commit comments

Comments
 (0)