mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-17 15:09:26 +03:00

Within a dual VM test-setup a strange behaviour was observed. The two VMs are connected via one vde_switch instance (instancevirtualisation.vlans = [ 1 ]; IMO a bad attribute name for switch instances, has nothing to do with VLANs in sense of 802.1Q). A ping on the base interface (eth1) works, but not on VLAN subinterfaces (vlan1@eth1). A tcpdump of eth1 includes the ARP requests tagged with the subinterfaces VLAN ID, but responses seems not to pass the vde_switch. This works fine if performed on the base interface. Putting the vde_switch in hub mode results in flooding traffic to all vde_switch ports. This results in a expected behaviour and a ping on a VLAN subinterface works as expected. Signed-off-by: Philippe Schaaf <philippe.schaaf@secunet.com>
58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
from pathlib import Path
|
|
import io
|
|
import os
|
|
import pty
|
|
import subprocess
|
|
|
|
from test_driver.logger import rootlog
|
|
|
|
|
|
class VLan:
|
|
"""This class handles a VLAN that the run-vm scripts identify via its
|
|
number handles. The network's lifetime equals the object's lifetime.
|
|
"""
|
|
|
|
nr: int
|
|
socket_dir: Path
|
|
|
|
process: subprocess.Popen
|
|
pid: int
|
|
fd: io.TextIOBase
|
|
|
|
def __repr__(self) -> str:
|
|
return f"<Vlan Nr. {self.nr}>"
|
|
|
|
def __init__(self, nr: int, tmp_dir: Path):
|
|
self.nr = nr
|
|
self.socket_dir = tmp_dir / f"vde{self.nr}.ctl"
|
|
|
|
# TODO: don't side-effect environment here
|
|
os.environ[f"QEMU_VDE_SOCKET_{self.nr}"] = str(self.socket_dir)
|
|
|
|
rootlog.info("start vlan")
|
|
pty_master, pty_slave = pty.openpty()
|
|
|
|
self.process = subprocess.Popen(
|
|
["vde_switch", "-s", self.socket_dir, "--dirmode", "0700", "--hub"],
|
|
stdin=pty_slave,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
shell=False,
|
|
)
|
|
self.pid = self.process.pid
|
|
self.fd = os.fdopen(pty_master, "w")
|
|
self.fd.write("version\n")
|
|
|
|
# TODO: perl version checks if this can be read from
|
|
# an if not, dies. we could hang here forever. Fix it.
|
|
assert self.process.stdout is not None
|
|
self.process.stdout.readline()
|
|
if not (self.socket_dir / "ctl").exists():
|
|
rootlog.error("cannot start vde_switch")
|
|
|
|
rootlog.info(f"running vlan (pid {self.pid}; ctl {self.socket_dir})")
|
|
|
|
def __del__(self) -> None:
|
|
rootlog.info(f"kill vlan (pid {self.pid})")
|
|
self.fd.close()
|
|
self.process.terminate()
|