Skip to content

Commit

Permalink
Orchagent: Integrate P4Orch
Browse files Browse the repository at this point in the history
    * 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]
  • Loading branch information
PINS Working Group authored and ntoorchi committed Nov 13, 2021
1 parent cdea5e9 commit 7ef8440
Show file tree
Hide file tree
Showing 15 changed files with 278 additions and 21 deletions.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ AC_CONFIG_FILES([
swssconfig/Makefile
cfgmgr/Makefile
tests/Makefile
orchagent/p4orch/tests/Makefile
])

# If no SAI library is installed, compile with SAIVS and run unit tests
Expand Down
12 changes: 12 additions & 0 deletions orchagent/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ orchagent_SOURCES = \

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
orchagent_SOURCES += p4orch/p4orch.cpp \
p4orch/p4orch_util.cpp \
p4orch/p4oidmapper.cpp \
p4orch/router_interface_manager.cpp \
p4orch/neighbor_manager.cpp \
p4orch/next_hop_manager.cpp \
p4orch/route_manager.cpp \
p4orch/acl_util.cpp \
p4orch/acl_table_manager.cpp \
p4orch/acl_rule_manager.cpp \
p4orch/wcmp_manager.cpp \
p4orch/mirror_session_manager.cpp

orchagent_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
orchagent_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
Expand Down
29 changes: 28 additions & 1 deletion orchagent/acltable.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ extern "C" {

#define STAGE_INGRESS "INGRESS"
#define STAGE_EGRESS "EGRESS"
#define STAGE_PRE_INGRESS "PRE_INGRESS"

#define TABLE_TYPE_L3 "L3"
#define TABLE_TYPE_L3V6 "L3V6"
Expand All @@ -35,7 +36,8 @@ typedef enum
{
ACL_STAGE_UNKNOWN,
ACL_STAGE_INGRESS,
ACL_STAGE_EGRESS
ACL_STAGE_EGRESS,
ACL_STAGE_PRE_INGRESS
} acl_stage_type_t;

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

typedef std::unordered_map<std::string, acl_table_type_t> acl_table_type_lookup_t;
typedef std::map<std::string, sai_acl_stage_t> acl_stage_lookup_t;
typedef std::map<sai_acl_stage_t, sai_switch_attr_t> acl_stage_to_switch_attr_lookup_t;

struct AclTableGroupMember {
sai_object_id_t m_group_oid;
sai_object_id_t m_group_member_oid;
uint32_t m_priority;
AclTableGroupMember()
: m_group_oid(SAI_NULL_OBJECT_ID)
, m_group_member_oid(SAI_NULL_OBJECT_ID)
, m_priority(0)
{}
};

static const acl_stage_lookup_t aclStageLookup = {
{STAGE_INGRESS, SAI_ACL_STAGE_INGRESS},
{STAGE_EGRESS, SAI_ACL_STAGE_EGRESS},
{STAGE_PRE_INGRESS, SAI_ACL_STAGE_PRE_INGRESS},
};

static const acl_stage_to_switch_attr_lookup_t aclStageToSwitchAttrLookup = {
{SAI_ACL_STAGE_INGRESS, SAI_SWITCH_ATTR_INGRESS_ACL},
{SAI_ACL_STAGE_EGRESS, SAI_SWITCH_ATTR_EGRESS_ACL},
{SAI_ACL_STAGE_PRE_INGRESS, SAI_SWITCH_ATTR_PRE_INGRESS_ACL},
};
9 changes: 8 additions & 1 deletion orchagent/orchdaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ NatOrch *gNatOrch;
MlagOrch *gMlagOrch;
IsoGrpOrch *gIsoGrpOrch;
MACsecOrch *gMacsecOrch;
P4Orch *gP4Orch;
BfdOrch *gBfdOrch;
Srv6Orch *gSrv6Orch;

Expand Down Expand Up @@ -87,6 +88,9 @@ bool OrchDaemon::init()
SWSS_LOG_ENTER();

string platform = getenv("platform") ? getenv("platform") : "";

gCrmOrch = new CrmOrch(m_configDb, CFG_CRM_TABLE_NAME);

TableConnector stateDbSwitchTable(m_stateDb, "SWITCH_CAPABILITY");
TableConnector app_switch_table(m_applDb, APP_SWITCH_TABLE_NAME);
TableConnector conf_asic_sensors(m_configDb, CFG_ASIC_SENSORS_TABLE_NAME);
Expand Down Expand Up @@ -114,7 +118,6 @@ bool OrchDaemon::init()
{ APP_MCLAG_FDB_TABLE_NAME, FdbOrch::fdborch_pri}
};

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

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

