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

Updated handling of VRF_VNI mapping and VLAN_VNI mapping for same VNI ID #2538

Merged
merged 5 commits into from
Dec 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions orchagent/vrforch.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,19 @@ class VRFOrch : public Orch2
return (-1);
}
}

bool isL3VniVlan(const uint32_t vni) const
{
if (l3vni_table_.find(vni) != std::end(l3vni_table_))
{
return l3vni_table_.at(vni).l3_vni;
}
else
{
return false;
}
}

int updateL3VniVlan(uint32_t vni, uint16_t vlan_id);
private:
virtual bool addOperation(const Request& request);
Expand Down
96 changes: 93 additions & 3 deletions orchagent/vxlanorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1903,6 +1903,7 @@ bool VxlanTunnelMapOrch::addOperation(const Request& request)

sai_vlan_id_t vlan_id = (sai_vlan_id_t)request.getAttrVlan("vlan");
Port tempPort;
bool isL3Vni = false;

const auto full_tunnel_map_entry_name = request.getFullKey();
SWSS_LOG_INFO("Full name = %s",full_tunnel_map_entry_name.c_str());
Expand Down Expand Up @@ -1974,11 +1975,21 @@ bool VxlanTunnelMapOrch::addOperation(const Request& request)
tunnel_obj->vlan_vrf_vni_count++;
SWSS_LOG_INFO("vni count increased to %d",tunnel_obj->vlan_vrf_vni_count);

VRFOrch* vrf_orch = gDirectory.get<VRFOrch*>();
isL3Vni = vrf_orch->isL3VniVlan(vni_id);

