Skip to content

Commit 8b65f0f

Browse files
PINS Working Groupntoorchi
PINS Working Group
authored andcommitted
Orchagent: Integrate P4Orch
* support pushing switch configurations. * support ACL table definitions. * support insert/delete/modify in APPL_DB. * support for L3 forwarding, WCMP, and ACL tables. * support for response path through APPL_STATE_DB. Co-authored-by: Robert Halstead [email protected] Co-authored-by: Srikishen Pondicherry Shanmugam [email protected] Co-authored-by: Steffen Smolka [email protected] Co-authored-by: Jonathan Dilorenzo [email protected] Co-authored-by: Richard Yu [email protected] Co-authored-by: Brian O'Connor [email protected] Co-authored-by: Konstantin Weitz [email protected] Co-authored-by: Stefan Heule [email protected] Co-authored-by: Tianyu Xia [email protected]
1 parent c657f04 commit 8b65f0f

15 files changed

+278
-21
lines changed

configure.ac

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ AC_CONFIG_FILES([
138138
swssconfig/Makefile
139139
cfgmgr/Makefile
140140
tests/Makefile
141+
orchagent/p4orch/tests/Makefile
141142
])
142143

143144
# If no SAI library is installed, compile with SAIVS and run unit tests

orchagent/Makefile.am

+12
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ orchagent_SOURCES = \
8888

8989
orchagent_SOURCES += flex_counter/flex_counter_manager.cpp flex_counter/flex_counter_stat_manager.cpp
9090
orchagent_SOURCES += debug_counter/debug_counter.cpp debug_counter/drop_counter.cpp
91+
orchagent_SOURCES += p4orch/p4orch.cpp \
92+
p4orch/p4orch_util.cpp \
93+
p4orch/p4oidmapper.cpp \
94+
p4orch/router_interface_manager.cpp \
95+
p4orch/neighbor_manager.cpp \
96+
p4orch/next_hop_manager.cpp \
97+
p4orch/route_manager.cpp \
98+
p4orch/acl_util.cpp \
99+
p4orch/acl_table_manager.cpp \
100+
p4orch/acl_rule_manager.cpp \
101+
p4orch/wcmp_manager.cpp \
102+
p4orch/mirror_session_manager.cpp
91103

92104
orchagent_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
93105
orchagent_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)

orchagent/acltable.h

+28-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extern "C" {
1717

1818
#define STAGE_INGRESS "INGRESS"
1919
#define STAGE_EGRESS "EGRESS"
20+
#define STAGE_PRE_INGRESS "PRE_INGRESS"
2021

2122
#define TABLE_TYPE_L3 "L3"
2223
#define TABLE_TYPE_L3V6 "L3V6"
@@ -35,7 +36,8 @@ typedef enum
3536
{
3637
ACL_STAGE_UNKNOWN,
3738
ACL_STAGE_INGRESS,
38-
ACL_STAGE_EGRESS
39+
ACL_STAGE_EGRESS,
40+
ACL_STAGE_PRE_INGRESS
3941
} acl_stage_type_t;
4042

4143
typedef std::unordered_map<std::string, acl_stage_type_t> acl_stage_type_lookup_t;
@@ -59,3 +61,28 @@ typedef enum
5961
} acl_table_type_t;
6062

6163
typedef std::unordered_map<std::string, acl_table_type_t> acl_table_type_lookup_t;
64+
typedef std::map<std::string, sai_acl_stage_t> acl_stage_lookup_t;
65+
typedef std::map<sai_acl_stage_t, sai_switch_attr_t> acl_stage_to_switch_attr_lookup_t;
66+
67+
struct AclTableGroupMember {
68+
sai_object_id_t m_group_oid;
69+
sai_object_id_t m_group_member_oid;
70+
uint32_t m_priority;
71+
AclTableGroupMember()
72+
: m_group_oid(SAI_NULL_OBJECT_ID)
73+
, m_group_member_oid(SAI_NULL_OBJECT_ID)
74+
, m_priority(0)
75+
{}
76+
};
77+
78+
static const acl_stage_lookup_t aclStageLookup = {
79+
{STAGE_INGRESS, SAI_ACL_STAGE_INGRESS},
80+
{STAGE_EGRESS, SAI_ACL_STAGE_EGRESS},
81+
{STAGE_PRE_INGRESS, SAI_ACL_STAGE_PRE_INGRESS},
82+
};
83+
84+
static const acl_stage_to_switch_attr_lookup_t aclStageToSwitchAttrLookup = {
85+
{SAI_ACL_STAGE_INGRESS, SAI_SWITCH_ATTR_INGRESS_ACL},
86+
{SAI_ACL_STAGE_EGRESS, SAI_SWITCH_ATTR_EGRESS_ACL},
87+
{SAI_ACL_STAGE_PRE_INGRESS, SAI_SWITCH_ATTR_PRE_INGRESS_ACL},
88+
};

