Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- avocado/common.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/avocado/common.py b/avocado/common.py index 94308b8..d859c5d 100644 --- a/avocado/common.py +++ b/avocado/common.py @@ -7,6 +7,7 @@ # Copyright Red Hat # Author: David Gibson <david(a)gibson.dropbear.id.au> +import ipaddress import json import os.path import sys @@ -38,6 +39,11 @@ class NsTool: def pid(self): return self.pid + def relative_pid(self, relative_to): + cmd = '{} info -p {}'.format(NSTOOL, self.sockpath) + txt = relative_to.system_output(cmd) + return int(txt) + def _xcmd(self, cmd, sudo=False): if sudo: opts = '--keep-caps' @@ -71,6 +77,24 @@ class NsToolUnshare(NsTool): self.holder.stop() +def ll_addr(x, ifname): + ifinfo = json.loads(x('ip -6 -j addr show {}'.format(ifname))) + for adinfo in ifinfo[0]['addr_info']: + if adinfo['scope'] != 'link': + continue + if adinfo.get('tentative') is True: + continue + return ipaddress.ip_address(adinfo['local']) + return None + + +def slaac_wait(x, ifname): + addr = None + while addr is None: + addr = ll_addr(x, ifname) + return addr + + # # Tests for the test infrastructure itself # @@ -144,3 +168,46 @@ class NsConnectTests(BaseTest): def test_connect(self): hostns = NsTool(self.sockpath) hostns.system_output('true') + + +class SlaacWaitTests(BaseTest): + def setUp(self): + super().setUp() + + self.ns1 = NsToolUnshare(self.workdir, 'ns1', '-Ucn') + self.ns2 = NsToolUnshare(self.workdir, 'ns2', '-n', parent=self.ns1) + + def tearDown(self): + del(self.ns2) + del(self.ns1) + + super().tearDown() + + def test_slaac_wait(self, sysctls={}): + TESTMAC = '02:aa:bb:cc:dd:ee' + TESTIP = ipaddress.ip_address('fe80::aa:bbff:fecc:ddee') + + self.ns1.system_output('ip link add type veth', sudo=True) + relpid = self.ns2.relative_pid(self.ns1) + self.ns1.system_output( + 'ip link set veth1 netns {}'.format(relpid), sudo=True) + self.ns1.system_output( + 'ip link set dev veth0 address {}'.format(TESTMAC), sudo=True) + + for (key, val) in sysctls.items(): + self.ns1.system_output( + 'sysctl net.ipv6.conf.veth0.{}={}'.format(key, val), sudo=True) + self.ns2.system_output( + 'sysctl net.ipv6.conf.veth1.{}={}'.format(key, val), sudo=True) + + self.ns2.system_output('ip link set veth1 up', sudo=True) + self.ns1.system_output('ip link set veth0 up', sudo=True) + + addr = slaac_wait(self.ns1.system_output, 'veth0') + self.assertEqual(addr, TESTIP) + + def test_optimistic_dad(self): + self.test_slaac_wait({'optimistic_dad': 1}) + + def test_no_dad(self): + self.test_slaac_wait({'accept_dad': 0}) -- 2.40.0