diff --git a/libbpf/BpfMapTest.cpp b/libbpf/BpfMapTest.cpp
new file mode 100644
index 0000000..e367bdb
--- /dev/null
+++ b/libbpf/BpfMapTest.cpp
@@ -0,0 +1,276 @@
+/*
+ * 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 <netdutils/MockSyscalls.h>
+#include "bpf/BpfMap.h"
+#include "bpf/BpfNetworkStats.h"
+#include "bpf/BpfUtils.h"
+
+using ::testing::_;
+using ::testing::ByMove;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrictMock;
+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/BpfUtils.cpp b/libbpf/BpfUtils.cpp
new file mode 100644
index 0000000..955f2ec
--- /dev/null
+++ b/libbpf/BpfUtils.cpp
@@ -0,0 +1,415 @@
+/*
+ * 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 <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/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <netdutils/MemBlock.h>
+#include <netdutils/Slice.h>
+#include <netdutils/StatusOr.h>
+#include "bpf/BpfUtils.h"
+
+using android::base::GetUintProperty;
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::netdutils::MemBlock;
+using android::netdutils::Slice;
+using android::netdutils::statusFromErrno;
+using android::netdutils::StatusOr;
+
+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));
+    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/include/bpf/BpfMap.h b/libbpf/include/bpf/BpfMap.h
new file mode 100644
index 0000000..20db43e
--- /dev/null
+++ b/libbpf/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){};
+    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/include/bpf/BpfUtils.h b/libbpf/include/bpf/BpfUtils.h
new file mode 100644
index 0000000..ed31758
--- /dev/null
+++ b/libbpf/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
