Skip to content

Commit 7ba4e43

Browse files
weixchen1215Ubuntu
andauthored
[fgnhgorch] add warm reboot support for fgnhg (#1538)
- Add bake() functions in FgnhgOrch bake() function retrieves the state database information so that when the new route is added, fgnhg orch is able to recover the nexthop and bucket the same as before warm reboot. - Add priority to fgnhg tables so that fgnhg tables can be loaded prior to route table. Co-authored-by: Ubuntu <weixchen@weixchen-dev.papr3y04rasunohgmh0bxenl2f.xx.internal.cloudapp.net>
1 parent 4cf6617 commit 7ba4e43

File tree

5 files changed

+246
-39
lines changed

5 files changed

+246
-39
lines changed

orchagent/fgnhgorch.cpp

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "swssnet.h"
77
#include "crmorch.h"
88
#include <array>
9+
#include <algorithm>
910

1011
#define LINK_DOWN 0
1112
#define LINK_UP 1
@@ -20,7 +21,7 @@ extern RouteOrch *gRouteOrch;
2021
extern CrmOrch *gCrmOrch;
2122
extern PortsOrch *gPortsOrch;
2223

23-
FgNhgOrch::FgNhgOrch(DBConnector *db, DBConnector *appDb, DBConnector *stateDb, vector<string> &tableNames, NeighOrch *neighOrch, IntfsOrch *intfsOrch, VRFOrch *vrfOrch) :
24+
FgNhgOrch::FgNhgOrch(DBConnector *db, DBConnector *appDb, DBConnector *stateDb, vector<table_name_with_pri_t> &tableNames, NeighOrch *neighOrch, IntfsOrch *intfsOrch, VRFOrch *vrfOrch) :
2425
Orch(db, tableNames),
2526
m_neighOrch(neighOrch),
2627
m_intfsOrch(intfsOrch),
@@ -105,6 +106,39 @@ void FgNhgOrch::update(SubjectType type, void *cntx)
105106
}
106107
}
107108

109+
bool FgNhgOrch::bake()
110+
{
111+
SWSS_LOG_ENTER();
112+
113+
deque<KeyOpFieldsValuesTuple> entries;
114+
vector<string> keys;
115+
m_stateWarmRestartRouteTable.getKeys(keys);
116+
117+
SWSS_LOG_NOTICE("Warm reboot: recovering entry %lu from state", keys.size());
118+
119+
for (const auto &key : keys)
120+
{
121+
vector<FieldValueTuple> tuples;
122+
m_stateWarmRestartRouteTable.get(key, tuples);
123+
124+
NextHopIndexMap nhop_index_map(tuples.size(), std::string());
125+
for (const auto &tuple : tuples)
126+
{
127+
const auto index = stoi(fvField(tuple));
128+
const auto nextHop = fvValue(tuple);
129+
130+
nhop_index_map[index] = nextHop;
131+
SWSS_LOG_INFO("Storing next hop %s at index %d", nhop_index_map[index].c_str(), index);
132+
}
133+
134+
// Recover nexthop with index relationship
135+
m_recoveryMap[key] = nhop_index_map;
136+
137+
m_stateWarmRestartRouteTable.del(key);
138+
}
139+
140+
return Orch::bake();
141+
}
108142

