Snap for 11052082 from d023c314fa5f6a2b14c75c9c3e741449cda83470 to mainline-media-release

Change-Id: I2cbb6f78e74d283438cde136185a1ed431c524de
diff --git a/src/com/android/networkstack/netlink/TcpSocketTracker.java b/src/com/android/networkstack/netlink/TcpSocketTracker.java
index d28f4b5..fea858f 100644
--- a/src/com/android/networkstack/netlink/TcpSocketTracker.java
+++ b/src/com/android/networkstack/netlink/TcpSocketTracker.java
@@ -68,9 +68,9 @@
 import com.android.net.module.util.DeviceConfigUtils;
 import com.android.net.module.util.SocketUtils;
 import com.android.net.module.util.netlink.InetDiagMessage;
-import com.android.net.module.util.netlink.NetlinkConstants;
 import com.android.net.module.util.netlink.NetlinkUtils;
 import com.android.net.module.util.netlink.StructInetDiagMsg;
+import com.android.net.module.util.netlink.StructNlAttr;
 import com.android.net.module.util.netlink.StructNlMsgHdr;
 import com.android.networkstack.apishim.NetworkShimImpl;
 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
@@ -401,18 +401,13 @@
         int mark = NetlinkUtils.INIT_MARK_VALUE;
         // Get a tcp_info.
         while (bytes.position() < remainingDataSize) {
-            final RoutingAttribute rtattr =
-                    new RoutingAttribute(bytes.getShort(), bytes.getShort());
-            final short dataLen = rtattr.getDataLength();
-            if (rtattr.rtaType == NetlinkUtils.INET_DIAG_INFO) {
-                tcpInfo = TcpInfo.parse(bytes, dataLen);
-            } else if (rtattr.rtaType == NetlinkUtils.INET_DIAG_MARK) {
-                mark = bytes.getInt();
-            } else {
-                // Data provided by kernel will include both valid data and padding data. The data
-                // len provided from kernel indicates the valid data size. Readers must deduce the
-                // alignment by themselves.
-                skipRemainingAttributesBytesAligned(bytes, dataLen);
+            final StructNlAttr nlattr = StructNlAttr.parse(bytes);
+            if (nlattr == null) break;
+
+            if (nlattr.nla_type == NetlinkUtils.INET_DIAG_MARK) {
+                mark = nlattr.getValueAsInteger();
+            } else if (nlattr.nla_type == NetlinkUtils.INET_DIAG_INFO) {
+                tcpInfo = TcpInfo.parse(nlattr.getValueAsByteBuffer(), nlattr.getAlignedLength());
             }
         }
         final SocketInfo info = new SocketInfo(tcpInfo, family, mark, time, uid, cookie, dstPort);
@@ -503,31 +498,6 @@
         return mTcpPacketsFailRateThreshold;
     }
 
-    /**
-     * Method to skip the remaining attributes bytes.
-     * Corresponds to NLMSG_NEXT in bionic/libc/kernel/uapi/linux/netlink.h.
-     *
-     * @param buffer the target ByteBuffer
-     * @param len the remaining length to skip.
-     */
-    private static void skipRemainingAttributesBytesAligned(@NonNull final ByteBuffer buffer,
-            final short len) {
-        // Data in {@Code RoutingAttribute} is followed after header with size {@Code NLA_ALIGNTO}
-        // bytes long for each block. Next attribute will start after the padding bytes if any.
-        // If all remaining bytes after header are valid in a data block, next attr will just start
-        // after valid bytes.
-        //
-        // E.g. With NLA_ALIGNTO(4), an attr struct with length 5 means 1 byte valid data remains
-        // after header and 3(4-1) padding bytes. Next attr with length 8 will start after the
-        // padding bytes and contain 4(8-4) valid bytes of data. The next attr start after the
-        // valid bytes, like:
-        //
-        // [HEADER(L=5)][   4-Bytes DATA      ][ HEADER(L=8) ][4 bytes DATA][Next attr]
-        // [ 5 valid bytes ][3 padding bytes  ][      8 valid bytes        ]   ...
-        final int cur = buffer.position();
-        buffer.position(cur + NetlinkConstants.alignedLengthOf(len));
-    }
-
     private static void log(final String str) {
         if (DBG) Log.d(TAG, str);
     }