orchagent/orchdaemon.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ NatOrch *gNatOrch;
4444
MlagOrch *gMlagOrch;
4545
IsoGrpOrch *gIsoGrpOrch;
4646
MACsecOrch *gMacsecOrch;
47+
P4Orch *gP4Orch;
4748
BfdOrch *gBfdOrch;
4849
Srv6Orch *gSrv6Orch;
4950

@@ -87,6 +88,9 @@ bool OrchDaemon::init()
8788
SWSS_LOG_ENTER();
8889

8990
string platform = getenv("platform") ? getenv("platform") : "";
91+
92+
gCrmOrch = new CrmOrch(m_configDb, CFG_CRM_TABLE_NAME);
93+
9094
TableConnector stateDbSwitchTable(m_stateDb, "SWITCH_CAPABILITY");
9195
TableConnector app_switch_table(m_applDb, APP_SWITCH_TABLE_NAME);
9296
TableConnector conf_asic_sensors(m_configDb, CFG_ASIC_SENSORS_TABLE_NAME);
@@ -114,7 +118,6 @@ bool OrchDaemon::init()
114118
{ APP_MCLAG_FDB_TABLE_NAME, FdbOrch::fdborch_pri}
115119
};
116120

117-
gCrmOrch = new CrmOrch(m_configDb, CFG_CRM_TABLE_NAME);
118121
gPortsOrch = new PortsOrch(m_applDb, m_stateDb, ports_tables, m_chassisAppDb);
119122
TableConnector stateDbFdb(m_stateDb, STATE_FDB_TABLE_NAME);
120123
TableConnector stateMclagDbFdb(m_stateDb, STATE_MCLAG_REMOTE_FDB_TABLE_NAME);
@@ -589,6 +592,10 @@ bool OrchDaemon::init()
589592

590593
m_orchList.push_back(&CounterCheckOrch::getInstance(m_configDb));
591594

595+
vector<string> p4rt_tables = {APP_P4RT_TABLE_NAME};
596+
gP4Orch = new P4Orch(m_applDb, p4rt_tables, vrf_orch, copp_orch);
597+
m_orchList.push_back(gP4Orch);
598+
592599
if (WarmStart::isWarmStart())
593600
{
594601
bool suc = warmRestoreAndSyncUp();

orchagent/orchdaemon.h

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "mlagorch.h"
3939
#include "muxorch.h"
4040
#include "macsecorch.h"
41+
#include "p4orch/p4orch.h"
4142
#include "bfdorch.h"
4243
#include "srv6orch.h"
4344

orchagent/portsorch.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ class PortsOrch : public Orch, public Subject
162162
bool getPortIPG(sai_object_id_t port_id, uint32_t &ipg);
163163
bool setPortIPG(sai_object_id_t port_id, uint32_t ipg);
164164

165+
bool getPortOperStatus(const Port& port, sai_port_oper_status_t& status) const;
166+
165167
private:
166168
unique_ptr<Table> m_counterTable;
167169
unique_ptr<Table> m_counterLagTable;
@@ -315,7 +317,6 @@ class PortsOrch : public Orch, public Subject
315317
task_process_status setPortInterfaceType(sai_object_id_t id, sai_port_interface_type_t interface_type);
316318
task_process_status setPortAdvInterfaceTypes(sai_object_id_t id, std::vector<uint32_t> &interface_types);
317319

318-
bool getPortOperStatus(const Port& port, sai_port_oper_status_t& status) const;
319320
void updatePortOperStatus(Port &port, sai_port_oper_status_t status);
320321

321322
bool getPortOperSpeed(const Port& port, sai_uint32_t& speed) const;
@@ -356,4 +357,3 @@ class PortsOrch : public Orch, public Subject
356357

357358
};
358359
#endif /* SWSS_PORTSORCH_H */
359-

