]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
tests: Split proxyarp test cases into IPv4 and IPv6 parts
authorJouni Malinen <j@w1.fi>
Sat, 28 Jan 2017 23:20:43 +0000 (01:20 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 29 Jan 2017 12:32:17 +0000 (14:32 +0200)
This is useful for now since the IPv6 support for proxyarp is not yet
included in the upstream kernel. This allows the IPv4 test cases to pass
with the current upstream kernel while allowing the IPv6 test cases to
report SKIP instead of FAIL.

Signed-off-by: Jouni Malinen <j@w1.fi>
tests/hwsim/test_ap_hs20.py
tests/hwsim/vm/parallel-vm.py

index e4354750e7d35e3d8c76eb710ffbeccf28209762..af501af2259e2d5baf10e6694597c69dab947839 100644 (file)
@@ -4255,23 +4255,6 @@ def _test_proxyarp_open(dev, apdev, params, ebtables=False):
             subprocess.call(['ebtables', '-A', chain, '-p', 'ARP',
                              '-d', 'Broadcast', '-o', apdev[0]['ifname'],
                              '-j', 'DROP'])
-            subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
-                             '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
-                             '--ip6-icmp-type', 'neighbor-solicitation',
-                             '-o', apdev[0]['ifname'], '-j', 'DROP'])
-            subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
-                             '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
-                             '--ip6-icmp-type', 'neighbor-advertisement',
-                             '-o', apdev[0]['ifname'], '-j', 'DROP'])
-            subprocess.call(['ebtables', '-A', chain,
-                             '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
-                             '--ip6-icmp-type', 'router-solicitation',
-                             '-o', apdev[0]['ifname'], '-j', 'DROP'])
-            # Multicast Listener Report Message
-            subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
-                             '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
-                             '--ip6-icmp-type', '143',
-                             '-o', apdev[0]['ifname'], '-j', 'DROP'])
 
     time.sleep(0.5)
     cmd = {}
@@ -4308,32 +4291,6 @@ def _test_proxyarp_open(dev, apdev, params, ebtables=False):
     addr1 = dev[1].p2p_interface_addr()
     addr2 = dev[2].p2p_interface_addr()
 
-    src_ll_opt0 = "\x01\x01" + binascii.unhexlify(addr0.replace(':',''))
-    src_ll_opt1 = "\x01\x01" + binascii.unhexlify(addr1.replace(':',''))
-
-    # DAD NS
-    send_ns(dev[0], ip_src="::", target="aaaa:bbbb:cccc::2")
-
-    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2")
-    # test frame without source link-layer address option
-    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
-            opt='')
-    # test frame with bogus option
-    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
-            opt="\x70\x01\x01\x02\x03\x04\x05\x05")
-    # test frame with truncated source link-layer address option
-    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
-            opt="\x01\x01\x01\x02\x03\x04")
-    # test frame with foreign source link-layer address option
-    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
-            opt="\x01\x01\x01\x02\x03\x04\x05\x06")
-
-    send_ns(dev[1], ip_src="aaaa:bbbb:dddd::2", target="aaaa:bbbb:dddd::2")
-
-    send_ns(dev[1], ip_src="aaaa:bbbb:eeee::2", target="aaaa:bbbb:eeee::2")
-    # another copy for additional code coverage
-    send_ns(dev[1], ip_src="aaaa:bbbb:eeee::2", target="aaaa:bbbb:eeee::2")
-
     pkt = build_dhcp_ack(dst_ll="ff:ff:ff:ff:ff:ff", src_ll=bssid,
                          ip_src="192.168.1.1", ip_dst="255.255.255.255",
                          yiaddr="192.168.1.124", chaddr=addr0)
@@ -4405,14 +4362,8 @@ def _test_proxyarp_open(dev, apdev, params, ebtables=False):
 
     matches = get_permanent_neighbors("ap-br0")
     logger.info("After connect: " + str(matches))
-    if len(matches) != 4:
+    if len(matches) != 1:
         raise Exception("Unexpected number of neighbor entries after connect")
-    if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches:
-        raise Exception("dev0 addr missing")
-    if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches:
-        raise Exception("dev1 addr(1) missing")
-    if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches:
-        raise Exception("dev1 addr(2) missing")
     if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches:
         raise Exception("dev0 IPv4 addr missing")
 
@@ -4498,38 +4449,6 @@ def _test_proxyarp_open(dev, apdev, params, ebtables=False):
     send_arp(dev[1], sender_ip="192.168.1.127", target_ip="192.168.1.123")
     send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.127")
 
