diff options
author | Eric Lafontaine <eric.lafontaine@bell.ca> | 2019-12-09 19:48:37 -0500 |
---|---|---|
committer | Ryan Harper <ryan.harper@canonical.com> | 2019-12-09 18:48:37 -0600 |
commit | a47405af306219d804ed262d6f7e2039a75883f2 (patch) | |
tree | e26cac0fc0ebae67ee984e1901299f7dd9eff965 /cloudinit/net/dhcp.py | |
parent | 34ec440c1ad61c23c34b46f1798813d0f3ada952 (diff) | |
download | vyos-cloud-init-a47405af306219d804ed262d6f7e2039a75883f2.tar.gz vyos-cloud-init-a47405af306219d804ed262d6f7e2039a75883f2.zip |
dhcp: Support RedHat dhcp rfc3442 lease format for option 121 (#76)
RedHat dhcp client writes out rfc3442 classless-static-routes in a different format[1]
than what is found in isc-dhcp clients. This patch adds support for the RedHat format.
1. Background details on the format
https://bugzilla.redhat.com/show_bug.cgi?id=516325
https://github.com/vaijab/fedora-dhcp/blob/e83fb19c51765442d77fa60596bfdb2b3b9fbe2e/dhcp-rfc3442-classless-static-routes.patch#L252
https://github.com/heftig/NetworkManager/blob/f56c82d86122fc45304fc829b5f1e4766ed51589/src/dhcp-manager/nm-dhcp-client.c#L978
LP: #1850642
Diffstat (limited to 'cloudinit/net/dhcp.py')
-rw-r--r-- | cloudinit/net/dhcp.py | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py index 17379918..c033cc8e 100644 --- a/cloudinit/net/dhcp.py +++ b/cloudinit/net/dhcp.py @@ -92,9 +92,12 @@ class EphemeralDHCPv4(object): nmap = {'interface': 'interface', 'ip': 'fixed-address', 'prefix_or_mask': 'subnet-mask', 'broadcast': 'broadcast-address', - 'static_routes': 'rfc3442-classless-static-routes', + 'static_routes': [ + 'rfc3442-classless-static-routes', + 'classless-static-routes' + ], 'router': 'routers'} - kwargs = dict([(k, self.lease.get(v)) for k, v in nmap.items()]) + kwargs = self.extract_dhcp_options_mapping(nmap) if not kwargs['broadcast']: kwargs['broadcast'] = bcip(kwargs['prefix_or_mask'], kwargs['ip']) if kwargs['static_routes']: @@ -107,6 +110,25 @@ class EphemeralDHCPv4(object): self._ephipv4 = ephipv4 return self.lease + def extract_dhcp_options_mapping(self, nmap): + result = {} + for internal_reference, lease_option_names in nmap.items(): + if isinstance(lease_option_names, list): + self.get_first_option_value( + internal_reference, + lease_option_names, + result + ) + else: + result[internal_reference] = self.lease.get(lease_option_names) + return result + + def get_first_option_value(self, internal_mapping, + lease_option_names, result): + for different_names in lease_option_names: + if not result.get(internal_mapping): + result[internal_mapping] = self.lease.get(different_names) + def maybe_perform_dhcp_discovery(nic=None): """Perform dhcp discovery if nic valid and dhclient command exists. @@ -281,24 +303,30 @@ def parse_static_routes(rfc3442): """ parse rfc3442 format and return a list containing tuple of strings. The tuple is composed of the network_address (including net length) and - gateway for a parsed static route. + gateway for a parsed static route. It can parse two formats of rfc3442, + one from dhcpcd and one from dhclient (isc). - @param rfc3442: string in rfc3442 format + @param rfc3442: string in rfc3442 format (isc or dhcpd) @returns: list of tuple(str, str) for all valid parsed routes until the first parsing error. E.g. - sr = parse_state_routes("32,169,254,169,254,130,56,248,255,0,130,56,240,1") - sr = [ + sr=parse_static_routes("32,169,254,169,254,130,56,248,255,0,130,56,240,1") + sr=[ ("169.254.169.254/32", "130.56.248.255"), ("0.0.0.0/0", "130.56.240.1") ] + sr2 = parse_static_routes("24.191.168.128 192.168.128.1,0 192.168.128.1") + sr2 = [ + ("191.168.128.0/24", "192.168.128.1"), ("0.0.0.0/0", "192.168.128.1") + ] + Python version of isc-dhclient's hooks: /etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes """ # raw strings from dhcp lease may end in semi-colon rfc3442 = rfc3442.rstrip(";") - tokens = rfc3442.split(',') + tokens = [tok for tok in re.split(r"[, .]", rfc3442) if tok] static_routes = [] def _trunc_error(cidr, required, remain): |