orchagent/saihelper.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ sai_qos_map_api_t* sai_qos_map_api;
5757
sai_buffer_api_t* sai_buffer_api;
5858
sai_acl_api_t* sai_acl_api;
5959
sai_hash_api_t* sai_hash_api;
60+
sai_udf_api_t* sai_udf_api;
6061
sai_mirror_api_t* sai_mirror_api;
6162
sai_fdb_api_t* sai_fdb_api;
6263
sai_dtel_api_t* sai_dtel_api;
@@ -185,6 +186,7 @@ void initSaiApi()
185186
sai_api_query(SAI_API_SCHEDULER_GROUP, (void **)&sai_scheduler_group_api);
186187
sai_api_query(SAI_API_ACL, (void **)&sai_acl_api);
187188
sai_api_query(SAI_API_HASH, (void **)&sai_hash_api);
189+
sai_api_query(SAI_API_UDF, (void **)&sai_udf_api);
188190
sai_api_query(SAI_API_DTEL, (void **)&sai_dtel_api);
189191
sai_api_query(SAI_API_SAMPLEPACKET, (void **)&sai_samplepacket_api);
190192
sai_api_query(SAI_API_DEBUG_COUNTER, (void **)&sai_debug_counter_api);
@@ -221,6 +223,7 @@ void initSaiApi()
221223
sai_log_set(SAI_API_SCHEDULER_GROUP, SAI_LOG_LEVEL_NOTICE);
222224
sai_log_set(SAI_API_ACL, SAI_LOG_LEVEL_NOTICE);
223225
sai_log_set(SAI_API_HASH, SAI_LOG_LEVEL_NOTICE);
226+
sai_log_set(SAI_API_UDF, SAI_LOG_LEVEL_NOTICE);
224227
sai_log_set(SAI_API_DTEL, SAI_LOG_LEVEL_NOTICE);
225228
sai_log_set(SAI_API_SAMPLEPACKET, SAI_LOG_LEVEL_NOTICE);
226229
sai_log_set(SAI_API_DEBUG_COUNTER, SAI_LOG_LEVEL_NOTICE);

orchagent/switchorch.cpp

+155
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@
22
#include <inttypes.h>
33

44
#include "switchorch.h"
5+
#include "crmorch.h"
56
#include "converter.h"
67
#include "notifier.h"
78
#include "notificationproducer.h"
89
#include "macaddress.h"
10+
#include "return_code.h"
911

1012
using namespace std;
1113
using namespace swss;
1214

1315
extern sai_object_id_t gSwitchId;
1416
extern sai_switch_api_t *sai_switch_api;
17+
extern sai_acl_api_t* sai_acl_api;
1518
extern MacAddress gVxlanMacAddress;
19+
extern CrmOrch *gCrmOrch;
1620