-    time.sleep(0.1)
-
-    send_ns(dev[0], target="aaaa:bbbb:dddd::2", ip_src="aaaa:bbbb:cccc::2")
-    time.sleep(0.1)
-    send_ns(dev[1], target="aaaa:bbbb:cccc::2", ip_src="aaaa:bbbb:dddd::2")
-    time.sleep(0.1)
-    send_ns(hapd, hapd_bssid=bssid, target="aaaa:bbbb:dddd::2",
-            ip_src="aaaa:bbbb:ffff::2")
-    time.sleep(0.1)
-    send_ns(dev[2], target="aaaa:bbbb:cccc::2", ip_src="aaaa:bbbb:ff00::2")
-    time.sleep(0.1)
-    send_ns(dev[2], target="aaaa:bbbb:dddd::2", ip_src="aaaa:bbbb:ff00::2")
-    time.sleep(0.1)
-    send_ns(dev[2], target="aaaa:bbbb:eeee::2", ip_src="aaaa:bbbb:ff00::2")
-    time.sleep(0.1)
-
-    # Try to probe for an already assigned address
-    send_ns(dev[1], target="aaaa:bbbb:cccc::2", ip_src="::")
-    time.sleep(0.1)
-    send_ns(hapd, hapd_bssid=bssid, target="aaaa:bbbb:cccc::2", ip_src="::")
-    time.sleep(0.1)
-    send_ns(dev[2], target="aaaa:bbbb:cccc::2", ip_src="::")
-    time.sleep(0.1)
-
-    # Unsolicited NA
-    send_na(dev[1], target="aaaa:bbbb:cccc:aeae::3",
-            ip_src="aaaa:bbbb:cccc:aeae::3", ip_dst="ff02::1")
-    send_na(hapd, hapd_bssid=bssid, target="aaaa:bbbb:cccc:aeae::4",
-            ip_src="aaaa:bbbb:cccc:aeae::4", ip_dst="ff02::1")
-    send_na(dev[2], target="aaaa:bbbb:cccc:aeae::5",
-            ip_src="aaaa:bbbb:cccc:aeae::5", ip_dst="ff02::1")
-
     try:
         hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
     except Exception, e:
@@ -4621,6 +4540,195 @@ def _test_proxyarp_open(dev, apdev, params, ebtables=False):
     #     bssid, '192.168.1.101' ] not in arp_reply:
     #    raise Exception("br did not get ARP response for 192.168.1.123")
 
