Skip to content

[macsecorch]: Add IPG adjusting for MACsec gearbox model #1925

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/gearboxutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ std::map<int, gearbox_phy_t> 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;
}
Expand Down
1 change: 1 addition & 0 deletions lib/gearboxutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
121 changes: 88 additions & 33 deletions orchagent/macsecorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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<std::string> m_port_name;
sai_macsec_direction_t m_direction;
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}
Expand All @@ -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))
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -906,16 +934,18 @@ 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();

RecoverStack recover;

if (!createMACsecPort(
macsec_port.m_egress_port_id,
line_port_id,
port_id,
switch_id,
SAI_MACSEC_DIRECTION_EGRESS))
{
Expand All @@ -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))
{
Expand Down Expand Up @@ -982,38 +1012,52 @@ 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))
{
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))
{
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<FieldValueTuple> fvVector;
Expand All @@ -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)
{
Expand All @@ -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,
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
13 changes: 9 additions & 4 deletions orchagent/macsecorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -115,19 +116,23 @@ 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);
bool 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);
bool deleteMACsecPort(sai_object_id_t macsec_port_id);

/* MACsec Flow */
Expand Down
59 changes: 59 additions & 0 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Table> m_counterTable;
unique_ptr<Table> m_counterLagTable;
Expand Down