Skip to content

Commit cab2673

Browse files
lolyusaravanansv
authored andcommitted
[dualtor] Add neighbor entry orchagent testcase (sonic-net#3031)
Approach What is the motivation for this PR? Verify that, for standby ToR, the traffic to the server will be dropped if the neighbor entry of server is removed. How did you do it? Verify that the traffic to server is neither passed to server directly by standby ToR or encapsulated to the active ToR. Signed-off-by: Longxiang Lyu <[email protected]>
1 parent 51be251 commit cab2673

5 files changed

Lines changed: 101 additions & 3 deletions

File tree

tests/common/dualtor/dual_tor_mock.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
'mock_server_base_ip_addr',
2525
'mock_server_ip_mac_map',
2626
'set_dual_tor_state_to_orchagent',
27-
'del_dual_tor_state_from_orchagent'
27+
'del_dual_tor_state_from_orchagent',
28+
'is_t0_mocked_dualtor'
2829
]
2930

3031
logger = logging.getLogger(__name__)

tests/common/dualtor/dual_tor_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ def _get_iface_ip(mg_facts, ifacename):
738738
servers = mux_cable_server_ip(standby_tor)
739739
random_server_iface = random.choice(servers.keys())
740740

741+
res['selected_port'] = random_server_iface
741742
res['target_server_ip'] = servers[random_server_iface]['server_ipv4'].split('/')[0]
742743
res['target_server_port'] = standby_tor_mg_facts['minigraph_ptf_indices'][random_server_iface]
743744

tests/common/dualtor/tunnel_traffic_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def _disassemble_ip_tos(tos):
8686
logging.debug("Outer packet DSCP: {0:06b}, inner packet DSCP: {1:06b}".format(outer_dscp, inner_dscp))
8787
logging.debug("Outer packet ECN: {0:02b}, inner packet ECN: {0:02b}".format(outer_ecn, inner_ecn))
8888
check_res = []
89-
if outer_dscp != inner_ecn:
89+
if outer_dscp != inner_dscp:
9090
check_res.append("outer packet DSCP not same as inner packet DSCP")
9191
if outer_ecn != inner_ecn:
9292
check_res.append("outer packet ECN not same as inner packet ECN")

tests/dualtor/test_orchagent_active_tor_downstream.py

Whitespace-only changes.

tests/dualtor/test_orchagent_standby_tor_downstream.py

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@
33
import time
44
import logging
55
import ipaddress
6+
import contextlib
7+
import time
8+
import scapy.all as scapyall
9+
10+
from ptf import testutils, mask
611
from tests.common.dualtor.dual_tor_mock import *
7-
from tests.common.dualtor.dual_tor_utils import dualtor_info, check_tunnel_balance, flush_neighbor
12+
from tests.common.dualtor.dual_tor_utils import dualtor_info, check_tunnel_balance, flush_neighbor, get_t1_ptf_ports
813
from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory, change_mac_addresses, run_garp_service, run_icmp_responder # lgtm[py/unused-import]
914
from tests.common.helpers.assertions import pytest_require as pt_require
15+
from tests.common.dualtor.tunnel_traffic_utils import tunnel_traffic_monitor
16+
from tests.common.dualtor.server_traffic_utils import ServerTrafficMonitor
1017

