Skip to content

Commit

Permalink
[swss/cfgmgr] teammgr configure lacp rate (#2121)
Browse files Browse the repository at this point in the history
* add lacp_rate config
* add lacp_rate to teammgr addLag params
* docs for portchannel db config
* add test

Co-authored-by: Anton <[email protected]>
Co-authored-by: Myron Sosyak <[email protected]>
  • Loading branch information
3 people authored Aug 3, 2022
1 parent 3161eaa commit dc477fb
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 12 deletions.
20 changes: 16 additions & 4 deletions cfgmgr/teammgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ void TeamMgr::doLagTask(Consumer &consumer)
{
int min_links = 0;
bool fallback = false;
bool fast_rate = false;
string admin_status = DEFAULT_ADMIN_STATUS_STR;
string mtu = DEFAULT_MTU_STR;
string learn_mode;
Expand Down Expand Up @@ -293,12 +294,18 @@ void TeamMgr::doLagTask(Consumer &consumer)
{
tpid = fvValue(i);
SWSS_LOG_INFO("Get TPID %s", tpid.c_str());
}
}
else if (fvField(i) == "fast_rate")
{
fast_rate = fvValue(i) == "true";
SWSS_LOG_INFO("Get fast_rate `%s`",
fast_rate ? "true" : "false");
}
}

