diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2014-04-10 16:17:49 +0900 |
---|---|---|
committer | Lorenzo Colitti <lorenzo@google.com> | 2015-02-02 17:47:25 +0900 |
commit | 455a2a6964ec6408d8f7cb2c629a65a34bc43f08 (patch) | |
tree | a890f2e92ca123a7ad9b2f8648cf7c25815bddc7 | |
parent | d6d303df685e53f93d2a9e15496d2fc083928b74 (diff) | |
download | extras-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.py | 18 |
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 |