diff --git a/orchagent/muxorch.cpp b/orchagent/muxorch.cpp index 296d5a3cf3..81ed9877d3 100644 --- a/orchagent/muxorch.cpp +++ b/orchagent/muxorch.cpp @@ -553,6 +553,8 @@ void MuxCable::updateNeighbor(NextHopKey nh, bool add) void MuxNbrHandler::update(NextHopKey nh, sai_object_id_t tunnelId, bool add, MuxState state) { + uint32_t num_routes = 0; + SWSS_LOG_INFO("Neigh %s on %s, add %d, state %d", nh.ip_address.to_string().c_str(), nh.alias.c_str(), add, state); @@ -579,6 +581,7 @@ void MuxNbrHandler::update(NextHopKey nh, sai_object_id_t tunnelId, bool add, Mu case MuxState::MUX_STATE_ACTIVE: neighbors_[nh.ip_address] = gNeighOrch->getLocalNextHopId(nh); gNeighOrch->enableNeighbor(nh); + gRouteOrch->updateNextHopRoutes(nh, num_routes); break; case MuxState::MUX_STATE_STANDBY: neighbors_[nh.ip_address] = tunnelId; diff --git a/orchagent/neighorch.cpp b/orchagent/neighorch.cpp index 562793b5f7..bcd6f50f3a 100644 --- a/orchagent/neighorch.cpp +++ b/orchagent/neighorch.cpp @@ -591,6 +591,12 @@ void NeighOrch::decreaseNextHopRefCount(const NextHopKey &nexthop, uint32_t coun assert(hasNextHop(nexthop)); if (m_syncdNextHops.find(nexthop) != m_syncdNextHops.end()) { + if ((m_syncdNextHops[nexthop].ref_count - (int)count) < 0) + { + SWSS_LOG_ERROR("Ref count cannot be negative for next_hop_id: 0x%" PRIx64 " with ip: %s and alias: %s", + m_syncdNextHops[nexthop].next_hop_id, nexthop.ip_address.to_string().c_str(), nexthop.alias.c_str()); + return; + } m_syncdNextHops[nexthop].ref_count -= count; } } diff --git a/tests/test_mux.py b/tests/test_mux.py index 71193735c9..593ab63229 100644 --- a/tests/test_mux.py +++ b/tests/test_mux.py @@ -500,6 +500,80 @@ def create_and_test_route(self, appdb, asicdb, dvs, dvs_route): ps._del(rtprefix) + def create_and_test_NH_routes(self, appdb, asicdb, dvs, dvs_route, mac): + ''' + Tests case where neighbor is removed in standby and added in active with route + ''' + nh_route = "2.2.2.0/24" + nh_route_ipv6 = "2023::/64" + neigh_ip = self.SERV1_IPV4 + neigh_ipv6 = self.SERV1_IPV6 + apdb = dvs.get_app_db() + + # Setup + self.set_mux_state(appdb, "Ethernet0", "active") + self.add_neighbor(dvs, neigh_ip, mac) + self.add_neighbor(dvs, neigh_ipv6, mac) + dvs.runcmd( + "vtysh -c \"configure terminal\" -c \"ip route " + nh_route + + " " + neigh_ip + "\"" + ) + dvs.runcmd( + "vtysh -c \"configure terminal\" -c \"ipv6 route " + nh_route_ipv6 + + " " + neigh_ipv6 + "\"" + ) + apdb.wait_for_entry("ROUTE_TABLE", nh_route) + apdb.wait_for_entry("ROUTE_TABLE", nh_route_ipv6) + + rtkeys = dvs_route.check_asicdb_route_entries([nh_route]) + rtkeys_ipv6 = dvs_route.check_asicdb_route_entries([nh_route_ipv6]) + self.check_nexthop_in_asic_db(asicdb, rtkeys[0]) + self.check_nexthop_in_asic_db(asicdb, rtkeys_ipv6[0]) + + # Set state to standby and delete neighbor + self.set_mux_state(appdb, "Ethernet0", "standby") + self.check_nexthop_in_asic_db(asicdb, rtkeys[0], True) + self.check_nexthop_in_asic_db(asicdb, rtkeys_ipv6[0], True) + + self.del_neighbor(dvs, neigh_ip) + self.del_neighbor(dvs, neigh_ipv6) + apdb.wait_for_deleted_entry(self.APP_NEIGH_TABLE, neigh_ip) + apdb.wait_for_deleted_entry(self.APP_NEIGH_TABLE, neigh_ipv6) + asicdb.wait_for_deleted_entry(self.ASIC_NEIGH_TABLE, neigh_ip) + asicdb.wait_for_deleted_entry(self.ASIC_NEIGH_TABLE, neigh_ip) + + self.check_nexthop_in_asic_db(asicdb, rtkeys[0], True) + self.check_nexthop_in_asic_db(asicdb, rtkeys_ipv6[0], True) + + # Set state to active, learn neighbor again + self.set_mux_state(appdb, "Ethernet0", "active") + + self.add_neighbor(dvs, neigh_ip, mac) + self.add_neighbor(dvs, neigh_ipv6, mac) + self.check_neigh_in_asic_db(asicdb, neigh_ip) + self.check_neigh_in_asic_db(asicdb, neigh_ipv6) + + self.check_nexthop_in_asic_db(asicdb, rtkeys[0]) + self.check_nexthop_in_asic_db(asicdb, rtkeys_ipv6[0]) + dvs.runcmd( + "ip neigh flush " + neigh_ip + ) + dvs.runcmd( + "ip neigh flush " + neigh_ipv6 + ) + + # Cleanup + dvs.runcmd( + "vtysh -c \"configure terminal\" -c \"no ip route " + nh_route + + " " + neigh_ip + "\"" + ) + dvs.runcmd( + "vtysh -c \"configure terminal\" -c \"no ipv6 route " + nh_route_ipv6 + + " " + neigh_ipv6 + "\"" + ) + self.del_neighbor(dvs, neigh_ip) + self.del_neighbor(dvs, neigh_ipv6) + def get_expected_sai_qualifiers(self, portlist, dvs_acl): expected_sai_qualifiers = { "SAI_ACL_ENTRY_ATTR_PRIORITY": self.ACL_PRIORITY, @@ -1050,6 +1124,14 @@ def test_Route(self, dvs, dvs_route, testlog): self.create_and_test_route(appdb, asicdb, dvs, dvs_route) + def test_NH(self, dvs, dvs_route, intf_fdb_map, setup_peer_switch, setup_tunnel, testlog): + """ test NH routes and mux state change """ + appdb = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0) + asicdb = dvs.get_asic_db() + mac = intf_fdb_map["Ethernet0"] + + self.create_and_test_NH_routes(appdb, asicdb, dvs, dvs_route, mac) + def test_acl(self, dvs, dvs_acl, testlog): """ test acl and mux state change """