if (m_lagList.find(alias) == m_lagList.end())
{
if (addLag(alias, min_links, fallback) == task_need_retry)
if (addLag(alias, min_links, fallback, fast_rate) == task_need_retry)
{
it++;
continue;
Expand Down Expand Up @@ -553,7 +560,7 @@ bool TeamMgr::setLagLearnMode(const string &alias, const string &learn_mode)
return true;
}

task_process_status TeamMgr::addLag(const string &alias, int min_links, bool fallback)
task_process_status TeamMgr::addLag(const string &alias, int min_links, bool fallback, bool fast_rate)
{
SWSS_LOG_ENTER();

Expand Down Expand Up @@ -610,6 +617,11 @@ task_process_status TeamMgr::addLag(const string &alias, int min_links, bool fal
conf << ",\"fallback\":true";
}

if (fast_rate)
{
conf << ",\"fast_rate\":true";
}

conf << "}}'";

SWSS_LOG_INFO("Port channel %s teamd configuration: %s",
Expand Down Expand Up @@ -652,7 +664,7 @@ bool TeamMgr::removeLag(const string &alias)
}

// Port-channel names are in the pattern of "PortChannel####"
//
//
// The LACP key could be generated in 3 ways based on the value in config DB:
// 1. "auto" - LACP key is extracted from the port-channel name and is set to be the number at the end of the port-channel name
// We are adding 1 at the beginning to avoid LACP key collisions between similar LACP keys e.g. PortChannel10 and PortChannel010.
Expand Down
2 changes: 1 addition & 1 deletion cfgmgr/teammgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class TeamMgr : public Orch
void doLagMemberTask(Consumer &consumer);
void doPortUpdateTask(Consumer &consumer);

task_process_status addLag(const std::string &alias, int min_links, bool fall_back);
task_process_status addLag(const std::string &alias, int min_links, bool fall_back, bool fast_rate);
bool removeLag(const std::string &alias);
task_process_status addLagMember(const std::string &lag, const std::string &member);
bool removeLagMember(const std::string &lag, const std::string &member);
Expand Down
7 changes: 4 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ def create_servers(self):
for i in range(NUM_PORTS):
server = VirtualServer(self.ctn_sw.name, self.ctn_sw_pid, i)
self.servers.append(server)

def reset_dbs(self):
# DB wrappers are declared here, lazy-loaded in the tests
self.app_db = None
Expand Down Expand Up @@ -1853,7 +1853,8 @@ def dvs_route(request, dvs) -> DVSRoute:
@pytest.yield_fixture(scope="class")
def dvs_lag_manager(request, dvs):
request.cls.dvs_lag = dvs_lag.DVSLag(dvs.get_asic_db(),
dvs.get_config_db())
dvs.get_config_db(),
dvs)


@pytest.yield_fixture(scope="class")
Expand All @@ -1868,7 +1869,7 @@ def dvs_vlan_manager(request, dvs):
def dvs_port_manager(request, dvs):
request.cls.dvs_port = dvs_port.DVSPort(dvs.get_asic_db(),
dvs.get_config_db())

@pytest.yield_fixture(scope="class")
def dvs_mirror_manager(request, dvs):
request.cls.dvs_mirror = dvs_mirror.DVSMirror(dvs.get_asic_db(),
Expand Down
18 changes: 15 additions & 3 deletions tests/dvslib/dvs_lag.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import json

class DVSLag(object):
def __init__(self, adb, cdb):
def __init__(self, adb, cdb, dvs):
self.asic_db = adb
self.config_db = cdb
self.dvs = dvs

def create_port_channel(self, lag_id, admin_status="up", mtu="1500"):
def create_port_channel(self, lag_id, admin_status="up", mtu="1500", fast_rate=False):
lag = "PortChannel{}".format(lag_id)
lag_entry = {"admin_status": admin_status, "mtu": mtu}
lag_entry = {"admin_status": admin_status, "mtu": mtu, "fast_rate": str(fast_rate).lower()}
self.config_db.create_entry("PORTCHANNEL", lag, lag_entry)

def remove_port_channel(self, lag_id):
Expand All @@ -27,3 +30,12 @@ def get_and_verify_port_channel_members(self, expected_num):
def get_and_verify_port_channel(self, expected_num):
return self.asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_LAG", expected_num)

def dump_portchannel(self, lag_id):
lag = "PortChannel{}".format(lag_id)
output = self.dvs.runcmd("teamdctl {} state dump".format(lag))[1]
port_state_dump = json.loads(output)
return port_state_dump

def get_and_verify_port_channel_fast_rate(self, lag_id, fast_rate):
assert self.dump_portchannel(lag_id)["runner"]["fast_rate"] == fast_rate

26 changes: 25 additions & 1 deletion tests/test_portchannel.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
import time
import re
import json
Expand All @@ -6,6 +7,7 @@
from swsscommon import swsscommon


@pytest.mark.usefixtures('dvs_lag_manager')
class TestPortchannel(object):
def test_Portchannel(self, dvs, testlog):

Expand Down Expand Up @@ -89,6 +91,28 @@ def test_Portchannel(self, dvs, testlog):
lagms = lagmtbl.getKeys()
assert len(lagms) == 0

@pytest.mark.parametrize("fast_rate", [False, True])
def test_Portchannel_fast_rate(self, dvs, testlog, fast_rate):
po_id = "0003"
po_member = "Ethernet16"

# Create PortChannel
self.dvs_lag.create_port_channel(po_id, fast_rate=fast_rate)
self.dvs_lag.get_and_verify_port_channel(1)

# Add member to PortChannel
self.dvs_lag.create_port_channel_member(po_id, po_member)
self.dvs_lag.get_and_verify_port_channel_members(1)

# test fast rate configuration
self.dvs_lag.get_and_verify_port_channel_fast_rate(po_id, fast_rate)

# remove PortChannel
self.dvs_lag.create_port_channel_member(po_id, po_member)

This comment has been minimized.

Copy link
@prabhataravind

prabhataravind Aug 8, 2022

Contributor

Shouldn't this be remove_port_channel_member instead of create_port_channel_member?

self.dvs_lag.remove_port_channel(po_id)
self.dvs_lag.get_and_verify_port_channel(0)


def test_Portchannel_lacpkey(self, dvs, testlog):
portchannelNamesAuto = [("PortChannel001", "Ethernet0", 1001),
("PortChannel002", "Ethernet4", 1002),
Expand All @@ -108,7 +132,7 @@ def test_Portchannel_lacpkey(self, dvs, testlog):

for portchannel in portchannelNamesAuto:
tbl.set(portchannel[0], fvs)

fvs_no_lacp_key = swsscommon.FieldValuePairs(
[("admin_status", "up"), ("mtu", "9100"), ("oper_status", "up")])
tbl.set(portchannelNames[0][0], fvs_no_lacp_key)
Expand Down

0 comments on commit dc477fb

Please sign in to comment.