Skip to content

Commit ca8ba6d

Browse files
[vlan] Add support of VLAN host interface (sonic-net#1645)
* [vlan] Add support of VLAN host interface * Infrastructure needed for the VNET ping tool Signed-off-by: Volodymyr Samotiy <[email protected]>
1 parent 5c63670 commit ca8ba6d

File tree

6 files changed

+123
-0
lines changed

6 files changed

+123
-0
lines changed

cfgmgr/vlanmgr.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ void VlanMgr::doVlanTask(Consumer &consumer)
306306
string admin_status;
307307
string mtu = DEFAULT_MTU_STR;
308308
string mac = gMacAddress.to_string();
309+
string hostif_name = "";
309310
vector<FieldValueTuple> fvVector;
310311
string members;
311312

@@ -362,6 +363,10 @@ void VlanMgr::doVlanTask(Consumer &consumer)
362363
mac = fvValue(i);
363364
setHostVlanMac(vlan_id, mac);
364365
}
366+
else if (fvField(i) == "hostif_name")
367+
{
368+
hostif_name = fvValue(i);
369+
}
365370
}
366371
/* fvVector should not be empty */
367372
if (fvVector.empty())
@@ -376,6 +381,9 @@ void VlanMgr::doVlanTask(Consumer &consumer)
376381
FieldValueTuple mc("mac", mac);
377382
fvVector.push_back(mc);
378383

384+
FieldValueTuple hostif_name_fvt("hostif_name", hostif_name);
385+
fvVector.push_back(hostif_name_fvt);
386+
379387
m_appVlanTableProducer.set(key, fvVector);
380388
m_vlans.insert(key);
381389

orchagent/port.h

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct VlanInfo
3636
{
3737
sai_object_id_t vlan_oid = 0;
3838
sai_vlan_id_t vlan_id = 0;
39+
sai_object_id_t host_intf_id = SAI_NULL_OBJECT_ID;
3940
};
4041

4142
struct SystemPortInfo

orchagent/portsorch.cpp

+71
Original file line numberDiff line numberDiff line change
@@ -1932,6 +1932,55 @@ bool PortsOrch::setHostIntfsOperStatus(const Port& port, bool isUp) const
19321932
return true;
19331933
}
19341934

