summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2014-04-10 16:17:49 +0900
committerLorenzo Colitti <lorenzo@google.com>2015-02-02 17:47:25 +0900
commit455a2a6964ec6408d8f7cb2c629a65a34bc43f08 (patch)
treea890f2e92ca123a7ad9b2f8648cf7c25815bddc7
parentd6d303df685e53f93d2a9e15496d2fc083928b74 (diff)
downloadextras-455a2a6964ec6408d8f7cb2c629a65a34bc43f08.tar.gz
Fixes to iproute.
1. Expect NLMSG_DONE after a dump. Otherwise, the NLMSG_DONE message will remain in the socket buffer and the next read on the socket (e.g., the read for an ACK) will get an unexpected message. 2. Properly pad attributes that are not multiples of 4 bytes long. This is useful, for example, for interface names, which are not necessarily a multiple of 4 characters long. Change-Id: I08872ae6b287ec24231fdb4c9e54852c87daca69
-rw-r--r--tests/net_test/iproute.py18
1 files changed, 15 insertions, 3 deletions
diff --git a/tests/net_test/iproute.py b/tests/net_test/iproute.py
index 70b327a5..93370ee0 100644
--- a/tests/net_test/iproute.py
+++ b/tests/net_test/iproute.py
@@ -23,6 +23,7 @@ NLM_F_DUMP = 0x300
# Message types.
NLMSG_ERROR = 2
+NLMSG_DONE = 3
# Data structure formats.
# These aren't constants, they're classes. So, pylint: disable=invalid-name
@@ -85,8 +86,11 @@ class IPRoute(object):
print s
def _NlAttr(self, nla_type, data):
- nla_len = len(data) + len(NLAttr)
- return NLAttr((nla_len, nla_type)).Pack() + data
+ datalen = len(data)
+ # Pad the data if it's not a multiple of NLA_ALIGNTO bytes long.
+ padding = "\x00" * (PaddedLength(datalen) - datalen)
+ nla_len = datalen + len(NLAttr)
+ return NLAttr((nla_len, nla_type)).Pack() + data + padding
def _NlAttrU32(self, nla_type, value):
return self._NlAttr(nla_type, struct.pack("=I", value))
@@ -106,6 +110,13 @@ class IPRoute(object):
def _Recv(self):
return self.sock.recv(self.BUFSIZE)
+ def _ExpectDone(self):
+ response = self._Recv()
+ hdr, _ = cstruct.Read(response, NLMsgHdr)
+ if hdr.type != NLMSG_DONE:
+ raise ValueError("Expected NLMSG_DONE (%d), got %d" % (NLMSG_DONE,
+ hdr.type))
+
def _ExpectAck(self):
# Find the error code.
response = self._Recv()
@@ -161,7 +172,7 @@ class IPRoute(object):
return self._Rule(version, is_add, table, nlattr, priority)
def OifRule(self, version, is_add, oif, table, priority=16383):
- nlattr = self._NlAttr(FRA_OIFNAME, struct.pack("16s", oif))
+ nlattr = self._NlAttr(FRA_OIFNAME, oif)
return self._Rule(version, is_add, table, nlattr, priority)
def UidRule(self, version, is_add, uid, table, priority=16383):
@@ -210,6 +221,7 @@ class IPRoute(object):
rules.append((rtmsg, attributes))
+ self._ExpectDone()
return rules