Skip to content

Commit c4f8c16

Browse files
Merge branch 'master' into fix-no-pgs
2 parents 8478701 + 3ccfa62 commit c4f8c16

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2124
-421
lines changed

fpmsyncd/routesync.cpp

Lines changed: 235 additions & 127 deletions
Large diffs are not rendered by default.

fpmsyncd/routesync.h

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,138 @@ struct NextHopGroup {
4242
/* Path to protocol name database provided by iproute2 */
4343
constexpr auto DefaultRtProtoPath = "/etc/iproute2/rt_protos";
4444

45+
class FieldValueTupleWrapperBase {
46+
public:
47+
FieldValueTupleWrapperBase(const string & _key) : key(_key) {}
48+
FieldValueTupleWrapperBase(const string && _key) : key(std::move(_key)) {}
49+
virtual ~FieldValueTupleWrapperBase() = default;
50+
51+
virtual vector<FieldValueTuple> fieldValueTupleVector() = 0;
52+
53+
vector<KeyOpFieldsValuesTuple> KeyOpFieldsValuesTupleVector() {
54+
// The following code calls the batched version of set() for the table.
55+
// The reason for the DEL followed by a SET is that redis only overwrites
56+
// hashset fields that are explicitly set against a given key. It does leaves
57+
// previously set fields as is. If a route changes in such a way that earlier
58+
// fields are not valid any more (Ex: from using nexthop to nexthop-group),
59+
// then we would like to atomically cleanup earlier fields and set the new
60+
// fields in the hash-set in redis.
61+
vector<KeyOpFieldsValuesTuple> kfvVector;
62+
kfvVector.push_back(KeyOpFieldsValuesTuple {key.c_str(), "DEL", {}});
63+
auto fvVector = fieldValueTupleVector();
64+
kfvVector.push_back(KeyOpFieldsValuesTuple {key.c_str(), "SET", fvVector});
65+
return kfvVector;
66+
}
67+
68+
// For DEL-only operations with warm restart support
69+
KeyOpFieldsValuesTuple KeyOpFieldsValuesTupleVectorForDel() {
70+
return KeyOpFieldsValuesTuple {key.c_str(), "DEL", {}};
71+
}
72+
73+
string key = string();
74+
};
75+
76+
class RouteTableFieldValueTupleWrapper : public FieldValueTupleWrapperBase {
77+
public:
78+
RouteTableFieldValueTupleWrapper(const string & _key, string && _protocol) :
79+
FieldValueTupleWrapperBase(_key), protocol(std::move(_protocol)) {}
80+
RouteTableFieldValueTupleWrapper(const string && _key, string && _protocol) :
81+
FieldValueTupleWrapperBase(std::move(_key)), protocol(std::move(_protocol)) {}
82+
83+
vector<FieldValueTuple> fieldValueTupleVector() override;
84+
85+
string protocol = string();
86+
string blackhole = string();
87+
string nexthop = string();
88+
string ifname = string();
89+
string nexthop_group = string();
90+
string mpls_nh = string();
91+
string weight = string();
92+
string vni_label = string();
93+
string router_mac = string();
94+
string segment = string();
95+
string seg_src = string();
96+
};
97+
98+
class LabelRouteTableFieldValueTupleWrapper : public FieldValueTupleWrapperBase {
99+
public:
100+
LabelRouteTableFieldValueTupleWrapper(const string & _key, string && _protocol) :
101+
FieldValueTupleWrapperBase(_key),
102+
protocol(std::move(_protocol)) {}
103+
LabelRouteTableFieldValueTupleWrapper(const string && _key, string && _protocol) :
104+
FieldValueTupleWrapperBase(std::move(_key)),
105+
protocol(std::move(_protocol)) {}
106+
107+
vector<FieldValueTuple> fieldValueTupleVector() override;
108+
109+
string protocol = string();
110+
string blackhole = string();
111+
string nexthop = string();
112+
string ifname = string();
113+
string mpls_nh = string();
114+
string mpls_pop = string();
115+
};
116+
117+
class VnetRouteTableFieldValueTupleWrapper : public FieldValueTupleWrapperBase {
118+
public:
119+
VnetRouteTableFieldValueTupleWrapper(const string & _key) : FieldValueTupleWrapperBase(_key) {}
120+
VnetRouteTableFieldValueTupleWrapper(const string && _key)
121+
: FieldValueTupleWrapperBase(std::move(_key)) {}
122+
123+
vector<FieldValueTuple> fieldValueTupleVector() override;
124+
125+
string nexthop = string();
126+
string ifname = string();
127+
};
128+
129+
class VnetTunnelTableFieldValueTupleWrapper : public FieldValueTupleWrapperBase {
130+
public:
131+
VnetTunnelTableFieldValueTupleWrapper(const string & _key) : FieldValueTupleWrapperBase(_key) {}
132+
VnetTunnelTableFieldValueTupleWrapper(const string && _key)
133+
: FieldValueTupleWrapperBase(std::move(_key)) {}
134+
135+
vector<FieldValueTuple> fieldValueTupleVector() override;
136+
137+
string endpoint = string();
138+
};
139+
140+
class NextHopGroupTableFieldValueTupleWrapper : public FieldValueTupleWrapperBase {
141+
public:
142+
NextHopGroupTableFieldValueTupleWrapper(const string & _key) : FieldValueTupleWrapperBase(_key) {}
143+
NextHopGroupTableFieldValueTupleWrapper(const string && _key)
144+
: FieldValueTupleWrapperBase(std::move(_key)) {}
145+
146+
vector<FieldValueTuple> fieldValueTupleVector() override;
147+
148+
string nexthop = string();
149+
string ifname = string();
150+
string weight = string();
151+
};
152+
153+
class Srv6MySidTableFieldValueTupleWrapper : public FieldValueTupleWrapperBase {
154+
public:
155+
Srv6MySidTableFieldValueTupleWrapper(const string & _key) : FieldValueTupleWrapperBase(_key) {}
156+
Srv6MySidTableFieldValueTupleWrapper(const string && _key)
157+
: FieldValueTupleWrapperBase(std::move(_key)) {}
158+
159+
vector<FieldValueTuple> fieldValueTupleVector() override;
160+
161+
string action = string();
162+
string vrf = string();
163+
string adj = string();
164+
};
165+
166+
class Srv6SidListTableFieldValueTupleWrapper : public FieldValueTupleWrapperBase {
167+
public:
168+
Srv6SidListTableFieldValueTupleWrapper(const string & _key) : FieldValueTupleWrapperBase(_key) {}
169+
Srv6SidListTableFieldValueTupleWrapper(const string && _key)
170+
: FieldValueTupleWrapperBase(std::move(_key)) {}
171+
172+
vector<FieldValueTuple> fieldValueTupleVector() override;
173+
174+
string path = string();
175+
};
176+
45177
class RouteSync : public NetMsg
46178
{
47179
public:
@@ -61,8 +193,18 @@ class RouteSync : public NetMsg
61193
}
62194

63195
/* Helper method to set route table with warm restart support */
64-
void setRouteWithWarmRestart(const std::string& key, const std::vector<FieldValueTuple>& fvVector,
65-
shared_ptr<ProducerStateTable> table, const std::string& cmd = SET_COMMAND);
196+
void setRouteWithWarmRestart(
197+
FieldValueTupleWrapperBase & fvw,
198+
ProducerStateTable & table);
199+
200+
void setTable(
201+
FieldValueTupleWrapperBase & fvw,
202+
ProducerStateTable & table);
203+
204+
// Generic method for DEL operations with warm restart support
205+
void delWithWarmRestart(
206+
FieldValueTupleWrapperBase && fvw,
207+
ProducerStateTable & table);
66208

67209
void onRouteResponse(const std::string& key, const std::vector<FieldValueTuple>& fieldValues);
68210

orchagent/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dist_swss_DATA = \
2929
pfc_restore.lua \
3030
pfc_restore_cisco-8000.lua \
3131
port_rates.lua \
32+
port_flr.lua \
3233
drop_monitor.lua \
3334
watermark_queue.lua \
3435
watermark_pg.lua \

orchagent/aclorch.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static acl_rule_attr_lookup_t aclL3ActionLookup =
112112
{ ACTION_DISABLE_TRIM, SAI_ACL_ENTRY_ATTR_ACTION_PACKET_TRIM_DISABLE }
113113
};
114114