try
{
auto tunnel_map_entry_id = create_tunnel_map_entry(MAP_T::VNI_TO_VLAN_ID,
tunnel_map_id, vni_id, vlan_id);
vxlan_tunnel_map_table_[full_tunnel_map_entry_name].map_entry_id = tunnel_map_entry_id;
if (isL3Vni == false)
{
auto tunnel_map_entry_id = create_tunnel_map_entry(MAP_T::VNI_TO_VLAN_ID,
tunnel_map_id, vni_id, vlan_id);
vxlan_tunnel_map_table_[full_tunnel_map_entry_name].map_entry_id = tunnel_map_entry_id;
}
else
{
vxlan_tunnel_map_table_[full_tunnel_map_entry_name].map_entry_id = SAI_NULL_OBJECT_ID;
}
vxlan_tunnel_map_table_[full_tunnel_map_entry_name].vlan_id = vlan_id;
vxlan_tunnel_map_table_[full_tunnel_map_entry_name].vni_id = vni_id;
}
Expand Down Expand Up @@ -2124,9 +2135,13 @@ bool VxlanTunnelMapOrch::delOperation(const Request& request)
bool VxlanVrfMapOrch::addOperation(const Request& request)
{
SWSS_LOG_ENTER();
std::string vniVlanMapName;
uint32_t vlan_id = 0;
sai_object_id_t tnl_map_entry_id = SAI_NULL_OBJECT_ID;

auto tunnel_name = request.getKeyString(0);
VxlanTunnelOrch* tunnel_orch = gDirectory.get<VxlanTunnelOrch*>();
VxlanTunnelMapOrch* vxlan_tun_map_orch = gDirectory.get<VxlanTunnelMapOrch*>();
if (!tunnel_orch->isTunnelExists(tunnel_name))
{
SWSS_LOG_WARN("Vxlan tunnel '%s' doesn't exist", tunnel_name.c_str());
Expand Down Expand Up @@ -2188,6 +2203,15 @@ bool VxlanVrfMapOrch::addOperation(const Request& request)
vrf_map_entry_t entry;
try
{
entry.isL2Vni = vxlan_tun_map_orch->isVniVlanMapExists(vni_id, vniVlanMapName, &tnl_map_entry_id, &vlan_id);
entry.vni_id = vni_id;
if (entry.isL2Vni)
{
entry.vniVlanMapName = vniVlanMapName;
entry.vlan_id = vlan_id;
remove_tunnel_map_entry(tnl_map_entry_id);
SWSS_LOG_DEBUG("remove_tunnel_map_entry name %s, vlan %d, vni %d\n", entry.vniVlanMapName.c_str(), entry.vlan_id, entry.vni_id);
}
/*
* Create encap and decap mapper
*/
Expand Down Expand Up @@ -2219,7 +2243,12 @@ bool VxlanVrfMapOrch::delOperation(const Request& request)
SWSS_LOG_ENTER();

VRFOrch* vrf_orch = gDirectory.get<VRFOrch*>();
VxlanTunnelOrch* tunnel_orch = gDirectory.get<VxlanTunnelOrch*>();
VxlanTunnelMapOrch* vxlan_tun_map_orch = gDirectory.get<VxlanTunnelMapOrch*>();
const auto full_map_entry_name = request.getFullKey();
std::string vniVlanMapName;
uint32_t vlan_id = 0;
sai_object_id_t tnl_map_entry_id = SAI_NULL_OBJECT_ID;

if (!isVrfMapExists(full_map_entry_name))
{
Expand All @@ -2241,6 +2270,9 @@ bool VxlanVrfMapOrch::delOperation(const Request& request)
return false;
}
SWSS_LOG_NOTICE("VxlanVrfMapOrch VRF VNI mapping '%s' remove vrf %s", full_map_entry_name.c_str(), vrf_name.c_str());
auto tunnel_name = request.getKeyString(0);
auto tunnel_obj = tunnel_orch->getVxlanTunnel(tunnel_name);

vrf_map_entry_t entry;
try
{
Expand All @@ -2256,6 +2288,32 @@ bool VxlanVrfMapOrch::delOperation(const Request& request)
vrf_orch->decreaseVrfRefCount(vrf_name);
remove_tunnel_map_entry(entry.decap_id);
vrf_orch->decreaseVrfRefCount(vrf_name);

if (!entry.isL2Vni)
{
entry.isL2Vni = vxlan_tun_map_orch->isVniVlanMapExists(entry.vni_id, vniVlanMapName, &tnl_map_entry_id, &vlan_id);
SWSS_LOG_NOTICE("VxlanVrfMapOrch vni %d, isL2Vni %d\n", entry.vni_id, entry.isL2Vni);

if (entry.isL2Vni)
{
entry.vniVlanMapName = vniVlanMapName;
entry.vlan_id = vlan_id;
SWSS_LOG_DEBUG("add_tunnel_map_entry name %s, vlan %d, vni %d\n", entry.vniVlanMapName.c_str(), entry.vlan_id, entry.vni_id);
}
}
if(entry.isL2Vni)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please have space afterif.

{
const auto tunnel_map_id = tunnel_obj->getDecapMapId(TUNNEL_MAP_T_VLAN);
SWSS_LOG_NOTICE("Adding tunnel map entry. Tunnel: %s %s",tunnel_name.c_str(),entry.vniVlanMapName.c_str());

SWSS_LOG_DEBUG("create_tunnel_map_entry vni %d, vlan %d\n", entry.vni_id, entry.vlan_id);
auto tunnel_map_entry_id = create_tunnel_map_entry(MAP_T::VNI_TO_VLAN_ID,
tunnel_map_id, entry.vni_id, (uint16_t)entry.vlan_id);
SWSS_LOG_DEBUG("updateTnlMapId name %s\n", entry.vniVlanMapName.c_str());

vxlan_tun_map_orch->updateTnlMapId(entry.vniVlanMapName, tunnel_map_entry_id);
}

vxlan_vrf_table_.erase(full_map_entry_name);
vxlan_vrf_tunnel_.erase(vrf_name);
}
Expand Down Expand Up @@ -2599,3 +2657,35 @@ bool EvpnNvoOrch::delOperation(const Request& request)

return true;
}

bool VxlanTunnelMapOrch::isVniVlanMapExists(uint32_t vni_id, std::string& vniVlanMapName, sai_object_id_t *tnl_map_entry_id, uint32_t *vlan_id)
{
SWSS_LOG_ENTER();
bool map_entry_exists = false;
std::map<std::string, tunnel_map_entry_t>::iterator it;
for(it = vxlan_tunnel_map_table_.begin(); it != vxlan_tunnel_map_table_.end(); it++)
{
auto full_tunnel_map_entry_name = it->first;
tunnel_map_entry_t tunnel_map_entry = it->second;

if (vni_id == tunnel_map_entry.vni_id)
{
vniVlanMapName = full_tunnel_map_entry_name;
*tnl_map_entry_id = tunnel_map_entry.map_entry_id;
*vlan_id = tunnel_map_entry.vlan_id;
map_entry_exists = true;
SWSS_LOG_NOTICE("vniVlanMapName %s, vlan %d\n", vniVlanMapName.c_str(), *vlan_id);
break;
}
}

return map_entry_exists;
}

void VxlanTunnelMapOrch::updateTnlMapId(std::string vniVlanMapName, sai_object_id_t tunnel_map_id)
{
SWSS_LOG_ENTER();
SWSS_LOG_NOTICE("name %s\n", vniVlanMapName.c_str());
vxlan_tunnel_map_table_[vniVlanMapName].map_entry_id = tunnel_map_id;
}

8 changes: 8 additions & 0 deletions orchagent/vxlanorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,10 @@ class VxlanTunnelMapOrch : public Orch2
{
return vxlan_tunnel_map_table_.find(name) != std::end(vxlan_tunnel_map_table_);
}

bool isVniVlanMapExists(uint32_t vni_id, std::string& vniVlanMapName, sai_object_id_t *tnl_map_entry_id, uint32_t *vlan_id);

void updateTnlMapId(std::string vniVlanMapName, sai_object_id_t tunnel_map_id);
private:
virtual bool addOperation(const Request& request);
virtual bool delOperation(const Request& request);
Expand All @@ -436,6 +440,10 @@ class VxlanVrfRequest : public Request
struct vrf_map_entry_t {
sai_object_id_t encap_id;
sai_object_id_t decap_id;
bool isL2Vni;
std::string vniVlanMapName;
uint32_t vlan_id;
uint32_t vni_id;
};

typedef std::map<string, vrf_map_entry_t> VxlanVrfTable;
Expand Down
25 changes: 21 additions & 4 deletions tests/evpn_tunnel.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,22 @@ def check_vxlan_tunnel_map_entry(self, dvs, tunnel_name, vidlist, vnidlist):
(exitcode, out) = dvs.runcmd(iplinkcmd)
assert exitcode == 0, "Kernel device not created"

def check_vxlan_tunnel_map_entry_removed(self, dvs, tunnel_name, vidlist, vnidlist):
asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0)

expected_attributes_1 = {
'SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP_TYPE': 'SAI_TUNNEL_MAP_TYPE_VNI_TO_VLAN_ID',
'SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP': self.tunnel_map_map[tunnel_name][0],
'SAI_TUNNEL_MAP_ENTRY_ATTR_VLAN_ID_VALUE': vidlist[0],
'SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_KEY': vnidlist[0],
}

for x in range(len(vidlist)):
expected_attributes_1['SAI_TUNNEL_MAP_ENTRY_ATTR_VLAN_ID_VALUE'] = vidlist[x]
expected_attributes_1['SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_KEY'] = vnidlist[x]
ret = self.helper.get_key_with_attr(asic_db, self.ASIC_TUNNEL_MAP_ENTRY, expected_attributes_1)
assert len(ret) == 0, "SIP TunnelMap entry not removed"

def check_vxlan_sip_tunnel_delete(self, dvs, tunnel_name, sip, ignore_bp = True):
asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0)
app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
Expand Down Expand Up @@ -517,7 +533,8 @@ def check_vxlan_sip_tunnel_delete(self, dvs, tunnel_name, sip, ignore_bp = True)
assert status == False, "Tunnel bridgeport entry not deleted"

