Skip to content

Commit

Permalink
[switchorch] Implement VXLAN src port range feature (sonic-net#1959)
Browse files Browse the repository at this point in the history
* Implement VXLAN src port range feature configuring
Signed-off-by: Andriy Yurkiv <ayurkiv@nvidia.com>
  • Loading branch information
ayurkiv-nvda committed Nov 5, 2021
1 parent b20f0f4 commit c91a7f2
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 9 deletions.
81 changes: 77 additions & 4 deletions orchagent/switchorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ const map<string, sai_switch_attr_t> switch_attribute_map =
{"vxlan_router_mac", SAI_SWITCH_ATTR_VXLAN_DEFAULT_ROUTER_MAC}
};

const map<string, sai_switch_tunnel_attr_t> switch_tunnel_attribute_map =
{
{"vxlan_sport", SAI_SWITCH_TUNNEL_ATTR_VXLAN_UDP_SPORT},
{"vxlan_mask", SAI_SWITCH_TUNNEL_ATTR_VXLAN_UDP_SPORT_MASK}
};

const map<string, sai_packet_action_t> packet_action_map =
{
{"drop", SAI_PACKET_ACTION_DROP},
Expand Down Expand Up @@ -127,6 +133,61 @@ void SwitchOrch::doCfgSensorsTableTask(Consumer &consumer)
}
}


sai_status_t SwitchOrch::setSwitchTunnelVxlanParams(swss::FieldValueTuple &val)
{
auto attribute = fvField(val);
auto value = fvValue(val);
sai_attribute_t attr;
sai_status_t status;

if (!m_vxlanSportUserModeEnabled)
{
// Enable Vxlan src port range feature
vector<sai_attribute_t> attrs;
attr.id = SAI_SWITCH_TUNNEL_ATTR_TUNNEL_TYPE;
attr.value.s32 = SAI_TUNNEL_TYPE_VXLAN;
attrs.push_back(attr);
attr.id = SAI_SWITCH_TUNNEL_ATTR_TUNNEL_VXLAN_UDP_SPORT_MODE;
attr.value.s32 = SAI_TUNNEL_VXLAN_UDP_SPORT_MODE_USER_DEFINED;
attrs.push_back(attr);

status = sai_switch_api->create_switch_tunnel(&m_switchTunnelId, gSwitchId, static_cast<uint32_t>(attrs.size()), attrs.data());

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to create switch_tunnel object, rv:%d", status);
return status;
}

m_vxlanSportUserModeEnabled = true;
}

attr.id = switch_tunnel_attribute_map.at(attribute);
switch (attr.id)
{
case SAI_SWITCH_TUNNEL_ATTR_VXLAN_UDP_SPORT:
attr.value.u16 = to_uint<uint16_t>(value);
break;
case SAI_SWITCH_TUNNEL_ATTR_VXLAN_UDP_SPORT_MASK:
attr.value.u8 = to_uint<uint8_t>(value);
break;
default:
SWSS_LOG_ERROR("Invalid switch tunnel attribute id %d", attr.id);
return SAI_STATUS_SUCCESS;
}

status = sai_switch_api->set_switch_tunnel_attribute(m_switchTunnelId, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to set tunnnel switch attribute %s to %s, rv:%d", attribute.c_str(), value.c_str(), status);
return status;
}

SWSS_LOG_NOTICE("Set switch attribute %s to %s", attribute.c_str(), value.c_str());
return SAI_STATUS_SUCCESS;
}

void SwitchOrch::doAppSwitchTableTask(Consumer &consumer)
{
SWSS_LOG_ENTER();
Expand All @@ -136,19 +197,31 @@ void SwitchOrch::doAppSwitchTableTask(Consumer &consumer)
{
auto t = it->second;
auto op = kfvOp(t);
bool retry = false;

if (op == SET_COMMAND)
{
bool retry = false;

for (auto i : kfvFieldsValues(t))
{
auto attribute = fvField(i);

if (switch_attribute_map.find(attribute) == switch_attribute_map.end())
{
SWSS_LOG_ERROR("Unsupported switch attribute %s", attribute.c_str());
break;
// Check additionally 'switch_tunnel_attribute_map' for Switch Tunnel
if (switch_tunnel_attribute_map.find(attribute) == switch_tunnel_attribute_map.end())
{
SWSS_LOG_ERROR("Unsupported switch attribute %s", attribute.c_str());
break;
}

auto status = setSwitchTunnelVxlanParams(i);
if ((status != SAI_STATUS_SUCCESS) && (handleSaiSetStatus(SAI_API_SWITCH, status) == task_need_retry))
{
retry = true;
break;
}

continue;
}

auto value = fvValue(i);
Expand Down
3 changes: 3 additions & 0 deletions orchagent/switchorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ class SwitchOrch : public Orch
void doAppSwitchTableTask(Consumer &consumer);
void initSensorsTable();
void querySwitchTpidCapability();
sai_status_t setSwitchTunnelVxlanParams(swss::FieldValueTuple &val);

swss::NotificationConsumer* m_restartCheckNotificationConsumer;
void doTask(swss::NotificationConsumer& consumer);
swss::DBConnector *m_db;
swss::Table m_switchTable;
sai_object_id_t m_switchTunnelId;

// ASIC temperature sensors
std::shared_ptr<swss::DBConnector> m_stateDb = nullptr;
Expand All @@ -52,6 +54,7 @@ class SwitchOrch : public Orch
bool m_numTempSensorsInitialized = false;
bool m_sensorsMaxTempSupported = true;
bool m_sensorsAvgTempSupported = true;
bool m_vxlanSportUserModeEnabled = false;

// Information contained in the request from
// external program for orchagent pre-shutdown state check
Expand Down
13 changes: 8 additions & 5 deletions tests/test_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@ def check_object(db, table, key, expected_attributes):
(value, name, expected_attributes[name])


def vxlan_switch_test(dvs, oid, port, mac):
def vxlan_switch_test(dvs, oid, port, mac, mask, sport):
app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
create_entry_pst(
app_db,
"SWITCH_TABLE", ':', "switch",
[
("vxlan_port", port),
("vxlan_router_mac", mac)
("vxlan_router_mac", mac),
("vxlan_mask", mask),
("vxlan_sport", sport),
],
)
time.sleep(2)
Expand All @@ -57,6 +59,8 @@ def vxlan_switch_test(dvs, oid, port, mac):
{
'SAI_SWITCH_ATTR_VXLAN_DEFAULT_PORT': port,
'SAI_SWITCH_ATTR_VXLAN_DEFAULT_ROUTER_MAC': mac,
'SAI_SWITCH_TUNNEL_ATTR_VXLAN_UDP_SPORT_MASK': mask,
'SAI_SWITCH_TUNNEL_ATTR_VXLAN_UDP_SPORT': sport,
}
)

Expand All @@ -67,10 +71,9 @@ class TestSwitch(object):
'''
def test_switch_attribute(self, dvs, testlog):
switch_oid = get_exist_entry(dvs, "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH")
vxlan_switch_test(dvs, switch_oid, "12345", "00:01:02:03:04:05", "20", "54321")

vxlan_switch_test(dvs, switch_oid, "12345", "00:01:02:03:04:05")

vxlan_switch_test(dvs, switch_oid, "56789", "00:0A:0B:0C:0D:0E")
vxlan_switch_test(dvs, switch_oid, "56789", "00:0A:0B:0C:0D:0E", "15", "56789")


# Add Dummy always-pass test at end as workaroud
Expand Down

0 comments on commit c91a7f2

Please sign in to comment.