diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index d8557ad..0c9801c 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -60,8 +60,12 @@
         "com.android.tethering",
     ],
     min_sdk_version: "30",
+    include_dirs: [
+        // TODO: use the libbpf_android_headers instead of just including the header files.
+        "system/bpf/libbpf_android/include/",
+    ],
     srcs: [
-        "jni/android_net_util_TetheringUtils.cpp",
+        "jni/*.cpp",
     ],
     shared_libs: [
         "liblog",
diff --git a/Tethering/bpf_progs/offload.c b/Tethering/bpf_progs/offload.c
index cc5af31..d8dc60d 100644
--- a/Tethering/bpf_progs/offload.c
+++ b/Tethering/bpf_progs/offload.c
@@ -34,6 +34,10 @@
 // (tethering allowed when stats[iif].rxBytes + stats[iif].txBytes < limit[iif])
 DEFINE_BPF_MAP_GRW(tether_limit_map, HASH, uint32_t, uint64_t, 16, AID_NETWORK_STACK)
 
+// Used only by TetheringPrivilegedTests, not by production code.
+DEFINE_BPF_MAP_GRW(tether_ingress_map_TEST, HASH, TetherIngressKey, TetherIngressValue, 16,
+                   AID_NETWORK_STACK)
+
 static inline __always_inline int do_forward(struct __sk_buff* skb, bool is_ethernet) {
     int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
     void* data = (void*)(long)skb->data;
diff --git a/Tethering/jarjar-rules.txt b/Tethering/jarjar-rules.txt
index 591861f..d1ad569 100644
--- a/Tethering/jarjar-rules.txt
+++ b/Tethering/jarjar-rules.txt
@@ -8,4 +8,7 @@
 rule android.net.shared.Inet4AddressUtils* com.android.networkstack.tethering.shared.Inet4AddressUtils@1
 
 # Classes from net-utils-framework-common
-rule com.android.net.module.util.** com.android.networkstack.tethering.util.@1
\ No newline at end of file
+rule com.android.net.module.util.** com.android.networkstack.tethering.util.@1
+
+# Classes from net-utils-device-common
+rule com.android.net.module.util.Struct* com.android.networkstack.tethering.util.Struct@1
diff --git a/Tethering/jni/android_net_util_TetheringUtils.cpp b/Tethering/jni/android_net_util_TetheringUtils.cpp
index 7bfb6da..27c84cf 100644
--- a/Tethering/jni/android_net_util_TetheringUtils.cpp
+++ b/Tethering/jni/android_net_util_TetheringUtils.cpp
@@ -28,9 +28,6 @@
 #include <sys/socket.h>
 #include <stdio.h>
 
-#define LOG_TAG "TetheringUtils"
-#include <android/log.h>
-
 namespace android {
 
 static const uint32_t kIPv6NextHeaderOffset = offsetof(ip6_hdr, ip6_nxt);
@@ -184,18 +181,4 @@
             gMethods, NELEM(gMethods));
 }
 
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
-        return JNI_ERR;
-    }
-
-    if (register_android_net_util_TetheringUtils(env) < 0) {
-        return JNI_ERR;
-    }
-
-    return JNI_VERSION_1_6;
-}
-
 }; // namespace android
diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
new file mode 100644
index 0000000..64f7dcf
--- /dev/null
+++ b/Tethering/jni/com_android_networkstack_tethering_BpfMap.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#include <linux/bpf.h>
+#include <errno.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "nativehelper/scoped_primitive_array.h"
+#include "nativehelper/scoped_utf_chars.h"
+
+#define BPF_FD_JUST_USE_INT
+#include "bpf/BpfUtils.h"
+
+namespace android {
+
+static jclass sErrnoExceptionClass;
+static jmethodID sErrnoExceptionCtor2;
+static jmethodID sErrnoExceptionCtor3;
+
+static void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
+    if (sErrnoExceptionClass == nullptr || sErrnoExceptionClass == nullptr) return;
+
+    jthrowable cause = nullptr;
+    if (env->ExceptionCheck()) {
+        cause = env->ExceptionOccurred();
+        env->ExceptionClear();
+    }
+
+    ScopedLocalRef<jstring> msg(env, env->NewStringUTF(functionName));
+
+    // Not really much we can do here if msg is null, let's try to stumble on...
+    if (msg.get() == nullptr) env->ExceptionClear();
+
+    jobject errnoException;
+    if (cause != nullptr) {
+        errnoException = env->NewObject(sErrnoExceptionClass, sErrnoExceptionCtor3, msg.get(),
+                error, cause);
+    } else {
+        errnoException = env->NewObject(sErrnoExceptionClass, sErrnoExceptionCtor2, msg.get(),
+                error);
+    }
+    env->Throw(static_cast<jthrowable>(errnoException));
+}
+
+static jint com_android_networkstack_tethering_BpfMap_closeMap(JNIEnv *env, jobject clazz,
+        jint fd) {
+    int ret = close(fd);
+
+    if (ret) throwErrnoException(env, "closeMap", errno);
+
+    return ret;
+}
+
+static jint com_android_networkstack_tethering_BpfMap_bpfFdGet(JNIEnv *env, jobject clazz,
+        jstring path, jint mode) {
+    ScopedUtfChars pathname(env, path);
+
+    jint fd = bpf::bpfFdGet(pathname.c_str(), static_cast<unsigned>(mode));
+
+    return fd;
+}
+
+static void com_android_networkstack_tethering_BpfMap_writeToMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray value, jint flags) {
+    ScopedByteArrayRO keyRO(env, key);
+    ScopedByteArrayRO valueRO(env, value);
+
+    int ret = bpf::writeToMapEntry(static_cast<int>(fd), keyRO.get(), valueRO.get(),
+            static_cast<int>(flags));
+
+    if (ret) throwErrnoException(env, "writeToMapEntry", errno);
+}
+
+static jboolean throwIfNotEnoent(JNIEnv *env, const char* functionName, int ret, int err) {
+    if (ret == 0) return true;
+
+    if (err != ENOENT) throwErrnoException(env, functionName, err);
+    return false;
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_deleteMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key) {
+    ScopedByteArrayRO keyRO(env, key);
+
+    // On success, zero is returned.  If the element is not found, -1 is returned and errno is set
+    // to ENOENT.
+    int ret = bpf::deleteMapEntry(static_cast<int>(fd), keyRO.get());
+
+    return throwIfNotEnoent(env, "deleteMapEntry", ret, errno);
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_getNextMapKey(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray nextKey) {
+    // If key is found, the operation returns zero and sets the next key pointer to the key of the
+    // next element.  If key is not found, the operation returns zero and sets the next key pointer
+    // to the key of the first element.  If key is the last element, -1 is returned and errno is
+    // set to ENOENT.  Other possible errno values are ENOMEM, EFAULT, EPERM, and EINVAL.
+    ScopedByteArrayRW nextKeyRW(env, nextKey);
+    int ret;
+    if (key == nullptr) {
+        // Called by getFirstKey. Find the first key in the map.
+        ret = bpf::getNextMapKey(static_cast<int>(fd), nullptr, nextKeyRW.get());
+    } else {
+        ScopedByteArrayRO keyRO(env, key);
+        ret = bpf::getNextMapKey(static_cast<int>(fd), keyRO.get(), nextKeyRW.get());
+    }
+
+    return throwIfNotEnoent(env, "getNextMapKey", ret, errno);
+}
+
+static jboolean com_android_networkstack_tethering_BpfMap_findMapEntry(JNIEnv *env, jobject clazz,
+        jint fd, jbyteArray key, jbyteArray value) {
+    ScopedByteArrayRO keyRO(env, key);
+    ScopedByteArrayRW valueRW(env, value);
+
+    // If an element is found, the operation returns zero and stores the element's value into
+    // "value".  If no element is found, the operation returns -1 and sets errno to ENOENT.
+    int ret = bpf::findMapEntry(static_cast<int>(fd), keyRO.get(), valueRW.get());
+
+    return throwIfNotEnoent(env, "findMapEntry", ret, errno);
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "closeMap", "(I)I",
+        (void*) com_android_networkstack_tethering_BpfMap_closeMap },
+    { "bpfFdGet", "(Ljava/lang/String;I)I",
+        (void*) com_android_networkstack_tethering_BpfMap_bpfFdGet },
+    { "writeToMapEntry", "(I[B[BI)V",
+        (void*) com_android_networkstack_tethering_BpfMap_writeToMapEntry },
+    { "deleteMapEntry", "(I[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_deleteMapEntry },
+    { "getNextMapKey", "(I[B[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_getNextMapKey },
+    { "findMapEntry", "(I[B[B)Z",
+        (void*) com_android_networkstack_tethering_BpfMap_findMapEntry },
+
+};
+
+int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env) {
+    sErrnoExceptionClass = static_cast<jclass>(env->NewGlobalRef(
+            env->FindClass("android/system/ErrnoException")));
+    if (sErrnoExceptionClass == nullptr) return JNI_ERR;
+
+    sErrnoExceptionCtor2 = env->GetMethodID(sErrnoExceptionClass, "<init>",
+            "(Ljava/lang/String;I)V");
+    if (sErrnoExceptionCtor2 == nullptr) return JNI_ERR;
+
+    sErrnoExceptionCtor3 = env->GetMethodID(sErrnoExceptionClass, "<init>",
+            "(Ljava/lang/String;ILjava/lang/Throwable;)V");
+    if (sErrnoExceptionCtor3 == nullptr) return JNI_ERR;
+
+    return jniRegisterNativeMethods(env,
+            "com/android/networkstack/tethering/BpfMap",
+            gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/Tethering/jni/onload.cpp b/Tethering/jni/onload.cpp
new file mode 100644
index 0000000..3766de9
--- /dev/null
+++ b/Tethering/jni/onload.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+
+#define LOG_TAG "TetheringJni"
+#include <android/log.h>
+
+namespace android {
+
+int register_android_net_util_TetheringUtils(JNIEnv* env);
+int register_com_android_networkstack_tethering_BpfMap(JNIEnv* env);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "ERROR: GetEnv failed");
+        return JNI_ERR;
+    }
+
+    if (register_android_net_util_TetheringUtils(env) < 0) return JNI_ERR;
+
+    if (register_com_android_networkstack_tethering_BpfMap(env) < 0) return JNI_ERR;
+
+    return JNI_VERSION_1_6;
+}
+
+}; // namespace android
diff --git a/Tethering/proguard.flags b/Tethering/proguard.flags
index 86b9033..9ab56c2 100644
--- a/Tethering/proguard.flags
+++ b/Tethering/proguard.flags
@@ -4,6 +4,14 @@
     static final int EVENT_*;
 }
 
