Skip to content

Commit

Permalink
[SRV6] Sonic-swss changes for SRV6 (sonic-net#1964)
Browse files Browse the repository at this point in the history
*RouteOrch changes to trigger SRV6 nexthops and update route entries
*SRV6Orch changes to create SRV6 nexthops, tunnel and SRV6 MY_SID_ENTRY objects
  • Loading branch information
Kumaresh Perumal authored and liuyuefengcn committed Jan 15, 2024
1 parent 544773a commit aa0206c
Show file tree
Hide file tree
Showing 18 changed files with 1,361 additions and 42 deletions.
17 changes: 17 additions & 0 deletions doc/swss-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ and reflects the LAG ports into the redis under: `LAG_TABLE:<team0>:port`
nexthop = *prefix, ;IP addresses separated “,” (empty indicates no gateway)
intf = ifindex? PORT_TABLE.key ; zero or more separated by “,” (zero indicates no interface)
blackhole = BIT ; Set to 1 if this route is a blackhole (or null0)
segment = string ; SRV6 segment name
seg_src = string ; ipv6 address for SRV6 tunnel source

---------------------------------------------
### NEIGH_TABLE
Expand All @@ -173,6 +175,21 @@ and reflects the LAG ports into the redis under: `LAG_TABLE:<team0>:port`
neigh = 12HEXDIG ; mac address of the neighbor
family = "IPv4" / "IPv6" ; address family

---------------------------------------------
### SRV6_SID_LIST_TABLE
; Stores IPV6 prefixes for a SRV6 segment name
key = ROUTE_TABLE:segment ; SRV6 segment name
; field = value
path = STRING ; Comma-separated list of IPV6 prefixes for a SRV6 segment

---------------------------------------------
### SRV6_MY_SID_TABLE
; Stores SRV6 MY_SID table entries and associated actions
key = STRING ; SRV6 MY_SID prefix string
; field = value
action = STRING ; MY_SID actions like "end", "end.dt46"
vrf = STRING ; VRF string for END.DT46 or END.DT4 or END.DT6

---------------------------------------------
### FDB_TABLE

Expand Down
2 changes: 2 additions & 0 deletions orchagent/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ orchagent_SOURCES = \
debugcounterorch.cpp \
natorch.cpp \
muxorch.cpp
bfdorch.cpp \
srv6orch.cpp

orchagent_SOURCES += flex_counter/flex_counter_manager.cpp flex_counter/flex_counter_stat_manager.cpp
orchagent_SOURCES += debug_counter/debug_counter.cpp debug_counter/drop_counter.cpp
Expand Down
70 changes: 70 additions & 0 deletions orchagent/crmorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const map<CrmResourceType, string> crmResTypeNameMap =
{ CrmResourceType::CRM_IPMC_ENTRY, "IPMC_ENTRY" },
{ CrmResourceType::CRM_SNAT_ENTRY, "SNAT_ENTRY" },
{ CrmResourceType::CRM_DNAT_ENTRY, "DNAT_ENTRY" }
{ CrmResourceType::CRM_SRV6_MY_SID_ENTRY, "SRV6_MY_SID_ENTRY" },
{ CrmResourceType::CRM_SRV6_NEXTHOP, "SRV6_NEXTHOP" },
};

const map<CrmResourceType, uint32_t> crmResSaiAvailAttrMap =
Expand All @@ -61,6 +63,8 @@ const map<CrmResourceType, uint32_t> crmResSaiAvailAttrMap =
{ CrmResourceType::CRM_IPMC_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_IPMC_ENTRY},
{ CrmResourceType::CRM_SNAT_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_SNAT_ENTRY },
{ CrmResourceType::CRM_DNAT_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_DNAT_ENTRY }
{ CrmResourceType::CRM_SRV6_MY_SID_ENTRY, SAI_OBJECT_TYPE_MY_SID_ENTRY },
{ CrmResourceType::CRM_SRV6_NEXTHOP, SAI_SWITCH_ATTR_AVAILABLE_IPV6_NEXTHOP_ENTRY },
};

const map<string, CrmResourceType> crmThreshTypeResMap =
Expand All @@ -81,6 +85,8 @@ const map<string, CrmResourceType> crmThreshTypeResMap =
{ "ipmc_entry_threshold_type", CrmResourceType::CRM_IPMC_ENTRY },
{ "snat_entry_threshold_type", CrmResourceType::CRM_SNAT_ENTRY },
{ "dnat_entry_threshold_type", CrmResourceType::CRM_DNAT_ENTRY }
{ "srv6_my_sid_entry_threshold_type", CrmResourceType::CRM_SRV6_MY_SID_ENTRY },
{ "srv6_nexthop_threshold_type", CrmResourceType::CRM_SRV6_NEXTHOP },
};

