@@ -123,6 +123,10 @@ static sai_status_t create_route(IpPrefix &pfx, sai_object_id_t nh)
123123 sai_status_t status = sai_route_api->create_route_entry (&route_entry, (uint32_t )attrs.size (), attrs.data ());
124124 if (status != SAI_STATUS_SUCCESS)
125125 {
126+ if (status == SAI_STATUS_ITEM_ALREADY_EXISTS) {
127+ SWSS_LOG_NOTICE (" Tunnel route to %s already exists" , pfx.to_string ().c_str ());
128+ return SAI_STATUS_SUCCESS;
129+ }
126130 SWSS_LOG_ERROR (" Failed to create tunnel route %s,nh %" PRIx64 " rv:%d" ,
127131 pfx.getIp ().to_string ().c_str (), nh, status);
128132 return status;
@@ -152,6 +156,10 @@ static sai_status_t remove_route(IpPrefix &pfx)
152156 sai_status_t status = sai_route_api->remove_route_entry (&route_entry);
153157 if (status != SAI_STATUS_SUCCESS)
154158 {
159+ if (status == SAI_STATUS_ITEM_NOT_FOUND) {
160+ SWSS_LOG_NOTICE (" Tunnel route to %s already removed" , pfx.to_string ().c_str ());
161+ return SAI_STATUS_SUCCESS;
162+ }
155163 SWSS_LOG_ERROR (" Failed to remove tunnel route %s, rv:%d" ,
156164 pfx.getIp ().to_string ().c_str (), status);
157165 return status;
@@ -504,15 +512,15 @@ void MuxCable::setState(string new_state)
504512
505513 mux_cb_orch_->updateMuxMetricState (mux_name_, new_state, true );
506514
507- MuxState state = state_;
515+ prev_state_ = state_;
508516 state_ = ns;
509517
510518 st_chg_in_progress_ = true ;
511519
512520 if (!(this ->*(state_machine_handlers_[it->second ]))())
513521 {
514522 // Reset back to original state
515- state_ = state ;
523+ state_ = prev_state_ ;
516524 st_chg_in_progress_ = false ;
517525 st_chg_failed_ = true ;
518526 throw std::runtime_error (" Failed to handle state transition" );
@@ -528,6 +536,51 @@ void MuxCable::setState(string new_state)
528536 return ;
529537}
530538
539+ void MuxCable::rollbackStateChange ()
540+ {
541+ if (prev_state_ == MuxState::MUX_STATE_FAILED || prev_state_ == MuxState::MUX_STATE_PENDING)
542+ {
543+ SWSS_LOG_ERROR (" [%s] Rollback to %s not supported" , mux_name_.c_str (),
544+ muxStateValToString.at (prev_state_).c_str ());
545+ return ;
546+ }
547+ SWSS_LOG_WARN (" [%s] Rolling back state change to %s" , mux_name_.c_str (),
548+ muxStateValToString.at (prev_state_).c_str ());
549+ mux_cb_orch_->updateMuxMetricState (mux_name_, muxStateValToString.at (prev_state_), true );
550+ st_chg_in_progress_ = true ;
551+ state_ = prev_state_;
552+ bool success = false ;
553+ switch (prev_state_)
554+ {
555+ case MuxState::MUX_STATE_ACTIVE:
556+ success = stateActive ();
557+ break ;
558+ case MuxState::MUX_STATE_INIT:
559+ case MuxState::MUX_STATE_STANDBY:
560+ success = stateStandby ();
561+ break ;
562+ case MuxState::MUX_STATE_FAILED:
563+ case MuxState::MUX_STATE_PENDING:
564+ // Check at the start of the function means we will never reach here
565+ SWSS_LOG_ERROR (" [%s] Rollback to %s not supported" , mux_name_.c_str (),
566+ muxStateValToString.at (prev_state_).c_str ());
567+ return ;
568+ }
569+ st_chg_in_progress_ = false ;
570+ if (success)
571+ {
572+ st_chg_failed_ = false ;
573+ }
574+ else
575+ {
576+ st_chg_failed_ = true ;
577+ SWSS_LOG_ERROR (" [%s] Rollback to %s failed" ,
578+ mux_name_.c_str (), muxStateValToString.at (prev_state_).c_str ());
579+ }
580+ mux_cb_orch_->updateMuxMetricState (mux_name_, muxStateValToString.at (state_), false );
581+ mux_cb_orch_->updateMuxState (mux_name_, muxStateValToString.at (state_));
582+ }
583+
531584string MuxCable::getState ()
532585{
533586 SWSS_LOG_INFO (" Get state request for %s, state %s" ,
@@ -845,8 +898,6 @@ void MuxNbrHandler::updateTunnelRoute(NextHopKey nh, bool add)
845898 }
846899}
847900
848- std::map<std::string, AclTable> MuxAclHandler::acl_table_;
849-
850901MuxAclHandler::MuxAclHandler (sai_object_id_t port, string alias)
851902{
852903 SWSS_LOG_ENTER ();
@@ -858,32 +909,21 @@ MuxAclHandler::MuxAclHandler(sai_object_id_t port, string alias)
858909 port_ = port;
859910 alias_ = alias;
860911
861- auto found = acl_table_.find (table_name);
862- if (found == acl_table_.end ())
863- {
864- SWSS_LOG_NOTICE (" First time create for port %" PRIx64 " " , port);
912+ // Always try to create the table first. If it already exists, function will return early.
913+ createMuxAclTable (port, table_name);
865914
866- // First time handling of Mux Table, create ACL table, and bind
867- createMuxAclTable (port, table_name);
915+ SWSS_LOG_NOTICE (" Binding port %" PRIx64 " " , port);
916+
917+ AclRule* rule = gAclOrch ->getAclRule (table_name, rule_name);
918+ if (rule == nullptr )
919+ {
868920 shared_ptr<AclRulePacket> newRule =
869921 make_shared<AclRulePacket>(gAclOrch , rule_name, table_name, false /* no counters*/ );
870922 createMuxAclRule (newRule, table_name);
871923 }
872924 else
873925 {
874- SWSS_LOG_NOTICE (" Binding port %" PRIx64 " " , port);
875-
876- AclRule* rule = gAclOrch ->getAclRule (table_name, rule_name);
877- if (rule == nullptr )
878- {
879- shared_ptr<AclRulePacket> newRule =
880- make_shared<AclRulePacket>(gAclOrch , rule_name, table_name, false /* no counters*/ );
881- createMuxAclRule (newRule, table_name);
882- }
883- else
884- {
885- gAclOrch ->updateAclRule (table_name, rule_name, MATCH_IN_PORTS, &port, RULE_OPER_ADD);
886- }
926+ gAclOrch ->updateAclRule (table_name, rule_name, MATCH_IN_PORTS, &port, RULE_OPER_ADD);
887927 }
888928}
889929
@@ -916,23 +956,16 @@ void MuxAclHandler::createMuxAclTable(sai_object_id_t port, string strTable)
916956{
917957 SWSS_LOG_ENTER ();
918958
919- auto inserted = acl_table_.emplace (piecewise_construct,
920- std::forward_as_tuple (strTable),
921- std::forward_as_tuple (gAclOrch , strTable));
922-
923- assert (inserted.second );
924-
925- AclTable& acl_table = inserted.first ->second ;
926-
927959 sai_object_id_t table_oid = gAclOrch ->getTableById (strTable);
928960 if (table_oid != SAI_NULL_OBJECT_ID)
929961 {
930962 // DROP ACL table is already created
931- SWSS_LOG_NOTICE (" ACL table %s exists, reuse the same" , strTable.c_str ());
932- acl_table = *(gAclOrch ->getTableByOid (table_oid));
963+ SWSS_LOG_INFO (" ACL table %s exists, reuse the same" , strTable.c_str ());
933964 return ;
934965 }
935966
967+ SWSS_LOG_NOTICE (" First time create for port %" PRIx64 " " , port);
968+ AclTable acl_table (gAclOrch , strTable);
936969 auto dropType = gAclOrch ->getAclTableType (TABLE_TYPE_DROP);
937970 assert (dropType);
938971 acl_table.validateAddType (*dropType);
@@ -1770,10 +1803,25 @@ bool MuxCableOrch::addOperation(const Request& request)
17701803 {
17711804 mux_obj->setState (state);
17721805 }
1773- catch (const std::runtime_error& error )
1806+ catch (const std::runtime_error& e )
17741807 {
17751808 SWSS_LOG_ERROR (" Mux Error setting state %s for port %s. Error: %s" ,
1776- state.c_str (), port_name.c_str (), error.what ());
1809+ state.c_str (), port_name.c_str (), e.what ());
1810+ mux_obj->rollbackStateChange ();
1811+ return true ;
1812+ }
1813+ catch (const std::logic_error& e)
1814+ {
1815+ SWSS_LOG_ERROR (" Logic error while setting state %s for port %s. Error: %s" ,
1816+ state.c_str (), port_name.c_str (), e.what ());
1817+ mux_obj->rollbackStateChange ();
1818+ return true ;
1819+ }
1820+ catch (const std::exception& e)
1821+ {
1822+ SWSS_LOG_ERROR (" Exception caught while setting state %s for port %s. Error: %s" ,
1823+ state.c_str (), port_name.c_str (), e.what ());
1824+ mux_obj->rollbackStateChange ();
17771825 return true ;
17781826 }
17791827
0 commit comments