1118
pytestmark = [
1219
pytest.mark.topology('t0'),
@@ -19,6 +26,7 @@
1926

2027
logger = logging.getLogger(__file__)
2128

29+
2230
def shutdown_random_one_t1_link(dut):
2331
"""
2432
Shutdown a random t1 link
@@ -185,3 +193,91 @@ def test_standby_tor_downstream_loopback_route_readded(ptfhost, rand_selected_du
185193
# Readd loopback routes and verify traffic is equally distributed
186194
add_loopback_routes(rand_selected_dut, active_tor_loopback0)
187195
check_tunnel_balance(**params)
196+
197+
198+
def test_standby_tor_remove_neighbor_downstream_standby(
199+
conn_graph_facts, ptfadapter, ptfhost,
200+
rand_selected_dut, rand_unselected_dut, tbinfo,
201+
set_crm_polling_interval,
202+
tunnel_traffic_monitor, vmhost
203+
):
204+
"""
205+
@summary: Verify that after removing neighbor entry for a server over standby
206+
ToR, the packets sent to the server will be dropped(neither passed to the server
207+
or redirected to the active ToR).
208+
"""
209+
def build_packet_to_server(tor, ptfadapter, target_server_ip, tunnel_traffic_monitor):
210+
"""Build packet destinated to server."""
211+
pkt_dscp = random.choice(range(0, 33))
212+
pkt_ttl = random.choice(range(3, 65))
213+
pkt = testutils.simple_ip_packet(
214+
eth_dst=tor.facts["router_mac"],
215+
eth_src=ptfadapter.dataplane.get_mac(0, 0),
216+
ip_src="1.1.1.1",
217+
ip_dst=target_server_ip,
218+
ip_dscp=pkt_dscp,
219+
ip_ttl=pkt_ttl
220+
)
221+
logging.info(
222+
"the packet destinated to server %s:\n%s", target_server_ip,
223+
tunnel_traffic_monitor._dump_show_str(pkt)
224+
)
225+
return pkt
226+
227+
def build_expected_packet_to_server(packet):
228+
"""Build expected mask packet downstream to server."""
229+
exp_pkt = mask.Mask(packet)
230+
exp_pkt.set_do_not_care_scapy(scapyall.Ether, "dst")
231+
exp_pkt.set_do_not_care_scapy(scapyall.Ether, "src")
232+
exp_pkt.set_do_not_care_scapy(scapyall.IP, "tos")
233+
exp_pkt.set_do_not_care_scapy(scapyall.IP, "ttl")
234+
exp_pkt.set_do_not_care_scapy(scapyall.IP, "chksum")
235+
return exp_pkt
236+
237+
@contextlib.contextmanager
238+
def crm_neighbor_checker(duthost):
239+
crm_facts_before = duthost.get_crm_facts()
240+
ipv4_neighbor_before = crm_facts_before["resources"]["ipv4_neighbor"]["used"]
241+
logging.info("ipv4 neighbor before test: %s", ipv4_neighbor_before)
242+
yield
243+
time.sleep(crm_facts_before["polling_interval"])
244+
crm_facts_after = duthost.get_crm_facts()
245+
ipv4_neighbor_after = crm_facts_after["resources"]["ipv4_neighbor"]["used"]
246+
logging.info("ipv4 neighbor after test: %s", ipv4_neighbor_after)
247+
if ipv4_neighbor_after != ipv4_neighbor_before:
248+
raise ValueError("ipv4 neighbor differs, before %s, after %s", ipv4_neighbor_before, ipv4_neighbor_after)
249+
250+
@contextlib.contextmanager
251+
def stop_garp(ptfhost):
252+
"""Temporarily stop garp service."""
253+
ptfhost.shell("supervisorctl stop garp_service")
254+
yield
255+
ptfhost.shell("supervisorctl start garp_service")
256+
257+
tor = rand_selected_dut
258+
test_params = dualtor_info(ptfhost, rand_selected_dut, rand_unselected_dut, tbinfo)
259+
server_ipv4 = test_params["target_server_ip"]
260+
261+
pkt = build_packet_to_server(tor, ptfadapter, server_ipv4, tunnel_traffic_monitor)
262+
exp_pkt = build_expected_packet_to_server(pkt)
263+
ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo))
264+
logging.info("send traffic to server %s from ptf t1 interface %s", server_ipv4, ptf_t1_intf)
265+
tunnel_monitor = tunnel_traffic_monitor(tor, existing=True)
266+
with tunnel_monitor:
267+
testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), pkt, count=10)
268+
269+
logging.info("send traffic to server %s after removing neighbor entry", server_ipv4)
270+
tunnel_monitor.existing = False
271+
server_traffic_monitor = ServerTrafficMonitor(
272+
tor, vmhost, test_params["selected_port"],
273+
conn_graph_facts, exp_pkt, existing=False
274+
)
275+
# for real dualtor testbed, leave the neighbor restoration to garp service
276+
flush_neighbor_ct = flush_neighbor(tor, server_ipv4, restore=is_t0_mocked_dualtor)
277+
with crm_neighbor_checker(tor), stop_garp(ptfhost), flush_neighbor_ct, tunnel_monitor, server_traffic_monitor:
278+
testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), pkt, count=10)
279+
280+
logging.info("send traffic to server %s after neighbor entry is restored", server_ipv4)
281+
tunnel_monitor.existing = True
282+
with crm_neighbor_checker(tor), tunnel_monitor:
283+
testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), pkt, count=10)

0 commit comments

Comments
 (0)