Use gateway from DHCP

pull/8/head
Jack O'Sullivan 5 years ago
parent 05aec4b0f8
commit 02d5109ced

@ -27,6 +27,17 @@ client = docker.from_env()
def close_docker():
client.close()
host_dhcp_clients = {}
container_dhcp_clients = {}
@atexit.register
def cleanup_dhcp():
for endpoint, dhcp in host_dhcp_clients.items():
logger.warning('cleaning up orphaned host DHCP client (endpoint "%s")', endpoint)
dhcp.finish(timeout=1)
for endpoint, dhcp in container_dhcp_clients.items():
logger.warning('cleaning up orphaned container DHCP client (endpoint "%s")', endpoint)
dhcp.finish(timeout=1)
def veth_pair(e):
return f'dh-{e[:12]}', f'{e[:12]}-dh'
@ -114,10 +125,10 @@ def create_endpoint():
if addr.ip == bridge_addr.ip:
raise NetDhcpError(400, f'Address {addr} is already in use on bridge {bridge["ifname"]}')
elif type_ == 'v4':
dhcp = udhcpc.DHCPClient(if_container['ifname'], once=True)
dhcp.finish()
addr = dhcp.ip
dhcp = udhcpc.DHCPClient(if_container['ifname'])
addr = dhcp.await_ip(timeout=10)
res_iface['Address'] = str(addr)
host_dhcp_clients[req['EndpointID']] = dhcp
else:
raise NetDhcpError(400, f'DHCPv6 is currently unsupported')
logger.info('Adding address %s to %s', addr, if_container['ifname'])
@ -180,6 +191,7 @@ def delete_endpoint():
@app.route('/NetworkDriver.Join', methods=['POST'])
def join():
req = request.get_json(force=True)
endpoint = req['EndpointID']
bridge = net_bridge(req['NetworkID'])
_if_host, if_container = veth_pair(req['EndpointID'])
@ -191,6 +203,13 @@ def join():
},
'StaticRoutes': []
}
if endpoint in host_dhcp_clients:
dhcp = host_dhcp_clients[endpoint]
logger.info('Setting IPv4 gateway from DHCP (%s)', dhcp.gateway)
res['Gateway'] = str(dhcp.gateway)
dhcp.finish(timeout=1)
del host_dhcp_clients[endpoint]
ipv6 = ipv6_enabled(req['NetworkID'])
for route in bridge.routes:
if route['type'] != rtypes['RTN_UNICAST'] or (route['family'] == socket.AF_INET6 and not ipv6):

@ -1,6 +1,7 @@
from enum import Enum
import ipaddress
from os import path
import time
import threading
import subprocess
import logging
@ -9,6 +10,7 @@ from pyroute2.netns.process.proxy import NSPopen
INFO_PREFIX = '__info'
HANDLER_SCRIPT = path.join(path.dirname(__file__), 'udhcpc_handler.py')
AWAIT_INTERVAL = 0.1
class EventType(Enum):
BOUND = 'bound'
@ -62,12 +64,22 @@ class DHCPClient:
logger.debug('[udhcp event] %s %s %s %s', event_type, self.ip, self.gateway, self.domain)
self.event_listener(event_type, self.ip, self.gateway, self.domain)
def finish(self):
def await_ip(self, timeout=5):
# TODO: this bad
waited = 0
while not self.ip:
if waited >= timeout:
raise DHCPClientError('Timed out waiting for dhcp lease')
time.sleep(AWAIT_INTERVAL)
waited += AWAIT_INTERVAL
return self.ip
def finish(self, timeout=5):
if not self.once:
self.proc.terminate()
if self.proc.wait(timeout=10) != 0:
if self.proc.wait(timeout=timeout) != 0:
raise DHCPClientError(f'udhcpc exited with non-zero exit code {self.proc.returncode}')
self._event_thread.join()
if self.once and not self.ip:
raise DHCPClientError(f'failed to obtain lease')
raise DHCPClientError(f'Timed out waiting for dhcp lease')

Loading…
Cancel
Save