Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sub port interface implementation #969

Merged
merged 57 commits into from
Nov 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
ccbfb48
Remove unused data member
wendani Jun 19, 2019
6c99720
IntfMgr parses dot1q interface
wendani Jun 25, 2019
9a1dde4
Set dot1q interface state
wendani Jun 25, 2019
ed9f2e9
Fix compile error
wendani Jun 25, 2019
4ddb2da
Remove sub interface from STATE_DB in DEL_COMMAND
wendani Jun 26, 2019
fb8a564
Create sub interface only once; retry if netlink command fails
wendani Jun 26, 2019
fb045d3
Follow naming convention
wendani Jun 26, 2019
b15eee6
Create Port object for sub interface
wendani Jun 27, 2019
a02dc31
Introduce parent_port_id in Port to track the oid of the parent inter…
wendani Jun 27, 2019
f8e482a
Deal with sub port case in creating router interface
wendani Jun 27, 2019
f5f49d3
Let parent port track its child sub ports
wendani Jun 27, 2019
5cf5074
Remove admin status field and its processing in CONFIG_DB; Runtime mt…
wendani Jun 28, 2019
60b3296
Fix compile error
wendani Jun 28, 2019
3a6ecce
Fix compile error for runtime mtu change
wendani Jun 28, 2019
fcd0772
Move sub port add/remove as member functions to PortsOrch; Add sub i…
wendani Jun 28, 2019
99c887b
Fix compile error
wendani Jun 29, 2019
0014f40
Remove sub interface alias from IntfMgr::m_subIntfList
wendani Jul 1, 2019
789b198
Merge remote-tracking branch 'public/master' into sub_intf_master
wendani Aug 27, 2019
de1577f
Disable mtu config; Inherit mtu from parent port or port channel
wendani Aug 30, 2019
fd66f3d
Per sub port interface mtu config
wendani Aug 30, 2019
4f64469
CONFIG_DB table name schema change
wendani Aug 30, 2019
b57e78c
Explicitly set admin status in creating sub port interface
wendani Aug 30, 2019
642c708
Set admin status up to host sub port interface if admin_status is not…
wendani Sep 3, 2019
fc54c58
Remove debugging logs
wendani Sep 4, 2019
b1aff64
Define macro for vlan sub interface separator "."
wendani Sep 4, 2019
07a85aa
Merge remote-tracking branch 'public/master' into sub_intf_master
wendani Sep 5, 2019
227848c
Remove the need to create an object id for vlan in creating a sub port
wendani Sep 5, 2019
a43889a
Add test on creating a sub port interface
wendani Sep 6, 2019
892380e
Consolidate check with one utility
wendani Sep 6, 2019
1052443
Add test on sub port interface creation
wendani Sep 7, 2019
d6163db
Add test on adding ip addresses to a sub port interface
wendani Sep 7, 2019
0b8bd14
Add test on sub port interface admin status change
wendani Sep 8, 2019
b09fb5a
Add test on removing IP addresses from a sub port interface
wendani Sep 8, 2019
672ef03
Break long statement into multi-lines
wendani Sep 8, 2019
1207094
Add test on removing a sub port interface
wendani Sep 8, 2019
3896135
Merge remote-tracking branch 'public/master' into sub_intf_master
wendani Sep 8, 2019
6f2d143
Merge remote-tracking branch 'public/master' into sub_intf_master
wendani Oct 1, 2019
e127cf6
Address comment: validate caller input before concatenate a system call
wendani Oct 1, 2019
3914387
Address comment: include & specify namespace
wendani Oct 1, 2019
5620d26
Address comment: not use reference
wendani Oct 1, 2019
4f64be8
Correct BUFFER_PG table schema name in comment
wendani Oct 1, 2019
2a1dab3
Address comment: not using namespace in header files
wendani Oct 1, 2019
018cf2d
Address comment: remove redundant check
wendani Oct 2, 2019
67b93d2
Address comment: check parent port name contains only alphanumeric
wendani Oct 2, 2019
b33df4e
Address comment: remove mtu field processing
wendani Oct 2, 2019
965dafd
check parent port name contains only alphanumeric characters and vlan id
wendani Oct 2, 2019
0ceb374
Fix compile error caused by removing namespace swss
wendani Oct 3, 2019
631f3f7
Merge remote-tracking branch 'public/master' into sub_intf_master
wendani Oct 4, 2019
59049bb
Allow buffer profile application after init (i.e., at run time)
wendani Oct 18, 2019
fd7089e
Fix compile error
wendani Oct 31, 2019
759bf2f
Merge remote-tracking branch 'public/master' into sub_intf_master
wendani Nov 1, 2019
0011b12
Resolve vs sub port interface test failure
wendani Nov 2, 2019
7f59f07
Address comments: Handling all default values for fields at the IntfMgr
wendani Nov 6, 2019
c4bd373
Fix compile error; IntfMgr change variable mtu to type string
wendani Nov 6, 2019
a2a8531
setIntf: differentiate between create/set sub interface and add/remove
wendani Nov 6, 2019
fe91b6c
Merge remote-tracking branch 'public/master' into sub_intf_master
wendani Nov 6, 2019
bdb92b6
Add sub interface to STATE_DB INTERFACE_TABLE introduced by vrf feature
wendani Nov 7, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 247 additions & 9 deletions cfgmgr/intfmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ using namespace swss;
#define LAG_PREFIX "PortChannel"
#define LOOPBACK_PREFIX "Loopback"
#define VNET_PREFIX "Vnet"
#define MTU_INHERITANCE "0"
#define VRF_PREFIX "Vrf"