vector<string> p4rt_tables = {APP_P4RT_TABLE_NAME};
gP4Orch = new P4Orch(m_applDb, p4rt_tables, vrf_orch, copp_orch);
m_orchList.push_back(gP4Orch);

if (WarmStart::isWarmStart())
{
bool suc = warmRestoreAndSyncUp();
Expand Down
1 change: 1 addition & 0 deletions orchagent/orchdaemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "mlagorch.h"
#include "muxorch.h"
#include "macsecorch.h"
#include "p4orch/p4orch.h"
#include "bfdorch.h"
#include "srv6orch.h"

Expand Down
4 changes: 2 additions & 2 deletions orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ class PortsOrch : public Orch, public Subject
bool getPortIPG(sai_object_id_t port_id, uint32_t &ipg);
bool setPortIPG(sai_object_id_t port_id, uint32_t ipg);

bool getPortOperStatus(const Port& port, sai_port_oper_status_t& status) const;

private:
unique_ptr<Table> m_counterTable;
unique_ptr<Table> m_counterLagTable;
Expand Down Expand Up @@ -315,7 +317,6 @@ class PortsOrch : public Orch, public Subject
task_process_status setPortInterfaceType(sai_object_id_t id, sai_port_interface_type_t interface_type);
task_process_status setPortAdvInterfaceTypes(sai_object_id_t id, std::vector<uint32_t> &interface_types);

bool getPortOperStatus(const Port& port, sai_port_oper_status_t& status) const;
void updatePortOperStatus(Port &port, sai_port_oper_status_t status);

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

};
#endif /* SWSS_PORTSORCH_H */

3 changes: 3 additions & 0 deletions orchagent/saihelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ sai_qos_map_api_t* sai_qos_map_api;
sai_buffer_api_t* sai_buffer_api;
sai_acl_api_t* sai_acl_api;
sai_hash_api_t* sai_hash_api;
sai_udf_api_t* sai_udf_api;
sai_mirror_api_t* sai_mirror_api;
sai_fdb_api_t* sai_fdb_api;
sai_dtel_api_t* sai_dtel_api;
Expand Down Expand Up @@ -185,6 +186,7 @@ void initSaiApi()
sai_api_query(SAI_API_SCHEDULER_GROUP, (void **)&sai_scheduler_group_api);
sai_api_query(SAI_API_ACL, (void **)&sai_acl_api);
sai_api_query(SAI_API_HASH, (void **)&sai_hash_api);
sai_api_query(SAI_API_UDF, (void **)&sai_udf_api);
sai_api_query(SAI_API_DTEL, (void **)&sai_dtel_api);
sai_api_query(SAI_API_SAMPLEPACKET, (void **)&sai_samplepacket_api);
sai_api_query(SAI_API_DEBUG_COUNTER, (void **)&sai_debug_counter_api);
Expand Down Expand Up @@ -221,6 +223,7 @@ void initSaiApi()
sai_log_set(SAI_API_SCHEDULER_GROUP, SAI_LOG_LEVEL_NOTICE);
sai_log_set(SAI_API_ACL, SAI_LOG_LEVEL_NOTICE);
sai_log_set(SAI_API_HASH, SAI_LOG_LEVEL_NOTICE);
sai_log_set(SAI_API_UDF, SAI_LOG_LEVEL_NOTICE);
sai_log_set(SAI_API_DTEL, SAI_LOG_LEVEL_NOTICE);
sai_log_set(SAI_API_SAMPLEPACKET, SAI_LOG_LEVEL_NOTICE);
sai_log_set(SAI_API_DEBUG_COUNTER, SAI_LOG_LEVEL_NOTICE);
Expand Down
155 changes: 155 additions & 0 deletions orchagent/switchorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
#include <inttypes.h>

#include "switchorch.h"
#include "crmorch.h"
#include "converter.h"
#include "notifier.h"
#include "notificationproducer.h"
#include "macaddress.h"
#include "return_code.h"

using namespace std;
using namespace swss;

extern sai_object_id_t gSwitchId;
extern sai_switch_api_t *sai_switch_api;
extern sai_acl_api_t* sai_acl_api;
extern MacAddress gVxlanMacAddress;
extern CrmOrch *gCrmOrch;

