Skip to content

Commit 3db6516

Browse files
committed
network: add tcpdump() function and use it
test_vlan_filtering.py is running tcpdump for various tests. as it something we want to use more in network tests, create a function. Signed-off-by: Sebastien Rodot <sebastien.rodot@vates.tech>
1 parent 99364ae commit 3db6516

2 files changed

Lines changed: 70 additions & 22 deletions

File tree

tests/network/__init__.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from __future__ import annotations
2+
3+
import logging
4+
5+
from lib.common import wait_for
6+
from lib.vm import VM
7+
8+
from typing import Callable
9+
10+
def tcpdump(
11+
pcapfile: str,
12+
vm: VM,
13+
interface: str,
14+
filter: str | None = None,
15+
*,
16+
count: int | None = None,
17+
) -> Callable[[], None]:
18+
"""
19+
Run tcpdump on the vm with specific interface.
20+
Returns a lambda to permit to cleanup (kill tcpdump + file cleanup).
21+
"""
22+
def cleanup():
23+
# if vm is gone, do not fail
24+
if vm.exists() and vm.is_running():
25+
vm.ssh(
26+
f"xargs kill < {pcapfile}.pid || true; "
27+
f"rm -f -- {pcapfile}.pid; ",
28+
check=False,
29+
)
30+
31+
# check no concurrent run
32+
assert not vm.file_exists(f"{pcapfile}.pid")
33+
34+
# tcpdump arguments
35+
args = f"-n -w {pcapfile} -i {interface}"
36+
if count is not None:
37+
args += f" -c {count}"
38+
if filter is not None:
39+
args += f" '{filter}'"
40+
41+
# run tcpdump in background
42+
logging.info(f"Running tcpdump on '{vm.name()}'")
43+
vm.ssh(
44+
f"tcpdump --immediate-mode {args} & "
45+
f"echo $! > {pcapfile}.pid; ",
46+
background=True,
47+
)
48+
49+
# wait tcpdump to start properly
50+
wait_for(lambda: vm.file_exists(pcapfile), timeout_secs=2)
51+
52+
return cleanup

tests/network/test_vlan_filtering.py

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from lib.network import Network
77
from lib.vm import VM
88

9+
from . import tcpdump
10+
911
# Requirements:
1012
# From --hosts parameter:
1113
# - host(A1): an XCP-ng host
@@ -59,18 +61,15 @@ def test_passing(self, defer: Defer, empty_network: Network, imported_vm: VM, vm
5961
vm_writer.ssh(f"ip addr add 192.168.42.1/24 dev {ifaceW}.42")
6062
vm_writer.ssh(f"ip link set {ifaceW}.42 up")
6163

64+
tcpdump_stop = tcpdump("tcpdump.pcap", vm_reader, ifaceR, "vlan 42 and arp", count=1)
65+
defer(tcpdump_stop)
66+
6267
# send some packets on VLAN 42 (ARP packets will be send)
63-
# the ping process could be still running after the test,
64-
# but vm_writer will be destroyed, so it isn't a problem.
65-
vm_writer.ssh("ping -c1 -w1 192.168.42.2", background=True, check=False)
66-
67-
# check packets are seen on vm_reader
68-
# fail if /tmp/out is empty
69-
vm_reader.ssh(
70-
f"tcpdump -i {ifaceR} -w /tmp/out -c1 -n 'vlan 42 and arp' &"
71-
"pid=$! ; sleep 5 ; kill $pid ;"
72-
"test -s /tmp/out"
73-
)
68+
vm_writer.ssh("ping -c1 -w1 192.168.42.2", check=False)
69+
tcpdump_stop()
70+
71+
# check packets are seen on vm_reader (trunks=42)
72+
vm_reader.ssh("test $(tcpdump -n -r tcpdump.pcap | wc -l) -gt 0")
7473

7574
def test_filtered(self, defer: Defer, empty_network: Network, imported_vm: VM, vm_with_tcpdump_scope_function: VM):
7675
vm_writer, ifaceW = start_vm_on_trunk(
@@ -95,15 +94,12 @@ def test_filtered(self, defer: Defer, empty_network: Network, imported_vm: VM, v
9594
vm_writer.ssh(f"ip addr add 192.168.42.1/24 dev {ifaceW}.42")
9695
vm_writer.ssh(f"ip link set {ifaceW}.42 up")
9796

97+
tcpdump_stop = tcpdump("tcpdump.pcap", vm_reader, ifaceR, "vlan 42 and arp", count=1)
98+
defer(tcpdump_stop)
99+
98100
# send some packets on VLAN 42 (ARP packets will be send)
99-
# the ping process could be still running after the test,
100-
# but vm_writer will be destroyed, so it isn't a problem.
101-
vm_writer.ssh("ping -c1 -w1 192.168.42.2", background=True, check=False)
102-
103-
# check packets are seen on vm_reader
104-
# fail if /tmp/out is not empty
105-
vm_reader.ssh(
106-
f"tcpdump -i {ifaceR} -w /tmp/out -c1 -n 'vlan 42 and arp' &"
107-
"pid=$! ; sleep 5 ; kill $pid ;"
108-
"test ! -s /tmp/out"
109-
)
101+
vm_writer.ssh("ping -c1 -w1 192.168.42.2", check=False)
102+
tcpdump_stop()
103+
104+
# check packets are *NOT* seen on vm_reader (trunks=52)
105+
vm_reader.ssh("test $(tcpdump -n -r tcpdump.pcap | wc -l) -eq 0")

0 commit comments

Comments
 (0)