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;
2021extern CrmOrch *gCrmOrch ;
2122extern 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-
195228bool 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)
0 commit comments