1 # Copyright 2016 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 import logging 6 import time 7 8 from autotest_lib.client.common_lib import error 9 from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes 10 from autotest_lib.server.cros.network import wifi_cell_test_base 11 from autotest_lib.server.cros.network import hostap_config 12 from autotest_lib.server.cros.packet_generation import IP_utils 13 14 LIFETIME_FRACTION = 6 15 LIFETIME = 180 16 INTERVAL = 2 17 18 class network_WiFi_IPv6RA(wifi_cell_test_base.WiFiCellTestBase): 19 """Test that we can drop/accept various IPv6 RAs.""" 20 version = 1 21 22 def _cleanup(self, client_conf, router, ip_utils): 23 """Deconfigure AP and cleanup test resources. 24 25 @param client_conf: association parameters for test. 26 @param router: Router host object. 27 @param ip_utils object to cleanup. 28 29 """ 30 self.context.client.shill.disconnect(client_conf.ssid) 31 self.context.client.shill.delete_entries_for_ssid(client_conf.ssid) 32 self.context.router.deconfig() 33 self.context.capture_host.stop_capture() 34 ip_utils.cleanup_scapy() 35 36 37 def run_once(self): 38 """Sets up a router, connects to it, and sends RAs.""" 39 client_conf = xmlrpc_datatypes.AssociationParameters() 40 client_mac = self.context.client.wifi_mac 41 self.context.router.deconfig() 42 ap_config = hostap_config.HostapConfig(channel=6, 43 mode=hostap_config.HostapConfig.MODE_11G, 44 ssid='OnHubWiFi_ch6_802.11g') 45 self.context.configure(ap_config) 46 self.context.capture_host.start_capture(2437, ht_type='HT20') 47 client_conf.ssid = self.context.router.get_ssid() 48 assoc_result = self.context.assert_connect_wifi(client_conf) 49 self.context.client.collect_debug_info(client_conf.ssid) 50 51 with self.context.client.assert_no_disconnects(): 52 self.context.assert_ping_from_dut() 53 if self.context.router.detect_client_deauth(client_mac): 54 raise error.TestFail( 55 'Client de-authenticated during the test') 56 57 # Sleep for 10 seconds to put the phone in WoW mode. 58 time.sleep(10) 59 60 ip_utils = IP_utils.IPutils(self.context.router.host) 61 ip_utils.install_scapy() 62 ra_count = ip_utils.get_icmp6intype134(self.context.client.host) 63 64 # Start scapy to send RA to the phone's MAC 65 ip_utils.send_ra(mac=client_mac, interval=0, count=1) 66 ra_count_latest = ip_utils.get_icmp6intype134(self.context.client.host) 67 68 # The phone should accept the first unique RA in sequence. 69 if ra_count_latest != ra_count + 1: 70 logging.debug('Device dropped the first RA in sequence') 71 raise error.TestFail('Device dropped the first RA in sequence.') 72 73 # Generate and send 'x' number of duplicate RAs, for 1/6th of the the 74 # lifetime of the original RA. Test assumes that the original RA has a 75 # lifetime of 180s. Hence, all RAs received within the next 30s of the 76 # original RA should be filtered. 77 ra_count = ra_count_latest 78 count = LIFETIME / LIFETIME_FRACTION / INTERVAL 79 ip_utils.send_ra(mac=client_mac, interval=INTERVAL, count=count) 80 ra_count_latest = ip_utils.get_icmp6intype134(self.context.client.host) 81 pkt_loss = count - (ra_count_latest - ra_count) 82 percentage_loss = float(pkt_loss) / count * 100 83 84 # Fail test if at least 90% of RAs were not dropped. 85 if percentage_loss < 90: 86 logging.debug('Device did not filter duplicate RAs correctly.' 87 '%d Percent of duplicate RAs were accepted' % 88 (100 - percentage_loss)) 89 raise error.TestFail('Device accepted a duplicate RA.') 90 91 # Any new RA after this should be accepted. 92 ip_utils.send_ra(mac=client_mac, interval=INTERVAL, count=2) 93 ra_count_latest = ip_utils.get_icmp6intype134(self.context.client.host) 94 if ra_count_latest != ra_count + 1: 95 logging.debug('Device did not accept new RA after 1/6th time' 96 ' interval.') 97 raise error.TestFail('Device dropped a valid RA in sequence.') 98 99 self._cleanup(client_conf, self.context.router.host, ip_utils) 100