You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.1 KiB
139 lines
5.1 KiB
# Lint as: python2, python3
|
|
# Copyright 2015 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 dhcpd 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.
|
|
DHCPV6_SERVER_EXECUTABLE = '/usr/local/sbin/dhcpd'
|
|
DHCPV6_SERVER_CONFIG_FILE = '/tmp/dhcpv6_test.conf'
|
|
DHCPV6_SERVER_PID_FILE = '/tmp/dhcpv6_test.pid'
|
|
|
|
DHCPV6_SERVER_ADDRESS = '2001:db8:0:1::1'
|
|
DHCPV6_SERVER_SUBNET_PREFIX = '2001:db8:0:1::'
|
|
DHCPV6_SERVER_SUBNET_PREFIX_LENGTH = 64
|
|
DHCPV6_ADDRESS_RANGE_LOW = 0x100
|
|
DHCPV6_ADDRESS_RANGE_HIGH = 0x1ff
|
|
DHCPV6_PREFIX_DELEGATION_INDEX_LOW = 0x1
|
|
DHCPV6_PREFIX_DELEGATION_INDEX_HIGH = 0xf
|
|
DHCPV6_PREFIX_DELEGATION_RANGE_FORMAT = '2001:db8:0:%x00::'
|
|
DHCPV6_PREFIX_DELEGATION_RANGE_LOW = (DHCPV6_PREFIX_DELEGATION_RANGE_FORMAT %
|
|
(DHCPV6_PREFIX_DELEGATION_INDEX_LOW))
|
|
DHCPV6_PREFIX_DELEGATION_RANGE_HIGH = (DHCPV6_PREFIX_DELEGATION_RANGE_FORMAT %
|
|
(DHCPV6_PREFIX_DELEGATION_INDEX_HIGH))
|
|
DHCPV6_PREFIX_DELEGATION_PREFIX_LENGTH = 56
|
|
DHCPV6_DEFAULT_LEASE_TIME = 600
|
|
DHCPV6_MAX_LEASE_TIME = 7200
|
|
DHCPV6_NAME_SERVERS = 'fec0:0:0:1::1'
|
|
DHCPV6_DOMAIN_SEARCH = 'domain.example'
|
|
|
|
CONFIG_DEFAULT_LEASE_TIME = 'default_lease_time'
|
|
CONFIG_MAX_LEASE_TIME = 'max_lease_time'
|
|
CONFIG_SUBNET = 'subnet'
|
|
CONFIG_RANGE = 'range'
|
|
CONFIG_NAME_SERVERS = 'name_servers'
|
|
CONFIG_DOMAIN_SEARCH = 'domain_search'
|
|
CONFIG_PREFIX_RANGE = 'prefix_range'
|
|
|
|
class Dhcpv6TestServer(object):
|
|
"""
|
|
This is an embodiment of the DHCPv6 server (dhcpd) process. It converts an
|
|
config dict into parameters for the dhcpd configuration file and
|
|
manages startup and cleanup of the process.
|
|
"""
|
|
|
|
def __init__(self, interface = None):
|
|
if not os.path.exists(DHCPV6_SERVER_EXECUTABLE):
|
|
raise error.TestNAError('Could not find executable %s; '
|
|
'this is likely an old version of '
|
|
'ChromiumOS' %
|
|
DHCPV6_SERVER_EXECUTABLE)
|
|
self._interface = interface
|
|
# "2001:db8:0:1::/64"
|
|
subnet = '%s/%d' % (DHCPV6_SERVER_SUBNET_PREFIX,
|
|
DHCPV6_SERVER_SUBNET_PREFIX_LENGTH)
|
|
# "2001:db8:0:1::100 2001:db8:1::1ff"
|
|
range = '%s%x %s%x' % (DHCPV6_SERVER_SUBNET_PREFIX,
|
|
DHCPV6_ADDRESS_RANGE_LOW,
|
|
DHCPV6_SERVER_SUBNET_PREFIX,
|
|
DHCPV6_ADDRESS_RANGE_HIGH)
|
|
# "2001:db8:0:100:: 2001:db8:1:f00:: /56"
|
|
prefix_range = '%s %s /%d' % (DHCPV6_PREFIX_DELEGATION_RANGE_LOW,
|
|
DHCPV6_PREFIX_DELEGATION_RANGE_HIGH,
|
|
DHCPV6_PREFIX_DELEGATION_PREFIX_LENGTH)
|
|
self._config = {
|
|
CONFIG_DEFAULT_LEASE_TIME: DHCPV6_DEFAULT_LEASE_TIME,
|
|
CONFIG_MAX_LEASE_TIME: DHCPV6_MAX_LEASE_TIME,
|
|
CONFIG_SUBNET: subnet,
|
|
CONFIG_RANGE: range,
|
|
CONFIG_NAME_SERVERS: DHCPV6_NAME_SERVERS,
|
|
CONFIG_DOMAIN_SEARCH: DHCPV6_DOMAIN_SEARCH,
|
|
CONFIG_PREFIX_RANGE: prefix_range
|
|
}
|
|
|
|
|
|
def _write_config_file(self):
|
|
"""
|
|
Write out a configuration file for DHCPv6 server to use.
|
|
"""
|
|
config = '\n'.join([
|
|
'default-lease-time %(default_lease_time)d;',
|
|
'max-lease-time %(max_lease_time)d;',
|
|
'subnet6 %(subnet)s {',
|
|
' range6 %(range)s;',
|
|
' option dhcp6.name-servers %(name_servers)s;',
|
|
' option dhcp6.domain-search \"%(domain_search)s\";',
|
|
' prefix6 %(prefix_range)s;',
|
|
'}'
|
|
'']) % self._config
|
|
with open(DHCPV6_SERVER_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(DHCPV6_SERVER_PID_FILE):
|
|
with open(DHCPV6_SERVER_PID_FILE) as rf:
|
|
pid = int(rf.read())
|
|
os.remove(DHCPV6_SERVER_PID_FILE)
|
|
try:
|
|
os.kill(pid, signal.SIGTERM)
|
|
except OSError:
|
|
pass
|
|
if os.path.exists(DHCPV6_SERVER_CONFIG_FILE):
|
|
os.remove(DHCPV6_SERVER_CONFIG_FILE)
|
|
|
|
|
|
def start(self):
|
|
"""
|
|
Start the DHCPv6 server. The server will daemonize itself and
|
|
run in the background.
|
|
"""
|
|
self._cleanup()
|
|
self._write_config_file()
|
|
utils.system('%s -6 -pf %s -cf %s %s' %
|
|
(DHCPV6_SERVER_EXECUTABLE,
|
|
DHCPV6_SERVER_PID_FILE,
|
|
DHCPV6_SERVER_CONFIG_FILE,
|
|
self._interface))
|
|
|
|
|
|
def stop(self):
|
|
"""
|
|
Halt the DHCPv6 server.
|
|
"""
|
|
self._cleanup()
|