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
