From 452cbc12fb8d90350248715685b9c297559bcac3 Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Mon, 18 Oct 2021 22:51:24 +0800 Subject: [PATCH] [macsecorch]: Add IPG adjusting for MACsec gearbox model (#1925) * Add IPGadjusting for MACsec gearbox model Signed-off-by: Ze Gan * fix bug Signed-off-by: Ze Gan * fix bug Signed-off-by: Ze Gan * Polish variable name and comment Signed-off-by: Ze Gan * Set IPG to optional Signed-off-by: Ze Gan * refactor code Signed-off-by: Ze Gan --- lib/gearboxutils.cpp | 4 ++ lib/gearboxutils.h | 1 + orchagent/macsecorch.cpp | 121 ++++++++++++++++++++++++++++----------- orchagent/macsecorch.h | 13 +++-- orchagent/portsorch.cpp | 59 +++++++++++++++++++ orchagent/portsorch.h | 5 ++ 6 files changed, 166 insertions(+), 37 deletions(-) diff --git a/lib/gearboxutils.cpp b/lib/gearboxutils.cpp index 30c89ab494ce..f9b32286213a 100644 --- a/lib/gearboxutils.cpp +++ b/lib/gearboxutils.cpp @@ -189,6 +189,10 @@ std::map GearboxUtils::loadPhyMap(Table *gearboxTable) { phy.context_id = std::stoi(val.second); } + else if (val.first == "macsec_ipg") + { + phy.macsec_ipg = std::stoi(val.second); + } } gearboxPhyMap[phy.phy_id] = phy; } diff --git a/lib/gearboxutils.h b/lib/gearboxutils.h index b28b7b1080ab..28ab48761e66 100644 --- a/lib/gearboxutils.h +++ b/lib/gearboxutils.h @@ -45,6 +45,7 @@ typedef struct uint32_t address; uint32_t bus_id; uint32_t context_id; + uint32_t macsec_ipg; } gearbox_phy_t; typedef struct diff --git a/orchagent/macsecorch.cpp b/orchagent/macsecorch.cpp index 337c8cbbdf2c..f3c085047cdb 100644 --- a/orchagent/macsecorch.cpp +++ b/orchagent/macsecorch.cpp @@ -382,24 +382,27 @@ class MACsecOrchContext return m_macsec_sa; } -private: - MACsecOrchContext(MACsecOrch *orch) : m_orch(orch), - m_port_name(nullptr), - m_direction(SAI_MACSEC_DIRECTION_EGRESS), - m_sci(nullptr), - m_an(nullptr), - m_port(nullptr), - m_macsec_obj(nullptr), - m_port_id(nullptr), - m_switch_id(nullptr), - m_macsec_port(nullptr), - m_acl_table(nullptr), - m_macsec_sc(nullptr), - m_macsec_sa(nullptr) + const gearbox_phy_t* get_gearbox_phy() { + if (m_gearbox_phy) + { + return m_gearbox_phy; + } + auto switch_id = get_switch_id(); + if (switch_id == nullptr || get_port() == nullptr) + { + SWSS_LOG_ERROR("Switch/Port wasn't provided"); + return nullptr; + } + if (*switch_id == gSwitchId) + { + return nullptr; + } + m_gearbox_phy = m_orch->m_port_orch->getGearboxPhy(*get_port()); + return m_gearbox_phy; } - const Port *get_port() + Port *get_port() { if (m_port == nullptr) { @@ -424,6 +427,24 @@ class MACsecOrchContext return m_port.get(); } +private: + MACsecOrchContext(MACsecOrch *orch) : m_orch(orch), + m_port_name(nullptr), + m_direction(SAI_MACSEC_DIRECTION_EGRESS), + m_sci(nullptr), + m_an(nullptr), + m_port(nullptr), + m_macsec_obj(nullptr), + m_port_id(nullptr), + m_switch_id(nullptr), + m_macsec_port(nullptr), + m_acl_table(nullptr), + m_macsec_sc(nullptr), + m_macsec_sa(nullptr), + m_gearbox_phy(nullptr) + { + } + MACsecOrch *m_orch; std::shared_ptr m_port_name; sai_macsec_direction_t m_direction; @@ -440,6 +461,7 @@ class MACsecOrchContext MACsecOrch::MACsecSC *m_macsec_sc; sai_object_id_t *m_macsec_sa; + const gearbox_phy_t *m_gearbox_phy; }; /* MACsec Orchagent */ @@ -592,7 +614,9 @@ task_process_status MACsecOrch::taskUpdateMACsecPort( port_attr, *ctx.get_macsec_obj(), *ctx.get_port_id(), - *ctx.get_switch_id())) + *ctx.get_switch_id(), + *ctx.get_port(), + ctx.get_gearbox_phy())) { return task_failed; } @@ -602,7 +626,9 @@ task_process_status MACsecOrch::taskUpdateMACsecPort( *macsec_port_itr->second, port_name, *ctx.get_macsec_obj(), - *ctx.get_port_id()); + *ctx.get_port_id(), + *ctx.get_port(), + ctx.get_gearbox_phy()); }); } if (!updateMACsecPort(*ctx.get_macsec_port(), port_attr)) @@ -644,7 +670,9 @@ task_process_status MACsecOrch::taskDisableMACsecPort( *ctx.get_macsec_port(), port_name, *ctx.get_macsec_obj(), - *ctx.get_port_id())) + *ctx.get_port_id(), + *ctx.get_port(), + ctx.get_gearbox_phy())) { result = task_failed; } @@ -906,8 +934,10 @@ bool MACsecOrch::createMACsecPort( const std::string &port_name, const TaskArgs &port_attr, const MACsecObject &macsec_obj, - sai_object_id_t line_port_id, - sai_object_id_t switch_id) + sai_object_id_t port_id, + sai_object_id_t switch_id, + Port &port, + const gearbox_phy_t* phy) { SWSS_LOG_ENTER(); @@ -915,7 +945,7 @@ bool MACsecOrch::createMACsecPort( if (!createMACsecPort( macsec_port.m_egress_port_id, - line_port_id, + port_id, switch_id, SAI_MACSEC_DIRECTION_EGRESS)) { @@ -929,7 +959,7 @@ bool MACsecOrch::createMACsecPort( if (!createMACsecPort( macsec_port.m_ingress_port_id, - line_port_id, + port_id, switch_id, SAI_MACSEC_DIRECTION_INGRESS)) { @@ -982,7 +1012,7 @@ bool MACsecOrch::createMACsecPort( if (!initMACsecACLTable( macsec_port.m_egress_acl_table, - line_port_id, + port_id, switch_id, SAI_MACSEC_DIRECTION_EGRESS, macsec_port.m_sci_in_sectag)) @@ -990,16 +1020,16 @@ bool MACsecOrch::createMACsecPort( SWSS_LOG_WARN("Cannot init the ACL Table at the port %s.", port_name.c_str()); return false; } - recover.add_action([this, &macsec_port, line_port_id]() { + recover.add_action([this, &macsec_port, port_id]() { this->deinitMACsecACLTable( macsec_port.m_egress_acl_table, - line_port_id, + port_id, SAI_MACSEC_DIRECTION_EGRESS); }); if (!initMACsecACLTable( macsec_port.m_ingress_acl_table, - line_port_id, + port_id, switch_id, SAI_MACSEC_DIRECTION_INGRESS, macsec_port.m_sci_in_sectag)) @@ -1007,13 +1037,27 @@ bool MACsecOrch::createMACsecPort( SWSS_LOG_WARN("Cannot init the ACL Table at the port %s.", port_name.c_str()); return false; } - recover.add_action([this, &macsec_port, line_port_id]() { + recover.add_action([this, &macsec_port, port_id]() { this->deinitMACsecACLTable( macsec_port.m_ingress_acl_table, - line_port_id, + port_id, SAI_MACSEC_DIRECTION_INGRESS); }); + if (phy && phy->macsec_ipg != 0) + { + if (!m_port_orch->getPortIPG(port.m_port_id, macsec_port.m_original_ipg)) + { + SWSS_LOG_WARN("Cannot get Port IPG at the port %s", port_name.c_str()); + return false; + } + if (!m_port_orch->setPortIPG(port.m_port_id, phy->macsec_ipg)) + { + SWSS_LOG_WARN("Cannot set MACsec IPG to %u at the port %s", phy->macsec_ipg, port_name.c_str()); + return false; + } + } + SWSS_LOG_NOTICE("MACsec port %s is created.", port_name.c_str()); std::vector fvVector; @@ -1026,7 +1070,7 @@ bool MACsecOrch::createMACsecPort( bool MACsecOrch::createMACsecPort( sai_object_id_t &macsec_port_id, - sai_object_id_t line_port_id, + sai_object_id_t port_id, sai_object_id_t switch_id, sai_macsec_direction_t direction) { @@ -1039,7 +1083,7 @@ bool MACsecOrch::createMACsecPort( attr.value.s32 = direction; attrs.push_back(attr); attr.id = SAI_MACSEC_PORT_ATTR_PORT_ID; - attr.value.oid = line_port_id; + attr.value.oid = port_id; attrs.push_back(attr); sai_status_t status = sai_macsec_api->create_macsec_port( &macsec_port_id, @@ -1141,7 +1185,9 @@ bool MACsecOrch::deleteMACsecPort( const MACsecPort &macsec_port, const std::string &port_name, const MACsecObject &macsec_obj, - sai_object_id_t line_port_id) + sai_object_id_t port_id, + Port &port, + const gearbox_phy_t* phy) { SWSS_LOG_ENTER(); @@ -1179,13 +1225,13 @@ bool MACsecOrch::deleteMACsecPort( } } - if (!deinitMACsecACLTable(macsec_port.m_ingress_acl_table, line_port_id, SAI_MACSEC_DIRECTION_INGRESS)) + if (!deinitMACsecACLTable(macsec_port.m_ingress_acl_table, port_id, SAI_MACSEC_DIRECTION_INGRESS)) { SWSS_LOG_WARN("Cannot deinit ingress ACL table at the port %s.", port_name.c_str()); result &= false; } - if (!deinitMACsecACLTable(macsec_port.m_egress_acl_table, line_port_id, SAI_MACSEC_DIRECTION_EGRESS)) + if (!deinitMACsecACLTable(macsec_port.m_egress_acl_table, port_id, SAI_MACSEC_DIRECTION_EGRESS)) { SWSS_LOG_WARN("Cannot deinit egress ACL table at the port %s.", port_name.c_str()); result &= false; @@ -1203,6 +1249,15 @@ bool MACsecOrch::deleteMACsecPort( result &= false; } + if (phy && phy->macsec_ipg != 0) + { + if (!m_port_orch->setPortIPG(port.m_port_id, macsec_port.m_original_ipg)) + { + SWSS_LOG_WARN("Cannot set MACsec IPG to %u at the port %s", macsec_port.m_original_ipg, port_name.c_str()); + result &= false; + } + } + m_state_macsec_port.del(port_name); return true; diff --git a/orchagent/macsecorch.h b/orchagent/macsecorch.h index 8e6b9e86754d..20c3f82c242b 100644 --- a/orchagent/macsecorch.h +++ b/orchagent/macsecorch.h @@ -94,6 +94,7 @@ class MACsecOrch : public Orch bool m_enable_encrypt; bool m_sci_in_sectag; bool m_enable; + uint32_t m_original_ipg; }; struct MACsecObject { @@ -115,11 +116,13 @@ class MACsecOrch : public Orch const std::string &port_name, const TaskArgs & port_attr, const MACsecObject &macsec_obj, - sai_object_id_t line_port_id, - sai_object_id_t switch_id); + sai_object_id_t port_id, + sai_object_id_t switch_id, + Port &port, + const gearbox_phy_t* phy); bool createMACsecPort( sai_object_id_t &macsec_port_id, - sai_object_id_t line_port_id, + sai_object_id_t port_id, sai_object_id_t switch_id, sai_macsec_direction_t direction); bool updateMACsecPort(MACsecPort &macsec_port, const TaskArgs & port_attr); @@ -127,7 +130,9 @@ class MACsecOrch : public Orch const MACsecPort &macsec_port, const std::string &port_name, const MACsecObject &macsec_obj, - sai_object_id_t line_port_id); + sai_object_id_t port_id, + Port &port, + const gearbox_phy_t* phy); bool deleteMACsecPort(sai_object_id_t macsec_port_id); /* MACsec Flow */ diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index a8bcef67c730..2f5343782cdb 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -5991,6 +5991,65 @@ bool PortsOrch::initGearboxPort(Port &port) return true; } +const gearbox_phy_t* PortsOrch::getGearboxPhy(const Port &port) +{ + auto gearbox_interface = m_gearboxInterfaceMap.find(port.m_index); + if (gearbox_interface == m_gearboxInterfaceMap.end()) + { + return nullptr; + } + + auto phy = m_gearboxPhyMap.find(gearbox_interface->second.phy_id); + if (phy == m_gearboxPhyMap.end()) + { + SWSS_LOG_ERROR("Gearbox Phy %d dones't exist", gearbox_interface->second.phy_id); + return nullptr; + } + + return &phy->second; +} + +bool PortsOrch::getPortIPG(sai_object_id_t port_id, uint32_t &ipg) +{ + sai_attribute_t attr; + attr.id = SAI_PORT_ATTR_IPG; + + sai_status_t status = sai_port_api->get_port_attribute(port_id, 1, &attr); + + if (status != SAI_STATUS_SUCCESS) + { + task_process_status handle_status = handleSaiGetStatus(SAI_API_PORT, status); + if (handle_status != task_success) + { + return parseHandleSaiStatusFailure(handle_status); + } + } + + ipg = attr.value.u32; + + return true; +} + +bool PortsOrch::setPortIPG(sai_object_id_t port_id, uint32_t ipg) +{ + sai_attribute_t attr; + attr.id = SAI_PORT_ATTR_IPG; + attr.value.u32 = ipg; + + sai_status_t status = sai_port_api->set_port_attribute(port_id, &attr); + + if (status != SAI_STATUS_SUCCESS) + { + task_process_status handle_status = handleSaiSetStatus(SAI_API_PORT, status); + if (handle_status != task_success) + { + return parseHandleSaiStatusFailure(handle_status); + } + } + + return true; +} + bool PortsOrch::getSystemPorts() { sai_status_t status; diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index 9ae26242ce6c..ce950330d6e9 100755 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -152,6 +152,11 @@ class PortsOrch : public Orch, public Subject bool getRecircPort(Port &p, string role); + const gearbox_phy_t* getGearboxPhy(const Port &port); + + bool getPortIPG(sai_object_id_t port_id, uint32_t &ipg); + bool setPortIPG(sai_object_id_t port_id, uint32_t ipg); + private: unique_ptr m_counterTable; unique_ptr
m_counterLagTable;