[NETD-BPF#1] Move libnetdutils to frameworks/libs/net/...

libnetdutils is referenced by netd.c and TrafficController.cpp, which
are going to be mainlined. Therefore, move libnetdutils to a common
place where both mainline module and platform code (Netd) can refer to.

Bug: 202086915
Test: build; flash; cd system/netd; atest
Ignore-AOSP-First: the netd change(same topic) would not automerge from
aosp.
No-Typo-Check: Clean code move with no other changes.
BYPASS_INCLUSIVE_LANGUAGE_REASON=Clean code move with no other changes.
Change-Id: I645bfe35f6543149c9a9f894cd4158d27a481abe
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/BackoffSequence.h b/staticlibs/netd/libnetdutils/include/netdutils/BackoffSequence.h
new file mode 100644
index 0000000..a52e72d
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/BackoffSequence.h
@@ -0,0 +1,153 @@
+/*
+ * 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 NETDUTILS_BACKOFFSEQUENCE_H
+#define NETDUTILS_BACKOFFSEQUENCE_H
+
+#include <stdint.h>
+#include <algorithm>
+#include <chrono>
+#include <limits>
+
+namespace android {
+namespace netdutils {
+
+// Encapsulate some RFC 3315 section 14 -style backoff mechanics.
+//
+//     https://tools.ietf.org/html/rfc3315#section-14
+template<typename time_type = std::chrono::seconds, typename counter_type = uint32_t>
+class BackoffSequence {
+  public:
+    struct Parameters {
+        time_type initialRetransTime{TIME_UNITY};
+        counter_type maxRetransCount{0U};
+        time_type maxRetransTime{TIME_ZERO};
+        time_type maxRetransDuration{TIME_ZERO};
+        time_type endOfSequenceIndicator{TIME_ZERO};
+    };
+
+    BackoffSequence() : BackoffSequence(Parameters{}) {}
+    BackoffSequence(const BackoffSequence &) = default;
+    BackoffSequence(BackoffSequence &&) = default;
+    BackoffSequence& operator=(const BackoffSequence &) = default;
+    BackoffSequence& operator=(BackoffSequence &&) = default;
+
+    bool hasNextTimeout() const noexcept {
+        return !maxRetransCountExceed() && !maxRetransDurationExceeded();
+    }
+
+    // Returns 0 when the sequence is exhausted.
+    time_type getNextTimeout() {
+        if (!hasNextTimeout()) return getEndOfSequenceIndicator();
+
+        mRetransTime = getNextTimeoutAfter(mRetransTime);
+
+        mRetransCount++;
+        mTotalRetransDuration += mRetransTime;
+        return mRetransTime;
+    }
+
+    time_type getEndOfSequenceIndicator() const noexcept {
+        return mParams.endOfSequenceIndicator;
+    }
+
+    class Builder {
+      public:
+        Builder() {}
+
+        constexpr Builder& withInitialRetransmissionTime(time_type irt) {
+            mParams.initialRetransTime = irt;
+            return *this;
+        }
+        constexpr Builder& withMaximumRetransmissionCount(counter_type mrc) {
+            mParams.maxRetransCount = mrc;
+            return *this;
+        }
+        constexpr Builder& withMaximumRetransmissionTime(time_type mrt) {
+            mParams.maxRetransTime = mrt;
+            return *this;
+        }
+        constexpr Builder& withMaximumRetransmissionDuration(time_type mrd) {
+            mParams.maxRetransDuration = mrd;
+            return *this;
+        }
+        constexpr Builder& withEndOfSequenceIndicator(time_type eos) {
+            mParams.endOfSequenceIndicator = eos;
+            return *this;
+        }
+
+        constexpr BackoffSequence build() const {
+            return BackoffSequence(mParams);
+        }
+
+      private:
+        Parameters mParams;
+    };
+
+  private:
+    static constexpr int PER_ITERATION_SCALING_FACTOR = 2;
+    static constexpr time_type TIME_ZERO = time_type();
+    static constexpr time_type TIME_UNITY = time_type(1);
+
+    constexpr BackoffSequence(const struct Parameters &params)
+            : mParams(params),
+              mRetransCount(0),
+              mRetransTime(TIME_ZERO),
+              mTotalRetransDuration(TIME_ZERO) {}
+
+    constexpr bool maxRetransCountExceed() const {
+        return (mParams.maxRetransCount > 0) && (mRetransCount >= mParams.maxRetransCount);
+    }
+
+    constexpr bool maxRetransDurationExceeded() const {
+        return (mParams.maxRetransDuration > TIME_ZERO) &&
+               (mTotalRetransDuration >= mParams.maxRetransDuration);
+    }
+
+    time_type getNextTimeoutAfter(time_type lastTimeout) const {
+        // TODO: Support proper random jitter. Also, consider supporting some
+        // per-iteration scaling factor other than doubling.
+        time_type nextTimeout = (lastTimeout > TIME_ZERO)
+                ? PER_ITERATION_SCALING_FACTOR * lastTimeout
+                : mParams.initialRetransTime;
+
+        // Check if overflow occurred.
+        if (nextTimeout < lastTimeout) {
+            nextTimeout = std::numeric_limits<time_type>::max();
+        }
+
+        // Cap to maximum allowed, if necessary.
+        if (mParams.maxRetransTime > TIME_ZERO) {
+            nextTimeout = std::min(nextTimeout, mParams.maxRetransTime);
+        }
+
+        // Don't overflow the maximum total duration.
+        if (mParams.maxRetransDuration > TIME_ZERO) {
+            nextTimeout = std::min(nextTimeout, mParams.maxRetransDuration - lastTimeout);
+        }
+        return nextTimeout;
+    }
+
+    const Parameters mParams;
+    counter_type mRetransCount;
+    time_type mRetransTime;
+    time_type mTotalRetransDuration;
+};
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETDUTILS_BACKOFFSEQUENCE_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/DumpWriter.h b/staticlibs/netd/libnetdutils/include/netdutils/DumpWriter.h
new file mode 100644
index 0000000..a50b5e6
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/DumpWriter.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NETDUTILS_DUMPWRITER_H_
+#define NETDUTILS_DUMPWRITER_H_
+
+#include <string>
+
+namespace android {
+namespace netdutils {
+
+class DumpWriter {
+  public:
+    DumpWriter(int fd);
+
+    void incIndent();
+    void decIndent();
+
+    void println(const std::string& line);
+    template <size_t n>
+    void println(const char line[n]) {
+        println(std::string(line));
+    }
+    // Hint to the compiler that it should apply printf validation of
+    // arguments (beginning at position 3) of the format (specified in
+    // position 2). Note that position 1 is the implicit "this" argument.
+    void println(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
+    void blankline() { println(""); }
+
+  private:
+    uint8_t mIndentLevel;
+    int mFd;
+};
+
+class ScopedIndent {
+  public:
+    ScopedIndent() = delete;
+    ScopedIndent(const ScopedIndent&) = delete;
+    ScopedIndent(ScopedIndent&&) = delete;
+    explicit ScopedIndent(DumpWriter& dw) : mDw(dw) { mDw.incIndent(); }
+    ~ScopedIndent() { mDw.decIndent(); }
+    ScopedIndent& operator=(const ScopedIndent&) = delete;
+    ScopedIndent& operator=(ScopedIndent&&) = delete;
+
+    // TODO: consider additional {inc,dec}Indent methods and a counter that
+    // can be used to unwind all pending increments on exit.
+
+  private:
+    DumpWriter& mDw;
+};
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif  // NETDUTILS_DUMPWRITER_H_
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Fd.h b/staticlibs/netd/libnetdutils/include/netdutils/Fd.h
new file mode 100644
index 0000000..7db4087
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Fd.h
@@ -0,0 +1,54 @@
+/*
+ * 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 NETUTILS_FD_H
+#define NETUTILS_FD_H
+
+#include <ostream>
+
+#include "netdutils/Status.h"
+
+namespace android {
+namespace netdutils {
+
+// Strongly typed wrapper for file descriptors with value semantics.
+// This class should typically hold unowned file descriptors.
+class Fd {
+  public:
+    constexpr Fd() = default;
+
+    constexpr Fd(int fd) : mFd(fd) {}
+
+    int get() const { return mFd; }
+
+    bool operator==(const Fd& other) const { return get() == other.get(); }
+    bool operator!=(const Fd& other) const { return get() != other.get(); }
+
+  private:
+    int mFd = -1;
+};
+
+// Return true if fd appears valid (non-negative)
+inline bool isWellFormed(const Fd fd) {
+    return fd.get() >= 0;
+}
+
+std::ostream& operator<<(std::ostream& os, const Fd& fd);
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_FD_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Handle.h b/staticlibs/netd/libnetdutils/include/netdutils/Handle.h
new file mode 100644
index 0000000..82083d4
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Handle.h
@@ -0,0 +1,74 @@
+/*
+ * 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 NETUTILS_HANDLE_H
+#define NETUTILS_HANDLE_H
+
+#include <ostream>
+
+namespace android {
+namespace netdutils {
+
+// Opaque, strongly typed wrapper for integer-like handles.
+// Explicitly avoids implementing arithmetic operations.
+//
+// This class is intended to avoid common errors when reordering
+// arguments to functions, typos and other cases where plain integer
+// types would silently cover up the mistake.
+//
+// usage:
+// DEFINE_HANDLE(ProductId, uint64_t);
+// DEFINE_HANDLE(ThumbnailHash, uint64_t);
+// void foo(ProductId p, ThumbnailHash th) {...}
+//
+// void test() {
+//     ProductId p(88);
+//     ThumbnailHash th1(100), th2(200);
+//
+//     foo(p, th1);        <- ok!
+//     foo(th1, p);        <- disallowed!
+//     th1 += 10;          <- disallowed!
+//     p = th2;            <- disallowed!
+//     assert(th1 != th2); <- ok!
+// }
+template <typename T, typename TagT>
+class Handle {
+  public:
+    constexpr Handle() = default;
+    constexpr Handle(const T& value) : mValue(value) {}
+
+    const T get() const { return mValue; }
+
+    bool operator==(const Handle& that) const { return get() == that.get(); }
+    bool operator!=(const Handle& that) const { return get() != that.get(); }
+
+  private:
+    T mValue;
+};
+
+#define DEFINE_HANDLE(name, type) \
+    struct _##name##Tag {};       \
+    using name = ::android::netdutils::Handle<type, _##name##Tag>;
+
+template <typename T, typename TagT>
+inline std::ostream& operator<<(std::ostream& os, const Handle<T, TagT>& handle) {
+    return os << handle.get();
+}
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_HANDLE_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/InternetAddresses.h b/staticlibs/netd/libnetdutils/include/netdutils/InternetAddresses.h
new file mode 100644
index 0000000..d5cbe2b
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/InternetAddresses.h
@@ -0,0 +1,325 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <cstring>
+#include <limits>
+#include <string>
+
+#include "netdutils/NetworkConstants.h"
+
+namespace android {
+namespace netdutils {
+
+namespace internal_ {
+
+// A structure to hold data for dealing with Internet addresses (IPAddress) and
+// related types such as IPSockAddr and IPPrefix.
+struct compact_ipdata {
+    uint8_t family{AF_UNSPEC};
+    uint8_t cidrlen{0U};  // written and read in host-byte order
+    in_port_t port{0U};   // written and read in host-byte order
+    uint32_t scope_id{0U};
+    union {
+        in_addr v4;
+        in6_addr v6;
+    } ip{.v6 = IN6ADDR_ANY_INIT};  // written and read in network-byte order
+
+    // Classes that use compact_ipdata and this method should be sure to clear
+    // (i.e. zero or make uniform) any fields not relevant to the class.
+    friend bool operator==(const compact_ipdata& a, const compact_ipdata& b) {
+        if ((a.family != b.family) || (a.cidrlen != b.cidrlen) || (a.port != b.port) ||
+            (a.scope_id != b.scope_id)) {
+            return false;
+        }
+        switch (a.family) {
+            case AF_UNSPEC:
+                // After the above checks, two AF_UNSPEC objects can be
+                // considered equal, for convenience.
+                return true;
+            case AF_INET: {
+                const in_addr v4a = a.ip.v4;
+                const in_addr v4b = b.ip.v4;
+                return (v4a.s_addr == v4b.s_addr);
+            }
+            case AF_INET6: {
+                const in6_addr v6a = a.ip.v6;
+                const in6_addr v6b = b.ip.v6;
+                return IN6_ARE_ADDR_EQUAL(&v6a, &v6b);
+            }
+        }
+        return false;
+    }
+
+    // Classes that use compact_ipdata and this method should be sure to clear
+    // (i.e. zero or make uniform) any fields not relevant to the class.
+    friend bool operator!=(const compact_ipdata& a, const compact_ipdata& b) { return !(a == b); }
+
+    // Classes that use compact_ipdata and this method should be sure to clear
+    // (i.e. zero or make uniform) any fields not relevant to the class.
+    friend bool operator<(const compact_ipdata& a, const compact_ipdata& b) {
+        if (a.family != b.family) return (a.family < b.family);
+        switch (a.family) {
+            case AF_INET: {
+                const in_addr v4a = a.ip.v4;
+                const in_addr v4b = b.ip.v4;
+                if (v4a.s_addr != v4b.s_addr) return (ntohl(v4a.s_addr) < ntohl(v4b.s_addr));
+                break;
+            }
+            case AF_INET6: {
+                const in6_addr v6a = a.ip.v6;
+                const in6_addr v6b = b.ip.v6;
+                const int cmp = std::memcmp(v6a.s6_addr, v6b.s6_addr, IPV6_ADDR_LEN);
+                if (cmp != 0) return cmp < 0;
+                break;
+            }
+        }
+        if (a.cidrlen != b.cidrlen) return (a.cidrlen < b.cidrlen);
+        if (a.port != b.port) return (a.port < b.port);
+        return (a.scope_id < b.scope_id);
+    }
+};
+
+static_assert(AF_UNSPEC <= std::numeric_limits<uint8_t>::max(), "AF_UNSPEC value too large");
+static_assert(AF_INET <= std::numeric_limits<uint8_t>::max(), "AF_INET value too large");
+static_assert(AF_INET6 <= std::numeric_limits<uint8_t>::max(), "AF_INET6 value too large");
+static_assert(sizeof(compact_ipdata) == 24U, "compact_ipdata unexpectedly large");
+
+}  // namespace internal_
+
+struct AddrinfoDeleter {
+    void operator()(struct addrinfo* p) const {
+        if (p != nullptr) {
+            freeaddrinfo(p);
+        }
+    }
+};
+
+typedef std::unique_ptr<struct addrinfo, struct AddrinfoDeleter> ScopedAddrinfo;
+
+inline bool usesScopedIds(const in6_addr& ipv6) {
+    return (IN6_IS_ADDR_LINKLOCAL(&ipv6) || IN6_IS_ADDR_MC_LINKLOCAL(&ipv6));
+}
+
+class IPPrefix;
+class IPSockAddr;
+
+class IPAddress {
+  public:
+    static bool forString(const std::string& repr, IPAddress* ip);
+    static IPAddress forString(const std::string& repr) {
+        IPAddress ip;
+        if (!forString(repr, &ip)) return IPAddress();
+        return ip;
+    }
+
+    IPAddress() = default;
+    IPAddress(const IPAddress&) = default;
+    IPAddress(IPAddress&&) = default;
+
+    explicit IPAddress(const in_addr& ipv4)
+        : mData({AF_INET, IPV4_ADDR_BITS, 0U, 0U, {.v4 = ipv4}}) {}
+    explicit IPAddress(const in6_addr& ipv6)
+        : mData({AF_INET6, IPV6_ADDR_BITS, 0U, 0U, {.v6 = ipv6}}) {}
+    IPAddress(const in6_addr& ipv6, uint32_t scope_id)
+        : mData({AF_INET6,
+                 IPV6_ADDR_BITS,
+                 0U,
+                 // Sanity check: scoped_ids only for link-local addresses.
+                 usesScopedIds(ipv6) ? scope_id : 0U,
+                 {.v6 = ipv6}}) {}
+    IPAddress(const IPAddress& ip, uint32_t scope_id) : IPAddress(ip) {
+        mData.scope_id = (family() == AF_INET6 && usesScopedIds(mData.ip.v6)) ? scope_id : 0U;
+    }
+
+    IPAddress& operator=(const IPAddress&) = default;
+    IPAddress& operator=(IPAddress&&) = default;
+
+    constexpr sa_family_t family() const noexcept { return mData.family; }
+    constexpr uint32_t scope_id() const noexcept { return mData.scope_id; }
+
+    std::string toString() const noexcept;
+
+    friend std::ostream& operator<<(std::ostream& os, const IPAddress& ip) {
+        os << ip.toString();
+        return os;
+    }
+    friend bool operator==(const IPAddress& a, const IPAddress& b) { return (a.mData == b.mData); }
+    friend bool operator!=(const IPAddress& a, const IPAddress& b) { return (a.mData != b.mData); }
+    friend bool operator<(const IPAddress& a, const IPAddress& b) { return (a.mData < b.mData); }
+    friend bool operator>(const IPAddress& a, const IPAddress& b) { return (b.mData < a.mData); }
+    friend bool operator<=(const IPAddress& a, const IPAddress& b) { return (a < b) || (a == b); }
+    friend bool operator>=(const IPAddress& a, const IPAddress& b) { return (b < a) || (a == b); }
+
+  private:
+    friend class IPPrefix;
+    friend class IPSockAddr;
+
+    explicit IPAddress(const internal_::compact_ipdata& ipdata) : mData(ipdata) {
+        mData.port = 0U;
+        switch (mData.family) {
+            case AF_INET:
+                mData.cidrlen = IPV4_ADDR_BITS;
+                mData.scope_id = 0U;
+                break;
+            case AF_INET6:
+                mData.cidrlen = IPV6_ADDR_BITS;
+                if (usesScopedIds(ipdata.ip.v6)) mData.scope_id = ipdata.scope_id;
+                break;
+            default:
+                mData.cidrlen = 0U;
+                mData.scope_id = 0U;
+                break;
+        }
+    }
+
+    internal_::compact_ipdata mData{};
+};
+
+class IPPrefix {
+  public:
+    static bool forString(const std::string& repr, IPPrefix* prefix);
+    static IPPrefix forString(const std::string& repr) {
+        IPPrefix prefix;
+        if (!forString(repr, &prefix)) return IPPrefix();
+        return prefix;
+    }
+
+    IPPrefix() = default;
+    IPPrefix(const IPPrefix&) = default;
+    IPPrefix(IPPrefix&&) = default;
+
+    explicit IPPrefix(const IPAddress& ip) : mData(ip.mData) {}
+
+    // Truncate the IP address |ip| at length |length|. Lengths greater than
+    // the address-family-relevant maximum, along with negative values, are
+    // interpreted as if the address-family-relevant maximum had been given.
+    IPPrefix(const IPAddress& ip, int length);
+
+    IPPrefix& operator=(const IPPrefix&) = default;
+    IPPrefix& operator=(IPPrefix&&) = default;
+
+    constexpr sa_family_t family() const noexcept { return mData.family; }
+    IPAddress ip() const noexcept { return IPAddress(mData); }
+    in_addr addr4() const noexcept { return mData.ip.v4; }
+    in6_addr addr6() const noexcept { return mData.ip.v6; }
+    constexpr int length() const noexcept { return mData.cidrlen; }
+
+    bool isUninitialized() const noexcept;
+    std::string toString() const noexcept;
+
+    friend std::ostream& operator<<(std::ostream& os, const IPPrefix& prefix) {
+        os << prefix.toString();
+        return os;
+    }
+    friend bool operator==(const IPPrefix& a, const IPPrefix& b) { return (a.mData == b.mData); }
+    friend bool operator!=(const IPPrefix& a, const IPPrefix& b) { return (a.mData != b.mData); }
+    friend bool operator<(const IPPrefix& a, const IPPrefix& b) { return (a.mData < b.mData); }
+    friend bool operator>(const IPPrefix& a, const IPPrefix& b) { return (b.mData < a.mData); }
+    friend bool operator<=(const IPPrefix& a, const IPPrefix& b) { return (a < b) || (a == b); }
+    friend bool operator>=(const IPPrefix& a, const IPPrefix& b) { return (b < a) || (a == b); }
+
+  private:
+    internal_::compact_ipdata mData{};
+};
+
+// An Internet socket address.
+//
+// Cannot represent other types of socket addresses (e.g. UNIX socket address, et cetera).
+class IPSockAddr {
+  public:
+    // TODO: static forString
+
+    static IPSockAddr toIPSockAddr(const std::string& repr, in_port_t port) {
+        return IPSockAddr(IPAddress::forString(repr), port);
+    }
+    static IPSockAddr toIPSockAddr(const sockaddr& sa) {
+        switch (sa.sa_family) {
+            case AF_INET:
+                return IPSockAddr(*reinterpret_cast<const sockaddr_in*>(&sa));
+            case AF_INET6:
+                return IPSockAddr(*reinterpret_cast<const sockaddr_in6*>(&sa));
+            default:
+                return IPSockAddr();
+        }
+    }
+    static IPSockAddr toIPSockAddr(const sockaddr_storage& ss) {
+        return toIPSockAddr(*reinterpret_cast<const sockaddr*>(&ss));
+    }
+
+    IPSockAddr() = default;
+    IPSockAddr(const IPSockAddr&) = default;
+    IPSockAddr(IPSockAddr&&) = default;
+
+    explicit IPSockAddr(const IPAddress& ip) : mData(ip.mData) {}
+    IPSockAddr(const IPAddress& ip, in_port_t port) : mData(ip.mData) { mData.port = port; }
+    explicit IPSockAddr(const sockaddr_in& ipv4sa)
+        : IPSockAddr(IPAddress(ipv4sa.sin_addr), ntohs(ipv4sa.sin_port)) {}
+    explicit IPSockAddr(const sockaddr_in6& ipv6sa)
+        : IPSockAddr(IPAddress(ipv6sa.sin6_addr, ipv6sa.sin6_scope_id), ntohs(ipv6sa.sin6_port)) {}
+
+    IPSockAddr& operator=(const IPSockAddr&) = default;
+    IPSockAddr& operator=(IPSockAddr&&) = default;
+
+    constexpr sa_family_t family() const noexcept { return mData.family; }
+    IPAddress ip() const noexcept { return IPAddress(mData); }
+    constexpr in_port_t port() const noexcept { return mData.port; }
+
+    // Implicit conversion to sockaddr_storage.
+    operator sockaddr_storage() const noexcept {
+        sockaddr_storage ss;
+        ss.ss_family = mData.family;
+        switch (mData.family) {
+            case AF_INET:
+                reinterpret_cast<sockaddr_in*>(&ss)->sin_addr = mData.ip.v4;
+                reinterpret_cast<sockaddr_in*>(&ss)->sin_port = htons(mData.port);
+                break;
+            case AF_INET6:
+                reinterpret_cast<sockaddr_in6*>(&ss)->sin6_addr = mData.ip.v6;
+                reinterpret_cast<sockaddr_in6*>(&ss)->sin6_port = htons(mData.port);
+                reinterpret_cast<sockaddr_in6*>(&ss)->sin6_scope_id = mData.scope_id;
+                break;
+        }
+        return ss;
+    }
+
+    std::string toString() const noexcept;
+
+    friend std::ostream& operator<<(std::ostream& os, const IPSockAddr& prefix) {
+        os << prefix.toString();
+        return os;
+    }
+    friend bool operator==(const IPSockAddr& a, const IPSockAddr& b) {
+        return (a.mData == b.mData);
+    }
+    friend bool operator!=(const IPSockAddr& a, const IPSockAddr& b) {
+        return (a.mData != b.mData);
+    }
+    friend bool operator<(const IPSockAddr& a, const IPSockAddr& b) { return (a.mData < b.mData); }
+    friend bool operator>(const IPSockAddr& a, const IPSockAddr& b) { return (b.mData < a.mData); }
+    friend bool operator<=(const IPSockAddr& a, const IPSockAddr& b) { return (a < b) || (a == b); }
+    friend bool operator>=(const IPSockAddr& a, const IPSockAddr& b) { return (b < a) || (a == b); }
+
+  private:
+    internal_::compact_ipdata mData{};
+};
+
+}  // namespace netdutils
+}  // namespace android
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Log.h b/staticlibs/netd/libnetdutils/include/netdutils/Log.h
new file mode 100644
index 0000000..77ae649
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Log.h
@@ -0,0 +1,211 @@
+/*
+ * 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 NETUTILS_LOG_H
+#define NETUTILS_LOG_H
+
+#include <chrono>
+#include <deque>
+#include <shared_mutex>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include <android-base/stringprintf.h>
+#include <android-base/thread_annotations.h>
+
+#include <netdutils/Status.h>
+
+namespace android {
+namespace netdutils {
+
+class LogEntry {
+  public:
+    LogEntry() = default;
+    LogEntry(const LogEntry&) = default;
+    LogEntry(LogEntry&&) = default;
+    ~LogEntry() = default;
+    LogEntry& operator=(const LogEntry&) = default;
+    LogEntry& operator=(LogEntry&&) = default;
+
+    std::string toString() const;
+
+    ///
+    // Helper methods that make it easy to build up a LogEntry message.
+    // If performance becomes a factor the implementations could be inlined.
+    ///
+    LogEntry& message(const std::string& message);
+
+    // For calling with __FUNCTION__.
+    LogEntry& function(const std::string& function_name);
+    // For calling with __PRETTY_FUNCTION__.
+    LogEntry& prettyFunction(const std::string& pretty_function);
+
+    // Convenience methods for each of the common types of function arguments.
+    LogEntry& arg(const std::string& val);
+    // Intended for binary buffers, formats as hex
+    LogEntry& arg(const std::vector<uint8_t>& val);
+    LogEntry& arg(const std::vector<int32_t>& val);
+    LogEntry& arg(const std::vector<std::string>& val);
+    template <typename IntT, typename = std::enable_if_t<std::is_arithmetic_v<IntT>>>
+    LogEntry& arg(IntT val) {
+        mArgs.push_back(std::to_string(val));
+        return *this;
+    }
+    // Not using a plain overload here to avoid the implicit conversion from
+    // any pointer to bool, which causes string literals to print as 'true'.
+    template <>
+    LogEntry& arg<>(bool val);
+
+    template <typename... Args>
+    LogEntry& args(const Args&... a) {
+        // Cleverness ahead: we throw away the initializer_list filled with
+        // zeroes, all we care about is calling arg() for each argument.
+        (void) std::initializer_list<int>{(arg(a), 0)...};
+        return *this;
+    }
+
+    // Some things can return more than one value, or have multiple output
+    // parameters, so each of these adds to the mReturns vector.
+    LogEntry& returns(const std::string& rval);
+    LogEntry& returns(const Status& status);
+    LogEntry& returns(bool rval);
+    template <class T>
+    LogEntry& returns(T val) {
+        mReturns.push_back(std::to_string(val));
+        return *this;
+    }
+
+    LogEntry& withUid(uid_t uid);
+
+    // Append the duration computed since the creation of this instance.
+    LogEntry& withAutomaticDuration();
+    // Append the string-ified duration computed by some other means.
+    LogEntry& withDuration(const std::string& duration);
+
+  private:
+    std::chrono::steady_clock::time_point mStart = std::chrono::steady_clock::now();
+    std::string mMsg{};
+    std::string mFunc{};
+    std::vector<std::string> mArgs{};
+    std::vector<std::string> mReturns{};
+    std::string mUid{};
+    std::string mDuration{};
+};
+
+class Log {
+  public:
+    Log() = delete;
+    Log(const std::string& tag) : Log(tag, MAX_ENTRIES) {}
+    Log(const std::string& tag, size_t maxEntries) : mTag(tag), mMaxEntries(maxEntries) {}
+    Log(const Log&) = delete;
+    Log(Log&&) = delete;
+    ~Log();
+    Log& operator=(const Log&) = delete;
+    Log& operator=(Log&&) = delete;
+
+    LogEntry newEntry() const { return LogEntry(); }
+
+    // Record a log entry in internal storage only.
+    void log(const std::string& entry) { record(Level::LOG, entry); }
+    template <size_t n>
+    void log(const char entry[n]) { log(std::string(entry)); }
+    void log(const LogEntry& entry) { log(entry.toString()); }
+    void log(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
+        using ::android::base::StringAppendV;
+        std::string result;
+        va_list ap;
+        va_start(ap, fmt);
+        StringAppendV(&result, fmt, ap);
+        va_end(ap);
+        log(result);
+    }
+
+    // Record a log entry in internal storage and to ALOGI as well.
+    void info(const std::string& entry) { record(Level::INFO, entry); }
+    template <size_t n>
+    void info(const char entry[n]) { info(std::string(entry)); }
+    void info(const LogEntry& entry) { info(entry.toString()); }
+    void info(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
+        using ::android::base::StringAppendV;
+        std::string result;
+        va_list ap;
+        va_start(ap, fmt);
+        StringAppendV(&result, fmt, ap);
+        va_end(ap);
+        info(result);
+    }
+
+    // Record a log entry in internal storage and to ALOGW as well.
+    void warn(const std::string& entry) { record(Level::WARN, entry); }
+    template <size_t n>
+    void warn(const char entry[n]) { warn(std::string(entry)); }
+    void warn(const LogEntry& entry) { warn(entry.toString()); }
+    void warn(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
+        using ::android::base::StringAppendV;
+        std::string result;
+        va_list ap;
+        va_start(ap, fmt);
+        StringAppendV(&result, fmt, ap);
+        va_end(ap);
+        warn(result);
+    }
+
+    // Record a log entry in internal storage and to ALOGE as well.
+    void error(const std::string& entry) { record(Level::ERROR, entry); }
+    template <size_t n>
+    void error(const char entry[n]) { error(std::string(entry)); }
+    void error(const LogEntry& entry) { error(entry.toString()); }
+    void error(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
+        using ::android::base::StringAppendV;
+        std::string result;
+        va_list ap;
+        va_start(ap, fmt);
+        StringAppendV(&result, fmt, ap);
+        va_end(ap);
+        error(result);
+    }
+
+    // Iterates over every entry in the log in chronological order. Operates
+    // on a copy of the log entries, and so perEntryFn may itself call one of
+    // the logging functions if needed.
+    void forEachEntry(const std::function<void(const std::string&)>& perEntryFn) const;
+
+  private:
+    static constexpr const size_t MAX_ENTRIES = 750U;
+    const std::string mTag;
+    const size_t mMaxEntries;
+
+    // The LOG level adds an entry to mEntries but does not output the message
+    // to the system log. All other levels append to mEntries and output to the
+    // the system log.
+    enum class Level {
+        LOG,
+        INFO,
+        WARN,
+        ERROR,
+    };
+
+    void record(Level lvl, const std::string& entry);
+
+    mutable std::shared_mutex mLock;
+    std::deque<const std::string> mEntries;  // GUARDED_BY(mLock), when supported
+};
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_LOG_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Math.h b/staticlibs/netd/libnetdutils/include/netdutils/Math.h
new file mode 100644
index 0000000..c41fbf5
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Math.h
@@ -0,0 +1,40 @@
+/*
+ * 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 NETUTILS_MATH_H
+#define NETUTILS_MATH_H
+
+#include <algorithm>
+#include <cstdint>
+
+namespace android {
+namespace netdutils {
+
+template <class T>
+inline constexpr const T mask(const int shift) {
+    return (1 << shift) - 1;
+}
+
+// Align x up to the nearest integer multiple of 2^shift
+template <class T>
+inline constexpr const T align(const T& x, const int shift) {
+    return (x + mask<T>(shift)) & ~mask<T>(shift);
+}
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_MATH_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/MemBlock.h b/staticlibs/netd/libnetdutils/include/netdutils/MemBlock.h
new file mode 100644
index 0000000..fd4d612
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/MemBlock.h
@@ -0,0 +1,67 @@
+/*
+ * 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 NETUTILS_MEMBLOCK_H
+#define NETUTILS_MEMBLOCK_H
+
+#include <memory>
+#include "netdutils/Slice.h"
+
+namespace android {
+namespace netdutils {
+
+// A class to encapsulate self-deleting byte arrays while preserving access
+// to the underlying length (without the length being part of the type, e.g.
+// std::array<>). By design, the only interface to the underlying bytes is
+// via Slice, to encourage safer memory access usage.
+//
+// No thread-safety guarantees whatsoever.
+class MemBlock {
+  public:
+    MemBlock() : MemBlock(0U) {}
+    explicit MemBlock(size_t len)
+            : mData((len > 0U) ? new uint8_t[len]{} : nullptr),
+              mLen(len) {}
+    // Allocate memory of size src.size() and copy src into this MemBlock.
+    explicit MemBlock(Slice src) : MemBlock(src.size()) {
+        copy(get(), src);
+    }
+
+    // No copy construction or assignment.
+    MemBlock(const MemBlock&) = delete;
+    MemBlock& operator=(const MemBlock&) = delete;
+
+    // Move construction and assignment are okay.
+    MemBlock(MemBlock&&) = default;
+    MemBlock& operator=(MemBlock&&) = default;
+
+    // Even though this method is const, the memory wrapped by the
+    // returned Slice is mutable.
+    Slice get() const noexcept { return Slice(mData.get(), mLen); }
+
+    // Implicit cast to Slice.
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    operator const Slice() const noexcept { return get(); }
+
+  private:
+    std::unique_ptr<uint8_t[]> mData;
+    size_t mLen;
+};
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_MEMBLOCK_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Misc.h b/staticlibs/netd/libnetdutils/include/netdutils/Misc.h
new file mode 100644
index 0000000..d344f81
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Misc.h
@@ -0,0 +1,63 @@
+/*
+ * 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 NETUTILS_MISC_H
+#define NETUTILS_MISC_H
+
+#include <map>
+
+namespace android {
+namespace netdutils {
+
+// Lookup key in map, returing a default value if key is not found
+template <typename U, typename V>
+inline const V& findWithDefault(const std::map<U, V>& map, const U& key, const V& dflt) {
+    auto it = map.find(key);
+    return (it == map.end()) ? dflt : it->second;
+}
+
+// Movable, copiable, scoped lambda (or std::function) runner. Useful
+// for running arbitrary cleanup or logging code when exiting a scope.
+//
+// Compare to defer in golang.
+template <typename FnT>
+class Cleanup {
+  public:
+    Cleanup() = delete;
+    explicit Cleanup(FnT fn) : mFn(fn) {}
+    ~Cleanup() { if (!mReleased) mFn(); }
+
+    void release() { mReleased = true; }
+
+  private:
+    bool mReleased{false};
+    FnT mFn;
+};
+
+// Helper to make a new Cleanup. Avoids complex or impossible syntax
+// when wrapping lambdas.
+//
+// Usage:
+// auto cleanup = makeCleanup([](){ your_code_here; });
+template <typename FnT>
+Cleanup<FnT> makeCleanup(FnT fn) {
+    return Cleanup<FnT>(fn);
+}
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_MISC_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/MockSyscalls.h b/staticlibs/netd/libnetdutils/include/netdutils/MockSyscalls.h
new file mode 100644
index 0000000..f57b55c
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/MockSyscalls.h
@@ -0,0 +1,90 @@
+/*
+ * 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 NETUTILS_MOCK_SYSCALLS_H
+#define NETUTILS_MOCK_SYSCALLS_H
+
+#include <atomic>
+#include <cassert>
+#include <memory>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "netdutils/Syscalls.h"
+
+namespace android {
+namespace netdutils {
+
+class MockSyscalls : public Syscalls {
+  public:
+    virtual ~MockSyscalls() = default;
+    // Use Return(ByMove(...)) to deal with movable return types.
+    MOCK_CONST_METHOD3(open,
+                       StatusOr<UniqueFd>(const std::string& pathname, int flags, mode_t mode));
+    MOCK_CONST_METHOD3(socket, StatusOr<UniqueFd>(int domain, int type, int protocol));
+    MOCK_CONST_METHOD3(getsockname, Status(Fd sock, sockaddr* addr, socklen_t* addrlen));
+    MOCK_CONST_METHOD5(getsockopt, Status(Fd sock, int level, int optname, void* optval,
+                                          socklen_t *optlen));
+    MOCK_CONST_METHOD5(setsockopt, Status(Fd sock, int level, int optname, const void* optval,
+                                          socklen_t optlen));
+
+    MOCK_CONST_METHOD3(bind, Status(Fd sock, const sockaddr* addr, socklen_t addrlen));
+    MOCK_CONST_METHOD3(connect, Status(Fd sock, const sockaddr* addr, socklen_t addrlen));
+    MOCK_CONST_METHOD3(ioctl, StatusOr<ifreq>(Fd sock, unsigned long request, ifreq* ifr));
+
+    // Use Return(ByMove(...)) to deal with movable return types.
+    MOCK_CONST_METHOD2(eventfd, StatusOr<UniqueFd>(unsigned int initval, int flags));
+    MOCK_CONST_METHOD3(ppoll, StatusOr<int>(pollfd* fds, nfds_t nfds, double timeout));
+
+    MOCK_CONST_METHOD2(writev, StatusOr<size_t>(Fd fd, const std::vector<iovec>& iov));
+    MOCK_CONST_METHOD2(write, StatusOr<size_t>(Fd fd, const Slice buf));
+    MOCK_CONST_METHOD2(read, StatusOr<Slice>(Fd fd, const Slice buf));
+    MOCK_CONST_METHOD5(sendto, StatusOr<size_t>(Fd sock, const Slice buf, int flags,
+                                                const sockaddr* dst, socklen_t dstlen));
+    MOCK_CONST_METHOD5(recvfrom, StatusOr<Slice>(Fd sock, const Slice dst, int flags, sockaddr* src,
+                                                 socklen_t* srclen));
+    MOCK_CONST_METHOD2(shutdown, Status(Fd fd, int how));
+    MOCK_CONST_METHOD1(close, Status(Fd fd));
+
+    MOCK_CONST_METHOD2(fopen,
+                       StatusOr<UniqueFile>(const std::string& path, const std::string& mode));
+    MOCK_CONST_METHOD3(vfprintf, StatusOr<int>(FILE* file, const char* format, va_list ap));
+    MOCK_CONST_METHOD3(vfscanf, StatusOr<int>(FILE* file, const char* format, va_list ap));
+    MOCK_CONST_METHOD1(fclose, Status(FILE* file));
+    MOCK_CONST_METHOD0(fork, StatusOr<pid_t>());
+};
+
+// For the lifetime of this mock, replace the contents of sSyscalls
+// with a pointer to this mock. Behavior is undefined if multiple
+// ScopedMockSyscalls instances exist concurrently.
+class ScopedMockSyscalls : public MockSyscalls {
+  public:
+    ScopedMockSyscalls() : mOld(sSyscalls.swap(*this)) { assert((mRefcount++) == 1); }
+    virtual ~ScopedMockSyscalls() {
+        sSyscalls.swap(mOld);
+        assert((mRefcount--) == 0);
+    }
+
+  private:
+    std::atomic<int> mRefcount{0};
+    Syscalls& mOld;
+};
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_MOCK_SYSCALLS_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Netfilter.h b/staticlibs/netd/libnetdutils/include/netdutils/Netfilter.h
new file mode 100644
index 0000000..22736f1
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Netfilter.h
@@ -0,0 +1,28 @@
+/*
+ * 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 NETUTILS_NETFILTER_H
+#define NETUTILS_NETFILTER_H
+
+#include <ostream>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+
+std::ostream& operator<<(std::ostream& os, const nfgenmsg& msg);
+
+#endif /* NETUTILS_NETFILTER_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Netlink.h b/staticlibs/netd/libnetdutils/include/netdutils/Netlink.h
new file mode 100644
index 0000000..ee5183a
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Netlink.h
@@ -0,0 +1,55 @@
+/*
+ * 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 NETUTILS_NETLINK_H
+#define NETUTILS_NETLINK_H
+
+#include <functional>
+#include <ostream>
+#include <linux/netlink.h>
+
+#include "netdutils/Slice.h"
+
+namespace android {
+namespace netdutils {
+
+// Invoke onMsg once for each netlink message in buf. onMsg will be
+// invoked with an aligned and deserialized header along with a Slice
+// containing the message payload.
+//
+// Assume that the first message begins at offset zero within buf.
+void forEachNetlinkMessage(const Slice buf,
+                           const std::function<void(const nlmsghdr&, const Slice)>& onMsg);
+
+// Invoke onAttr once for each netlink attribute in buf. onAttr will be
+// invoked with an aligned and deserialized header along with a Slice
+// containing the attribute payload.
+//
+// Assume that the first attribute begins at offset zero within buf.
+void forEachNetlinkAttribute(const Slice buf,
+                             const std::function<void(const nlattr&, const Slice)>& onAttr);
+
+}  // namespace netdutils
+}  // namespace android
+
+bool operator==(const sockaddr_nl& lhs, const sockaddr_nl& rhs);
+bool operator!=(const sockaddr_nl& lhs, const sockaddr_nl& rhs);
+
+std::ostream& operator<<(std::ostream& os, const nlmsghdr& hdr);
+std::ostream& operator<<(std::ostream& os, const nlattr& attr);
+std::ostream& operator<<(std::ostream& os, const sockaddr_nl& addr);
+
+#endif /* NETUTILS_NETLINK_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/NetworkConstants.h b/staticlibs/netd/libnetdutils/include/netdutils/NetworkConstants.h
new file mode 100644
index 0000000..dead9a1
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/NetworkConstants.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+namespace android {
+namespace netdutils {
+
+// See also NetworkConstants.java in frameworks/base.
+constexpr int IPV4_ADDR_LEN = 4;
+constexpr int IPV4_ADDR_BITS = 32;
+constexpr int IPV6_ADDR_LEN = 16;
+constexpr int IPV6_ADDR_BITS = 128;
+
+// Referred from SHA256_DIGEST_LENGTH in boringssl
+constexpr size_t SHA256_SIZE = 32;
+
+}  // namespace netdutils
+}  // namespace android
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/ResponseCode.h b/staticlibs/netd/libnetdutils/include/netdutils/ResponseCode.h
new file mode 100644
index 0000000..c170684
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/ResponseCode.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 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 NETDUTILS_RESPONSECODE_H
+#define NETDUTILS_RESPONSECODE_H
+
+namespace android {
+namespace netdutils {
+
+class ResponseCode {
+    // Keep in sync with
+    // frameworks/base/services/java/com/android/server/NetworkManagementService.java
+  public:
+    // 100 series - Requestion action was initiated; expect another reply
+    // before proceeding with a new command.
+    // clang-format off
+    static constexpr int ActionInitiated                = 100;
+    static constexpr int InterfaceListResult            = 110;
+    static constexpr int TetherInterfaceListResult      = 111;
+    static constexpr int TetherDnsFwdTgtListResult      = 112;
+    static constexpr int TtyListResult                  = 113;
+    static constexpr int TetheringStatsListResult       = 114;
+    static constexpr int TetherDnsFwdNetIdResult        = 115;
+
+    // 200 series - Requested action has been successfully completed
+    static constexpr int CommandOkay                    = 200;
+    static constexpr int TetherStatusResult             = 210;
+    static constexpr int IpFwdStatusResult              = 211;
+    static constexpr int InterfaceGetCfgResult          = 213;
+    // Formerly: int SoftapStatusResult                 = 214;
+    static constexpr int UsbRNDISStatusResult           = 215;
+    static constexpr int InterfaceRxCounterResult       = 216;
+    static constexpr int InterfaceTxCounterResult       = 217;
+    static constexpr int InterfaceRxThrottleResult      = 218;
+    static constexpr int InterfaceTxThrottleResult      = 219;
+    static constexpr int QuotaCounterResult             = 220;
+    static constexpr int TetheringStatsResult           = 221;
+    // NOTE: keep synced with bionic/libc/dns/net/gethnamaddr.c
+    static constexpr int DnsProxyQueryResult            = 222;
+    static constexpr int ClatdStatusResult              = 223;
+
+    // 400 series - The command was accepted but the requested action
+    // did not take place.
+    static constexpr int OperationFailed                = 400;
+    static constexpr int DnsProxyOperationFailed        = 401;
+    static constexpr int ServiceStartFailed             = 402;
+    static constexpr int ServiceStopFailed              = 403;
+
+    // 500 series - The command was not accepted and the requested
+    // action did not take place.
+    static constexpr int CommandSyntaxError             = 500;
+    static constexpr int CommandParameterError          = 501;
+
+    // 600 series - Unsolicited broadcasts
+    static constexpr int InterfaceChange                = 600;
+    static constexpr int BandwidthControl               = 601;
+    static constexpr int ServiceDiscoveryFailed         = 602;
+    static constexpr int ServiceDiscoveryServiceAdded   = 603;
+    static constexpr int ServiceDiscoveryServiceRemoved = 604;
+    static constexpr int ServiceRegistrationFailed      = 605;
+    static constexpr int ServiceRegistrationSucceeded   = 606;
+    static constexpr int ServiceResolveFailed           = 607;
+    static constexpr int ServiceResolveSuccess          = 608;
+    static constexpr int ServiceSetHostnameFailed       = 609;
+    static constexpr int ServiceSetHostnameSuccess      = 610;
+    static constexpr int ServiceGetAddrInfoFailed       = 611;
+    static constexpr int ServiceGetAddrInfoSuccess      = 612;
+    static constexpr int InterfaceClassActivity         = 613;
+    static constexpr int InterfaceAddressChange         = 614;
+    static constexpr int InterfaceDnsInfo               = 615;
+    static constexpr int RouteChange                    = 616;
+    static constexpr int StrictCleartext                = 617;
+    // clang-format on
+};
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif  // NETDUTILS_RESPONSECODE_H
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Slice.h b/staticlibs/netd/libnetdutils/include/netdutils/Slice.h
new file mode 100644
index 0000000..717fbd1
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Slice.h
@@ -0,0 +1,161 @@
+/*
+ * 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 NETUTILS_SLICE_H
+#define NETUTILS_SLICE_H
+
+#include <algorithm>
+#include <array>
+#include <cstring>
+#include <ostream>
+#include <tuple>
+#include <vector>
+
+namespace android {
+namespace netdutils {
+
+// Immutable wrapper for a linear region of unowned bytes.
+// Slice represents memory as a half-closed interval [base, limit).
+//
+// Note that without manually invoking the Slice() constructor, it is
+// impossible to increase the size of a slice. This guarantees that
+// applications that properly use the slice API will never access
+// memory outside of a slice.
+//
+// Note that const Slice still wraps mutable memory, however copy
+// assignment and move assignment to slice are disabled.
+class Slice {
+  public:
+    Slice() = default;
+
+    // Create a slice beginning at base and continuing to but not including limit
+    Slice(void* base, void* limit) : mBase(toUint8(base)), mLimit(toUint8(limit)) {}
+
+    // Create a slice beginning at base and continuing for size bytes
+    Slice(void* base, size_t size) : Slice(base, toUint8(base) + size) {}
+
+    // Return the address of the first byte in this slice
+    uint8_t* base() const { return mBase; }
+
+    // Return the address of the first byte following this slice
+    uint8_t* limit() const { return mLimit; }
+
+    // Return the size of this slice in bytes
+    size_t size() const { return limit() - base(); }
+
+    // Return true if size() == 0
+    bool empty() const { return base() == limit(); }
+
+  private:
+    static uint8_t* toUint8(void* ptr) { return reinterpret_cast<uint8_t*>(ptr); }
+
+    uint8_t* mBase = nullptr;
+    uint8_t* mLimit = nullptr;
+};
+
+// Return slice representation of ref which must be a POD type
+template <typename T>
+inline const Slice makeSlice(const T& ref) {
+    static_assert(std::is_pod<T>::value, "value must be a POD type");
+    static_assert(!std::is_pointer<T>::value, "value must not be a pointer type");
+    return {const_cast<T*>(&ref), sizeof(ref)};
+}
+
+// Return slice representation of string data()
+inline const Slice makeSlice(const std::string& s) {
+    using ValueT = std::string::value_type;
+    return {const_cast<ValueT*>(s.data()), s.size() * sizeof(ValueT)};
+}
+
+// Return slice representation of vector data()
+template <typename T>
+inline const Slice makeSlice(const std::vector<T>& v) {
+    return {const_cast<T*>(v.data()), v.size() * sizeof(T)};
+}
+
+// Return slice representation of array data()
+template <typename U, size_t V>
+inline const Slice makeSlice(const std::array<U, V>& a) {
+    return {const_cast<U*>(a.data()), a.size() * sizeof(U)};
+}
+
+// Return prefix and suffix of Slice s ending and starting at position cut
+inline std::pair<const Slice, const Slice> split(const Slice s, size_t cut) {
+    const size_t tmp = std::min(cut, s.size());
+    return {{s.base(), s.base() + tmp}, {s.base() + tmp, s.limit()}};
+}
+
+// Return prefix of Slice s ending at position cut
+inline const Slice take(const Slice s, size_t cut) {
+    return std::get<0>(split(s, cut));
+}
+
+// Return suffix of Slice s starting at position cut
+inline const Slice drop(const Slice s, size_t cut) {
+    return std::get<1>(split(s, cut));
+}
+
+// Copy from src into dst. Bytes copied is the lesser of dst.size() and src.size()
+inline size_t copy(const Slice dst, const Slice src) {
+    const auto min = std::min(dst.size(), src.size());
+    memcpy(dst.base(), src.base(), min);
+    return min;
+}
+
+// Base case for variadic extract below
+template <typename Head>
+inline size_t extract(const Slice src, Head& head) {
+    return copy(makeSlice(head), src);
+}
+
+// Copy from src into one or more pointers to POD data.  If src.size()
+// is less than the sum of all data pointers a suffix of data will be
+// left unmodified. Return the number of bytes copied.
+template <typename Head, typename... Tail>
+inline size_t extract(const Slice src, Head& head, Tail&... tail) {
+    const auto extracted = extract(src, head);
+    return extracted + extract(drop(src, extracted), tail...);
+}
+
+// Return a string containing a copy of the contents of s
+std::string toString(const Slice s);
+
+// Return a string containing a hexadecimal representation of the contents of s.
+// This function inserts a newline into its output every wrap bytes.
+std::string toHex(const Slice s, int wrap = INT_MAX);
+
+inline bool operator==(const Slice& lhs, const Slice& rhs) {
+    return (lhs.base() == rhs.base()) && (lhs.limit() == rhs.limit());
+}
+
+inline bool operator!=(const Slice& lhs, const Slice& rhs) {
+    return !(lhs == rhs);
+}
+
+std::ostream& operator<<(std::ostream& os, const Slice& slice);
+
+// Return suffix of Slice s starting at the first match of byte c. If no matched
+// byte, return an empty Slice.
+inline const Slice findFirstMatching(const Slice s, uint8_t c) {
+    uint8_t* match = (uint8_t*)memchr(s.base(), c, s.size());
+    if (!match) return Slice();
+    return drop(s, match - s.base());
+}
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_SLICE_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Socket.h b/staticlibs/netd/libnetdutils/include/netdutils/Socket.h
new file mode 100644
index 0000000..e5aaab9
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Socket.h
@@ -0,0 +1,44 @@
+/*
+ * 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 NETDUTILS_SOCKET_H
+#define NETDUTILS_SOCKET_H
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <string>
+
+#include "netdutils/StatusOr.h"
+
+namespace android {
+namespace netdutils {
+
+inline sockaddr* asSockaddrPtr(void* addr) {
+    return reinterpret_cast<sockaddr*>(addr);
+}
+
+inline const sockaddr* asSockaddrPtr(const void* addr) {
+    return reinterpret_cast<const sockaddr*>(addr);
+}
+
+// Return a string representation of addr or Status if there was a
+// failure during conversion.
+StatusOr<std::string> toString(const in6_addr& addr);
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETDUTILS_SOCKET_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/SocketOption.h b/staticlibs/netd/libnetdutils/include/netdutils/SocketOption.h
new file mode 100644
index 0000000..3b0aab7
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/SocketOption.h
@@ -0,0 +1,60 @@
+/*
+ * 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 NETDUTILS_SOCKETOPTION_H
+#define NETDUTILS_SOCKETOPTION_H
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <string>
+
+#include "netdutils/Fd.h"
+#include "netdutils/Status.h"
+
+namespace android {
+namespace netdutils {
+
+// Turn on simple "boolean" socket options.
+//
+// This is simple wrapper for options that are enabled via code of the form:
+//
+//     int on = 1;
+//     setsockopt(..., &on, sizeof(on));
+Status enableSockopt(Fd sock, int level, int optname);
+
+// Turn on TCP keepalives, and set keepalive parameters for this socket.
+//
+// A parameter value of zero does not set that parameter.
+//
+// Typical system defaults are:
+//
+//     idleTime (in seconds)
+//     $ cat /proc/sys/net/ipv4/tcp_keepalive_time
+//     7200
+//
+//     numProbes
+//     $ cat /proc/sys/net/ipv4/tcp_keepalive_probes
+//     9
+//
+//     probeInterval (in seconds)
+//     $ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
+//     75
+Status enableTcpKeepAlives(Fd sock, unsigned idleTime, unsigned numProbes, unsigned probeInterval);
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETDUTILS_SOCKETOPTION_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Status.h b/staticlibs/netd/libnetdutils/include/netdutils/Status.h
new file mode 100644
index 0000000..bc347d5
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Status.h
@@ -0,0 +1,136 @@
+/*
+ * 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 NETUTILS_STATUS_H
+#define NETUTILS_STATUS_H
+
+#include <cassert>
+#include <limits>
+#include <ostream>
+
+#include <android-base/result.h>
+
+namespace android {
+namespace netdutils {
+
+// Simple status implementation suitable for use on the stack in low
+// or moderate performance code. This can definitely be improved but
+// for now short string optimization is expected to keep the common
+// success case fast.
+//
+// Status is implicitly movable via the default noexcept move constructor
+// and noexcept move-assignment operator.
+class [[nodiscard]] Status {
+  public:
+    Status() = default;
+    explicit Status(int code) : mCode(code) {}
+
+    // Constructs an error Status, |code| must be non-zero.
+    Status(int code, std::string msg) : mCode(code), mMsg(std::move(msg)) { assert(!ok()); }
+
+    Status(android::base::Result<void> result)
+        : mCode(result.ok() ? 0 : result.error().code()),
+          mMsg(result.ok() ? "" : result.error().message()) {}
+
+    int code() const { return mCode; }
+
+    bool ok() const { return code() == 0; }
+
+    const std::string& msg() const { return mMsg; }
+
+    // Explicitly ignores the Status without triggering [[nodiscard]] errors.
+    void ignoreError() const {}
+
+    bool operator==(const Status& other) const { return code() == other.code(); }
+    bool operator!=(const Status& other) const { return !(*this == other); }
+
+  private:
+    int mCode = 0;
+    std::string mMsg;
+};
+
+namespace status {
+
+const Status ok{0};
+// EOF is not part of errno space, we'll place it far above the
+// highest existing value.
+const Status eof{0x10001, "end of file"};
+const Status undefined{std::numeric_limits<int>::max(), "undefined"};
+
+}  // namespace status
+
+// Return true if status is "OK". This is sometimes preferable to
+// status.ok() when we want to check the state of Status-like objects
+// that implicitly cast to Status.
+inline bool isOk(const Status& status) {
+    return status.ok();
+}
+
+// For use only in tests. Used for both Status and Status-like objects. See also isOk().
+#define EXPECT_OK(status) EXPECT_TRUE(isOk(status))
+#define ASSERT_OK(status) ASSERT_TRUE(isOk(status))
+
+// Documents that status is expected to be ok. This function may log
+// (or assert when running in debug mode) if status has an unexpected value.
+inline void expectOk(const Status& /*status*/) {
+    // TODO: put something here, for now this function serves solely as documentation.
+}
+
+// Convert POSIX errno to a Status object.
+// If Status is extended to have more features, this mapping may
+// become more complex.
+Status statusFromErrno(int err, const std::string& msg);
+
+// Helper that checks Status-like object (notably StatusOr) against a
+// value in the errno space.
+bool equalToErrno(const Status& status, int err);
+
+// Helper that converts Status-like object (notably StatusOr) to a
+// message.
+std::string toString(const Status& status);
+
+std::ostream& operator<<(std::ostream& os, const Status& s);
+
+// Evaluate 'stmt' to a Status object and if it results in an error, return that
+// error.  Use 'tmp' as a variable name to avoid shadowing any variables named
+// tmp.
+#define RETURN_IF_NOT_OK_IMPL(tmp, stmt)           \
+    do {                                           \
+        ::android::netdutils::Status tmp = (stmt); \
+        if (!isOk(tmp)) {                          \
+            return tmp;                            \
+        }                                          \
+    } while (false)
+
+// Create a unique variable name to avoid shadowing local variables.
+#define RETURN_IF_NOT_OK_CONCAT(line, stmt) RETURN_IF_NOT_OK_IMPL(__CONCAT(_status_, line), stmt)
+
+// Macro to allow exception-like handling of error return values.
+//
+// If the evaluation of stmt results in an error, return that error
+// from current function.
+//
+// Example usage:
+// Status bar() { ... }
+//
+// RETURN_IF_NOT_OK(status);
+// RETURN_IF_NOT_OK(bar());
+#define RETURN_IF_NOT_OK(stmt) RETURN_IF_NOT_OK_CONCAT(__LINE__, stmt)
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_STATUS_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/StatusOr.h b/staticlibs/netd/libnetdutils/include/netdutils/StatusOr.h
new file mode 100644
index 0000000..c7aa4e4
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/StatusOr.h
@@ -0,0 +1,119 @@
+/*
+ * 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 NETUTILS_STATUSOR_H
+#define NETUTILS_STATUSOR_H
+
+#include <cassert>
+#include "netdutils/Status.h"
+
+namespace android {
+namespace netdutils {
+
+// Wrapper around a combination of Status and application value type.
+// T may be any copyable or movable type.
+template <typename T>
+class [[nodiscard]] StatusOr {
+  public:
+    // Constructs a new StatusOr with status::undefined status.
+    // This is marked 'explicit' to try to catch cases like 'return {};',
+    // where people think StatusOr<std::vector<int>> will be initialized
+    // with an empty vector, instead of a status::undefined.
+    explicit StatusOr() = default;
+
+    // Implicit copy constructor and construction from T.
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    StatusOr(Status status) : mStatus(std::move(status)) { assert(!isOk(mStatus)); }
+
+    // Implicit construction from T. It is convenient and sensible to be able
+    // to do 'return T()' when the return type is StatusOr<T>.
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    StatusOr(const T& value) : mStatus(status::ok), mValue(value) {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    StatusOr(T&& value) : mStatus(status::ok), mValue(std::move(value)) {}
+
+    // Move constructor ok (if T supports move)
+    StatusOr(StatusOr&&) noexcept = default;
+    // Move assignment ok (if T supports move)
+    StatusOr& operator=(StatusOr&&) noexcept = default;
+    // Copy constructor ok (if T supports copy)
+    StatusOr(const StatusOr&) = default;
+    // Copy assignment ok (if T supports copy)
+    StatusOr& operator=(const StatusOr&) = default;
+
+    // Returns a const reference to wrapped type.
+    // It is an error to call value() when !isOk(status())
+    const T& value() const & { return mValue; }
+    const T&& value() const && { return mValue; }
+
+    // Returns an rvalue reference to wrapped type
+    // It is an error to call value() when !isOk(status())
+    //
+    // If T is expensive to copy but supports efficient move, it can be moved
+    // out of a StatusOr as follows:
+    //   T value = std::move(statusor).value();
+    T& value() & { return mValue; }
+    T&& value() && { return mValue; }
+
+    // Returns the Status object assigned at construction time.
+    const Status status() const { return mStatus; }
+
+    // Explicitly ignores the Status without triggering [[nodiscard]] errors.
+    void ignoreError() const {}
+
+    // Implicit cast to Status.
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    operator Status() const { return status(); }
+
+  private:
+    Status mStatus = status::undefined;
+    T mValue;
+};
+
+template <typename T>
+inline std::ostream& operator<<(std::ostream& os, const StatusOr<T>& s) {
+    return os << "StatusOr[status: " << s.status() << "]";
+}
+
+#define ASSIGN_OR_RETURN_IMPL(tmp, lhs, stmt) \
+    auto tmp = (stmt);                        \
+    RETURN_IF_NOT_OK(tmp);                    \
+    lhs = std::move(tmp.value());
+
+#define ASSIGN_OR_RETURN_CONCAT(line, lhs, stmt) \
+    ASSIGN_OR_RETURN_IMPL(__CONCAT(_status_or_, line), lhs, stmt)
+
+// Macro to allow exception-like handling of error return values.
+//
+// If the evaluation of stmt results in an error, return that error
+// from the current function. Otherwise, assign the result to lhs.
+//
+// This macro supports both move and copy assignment operators. lhs
+// may be either a new local variable or an existing non-const
+// variable accessible in the current scope.
+//
+// Example usage:
+// StatusOr<MyType> foo() { ... }
+//
+// ASSIGN_OR_RETURN(auto myVar, foo());
+// ASSIGN_OR_RETURN(myExistingVar, foo());
+// ASSIGN_OR_RETURN(myMemberVar, foo());
+#define ASSIGN_OR_RETURN(lhs, stmt) ASSIGN_OR_RETURN_CONCAT(__LINE__, lhs, stmt)
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_STATUSOR_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Stopwatch.h b/staticlibs/netd/libnetdutils/include/netdutils/Stopwatch.h
new file mode 100644
index 0000000..e7b4326
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Stopwatch.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NETDUTILS_STOPWATCH_H
+#define NETDUTILS_STOPWATCH_H
+
+#include <chrono>
+
+namespace android {
+namespace netdutils {
+
+class Stopwatch {
+  private:
+    using clock = std::chrono::steady_clock;
+    using time_point = std::chrono::time_point<clock>;
+
+  public:
+    Stopwatch() : mStart(clock::now()) {}
+    virtual ~Stopwatch() = default;
+
+    int64_t timeTakenUs() const { return getElapsedUs(clock::now()); }
+    int64_t getTimeAndResetUs() {
+        const auto& now = clock::now();
+        int64_t elapsed = getElapsedUs(now);
+        mStart = now;
+        return elapsed;
+    }
+
+  private:
+    time_point mStart;
+
+    int64_t getElapsedUs(const time_point& now) const {
+        return (std::chrono::duration_cast<std::chrono::microseconds>(now - mStart)).count();
+    }
+};
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif  // NETDUTILS_STOPWATCH_H
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/Syscalls.h b/staticlibs/netd/libnetdutils/include/netdutils/Syscalls.h
new file mode 100644
index 0000000..36fcd85
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/Syscalls.h
@@ -0,0 +1,204 @@
+/*
+ * 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 NETDUTILS_SYSCALLS_H
+#define NETDUTILS_SYSCALLS_H
+
+#include <memory>
+
+#include <net/if.h>
+#include <poll.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+#include "netdutils/Fd.h"
+#include "netdutils/Slice.h"
+#include "netdutils/Socket.h"
+#include "netdutils/Status.h"
+#include "netdutils/StatusOr.h"
+#include "netdutils/UniqueFd.h"
+#include "netdutils/UniqueFile.h"
+
+namespace android {
+namespace netdutils {
+
+class Syscalls {
+  public:
+    virtual ~Syscalls() = default;
+
+    virtual StatusOr<UniqueFd> open(const std::string& pathname, int flags,
+                                    mode_t mode = 0) const = 0;
+
+    virtual StatusOr<UniqueFd> socket(int domain, int type, int protocol) const = 0;
+
+    virtual Status getsockname(Fd sock, sockaddr* addr, socklen_t* addrlen) const = 0;
+
+    virtual Status getsockopt(Fd sock, int level, int optname, void *optval,
+                              socklen_t *optlen) const = 0;
+
+    virtual Status setsockopt(Fd sock, int level, int optname, const void* optval,
+                              socklen_t optlen) const = 0;
+
+    virtual Status bind(Fd sock, const sockaddr* addr, socklen_t addrlen) const = 0;
+
+    virtual Status connect(Fd sock, const sockaddr* addr, socklen_t addrlen) const = 0;
+
+    virtual StatusOr<ifreq> ioctl(Fd sock, unsigned long request, ifreq* ifr) const = 0;
+
+    virtual StatusOr<UniqueFd> eventfd(unsigned int initval, int flags) const = 0;
+
+    virtual StatusOr<int> ppoll(pollfd* fds, nfds_t nfds, double timeout) const = 0;
+
+    virtual StatusOr<size_t> writev(Fd fd, const std::vector<iovec>& iov) const = 0;
+
+    virtual StatusOr<size_t> write(Fd fd, const Slice buf) const = 0;
+
+    virtual StatusOr<Slice> read(Fd fd, const Slice buf) const = 0;
+
+    virtual StatusOr<size_t> sendto(Fd sock, const Slice buf, int flags, const sockaddr* dst,
+                                    socklen_t dstlen) const = 0;
+
+    virtual StatusOr<Slice> recvfrom(Fd sock, const Slice dst, int flags, sockaddr* src,
+                                     socklen_t* srclen) const = 0;
+
+    virtual Status shutdown(Fd fd, int how) const = 0;
+
+    virtual Status close(Fd fd) const = 0;
+
+    virtual StatusOr<UniqueFile> fopen(const std::string& path, const std::string& mode) const = 0;
+
+    virtual StatusOr<int> vfprintf(FILE* file, const char* format, va_list ap) const = 0;
+
+    virtual StatusOr<int> vfscanf(FILE* file, const char* format, va_list ap) const = 0;
+
+    virtual Status fclose(FILE* file) const = 0;
+
+    virtual StatusOr<pid_t> fork() const = 0;
+
+    // va_args helpers
+    // va_start doesn't work when the preceding argument is a reference
+    // type so we're forced to use const char*.
+    StatusOr<int> fprintf(FILE* file, const char* format, ...) const {
+        va_list ap;
+        va_start(ap, format);
+        auto result = vfprintf(file, format, ap);
+        va_end(ap);
+        return result;
+    }
+
+    // va_start doesn't work when the preceding argument is a reference
+    // type so we're forced to use const char*.
+    StatusOr<int> fscanf(FILE* file, const char* format, ...) const {
+        va_list ap;
+        va_start(ap, format);
+        auto result = vfscanf(file, format, ap);
+        va_end(ap);
+        return result;
+    }
+
+    // Templated helpers that forward directly to methods declared above
+    template <typename SockaddrT>
+    StatusOr<SockaddrT> getsockname(Fd sock) const {
+        SockaddrT addr = {};
+        socklen_t addrlen = sizeof(addr);
+        RETURN_IF_NOT_OK(getsockname(sock, asSockaddrPtr(&addr), &addrlen));
+        return addr;
+    }
+
+    template <typename SockoptT>
+    Status getsockopt(Fd sock, int level, int optname, void* optval, socklen_t* optlen) const {
+        return getsockopt(sock, level, optname, optval, optlen);
+    }
+
+    template <typename SockoptT>
+    Status setsockopt(Fd sock, int level, int optname, const SockoptT& opt) const {
+        return setsockopt(sock, level, optname, &opt, sizeof(opt));
+    }
+
+    template <typename SockaddrT>
+    Status bind(Fd sock, const SockaddrT& addr) const {
+        return bind(sock, asSockaddrPtr(&addr), sizeof(addr));
+    }
+
+    template <typename SockaddrT>
+    Status connect(Fd sock, const SockaddrT& addr) const {
+        return connect(sock, asSockaddrPtr(&addr), sizeof(addr));
+    }
+
+    template <size_t size>
+    StatusOr<std::array<uint16_t, size>> ppoll(const std::array<Fd, size>& fds, uint16_t events,
+                                               double timeout) const {
+        std::array<pollfd, size> tmp;
+        for (size_t i = 0; i < size; ++i) {
+            tmp[i].fd = fds[i].get();
+            tmp[i].events = events;
+            tmp[i].revents = 0;
+        }
+        RETURN_IF_NOT_OK(ppoll(tmp.data(), tmp.size(), timeout).status());
+        std::array<uint16_t, size> out;
+        for (size_t i = 0; i < size; ++i) {
+            out[i] = tmp[i].revents;
+        }
+        return out;
+    }
+
+    template <typename SockaddrT>
+    StatusOr<size_t> sendto(Fd sock, const Slice buf, int flags, const SockaddrT& dst) const {
+        return sendto(sock, buf, flags, asSockaddrPtr(&dst), sizeof(dst));
+    }
+
+    // Ignore src sockaddr
+    StatusOr<Slice> recvfrom(Fd sock, const Slice dst, int flags) const {
+        return recvfrom(sock, dst, flags, nullptr, nullptr);
+    }
+
+    template <typename SockaddrT>
+    StatusOr<std::pair<Slice, SockaddrT>> recvfrom(Fd sock, const Slice dst, int flags) const {
+        SockaddrT addr = {};
+        socklen_t addrlen = sizeof(addr);
+        ASSIGN_OR_RETURN(auto used, recvfrom(sock, dst, flags, asSockaddrPtr(&addr), &addrlen));
+        return std::make_pair(used, addr);
+    }
+};
+
+// Specialized singleton that supports zero initialization and runtime
+// override of contained pointer.
+class SyscallsHolder {
+  public:
+    ~SyscallsHolder();
+
+    // Return a pointer to an unowned instance of Syscalls.
+    Syscalls& get();
+
+    // Testing only: set the value returned by getSyscalls. Return the old value.
+    // Callers are responsible for restoring the previous value returned
+    // by getSyscalls to avoid leaks.
+    Syscalls& swap(Syscalls& syscalls);
+
+  private:
+    std::atomic<Syscalls*> mSyscalls{nullptr};
+};
+
+// Syscalls instance used throughout netdutils
+extern SyscallsHolder sSyscalls;
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETDUTILS_SYSCALLS_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/ThreadUtil.h b/staticlibs/netd/libnetdutils/include/netdutils/ThreadUtil.h
new file mode 100644
index 0000000..62e6f70
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/ThreadUtil.h
@@ -0,0 +1,83 @@
+/*
+ * 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 NETDUTILS_THREADUTIL_H
+#define NETDUTILS_THREADUTIL_H
+
+#include <pthread.h>
+#include <memory>
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace netdutils {
+
+struct scoped_pthread_attr {
+    scoped_pthread_attr() { pthread_attr_init(&attr); }
+    ~scoped_pthread_attr() { pthread_attr_destroy(&attr); }
+
+    int detach() { return -pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); }
+
+    pthread_attr_t attr;
+};
+
+inline void setThreadName(std::string name) {
+    // MAX_TASK_COMM_LEN=16 is not exported by bionic.
+    const size_t MAX_TASK_COMM_LEN = 16;
+
+    // Crop name to 16 bytes including the NUL byte, as required by pthread_setname_np()
+    if (name.size() >= MAX_TASK_COMM_LEN) name.resize(MAX_TASK_COMM_LEN - 1);
+
+    if (int ret = pthread_setname_np(pthread_self(), name.c_str()); ret != 0) {
+        LOG(WARNING) << "Unable to set thread name to " << name << ": " << strerror(ret);
+    }
+}
+
+template <typename T>
+inline void* runAndDelete(void* obj) {
+    std::unique_ptr<T> handler(reinterpret_cast<T*>(obj));
+    setThreadName(handler->threadName().c_str());
+    handler->run();
+    return nullptr;
+}
+
+template <typename T>
+inline int threadLaunch(T* obj) {
+    if (obj == nullptr) {
+        return -EINVAL;
+    }
+
+    scoped_pthread_attr scoped_attr;
+
+    int rval = scoped_attr.detach();
+    if (rval != 0) {
+        return rval;
+    }
+
+    pthread_t thread;
+    rval = pthread_create(&thread, &scoped_attr.attr, &runAndDelete<T>, obj);
+    if (rval != 0) {
+        LOG(WARNING) << __func__ << ": pthread_create failed: " << rval;
+        return -rval;
+    }
+
+    return rval;
+}
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif  // NETDUTILS_THREADUTIL_H
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/UidConstants.h b/staticlibs/netd/libnetdutils/include/netdutils/UidConstants.h
new file mode 100644
index 0000000..42c1090
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/UidConstants.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NETDUTILS_UID_CONSTANTS_H
+#define NETDUTILS_UID_CONSTANTS_H
+
+// These are used by both eBPF kernel programs and netd, we cannot put them in NetdConstant.h since
+// we have to minimize the number of headers included by the BPF kernel program.
+#define MIN_SYSTEM_UID 0
+#define MAX_SYSTEM_UID 9999
+
+#define PER_USER_RANGE 100000
+
+#endif  // NETDUTILS_UID_CONSTANTS_H
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/UniqueFd.h b/staticlibs/netd/libnetdutils/include/netdutils/UniqueFd.h
new file mode 100644
index 0000000..61101f9
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/UniqueFd.h
@@ -0,0 +1,71 @@
+/*
+ * 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 NETUTILS_UNIQUEFD_H
+#define NETUTILS_UNIQUEFD_H
+
+#include <unistd.h>
+#include <ostream>
+
+#include "netdutils/Fd.h"
+
+namespace android {
+namespace netdutils {
+
+// Stricter unique_fd implementation that:
+// *) Does not implement release()
+// *) Does not implicitly cast to int
+// *) Uses a strongly typed wrapper (Fd) for the underlying file descriptor
+//
+// Users of UniqueFd should endeavor to treat this as a completely
+// opaque object. The only code that should interpret the wrapped
+// value is in Syscalls.h
+class UniqueFd {
+  public:
+    UniqueFd() = default;
+
+    UniqueFd(Fd fd) : mFd(fd) {}
+
+    ~UniqueFd() { reset(); }
+
+    // Disallow copy
+    UniqueFd(const UniqueFd&) = delete;
+    UniqueFd& operator=(const UniqueFd&) = delete;
+
+    // Allow move
+    UniqueFd(UniqueFd&& other) { std::swap(mFd, other.mFd); }
+    UniqueFd& operator=(UniqueFd&& other) {
+        std::swap(mFd, other.mFd);
+        return *this;
+    }
+
+    // Cleanup any currently owned Fd, replacing it with the optional
+    // parameter fd
+    void reset(Fd fd = Fd());
+
+    // Implict cast to Fd
+    operator const Fd &() const { return mFd; }
+
+  private:
+    Fd mFd;
+};
+
+std::ostream& operator<<(std::ostream& os, const UniqueFd& fd);
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETUTILS_UNIQUEFD_H */
diff --git a/staticlibs/netd/libnetdutils/include/netdutils/UniqueFile.h b/staticlibs/netd/libnetdutils/include/netdutils/UniqueFile.h
new file mode 100644
index 0000000..6dd6d67
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/include/netdutils/UniqueFile.h
@@ -0,0 +1,35 @@
+/*
+ * 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 NETDUTILS_UNIQUEFILE_H
+#define NETDUTILS_UNIQUEFILE_H
+
+#include <stdio.h>
+#include <memory>
+
+namespace android {
+namespace netdutils {
+
+struct UniqueFileDtor {
+    void operator()(FILE* file) const;
+};
+
+using UniqueFile = std::unique_ptr<FILE, UniqueFileDtor>;
+
+}  // namespace netdutils
+}  // namespace android
+
+#endif /* NETDUTILS_UNIQUEFILE_H */