diff --git a/orchagent/macsecorch.cpp b/orchagent/macsecorch.cpp index a82882ed2496..5a45f51d4109 100644 --- a/orchagent/macsecorch.cpp +++ b/orchagent/macsecorch.cpp @@ -13,6 +13,7 @@ #include #include #include +#include /* Global Variables*/ @@ -821,7 +822,30 @@ task_process_status MACsecOrch::taskUpdateEgressSA( } if (ctx.get_macsec_sc()->m_encoding_an == an) { - return createMACsecSA(port_sci_an, sa_attr, SAI_MACSEC_DIRECTION_EGRESS); + if (ctx.get_macsec_sa() == nullptr) + { + // The MACsec SA hasn't been created + return createMACsecSA(port_sci_an, sa_attr, SAI_MACSEC_DIRECTION_EGRESS); + } + else + { + // The MACsec SA has enabled, update SA's attributes + sai_uint64_t pn; + + if (get_value(sa_attr, "next_pn", pn)) + { + sai_attribute_t attr; + attr.id = SAI_MACSEC_SA_ATTR_CONFIGURED_EGRESS_XPN; + attr.value.u64 = pn; + if (!this->updateMACsecAttr(SAI_OBJECT_TYPE_MACSEC_SA, *(ctx.get_macsec_sa()), attr)) + { + SWSS_LOG_WARN("Fail to update next pn (%" PRIu64 ") of egress MACsec SA %s", pn, port_sci_an.c_str()); + return task_failed; + } + } + + return task_success; + } } return task_need_retry; } @@ -841,7 +865,7 @@ task_process_status MACsecOrch::taskUpdateIngressSA( SWSS_LOG_ENTER(); swss::AlphaBoolean alpha_boolean = false; - get_value(sa_attr, "active", alpha_boolean); + bool has_active_field = get_value(sa_attr, "active", alpha_boolean); bool active = alpha_boolean.operator bool(); if (active) { @@ -863,7 +887,29 @@ task_process_status MACsecOrch::taskUpdateIngressSA( if (ctx.get_macsec_sa() != nullptr) { - return deleteMACsecSA(port_sci_an, SAI_MACSEC_DIRECTION_INGRESS); + if (has_active_field) + { + // Delete MACsec SA explicitly by set active to false + return deleteMACsecSA(port_sci_an, SAI_MACSEC_DIRECTION_INGRESS); + } + else + { + sai_uint64_t pn; + + if (get_value(sa_attr, "lowest_acceptable_pn", pn)) + { + sai_attribute_t attr; + attr.id = SAI_MACSEC_SA_ATTR_MINIMUM_INGRESS_XPN; + attr.value.u64 = pn; + if (!this->updateMACsecAttr(SAI_OBJECT_TYPE_MACSEC_SA, *(ctx.get_macsec_sa()), attr)) + { + SWSS_LOG_WARN("Fail to update lowest acceptable PN (%" PRIu64 ") of ingress MACsec SA %s", pn, port_sci_an.c_str()); + return task_failed; + } + } + + return task_success; + } } else { @@ -874,6 +920,8 @@ task_process_status MACsecOrch::taskUpdateIngressSA( return task_need_retry; } } + + return task_success; } task_process_status MACsecOrch::taskDeleteIngressSA( diff --git a/tests/test_macsec.py b/tests/test_macsec.py index f74f31c00876..4c9e22c05fe1 100644 --- a/tests/test_macsec.py +++ b/tests/test_macsec.py @@ -321,6 +321,13 @@ def delete_transmit_sa(self, sai: str): del self.app_transmit_sa_table[sai] self.state_transmit_sa_table.wait_delete(sai) + @macsec_sa() + def set_macsec_pn( + self, + sai: str, + pn: int): + self.app_transmit_sa_table[sai] = {"next_pn": pn} + @macsec_sc() def set_enable_transmit_sa(self, sci: str, an: int, enable: bool): if enable: @@ -475,6 +482,12 @@ def rekey_macsec( auth_key: str, ssci: int, salt: str): + wpa.set_macsec_pn( + port_name, + local_mac_address, + macsec_port_identifier, + an, + 0x00000000C0000000) wpa.create_receive_sa( port_name, peer_mac_address,