109143
/* calculateBankHashBucketStartIndices: generates the hash_bucket_indices for all banks
110144
* and stores it in fgNhgEntry for the group.
@@ -191,7 +225,6 @@ void FgNhgOrch::setStateDbRouteEntry(const IpPrefix &ipPrefix, uint32_t index, N
191225

192226
}
193227

194-
195228
bool FgNhgOrch::writeHashBucketChange(FGNextHopGroupEntry *syncd_fg_route_entry, uint32_t index, sai_object_id_t nh_oid,
196229
const IpPrefix &ipPrefix, NextHopKey nextHop)
197230
{
@@ -881,6 +914,8 @@ bool FgNhgOrch::setNewNhgMembers(FGNextHopGroupEntry &syncd_fg_route_entry, FgNh
881914
SWSS_LOG_ENTER();
882915

883916
sai_status_t status;
917+
bool isWarmReboot = false;
918+
auto nexthopsMap = m_recoveryMap.find(ipPrefix.to_string());
884919
for (uint32_t i = 0; i < fgNhgEntry->hash_bucket_indices.size(); i++)
885920
{
886921
uint32_t bank = i;
@@ -913,11 +948,33 @@ bool FgNhgOrch::setNewNhgMembers(FGNextHopGroupEntry &syncd_fg_route_entry, FgNh
913948
return false;
914949
}
915950

951+
// recover state before warm reboot
952+
if (nexthopsMap != m_recoveryMap.end())
953+
{
954+
isWarmReboot = true;
955+
}
956+
957+
SWSS_LOG_INFO("Warm reboot is set to %d", isWarmReboot);
958+
916959
for (uint32_t j = fgNhgEntry->hash_bucket_indices[i].start_index;
917960
j <= fgNhgEntry->hash_bucket_indices[i].end_index; j++)
918961
{
919-
NextHopKey bank_nh_memb = bank_member_changes[bank].nhs_to_add[j %
920-
bank_member_changes[bank].nhs_to_add.size()];
962+
NextHopKey bank_nh_memb;
963+
if (isWarmReboot)
964+
{
965+
bank_nh_memb = nexthopsMap->second[j];
966+
SWSS_LOG_INFO("Recovering nexthop %s with bucket %d", bank_nh_memb.ip_address.to_string().c_str(), j);
967+
// case nhps in bank are all down
968+
if (fgNhgEntry->next_hops[bank_nh_memb.ip_address].bank != i)
969+
{
970+
syncd_fg_route_entry.inactive_to_active_map[i] = fgNhgEntry->next_hops[bank_nh_memb.ip_address].bank;
971+
}
972+
}
973+
else
974+
{
975+
bank_nh_memb = bank_member_changes[bank].nhs_to_add[j %
976+
bank_member_changes[bank].nhs_to_add.size()];
977+
}
921978

922979
// Create a next hop group member
923980
sai_attribute_t nhgm_attr;
@@ -961,6 +1018,11 @@ bool FgNhgOrch::setNewNhgMembers(FGNextHopGroupEntry &syncd_fg_route_entry, FgNh
9611018
}
9621019
}
9631020

1021+
if (isWarmReboot)
1022+
{
1023+
m_recoveryMap.erase(nexthopsMap);
1024+
}
1025+
9641026
return true;
9651027
}
9661028

@@ -1592,7 +1654,7 @@ bool FgNhgOrch::doTaskFgNhgMember(const KeyOpFieldsValuesTuple & t)
15921654
}
15931655
fgNhg_entry->second.next_hops[next_hop] = fg_nh_info;
15941656
SWSS_LOG_INFO("FG_NHG member added for group %s, next-hop %s",
1595-
fgNhg_entry->second.fg_nhg_name.c_str(), next_hop.to_string().c_str());
1657+
fgNhg_entry->second.fg_nhg_name.c_str(), nhk.to_string().c_str());
15961658
}
15971659
}
15981660
else if (op == DEL_COMMAND)

orchagent/fgnhgorch.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,24 @@ typedef struct
8383
std::vector<NextHopKey> active_nhs;
8484
} BankMemberChanges;
8585

86+
typedef std::vector<string> NextHopIndexMap;
87+
typedef map<string, NextHopIndexMap> WarmBootRecoveryMap;
88+
8689
class FgNhgOrch : public Orch, public Observer
8790
{
8891
public:
8992
FgNhgPrefixes fgNhgPrefixes;
90-
FgNhgOrch(DBConnector *db, DBConnector *appDb, DBConnector *stateDb, vector<string> &tableNames, NeighOrch *neighOrch, IntfsOrch *intfsOrch, VRFOrch *vrfOrch);
93+
FgNhgOrch(DBConnector *db, DBConnector *appDb, DBConnector *stateDb, vector<table_name_with_pri_t> &tableNames, NeighOrch *neighOrch, IntfsOrch *intfsOrch, VRFOrch *vrfOrch);
9194

9295
void update(SubjectType type, void *cntx);
9396
bool addRoute(sai_object_id_t, const IpPrefix&, const NextHopGroupKey&);
9497
bool removeRoute(sai_object_id_t, const IpPrefix&);
9598
bool validNextHopInNextHopGroup(const NextHopKey&);
9699
bool invalidNextHopInNextHopGroup(const NextHopKey&);
97100

101+
// warm reboot support
102+
bool bake() override;
103+
98104
private:
99105
NeighOrch *m_neighOrch;
100106
IntfsOrch *m_intfsOrch;
@@ -106,6 +112,10 @@ class FgNhgOrch : public Orch, public Observer
106112
FgPrefixOpCache m_fgPrefixAddCache;
107113
FgPrefixOpCache m_fgPrefixDelCache;
108114

115+
// warm reboot support for recovery
116+
// < ip_prefix, < HashBuckets, nh_ip>>
117+
WarmBootRecoveryMap m_recoveryMap;
118+
109119
bool setNewNhgMembers(FGNextHopGroupEntry &syncd_fg_route_entry, FgNhgEntry *fgNhgEntry,
110120
std::vector<BankMemberChanges> &bank_member_changes,
111121
std::map<NextHopKey,sai_object_id_t> &nhopgroup_members_set, const IpPrefix&);

orchagent/orchdaemon.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,12 @@ bool OrchDaemon::init()
123123
gIntfsOrch = new IntfsOrch(m_applDb, APP_INTF_TABLE_NAME, vrf_orch);
124124
gNeighOrch = new NeighOrch(m_applDb, APP_NEIGH_TABLE_NAME, gIntfsOrch, gFdbOrch, gPortsOrch);
125125

126-
vector<string> fgnhg_tables = {
127-
CFG_FG_NHG,
128-
CFG_FG_NHG_PREFIX,
129-
CFG_FG_NHG_MEMBER
126+
const int fgnhgorch_pri = 15;
127+
128+
vector<table_name_with_pri_t> fgnhg_tables = {
129+
{ CFG_FG_NHG, fgnhgorch_pri },
130+
{ CFG_FG_NHG_PREFIX, fgnhgorch_pri },
131+
{ CFG_FG_NHG_MEMBER, fgnhgorch_pri }
130132
};
131133

132134
gFgNhgOrch = new FgNhgOrch(m_configDb, m_applDb, m_stateDb, fgnhg_tables, gNeighOrch, gIntfsOrch, vrf_orch);

tests/mock_tests/aclorch_ut.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,12 @@ namespace aclorch_test
323323
gNeighOrch = new NeighOrch(m_app_db.get(), APP_NEIGH_TABLE_NAME, gIntfsOrch, gFdbOrch, gPortsOrch);
324324

325325
ASSERT_EQ(gFgNhgOrch, nullptr);
326-
vector<string> fgnhg_tables = {
327-
CFG_FG_NHG,
328-
CFG_FG_NHG_PREFIX,
329-
CFG_FG_NHG_MEMBER
326+
const int fgnhgorch_pri = 15;
327+
328+
vector<table_name_with_pri_t> fgnhg_tables = {
329+
{ CFG_FG_NHG, fgnhgorch_pri },
330+
{ CFG_FG_NHG_PREFIX, fgnhgorch_pri },
331+
{ CFG_FG_NHG_MEMBER, fgnhgorch_pri }
330332
};
331333
gFgNhgOrch = new FgNhgOrch(m_config_db.get(), m_app_db.get(), m_state_db.get(), fgnhg_tables, gNeighOrch, gIntfsOrch, gVrfOrch);
332334

0 commit comments

Comments
 (0)