Skip to content

Commit 85a0615

Browse files
authored
[ssw][ha] set SAI_ENI_ATTR_IS_HA_FLOW_OWNER & SAI_ENI_ATTR_HA_SCOPE_ID when creating eni (sonic-net#3881)
What I did Before ENI is programmed, supposedly HA is programmed already. Based on the ha scope, we will configure SAI_ENI_ATTR_IS_HA_FLOW_OWNER & SAI_ENI_ATTR_HA_SCOPE_ID.
1 parent bc40a04 commit 85a0615

5 files changed

Lines changed: 104 additions & 10 deletions

File tree

orchagent/dash/dashhaorch.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ DashHaOrch::DashHaOrch(DBConnector *db, const vector<string> &tables, DashOrch *
8686

8787
register_ha_set_notifier();
8888
register_ha_scope_notifier();
89+
90+
// Register this DashHaOrch instance with DashOrch
91+
m_dash_orch->setDashHaOrch(this);
8992
}
9093

9194
bool DashHaOrch::register_ha_set_notifier()
@@ -190,6 +193,21 @@ std::string DashHaOrch::getHaScopeObjectKey(const sai_object_id_t ha_scope_oid)
190193
return "";
191194
}
192195

196+
HaScopeEntry DashHaOrch::getHaScopeForEni(const std::string& eni)
197+
{
198+
SWSS_LOG_ENTER();
199+
200+
if (m_ha_scope_entries.empty())
201+
{
202+
HaScopeEntry emptyEntry;
203+
emptyEntry.ha_scope_id = SAI_NULL_OBJECT_ID;
204+
return emptyEntry;
205+
}
206+
207+
/* Return the first entry. This logic only applies to DPU Scope HA */
208+
return m_ha_scope_entries.begin()->second;
209+
}
210+
193211
bool DashHaOrch::addHaSetEntry(const std::string &key, const dash::ha_set::HaSet &entry)
194212
{
195213
SWSS_LOG_ENTER();

orchagent/dash/dashhaorch.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class DashHaOrch : public ZmqOrch
9898

9999
std::unique_ptr<swss::Table> dash_ha_set_result_table_;
100100
std::unique_ptr<swss::Table> dash_ha_scope_result_table_;
101-
101+
102102
std::unique_ptr<swss::DBConnector> m_dpuStateDbConnector;
103103
std::unique_ptr<swss::Table> m_dpuStateDbHaSetTable;
104104
std::unique_ptr<swss::Table> m_dpuStateDbHaScopeTable;
@@ -110,6 +110,7 @@ class DashHaOrch : public ZmqOrch
110110
const HaSetTable& getHaSetEntries() const { return m_ha_set_entries; };
111111
const HaScopeTable& getHaScopeEntries() const { return m_ha_scope_entries; };
112112
const DashBfdSessionTable& getBfdSessionPendingCreation() const { return m_bfd_session_pending_creation; };
113+
virtual HaScopeEntry getHaScopeForEni(const std::string& eni);
113114
};
114115

115116
#endif // DASHHAORCH_H

orchagent/dash/dashorch.cpp

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "converter.h"
1111
#include "dashorch.h"
12+
#include "dashhaorch.h"
1213
#include "macaddress.h"
1314
#include "orch.h"
1415
#include "sai.h"
@@ -91,6 +92,12 @@ DashOrch::DashOrch(DBConnector *db, vector<string> &tableName, DBConnector *app_
9192
}
9293
}
9394

95+
void DashOrch::setDashHaOrch(DashHaOrch *dash_ha_orch)
96+
{
97+
SWSS_LOG_ENTER();
98+
m_dash_ha_orch = dash_ha_orch;
99+
}
100+
94101
bool DashOrch::getRouteTypeActions(dash::route_type::RoutingType routing_type, dash::route_type::RouteType& route_type)
95102
{
96103
SWSS_LOG_ENTER();
@@ -554,14 +561,14 @@ bool DashOrch::addEniObject(const string& eni, EniEntry& entry)
554561
}
555562

556563
DashMeterOrch *dash_meter_orch = gDirectory.get<DashMeterOrch*>();
557-
const string &v4_meter_policy = entry.metadata.has_v4_meter_policy_id() ?
564+
const string &v4_meter_policy = entry.metadata.has_v4_meter_policy_id() ?
558565
entry.metadata.v4_meter_policy_id() : "";
559-
const string &v6_meter_policy = entry.metadata.has_v6_meter_policy_id() ?
566+
const string &v6_meter_policy = entry.metadata.has_v6_meter_policy_id() ?
560567
entry.metadata.v6_meter_policy_id() : "";
561568