#define LOOPBACK_DEFAULT_MTU_STR "65536"

IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector<string> &tableNames) :
Orch(cfgDb, tableNames),
m_cfgIntfTable(cfgDb, CFG_INTF_TABLE_NAME),
m_cfgVlanIntfTable(cfgDb, CFG_VLAN_INTF_TABLE_NAME),
m_statePortTable(stateDb, STATE_PORT_TABLE_NAME),
m_stateLagTable(stateDb, STATE_LAG_TABLE_NAME),
m_stateVlanTable(stateDb, STATE_VLAN_TABLE_NAME),
Expand Down Expand Up @@ -167,6 +166,157 @@ bool IntfMgr::isIntfChangeVrf(const string &alias, const string &vrfName)
return false;
}

void IntfMgr::addHostSubIntf(const string&intf, const string &subIntf, const string &vlan)
{
// TODO: remove when validation check at mgmt is in place
for (const auto &c : intf)
{
if (!isalnum(c))
{
SWSS_LOG_ERROR("Invalid parent port name %s for host sub interface %s", intf.c_str(), subIntf.c_str());
return;
}
}
for (const auto &c : vlan)
{
if (!isdigit(c))
{
SWSS_LOG_ERROR("Invalid vlan id %s for host sub interface %s", vlan.c_str(), subIntf.c_str());
return;
}
}

stringstream cmd;
string res;

cmd << IP_CMD << " link add link " << intf << " name " << subIntf << " type vlan id " << vlan;
wendani marked this conversation as resolved.
Show resolved Hide resolved
EXEC_WITH_ERROR_THROW(cmd.str(), res);
}

void IntfMgr::setHostSubIntfMtu(const string &subIntf, const string &mtu)
{
// TODO: remove when validation check at mgmt is in place
size_t found = subIntf.find(VLAN_SUB_INTERFACE_SEPARATOR);
if (found == string::npos)
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
size_t i = 0;
for (const auto &c : subIntf)
{
if (i < found && !isalnum(c))
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
else if (i > found && !isdigit(c))
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
i++;
}

stringstream cmd;
string res;

cmd << IP_CMD << " link set " << subIntf << " mtu " << mtu;
EXEC_WITH_ERROR_THROW(cmd.str(), res);
}

void IntfMgr::setHostSubIntfAdminStatus(const string &subIntf, const string &adminStatus)
{
// TODO: remove when validation check at mgmt is in place
size_t found = subIntf.find(VLAN_SUB_INTERFACE_SEPARATOR);
if (found == string::npos)
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
size_t i = 0;
for (const auto &c : subIntf)
{
if (i < found && !isalnum(c))
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
else if (i > found && !isdigit(c))
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
i++;
}

stringstream cmd;
string res;

cmd << IP_CMD << " link set " << subIntf << " " << adminStatus;
EXEC_WITH_ERROR_THROW(cmd.str(), res);
}