@@ -539,30 +509,6 @@
     }
 
     /**
-     * Corresponds to {@code struct rtattr} from bionic/libc/kernel/uapi/linux/rtnetlink.h
-     *
-     * struct rtattr {
-     *    unsigned short rta_len;    // Length of option
-     *    unsigned short rta_type;   // Type of option
-     *    // Data follows
-     * };
-     */
-    static class RoutingAttribute {
-        public static final int HEADER_LENGTH = 4;
-
-        public final short rtaLen;  // The whole valid size of the struct.
-        public final short rtaType;
-
-        RoutingAttribute(final short len, final short type) {
-            rtaLen = len;
-            rtaType = type;
-        }
-        public short getDataLength() {
-            return (short) (rtaLen - HEADER_LENGTH);
-        }
-    }
-
-    /**
      * Data class for keeping the socket info.
      */
     @VisibleForTesting
diff --git a/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java b/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java
index a697d8d..165deab 100644
--- a/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java
+++ b/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java
@@ -474,82 +474,82 @@
 
     private static String composeSockDiagTcpHex(int retrans, int sent, short dstPort, long cookie) {
         return // struct nlmsghdr.
-                "14010000" +        // length = 276
-                "1400" +            // type = SOCK_DIAG_BY_FAMILY
-                "0301" +            // flags = NLM_F_REQUEST | NLM_F_DUMP
-                "00000000" +        // seqno
-                "00000000" +        // pid (0 == kernel)
+                "14010000"          // length = 276
+                + "1400"            // type = SOCK_DIAG_BY_FAMILY
+                + "0301"            // flags = NLM_F_REQUEST | NLM_F_DUMP
+                + "00000000"        // seqno
+                + "00000000"        // pid (0 == kernel)
                 // struct inet_diag_req_v2
-                "02" +              // family = AF_INET
-                "06" +              // state
-                "00" +              // timer
-                "00" +              // retrans
+                + "02"              // family = AF_INET
+                + "06"              // state
+                + "00"              // timer
+                + "00"              // retrans
                 // inet_diag_sockid: ports and addresses are always in big endian,
                 // see StructInetDiagSockId.
-                "DEA5" +                                               // idiag_sport = 56997
-                getHexStringFromShort(dstPort, ByteOrder.BIG_ENDIAN) + // idiag_dport
-                "0a006402000000000000000000000000" +                   // idiag_src = 10.0.100.2
-                "08080808000000000000000000000000" +                   // idiag_dst = 8.8.8.8
-                "00000000" +                                           // idiag_if
-                getHexStringFromLong(cookie) +                         // idiag_cookie
-                "00000000" +                                           // idiag_expires
-                "00000000" +                                           // idiag_rqueue
-                "00000000" +                                           // idiag_wqueue
-                getHexStringFromInt(TEST_UID1) +                       // idiag_uid
-                "00000000" +                                           // idiag_inode
+                + "DEA5"                                               // idiag_sport = 56997
+                + getHexStringFromShort(dstPort, ByteOrder.BIG_ENDIAN) // idiag_dport
+                + "0a006402000000000000000000000000"                   // idiag_src = 10.0.100.2
+                + "08080808000000000000000000000000"                   // idiag_dst = 8.8.8.8
+                + "00000000"                                           // idiag_if
+                + getHexStringFromLong(cookie)                         // idiag_cookie
+                + "00000000"                                           // idiag_expires
+                + "00000000"                                           // idiag_rqueue
+                + "00000000"                                           // idiag_wqueue
+                + getHexStringFromInt(TEST_UID1)                       // idiag_uid
+                + "00000000"                                           // idiag_inode
                 // rtattr
-                "0500" +            // len = 5
-                "0800" +            // type = 8
-                "00000000" +        // data
-                "0800" +            // len = 8
-                "0F00" +            // type = 15(INET_DIAG_MARK)
-                "850A0C00" +        // data, socket mark=789125
-                "AC00" +            // len = 172
-                "0200" +            // type = 2(INET_DIAG_INFO)
+                + "0500"            // len = 5
+                + "0800"            // type = 8
+                + "00000000"        // data
+                + "0800"            // len = 8
+                + "0F00"            // type = 15(INET_DIAG_MARK)
+                + "850A0C00"        // data, socket mark=789125
+                + "AC00"            // len = 172
+                + "0200"            // type = 2(INET_DIAG_INFO)
                 // tcp_info
-                "01" +              // state = TCP_ESTABLISHED
-                "00" +              // ca_state = TCP_CA_OPEN
-                "05" +              // retransmits = 5
-                "00" +              // probes = 0
-                "00" +              // backoff = 0
-                "07" +              // option = TCPI_OPT_WSCALE|TCPI_OPT_SACK|TCPI_OPT_TIMESTAMPS
-                "88" +              // wscale = 8
-                "00" +              // delivery_rate_app_limited = 0
-                "4A911B00" +        // rto = 1806666
-                "00000000" +        // ato = 0
-                "2E050000" +        // sndMss = 1326
-                "18020000" +        // rcvMss = 536
-                "00000000" +        // unsacked = 0
-                "00000000" +        // acked = 0
-                "00000000" +        // lost
-                "00000000" +        // retrans = 0
-                "00000000" +        // fackets = 0
-                "BB000000" +        // lastDataSent = 187
-                "00000000" +        // lastAckSent = 0
-                "BB000000" +        // lastDataRecv = 187
-                "BB000000" +        // lastDataAckRecv = 187
-                "DC050000" +        // pmtu = 1500
-                "30560100" +        // rcvSsthresh = 87600
-                "3E2C0900" +        // rttt = 601150
-                "1F960400" +        // rttvar = 300575
-                "78050000" +        // sndSsthresh = 1400
-                "0A000000" +        // sndCwnd = 10
-                "A8050000" +        // advmss = 1448
-                "03000000" +        // reordering = 3
-                "00000000" +        // rcvrtt = 0
-                "30560100" +        // rcvspace = 87600
-                getHexStringFromInt(retrans) +   // totalRetrans
-                "53AC000000000000" +    // pacingRate = 44115
-                "FFFFFFFFFFFFFFFF" +    // maxPacingRate = 18446744073709551615
-                "0100000000000000" +    // bytesAcked = 1
-                "0000000000000000" +    // bytesReceived = 0
-                getHexStringFromInt(sent) + // SegsOut
-                "00000000" +        // SegsIn = 0
-                "00000000" +        // NotSentBytes = 0
-                "3E2C0900" +        // minRtt = 601150
-                "00000000" +        // DataSegsIn = 0
-                "00000000" +        // DataSegsOut = 0
-                "0000000000000000"; // deliverRate = 0
+                + "01"              // state = TCP_ESTABLISHED
+                + "00"              // ca_state = TCP_CA_OPEN
+                + "05"              // retransmits = 5
+                + "00"              // probes = 0
+                + "00"              // backoff = 0
+                + "07"              // option = TCPI_OPT_WSCALE|TCPI_OPT_SACK|TCPI_OPT_TIMESTAMPS
+                + "88"              // wscale = 8
+                + "00"              // delivery_rate_app_limited = 0
+                + "4A911B00"        // rto = 1806666
+                + "00000000"        // ato = 0
+                + "2E050000"        // sndMss = 1326
+                + "18020000"        // rcvMss = 536
+                + "00000000"        // unsacked = 0
+                + "00000000"        // acked = 0
+                + "00000000"        // lost
+                + "00000000"        // retrans = 0
+                + "00000000"        // fackets = 0
+                + "BB000000"        // lastDataSent = 187
+                + "00000000"        // lastAckSent = 0
+                + "BB000000"        // lastDataRecv = 187
+                + "BB000000"        // lastDataAckRecv = 187
+                + "DC050000"        // pmtu = 1500
+                + "30560100"        // rcvSsthresh = 87600
+                + "3E2C0900"        // rttt = 601150
+                + "1F960400"        // rttvar = 300575
+                + "78050000"        // sndSsthresh = 1400
+                + "0A000000"        // sndCwnd = 10
+                + "A8050000"        // advmss = 1448
+                + "03000000"        // reordering = 3
+                + "00000000"        // rcvrtt = 0
+                + "30560100"        // rcvspace = 87600
+                + getHexStringFromInt(retrans)   // totalRetrans
+                + "53AC000000000000"    // pacingRate = 44115
+                + "FFFFFFFFFFFFFFFF"    // maxPacingRate = 18446744073709551615
+                + "0100000000000000"    // bytesAcked = 1
+                + "0000000000000000"    // bytesReceived = 0
+                + getHexStringFromInt(sent) // SegsOut
+                + "00000000"        // SegsIn = 0
+                + "00000000"        // NotSentBytes = 0
+                + "3E2C0900"        // minRtt = 601150
+                + "00000000"        // DataSegsIn = 0
+                + "00000000"        // DataSegsOut = 0
+                + "0000000000000000"; // deliverRate = 0
     }
 
     @Test