const map<string, CrmResourceType> crmThreshLowResMap =
Expand All @@ -101,6 +107,8 @@ const map<string, CrmResourceType> crmThreshLowResMap =
{"ipmc_entry_low_threshold", CrmResourceType::CRM_IPMC_ENTRY },
{"snat_entry_low_threshold", CrmResourceType::CRM_SNAT_ENTRY },
{"dnat_entry_low_threshold", CrmResourceType::CRM_DNAT_ENTRY }
{"srv6_my_sid_entry_low_threshold", CrmResourceType::CRM_SRV6_MY_SID_ENTRY },
{"srv6_nexthop_low_threshold", CrmResourceType::CRM_SRV6_NEXTHOP },
};

const map<string, CrmResourceType> crmThreshHighResMap =
Expand All @@ -121,6 +129,8 @@ const map<string, CrmResourceType> crmThreshHighResMap =
{"ipmc_entry_high_threshold", CrmResourceType::CRM_IPMC_ENTRY },
{"snat_entry_high_threshold", CrmResourceType::CRM_SNAT_ENTRY },
{"dnat_entry_high_threshold", CrmResourceType::CRM_DNAT_ENTRY }
{"srv6_my_sid_entry_high_threshold", CrmResourceType::CRM_SRV6_MY_SID_ENTRY },
{"srv6_nexthop_high_threshold", CrmResourceType::CRM_SRV6_NEXTHOP },
};

const map<string, CrmThresholdType> crmThreshTypeMap =
Expand Down Expand Up @@ -148,6 +158,8 @@ const map<string, CrmResourceType> crmAvailCntsTableMap =
{ "crm_stats_ipmc_entry_available", CrmResourceType::CRM_IPMC_ENTRY },
{ "crm_stats_snat_entry_available", CrmResourceType::CRM_SNAT_ENTRY },
{ "crm_stats_dnat_entry_available", CrmResourceType::CRM_DNAT_ENTRY }
{ "crm_stats_srv6_my_sid_entry_available", CrmResourceType::CRM_SRV6_MY_SID_ENTRY },
{ "crm_stats_srv6_nexthop_available", CrmResourceType::CRM_SRV6_NEXTHOP },
};

const map<string, CrmResourceType> crmUsedCntsTableMap =
Expand All @@ -168,6 +180,8 @@ const map<string, CrmResourceType> crmUsedCntsTableMap =
{ "crm_stats_ipmc_entry_used", CrmResourceType::CRM_IPMC_ENTRY },
{ "crm_stats_snat_entry_used", CrmResourceType::CRM_SNAT_ENTRY },
{ "crm_stats_dnat_entry_used", CrmResourceType::CRM_DNAT_ENTRY }
{ "crm_stats_srv6_my_sid_entry_used", CrmResourceType::CRM_SRV6_MY_SID_ENTRY },
{ "crm_stats_srv6_nexthop_used", CrmResourceType::CRM_SRV6_NEXTHOP },
};

CrmOrch::CrmOrch(DBConnector *db, string tableName):
Expand Down Expand Up @@ -530,6 +544,62 @@ void CrmOrch::getResAvailableCounters()
break;
}

case CrmResourceType::CRM_SRV6_MY_SID_ENTRY:
{
sai_object_type_t objType = static_cast<sai_object_type_t>(crmResSaiAvailAttrMap.at(res.first));
uint64_t availCount = 0;
sai_status_t status = sai_object_type_get_availability(gSwitchId, objType, 0, nullptr, &availCount);
if (status != SAI_STATUS_SUCCESS)
{
if ((status == SAI_STATUS_NOT_SUPPORTED) ||
(status == SAI_STATUS_NOT_IMPLEMENTED) ||
SAI_STATUS_IS_ATTR_NOT_SUPPORTED(status) ||
SAI_STATUS_IS_ATTR_NOT_IMPLEMENTED(status))
{
// mark unsupported resources
res.second.resStatus = CrmResourceStatus::CRM_RES_NOT_SUPPORTED;
SWSS_LOG_NOTICE("CRM Resource %s not supported", crmResTypeNameMap.at(res.first).c_str());
break;
}
SWSS_LOG_ERROR("Failed to get availability for object_type %u , rv:%d", objType, status);
break;
}

res.second.countersMap[CRM_COUNTERS_TABLE_KEY].availableCounter = static_cast<uint32_t>(availCount);

break;
}

