Skip to content

Commit 9923d9c

Browse files
mint570bibhuprasad-hcl
authored andcommitted
[P4Orch] Add P4MulticastRouterInterfaceEntry that use the no_action action.
Signed-off-by: Bibhuprasad Singh <[email protected]>
1 parent dcaf384 commit 9923d9c

File tree

3 files changed

+251
-65
lines changed

3 files changed

+251
-65
lines changed

orchagent/p4orch/l3_multicast_manager.cpp

Lines changed: 120 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ extern sai_object_id_t gSwitchId;
3232
extern sai_object_id_t gVirtualRouterId;
3333
extern sai_ipmc_group_api_t* sai_ipmc_group_api;
3434
extern sai_router_interface_api_t* sai_router_intfs_api;
35+
extern sai_bridge_api_t* sai_bridge_api;
3536

3637
extern PortsOrch* gPortsOrch;
3738

@@ -820,11 +821,10 @@ ReturnCode L3MulticastManager::validateL3SetMulticastRouterInterfaceEntry(
820821
<< "RIF was not assigned before updating multicast router "
821822
"interface "
822823
"entry with keys "
823-
<< QuotedVar(
824-
multicast_router_interface_entry.multicast_replica_port)
824+
<< QuotedVar(multicast_router_interface_entry.multicast_replica_port)
825825
<< " and "
826-
<< QuotedVar(multicast_router_interface_entry
827-
.multicast_replica_instance);
826+
<< QuotedVar(
827+
multicast_router_interface_entry.multicast_replica_instance);
828828
}
829829

830830
// Confirm we have a reference to the RIF object ID.
@@ -876,10 +876,11 @@ ReturnCode L3MulticastManager::validateSetMulticastRouterInterfaceEntry(
876876
router_interface_entry_ptr->action) {
877877
return ReturnCode(StatusCode::SWSS_RC_INVALID_PARAM)
878878
<< "Multicast router interface entry with key "
879-
<< QuotedVar(multicast_router_interface_entry.multicast_router_interface_entry_key)
879+
<< QuotedVar(multicast_router_interface_entry
880+
.multicast_router_interface_entry_key)
880881
<< " cannot change action from "
881-
<< QuotedVar(router_interface_entry_ptr->action)
882-
<< " to " << QuotedVar(multicast_router_interface_entry.action);
882+
<< QuotedVar(router_interface_entry_ptr->action) << " to "
883+
<< QuotedVar(multicast_router_interface_entry.action);
883884
}
884885

