• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2013 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"""
6Encapsulate functionality of the Linux IPv6 Router Advertisement Daemon.
7Support writing out a configuration file as well as starting and stopping
8the service.
9"""
10
11import os
12import signal
13
14from autotest_lib.client.common_lib import error
15from autotest_lib.client.common_lib import utils
16
17# Filenames used for execution.
18RADVD_EXECUTABLE = '/usr/local/sbin/radvd'
19RADVD_CONFIG_FILE = '/tmp/radvd_test.conf'
20RADVD_PID_FILE = '/tmp/radvd_test.pid'
21
22# These are default configuration values.
23RADVD_DEFAULT_ADV_ON_LINK = 'on'
24RADVD_DEFAULT_ADV_AUTONOMOUS = 'on'
25RADVD_DEFAULT_ADV_ROUTER_ADDR = 'on'
26RADVD_DEFAULT_ADV_RDNSS_LIFETIME = 'infinity'
27RADVD_DEFAULT_DNSSL_LIST = 'a.com b.com'
28RADVD_DEFAULT_MAX_ADV_INTERVAL = 10
29RADVD_DEFAULT_MIN_ADV_INTERVAL = 3
30RADVD_DEFAULT_SEND_ADVERT = 'on'
31
32# The addresses below are within the  2001:0db8/32 "documentation only" prefix
33# (RFC3849), which is guaranteed never to be assigned to a real network.
34RADVD_DEFAULT_SUFFIX = '/64'
35RADVD_DEFAULT_PREFIX = '2001:db8:100:f101::/64'
36RADVD_DEFAULT_RDNSS_SERVERS = ( '2001:db8:100:f101::1 '
37                                '2001:db8:100:f101::2' )
38
39# Option names.
40OPTION_ADV_ON_LINK = 'adv_on_link'
41OPTION_ADV_AUTONOMOUS = 'adv_autonomous'
42OPTION_ADV_ROUTER_ADDR = 'adv_router_addr'
43OPTION_ADV_RDNSS_LIFETIME = 'adv_rdnss_lifetime'
44OPTION_DNSSL_LIST = 'dnssl_list'
45OPTION_INTERFACE = 'interface'
46OPTION_MAX_ADV_INTERVAL = 'max_adv_interval'
47OPTION_MIN_ADV_INTERVAL = 'min_adv_interval'
48OPTION_PREFIX = 'prefix'
49OPTION_RDNSS_SERVERS = 'rdnss_servers'
50OPTION_SEND_ADVERT = 'adv_send_advert'
51
52class RadvdServer(object):
53    """
54    This is an embodiment of the radvd server process.  It converts an
55    option dict into parameters for the radvd configuration file and
56    manages startup and cleanup of the process.
57    """
58
59    def __init__(self, interface = None):
60        if not os.path.exists(RADVD_EXECUTABLE):
61            raise error.TestNAError('Could not find executable %s; '
62                                    'this is likely an old version of '
63                                    'ChromiumOS' %
64                                    RADVD_EXECUTABLE)
65        self._options = {
66            OPTION_INTERFACE: interface,
67            OPTION_ADV_ON_LINK: RADVD_DEFAULT_ADV_ON_LINK,
68            OPTION_ADV_AUTONOMOUS: RADVD_DEFAULT_ADV_AUTONOMOUS,
69            OPTION_ADV_ROUTER_ADDR: RADVD_DEFAULT_ADV_ROUTER_ADDR,
70            OPTION_ADV_RDNSS_LIFETIME: RADVD_DEFAULT_ADV_RDNSS_LIFETIME,
71            OPTION_DNSSL_LIST: RADVD_DEFAULT_DNSSL_LIST,
72            OPTION_MAX_ADV_INTERVAL: RADVD_DEFAULT_MAX_ADV_INTERVAL,
73            OPTION_MIN_ADV_INTERVAL: RADVD_DEFAULT_MIN_ADV_INTERVAL,
74            OPTION_PREFIX: RADVD_DEFAULT_PREFIX,
75            OPTION_RDNSS_SERVERS: RADVD_DEFAULT_RDNSS_SERVERS,
76            OPTION_SEND_ADVERT: RADVD_DEFAULT_SEND_ADVERT
77        }
78
79    @property
80    def options(self):
81        """
82        Property dict used to generate configuration file.
83        """
84        return self._options
85
86    def _write_config_file(self):
87        """
88        Write out a configuration file for radvd to use.
89        """
90        config = '\n'.join([
91                     'interface %(interface)s {',
92                     '  AdvSendAdvert %(adv_send_advert)s;',
93                     '  MinRtrAdvInterval %(min_adv_interval)d;',
94                     '  MaxRtrAdvInterval %(max_adv_interval)d;',
95                     '  prefix %(prefix)s {',
96                     '    AdvOnLink %(adv_on_link)s;',
97                     '    AdvAutonomous %(adv_autonomous)s;',
98                     '    AdvRouterAddr %(adv_router_addr)s;',
99                     '  };',
100                     '  RDNSS %(rdnss_servers)s {',
101                     '    AdvRDNSSLifetime %(adv_rdnss_lifetime)s;',
102                     '  };',
103                     '  DNSSL %(dnssl_list)s {',
104                     '  };',
105                     '};',
106                     '']) % self.options
107        with open(RADVD_CONFIG_FILE, 'w') as f:
108            f.write(config)
109
110    def _cleanup(self):
111        """
112        Cleanup temporary files.  If PID file exists, also kill the
113        associated process.
114        """
115        if os.path.exists(RADVD_PID_FILE):
116            pid = int(file(RADVD_PID_FILE).read())
117            os.remove(RADVD_PID_FILE)
118            try:
119                os.kill(pid, signal.SIGTERM)
120            except OSError:
121                pass
122        if os.path.exists(RADVD_CONFIG_FILE):
123            os.remove(RADVD_CONFIG_FILE)
124
125    def start_server(self):
126        """
127        Start the radvd server.  The server will daemonize itself and
128        run in the background.
129        """
130        self._cleanup()
131        self._write_config_file()
132        utils.system('%s -p %s -C %s' %
133                     (RADVD_EXECUTABLE, RADVD_PID_FILE, RADVD_CONFIG_FILE))
134
135    def stop_server(self):
136        """
137        Halt the radvd server.
138        """
139        self._cleanup()
140