def check_vxlan_sip_tunnel(self, dvs, tunnel_name, src_ip, vidlist, vnidlist,
dst_ip = '0.0.0.0', skip_dst_ip = 'True', ignore_bp = True):
dst_ip = '0.0.0.0', skip_dst_ip = 'True', ignore_bp = True,
tunnel_map_entry_count = 3):
asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0)
app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)

Expand All @@ -527,7 +544,7 @@ def check_vxlan_sip_tunnel(self, dvs, tunnel_name, src_ip, vidlist, vnidlist,

# check that the vxlan tunnel termination are there
assert self.helper.how_many_entries_exist(asic_db, self.ASIC_TUNNEL_MAP) == (len(self.tunnel_map_ids) + 4), "The TUNNEL_MAP wasn't created"
assert self.helper.how_many_entries_exist(asic_db, self.ASIC_TUNNEL_MAP_ENTRY) == (len(self.tunnel_map_entry_ids) + 3), "The TUNNEL_MAP_ENTRY is created"
assert self.helper.how_many_entries_exist(asic_db, self.ASIC_TUNNEL_MAP_ENTRY) == (len(self.tunnel_map_entry_ids) + tunnel_map_entry_count), "The TUNNEL_MAP_ENTRY is created"
assert self.helper.how_many_entries_exist(asic_db, self.ASIC_TUNNEL_TABLE) == (len(self.tunnel_ids) + 1), "The TUNNEL wasn't created"
assert self.helper.how_many_entries_exist(asic_db, self.ASIC_TUNNEL_TERM_ENTRY) == (len(self.tunnel_term_ids) + 1), "The TUNNEL_TERM_TABLE_ENTRY wasm't created"

Expand Down Expand Up @@ -798,10 +815,10 @@ def check_vxlan_tunnel_entry(self, dvs, tunnel_name, vnet_name, vni_id):
def check_vxlan_tunnel_vrf_map_entry(self, dvs, tunnel_name, vrf_name, vni_id):
asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0)

