Skip to content

Commit b8cd435

Browse files
lolyuyxieca
authored andcommitted
[muxorch] Always use direct link for SoC IPs (#2369)
What I did For SoC IPs of ports in active-active cable type, if mux is toggled to standby, still use direct link instead of changing next-hop to the tunnel. Why I did it In an active-active dualtor setup, changing the nexthop of route to SoC IP to the tunnel will have the following problem: If lower ToR is already standby, and somehow the upper ToR decides to toggle itself to standby, the toggle will fail: linkmgrd decide to toggle to standby --> muxorch disables the SoC IP neighbor and change the route next-hop to the tunnel --> ycabled could not setup gRPC connection. How I verified it Add unittest and verify the change on active-active testbeds.
1 parent 6158d5c commit b8cd435

File tree

3 files changed

+47
-10
lines changed

3 files changed

+47
-10
lines changed

orchagent/muxorch.cpp

+26-3
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,8 @@ static bool remove_nh_tunnel(sai_object_id_t nh_id, IpAddress& ipAddr)
351351
return true;
352352
}
353353

354-
MuxCable::MuxCable(string name, IpPrefix& srv_ip4, IpPrefix& srv_ip6, IpAddress peer_ip)
355-
:mux_name_(name), srv_ip4_(srv_ip4), srv_ip6_(srv_ip6), peer_ip4_(peer_ip)
354+
MuxCable::MuxCable(string name, IpPrefix& srv_ip4, IpPrefix& srv_ip6, IpAddress peer_ip, std::set<IpAddress> skip_neighbors)
355+
:mux_name_(name), srv_ip4_(srv_ip4), srv_ip6_(srv_ip6), peer_ip4_(peer_ip), skip_neighbors_(skip_neighbors)
356356
{
357357
mux_orch_ = gDirectory.get<MuxOrch*>();
358358
mux_cb_orch_ = gDirectory.get<MuxCableOrch*>();
@@ -534,6 +534,11 @@ bool MuxCable::nbrHandler(bool enable, bool update_rt)
534534
void MuxCable::updateNeighbor(NextHopKey nh, bool add)
535535
{
536536
sai_object_id_t tnh = mux_orch_->getNextHopTunnelId(MUX_TUNNEL, peer_ip4_);
537+
if (add && skip_neighbors_.find(nh.ip_address) != skip_neighbors_.end())
538+
{
539+
SWSS_LOG_INFO("Skip update neighbor %s on %s", nh.ip_address.to_string().c_str(), nh.alias.c_str());
540+
return;
541+
}
537542
nbr_handler_->update(nh, tnh, add, state_);
538543
if (add)
539544
{
@@ -1208,9 +1213,27 @@ bool MuxOrch::handleMuxCfg(const Request& request)
12081213
auto srv_ip = request.getAttrIpPrefix("server_ipv4");
12091214
auto srv_ip6 = request.getAttrIpPrefix("server_ipv6");
12101215

1216+
std::set<IpAddress> skip_neighbors;
1217+
12111218
const auto& port_name = request.getKeyString(0);
12121219
auto op = request.getOperation();
12131220

1221+
for (const auto &name : request.getAttrFieldNames())
1222+
{
1223+
if (name == "soc_ipv4")
1224+
{
1225+
auto soc_ip = request.getAttrIpPrefix("soc_ipv4");
1226+
SWSS_LOG_NOTICE("%s: %s was added to ignored neighbor list", port_name.c_str(), soc_ip.getIp().to_string().c_str());
1227+
skip_neighbors.insert(soc_ip.getIp());
1228+
}
1229+
else if (name == "soc_ipv6")
1230+
{
1231+
auto soc_ip6 = request.getAttrIpPrefix("soc_ipv6");
1232+
SWSS_LOG_NOTICE("%s: %s was added to ignored neighbor list", port_name.c_str(), soc_ip6.getIp().to_string().c_str());
1233+
skip_neighbors.insert(soc_ip6.getIp());
1234+
}
1235+
}
1236+
12141237
if (op == SET_COMMAND)
12151238
{
12161239
if(isMuxExists(port_name))
@@ -1226,7 +1249,7 @@ bool MuxOrch::handleMuxCfg(const Request& request)
12261249
}
12271250

12281251
mux_cable_tb_[port_name] = std::make_unique<MuxCable>
1229-
(MuxCable(port_name, srv_ip, srv_ip6, mux_peer_switch_));
1252+
(MuxCable(port_name, srv_ip, srv_ip6, mux_peer_switch_, skip_neighbors));
12301253

12311254
SWSS_LOG_NOTICE("Mux entry for port '%s' was added", port_name.c_str());
12321255
}

orchagent/muxorch.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class MuxNbrHandler
7676
class MuxCable
7777
{
7878
public:
79-
MuxCable(string name, IpPrefix& srv_ip4, IpPrefix& srv_ip6, IpAddress peer_ip);
79+
MuxCable(string name, IpPrefix& srv_ip4, IpPrefix& srv_ip6, IpAddress peer_ip, std::set<IpAddress> skip_neighbors);
8080

8181
bool isActive() const
8282
{
@@ -115,6 +115,8 @@ class MuxCable
115115
IpPrefix srv_ip4_, srv_ip6_;
116116
IpAddress peer_ip4_;
117117

118+
std::set<IpAddress> skip_neighbors_;
119+
118120
MuxOrch *mux_orch_;
119121
MuxCableOrch *mux_cb_orch_;
120122
MuxStateOrch *mux_state_orch_;
@@ -132,6 +134,7 @@ const request_description_t mux_cfg_request_description = {
132134
{ "server_ipv6", REQ_T_IP_PREFIX },
133135
{ "address_ipv4", REQ_T_IP },
134136
{ "soc_ipv4", REQ_T_IP_PREFIX },
137+
{ "soc_ipv6", REQ_T_IP_PREFIX },
135138
{ "cable_type", REQ_T_STRING },
136139
},
137140
{ }

tests/test_mux.py

+17-6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class TestMuxTunnelBase(object):
2727

2828
SERV1_IPV4 = "192.168.0.100"
2929
SERV1_IPV6 = "fc02:1000::100"
30+
SERV1_SOC_IPV4 = "192.168.0.102"
3031
SERV2_IPV4 = "192.168.0.101"
3132
SERV2_IPV6 = "fc02:1000::101"
3233
IPV4_MASK = "/32"
@@ -74,7 +75,12 @@ def create_vlan_interface(self, confdb, asicdb, dvs):
7475

7576
def create_mux_cable(self, confdb):
7677

77-
fvs = { "server_ipv4":self.SERV1_IPV4+self.IPV4_MASK, "server_ipv6":self.SERV1_IPV6+self.IPV6_MASK }
78+
fvs = {
79+
"server_ipv4":self.SERV1_IPV4 + self.IPV4_MASK,
80+
"server_ipv6":self.SERV1_IPV6 + self.IPV6_MASK,
81+
"soc_ipv4": self.SERV1_SOC_IPV4 + self.IPV4_MASK,
82+
"cable_type": "active-active"
83+
}
7884
confdb.create_entry(self.CONFIG_MUX_CABLE, "Ethernet0", fvs)
7985

8086
fvs = { "server_ipv4":self.SERV2_IPV4+self.IPV4_MASK, "server_ipv6":self.SERV2_IPV6+self.IPV6_MASK }
@@ -201,6 +207,9 @@ def create_and_test_neighbor(self, confdb, appdb, asicdb, dvs, dvs_route):
201207
self.add_neighbor(dvs, self.SERV1_IPV6, "00:00:00:00:00:01", True)
202208
srv1_v6 = self.check_neigh_in_asic_db(asicdb, self.SERV1_IPV6, 3)
203209

210+
self.add_neighbor(dvs, self.SERV1_SOC_IPV4, "00:00:00:00:00:01")
211+
self.check_neigh_in_asic_db(asicdb, self.SERV1_SOC_IPV4, 4)
212+
204213
existing_keys = asicdb.get_keys(self.ASIC_NEIGH_TABLE)
205214

206215
self.add_neighbor(dvs, self.SERV2_IPV4, "00:00:00:00:00:02")
@@ -212,21 +221,23 @@ def create_and_test_neighbor(self, confdb, appdb, asicdb, dvs, dvs_route):
212221
dvs_route.check_asicdb_route_entries([self.SERV2_IPV4+self.IPV4_MASK, self.SERV2_IPV6+self.IPV6_MASK])
213222

214223
# The first standby route also creates as tunnel Nexthop
215-
self.check_tnl_nexthop_in_asic_db(asicdb, 3)
224+
self.check_tnl_nexthop_in_asic_db(asicdb, 4)
216225

217226
# Change state to Standby. This will delete Neigh and add Route
218227
self.set_mux_state(appdb, "Ethernet0", "standby")
219228

220229
asicdb.wait_for_deleted_entry(self.ASIC_NEIGH_TABLE, srv1_v4)
221230
asicdb.wait_for_deleted_entry(self.ASIC_NEIGH_TABLE, srv1_v6)
222231
dvs_route.check_asicdb_route_entries([self.SERV1_IPV4+self.IPV4_MASK, self.SERV1_IPV6+self.IPV6_MASK])
232+
self.check_neigh_in_asic_db(asicdb, self.SERV1_SOC_IPV4, 2)
233+
dvs_route.check_asicdb_deleted_route_entries([self.SERV1_SOC_IPV4+self.IPV4_MASK])
223234

224235
# Change state to Active. This will add Neigh and delete Route
225236
self.set_mux_state(appdb, "Ethernet4", "active")
226237

227238
dvs_route.check_asicdb_deleted_route_entries([self.SERV2_IPV4+self.IPV4_MASK, self.SERV2_IPV6+self.IPV6_MASK])
228-
self.check_neigh_in_asic_db(asicdb, self.SERV2_IPV4, 3)
229-
self.check_neigh_in_asic_db(asicdb, self.SERV2_IPV6, 3)
239+
self.check_neigh_in_asic_db(asicdb, self.SERV2_IPV4, 4)
240+
self.check_neigh_in_asic_db(asicdb, self.SERV2_IPV6, 4)
230241

231242

232243
def create_and_test_fdb(self, appdb, asicdb, dvs, dvs_route):
@@ -244,7 +255,7 @@ def create_and_test_fdb(self, appdb, asicdb, dvs, dvs_route):
244255
self.add_neighbor(dvs, ip_2, "00:00:00:00:00:12", True)
245256

246257
# ip_1 is on Active Mux, hence added to Host table
247-
self.check_neigh_in_asic_db(asicdb, ip_1, 4)
258+
self.check_neigh_in_asic_db(asicdb, ip_1, 5)
248259

249260
# ip_2 is on Standby Mux, hence added to Route table
250261
dvs_route.check_asicdb_route_entries([ip_2+self.IPV6_MASK])
@@ -260,7 +271,7 @@ def create_and_test_fdb(self, appdb, asicdb, dvs, dvs_route):
260271

261272
# ip_2 moved to active Mux, hence remove from Route table
262273
dvs_route.check_asicdb_deleted_route_entries([ip_2+self.IPV6_MASK])
263-
self.check_neigh_in_asic_db(asicdb, ip_2, 4)
274+
self.check_neigh_in_asic_db(asicdb, ip_2, 5)
264275

265276
# Simulate FDB aging out test case
266277
ip_3 = "192.168.0.200"

0 commit comments

Comments
 (0)