diff --git a/libbpf_android/Android.bp b/libbpf_android/Android.bp
new file mode 100644
index 0000000..2ffacf3
--- /dev/null
+++ b/libbpf_android/Android.bp
@@ -0,0 +1,83 @@
+//
+// 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.
+//
+
+cc_library_headers {
+    name: "libbpf_android_headers",
+    vendor_available: false,
+    host_supported: false,
+    export_include_dirs: ["include"],
+    target: {
+        linux_bionic: {
+            enabled: true,
+        },
+    },
+}
+
+cc_library {
+    name: "libbpf_android",
+    vendor_available: false,
+    host_supported: false,
+    target: {
+        android: {
+            srcs: [
+                "BpfUtils.cpp",
+            ],
+            sanitize: {
+                misc_undefined: ["integer"],
+            },
+        },
+    },
+
+    shared_libs: [
+        "libbase",
+        "libutils",
+        "liblog",
+        "libnetdutils",
+    ],
+    header_libs: [
+        "libbpf_android_headers"
+    ],
+    export_header_lib_headers: ["libbpf_android_headers"],
+    local_include_dirs: ["include"],
+
+    defaults: ["bpf_defaults"],
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wextra",
+    ],
+}
+
+cc_test {
+    name: "libbpf_android_test",
+    srcs: [
+        "BpfMapTest.cpp",
+    ],
+    defaults: ["bpf_defaults"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-error=unused-variable",
+    ],
+    static_libs: ["libgmock"],
+    shared_libs: [
+        "libbpf_android",
+        "libbase",
+        "liblog",
+        "libnetdutils",
+        "libutils",
+    ],
+}
diff --git a/libbpf_android/BpfMapTest.cpp b/libbpf_android/BpfMapTest.cpp
new file mode 100644
index 0000000..d0bd79e
--- /dev/null
+++ b/libbpf_android/BpfMapTest.cpp
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <linux/inet_diag.h>
+#include <linux/sock_diag.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#include "bpf/BpfMap.h"
+#include "bpf/BpfUtils.h"
+
+using ::testing::Test;
+
+namespace android {
+namespace bpf {
+
+using base::unique_fd;
+using netdutils::StatusOr;
+
+constexpr uint32_t TEST_MAP_SIZE = 10;
+constexpr uint32_t TEST_KEY1 = 1;
+constexpr uint32_t TEST_VALUE1 = 10;
+constexpr const char PINNED_MAP_PATH[] = "/sys/fs/bpf/testMap";
+
+class BpfMapTest : public testing::Test {
+  protected:
+    BpfMapTest() {}
+    int mMapFd;
+
+    void SetUp() {
+        if (!access(PINNED_MAP_PATH, R_OK)) {
+            EXPECT_EQ(0, remove(PINNED_MAP_PATH));
+        }
+        mMapFd = createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint32_t), TEST_MAP_SIZE,
+                           BPF_F_NO_PREALLOC);
+    }
+
+    void TearDown() {
+        if (!access(PINNED_MAP_PATH, R_OK)) {
+            EXPECT_EQ(0, remove(PINNED_MAP_PATH));
+        }
+        close(mMapFd);
+    }
+
+    void checkMapInvalid(BpfMap<uint32_t, uint32_t>& map) {
+        EXPECT_FALSE(map.isValid());
+        EXPECT_EQ(-1, map.getMap().get());
+        EXPECT_TRUE(map.getPinnedPath().empty());
+    }
+
+    void checkMapValid(BpfMap<uint32_t, uint32_t>& map) {
+        EXPECT_LE(0, map.getMap().get());
+        EXPECT_TRUE(map.isValid());
+    }
+
+    void writeToMapAndCheck(BpfMap<uint32_t, uint32_t>& map, uint32_t key, uint32_t value) {
+        ASSERT_TRUE(isOk(map.writeValue(key, value, BPF_ANY)));
+        uint32_t value_read;
+        ASSERT_EQ(0, findMapEntry(map.getMap(), &key, &value_read));
+        checkValueAndStatus(value, value_read);
+    }
+
+    void checkValueAndStatus(uint32_t refValue, StatusOr<uint32_t> value) {
+        ASSERT_TRUE(isOk(value.status()));
+        ASSERT_EQ(refValue, value.value());
+    }
+
+    void populateMap(uint32_t total, BpfMap<uint32_t, uint32_t>& map) {
+        for (uint32_t key = 0; key < total; key++) {
+            uint32_t value = key * 10;
+            EXPECT_TRUE(isOk(map.writeValue(key, value, BPF_ANY)));
+        }
+    }
+
+    void expectMapEmpty(BpfMap<uint32_t, uint32_t>& map) {
+        auto isEmpty = map.isEmpty();
+        ASSERT_TRUE(isOk(isEmpty));
+        ASSERT_TRUE(isEmpty.value());
+    }
+};
+
+TEST_F(BpfMapTest, constructor) {
+    BpfMap<uint32_t, uint32_t> testMap1;
+    checkMapInvalid(testMap1);
+
+    BpfMap<uint32_t, uint32_t> testMap2(mMapFd);
+    checkMapValid(testMap2);
+    EXPECT_TRUE(testMap2.getPinnedPath().empty());
+
+    BpfMap<uint32_t, uint32_t> testMap3(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+    checkMapValid(testMap3);
+    EXPECT_TRUE(testMap3.getPinnedPath().empty());
+}
+
+TEST_F(BpfMapTest, basicHelpers) {
+    BpfMap<uint32_t, uint32_t> testMap(mMapFd);
+    uint32_t key = TEST_KEY1;
+    uint32_t value_write = TEST_VALUE1;
+    writeToMapAndCheck(testMap, key, value_write);
+    StatusOr<uint32_t> value_read = testMap.readValue(key);
+    checkValueAndStatus(value_write, value_read);
+    StatusOr<uint32_t> key_read = testMap.getFirstKey();
+    checkValueAndStatus(key, key_read);
+    ASSERT_TRUE(isOk(testMap.deleteValue(key)));
+    ASSERT_GT(0, findMapEntry(testMap.getMap(), &key, &value_read));
+    ASSERT_EQ(ENOENT, errno);
+}
+
+TEST_F(BpfMapTest, reset) {
+    BpfMap<uint32_t, uint32_t> testMap;
+    testMap.reset(mMapFd);
+    uint32_t key = TEST_KEY1;
+    uint32_t value_write = TEST_VALUE1;
+    writeToMapAndCheck(testMap, key, value_write);
+    testMap.reset();
+    checkMapInvalid(testMap);
+    unique_fd invalidFd(mMapFd);
+    ASSERT_GT(0, findMapEntry(invalidFd, &key, &value_write));
+    ASSERT_EQ(EBADF, errno);
+}
+
+TEST_F(BpfMapTest, moveConstructor) {
+    BpfMap<uint32_t, uint32_t> testMap1(mMapFd);
+    BpfMap<uint32_t, uint32_t> testMap2;
+    testMap2 = std::move(testMap1);
+    uint32_t key = TEST_KEY1;
+    checkMapInvalid(testMap1);
+    uint32_t value = TEST_VALUE1;
+    writeToMapAndCheck(testMap2, key, value);
+}
+
+TEST_F(BpfMapTest, pinnedToPath) {
+    BpfMap<uint32_t, uint32_t> testMap1(mMapFd);
+    EXPECT_OK(testMap1.pinToPath(PINNED_MAP_PATH));
+    EXPECT_EQ(0, access(PINNED_MAP_PATH, R_OK));
+    EXPECT_EQ(0, testMap1.getPinnedPath().compare(PINNED_MAP_PATH));
+    BpfMap<uint32_t, uint32_t> testMap2(mapRetrieve(PINNED_MAP_PATH, 0));
+    checkMapValid(testMap2);
+    uint32_t key = TEST_KEY1;
+    uint32_t value = TEST_VALUE1;
+    writeToMapAndCheck(testMap1, key, value);
+    StatusOr<uint32_t> value_read = testMap2.readValue(key);
+    checkValueAndStatus(value, value_read);
+}
+
+TEST_F(BpfMapTest, SetUpMap) {
+    BpfMap<uint32_t, uint32_t> testMap1;
+    EXPECT_OK(testMap1.getOrCreate(TEST_MAP_SIZE, PINNED_MAP_PATH, BPF_MAP_TYPE_HASH));
+    EXPECT_EQ(0, access(PINNED_MAP_PATH, R_OK));
+    checkMapValid(testMap1);
+    EXPECT_EQ(0, testMap1.getPinnedPath().compare(PINNED_MAP_PATH));
+    BpfMap<uint32_t, uint32_t> testMap2;
+    EXPECT_OK(testMap2.getOrCreate(TEST_MAP_SIZE, PINNED_MAP_PATH, BPF_MAP_TYPE_HASH));
+    checkMapValid(testMap2);
+    EXPECT_EQ(0, testMap2.getPinnedPath().compare(PINNED_MAP_PATH));
+    uint32_t key = TEST_KEY1;
+    uint32_t value = TEST_VALUE1;
+    writeToMapAndCheck(testMap1, key, value);
+    StatusOr<uint32_t> value_read = testMap2.readValue(key);
+    checkValueAndStatus(value, value_read);
+}
+
+TEST_F(BpfMapTest, iterate) {
+    BpfMap<uint32_t, uint32_t> testMap(mMapFd);
+    populateMap(TEST_MAP_SIZE, testMap);
+    int totalCount = 0;
+    int totalSum = 0;
+    const auto iterateWithDeletion = [&totalCount, &totalSum](const uint32_t& key,
+                                                              BpfMap<uint32_t, uint32_t>& map) {
+        EXPECT_GE((uint32_t)TEST_MAP_SIZE, key);
+        totalCount++;
+        totalSum += key;
+        return map.deleteValue(key);
+    };
+    EXPECT_OK(testMap.iterate(iterateWithDeletion));
+    EXPECT_EQ((int)TEST_MAP_SIZE, totalCount);
+    EXPECT_EQ(((1 + TEST_MAP_SIZE - 1) * (TEST_MAP_SIZE - 1)) / 2, (uint32_t)totalSum);
+    expectMapEmpty(testMap);
+}
+
+TEST_F(BpfMapTest, iterateWithValue) {
+    BpfMap<uint32_t, uint32_t> testMap(mMapFd);
+    populateMap(TEST_MAP_SIZE, testMap);
+    int totalCount = 0;
+    int totalSum = 0;
+    const auto iterateWithDeletion = [&totalCount, &totalSum](const uint32_t& key,
+                                                              const uint32_t& value,
+                                                              BpfMap<uint32_t, uint32_t>& map) {
+        EXPECT_GE((uint32_t)TEST_MAP_SIZE, key);
+        EXPECT_EQ(value, key * 10);
+        totalCount++;
+        totalSum += value;
+        return map.deleteValue(key);
+    };
+    EXPECT_OK(testMap.iterateWithValue(iterateWithDeletion));
+    EXPECT_EQ((int)TEST_MAP_SIZE, totalCount);
+    EXPECT_EQ(((1 + TEST_MAP_SIZE - 1) * (TEST_MAP_SIZE - 1)) * 5, (uint32_t)totalSum);
+    expectMapEmpty(testMap);
+}
+
+TEST_F(BpfMapTest, mapIsEmpty) {
+    BpfMap<uint32_t, uint32_t> testMap(mMapFd);
+    expectMapEmpty(testMap);
+    uint32_t key = TEST_KEY1;
+    uint32_t value_write = TEST_VALUE1;
+    writeToMapAndCheck(testMap, key, value_write);
+    auto isEmpty = testMap.isEmpty();
+    ASSERT_TRUE(isOk(isEmpty));
+    ASSERT_FALSE(isEmpty.value());
+    ASSERT_TRUE(isOk(testMap.deleteValue(key)));
+    ASSERT_GT(0, findMapEntry(testMap.getMap(), &key, &value_write));
+    ASSERT_EQ(ENOENT, errno);
+    expectMapEmpty(testMap);
+    int entriesSeen = 0;
+    EXPECT_OK(testMap.iterate(
+            [&entriesSeen](const unsigned int&,
+                           const BpfMap<unsigned int, unsigned int>&) -> netdutils::Status {
+                entriesSeen++;
+                return netdutils::status::ok;
+            }));
+    EXPECT_EQ(0, entriesSeen);
+    EXPECT_OK(testMap.iterateWithValue(
+            [&entriesSeen](const unsigned int&, const unsigned int&,
+                           const BpfMap<unsigned int, unsigned int>&) -> netdutils::Status {
+                entriesSeen++;
+                return netdutils::status::ok;
+            }));
+    EXPECT_EQ(0, entriesSeen);
+}
+
+TEST_F(BpfMapTest, mapClear) {
+    BpfMap<uint32_t, uint32_t> testMap(mMapFd);
+    populateMap(TEST_MAP_SIZE, testMap);
+    auto isEmpty = testMap.isEmpty();
+    ASSERT_TRUE(isOk(isEmpty));
+    ASSERT_FALSE(isEmpty.value());
+    ASSERT_TRUE(isOk(testMap.clear()));
+    expectMapEmpty(testMap);
+}
+
+}  // namespace bpf
+}  // namespace android
diff --git a/libbpf_android/BpfUtils.cpp b/libbpf_android/BpfUtils.cpp
new file mode 100644
index 0000000..4d4cae3
--- /dev/null
+++ b/libbpf_android/BpfUtils.cpp
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2017 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 "BpfUtils"
+
+#include "bpf/BpfUtils.h"
+
+#include <elf.h>
+#include <inttypes.h>
+#include <linux/bpf.h>
+#include <linux/if_ether.h>
+#include <linux/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <sstream>
+#include <string>
+
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
+#include <log/log.h>
+#include <netdutils/MemBlock.h>
+#include <netdutils/Slice.h>
+
+using android::base::GetUintProperty;
+using android::base::unique_fd;
+using android::netdutils::MemBlock;
+using android::netdutils::Slice;
+using android::netdutils::statusFromErrno;
+
+constexpr size_t LOG_BUF_SIZE = 65536;
+
+namespace android {
+namespace bpf {
+
+/*  The bpf_attr is a union which might have a much larger size then the struct we are using, while
+ *  The inline initializer only reset the field we are using and leave the reset of the memory as
+ *  is. The bpf kernel code will performs a much stricter check to ensure all unused field is 0. So
+ *  this syscall will normally fail with E2BIG if we don't do a memset to bpf_attr.
+ */
+bool operator==(const StatsKey& lhs, const StatsKey& rhs) {
+    return ((lhs.uid == rhs.uid) && (lhs.tag == rhs.tag) && (lhs.counterSet == rhs.counterSet) &&
+            (lhs.ifaceIndex == rhs.ifaceIndex));
+}
+
+bool operator==(const UidTag& lhs, const UidTag& rhs) {
+    return ((lhs.uid == rhs.uid) && (lhs.tag == rhs.tag));
+}
+
+bool operator==(const StatsValue& lhs, const StatsValue& rhs) {
+    return ((lhs.rxBytes == rhs.rxBytes) && (lhs.txBytes == rhs.txBytes) &&
+            (lhs.rxPackets == rhs.rxPackets) && (lhs.txPackets == rhs.txPackets));
+}
+
+int bpf(int cmd, Slice bpfAttr) {
+    return syscall(__NR_bpf, cmd, bpfAttr.base(), bpfAttr.size());
+}
+
+int createMap(bpf_map_type map_type, uint32_t key_size, uint32_t value_size, uint32_t max_entries,
+              uint32_t map_flags) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.map_type = map_type;
+    attr.key_size = key_size;
+    attr.value_size = value_size;
+    attr.max_entries = max_entries;
+    attr.map_flags = map_flags;
+
+    return bpf(BPF_MAP_CREATE, Slice(&attr, sizeof(attr)));
+}
+
+int writeToMapEntry(const base::unique_fd& map_fd, void* key, void* value, uint64_t flags) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.map_fd = map_fd.get();
+    attr.key = ptr_to_u64(key);
+    attr.value = ptr_to_u64(value);
+    attr.flags = flags;
+
+    return bpf(BPF_MAP_UPDATE_ELEM, Slice(&attr, sizeof(attr)));
+}
+
+int findMapEntry(const base::unique_fd& map_fd, void* key, void* value) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.map_fd = map_fd.get();
+    attr.key = ptr_to_u64(key);
+    attr.value = ptr_to_u64(value);
+
+    return bpf(BPF_MAP_LOOKUP_ELEM, Slice(&attr, sizeof(attr)));
+}
+
+int deleteMapEntry(const base::unique_fd& map_fd, void* key) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.map_fd = map_fd.get();
+    attr.key = ptr_to_u64(key);
+
+    return bpf(BPF_MAP_DELETE_ELEM, Slice(&attr, sizeof(attr)));
+}
+
+int getNextMapKey(const base::unique_fd& map_fd, void* key, void* next_key) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.map_fd = map_fd.get();
+    attr.key = ptr_to_u64(key);
+    attr.next_key = ptr_to_u64(next_key);
+
+    return bpf(BPF_MAP_GET_NEXT_KEY, Slice(&attr, sizeof(attr)));
+}
+
+int getFirstMapKey(const base::unique_fd& map_fd, void* firstKey) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.map_fd = map_fd.get();
+    attr.key = 0;
+    attr.next_key = ptr_to_u64(firstKey);
+
+    return bpf(BPF_MAP_GET_NEXT_KEY, Slice(&attr, sizeof(attr)));
+}
+
+int bpfProgLoad(bpf_prog_type prog_type, Slice bpf_insns, const char* license,
+                uint32_t kern_version, Slice bpf_log) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.prog_type = prog_type;
+    attr.insns = ptr_to_u64(bpf_insns.base());
+    attr.insn_cnt = bpf_insns.size() / sizeof(struct bpf_insn);
+    attr.license = ptr_to_u64((void*)license);
+    attr.log_buf = ptr_to_u64(bpf_log.base());
+    attr.log_size = bpf_log.size();
+    attr.log_level = DEFAULT_LOG_LEVEL;
+    attr.kern_version = kern_version;
+    int ret = bpf(BPF_PROG_LOAD, Slice(&attr, sizeof(attr)));
+
+    if (ret < 0) {
+        std::string prog_log = netdutils::toString(bpf_log);
+        std::istringstream iss(prog_log);
+        for (std::string line; std::getline(iss, line);) {
+            ALOGE("%s", line.c_str());
+        }
+    }
+    return ret;
+}
+
+int bpfFdPin(const base::unique_fd& map_fd, const char* pathname) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.pathname = ptr_to_u64((void*)pathname);
+    attr.bpf_fd = map_fd.get();
+
+    return bpf(BPF_OBJ_PIN, Slice(&attr, sizeof(attr)));
+}
+
+int mapRetrieve(const char* pathname, uint32_t flag) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.pathname = ptr_to_u64((void*)pathname);
+    attr.file_flags = flag;
+    return bpf(BPF_OBJ_GET, Slice(&attr, sizeof(attr)));
+}
+
+int attachProgram(bpf_attach_type type, uint32_t prog_fd, uint32_t cg_fd) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.target_fd = cg_fd;
+    attr.attach_bpf_fd = prog_fd;
+    attr.attach_type = type;
+
+    return bpf(BPF_PROG_ATTACH, Slice(&attr, sizeof(attr)));
+}
+
+int detachProgram(bpf_attach_type type, uint32_t cg_fd) {
+    bpf_attr attr;
+    memset(&attr, 0, sizeof(attr));
+    attr.target_fd = cg_fd;
+    attr.attach_type = type;
+
+    return bpf(BPF_PROG_DETACH, Slice(&attr, sizeof(attr)));
+}
+
+uint64_t getSocketCookie(int sockFd) {
+    uint64_t sock_cookie;
+    socklen_t cookie_len = sizeof(sock_cookie);
+    int res = getsockopt(sockFd, SOL_SOCKET, SO_COOKIE, &sock_cookie, &cookie_len);
+    if (res < 0) {
+        res = -errno;
+        ALOGE("Failed to get socket cookie: %s\n", strerror(errno));
+        errno = -res;
+        // 0 is an invalid cookie. See sock_gen_cookie.
+        return NONEXISTENT_COOKIE;
+    }
+    return sock_cookie;
+}
+
+bool hasBpfSupport() {
+    struct utsname buf;
+    int kernel_version_major;
+    int kernel_version_minor;
+
+    uint64_t api_level = GetUintProperty<uint64_t>("ro.product.first_api_level", 0);
+    if (api_level == 0) {
+        ALOGE("Cannot determine initial API level of the device");
+        api_level = GetUintProperty<uint64_t>("ro.build.version.sdk", 0);
+    }
+
+    int ret = uname(&buf);
+    if (ret) {
+        return false;
+    }
+    char dummy;
+    ret = sscanf(buf.release, "%d.%d%c", &kernel_version_major, &kernel_version_minor, &dummy);
+    if (ret >= 2 && ((kernel_version_major > 4) ||
+                         (kernel_version_major == 4 && kernel_version_minor >= 9))) {
+        // Check if the device is shipped originally with android P.
+        return api_level >= MINIMUM_API_REQUIRED;
+    }
+    return false;
+}
+
+int loadAndPinProgram(BpfProgInfo* prog, Slice progBlock) {
+    // Program doesn't exist. Try to load it.
+    char bpf_log_buf[LOG_BUF_SIZE];
+    Slice bpfLog = Slice(bpf_log_buf, sizeof(bpf_log_buf));
+    prog->fd.reset(bpfProgLoad(prog->loadType, progBlock, "Apache 2.0", 0, bpfLog));
+    if (prog->fd < 0) {
+        int ret = -errno;
+        ALOGE("load %s failed: %s", prog->name, strerror(errno));
+        return ret;
+    }
+    if (prog->attachType == BPF_CGROUP_INET_EGRESS || prog->attachType == BPF_CGROUP_INET_INGRESS) {
+        unique_fd cg_fd(open(CGROUP_ROOT_PATH, O_DIRECTORY | O_RDONLY | O_CLOEXEC));
+        if (cg_fd < 0) {
+            int ret = -errno;
+            ALOGE("Failed to open the cgroup directory");
+            return ret;
+        }
+        int ret = android::bpf::attachProgram(prog->attachType, prog->fd, cg_fd);
+        if (ret) {
+            ret = -errno;
+            ALOGE("%s attach failed: %s", prog->name, strerror(errno));
+            return ret;
+        }
+    }
+    if (prog->path) {
+        int ret = android::bpf::bpfFdPin(prog->fd, prog->path);
+        if (ret) {
+            ret = -errno;
+            ALOGE("Pin %s as file %s failed: %s", prog->name, prog->path, strerror(errno));
+            return ret;
+        }
+    }
+    return 0;
+}
+
+int extractAndLoadProg(BpfProgInfo* prog, Elf64_Shdr* sectionPtr, Slice fileContents,
+                       const std::vector<BpfMapInfo>& mapPatterns) {
+    uint64_t progSize = (uint64_t) sectionPtr->sh_size;
+    Slice progSection = take(drop(fileContents, sectionPtr->sh_offset), progSize);
+    if (progSection.size() < progSize) {
+        ALOGE("programSection out of bound");
+        return -EINVAL;
+    }
+    MemBlock progCopy(progSection);
+    if (progCopy.get().size() != progSize) {
+        ALOGE("program cannot be extracted");
+        return -EINVAL;
+    }
+    Slice remaining = progCopy.get();
+    while (remaining.size() >= MAP_CMD_SIZE) {
+        // Scan the program, examining all possible places that might be the start of a
+        // map load operation (i.e., all bytes of value MAP_LD_CMD_HEAD).
+        // In each of these places, check whether it is the start of one of the patterns
+        // we want to replace, and if so, replace it.
+        Slice mapHead = findFirstMatching(remaining, MAP_LD_CMD_HEAD);
+        if (mapHead.size() < MAP_CMD_SIZE) break;
+        bool replaced = false;
+        for (const auto& pattern : mapPatterns) {
+            if (!memcmp(mapHead.base(), pattern.search.data(), MAP_CMD_SIZE)) {
+                memcpy(mapHead.base(), pattern.replace.data(), MAP_CMD_SIZE);
+                replaced = true;
+                break;
+            }
+        }
+        remaining = drop(mapHead, replaced ? MAP_CMD_SIZE : sizeof(uint8_t));
+    }
+    if (!(prog->path) || access(prog->path, R_OK) == -1) {
+        return loadAndPinProgram(prog, progCopy.get());
+    }
+    return 0;
+}
+
+int parsePrograms(Slice fileContents, BpfProgInfo* programs, size_t size,
+                  const std::vector<BpfMapInfo>& mapPatterns) {
+    Slice elfHeader = take(fileContents, sizeof(Elf64_Ehdr));
+    if (elfHeader.size() < sizeof(Elf64_Ehdr)) {
+        ALOGE("bpf fileContents does not have complete elf header");
+        return -EINVAL;
+    }
+
+    Elf64_Ehdr* elf = (Elf64_Ehdr*) elfHeader.base();
+    // Find section names string table. This is the section whose index is e_shstrndx.
+    if (elf->e_shstrndx == SHN_UNDEF) {
+        ALOGE("cannot locate namesSection\n");
+        return -EINVAL;
+    }
+    size_t totalSectionSize = (elf->e_shnum) * sizeof(Elf64_Shdr);
+    Slice sections = take(drop(fileContents, elf->e_shoff), totalSectionSize);
+    if (sections.size() < totalSectionSize) {
+        ALOGE("sections corrupted");
+        return -EMSGSIZE;
+    }
+
+    Slice namesSection =
+            take(drop(sections, elf->e_shstrndx * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr));
+    if (namesSection.size() != sizeof(Elf64_Shdr)) {
+        ALOGE("namesSection corrupted");
+        return -EMSGSIZE;
+    }
+    size_t strTabOffset = ((Elf64_Shdr*) namesSection.base())->sh_offset;
+    size_t strTabSize = ((Elf64_Shdr*) namesSection.base())->sh_size;
+
+    Slice strTab = take(drop(fileContents, strTabOffset), strTabSize);
+    if (strTab.size() < strTabSize) {
+        ALOGE("string table out of bound\n");
+        return -EMSGSIZE;
+    }
+
+    for (int i = 0; i < elf->e_shnum; i++) {
+        Slice section = take(drop(sections, i * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr));
+        if (section.size() < sizeof(Elf64_Shdr)) {
+            ALOGE("section %d is out of bound, section size: %zu, header size: %zu, total size: "
+                  "%zu",
+                  i, section.size(), sizeof(Elf64_Shdr), sections.size());
+            return -EBADF;
+        }
+        Elf64_Shdr* sectionPtr = (Elf64_Shdr*) section.base();
+        Slice nameSlice = drop(strTab, sectionPtr->sh_name);
+        if (nameSlice.size() == 0) {
+            ALOGE("nameSlice out of bound, i: %d, strTabSize: %zu, sh_name: %u", i, strTabSize,
+                  sectionPtr->sh_name);
+            return -EBADF;
+        }
+        for (size_t i = 0; i < size; i++) {
+            BpfProgInfo* prog = programs + i;
+            if (!strcmp((char*) nameSlice.base(), prog->name)) {
+                int ret = extractAndLoadProg(prog, sectionPtr, fileContents, mapPatterns);
+                if (ret) return ret;
+            }
+        }
+    }
+
+    // Check all the program struct passed in to make sure they all have a valid fd.
+    for (size_t i = 0; i < size; i++) {
+        BpfProgInfo* prog = programs + i;
+        if (access(prog->path, R_OK) == -1) {
+            ALOGE("Load program %s failed", prog->name);
+            return -EINVAL;
+        }
+    }
+    return 0;
+}
+
+int parseProgramsFromFile(const char* path, BpfProgInfo* programs, size_t size,
+                          const std::vector<BpfMapInfo>& mapPatterns) {
+    unique_fd fd(open(path, O_RDONLY | O_CLOEXEC));
+    int ret;
+    if (fd < 0) {
+        ret = -errno;
+        ALOGE("Failed to open %s program: %s", path, strerror(errno));
+        return ret;
+    }
+
+    struct stat stat;
+    if (fstat(fd.get(), &stat)) {
+        ret = -errno;
+        ALOGE("Failed to get file (%s) size: %s", path, strerror(errno));
+        return ret;
+    }
+
+    off_t fileLen = stat.st_size;
+    char* baseAddr =
+            (char*) mmap(NULL, fileLen, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd.get(), 0);
+    if (baseAddr == MAP_FAILED) {
+        ALOGE("Failed to map the program (%s) into memory: %s", path, strerror(errno));
+        ret = -errno;
+        return ret;
+    }
+
+    ret = parsePrograms(Slice(baseAddr, fileLen), programs, size, mapPatterns);
+
+    munmap(baseAddr, fileLen);
+    return ret;
+}
+
+}  // namespace bpf
+}  // namespace android
diff --git a/libbpf_android/include/bpf/BpfMap.h b/libbpf_android/include/bpf/BpfMap.h
new file mode 100644
index 0000000..deeed14
--- /dev/null
+++ b/libbpf_android/include/bpf/BpfMap.h
@@ -0,0 +1,284 @@
+/*
+ * 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.
+ */
+
+#ifndef BPF_BPFMAP_H
+#define BPF_BPFMAP_H
+
+#include <linux/bpf.h>
+
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <utils/Log.h>
+#include "bpf/BpfUtils.h"
+#include "netdutils/Status.h"
+#include "netdutils/StatusOr.h"
+
+namespace android {
+namespace bpf {
+
+// This is a class wrapper for eBPF maps. The eBPF map is a special in-kernel
+// data structure that stores data in <Key, Value> pairs. It can be read/write
+// from userspace by passing syscalls with the map file descriptor. This class
+// is used to generalize the procedure of interacting with eBPF maps and hide
+// the implementation detail from other process. Besides the basic syscalls
+// wrapper, it also provides some useful helper functions as well as an iterator
+// nested class to iterate the map more easily.
+//
+// NOTE: A kernel eBPF map may be accessed by both kernel and userspace
+// processes at the same time. Or if the map is pinned as a virtual file, it can
+// be obtained by multiple eBPF map class object and accessed concurrently.
+// Though the map class object and the underlying kernel map are thread safe, it
+// is not safe to iterate over a map while another thread or process is deleting
+// from it. In this case the iteration can return duplicate entries.
+template <class Key, class Value>
+class BpfMap {
+  public:
+    BpfMap<Key, Value>() : mMapFd(-1){};
+    explicit BpfMap<Key, Value>(int fd) : mMapFd(fd){};
+    BpfMap<Key, Value>(bpf_map_type map_type, uint32_t max_entries, uint32_t map_flags) {
+        int map_fd = createMap(map_type, sizeof(Key), sizeof(Value), max_entries, map_flags);
+        if (map_fd < 0) {
+            mMapFd.reset(-1);
+        } else {
+            mMapFd.reset(map_fd);
+        }
+    }
+
+    netdutils::Status pinToPath(const std::string& path) {
+        int ret = bpfFdPin(mMapFd, path.c_str());
+        if (ret) {
+            return netdutils::statusFromErrno(errno,
+                                              base::StringPrintf("pin to %s failed", path.c_str()));
+        }
+        mPinnedPath = path;
+        return netdutils::status::ok;
+    }
+
+    netdutils::StatusOr<Key> getFirstKey() const {
+        Key firstKey;
+        if (getFirstMapKey(mMapFd, &firstKey)) {
+            return netdutils::statusFromErrno(
+                errno, base::StringPrintf("Get firstKey map %d failed", mMapFd.get()));
+        }
+        return firstKey;
+    }
+
+    netdutils::StatusOr<Key> getNextKey(const Key& key) const {
+        Key nextKey;
+        if (getNextMapKey(mMapFd, const_cast<Key*>(&key), &nextKey)) {
+            return netdutils::statusFromErrno(
+                errno, base::StringPrintf("Get next key of map %d failed", mMapFd.get()));
+        }
+        return nextKey;
+    }
+
+    netdutils::Status writeValue(const Key& key, const Value& value, uint64_t flags) {
+        if (writeToMapEntry(mMapFd, const_cast<Key*>(&key), const_cast<Value*>(&value), flags)) {
+            return netdutils::statusFromErrno(
+                errno, base::StringPrintf("write to map %d failed", mMapFd.get()));
+        }
+        return netdutils::status::ok;
+    }
+
+    netdutils::StatusOr<Value> readValue(const Key key) const {
+        Value value;
+        if (findMapEntry(mMapFd, const_cast<Key*>(&key), &value)) {
+            return netdutils::statusFromErrno(
+                errno, base::StringPrintf("read value of map %d failed", mMapFd.get()));
+        }
+        return value;
+    }
+
+    netdutils::Status deleteValue(const Key& key) {
+        if (deleteMapEntry(mMapFd, const_cast<Key*>(&key))) {
+            return netdutils::statusFromErrno(
+                errno, base::StringPrintf("delete entry from map %d failed", mMapFd.get()));
+        }
+        return netdutils::status::ok;
+    }
+
+    // Function that tries to get map from a pinned path, if the map doesn't
+    // exist yet, create a new one and pinned to the path.
+    netdutils::Status getOrCreate(const uint32_t maxEntries, const char* path,
+                                  const bpf_map_type mapType);
+
+    // Iterate through the map and handle each key retrieved based on the filter
+    // without modification of map content.
+    netdutils::Status iterate(
+        const std::function<netdutils::Status(const Key& key, const BpfMap<Key, Value>& map)>&
+            filter) const;
+
+    // Iterate through the map and get each <key, value> pair, handle each <key,
+    // value> pair based on the filter without modification of map content.
+    netdutils::Status iterateWithValue(
+        const std::function<netdutils::Status(const Key& key, const Value& value,
+                                              const BpfMap<Key, Value>& map)>& filter) const;
+
+    // Iterate through the map and handle each key retrieved based on the filter
+    netdutils::Status iterate(
+        const std::function<netdutils::Status(const Key& key, BpfMap<Key, Value>& map)>& filter);
+
+    // Iterate through the map and get each <key, value> pair, handle each <key,
+    // value> pair based on the filter.
+    netdutils::Status iterateWithValue(
+        const std::function<netdutils::Status(const Key& key, const Value& value,
+                                              BpfMap<Key, Value>& map)>& filter);
+
+    const base::unique_fd& getMap() const { return mMapFd; };
+
+    const std::string getPinnedPath() const { return mPinnedPath; };
+
+    // Move constructor
+    void operator=(BpfMap<Key, Value>&& other) noexcept {
+        mMapFd = std::move(other.mMapFd);
+        if (!other.mPinnedPath.empty()) {
+            mPinnedPath = other.mPinnedPath;
+        } else {
+            mPinnedPath.clear();
+        }
+        other.reset();
+    }
+
+    void reset(int fd = -1) {
+        mMapFd.reset(fd);
+        mPinnedPath.clear();
+    }
+
+    bool isValid() const { return mMapFd != -1; }
+
+    // It is only safe to call this method if it is guaranteed that nothing will concurrently
+    // iterate over the map in any process.
+    netdutils::Status clear() {
+        const auto deleteAllEntries = [](const Key& key, BpfMap<Key, Value>& map) {
+            netdutils::Status res = map.deleteValue(key);
+            if (!isOk(res) && (res.code() != ENOENT)) {
+                ALOGE("Failed to delete data %s\n", strerror(res.code()));
+            }
+            return netdutils::status::ok;
+        };
+        RETURN_IF_NOT_OK(iterate(deleteAllEntries));
+        return netdutils::status::ok;
+    }
+
+    netdutils::StatusOr<bool> isEmpty() const {
+        auto key = this->getFirstKey();
+        // Return error code ENOENT means the map is empty
+        if (!isOk(key) && key.status().code() == ENOENT) return true;
+        RETURN_IF_NOT_OK(key);
+        return false;
+    }
+
+  private:
+    base::unique_fd mMapFd;
+    std::string mPinnedPath;
+};
+
+template <class Key, class Value>
+netdutils::Status BpfMap<Key, Value>::getOrCreate(const uint32_t maxEntries, const char* path,
+                                                  bpf_map_type mapType) {
+    int ret = access(path, R_OK);
+    /* Check the pinned location first to check if the map is already there.
+     * otherwise create a new one.
+     */
+    if (ret == 0) {
+        mMapFd = base::unique_fd(mapRetrieve(path, 0));
+        if (mMapFd == -1) {
+            reset();
+            return netdutils::statusFromErrno(
+                errno,
+                base::StringPrintf("pinned map not accessible or does not exist: (%s)\n", path));
+        }
+        mPinnedPath = path;
+    } else if (ret == -1 && errno == ENOENT) {
+        mMapFd = base::unique_fd(
+            createMap(mapType, sizeof(Key), sizeof(Value), maxEntries, BPF_F_NO_PREALLOC));
+        if (mMapFd == -1) {
+            reset();
+            return netdutils::statusFromErrno(errno,
+                                              base::StringPrintf("map create failed!: %s", path));
+        }
+        netdutils::Status pinStatus = pinToPath(path);
+        if (!isOk(pinStatus)) {
+            reset();
+            return pinStatus;
+        }
+        mPinnedPath = path;
+    } else {
+        return netdutils::statusFromErrno(
+            errno, base::StringPrintf("pinned map not accessible: %s", path));
+    }
+    return netdutils::status::ok;
+}
+
+template <class Key, class Value>
+netdutils::Status BpfMap<Key, Value>::iterate(
+    const std::function<netdutils::Status(const Key& key, const BpfMap<Key, Value>& map)>& filter)
+    const {
+    netdutils::StatusOr<Key> curKey = getFirstKey();
+    while (isOk(curKey)) {
+        const netdutils::StatusOr<Key>& nextKey = getNextKey(curKey.value());
+        RETURN_IF_NOT_OK(filter(curKey.value(), *this));
+        curKey = nextKey;
+    }
+    return curKey.status().code() == ENOENT ? netdutils::status::ok : curKey.status();
+}
+
+template <class Key, class Value>
+netdutils::Status BpfMap<Key, Value>::iterateWithValue(
+    const std::function<netdutils::Status(const Key& key, const Value& value,
+                                          const BpfMap<Key, Value>& map)>& filter) const {
+    netdutils::StatusOr<Key> curKey = getFirstKey();
+    while (isOk(curKey)) {
+        const netdutils::StatusOr<Key>& nextKey = getNextKey(curKey.value());
+        Value curValue;
+        ASSIGN_OR_RETURN(curValue, this->readValue(curKey.value()));
+        RETURN_IF_NOT_OK(filter(curKey.value(), curValue, *this));
+        curKey = nextKey;
+    }
+    return curKey.status().code() == ENOENT ? netdutils::status::ok : curKey.status();
+}
+
+template <class Key, class Value>
+netdutils::Status BpfMap<Key, Value>::iterate(
+    const std::function<netdutils::Status(const Key& key, BpfMap<Key, Value>& map)>& filter) {
+    netdutils::StatusOr<Key> curKey = getFirstKey();
+    while (isOk(curKey)) {
+        const netdutils::StatusOr<Key>& nextKey = getNextKey(curKey.value());
+        RETURN_IF_NOT_OK(filter(curKey.value(), *this));
+        curKey = nextKey;
+    }
+    return curKey.status().code() == ENOENT ? netdutils::status::ok : curKey.status();
+}
+
+template <class Key, class Value>
+netdutils::Status BpfMap<Key, Value>::iterateWithValue(
+    const std::function<netdutils::Status(const Key& key, const Value& value,
+                                          BpfMap<Key, Value>& map)>& filter) {
+    netdutils::StatusOr<Key> curKey = getFirstKey();
+    while (isOk(curKey)) {
+        const netdutils::StatusOr<Key>& nextKey = getNextKey(curKey.value());
+        Value curValue;
+        ASSIGN_OR_RETURN(curValue, this->readValue(curKey.value()));
+        RETURN_IF_NOT_OK(filter(curKey.value(), curValue, *this));
+        curKey = nextKey;
+    }
+    return curKey.status().code() == ENOENT ? netdutils::status::ok : curKey.status();
+}
+
+}  // namespace bpf
+}  // namespace android
+
+#endif
diff --git a/libbpf_android/include/bpf/BpfUtils.h b/libbpf_android/include/bpf/BpfUtils.h
new file mode 100644
index 0000000..ed31758
--- /dev/null
+++ b/libbpf_android/include/bpf/BpfUtils.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef BPF_BPFUTILS_H
+#define BPF_BPFUTILS_H
+
+#include <linux/bpf.h>
+#include <linux/if_ether.h>
+#include <linux/in.h>
+#include <linux/unistd.h>
+#include <net/if.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+
+#include "android-base/unique_fd.h"
+#include "netdutils/Slice.h"
+#include "netdutils/StatusOr.h"
+
+#define BPF_PASS 1
+#define BPF_DROP 0
+
+#define ptr_to_u64(x) ((uint64_t)(uintptr_t)(x))
+#define DEFAULT_LOG_LEVEL 1
+
+#define MAP_LD_CMD_HEAD 0x18
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+
+// The BPF instruction bytes that we need to replace. x is a placeholder (e.g., COOKIE_TAG_MAP).
+#define BPF_MAP_SEARCH_PATTERN(x)                                                               \
+    {                                                                                           \
+        0x18, 0x01, 0x00, 0x00,                                                                 \
+        (x)[0], (x)[1], (x)[2], (x)[3],                                                         \
+        0x00, 0x00, 0x00, 0x00,                                                                 \
+        (x)[4], (x)[5], (x)[6], (x)[7]                                                          \
+    }
+
+// The bytes we'll replace them with. x is the actual fd number for the map at runtime.
+// The second byte is changed from 0x01 to 0x11 since 0x11 is the special command used
+// for bpf map fd loading. The original 0x01 is only a normal load command.
+#define BPF_MAP_REPLACE_PATTERN(x)                                                              \
+    {                                                                                           \
+        0x18, 0x11, 0x00, 0x00,                                                                 \
+        (x)[0], (x)[1], (x)[2], (x)[3],                                                         \
+        0x00, 0x00, 0x00, 0x00,                                                                 \
+        (x)[4], (x)[5], (x)[6], (x)[7]                                                          \
+    }
+
+#define MAP_CMD_SIZE 16
+
+namespace android {
+namespace bpf {
+
+struct UidTag {
+    uint32_t uid;
+    uint32_t tag;
+};
+
+struct StatsKey {
+    uint32_t uid;
+    uint32_t tag;
+    uint32_t counterSet;
+    uint32_t ifaceIndex;
+};
+
+struct StatsValue {
+    uint64_t rxPackets;
+    uint64_t rxBytes;
+    uint64_t txPackets;
+    uint64_t txBytes;
+};
+
+struct Stats {
+    uint64_t rxBytes;
+    uint64_t rxPackets;
+    uint64_t txBytes;
+    uint64_t txPackets;
+    uint64_t tcpRxPackets;
+    uint64_t tcpTxPackets;
+};
+
+struct IfaceValue {
+    char name[IFNAMSIZ];
+};
+
+struct BpfProgInfo {
+    bpf_attach_type attachType;
+    const char* path;
+    const char* name;
+    bpf_prog_type loadType;
+    base::unique_fd fd;
+};
+
+int mapRetrieve(const char* pathname, uint32_t flags);
+
+struct BpfMapInfo {
+    std::array<uint8_t, MAP_CMD_SIZE> search;
+    std::array<uint8_t, MAP_CMD_SIZE> replace;
+    const int fd;
+    std::string path;
+
+    BpfMapInfo(uint64_t dummyFd, const char* mapPath)
+        : BpfMapInfo(dummyFd, android::bpf::mapRetrieve(mapPath, 0)) {}
+
+    BpfMapInfo(uint64_t dummyFd, int realFd, const char* mapPath = "") : fd(realFd), path(mapPath) {
+        search = BPF_MAP_SEARCH_PATTERN((uint8_t*) &dummyFd);
+        replace = BPF_MAP_REPLACE_PATTERN((uint8_t*) &realFd);
+    }
+};
+
+#ifndef DEFAULT_OVERFLOWUID
+#define DEFAULT_OVERFLOWUID 65534
+#endif
+
+constexpr const char* CGROUP_ROOT_PATH = "/dev/cg2_bpf";
+
+constexpr const int OVERFLOW_COUNTERSET = 2;
+
+constexpr const uint64_t NONEXISTENT_COOKIE = 0;
+
+constexpr const int MINIMUM_API_REQUIRED = 28;
+
+int createMap(bpf_map_type map_type, uint32_t key_size, uint32_t value_size,
+              uint32_t max_entries, uint32_t map_flags);
+int writeToMapEntry(const base::unique_fd& map_fd, void* key, void* value, uint64_t flags);
+int findMapEntry(const base::unique_fd& map_fd, void* key, void* value);
+int deleteMapEntry(const base::unique_fd& map_fd, void* key);
+int getNextMapKey(const base::unique_fd& map_fd, void* key, void* next_key);
+int getFirstMapKey(const base::unique_fd& map_fd, void* firstKey);
+int bpfProgLoad(bpf_prog_type prog_type, netdutils::Slice bpf_insns, const char* license,
+                uint32_t kern_version, netdutils::Slice bpf_log);
+int bpfFdPin(const base::unique_fd& map_fd, const char* pathname);
+int attachProgram(bpf_attach_type type, uint32_t prog_fd, uint32_t cg_fd);
+int detachProgram(bpf_attach_type type, uint32_t cg_fd);
+uint64_t getSocketCookie(int sockFd);
+bool hasBpfSupport();
+int parseProgramsFromFile(const char* path, BpfProgInfo* programs, size_t size,
+                          const std::vector<BpfMapInfo>& mapPatterns);
+
+#define SKIP_IF_BPF_NOT_SUPPORTED     \
+    do {                              \
+        if (!hasBpfSupport()) return; \
+    } while (0)
+
+constexpr int BPF_CONTINUE = 0;
+constexpr int BPF_DELETED = 1;
+
+bool operator==(const StatsValue& lhs, const StatsValue& rhs);
+bool operator==(const UidTag& lhs, const UidTag& rhs);
+bool operator==(const StatsKey& lhs, const StatsKey& rhs);
+
+}  // namespace bpf
+}  // namespace android
+
+#endif
