Merge "Support "dumpsys connectivity trafficcontroller""
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 1b2c0ed..b1e6a9f 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -111,7 +111,10 @@
       ]
     },
     // TODO: move to mainline-presubmit when known green.
-    // Test with connectivity/tethering module only, to catch integration issues with older versions of other modules
+    // Test with connectivity/tethering module only, to catch integration issues with older versions of other modules.
+    // "new tethering + old NetworkStack" is not a configuration that should really exist in the field, but
+    // there is no strong guarantee, and it is required by MTS testing for module qualification, where modules
+    // are tested independently.
     {
       "name": "CtsNetTestCasesLatestSdk[com.google.android.tethering.apex]",
       "options": [
@@ -160,9 +163,6 @@
     },
     {
       "path": "packages/modules/CaptivePortalLogin"
-    },
-    {
-      "path": "packages/modules/Connectivity/Tethering"
     }
   ]
 }
diff --git a/service/native/libs/libclat/bpfhelper.cpp b/service/native/libs/libclat/bpfhelper.cpp
index 6e230d0..00785ad 100644
--- a/service/native/libs/libclat/bpfhelper.cpp
+++ b/service/native/libs/libclat/bpfhelper.cpp
@@ -28,16 +28,6 @@
 #define DEVICEPREFIX "v4-"
 
 using android::base::unique_fd;
-using android::net::RAWIP;
-using android::net::getClatEgress4MapFd;
-using android::net::getClatIngress6MapFd;
-using android::net::getClatEgress4ProgFd;
-using android::net::getClatIngress6ProgFd;
-using android::net::tcQdiscAddDevClsact;
-using android::net::tcFilterAddDevEgressClatIpv4;
-using android::net::tcFilterAddDevIngressClatIpv6;
-using android::net::tcFilterDelDevEgressClatIpv4;
-using android::net::tcFilterDelDevIngressClatIpv6;
 using android::bpf::BpfMap;
 
 BpfMap<ClatEgress4Key, ClatEgress4Value> mClatEgress4Map;
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index d46ec61..1b57c27 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -646,8 +646,9 @@
      * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
      * Both of the arguments are bitmasks, and the value of bits come from
      * INetworkMonitor.NETWORK_VALIDATION_PROBE_*.
-     * arg1 = A bitmask to describe which probes are completed.
-     * arg2 = A bitmask to describe which probes are successful.
+     * arg1 = unused
+     * arg2 = netId
+     * obj = A Pair of integers: the bitmasks of, respectively, completed and successful probes.
      */
     public static final int EVENT_PROBE_STATUS_CHANGED = 45;
 
@@ -1410,6 +1411,8 @@
                 // converting rateInBytesPerSecond from long to int is safe here because the
                 // setting's range is limited to INT_MAX.
                 // TODO: add long/uint64 support to tcFilterAddDevIngressPolice.
