Use more route information to improve default_ipvX facts on BSDs (#64172)
* Use "default" route info to help pick the default address. Before this change, the address information used for the "default_ipv4" and "default_ipv6" information is whatever is first on the interface identified by the looking up the "default" route. On OpenBSD at least, the first IPv6 address tends to be a link-local address, which is not useful if you want to try and put a globally routable v6 address in a template somewhere. OpenBSD and NetBSD list the local address used for the default route, so we can then use that to filter the addresses on the interface and use the right one when it is available. This should also help in situations where the interface has a lot of aliases, or if you're doing IP multipath. Thanks to John-Mark Gurney and Jared McNeill for providing me output from the route command on FreeBSD and NetBSD respectively. * Use "route get default" to get default route information. Using some other arbitrary address makes these facts produce unexpected results in some situations.
This commit is contained in:
parent
adcf9458f1
commit
8c0ab43f05
1 changed files with 24 additions and 10 deletions
|
@ -73,12 +73,12 @@ class GenericBsdIfconfigNetwork(Network):
|
||||||
def get_default_interfaces(self, route_path):
|
def get_default_interfaces(self, route_path):
|
||||||
|
|
||||||
# Use the commands:
|
# Use the commands:
|
||||||
# route -n get 8.8.8.8 -> Google public DNS
|
# route -n get default
|
||||||
# route -n get -inet6 2404:6800:400a:800::1012 -> ipv6.google.com
|
# route -n get -inet6 default
|
||||||
# to find out the default outgoing interface, address, and gateway
|
# to find out the default outgoing interface, address, and gateway
|
||||||
|
|
||||||
command = dict(v4=[route_path, '-n', 'get', '8.8.8.8'],
|
command = dict(v4=[route_path, '-n', 'get', 'default'],
|
||||||
v6=[route_path, '-n', 'get', '-inet6', '2404:6800:400a:800::1012'])
|
v6=[route_path, '-n', 'get', '-inet6', 'default'])
|
||||||
|
|
||||||
interface = dict(v4={}, v6={})
|
interface = dict(v4={}, v6={})
|
||||||
|
|
||||||
|
@ -92,13 +92,19 @@ class GenericBsdIfconfigNetwork(Network):
|
||||||
# RTNETLINK answers: Invalid argument
|
# RTNETLINK answers: Invalid argument
|
||||||
continue
|
continue
|
||||||
for line in out.splitlines():
|
for line in out.splitlines():
|
||||||
words = line.split()
|
words = line.strip().split(': ')
|
||||||
# Collect output from route command
|
# Collect output from route command
|
||||||
if len(words) > 1:
|
if len(words) > 1:
|
||||||
if words[0] == 'interface:':
|
if words[0] == 'interface':
|
||||||
interface[v]['interface'] = words[1]
|
interface[v]['interface'] = words[1]
|
||||||
if words[0] == 'gateway:':
|
if words[0] == 'gateway':
|
||||||
interface[v]['gateway'] = words[1]
|
interface[v]['gateway'] = words[1]
|
||||||
|
# help pick the right interface address on OpenBSD
|
||||||
|
if words[0] == 'if address':
|
||||||
|
interface[v]['address'] = words[1]
|
||||||
|
# help pick the right interface address on NetBSD
|
||||||
|
if words[0] == 'local addr':
|
||||||
|
interface[v]['address'] = words[1]
|
||||||
|
|
||||||
return interface['v4'], interface['v6']
|
return interface['v4'], interface['v6']
|
||||||
|
|
||||||
|
@ -291,6 +297,14 @@ class GenericBsdIfconfigNetwork(Network):
|
||||||
for item in ifinfo:
|
for item in ifinfo:
|
||||||
if item != 'ipv4' and item != 'ipv6':
|
if item != 'ipv4' and item != 'ipv6':
|
||||||
defaults[item] = ifinfo[item]
|
defaults[item] = ifinfo[item]
|
||||||
if len(ifinfo[ip_type]) > 0:
|
|
||||||
for item in ifinfo[ip_type][0]:
|
ipinfo = []
|
||||||
defaults[item] = ifinfo[ip_type][0][item]
|
if 'address' in defaults:
|
||||||
|
ipinfo = [x for x in ifinfo[ip_type] if x['address'] == defaults['address']]
|
||||||
|
|
||||||
|
if len(ipinfo) == 0:
|
||||||
|
ipinfo = ifinfo[ip_type]
|
||||||
|
|
||||||
|
if len(ipinfo) > 0:
|
||||||
|
for item in ipinfo[0]:
|
||||||
|
defaults[item] = ipinfo[0][item]
|
||||||
|
|
Loading…
Reference in a new issue