case CrmResourceType::CRM_SRV6_NEXTHOP:
{
sai_object_type_t objType = static_cast<sai_object_type_t>(crmResSaiAvailAttrMap.at(res.first));
sai_attribute_t attr;
uint64_t availCount = 0;

attr.id = SAI_NEXT_HOP_ATTR_TYPE;
attr.value.s32 = SAI_NEXT_HOP_TYPE_SRV6_SIDLIST;
sai_status_t status = sai_object_type_get_availability(gSwitchId, objType, 1, &attr, &availCount);
if (status != SAI_STATUS_SUCCESS)
{
if ((status == SAI_STATUS_NOT_SUPPORTED) ||
(status == SAI_STATUS_NOT_IMPLEMENTED) ||
SAI_STATUS_IS_ATTR_NOT_SUPPORTED(status) ||
SAI_STATUS_IS_ATTR_NOT_IMPLEMENTED(status))
{
// mark unsupported resources
res.second.resStatus = CrmResourceStatus::CRM_RES_NOT_SUPPORTED;
SWSS_LOG_NOTICE("CRM Resource %s not supported", crmResTypeNameMap.at(res.first).c_str());
break;
}
SWSS_LOG_ERROR("Failed to get availability for object_type %u , rv:%d", objType, status);
break;
}

res.second.countersMap[CRM_COUNTERS_TABLE_KEY].availableCounter = static_cast<uint32_t>(availCount);

break;
}

default:
SWSS_LOG_ERROR("Failed to get CRM attribute %u. Unknown attribute.\n", attr.id);
return;
Expand Down
2 changes: 2 additions & 0 deletions orchagent/crmorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ enum class CrmResourceType
CRM_IPMC_ENTRY,
CRM_SNAT_ENTRY,
CRM_DNAT_ENTRY,
CRM_SRV6_MY_SID_ENTRY,
CRM_SRV6_NEXTHOP,
};

enum class CrmThresholdType
Expand Down
18 changes: 18 additions & 0 deletions orchagent/neighorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,3 +943,21 @@ bool NeighOrch::removeTunnelNextHop(const NextHopKey& nh)
return true;
}

void NeighOrch::updateSrv6Nexthop(const NextHopKey &nh, const sai_object_id_t &nh_id)
{
if (nh_id != SAI_NULL_OBJECT_ID)
{
NextHopEntry next_hop_entry;
next_hop_entry.next_hop_id = nh_id;
next_hop_entry.ref_count = 0;
next_hop_entry.nh_flags = 0;
m_syncdNextHops[nh] = next_hop_entry;
gCrmOrch->incCrmResUsedCounter(CrmResourceType::CRM_SRV6_NEXTHOP);
}
else
{
assert(m_syncdNextHops[nh].ref_count == 0);
gCrmOrch->decCrmResUsedCounter(CrmResourceType::CRM_SRV6_NEXTHOP);
m_syncdNextHops.erase(nh);
}
}
1 change: 1 addition & 0 deletions orchagent/neighorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class NeighOrch : public Orch, public Subject, public Observer
void update(SubjectType, void *);

void resolveNeighbor(const NeighborEntry &);
void updateSrv6Nexthop(const NextHopKey &, const sai_object_id_t &);

