summaryrefslogtreecommitdiff
path: root/tests/common
diff options
context:
space:
mode:
Diffstat (limited to 'tests/common')
-rw-r--r--tests/common/ipoe_iface.py84
-rw-r--r--tests/common/veth.py26
2 files changed, 104 insertions, 6 deletions
diff --git a/tests/common/ipoe_iface.py b/tests/common/ipoe_iface.py
new file mode 100644
index 00000000..62b26355
--- /dev/null
+++ b/tests/common/ipoe_iface.py
@@ -0,0 +1,84 @@
+from common import process
+import os
+import signal
+import time
+
+
+# (ifindex, name) of every ipoe session interface currently in the kernel.
+# Matched by name rather than by 'ip link show type ipoe' so that the helper
+# keeps working with a module that does not register rtnl_link_ops.
+def list_ipoe():
+ (exit_code, out, err) = process.run(["ip", "-o", "link", "show"])
+ assert exit_code == 0, "ip link show failed: " + err
+
+ ifaces = []
+ for line in out.splitlines():
+ fields = line.split(":")
+ if len(fields) < 2:
+ continue
+ try:
+ ifindex = int(fields[0].strip())
+ except ValueError:
+ continue
+ name = fields[1].strip().split("@")[0]
+ if name.startswith("ipoe"):
+ ifaces.append((ifindex, name))
+
+ return ifaces
+
+
+# pids of the running accel-pppd processes
+def accel_pppd_pids():
+ pids = []
+ for entry in os.listdir("/proc"):
+ if not entry.isdigit():
+ continue
+ try:
+ with open("/proc/" + entry + "/comm") as comm:
+ if comm.read().strip() == "accel-pppd":
+ pids.append(int(entry))
+ except OSError: # process is gone, or not ours to look at
+ pass
+
+ return pids
+
+
+# SIGKILL every accel-pppd and wait until they are really gone.
+# Returns the number of processes that were killed.
+def kill_accel_pppd(max_wait_time=10.0):
+ pids = accel_pppd_pids()
+ for pid in pids:
+ print("kill_accel_pppd: SIGKILL to pid " + str(pid))
+ try:
+ os.kill(pid, signal.SIGKILL)
+ except OSError:
+ pass
+
+ sleep_time = 0.0
+ while sleep_time < max_wait_time:
+ if not accel_pppd_pids():
+ print("kill_accel_pppd: gone in (sec): " + str(sleep_time))
+ break
+ time.sleep(0.1)
+ sleep_time += 0.1
+
+ return len(pids)
+
+
+# wait until accel-pppd reports an active ipoe session on the given interface
+def wait_for_session(accel_cmd, called_sid, max_wait_time=10.0):
+ sleep_time = 0.0
+ out = ""
+ while sleep_time < max_wait_time:
+ (exit_code, out, err) = process.run(
+ [accel_cmd, "show sessions called-sid,ip,state"]
+ )
+ assert exit_code == 0, "accel-cmd failed: " + err
+ if called_sid in out and "192.0.2." in out and "active" in out:
+ print("wait_for_session: session found in (sec): " + str(sleep_time))
+ return True
+ time.sleep(0.1)
+ sleep_time += 0.1
+
+ print("wait_for_session: last accel-cmd out: " + out)
+ return False
diff --git a/tests/common/veth.py b/tests/common/veth.py
index c9d3006c..9d51ab7a 100644
--- a/tests/common/veth.py
+++ b/tests/common/veth.py
@@ -2,11 +2,16 @@ from common import process, netns, vlan, iface
import time
import math
-# creates veth pair. if ok returns 0
-def create_pair(name_a, name_b):
- veth, out, err = process.run(
- ["ip", "link", "add", name_a, "type", "veth", "peer", "name", name_b]
- )
+# creates veth pair, optionally with fixed hardware addresses. if ok returns 0
+def create_pair(name_a, name_b, mac_a=None, mac_b=None):
+ command = ["ip", "link", "add", name_a]
+ if mac_a:
+ command += ["address", mac_a]
+ command += ["type", "veth", "peer", "name", name_b]
+ if mac_b:
+ command += ["address", mac_b]
+
+ veth, out, err = process.run(command)
print("veth.create: exit=%d out=%s err=%s" % (veth, out, err))
return veth
@@ -32,7 +37,16 @@ def create_veth_pair_netns(veth_pair_vlans_config):
veth_a = "A" + name
veth_b = "B" + name
- pair_status = create_pair(veth_a, veth_b)
+
+ # fixed addresses: a veth pair created without them gets random ones, which
+ # systemd-udevd may replace right after creation (MACAddressPolicy in its
+ # .link rules). accel-pppd reads the address of the interface it serves once
+ # at startup, so when udev wins that race the daemon advertises an address
+ # the interface no longer has and the session never passes a frame.
+ # See https://github.com/accel-ppp/accel-ppp/issues/363
+ num = int(name)
+ mac = "02:00:%02x:%02x:%02x:" % ((num >> 16) & 0xFF, (num >> 8) & 0xFF, num & 0xFF)
+ pair_status = create_pair(veth_a, veth_b, mac + "0a", mac + "0b")
print("create_veth_pair_netns: pair_status=%d" % pair_status)
iface.up(veth_a, None)