562569
if (!v4_meter_policy.empty())
563570
{
564-
sai_object_id_t meter_policy_oid = dash_meter_orch->getMeterPolicyOid(v4_meter_policy);
571+
sai_object_id_t meter_policy_oid = dash_meter_orch->getMeterPolicyOid(v4_meter_policy);
565572
if (meter_policy_oid == SAI_NULL_OBJECT_ID)
566573
{
567574
SWSS_LOG_INFO("Retry as v4 meter_policy %s not found", v4_meter_policy.c_str());
@@ -570,7 +577,7 @@ bool DashOrch::addEniObject(const string& eni, EniEntry& entry)
570577
}
571578
if (!v6_meter_policy.empty())
572579
{
573-
sai_object_id_t meter_policy_oid = dash_meter_orch->getMeterPolicyOid(v6_meter_policy);
580+
sai_object_id_t meter_policy_oid = dash_meter_orch->getMeterPolicyOid(v6_meter_policy);
574581
if (meter_policy_oid == SAI_NULL_OBJECT_ID)
575582
{
576583
SWSS_LOG_INFO("Retry as v6 meter_policy %s not found", v6_meter_policy.c_str());
@@ -639,17 +646,54 @@ bool DashOrch::addEniObject(const string& eni, EniEntry& entry)
639646
if (!v4_meter_policy.empty())
640647
{
641648
eni_attr.id = SAI_ENI_ATTR_V4_METER_POLICY_ID;
642-
eni_attr.value.oid = dash_meter_orch->getMeterPolicyOid(v4_meter_policy);
649+
eni_attr.value.oid = dash_meter_orch->getMeterPolicyOid(v4_meter_policy);
643650
eni_attrs.push_back(eni_attr);
644651
}
645652

646653
if (!v6_meter_policy.empty())
647654
{
648655
eni_attr.id = SAI_ENI_ATTR_V6_METER_POLICY_ID;
649-
eni_attr.value.oid = dash_meter_orch->getMeterPolicyOid(v6_meter_policy);
656+
eni_attr.value.oid = dash_meter_orch->getMeterPolicyOid(v6_meter_policy);
650657
eni_attrs.push_back(eni_attr);
651658
}
652659

660+
// Set HA Scope ID if DashHaOrch is available and has HA scopes configured
661+
if (m_dash_ha_orch != nullptr)
662+
{
663+
HaScopeEntry ha_scope_entry = m_dash_ha_orch->getHaScopeForEni(eni);
664+
if (ha_scope_entry.ha_scope_id != SAI_NULL_OBJECT_ID)
665+
{
666+
eni_attr.id = SAI_ENI_ATTR_HA_SCOPE_ID;
667+
eni_attr.value.oid = ha_scope_entry.ha_scope_id;
668+
eni_attrs.push_back(eni_attr);
669+
SWSS_LOG_INFO("Setting HA Scope ID %" PRIx64 " for ENI %s", ha_scope_entry.ha_scope_id, eni.c_str());
670+
671+
// Set HA flow owner based on HA role
672+
eni_attr.id = SAI_ENI_ATTR_IS_HA_FLOW_OWNER;
673+
if (ha_scope_entry.metadata.ha_role() == dash::types::HA_ROLE_ACTIVE || ha_scope_entry.metadata.ha_role() == dash::types::HA_ROLE_STANDALONE)
674+
{
675+
eni_attr.value.booldata = true;
676+
SWSS_LOG_INFO("Setting HA flow owner to true (ACTIVE) for ENI %s", eni.c_str());
677+
}
678+
else if (ha_scope_entry.metadata.ha_role() == dash::types::HA_ROLE_STANDBY)
679+
{
680+
eni_attr.value.booldata = false;
681+
SWSS_LOG_INFO("Setting HA flow owner to false (STANDBY) for ENI %s", eni.c_str());
682+
}
683+
else
684+
{
685+
// For other roles (DEAD, SWITCHING_TO_ACTIVE), default to false
686+
eni_attr.value.booldata = false;
687+
SWSS_LOG_INFO("Setting HA flow owner to false (role: %s) for ENI %s", dash::types::HaRole_Name(ha_scope_entry.metadata.ha_role()).c_str(), eni.c_str());
688+
}
689+
eni_attrs.push_back(eni_attr);
690+
}
691+
else
692+
{
693+
SWSS_LOG_INFO("No HA Scope ID set for ENI %s", eni.c_str());
694+
}
695+
}
696+
653697
if (entry.metadata.has_eni_mode()) {
654698
auto it = eniModeMap.find(entry.metadata.eni_mode());
655699
eni_attr.id = SAI_ENI_ATTR_DASH_ENI_MODE;
@@ -838,9 +882,9 @@ bool DashOrch::removeEniObject(const string& eni)
838882
}
839883
}
840884

841-
const string &v4_meter_policy = entry.metadata.has_v4_meter_policy_id() ?
885+
const string &v4_meter_policy = entry.metadata.has_v4_meter_policy_id() ?
842886
entry.metadata.v4_meter_policy_id() : "";
843-
const string &v6_meter_policy = entry.metadata.has_v6_meter_policy_id() ?
887+
const string &v6_meter_policy = entry.metadata.has_v6_meter_policy_id() ?
844888
entry.metadata.v6_meter_policy_id() : "";
845889

846890
if (!v4_meter_policy.empty())
@@ -1367,7 +1411,7 @@ void DashOrch::removeEniMapEntry(sai_object_id_t oid, const string &name) {
13671411

13681412
void DashOrch::addEniToFC(sai_object_id_t oid, const string &name)
13691413
{
1370-
if (!m_eni_fc_status)
1414+
if (!m_eni_fc_status)
13711415
{
13721416
return ;
13731417
}

orchagent/dash/dashorch.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#define DASH_RESULT_SUCCESS 0
3232
#define DASH_RESULT_FAILURE 1
3333

34+
class DashHaOrch;
35+
3436
struct EniEntry
3537
{
3638
sai_object_id_t eni_id;
@@ -53,6 +55,7 @@ class DashOrch : public ZmqOrch
5355
{
5456
public:
5557
DashOrch(swss::DBConnector *db, std::vector<std::string> &tables, swss::DBConnector *app_state_db, swss::ZmqServer *zmqServer);
58+
void setDashHaOrch(DashHaOrch *dash_ha_orch);
5659
const EniEntry *getEni(const std::string &eni) const;
5760
const EniTable *getEniTable() const { return &eni_entries_; };
5861
bool getRouteTypeActions(dash::route_type::RoutingType routing_type, dash::route_type::RouteType& route_type);
@@ -110,6 +113,7 @@ class DashOrch : public ZmqOrch
110113
std::shared_ptr<swss::DBConnector> m_counter_db;
111114
std::shared_ptr<swss::DBConnector> m_asic_db;
112115
swss::SelectableTimer* m_fc_update_timer = nullptr;
116+
DashHaOrch* m_dash_ha_orch = nullptr;
113117

114118
void doTask(swss::SelectableTimer&);
115119
void addEniMapEntry(sai_object_id_t oid, const std::string& name);

tests/mock_tests/dashorch_ut.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,24 @@ EXTERN_MOCK_FNS
2020

2121
namespace dashorch_test
2222
{
23+
class MockDashHaOrch : public DashHaOrch
24+
{
25+
public:
26+
MockDashHaOrch(DBConnector *db, const std::vector<std::string> &tableNames, DashOrch *dash_orch, BfdOrch *bfd_orch, DBConnector *app_state_db, ZmqServer *zmqServer)
27+
: DashHaOrch(db, tableNames, dash_orch, bfd_orch, app_state_db, zmqServer) {}
28+
29+
HaScopeEntry getHaScopeForEni(const std::string& eni) override
30+
{
31+
HaScopeEntry entry;
32+
33+
entry.ha_scope_id = 0x123456789ABCDEF0ULL;
34+
entry.metadata.set_ha_role(dash::types::HA_ROLE_ACTIVE);
35+
entry.metadata.set_disabled(false);
36+
37+
return entry;
38+
}
39+
};
40+
2341
DEFINE_SAI_GENERIC_APIS_MOCK(dash_eni, eni)
2442
DEFINE_SAI_ENTRY_APIS_MOCK(dash_trusted_vni, global_trusted_vni, eni_trusted_vni)
2543
DEFINE_SAI_ENTRY_APIS_MOCK(dash_direction_lookup, direction_lookup)
@@ -63,6 +81,8 @@ namespace dashorch_test
6381
}
6482
}
6583
class DashOrchTest : public MockDashOrchTest, public ::testing::WithParamInterface<std::tuple<ValueOrRange, ValueOrRange>> {
84+
private:
85+
std::unique_ptr<MockDashHaOrch> m_mock_dash_ha_orch;
6686

6787
void ApplySaiMock()
6888
{
@@ -72,6 +92,13 @@ namespace dashorch_test
7292
MockSaiApis();
7393
}
7494

95+
void PostSetUp()
96+
{
97+
m_mock_dash_ha_orch = std::make_unique<MockDashHaOrch>(m_dpu_app_db.get(), std::vector<std::string>{APP_DASH_HA_SET_TABLE_NAME, APP_DASH_HA_SCOPE_TABLE_NAME}, m_DashOrch, nullptr, m_dpu_app_state_db.get(), nullptr);
98+
99+
m_DashOrch->setDashHaOrch(m_mock_dash_ha_orch.get());
100+
}
101+
75102
void PreTearDown() override
76103
{
77104
RestoreSaiApis();

0 commit comments

Comments
 (0)