+                Log.i(TAG,
+                        "enableIngressRateLimit on " + iface + ": " + rateInBytesPerSecond + "B/s");
                 TcUtils.tcFilterAddDevIngressPolice(params.index, TC_PRIO_POLICE, (short) ETH_P_ALL,
                         (int) rateInBytesPerSecond, TC_POLICE_BPF_PROG_PATH);
             } catch (IOException e) {
@@ -1431,6 +1434,8 @@
                 return;
             }
             try {
+                Log.i(TAG,
+                        "disableIngressRateLimit on " + iface);
                 TcUtils.tcFilterDelDev(params.index, true, TC_PRIO_POLICE, (short) ETH_P_ALL);
             } catch (IOException e) {
                 loge("TcUtils.tcFilterDelDev(ifaceIndex=" + params.index
@@ -1753,7 +1758,7 @@
 
         // Watch for ingress rate limit changes.
         mSettingsObserver.observe(
-                Settings.Secure.getUriFor(
+                Settings.Global.getUriFor(
                         ConnectivitySettingsManager.INGRESS_RATE_LIMIT_BYTES_PER_SECOND),
                 EVENT_INGRESS_RATE_LIMIT_CHANGED);
     }
@@ -3618,19 +3623,21 @@
         }
 
         private boolean maybeHandleNetworkMonitorMessage(Message msg) {
+            final int netId = msg.arg2;
+            final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
             switch (msg.what) {
                 default:
                     return false;
                 case EVENT_PROBE_STATUS_CHANGED: {
-                    final Integer netId = (Integer) msg.obj;
-                    final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
                     if (nai == null) {
                         break;
                     }
+                    final int probesCompleted = ((Pair<Integer, Integer>) msg.obj).first;
+                    final int probesSucceeded = ((Pair<Integer, Integer>) msg.obj).second;
                     final boolean probePrivateDnsCompleted =
-                            ((msg.arg1 & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
+                            ((probesCompleted & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
                     final boolean privateDnsBroken =
-                            ((msg.arg2 & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
+                            ((probesSucceeded & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
                     if (probePrivateDnsCompleted) {
                         if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) {
                             nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken);
@@ -3657,7 +3664,6 @@
                 case EVENT_NETWORK_TESTED: {
                     final NetworkTestedResults results = (NetworkTestedResults) msg.obj;
 
-                    final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(results.mNetId);
                     if (nai == null) break;
 
                     handleNetworkTested(nai, results.mTestResult,
@@ -3665,9 +3671,7 @@
                     break;
                 }
                 case EVENT_PROVISIONING_NOTIFICATION: {
-                    final int netId = msg.arg2;
                     final boolean visible = toBool(msg.arg1);
-                    final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
                     // If captive portal status has changed, update capabilities or disconnect.
                     if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
                         nai.lastCaptivePortalDetected = visible;
@@ -3701,14 +3705,12 @@
                     break;
                 }
                 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: {
-                    final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
                     if (nai == null) break;
 
                     updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
                     break;
                 }
                 case EVENT_CAPPORT_DATA_CHANGED: {
-                    final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
                     if (nai == null) break;
                     handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj);
                     break;
@@ -3848,6 +3850,7 @@
             // the same looper so messages will be processed in sequence.
             final Message msg = mTrackerHandler.obtainMessage(
                     EVENT_NETWORK_TESTED,
+                    0, mNetId,
                     new NetworkTestedResults(
                             mNetId, p.result, p.timestampMillis, p.redirectUrl));
             mTrackerHandler.sendMessage(msg);
@@ -3885,7 +3888,7 @@
         public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) {
             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
                     EVENT_PROBE_STATUS_CHANGED,
-                    probesCompleted, probesSucceeded, new Integer(mNetId)));
+                    0, mNetId, new Pair<>(probesCompleted, probesSucceeded)));
         }
 
         @Override
@@ -10700,8 +10703,11 @@
     }
 
     private boolean canNetworkBeRateLimited(@NonNull final NetworkAgentInfo networkAgent) {
-        if (!networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)) {
-            // rate limits only apply to networks that provide internet connectivity.
+        final NetworkCapabilities agentCaps = networkAgent.networkCapabilities;
+        // Only test networks (they cannot hold NET_CAPABILITY_INTERNET) and networks that provide
+        // internet connectivity can be rate limited.
+        if (!agentCaps.hasCapability(NET_CAPABILITY_INTERNET) && !agentCaps.hasTransport(
+                TRANSPORT_TEST)) {
             return false;
         }
 
diff --git a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
index 886b078..ea98289 100644
--- a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
+++ b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
@@ -75,6 +75,7 @@
 import com.android.testutils.TestableNetworkCallback
 import org.junit.After
 import org.junit.AfterClass
+import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.BeforeClass
 import org.junit.Rule
@@ -88,6 +89,7 @@
 import java.nio.ByteBuffer
 import java.nio.ByteOrder
 import java.util.UUID
+import java.util.regex.Pattern
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
@@ -125,8 +127,25 @@
     private lateinit var tunNetworkCallback: TestNetworkCallback
     private lateinit var reader: TapPacketReader
 
+    private fun getKernelVersion(): IntArray {
+        // Example:
+        // 4.9.29-g958411d --> 4.9
+        val release = Os.uname().release
+        val m = Pattern.compile("^(\\d+)\\.(\\d+)").matcher(release)
+        assertTrue(m.find(), "No pattern in release string: " + release)
+        return intArrayOf(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)))
+    }
+
+    private fun kernelIsAtLeast(major: Int, minor: Int): Boolean {
+        val version = getKernelVersion()
+        return (version.get(0) > major || (version.get(0) == major && version.get(1) >= minor))
+    }
+
     @Before
     fun setUp() {
+        // For BPF support kernel needs to be at least 5.4.
+        assumeTrue(kernelIsAtLeast(5, 4))
+
         runAsShell(MANAGE_TEST_NETWORKS) {
             val tnm = realContext.getSystemService(TestNetworkManager::class.java)
 
diff --git a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java
index 23744eb..1d19d26 100644
--- a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java
+++ b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java
@@ -107,7 +107,11 @@
         assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
     }
 
-    @ConnectivityModuleTest @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+    @ConnectivityModuleTest // The builder was added in an S+ module update.
+    // This whole class is not skipped (marked @ConnectivityModuleTest) in MTS for non-connectivity
+    // modules like NetworkStack, as NetworkStack uses IpConfiguration a lot on Q+, so tests that
+    // cover older APIs are still useful to provide used API coverage for NetworkStack.
+    @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
     @Test
     public void testBuilder() {
         final IpConfiguration c = new IpConfiguration.Builder()
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index bf97339..810d1c6 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -154,6 +154,10 @@
 // NetworkAgent is not updatable in R-, so this test does not need to be compatible with older
 // versions. NetworkAgent was also based on AsyncChannel before S so cannot be tested the same way.
 @IgnoreUpTo(Build.VERSION_CODES.R)
+// NetworkAgent is updated as part of the connectivity module, and running NetworkAgent tests in MTS
+// for modules other than Connectivity does not provide much value. Only run them in connectivity
+// module MTS, so the tests only need to cover the case of an updated NetworkAgent.
+@ConnectivityModuleTest
 class NetworkAgentTest {
     private val LOCAL_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1")
     private val REMOTE_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.2")
@@ -466,7 +470,6 @@
                 .addTransportType(TRANSPORT_TEST)
                 .setAccessUids(uids.toSet()).build()
 
-    @ConnectivityModuleTest // Functionality was added post-S via connectivity module update
     @Test
     fun testRejectedUpdates() {
         val callback = TestableNetworkCallback()