Merge cherrypicks of ['googleplex-android-review.googlesource.com/39647656'] into 26Q2-release.

Change-Id: I7e21778100b090044fb8e226b9051d1b78462485
Signed-off-by: Coastguard Worker <android-build-coastguard-worker@google.com>
diff --git a/net/test/netlink.py b/net/test/netlink.py
index 1a5aefd..92b2e4c 100644
--- a/net/test/netlink.py
+++ b/net/test/netlink.py
@@ -240,18 +240,21 @@
     nlmsghdr, data = cstruct.Read(data, NLMsgHdr)
     self._Debug("  %s" % nlmsghdr)
 
-    if nlmsghdr.type == NLMSG_ERROR or nlmsghdr.type == NLMSG_DONE:
-      print("done")
-      return (None, None), data
+    # Netlink messages are 4-byte aligned. The length in the header is the
+    # actual length of the message. Any padding to reach the next 4-byte
+    # boundary is not included in the length.
+    padlen = util.GetPadLength(NLA_ALIGNTO, nlmsghdr.length)
+    data, remainder = data[:nlmsghdr.length - len(nlmsghdr)], data[nlmsghdr.length - len(nlmsghdr) + padlen:]
 
-    nlmsg, data = cstruct.Read(data, msgtype)
+    if nlmsghdr.type == NLMSG_ERROR or nlmsghdr.type == NLMSG_DONE:
+      return (nlmsghdr, None), remainder
+
+    nlmsg, attr_data = cstruct.Read(data, msgtype)
     self._Debug("    %s" % nlmsg)
 
     # Parse the attributes in the nlmsg.
-    attrlen = nlmsghdr.length - len(nlmsghdr) - len(nlmsg)
-    attributes = self._ParseAttributes(nlmsghdr.type, nlmsg, data[:attrlen], [])
-    data = data[attrlen:]
-    return (nlmsg, attributes), data
+    attributes = self._ParseAttributes(nlmsghdr.type, nlmsg, attr_data, [])
+    return (nlmsg, attributes), remainder
 
   def _GetMsg(self, msgtype):
     data = self._Recv()
@@ -263,8 +266,13 @@
     out = []
     while data:
       msg, data = self._ParseNLMsg(data, msgtype)
-      if msg is None:
-        break
+      if isinstance(msg[0], NLMsgHdr):
+        if msg[0].type == NLMSG_DONE:
+          expect_done = False
+          break
+        elif msg[0].type == NLMSG_ERROR:
+          # This should not happen in a dump, but let's be safe.
+          raise ValueError("Netlink error in message list")
       out.append(msg)
     if expect_done:
       self._ExpectDone()
@@ -296,15 +304,21 @@
 
     # Keep reading netlink messages until we get a NLMSG_DONE.
     out = []
-    while True:
+    done = False
+    while not done:
       data = self._Recv()
-      response_type = NLMsgHdr(data).type
-      if response_type == NLMSG_DONE:
-        break
-      elif response_type == NLMSG_ERROR:
-        # Likely means that the kernel didn't like our dump request.
-        # Parse the error and throw an exception.
-        self._ParseAck(data)
-      out.extend(self._GetMsgList(msgtype, data, False))
+      while data:
+        msg_header = NLMsgHdr(data)
+        if msg_header.type == NLMSG_DONE:
+          done = True
+          break
+        elif msg_header.type == NLMSG_ERROR:
+          # Likely means that the kernel didn't like our dump request.
+          # Parse the error and throw an exception.
+          self._ParseAck(data)
+
+        # Parse one message and its attributes.
+        msg, data = self._ParseNLMsg(data, msgtype)
+        out.append(msg)
 
     return out