Merge "Reference DataSaver setting from BPF map on V+ only" into main
diff --git a/common/flags.aconfig b/common/flags.aconfig
index ad78d62..0ad1804 100644
--- a/common/flags.aconfig
+++ b/common/flags.aconfig
@@ -41,3 +41,10 @@
   description: "The flag controls the access for registerOffloadEngine API in NsdManager"
   bug: "294777050"
 }
+
+flag {
+  name: "ipsec_transform_state"
+  namespace: "android_core_networking_ipsec"
+  description: "The flag controls the access for getIpSecTransformState and IpSecTransformState"
+  bug: "308011229"
+}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 5f67246..22120e9 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -7654,7 +7654,7 @@
     }
 
     private void enforceRequestCapabilitiesDeclaration(@NonNull final String callerPackageName,
-            @NonNull final NetworkCapabilities networkCapabilities) {
+            @NonNull final NetworkCapabilities networkCapabilities, int callingUid) {
         // This check is added to fix the linter error for "current min is 30", which is not going
         // to happen because Connectivity service always run in S+.
         if (!mDeps.isAtLeastS()) {
@@ -7668,7 +7668,9 @@
                 applicationNetworkCapabilities = mSelfCertifiedCapabilityCache.get(
                         callerPackageName);
                 if (applicationNetworkCapabilities == null) {
-                    final PackageManager packageManager = mContext.getPackageManager();
+                    final PackageManager packageManager =
+                            mContext.createContextAsUser(UserHandle.getUserHandleForUid(
+                                    callingUid), 0 /* flags */).getPackageManager();
                     final PackageManager.Property networkSliceProperty = packageManager.getProperty(
                             ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES,
                             callerPackageName
@@ -7700,7 +7702,8 @@
             String callingPackageName, String callingAttributionTag, final int callingUid) {
         if (shouldCheckCapabilitiesDeclaration(networkCapabilities, callingUid,
                 callingPackageName)) {
-            enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities);
+            enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities,
+                    callingUid);
         }
         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
             // For T+ devices, callers with carrier privilege could request with CBS capabilities.
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmReplayStateEsn.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmReplayStateEsn.java
new file mode 100644
index 0000000..01dc66e
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmReplayStateEsn.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util.netlink.xfrm;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Struct xfrm_replay_state_esn
+ *
+ * <p>see include/uapi/linux/xfrm.h
+ *
+ * <pre>
+ * struct xfrm_replay_state_esn {
+ *      unsigned int bmp_len;
+ *      __u32 oseq;
+ *      __u32 seq;
+ *      __u32 oseq_hi;
+ *      __u32 seq_hi;
+ *      __u32 replay_window;
+ *      __u32 bmp[];
+ * };
+ * </pre>
+ *
+ * @hide
+ */
+public class StructXfrmReplayStateEsn {
+    // include/uapi/linux/xfrm.h XFRMA_REPLAY_ESN_MAX
+    private static final int XFRMA_REPLAY_ESN_BMP_LEN_MAX = 128;
+
+    @NonNull private final StructXfrmReplayStateEsnWithoutBitmap mWithoutBitmap;
+    @NonNull private final byte[] mBitmap;
+
+    private StructXfrmReplayStateEsn(
+            @NonNull final StructXfrmReplayStateEsnWithoutBitmap withoutBitmap,
+            @NonNull final byte[] bitmap) {
+        mWithoutBitmap = withoutBitmap;
+        mBitmap = bitmap;
+        validate();
+    }
+
+    /** Constructor to build a new message */
+    public StructXfrmReplayStateEsn(
+            long bmpLen,
+            long oSeq,
+            long seq,
+            long oSeqHi,
+            long seqHi,
+            long replayWindow,
+            @NonNull final byte[] bitmap) {
+        mWithoutBitmap =
+                new StructXfrmReplayStateEsnWithoutBitmap(
+                        bmpLen, oSeq, seq, oSeqHi, seqHi, replayWindow);
+        mBitmap = bitmap.clone();
+        validate();
+    }
+
+    private void validate() {
+        if (mWithoutBitmap.mBmpLenInBytes != mBitmap.length) {
+            throw new IllegalArgumentException(
+                    "mWithoutBitmap.mBmpLenInBytes not aligned with bitmap."
+                            + " mWithoutBitmap.mBmpLenInBytes: "
+                            + mWithoutBitmap.mBmpLenInBytes
+                            + " bitmap.length "
+                            + mBitmap.length);
+        }
+    }
+
+    /** Parse IpSecStructXfrmReplayStateEsn from ByteBuffer. */
+    @Nullable
+    public static StructXfrmReplayStateEsn parse(@NonNull final ByteBuffer buf) {
+        final StructXfrmReplayStateEsnWithoutBitmap withoutBitmap =
+                Struct.parse(StructXfrmReplayStateEsnWithoutBitmap.class, buf);
+        if (withoutBitmap == null) {
+            return null;
+        }
+
+        final byte[] bitmap = new byte[withoutBitmap.mBmpLenInBytes];
+        buf.get(bitmap);
+
+        return new StructXfrmReplayStateEsn(withoutBitmap, bitmap);
+    }
+
+    /** Convert the parsed object to ByteBuffer. */
+    public void writeToByteBuffer(@NonNull final ByteBuffer buf) {
+        mWithoutBitmap.writeToByteBuffer(buf);
+        buf.put(mBitmap);
+    }
+
+    /** Return the struct size */
+    public int getStructSize() {
+        return StructXfrmReplayStateEsnWithoutBitmap.STRUCT_SIZE + mBitmap.length;
+    }
+
+    /** Return the bitmap */
+    public byte[] getBitmap() {
+        return mBitmap.clone();
+    }
+
+    /** Return the bmp_len */
+    public long getBmpLen() {
+        return mWithoutBitmap.bmpLen;
+    }
+
+    /** Return the replay_window */
+    public long getReplayWindow() {
+        return mWithoutBitmap.replayWindow;
+    }
+
+    /** Return the TX sequence number in unisgned long */
+    public long getTxSequenceNumber() {
+        return getSequenceNumber(mWithoutBitmap.seqHi, mWithoutBitmap.seq);
+    }
+
+    /** Return the RX sequence number in unisgned long */
+    public long getRxSequenceNumber() {
+        return getSequenceNumber(mWithoutBitmap.oSeqHi, mWithoutBitmap.oSeq);
+    }
+
+    @VisibleForTesting
+    static long getSequenceNumber(long hi, long low) {
+        final ByteBuffer buffer = ByteBuffer.allocate(8);
+        buffer.order(ByteOrder.BIG_ENDIAN);
+        buffer.putInt((int) hi).putInt((int) low);
+        buffer.rewind();
+
+        return buffer.getLong();
+    }
+
+    /** The xfrm_replay_state_esn struct without the bitmap */
+    // Because the size of the bitmap is decided at runtime, it cannot be included in a Struct
+    // subclass. Therefore, this nested class is defined to include all other fields supported by
+    // Struct for code reuse.
+    public static class StructXfrmReplayStateEsnWithoutBitmap extends Struct {
+        public static final int STRUCT_SIZE = 24;
+
+        @Field(order = 0, type = Type.U32)
+        public final long bmpLen; // replay bitmap length in 32-bit integers
+
+        @Field(order = 1, type = Type.U32)
+        public final long oSeq;
+
+        @Field(order = 2, type = Type.U32)
+        public final long seq;
+
+        @Field(order = 3, type = Type.U32)
+        public final long oSeqHi;
+
+        @Field(order = 4, type = Type.U32)
+        public final long seqHi;
+
+        @Field(order = 5, type = Type.U32)
+        public final long replayWindow; // replay bitmap length in bit
+
+        @Computed private final int mBmpLenInBytes; // replay bitmap length in bytes
+
+        public StructXfrmReplayStateEsnWithoutBitmap(
+                long bmpLen, long oSeq, long seq, long oSeqHi, long seqHi, long replayWindow) {
+            this.bmpLen = bmpLen;
+            this.oSeq = oSeq;
+            this.seq = seq;
+            this.oSeqHi = oSeqHi;
+            this.seqHi = seqHi;
+            this.replayWindow = replayWindow;
+
+            if (bmpLen > XFRMA_REPLAY_ESN_BMP_LEN_MAX) {
+                throw new IllegalArgumentException("Invalid bmpLen " + bmpLen);
+            }
+
+            if (bmpLen * 4 * 8 != replayWindow) {
+                throw new IllegalArgumentException(
+                        "bmpLen not aligned with replayWindow. bmpLen: "
+                                + bmpLen
+                                + " replayWindow "
+                                + replayWindow);
+            }
+
+            mBmpLenInBytes = (int) bmpLen * 4;
+        }
+    }
+}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
index 14a3a0f..72d02d4 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
@@ -44,6 +44,9 @@
     public static final int XFRM_MODE_TRANSPORT = 0;
     public static final int XFRM_MODE_TUNNEL = 1;
 
+    public static final short XFRMA_REPLAY_VAL = 10;
+    public static final short XFRMA_REPLAY_ESN_VAL = 23;
+
     public static final BigInteger XFRM_INF = new BigInteger("FFFFFFFFFFFFFFFF", 16);
 
     public XfrmNetlinkMessage(@NonNull final StructNlMsgHdr header) {
@@ -64,6 +67,8 @@
     public static XfrmNetlinkMessage parseXfrmInternal(
             @NonNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer) {
         switch (nlmsghdr.nlmsg_type) {
+            case XFRM_MSG_NEWSA:
+                return XfrmNetlinkNewSaMessage.parseInternal(nlmsghdr, byteBuffer);
             case XFRM_MSG_GETSA:
                 return XfrmNetlinkGetSaMessage.parseInternal(nlmsghdr, byteBuffer);
             default:
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkNewSaMessage.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkNewSaMessage.java
new file mode 100644
index 0000000..2f374ba
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkNewSaMessage.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util.netlink.xfrm;
+
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.XFRMA_REPLAY_ESN_VAL;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.netlink.StructNlAttr;
+import com.android.net.module.util.netlink.StructNlMsgHdr;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * A NetlinkMessage subclass for XFRM_MSG_NEWSA messages.
+ *
+ * <p>see also: &lt;linux_src&gt;/include/uapi/linux/xfrm.h
+ *
+ * <p>XFRM_MSG_NEWSA syntax
+ *
+ * <ul>
+ *   <li>TLV: xfrm_usersa_info
+ *   <li>Attributes: XFRMA_ALG_CRYPT, XFRMA_ALG_AUTH, XFRMA_OUTPUT_MARK, XFRMA_IF_ID,
+ *       XFRMA_REPLAY_ESN_VAL,XFRMA_REPLAY_VAL
+ * </ul>
+ *
+ * @hide
+ */
+public class XfrmNetlinkNewSaMessage extends XfrmNetlinkMessage {
+    private static final String TAG = XfrmNetlinkNewSaMessage.class.getSimpleName();
+    @NonNull private final StructXfrmUsersaInfo mXfrmUsersaInfo;
+
+    @NonNull private final StructXfrmReplayStateEsn mXfrmReplayStateEsn;
+
+    private XfrmNetlinkNewSaMessage(
+            @NonNull final StructNlMsgHdr header,
+            @NonNull final StructXfrmUsersaInfo xfrmUsersaInfo,
+            @NonNull final StructXfrmReplayStateEsn xfrmReplayStateEsn) {
+        super(header);
+        mXfrmUsersaInfo = xfrmUsersaInfo;
+        mXfrmReplayStateEsn = xfrmReplayStateEsn;
+    }
+
+    @Override
+    protected void packPayload(@NonNull final ByteBuffer byteBuffer) {
+        mXfrmUsersaInfo.writeToByteBuffer(byteBuffer);
+        if (mXfrmReplayStateEsn != null) {
+            mXfrmReplayStateEsn.writeToByteBuffer(byteBuffer);
+        }
+    }
+
+    /**
+     * Parse XFRM_MSG_NEWSA message from ByteBuffer.
+     *
+     * <p>This method should be called from NetlinkMessage#parse(ByteBuffer, int) for generic
+     * message validation and processing
+     *
+     * @param nlmsghdr netlink message header.
+     * @param byteBuffer the ByteBuffer instance that wraps the raw netlink message bytes. MUST be
+     *                   host order
+     */
+    @Nullable
+    static XfrmNetlinkNewSaMessage parseInternal(
+            @NonNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer) {
+        final StructXfrmUsersaInfo xfrmUsersaInfo =
+                Struct.parse(StructXfrmUsersaInfo.class, byteBuffer);
+        if (xfrmUsersaInfo == null) {
+            Log.d(TAG, "parse: fail to parse xfrmUsersaInfo");
+            return null;
+        }
+
+        StructXfrmReplayStateEsn xfrmReplayStateEsn = null;
+
+        final int payloadLen = nlmsghdr.nlmsg_len - StructNlMsgHdr.STRUCT_SIZE;
+        int parsedLength = StructXfrmUsersaInfo.STRUCT_SIZE;
+        while (parsedLength < payloadLen) {
+            final StructNlAttr attr = StructNlAttr.parse(byteBuffer);
+
+            if (attr == null) {
+                Log.d(TAG, "parse: fail to parse netlink attributes");
+                return null;
+            }
+
+            final ByteBuffer attrValueBuff = ByteBuffer.wrap(attr.nla_value);
+            attrValueBuff.order(ByteOrder.nativeOrder());
+
+            if (attr.nla_type == XFRMA_REPLAY_ESN_VAL) {
+                xfrmReplayStateEsn = StructXfrmReplayStateEsn.parse(attrValueBuff);
+            }
+
+            parsedLength += attr.nla_len;
+        }
+
+        // TODO: Add the support of XFRMA_REPLAY_VAL
+
+        if (xfrmReplayStateEsn == null) {
+            Log.d(TAG, "parse: xfrmReplayStateEsn not found");
+            return null;
+        }
+
+        final XfrmNetlinkNewSaMessage msg =
+                new XfrmNetlinkNewSaMessage(nlmsghdr, xfrmUsersaInfo, xfrmReplayStateEsn);
+
+        return msg;
+    }
+
+    /** Return the TX sequence number in unisgned long */
+    public long getTxSequenceNumber() {
+        return mXfrmReplayStateEsn.getTxSequenceNumber();
+    }
+
+    /** Return the RX sequence number in unisgned long */
+    public long getRxSequenceNumber() {
+        return mXfrmReplayStateEsn.getRxSequenceNumber();
+    }
+
+    /** Return the bitmap */
+    public byte[] getBitmap() {
+        return mXfrmReplayStateEsn.getBitmap();
+    }
+
+    /** Return the packet count in unsigned long */
+    public long getPacketCount() {
+        // It is safe because "packets" is a 64-bit value
+        return mXfrmUsersaInfo.getCurrentLifetime().packets.longValue();
+    }
+
+    /** Return the byte count in unsigned long */
+    public long getByteCount() {
+        // It is safe because "bytes" is a 64-bit value
+        return mXfrmUsersaInfo.getCurrentLifetime().bytes.longValue();
+    }
+
+    /** Return the xfrm_usersa_info */
+    public StructXfrmUsersaInfo getXfrmUsersaInfo() {
+        return mXfrmUsersaInfo;
+    }
+}
diff --git a/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java b/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
index f9895c6..7c4abe0 100644
--- a/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
+++ b/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
@@ -189,6 +189,7 @@
 
     public static final byte PIO_FLAG_ON_LINK = (byte) (1 << 7);
     public static final byte PIO_FLAG_AUTONOMOUS = (byte) (1 << 6);
+    public static final byte PIO_FLAG_DHCPV6_PD_PREFERRED = (byte) (1 << 4);
 
     /**
      * TCP constants.
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmReplayStateEsnTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmReplayStateEsnTest.java
new file mode 100644
index 0000000..1eb968d
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmReplayStateEsnTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util.netlink.xfrm;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.HexDump;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StructXfrmReplayStateEsnTest {
+    private static final String EXPECTED_HEX_STRING =
+            "80000000000000000000000000000000"
+                    + "00000000001000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "0000000000000000";
+
+    private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
+
+    private static final long BMP_LEN = 128;
+    private static final long REPLAY_WINDOW = 4096;
+    private static final byte[] BITMAP = new byte[512];
+
+    @Test
+    public void testEncode() throws Exception {
+        final StructXfrmReplayStateEsn struct =
+                new StructXfrmReplayStateEsn(BMP_LEN, 0L, 0L, 0L, 0L, REPLAY_WINDOW, BITMAP);
+
+        final ByteBuffer buffer = ByteBuffer.allocate(struct.getStructSize());
+        buffer.order(ByteOrder.nativeOrder());
+        struct.writeToByteBuffer(buffer);
+
+        assertArrayEquals(EXPECTED_HEX, buffer.array());
+    }
+
+    @Test
+    public void testDecode() throws Exception {
+        final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
+        buffer.order(ByteOrder.nativeOrder());
+
+        final StructXfrmReplayStateEsn struct = StructXfrmReplayStateEsn.parse(buffer);
+
+        assertEquals(BMP_LEN, struct.getBmpLen());
+        assertEquals(REPLAY_WINDOW, struct.getReplayWindow());
+        assertArrayEquals(BITMAP, struct.getBitmap());
+        assertEquals(0L, struct.getRxSequenceNumber());
+        assertEquals(0L, struct.getTxSequenceNumber());
+    }
+
+    @Test
+    public void testGetSequenceNumber() throws Exception {
+        final long low = 0x00ab112233L;
+        final long hi = 0x01L;
+
+        assertEquals(0x01ab112233L, StructXfrmReplayStateEsn.getSequenceNumber(hi, low));
+        assertEquals(0xab11223300000001L, StructXfrmReplayStateEsn.getSequenceNumber(low, hi));
+    }
+
+    // TODO: Add test cases that the test bitmap is not all zeros
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/XfrmNetlinkNewSaMessageTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/XfrmNetlinkNewSaMessageTest.java
new file mode 100644
index 0000000..3d0ce2c
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/XfrmNetlinkNewSaMessageTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util.netlink.xfrm;
+
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.NETLINK_XFRM;
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.XFRM_MODE_TRANSPORT;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.net.InetAddresses;
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.HexDump;
+import com.android.net.module.util.netlink.NetlinkMessage;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class XfrmNetlinkNewSaMessageTest {
+    private static final String EXPECTED_HEX_STRING =
+            "2004000010000000000000003FE1D4B6"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000A00000000000000"
+                    + "000000000000000020010DB800000000"
+                    + "0000000000000111AABBCCDD32000000"
+                    + "20010DB8000000000000000000000222"
+                    + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "FD464C65000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "024000000A0000000000000000000000"
+                    + "5C000100686D61632873686131290000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000A000000055F01AC07E15E437"
+                    + "115DDE0AEDD18A822BA9F81E60001400"
+                    + "686D6163287368613129000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "A00000006000000055F01AC07E15E437"
+                    + "115DDE0AEDD18A822BA9F81E58000200"
+                    + "63626328616573290000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "800000006AED4975ADF006D65C76F639"
+                    + "23A6265B1C0217008000000000000000"
+                    + "00000000000000000000000000100000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000"
+                    + "00000000000000000000000000000000";
+
+    private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
+
+    private static final InetAddress DEST_ADDRESS =
+            InetAddresses.parseNumericAddress("2001:db8::111");
+    private static final InetAddress SOURCE_ADDRESS =
+            InetAddresses.parseNumericAddress("2001:db8::222");
+    private static final int FAMILY = OsConstants.AF_INET6;
+    private static final long SPI = 0xaabbccddL;
+    private static final long SEQ = 0L;
+    private static final long REQ_ID = 16386L;
+    private static final short MODE = XFRM_MODE_TRANSPORT;
+    private static final short REPLAY_WINDOW_LEGACY = 0;
+    private static final short FLAGS = 0;
+    private static final byte[] BITMAP = new byte[512];
+
+    @Test
+    public void testDecode() throws Exception {
+        final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
+        buffer.order(ByteOrder.nativeOrder());
+        final XfrmNetlinkNewSaMessage message =
+                (XfrmNetlinkNewSaMessage) NetlinkMessage.parse(buffer, NETLINK_XFRM);
+        final StructXfrmUsersaInfo xfrmUsersaInfo = message.getXfrmUsersaInfo();
+
+        assertEquals(DEST_ADDRESS, xfrmUsersaInfo.getDestAddress());
+        assertEquals(SOURCE_ADDRESS, xfrmUsersaInfo.getSrcAddress());
+        assertEquals(SPI, xfrmUsersaInfo.getSpi());
+        assertEquals(SEQ, xfrmUsersaInfo.seq);
+        assertEquals(REQ_ID, xfrmUsersaInfo.reqId);
+        assertEquals(FAMILY, xfrmUsersaInfo.family);
+        assertEquals(MODE, xfrmUsersaInfo.mode);
+        assertEquals(REPLAY_WINDOW_LEGACY, xfrmUsersaInfo.replayWindowLegacy);
+        assertEquals(FLAGS, xfrmUsersaInfo.flags);
+
+        assertArrayEquals(BITMAP, message.getBitmap());
+        assertEquals(0L, message.getRxSequenceNumber());
+        assertEquals(0L, message.getTxSequenceNumber());
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 02d3823..544f300 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -279,7 +279,7 @@
 
     private static final int NETWORK_CALLBACK_TIMEOUT_MS = 30_000;
     // Timeout for waiting network to be validated.
-    private static final int LISTEN_ACTIVITY_TIMEOUT_MS = 5_000;
+    private static final int LISTEN_ACTIVITY_TIMEOUT_MS = 30_000;
     private static final int NO_CALLBACK_TIMEOUT_MS = 100;
     private static final int NETWORK_REQUEST_TIMEOUT_MS = 3000;
     private static final int SOCKET_TIMEOUT_MS = 100;
@@ -726,6 +726,7 @@
         return mCm.getRedactedNetworkCapabilitiesForPackage(nc, uid, packageName);
     }
 
+    @ConnectivityModuleTest
     @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
     @AppModeFull(reason = "Cannot get installed packages in instant app mode")
     @Test
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index c7d6555..fe2f813 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -774,11 +774,13 @@
 
             // Cell and WiFi are allowed to set UIDs, but not Bluetooth or agents with multiple
             // transports.
-            doTestAllowedUids(defaultSubId, TRANSPORT_CELLULAR, uid, expectUidsPresent = true)
+            // TODO(b/315136340): Allow ownerUid to see allowedUids and enable below test case
+            // doTestAllowedUids(defaultSubId, TRANSPORT_CELLULAR, uid, expectUidsPresent = true)
             if (SdkLevel.isAtLeastV()) {
                 // Cannot be tested before V because WifiInfo.Builder#setSubscriptionId doesn't
                 // exist
-                doTestAllowedUids(defaultSubId, TRANSPORT_WIFI, uid, expectUidsPresent = true)
+                // TODO(b/315136340): Allow ownerUid to see allowedUids and enable below test case
+                // doTestAllowedUids(defaultSubId, TRANSPORT_WIFI, uid, expectUidsPresent = true)
             }
             doTestAllowedUids(defaultSubId, TRANSPORT_BLUETOOTH, uid, expectUidsPresent = false)
             doTestAllowedUids(defaultSubId, intArrayOf(TRANSPORT_CELLULAR, TRANSPORT_WIFI), uid,
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
index 582e7b1..c74e330 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
@@ -150,12 +150,7 @@
         repository.updateService(TEST_SERVICE_ID_1, TEST_SUBTYPE)
 
         val queriedName = arrayOf(TEST_SUBTYPE, "_sub", "_testservice", "_tcp", "local")
-        val questions = listOf(MdnsPointerRecord(queriedName,
-                0L /* receiptTimeMillis */,
-                false /* cacheFlush */,
-                // TTL and data is empty for a question
-                0L /* ttlMillis */,
-                null /* pointer */))
+        val questions = listOf(MdnsPointerRecord(queriedName, false /* isUnicast */))
         val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
                 listOf() /* authorityRecords */, listOf() /* additionalRecords */)
         val src = InetSocketAddress(parseNumericAddress("192.0.2.123"), 5353)
@@ -475,13 +470,8 @@
     fun testGetReplyCaseInsensitive() {
         val repository = MdnsRecordRepository(thread.looper, deps, TEST_HOSTNAME, flags)
         repository.initWithService(TEST_SERVICE_ID_1, TEST_SERVICE_1)
-        val questionsCaseInSensitive =
-            listOf(MdnsPointerRecord(arrayOf("_TESTSERVICE", "_TCP", "local"),
-                0L /* receiptTimeMillis */,
-                false /* cacheFlush */,
-                // TTL and data is empty for a question
-                0L /* ttlMillis */,
-                null /* pointer */))
+        val questionsCaseInSensitive = listOf(
+                MdnsPointerRecord(arrayOf("_TESTSERVICE", "_TCP", "local"), false /* isUnicast */))
         val queryCaseInsensitive = MdnsPacket(0 /* flags */, questionsCaseInSensitive,
             listOf() /* answers */, listOf() /* authorityRecords */,
             listOf() /* additionalRecords */)
@@ -508,12 +498,7 @@
         val queriedName = if (subtype == null) arrayOf("_testservice", "_tcp", "local")
         else arrayOf(subtype, "_sub", "_testservice", "_tcp", "local")
 
-        val questions = listOf(MdnsPointerRecord(queriedName,
-                0L /* receiptTimeMillis */,
-                false /* cacheFlush */,
-                // TTL and data is empty for a question
-                0L /* ttlMillis */,
-                null /* pointer */))
+        val questions = listOf(MdnsPointerRecord(queriedName, false /* isUnicast */))
         val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
                 listOf() /* authorityRecords */, listOf() /* additionalRecords */)
         val src = InetSocketAddress(parseNumericAddress("192.0.2.123"), 5353)
@@ -711,12 +696,8 @@
         assertEquals(MdnsConstants.NO_PACKET,
                 repository.getServiceRepliedRequestsCount(TEST_SERVICE_ID_1))
 
-        val questions = listOf(MdnsPointerRecord(arrayOf("_testservice", "_tcp", "local"),
-                0L /* receiptTimeMillis */,
-                false /* cacheFlush */,
-                // TTL and data is empty for a question
-                0L /* ttlMillis */,
-                null /* pointer */))
+        val questions = listOf(
+                MdnsPointerRecord(arrayOf("_testservice", "_tcp", "local"), false /* isUnicast */))
         val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
                 listOf() /* authorityRecords */, listOf() /* additionalRecords */)
         val src = InetSocketAddress(parseNumericAddress("192.0.2.123"), 5353)