tunnel_map_entry_id = self.helper.get_created_entries(asic_db, self.ASIC_TUNNEL_MAP_ENTRY, self.tunnel_map_entry_ids, 3)
tunnel_map_entry_id = self.helper.get_created_entries(asic_db, self.ASIC_TUNNEL_MAP_ENTRY, self.tunnel_map_entry_ids, 2)

# check that the vxlan tunnel termination are there
assert self.helper.how_many_entries_exist(asic_db, self.ASIC_TUNNEL_MAP_ENTRY) == (len(self.tunnel_map_entry_ids) + 3), "The TUNNEL_MAP_ENTRY is created too early"
assert self.helper.how_many_entries_exist(asic_db, self.ASIC_TUNNEL_MAP_ENTRY) == (len(self.tunnel_map_entry_ids) + 2), "The TUNNEL_MAP_ENTRY is created too early"

ret = self.helper.get_key_with_attr(asic_db, self.ASIC_TUNNEL_MAP_ENTRY,
{
Expand Down
20 changes: 12 additions & 8 deletions tests/test_evpn_l3_vxlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog):
helper.check_object(self.pdb, "VXLAN_VRF_TABLE", "%s:%s" % (tunnel_name, vrf_map_name), exp_attr1)

print ("\tTesting SIP Tunnel Creation")
vxlan_obj.check_vxlan_sip_tunnel(dvs, tunnel_name, '6.6.6.6', vlanlist, vnilist)
vxlan_obj.check_vxlan_sip_tunnel(dvs, tunnel_name, '6.6.6.6', vlanlist, vnilist, tunnel_map_entry_count = 2)

print ("\tTesting Tunnel Vlan VNI Map Entry")
vxlan_obj.check_vxlan_tunnel_map_entry(dvs, tunnel_name, vlanlist, vnilist)
vxlan_obj.check_vxlan_tunnel_map_entry_removed(dvs, tunnel_name, vlanlist, vnilist)

print ("\tTesting Tunnel VRF VNI Map Entry")
vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000')
Expand All @@ -82,6 +82,7 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog):
vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000')

print ("\tTesting Tunnel Vlan VNI Map entry removal")
vxlan_obj.check_vxlan_tunnel_map_entry(dvs, tunnel_name, vlanlist, vnilist)
vxlan_obj.remove_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100')
vxlan_obj.check_vxlan_tunnel_map_entry_delete(dvs, tunnel_name, vlanlist, vnilist)

Expand Down Expand Up @@ -143,10 +144,10 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog):
helper.check_object(self.pdb, "VXLAN_VRF_TABLE", "%s:%s" % (tunnel_name, vrf_map_name), exp_attr1)