1721
const map<string, sai_switch_attr_t> switch_attribute_map =
1822
{
@@ -55,6 +59,157 @@ SwitchOrch::SwitchOrch(DBConnector *db, vector<TableConnector>& connectors, Tabl
5559
querySwitchTpidCapability();
5660
auto executorT = new ExecutableTimer(m_sensorsPollerTimer, this, "ASIC_SENSORS_POLL_TIMER");
5761
Orch::addExecutor(executorT);
62+
initAclGroupsBindToSwitch();
63+
}
64+
65+
void SwitchOrch::initAclGroupsBindToSwitch()
66+
{
67+
// Create an ACL group per stage, INGRESS, EGRESS and PRE_INGRESS
68+
for (auto stage_it : aclStageLookup) {
69+
sai_object_id_t group_oid;
70+
auto status = createAclGroup(fvValue(stage_it), &group_oid);
71+
if (!status.ok())
72+
{
73+
status.prepend("Failed to create ACL group for stage " +
74+
fvField(stage_it) + ": ");
75+
SWSS_LOG_THROW("%s", status.message().c_str());
76+
}
77+
SWSS_LOG_NOTICE("Created ACL group for stage %s",
78+
fvField(stage_it).c_str());
79+
m_aclGroups[fvValue(stage_it)] = group_oid;
80+
status = bindAclGroupToSwitch(fvValue(stage_it), group_oid);
81+
if (!status.ok())
82+
{
83+
status.prepend("Failed to bind ACL group to stage " +
84+
fvField(stage_it) + ": ");
85+
SWSS_LOG_THROW("%s", status.message().c_str());
86+
}
87+
}
88+
}
89+
90+
const std::map<sai_acl_stage_t, sai_object_id_t>&
91+
SwitchOrch::getAclGroupOidsBindingToSwitch()
92+
{
93+
return m_aclGroups;
94+
}
95+
96+
ReturnCode SwitchOrch::createAclGroup(const sai_acl_stage_t& group_stage,
97+
sai_object_id_t* acl_grp_oid)
98+
{
99+
SWSS_LOG_ENTER();
100+
101+
std::vector<sai_attribute_t> acl_grp_attrs;
102+
sai_attribute_t acl_grp_attr;
103+
acl_grp_attr.id = SAI_ACL_TABLE_GROUP_ATTR_ACL_STAGE;
104+
acl_grp_attr.value.s32 = group_stage;
105+
acl_grp_attrs.push_back(acl_grp_attr);
106+
107+
acl_grp_attr.id = SAI_ACL_TABLE_GROUP_ATTR_TYPE;
108+
acl_grp_attr.value.s32 = SAI_ACL_TABLE_GROUP_TYPE_PARALLEL;
109+
acl_grp_attrs.push_back(acl_grp_attr);
110+
111+
acl_grp_attr.id = SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST;
112+
std::vector<int32_t> bpoint_list;
113+
bpoint_list.push_back(SAI_ACL_BIND_POINT_TYPE_SWITCH);
114+
acl_grp_attr.value.s32list.count = (uint32_t)bpoint_list.size();
115+
acl_grp_attr.value.s32list.list = bpoint_list.data();
116+
acl_grp_attrs.push_back(acl_grp_attr);
117+
118+
CHECK_ERROR_AND_LOG_AND_RETURN(
119+
sai_acl_api->create_acl_table_group(acl_grp_oid, gSwitchId,
120+
(uint32_t)acl_grp_attrs.size(),
121+
acl_grp_attrs.data()),
122+
"Failed to create ACL group for stage " << group_stage);
123+
if (group_stage == SAI_ACL_STAGE_INGRESS ||
124+
group_stage == SAI_ACL_STAGE_PRE_INGRESS ||
125+
group_stage == SAI_ACL_STAGE_EGRESS)
126+
{
127+
gCrmOrch->incCrmAclUsedCounter(CrmResourceType::CRM_ACL_GROUP,
128+
(sai_acl_stage_t)group_stage,
129+
SAI_ACL_BIND_POINT_TYPE_SWITCH);
130+
}
131+
SWSS_LOG_INFO("Suceeded to create ACL group %s in stage %d ",
132+
sai_serialize_object_id(*acl_grp_oid).c_str(), group_stage);
133+
return ReturnCode();
134+
}
135+
136+
ReturnCode SwitchOrch::bindAclGroupToSwitch(
137+
const sai_acl_stage_t& group_stage, const sai_object_id_t& acl_grp_oid)
138+
{
139+
SWSS_LOG_ENTER();
140+
141+
auto switch_attr_it = aclStageToSwitchAttrLookup.find(group_stage);
142+
if (switch_attr_it == aclStageToSwitchAttrLookup.end())
143+
{
144+
LOG_ERROR_AND_RETURN(ReturnCode(StatusCode::SWSS_RC_INVALID_PARAM)
145+
<< "Failed to set ACL group(" << acl_grp_oid
146+
<< ") to the SWITCH bind point at stage "
147+
<< group_stage);
148+
}
149+
sai_attribute_t attr;
150+
attr.id = switch_attr_it->second;
151+
attr.value.oid = acl_grp_oid;
152+
auto sai_status = sai_switch_api->set_switch_attribute(gSwitchId, &attr);
153+
if (sai_status != SAI_STATUS_SUCCESS)
154+
{
155+
LOG_ERROR_AND_RETURN(
156+
ReturnCode(sai_status)
157+
<< "[SAI] Failed to set_switch_attribute with attribute.id=" << attr.id
158+
<< " and acl group oid=" << acl_grp_oid);
159+
}
160+
return ReturnCode();
161+
}
162+
163+
ReturnCode SwitchOrch::unbindAclGroupToSwitch(
164+
const sai_acl_stage_t& group_stage)
165+
{
166+
SWSS_LOG_ENTER();
167+
168+
return bindAclGroupToSwitch(group_stage, SAI_NULL_OBJECT_ID);
169+
}
170+
171+
ReturnCode SwitchOrch::removeAclGroup(const sai_acl_stage_t& group_stage)
172+
{
173+
SWSS_LOG_ENTER();
174+
175+
auto group_it = m_aclGroups.find(group_stage);
176+
if (group_it == m_aclGroups.end())
177+
{
178+
LOG_ERROR_AND_RETURN(
179+
ReturnCode(SAI_STATUS_INVALID_PARAMETER)
180+
<< "Failed to find ACL group by stage '" << group_stage << "'");
181+
}
182+
CHECK_ERROR_AND_LOG_AND_RETURN(
183+
sai_acl_api->remove_acl_table_group(group_it->second),
184+
"Failed to create ACL group for stage " << group_stage);
185+
if (group_stage == SAI_ACL_STAGE_INGRESS ||
186+
group_stage == SAI_ACL_STAGE_PRE_INGRESS ||
187+
group_stage == SAI_ACL_STAGE_EGRESS)
188+
{
189+
gCrmOrch->decCrmAclUsedCounter(CrmResourceType::CRM_ACL_GROUP,
190+
(sai_acl_stage_t)group_stage,
191+
SAI_ACL_BIND_POINT_TYPE_SWITCH,
192+
group_it->second);
193+
}
194+
m_aclGroups.erase(group_stage);
195+
SWSS_LOG_NOTICE("Suceeded to remove ACL group %s in stage %d ",
196+
sai_serialize_object_id(group_it->second).c_str(), group_stage);
197+
return ReturnCode();
198+
}
199+
200+
ReturnCode SwitchOrch::removeAllAclGroups()
201+
{
202+
SWSS_LOG_ENTER();
203+
204+
for (auto stage_it : aclStageLookup)
205+
{
206+
if (m_aclGroups.find(fvValue(stage_it)) != m_aclGroups.end())
207+
{
208+
LOG_AND_RETURN_IF_ERROR(unbindAclGroupToSwitch(fvValue(stage_it)));
209+
LOG_AND_RETURN_IF_ERROR(removeAclGroup(fvValue(stage_it)));
210+
}
211+
}
212+
return ReturnCode();
58213
}
59214

60215
void SwitchOrch::doCfgSensorsTableTask(Consumer &consumer)

orchagent/switchorch.h

+29
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "orch.h"
44
#include "timer.h"
5+
#include "acltable.h"
56

67
#define DEFAULT_ASIC_SENSORS_POLLER_INTERVAL 60
78
#define ASIC_SENSORS_POLLER_STATUS "ASIC_SENSORS_POLLER_STATUS"
@@ -28,6 +29,10 @@ class SwitchOrch : public Orch
2829
void restartCheckReply(const std::string &op, const std::string &data, std::vector<swss::FieldValueTuple> &values);
2930
bool setAgingFDB(uint32_t sec);
3031
void set_switch_capability(const std::vector<swss::FieldValueTuple>& values);
32+
33+
// Return reference to ACL group created for each stage and the bind point is
34+
// the switch
35+
const std::map<sai_acl_stage_t, sai_object_id_t>& getAclGroupOidsBindingToSwitch();
3136
private:
3237
void doTask(Consumer &consumer);
3338
void doTask(swss::SelectableTimer &timer);
@@ -37,10 +42,34 @@ class SwitchOrch : public Orch
3742
void querySwitchTpidCapability();
3843
sai_status_t setSwitchTunnelVxlanParams(swss::FieldValueTuple &val);
3944

45+
// Initialize the ACL groups bind to Switch
46+
void initAclGroupsBindToSwitch();
47+
// Create the default ACL group for the given stage, bind point is
48+
// SAI_ACL_BIND_POINT_TYPE_SWITCH and group type is
49+
// SAI_ACL_TABLE_GROUP_TYPE_PARALLEL.
50+
ReturnCode createAclGroup(const sai_acl_stage_t& group_stage,
51+
sai_object_id_t* acl_grp_oid);
52+
53+
// Bind the ACL group to switch for the given stage.
54+
// Set the SAI_SWITCH_ATTR_{STAGE}_ACL with the group oid.
55+
ReturnCode bindAclGroupToSwitch(const sai_acl_stage_t& group_stage,
56+
const sai_object_id_t& acl_grp_oid);
57+
58+
// Unbind the ACL group to switch for the given stage.
59+
// Set the SAI_SWITCH_ATTR_{STAGE}_ACL to SAI_NULL_OBJECT_ID
60+
ReturnCode unbindAclGroupToSwitch(const sai_acl_stage_t& group_stage);
61+
62+
// Remove the ACL group on given stage if reference count is zero.
63+
ReturnCode removeAclGroup(const sai_acl_stage_t& group_stage);
64+
65+
// Remove all ACL groups on all stages.
66+
ReturnCode removeAllAclGroups();
67+
4068
swss::NotificationConsumer* m_restartCheckNotificationConsumer;
4169
void doTask(swss::NotificationConsumer& consumer);
4270
swss::DBConnector *m_db;
4371
swss::Table m_switchTable;
72+
std::map<sai_acl_stage_t, sai_object_id_t> m_aclGroups;
4473
sai_object_id_t m_switchTunnelId;
4574

4675
// ASIC temperature sensors

0 commit comments

Comments
 (0)