Merge "[NETD-TC#12] Fix dependency on libtraffic_controller"
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index 50cfb02..ea38eca 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -112,6 +112,7 @@
     srcs: [
         "device/com/android/net/module/util/BpfMap.java",
         "device/com/android/net/module/util/JniUtil.java",
+        "device/com/android/net/module/util/TcUtils.java",
     ],
     sdk_version: "system_current",
     min_sdk_version: "29",
diff --git a/staticlibs/device/com/android/net/module/util/TcUtils.java b/staticlibs/device/com/android/net/module/util/TcUtils.java
new file mode 100644
index 0000000..14724d4
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/TcUtils.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 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;
+
+import java.io.IOException;
+
+/**
+ * Contains mostly tc-related functionality.
+ */
+public class TcUtils {
+    /**
+     * Checks if the network interface uses an ethernet L2 header.
+     *
+     * @param iface the network interface.
+     * @return true if the interface uses an ethernet L2 header.
+     * @throws IOException
+     */
+    public static native boolean isEthernet(String iface) throws IOException;
+
+    /**
+     * Attach a tc bpf filter.
+     *
+     * Equivalent to the following 'tc' command:
+     * tc filter add dev .. in/egress prio .. protocol ipv6/ip bpf object-pinned
+     * /sys/fs/bpf/... direct-action
+     *
+     * @param ifIndex the network interface index.
+     * @param ingress ingress or egress qdisc.
+     * @param prio
+     * @param proto
+     * @param bpfProgPath
+     * @throws IOException
+     */
+    public static native void tcFilterAddDevBpf(int ifIndex, boolean ingress, short prio,
+            short proto, String bpfProgPath) throws IOException;
+
+    /**
+     * Delete a tc filter.
+     *
+     * Equivalent to the following 'tc' command:
+     * tc filter del dev .. in/egress prio .. protocol ..
+     *
+     * @param ifIndex the network interface index.
+     * @param ingress ingress or egress qdisc.
+     * @param prio the filter preference.
+     * @param proto protocol.
+     * @throws IOException
+     */
+    public static native void tcFilterDelDev(int ifIndex, boolean ingress, short prio,
+            short proto) throws IOException;
+}
diff --git a/staticlibs/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java b/staticlibs/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
index d6222a7..71a0c96 100644
--- a/staticlibs/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
@@ -27,6 +27,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_MCX;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_MMTEL;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
@@ -84,40 +85,41 @@
       * and {@code FORCE_RESTRICTED_CAPABILITIES}.
      */
     @VisibleForTesting
-    static final long RESTRICTED_CAPABILITIES =
-            (1 << NET_CAPABILITY_BIP)
-            | (1 << NET_CAPABILITY_CBS)
-            | (1 << NET_CAPABILITY_DUN)
-            | (1 << NET_CAPABILITY_EIMS)
-            | (1 << NET_CAPABILITY_ENTERPRISE)
-            | (1 << NET_CAPABILITY_FOTA)
-            | (1 << NET_CAPABILITY_IA)
-            | (1 << NET_CAPABILITY_IMS)
-            | (1 << NET_CAPABILITY_MCX)
-            | (1 << NET_CAPABILITY_RCS)
-            | (1 << NET_CAPABILITY_VEHICLE_INTERNAL)
-            | (1 << NET_CAPABILITY_VSIM)
-            | (1 << NET_CAPABILITY_XCAP);
+    static final long RESTRICTED_CAPABILITIES = packBitList(
+            NET_CAPABILITY_BIP,
+            NET_CAPABILITY_CBS,
+            NET_CAPABILITY_DUN,
+            NET_CAPABILITY_EIMS,
+            NET_CAPABILITY_ENTERPRISE,
+            NET_CAPABILITY_FOTA,
+            NET_CAPABILITY_IA,
+            NET_CAPABILITY_IMS,
+            NET_CAPABILITY_MCX,
+            NET_CAPABILITY_RCS,
+            NET_CAPABILITY_VEHICLE_INTERNAL,
+            NET_CAPABILITY_VSIM,
+            NET_CAPABILITY_XCAP,
+            NET_CAPABILITY_MMTEL);
 
     /**
      * Capabilities that force network to be restricted.
      * See {@code NetworkCapabilities#maybeMarkCapabilitiesRestricted}.
      */
-    private static final long FORCE_RESTRICTED_CAPABILITIES =
-            (1 << NET_CAPABILITY_ENTERPRISE)
-            | (1 << NET_CAPABILITY_OEM_PAID)
-            | (1 << NET_CAPABILITY_OEM_PRIVATE);
+    private static final long FORCE_RESTRICTED_CAPABILITIES = packBitList(
+            NET_CAPABILITY_ENTERPRISE,
+            NET_CAPABILITY_OEM_PAID,
+            NET_CAPABILITY_OEM_PRIVATE);
 
     /**
      * Capabilities that suggest that a network is unrestricted.
      * See {@code NetworkCapabilities#maybeMarkCapabilitiesRestricted}.
      */
     @VisibleForTesting
