commit bce6e4902320eb10b3d01093b1070db90115a77c
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Fri Aug 16 09:54:45 2013 +0200
NetUtils: rewrite scan_netdevs function
The scan_netdev function was starting to be a bit unreliable sometimes
causing crashes. It also wasn't a very pretty solution of the
problem.
The new scan_netdev function connects to a netlink socket and requests a
dump of all interfaces on the system, and parses the result to return a
similar data structure to the previous implementation of the function.
Again it contains the addditional kernel index of the interface that
will be used in the future.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst/Common/NetUtils.py | 57 ++++++++++++++++++++++++++++++++++++----------
1 files changed, 44 insertions(+), 13 deletions(-)
---
diff --git a/lnst/Common/NetUtils.py b/lnst/Common/NetUtils.py
index fb39a41..efa14f5 100644
--- a/lnst/Common/NetUtils.py
+++ b/lnst/Common/NetUtils.py
@@ -15,26 +15,57 @@ import os
import re
import socket
import subprocess
+from resource import getpagesize
+from pyroute2.netlink import NetlinkSocket
+from pyroute2.netlink import NLM_F_REQUEST
+from pyroute2.netlink import NLM_F_DUMP
+from pyroute2.netlink import NLMSG_DONE
+from pyroute2.netlink import NLMSG_ERROR
+from pyroute2.netlink.generic import NETLINK_ROUTE
+from pyroute2.netlink.iproute import MarshalRtnl
+from pyroute2.netlink.iproute import RTM_GETLINK
+from pyroute2.netlink.iproute import RTM_NEWLINK
+from pyroute2.netlink.rtnl.ifinfmsg import ifinfmsg
def normalize_hwaddr(hwaddr):
return hwaddr.upper().rstrip("\n")
def scan_netdevs():
- sys_dir = "/sys/class/net"
scan = []
- for root, dirs, files in os.walk(sys_dir):
- if "lo" in dirs:
- dirs.remove("lo")
- for d in dirs:
- dev_path = os.path.join(sys_dir, d)
- addr_path = os.path.join(dev_path, "address")
- if not os.path.isfile(addr_path):
+ nl_socket = NetlinkSocket(family=NETLINK_ROUTE)
+ msg = ifinfmsg()
+ msg["family"] = socket.AF_UNSPEC
+ msg["header"]["type"] = RTM_GETLINK
+ msg["header"]["flags"] = NLM_F_REQUEST | NLM_F_DUMP
+ msg["header"]["pid"] = os.getpid()
+ msg["header"]["sequence_number"] = 1
+ msg.encode()
+
+ nl_socket.sendto(msg.buf.getvalue(), (0,0))
+
+ finished = False
+ marshal = MarshalRtnl()
+ while not finished:
+ response = nl_socket.recv(getpagesize())
+ parts = marshal.parse(response)
+ for part in parts:
+ if part["header"]["type"] in [NLMSG_DONE, NLMSG_ERROR]:
+ finished = True
continue
- handle = open(addr_path, "rb")
- addr = handle.read()
- handle.close()
- addr = normalize_hwaddr(addr)
- scan.append({"name": d, "hwaddr": addr})
+ if part["header"]["sequence_number"] != 1:
+ continue
+
+ if part["header"]["type"] == RTM_NEWLINK:
+ new_link = {}
+ for name, value in part["attrs"]:
+ if name == "IFLA_IFNAME":
+ new_link["name"] = value
+ elif name == "IFLA_ADDRESS":
+ new_link["hwaddr"] = normalize_hwaddr(value)
+ new_link["index"] = part["index"]
+ scan.append(new_link)
+
+ nl_socket.close()
return scan
def test_tcp_connection(host, port):
Show replies by date