142 lines
5.0 KiB
Python
142 lines
5.0 KiB
Python
# Lint as: python2, python3
|
|
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""
|
|
Encapsulate functionality of the Linux IPv6 Router Advertisement Daemon.
|
|
Support writing out a configuration file as well as starting and stopping
|
|
the service.
|
|
"""
|
|
|
|
import os
|
|
import signal
|
|
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.client.common_lib import utils
|
|
|
|
# Filenames used for execution.
|
|
RADVD_EXECUTABLE = '/usr/local/sbin/radvd'
|
|
RADVD_CONFIG_FILE = '/tmp/radvd_test.conf'
|
|
RADVD_PID_FILE = '/tmp/radvd_test.pid'
|
|
|
|
# These are default configuration values.
|
|
RADVD_DEFAULT_ADV_ON_LINK = 'on'
|
|
RADVD_DEFAULT_ADV_AUTONOMOUS = 'on'
|
|
RADVD_DEFAULT_ADV_ROUTER_ADDR = 'on'
|
|
RADVD_DEFAULT_ADV_RDNSS_LIFETIME = 'infinity'
|
|
RADVD_DEFAULT_DNSSL_LIST = 'a.com b.com'
|
|
RADVD_DEFAULT_MAX_ADV_INTERVAL = 10
|
|
RADVD_DEFAULT_MIN_ADV_INTERVAL = 3
|
|
RADVD_DEFAULT_SEND_ADVERT = 'on'
|
|
|
|
# The addresses below are within the 2001:0db8/32 "documentation only" prefix
|
|
# (RFC3849), which is guaranteed never to be assigned to a real network.
|
|
RADVD_DEFAULT_SUFFIX = '/64'
|
|
RADVD_DEFAULT_PREFIX = '2001:db8:100:f101::/64'
|
|
RADVD_DEFAULT_RDNSS_SERVERS = ( '2001:db8:100:f101::1 '
|
|
'2001:db8:100:f101::2' )
|
|
|
|
# Option names.
|
|
OPTION_ADV_ON_LINK = 'adv_on_link'
|
|
OPTION_ADV_AUTONOMOUS = 'adv_autonomous'
|
|
OPTION_ADV_ROUTER_ADDR = 'adv_router_addr'
|
|
OPTION_ADV_RDNSS_LIFETIME = 'adv_rdnss_lifetime'
|
|
OPTION_DNSSL_LIST = 'dnssl_list'
|
|
OPTION_INTERFACE = 'interface'
|
|
OPTION_MAX_ADV_INTERVAL = 'max_adv_interval'
|
|
OPTION_MIN_ADV_INTERVAL = 'min_adv_interval'
|
|
OPTION_PREFIX = 'prefix'
|
|
OPTION_RDNSS_SERVERS = 'rdnss_servers'
|
|
OPTION_SEND_ADVERT = 'adv_send_advert'
|
|
|
|
class RadvdServer(object):
|
|
"""
|
|
This is an embodiment of the radvd server process. It converts an
|
|
option dict into parameters for the radvd configuration file and
|
|
manages startup and cleanup of the process.
|
|
"""
|
|
|
|
def __init__(self, interface = None):
|
|
if not os.path.exists(RADVD_EXECUTABLE):
|
|
raise error.TestNAError('Could not find executable %s; '
|
|
'this is likely an old version of '
|
|
'ChromiumOS' %
|
|
RADVD_EXECUTABLE)
|
|
self._options = {
|
|
OPTION_INTERFACE: interface,
|
|
OPTION_ADV_ON_LINK: RADVD_DEFAULT_ADV_ON_LINK,
|
|
OPTION_ADV_AUTONOMOUS: RADVD_DEFAULT_ADV_AUTONOMOUS,
|
|
OPTION_ADV_ROUTER_ADDR: RADVD_DEFAULT_ADV_ROUTER_ADDR,
|
|
OPTION_ADV_RDNSS_LIFETIME: RADVD_DEFAULT_ADV_RDNSS_LIFETIME,
|
|
OPTION_DNSSL_LIST: RADVD_DEFAULT_DNSSL_LIST,
|
|
OPTION_MAX_ADV_INTERVAL: RADVD_DEFAULT_MAX_ADV_INTERVAL,
|
|
OPTION_MIN_ADV_INTERVAL: RADVD_DEFAULT_MIN_ADV_INTERVAL,
|
|
OPTION_PREFIX: RADVD_DEFAULT_PREFIX,
|
|
OPTION_RDNSS_SERVERS: RADVD_DEFAULT_RDNSS_SERVERS,
|
|
OPTION_SEND_ADVERT: RADVD_DEFAULT_SEND_ADVERT
|
|
}
|
|
|
|
@property
|
|
def options(self):
|
|
"""
|
|
Property dict used to generate configuration file.
|
|
"""
|
|
return self._options
|
|
|
|
def _write_config_file(self):
|
|
"""
|
|
Write out a configuration file for radvd to use.
|
|
"""
|
|
config = '\n'.join([
|
|
'interface %(interface)s {',
|
|
' AdvSendAdvert %(adv_send_advert)s;',
|
|
' MinRtrAdvInterval %(min_adv_interval)d;',
|
|
' MaxRtrAdvInterval %(max_adv_interval)d;',
|
|
' prefix %(prefix)s {',
|
|
' AdvOnLink %(adv_on_link)s;',
|
|
' AdvAutonomous %(adv_autonomous)s;',
|
|
' AdvRouterAddr %(adv_router_addr)s;',
|
|
' };',
|
|
' RDNSS %(rdnss_servers)s {',
|
|
' AdvRDNSSLifetime %(adv_rdnss_lifetime)s;',
|
|
' };',
|
|
' DNSSL %(dnssl_list)s {',
|
|
' };',
|
|
'};',
|
|
'']) % self.options
|
|
with open(RADVD_CONFIG_FILE, 'w') as f:
|
|
f.write(config)
|
|
|
|
def _cleanup(self):
|
|
"""
|
|
Cleanup temporary files. If PID file exists, also kill the
|
|
associated process.
|
|
"""
|
|
if os.path.exists(RADVD_PID_FILE):
|
|
with open(RADVD_PID_FILE, 'r') as rf:
|
|
pid = int(rf.read())
|
|
os.remove(RADVD_PID_FILE)
|
|
try:
|
|
os.kill(pid, signal.SIGTERM)
|
|
except OSError:
|
|
pass
|
|
if os.path.exists(RADVD_CONFIG_FILE):
|
|
os.remove(RADVD_CONFIG_FILE)
|
|
|
|
def start_server(self):
|
|
"""
|
|
Start the radvd server. The server will daemonize itself and
|
|
run in the background.
|
|
"""
|
|
self._cleanup()
|
|
self._write_config_file()
|
|
utils.system('%s -p %s -C %s' %
|
|
(RADVD_EXECUTABLE, RADVD_PID_FILE, RADVD_CONFIG_FILE))
|
|
|
|
def stop_server(self):
|
|
"""
|
|
Halt the radvd server.
|
|
"""
|
|
self._cleanup()
|