print ("\tTesting SIP Tunnel Creation")
vxlan_obj.check_vxlan_sip_tunnel(dvs, tunnel_name, '6.6.6.6', vlanlist, vnilist)
vxlan_obj.check_vxlan_sip_tunnel(dvs, tunnel_name, '6.6.6.6', vlanlist, vnilist, tunnel_map_entry_count = 2)

print ("\tTesting Tunnel Vlan Map Entry")
vxlan_obj.check_vxlan_tunnel_map_entry(dvs, tunnel_name, vlanlist, vnilist)
vxlan_obj.check_vxlan_tunnel_map_entry_removed(dvs, tunnel_name, vlanlist, vnilist)

print ("\tTesting Tunnel Vrf Map Entry")
vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000')
Expand Down Expand Up @@ -180,6 +181,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog):
vxlan_obj.check_del_router_interface(dvs, "Vlan100")

print ("\tTesting Tunnel Map entry removal")
vxlan_obj.check_vxlan_tunnel_map_entry(dvs, tunnel_name, vlanlist, vnilist)
vxlan_obj.remove_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100')
vxlan_obj.check_vxlan_tunnel_map_entry_delete(dvs, tunnel_name, vlanlist, vnilist)

Expand Down Expand Up @@ -242,10 +244,10 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog):
helper.check_object(self.pdb, "VXLAN_VRF_TABLE", "%s:%s" % (tunnel_name, vrf_map_name), exp_attr1)

print ("\tTesting SIP Tunnel Creation")
vxlan_obj.check_vxlan_sip_tunnel(dvs, tunnel_name, '6.6.6.6', vlanlist, vnilist)
vxlan_obj.check_vxlan_sip_tunnel(dvs, tunnel_name, '6.6.6.6', vlanlist, vnilist, tunnel_map_entry_count = 2)

print ("\tTesting Tunnel Vlan Map Entry")
vxlan_obj.check_vxlan_tunnel_map_entry(dvs, tunnel_name, vlanlist, vnilist)
vxlan_obj.check_vxlan_tunnel_map_entry_removed(dvs, tunnel_name, vlanlist, vnilist)

print ("\tTesting Tunnel Vrf Map Entry")
vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000')
Expand Down Expand Up @@ -386,6 +388,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog):
vxlan_obj.check_del_router_interface(dvs, "Vlan100")

print ("\tTesting Tunnel Map entry removal")
vxlan_obj.check_vxlan_tunnel_map_entry(dvs, tunnel_name, vlanlist, vnilist)
vxlan_obj.remove_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100')
vxlan_obj.check_vxlan_tunnel_map_entry_delete(dvs, tunnel_name, vlanlist, vnilist)

Expand Down Expand Up @@ -449,10 +452,10 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog):
helper.check_object(self.pdb, "VXLAN_VRF_TABLE", "%s:%s" % (tunnel_name, vrf_map_name), exp_attr1)

print ("\tTesting SIP Tunnel Creation")
vxlan_obj.check_vxlan_sip_tunnel(dvs, tunnel_name, '6.6.6.6', vlanlist, vnilist)
vxlan_obj.check_vxlan_sip_tunnel(dvs, tunnel_name, '6.6.6.6', vlanlist, vnilist, tunnel_map_entry_count = 2)

print ("\tTesting Tunnel Vlan Map Entry")
vxlan_obj.check_vxlan_tunnel_map_entry(dvs, tunnel_name, vlanlist, vnilist)
vxlan_obj.check_vxlan_tunnel_map_entry_removed(dvs, tunnel_name, vlanlist, vnilist)

print ("\tTesting Tunnel Vrf Map Entry")
vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000')
Expand Down Expand Up @@ -594,6 +597,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog):
vxlan_obj.check_del_router_interface(dvs, "Vlan100")

print ("\tTesting Tunnel Map entry removal")
vxlan_obj.check_vxlan_tunnel_map_entry(dvs, tunnel_name, vlanlist, vnilist)
vxlan_obj.remove_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100')
vxlan_obj.check_vxlan_tunnel_map_entry_delete(dvs, tunnel_name, vlanlist, vnilist)

Expand Down
Loading