-    static final long UNRESTRICTED_CAPABILITIES =
-            (1 << NET_CAPABILITY_INTERNET)
-            | (1 << NET_CAPABILITY_MMS)
-            | (1 << NET_CAPABILITY_SUPL)
-            | (1 << NET_CAPABILITY_WIFI_P2P);
+    static final long UNRESTRICTED_CAPABILITIES = packBitList(
+            NET_CAPABILITY_INTERNET,
+            NET_CAPABILITY_MMS,
+            NET_CAPABILITY_SUPL,
+            NET_CAPABILITY_WIFI_P2P);
 
     /**
      * Get a transport that can be used to classify a network when displaying its info to users.
@@ -196,7 +198,26 @@
     }
 
     /**
+     * Packs a list of ints in the same way as packBits()
+     *
+     * Each passed int is the rank of a bit that should be set in the returned long.
+     * Example : passing (1,3) will return in 0b00001010 and passing (5,6,0) will return 0b01100001
+     *
+     * @param bits bits to pack
+     * @return a long with the specified bits set.
+     */
+    public static long packBitList(int... bits) {
+        return packBits(bits);
+    }
+
+    /**
      * Packs array of bits into a long value.
+     *
+     * Each passed int is the rank of a bit that should be set in the returned long.
+     * Example : passing [1,3] will return in 0b00001010 and passing [5,6,0] will return 0b01100001
+     *
+     * @param bits bits to pack
+     * @return a long with the specified bits set.
      */
     public static long packBits(int[] bits) {
         long packed = 0;
diff --git a/staticlibs/framework/com/android/net/module/util/NetworkStatsUtils.java b/staticlibs/framework/com/android/net/module/util/NetworkStatsUtils.java
index d4ad1f2..28ff770 100644
--- a/staticlibs/framework/com/android/net/module/util/NetworkStatsUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/NetworkStatsUtils.java
@@ -68,6 +68,12 @@
     public static final int SUBSCRIBER_ID_MATCH_RULE_ALL = 1;
 
     /**
+     * Name representing {@link #bandwidthSetGlobalAlert(long)} limit when delivered to
+     * {@link AlertObserver#onQuotaLimitReached(String, String)}.
+     */
+    public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
+
+    /**
      * Return the constrained value by given the lower and upper bounds.
      */
     public static int constrain(int amount, int low, int high) {
diff --git a/staticlibs/native/bpf_syscall_wrappers/Android.bp b/staticlibs/native/bpf_syscall_wrappers/Android.bp
index 6d61256..c1bfd80 100644
--- a/staticlibs/native/bpf_syscall_wrappers/Android.bp
+++ b/staticlibs/native/bpf_syscall_wrappers/Android.bp
@@ -36,6 +36,7 @@
     visibility: [
         "//frameworks/libs/net/common/native/bpf_headers",
         "//frameworks/libs/net/common/native/bpfmapjni",
+        "//frameworks/libs/net/common/native/tcutils",
         "//packages/modules/Connectivity/netd",
         "//packages/modules/Connectivity/service",
         "//packages/modules/Connectivity/service/native",
diff --git a/staticlibs/native/bpfmapjni/Android.bp b/staticlibs/native/bpfmapjni/Android.bp
index b7af22d..8d3c90b 100644
--- a/staticlibs/native/bpfmapjni/Android.bp
+++ b/staticlibs/native/bpfmapjni/Android.bp
@@ -18,7 +18,10 @@
 
 cc_library_static {
     name: "libnet_utils_device_common_bpfjni",
-    srcs: ["com_android_net_module_util_BpfMap.cpp"],
+    srcs: [
+        "com_android_net_module_util_BpfMap.cpp",
+        "com_android_net_module_util_TcUtils.cpp",
+    ],
     header_libs: [
         "bpf_syscall_wrappers",
         "jni_headers",
@@ -27,6 +30,9 @@
         "liblog",
         "libnativehelper_compat_libc++",
     ],
+    static_libs: [
+        "libtcutils",
+    ],
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp b/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp
new file mode 100644
index 0000000..e5a3668
--- /dev/null
+++ b/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_utf_chars.h>
+#include <tcutils/tcutils.h>
+
+namespace android {
+
+static void throwIOException(JNIEnv *env, const char *msg, int error) {
+  jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg,
+                       strerror(error));
+}
+
+static jboolean com_android_net_module_util_TcUtils_isEthernet(JNIEnv *env,
+                                                               jobject clazz,
+                                                               jstring iface) {
+  ScopedUtfChars interface(env, iface);
+  bool result = false;
+  int error = isEthernet(interface.c_str(), result);
+  if (error) {
+    throwIOException(
+        env, "com_android_net_module_util_TcUtils_isEthernet error: ", error);
+  }
+  // result is not touched when error is returned; leave false.
+  return result;
+}
+
+// tc filter add dev .. in/egress prio 1 protocol ipv6/ip bpf object-pinned
+// /sys/fs/bpf/... direct-action
+static void com_android_net_module_util_TcUtils_tcFilterAddDevBpf(
+    JNIEnv *env, jobject clazz, jint ifIndex, jboolean ingress, jshort prio,
+    jshort proto, jstring bpfProgPath) {
+  ScopedUtfChars pathname(env, bpfProgPath);
+  int error = tcAddBpfFilter(ifIndex, ingress, prio, proto, pathname.c_str());
+  if (error) {
+    throwIOException(
+        env,
+        "com_android_net_module_util_TcUtils_tcFilterAddDevBpf error: ", error);
+  }
+}
+
+// tc filter del dev .. in/egress prio .. protocol ..
+static void com_android_net_module_util_TcUtils_tcFilterDelDev(
+    JNIEnv *env, jobject clazz, jint ifIndex, jboolean ingress, jshort prio,
+    jshort proto) {
+  int error = tcDeleteFilter(ifIndex, ingress, prio, proto);
+  if (error) {
+    throwIOException(
+        env,
+        "com_android_net_module_util_TcUtils_tcFilterDelDev error: ", error);
+  }
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    {"isEthernet", "(Ljava/lang/String;)Z",
+     (void *)com_android_net_module_util_TcUtils_isEthernet},
+    {"tcFilterAddDevBpf", "(IZSSLjava/lang/String;)V",
+     (void *)com_android_net_module_util_TcUtils_tcFilterAddDevBpf},
+    {"tcFilterDelDev", "(IZSS)V",
+     (void *)com_android_net_module_util_TcUtils_tcFilterDelDev},
+};
+
+int register_com_android_net_module_util_TcUtils(JNIEnv *env,
+                                                 char const *class_name) {
+  return jniRegisterNativeMethods(env, class_name, gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/staticlibs/native/tcutils/Android.bp b/staticlibs/native/tcutils/Android.bp
new file mode 100644
index 0000000..c26fca6
--- /dev/null
+++ b/staticlibs/native/tcutils/Android.bp
@@ -0,0 +1,44 @@
+// Copyright (C) 2022 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_static {
+    name: "libtcutils",
+    srcs: ["tcutils.cpp"],
+    export_include_dirs: ["include"],
+    header_libs: ["bpf_syscall_wrappers"],
+    shared_libs: [
+        "liblog",
+    ],
+    stl: "libc++_static",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+    ],
+    sdk_version: "30",
+    min_sdk_version: "30",
+    apex_available: [
+        "com.android.tethering",
+        "//apex_available:platform",
+    ],
+    visibility: [
+        "//frameworks/libs/net/common/native/bpfmapjni",
+        "//packages/modules/Connectivity:__subpackages__",
+        "//system/netd/server",
+    ],
+}
diff --git a/staticlibs/native/tcutils/include/tcutils/tcutils.h b/staticlibs/native/tcutils/include/tcutils/tcutils.h
new file mode 100644
index 0000000..d1e1bb7
--- /dev/null
+++ b/staticlibs/native/tcutils/include/tcutils/tcutils.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+namespace android {
+
+int isEthernet(const char *iface, bool &isEthernet);
+int tcAddBpfFilter(int ifIndex, bool ingress, uint16_t prio, uint16_t proto,
+                   const char *bpfProgPath);
+int tcDeleteFilter(int ifIndex, bool ingress, uint16_t prio, uint16_t proto);
+
+} // namespace android
diff --git a/staticlibs/native/tcutils/kernelversion.h b/staticlibs/native/tcutils/kernelversion.h
new file mode 100644
index 0000000..59b9e05
--- /dev/null
+++ b/staticlibs/native/tcutils/kernelversion.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+// -----------------------------------------------------------------------------
+// TODO - This should be replaced with BpfUtils in bpf_headers.
+// Currently, bpf_headers contains a bunch requirements it doesn't actually provide, such as a
+// non-ndk liblog version, and some version of libbase. libtcutils does not have access to either of
+// these, so I think this will have to wait until we figure out a way around this.
+//
+// In the mean time copying verbatim from:
+//   frameworks/libs/net/common/native/bpf_headers
+
+#include <stdio.h>
+#include <sys/utsname.h>
+
+#define KVER(a, b, c) (((a) << 24) + ((b) << 16) + (c))
+
+namespace android {
+
+unsigned kernelVersion() {
+  struct utsname buf;
+  int ret = uname(&buf);
+  if (ret)
+    return 0;
+
+  unsigned kver_major;
+  unsigned kver_minor;
+  unsigned kver_sub;
+  char discard;
+  ret = sscanf(buf.release, "%u.%u.%u%c", &kver_major, &kver_minor, &kver_sub,
+               &discard);
+  // Check the device kernel version
+  if (ret < 3)
+    return 0;
+
+  return KVER(kver_major, kver_minor, kver_sub);
+}
+
+bool isAtLeastKernelVersion(unsigned major, unsigned minor, unsigned sub) {
+  return kernelVersion() >= KVER(major, minor, sub);
+}
+
+}
diff --git a/staticlibs/native/tcutils/scopeguard.h b/staticlibs/native/tcutils/scopeguard.h
new file mode 100644
index 0000000..76bbb93
--- /dev/null
+++ b/staticlibs/native/tcutils/scopeguard.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+// -----------------------------------------------------------------------------
+// TODO: figure out a way to use libbase_ndk. This is currently not working
+// because of missing apex availability. For now, we can use a copy of
+// ScopeGuard which is very lean compared to unique_fd. This code has been
+// copied verbatim from:
+// https://cs.android.com/android/platform/superproject/+/master:system/libbase/include/android-base/scopeguard.h
+
+#pragma once
+
+#include <utility> // for std::move, std::forward
+
+namespace android {
+namespace base {
+
+// ScopeGuard ensures that the specified functor is executed no matter how the
+// current scope exits.
+template <typename F> class ScopeGuard {
+public:
+  ScopeGuard(F &&f) : f_(std::forward<F>(f)), active_(true) {}
+
+  ScopeGuard(ScopeGuard &&that) noexcept
+      : f_(std::move(that.f_)), active_(that.active_) {
+    that.active_ = false;
+  }
+
+  template <typename Functor>
+  ScopeGuard(ScopeGuard<Functor> &&that)
+      : f_(std::move(that.f_)), active_(that.active_) {
+    that.active_ = false;
+  }
+
+  ~ScopeGuard() {
+    if (active_)
+      f_();
+  }
+
+  ScopeGuard() = delete;
+  ScopeGuard(const ScopeGuard &) = delete;
+  void operator=(const ScopeGuard &) = delete;
+  void operator=(ScopeGuard &&that) = delete;
+
+  void Disable() { active_ = false; }
+
+  bool active() const { return active_; }
+
+private:
+  template <typename Functor> friend class ScopeGuard;
+
+  F f_;
+  bool active_;
+};
+
+template <typename F> ScopeGuard<F> make_scope_guard(F &&f) {
+  return ScopeGuard<F>(std::forward<F>(f));
+}
+
+} // namespace base
+} // namespace android
diff --git a/staticlibs/native/tcutils/tcutils.cpp b/staticlibs/native/tcutils/tcutils.cpp
new file mode 100644
index 0000000..e30a500
--- /dev/null
+++ b/staticlibs/native/tcutils/tcutils.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#define LOG_TAG "TcUtils"
+
+#include "tcutils/tcutils.h"
+
+#include "kernelversion.h"
+#include "scopeguard.h"
+
+#include <android/log.h>
+#include <arpa/inet.h>
+#include <cerrno>
+#include <cstring>
+#include <libgen.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/netlink.h>
+#include <linux/pkt_cls.h>
+#include <linux/pkt_sched.h>
+#include <linux/rtnetlink.h>
+#include <net/if.h>
+#include <stdarg.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <utility>
+
+#define BPF_FD_JUST_USE_INT
+#include <BpfSyscallWrappers.h>
+#undef BPF_FD_JUST_USE_INT
+
+// The maximum length of TCA_BPF_NAME. Sync from net/sched/cls_bpf.c.
+#define CLS_BPF_NAME_LEN 256
+
+// Classifier name. See cls_bpf_ops in net/sched/cls_bpf.c.
+#define CLS_BPF_KIND_NAME "bpf"
+
+namespace android {
+namespace {
+
+void logError(const char *fmt...) {
+  va_list args;
+  va_start(args, fmt);
+  __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, fmt, args);
+  va_end(args);
+}
+
+const sockaddr_nl KERNEL_NLADDR = {AF_NETLINK, 0, 0, 0};
+const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;
+
+int sendAndProcessNetlinkResponse(const void *req, int len) {
+  // TODO: use unique_fd instead of ScopeGuard
+  int fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
+  if (fd == -1) {
+    int error = errno;
+    logError("socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE): %d",
+             error);
+    return -error;
+  }
+  auto scopeGuard = base::make_scope_guard([fd] { close(fd); });
+
+  static constexpr int on = 1;
+  if (setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on))) {
+    int error = errno;
+    logError("setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, 1): %d", error);
+    return -error;
+  }
+
+  // this is needed to get valid strace netlink parsing, it allocates the pid
+  if (bind(fd, (const struct sockaddr *)&KERNEL_NLADDR,
+           sizeof(KERNEL_NLADDR))) {
+    int error = errno;
+    logError("bind(fd, {AF_NETLINK, 0, 0}: %d)", error);
+    return -error;
+  }
+
+  // we do not want to receive messages from anyone besides the kernel
+  if (connect(fd, (const struct sockaddr *)&KERNEL_NLADDR,
+              sizeof(KERNEL_NLADDR))) {
+    int error = errno;
+    logError("connect(fd, {AF_NETLINK, 0, 0}): %d", error);
+    return -error;
+  }
+
+  int rv = send(fd, req, len, 0);
+
+  if (rv == -1) {
+    int error = errno;
+    logError("send(fd, req, len, 0) failed: %d", error);
+    return -error;
+  }
+
+  if (rv != len) {
+    logError("send(fd, req, len = %d, 0) returned invalid message size %d", len,
+             rv);
+    return -EMSGSIZE;
+  }
+
+  struct {
+    nlmsghdr h;
+    nlmsgerr e;
+    char buf[256];
+  } resp = {};
+
+  rv = recv(fd, &resp, sizeof(resp), MSG_TRUNC);
+
+  if (rv == -1) {
+    int error = errno;
+    logError("recv() failed: %d", error);
+    return -error;
+  }
+
+  if (rv < (int)NLMSG_SPACE(sizeof(struct nlmsgerr))) {
+    logError("recv() returned short packet: %d", rv);
+    return -EBADMSG;
+  }
+
+  if (resp.h.nlmsg_len != (unsigned)rv) {
+    logError("recv() returned invalid header length: %d != %d",
+             resp.h.nlmsg_len, rv);
+    return -EBADMSG;
+  }
+
+  if (resp.h.nlmsg_type != NLMSG_ERROR) {
+    logError("recv() did not return NLMSG_ERROR message: %d",
+             resp.h.nlmsg_type);
+    return -ENOMSG;
+  }
+
+  if (resp.e.error) {
+    logError("NLMSG_ERROR message return error: %d", resp.e.error);
+  }
+  return resp.e.error; // returns 0 on success
+}
+
+int hardwareAddressType(const char *interface) {
+  int fd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+  if (fd < 0)
+    return -errno;
+  auto scopeGuard = base::make_scope_guard([fd] { close(fd); });
+
+  struct ifreq ifr = {};
+  // We use strncpy() instead of strlcpy() since kernel has to be able
+  // to handle non-zero terminated junk passed in by userspace anyway,
+  // and this way too long interface names (more than IFNAMSIZ-1 = 15
+  // characters plus terminating NULL) will not get truncated to 15
+  // characters and zero-terminated and thus potentially erroneously
+  // match a truncated interface if one were to exist.
+  strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
+
+  if (ioctl(fd, SIOCGIFHWADDR, &ifr, sizeof(ifr))) {
+    return -errno;
+  }
+  return ifr.ifr_hwaddr.sa_family;
+}
+
+} // namespace
+
+int isEthernet(const char *iface, bool &isEthernet) {
+  int rv = hardwareAddressType(iface);
+  if (rv < 0) {
+    logError("Get hardware address type of interface %s failed: %s", iface,
+             strerror(-rv));
+    return -rv;
+  }
+
+  // Backwards compatibility with pre-GKI kernels that use various custom
+  // ARPHRD_* for their cellular interface
+  switch (rv) {
+  // ARPHRD_PUREIP on at least some Mediatek Android kernels
+  // example: wembley with 4.19 kernel
+  case 520:
+  // in Linux 4.14+ rmnet support was upstreamed and ARHRD_RAWIP became 519,
+  // but it is 530 on at least some Qualcomm Android 4.9 kernels with rmnet
+  // example: Pixel 3 family
+  case 530:
+    // >5.4 kernels are GKI2.0 and thus upstream compatible, however 5.10
+    // shipped with Android S, so (for safety) let's limit ourselves to
+    // >5.10, ie. 5.11+ as a guarantee we're on Android T+ and thus no
+    // longer need this non-upstream compatibility logic
+    static bool is_pre_5_11_kernel = !isAtLeastKernelVersion(5, 11, 0);
+    if (is_pre_5_11_kernel)
+      return false;
+  }
+
+  switch (rv) {
+  case ARPHRD_ETHER:
+    isEthernet = true;
+    return 0;
+  case ARPHRD_NONE:
+  case ARPHRD_PPP:
+  case ARPHRD_RAWIP:
+    isEthernet = false;
+    return 0;
+  default:
+    logError("Unknown hardware address type %d on interface %s", rv, iface);
+    return -ENOENT;
+  }
+}
+
+// tc filter add dev .. in/egress prio 1 protocol ipv6/ip bpf object-pinned
+// /sys/fs/bpf/... direct-action
+int tcAddBpfFilter(int ifIndex, bool ingress, uint16_t prio, uint16_t proto,
+                   const char *bpfProgPath) {
+  const int bpfFd = bpf::retrieveProgram(bpfProgPath);
+  if (bpfFd == -1) {
+    logError("retrieveProgram failed: %d", errno);
+    return -errno;
+  }
+  auto scopeGuard = base::make_scope_guard([bpfFd] { close(bpfFd); });
+
+  struct {
+    nlmsghdr n;
+    tcmsg t;
+    struct {
+      nlattr attr;
+      // The maximum classifier name length is defined in
+      // tcf_proto_ops in include/net/sch_generic.h.
+      char str[NLMSG_ALIGN(sizeof(CLS_BPF_KIND_NAME))];
+    } kind;
+    struct {
+      nlattr attr;
+      struct {
+        nlattr attr;
+        __u32 u32;
+      } fd;
+      struct {
+        nlattr attr;
+        char str[NLMSG_ALIGN(CLS_BPF_NAME_LEN)];
+      } name;
+      struct {
+        nlattr attr;
+        __u32 u32;
+      } flags;
+    } options;
+  } req = {
+      .n =
+          {
+              .nlmsg_len = sizeof(req),
+              .nlmsg_type = RTM_NEWTFILTER,
+              .nlmsg_flags = NETLINK_REQUEST_FLAGS | NLM_F_EXCL | NLM_F_CREATE,
+          },
+      .t =
+          {
+              .tcm_family = AF_UNSPEC,
+              .tcm_ifindex = ifIndex,
+              .tcm_handle = TC_H_UNSPEC,
+              .tcm_parent = TC_H_MAKE(TC_H_CLSACT, ingress ? TC_H_MIN_INGRESS
+                                                           : TC_H_MIN_EGRESS),
+              .tcm_info =
+                  static_cast<__u32>((static_cast<uint16_t>(prio) << 16) |
+                                     htons(static_cast<uint16_t>(proto))),
+          },
+      .kind =
+          {
+              .attr =
+                  {
+                      .nla_len = sizeof(req.kind),
+                      .nla_type = TCA_KIND,
+                  },
+              .str = CLS_BPF_KIND_NAME,
+          },
+      .options =
+          {
+              .attr =
+                  {
+                      .nla_len = sizeof(req.options),
+                      .nla_type = NLA_F_NESTED | TCA_OPTIONS,
+                  },
+              .fd =
+                  {
+                      .attr =
+                          {
+                              .nla_len = sizeof(req.options.fd),
+                              .nla_type = TCA_BPF_FD,
+                          },
+                      .u32 = static_cast<__u32>(bpfFd),
+                  },
+              .name =
+                  {
+                      .attr =
+                          {
+                              .nla_len = sizeof(req.options.name),
+                              .nla_type = TCA_BPF_NAME,
+                          },
+                      // Visible via 'tc filter show', but
+                      // is overwritten by strncpy below
+                      .str = "placeholder",
+                  },
+              .flags =
+                  {
+                      .attr =
+                          {
+                              .nla_len = sizeof(req.options.flags),
+                              .nla_type = TCA_BPF_FLAGS,
+                          },
+                      .u32 = TCA_BPF_FLAG_ACT_DIRECT,
+                  },
+          },
+  };
+
+  snprintf(req.options.name.str, sizeof(req.options.name.str), "%s:[*fsobj]",
+           basename(bpfProgPath));
+
+  int error = sendAndProcessNetlinkResponse(&req, sizeof(req));
+  return error;
+}
+
+// tc filter del dev .. in/egress prio .. protocol ..
+int tcDeleteFilter(int ifIndex, bool ingress, uint16_t prio, uint16_t proto) {
+  const struct {
+    nlmsghdr n;
+    tcmsg t;
+  } req = {
+      .n =
+          {
+              .nlmsg_len = sizeof(req),
+              .nlmsg_type = RTM_DELTFILTER,
+              .nlmsg_flags = NETLINK_REQUEST_FLAGS,
+          },
+      .t =
+          {
+              .tcm_family = AF_UNSPEC,
+              .tcm_ifindex = ifIndex,
+              .tcm_handle = TC_H_UNSPEC,
+              .tcm_parent = TC_H_MAKE(TC_H_CLSACT, ingress ? TC_H_MIN_INGRESS
+                                                           : TC_H_MIN_EGRESS),
+              .tcm_info =
+                  static_cast<__u32>((static_cast<uint16_t>(prio) << 16) |
+                                     htons(static_cast<uint16_t>(proto))),
+          },
+  };
+
+  return sendAndProcessNetlinkResponse(&req, sizeof(req));
+}
+
+} // namespace android
diff --git a/staticlibs/netd/Android.bp b/staticlibs/netd/Android.bp
index a615ec1..e249e19 100644
--- a/staticlibs/netd/Android.bp
+++ b/staticlibs/netd/Android.bp
@@ -21,7 +21,7 @@
     sdk_version: "system_current",
     min_sdk_version: "29",
     static_libs: [
-        "netd_aidl_interface-V7-java",
+        "netd_aidl_interface-V8-java",
     ],
     apex_available: [
         "//apex_available:platform", // used from services.net
@@ -44,7 +44,7 @@
 cc_library_static {
     name: "netd_aidl_interface-lateststable-ndk",
     whole_static_libs: [
-        "netd_aidl_interface-V7-ndk",
+        "netd_aidl_interface-V8-ndk",
     ],
     apex_available: [
         "com.android.resolv",
@@ -56,7 +56,7 @@
 cc_library_static {
     name: "netd_aidl_interface-lateststable-cpp",
     whole_static_libs: [
-        "netd_aidl_interface-V7-cpp",
+        "netd_aidl_interface-V8-cpp",
     ],
 }
 
@@ -113,6 +113,7 @@
         "5",
         "6",
         "7",
+        "8",
     ],
 }
 
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/.hash b/staticlibs/netd/aidl_api/netd_aidl_interface/8/.hash
new file mode 100644
index 0000000..0933816
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/.hash
@@ -0,0 +1 @@
+e8cf8586fc5da9063818d8775e9a21c4b0addb5b
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/INetd.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/INetd.aidl
new file mode 100644
index 0000000..ec03d86
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/INetd.aidl
@@ -0,0 +1,200 @@
+/**
+ * Copyright (c) 2016, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetd {
+  boolean isAlive();
+  boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isAllowlist, in int[] uids);
+  boolean bandwidthEnableDataSaver(boolean enable);
+  /**
+   * @deprecated use networkCreate() instead.
+   */
+  void networkCreatePhysical(int netId, int permission);
+  /**
+   * @deprecated use networkCreate() instead.
+   */
+  void networkCreateVpn(int netId, boolean secure);
+  void networkDestroy(int netId);
+  void networkAddInterface(int netId, in @utf8InCpp String iface);
+  void networkRemoveInterface(int netId, in @utf8InCpp String iface);
+  void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
+  void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
+  void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
+  void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
+  boolean tetherApplyDnsInterfaces();
+  android.net.TetherStatsParcel[] tetherGetStats();
+  void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
+  void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
+  @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
+  void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
+  void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
+  int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
+  void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
+  void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
+  void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
+  void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
+  void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
+  void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
+  void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
+  void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
+  void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
+  void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
+  void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
+  void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
+  void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
+  void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
+  void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
+  void strictUidCleartextPenalty(int uid, int policyPenalty);
+  @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
+  void clatdStop(in @utf8InCpp String ifName);
+  boolean ipfwdEnabled();
+  @utf8InCpp String[] ipfwdGetRequesterList();
+  void ipfwdEnableForwarding(in @utf8InCpp String requester);
+  void ipfwdDisableForwarding(in @utf8InCpp String requester);
+  void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
+  void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
+  void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
+  void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
+  void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
+  void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
+  void bandwidthSetGlobalAlert(long bytes);
+  void bandwidthAddNaughtyApp(int uid);
+  void bandwidthRemoveNaughtyApp(int uid);
+  void bandwidthAddNiceApp(int uid);
+  void bandwidthRemoveNiceApp(int uid);
+  void tetherStart(in @utf8InCpp String[] dhcpRanges);
+  void tetherStop();
+  boolean tetherIsEnabled();
+  void tetherInterfaceAdd(in @utf8InCpp String ifName);
+  void tetherInterfaceRemove(in @utf8InCpp String ifName);
+  @utf8InCpp String[] tetherInterfaceList();
+  void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
+  @utf8InCpp String[] tetherDnsList();
+  void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
+  void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
+  void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
+  void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
+  int networkGetDefault();
+  void networkSetDefault(int netId);
+  void networkClearDefault();
+  void networkSetPermissionForNetwork(int netId, int permission);
+  void networkSetPermissionForUser(int permission, in int[] uids);
+  void networkClearPermissionForUser(in int[] uids);
+  void trafficSetNetPermForUids(int permission, in int[] uids);
+  void networkSetProtectAllow(int uid);
+  void networkSetProtectDeny(int uid);
+  boolean networkCanProtect(int uid);
+  void firewallSetFirewallType(int firewalltype);
+  void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
+  void firewallSetUidRule(int childChain, int uid, int firewallRule);
+  void firewallEnableChildChain(int childChain, boolean enable);
+  @utf8InCpp String[] interfaceGetList();
+  android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
+  void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
+  void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
+  void interfaceClearAddrs(in @utf8InCpp String ifName);
+  void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
+  void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
+  void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
+  void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
+  void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
+  void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
+  void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
+  void firewallRemoveUidInterfaceRules(in int[] uids);
+  void trafficSwapActiveStatsMap();
+  IBinder getOemNetd();
+  void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
+  android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
+  void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+  void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+  void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+  void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
+  void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
+  android.net.TetherStatsParcel[] tetherOffloadGetStats();
+  void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
+  android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
+  void networkCreate(in android.net.NativeNetworkConfig config);
+  void networkAddUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+  void networkRemoveUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+  const int IPV4 = 4;
+  const int IPV6 = 6;
+  const int CONF = 1;
+  const int NEIGH = 2;
+  const String IPSEC_INTERFACE_PREFIX = "ipsec";
+  const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
+  const int IPV6_ADDR_GEN_MODE_NONE = 1;
+  const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
+  const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
+  const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
+  const int PENALTY_POLICY_ACCEPT = 1;
+  const int PENALTY_POLICY_LOG = 2;
+  const int PENALTY_POLICY_REJECT = 3;
+  const int LOCAL_NET_ID = 99;
+  const int DUMMY_NET_ID = 51;
+  const int UNREACHABLE_NET_ID = 52;
+  const String NEXTHOP_NONE = "";
+  const String NEXTHOP_UNREACHABLE = "unreachable";
+  const String NEXTHOP_THROW = "throw";
+  const int PERMISSION_NONE = 0;
+  const int PERMISSION_NETWORK = 1;
+  const int PERMISSION_SYSTEM = 2;
+  const int NO_PERMISSIONS = 0;
+  const int PERMISSION_INTERNET = 4;
+  const int PERMISSION_UPDATE_DEVICE_STATS = 8;
+  const int PERMISSION_UNINSTALLED = -1;
+  /**
+   * @deprecated use FIREWALL_ALLOWLIST.
+   */
+  const int FIREWALL_WHITELIST = 0;
+  const int FIREWALL_ALLOWLIST = 0;
+  /**
+   * @deprecated use FIREWALL_DENYLIST.
+   */
+  const int FIREWALL_BLACKLIST = 1;
+  const int FIREWALL_DENYLIST = 1;
+  const int FIREWALL_RULE_ALLOW = 1;
+  const int FIREWALL_RULE_DENY = 2;
+  const int FIREWALL_CHAIN_NONE = 0;
+  const int FIREWALL_CHAIN_DOZABLE = 1;
+  const int FIREWALL_CHAIN_STANDBY = 2;
+  const int FIREWALL_CHAIN_POWERSAVE = 3;
+  const int FIREWALL_CHAIN_RESTRICTED = 4;
+  const String IF_STATE_UP = "up";
+  const String IF_STATE_DOWN = "down";
+  const String IF_FLAG_BROADCAST = "broadcast";
+  const String IF_FLAG_LOOPBACK = "loopback";
+  const String IF_FLAG_POINTOPOINT = "point-to-point";
+  const String IF_FLAG_RUNNING = "running";
+  const String IF_FLAG_MULTICAST = "multicast";
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/INetdUnsolicitedEventListener.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/INetdUnsolicitedEventListener.aidl
new file mode 100644
index 0000000..31775df
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/INetdUnsolicitedEventListener.aidl
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2018, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetdUnsolicitedEventListener {
+  oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
+  oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
+  oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
+  oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
+  oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
+  oneway void onInterfaceAdded(@utf8InCpp String ifName);
+  oneway void onInterfaceRemoved(@utf8InCpp String ifName);
+  oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
+  oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
+  oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
+  oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/InterfaceConfigurationParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/InterfaceConfigurationParcel.aidl
new file mode 100644
index 0000000..1869d8d
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/InterfaceConfigurationParcel.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable InterfaceConfigurationParcel {
+  @utf8InCpp String ifName;
+  @utf8InCpp String hwAddr;
+  @utf8InCpp String ipv4Addr;
+  int prefixLength;
+  @utf8InCpp String[] flags;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/MarkMaskParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/MarkMaskParcel.aidl
new file mode 100644
index 0000000..8ea20d1
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/MarkMaskParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable MarkMaskParcel {
+  int mark;
+  int mask;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeNetworkConfig.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeNetworkConfig.aidl
new file mode 100644
index 0000000..77d814b
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeNetworkConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeNetworkConfig {
+  int netId;
+  android.net.NativeNetworkType networkType = android.net.NativeNetworkType.PHYSICAL;
+  int permission;
+  boolean secure;
+  android.net.NativeVpnType vpnType = android.net.NativeVpnType.PLATFORM;
+  boolean excludeLocalRoutes = false;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeNetworkType.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeNetworkType.aidl
new file mode 100644
index 0000000..06c8979
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeNetworkType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@Backing(type="int")
+enum NativeNetworkType {
+  PHYSICAL = 0,
+  VIRTUAL = 1,
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeVpnType.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeVpnType.aidl
new file mode 100644
index 0000000..8a8be83
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/NativeVpnType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@Backing(type="int")
+enum NativeVpnType {
+  SERVICE = 1,
+  PLATFORM = 2,
+  LEGACY = 3,
+  OEM = 4,
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/RouteInfoParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/RouteInfoParcel.aidl
new file mode 100644
index 0000000..5ef95e6
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/RouteInfoParcel.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2020, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable RouteInfoParcel {
+  @utf8InCpp String destination;
+  @utf8InCpp String ifName;
+  @utf8InCpp String nextHop;
+  int mtu;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherConfigParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherConfigParcel.aidl
new file mode 100644
index 0000000..7b39c22
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherConfigParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherConfigParcel {
+  boolean usingLegacyDnsProxy;
+  @utf8InCpp String[] dhcpRanges;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherOffloadRuleParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherOffloadRuleParcel.aidl
new file mode 100644
index 0000000..983e986
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherOffloadRuleParcel.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherOffloadRuleParcel {
+  int inputInterfaceIndex;
+  int outputInterfaceIndex;
+  byte[] destination;
+  int prefixLength;
+  byte[] srcL2Address;
+  byte[] dstL2Address;
+  int pmtu = 1500;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherStatsParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherStatsParcel.aidl
new file mode 100644
index 0000000..5f1b722
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/TetherStatsParcel.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherStatsParcel {
+  @utf8InCpp String iface;
+  long rxBytes;
+  long rxPackets;
+  long txBytes;
+  long txPackets;
+  int ifIndex = 0;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/UidRangeParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/UidRangeParcel.aidl
new file mode 100644
index 0000000..72e987a
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/UidRangeParcel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable UidRangeParcel {
+  int start;
+  int stop;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/netd/aidl/NativeUidRangeConfig.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/netd/aidl/NativeUidRangeConfig.aidl
new file mode 100644
index 0000000..9bb679f
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/8/android/net/netd/aidl/NativeUidRangeConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.netd.aidl;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeUidRangeConfig {
+  int netId;
+  android.net.UidRangeParcel[] uidRanges;
+  int subPriority;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkConfig.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkConfig.aidl
index 76562b2..77d814b 100644
--- a/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkConfig.aidl
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkConfig.aidl
@@ -40,4 +40,5 @@
   int permission;
   boolean secure;
   android.net.NativeVpnType vpnType = android.net.NativeVpnType.PLATFORM;
+  boolean excludeLocalRoutes = false;
 }
diff --git a/staticlibs/netd/binder/android/net/NativeNetworkConfig.aidl b/staticlibs/netd/binder/android/net/NativeNetworkConfig.aidl
index 2c4f83a..e654a1f 100644
--- a/staticlibs/netd/binder/android/net/NativeNetworkConfig.aidl
+++ b/staticlibs/netd/binder/android/net/NativeNetworkConfig.aidl
@@ -49,4 +49,9 @@
 
     /** For virtual networks. The type of VPN to create.  Ignored for all other network types. */
     NativeVpnType vpnType = NativeVpnType.PLATFORM;
+
+    /**
+     * For virtual networks. Whether local traffic is excluded from the VPN.
+     */
+    boolean excludeLocalRoutes = false;
 }
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt
index f78c74e..256ea1e 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt
@@ -18,6 +18,7 @@
 
 import android.annotation.TargetApi
 import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_BIP
 import android.net.NetworkCapabilities.NET_CAPABILITY_CBS
 import android.net.NetworkCapabilities.NET_CAPABILITY_EIMS
 import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
@@ -33,6 +34,7 @@
 import android.os.Build
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
+import com.android.modules.utils.build.SdkLevel
 import com.android.net.module.util.NetworkCapabilitiesUtils.RESTRICTED_CAPABILITIES
 import com.android.net.module.util.NetworkCapabilitiesUtils.UNRESTRICTED_CAPABILITIES
 import com.android.net.module.util.NetworkCapabilitiesUtils.getDisplayTransport
@@ -110,6 +112,12 @@
         // as restricted when there is no any unrestricted capability.
         nc.removeCapability(NET_CAPABILITY_INTERNET)
         assertTrue(NetworkCapabilitiesUtils.inferRestrictedCapability(nc))
+        if (!SdkLevel.isAtLeastS()) return
+        // BIP deserves its specific test because it's the first capability over 30, meaning the
+        // shift will overflow
+        nc.removeCapability(NET_CAPABILITY_CBS)
+        nc.addCapability(NET_CAPABILITY_BIP)
+        assertTrue(NetworkCapabilitiesUtils.inferRestrictedCapability(nc))
     }
 
     @Test
@@ -122,9 +130,17 @@
         assertEquals((1 shl NET_CAPABILITY_CBS).toLong() and RESTRICTED_CAPABILITIES,
                 (1 shl NET_CAPABILITY_CBS).toLong())
 
+        // verify BIP is also restricted
+        // BIP is not available in R and before, but the BIP constant is inlined so
+        // this test can still run on R.
+        assertEquals((1L shl NET_CAPABILITY_BIP) and RESTRICTED_CAPABILITIES,
+                (1L shl NET_CAPABILITY_BIP))
+
         // verify default is not restricted
         assertEquals((1 shl NET_CAPABILITY_INTERNET).toLong() and RESTRICTED_CAPABILITIES, 0)
 
+        assertTrue(RESTRICTED_CAPABILITIES > 0)
+
         // just to see
         assertEquals(RESTRICTED_CAPABILITIES and UNRESTRICTED_CAPABILITIES, 0)
     }