+def _test_proxyarp_open_ipv6(dev, apdev, params, ebtables=False):
+    prefix = "proxyarp_open"
+    if ebtables:
+        prefix += "_ebtables"
+    cap_br = os.path.join(params['logdir'], prefix + ".ap-br0.pcap")
+    cap_dev0 = os.path.join(params['logdir'],
+                            prefix + ".%s.pcap" % dev[0].ifname)
+    cap_dev1 = os.path.join(params['logdir'],
+                            prefix + ".%s.pcap" % dev[1].ifname)
+    cap_dev2 = os.path.join(params['logdir'],
+                            prefix + ".%s.pcap" % dev[2].ifname)
+
+    bssid = apdev[0]['bssid']
+    params = { 'ssid': 'open' }
+    params['proxy_arp'] = '1'
+    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
+    hapd.set("ap_isolate", "1")
+    hapd.set('bridge', 'ap-br0')
+    hapd.dump_monitor()
+    try:
+        hapd.enable()
+    except:
+        # For now, do not report failures due to missing kernel support
+        raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
+    ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
+    if ev is None:
+        raise Exception("AP startup timed out")
+    if "AP-ENABLED" not in ev:
+        raise Exception("AP startup failed")
+
+    params2 = { 'ssid': 'another' }
+    hapd2 = hostapd.add_ap(apdev[1], params2, no_enable=True)
+    hapd2.set('bridge', 'ap-br0')
+    hapd2.enable()
+
+    subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
+    subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
+
+    if ebtables:
+        for chain in [ 'FORWARD', 'OUTPUT' ]:
+            subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
+                             '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
+                             '--ip6-icmp-type', 'neighbor-solicitation',
+                             '-o', apdev[0]['ifname'], '-j', 'DROP'])
+            subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
+                             '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
+                             '--ip6-icmp-type', 'neighbor-advertisement',
+                             '-o', apdev[0]['ifname'], '-j', 'DROP'])
+            subprocess.call(['ebtables', '-A', chain,
+                             '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
+                             '--ip6-icmp-type', 'router-solicitation',
+                             '-o', apdev[0]['ifname'], '-j', 'DROP'])
+            # Multicast Listener Report Message
+            subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
+                             '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
+                             '--ip6-icmp-type', '143',
+                             '-o', apdev[0]['ifname'], '-j', 'DROP'])
+
+    time.sleep(0.5)
+    cmd = {}
+    cmd[0] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
+                               '-w', cap_br, '-s', '2000'],
+                              stderr=open('/dev/null', 'w'))
+    cmd[1] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[0].ifname,
+                               '-w', cap_dev0, '-s', '2000'],
+                              stderr=open('/dev/null', 'w'))
+    cmd[2] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[1].ifname,
+                               '-w', cap_dev1, '-s', '2000'],
+                              stderr=open('/dev/null', 'w'))
+    cmd[3] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[2].ifname,
+                               '-w', cap_dev2, '-s', '2000'],
+                              stderr=open('/dev/null', 'w'))
+
+    dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
+    dev[1].connect("open", key_mgmt="NONE", scan_freq="2412")
+    dev[2].connect("another", key_mgmt="NONE", scan_freq="2412")
+    time.sleep(0.1)
+
+    brcmd = subprocess.Popen(['brctl', 'show'], stdout=subprocess.PIPE)
+    res = brcmd.stdout.read()
+    brcmd.stdout.close()
+    logger.info("Bridge setup: " + res)
+
+    brcmd = subprocess.Popen(['brctl', 'showstp', 'ap-br0'],
+                             stdout=subprocess.PIPE)
+    res = brcmd.stdout.read()
+    brcmd.stdout.close()
+    logger.info("Bridge showstp: " + res)
+
+    addr0 = dev[0].p2p_interface_addr()
+    addr1 = dev[1].p2p_interface_addr()
+    addr2 = dev[2].p2p_interface_addr()
+
+    src_ll_opt0 = "\x01\x01" + binascii.unhexlify(addr0.replace(':',''))
+    src_ll_opt1 = "\x01\x01" + binascii.unhexlify(addr1.replace(':',''))
+
+    # DAD NS
+    send_ns(dev[0], ip_src="::", target="aaaa:bbbb:cccc::2")
+
+    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2")
+    # test frame without source link-layer address option
+    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
+            opt='')
+    # test frame with bogus option
+    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
+            opt="\x70\x01\x01\x02\x03\x04\x05\x05")
+    # test frame with truncated source link-layer address option
+    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
+            opt="\x01\x01\x01\x02\x03\x04")
+    # test frame with foreign source link-layer address option
+    send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
+            opt="\x01\x01\x01\x02\x03\x04\x05\x06")
+
+    send_ns(dev[1], ip_src="aaaa:bbbb:dddd::2", target="aaaa:bbbb:dddd::2")
+
+    send_ns(dev[1], ip_src="aaaa:bbbb:eeee::2", target="aaaa:bbbb:eeee::2")
+    # another copy for additional code coverage
+    send_ns(dev[1], ip_src="aaaa:bbbb:eeee::2", target="aaaa:bbbb:eeee::2")
+
+    macs = get_bridge_macs("ap-br0")
+    logger.info("After connect (showmacs): " + str(macs))
+
+    matches = get_permanent_neighbors("ap-br0")
+    logger.info("After connect: " + str(matches))
+    if len(matches) != 3:
+        raise Exception("Unexpected number of neighbor entries after connect")
+    if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches:
+        raise Exception("dev0 addr missing")
+    if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches:
+        raise Exception("dev1 addr(1) missing")
+    if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches:
+        raise Exception("dev1 addr(2) missing")
+
+    send_ns(dev[0], target="aaaa:bbbb:dddd::2", ip_src="aaaa:bbbb:cccc::2")
+    time.sleep(0.1)
+    send_ns(dev[1], target="aaaa:bbbb:cccc::2", ip_src="aaaa:bbbb:dddd::2")
+    time.sleep(0.1)
+    send_ns(hapd, hapd_bssid=bssid, target="aaaa:bbbb:dddd::2",
+            ip_src="aaaa:bbbb:ffff::2")
+    time.sleep(0.1)
+    send_ns(dev[2], target="aaaa:bbbb:cccc::2", ip_src="aaaa:bbbb:ff00::2")
+    time.sleep(0.1)
+    send_ns(dev[2], target="aaaa:bbbb:dddd::2", ip_src="aaaa:bbbb:ff00::2")
+    time.sleep(0.1)
+    send_ns(dev[2], target="aaaa:bbbb:eeee::2", ip_src="aaaa:bbbb:ff00::2")
+    time.sleep(0.1)
+
+    # Try to probe for an already assigned address
+    send_ns(dev[1], target="aaaa:bbbb:cccc::2", ip_src="::")
+    time.sleep(0.1)
+    send_ns(hapd, hapd_bssid=bssid, target="aaaa:bbbb:cccc::2", ip_src="::")
+    time.sleep(0.1)
+    send_ns(dev[2], target="aaaa:bbbb:cccc::2", ip_src="::")
+    time.sleep(0.1)
+
+    # Unsolicited NA
+    send_na(dev[1], target="aaaa:bbbb:cccc:aeae::3",
+            ip_src="aaaa:bbbb:cccc:aeae::3", ip_dst="ff02::1")
+    send_na(hapd, hapd_bssid=bssid, target="aaaa:bbbb:cccc:aeae::4",
+            ip_src="aaaa:bbbb:cccc:aeae::4", ip_dst="ff02::1")
+    send_na(dev[2], target="aaaa:bbbb:cccc:aeae::5",
+            ip_src="aaaa:bbbb:cccc:aeae::5", ip_dst="ff02::1")
+
+    try:
+        hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
+    except Exception, e:
+        logger.info("test_connectibity_iface failed: " + str(e))
+        raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
+    hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0")
+    hwsim_utils.test_connectivity(dev[0], dev[1])
+
+    dev[0].request("DISCONNECT")
+    dev[1].request("DISCONNECT")
+    time.sleep(0.5)
+    for i in range(len(cmd)):
+        cmd[i].terminate()
+    macs = get_bridge_macs("ap-br0")
+    logger.info("After disconnect (showmacs): " + str(macs))
+    matches = get_permanent_neighbors("ap-br0")
+    logger.info("After disconnect: " + str(matches))
+    if len(matches) > 0:
+        raise Exception("Unexpected neighbor entries after disconnect")
+    if ebtables:
+        cmd = subprocess.Popen(['ebtables', '-L', '--Lc'],
+                               stdout=subprocess.PIPE)
+        res = cmd.stdout.read()
+        cmd.stdout.close()
+        logger.info("ebtables results:\n" + res)
+
     ns = tshark_get_ns(cap_dev0)
     logger.info("dev0 seen NS: " + str(ns))
     na = tshark_get_na(cap_dev0)
