From 0982927c1bfe2a91b8244e148e3d7098b7c44ede Mon Sep 17 00:00:00 2001 From: Dominique Roux Date: Thu, 23 Jan 2020 18:43:41 +0100 Subject: [PATCH] Added DNSmasq ability for RA --- uncloud/hack/main.py | 10 ++++++---- uncloud/hack/net.py | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/uncloud/hack/main.py b/uncloud/hack/main.py index f275e62..281c251 100644 --- a/uncloud/hack/main.py +++ b/uncloud/hack/main.py @@ -54,8 +54,10 @@ def main(arguments): vb._route_network() if arguments['run_dns_ra']: - if not arguments['network']: - raise UncloudException("Providing DNS/RAs requires a /64 IPv6 network. You can use fd00::/64 for testing (non production!)") + if not arguments['network'] or not arguments['vni']: + raise UncloudException("Providing DNS/RAs requires a /64 IPv6 network and a VNI. You can use fd00::/64 and vni=1 for testing (non production!)") - dnsra = DNSRA(arguments['network']) - dnsra.setup() + dnsra = DNSRA(route=arguments['network'], + vni=arguments['vni'], + use_sudo=arguments['use_sudo']) + dnsra._setup_dnsmasq() diff --git a/uncloud/hack/net.py b/uncloud/hack/net.py index e18b36a..b036198 100644 --- a/uncloud/hack/net.py +++ b/uncloud/hack/net.py @@ -77,9 +77,41 @@ class ManagementBridge(VXLANBridge): class DNSRA(object): - def __init__(self): - pass + # VXLAN ids are at maximum 24 bit + max_vni = (2**24)-1 + # Command to start dnsmasq + cmd_start_dnsmasq="{sudo}dnsmasq --interface={bridgedev} --bind-interfaces --dhcp-range={route},ra-only,infinite --enable-ra" + + def __init__(self, + vni, + route=None, + use_sudo=False): + self.config = {} + + if vni > self.max_vni: + raise UncloudException("VNI must be in the range of 0 .. {}".format(self.max_vni)) + + if use_sudo: + self.config['sudo'] = 'sudo ' + + #TODO: remove if not needed + #self.config['vni_dec'] = vni + self.config['vni_hex'] = "{:x}".format(vni) + + # dnsmasq only wants the network without the prefix, therefore, cut it off + self.config['route'] = ipaddress.IPv6Network(route).network_address + self.config['bridgedev'] = "br{}".format(self.config['vni_hex']) + + def _setup_dnsmasq(self): + self._execute_cmd(self.cmd_start_dnsmasq) + + def _execute_cmd(self, cmd_string, **kwargs): + cmd = cmd_string.format(**self.config, **kwargs) + log.info("Executing: {}".format(cmd)) + print("Executing: {}".format(cmd)) + subprocess.run(cmd.split()) + class Firewall(object): pass