void IntfMgr::removeHostSubIntf(const string &subIntf)
{
// TODO: remove when validation check at mgmt is in place
size_t found = subIntf.find(VLAN_SUB_INTERFACE_SEPARATOR);
if (found == string::npos)
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
size_t i = 0;
for (const auto &c : subIntf)
{
if (i < found && !isalnum(c))
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
else if (i > found && !isdigit(c))
{
SWSS_LOG_ERROR("Invalid host sub interface name: %s", subIntf.c_str());
return;
}
i++;
}

stringstream cmd;
string res;

cmd << IP_CMD << " link del " << subIntf;
EXEC_WITH_ERROR_THROW(cmd.str(), res);
}

void IntfMgr::setSubIntfStateOk(const string &alias)
{
vector<FieldValueTuple> fvTuples = {{"state", "ok"}};

if (!alias.compare(0, strlen(LAG_PREFIX), LAG_PREFIX))
{
m_stateLagTable.set(alias, fvTuples);
}
else
{
// EthernetX using PORT_TABLE
m_statePortTable.set(alias, fvTuples);
}
}

void IntfMgr::removeSubIntfState(const string &alias)
{
if (!alias.compare(0, strlen(LAG_PREFIX), LAG_PREFIX))
{
m_stateLagTable.del(alias);
}
else
{
// EthernetX using PORT_TABLE
m_statePortTable.del(alias);
}
}

bool IntfMgr::isIntfStateOk(const string &alias)
{
vector<FieldValueTuple> temp;
Expand Down Expand Up @@ -217,23 +367,43 @@ bool IntfMgr::isIntfStateOk(const string &alias)
}

bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
const vector<FieldValueTuple>& data,
vector<FieldValueTuple> data,
const string& op)
{
SWSS_LOG_ENTER();

string alias(keys[0]);
string vrf_name = "";
string vlanId;
string subIntfAlias;
size_t found = alias.find(VLAN_SUB_INTERFACE_SEPARATOR);
if (found != string::npos)
{
// This is a sub interface
// subIntfAlias holds the complete sub interface name
// while alias becomes the parent interface
subIntfAlias = alias;
vlanId = alias.substr(found + 1);
alias = alias.substr(0, found);
}
bool is_lo = !alias.compare(0, strlen(LOOPBACK_PREFIX), LOOPBACK_PREFIX);

string vrf_name = "";
string mtu = "";
string adminStatus = "";
for (auto idx : data)
{
const auto &field = fvField(idx);
const auto &value = fvValue(idx);

if (field == "vnet_name" || field == "vrf_name")
{
vrf_name = value;
}

if (field == "admin_status")
{
adminStatus = value;
}
}

if (op == SET_COMMAND)
Expand All @@ -256,16 +426,73 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
SWSS_LOG_ERROR("%s can not change to %s directly, skipping", alias.c_str(), vrf_name.c_str());
return true;
}

if (is_lo)
{
addLoopbackIntf(alias);
}

if (!vrf_name.empty())
{
setIntfVrf(alias, vrf_name);
}
m_appIntfTableProducer.set(alias, data);
m_stateIntfTable.hset(alias, "vrf", vrf_name);