@@ -4628,7 +4736,10 @@ def _test_proxyarp_open(dev, apdev, params, ebtables=False):
 
     if [ addr0, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2',
          'aaaa:bbbb:dddd::2', addr1 ] not in na:
-        raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
+        # For now, skip the test instead of reporting the error since the IPv6
+        # proxyarp support is not yet in the upstream kernel tree.
+        #raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
+        raise HwsimSkip("Assume kernel did not have the required patches for proxyarp (IPv6)")
 
     if ebtables:
         for req in ns:
@@ -4675,6 +4786,16 @@ def test_proxyarp_open(dev, apdev, params):
         subprocess.call(['brctl', 'delbr', 'ap-br0'],
                         stderr=open('/dev/null', 'w'))
 
+def test_proxyarp_open_ipv6(dev, apdev, params):
+    """ProxyARP with open network (IPv6)"""
+    try:
+        _test_proxyarp_open_ipv6(dev, apdev, params)
+    finally:
+        subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
+                        stderr=open('/dev/null', 'w'))
+        subprocess.call(['brctl', 'delbr', 'ap-br0'],
+                        stderr=open('/dev/null', 'w'))
+
 def test_proxyarp_open_ebtables(dev, apdev, params):
     """ProxyARP with open network"""
     try:
@@ -4690,6 +4811,21 @@ def test_proxyarp_open_ebtables(dev, apdev, params):
         subprocess.call(['brctl', 'delbr', 'ap-br0'],
                         stderr=open('/dev/null', 'w'))
 
+def test_proxyarp_open_ebtables_ipv6(dev, apdev, params):
+    """ProxyARP with open network (IPv6)"""
+    try:
+        _test_proxyarp_open_ipv6(dev, apdev, params, ebtables=True)
+    finally:
+        try:
+            subprocess.call(['ebtables', '-F', 'FORWARD'])
+            subprocess.call(['ebtables', '-F', 'OUTPUT'])
+        except:
+            pass
+        subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
+                        stderr=open('/dev/null', 'w'))
+        subprocess.call(['brctl', 'delbr', 'ap-br0'],
+                        stderr=open('/dev/null', 'w'))
+
 def test_ap_hs20_connect_deinit(dev, apdev):
     """Hotspot 2.0 connection interrupted with deinit"""
     check_eap_capa(dev[0], "MSCHAPV2")
index 40bbb76090a3c31f26c701488c25744d5c2574a5..24661a1cfd5a73883f6143d1f11324fd6d9ffae6 100755 (executable)
@@ -58,10 +58,12 @@ long_tests = [ "ap_roam_open",
                "hostapd_oom_wpa2_eap",
                "ibss_open",
                "proxyarp_open_ebtables",
+               "proxyarp_open_ebtables_ipv6",
                "radius_failover",
                "obss_scan_40_intolerant",
                "dbus_connect_oom",
                "proxyarp_open",
+               "proxyarp_open_ipv6",
                "ap_wps_iteration",
                "ap_wps_iteration_error",
                "ap_wps_pbc_timeout",