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