private:
PortsOrch *m_portsOrch;
Expand Down
38 changes: 30 additions & 8 deletions orchagent/nexthopgroupkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class NextHopGroupKey
NextHopGroupKey(const std::string &nexthops)
{
m_overlay_nexthops = false;
m_srv6_nexthops = false;
auto nhv = tokenize(nexthops, NHG_DELIMITER);
for (const auto &nh : nhv)
{
Expand All @@ -20,14 +21,29 @@ class NextHopGroupKey
}

/* ip_string|if_alias|vni|router_mac separated by ',' */
NextHopGroupKey(const std::string &nexthops, bool overlay_nh)
NextHopGroupKey(const std::string &nexthops, bool overlay_nh, bool srv6_nh)
{
m_overlay_nexthops = true;
auto nhv = tokenize(nexthops, NHG_DELIMITER);
for (const auto &nh_str : nhv)
if (overlay_nh)
{
auto nh = NextHopKey(nh_str, overlay_nh);
m_nexthops.insert(nh);
m_overlay_nexthops = true;
m_srv6_nexthops = false;
auto nhv = tokenize(nexthops, NHG_DELIMITER);
for (const auto &nh_str : nhv)
{
auto nh = NextHopKey(nh_str, overlay_nh, srv6_nh);
m_nexthops.insert(nh);
}
}
else if (srv6_nh)
{
m_overlay_nexthops = false;
m_srv6_nexthops = true;
auto nhv = tokenize(nexthops, NHG_DELIMITER);
for (const auto &nh_str : nhv)
{
auto nh = NextHopKey(nh_str, overlay_nh, srv6_nh);
m_nexthops.insert(nh);
}
}
}

Expand Down Expand Up @@ -137,8 +153,8 @@ class NextHopGroupKey
{
nhs_str += NHG_DELIMITER;
}
if (m_overlay_nexthops) {
nhs_str += it->to_string(m_overlay_nexthops);
if (m_overlay_nexthops || m_srv6_nexthops) {
nhs_str += it->to_string(m_overlay_nexthops, m_srv6_nexthops);
} else {
nhs_str += it->to_string();
}
Expand All @@ -152,6 +168,11 @@ class NextHopGroupKey
return m_overlay_nexthops;
}

inline bool is_srv6_nexthop() const
{
return m_srv6_nexthops;
}

void clear()
{
m_nexthops.clear();
Expand All @@ -160,6 +181,7 @@ class NextHopGroupKey
private:
std::set<NextHopKey> m_nexthops;
bool m_overlay_nexthops;
bool m_srv6_nexthops;
};

#endif /* SWSS_NEXTHOPGROUPKEY_H */
57 changes: 44 additions & 13 deletions orchagent/nexthopkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ struct NextHopKey
string alias; // incoming interface alias
uint32_t vni; // Encap VNI overlay nexthop
MacAddress mac_address; // Overlay Nexthop MAC.
string srv6_segment; // SRV6 segment string
string srv6_source; // SRV6 source address

NextHopKey() = default;
NextHopKey(const std::string &ipstr, const std::string &alias) : ip_address(ipstr), alias(alias), vni(0), mac_address() {}
Expand Down Expand Up @@ -49,44 +51,68 @@ struct NextHopKey
throw std::invalid_argument(err);
}
}
NextHopKey(const std::string &str, bool overlay_nh)
NextHopKey(const std::string &str, bool overlay_nh, bool srv6_nh)
{
if (str.find(NHG_DELIMITER) != string::npos)
{
std::string err = "Error converting " + str + " to NextHop";
throw std::invalid_argument(err);
}
auto keys = tokenize(str, NH_DELIMITER);
if (keys.size() != 4)
if (srv6_nh == true)
{
std::string err = "Error converting " + str + " to NextHop";
throw std::invalid_argument(err);
weight = 0;
vni = 0;
weight = 0;
auto keys = tokenize(str, NH_DELIMITER);
if (keys.size() != 3)
{
std::string err = "Error converting " + str + " to Nexthop";
throw std::invalid_argument(err);
}
ip_address = keys[0];
srv6_segment = keys[1];
srv6_source = keys[2];
}
else
{
auto keys = tokenize(str, NH_DELIMITER);
if (keys.size() != 4)
{
std::string err = "Error converting " + str + " to NextHop";
throw std::invalid_argument(err);
}
ip_address = keys[0];
alias = keys[1];
vni = static_cast<uint32_t>(std::stoul(keys[2]));
mac_address = keys[3];
weight = 0;
}
ip_address = keys[0];
alias = keys[1];
vni = static_cast<uint32_t>(std::stoul(keys[2]));
mac_address = keys[3];
}

const std::string to_string() const
{
return ip_address.to_string() + NH_DELIMITER + alias;
}

const std::string to_string(bool overlay_nh) const
const std::string to_string(bool overlay_nh, bool srv6_nh) const
{
if (srv6_nh)
{
return ip_address.to_string() + NH_DELIMITER + srv6_segment + NH_DELIMITER + srv6_source;
}
std::string s_vni = std::to_string(vni);
return ip_address.to_string() + NH_DELIMITER + alias + NH_DELIMITER + s_vni + NH_DELIMITER + mac_address.to_string();
}

bool operator<(const NextHopKey &o) const
{
return tie(ip_address, alias, vni, mac_address) < tie(o.ip_address, o.alias, o.vni, o.mac_address);
return tie(ip_address, alias, vni, mac_address, srv6_segment, srv6_source) < tie(o.ip_address, o.alias, o.vni, o.mac_address, o.srv6_segment, o.srv6_source);
}

bool operator==(const NextHopKey &o) const
{
return (ip_address == o.ip_address) && (alias == o.alias) && (vni == o.vni) && (mac_address == o.mac_address);
return (ip_address == o.ip_address) && (alias == o.alias) && (vni == o.vni) && (mac_address == o.mac_address) &&
(srv6_segment == o.srv6_segment) && (srv6_source == o.srv6_source);
}

bool operator!=(const NextHopKey &o) const
Expand All @@ -96,7 +122,12 @@ struct NextHopKey

bool isIntfNextHop() const
{
return (ip_address.getV4Addr() == 0);
return ((ip_address.getV4Addr() == 0) && !isSrv6NextHop());
}

bool isSrv6NextHop() const
{
return (srv6_segment != "");
}
};

Expand Down
Loading

0 comments on commit aa0206c

Please sign in to comment.