Improvements to iproute.
1. Teach it about links.
2. Use decoded attribute names instead of raw attribute numbers
in debug output.
3. Add a function to decode netlink messages.
Change-Id: I3cb7581bac750e4784e7fbf5567d373ecc0cefdf
diff --git a/net/test/iproute.py b/net/test/iproute.py
index 0ac7222..1060fb7 100644
--- a/net/test/iproute.py
+++ b/net/test/iproute.py
@@ -53,6 +53,9 @@
### rtnetlink constants. See include/uapi/linux/rtnetlink.h.
# Message types.
+RTM_NEWLINK = 16
+RTM_DELLINK = 17
+RTM_GETLINK = 18
RTM_NEWADDR = 20
RTM_DELADDR = 21
RTM_GETADDR = 22
@@ -98,6 +101,8 @@
RTAX_MTU = 2
# Data structure formats.
+IfinfoMsg = cstruct.Struct(
+ "IfinfoMsg", "=BBHiII", "family pad type index flags change")
RTMsg = cstruct.Struct(
"RTMsg", "=BBBBBBBBI",
"family dst_len src_len tos table protocol scope type flags")
@@ -147,12 +152,33 @@
### FIB rule constants. See include/uapi/linux/fib_rules.h.
FRA_PRIORITY = 6
FRA_FWMARK = 10
+FRA_SUPPRESS_PREFIXLEN = 14
FRA_TABLE = 15
FRA_OIFNAME = 17
FRA_UID_START = 18
FRA_UID_END = 19
+# Link constants. See include/uapi/linux/if_link.h.
+IFLA_ADDRESS = 1
+IFLA_BROADCAST = 2
+IFLA_IFNAME = 3
+IFLA_MTU = 4
+IFLA_QDISC = 6
+IFLA_STATS = 7
+IFLA_TXQLEN = 13
+IFLA_MAP = 14
+IFLA_OPERSTATE = 16
+IFLA_LINKMODE = 17
+IFLA_STATS64 = 23
+IFLA_AF_SPEC = 26
+IFLA_GROUP = 27
+IFLA_EXT_MASK = 29
+IFLA_PROMISCUITY = 30
+IFLA_NUM_TX_QUEUES = 31
+IFLA_NUM_RX_QUEUES = 32
+IFLA_CARRIER = 33
+
def CommandVerb(command):
return ["NEW", "DEL", "GET", "SET"][command % 4]
@@ -246,6 +272,8 @@
name = self._GetConstantName(nla_type, "RTAX_")
elif CommandSubject(command) == "ADDR":
name = self._GetConstantName(nla_type, "IFA_")
+ elif CommandSubject(command) == "LINK":
+ name = self._GetConstantName(nla_type, "IFLA_")
elif CommandSubject(command) == "RULE":
name = self._GetConstantName(nla_type, "FRA_")
elif CommandSubject(command) == "ROUTE":
@@ -258,13 +286,20 @@
if name in ["FRA_PRIORITY", "FRA_FWMARK", "FRA_TABLE",
"FRA_UID_START", "FRA_UID_END",
- "RTA_OIF", "RTA_PRIORITY", "RTA_TABLE", "RTA_MARK"]:
+ "RTA_OIF", "RTA_PRIORITY", "RTA_TABLE", "RTA_MARK",
+ "IFLA_MTU", "IFLA_TXQLEN", "IFLA_GROUP", "IFLA_EXT_MASK",
+ "IFLA_PROMISCUITY", "IFLA_NUM_RX_QUEUES",
+ "IFLA_NUM_TX_QUEUES"]:
data = struct.unpack("=I", nla_data)[0]
+ elif name == "FRA_SUPPRESS_PREFIXLEN":
+ data = struct.unpack("=i", nla_data)[0]
+ elif name in ["IFLA_LINKMODE", "IFLA_OPERSTATE", "IFLA_CARRIER"]:
+ data = ord(nla_data)
elif name in ["IFA_ADDRESS", "IFA_LOCAL", "RTA_DST", "RTA_SRC",
"RTA_GATEWAY", "RTA_PREFSRC", "RTA_UID",
"NDA_DST"]:
data = socket.inet_ntop(family, nla_data)
- elif name in ["FRA_IIFNAME", "FRA_OIFNAME"]:
+ elif name in ["FRA_IIFNAME", "FRA_OIFNAME", "IFLA_IFNAME", "IFLA_QDISC"]:
data = nla_data.strip("\x00")
elif name == "RTA_METRICS":
data = self._ParseAttributes(-RTA_METRICS, family, nla_data)
@@ -272,7 +307,7 @@
data = RTACacheinfo(nla_data)
elif name == "IFA_CACHEINFO":
data = IFACacheinfo(nla_data)
- elif name == "NDA_LLADDR":
+ elif name in ["NDA_LLADDR", "IFLA_ADDRESS"]:
data = ":".join(x.encode("hex") for x in nla_data)
else:
data = nla_data
@@ -314,7 +349,7 @@
raise ValueError("Duplicate attribute %d" % nla_name)
attributes[nla_name] = nla_data
- self._Debug(" %s" % str((nla, nla_data)))
+ self._Debug(" %s" % str((nla_name, nla_data)))
return attributes
@@ -479,6 +514,7 @@
try:
struct_type = {
"ADDR": IfAddrMsg,
+ "LINK": IfinfoMsg,
"NEIGH": NdMsg,
"ROUTE": RTMsg,
"RULE": RTMsg,
@@ -488,6 +524,10 @@
except KeyError:
raise ValueError("Don't know how to print command type %s" % name)
+ def MaybeDebugMessage(self, message):
+ hdr = NLMsgHdr(message)
+ self.MaybeDebugCommand(hdr.type, message)
+
def _Dump(self, command, msg, msgtype):
"""Sends a dump request and returns a list of decoded messages."""
# Create a netlink dump request containing the msg.
@@ -516,6 +556,10 @@
rtmsg = RTMsg((family, 0, 0, 0, 0, 0, 0, 0, 0))
return self._Dump(RTM_GETRULE, rtmsg, RTMsg)
+ def DumpLinks(self):
+ ifinfomsg = IfinfoMsg((0, 0, 0, 0, 0, 0))
+ return self._Dump(RTM_GETLINK, ifinfomsg, IfinfoMsg)
+
def _Address(self, version, command, addr, prefixlen, flags, scope, ifindex):
"""Adds or deletes an IP address."""
family = self._AddressFamily(version)
@@ -620,4 +664,5 @@
iproute = IPRoute()
iproute.DEBUG = True
iproute.DumpRules(6)
+ iproute.DumpLinks()
print iproute.GetRoutes("2001:4860:4860::8888", 0, 0, None)