885886
if (multicast_router_interface_entry.action == p4orch::kSetMulticastSrcMac) {
@@ -1009,6 +1010,42 @@ ReturnCode L3MulticastManager::processMulticastGroupEntries(
10091010
return status;
10101011
}
10111012

1013+
ReturnCode L3MulticastManager::createBridgePort(
1014+
P4MulticastRouterInterfaceEntry& entry, sai_object_id_t* bridge_port_oid) {
1015+
SWSS_LOG_ENTER();
1016+
1017+
Port port;
1018+
if (!gPortsOrch->getPort(entry.multicast_replica_port, port)) {
1019+
LOG_ERROR_AND_RETURN(ReturnCode(StatusCode::SWSS_RC_NOT_FOUND)
1020+
<< "Unable to find port object "
1021+
<< QuotedVar(entry.multicast_replica_port)
1022+
<< " to create bridge port");
1023+
}
1024+
1025+
std::vector<sai_attribute_t> attrs;
1026+
sai_attribute_t attr;
1027+
1028+
attr.id = SAI_BRIDGE_PORT_ATTR_TYPE;
1029+
attr.value.s32 = SAI_BRIDGE_PORT_TYPE_PORT;
1030+
attrs.push_back(attr);
1031+
1032+
attr.id = SAI_BRIDGE_PORT_ATTR_PORT_ID;
1033+
attr.value.oid = port.m_port_id;
1034+
attrs.push_back(attr);
1035+
1036+
sai_status_t status = sai_bridge_api->create_bridge_port(
1037+
bridge_port_oid, gSwitchId, (uint32_t)attrs.size(), attrs.data());
1038+
1039+
if (status != SAI_STATUS_SUCCESS) {
1040+
LOG_ERROR_AND_RETURN(
1041+
ReturnCode(status)
1042+
<< "Failed to create bridge port for L2 multicast on port "
1043+
<< QuotedVar(entry.multicast_replica_port));
1044+
}
1045+
1046+
return ReturnCode();
1047+
}
1048+
10121049
ReturnCode L3MulticastManager::createRouterInterface(
10131050
const std::string& rif_key, P4MulticastRouterInterfaceEntry& entry,
10141051
sai_object_id_t* rif_oid) {
@@ -1136,6 +1173,26 @@ ReturnCode L3MulticastManager::deleteMulticastGroup(
11361173

11371174
std::vector<ReturnCode> L3MulticastManager::addMulticastRouterInterfaceEntries(
11381175
std::vector<P4MulticastRouterInterfaceEntry>& entries) {
1176+
SWSS_LOG_ENTER();
1177+
std::vector<ReturnCode> statuses(entries.size());
1178+
fillStatusArrayWithNotExecuted(statuses, 0);
1179+
1180+
for (size_t i = 0; i < entries.size(); ++i) {
1181+
auto& entry = entries[i];
1182+
if (entry.action == p4orch::kSetMulticastSrcMac) {
1183+
statuses[i] = addL3MulticastRouterInterfaceEntry(entry);
1184+
} else {
1185+
statuses[i] = addL2MulticastRouterInterfaceEntry(entry);
1186+
}
1187+
if (!statuses[i].ok()) {
1188+
break;
1189+
}
1190+
}
1191+
return statuses;
1192+
}
1193+
1194+
ReturnCode L3MulticastManager::addL3MulticastRouterInterfaceEntry(
1195+
P4MulticastRouterInterfaceEntry& entry) {
11391196
// There are two cases for add:
11401197
// 1. The new entry (multicast_replica_port, multicast_replica_instance) will
11411198
// need a new RIF allocated.
@@ -1144,43 +1201,52 @@ std::vector<ReturnCode> L3MulticastManager::addMulticastRouterInterfaceEntries(
11441201
// src mac, and src mac is the action parameter associated with a table entry.
11451202
SWSS_LOG_ENTER();
11461203

1147-
std::vector<ReturnCode> statuses(entries.size());
1148-
fillStatusArrayWithNotExecuted(statuses, 0);
1149-
for (size_t i = 0; i < entries.size(); ++i) {
1150-
auto& entry = entries[i];
1204+
sai_object_id_t rif_oid = getRifOid(&entry);
1205+
if (rif_oid == SAI_NULL_OBJECT_ID) {
1206+
std::string rif_key = KeyGenerator::generateMulticastRouterInterfaceRifKey(
1207+
entry.multicast_replica_port, entry.src_mac);
11511208

1152-
sai_object_id_t rif_oid = getRifOid(&entry);
1153-
if (rif_oid == SAI_NULL_OBJECT_ID) {
1154-
std::string rif_key =
1155-
KeyGenerator::generateMulticastRouterInterfaceRifKey(
1156-
entry.multicast_replica_port, entry.src_mac);
1209+
RETURN_IF_ERROR(createRouterInterface(rif_key, entry, &rif_oid));
11571210

1158-
ReturnCode create_status =
1159-
createRouterInterface(rif_key, entry, &rif_oid);
1160-
statuses[i] = create_status;
1161-
if (!create_status.ok()) {
1162-
break;
1163-
}
1211+
gPortsOrch->increasePortRefCount(entry.multicast_replica_port);
1212+
m_p4OidMapper->setOID(SAI_OBJECT_TYPE_ROUTER_INTERFACE, rif_key, rif_oid);
1213+
m_rifOids[rif_key] = rif_oid;
1214+
m_rifOidToMulticastGroupMembers[rif_oid] = {};
1215+
}
11641216

1165-
gPortsOrch->increasePortRefCount(entry.multicast_replica_port);
1166-
m_p4OidMapper->setOID(SAI_OBJECT_TYPE_ROUTER_INTERFACE, rif_key, rif_oid);
1167-
m_rifOids[rif_key] = rif_oid;
1168-
m_rifOidToMulticastGroupMembers[rif_oid] = {};
1169-
}
1217+
// Operations done regardless of whether RIF was created or not.
1218+
// Set the entry RIF.
1219+
entry.router_interface_oid = rif_oid;
11701220

1171-
// Operations done regardless of whether RIF was created or not.
1172-
// Set the entry RIF.
1173-
entry.router_interface_oid = rif_oid;
1221+
// Update internal state.
1222+
m_multicastRouterInterfaceTable[entry.multicast_router_interface_entry_key] =
1223+
entry;
1224+
m_rifOidToRouterInterfaceEntries[rif_oid].push_back(entry);
1225+
return ReturnCode();
1226+
}
11741227

1175-
// Update internal state.
1176-
m_multicastRouterInterfaceTable[entry
1177-
.multicast_router_interface_entry_key] =
1178-
entry;
1179-
m_rifOidToRouterInterfaceEntries[rif_oid].push_back(entry);
1228+
ReturnCode L3MulticastManager::addL2MulticastRouterInterfaceEntry(
1229+
P4MulticastRouterInterfaceEntry& entry) {
1230+
// There are two cases for add:
1231+
// 1. The new entry (multicast_replica_port, multicast_replica_instance) will
1232+
// need a new bridge port allocated.
1233+
// 2. The new entry will be able to use an existing bridge port.
1234+
// Recall that bridge ports depend only on the multicast_replica_port.
1235+
SWSS_LOG_ENTER();
11801236

1181-
statuses[i] = ReturnCode();
1182-
} // for i
1183-
return statuses;
1237+
sai_object_id_t bridge_port_oid = getBridgePortOid(&entry);
1238+
if (bridge_port_oid == SAI_NULL_OBJECT_ID) {
1239+
RETURN_IF_ERROR(createBridgePort(entry, &bridge_port_oid));
1240+
gPortsOrch->increasePortRefCount(entry.multicast_replica_port);
1241+
m_p4OidMapper->setOID(SAI_OBJECT_TYPE_BRIDGE_PORT,
1242+
entry.multicast_replica_port, bridge_port_oid);
1243+
}
1244+
1245+
// Operations done regardless of whether bridge port was created or not.
1246+
// Set the entry bridge port.
1247+
m_multicastRouterInterfaceTable[entry.multicast_router_interface_entry_key] =
1248+
entry;
1249+
return ReturnCode();
11841250
}
11851251

11861252
std::vector<ReturnCode>
@@ -2172,14 +2238,7 @@ std::string L3MulticastManager::verifyMulticastGroupStateCache(
21722238

21732239
std::string L3MulticastManager::verifyMulticastGroupStateAsicDb(
21742240
const P4MulticastGroupEntry* multicast_group_entry) {
2175-
21762241
// Confirm group settings.
2177-
std::vector<sai_attribute_t> group_attrs; // no required attributes
2178-
std::vector<swss::FieldValueTuple> exp =
2179-
saimeta::SaiAttributeList::serialize_attr_list(
2180-
SAI_OBJECT_TYPE_IPMC_GROUP, (uint32_t)group_attrs.size(),
2181-
group_attrs.data(), /*countOnly=*/false);
2182-
21832242
swss::DBConnector db("ASIC_DB", 0);
21842243
swss::Table table(&db, "ASIC_STATE");
21852244
std::string key =
@@ -2189,12 +2248,9 @@ std::string L3MulticastManager::verifyMulticastGroupStateAsicDb(
21892248
if (!table.get(key, values)) {
21902249
return std::string("ASIC DB key not found ") + key;
21912250
}
2192-
std::string group_msg =
2193-
verifyAttrs(values, exp, std::vector<swss::FieldValueTuple>{},
2194-
/*allow_unknown=*/false);
2195-
if (!group_msg.empty()) {
2196-
return group_msg;
2197-
}
2251+
// There are no IPMC group attributes to verify. The attributes that do
2252+
// exist are read-only attributes related to how many group members there are.
2253+
// We check group members and their attributes below.
21982254

21992255
// Confirm group member settings.
22002256
for (auto& replica : multicast_group_entry->replicas) {
@@ -2217,7 +2273,8 @@ std::string L3MulticastManager::verifyMulticastGroupStateAsicDb(
22172273

22182274
auto member_attrs = prepareMulticastGroupMemberSaiAttrs(
22192275
multicast_group_entry->multicast_group_oid, rif_oid);
2220-
exp = saimeta::SaiAttributeList::serialize_attr_list(
2276+
std::vector<swss::FieldValueTuple> exp =
2277+
saimeta::SaiAttributeList::serialize_attr_list(
22212278
SAI_OBJECT_TYPE_IPMC_GROUP_MEMBER, (uint32_t)member_attrs.size(),
22222279
member_attrs.data(), /*countOnly=*/false);
22232280
key = sai_serialize_object_type(SAI_OBJECT_TYPE_IPMC_GROUP_MEMBER) + ":" +
@@ -2270,6 +2327,17 @@ sai_object_id_t L3MulticastManager::getRifOid(
22702327
return m_rifOids[rif_key];
22712328
}
22722329

2330+
// A bridge port is associated with an egress port.
2331+
sai_object_id_t L3MulticastManager::getBridgePortOid(
2332+
const P4MulticastRouterInterfaceEntry* multicast_router_interface_entry) {
2333+
sai_object_id_t bridge_port_oid = SAI_NULL_OBJECT_ID;
2334+
m_p4OidMapper->getOID(
2335+
SAI_OBJECT_TYPE_BRIDGE_PORT,
2336+
multicast_router_interface_entry->multicast_replica_port,
2337+
&bridge_port_oid);
2338+
return bridge_port_oid;
2339+
}
2340+
22732341
// A RIF is associated with an egress port and Ethernet src mac value.
22742342
sai_object_id_t L3MulticastManager::getRifOid(const P4Replica& replica) {
22752343

orchagent/p4orch/l3_multicast_manager.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ class L3MulticastManager : public ObjectManagerInterface {
190190
const std::string& op, bool update);
191191

192192
// Wrapper around SAI setup and call, for easy mocking.
193+
ReturnCode createBridgePort(P4MulticastRouterInterfaceEntry& entry,
194+
sai_object_id_t* bridge_port_oid);
193195
ReturnCode createRouterInterface(const std::string& rif_key,
194196
P4MulticastRouterInterfaceEntry& entry,
195197
sai_object_id_t* rif_oid);
@@ -211,6 +213,10 @@ class L3MulticastManager : public ObjectManagerInterface {
211213
// Add new multicast router interface table entries.
212214
std::vector<ReturnCode> addMulticastRouterInterfaceEntries(
213215
std::vector<P4MulticastRouterInterfaceEntry>& entries);
216+
ReturnCode addL3MulticastRouterInterfaceEntry(
217+
P4MulticastRouterInterfaceEntry& entry);
218+
ReturnCode addL2MulticastRouterInterfaceEntry(
219+
P4MulticastRouterInterfaceEntry& entry);
214220
// Update existing multicast router interface table entries.
215221
std::vector<ReturnCode> updateMulticastRouterInterfaceEntries(
216222
std::vector<P4MulticastRouterInterfaceEntry>& entries);
@@ -282,6 +288,11 @@ class L3MulticastManager : public ObjectManagerInterface {
282288
// This would be the value used by the group member.
283289
sai_object_id_t getRifOid(const P4Replica& replica);
284290

291+
// Fetches a bridge port OID for a port that will be used for L2 multicast
292+
// group members.
293+
sai_object_id_t getBridgePortOid(
294+
const P4MulticastRouterInterfaceEntry* multicast_router_interface_entry);
295+
285296
// Internal cache of entries.
286297
P4MulticastRouterInterfaceTable m_multicastRouterInterfaceTable;
287298
P4MulticastGroupTable m_multicastGroupEntryTable;

0 commit comments

Comments
 (0)