Merge changes I90c8abad,I9ea0755f into main

* changes:
  Revert "Log bpf rc file if it differs from the template files."
  Revert "Fix BpfLoaderRcUtils to support IOS_8859_1"
diff --git a/staticlibs/device/com/android/net/module/util/structs/FragmentHeader.java b/staticlibs/device/com/android/net/module/util/structs/FragmentHeader.java
new file mode 100644
index 0000000..3da6a38
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/structs/FragmentHeader.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 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.structs;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * IPv6 Fragment Extension header, as per https://tools.ietf.org/html/rfc2460.
+ *
+ * 0                   1                   2                   3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Next Header  |   Reserved    |      Fragment Offset    |Res|M|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                         Identification                        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+public class FragmentHeader extends Struct {
+    @Field(order = 0, type = Type.U8)
+    public final short nextHeader;
+    @Field(order = 1, type = Type.S8)
+    public final byte reserved;
+    @Field(order = 2, type = Type.U16)
+    public final int fragmentOffset;
+    @Field(order = 3, type = Type.S32)
+    public final int identification;
+
+    public FragmentHeader(final short nextHeader, final byte reserved, final int fragmentOffset,
+            final int identification) {
+        this.nextHeader = nextHeader;
+        this.reserved = reserved;
+        this.fragmentOffset = fragmentOffset;
+        this.identification = identification;
+    }
+
+    public FragmentHeader(final short nextHeader, final int fragmentOffset,
+            final int identification) {
+        this(nextHeader, (byte) 0, fragmentOffset, identification);
+    }
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/structs/FragmentHeaderTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/structs/FragmentHeaderTest.java
new file mode 100644
index 0000000..1a78ca5
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/structs/FragmentHeaderTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 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.structs;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class FragmentHeaderTest {
+    private static final byte[] HEADER_BYTES = new byte[] {
+        17, /* nextHeader  */
+        0, /* reserved */
+        15, 1, /* fragmentOffset */
+        1, 2, 3, 4 /* identification */
+    };
+
+    @Test
+    public void testConstructor() {
+        FragmentHeader fragHdr = new FragmentHeader((short) 10 /* nextHeader */,
+                (byte) 11 /* reserved */,
+                12 /* fragmentOffset */,
+                13 /* identification */);
+
+        assertEquals(10, fragHdr.nextHeader);
+        assertEquals(11, fragHdr.reserved);
+        assertEquals(12, fragHdr.fragmentOffset);
+        assertEquals(13, fragHdr.identification);
+    }
+
+    @Test
+    public void testParseFragmentHeader() {
+        final ByteBuffer buf = ByteBuffer.wrap(HEADER_BYTES);
+        buf.order(ByteOrder.BIG_ENDIAN);
+        FragmentHeader fragHdr = FragmentHeader.parse(FragmentHeader.class, buf);
+
+        assertEquals(17, fragHdr.nextHeader);
+        assertEquals(0, fragHdr.reserved);
+        assertEquals(0xF01, fragHdr.fragmentOffset);
+        assertEquals(0x1020304, fragHdr.identification);
+    }
+
+    @Test
+    public void testWriteToBytes() {
+        FragmentHeader fragHdr = new FragmentHeader((short) 17 /* nextHeader */,
+                (byte) 0 /* reserved */,
+                0xF01 /* fragmentOffset */,
+                0x1020304 /* identification */);
+
+        byte[] bytes = fragHdr.writeToBytes(ByteOrder.BIG_ENDIAN);
+
+        assertArrayEquals("bytes = " + Arrays.toString(bytes), HEADER_BYTES, bytes);
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 84b6745..beb9274 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -21,6 +21,7 @@
 import android.app.Instrumentation
 import android.content.Context
 import android.content.pm.PackageManager
+import android.content.pm.PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION
 import android.net.ConnectivityManager
 import android.net.EthernetNetworkSpecifier
 import android.net.INetworkAgent
@@ -70,6 +71,7 @@
 import android.net.TelephonyNetworkSpecifier
 import android.net.TestNetworkInterface
 import android.net.TestNetworkManager
+import android.net.TransportInfo
 import android.net.Uri
 import android.net.VpnManager
 import android.net.VpnTransportInfo
@@ -150,6 +152,7 @@
 import kotlin.test.assertTrue
 import kotlin.test.fail
 import org.junit.After
+import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -574,27 +577,13 @@
     }
 
     private fun doTestAllowedUids(
-            subId: Int,
-            transport: Int,
-            uid: Int,
-            expectUidsPresent: Boolean
-    ) {
-        doTestAllowedUids(subId, intArrayOf(transport), uid, expectUidsPresent)
-    }
-
-    private fun doTestAllowedUids(
-            subId: Int,
             transports: IntArray,
             uid: Int,
-            expectUidsPresent: Boolean
+            expectUidsPresent: Boolean,
+            specifier: NetworkSpecifier?,
+            transportInfo: TransportInfo?
     ) {
         val callback = TestableNetworkCallback(DEFAULT_TIMEOUT_MS)
-        val specifier = when {
-            transports.size != 1 -> null
-            TRANSPORT_ETHERNET in transports -> EthernetNetworkSpecifier("testInterface")
-            TRANSPORT_CELLULAR in transports -> TelephonyNetworkSpecifier(subId)
-            else -> null
-        }
         val agent = createNetworkAgent(initialNc = NetworkCapabilities.Builder().run {
             addTransportType(TRANSPORT_TEST)
             transports.forEach { addTransportType(it) }
@@ -602,10 +591,7 @@
             addCapability(NET_CAPABILITY_NOT_SUSPENDED)
             removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
             setNetworkSpecifier(specifier)
-            if (TRANSPORT_WIFI in transports && SdkLevel.isAtLeastV()) {
-                // setSubscriptionId only exists in V+
-                setTransportInfo(WifiInfo.Builder().setSubscriptionId(subId).build())
-            }
+            setTransportInfo(transportInfo)
             setAllowedUids(setOf(uid))
             setOwnerUid(Process.myUid())
             setAdministratorUids(intArrayOf(Process.myUid()))
@@ -630,6 +616,45 @@
         // callback will be unregistered in tearDown()
     }
 
+    private fun doTestAllowedUids(
+            transport: Int,
+            uid: Int,
+            expectUidsPresent: Boolean
+    ) {
+        doTestAllowedUids(intArrayOf(transport), uid, expectUidsPresent,
+                specifier = null, transportInfo = null)
+    }
+
+    private fun doTestAllowedUidsWithSubId(
+            subId: Int,
+            transport: Int,
+            uid: Int,
+            expectUidsPresent: Boolean
+    ) {
+        doTestAllowedUidsWithSubId(subId, intArrayOf(transport), uid, expectUidsPresent)
+    }
+
+    private fun doTestAllowedUidsWithSubId(
+            subId: Int,
+            transports: IntArray,
+            uid: Int,
+            expectUidsPresent: Boolean
+    ) {
+        val specifier = when {
+            transports.size != 1 -> null
+            TRANSPORT_ETHERNET in transports -> EthernetNetworkSpecifier("testInterface")
+            TRANSPORT_CELLULAR in transports -> TelephonyNetworkSpecifier(subId)
+            else -> null
+        }
+        val transportInfo = if (TRANSPORT_WIFI in transports && SdkLevel.isAtLeastV()) {
+            // setSubscriptionId only exists in V+
+            WifiInfo.Builder().setSubscriptionId(subId).build()
+        } else {
+            null
+        }
+        doTestAllowedUids(transports, uid, expectUidsPresent, specifier, transportInfo)
+    }
+
     private fun setHoldCarrierPrivilege(hold: Boolean, subId: Int) {
         fun getCertHash(): String {
             val pkgInfo = realContext.packageManager.getPackageInfo(realContext.opPackageName,
@@ -723,6 +748,19 @@
     @Test
     @IgnoreUpTo(Build.VERSION_CODES.S)
     fun testAllowedUids() {
+        doTestAllowedUids(TRANSPORT_CELLULAR, Process.myUid(), expectUidsPresent = false)
+        doTestAllowedUids(TRANSPORT_WIFI, Process.myUid(), expectUidsPresent = false)
+        doTestAllowedUids(TRANSPORT_BLUETOOTH, Process.myUid(), expectUidsPresent = false)
+
+        // TODO(b/315136340): Allow ownerUid to see allowedUids and add cases that expect uids
+        // present
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S)
+    fun testAllowedUids_WithCarrierServicePackage() {
+        assumeTrue(realContext.packageManager.hasSystemFeature(FEATURE_TELEPHONY_SUBSCRIPTION))
+
         // Use a different package than this one to make sure that a package that doesn't hold
         // carrier service permission can be set as an allowed UID.
         val servicePackage = "android.net.cts.carrierservicepackage"
@@ -735,12 +773,17 @@
 
         val tm = realContext.getSystemService(TelephonyManager::class.java)!!
         val defaultSubId = SubscriptionManager.getDefaultSubscriptionId()
+        assertTrue(defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                "getDefaultSubscriptionId returns INVALID_SUBSCRIPTION_ID")
         tryTest {
             // This process is not the carrier service UID, so allowedUids should be ignored in all
             // the following cases.
-            doTestAllowedUids(defaultSubId, TRANSPORT_CELLULAR, uid, expectUidsPresent = false)
-            doTestAllowedUids(defaultSubId, TRANSPORT_WIFI, uid, expectUidsPresent = false)
-            doTestAllowedUids(defaultSubId, TRANSPORT_BLUETOOTH, uid, expectUidsPresent = false)
+            doTestAllowedUidsWithSubId(defaultSubId, TRANSPORT_CELLULAR, uid,
+                    expectUidsPresent = false)
+            doTestAllowedUidsWithSubId(defaultSubId, TRANSPORT_WIFI, uid,
+                    expectUidsPresent = false)
+            doTestAllowedUidsWithSubId(defaultSubId, TRANSPORT_BLUETOOTH, uid,
+                    expectUidsPresent = false)
 
             // The tools to set the carrier service package override do not exist before U,
             // so there is no way to test the rest of this test on < U.
@@ -783,9 +826,10 @@
                 // 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,
+            doTestAllowedUidsWithSubId(defaultSubId, TRANSPORT_BLUETOOTH, uid,
                     expectUidsPresent = false)
+            doTestAllowedUidsWithSubId(defaultSubId, intArrayOf(TRANSPORT_CELLULAR, TRANSPORT_WIFI),
+                    uid, expectUidsPresent = false)
         } cleanupStep {
             if (SdkLevel.isAtLeastU()) setCarrierServicePackageOverride(defaultSubId, null)
         } cleanup {