Skip to content

Commit

Permalink
[nhg]: Add support for weight in nexthop group member. (#1752)
Browse files Browse the repository at this point in the history
* 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 <zcai@juniper.net>
  • Loading branch information
caizhenghui-juniper authored May 26, 2021
1 parent 5c625b2 commit a44e651
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 5 deletions.
39 changes: 39 additions & 0 deletions fpmsyncd/routesync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,7 @@ void RouteSync::onRouteMsg(int nlmsg_type, struct nl_object *obj, char *vrf)
/* Get nexthop lists */
string nexthops = getNextHopGw(route_obj);
string ifnames = getNextHopIf(route_obj);
string weights = getNextHopWt(route_obj);

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

fvVector.push_back(nh);
fvVector.push_back(idx);
if (!weights.empty())
{
FieldValueTuple wt("weight", weights);
fvVector.push_back(wt);
}

if (!warmRestartInProgress)
{
Expand Down Expand Up @@ -962,3 +968,36 @@ string RouteSync::getNextHopIf(struct rtnl_route *route_obj)

return result;
}

/*
* Get next hop weights
* @arg route_obj route object
*
* Return concatenation of interface names: wt0 + "," + wt1 + .... + "," + wtN
*/
string RouteSync::getNextHopWt(struct rtnl_route *route_obj)
{
string result = "";

for (int i = 0; i < rtnl_route_get_nnexthops(route_obj); i++)
{
struct rtnl_nexthop *nexthop = rtnl_route_nexthop_n(route_obj, i);
/* Get the weight of next hop */
uint8_t weight = rtnl_route_nh_get_weight(nexthop);
if (weight)
{
result += to_string(weight + 1);
}
else
{
return "";
}

if (i + 1 < rtnl_route_get_nnexthops(route_obj))
{
result += string(",");
}
}

return result;
}
3 changes: 3 additions & 0 deletions fpmsyncd/routesync.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ class RouteSync : public NetMsg

/* Get next hop interfaces */
string getNextHopIf(struct rtnl_route *route_obj);

/* Get next hop weights*/
string getNextHopWt(struct rtnl_route *route_obj);
};

}
Expand Down
15 changes: 15 additions & 0 deletions orchagent/nexthopgroupkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ class NextHopGroupKey
}
}

NextHopGroupKey(const std::string &nexthops, const std::string &weights)
{
std::vector<std::string> nhv = tokenize(nexthops, NHG_DELIMITER);
std::vector<std::string> wtv = tokenize(weights, NHG_DELIMITER);
for (uint32_t i = 0; i < nhv.size(); i++)
{
NextHopKey nh(nhv[i]);
if (i < wtv.size())
{
nh.weight = (uint32_t)std::stoi(wtv[i]);
}
m_nexthops.insert(nh);
}
}

inline const std::set<NextHopKey> &getNextHops() const
{
return m_nexthops;
Expand Down
8 changes: 5 additions & 3 deletions orchagent/nexthopkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ struct NextHopKey
string alias; // incoming interface alias
uint32_t vni; // Encap VNI overlay nexthop
MacAddress mac_address; // Overlay Nexthop MAC.
uint32_t weight; // NH weight for NHGs

NextHopKey() = default;
NextHopKey(const std::string &ipstr, const std::string &alias) : ip_address(ipstr), alias(alias), vni(0), mac_address() {}
NextHopKey(const IpAddress &ip, const std::string &alias) : ip_address(ip), alias(alias), vni(0), mac_address() {}

NextHopKey() : weight(0) {}
NextHopKey(const std::string &ipstr, const std::string &alias) : ip_address(ipstr), alias(alias), vni(0), mac_address(), weight(0) {}
NextHopKey(const IpAddress &ip, const std::string &alias) : ip_address(ip), alias(alias), vni(0), mac_address(), weight(0) {}
NextHopKey(const std::string &str)
{
if (str.find(NHG_DELIMITER) != string::npos)
Expand Down
21 changes: 20 additions & 1 deletion orchagent/routeorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,13 @@ bool RouteOrch::validnexthopinNextHopGroup(const NextHopKey &nexthop, uint32_t&
nhgm_attr.value.oid = m_neighOrch->getNextHopId(nexthop);
nhgm_attrs.push_back(nhgm_attr);

if (nexthop.weight)
{
nhgm_attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_WEIGHT;
nhgm_attr.value.s32 = nexthop.weight;
nhgm_attrs.push_back(nhgm_attr);
}

status = sai_next_hop_group_api->create_next_hop_group_member(&nexthop_id, gSwitchId,
(uint32_t)nhgm_attrs.size(),
nhgm_attrs.data());
Expand Down Expand Up @@ -513,6 +520,7 @@ void RouteOrch::doTask(Consumer& consumer)
string aliases;
string vni_labels;
string remote_macs;
string weights;
bool& excp_intfs_flag = ctx.excp_intfs_flag;
bool overlay_nh = false;
bool blackhole = false;
Expand All @@ -535,6 +543,9 @@ void RouteOrch::doTask(Consumer& consumer)

if (fvField(i) == "blackhole")
blackhole = fvValue(i) == "true";

if (fvField(i) == "weight")
weights = fvValue(i);
}

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

nhg = NextHopGroupKey(nhg_str);
nhg = NextHopGroupKey(nhg_str, weights);

}
else
Expand Down Expand Up @@ -1102,6 +1113,7 @@ bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops)
for (size_t i = 0; i < npid_count; i++)
{
auto nhid = next_hop_ids[i];
auto weight = nhopgroup_members_set[nhid].weight;

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

if (weight)
{
nhgm_attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_WEIGHT;
nhgm_attr.value.s32 = weight;
nhgm_attrs.push_back(nhgm_attr);
}

gNextHopGroupMemberBulker.create_entry(&nhgm_ids[i],
(uint32_t)nhgm_attrs.size(),
nhgm_attrs.data());
Expand Down
14 changes: 13 additions & 1 deletion tests/test_nhg.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ def test_route_nhg(self, dvs, dvs_route, testlog):

dvs_route.check_asicdb_deleted_route_entries([rtprefix])

fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.1,10.0.0.3,10.0.0.5"), ("ifname", "Ethernet0,Ethernet4,Ethernet8")])
fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.1,10.0.0.3,10.0.0.5"),
("ifname", "Ethernet0,Ethernet4,Ethernet8"),
("weight", "10,30,50")])
ps.set(rtprefix, fvs)

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

assert fvs["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID"] == nhgid

# verify weight attributes in asic db
nhid = fvs["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID"]
weight = fvs["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_WEIGHT"]

fvs = asic_db.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP", nhid)
nhip = fvs["SAI_NEXT_HOP_ATTR_IP"].split('.')
expected_weight = int(nhip[3]) * 10

assert int(weight) == expected_weight

# bring links down one-by-one
for i in [0, 1, 2]:
dvs.servers[i].runcmd("ip link set down dev eth0") == 0
Expand Down

0 comments on commit a44e651

Please sign in to comment.