@@ -643,28 +643,28 @@
 
     private static final String BAD_DIAG_MSG_HEX =
         // struct nlmsghdr.
-            "00000058" +      // length = 1476395008
-            "1400" +         // type = SOCK_DIAG_BY_FAMILY
-            "0301" +         // flags = NLM_F_REQUEST | NLM_F_DUMP
-            "00000000" +     // seqno
-            "00000000" +     // pid (0 == kernel)
+            "00000058"      // length = 1476395008
+            + "1400"         // type = SOCK_DIAG_BY_FAMILY
+            + "0301"         // flags = NLM_F_REQUEST | NLM_F_DUMP
+            + "00000000"     // seqno
+            + "00000000"     // pid (0 == kernel)
             // struct inet_diag_req_v2
-            "02" +           // family = AF_INET
-            "06" +           // state
-            "00" +           // timer
-            "00" +           // retrans
+            + "02"           // family = AF_INET
+            + "06"           // state
+            + "00"           // timer
+            + "00"           // retrans
             // inet_diag_sockid
-            "DEA5" +         // idiag_sport = 42462
-            "71B9" +         // idiag_dport = 47473
-            "0a006402000000000000000000000000" + // idiag_src = 10.0.100.2
-            "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8
-            "00000000" +    // idiag_if
-            "34ED000076270000" + // idiag_cookie = 43387759684916
-            "00000000" +    // idiag_expires
-            "00000000" +    // idiag_rqueue
-            "00000000" +    // idiag_wqueue
-            "00000000" +    // idiag_uid
-            "00000000";    // idiag_inode
+            + "DEA5"         // idiag_sport = 42462
+            + "71B9"         // idiag_dport = 47473
+            + "0a006402000000000000000000000000" // idiag_src = 10.0.100.2
+            + "08080808000000000000000000000000" // idiag_dst = 8.8.8.8
+            + "00000000"    // idiag_if
+            + "34ED000076270000" // idiag_cookie = 43387759684916
+            + "00000000"    // idiag_expires
+            + "00000000"    // idiag_rqueue
+            + "00000000"    // idiag_wqueue
+            + "00000000"    // idiag_uid
+            + "00000000";    // idiag_inode
     private static final byte[] BAD_SOCK_DIAG_MSG_BYTES =
         HexEncoding.decode(BAD_DIAG_MSG_HEX.toCharArray(), false);