@@ -116,6 +116,10 @@ static sai_status_t create_route(IpPrefix &pfx, sai_object_id_t nh)
116
116
sai_status_t status = sai_route_api->create_route_entry (&route_entry, (uint32_t )attrs.size (), attrs.data ());
117
117
if (status != SAI_STATUS_SUCCESS)
118
118
{
119
+ if (status == SAI_STATUS_ITEM_ALREADY_EXISTS) {
120
+ SWSS_LOG_NOTICE (" Tunnel route to %s already exists" , pfx.to_string ().c_str ());
121
+ return SAI_STATUS_SUCCESS;
122
+ }
119
123
SWSS_LOG_ERROR (" Failed to create tunnel route %s,nh %" PRIx64 " rv:%d" ,
120
124
pfx.getIp ().to_string ().c_str (), nh, status);
121
125
return status;
@@ -145,6 +149,10 @@ static sai_status_t remove_route(IpPrefix &pfx)
145
149
sai_status_t status = sai_route_api->remove_route_entry (&route_entry);
146
150
if (status != SAI_STATUS_SUCCESS)
147
151
{
152
+ if (status == SAI_STATUS_ITEM_NOT_FOUND) {
153
+ SWSS_LOG_NOTICE (" Tunnel route to %s already removed" , pfx.to_string ().c_str ());
154
+ return SAI_STATUS_SUCCESS;
155
+ }
148
156
SWSS_LOG_ERROR (" Failed to remove tunnel route %s, rv:%d" ,
149
157
pfx.getIp ().to_string ().c_str (), status);
150
158
return status;
@@ -497,15 +505,15 @@ void MuxCable::setState(string new_state)
497
505
498
506
mux_cb_orch_->updateMuxMetricState (mux_name_, new_state, true );
499
507
500
- MuxState state = state_;
508
+ prev_state_ = state_;
501
509
state_ = ns;
502
510
503
511
st_chg_in_progress_ = true ;
504
512
505
513
if (!(this ->*(state_machine_handlers_[it->second ]))())
506
514
{
507
515
// Reset back to original state
508
- state_ = state ;
516
+ state_ = prev_state_ ;
509
517
st_chg_in_progress_ = false ;
510
518
st_chg_failed_ = true ;
511
519
throw std::runtime_error (" Failed to handle state transition" );
@@ -521,6 +529,51 @@ void MuxCable::setState(string new_state)
521
529
return ;
522
530
}
523
531
532
+ void MuxCable::rollbackStateChange ()
533
+ {
534
+ if (prev_state_ == MuxState::MUX_STATE_FAILED || prev_state_ == MuxState::MUX_STATE_PENDING)
535
+ {
536
+ SWSS_LOG_ERROR (" [%s] Rollback to %s not supported" , mux_name_.c_str (),
537
+ muxStateValToString.at (prev_state_).c_str ());
538
+ return ;
539
+ }
540
+ SWSS_LOG_WARN (" [%s] Rolling back state change to %s" , mux_name_.c_str (),
541
+ muxStateValToString.at (prev_state_).c_str ());
542
+ mux_cb_orch_->updateMuxMetricState (mux_name_, muxStateValToString.at (prev_state_), true );
543
+ st_chg_in_progress_ = true ;
544
+ state_ = prev_state_;
545
+ bool success = false ;
546
+ switch (prev_state_)
547
+ {
548
+ case MuxState::MUX_STATE_ACTIVE:
549
+ success = stateActive ();
550
+ break ;
551
+ case MuxState::MUX_STATE_INIT:
552
+ case MuxState::MUX_STATE_STANDBY:
553
+ success = stateStandby ();
554
+ break ;
555
+ case MuxState::MUX_STATE_FAILED:
556
+ case MuxState::MUX_STATE_PENDING:
557
+ // Check at the start of the function means we will never reach here
558
+ SWSS_LOG_ERROR (" [%s] Rollback to %s not supported" , mux_name_.c_str (),
559
+ muxStateValToString.at (prev_state_).c_str ());
560
+ return ;
561
+ }
562
+ st_chg_in_progress_ = false ;
563
+ if (success)
564
+ {
565
+ st_chg_failed_ = false ;
566
+ }
567
+ else
568
+ {
569
+ st_chg_failed_ = true ;
570
+ SWSS_LOG_ERROR (" [%s] Rollback to %s failed" ,
571
+ mux_name_.c_str (), muxStateValToString.at (prev_state_).c_str ());
572
+ }
573
+ mux_cb_orch_->updateMuxMetricState (mux_name_, muxStateValToString.at (state_), false );
574
+ mux_cb_orch_->updateMuxState (mux_name_, muxStateValToString.at (state_));
575
+ }
576
+
524
577
string MuxCable::getState ()
525
578
{
526
579
SWSS_LOG_INFO (" Get state request for %s, state %s" ,
@@ -838,8 +891,6 @@ void MuxNbrHandler::updateTunnelRoute(NextHopKey nh, bool add)
838
891
}
839
892
}
840
893
841
- std::map<std::string, AclTable> MuxAclHandler::acl_table_;
842
-
843
894
MuxAclHandler::MuxAclHandler (sai_object_id_t port, string alias)
844
895
{
845
896
SWSS_LOG_ENTER ();
@@ -857,32 +908,21 @@ MuxAclHandler::MuxAclHandler(sai_object_id_t port, string alias)
857
908
port_ = port;
858
909
alias_ = alias;
859
910
860
- auto found = acl_table_.find (table_name);
861
- if (found == acl_table_.end ())
862
- {
863
- SWSS_LOG_NOTICE (" First time create for port %" PRIx64 " " , port);
911
+ // Always try to create the table first. If it already exists, function will return early.
912
+ createMuxAclTable (port, table_name);
864
913
865
- // First time handling of Mux Table, create ACL table, and bind
866
- createMuxAclTable (port, table_name);
914
+ SWSS_LOG_NOTICE (" Binding port %" PRIx64 " " , port);
915
+
916
+ AclRule* rule = gAclOrch ->getAclRule (table_name, rule_name);
917
+ if (rule == nullptr )
918
+ {
867
919
shared_ptr<AclRulePacket> newRule =
868
920
make_shared<AclRulePacket>(gAclOrch , rule_name, table_name, false /* no counters*/ );
869
921
createMuxAclRule (newRule, table_name);
870
922
}
871
923
else
872
924
{
873
- SWSS_LOG_NOTICE (" Binding port %" PRIx64 " " , port);
874
-
875
- AclRule* rule = gAclOrch ->getAclRule (table_name, rule_name);
876
- if (rule == nullptr )
877
- {
878
- shared_ptr<AclRulePacket> newRule =
879
- make_shared<AclRulePacket>(gAclOrch , rule_name, table_name, false /* no counters*/ );
880
- createMuxAclRule (newRule, table_name);
881
- }
882
- else
883
- {
884
- gAclOrch ->updateAclRule (table_name, rule_name, MATCH_IN_PORTS, &port, RULE_OPER_ADD);
885
- }
925
+ gAclOrch ->updateAclRule (table_name, rule_name, MATCH_IN_PORTS, &port, RULE_OPER_ADD);
886
926
}
887
927
}
888
928
@@ -915,23 +955,16 @@ void MuxAclHandler::createMuxAclTable(sai_object_id_t port, string strTable)
915
955
{
916
956
SWSS_LOG_ENTER ();
917
957
918
- auto inserted = acl_table_.emplace (piecewise_construct,
919
- std::forward_as_tuple (strTable),
920
- std::forward_as_tuple (gAclOrch , strTable));
921
-
922
- assert (inserted.second );
923
-
924
- AclTable& acl_table = inserted.first ->second ;
925
-
926
958
sai_object_id_t table_oid = gAclOrch ->getTableById (strTable);
927
959
if (table_oid != SAI_NULL_OBJECT_ID)
928
960
{
929
961
// DROP ACL table is already created
930
- SWSS_LOG_NOTICE (" ACL table %s exists, reuse the same" , strTable.c_str ());
931
- acl_table = *(gAclOrch ->getTableByOid (table_oid));
962
+ SWSS_LOG_INFO (" ACL table %s exists, reuse the same" , strTable.c_str ());
932
963
return ;
933
964
}
934
965
966
+ SWSS_LOG_NOTICE (" First time create for port %" PRIx64 " " , port);
967
+ AclTable acl_table (gAclOrch , strTable);
935
968
auto dropType = gAclOrch ->getAclTableType (TABLE_TYPE_DROP);
936
969
assert (dropType);
937
970
acl_table.validateAddType (*dropType);
@@ -1776,10 +1809,25 @@ bool MuxCableOrch::addOperation(const Request& request)
1776
1809
{
1777
1810
mux_obj->setState (state);
1778
1811
}
1779
- catch (const std::runtime_error& error )
1812
+ catch (const std::runtime_error& e )
1780
1813
{
1781
1814
SWSS_LOG_ERROR (" Mux Error setting state %s for port %s. Error: %s" ,
1782
- state.c_str (), port_name.c_str (), error.what ());
1815
+ state.c_str (), port_name.c_str (), e.what ());
1816
+ mux_obj->rollbackStateChange ();
1817
+ return true ;
1818
+ }
1819
+ catch (const std::logic_error& e)
1820
+ {
1821
+ SWSS_LOG_ERROR (" Logic error while setting state %s for port %s. Error: %s" ,
1822
+ state.c_str (), port_name.c_str (), e.what ());
1823
+ mux_obj->rollbackStateChange ();
1824
+ return true ;
1825
+ }
1826
+ catch (const std::exception & e)
1827
+ {
1828
+ SWSS_LOG_ERROR (" Exception caught while setting state %s for port %s. Error: %s" ,
1829
+ state.c_str (), port_name.c_str (), e.what ());
1830
+ mux_obj->rollbackStateChange ();
1783
1831
return true ;
1784
1832
}
1785
1833
0 commit comments