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

SRv6: add dscp_mode configuration for MySID entry #3443

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
86 changes: 44 additions & 42 deletions orchagent/srv6orch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,35 +148,33 @@ void Srv6Orch::addMySidCfgCacheEntry(const string& my_sid_key, const vector<Fiel
{
auto key_list = tokenize(my_sid_key, '|');
auto locator = key_list[0];
auto my_sid_addr = key_list[1];
auto my_sid_prefix = key_list[1];

string dscp_mode_cfg = "uniform";
sai_tunnel_dscp_mode_t dscp_mode = SAI_TUNNEL_DSCP_MODE_UNIFORM_MODEL;
for (const auto& fv : fvs)
auto cfg = fvsGetValue(fvs, "decap_dscp_mode", false);
if (!cfg)
{
if (fvField(fv) == "decap_dscp_mode")
{
dscp_mode_cfg = fvValue(fv);
if (!mySidDscpModeToSai(dscp_mode_cfg, dscp_mode))
{
SWSS_LOG_ERROR("Invalid MySID %s DSCP mode: %s", my_sid_addr.c_str(), dscp_mode_cfg.c_str());
return;
}
break;
}
SWSS_LOG_ERROR("MySID entry %s doesn't have mandatory decap_dscp_mode configuration", my_sid_prefix.c_str());
return;
}

my_sid_dscp_cfg_cache_.insert({my_sid_addr, {locator, dscp_mode}});
SWSS_LOG_INFO("Saving MySID entry %s %s DSCP mode %s", locator.c_str(), my_sid_addr.c_str(), dscp_mode_cfg.c_str());
sai_tunnel_dscp_mode_t dscp_mode;
if (!mySidDscpModeToSai(*cfg, dscp_mode))
{
SWSS_LOG_ERROR("Invalid MySID %s DSCP mode: %s", my_sid_prefix.c_str(), cfg->c_str());
return;
}

my_sid_dscp_cfg_cache_.insert({my_sid_prefix, {locator, dscp_mode}});
SWSS_LOG_INFO("Saving MySID entry %s %s DSCP mode %s", locator.c_str(), my_sid_prefix.c_str(), cfg->c_str());
}

void Srv6Orch::removeMySidCfgCacheEntry(const string& my_sid_key)
{
auto key_list = tokenize(my_sid_key, '|');
auto locator = key_list[0];
auto my_sid_addr = key_list[1];
auto my_sid_prefix = key_list[1];

auto cfg_cache = my_sid_dscp_cfg_cache_.equal_range(my_sid_addr);
auto cfg_cache = my_sid_dscp_cfg_cache_.equal_range(my_sid_prefix);
for (auto it = cfg_cache.first; it != cfg_cache.second; ++it)
{
if (it->second.first == locator)
Expand All @@ -202,15 +200,17 @@ void Srv6Orch::mySidCfgCacheRefresh()

bool Srv6Orch::getMySidEntryDscpMode(const string& my_sid_addr, const MySidLocatorCfg& locator_cfg, sai_tunnel_dscp_mode_t& dscp_mode)
{
auto cfg_cache = my_sid_dscp_cfg_cache_.equal_range(my_sid_addr);
auto my_sid_prefix = my_sid_addr + "/" + to_string(locator_cfg.block_len + locator_cfg.node_len);

Choose a reason for hiding this comment

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

the prefix length of SID is equal to block_len + node_len + fucn_len in APPL_DB

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed in 0bba0ae


auto cfg_cache = my_sid_dscp_cfg_cache_.equal_range(my_sid_prefix);
if (cfg_cache.first == my_sid_dscp_cfg_cache_.end())
{
mySidCfgCacheRefresh();

cfg_cache = my_sid_dscp_cfg_cache_.equal_range(my_sid_addr);
cfg_cache = my_sid_dscp_cfg_cache_.equal_range(my_sid_prefix);
if (cfg_cache.first == my_sid_dscp_cfg_cache_.end())
{
SWSS_LOG_ERROR("SRv6 MySID entry %s is not available in the CONFIG_DB", my_sid_addr.c_str());
SWSS_LOG_INFO("SRv6 MySID entry %s is not available in the CONFIG_DB", my_sid_prefix.c_str());
return false;
}
}
Expand All @@ -223,7 +223,7 @@ bool Srv6Orch::getMySidEntryDscpMode(const string& my_sid_addr, const MySidLocat
const Srv6MySidDscpCfgCacheVal& cache_val = cache_start->second;
dscp_mode = cache_val.second;

SWSS_LOG_INFO("Found decap DSCP mode for MySID addr %s locator %s in the cache", my_sid_addr.c_str(), cache_val.first.c_str());
SWSS_LOG_INFO("Found decap DSCP mode for MySID addr %s locator %s in the cache", my_sid_prefix.c_str(), cache_val.first.c_str());
return true;
}

Expand All @@ -236,7 +236,7 @@ bool Srv6Orch::getMySidEntryDscpMode(const string& my_sid_addr, const MySidLocat
auto found = reverseLookupLocator(locator_candidates, locator_cfg, locator);
if (!found)
{
SWSS_LOG_ERROR("Cannot find a locator in the CONFIG DB for MySID Entry %s", my_sid_addr.c_str());
SWSS_LOG_ERROR("Cannot find a locator in the CONFIG DB for MySID Entry %s", my_sid_prefix.c_str());
return false;
}

Expand All @@ -245,7 +245,7 @@ bool Srv6Orch::getMySidEntryDscpMode(const string& my_sid_addr, const MySidLocat
const Srv6MySidDscpCfgCacheVal& cache_val = it->second;
if (cache_val.first == locator)
{
SWSS_LOG_INFO("Found decap DSCP mode for MySID addr %s locator %s after locator reverse lookup", my_sid_addr.c_str(), locator.c_str());
SWSS_LOG_INFO("Found decap DSCP mode for MySID addr %s locator %s after locator reverse lookup", my_sid_prefix.c_str(), locator.c_str());
dscp_mode = cache_val.second;
return true;
}
Expand Down Expand Up @@ -1024,9 +1024,17 @@ bool Srv6Orch::mySidNextHopRequired(const sai_my_sid_entry_endpoint_behavior_t e
return false;
}

bool Srv6Orch::mySidTunnelRequired(const sai_my_sid_entry_endpoint_behavior_t end_behavior)
bool Srv6Orch::mySidTunnelRequired(const string& my_sid_addr, const sai_my_sid_entry_t& sai_entry, sai_my_sid_entry_endpoint_behavior_t end_behavior, sai_tunnel_dscp_mode_t& dscp_mode)
{
return end_behavior == SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_UDT46;
if (end_behavior != SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_UN &&
end_behavior != SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_UDT46)
{
return false;
}

auto locator_cfg = getMySidEntryLocatorCfg(sai_entry);

return getMySidEntryDscpMode(my_sid_addr, locator_cfg, dscp_mode);
}

bool Srv6Orch::createUpdateMysidEntry(string my_sid_string, const string dt_vrf, const string adj, const string end_action)
Expand Down Expand Up @@ -1148,21 +1156,11 @@ bool Srv6Orch::createUpdateMysidEntry(string my_sid_string, const string dt_vrf,
nh_update = true;
}

if (mySidTunnelRequired(end_behavior))
sai_tunnel_dscp_mode_t dscp_mode;
if (mySidTunnelRequired(my_sid_string, my_sid_entry, end_behavior, dscp_mode))
{
sai_tunnel_dscp_mode_t dcsp_mode;
auto locator_cfg = getMySidEntryLocatorCfg(my_sid_entry);
auto ok = getMySidEntryDscpMode(my_sid_string, locator_cfg, dcsp_mode);
if (!ok)
{
SWSS_LOG_ERROR("Failed to get dscp mode for MySID %s", my_sid_string.c_str());
return false;
}

srv6_my_sid_table_[key_string].dscp_mode = dcsp_mode;

sai_object_id_t tunnel_oid;
ok = createMySidIpInIpTunnel(dcsp_mode, tunnel_oid);
auto ok = createMySidIpInIpTunnel(dscp_mode, tunnel_oid);
if (!ok)
{
return false;
Expand All @@ -1172,15 +1170,18 @@ bool Srv6Orch::createUpdateMysidEntry(string my_sid_string, const string dt_vrf,
ok = createMySidIpInIpTunnelTermEntry(tunnel_oid, my_sid_entry.sid, term_entry_oid);
if (!ok)
{
removeMySidIpInIpTunnel(dcsp_mode);
removeMySidIpInIpTunnel(dscp_mode);
return false;
}

srv6_my_sid_table_[key_string].tunnel_term_entry = term_entry_oid;
srv6_my_sid_table_[key_string].dscp_mode = dscp_mode;

attr.id = SAI_MY_SID_ENTRY_ATTR_TUNNEL_ID;
attr.value.oid = tunnel_oid;
attributes.push_back(attr);

end_flavor = SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_FLAVOR_USD;
}

attr.id = SAI_MY_SID_ENTRY_ATTR_ENDPOINT_BEHAVIOR;
Expand Down Expand Up @@ -1283,9 +1284,10 @@ bool Srv6Orch::deleteMysidEntry(const string my_sid_string)
m_neighOrch->getNextHopRefCount(nexthop), nexthop.to_string(false,true).c_str());
}

if (mySidTunnelRequired(endBehavior))
auto tunnel_term_entry = srv6_my_sid_table_[my_sid_string].tunnel_term_entry;
if (tunnel_term_entry != SAI_NULL_OBJECT_ID)
{
auto ok = removeMySidIpInIpTunnelTermEntry(srv6_my_sid_table_[my_sid_string].tunnel_term_entry);
auto ok = removeMySidIpInIpTunnelTermEntry(tunnel_term_entry);
if (!ok)
{
return false;
Expand Down
6 changes: 3 additions & 3 deletions orchagent/srv6orch.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ struct MySidEntry
sai_my_sid_entry_endpoint_behavior_t endBehavior;
string endVrfString; // Used for END.T, END.DT4, END.DT6 and END.DT46,
string endAdjString; // Used for END.X, END.DX4, END.DX6
sai_tunnel_dscp_mode_t dscp_mode; // Used for UDT46
sai_object_id_t tunnel_term_entry; // Used for UDT46
sai_tunnel_dscp_mode_t dscp_mode; // Used for decapsulation configuration
sai_object_id_t tunnel_term_entry; // Used for decapsulation configuration
};

struct MySidIpInIpTunnel
Expand Down Expand Up @@ -129,7 +129,7 @@ class Srv6Orch : public Orch, public Observer
bool mySidExists(const string mysid_string);
bool mySidVrfRequired(const sai_my_sid_entry_endpoint_behavior_t end_behavior);
bool mySidNextHopRequired(const sai_my_sid_entry_endpoint_behavior_t end_behavior);
bool mySidTunnelRequired(const sai_my_sid_entry_endpoint_behavior_t end_behavior);
bool mySidTunnelRequired(const string& my_sid_addr, const sai_my_sid_entry_t& sai_entry, sai_my_sid_entry_endpoint_behavior_t end_behavior, sai_tunnel_dscp_mode_t& dscp_mode);
void srv6TunnelUpdateNexthops(const string srv6_source, const NextHopKey nhkey, bool insert);
size_t srv6TunnelNexthopSize(const string srv6_source);
bool initIpInIpTunnel(MySidIpInIpTunnel& tunnel, sai_tunnel_dscp_mode_t dscp_mode);
Expand Down
25 changes: 11 additions & 14 deletions tests/test_srv6.py
Original file line number Diff line number Diff line change
Expand Up @@ -1259,9 +1259,6 @@ def test_AddRemoveSrv6MySidUDT46(self, dvs, testlog):
# enable VRF strict mode
dvs.runcmd("sysctl -w net.vrf.strict_mode=1")

# create an empty entry in confg db. The UDT46 entry processing will query config db for optional dscp_mode configuration
self.cdb.create_entry("SRV6_MY_SIDS", "loc1|fc00:0:2:ff05::", {"NULL": "NULL"})

# configure srv6 usid locator
dvs.runcmd("vtysh -c \"configure terminal\" -c \"segment-routing\" -c \"srv6\" -c \"locators\" -c \"locator loc1\" -c \"prefix fc00:0:2::/48 block-len 32 node-len 16 func-bits 16\" -c \"behavior usid\"")

Expand Down Expand Up @@ -1294,8 +1291,6 @@ def test_AddRemoveSrv6MySidUDT46(self, dvs, testlog):
# verify that the mysid has been removed from the ASIC
self.adb.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_MY_SID_ENTRY", len(self.initial_my_sid_entries))

self.cdb.delete_entry("SRV6_MY_SIDS", "loc1|fc00:0:2:ff05::")

# unconfigure srv6 locator
dvs.runcmd("vtysh -c \"configure terminal\" -c \"segment-routing\" -c \"no srv6\"")

Expand All @@ -1310,15 +1305,15 @@ def verify_attribute_value(self, table, key, attribute, expected_value):

def add_mysid_cfgdb(self, locator, prefix, addr, dscp_mode):
self.cdb.create_entry("SRV6_MY_LOCATORS", locator, {"prefix": prefix, "block_len": "32", "node_len": "16", "func_len": "16", "arg_len": "0"})
self.cdb.create_entry("SRV6_MY_SIDS", f'{locator}|{addr}', {"decap_dscp_mode": dscp_mode})
self.cdb.create_entry("SRV6_MY_SIDS", f'{locator}|{addr}/48', {"decap_dscp_mode": dscp_mode})

def remove_mysid_cfgdb(self, locator, addr):
self.cdb.delete_entry("SRV6_MY_SIDS", f"{locator}|{addr}")
self.cdb.delete_entry("SRV6_MY_SIDS", f"{locator}|{addr}/48")
self.cdb.delete_entry("SRV6_MY_LOCATORS", locator)

@pytest.mark.skipif(LooseVersion(platform.release()) < LooseVersion('5.14'),
reason="This test requires Linux kernel 5.14 or higher")
def test_Srv6MySidUDT46TunnelDscpMode(self, dvs, testlog):
def test_Srv6MySidUNTunnelDscpMode(self, dvs, testlog):

_, output = dvs.runcmd(f"vtysh -c 'show zebra dplane providers'")
if 'dplane_fpm_sonic' not in output:
Expand All @@ -1339,7 +1334,7 @@ def test_Srv6MySidUDT46TunnelDscpMode(self, dvs, testlog):

# Create MySID entry with dscp_mode uniform
dvs.runcmd("vtysh -c \"configure terminal\" -c \"segment-routing\" -c \"srv6\" -c \"locators\" -c \"locator loc1\" -c \"prefix fc00:0:2::/48 block-len 32 node-len 16 func-bits 16\" -c \"behavior usid\"")
Copy link

Choose a reason for hiding this comment

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

why do we need to add both FRR config and Linux Kernel Table config here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is how all the SRv6 vstests are done now, the new test is aligned to use the same approach

dvs.runcmd("ip -6 route add fc00:0:2:ff05::/128 encap seg6local action End.DT46 vrftable {} dev sr0".format(self.vrf_table_id))
dvs.runcmd("ip -6 route add fc00:0:2:ff05::/128 encap seg6local action End vrftable {} dev sr0".format(self.vrf_table_id))

self.pdb.wait_for_entry("SRV6_MY_SID_TABLE", "32:16:16:0:fc00:0:2:ff05::")
self.adb.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_MY_SID_ENTRY", len(self.initial_my_sid_entries) + 1)
Expand All @@ -1351,7 +1346,7 @@ def test_Srv6MySidUDT46TunnelDscpMode(self, dvs, testlog):

# Create MySID entry with dscp_mode pipe
dvs.runcmd("vtysh -c \"configure terminal\" -c \"segment-routing\" -c \"srv6\" -c \"locators\" -c \"locator loc1\" -c \"prefix fd00:0:2::/48 block-len 32 node-len 16 func-bits 16\" -c \"behavior usid\"")
dvs.runcmd("ip -6 route add fd00:0:2:ff05::/128 encap seg6local action End.DT46 vrftable {} dev sr0".format(self.vrf_table_id))
dvs.runcmd("ip -6 route add fd00:0:2:ff05::/128 encap seg6local action End vrftable {} dev sr0".format(self.vrf_table_id))

self.pdb.wait_for_entry("SRV6_MY_SID_TABLE", "32:16:16:0:fd00:0:2:ff05::")
self.adb.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_MY_SID_ENTRY", len(self.initial_my_sid_entries) + 2)
Expand All @@ -1366,6 +1361,8 @@ def test_Srv6MySidUDT46TunnelDscpMode(self, dvs, testlog):
self.verify_attribute_value(my_sid_table, my_sid_pipe, "SAI_MY_SID_ENTRY_ATTR_TUNNEL_ID", tunnel_pipe)
self.verify_attribute_value(tunnel_table, tunnel_uniform, "SAI_TUNNEL_ATTR_DECAP_DSCP_MODE", "SAI_TUNNEL_DSCP_MODE_UNIFORM_MODEL")
self.verify_attribute_value(tunnel_table, tunnel_pipe, "SAI_TUNNEL_ATTR_DECAP_DSCP_MODE", "SAI_TUNNEL_DSCP_MODE_PIPE_MODEL")
self.verify_attribute_value(my_sid_table, my_sid_uniform, "SAI_MY_SID_ENTRY_ATTR_ENDPOINT_BEHAVIOR_FLAVOR", "SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_FLAVOR_USD")
self.verify_attribute_value(my_sid_table, my_sid_pipe, "SAI_MY_SID_ENTRY_ATTR_ENDPOINT_BEHAVIOR_FLAVOR", "SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_FLAVOR_USD")

# Validate tunnel term configuration
self.verify_attribute_value(tunnel_term_table, mysid_uniform_term_entry, "SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID", tunnel_uniform)
Expand All @@ -1375,7 +1372,7 @@ def test_Srv6MySidUDT46TunnelDscpMode(self, dvs, testlog):

# Add another MySID entry with dscp_mode pipe
dvs.runcmd("vtysh -c \"configure terminal\" -c \"segment-routing\" -c \"srv6\" -c \"locators\" -c \"locator loc1\" -c \"prefix fe00:0:2::/48 block-len 32 node-len 16 func-bits 16\" -c \"behavior usid\"")
dvs.runcmd("ip -6 route add fe00:0:2:ff05::/128 encap seg6local action End.DT46 vrftable {} dev sr0".format(self.vrf_table_id))
dvs.runcmd("ip -6 route add fe00:0:2:ff05::/128 encap seg6local action End vrftable {} dev sr0".format(self.vrf_table_id))

self.pdb.wait_for_entry("SRV6_MY_SID_TABLE", "32:16:16:0:fe00:0:2:ff05::")
self.adb.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_MY_SID_ENTRY", len(self.initial_my_sid_entries) + 3)
Expand All @@ -1387,9 +1384,9 @@ def test_Srv6MySidUDT46TunnelDscpMode(self, dvs, testlog):
self.verify_attribute_value(my_sid_table, my_sid_pipe2, "SAI_MY_SID_ENTRY_ATTR_TUNNEL_ID", tunnel_pipe)

# Remove MySID entries
dvs.runcmd("ip -6 route del fc00:0:2:ff05::/128 encap seg6local action End.DT46 vrftable {} dev sr0".format(self.vrf_table_id))
dvs.runcmd("ip -6 route del fd00:0:2:ff05::/128 encap seg6local action End.DT46 vrftable {} dev sr0".format(self.vrf_table_id))
dvs.runcmd("ip -6 route del fe00:0:2:ff05::/128 encap seg6local action End.DT46 vrftable {} dev sr0".format(self.vrf_table_id))
dvs.runcmd("ip -6 route del fc00:0:2:ff05::/128 encap seg6local action End vrftable {} dev sr0".format(self.vrf_table_id))
dvs.runcmd("ip -6 route del fd00:0:2:ff05::/128 encap seg6local action End vrftable {} dev sr0".format(self.vrf_table_id))
dvs.runcmd("ip -6 route del fe00:0:2:ff05::/128 encap seg6local action End vrftable {} dev sr0".format(self.vrf_table_id))

self.pdb.wait_for_deleted_entry("SRV6_MY_SID_TABLE", "32:16:16:0:fc00:0:2:ff05::")
self.pdb.wait_for_deleted_entry("SRV6_MY_SID_TABLE", "32:16:16:0:fd00:0:2:ff05::")
Expand Down
Loading