const map<string, sai_switch_attr_t> switch_attribute_map =
{
Expand Down Expand Up @@ -55,6 +59,157 @@ SwitchOrch::SwitchOrch(DBConnector *db, vector<TableConnector>& connectors, Tabl
querySwitchTpidCapability();
auto executorT = new ExecutableTimer(m_sensorsPollerTimer, this, "ASIC_SENSORS_POLL_TIMER");
Orch::addExecutor(executorT);
initAclGroupsBindToSwitch();
}

void SwitchOrch::initAclGroupsBindToSwitch()
{
// Create an ACL group per stage, INGRESS, EGRESS and PRE_INGRESS
for (auto stage_it : aclStageLookup) {
sai_object_id_t group_oid;
auto status = createAclGroup(fvValue(stage_it), &group_oid);
if (!status.ok())
{
status.prepend("Failed to create ACL group for stage " +
fvField(stage_it) + ": ");
SWSS_LOG_THROW("%s", status.message().c_str());
}
SWSS_LOG_NOTICE("Created ACL group for stage %s",
fvField(stage_it).c_str());
m_aclGroups[fvValue(stage_it)] = group_oid;
status = bindAclGroupToSwitch(fvValue(stage_it), group_oid);
if (!status.ok())
{
status.prepend("Failed to bind ACL group to stage " +
fvField(stage_it) + ": ");
SWSS_LOG_THROW("%s", status.message().c_str());
}
}
}

const std::map<sai_acl_stage_t, sai_object_id_t>&
SwitchOrch::getAclGroupOidsBindingToSwitch()
{
return m_aclGroups;
}

ReturnCode SwitchOrch::createAclGroup(const sai_acl_stage_t& group_stage,
sai_object_id_t* acl_grp_oid)
{
SWSS_LOG_ENTER();

std::vector<sai_attribute_t> acl_grp_attrs;
sai_attribute_t acl_grp_attr;
acl_grp_attr.id = SAI_ACL_TABLE_GROUP_ATTR_ACL_STAGE;
acl_grp_attr.value.s32 = group_stage;
acl_grp_attrs.push_back(acl_grp_attr);

acl_grp_attr.id = SAI_ACL_TABLE_GROUP_ATTR_TYPE;
acl_grp_attr.value.s32 = SAI_ACL_TABLE_GROUP_TYPE_PARALLEL;
acl_grp_attrs.push_back(acl_grp_attr);

acl_grp_attr.id = SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST;
std::vector<int32_t> bpoint_list;
bpoint_list.push_back(SAI_ACL_BIND_POINT_TYPE_SWITCH);
acl_grp_attr.value.s32list.count = (uint32_t)bpoint_list.size();
acl_grp_attr.value.s32list.list = bpoint_list.data();
acl_grp_attrs.push_back(acl_grp_attr);

CHECK_ERROR_AND_LOG_AND_RETURN(
sai_acl_api->create_acl_table_group(acl_grp_oid, gSwitchId,
(uint32_t)acl_grp_attrs.size(),
acl_grp_attrs.data()),
"Failed to create ACL group for stage " << group_stage);
if (group_stage == SAI_ACL_STAGE_INGRESS ||
group_stage == SAI_ACL_STAGE_PRE_INGRESS ||
group_stage == SAI_ACL_STAGE_EGRESS)
{
gCrmOrch->incCrmAclUsedCounter(CrmResourceType::CRM_ACL_GROUP,
(sai_acl_stage_t)group_stage,
SAI_ACL_BIND_POINT_TYPE_SWITCH);
}
SWSS_LOG_INFO("Suceeded to create ACL group %s in stage %d ",
sai_serialize_object_id(*acl_grp_oid).c_str(), group_stage);
return ReturnCode();
}

ReturnCode SwitchOrch::bindAclGroupToSwitch(
const sai_acl_stage_t& group_stage, const sai_object_id_t& acl_grp_oid)
{
SWSS_LOG_ENTER();

auto switch_attr_it = aclStageToSwitchAttrLookup.find(group_stage);
if (switch_attr_it == aclStageToSwitchAttrLookup.end())
{
LOG_ERROR_AND_RETURN(ReturnCode(StatusCode::SWSS_RC_INVALID_PARAM)
<< "Failed to set ACL group(" << acl_grp_oid
<< ") to the SWITCH bind point at stage "
<< group_stage);
}
sai_attribute_t attr;
attr.id = switch_attr_it->second;
attr.value.oid = acl_grp_oid;
auto sai_status = sai_switch_api->set_switch_attribute(gSwitchId, &attr);
if (sai_status != SAI_STATUS_SUCCESS)
{
LOG_ERROR_AND_RETURN(
ReturnCode(sai_status)
<< "[SAI] Failed to set_switch_attribute with attribute.id=" << attr.id
<< " and acl group oid=" << acl_grp_oid);
}
return ReturnCode();
}

ReturnCode SwitchOrch::unbindAclGroupToSwitch(
const sai_acl_stage_t& group_stage)
{
SWSS_LOG_ENTER();

return bindAclGroupToSwitch(group_stage, SAI_NULL_OBJECT_ID);
}

ReturnCode SwitchOrch::removeAclGroup(const sai_acl_stage_t& group_stage)
{
SWSS_LOG_ENTER();

auto group_it = m_aclGroups.find(group_stage);
if (group_it == m_aclGroups.end())
{
LOG_ERROR_AND_RETURN(
ReturnCode(SAI_STATUS_INVALID_PARAMETER)
<< "Failed to find ACL group by stage '" << group_stage << "'");
}
CHECK_ERROR_AND_LOG_AND_RETURN(
sai_acl_api->remove_acl_table_group(group_it->second),
"Failed to create ACL group for stage " << group_stage);
if (group_stage == SAI_ACL_STAGE_INGRESS ||
group_stage == SAI_ACL_STAGE_PRE_INGRESS ||
group_stage == SAI_ACL_STAGE_EGRESS)
{
gCrmOrch->decCrmAclUsedCounter(CrmResourceType::CRM_ACL_GROUP,
(sai_acl_stage_t)group_stage,
SAI_ACL_BIND_POINT_TYPE_SWITCH,
group_it->second);
}
m_aclGroups.erase(group_stage);
SWSS_LOG_NOTICE("Suceeded to remove ACL group %s in stage %d ",
sai_serialize_object_id(group_it->second).c_str(), group_stage);
return ReturnCode();
}

ReturnCode SwitchOrch::removeAllAclGroups()
{
SWSS_LOG_ENTER();

for (auto stage_it : aclStageLookup)
{
if (m_aclGroups.find(fvValue(stage_it)) != m_aclGroups.end())
{
LOG_AND_RETURN_IF_ERROR(unbindAclGroupToSwitch(fvValue(stage_it)));
LOG_AND_RETURN_IF_ERROR(removeAclGroup(fvValue(stage_it)));
}
}
return ReturnCode();
}

void SwitchOrch::doCfgSensorsTableTask(Consumer &consumer)
Expand Down
29 changes: 29 additions & 0 deletions orchagent/switchorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "orch.h"
#include "timer.h"
#include "acltable.h"

#define DEFAULT_ASIC_SENSORS_POLLER_INTERVAL 60
#define ASIC_SENSORS_POLLER_STATUS "ASIC_SENSORS_POLLER_STATUS"
Expand All @@ -28,6 +29,10 @@ class SwitchOrch : public Orch
void restartCheckReply(const std::string &op, const std::string &data, std::vector<swss::FieldValueTuple> &values);
bool setAgingFDB(uint32_t sec);
void set_switch_capability(const std::vector<swss::FieldValueTuple>& values);

// Return reference to ACL group created for each stage and the bind point is
// the switch
const std::map<sai_acl_stage_t, sai_object_id_t>& getAclGroupOidsBindingToSwitch();
private:
void doTask(Consumer &consumer);
void doTask(swss::SelectableTimer &timer);
Expand All @@ -37,10 +42,34 @@ class SwitchOrch : public Orch
void querySwitchTpidCapability();
sai_status_t setSwitchTunnelVxlanParams(swss::FieldValueTuple &val);

// Initialize the ACL groups bind to Switch
void initAclGroupsBindToSwitch();
// Create the default ACL group for the given stage, bind point is
// SAI_ACL_BIND_POINT_TYPE_SWITCH and group type is
// SAI_ACL_TABLE_GROUP_TYPE_PARALLEL.
ReturnCode createAclGroup(const sai_acl_stage_t& group_stage,
sai_object_id_t* acl_grp_oid);

// Bind the ACL group to switch for the given stage.
// Set the SAI_SWITCH_ATTR_{STAGE}_ACL with the group oid.
ReturnCode bindAclGroupToSwitch(const sai_acl_stage_t& group_stage,
const sai_object_id_t& acl_grp_oid);

// Unbind the ACL group to switch for the given stage.
// Set the SAI_SWITCH_ATTR_{STAGE}_ACL to SAI_NULL_OBJECT_ID
ReturnCode unbindAclGroupToSwitch(const sai_acl_stage_t& group_stage);

// Remove the ACL group on given stage if reference count is zero.
ReturnCode removeAclGroup(const sai_acl_stage_t& group_stage);

// Remove all ACL groups on all stages.
ReturnCode removeAllAclGroups();

swss::NotificationConsumer* m_restartCheckNotificationConsumer;
void doTask(swss::NotificationConsumer& consumer);
swss::DBConnector *m_db;
swss::Table m_switchTable;
std::map<sai_acl_stage_t, sai_object_id_t> m_aclGroups;
sai_object_id_t m_switchTunnelId;

// ASIC temperature sensors
Expand Down
Loading

0 comments on commit 7ef8440

Please sign in to comment.