1935+
bool PortsOrch::createVlanHostIntf(Port& vl, string hostif_name)
1936+
{
1937+
SWSS_LOG_ENTER();
1938+
1939+
if (vl.m_vlan_info.host_intf_id != SAI_NULL_OBJECT_ID)
1940+
{
1941+
SWSS_LOG_ERROR("Host interface already assigned to VLAN %d", vl.m_vlan_info.vlan_id);
1942+
return false;
1943+
}
1944+
1945+
vector<sai_attribute_t> attrs;
1946+
sai_attribute_t attr;
1947+
1948+
attr.id = SAI_HOSTIF_ATTR_TYPE;
1949+
attr.value.s32 = SAI_HOSTIF_TYPE_NETDEV;
1950+
attrs.push_back(attr);
1951+
1952+
attr.id = SAI_HOSTIF_ATTR_OBJ_ID;
1953+
attr.value.oid = vl.m_vlan_info.vlan_oid;
1954+
attrs.push_back(attr);
1955+
1956+
attr.id = SAI_HOSTIF_ATTR_NAME;
1957+
strncpy(attr.value.chardata, hostif_name.c_str(), sizeof(attr.value.chardata));
1958+
attrs.push_back(attr);
1959+
1960+
sai_status_t status = sai_hostif_api->create_hostif(&vl.m_vlan_info.host_intf_id, gSwitchId, (uint32_t)attrs.size(), attrs.data());
1961+
if (status != SAI_STATUS_SUCCESS)
1962+
{
1963+
SWSS_LOG_ERROR("Failed to create host interface %s for VLAN %d", hostif_name.c_str(), vl.m_vlan_info.vlan_id);
1964+
return false;
1965+
}
1966+
1967+
m_portList[vl.m_alias] = vl;
1968+
1969+
return true;
1970+
}
1971+
1972+
bool PortsOrch::removeVlanHostIntf(Port vl)
1973+
{
1974+
sai_status_t status = sai_hostif_api->remove_hostif(vl.m_vlan_info.host_intf_id);
1975+
if (status != SAI_STATUS_SUCCESS)
1976+
{
1977+
SWSS_LOG_ERROR("Failed to remove VLAN %d host interface", vl.m_vlan_info.vlan_id);
1978+
return false;
1979+
}
1980+
1981+
return true;
1982+
}
1983+
19351984
void PortsOrch::updateDbPortOperStatus(const Port& port, sai_port_oper_status_t status) const
19361985
{
19371986
SWSS_LOG_ENTER();
@@ -2870,6 +2919,7 @@ void PortsOrch::doVlanTask(Consumer &consumer)
28702919
// Retrieve attributes
28712920
uint32_t mtu = 0;
28722921
MacAddress mac;
2922+
string hostif_name = "";
28732923
for (auto i : kfvFieldsValues(t))
28742924
{
28752925
if (fvField(i) == "mtu")
@@ -2880,6 +2930,10 @@ void PortsOrch::doVlanTask(Consumer &consumer)
28802930
{
28812931
mac = MacAddress(fvValue(i));
28822932
}
2933+
if (fvField(i) == "hostif_name")
2934+
{
2935+
hostif_name = fvValue(i);
2936+
}
28832937
}
28842938

28852939
/*
@@ -2922,6 +2976,16 @@ void PortsOrch::doVlanTask(Consumer &consumer)
29222976
gIntfsOrch->setRouterIntfsMac(vl);
29232977
}
29242978
}
2979+
if (!hostif_name.empty())
2980+
{
2981+
if (!createVlanHostIntf(vl, hostif_name))
2982+
{
2983+
// No need to fail in case of error as this is for monitoring VLAN.
2984+
// Error message is printed by "createVlanHostIntf" so just handle failure gracefully.
2985+
it = consumer.m_toSync.erase(it);
2986+
continue;
2987+
}
2988+
}
29252989
}
29262990

29272991
it = consumer.m_toSync.erase(it);
@@ -3914,6 +3978,13 @@ bool PortsOrch::removeVlan(Port vlan)
39143978
return false;
39153979
}
39163980

3981+
3982+
if (vlan.m_vlan_info.host_intf_id && !removeVlanHostIntf(vlan))
3983+
{
3984+
SWSS_LOG_ERROR("Failed to remove VLAN %d host interface", vlan.m_vlan_info.vlan_id);
3985+
return false;
3986+
}
3987+
39173988
sai_status_t status = sai_vlan_api->remove_vlan(vlan.m_vlan_info.vlan_oid);
39183989
if (status != SAI_STATUS_SUCCESS)
39193990
{

orchagent/portsorch.h

+3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ class PortsOrch : public Orch, public Subject
9999
bool setHostIntfsOperStatus(const Port& port, bool up) const;
100100
void updateDbPortOperStatus(const Port& port, sai_port_oper_status_t status) const;
101101

102+
bool createVlanHostIntf(Port& vl, string hostif_name);
103+
bool removeVlanHostIntf(Port vl);
104+
102105
bool createBindAclTableGroup(sai_object_id_t port_oid,
103106
sai_object_id_t acl_table_oid,
104107
sai_object_id_t &group_oid,

tests/dvslib/dvs_vlan.py

+24
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ def create_vlan(self, vlan):
1313
vlan_entry = {"vlanid": vlan}
1414
self.config_db.create_entry("VLAN", vlan, vlan_entry)
1515

16+
def create_vlan_hostif(self, vlan, hostif_name):
17+
vlan = "Vlan{}".format(vlan)
18+
vlan_entry = {"vlanid": vlan, "hostif_name": hostif_name}
19+
self.config_db.update_entry("VLAN", vlan, vlan_entry)
20+
1621
def remove_vlan(self, vlan):
1722
vlan = "Vlan{}".format(vlan)
1823
self.config_db.delete_entry("VLAN", vlan)
@@ -53,6 +58,7 @@ def get_and_verify_vlan_ids(self,
5358
vlan_entries = self.asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_VLAN",
5459
expected_num + 1,
5560
polling_config)
61+
5662
return [v for v in vlan_entries if v != self.asic_db.default_vlan_id]
5763

5864
def verify_vlan_member(self, vlan_oid, iface, tagging_mode="SAI_VLAN_TAGGING_MODE_UNTAGGED"):
@@ -74,3 +80,21 @@ def get_bridge_port_id(self, expected_iface):
7480
assert self.asic_db.port_to_id_map[bridge_port["SAI_BRIDGE_PORT_ATTR_PORT_ID"]] == expected_iface
7581
return bridge_port_id
7682

83+
def verify_vlan_hostif(self, hostif_name, hostifs_oid, vlan_oid):
84+
hostif = {}
85+
86+
for hostif_oid in hostifs_oid:
87+
hostif = self.asic_db.wait_for_entry("ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF", hostif_oid)
88+
if hostif.get("SAI_HOSTIF_ATTR_NAME") == hostif_name:
89+
break
90+
91+
assert hostif.get("SAI_HOSTIF_ATTR_TYPE") == "SAI_HOSTIF_TYPE_NETDEV"
92+
assert hostif.get("SAI_HOSTIF_ATTR_OBJ_ID") == vlan_oid
93+
assert hostif.get("SAI_HOSTIF_ATTR_NAME") == hostif_name
94+
95+
def get_and_verify_vlan_hostif_ids(self, expected_num, polling_config=PollingConfig()):
96+
hostif_entries = self.asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF",
97+
expected_num + 1,
98+
polling_config)
99+
return hostif_entries
100+

tests/test_vlan.py

+16
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,22 @@ def test_VlanMemberDbData(self, dvs, test_input, expected):
419419
self.dvs_vlan.remove_vlan(vlan)
420420
self.dvs_vlan.get_and_verify_vlan_ids(0)
421421

422+
def test_VlanHostIf(self, dvs):
423+
424+
vlan = "2"
425+
hostif_name = "MonVlan2"
426+
427+
self.dvs_vlan.create_vlan(vlan)
428+
vlan_oid = self.dvs_vlan.get_and_verify_vlan_ids(1)[0]
429+
self.dvs_vlan.verify_vlan(vlan_oid, vlan)
430+
431+
self.dvs_vlan.create_vlan_hostif(vlan, hostif_name)
432+
hostif_oid = self.dvs_vlan.get_and_verify_vlan_hostif_ids(len(dvs.asic_db.hostif_name_map))
433+
self.dvs_vlan.verify_vlan_hostif(hostif_name, hostif_oid, vlan_oid)
434+
435+
self.dvs_vlan.remove_vlan(vlan)
436+
self.dvs_vlan.get_and_verify_vlan_ids(0)
437+
self.dvs_vlan.get_and_verify_vlan_hostif_ids(len(dvs.asic_db.hostif_name_map) - 1)
422438

423439
# Add Dummy always-pass test at end as workaroud
424440
# for issue when Flaky fail on final test it invokes module tear-down before retrying

0 commit comments

Comments
 (0)