Antoni Segura Puimedon has uploaded a new change for review.
Change subject: netinfo: add gateway reporting to all devices
......................................................................
netinfo: add gateway reporting to all devices
by adding gateway reporting to all the devices we make it possible
to for a vdsm client to gather which is the gateway of the device
that is to be used for providing link to a bridged (VM) network.
Change-Id: I5dc4730214efa9eaba8425c3bf4842441b97084f
Signed-off-by: Antoni S. Puimedon <asegurap(a)redhat.com>
---
M lib/vdsm/netinfo.py
M lib/vdsm/netlink/route.py
2 files changed, 48 insertions(+), 31 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/04/28704/1
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index e42e6f4..bcbfcab 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -48,6 +48,7 @@
from .utils import execCmd, memoized, CommandPath
from .netlink import link as nl_link
from .netlink import addr as nl_addr
+from .netlink import route as nl_route
NET_CONF_DIR = '/etc/sysconfig/network-scripts/'
@@ -511,8 +512,8 @@
return paddr
-def _getNetInfo(iface, dhcp4, bridged, gateways, ipv6routes, ipaddrs,
- qosInbound, qosOutbound):
+def _getNetInfo(iface, dhcp4, bridged, routes, ipaddrs, qosInbound,
+ qosOutbound):
'''Returns a dictionary of properties about the network's interface
status.
Raises a KeyError if the iface does not exist.'''
data = {}
@@ -530,10 +531,10 @@
data.update({'iface': iface, 'bridged': bridged,
'addr': ipv4addr, 'netmask': ipv4netmask,
'bootproto4': 'dhcp' if iface in dhcp4 else
'none',
- 'gateway': getgateway(gateways, iface),
'ipv4addrs': ipv4addrs,
'ipv6addrs': ipv6addrs,
- 'ipv6gateway': ipv6routes.get(iface, '::'),
+ 'gateway': _getGateway(routes, iface),
+ 'ipv6gateway': _getGateway(routes, iface, family=6),
'mtu': str(getMtu(iface))})
if qosInbound:
data['qosInbound'] = qosInbound
@@ -548,18 +549,16 @@
return data
-def _bridgeinfo(link, gateways, ipv6routes, ipaddrs):
- info = _devinfo(link, ipaddrs)
- info.update({'gateway': getgateway(gateways, link.name),
- 'ipv6gateway': ipv6routes.get(link.name, '::'),
- 'ports': ports(link.name),
+def _bridgeinfo(link, routes, ipaddrs):
+ info = _devinfo(link, routes, ipaddrs)
+ info.update({'ports': ports(link.name),
'stp': bridge_stp_state(link.name),
'opts': bridgeOpts(link.name)})
return info
-def _nicinfo(link, paddr, ipaddrs):
- info = _devinfo(link, ipaddrs)
+def _nicinfo(link, paddr, routes, ipaddrs):
+ info = _devinfo(link, routes, ipaddrs)
info.update({'hwaddr': link.address, 'speed': nicSpeed(link.name)})
if paddr.get(link.name):
info['permhwaddr'] = paddr[link.name]
@@ -636,24 +635,26 @@
if val and val != defaults.get(opt)))
-def _bondinfo(link, ipaddrs):
- info = _devinfo(link, ipaddrs)
+def _bondinfo(link, routes, ipaddrs):
+ info = _devinfo(link, routes, ipaddrs)
info.update({'hwaddr': link.address, 'slaves': slaves(link.name)})
return info
-def _vlaninfo(link, ipaddrs):
- info = _devinfo(link, ipaddrs)
+def _vlaninfo(link, routes, ipaddrs):
+ info = _devinfo(link, routes, ipaddrs)
info.update({'iface': link.device, 'vlanid': link.vlanid})
return info
-def _devinfo(link, ipaddrs):
+def _devinfo(link, routes, ipaddrs):
ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(link.name, ipaddrs)
return {'addr': ipv4addr,
'cfg': getIfaceCfg(link.name),
'ipv4addrs': ipv4addrs,
'ipv6addrs': ipv6addrs,
+ 'gateway': _getGateway(routes, link.name),
+ 'ipv6gateway': _getGateway(routes, link.name, family=6),
'mtu': str(link.mtu),
'netmask': ipv4netmask}
@@ -734,13 +735,30 @@
return addrs
-def _libvirtNets2vdsm(nets, gateways=None, ipv6routes=None,
- ipAddrs=None):
+def _getGateway(routes, dev, family=4):
+ """Returns the default gateway for a device and an address
family"""
+ try:
+ gateway, = [r for r in routes[dev] if
+ r['destination'] == 'none' and
+ r['family'] == ('inet6' if family == 6 else
'inet') and
+ r['scope'] == 'universe' and
+ r['table'] == nl_route.MAIN_TABLE]
+ except ValueError: # no default gateway for the device
+ return '::' if family == 6 else ''
+ return gateway['gateway']
+
+
+def _getRoutes():
+ routes = defaultdict(list)
+ for route in nl_route.iter_routes():
+ routes[route['oif']].append(route)
+ return routes
+
+
+def _libvirtNets2vdsm(nets, routes=None, ipAddrs=None):
dhcp4 = getDhclientIfaces(_DHCLIENT_LEASES_GLOBS)
- if gateways is None:
- gateways = getRoutes()
- if ipv6routes is None:
- ipv6routes = getIPv6Routes()
+ if routes is None:
+ routes = _getRoutes()
if ipAddrs is None:
ipAddrs = _getIpAddrs()
d = {}
@@ -748,8 +766,7 @@
try:
d[net] = _getNetInfo(netAttr.get('iface', net),
dhcp4,
- netAttr['bridged'], gateways,
- ipv6routes, ipAddrs,
+ netAttr['bridged'], routes, ipAddrs,
netAttr.get('qosInbound'),
netAttr.get('qosOutbound'))
except KeyError:
@@ -774,27 +791,26 @@
def get(vdsmnets=None):
d = {'bondings': {}, 'bridges': {}, 'networks': {},
'nics': {},
'vlans': {}}
- gateways = getRoutes()
- ipv6routes = getIPv6Routes()
paddr = permAddr()
ipaddrs = _getIpAddrs()
+ routes = _getRoutes()
if vdsmnets is None:
nets = networks()
- d['networks'] = _libvirtNets2vdsm(nets, gateways, ipv6routes, ipaddrs)
+ d['networks'] = _libvirtNets2vdsm(nets, routes, ipaddrs)
else:
d['networks'] = vdsmnets
for dev in (link for link in getLinks() if not link.isHidden()):
if dev.isBRIDGE():
d['bridges'][dev.name] = \
- _bridgeinfo(dev, gateways, ipv6routes, ipaddrs)
+ _bridgeinfo(dev, routes, ipaddrs)
elif dev.isNICLike():
- d['nics'][dev.name] = _nicinfo(dev, paddr, ipaddrs)
+ d['nics'][dev.name] = _nicinfo(dev, paddr, routes, ipaddrs)
elif dev.isBOND():
- d['bondings'][dev.name] = _bondinfo(dev, ipaddrs)
+ d['bondings'][dev.name] = _bondinfo(dev, routes, ipaddrs)
elif dev.isVLAN():
- d['vlans'][dev.name] = _vlaninfo(dev, ipaddrs)
+ d['vlans'][dev.name] = _vlaninfo(dev, routes, ipaddrs)
_cfgBootprotoCompat(d)
diff --git a/lib/vdsm/netlink/route.py b/lib/vdsm/netlink/route.py
index 389a238..5e60d13 100644
--- a/lib/vdsm/netlink/route.py
+++ b/lib/vdsm/netlink/route.py
@@ -26,6 +26,7 @@
from .link import _nl_link_cache, _link_index_to_name
EXTRA_TABLE_FIELD = 252
+MAIN_TABLE = 254
def iter_routes():
--
To view, visit
http://gerrit.ovirt.org/28704
To unsubscribe, visit
http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5dc4730214efa9eaba8425c3bf4842441b97084f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>