From 14f994902ec5a5c639b25a6c70afb4987bc722fa Mon Sep 17 00:00:00 2001 From: JDierkse Date: Wed, 28 Jan 2026 21:29:47 +0100 Subject: [PATCH] Add Gateway Priority Option --- net-dhcp/network.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/net-dhcp/network.py b/net-dhcp/network.py index dfe8607..89e2d1a 100644 --- a/net-dhcp/network.py +++ b/net-dhcp/network.py @@ -61,8 +61,9 @@ def iface_nets(iface): def get_bridges(): get_docker_client() reserved_nets = set(map(ipaddress.ip_network, map(lambda c: c['Subnet'], \ - itertools.chain.from_iterable(map(lambda i: i['Config'], filter(lambda i: i['Driver'] != 'net-dhcp', \ - map(lambda n: n.attrs['IPAM'], dockerClient.networks.list()))))))) + itertools.chain.from_iterable(map(lambda x: [] if x is None else x, \ + map(lambda i: i['Config'], filter(lambda i: i['Driver'] != 'net-dhcp', \ + map(lambda n: n.attrs['IPAM'], dockerClient.networks.list())))))))) return dict(map(lambda i: (i['ifname'], i), filter(lambda i: i['kind'] == 'bridge' and not \ set(iface_nets(i)).intersection(reserved_nets), map(lambda i: interface.GetInterface(LIBRARY, i['ifname']), \ @@ -95,6 +96,7 @@ def endpoint_container_iface(n, e): } break return None + def await_endpoint_container_iface(n, e, timeout=5): start = time.time() iface = None @@ -103,6 +105,8 @@ def await_endpoint_container_iface(n, e, timeout=5): iface = endpoint_container_iface(n, e) except docker.errors.NotFound: time.sleep(0.5) + except KeyError: + time.sleep(0.5) if not iface: raise NetDhcpError('Timed out waiting for container to become availabile') return iface @@ -114,6 +118,17 @@ def endpoint_container_hostname(n, e): return dockerClient.containers.get(cid).attrs['Config']['Hostname'] return None +def endpoint_container_network_gwpriority(n, e): + get_docker_client() + for cid, info in dockerClient.networks.get(n).attrs['Containers'].items(): + if info['EndpointID'] == e: + networkName = dockerClient.networks.get(n).attrs['Name'] + if 'GwPriority' in dockerClient.containers.get(cid).attrs['NetworkSettings']['Networks'][networkName]: + return dockerClient.containers.get(cid).attrs['NetworkSettings']['Networks'][networkName]['GwPriority'] + else: + return 0 + return None + @app.route('/NetworkDriver.GetCapabilities', methods=['POST']) def net_get_capabilities(): return jsonify({ @@ -335,6 +350,7 @@ class ContainerDHCPManager: self.dhcp = None self.dhcp6 = None + self.gwPriority = None self._thread = threading.Thread(target=self.run) self._thread.start() @@ -373,7 +389,7 @@ class ContainerDHCPManager: str(dhcp.iface['ifname'])], timeout=1, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - if dhcp.gateway: + if dhcp.gateway and self.gwPriority >= 0: logger.info('[dhcp container] Replacing gateway with %s', dhcp.gateway) subprocess.check_call(['nsenter', f'-n{dhcp.netns}', '--', '/sbin/ip', 'route', 'replace', 'default', 'via', str(dhcp.gateway)], @@ -393,8 +409,12 @@ class ContainerDHCPManager: try: iface = await_endpoint_container_iface(self.network, self.endpoint) hostname = endpoint_container_hostname(self.network, self.endpoint) + self.gwPriority = endpoint_container_network_gwpriority(self.network, self.endpoint) - self.dhcp = udhcpc.DHCPClient(iface, event_listener=self._on_event, hostname=hostname) + if self.gwPriority >= 0: + self.dhcp = udhcpc.DHCPClient(iface, event_listener=self._on_event, hostname=hostname) + else: + self.dhcp = udhcpc.DHCPClient(iface, event_listener=self._on_event) logger.info('Starting DHCPv4 client on %s in container namespace %s', iface['ifname'], \ self.dhcp.netns)