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