+-keep class com.android.networkstack.tethering.BpfMap {
+    native <methods>;
+}
+
+-keepclassmembers public class * extends com.android.networkstack.tethering.util.Struct {
+    public <init>(...);
+}
+
 -keepclassmembers class android.net.ip.IpServer {
     static final int CMD_*;
 }
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfMap.java b/Tethering/src/com/android/networkstack/tethering/BpfMap.java
new file mode 100644
index 0000000..9505709
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/BpfMap.java
@@ -0,0 +1,222 @@
+/*
+ * 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.
+ */
+package com.android.networkstack.tethering;
+
+import static android.system.OsConstants.EEXIST;
+import static android.system.OsConstants.ENOENT;
+
+import android.system.ErrnoException;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.net.module.util.Struct;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+
+/**
+ * BpfMap is a key -> value mapping structure that is designed to maintained the bpf map entries.
+ * This is a wrapper class of in-kernel data structure. The in-kernel data can be read/written by
+ * passing syscalls with map file descriptor.
+ *
+ * @param <K> the key of the map.
+ * @param <V> the value of the map.
+ */
+public class BpfMap<K extends Struct, V extends Struct> implements AutoCloseable {
+    // Following definitions from kernel include/uapi/linux/bpf.h
+    public static final int BPF_F_RDWR = 0;
+    public static final int BPF_F_RDONLY = 1 << 3;
+    public static final int BPF_F_WRONLY = 1 << 4;
+
+    public static final int BPF_MAP_TYPE_HASH = 1;
+
+    private static final int BPF_F_NO_PREALLOC = 1;
+
+    private static final int BPF_ANY = 0;
+    private static final int BPF_NOEXIST = 1;
+    private static final int BPF_EXIST = 2;
+
+    private final int mMapFd;
+    private final Class<K> mKeyClass;
+    private final Class<V> mValueClass;
+    private final int mKeySize;
+    private final int mValueSize;
+
+    /**
+     * Create a BpfMap map wrapper with "path" of filesystem.
+     *
+     * @param flag the access mode, one of BPF_F_RDWR, BPF_F_RDONLY, or BPF_F_WRONLY.
+     * @throws ErrnoException if the BPF map associated with {@code path} cannot be retrieved.
+     * @throws NullPointerException if {@code path} is null.
+     */
+    public BpfMap(@NonNull final String path, final int flag, final Class<K> key,
+            final Class<V> value) throws ErrnoException, NullPointerException {
+        mMapFd = bpfFdGet(path, flag);
+
+        mKeyClass = key;
+        mValueClass = value;
+        mKeySize = Struct.getSize(key);
+        mValueSize = Struct.getSize(value);
+    }
+
+    /**
+     * Update an existing or create a new key -> value entry in an eBbpf map.
+     */
+    public void updateEntry(K key, V value) throws ErrnoException {
+        writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_ANY);
+    }
+
+    /**
+     * If the key does not exist in the map, insert key -> value entry into eBpf map.
+     * Otherwise IllegalStateException will be thrown.
+     */
+    public void insertEntry(K key, V value)
+            throws ErrnoException, IllegalStateException {
+        try {
+            writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_NOEXIST);
+        } catch (ErrnoException e) {
+            if (e.errno == EEXIST) throw new IllegalStateException(key + " already exists");
+
+            throw e;
+        }
+    }
+
+    /**
+     * If the key already exists in the map, replace its value. Otherwise NoSuchElementException
+     * will be thrown.
+     */
+    public void replaceEntry(K key, V value)
+            throws ErrnoException, NoSuchElementException {
+        try {
+            writeToMapEntry(mMapFd, key.writeToBytes(), value.writeToBytes(), BPF_EXIST);
+        } catch (ErrnoException e) {
+            if (e.errno == ENOENT) throw new NoSuchElementException(key + " not found");
+
+            throw e;
+        }
+    }
+
+    /** Remove existing key from eBpf map. Return false if map was not modified. */
+    public boolean deleteEntry(K key) throws ErrnoException {
+        return deleteMapEntry(mMapFd, key.writeToBytes());
+    }
+
+    private K getNextKeyInternal(@Nullable K key) throws ErrnoException {
+        final byte[] rawKey = getNextRawKey(
+                key == null ? null : key.writeToBytes());
+        if (rawKey == null) return null;
+
+        final ByteBuffer buffer = ByteBuffer.wrap(rawKey);
+        buffer.order(ByteOrder.nativeOrder());
+        return Struct.parse(mKeyClass, buffer);
+    }
+
+    /**
+     * Get the next key of the passed-in key. If the passed-in key is not found, return the first
+     * key. If the passed-in key is the last one, return null.
+     *
+     * TODO: consider allowing null passed-in key.
+     */
+    public K getNextKey(@Nullable K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+        return getNextKeyInternal(key);
+    }
+
+    private byte[] getNextRawKey(@Nullable final byte[] key) throws ErrnoException {
+        byte[] nextKey = new byte[mKeySize];
+        if (getNextMapKey(mMapFd, key, nextKey)) return nextKey;
+
+        return null;
+    }
+
+    /** Get the first key of eBpf map. */
+    public K getFirstKey() throws ErrnoException {
+        return getNextKeyInternal(null);
+    }
+
+    /** Check whether a key exists in the map. */
+    public boolean containsKey(@NonNull K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+
+        final byte[] rawValue = getRawValue(key.writeToBytes());
+        return rawValue != null;
+    }
+
+    /** Retrieve a value from the map. Return null if there is no such key. */
+    public V getValue(@NonNull K key) throws ErrnoException {
+        Objects.requireNonNull(key);
+        final byte[] rawValue = getRawValue(key.writeToBytes());
+
+        if (rawValue == null) return null;
+
+        final ByteBuffer buffer = ByteBuffer.wrap(rawValue);
+        buffer.order(ByteOrder.nativeOrder());
+        return Struct.parse(mValueClass, buffer);
+    }
+
+    private byte[] getRawValue(final byte[] key) throws ErrnoException {
+        byte[] value = new byte[mValueSize];
+        if (findMapEntry(mMapFd, key, value)) return value;
+
+        return null;
+    }
+
+    /**
+     * Iterate through the map and handle each key -> value retrieved base on the given BiConsumer.
+     * The given BiConsumer may to delete the passed-in entry, but is not allowed to perform any
+     * other structural modifications to the map, such as adding entries or deleting other entries.
+     * Otherwise, iteration will result in undefined behaviour.
+     */
+    public void forEach(BiConsumer<K, V> action) throws ErrnoException {
+        @Nullable
+        K nextKey = getFirstKey();
+
+        while (nextKey != null) {
+            @NonNull
+            final K curKey = nextKey;
+            @NonNull
+            final V value = getValue(curKey);
+
+            nextKey = getNextKey(curKey);
+            action.accept(curKey, value);
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        closeMap(mMapFd);
+    }
+
+    private static native int closeMap(int fd) throws ErrnoException;
+
+    private native int bpfFdGet(String path, int mode) throws ErrnoException, NullPointerException;
+
+    private native void writeToMapEntry(int fd, byte[] key, byte[] value, int flags)
+            throws ErrnoException;
+
+    private native boolean deleteMapEntry(int fd, byte[] key) throws ErrnoException;
+
+    // If key is found, the operation returns true and the nextKey would reference to the next
+    // element.  If key is not found, the operation returns true and the nextKey would reference to
+    // the first element.  If key is the last element, false is returned.
+    private native boolean getNextMapKey(int fd, byte[] key, byte[] nextKey) throws ErrnoException;
+
+    private native boolean findMapEntry(int fd, byte[] key, byte[] value) throws ErrnoException;
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherIngressKey.java b/Tethering/src/com/android/networkstack/tethering/TetherIngressKey.java
new file mode 100644
index 0000000..78683c5
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherIngressKey.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+package com.android.networkstack.tethering;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/** The key of BpfMap which is used for bpf offload. */
+public class TetherIngressKey extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long iif; // The input interface index.
+
+    @Field(order = 1, type = Type.ByteArray, arraysize = 16)
+    public final byte[] neigh6; // The destination IPv6 address.
+
+    public TetherIngressKey(final long iif, final byte[] neigh6) {
+        try {
+            final Inet6Address unused = (Inet6Address) InetAddress.getByAddress(neigh6);
+        } catch (ClassCastException | UnknownHostException e) {
+            throw new IllegalArgumentException("Invalid IPv6 address: "
+                    + Arrays.toString(neigh6));
+        }
+        this.iif = iif;
+        this.neigh6 = neigh6;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherIngressKey)) return false;
+
+        final TetherIngressKey that = (TetherIngressKey) obj;
+
+        return iif == that.iif && Arrays.equals(neigh6, that.neigh6);
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(iif) ^ Arrays.hashCode(neigh6);
+    }
+
+    @Override
+    public String toString() {
+        try {
+            return String.format("iif: %d, neigh: %s", iif, Inet6Address.getByAddress(neigh6));
+        } catch (UnknownHostException e) {
+            // Should not happen because construtor already verify neigh6.
+            throw new IllegalStateException("Invalid TetherIngressKey");
+        }
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherIngressValue.java b/Tethering/src/com/android/networkstack/tethering/TetherIngressValue.java
new file mode 100644
index 0000000..e2116fc
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/TetherIngressValue.java
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+package com.android.networkstack.tethering;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.util.Objects;
+
+/** The value of BpfMap which is used for bpf offload. */
+public class TetherIngressValue extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long oif; // The output interface index.
+
+    // The ethhdr struct which is defined in uapi/linux/if_ether.h
+    @Field(order = 1, type = Type.EUI48)
+    public final MacAddress ethDstMac; // The destination mac address.
+    @Field(order = 2, type = Type.EUI48)
+    public final MacAddress ethSrcMac; // The source mac address.
+    @Field(order = 3, type = Type.UBE16)
+    public final int ethProto; // Packet type ID field.
+
+    @Field(order = 4, type = Type.U16)
+    public final int pmtu; // The maximum L3 output path/route mtu.
+
+    public TetherIngressValue(final long oif, @NonNull final MacAddress ethDstMac,
+            @NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu) {
+        Objects.requireNonNull(ethSrcMac);
+        Objects.requireNonNull(ethDstMac);
+
+        this.oif = oif;
+        this.ethDstMac = ethDstMac;
+        this.ethSrcMac = ethSrcMac;
+        this.ethProto = ethProto;
+        this.pmtu = pmtu;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherIngressValue)) return false;
+
+        final TetherIngressValue that = (TetherIngressValue) obj;
+
+        return oif == that.oif && ethDstMac.equals(that.ethDstMac)
+                && ethSrcMac.equals(that.ethSrcMac) && ethProto == that.ethProto
+                && pmtu == that.pmtu;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(oif, ethDstMac, ethSrcMac, ethProto, pmtu);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("oif: %d, dstMac: %s, srcMac: %s, proto: %d, pmtu: %d", oif,
+                ethDstMac, ethSrcMac, ethProto, pmtu);
+    }
+}
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
new file mode 100644
index 0000000..77c0961
--- /dev/null
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
@@ -0,0 +1,356 @@
+/*
+ * 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.
+ */
+
+package com.android.networkstack.tethering;
+
+import static android.system.OsConstants.ETH_P_IPV6;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.net.MacAddress;
+import android.os.Build;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.util.ArrayMap;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+import java.util.NoSuchElementException;
+
+
+@RunWith(AndroidJUnit4.class)
+@IgnoreUpTo(Build.VERSION_CODES.R)
+public final class BpfMapTest {
+    // Sync from packages/modules/Connectivity/Tethering/bpf_progs/offload.c.
+    private static final int TEST_MAP_SIZE = 16;
+    private static final String TETHER_INGRESS_FS_PATH =
+            "/sys/fs/bpf/map_offload_tether_ingress_map_TEST";
+
+    private ArrayMap<TetherIngressKey, TetherIngressValue> mTestData;
+
+    @BeforeClass
+    public static void setupOnce() {
+        System.loadLibrary("tetherutilsjni");
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        // TODO: Simply the test map creation and deletion.
+        // - Make the map a class member (mTestMap)
+        // - Open the test map RW in setUp
+        // - Close the test map in tearDown.
+        cleanTestMap();
+
+        mTestData = new ArrayMap<>();
+        mTestData.put(createTetherIngressKey(101, "2001:db8::1"),
+                createTetherIngressValue(11, "00:00:00:00:00:0a", "11:11:11:00:00:0b", ETH_P_IPV6,
+                1280));
+        mTestData.put(createTetherIngressKey(102, "2001:db8::2"),
+                createTetherIngressValue(22, "00:00:00:00:00:0c", "22:22:22:00:00:0d", ETH_P_IPV6,
+                1400));
+        mTestData.put(createTetherIngressKey(103, "2001:db8::3"),
+                createTetherIngressValue(33, "00:00:00:00:00:0e", "33:33:33:00:00:0f", ETH_P_IPV6,
+                1500));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        cleanTestMap();
+    }
+
+    private BpfMap<TetherIngressKey, TetherIngressValue> getTestMap() throws Exception {
+        return new BpfMap<>(
+                TETHER_INGRESS_FS_PATH, BpfMap.BPF_F_RDWR,
+                TetherIngressKey.class, TetherIngressValue.class);
+    }
+
+    private void cleanTestMap() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            bpfMap.forEach((key, value) -> {
+                try {
+                    assertTrue(bpfMap.deleteEntry(key));
+                } catch (ErrnoException ignored) { }
+            });
+            assertNull(bpfMap.getFirstKey());
+        }
+    }
+
+    private TetherIngressKey createTetherIngressKey(long iif, String address) throws Exception {
+        final InetAddress ipv6Address = InetAddress.getByName(address);
+
+        return new TetherIngressKey(iif, ipv6Address.getAddress());
+    }
+
+    private TetherIngressValue createTetherIngressValue(long oif, String src, String dst, int proto,
+            int pmtu) throws Exception {
+        final MacAddress srcMac = MacAddress.fromString(src);
+        final MacAddress dstMac = MacAddress.fromString(dst);
+
+        return new TetherIngressValue(oif, dstMac, srcMac, proto, pmtu);
+    }
+
+    @Test
+    public void testGetFd() throws Exception {
+        try (BpfMap readOnlyMap = new BpfMap<>(TETHER_INGRESS_FS_PATH, BpfMap.BPF_F_RDONLY,
+                TetherIngressKey.class, TetherIngressValue.class)) {
+            assertNotNull(readOnlyMap);
+            try {
+                readOnlyMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+                fail("Writing RO map should throw ErrnoException");
+            } catch (ErrnoException expected) {
+                assertEquals(OsConstants.EPERM, expected.errno);
+            }
+        }
+        try (BpfMap writeOnlyMap = new BpfMap<>(TETHER_INGRESS_FS_PATH, BpfMap.BPF_F_WRONLY,
+                TetherIngressKey.class, TetherIngressValue.class)) {
+            assertNotNull(writeOnlyMap);
+            try {
+                writeOnlyMap.getFirstKey();
+                fail("Reading WO map should throw ErrnoException");
+            } catch (ErrnoException expected) {
+                assertEquals(OsConstants.EPERM, expected.errno);
+            }
+        }
+        try (BpfMap readWriteMap = new BpfMap<>(TETHER_INGRESS_FS_PATH, BpfMap.BPF_F_RDWR,
+                TetherIngressKey.class, TetherIngressValue.class)) {
+            assertNotNull(readWriteMap);
+        }
+    }
+
+    @Test
+    public void testGetFirstKey() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            // getFirstKey on an empty map returns null.
+            assertFalse(bpfMap.containsKey(mTestData.keyAt(0)));
+            assertNull(bpfMap.getFirstKey());
+            assertNull(bpfMap.getValue(mTestData.keyAt(0)));
+
+            // getFirstKey on a non-empty map returns the first key.
+            bpfMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+            assertEquals(mTestData.keyAt(0), bpfMap.getFirstKey());
+        }
+    }
+
+    @Test
+    public void testGetNextKey() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            // [1] If the passed-in key is not found on empty map, return null.
+            final TetherIngressKey nonexistentKey = createTetherIngressKey(1234, "2001:db8::10");
+            assertNull(bpfMap.getNextKey(nonexistentKey));
+
+            // [2] If the passed-in key is null on empty map, throw NullPointerException.
+            try {
+                bpfMap.getNextKey(null);
+                fail("Getting next key with null key should throw NullPointerException");
+            } catch (NullPointerException expected) { }
+
+            // The BPF map has one entry now.
+            final ArrayMap<TetherIngressKey, TetherIngressValue> resultMap = new ArrayMap<>();
+            bpfMap.insertEntry(mTestData.keyAt(0), mTestData.valueAt(0));
+            resultMap.put(mTestData.keyAt(0), mTestData.valueAt(0));
+
+            // [3] If the passed-in key is the last key, return null.
+            // Because there is only one entry in the map, the first key equals the last key.
+            final TetherIngressKey lastKey = bpfMap.getFirstKey();
+            assertNull(bpfMap.getNextKey(lastKey));
+
+            // The BPF map has two entries now.
+            bpfMap.insertEntry(mTestData.keyAt(1), mTestData.valueAt(1));
+            resultMap.put(mTestData.keyAt(1), mTestData.valueAt(1));
+
+            // [4] If the passed-in key is found, return the next key.
+            TetherIngressKey nextKey = bpfMap.getFirstKey();
+            while (nextKey != null) {
+                if (resultMap.remove(nextKey).equals(nextKey)) {
+                    fail("Unexpected result: " + nextKey);
+                }
+                nextKey = bpfMap.getNextKey(nextKey);
+            }
+            assertTrue(resultMap.isEmpty());
+
+            // [5] If the passed-in key is not found on non-empty map, return the first key.
+            assertEquals(bpfMap.getFirstKey(), bpfMap.getNextKey(nonexistentKey));
+
+            // [6] If the passed-in key is null on non-empty map, throw NullPointerException.
+            try {
+                bpfMap.getNextKey(null);
+                fail("Getting next key with null key should throw NullPointerException");
+            } catch (NullPointerException expected) { }
+        }
+    }
+
+    @Test
+    public void testUpdateBpfMap() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+
+            final TetherIngressKey key = mTestData.keyAt(0);
+            final TetherIngressValue value = mTestData.valueAt(0);
+            final TetherIngressValue value2 = mTestData.valueAt(1);
+            assertFalse(bpfMap.deleteEntry(key));
+
+            // updateEntry will create an entry if it does not exist already.
+            bpfMap.updateEntry(key, value);
+            assertTrue(bpfMap.containsKey(key));
+            final TetherIngressValue result = bpfMap.getValue(key);
+            assertEquals(value, result);
+
+            // updateEntry will update an entry that already exists.
+            bpfMap.updateEntry(key, value2);
+            assertTrue(bpfMap.containsKey(key));
+            final TetherIngressValue result2 = bpfMap.getValue(key);
+            assertEquals(value2, result2);
+
+            assertTrue(bpfMap.deleteEntry(key));
+            assertFalse(bpfMap.containsKey(key));
+        }
+    }
+
+    @Test
+    public void testInsertReplaceEntry() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+
+            final TetherIngressKey key = mTestData.keyAt(0);
+            final TetherIngressValue value = mTestData.valueAt(0);
+            final TetherIngressValue value2 = mTestData.valueAt(1);
+
+            try {
+                bpfMap.replaceEntry(key, value);
+                fail("Replacing non-existent key " + key + " should throw NoSuchElementException");
+            } catch (NoSuchElementException expected) { }
+            assertFalse(bpfMap.containsKey(key));
+
+            bpfMap.insertEntry(key, value);
+            assertTrue(bpfMap.containsKey(key));
+            final TetherIngressValue result = bpfMap.getValue(key);
+            assertEquals(value, result);
+            try {
+                bpfMap.insertEntry(key, value);
+                fail("Inserting existing key " + key + " should throw IllegalStateException");
+            } catch (IllegalStateException expected) { }
+
+            bpfMap.replaceEntry(key, value2);
+            assertTrue(bpfMap.containsKey(key));
+            final TetherIngressValue result2 = bpfMap.getValue(key);
+            assertEquals(value2, result2);
+        }
+    }
+
+    @Test
+    public void testIterateBpfMap() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            final ArrayMap<TetherIngressKey, TetherIngressValue> resultMap =
+                    new ArrayMap<>(mTestData);
+
+            for (int i = 0; i < resultMap.size(); i++) {
+                bpfMap.insertEntry(resultMap.keyAt(i), resultMap.valueAt(i));
+            }
+
+            bpfMap.forEach((key, value) -> {
+                if (!value.equals(resultMap.remove(key))) {
+                    fail("Unexpected result: " + key + ", value: " + value);
+                }
+            });
+            assertTrue(resultMap.isEmpty());
+        }
+    }
+
+    @Test
+    public void testIterateEmptyMap() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            // Use an one element array to be a trick for a counter because local variables
+            // referenced from a lambda expression must be final.
+            final int[] count = {0};
+            bpfMap.forEach((key, value) -> {
+                count[0]++;
+            });
+
+            // Expect that consumer has never be called.
+            assertEquals(0, count[0]);
+        }
+    }
+
+    @Test
+    public void testIterateDeletion() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            final ArrayMap<TetherIngressKey, TetherIngressValue> resultMap =
+                    new ArrayMap<>(mTestData);
+
+            for (int i = 0; i < resultMap.size(); i++) {
+                bpfMap.insertEntry(resultMap.keyAt(i), resultMap.valueAt(i));
+            }
+
+            // Use an one element array to be a trick for a counter because local variables
+            // referenced from a lambda expression must be final.
+            final int[] count = {0};
+            bpfMap.forEach((key, value) -> {
+                try {
+                    assertTrue(bpfMap.deleteEntry(key));
+                } catch (ErrnoException e) {
+                    fail("Fail to delete key " + key + ": " + e);
+                }
+                if (!value.equals(resultMap.remove(key))) {
+                    fail("Unexpected result: " + key + ", value: " + value);
+                }
+                count[0]++;
+            });
+            assertEquals(3, count[0]);
+            assertTrue(resultMap.isEmpty());
+            assertNull(bpfMap.getFirstKey());
+        }
+    }
+
+    @Test
+    public void testInsertOverflow() throws Exception {
+        try (BpfMap<TetherIngressKey, TetherIngressValue> bpfMap = getTestMap()) {
+            final ArrayMap<TetherIngressKey, TetherIngressValue> testData = new ArrayMap<>();
+
+            // Build test data for TEST_MAP_SIZE + 1 entries.
+            for (int i = 1; i <= TEST_MAP_SIZE + 1; i++) {
+                testData.put(createTetherIngressKey(i, "2001:db8::1"), createTetherIngressValue(
+                        100, "de:ad:be:ef:00:01", "de:ad:be:ef:00:02", ETH_P_IPV6, 1500));
+            }
+
+            // Insert #TEST_MAP_SIZE test entries to the map. The map has reached the limit.
+            for (int i = 0; i < TEST_MAP_SIZE; i++) {
+                bpfMap.insertEntry(testData.keyAt(i), testData.valueAt(i));
+            }
+
+            // The map won't allow inserting any more entries.
+            try {
+                bpfMap.insertEntry(testData.keyAt(TEST_MAP_SIZE), testData.valueAt(TEST_MAP_SIZE));
+                fail("Writing too many entries should throw ErrnoException");
+            } catch (ErrnoException expected) {
+                // Expect that can't insert the entry anymore because the number of elements in the
+                // map reached the limit. See man-pages/bpf.
+                assertEquals(OsConstants.E2BIG, expected.errno);
+            }
+        }
+    }
+}
