1# Copyright 2015 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
5from autotest_lib.client.common_lib import error
6from autotest_lib.client.common_lib.cros.network import interface
7from autotest_lib.client.cros import dhcp_handling_rule
8from autotest_lib.client.cros import dhcp_packet
9from autotest_lib.client.cros import dhcp_test_base
10from autotest_lib.client.cros.networking import shill_proxy
11
12# Length of time the lease from the DHCP server is valid.
13LEASE_TIME_SECONDS = 60
14# We'll fill in the subnet and give this address to the client.
15INTENDED_IP_SUFFIX = '0.0.0.101'
16# We should be able to complete a DHCP negotiation in this amount of time.
17DHCP_NEGOTIATION_TIMEOUT_SECONDS = 10
18
19class network_DhcpBrokenDefaultGateway(dhcp_test_base.DhcpTestBase):
20    """Test application of broken gateway route from DHCP server."""
21
22    def check_shill_gateway_setup(self, interface_name, gateway_ip):
23        """Check that the ipconfig in the client shows the gateway IP.
24
25        @param interface_name string client network interface name.
26        @param gateway_ip string expected gateway IP address.
27
28        """
29        proxy = shill_proxy.ShillProxy()
30        device = proxy.find_object('Device', {'Name': interface_name})
31        if device is None:
32            raise error.TestFail('Device was not found.')
33        device_properties = device.GetProperties(utf8_strings=True)
34        ipconfig_path = device_properties['IPConfigs'][0]
35        ipconfig = proxy.get_dbus_object('org.chromium.flimflam.IPConfig',
36                                         ipconfig_path)
37        ipconfig_properties = ipconfig.GetProperties(utf8_strings=True)
38        ipconfig_gateway = ipconfig_properties['Gateway']
39        if ipconfig_gateway != gateway_ip:
40            raise error.TestFail('Shill gateway %s does '
41                                 'not match expected %s.' %
42                                 (ipconfig_gateway, gateway_ip))
43
44
45    def check_routing_table_gateway_setup(self, interface_name, gateway_ip):
46        """Check that the routing table in the client shows the gateway IP.
47
48        @param interface_name string client network interface name.
49        @param gateway_ip string expected gateway IP address.
50
51        """
52        default_route = interface.get_prioritized_default_route(
53            host=None, interface_name_regex=interface_name)
54        if not default_route:
55            raise error.TestFail('No default route found.')
56        if default_route.gateway != gateway_ip:
57            raise error.TestFail('Routing table gateway %s does '
58                                 'not match expected %s.' %
59                                 (default_route.gateway, gateway_ip))
60
61
62    def test_body(self):
63        """Main body of the test."""
64        subnet_mask = self.ethernet_pair.interface_subnet_mask
65        intended_ip = dhcp_test_base.DhcpTestBase.rewrite_ip_suffix(
66                subnet_mask,
67                self.server_ip,
68                INTENDED_IP_SUFFIX)
69        # Pick an address that's unlikely to be in the broadcast domain of the
70        # virtual network pair.
71        gateway_ip = "10.11.12.13"
72        # Two real name servers, and a bogus one to be unpredictable.
73        dns_servers = ['8.8.8.8', '8.8.4.4', '192.168.87.88']
74        vendor_options = 'ANDROID_METERED'
75        # This is the pool of information the server will give out to the client
76        # upon request.
77        dhcp_options = {
78                dhcp_packet.OPTION_SERVER_ID : self.server_ip,
79                dhcp_packet.OPTION_SUBNET_MASK : subnet_mask,
80                dhcp_packet.OPTION_IP_LEASE_TIME : LEASE_TIME_SECONDS,
81                dhcp_packet.OPTION_REQUESTED_IP : intended_ip,
82                dhcp_packet.OPTION_DNS_SERVERS : dns_servers,
83                dhcp_packet.OPTION_ROUTERS : [ gateway_ip ],
84                }
85        rules = [
86                dhcp_handling_rule.DhcpHandlingRule_RespondToDiscovery(
87                        intended_ip, self.server_ip, dhcp_options, {}),
88                dhcp_handling_rule.DhcpHandlingRule_RespondToRequest(
89                        intended_ip, self.server_ip, dhcp_options, {})
90                ]
91        rules[-1].is_final_handler = True
92
93        self.server.start_test(rules, DHCP_NEGOTIATION_TIMEOUT_SECONDS)
94        self.server.wait_for_test_to_finish()
95        if not self.server.last_test_passed:
96            raise error.TestFail('Test server didn\'t get all the messages it '
97                                 'was told to expect during negotiation.')
98
99        self.wait_for_dhcp_propagation()
100        interface_name = self.ethernet_pair.peer_interface_name
101        self.check_shill_gateway_setup(interface_name, gateway_ip)
102        self.check_routing_table_gateway_setup(interface_name, gateway_ip)
103