diff --git a/tests/hwsim/test_ap_hs20.py b/tests/hwsim/test_ap_hs20.py index e4354750e..af501af22 100644 --- a/tests/hwsim/test_ap_hs20.py +++ b/tests/hwsim/test_ap_hs20.py @@ -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") diff --git a/tests/hwsim/vm/parallel-vm.py b/tests/hwsim/vm/parallel-vm.py index 40bbb7609..24661a1cf 100755 --- a/tests/hwsim/vm/parallel-vm.py +++ b/tests/hwsim/vm/parallel-vm.py @@ -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",