Merge "Add NetNativeTestBase"
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index 2fc4142..31a7262 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -290,6 +290,7 @@
         "//packages/modules/Connectivity/service",
         "//packages/modules/Connectivity/tests:__subpackages__",
         "//packages/modules/Bluetooth/android/app",
+        "//packages/modules/Wifi/service:__subpackages__",
     ],
     lint: { strict_updatability_linting: true },
 }
diff --git a/staticlibs/device/com/android/net/module/util/ip/IpNeighborMonitor.java b/staticlibs/device/com/android/net/module/util/ip/IpNeighborMonitor.java
index 88f8c9d..4a61794 100644
--- a/staticlibs/device/com/android/net/module/util/ip/IpNeighborMonitor.java
+++ b/staticlibs/device/com/android/net/module/util/ip/IpNeighborMonitor.java
@@ -22,6 +22,7 @@
 import static com.android.net.module.util.netlink.NetlinkConstants.hexify;
 import static com.android.net.module.util.netlink.NetlinkConstants.stringForNlMsgType;
 
+import android.annotation.NonNull;
 import android.net.MacAddress;
 import android.os.Handler;
 import android.system.ErrnoException;
@@ -80,15 +81,17 @@
      * An event about a neighbor.
      */
     public static class NeighborEvent {
-        final long elapsedMs;
-        final short msgType;
-        final int ifindex;
-        final InetAddress ip;
-        final short nudState;
-        final MacAddress macAddr;
+        public final long elapsedMs;
+        public final short msgType;
+        public final int ifindex;
+        @NonNull
+        public final InetAddress ip;
+        public final short nudState;
+        @NonNull
+        public final MacAddress macAddr;
 
-        public NeighborEvent(long elapsedMs, short msgType, int ifindex, InetAddress ip,
-                short nudState, MacAddress macAddr) {
+        public NeighborEvent(long elapsedMs, short msgType, int ifindex, @NonNull InetAddress ip,
+                short nudState, @NonNull MacAddress macAddr) {
             this.elapsedMs = elapsedMs;
             this.msgType = msgType;
             this.ifindex = ifindex;
@@ -101,7 +104,7 @@
             return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateConnected(nudState);
         }
 
-        boolean isValid() {
+        public boolean isValid() {
             return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateValid(nudState);
         }
 
diff --git a/staticlibs/native/bpf_headers/include/bpf/BpfMap.h b/staticlibs/native/bpf_headers/include/bpf/BpfMap.h
index 297b200..47256fa 100644
--- a/staticlibs/native/bpf_headers/include/bpf/BpfMap.h
+++ b/staticlibs/native/bpf_headers/include/bpf/BpfMap.h
@@ -50,10 +50,8 @@
     // (later on, for testing, we still make available a copy assignment operator)
     BpfMap<Key, Value>(const BpfMap<Key, Value>&) = delete;
 
-  protected:
-    // flag must be within BPF_OBJ_FLAG_MASK, ie. 0, BPF_F_RDONLY, BPF_F_WRONLY
-    BpfMap<Key, Value>(const char* pathname, uint32_t flags) {
-        mMapFd.reset(mapRetrieve(pathname, flags));
+  private:
+    void abortOnKeyOrValueSizeMismatch() {
         if (!mMapFd.ok()) abort();
         if (isAtLeastKernelVersion(4, 14, 0)) {
             if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort();
@@ -61,6 +59,13 @@
         }
     }
 
+  protected:
+    // flag must be within BPF_OBJ_FLAG_MASK, ie. 0, BPF_F_RDONLY, BPF_F_WRONLY
+    BpfMap<Key, Value>(const char* pathname, uint32_t flags) {
+        mMapFd.reset(mapRetrieve(pathname, flags));
+        abortOnKeyOrValueSizeMismatch();
+    }
+
   public:
     explicit BpfMap<Key, Value>(const char* pathname) : BpfMap<Key, Value>(pathname, 0) {}
 
@@ -117,14 +122,11 @@
         if (!mMapFd.ok()) {
             return ErrnoErrorf("Pinned map not accessible or does not exist: ({})", path);
         }
-        if (isAtLeastKernelVersion(4, 14, 0)) {
-            // Normally we should return an error here instead of calling abort,
-            // but this cannot happen at runtime without a massive code bug (K/V type mismatch)
-            // and as such it's better to just blow the system up and let the developer fix it.
-            // Crashes are much more likely to be noticed than logs and missing functionality.
-            if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort();
-            if (bpfGetFdValueSize(mMapFd) != sizeof(Value)) abort();
-        }
+        // Normally we should return an error here instead of calling abort,
+        // but this cannot happen at runtime without a massive code bug (K/V type mismatch)
+        // and as such it's better to just blow the system up and let the developer fix it.
+        // Crashes are much more likely to be noticed than logs and missing functionality.
+        abortOnKeyOrValueSizeMismatch();
         return {};
     }
 
@@ -202,11 +204,7 @@
     // check BpfMap.isValid() and look at errno and see why systemcall() failed.
     [[clang::reinitializes]] void reset(int fd) {
         mMapFd.reset(fd);
-        if ((fd >= 0) && isAtLeastKernelVersion(4, 14, 0)) {
-            if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort();
-            if (bpfGetFdValueSize(mMapFd) != sizeof(Value)) abort();
-            if (bpfGetFdMapFlags(mMapFd) != 0) abort(); // TODO: fix for BpfMapRO
-        }
+        if (mMapFd.ok()) abortOnKeyOrValueSizeMismatch();
     }
 #endif
 
diff --git a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
index ae3ad2c..8bc8eb1 100644
--- a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
+++ b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
@@ -30,6 +30,13 @@
 // Android T / 13 Beta 3 (api level 33) - added support for 'netd_shared'
 #define BPFLOADER_T_BETA3_VERSION 13u
 
+// v0.18 added support for shared and pindir, but still ignores selinux_content
+// v0.19 added support for selinux_content along with the required selinux changes
+// and should be available starting with Android T Beta 4
+//
+// Android T / 13 (api level 33) - support for shared/selinux_context/pindir
+#define BPFLOADER_T_VERSION 19u
+
 /* For mainline module use, you can #define BPFLOADER_{MIN/MAX}_VER
  * before #include "bpf_helpers.h" to change which bpfloaders will
  * process the resulting .o file.
diff --git a/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h b/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
index 4b29c44..d5b7670 100644
--- a/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
+++ b/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
@@ -150,8 +150,12 @@
                                 });
 }
 
-// requires 4.14+ kernel
-
+// BPF_OBJ_GET_INFO_BY_FD requires 4.14+ kernel
+//
+// Note: some fields are only defined in newer kernels (ie. the map_info struct grows
+// over time), so we need to check that the field we're interested in is actually
+// supported/returned by the running kernel.  We do this by checking it is fully
+// within the bounds of the struct size as reported by the kernel.
 #define DEFINE_BPF_GET_FD_INFO(NAME, FIELD) \
 inline int bpfGetFd ## NAME(const BPF_FD_TYPE map_fd) { \
     struct bpf_map_info map_info = {}; \
diff --git a/staticlibs/netd/Android.bp b/staticlibs/netd/Android.bp
index a648941..79bde9b 100644
--- a/staticlibs/netd/Android.bp
+++ b/staticlibs/netd/Android.bp
@@ -53,14 +53,6 @@
     min_sdk_version: "29",
 }
 
-// TODO: delete this one when AOSP is no longer auto-merge to git_sc-mainline-prod.
-cc_library_static {
-    name: "netd_aidl_interface-lateststable-cpp",
-    whole_static_libs: [
-        "netd_aidl_interface-V10-cpp",
-    ],
-}
-
 cc_defaults {
     name: "netd_aidl_interface_lateststable_cpp_static",
     static_libs: ["netd_aidl_interface-V10-cpp"],
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt
index 649b30e..851d09a 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt
@@ -175,6 +175,25 @@
     }
 
     @Test
+    fun testAssertionErrorInCatch() {
+        var x = 1
+        val thrown = assertFailsWith<AssertionError> {
+            tryTest {
+                x = 2
+                throw TestException1()
+            }.catch<TestException1> {
+                x = 3
+                fail("Test failure in catch")
+            } cleanup {
+                assertTrue(x == 3)
+                x = 4
+            }
+        }
+        assertTrue(x == 4)
+        assertTrue(thrown.suppressedExceptions.isEmpty())
+    }
+
+    @Test
     fun testMultipleCleanups() {
         var x = 1
         val thrown = assertFailsWith<TestException1> {
diff --git a/staticlibs/tests/unit/src/com/android/testutils/DeviceInfoUtilsTest.java b/staticlibs/tests/unit/src/com/android/testutils/DeviceInfoUtilsTest.java
index 6f603d5..e46dd59 100644
--- a/staticlibs/tests/unit/src/com/android/testutils/DeviceInfoUtilsTest.java
+++ b/staticlibs/tests/unit/src/com/android/testutils/DeviceInfoUtilsTest.java
@@ -106,4 +106,18 @@
         assertFalse(v1.isAtLeast(v4));
         assertFalse(v1.isAtLeast(v5));
     }
+
+    @Test
+    public void testKernelVersionIsAtLeast() {
+        // Pick a lower kernel version 4.0 which was released at April 2015, the kernel
+        // version running on all test devices nowadays should be higher than it.
+        assertTrue(DeviceInfoUtils.isKernelVersionAtLeast("4.0"));
+
+        // Invalid kernel version.
+        assertTrue(DeviceInfoUtils.isKernelVersionAtLeast("0.0.0"));
+
+        // Pick a higher kernel version which isn't released yet, comparison should return false.
+        // Need to update the target version in the future to make sure the test still passes.
+        assertFalse(DeviceInfoUtils.isKernelVersionAtLeast("20.0.0"));
+    }
 }
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java b/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java
index 1925b55..ea89eda 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.testutils;
 
+import android.os.VintfRuntimeInfo;
 import android.text.TextUtils;
 import android.util.Pair;
 
@@ -157,4 +158,18 @@
             return new KVersion(0, 0, 0);
         }
     }
+
+    /**
+     * Check if the current kernel version is at least satisfied with the given version.
+     *
+     * @param  version the start version to compare
+     * @return return true if the current version is at least satisfied with the given version.
+     *         otherwise, return false.
+     */
+    public static boolean isKernelVersionAtLeast(final String version) {
+        final String kernelVersion = VintfRuntimeInfo.getKernelVersion();
+        final KVersion current = DeviceInfoUtils.getMajorMinorSubminorVersion(kernelVersion);
+        final KVersion from = DeviceInfoUtils.getMajorMinorSubminorVersion(version);
+        return current.isAtLeast(from);
+    }
 }
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
index 45783d8..3db357b 100644
--- a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
@@ -90,7 +90,7 @@
         if (originalException !is E) return this
         return TryExpr(try {
             Result.success(block(originalException))
-        } catch (e: Exception) {
+        } catch (e: Throwable) {
             Result.failure(e)
         })
     }