115-
static acl_rule_attr_lookup_t aclInnerActionLookup =
115+
static acl_rule_attr_lookup_t aclInnerActionLookup =
116116
{
117117
{ ACTION_INNER_SRC_MAC_REWRITE_ACTION, SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_SRC_MAC},
118118
};
@@ -923,7 +923,7 @@ bool AclRule::validateAddMatch(string attr_name, string attr_value)
923923
}
924924
else if (attr_name == MATCH_TUNNEL_TERM)
925925
{
926-
matchData.data.booldata = (attr_name == "true");
926+
matchData.data.booldata = (to_upper(attr_value) == "TRUE");;
927927
}
928928
else if (attr_name == MATCH_INNER_DST_MAC || attr_name == MATCH_INNER_SRC_MAC)
929929
{
@@ -2186,8 +2186,8 @@ AclRuleInnerSrcMacRewrite::AclRuleInnerSrcMacRewrite(AclOrch *aclOrch, string ru
21862186
memcpy(actionData.parameter.mac, inner_src_mac_addr.getMac(), sizeof(sai_mac_t));
21872187
action_str = ACTION_INNER_SRC_MAC_REWRITE_ACTION;
21882188
SWSS_LOG_INFO("Converting the Mac address %s to SAI acl action parameter", _attr_value.c_str());
2189-
}
2190-
2189+
}
2190+
21912191
else
21922192
{
21932193
return false;
@@ -2216,7 +2216,7 @@ AclRuleInnerSrcMacRewrite::AclRuleInnerSrcMacRewrite(AclOrch *aclOrch, string ru
22162216

22172217
void AclRuleInnerSrcMacRewrite::onUpdate(SubjectType type, void *cntx)
22182218
{
2219-
//do nothing
2219+
//do nothing
22202220
}
22212221

22222222
AclRuleMirror::AclRuleMirror(AclOrch *aclOrch, MirrorOrch *mirror, string rule, string table) :
@@ -2522,7 +2522,7 @@ void AclRuleUnderlaySetDscp::onUpdate(SubjectType, void *)
25222522
{
25232523
// Do nothing
25242524
}
2525-
2525+
25262526
AclTable::AclTable(AclOrch *pAclOrch, string id) noexcept : m_pAclOrch(pAclOrch), id(id)
25272527
{
25282528

@@ -4419,7 +4419,7 @@ EgressSetDscpTableStatus AclOrch::addEgrSetDscpTable(string table_id, AclTable &
44194419
if (!isAclMetaDataSupported())
44204420
{
44214421
SWSS_LOG_ERROR("Platform does not support MARK_META/MARK_METAV6 tables.");
4422-
return EgressSetDscpTableStatus::EGRESS_SET_DSCP_TABLE_NOT_SUPPORTED;
4422+
return EgressSetDscpTableStatus::EGRESS_SET_DSCP_TABLE_NOT_SUPPORTED;
44234423
}
44244424
AclTable egrSetDscpTable(this);
44254425

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
}

0 commit comments

Comments
 (0)