if (!subIntfAlias.empty())
{
if (m_subIntfList.find(subIntfAlias) == m_subIntfList.end())
{
try
{
addHostSubIntf(alias, subIntfAlias, vlanId);
}
catch (const std::runtime_error &e)
{
SWSS_LOG_NOTICE("Sub interface ip link add failure. Runtime error: %s", e.what());
return false;
}

m_subIntfList.insert(subIntfAlias);
}

if (!mtu.empty())
{
try
{
setHostSubIntfMtu(subIntfAlias, mtu);
}
catch (const std::runtime_error &e)
{
SWSS_LOG_NOTICE("Sub interface ip link set mtu failure. Runtime error: %s", e.what());
return false;
}
}
else
{
FieldValueTuple fvTuple("mtu", MTU_INHERITANCE);
data.push_back(fvTuple);
}

if (adminStatus.empty())
{
adminStatus = "up";
FieldValueTuple fvTuple("admin_status", adminStatus);
data.push_back(fvTuple);
}
try
{
setHostSubIntfAdminStatus(subIntfAlias, adminStatus);
}
catch (const std::runtime_error &e)
{
SWSS_LOG_NOTICE("Sub interface ip link set admin status %s failure. Runtime error: %s", adminStatus.c_str(), e.what());
return false;
}

// set STATE_DB port state
setSubIntfStateOk(subIntfAlias);
}
m_appIntfTableProducer.set(subIntfAlias.empty() ? alias : subIntfAlias, data);
m_stateIntfTable.hset(subIntfAlias.empty() ? alias : subIntfAlias, "vrf", vrf_name);
}
else if (op == DEL_COMMAND)
{
Expand All @@ -275,13 +502,24 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
{
return false;
}

setIntfVrf(alias, "");

if (is_lo)
{
delLoopbackIntf(alias);
}
m_appIntfTableProducer.del(alias);
m_stateIntfTable.del(alias);

if (!subIntfAlias.empty())
{
removeHostSubIntf(subIntfAlias);
m_subIntfList.erase(subIntfAlias);

removeSubIntfState(subIntfAlias);
}

m_appIntfTableProducer.del(subIntfAlias.empty() ? alias : subIntfAlias);
m_stateIntfTable.del(subIntfAlias.empty() ? alias : subIntfAlias);
}
else
{
Expand All @@ -304,7 +542,7 @@ bool IntfMgr::doIntfAddrTask(const vector<string>& keys,
if (op == SET_COMMAND)
{
/*
* Don't proceed if port/LAG/VLAN and intfGeneral are not ready yet.
* Don't proceed if port/LAG/VLAN/subport and intfGeneral is not ready yet.
* The pending task will be checked periodically and retried.
*/
if (!isIntfStateOk(alias) || !isIntfCreated(alias))
Expand Down
13 changes: 11 additions & 2 deletions cfgmgr/intfmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <map>
#include <string>
#include <set>

namespace swss {

Expand All @@ -18,12 +19,13 @@ class IntfMgr : public Orch

private:
ProducerStateTable m_appIntfTableProducer;
Table m_cfgIntfTable, m_cfgVlanIntfTable;
Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateVrfTable, m_stateIntfTable;

std::set<std::string> m_subIntfList;

void setIntfIp(const std::string &alias, const std::string &opCmd, const IpPrefix &ipPrefix);
void setIntfVrf(const std::string &alias, const std::string &vrfName);
bool doIntfGeneralTask(const std::vector<std::string>& keys, const std::vector<FieldValueTuple>& data, const std::string& op);
bool doIntfGeneralTask(const std::vector<std::string>& keys, std::vector<FieldValueTuple> data, const std::string& op);
bool doIntfAddrTask(const std::vector<std::string>& keys, const std::vector<FieldValueTuple>& data, const std::string& op);
void doTask(Consumer &consumer);
bool isIntfStateOk(const std::string &alias);
Expand All @@ -32,6 +34,13 @@ class IntfMgr : public Orch
int getIntfIpCount(const std::string &alias);
void addLoopbackIntf(const std::string &alias);
void delLoopbackIntf(const std::string &alias);

void addHostSubIntf(const std::string&intf, const std::string &subIntf, const std::string &vlan);
void setHostSubIntfMtu(const std::string &subIntf, const std::string &mtu);
void setHostSubIntfAdminStatus(const std::string &subIntf, const std::string &admin_status);
void removeHostSubIntf(const std::string &subIntf);
void setSubIntfStateOk(const std::string &alias);
void removeSubIntfState(const std::string &alias);
};

}
Expand Down
1 change: 1 addition & 0 deletions cfgmgr/intfmgrd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ int main(int argc, char **argv)
CFG_LAG_INTF_TABLE_NAME,
CFG_VLAN_INTF_TABLE_NAME,
CFG_LOOPBACK_INTERFACE_TABLE_NAME,
CFG_VLAN_SUB_INTF_TABLE_NAME,
};

DBConnector cfgDb(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
Expand Down
2 changes: 1 addition & 1 deletion orchagent/bufferorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ task_process_status BufferOrch::processQueue(Consumer &consumer)
}

/*
Input sample "BUFFER_PG_TABLE|Ethernet4,Ethernet45|10-15"
Input sample "BUFFER_PG|Ethernet4,Ethernet45|10-15"
*/
task_process_status BufferOrch::processPriorityGroup(Consumer &consumer)
{
Expand Down
Loading