/*
 * Copyright 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.
 *
 * binder_test.cpp - unit tests for netd binder RPCs.
 */

#include <cerrno>
#include <chrono>
#include <cinttypes>
#include <condition_variable>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <mutex>
#include <regex>
#include <set>
#include <string>
#include <thread>
#include <vector>

#include <dirent.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <openssl/base64.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <android-base/file.h>
#include <android-base/format.h>
#include <android-base/macros.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android/multinetwork.h>
#include <binder/IPCThreadState.h>
#include <bpf/BpfMap.h>
#include <bpf/BpfUtils.h>
#include <com/android/internal/net/BnOemNetdUnsolicitedEventListener.h>
#include <com/android/internal/net/IOemNetd.h>
#include <cutils/multiuser.h>
#include <gtest/gtest.h>
#include <netdbpf/bpf_shared.h>
#include <netutils/ifc.h>
#include <utils/Errors.h>
#include "Fwmark.h"
#include "InterfaceController.h"
#include "NetdClient.h"
#include "NetdConstants.h"
#include "NetworkController.h"
#include "RouteController.h"
#include "SockDiag.h"
#include "TestUnsolService.h"
#include "XfrmController.h"
#include "android/net/INetd.h"
#include "binder/IServiceManager.h"
#include "netdutils/InternetAddresses.h"
#include "netdutils/Stopwatch.h"
#include "netdutils/Syscalls.h"
#include "netid_client.h"  // NETID_UNSET
#include "test_utils.h"
#include "tun_interface.h"

#define IP6TABLES_PATH "/system/bin/ip6tables"
#define IPTABLES_PATH "/system/bin/iptables"
#define RAW_TABLE "raw"
#define MANGLE_TABLE "mangle"
#define FILTER_TABLE "filter"
#define NAT_TABLE "nat"

namespace binder = android::binder;

using android::IBinder;
using android::IServiceManager;
using android::sp;
using android::String16;
using android::String8;
using android::base::Join;
using android::base::make_scope_guard;
using android::base::ReadFdToString;
using android::base::ReadFileToString;
using android::base::StartsWith;
using android::base::StringPrintf;
using android::base::Trim;
using android::base::unique_fd;
using android::net::INetd;
using android::net::InterfaceConfigurationParcel;
using android::net::InterfaceController;
using android::net::MarkMaskParcel;
using android::net::NativeNetworkConfig;
using android::net::NativeNetworkType;
using android::net::NativeVpnType;
using android::net::RULE_PRIORITY_BYPASSABLE_VPN;
using android::net::RULE_PRIORITY_DEFAULT_NETWORK;
using android::net::RULE_PRIORITY_EXPLICIT_NETWORK;
using android::net::RULE_PRIORITY_OUTPUT_INTERFACE;
using android::net::RULE_PRIORITY_PROHIBIT_NON_VPN;
using android::net::RULE_PRIORITY_SECURE_VPN;
using android::net::RULE_PRIORITY_TETHERING;
using android::net::RULE_PRIORITY_UID_DEFAULT_NETWORK;
using android::net::RULE_PRIORITY_UID_DEFAULT_UNREACHABLE;
using android::net::RULE_PRIORITY_UID_EXPLICIT_NETWORK;
using android::net::RULE_PRIORITY_UID_IMPLICIT_NETWORK;
using android::net::RULE_PRIORITY_VPN_FALLTHROUGH;
using android::net::SockDiag;
using android::net::TetherOffloadRuleParcel;
using android::net::TetherStatsParcel;
using android::net::TunInterface;
using android::net::UidRangeParcel;
using android::net::UidRanges;
using android::net::netd::aidl::NativeUidRangeConfig;
using android::netdutils::IPAddress;
using android::netdutils::ScopedAddrinfo;
using android::netdutils::sSyscalls;
using android::netdutils::Stopwatch;

static const char* IP_RULE_V4 = "-4";
static const char* IP_RULE_V6 = "-6";
static const int TEST_NETID1 = 65501;
static const int TEST_NETID2 = 65502;
static const int TEST_NETID3 = 65503;
static const int TEST_NETID4 = 65504;
static const int TEST_DUMP_NETID = 65123;
static const char* DNSMASQ = "dnsmasq";

// Use maximum reserved appId for applications to avoid conflict with existing
// uids.
static const int TEST_UID1 = 99999;
static const int TEST_UID2 = 99998;
static const int TEST_UID3 = 99997;
static const int TEST_UID4 = 99996;
static const int TEST_UID5 = 99995;
static const int TEST_UID6 = 99994;

constexpr int BASE_UID = AID_USER_OFFSET * 5;

static const std::string NO_SOCKET_ALLOW_RULE("! owner UID match 0-4294967294");
static const std::string ESP_ALLOW_RULE("esp");

static const in6_addr V6_ADDR = {
        {// 2001:db8:cafe::8888
         .u6_addr8 = {0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0, 0, 0, 0, 0, 0, 0, 0, 0x88, 0x88}}};

class NetdBinderTest : public ::testing::Test {
  public:
    NetdBinderTest() {
        sp<IServiceManager> sm = android::defaultServiceManager();
        sp<IBinder> binder = sm->getService(String16("netd"));
        if (binder != nullptr) {
            mNetd = android::interface_cast<INetd>(binder);
        }
    }

    void SetUp() override {
        ASSERT_NE(nullptr, mNetd.get());
    }

    void TearDown() override {
        mNetd->networkDestroy(TEST_NETID1);
        mNetd->networkDestroy(TEST_NETID2);
        mNetd->networkDestroy(TEST_NETID3);
        mNetd->networkDestroy(TEST_NETID4);
        setNetworkForProcess(NETID_UNSET);
        // Restore default network
        if (mStoredDefaultNetwork >= 0) mNetd->networkSetDefault(mStoredDefaultNetwork);
    }

    bool allocateIpSecResources(bool expectOk, int32_t* spi);

    // Static because setting up the tun interface takes about 40ms.
    static void SetUpTestCase() {
        ASSERT_EQ(0, sTun.init());
        ASSERT_EQ(0, sTun2.init());
        ASSERT_EQ(0, sTun3.init());
        ASSERT_EQ(0, sTun4.init());
        ASSERT_LE(sTun.name().size(), static_cast<size_t>(IFNAMSIZ));
        ASSERT_LE(sTun2.name().size(), static_cast<size_t>(IFNAMSIZ));
        ASSERT_LE(sTun3.name().size(), static_cast<size_t>(IFNAMSIZ));
        ASSERT_LE(sTun4.name().size(), static_cast<size_t>(IFNAMSIZ));
    }

    static void TearDownTestCase() {
        // Closing the socket removes the interface and IP addresses.
        sTun.destroy();
        sTun2.destroy();
        sTun3.destroy();
        sTun4.destroy();
    }

    static void fakeRemoteSocketPair(unique_fd* clientSocket, unique_fd* serverSocket,
                                     unique_fd* acceptedSocket);

    void createVpnNetworkWithUid(bool secure, uid_t uid, int vpnNetId = TEST_NETID2,
                                 int fallthroughNetId = TEST_NETID1);

    void createAndSetDefaultNetwork(int netId, const std::string& interface,
                                    int permission = INetd::PERMISSION_NONE);

    void createPhysicalNetwork(int netId, const std::string& interface,
                               int permission = INetd::PERMISSION_NONE);

    void createDefaultAndOtherPhysicalNetwork(int defaultNetId, int otherNetId);

    void createVpnAndOtherPhysicalNetwork(int systemDefaultNetId, int otherNetId, int vpnNetId,
                                          bool secure);

    void createVpnAndAppDefaultNetworkWithUid(int systemDefaultNetId, int appDefaultNetId,
                                              int vpnNetId, bool secure,
                                              std::vector<UidRangeParcel>&& appDefaultUidRanges,
                                              std::vector<UidRangeParcel>&& vpnUidRanges);

  protected:
    // Use -1 to represent that default network was not modified because
    // real netId must be an unsigned value.
    int mStoredDefaultNetwork = -1;
    sp<INetd> mNetd;
    static TunInterface sTun;
    static TunInterface sTun2;
    static TunInterface sTun3;
    static TunInterface sTun4;
};

TunInterface NetdBinderTest::sTun;
TunInterface NetdBinderTest::sTun2;
TunInterface NetdBinderTest::sTun3;
TunInterface NetdBinderTest::sTun4;

class TimedOperation : public Stopwatch {
  public:
    explicit TimedOperation(const std::string &name): mName(name) {}
    virtual ~TimedOperation() {
        std::cerr << "    " << mName << ": " << timeTakenUs() << "us" << std::endl;
    }

  private:
    std::string mName;
};

TEST_F(NetdBinderTest, IsAlive) {
    TimedOperation t("isAlive RPC");
    bool isAlive = false;
    mNetd->isAlive(&isAlive);
    ASSERT_TRUE(isAlive);
}

namespace {

NativeNetworkConfig makeNativeNetworkConfig(int netId, NativeNetworkType networkType,
                                            int permission, bool secure) {
    NativeNetworkConfig config = {};
    config.netId = netId;
    config.networkType = networkType;
    config.permission = permission;
    config.secure = secure;
    // The vpnType doesn't matter in AOSP. Just pick a well defined one from INetd.
    config.vpnType = NativeVpnType::PLATFORM;
    return config;
}

}  // namespace

bool testNetworkExistsButCannotConnect(const sp<INetd>& netd, TunInterface& ifc, const int netId) {
    // If this network exists, we should definitely not be able to create it.
    // Note that this networkCreate is never allowed to create reserved network IDs, so
    // this call may fail for other reasons than the network already existing.
    const auto& config = makeNativeNetworkConfig(netId, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_FALSE(netd->networkCreate(config).isOk());
    // Test if the network exist by adding interface. INetd has no dedicated method to query. When
    // the network exists and the interface can be added, the function succeeds. When the network
    // exists but the interface cannot be added, it fails with EINVAL, otherwise it is ENONET.
    binder::Status status = netd->networkAddInterface(netId, ifc.name());
    if (status.isOk()) {  // clean up
        EXPECT_TRUE(netd->networkRemoveInterface(netId, ifc.name()).isOk());
    } else if (status.serviceSpecificErrorCode() == ENONET) {
        return false;
    }

    const sockaddr_in6 sin6 = {.sin6_family = AF_INET6,
                               .sin6_addr = {{.u6_addr32 = {htonl(0x20010db8), 0, 0, 0}}},
                               .sin6_port = 53};
    const int s = socket(AF_INET6, SOCK_DGRAM, 0);
    EXPECT_NE(-1, s);
    if (s == -1) return true;
    Fwmark fwmark;
    fwmark.explicitlySelected = true;
    fwmark.netId = netId;
    EXPECT_EQ(0, setsockopt(s, SOL_SOCKET, SO_MARK, &fwmark.intValue, sizeof(fwmark.intValue)));
    const int ret = connect(s, (struct sockaddr*)&sin6, sizeof(sin6));
    const int err = errno;
    EXPECT_EQ(-1, ret);
    EXPECT_EQ(ENETUNREACH, err);
    close(s);
    return true;
}

TEST_F(NetdBinderTest, InitialNetworksExist) {
    EXPECT_TRUE(testNetworkExistsButCannotConnect(mNetd, sTun, INetd::DUMMY_NET_ID));
    EXPECT_TRUE(testNetworkExistsButCannotConnect(mNetd, sTun, INetd::LOCAL_NET_ID));
    EXPECT_TRUE(testNetworkExistsButCannotConnect(mNetd, sTun, INetd::UNREACHABLE_NET_ID));
    EXPECT_FALSE(testNetworkExistsButCannotConnect(mNetd, sTun, 77 /* not exist */));
}

TEST_F(NetdBinderTest, IpSecTunnelInterface) {
    const struct TestData {
        const std::string family;
        const std::string deviceName;
        const std::string localAddress;
        const std::string remoteAddress;
        int32_t iKey;
        int32_t oKey;
        int32_t ifId;
    } kTestData[] = {
            {"IPV4", "ipsec_test", "127.0.0.1", "8.8.8.8", 0x1234 + 53, 0x1234 + 53, 0xFFFE},
            {"IPV6", "ipsec_test6", "::1", "2001:4860:4860::8888", 0x1234 + 50, 0x1234 + 50,
             0xFFFE},
    };

    for (size_t i = 0; i < std::size(kTestData); i++) {
        const auto& td = kTestData[i];

        binder::Status status;

        // Create Tunnel Interface.
        status = mNetd->ipSecAddTunnelInterface(td.deviceName, td.localAddress, td.remoteAddress,
                                                td.iKey, td.oKey, td.ifId);
        EXPECT_TRUE(status.isOk()) << td.family << status.exceptionMessage();

        // Check that the interface exists
        EXPECT_NE(0U, if_nametoindex(td.deviceName.c_str()));

        // Update Tunnel Interface.
        status = mNetd->ipSecUpdateTunnelInterface(td.deviceName, td.localAddress, td.remoteAddress,
                                                   td.iKey, td.oKey, td.ifId);
        EXPECT_TRUE(status.isOk()) << td.family << status.exceptionMessage();

        // Remove Tunnel Interface.
        status = mNetd->ipSecRemoveTunnelInterface(td.deviceName);
        EXPECT_TRUE(status.isOk()) << td.family << status.exceptionMessage();

        // Check that the interface no longer exists
        EXPECT_EQ(0U, if_nametoindex(td.deviceName.c_str()));
    }
}

TEST_F(NetdBinderTest, IpSecSetEncapSocketOwner) {
    unique_fd uniqueFd(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
    android::os::ParcelFileDescriptor sockFd(std::move(uniqueFd));

    int sockOptVal = UDP_ENCAP_ESPINUDP;
    setsockopt(sockFd.get(), IPPROTO_UDP, UDP_ENCAP, &sockOptVal, sizeof(sockOptVal));

    binder::Status res = mNetd->ipSecSetEncapSocketOwner(sockFd, 1001);
    EXPECT_TRUE(res.isOk());

    struct stat info;
    EXPECT_EQ(0, fstat(sockFd.get(), &info));
    EXPECT_EQ(1001, (int) info.st_uid);
}

// IPsec tests are not run in 32 bit mode; both 32-bit kernels and
// mismatched ABIs (64-bit kernel with 32-bit userspace) are unsupported.
#if INTPTR_MAX != INT32_MAX

using android::net::XfrmController;

static const int XFRM_DIRECTIONS[] = {static_cast<int>(android::net::XfrmDirection::IN),
                                      static_cast<int>(android::net::XfrmDirection::OUT)};
static const int ADDRESS_FAMILIES[] = {AF_INET, AF_INET6};

#define RETURN_FALSE_IF_NEQ(_expect_, _ret_) \
        do { if ((_expect_) != (_ret_)) return false; } while(false)
bool NetdBinderTest::allocateIpSecResources(bool expectOk, int32_t* spi) {
    android::netdutils::Status status = XfrmController::ipSecAllocateSpi(0, "::", "::1", 123, spi);
    SCOPED_TRACE(status);
    RETURN_FALSE_IF_NEQ(status.ok(), expectOk);

    // Add a policy
    status = XfrmController::ipSecAddSecurityPolicy(0, AF_INET6, 0, "::", "::1", 123, 0, 0, 0);
    SCOPED_TRACE(status);
    RETURN_FALSE_IF_NEQ(status.ok(), expectOk);

    // Add an ipsec interface
    return expectOk == XfrmController::ipSecAddTunnelInterface("ipsec_test", "::", "::1", 0xF00D,
                                                               0xD00D, 0xE00D, false)
                               .ok();
}

TEST_F(NetdBinderTest, XfrmDualSelectorTunnelModePoliciesV4) {
    android::binder::Status status;

    // Repeat to ensure cleanup and recreation works correctly
    for (int i = 0; i < 2; i++) {
        for (int direction : XFRM_DIRECTIONS) {
            for (int addrFamily : ADDRESS_FAMILIES) {
                status = mNetd->ipSecAddSecurityPolicy(0, addrFamily, direction, "127.0.0.5",
                                                       "127.0.0.6", 123, 0, 0, 0);
                EXPECT_TRUE(status.isOk())
                        << " family: " << addrFamily << " direction: " << direction;
            }
        }

        // Cleanup
        for (int direction : XFRM_DIRECTIONS) {
            for (int addrFamily : ADDRESS_FAMILIES) {
                status = mNetd->ipSecDeleteSecurityPolicy(0, addrFamily, direction, 0, 0, 0);
                EXPECT_TRUE(status.isOk());
            }
        }
    }
}

TEST_F(NetdBinderTest, XfrmDualSelectorTunnelModePoliciesV6) {
    binder::Status status;

    // Repeat to ensure cleanup and recreation works correctly
    for (int i = 0; i < 2; i++) {
        for (int direction : XFRM_DIRECTIONS) {
            for (int addrFamily : ADDRESS_FAMILIES) {
                status = mNetd->ipSecAddSecurityPolicy(0, addrFamily, direction, "2001:db8::f00d",
                                                       "2001:db8::d00d", 123, 0, 0, 0);
                EXPECT_TRUE(status.isOk())
                        << " family: " << addrFamily << " direction: " << direction;
            }
        }

        // Cleanup
        for (int direction : XFRM_DIRECTIONS) {
            for (int addrFamily : ADDRESS_FAMILIES) {
                status = mNetd->ipSecDeleteSecurityPolicy(0, addrFamily, direction, 0, 0, 0);
                EXPECT_TRUE(status.isOk());
            }
        }
    }
}

TEST_F(NetdBinderTest, XfrmControllerInit) {
    android::netdutils::Status status;
    status = XfrmController::Init();
    SCOPED_TRACE(status);

    // Older devices or devices with mismatched Kernel/User ABI cannot support the IPsec
    // feature.
    if (status.code() == EOPNOTSUPP) return;

    ASSERT_TRUE(status.ok());

    int32_t spi = 0;

    ASSERT_TRUE(allocateIpSecResources(true, &spi));
    ASSERT_TRUE(allocateIpSecResources(false, &spi));

    status = XfrmController::Init();
    ASSERT_TRUE(status.ok());
    ASSERT_TRUE(allocateIpSecResources(true, &spi));

    // Clean up
    status = XfrmController::ipSecDeleteSecurityAssociation(0, "::", "::1", 123, spi, 0, 0);
    SCOPED_TRACE(status);
    ASSERT_TRUE(status.ok());

    status = XfrmController::ipSecDeleteSecurityPolicy(0, AF_INET6, 0, 0, 0, 0);
    SCOPED_TRACE(status);
    ASSERT_TRUE(status.ok());

    // Remove Virtual Tunnel Interface.
    ASSERT_TRUE(XfrmController::ipSecRemoveTunnelInterface("ipsec_test").ok());
}

#endif  // INTPTR_MAX != INT32_MAX

static int bandwidthDataSaverEnabled(const char *binary) {
    std::vector<std::string> lines = listIptablesRule(binary, "bw_data_saver");

    // Output looks like this:
    //
    // Chain bw_data_saver (1 references)
    // target     prot opt source               destination
    // RETURN     all  --  0.0.0.0/0            0.0.0.0/0
    //
    // or:
    //
    // Chain bw_data_saver (1 references)
    // target     prot opt source               destination
    // ... possibly connectivity critical packet rules here ...
    // REJECT     all  --  ::/0            ::/0

    EXPECT_GE(lines.size(), 3U);

    if (lines.size() == 3 && StartsWith(lines[2], "RETURN ")) {
        // Data saver disabled.
        return 0;
    }

    size_t minSize = (std::string(binary) == IPTABLES_PATH) ? 3 : 9;

    if (lines.size() >= minSize && StartsWith(lines[lines.size() -1], "REJECT ")) {
        // Data saver enabled.
        return 1;
    }

    return -1;
}

bool enableDataSaver(sp<INetd>& netd, bool enable) {
    TimedOperation op(enable ? " Enabling data saver" : "Disabling data saver");
    bool ret;
    netd->bandwidthEnableDataSaver(enable, &ret);
    return ret;
}

int getDataSaverState() {
    const int enabled4 = bandwidthDataSaverEnabled(IPTABLES_PATH);
    const int enabled6 = bandwidthDataSaverEnabled(IP6TABLES_PATH);
    EXPECT_EQ(enabled4, enabled6);
    EXPECT_NE(-1, enabled4);
    EXPECT_NE(-1, enabled6);
    if (enabled4 != enabled6 || (enabled6 != 0 && enabled6 != 1)) {
        return -1;
    }
    return enabled6;
}

TEST_F(NetdBinderTest, BandwidthEnableDataSaver) {
    const int wasEnabled = getDataSaverState();
    ASSERT_NE(-1, wasEnabled);

    if (wasEnabled) {
        ASSERT_TRUE(enableDataSaver(mNetd, false));
        EXPECT_EQ(0, getDataSaverState());
    }

    ASSERT_TRUE(enableDataSaver(mNetd, false));
    EXPECT_EQ(0, getDataSaverState());

    ASSERT_TRUE(enableDataSaver(mNetd, true));
    EXPECT_EQ(1, getDataSaverState());

    ASSERT_TRUE(enableDataSaver(mNetd, true));
    EXPECT_EQ(1, getDataSaverState());

    if (!wasEnabled) {
        ASSERT_TRUE(enableDataSaver(mNetd, false));
        EXPECT_EQ(0, getDataSaverState());
    }
}

static bool ipRuleExistsForRange(const uint32_t priority, const UidRangeParcel& range,
                                 const std::string& action, const char* ipVersion,
                                 const char* oif) {
    // Output looks like this:
    //   "<priority>:\tfrom all iif lo oif netdc0ca6 uidrange 500000-500000 lookup netdc0ca6"
    //   "<priority>:\tfrom all fwmark 0x0/0x20000 iif lo uidrange 1000-2000 prohibit"
    std::vector<std::string> rules = listIpRules(ipVersion);

    std::string prefix = StringPrintf("%" PRIu32 ":", priority);
    std::string suffix;
    if (oif) {
        suffix = StringPrintf(" iif lo oif %s uidrange %d-%d %s\n", oif, range.start, range.stop,
                              action.c_str());
    } else {
        suffix = StringPrintf(" iif lo uidrange %d-%d %s\n", range.start, range.stop,
                              action.c_str());
    }
    for (const auto& line : rules) {
        if (android::base::StartsWith(line, prefix) && android::base::EndsWith(line, suffix)) {
            return true;
        }
    }
    return false;
}

// Overloads function with oif parameter for VPN rules compare.
static bool ipRuleExistsForRange(const uint32_t priority, const UidRangeParcel& range,
                                 const std::string& action, const char* oif) {
    bool existsIp4 = ipRuleExistsForRange(priority, range, action, IP_RULE_V4, oif);
    bool existsIp6 = ipRuleExistsForRange(priority, range, action, IP_RULE_V6, oif);
    EXPECT_EQ(existsIp4, existsIp6);
    return existsIp4;
}

static bool ipRuleExistsForRange(const uint32_t priority, const UidRangeParcel& range,
                                 const std::string& action) {
    return ipRuleExistsForRange(priority, range, action, nullptr);
}

namespace {

UidRangeParcel makeUidRangeParcel(int start, int stop) {
    UidRangeParcel res;
    res.start = start;
    res.stop = stop;

    return res;
}

NativeUidRangeConfig makeNativeUidRangeConfig(unsigned netId,
                                              std::vector<UidRangeParcel>&& uidRanges,
                                              uint32_t subPriority) {
    NativeUidRangeConfig res;
    res.netId = netId;
    res.uidRanges = uidRanges;
    res.subPriority = subPriority;

    return res;
}

}  // namespace

TEST_F(NetdBinderTest, NetworkInterfaces) {
    auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                          INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_EQ(EEXIST, mNetd->networkCreate(config).serviceSpecificErrorCode());

    config.networkType = NativeNetworkType::VIRTUAL;
    config.secure = true;
    EXPECT_EQ(EEXIST, mNetd->networkCreate(config).serviceSpecificErrorCode());

    config.netId = TEST_NETID2;
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());

    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
    EXPECT_EQ(EBUSY,
              mNetd->networkAddInterface(TEST_NETID2, sTun.name()).serviceSpecificErrorCode());

    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID2, sTun.name()).isOk());
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID2).isOk());
    EXPECT_EQ(ENONET, mNetd->networkDestroy(TEST_NETID1).serviceSpecificErrorCode());
}

TEST_F(NetdBinderTest, NetworkUidRules) {
    auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::VIRTUAL,
                                          INetd::PERMISSION_NONE, true);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_EQ(EEXIST, mNetd->networkCreate(config).serviceSpecificErrorCode());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    std::vector<UidRangeParcel> uidRanges = {makeUidRangeParcel(BASE_UID + 8005, BASE_UID + 8012),
                                             makeUidRangeParcel(BASE_UID + 8090, BASE_UID + 8099)};
    UidRangeParcel otherRange = makeUidRangeParcel(BASE_UID + 8190, BASE_UID + 8299);
    std::string action = StringPrintf("lookup %s ", sTun.name().c_str());

    EXPECT_TRUE(mNetd->networkAddUidRanges(TEST_NETID1, uidRanges).isOk());

    EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, uidRanges[0], action));
    EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, otherRange, action));
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(TEST_NETID1, uidRanges).isOk());
    EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, uidRanges[0], action));

    EXPECT_TRUE(mNetd->networkAddUidRanges(TEST_NETID1, uidRanges).isOk());
    EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, uidRanges[1], action));
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
    EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, uidRanges[1], action));

    EXPECT_EQ(ENONET, mNetd->networkDestroy(TEST_NETID1).serviceSpecificErrorCode());
}

TEST_F(NetdBinderTest, NetworkRejectNonSecureVpn) {
    std::vector<UidRangeParcel> uidRanges = {makeUidRangeParcel(BASE_UID + 150, BASE_UID + 224),
                                             makeUidRangeParcel(BASE_UID + 226, BASE_UID + 300)};
    // Make sure no rules existed before calling commands.
    for (auto const& range : uidRanges) {
        EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY_PROHIBIT_NON_VPN, range, "prohibit"));
    }
    // Create two valid rules.
    ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(true, uidRanges).isOk());
    for (auto const& range : uidRanges) {
        EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY_PROHIBIT_NON_VPN, range, "prohibit"));
    }

    // Remove the rules.
    ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(false, uidRanges).isOk());
    for (auto const& range : uidRanges) {
        EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY_PROHIBIT_NON_VPN, range, "prohibit"));
    }

    // Fail to remove the rules a second time after they are already deleted.
    binder::Status status = mNetd->networkRejectNonSecureVpn(false, uidRanges);
    ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
    EXPECT_EQ(ENOENT, status.serviceSpecificErrorCode());
}

// Create a socket pair that isLoopbackSocket won't think is local.
void NetdBinderTest::fakeRemoteSocketPair(unique_fd* clientSocket, unique_fd* serverSocket,
                                          unique_fd* acceptedSocket) {
    serverSocket->reset(socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0));
    struct sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.dstAddr() };
    ASSERT_EQ(0, bind(*serverSocket, (struct sockaddr *) &server6, sizeof(server6)));

    socklen_t addrlen = sizeof(server6);
    ASSERT_EQ(0, getsockname(*serverSocket, (struct sockaddr *) &server6, &addrlen));
    ASSERT_EQ(0, listen(*serverSocket, 10));

    clientSocket->reset(socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0));
    struct sockaddr_in6 client6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.srcAddr() };
    ASSERT_EQ(0, bind(*clientSocket, (struct sockaddr *) &client6, sizeof(client6)));
    ASSERT_EQ(0, connect(*clientSocket, (struct sockaddr *) &server6, sizeof(server6)));
    ASSERT_EQ(0, getsockname(*clientSocket, (struct sockaddr *) &client6, &addrlen));

    acceptedSocket->reset(
            accept4(*serverSocket, (struct sockaddr*)&server6, &addrlen, SOCK_CLOEXEC));
    ASSERT_NE(-1, *acceptedSocket);

    ASSERT_EQ(0, memcmp(&client6, &server6, sizeof(client6)));
}

void checkSocketpairOpen(int clientSocket, int acceptedSocket) {
    char buf[4096];
    EXPECT_EQ(4, write(clientSocket, "foo", sizeof("foo")));
    EXPECT_EQ(4, read(acceptedSocket, buf, sizeof(buf)));
    EXPECT_EQ(0, memcmp(buf, "foo", sizeof("foo")));
}

void checkSocketpairClosed(int clientSocket, int acceptedSocket) {
    // Check that the client socket was closed with ECONNABORTED.
    int ret = write(clientSocket, "foo", sizeof("foo"));
    int err = errno;
    EXPECT_EQ(-1, ret);
    EXPECT_EQ(ECONNABORTED, err);

    // Check that it sent a RST to the server.
    ret = write(acceptedSocket, "foo", sizeof("foo"));
    err = errno;
    EXPECT_EQ(-1, ret);
    EXPECT_EQ(ECONNRESET, err);
}

TEST_F(NetdBinderTest, SocketDestroy) {
    unique_fd clientSocket, serverSocket, acceptedSocket;
    ASSERT_NO_FATAL_FAILURE(fakeRemoteSocketPair(&clientSocket, &serverSocket, &acceptedSocket));

    // Pick a random UID in the system UID range.
    constexpr int baseUid = AID_APP - 2000;
    static_assert(baseUid > 0, "Not enough UIDs? Please fix this test.");
    int uid = baseUid + 500 + arc4random_uniform(1000);
    EXPECT_EQ(0, fchown(clientSocket, uid, -1));

    // UID ranges that don't contain uid.
    std::vector<UidRangeParcel> uidRanges = {
            makeUidRangeParcel(baseUid + 42, baseUid + 449),
            makeUidRangeParcel(baseUid + 1536, AID_APP - 4),
            makeUidRangeParcel(baseUid + 498, uid - 1),
            makeUidRangeParcel(uid + 1, baseUid + 1520),
    };
    // A skip list that doesn't contain UID.
    std::vector<int32_t> skipUids { baseUid + 123, baseUid + 1600 };

    // Close sockets. Our test socket should be intact.
    EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
    checkSocketpairOpen(clientSocket, acceptedSocket);

    // UID ranges that do contain uid.
    uidRanges = {
            makeUidRangeParcel(baseUid + 42, baseUid + 449),
            makeUidRangeParcel(baseUid + 1536, AID_APP - 4),
            makeUidRangeParcel(baseUid + 498, baseUid + 1520),
    };
    // Add uid to the skip list.
    skipUids.push_back(uid);

    // Close sockets. Our test socket should still be intact because it's in the skip list.
    EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
    checkSocketpairOpen(clientSocket, acceptedSocket);

    // Now remove uid from skipUids, and close sockets. Our test socket should have been closed.
    skipUids.resize(skipUids.size() - 1);
    EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
    checkSocketpairClosed(clientSocket, acceptedSocket);
}

TEST_F(NetdBinderTest, SocketDestroyLinkLocal) {
    // Add the same link-local address to two interfaces.
    const char* kLinkLocalAddress = "fe80::ace:d00d";

    const struct addrinfo hints = {
            .ai_family = AF_INET6,
            .ai_socktype = SOCK_STREAM,
            .ai_flags = AI_NUMERICHOST,
    };

    binder::Status status = mNetd->interfaceAddAddress(sTun.name(), kLinkLocalAddress, 64);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    status = mNetd->interfaceAddAddress(sTun2.name(), kLinkLocalAddress, 64);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Bind a listening socket to the address on each of two interfaces.
    // The sockets must be open at the same time, because this test checks that SOCK_DESTROY only
    // destroys the sockets on the interface where the address is deleted.
    struct addrinfo* addrinfoList = nullptr;
    int ret = getaddrinfo(kLinkLocalAddress, nullptr, &hints, &addrinfoList);
    ScopedAddrinfo addrinfoCleanup(addrinfoList);
    ASSERT_EQ(0, ret);

    socklen_t len = addrinfoList[0].ai_addrlen;
    sockaddr_in6 sin6_1 = *reinterpret_cast<sockaddr_in6*>(addrinfoList[0].ai_addr);
    sockaddr_in6 sin6_2 = sin6_1;
    sin6_1.sin6_scope_id = if_nametoindex(sTun.name().c_str());
    sin6_2.sin6_scope_id = if_nametoindex(sTun2.name().c_str());

    int s1 = socket(AF_INET6, SOCK_STREAM, 0);
    ASSERT_EQ(0, bind(s1, reinterpret_cast<sockaddr*>(&sin6_1), len));
    ASSERT_EQ(0, getsockname(s1, reinterpret_cast<sockaddr*>(&sin6_1), &len));

    int s2 = socket(AF_INET6, SOCK_STREAM, 0);
    ASSERT_EQ(0, bind(s2, reinterpret_cast<sockaddr*>(&sin6_2), len));
    ASSERT_EQ(0, getsockname(s2, reinterpret_cast<sockaddr*>(&sin6_2), &len));

    ASSERT_EQ(0, listen(s1, 10));
    ASSERT_EQ(0, listen(s2, 10));

    // Connect one client socket to each and accept the connections.
    int c1 = socket(AF_INET6, SOCK_STREAM, 0);
    int c2 = socket(AF_INET6, SOCK_STREAM, 0);
    ASSERT_EQ(0, connect(c1, reinterpret_cast<sockaddr*>(&sin6_1), len));
    ASSERT_EQ(0, connect(c2, reinterpret_cast<sockaddr*>(&sin6_2), len));
    int a1 = accept(s1, nullptr, 0);
    ASSERT_NE(-1, a1);
    int a2 = accept(s2, nullptr, 0);
    ASSERT_NE(-1, a2);

    // Delete the address on sTun2.
    status = mNetd->interfaceDelAddress(sTun2.name(), kLinkLocalAddress, 64);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // The sockets on sTun2 are closed, but the ones on sTun1 remain open.
    char buf[1024];
    EXPECT_EQ(-1, read(c2, buf, sizeof(buf)));
    EXPECT_EQ(ECONNABORTED, errno);
    // The blocking read above ensures that SOCK_DESTROY has completed.

    EXPECT_EQ(3, write(a1, "foo", 3));
    EXPECT_EQ(3, read(c1, buf, sizeof(buf)));
    EXPECT_EQ(-1, write(a2, "foo", 3));
    EXPECT_TRUE(errno == ECONNABORTED || errno == ECONNRESET);
}

namespace {

int netmaskToPrefixLength(const uint8_t *buf, size_t buflen) {
    if (buf == nullptr) return -1;

    int prefixLength = 0;
    bool endOfContiguousBits = false;
    for (unsigned int i = 0; i < buflen; i++) {
        const uint8_t value = buf[i];

        // Bad bit sequence: check for a contiguous set of bits from the high
        // end by verifying that the inverted value + 1 is a power of 2
        // (power of 2 iff. (v & (v - 1)) == 0).
        const uint8_t inverse = ~value + 1;
        if ((inverse & (inverse - 1)) != 0) return -1;

        prefixLength += (value == 0) ? 0 : CHAR_BIT - ffs(value) + 1;

        // Bogus netmask.
        if (endOfContiguousBits && value != 0) return -1;

        if (value != 0xff) endOfContiguousBits = true;
    }

    return prefixLength;
}

template<typename T>
int netmaskToPrefixLength(const T *p) {
    return netmaskToPrefixLength(reinterpret_cast<const uint8_t*>(p), sizeof(T));
}


static bool interfaceHasAddress(
        const std::string &ifname, const char *addrString, int prefixLength) {
    struct addrinfo *addrinfoList = nullptr;

    const struct addrinfo hints = {
        .ai_flags    = AI_NUMERICHOST,
        .ai_family   = AF_UNSPEC,
        .ai_socktype = SOCK_DGRAM,
    };
    if (getaddrinfo(addrString, nullptr, &hints, &addrinfoList) != 0 ||
        addrinfoList == nullptr || addrinfoList->ai_addr == nullptr) {
        return false;
    }
    ScopedAddrinfo addrinfoCleanup(addrinfoList);

    struct ifaddrs *ifaddrsList = nullptr;
    ScopedIfaddrs ifaddrsCleanup(ifaddrsList);

    if (getifaddrs(&ifaddrsList) != 0) {
        return false;
    }

    for (struct ifaddrs *addr = ifaddrsList; addr != nullptr; addr = addr->ifa_next) {
        if (std::string(addr->ifa_name) != ifname ||
            addr->ifa_addr == nullptr ||
            addr->ifa_addr->sa_family != addrinfoList->ai_addr->sa_family) {
            continue;
        }

        switch (addr->ifa_addr->sa_family) {
        case AF_INET: {
            auto *addr4 = reinterpret_cast<const struct sockaddr_in*>(addr->ifa_addr);
            auto *want = reinterpret_cast<const struct sockaddr_in*>(addrinfoList->ai_addr);
            if (memcmp(&addr4->sin_addr, &want->sin_addr, sizeof(want->sin_addr)) != 0) {
                continue;
            }

            if (prefixLength < 0) return true;  // not checking prefix lengths

            if (addr->ifa_netmask == nullptr) return false;
            auto *nm = reinterpret_cast<const struct sockaddr_in*>(addr->ifa_netmask);
            EXPECT_EQ(prefixLength, netmaskToPrefixLength(&nm->sin_addr));
            return (prefixLength == netmaskToPrefixLength(&nm->sin_addr));
        }
        case AF_INET6: {
            auto *addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr->ifa_addr);
            auto *want = reinterpret_cast<const struct sockaddr_in6*>(addrinfoList->ai_addr);
            if (memcmp(&addr6->sin6_addr, &want->sin6_addr, sizeof(want->sin6_addr)) != 0) {
                continue;
            }

            if (prefixLength < 0) return true;  // not checking prefix lengths

            if (addr->ifa_netmask == nullptr) return false;
            auto *nm = reinterpret_cast<const struct sockaddr_in6*>(addr->ifa_netmask);
            EXPECT_EQ(prefixLength, netmaskToPrefixLength(&nm->sin6_addr));
            return (prefixLength == netmaskToPrefixLength(&nm->sin6_addr));
        }
        default:
            // Cannot happen because we have already screened for matching
            // address families at the top of each iteration.
            continue;
        }
    }

    return false;
}

}  // namespace

TEST_F(NetdBinderTest, InterfaceAddRemoveAddress) {
    static const struct TestData {
        const char *addrString;
        const int   prefixLength;
        const int expectAddResult;
        const int expectRemoveResult;
    } kTestData[] = {
            {"192.0.2.1", 24, 0, 0},
            {"192.0.2.2", 25, 0, 0},
            {"192.0.2.3", 32, 0, 0},
            {"192.0.2.4", 33, EINVAL, EADDRNOTAVAIL},
            {"192.not.an.ip", 24, EINVAL, EINVAL},
            {"2001:db8::1", 64, 0, 0},
            {"2001:db8::2", 65, 0, 0},
            {"2001:db8::3", 128, 0, 0},
            {"fe80::1234", 64, 0, 0},
            {"2001:db8::4", 129, EINVAL, EINVAL},
            {"foo:bar::bad", 64, EINVAL, EINVAL},
            {"2001:db8::1/64", 64, EINVAL, EINVAL},
    };

    for (size_t i = 0; i < std::size(kTestData); i++) {
        const auto &td = kTestData[i];

        SCOPED_TRACE(String8::format("Offending IP address %s/%d", td.addrString, td.prefixLength));

        // [1.a] Add the address.
        binder::Status status = mNetd->interfaceAddAddress(
                sTun.name(), td.addrString, td.prefixLength);
        if (td.expectAddResult == 0) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        } else {
            ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            ASSERT_EQ(td.expectAddResult, status.serviceSpecificErrorCode());
        }

        // [1.b] Verify the addition meets the expectation.
        if (td.expectAddResult == 0) {
            EXPECT_TRUE(interfaceHasAddress(sTun.name(), td.addrString, td.prefixLength));
        } else {
            EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
        }

        // [2.a] Try to remove the address.  If it was not previously added, removing it fails.
        status = mNetd->interfaceDelAddress(sTun.name(), td.addrString, td.prefixLength);
        if (td.expectRemoveResult == 0) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        } else {
            ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            ASSERT_EQ(td.expectRemoveResult, status.serviceSpecificErrorCode());
        }

        // [2.b] No matter what, the address should not be present.
        EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
    }

    // Check that netlink errors are returned correctly.
    // We do this by attempting to create an IPv6 address on an interface that has IPv6 disabled,
    // which returns EACCES.
    TunInterface tun;
    ASSERT_EQ(0, tun.init());
    binder::Status status =
            mNetd->setProcSysNet(INetd::IPV6, INetd::CONF, tun.name(), "disable_ipv6", "1");
    ASSERT_TRUE(status.isOk()) << status.exceptionMessage();
    status = mNetd->interfaceAddAddress(tun.name(), "2001:db8::1", 64);
    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
    EXPECT_EQ(EACCES, status.serviceSpecificErrorCode());
    tun.destroy();
}

TEST_F(NetdBinderTest, GetProcSysNet) {
    const char* LOOPBACK = "lo";
    static const struct {
        const int ipversion;
        const int which;
        const char* ifname;
        const char* parameter;
        const char* expectedValue;
        const int expectedReturnCode;
    } kTestData[] = {
            {INetd::IPV4, INetd::CONF, LOOPBACK, "arp_ignore", "0", 0},
            {-1, INetd::CONF, sTun.name().c_str(), "arp_ignore", nullptr, EAFNOSUPPORT},
            {INetd::IPV4, -1, sTun.name().c_str(), "arp_ignore", nullptr, EINVAL},
            {INetd::IPV4, INetd::CONF, "..", "conf/lo/arp_ignore", nullptr, EINVAL},
            {INetd::IPV4, INetd::CONF, ".", "lo/arp_ignore", nullptr, EINVAL},
            {INetd::IPV4, INetd::CONF, sTun.name().c_str(), "../all/arp_ignore", nullptr, EINVAL},
            {INetd::IPV6, INetd::NEIGH, LOOPBACK, "ucast_solicit", "3", 0},
    };

    for (size_t i = 0; i < std::size(kTestData); i++) {
        const auto& td = kTestData[i];

        std::string value;
        const binder::Status status =
                mNetd->getProcSysNet(td.ipversion, td.which, td.ifname, td.parameter, &value);

        if (td.expectedReturnCode == 0) {
            SCOPED_TRACE(String8::format("test case %zu should have passed", i));
            EXPECT_EQ(0, status.exceptionCode());
            EXPECT_EQ(0, status.serviceSpecificErrorCode());
            EXPECT_EQ(td.expectedValue, value);
        } else {
            SCOPED_TRACE(String8::format("test case %zu should have failed", i));
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_EQ(td.expectedReturnCode, status.serviceSpecificErrorCode());
        }
    }
}

TEST_F(NetdBinderTest, SetProcSysNet) {
    static const struct {
        const int ipversion;
        const int which;
        const char* ifname;
        const char* parameter;
        const char* value;
        const int expectedReturnCode;
    } kTestData[] = {
            {INetd::IPV4, INetd::CONF, sTun.name().c_str(), "arp_ignore", "1", 0},
            {-1, INetd::CONF, sTun.name().c_str(), "arp_ignore", "1", EAFNOSUPPORT},
            {INetd::IPV4, -1, sTun.name().c_str(), "arp_ignore", "1", EINVAL},
            {INetd::IPV4, INetd::CONF, "..", "conf/lo/arp_ignore", "1", EINVAL},
            {INetd::IPV4, INetd::CONF, ".", "lo/arp_ignore", "1", EINVAL},
            {INetd::IPV4, INetd::CONF, sTun.name().c_str(), "../all/arp_ignore", "1", EINVAL},
            {INetd::IPV6, INetd::NEIGH, sTun.name().c_str(), "ucast_solicit", "7", 0},
    };

    for (size_t i = 0; i < std::size(kTestData); i++) {
        const auto& td = kTestData[i];
        const binder::Status status =
                mNetd->setProcSysNet(td.ipversion, td.which, td.ifname, td.parameter, td.value);

        if (td.expectedReturnCode == 0) {
            SCOPED_TRACE(String8::format("test case %zu should have passed", i));
            EXPECT_EQ(0, status.exceptionCode());
            EXPECT_EQ(0, status.serviceSpecificErrorCode());
        } else {
            SCOPED_TRACE(String8::format("test case %zu should have failed", i));
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_EQ(td.expectedReturnCode, status.serviceSpecificErrorCode());
        }
    }
}

TEST_F(NetdBinderTest, GetSetProcSysNet) {
    const int ipversion = INetd::IPV6;
    const int category = INetd::NEIGH;
    const std::string& tun = sTun.name();
    const std::string parameter("ucast_solicit");

    std::string value{};
    EXPECT_TRUE(mNetd->getProcSysNet(ipversion, category, tun, parameter, &value).isOk());
    ASSERT_FALSE(value.empty());
    const int ival = std::stoi(value);
    EXPECT_GT(ival, 0);
    // Try doubling the parameter value (always best!).
    EXPECT_TRUE(mNetd->setProcSysNet(ipversion, category, tun, parameter, std::to_string(2 * ival))
            .isOk());
    EXPECT_TRUE(mNetd->getProcSysNet(ipversion, category, tun, parameter, &value).isOk());
    EXPECT_EQ(2 * ival, std::stoi(value));
    // Try resetting the parameter.
    EXPECT_TRUE(mNetd->setProcSysNet(ipversion, category, tun, parameter, std::to_string(ival))
            .isOk());
    EXPECT_TRUE(mNetd->getProcSysNet(ipversion, category, tun, parameter, &value).isOk());
    EXPECT_EQ(ival, std::stoi(value));
}

namespace {

void expectNoTestCounterRules() {
    for (const auto& binary : { IPTABLES_PATH, IP6TABLES_PATH }) {
        std::string command = StringPrintf("%s -w -nvL tetherctrl_counters", binary);
        std::string allRules = Join(runCommand(command), "\n");
        EXPECT_EQ(std::string::npos, allRules.find("netdtest_"));
    }
}

void addTetherCounterValues(const char* path, const std::string& if1, const std::string& if2,
                            int byte, int pkt) {
    runCommand(StringPrintf("%s -w -A tetherctrl_counters -i %s -o %s -j RETURN -c %d %d",
                            path, if1.c_str(), if2.c_str(), pkt, byte));
}

void delTetherCounterValues(const char* path, const std::string& if1, const std::string& if2) {
    runCommand(StringPrintf("%s -w -D tetherctrl_counters -i %s -o %s -j RETURN",
                            path, if1.c_str(), if2.c_str()));
    runCommand(StringPrintf("%s -w -D tetherctrl_counters -i %s -o %s -j RETURN",
                            path, if2.c_str(), if1.c_str()));
}

std::vector<int64_t> getStatsVectorByIf(const std::vector<TetherStatsParcel>& statsVec,
                                        const std::string& iface) {
    for (auto& stats : statsVec) {
        if (stats.iface == iface) {
            return {stats.rxBytes, stats.rxPackets, stats.txBytes, stats.txPackets};
        }
    }
    return {};
}

}  // namespace

TEST_F(NetdBinderTest, TetherGetStats) {
    expectNoTestCounterRules();

    // TODO: fold this into more comprehensive tests once we have binder RPCs for enabling and
    // disabling tethering. We don't check the return value because these commands will fail if
    // tethering is already enabled.
    runCommand(StringPrintf("%s -w -N tetherctrl_counters", IPTABLES_PATH));
    runCommand(StringPrintf("%s -w -N tetherctrl_counters", IP6TABLES_PATH));

    std::string intIface1 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
    std::string intIface2 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
    std::string intIface3 = StringPrintf("netdtest_%u", arc4random_uniform(10000));

    // Ensure we won't use the same interface name, otherwise the test will fail.
    u_int32_t rNumber = arc4random_uniform(10000);
    std::string extIface1 = StringPrintf("netdtest_%u", rNumber);
    std::string extIface2 = StringPrintf("netdtest_%u", rNumber + 1);

    addTetherCounterValues(IPTABLES_PATH,  intIface1, extIface1, 123, 111);
    addTetherCounterValues(IP6TABLES_PATH, intIface1, extIface1, 456,  10);
    addTetherCounterValues(IPTABLES_PATH,  extIface1, intIface1, 321, 222);
    addTetherCounterValues(IP6TABLES_PATH, extIface1, intIface1, 654,  20);
    // RX is from external to internal, and TX is from internal to external.
    // So rxBytes is 321 + 654  = 975, txBytes is 123 + 456 = 579, etc.
    std::vector<int64_t> expected1 = { 975, 242, 579, 121 };

    addTetherCounterValues(IPTABLES_PATH,  intIface2, extIface2, 1000, 333);
    addTetherCounterValues(IP6TABLES_PATH, intIface2, extIface2, 3000,  30);

    addTetherCounterValues(IPTABLES_PATH,  extIface2, intIface2, 2000, 444);
    addTetherCounterValues(IP6TABLES_PATH, extIface2, intIface2, 4000,  40);

    addTetherCounterValues(IP6TABLES_PATH, intIface3, extIface2, 1000,  25);
    addTetherCounterValues(IP6TABLES_PATH, extIface2, intIface3, 2000,  35);
    std::vector<int64_t> expected2 = { 8000, 519, 5000, 388 };

    std::vector<TetherStatsParcel> statsVec;
    binder::Status status = mNetd->tetherGetStats(&statsVec);
    EXPECT_TRUE(status.isOk()) << "Getting tethering stats failed: " << status;

    EXPECT_EQ(expected1, getStatsVectorByIf(statsVec, extIface1));

    EXPECT_EQ(expected2, getStatsVectorByIf(statsVec, extIface2));

    for (const auto& path : { IPTABLES_PATH, IP6TABLES_PATH }) {
        delTetherCounterValues(path, intIface1, extIface1);
        delTetherCounterValues(path, intIface2, extIface2);
        if (path == IP6TABLES_PATH) {
            delTetherCounterValues(path, intIface3, extIface2);
        }
    }

    expectNoTestCounterRules();
}

namespace {

constexpr char IDLETIMER_RAW_PREROUTING[] = "idletimer_raw_PREROUTING";
constexpr char IDLETIMER_MANGLE_POSTROUTING[] = "idletimer_mangle_POSTROUTING";

static std::vector<std::string> listIptablesRuleByTable(const char* binary, const char* table,
                                                        const char* chainName) {
    std::string command = StringPrintf("%s -t %s -w -n -v -L %s", binary, table, chainName);
    return runCommand(command);
}

// TODO: It is a duplicate function, need to remove it
bool iptablesIdleTimerInterfaceRuleExists(const char* binary, const char* chainName,
                                          const std::string& expectedInterface,
                                          const std::string& expectedRule, const char* table) {
    std::vector<std::string> rules = listIptablesRuleByTable(binary, table, chainName);
    for (const auto& rule : rules) {
        if (rule.find(expectedInterface) != std::string::npos) {
            if (rule.find(expectedRule) != std::string::npos) {
                return true;
            }
        }
    }
    return false;
}

void expectIdletimerInterfaceRuleExists(const std::string& ifname, int timeout,
                                        const std::string& classLabel) {
    std::string IdletimerRule =
            StringPrintf("timeout:%u label:%s send_nl_msg", timeout, classLabel.c_str());
    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesIdleTimerInterfaceRuleExists(binary, IDLETIMER_RAW_PREROUTING, ifname,
                                                         IdletimerRule, RAW_TABLE));
        EXPECT_TRUE(iptablesIdleTimerInterfaceRuleExists(binary, IDLETIMER_MANGLE_POSTROUTING,
                                                         ifname, IdletimerRule, MANGLE_TABLE));
    }
}

void expectIdletimerInterfaceRuleNotExists(const std::string& ifname, int timeout,
                                           const std::string& classLabel) {
    std::string IdletimerRule =
            StringPrintf("timeout:%u label:%s send_nl_msg", timeout, classLabel.c_str());
    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_FALSE(iptablesIdleTimerInterfaceRuleExists(binary, IDLETIMER_RAW_PREROUTING, ifname,
                                                          IdletimerRule, RAW_TABLE));
        EXPECT_FALSE(iptablesIdleTimerInterfaceRuleExists(binary, IDLETIMER_MANGLE_POSTROUTING,
                                                          ifname, IdletimerRule, MANGLE_TABLE));
    }
}

}  // namespace

TEST_F(NetdBinderTest, IdletimerAddRemoveInterface) {
    // TODO: We will get error in if expectIdletimerInterfaceRuleNotExists if there are the same
    // rule in the table. Because we only check the result after calling remove function. We might
    // check the actual rule which is removed by our function (maybe compare the results between
    // calling function before and after)
    binder::Status status;
    const struct TestData {
        const std::string ifname;
        int32_t timeout;
        const std::string classLabel;
    } idleTestData[] = {
            {"wlan0", 1234, "happyday"},
            {"rmnet_data0", 4567, "friday"},
    };
    for (const auto& td : idleTestData) {
        status = mNetd->idletimerAddInterface(td.ifname, td.timeout, td.classLabel);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        expectIdletimerInterfaceRuleExists(td.ifname, td.timeout, td.classLabel);

        status = mNetd->idletimerRemoveInterface(td.ifname, td.timeout, td.classLabel);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        expectIdletimerInterfaceRuleNotExists(td.ifname, td.timeout, td.classLabel);
    }
}

namespace {

constexpr char STRICT_OUTPUT[] = "st_OUTPUT";
constexpr char STRICT_CLEAR_CAUGHT[] = "st_clear_caught";

void expectStrictSetUidAccept(const int uid) {
    std::string uidRule = StringPrintf("owner UID match %u", uid);
    std::string perUidChain = StringPrintf("st_clear_caught_%u", uid);
    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_FALSE(iptablesRuleExists(binary, STRICT_OUTPUT, uidRule));
        EXPECT_FALSE(iptablesRuleExists(binary, STRICT_CLEAR_CAUGHT, uidRule));
        EXPECT_EQ(0, iptablesRuleLineLength(binary, perUidChain.c_str()));
    }
}

void expectStrictSetUidLog(const int uid) {
    static const char logRule[] = "st_penalty_log  all";
    std::string uidRule = StringPrintf("owner UID match %u", uid);
    std::string perUidChain = StringPrintf("st_clear_caught_%u", uid);
    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesRuleExists(binary, STRICT_OUTPUT, uidRule));
        EXPECT_TRUE(iptablesRuleExists(binary, STRICT_CLEAR_CAUGHT, uidRule));
        EXPECT_TRUE(iptablesRuleExists(binary, perUidChain.c_str(), logRule));
    }
}

void expectStrictSetUidReject(const int uid) {
    static const char rejectRule[] = "st_penalty_reject  all";
    std::string uidRule = StringPrintf("owner UID match %u", uid);
    std::string perUidChain = StringPrintf("st_clear_caught_%u", uid);
    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesRuleExists(binary, STRICT_OUTPUT, uidRule));
        EXPECT_TRUE(iptablesRuleExists(binary, STRICT_CLEAR_CAUGHT, uidRule));
        EXPECT_TRUE(iptablesRuleExists(binary, perUidChain.c_str(), rejectRule));
    }
}

}  // namespace

TEST_F(NetdBinderTest, StrictSetUidCleartextPenalty) {
    binder::Status status;
    int32_t uid = randomUid();

    // setUidCleartextPenalty Policy:Log with randomUid
    status = mNetd->strictUidCleartextPenalty(uid, INetd::PENALTY_POLICY_LOG);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectStrictSetUidLog(uid);

    // setUidCleartextPenalty Policy:Accept with randomUid
    status = mNetd->strictUidCleartextPenalty(uid, INetd::PENALTY_POLICY_ACCEPT);
    expectStrictSetUidAccept(uid);

    // setUidCleartextPenalty Policy:Reject with randomUid
    status = mNetd->strictUidCleartextPenalty(uid, INetd::PENALTY_POLICY_REJECT);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectStrictSetUidReject(uid);

    // setUidCleartextPenalty Policy:Accept with randomUid
    status = mNetd->strictUidCleartextPenalty(uid, INetd::PENALTY_POLICY_ACCEPT);
    expectStrictSetUidAccept(uid);

    // test wrong policy
    int32_t wrongPolicy = -123;
    status = mNetd->strictUidCleartextPenalty(uid, wrongPolicy);
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
}

namespace {

std::vector<std::string> tryToFindProcesses(const std::string& processName, uint32_t maxTries = 1,
                                            uint32_t intervalMs = 50) {
    // Output looks like:(clatd)
    // clat          4963   850 1 12:16:51 ?     00:00:00 clatd-netd10a88 -i netd10a88 ...
    // ...
    // root          5221  5219 0 12:18:12 ?     00:00:00 sh -c ps -Af | grep ' clatd-netdcc1a0'

    // (dnsmasq)
    // dns_tether    4620   792 0 16:51:28 ?     00:00:00 dnsmasq --keep-in-foreground ...

    if (maxTries == 0) return {};

    std::string cmd = StringPrintf("ps -Af | grep '[0-9] %s'", processName.c_str());
    std::vector<std::string> result;
    for (uint32_t run = 1;;) {
        result = runCommand(cmd);
        if (result.size() || ++run > maxTries) {
            break;
        }

        usleep(intervalMs * 1000);
    }
    return result;
}

void expectProcessExists(const std::string& processName) {
    EXPECT_EQ(1U, tryToFindProcesses(processName, 5 /*maxTries*/).size());
}

void expectProcessDoesNotExist(const std::string& processName) {
    EXPECT_FALSE(tryToFindProcesses(processName).size());
}

}  // namespace

TEST_F(NetdBinderTest, ClatdStartStop) {
    binder::Status status;

    const std::string clatdName = StringPrintf("clatd-%s", sTun.name().c_str());
    std::string clatAddress;
    std::string nat64Prefix = "2001:db8:cafe:f00d:1:2::/96";

    // Can't start clatd on an interface that's not part of any network...
    status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());

    // ... so create a test physical network and add our tun to it.
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    // Prefix must be 96 bits long.
    status = mNetd->clatdStart(sTun.name(), "2001:db8:cafe:f00d::/64", &clatAddress);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    // Can't start clatd unless there's a default route...
    status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EADDRNOTAVAIL, status.serviceSpecificErrorCode());

    // so add a default route.
    EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());

    // Can't start clatd unless there's a global address...
    status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EADDRNOTAVAIL, status.serviceSpecificErrorCode());

    // ... so add a global address.
    const std::string v6 = "2001:db8:1:2:f076:ae99:124e:aa99";
    EXPECT_EQ(0, sTun.addAddress(v6.c_str(), 64));

    // Now expect clatd to start successfully.
    status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
    EXPECT_TRUE(status.isOk());
    EXPECT_EQ(0, status.serviceSpecificErrorCode());

    // Starting it again returns EBUSY.
    status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EBUSY, status.serviceSpecificErrorCode());

    expectProcessExists(clatdName);

    // Expect clatd to stop successfully.
    status = mNetd->clatdStop(sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectProcessDoesNotExist(clatdName);

    // Stopping a clatd that doesn't exist returns ENODEV.
    status = mNetd->clatdStop(sTun.name());
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());
    expectProcessDoesNotExist(clatdName);

    // Clean up.
    EXPECT_TRUE(mNetd->networkRemoveRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
    EXPECT_EQ(0, ifc_del_address(sTun.name().c_str(), v6.c_str(), 64));
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

namespace {

bool getIpfwdV4Enable() {
    static const char ipv4IpfwdCmd[] = "cat /proc/sys/net/ipv4/ip_forward";
    std::vector<std::string> result = runCommand(ipv4IpfwdCmd);
    EXPECT_TRUE(!result.empty());
    int v4Enable = std::stoi(result[0]);
    return v4Enable;
}

bool getIpfwdV6Enable() {
    static const char ipv6IpfwdCmd[] = "cat /proc/sys/net/ipv6/conf/all/forwarding";
    std::vector<std::string> result = runCommand(ipv6IpfwdCmd);
    EXPECT_TRUE(!result.empty());
    int v6Enable = std::stoi(result[0]);
    return v6Enable;
}

void expectIpfwdEnable(bool enable) {
    int enableIPv4 = getIpfwdV4Enable();
    int enableIPv6 = getIpfwdV6Enable();
    EXPECT_EQ(enable, enableIPv4);
    EXPECT_EQ(enable, enableIPv6);
}

bool ipRuleIpfwdExists(const char* ipVersion, const std::string& ipfwdRule) {
    std::vector<std::string> rules = listIpRules(ipVersion);
    for (const auto& rule : rules) {
        if (rule.find(ipfwdRule) != std::string::npos) {
            return true;
        }
    }
    return false;
}

void expectIpfwdRuleExists(const char* fromIf, const char* toIf) {
    std::string ipfwdRule =
            StringPrintf("%u:\tfrom all iif %s lookup %s ", RULE_PRIORITY_TETHERING, fromIf, toIf);

    for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
        EXPECT_TRUE(ipRuleIpfwdExists(ipVersion, ipfwdRule));
    }
}

void expectIpfwdRuleNotExists(const char* fromIf, const char* toIf) {
    std::string ipfwdRule =
            StringPrintf("%u:\tfrom all iif %s lookup %s ", RULE_PRIORITY_TETHERING, fromIf, toIf);

    for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
        EXPECT_FALSE(ipRuleIpfwdExists(ipVersion, ipfwdRule));
    }
}

}  // namespace

TEST_F(NetdBinderTest, TestIpfwdEnableDisableStatusForwarding) {
    // Get ipfwd requester list from Netd
    std::vector<std::string> requesterList;
    binder::Status status = mNetd->ipfwdGetRequesterList(&requesterList);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    bool ipfwdEnabled;
    if (requesterList.size() == 0) {
        // No requester in Netd, ipfwd should be disabled
        // So add one test requester and verify
        status = mNetd->ipfwdEnableForwarding("TestRequester");
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

        expectIpfwdEnable(true);
        status = mNetd->ipfwdEnabled(&ipfwdEnabled);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        EXPECT_TRUE(ipfwdEnabled);

        // Remove test one, verify again
        status = mNetd->ipfwdDisableForwarding("TestRequester");
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

        expectIpfwdEnable(false);
        status = mNetd->ipfwdEnabled(&ipfwdEnabled);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        EXPECT_FALSE(ipfwdEnabled);
    } else {
        // Disable all requesters
        for (const auto& requester : requesterList) {
            status = mNetd->ipfwdDisableForwarding(requester);
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        }

        // After disable all requester, ipfwd should be disabled
        expectIpfwdEnable(false);
        status = mNetd->ipfwdEnabled(&ipfwdEnabled);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        EXPECT_FALSE(ipfwdEnabled);

        // Enable them back
        for (const auto& requester : requesterList) {
            status = mNetd->ipfwdEnableForwarding(requester);
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        }

        // ipfwd should be enabled
        expectIpfwdEnable(true);
        status = mNetd->ipfwdEnabled(&ipfwdEnabled);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        EXPECT_TRUE(ipfwdEnabled);
    }
}

TEST_F(NetdBinderTest, TestIpfwdAddRemoveInterfaceForward) {
    // Add test physical network
    auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                          INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    config.netId = TEST_NETID2;
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID2, sTun2.name()).isOk());

    binder::Status status = mNetd->ipfwdAddInterfaceForward(sTun.name(), sTun2.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectIpfwdRuleExists(sTun.name().c_str(), sTun2.name().c_str());

    status = mNetd->ipfwdRemoveInterfaceForward(sTun.name(), sTun2.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectIpfwdRuleNotExists(sTun.name().c_str(), sTun2.name().c_str());
}

namespace {

constexpr char BANDWIDTH_INPUT[] = "bw_INPUT";
constexpr char BANDWIDTH_OUTPUT[] = "bw_OUTPUT";
constexpr char BANDWIDTH_FORWARD[] = "bw_FORWARD";
constexpr char BANDWIDTH_NAUGHTY[] = "bw_penalty_box";
constexpr char BANDWIDTH_ALERT[] = "bw_global_alert";

// TODO: Move iptablesTargetsExists and listIptablesRuleByTable to the top.
//       Use either a std::vector<std::string> of things to match, or a variadic function.
bool iptablesTargetsExists(const char* binary, int expectedCount, const char* table,
                           const char* chainName, const std::string& expectedTargetA,
                           const std::string& expectedTargetB) {
    std::vector<std::string> rules = listIptablesRuleByTable(binary, table, chainName);
    int matchCount = 0;

    for (const auto& rule : rules) {
        if (rule.find(expectedTargetA) != std::string::npos) {
            if (rule.find(expectedTargetB) != std::string::npos) {
                matchCount++;
            }
        }
    }
    return matchCount == expectedCount;
}

void expectXtQuotaValueEqual(const char* ifname, long quotaBytes) {
    std::string path = StringPrintf("/proc/net/xt_quota/%s", ifname);
    std::string result = "";

    EXPECT_TRUE(ReadFileToString(path, &result));
    // Quota value might be decreased while matching packets
    EXPECT_GE(quotaBytes, std::stol(Trim(result)));
}

void expectBandwidthInterfaceQuotaRuleExists(const char* ifname, long quotaBytes) {
    std::string BANDWIDTH_COSTLY_IF = StringPrintf("bw_costly_%s", ifname);
    std::string quotaRule = StringPrintf("quota %s", ifname);

    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesTargetsExists(binary, 1, FILTER_TABLE, BANDWIDTH_INPUT, ifname,
                                          BANDWIDTH_COSTLY_IF));
        EXPECT_TRUE(iptablesTargetsExists(binary, 1, FILTER_TABLE, BANDWIDTH_OUTPUT, ifname,
                                          BANDWIDTH_COSTLY_IF));
        EXPECT_TRUE(iptablesTargetsExists(binary, 2, FILTER_TABLE, BANDWIDTH_FORWARD, ifname,
                                          BANDWIDTH_COSTLY_IF));
        EXPECT_TRUE(iptablesRuleExists(binary, BANDWIDTH_COSTLY_IF.c_str(), BANDWIDTH_NAUGHTY));
        EXPECT_TRUE(iptablesRuleExists(binary, BANDWIDTH_COSTLY_IF.c_str(), quotaRule));
    }
    expectXtQuotaValueEqual(ifname, quotaBytes);
}

void expectBandwidthInterfaceQuotaRuleDoesNotExist(const char* ifname) {
    std::string BANDWIDTH_COSTLY_IF = StringPrintf("bw_costly_%s", ifname);
    std::string quotaRule = StringPrintf("quota %s", ifname);

    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_FALSE(iptablesTargetsExists(binary, 1, FILTER_TABLE, BANDWIDTH_INPUT, ifname,
                                           BANDWIDTH_COSTLY_IF));
        EXPECT_FALSE(iptablesTargetsExists(binary, 1, FILTER_TABLE, BANDWIDTH_OUTPUT, ifname,
                                           BANDWIDTH_COSTLY_IF));
        EXPECT_FALSE(iptablesTargetsExists(binary, 2, FILTER_TABLE, BANDWIDTH_FORWARD, ifname,
                                           BANDWIDTH_COSTLY_IF));
        EXPECT_FALSE(iptablesRuleExists(binary, BANDWIDTH_COSTLY_IF.c_str(), BANDWIDTH_NAUGHTY));
        EXPECT_FALSE(iptablesRuleExists(binary, BANDWIDTH_COSTLY_IF.c_str(), quotaRule));
    }
}

void expectBandwidthInterfaceAlertRuleExists(const char* ifname, long alertBytes) {
    std::string BANDWIDTH_COSTLY_IF = StringPrintf("bw_costly_%s", ifname);
    std::string alertRule = StringPrintf("quota %sAlert", ifname);
    std::string alertName = StringPrintf("%sAlert", ifname);

    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesRuleExists(binary, BANDWIDTH_COSTLY_IF.c_str(), alertRule));
    }
    expectXtQuotaValueEqual(alertName.c_str(), alertBytes);
}

void expectBandwidthInterfaceAlertRuleDoesNotExist(const char* ifname) {
    std::string BANDWIDTH_COSTLY_IF = StringPrintf("bw_costly_%s", ifname);
    std::string alertRule = StringPrintf("quota %sAlert", ifname);

    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_FALSE(iptablesRuleExists(binary, BANDWIDTH_COSTLY_IF.c_str(), alertRule));
    }
}

void expectBandwidthGlobalAlertRuleExists(long alertBytes) {
    static const char globalAlertRule[] = "quota globalAlert";
    static const char globalAlertName[] = "globalAlert";

    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesRuleExists(binary, BANDWIDTH_ALERT, globalAlertRule));
    }
    expectXtQuotaValueEqual(globalAlertName, alertBytes);
}

}  // namespace

TEST_F(NetdBinderTest, BandwidthSetRemoveInterfaceQuota) {
    long testQuotaBytes = 5550;

    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    binder::Status status = mNetd->bandwidthSetInterfaceQuota(sTun.name(), testQuotaBytes);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectBandwidthInterfaceQuotaRuleExists(sTun.name().c_str(), testQuotaBytes);

    status = mNetd->bandwidthRemoveInterfaceQuota(sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectBandwidthInterfaceQuotaRuleDoesNotExist(sTun.name().c_str());

    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, BandwidthSetRemoveInterfaceAlert) {
    long testAlertBytes = 373;
    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
    // Need to have a prior interface quota set to set an alert
    binder::Status status = mNetd->bandwidthSetInterfaceQuota(sTun.name(), testAlertBytes);
    status = mNetd->bandwidthSetInterfaceAlert(sTun.name(), testAlertBytes);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectBandwidthInterfaceAlertRuleExists(sTun.name().c_str(), testAlertBytes);

    status = mNetd->bandwidthRemoveInterfaceAlert(sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectBandwidthInterfaceAlertRuleDoesNotExist(sTun.name().c_str());

    // Remove interface quota
    status = mNetd->bandwidthRemoveInterfaceQuota(sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectBandwidthInterfaceQuotaRuleDoesNotExist(sTun.name().c_str());

    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, BandwidthSetGlobalAlert) {
    int64_t testAlertBytes = 2097200;

    binder::Status status = mNetd->bandwidthSetGlobalAlert(testAlertBytes);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectBandwidthGlobalAlertRuleExists(testAlertBytes);

    testAlertBytes = 2098230;
    status = mNetd->bandwidthSetGlobalAlert(testAlertBytes);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectBandwidthGlobalAlertRuleExists(testAlertBytes);
}

namespace {

std::string ipRouteString(const std::string& ifName, const std::string& dst,
                          const std::string& nextHop, const std::string& mtu) {
    std::string dstString = (dst == "0.0.0.0/0" || dst == "::/0") ? "default" : dst;

    if (!nextHop.empty()) {
        dstString += " via " + nextHop;
    }

    dstString += " dev " + ifName;

    if (!mtu.empty()) {
        dstString += " proto static";
        // IPv6 routes report the metric, IPv4 routes report the scope.
        // TODO: move away from specifying the entire string and use a regexp instead.
        if (dst.find(':') != std::string::npos) {
            dstString += " metric 1024";
        } else {
            if (nextHop.empty()) {
                dstString += " scope link";
            }
        }
        dstString += " mtu " + mtu;
    }

    return dstString;
}

void expectNetworkRouteExistsWithMtu(const char* ipVersion, const std::string& ifName,
                                     const std::string& dst, const std::string& nextHop,
                                     const std::string& mtu, const char* table) {
    std::string routeString = ipRouteString(ifName, dst, nextHop, mtu);
    EXPECT_TRUE(ipRouteExists(ipVersion, table, ipRouteString(ifName, dst, nextHop, mtu)))
            << "Couldn't find route to " << dst << ": '" << routeString << "' in table " << table;
}

void expectNetworkRouteExists(const char* ipVersion, const std::string& ifName,
                              const std::string& dst, const std::string& nextHop,
                              const char* table) {
    expectNetworkRouteExistsWithMtu(ipVersion, ifName, dst, nextHop, "", table);
}

void expectNetworkRouteDoesNotExist(const char* ipVersion, const std::string& ifName,
                                    const std::string& dst, const std::string& nextHop,
                                    const char* table) {
    std::string routeString = ipRouteString(ifName, dst, nextHop, "");
    EXPECT_FALSE(ipRouteExists(ipVersion, table, ipRouteString(ifName, dst, nextHop, "")))
            << "Found unexpected route " << routeString << " in table " << table;
}

bool ipRuleExists(const char* ipVersion, const std::string& ipRule) {
    std::vector<std::string> rules = listIpRules(ipVersion);
    for (const auto& rule : rules) {
        if (rule.find(ipRule) != std::string::npos) {
            return true;
        }
    }
    return false;
}

void expectNetworkDefaultIpRuleExists(const char* ifName) {
    std::string networkDefaultRule =
            StringPrintf("%u:\tfrom all fwmark 0x0/0xffff iif lo lookup %s",
                         RULE_PRIORITY_DEFAULT_NETWORK, ifName);

    for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
        EXPECT_TRUE(ipRuleExists(ipVersion, networkDefaultRule));
    }
}

void expectNetworkDefaultIpRuleDoesNotExist() {
    std::string networkDefaultRule =
            StringPrintf("%u:\tfrom all fwmark 0x0/0xffff iif lo", RULE_PRIORITY_DEFAULT_NETWORK);

    for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
        EXPECT_FALSE(ipRuleExists(ipVersion, networkDefaultRule));
    }
}

void expectNetworkPermissionIpRuleExists(const char* ifName, int permission) {
    std::string networkPermissionRule = "";
    switch (permission) {
        case INetd::PERMISSION_NONE:
            networkPermissionRule =
                    StringPrintf("%u:\tfrom all fwmark 0x1ffdd/0x1ffff iif lo lookup %s",
                                 RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
            break;
        case INetd::PERMISSION_NETWORK:
            networkPermissionRule =
                    StringPrintf("%u:\tfrom all fwmark 0x5ffdd/0x5ffff iif lo lookup %s",
                                 RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
            break;
        case INetd::PERMISSION_SYSTEM:
            networkPermissionRule =
                    StringPrintf("%u:\tfrom all fwmark 0xdffdd/0xdffff iif lo lookup %s",
                                 RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
            break;
    }

    for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
        EXPECT_TRUE(ipRuleExists(ipVersion, networkPermissionRule));
    }
}

// TODO: It is a duplicate function, need to remove it
bool iptablesNetworkPermissionIptablesRuleExists(const char* binary, const char* chainName,
                                                 const std::string& expectedInterface,
                                                 const std::string& expectedRule,
                                                 const char* table) {
    std::vector<std::string> rules = listIptablesRuleByTable(binary, table, chainName);
    for (const auto& rule : rules) {
        if (rule.find(expectedInterface) != std::string::npos) {
            if (rule.find(expectedRule) != std::string::npos) {
                return true;
            }
        }
    }
    return false;
}

void expectNetworkPermissionIptablesRuleExists(const char* ifName, int permission) {
    static const char ROUTECTRL_INPUT[] = "routectrl_mangle_INPUT";
    std::string networkIncomingPacketMarkRule = "";
    switch (permission) {
        case INetd::PERMISSION_NONE:
            networkIncomingPacketMarkRule = "MARK xset 0x3ffdd/0xffefffff";
            break;
        case INetd::PERMISSION_NETWORK:
            networkIncomingPacketMarkRule = "MARK xset 0x7ffdd/0xffefffff";
            break;
        case INetd::PERMISSION_SYSTEM:
            networkIncomingPacketMarkRule = "MARK xset 0xfffdd/0xffefffff";
            break;
    }

    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesNetworkPermissionIptablesRuleExists(
                binary, ROUTECTRL_INPUT, ifName, networkIncomingPacketMarkRule, MANGLE_TABLE));
    }
}

}  // namespace

TEST_F(NetdBinderTest, NetworkAddRemoveRouteUserPermission) {
    static const struct {
        const char* ipVersion;
        const char* testDest;
        const char* testNextHop;
        const bool expectSuccess;
    } kTestData[] = {
            {IP_RULE_V4, "0.0.0.0/0", "", true},
            {IP_RULE_V4, "0.0.0.0/0", "10.251.10.0", true},
            {IP_RULE_V4, "10.251.0.0/16", "", true},
            {IP_RULE_V4, "10.251.0.0/16", "10.251.10.0", true},
            {IP_RULE_V4, "10.251.0.0/16", "fe80::/64", false},
            {IP_RULE_V6, "::/0", "", true},
            {IP_RULE_V6, "::/0", "2001:db8::", true},
            {IP_RULE_V6, "2001:db8:cafe::/64", "2001:db8::", true},
            {IP_RULE_V4, "fe80::/64", "0.0.0.0", false},
    };

    static const struct {
        const char* ipVersion;
        const char* testDest;
        const char* testNextHop;
    } kTestDataWithNextHop[] = {
            {IP_RULE_V4, "10.251.10.0/30", ""},
            {IP_RULE_V6, "2001:db8::/32", ""},
    };

    static const char testTableLegacySystem[] = "legacy_system";
    static const char testTableLegacyNetwork[] = "legacy_network";
    const int testUid = randomUid();
    const std::vector<int32_t> testUids = {testUid};

    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    // Setup route for testing nextHop
    for (size_t i = 0; i < std::size(kTestDataWithNextHop); i++) {
        const auto& td = kTestDataWithNextHop[i];

        // All route for test tun will disappear once the tun interface is deleted.
        binder::Status status =
                mNetd->networkAddRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        expectNetworkRouteExists(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                 sTun.name().c_str());

        // Add system permission for test uid, setup route in legacy system table.
        EXPECT_TRUE(mNetd->networkSetPermissionForUser(INetd::PERMISSION_SYSTEM, testUids).isOk());

        status = mNetd->networkAddLegacyRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop,
                                              testUid);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        expectNetworkRouteExists(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                 testTableLegacySystem);

        // Remove system permission for test uid, setup route in legacy network table.
        EXPECT_TRUE(mNetd->networkClearPermissionForUser(testUids).isOk());

        status = mNetd->networkAddLegacyRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop,
                                              testUid);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        expectNetworkRouteExists(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                 testTableLegacyNetwork);
    }

    for (size_t i = 0; i < std::size(kTestData); i++) {
        const auto& td = kTestData[i];

        binder::Status status =
                mNetd->networkAddRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteExists(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                     sTun.name().c_str());
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }

        status = mNetd->networkRemoveRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteDoesNotExist(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                           sTun.name().c_str());
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }

        // Add system permission for test uid, route will be added into legacy system table.
        EXPECT_TRUE(mNetd->networkSetPermissionForUser(INetd::PERMISSION_SYSTEM, testUids).isOk());

        status = mNetd->networkAddLegacyRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop,
                                              testUid);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteExists(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                     testTableLegacySystem);
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }

        status = mNetd->networkRemoveLegacyRoute(TEST_NETID1, sTun.name(), td.testDest,
                                                 td.testNextHop, testUid);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteDoesNotExist(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                           testTableLegacySystem);
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }

        // Remove system permission for test uid, route will be added into legacy network table.
        EXPECT_TRUE(mNetd->networkClearPermissionForUser(testUids).isOk());

        status = mNetd->networkAddLegacyRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop,
                                              testUid);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteExists(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                     testTableLegacyNetwork);
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }

        status = mNetd->networkRemoveLegacyRoute(TEST_NETID1, sTun.name(), td.testDest,
                                                 td.testNextHop, testUid);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteDoesNotExist(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                           testTableLegacyNetwork);
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }
    }

    for (size_t i = 0; i < std::size(kTestData); i++) {
        const auto& td = kTestData[i];
        int mtu = (i % 2) ? 1480 : 1280;

        android::net::RouteInfoParcel parcel;
        parcel.ifName = sTun.name();
        parcel.destination = td.testDest;
        parcel.nextHop = td.testNextHop;
        parcel.mtu = mtu;
        binder::Status status = mNetd->networkAddRouteParcel(TEST_NETID1, parcel);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteExistsWithMtu(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                            std::to_string(parcel.mtu), sTun.name().c_str());
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }

        parcel.mtu = 1337;
        status = mNetd->networkUpdateRouteParcel(TEST_NETID1, parcel);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteExistsWithMtu(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                            std::to_string(parcel.mtu), sTun.name().c_str());
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }

        status = mNetd->networkRemoveRouteParcel(TEST_NETID1, parcel);
        if (td.expectSuccess) {
            EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
            expectNetworkRouteDoesNotExist(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                           sTun.name().c_str());
        } else {
            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
            EXPECT_NE(0, status.serviceSpecificErrorCode());
        }
    }
    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, NetworkPermissionDefault) {
    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    // Get current default network NetId
    binder::Status status = mNetd->networkGetDefault(&mStoredDefaultNetwork);
    ASSERT_TRUE(status.isOk()) << status.exceptionMessage();

    // Test SetDefault
    status = mNetd->networkSetDefault(TEST_NETID1);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectNetworkDefaultIpRuleExists(sTun.name().c_str());

    status = mNetd->networkClearDefault();
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectNetworkDefaultIpRuleDoesNotExist();

    // Set default network back
    status = mNetd->networkSetDefault(mStoredDefaultNetwork);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Test SetPermission
    status = mNetd->networkSetPermissionForNetwork(TEST_NETID1, INetd::PERMISSION_SYSTEM);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectNetworkPermissionIpRuleExists(sTun.name().c_str(), INetd::PERMISSION_SYSTEM);
    expectNetworkPermissionIptablesRuleExists(sTun.name().c_str(), INetd::PERMISSION_SYSTEM);

    status = mNetd->networkSetPermissionForNetwork(TEST_NETID1, INetd::PERMISSION_NONE);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectNetworkPermissionIpRuleExists(sTun.name().c_str(), INetd::PERMISSION_NONE);
    expectNetworkPermissionIptablesRuleExists(sTun.name().c_str(), INetd::PERMISSION_NONE);

    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, NetworkSetProtectAllowDeny) {
    binder::Status status = mNetd->networkSetProtectAllow(TEST_UID1);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    bool ret = false;
    status = mNetd->networkCanProtect(TEST_UID1, &ret);
    EXPECT_TRUE(ret);

    status = mNetd->networkSetProtectDeny(TEST_UID1);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Clear uid permission before calling networkCanProtect to ensure
    // the call won't be affected by uid permission.
    EXPECT_TRUE(mNetd->networkClearPermissionForUser({TEST_UID1}).isOk());

    status = mNetd->networkCanProtect(TEST_UID1, &ret);
    EXPECT_FALSE(ret);
}

namespace {

int readIntFromPath(const std::string& path) {
    std::string result = "";
    EXPECT_TRUE(ReadFileToString(path, &result));
    return std::stoi(result);
}

int getTetherAcceptIPv6Ra(const std::string& ifName) {
    std::string path = StringPrintf("/proc/sys/net/ipv6/conf/%s/accept_ra", ifName.c_str());
    return readIntFromPath(path);
}

bool getTetherAcceptIPv6Dad(const std::string& ifName) {
    std::string path = StringPrintf("/proc/sys/net/ipv6/conf/%s/accept_dad", ifName.c_str());
    return readIntFromPath(path);
}

int getTetherIPv6DadTransmits(const std::string& ifName) {
    std::string path = StringPrintf("/proc/sys/net/ipv6/conf/%s/dad_transmits", ifName.c_str());
    return readIntFromPath(path);
}

bool getTetherEnableIPv6(const std::string& ifName) {
    std::string path = StringPrintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifName.c_str());
    int disableIPv6 = readIntFromPath(path);
    return !disableIPv6;
}

bool interfaceListContains(const std::vector<std::string>& ifList, const std::string& ifName) {
    for (const auto& iface : ifList) {
        if (iface == ifName) {
            return true;
        }
    }
    return false;
}

void expectTetherInterfaceConfigureForIPv6Router(const std::string& ifName) {
    EXPECT_EQ(getTetherAcceptIPv6Ra(ifName), 0);
    EXPECT_FALSE(getTetherAcceptIPv6Dad(ifName));
    EXPECT_EQ(getTetherIPv6DadTransmits(ifName), 0);
    EXPECT_TRUE(getTetherEnableIPv6(ifName));
}

void expectTetherInterfaceConfigureForIPv6Client(const std::string& ifName) {
    EXPECT_EQ(getTetherAcceptIPv6Ra(ifName), 2);
    EXPECT_TRUE(getTetherAcceptIPv6Dad(ifName));
    EXPECT_EQ(getTetherIPv6DadTransmits(ifName), 1);
    EXPECT_FALSE(getTetherEnableIPv6(ifName));
}

void expectTetherInterfaceExists(const std::vector<std::string>& ifList,
                                 const std::string& ifName) {
    EXPECT_TRUE(interfaceListContains(ifList, ifName));
}

void expectTetherInterfaceNotExists(const std::vector<std::string>& ifList,
                                    const std::string& ifName) {
    EXPECT_FALSE(interfaceListContains(ifList, ifName));
}

void expectTetherDnsListEquals(const std::vector<std::string>& dnsList,
                               const std::vector<std::string>& testDnsAddrs) {
    EXPECT_TRUE(dnsList == testDnsAddrs);
}

}  // namespace

TEST_F(NetdBinderTest, TetherStartStopStatus) {
    std::vector<std::string> noDhcpRange = {};
    for (bool usingLegacyDnsProxy : {true, false}) {
        android::net::TetherConfigParcel config;
        config.usingLegacyDnsProxy = usingLegacyDnsProxy;
        config.dhcpRanges = noDhcpRange;
        binder::Status status = mNetd->tetherStartWithConfiguration(config);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        SCOPED_TRACE(StringPrintf("usingLegacyDnsProxy: %d", usingLegacyDnsProxy));
        if (usingLegacyDnsProxy == true) {
            expectProcessExists(DNSMASQ);
        } else {
            expectProcessDoesNotExist(DNSMASQ);
        }

        bool tetherEnabled;
        status = mNetd->tetherIsEnabled(&tetherEnabled);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        EXPECT_TRUE(tetherEnabled);

        status = mNetd->tetherStop();
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        expectProcessDoesNotExist(DNSMASQ);

        status = mNetd->tetherIsEnabled(&tetherEnabled);
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
        EXPECT_FALSE(tetherEnabled);
    }
}

TEST_F(NetdBinderTest, TetherInterfaceAddRemoveList) {
    // TODO: verify if dnsmasq update interface successfully

    binder::Status status = mNetd->tetherInterfaceAdd(sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectTetherInterfaceConfigureForIPv6Router(sTun.name());

    std::vector<std::string> ifList;
    status = mNetd->tetherInterfaceList(&ifList);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectTetherInterfaceExists(ifList, sTun.name());

    status = mNetd->tetherInterfaceRemove(sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectTetherInterfaceConfigureForIPv6Client(sTun.name());

    status = mNetd->tetherInterfaceList(&ifList);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectTetherInterfaceNotExists(ifList, sTun.name());
}

TEST_F(NetdBinderTest, TetherDnsSetList) {
    // TODO: verify if dnsmasq update dns successfully
    std::vector<std::string> testDnsAddrs = {"192.168.1.37", "213.137.100.3",
                                             "fe80::1%" + sTun.name()};

    binder::Status status = mNetd->tetherDnsSet(TEST_NETID1, testDnsAddrs);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    std::vector<std::string> dnsList;
    status = mNetd->tetherDnsList(&dnsList);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectTetherDnsListEquals(dnsList, testDnsAddrs);
}

namespace {

std::vector<IPAddress> findDnsSockets(SockDiag* sd, unsigned numExpected) {
    std::vector<IPAddress> listenAddrs;

    // Callback lambda that finds all IPv4 sockets with source port 53.
    auto findDnsSockets = [&](uint8_t /* proto */, const inet_diag_msg* msg) {
        // Always return false, which means do not destroy this socket.
        if (msg->id.idiag_sport != htons(53)) return false;
        IPAddress addr(*(in_addr*)msg->id.idiag_src);
        listenAddrs.push_back(addr);
        return false;
    };

    // There is no way to know if dnsmasq has finished processing the update_interfaces command and
    // opened listening sockets. So, just spin a few times and return the first list of sockets
    // that is at least numExpected long.
    // Pick a relatively large timeout to avoid flaky tests, particularly when running on shared
    // devices.
    constexpr int kMaxAttempts = 50;
    constexpr int kSleepMs = 100;
    for (int i = 0; i < kMaxAttempts; i++) {
        listenAddrs.clear();
        EXPECT_EQ(0, sd->sendDumpRequest(IPPROTO_TCP, AF_INET, 1 << TCP_LISTEN))
                << "Failed to dump sockets, attempt " << i << " of " << kMaxAttempts;
        sd->readDiagMsg(IPPROTO_TCP, findDnsSockets);
        if (listenAddrs.size() >= numExpected) {
            break;
        }
        usleep(kSleepMs * 1000);
    }

    return listenAddrs;
}

}  // namespace

// Checks that when starting dnsmasq on an interface that no longer exists, it doesn't attempt to
// start on other interfaces instead.
TEST_F(NetdBinderTest, TetherDeletedInterface) {
    // Do this first so we don't need to clean up anything else if it fails.
    SockDiag sd;
    ASSERT_TRUE(sd.open()) << "Failed to open SOCK_DIAG socket";

    // Create our own TunInterfaces (so we can delete them without affecting other tests), and add
    // IP addresses to them. They must be IPv4 because tethering an interface disables and
    // re-enables IPv6 on the interface, which clears all addresses.
    TunInterface tun1, tun2;
    ASSERT_EQ(0, tun1.init());
    ASSERT_EQ(0, tun2.init());

    // Clean up. It is safe to call TunInterface::destroy multiple times.
    auto guard = android::base::make_scope_guard([&] {
        tun1.destroy();
        tun2.destroy();
        mNetd->tetherStop();
        mNetd->tetherInterfaceRemove(tun1.name());
        mNetd->tetherInterfaceRemove(tun2.name());
    });

    IPAddress addr1, addr2;
    ASSERT_TRUE(IPAddress::forString("192.0.2.1", &addr1));
    ASSERT_TRUE(IPAddress::forString("192.0.2.2", &addr2));
    EXPECT_EQ(0, tun1.addAddress(addr1.toString(), 32));
    EXPECT_EQ(0, tun2.addAddress(addr2.toString(), 32));

    // Stop tethering.
    binder::Status status = mNetd->tetherStop();
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Start dnsmasq on an interface that doesn't exist.
    // First, tether our tun interface...
    status = mNetd->tetherInterfaceAdd(tun1.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectTetherInterfaceConfigureForIPv6Router(tun1.name());

    // ... then delete it...
    tun1.destroy();

    // ... then start dnsmasq.
    android::net::TetherConfigParcel config;
    config.usingLegacyDnsProxy = true;
    config.dhcpRanges = {};
    status = mNetd->tetherStartWithConfiguration(config);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Wait for dnsmasq to start.
    expectProcessExists(DNSMASQ);

    // Make sure that netd thinks the interface is tethered (even though it doesn't exist).
    std::vector<std::string> ifList;
    status = mNetd->tetherInterfaceList(&ifList);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    ASSERT_EQ(1U, ifList.size());
    EXPECT_EQ(tun1.name(), ifList[0]);

    // Give dnsmasq some time to start up.
    usleep(200 * 1000);

    // Check that dnsmasq is not listening on any IP addresses. It shouldn't, because it was only
    // told to run on tun1, and tun1 does not exist. Ensure it stays running and doesn't listen on
    // any IP addresses.
    std::vector<IPAddress> listenAddrs = findDnsSockets(&sd, 0);
    EXPECT_EQ(0U, listenAddrs.size()) << "Unexpectedly found IPv4 socket(s) listening on port 53";

    // Now add an interface to dnsmasq and check that we can see the sockets. This confirms that
    // findDnsSockets is actually able to see sockets when they exist.
    status = mNetd->tetherInterfaceAdd(tun2.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    in_addr loopback = {htonl(INADDR_LOOPBACK)};
    listenAddrs = findDnsSockets(&sd, 2);
    EXPECT_EQ(2U, listenAddrs.size()) << "Expected exactly 2 IPv4 sockets listening on port 53";
    EXPECT_EQ(1, std::count(listenAddrs.begin(), listenAddrs.end(), addr2));
    EXPECT_EQ(1, std::count(listenAddrs.begin(), listenAddrs.end(), IPAddress(loopback)));

    // Clean up.
    status = mNetd->tetherStop();
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    expectProcessDoesNotExist(DNSMASQ);

    status = mNetd->tetherInterfaceRemove(tun1.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    status = mNetd->tetherInterfaceRemove(tun2.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
}

namespace {

constexpr char FIREWALL_INPUT[] = "fw_INPUT";
constexpr char FIREWALL_OUTPUT[] = "fw_OUTPUT";
constexpr char FIREWALL_FORWARD[] = "fw_FORWARD";

void expectFirewallAllowlistMode() {
    static const char dropRule[] = "DROP       all";
    static const char rejectRule[] = "REJECT     all";
    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesRuleExists(binary, FIREWALL_INPUT, dropRule));
        EXPECT_TRUE(iptablesRuleExists(binary, FIREWALL_OUTPUT, rejectRule));
        EXPECT_TRUE(iptablesRuleExists(binary, FIREWALL_FORWARD, rejectRule));
    }
}

void expectFirewallDenylistMode() {
    EXPECT_EQ(2, iptablesRuleLineLength(IPTABLES_PATH, FIREWALL_INPUT));
    EXPECT_EQ(2, iptablesRuleLineLength(IPTABLES_PATH, FIREWALL_OUTPUT));
    EXPECT_EQ(2, iptablesRuleLineLength(IPTABLES_PATH, FIREWALL_FORWARD));

    // for IPv6 there is an extra OUTPUT rule to DROP ::1 sourced packets to non-loopback devices
    EXPECT_EQ(2, iptablesRuleLineLength(IP6TABLES_PATH, FIREWALL_INPUT));
    EXPECT_EQ(3, iptablesRuleLineLength(IP6TABLES_PATH, FIREWALL_OUTPUT));
    EXPECT_EQ(2, iptablesRuleLineLength(IP6TABLES_PATH, FIREWALL_FORWARD));
}

bool iptablesFirewallInterfaceFirstRuleExists(const char* binary, const char* chainName,
                                              const std::string& expectedInterface,
                                              const std::string& expectedRule) {
    std::vector<std::string> rules = listIptablesRuleByTable(binary, FILTER_TABLE, chainName);
    // Expected rule:
    // Chain fw_INPUT (1 references)
    // pkts bytes target     prot opt in     out     source               destination
    // 0     0 RETURN     all  --  expectedInterface *       0.0.0.0/0            0.0.0.0/0
    // 0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0
    int firstRuleIndex = 2;
    if (rules.size() < 4) return false;
    if (rules[firstRuleIndex].find(expectedInterface) != std::string::npos) {
        if (rules[firstRuleIndex].find(expectedRule) != std::string::npos) {
            return true;
        }
    }
    return false;
}

// TODO: It is a duplicate function, need to remove it
bool iptablesFirewallInterfaceRuleExists(const char* binary, const char* chainName,
                                         const std::string& expectedInterface,
                                         const std::string& expectedRule) {
    std::vector<std::string> rules = listIptablesRuleByTable(binary, FILTER_TABLE, chainName);
    for (const auto& rule : rules) {
        if (rule.find(expectedInterface) != std::string::npos) {
            if (rule.find(expectedRule) != std::string::npos) {
                return true;
            }
        }
    }
    return false;
}

void expectFirewallInterfaceRuleAllowExists(const std::string& ifname) {
    static const char returnRule[] = "RETURN     all";
    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesFirewallInterfaceFirstRuleExists(binary, FIREWALL_INPUT, ifname,
                                                             returnRule));
        EXPECT_TRUE(iptablesFirewallInterfaceFirstRuleExists(binary, FIREWALL_OUTPUT, ifname,
                                                             returnRule));
    }
}

void expectFireWallInterfaceRuleAllowDoesNotExist(const std::string& ifname) {
    static const char returnRule[] = "RETURN     all";
    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_FALSE(
                iptablesFirewallInterfaceRuleExists(binary, FIREWALL_INPUT, ifname, returnRule));
        EXPECT_FALSE(
                iptablesFirewallInterfaceRuleExists(binary, FIREWALL_OUTPUT, ifname, returnRule));
    }
}

}  // namespace

TEST_F(NetdBinderTest, FirewallSetFirewallType) {
    binder::Status status = mNetd->firewallSetFirewallType(INetd::FIREWALL_ALLOWLIST);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectFirewallAllowlistMode();

    status = mNetd->firewallSetFirewallType(INetd::FIREWALL_DENYLIST);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectFirewallDenylistMode();

    // set firewall type blacklist twice
    mNetd->firewallSetFirewallType(INetd::FIREWALL_DENYLIST);
    status = mNetd->firewallSetFirewallType(INetd::FIREWALL_DENYLIST);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectFirewallDenylistMode();

    // set firewall type whitelist twice
    mNetd->firewallSetFirewallType(INetd::FIREWALL_ALLOWLIST);
    status = mNetd->firewallSetFirewallType(INetd::FIREWALL_ALLOWLIST);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectFirewallAllowlistMode();

    // reset firewall type to default
    status = mNetd->firewallSetFirewallType(INetd::FIREWALL_DENYLIST);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectFirewallDenylistMode();
}

TEST_F(NetdBinderTest, FirewallSetInterfaceRule) {
    // setinterfaceRule is not supported in BLACKLIST MODE
    binder::Status status = mNetd->firewallSetFirewallType(INetd::FIREWALL_DENYLIST);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    status = mNetd->firewallSetInterfaceRule(sTun.name(), INetd::FIREWALL_RULE_ALLOW);
    EXPECT_FALSE(status.isOk()) << status.exceptionMessage();

    // set WHITELIST mode first
    status = mNetd->firewallSetFirewallType(INetd::FIREWALL_ALLOWLIST);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    status = mNetd->firewallSetInterfaceRule(sTun.name(), INetd::FIREWALL_RULE_ALLOW);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectFirewallInterfaceRuleAllowExists(sTun.name());

    status = mNetd->firewallSetInterfaceRule(sTun.name(), INetd::FIREWALL_RULE_DENY);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectFireWallInterfaceRuleAllowDoesNotExist(sTun.name());

    // reset firewall mode to default
    status = mNetd->firewallSetFirewallType(INetd::FIREWALL_DENYLIST);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectFirewallDenylistMode();
}

namespace {

std::string hwAddrToStr(unsigned char* hwaddr) {
    return StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x", hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3],
                        hwaddr[4], hwaddr[5]);
}

int ipv4NetmaskToPrefixLength(in_addr_t mask) {
    int prefixLength = 0;
    uint32_t m = ntohl(mask);
    while (m & (1 << 31)) {
        prefixLength++;
        m = m << 1;
    }
    return prefixLength;
}

std::string toStdString(const String16& s) {
    return std::string(String8(s.string()));
}

android::netdutils::StatusOr<ifreq> ioctlByIfName(const std::string& ifName, unsigned long flag) {
    const auto& sys = sSyscalls.get();
    auto fd = sys.socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
    EXPECT_TRUE(isOk(fd.status()));

    struct ifreq ifr = {};
    strlcpy(ifr.ifr_name, ifName.c_str(), IFNAMSIZ);

    return sys.ioctl(fd.value(), flag, &ifr);
}

std::string getInterfaceHwAddr(const std::string& ifName) {
    auto res = ioctlByIfName(ifName, SIOCGIFHWADDR);

    unsigned char hwaddr[ETH_ALEN] = {};
    if (isOk(res.status())) {
        memcpy((void*) hwaddr, &res.value().ifr_hwaddr.sa_data, ETH_ALEN);
    }

    return hwAddrToStr(hwaddr);
}

int getInterfaceIPv4Prefix(const std::string& ifName) {
    auto res = ioctlByIfName(ifName, SIOCGIFNETMASK);

    int prefixLength = 0;
    if (isOk(res.status())) {
        prefixLength = ipv4NetmaskToPrefixLength(
                ((struct sockaddr_in*) &res.value().ifr_addr)->sin_addr.s_addr);
    }

    return prefixLength;
}

std::string getInterfaceIPv4Addr(const std::string& ifName) {
    auto res = ioctlByIfName(ifName, SIOCGIFADDR);

    struct in_addr addr = {};
    if (isOk(res.status())) {
        addr.s_addr = ((struct sockaddr_in*) &res.value().ifr_addr)->sin_addr.s_addr;
    }

    return std::string(inet_ntoa(addr));
}

std::vector<std::string> getInterfaceFlags(const std::string& ifName) {
    auto res = ioctlByIfName(ifName, SIOCGIFFLAGS);

    unsigned flags = 0;
    if (isOk(res.status())) {
        flags = res.value().ifr_flags;
    }

    std::vector<std::string> ifFlags;
    ifFlags.push_back(flags & IFF_UP ? toStdString(INetd::IF_STATE_UP())
                                     : toStdString(INetd::IF_STATE_DOWN()));

    if (flags & IFF_BROADCAST) ifFlags.push_back(toStdString(INetd::IF_FLAG_BROADCAST()));
    if (flags & IFF_LOOPBACK) ifFlags.push_back(toStdString(INetd::IF_FLAG_LOOPBACK()));
    if (flags & IFF_POINTOPOINT) ifFlags.push_back(toStdString(INetd::IF_FLAG_POINTOPOINT()));
    if (flags & IFF_RUNNING) ifFlags.push_back(toStdString(INetd::IF_FLAG_RUNNING()));
    if (flags & IFF_MULTICAST) ifFlags.push_back(toStdString(INetd::IF_FLAG_MULTICAST()));

    return ifFlags;
}

bool compareListInterface(const std::vector<std::string>& interfaceList) {
    const auto& res = InterfaceController::getIfaceNames();
    EXPECT_TRUE(isOk(res));

    std::vector<std::string> resIfList;
    resIfList.reserve(res.value().size());
    resIfList.insert(end(resIfList), begin(res.value()), end(res.value()));

    return resIfList == interfaceList;
}

int getInterfaceIPv6PrivacyExtensions(const std::string& ifName) {
    std::string path = StringPrintf("/proc/sys/net/ipv6/conf/%s/use_tempaddr", ifName.c_str());
    return readIntFromPath(path);
}

bool getInterfaceEnableIPv6(const std::string& ifName) {
    std::string path = StringPrintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifName.c_str());

    int disableIPv6 = readIntFromPath(path);
    return !disableIPv6;
}

int getInterfaceMtu(const std::string& ifName) {
    std::string path = StringPrintf("/sys/class/net/%s/mtu", ifName.c_str());
    return readIntFromPath(path);
}

void expectInterfaceList(const std::vector<std::string>& interfaceList) {
    EXPECT_TRUE(compareListInterface(interfaceList));
}

void expectCurrentInterfaceConfigurationEquals(const std::string& ifName,
                                               const InterfaceConfigurationParcel& interfaceCfg) {
    EXPECT_EQ(getInterfaceIPv4Addr(ifName), interfaceCfg.ipv4Addr);
    EXPECT_EQ(getInterfaceIPv4Prefix(ifName), interfaceCfg.prefixLength);
    EXPECT_EQ(getInterfaceHwAddr(ifName), interfaceCfg.hwAddr);
    EXPECT_EQ(getInterfaceFlags(ifName), interfaceCfg.flags);
}

void expectCurrentInterfaceConfigurationAlmostEqual(const InterfaceConfigurationParcel& setCfg) {
    EXPECT_EQ(getInterfaceIPv4Addr(setCfg.ifName), setCfg.ipv4Addr);
    EXPECT_EQ(getInterfaceIPv4Prefix(setCfg.ifName), setCfg.prefixLength);

    const auto& ifFlags = getInterfaceFlags(setCfg.ifName);
    for (const auto& flag : setCfg.flags) {
        EXPECT_TRUE(std::find(ifFlags.begin(), ifFlags.end(), flag) != ifFlags.end());
    }
}

void expectInterfaceIPv6PrivacyExtensions(const std::string& ifName, bool enable) {
    int v6PrivacyExtensions = getInterfaceIPv6PrivacyExtensions(ifName);
    EXPECT_EQ(v6PrivacyExtensions, enable ? 2 : 0);
}

void expectInterfaceNoAddr(const std::string& ifName) {
    // noAddr
    EXPECT_EQ(getInterfaceIPv4Addr(ifName), "0.0.0.0");
    // noPrefix
    EXPECT_EQ(getInterfaceIPv4Prefix(ifName), 0);
}

void expectInterfaceEnableIPv6(const std::string& ifName, bool enable) {
    int enableIPv6 = getInterfaceEnableIPv6(ifName);
    EXPECT_EQ(enableIPv6, enable);
}

void expectInterfaceMtu(const std::string& ifName, const int mtu) {
    int mtuSize = getInterfaceMtu(ifName);
    EXPECT_EQ(mtu, mtuSize);
}

InterfaceConfigurationParcel makeInterfaceCfgParcel(const std::string& ifName,
                                                    const std::string& addr, int prefixLength,
                                                    const std::vector<std::string>& flags) {
    InterfaceConfigurationParcel cfg;
    cfg.ifName = ifName;
    cfg.hwAddr = "";
    cfg.ipv4Addr = addr;
    cfg.prefixLength = prefixLength;
    cfg.flags = flags;
    return cfg;
}

void expectTunFlags(const InterfaceConfigurationParcel& interfaceCfg) {
    std::vector<std::string> expectedFlags = {"up", "point-to-point", "running", "multicast"};
    std::vector<std::string> unexpectedFlags = {"down", "broadcast"};

    for (const auto& flag : expectedFlags) {
        EXPECT_TRUE(std::find(interfaceCfg.flags.begin(), interfaceCfg.flags.end(), flag) !=
                    interfaceCfg.flags.end());
    }

    for (const auto& flag : unexpectedFlags) {
        EXPECT_TRUE(std::find(interfaceCfg.flags.begin(), interfaceCfg.flags.end(), flag) ==
                    interfaceCfg.flags.end());
    }
}

}  // namespace

TEST_F(NetdBinderTest, InterfaceList) {
    std::vector<std::string> interfaceListResult;

    binder::Status status = mNetd->interfaceGetList(&interfaceListResult);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectInterfaceList(interfaceListResult);
}

TEST_F(NetdBinderTest, InterfaceGetCfg) {
    InterfaceConfigurationParcel interfaceCfgResult;

    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    binder::Status status = mNetd->interfaceGetCfg(sTun.name(), &interfaceCfgResult);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectCurrentInterfaceConfigurationEquals(sTun.name(), interfaceCfgResult);
    expectTunFlags(interfaceCfgResult);

    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, InterfaceSetCfg) {
    const std::string testAddr = "192.0.2.3";
    const int testPrefixLength = 24;
    std::vector<std::string> upFlags = {"up"};
    std::vector<std::string> downFlags = {"down"};

    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    // Set tun interface down.
    auto interfaceCfg = makeInterfaceCfgParcel(sTun.name(), testAddr, testPrefixLength, downFlags);
    binder::Status status = mNetd->interfaceSetCfg(interfaceCfg);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectCurrentInterfaceConfigurationAlmostEqual(interfaceCfg);

    // Set tun interface up again.
    interfaceCfg = makeInterfaceCfgParcel(sTun.name(), testAddr, testPrefixLength, upFlags);
    status = mNetd->interfaceSetCfg(interfaceCfg);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    status = mNetd->interfaceClearAddrs(sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, InterfaceSetIPv6PrivacyExtensions) {
    // enable
    binder::Status status = mNetd->interfaceSetIPv6PrivacyExtensions(sTun.name(), true);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectInterfaceIPv6PrivacyExtensions(sTun.name(), true);

    // disable
    status = mNetd->interfaceSetIPv6PrivacyExtensions(sTun.name(), false);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectInterfaceIPv6PrivacyExtensions(sTun.name(), false);
}

TEST_F(NetdBinderTest, InterfaceClearAddr) {
    const std::string testAddr = "192.0.2.3";
    const int testPrefixLength = 24;
    std::vector<std::string> noFlags{};

    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    auto interfaceCfg = makeInterfaceCfgParcel(sTun.name(), testAddr, testPrefixLength, noFlags);
    binder::Status status = mNetd->interfaceSetCfg(interfaceCfg);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectCurrentInterfaceConfigurationAlmostEqual(interfaceCfg);

    status = mNetd->interfaceClearAddrs(sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectInterfaceNoAddr(sTun.name());

    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, InterfaceSetEnableIPv6) {
    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    // disable
    binder::Status status = mNetd->interfaceSetEnableIPv6(sTun.name(), false);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectInterfaceEnableIPv6(sTun.name(), false);

    // enable
    status = mNetd->interfaceSetEnableIPv6(sTun.name(), true);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectInterfaceEnableIPv6(sTun.name(), true);

    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, InterfaceSetMtu) {
    const int testMtu = 1200;

    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    binder::Status status = mNetd->interfaceSetMtu(sTun.name(), testMtu);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectInterfaceMtu(sTun.name(), testMtu);

    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

namespace {

constexpr const char TETHER_FORWARD[] = "tetherctrl_FORWARD";
constexpr const char TETHER_NAT_POSTROUTING[] = "tetherctrl_nat_POSTROUTING";
constexpr const char TETHER_RAW_PREROUTING[] = "tetherctrl_raw_PREROUTING";
constexpr const char TETHER_COUNTERS_CHAIN[] = "tetherctrl_counters";

int iptablesCountRules(const char* binary, const char* table, const char* chainName) {
    return listIptablesRuleByTable(binary, table, chainName).size();
}

bool iptablesChainMatch(const char* binary, const char* table, const char* chainName,
                        const std::vector<std::string>& targetVec) {
    std::vector<std::string> rules = listIptablesRuleByTable(binary, table, chainName);
    if (targetVec.size() != rules.size() - 2) {
        return false;
    }

    /*
     * Check that the rules match. Note that this function matches substrings, not entire rules,
     * because otherwise rules where "pkts" or "bytes" are nonzero would not match.
     * Skip first two lines since rules start from third line.
     * Chain chainName (x references)
     * pkts bytes target     prot opt in     out     source               destination
     * ...
     */
    int rIndex = 2;
    for (const auto& target : targetVec) {
        if (rules[rIndex].find(target) == std::string::npos) {
            return false;
        }
        rIndex++;
    }
    return true;
}

void expectNatEnable(const std::string& intIf, const std::string& extIf) {
    std::vector<std::string> postroutingV4Match = {"MASQUERADE"};
    std::vector<std::string> preroutingV4Match = {"CT helper ftp", "CT helper pptp"};
    std::vector<std::string> forwardV4Match = {
            "bw_global_alert", "state RELATED", "state INVALID",
            StringPrintf("tetherctrl_counters  all  --  %s %s", intIf.c_str(), extIf.c_str()),
            "DROP"};

    // V4
    EXPECT_TRUE(iptablesChainMatch(IPTABLES_PATH, NAT_TABLE, TETHER_NAT_POSTROUTING,
                                   postroutingV4Match));
    EXPECT_TRUE(
            iptablesChainMatch(IPTABLES_PATH, RAW_TABLE, TETHER_RAW_PREROUTING, preroutingV4Match));
    EXPECT_TRUE(iptablesChainMatch(IPTABLES_PATH, FILTER_TABLE, TETHER_FORWARD, forwardV4Match));

    std::vector<std::string> forwardV6Match = {"bw_global_alert", "tetherctrl_counters"};
    std::vector<std::string> preroutingV6Match = {"rpfilter invert"};

    // V6
    EXPECT_TRUE(iptablesChainMatch(IP6TABLES_PATH, FILTER_TABLE, TETHER_FORWARD, forwardV6Match));
    EXPECT_TRUE(iptablesChainMatch(IP6TABLES_PATH, RAW_TABLE, TETHER_RAW_PREROUTING,
                                   preroutingV6Match));

    for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
        EXPECT_TRUE(iptablesTargetsExists(binary, 2, FILTER_TABLE, TETHER_COUNTERS_CHAIN, intIf,
                                          extIf));
    }
}

void expectNatDisable() {
    // It is the default DROP rule with tethering disable.
    // Chain tetherctrl_FORWARD (1 references)
    // pkts bytes target     prot opt in     out     source               destination
    //    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0
    std::vector<std::string> forwardV4Match = {"DROP"};
    EXPECT_TRUE(iptablesChainMatch(IPTABLES_PATH, FILTER_TABLE, TETHER_FORWARD, forwardV4Match));

    // We expect that these chains should be empty.
    EXPECT_EQ(2, iptablesCountRules(IPTABLES_PATH, NAT_TABLE, TETHER_NAT_POSTROUTING));
    EXPECT_EQ(2, iptablesCountRules(IPTABLES_PATH, RAW_TABLE, TETHER_RAW_PREROUTING));

    EXPECT_EQ(2, iptablesCountRules(IP6TABLES_PATH, FILTER_TABLE, TETHER_FORWARD));
    EXPECT_EQ(2, iptablesCountRules(IP6TABLES_PATH, RAW_TABLE, TETHER_RAW_PREROUTING));

    // Netd won't clear tether quota rule, we don't care rule in tetherctrl_counters.
}

}  // namespace

TEST_F(NetdBinderTest, TetherForwardAddRemove) {
    binder::Status status = mNetd->tetherAddForward(sTun.name(), sTun2.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectNatEnable(sTun.name(), sTun2.name());

    status = mNetd->tetherRemoveForward(sTun.name(), sTun2.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectNatDisable();
}

namespace {

using TripleInt = std::array<int, 3>;

TripleInt readProcFileToTripleInt(const std::string& path) {
    std::string valueString;
    int min, def, max;
    EXPECT_TRUE(ReadFileToString(path, &valueString));
    EXPECT_EQ(3, sscanf(valueString.c_str(), "%d %d %d", &min, &def, &max));
    return {min, def, max};
}

void updateAndCheckTcpBuffer(sp<INetd>& netd, TripleInt& rmemValues, TripleInt& wmemValues) {
    std::string testRmemValues =
            StringPrintf("%u %u %u", rmemValues[0], rmemValues[1], rmemValues[2]);
    std::string testWmemValues =
            StringPrintf("%u %u %u", wmemValues[0], wmemValues[1], wmemValues[2]);
    EXPECT_TRUE(netd->setTcpRWmemorySize(testRmemValues, testWmemValues).isOk());

    TripleInt newRmemValues = readProcFileToTripleInt(TCP_RMEM_PROC_FILE);
    TripleInt newWmemValues = readProcFileToTripleInt(TCP_WMEM_PROC_FILE);

    for (int i = 0; i < 3; i++) {
        SCOPED_TRACE(StringPrintf("tcp_mem value %d should be equal", i));
        EXPECT_EQ(rmemValues[i], newRmemValues[i]);
        EXPECT_EQ(wmemValues[i], newWmemValues[i]);
    }
}

}  // namespace

TEST_F(NetdBinderTest, TcpBufferSet) {
    TripleInt rmemValue = readProcFileToTripleInt(TCP_RMEM_PROC_FILE);
    TripleInt testRmemValue{rmemValue[0] + 42, rmemValue[1] + 42, rmemValue[2] + 42};
    TripleInt wmemValue = readProcFileToTripleInt(TCP_WMEM_PROC_FILE);
    TripleInt testWmemValue{wmemValue[0] + 42, wmemValue[1] + 42, wmemValue[2] + 42};

    updateAndCheckTcpBuffer(mNetd, testRmemValue, testWmemValue);
    updateAndCheckTcpBuffer(mNetd, rmemValue, wmemValue);
}

namespace {

void checkUidsInPermissionMap(std::vector<int32_t>& uids, bool exist) {
    android::bpf::BpfMap<uint32_t, uint8_t> uidPermissionMap(UID_PERMISSION_MAP_PATH);
    for (int32_t uid : uids) {
        android::base::Result<uint8_t> permission = uidPermissionMap.readValue(uid);
        if (exist) {
            ASSERT_RESULT_OK(permission);
            EXPECT_EQ(INetd::PERMISSION_NONE, permission.value());
        } else {
            ASSERT_FALSE(permission.ok());
            EXPECT_EQ(ENOENT, permission.error().code());
        }
    }
}

}  // namespace

TEST_F(NetdBinderTest, TestInternetPermission) {
    std::vector<int32_t> appUids = {TEST_UID1, TEST_UID2};

    mNetd->trafficSetNetPermForUids(INetd::PERMISSION_INTERNET, appUids);
    checkUidsInPermissionMap(appUids, false);
    mNetd->trafficSetNetPermForUids(INetd::PERMISSION_NONE, appUids);
    checkUidsInPermissionMap(appUids, true);
    mNetd->trafficSetNetPermForUids(INetd::PERMISSION_UNINSTALLED, appUids);
    checkUidsInPermissionMap(appUids, false);
}

TEST_F(NetdBinderTest, UnsolEvents) {
    auto testUnsolService = android::net::TestUnsolService::start();
    std::string oldTunName = sTun.name();
    std::string newTunName = "unsolTest";
    testUnsolService->tarVec.push_back(oldTunName);
    testUnsolService->tarVec.push_back(newTunName);
    auto& cv = testUnsolService->getCv();
    auto& cvMutex = testUnsolService->getCvMutex();
    binder::Status status = mNetd->registerUnsolicitedEventListener(
            android::interface_cast<android::net::INetdUnsolicitedEventListener>(testUnsolService));
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // TODO: Add test for below events
    //       StrictCleartextDetected / InterfaceDnsServersAdded
    //       InterfaceClassActivity / QuotaLimitReached / InterfaceAddressRemoved

    {
        std::unique_lock lock(cvMutex);

        // Re-init test Tun, and we expect that we will get some unsol events.
        // Use the test Tun device name to verify if we receive its unsol events.
        sTun.destroy();
        // Use predefined name
        sTun.init(newTunName);

        EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lock, std::chrono::seconds(2)));
    }

    // bit mask 1101101000
    // Test only covers below events currently
    const uint32_t kExpectedEvents = InterfaceAddressUpdated | InterfaceAdded | InterfaceRemoved |
                                     InterfaceLinkStatusChanged | RouteChanged;
    EXPECT_EQ(kExpectedEvents, testUnsolService->getReceived());

    // Re-init sTun to clear predefined name
    sTun.destroy();
    sTun.init();
}

TEST_F(NetdBinderTest, NDC) {
    struct Command {
        const std::string cmdString;
        const std::string expectedResult;
    };

    // clang-format off
    // Do not change the commands order
    const Command networkCmds[] = {
            {StringPrintf("ndc network create %d", TEST_NETID1),
             "200 0 success"},
            {StringPrintf("ndc network interface add %d %s", TEST_NETID1, sTun.name().c_str()),
             "200 0 success"},
            {StringPrintf("ndc network interface remove %d %s", TEST_NETID1, sTun.name().c_str()),
             "200 0 success"},
            {StringPrintf("ndc network interface add %d %s", TEST_NETID2, sTun.name().c_str()),
             "400 0 addInterfaceToNetwork() failed (Machine is not on the network)"},
            {StringPrintf("ndc network destroy %d", TEST_NETID1),
             "200 0 success"},
    };

    const std::vector<Command> ipfwdCmds = {
            {"ndc ipfwd enable " + sTun.name(),
             "200 0 ipfwd operation succeeded"},
            {"ndc ipfwd disable " + sTun.name(),
             "200 0 ipfwd operation succeeded"},
            {"ndc ipfwd add lo2 lo3",
             "400 0 ipfwd operation failed (No such process)"},
            {"ndc ipfwd add " + sTun.name() + " " + sTun2.name(),
             "200 0 ipfwd operation succeeded"},
            {"ndc ipfwd remove " + sTun.name() + " " + sTun2.name(),
             "200 0 ipfwd operation succeeded"},
    };

    static const struct {
        const char* ipVersion;
        const char* testDest;
        const char* testNextHop;
        const bool expectSuccess;
        const std::string expectedResult;
    } kTestData[] = {
            {IP_RULE_V4, "0.0.0.0/0",          "",            true,
             "200 0 success"},
            {IP_RULE_V4, "10.251.0.0/16",      "",            true,
             "200 0 success"},
            {IP_RULE_V4, "10.251.0.0/16",      "fe80::/64",   false,
             "400 0 addRoute() failed (Invalid argument)",},
            {IP_RULE_V6, "::/0",               "",            true,
             "200 0 success"},
            {IP_RULE_V6, "2001:db8:cafe::/64", "",            true,
             "200 0 success"},
            {IP_RULE_V6, "fe80::/64",          "0.0.0.0",     false,
             "400 0 addRoute() failed (Invalid argument)"},
    };
    // clang-format on

    for (const auto& cmd : networkCmds) {
        const std::vector<std::string> result = runCommand(cmd.cmdString);
        SCOPED_TRACE(cmd.cmdString);
        EXPECT_EQ(result.size(), 1U);
        EXPECT_EQ(cmd.expectedResult, Trim(result[0]));
    }

    for (const auto& cmd : ipfwdCmds) {
        const std::vector<std::string> result = runCommand(cmd.cmdString);
        SCOPED_TRACE(cmd.cmdString);
        EXPECT_EQ(result.size(), 1U);
        EXPECT_EQ(cmd.expectedResult, Trim(result[0]));
    }

    // Add test physical network
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());

    for (const auto& td : kTestData) {
        const std::string routeAddCmd =
                StringPrintf("ndc network route add %d %s %s %s", TEST_NETID1, sTun.name().c_str(),
                             td.testDest, td.testNextHop);
        const std::string routeRemoveCmd =
                StringPrintf("ndc network route remove %d %s %s %s", TEST_NETID1,
                             sTun.name().c_str(), td.testDest, td.testNextHop);
        std::vector<std::string> result = runCommand(routeAddCmd);
        SCOPED_TRACE(routeAddCmd);
        EXPECT_EQ(result.size(), 1U);
        EXPECT_EQ(td.expectedResult, Trim(result[0]));
        if (td.expectSuccess) {
            expectNetworkRouteExists(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                     sTun.name().c_str());
            result = runCommand(routeRemoveCmd);
            EXPECT_EQ(result.size(), 1U);
            EXPECT_EQ(td.expectedResult, Trim(result[0]));
            expectNetworkRouteDoesNotExist(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
                                           sTun.name().c_str());
        }
    }
    // Remove test physical network
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

TEST_F(NetdBinderTest, OemNetdRelated) {
    sp<IBinder> binder;
    binder::Status status = mNetd->getOemNetd(&binder);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    sp<com::android::internal::net::IOemNetd> oemNetd;
    if (binder != nullptr) {
        oemNetd = android::interface_cast<com::android::internal::net::IOemNetd>(binder);
    }
    ASSERT_NE(nullptr, oemNetd.get());

    TimedOperation t("OemNetd isAlive RPC");
    bool isAlive = false;
    oemNetd->isAlive(&isAlive);
    ASSERT_TRUE(isAlive);

    class TestOemUnsolListener
        : public com::android::internal::net::BnOemNetdUnsolicitedEventListener {
      public:
        android::binder::Status onRegistered() override {
            std::lock_guard lock(mCvMutex);
            mCv.notify_one();
            return android::binder::Status::ok();
        }
        std::condition_variable& getCv() { return mCv; }
        std::mutex& getCvMutex() { return mCvMutex; }

      private:
        std::mutex mCvMutex;
        std::condition_variable mCv;
    };

    // Start the Binder thread pool.
    android::ProcessState::self()->startThreadPool();

    android::sp<TestOemUnsolListener> testListener = new TestOemUnsolListener();

    auto& cv = testListener->getCv();
    auto& cvMutex = testListener->getCvMutex();

    {
        std::unique_lock lock(cvMutex);

        status = oemNetd->registerOemUnsolicitedEventListener(
                ::android::interface_cast<
                        com::android::internal::net::IOemNetdUnsolicitedEventListener>(
                        testListener));
        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

        // Wait for receiving expected events.
        EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lock, std::chrono::seconds(2)));
    }
}

void NetdBinderTest::createVpnNetworkWithUid(bool secure, uid_t uid, int vpnNetId,
                                             int fallthroughNetId) {
    // Re-init sTun* to ensure route rule exists.
    sTun.destroy();
    sTun.init();
    sTun2.destroy();
    sTun2.init();

    // Create physical network with fallthroughNetId but not set it as default network
    auto config = makeNativeNetworkConfig(fallthroughNetId, NativeNetworkType::PHYSICAL,
                                          INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(fallthroughNetId, sTun.name()).isOk());

    // Create VPN with vpnNetId
    config.netId = vpnNetId;
    config.networkType = NativeNetworkType::VIRTUAL;
    config.secure = secure;
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());

    // Add uid to VPN
    EXPECT_TRUE(mNetd->networkAddUidRanges(vpnNetId, {makeUidRangeParcel(uid, uid)}).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(vpnNetId, sTun2.name()).isOk());

    // Add default route to fallthroughNetwork
    EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
    // Add limited route
    EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID2, sTun2.name(), "2001:db8::/32", "").isOk());
}

void NetdBinderTest::createAndSetDefaultNetwork(int netId, const std::string& interface,
                                                int permission) {
    // backup current default network.
    ASSERT_TRUE(mNetd->networkGetDefault(&mStoredDefaultNetwork).isOk());

    const auto& config =
            makeNativeNetworkConfig(netId, NativeNetworkType::PHYSICAL, permission, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(netId, interface).isOk());
    EXPECT_TRUE(mNetd->networkSetDefault(netId).isOk());
}

void NetdBinderTest::createPhysicalNetwork(int netId, const std::string& interface,
                                           int permission) {
    const auto& config =
            makeNativeNetworkConfig(netId, NativeNetworkType::PHYSICAL, permission, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(netId, interface).isOk());
}

// 1. Create a physical network on sTun, and set it as the system default network.
// 2. Create another physical network on sTun2.
void NetdBinderTest::createDefaultAndOtherPhysicalNetwork(int defaultNetId, int otherNetId) {
    createAndSetDefaultNetwork(defaultNetId, sTun.name());
    EXPECT_TRUE(mNetd->networkAddRoute(defaultNetId, sTun.name(), "::/0", "").isOk());

    createPhysicalNetwork(otherNetId, sTun2.name());
    EXPECT_TRUE(mNetd->networkAddRoute(otherNetId, sTun2.name(), "::/0", "").isOk());
}

// 1. Create a system default network and a physical network.
// 2. Create a VPN on sTun3.
void NetdBinderTest::createVpnAndOtherPhysicalNetwork(int systemDefaultNetId, int otherNetId,
                                                      int vpnNetId, bool secure) {
    createDefaultAndOtherPhysicalNetwork(systemDefaultNetId, otherNetId);

    auto config = makeNativeNetworkConfig(vpnNetId, NativeNetworkType::VIRTUAL,
                                          INetd::PERMISSION_NONE, secure);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(vpnNetId, sTun3.name()).isOk());
    EXPECT_TRUE(mNetd->networkAddRoute(vpnNetId, sTun3.name(), "2001:db8::/32", "").isOk());
}

// 1. Create system default network, a physical network (for per-app default), and a VPN.
// 2. Add per-app uid ranges and VPN ranges.
void NetdBinderTest::createVpnAndAppDefaultNetworkWithUid(
        int systemDefaultNetId, int appDefaultNetId, int vpnNetId, bool secure,
        std::vector<UidRangeParcel>&& appDefaultUidRanges,
        std::vector<UidRangeParcel>&& vpnUidRanges) {
    createVpnAndOtherPhysicalNetwork(systemDefaultNetId, appDefaultNetId, vpnNetId, secure);
    // add per-app uid ranges.
    EXPECT_TRUE(mNetd->networkAddUidRanges(appDefaultNetId, appDefaultUidRanges).isOk());
    // add VPN uid ranges.
    EXPECT_TRUE(mNetd->networkAddUidRanges(vpnNetId, vpnUidRanges).isOk());
}

namespace {

class ScopedUidChange {
  public:
    explicit ScopedUidChange(uid_t uid) : mInputUid(uid) {
        mStoredUid = geteuid();
        if (mInputUid == mStoredUid) return;
        EXPECT_TRUE(seteuid(uid) == 0);
    }
    ~ScopedUidChange() {
        if (mInputUid == mStoredUid) return;
        EXPECT_TRUE(seteuid(mStoredUid) == 0);
    }

  private:
    uid_t mInputUid;
    uid_t mStoredUid;
};

void clearQueue(int tunFd) {
    char buf[4096];
    int ret;
    do {
        ret = read(tunFd, buf, sizeof(buf));
    } while (ret > 0);
}

void checkDataReceived(int udpSocket, int tunFd, sockaddr* dstAddr, int addrLen) {
    char buf[4096] = {};
    // Clear tunFd's queue before write something because there might be some
    // arbitrary packets in the queue. (e.g. ICMPv6 packet)
    clearQueue(tunFd);
    EXPECT_EQ(4, sendto(udpSocket, "foo", sizeof("foo"), 0, dstAddr, addrLen));
    // TODO: extract header and verify data
    EXPECT_GT(read(tunFd, buf, sizeof(buf)), 0);
}

bool sendIPv6PacketFromUid(uid_t uid, const in6_addr& dstAddr, Fwmark* fwmark, int tunFd,
                           bool doConnect = true) {
    ScopedUidChange scopedUidChange(uid);
    unique_fd testSocket(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
    if (testSocket < 0) return false;

    const sockaddr_in6 dst6 = {
            .sin6_family = AF_INET6,
            .sin6_port = 42,
            .sin6_addr = dstAddr,
    };
    if (doConnect && connect(testSocket, (sockaddr*)&dst6, sizeof(dst6)) == -1) return false;

    socklen_t fwmarkLen = sizeof(fwmark->intValue);
    EXPECT_NE(-1, getsockopt(testSocket, SOL_SOCKET, SO_MARK, &(fwmark->intValue), &fwmarkLen));

    char addr[INET6_ADDRSTRLEN];
    inet_ntop(AF_INET6, &dstAddr, addr, INET6_ADDRSTRLEN);
    SCOPED_TRACE(StringPrintf("sendIPv6Packet, addr: %s, uid: %u, doConnect: %s", addr, uid,
                              doConnect ? "true" : "false"));
    if (doConnect) {
        checkDataReceived(testSocket, tunFd, nullptr, 0);
    } else {
        checkDataReceived(testSocket, tunFd, (sockaddr*)&dst6, sizeof(dst6));
    }
    return true;
}

// Send an IPv6 packet from the uid. Expect to fail and get specified errno.
bool sendIPv6PacketFromUidFail(uid_t uid, const in6_addr& dstAddr, Fwmark* fwmark, bool doConnect,
                               int expectedErr) {
    ScopedUidChange scopedUidChange(uid);
    unique_fd s(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
    if (s < 0) return false;

    const sockaddr_in6 dst6 = {
            .sin6_family = AF_INET6,
            .sin6_port = 42,
            .sin6_addr = dstAddr,
    };
    if (doConnect) {
        if (connect(s, (sockaddr*)&dst6, sizeof(dst6)) == 0) return false;
        if (errno != expectedErr) return false;
    }

    socklen_t fwmarkLen = sizeof(fwmark->intValue);
    EXPECT_NE(-1, getsockopt(s, SOL_SOCKET, SO_MARK, &(fwmark->intValue), &fwmarkLen));

    char addr[INET6_ADDRSTRLEN];
    inet_ntop(AF_INET6, &dstAddr, addr, INET6_ADDRSTRLEN);
    SCOPED_TRACE(StringPrintf("sendIPv6PacketFail, addr: %s, uid: %u, doConnect: %s", addr, uid,
                              doConnect ? "true" : "false"));
    if (!doConnect) {
        if (sendto(s, "foo", sizeof("foo"), 0, (sockaddr*)&dst6, sizeof(dst6)) == 0) return false;
        if (errno != expectedErr) return false;
    }
    return true;
}

void expectVpnFallthroughRuleExists(const std::string& ifName, int vpnNetId) {
    std::string vpnFallthroughRule =
            StringPrintf("%d:\tfrom all fwmark 0x%x/0xffff lookup %s",
                         RULE_PRIORITY_VPN_FALLTHROUGH, vpnNetId, ifName.c_str());
    for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
        EXPECT_TRUE(ipRuleExists(ipVersion, vpnFallthroughRule));
    }
}

void expectVpnFallthroughWorks(android::net::INetd* netdService, bool bypassable, uid_t uid,
                               const TunInterface& fallthroughNetwork,
                               const TunInterface& vpnNetwork, int vpnNetId = TEST_NETID2,
                               int fallthroughNetId = TEST_NETID1) {
    // Set default network to NETID_UNSET
    EXPECT_TRUE(netdService->networkSetDefault(NETID_UNSET).isOk());

    // insideVpnAddr based on the route we added in createVpnNetworkWithUid
    in6_addr insideVpnAddr = {
            {// 2001:db8:cafe::1
             .u6_addr8 = {0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}};
    // outsideVpnAddr will hit the route in the fallthrough network route table
    // because we added default route in createVpnNetworkWithUid
    in6_addr outsideVpnAddr = {
            {// 2607:f0d0:1002::4
             .u6_addr8 = {0x26, 0x07, 0xf0, 0xd0, 0x10, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}}};

    int fallthroughFd = fallthroughNetwork.getFdForTesting();
    int vpnFd = vpnNetwork.getFdForTesting();
    // Expect all connections to fail because UID 0 is not routed to the VPN and there is no
    // default network.
    Fwmark fwmark;
    EXPECT_FALSE(sendIPv6PacketFromUid(0, outsideVpnAddr, &fwmark, fallthroughFd));
    EXPECT_FALSE(sendIPv6PacketFromUid(0, insideVpnAddr, &fwmark, fallthroughFd));

    // Set default network
    EXPECT_TRUE(netdService->networkSetDefault(fallthroughNetId).isOk());

    // Connections go on the default network because UID 0 is not subject to the VPN.
    EXPECT_TRUE(sendIPv6PacketFromUid(0, outsideVpnAddr, &fwmark, fallthroughFd));
    EXPECT_EQ(fallthroughNetId | 0xC0000, static_cast<int>(fwmark.intValue));
    EXPECT_TRUE(sendIPv6PacketFromUid(0, insideVpnAddr, &fwmark, fallthroughFd));
    EXPECT_EQ(fallthroughNetId | 0xC0000, static_cast<int>(fwmark.intValue));

    // Check if fallthrough rule exists
    expectVpnFallthroughRuleExists(fallthroughNetwork.name(), vpnNetId);

    // Expect fallthrough to default network
    // The fwmark differs depending on whether the VPN is bypassable or not.
    EXPECT_TRUE(sendIPv6PacketFromUid(uid, outsideVpnAddr, &fwmark, fallthroughFd));
    EXPECT_EQ(bypassable ? vpnNetId : fallthroughNetId, static_cast<int>(fwmark.intValue));

    // Expect connect success, packet will be sent to vpnFd.
    EXPECT_TRUE(sendIPv6PacketFromUid(uid, insideVpnAddr, &fwmark, vpnFd));
    EXPECT_EQ(bypassable ? vpnNetId : fallthroughNetId, static_cast<int>(fwmark.intValue));

    // Explicitly select vpn network
    setNetworkForProcess(vpnNetId);

    // Expect fallthrough to default network
    EXPECT_TRUE(sendIPv6PacketFromUid(0, outsideVpnAddr, &fwmark, fallthroughFd));
    // Expect the mark contains all the bit because we've selected network.
    EXPECT_EQ(vpnNetId | 0xF0000, static_cast<int>(fwmark.intValue));

    // Expect connect success, packet will be sent to vpnFd.
    EXPECT_TRUE(sendIPv6PacketFromUid(0, insideVpnAddr, &fwmark, vpnFd));
    // Expect the mark contains all the bit because we've selected network.
    EXPECT_EQ(vpnNetId | 0xF0000, static_cast<int>(fwmark.intValue));

    // Explicitly select fallthrough network
    setNetworkForProcess(fallthroughNetId);

    // The mark is set to fallthrough network because we've selected it.
    EXPECT_TRUE(sendIPv6PacketFromUid(0, outsideVpnAddr, &fwmark, fallthroughFd));
    EXPECT_TRUE(sendIPv6PacketFromUid(0, insideVpnAddr, &fwmark, fallthroughFd));

    // If vpn is BypassableVPN, connections can also go on the fallthrough network under vpn uid.
    if (bypassable) {
        EXPECT_TRUE(sendIPv6PacketFromUid(uid, outsideVpnAddr, &fwmark, fallthroughFd));
        EXPECT_TRUE(sendIPv6PacketFromUid(uid, insideVpnAddr, &fwmark, fallthroughFd));
    } else {
        // If not, no permission to bypass vpn.
        EXPECT_FALSE(sendIPv6PacketFromUid(uid, outsideVpnAddr, &fwmark, fallthroughFd));
        EXPECT_FALSE(sendIPv6PacketFromUid(uid, insideVpnAddr, &fwmark, fallthroughFd));
    }
}

}  // namespace

TEST_F(NetdBinderTest, SecureVPNFallthrough) {
    createVpnNetworkWithUid(true /* secure */, TEST_UID1);
    // Get current default network NetId
    ASSERT_TRUE(mNetd->networkGetDefault(&mStoredDefaultNetwork).isOk());
    expectVpnFallthroughWorks(mNetd.get(), false /* bypassable */, TEST_UID1, sTun, sTun2);
}

TEST_F(NetdBinderTest, BypassableVPNFallthrough) {
    createVpnNetworkWithUid(false /* secure */, TEST_UID1);
    // Get current default network NetId
    ASSERT_TRUE(mNetd->networkGetDefault(&mStoredDefaultNetwork).isOk());
    expectVpnFallthroughWorks(mNetd.get(), true /* bypassable */, TEST_UID1, sTun, sTun2);
}

namespace {

int32_t createIpv6SocketAndCheckMark(int type, const in6_addr& dstAddr) {
    const sockaddr_in6 dst6 = {
            .sin6_family = AF_INET6,
            .sin6_port = 1234,
            .sin6_addr = dstAddr,
    };
    // create non-blocking socket.
    int sockFd = socket(AF_INET6, type | SOCK_NONBLOCK, 0);
    EXPECT_NE(-1, sockFd);
    EXPECT_EQ((type == SOCK_STREAM) ? -1 : 0, connect(sockFd, (sockaddr*)&dst6, sizeof(dst6)));

    // Get socket fwmark.
    Fwmark fwmark;
    socklen_t fwmarkLen = sizeof(fwmark.intValue);
    EXPECT_EQ(0, getsockopt(sockFd, SOL_SOCKET, SO_MARK, &fwmark.intValue, &fwmarkLen));
    EXPECT_EQ(0, close(sockFd));
    return fwmark.intValue;
}

}  // namespace

TEST_F(NetdBinderTest, GetFwmarkForNetwork) {
    // Save current default network.
    ASSERT_TRUE(mNetd->networkGetDefault(&mStoredDefaultNetwork).isOk());

    // Add test physical network 1 and set as default network.
    auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                          INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
    EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "2001:db8::/32", "").isOk());
    EXPECT_TRUE(mNetd->networkSetDefault(TEST_NETID1).isOk());
    // Add test physical network 2
    config.netId = TEST_NETID2;
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID2, sTun2.name()).isOk());

    // Get fwmark for network 1.
    MarkMaskParcel maskMarkNet1;
    ASSERT_TRUE(mNetd->getFwmarkForNetwork(TEST_NETID1, &maskMarkNet1).isOk());

    uint32_t fwmarkTcp = createIpv6SocketAndCheckMark(SOCK_STREAM, V6_ADDR);
    uint32_t fwmarkUdp = createIpv6SocketAndCheckMark(SOCK_DGRAM, V6_ADDR);
    EXPECT_EQ(maskMarkNet1.mark, static_cast<int>(fwmarkTcp & maskMarkNet1.mask));
    EXPECT_EQ(maskMarkNet1.mark, static_cast<int>(fwmarkUdp & maskMarkNet1.mask));

    // Get fwmark for network 2.
    MarkMaskParcel maskMarkNet2;
    ASSERT_TRUE(mNetd->getFwmarkForNetwork(TEST_NETID2, &maskMarkNet2).isOk());
    EXPECT_NE(maskMarkNet2.mark, static_cast<int>(fwmarkTcp & maskMarkNet2.mask));
    EXPECT_NE(maskMarkNet2.mark, static_cast<int>(fwmarkUdp & maskMarkNet2.mask));

    // Remove test physical network.
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID2).isOk());
    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}

namespace {

TetherOffloadRuleParcel makeTetherOffloadRule(int inputInterfaceIndex, int outputInterfaceIndex,
                                              const std::vector<uint8_t>& destination,
                                              int prefixLength,
                                              const std::vector<uint8_t>& srcL2Address,
                                              const std::vector<uint8_t>& dstL2Address, int pmtu) {
    android::net::TetherOffloadRuleParcel parcel;
    parcel.inputInterfaceIndex = inputInterfaceIndex;
    parcel.outputInterfaceIndex = outputInterfaceIndex;
    parcel.destination = destination;
    parcel.prefixLength = prefixLength;
    parcel.srcL2Address = srcL2Address;
    parcel.dstL2Address = dstL2Address;
    parcel.pmtu = pmtu;
    return parcel;
}

}  // namespace

// TODO: probably remove the test because TetherOffload* binder calls are deprecated.
TEST_F(NetdBinderTest, DISABLED_TetherOffloadRule) {
    // TODO: Perhaps verify invalid interface index once the netd handle the error in methods.
    constexpr uint32_t kIfaceInt = 101;
    constexpr uint32_t kIfaceExt = 102;
    constexpr uint32_t kIfaceNonExistent = 103;

    const std::vector<uint8_t> kAddr6 = {0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0x00, 0x00,
                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88};
    const std::vector<uint8_t> kSrcMac = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0a};
    const std::vector<uint8_t> kDstMac = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0b};

    const std::vector<uint8_t> kInvalidAddr4 = {0xac, 0x0a, 0x0d, 0xb8};  // should be IPv6 address
    const std::vector<uint8_t> kInvalidMac = {0xde, 0xad, 0xbe, 0xef};    // should be 6-byte length

    // Invalid IP address, add rule
    TetherOffloadRuleParcel rule = makeTetherOffloadRule(
            kIfaceExt, kIfaceInt, kInvalidAddr4 /*bad*/, 128, kSrcMac, kDstMac, 1500);
    auto status = mNetd->tetherOffloadRuleAdd(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EAFNOSUPPORT, status.serviceSpecificErrorCode());

    // Invalid source L2 address, add rule
    rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kInvalidMac /*bad*/, kDstMac,
                                 1500);
    status = mNetd->tetherOffloadRuleAdd(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(ENXIO, status.serviceSpecificErrorCode());

    // Invalid destination L2 address, add rule
    rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kInvalidMac /*bad*/,
                                 1500);
    status = mNetd->tetherOffloadRuleAdd(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(ENXIO, status.serviceSpecificErrorCode());

    // Invalid IP address, remove rule
    rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kInvalidAddr4 /*bad*/, 128, kSrcMac, kDstMac,
                                 1500);
    status = mNetd->tetherOffloadRuleRemove(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EAFNOSUPPORT, status.serviceSpecificErrorCode());

    // Invalid prefix length
    rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 64 /*bad*/, kSrcMac, kDstMac, 1500);
    status = mNetd->tetherOffloadRuleAdd(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
    status = mNetd->tetherOffloadRuleRemove(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    // Invalid interface index
    rule = makeTetherOffloadRule(kIfaceExt, 0, kAddr6, 128, kSrcMac, kDstMac, 1500);
    status = mNetd->tetherOffloadRuleAdd(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());
    rule = makeTetherOffloadRule(0, kIfaceInt, kAddr6, 64, kSrcMac, kDstMac, 1500);
    status = mNetd->tetherOffloadRuleRemove(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());

    // Invalid pmtu (too low)
    rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1279);
    status = mNetd->tetherOffloadRuleAdd(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    // Invalid pmtu (too high)
    rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 65536);
    status = mNetd->tetherOffloadRuleAdd(rule);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    // Remove non existent rule. Expect that silently return success if the rule did not exist.
    rule = makeTetherOffloadRule(kIfaceNonExistent, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1500);
    EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());

    // Add and remove rule normally.
    rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1500);
    EXPECT_TRUE(mNetd->tetherOffloadRuleAdd(rule).isOk());
    EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());
}

static bool expectPacket(int fd, uint8_t* ipPacket, ssize_t ipLen) {
    constexpr bool kDebug = false;

    uint8_t buf[ETHER_HDR_LEN + 1500];

    // Wait a bit to ensure that the packet we're interested in has arrived.
    // TODO: speed this up.
    usleep(100 * 1000);

    ssize_t bytesRead;
    ssize_t expectedLen = ipLen + ETHER_HDR_LEN;
    while ((bytesRead = read(fd, buf, sizeof(buf))) >= 0) {
        if (kDebug) {
            std::cerr << fmt::format(
                    "Expected: {:02x}\n  Actual: {:02x}\n",
                    fmt::join(ipPacket, ipPacket + ipLen, " "),
                    fmt::join(buf + ETHER_HDR_LEN, buf + ETHER_HDR_LEN + ipLen, " "));
        }

        if (bytesRead != expectedLen) {
            continue;
        }

        if (!memcmp(ipPacket, buf + ETHER_HDR_LEN, ipLen)) {
            return true;
        }
    }

    return false;
}

static bool tcQdiscExists(const std::string& interface) {
    std::string command = StringPrintf("tc qdisc show dev %s", interface.c_str());
    std::vector<std::string> lines = runCommand(command);
    for (const auto& line : lines) {
        if (StartsWith(line, "qdisc clsact ffff:")) return true;
    }
    return false;
}

static bool tcFilterExists(const std::string& interface) {
    std::string command = StringPrintf("tc filter show dev %s ingress", interface.c_str());
    std::vector<std::string> lines = runCommand(command);
    const std::basic_regex regex("^filter .* bpf .* prog_offload_schedcls_tether_.*$");
    for (const auto& line : lines) {
        if (std::regex_match(Trim(line), regex)) return true;
    }
    return false;
}

// TODO: probably remove the test because TetherOffload* binder calls are deprecated.
TEST_F(NetdBinderTest, DISABLED_TetherOffloadForwarding) {
    SKIP_IF_EXTENDED_BPF_NOT_SUPPORTED;

    constexpr const char* kDownstreamPrefix = "2001:db8:2::/64";

    // 1500-byte packet.
    constexpr unsigned short kPayloadLen = 1500 - sizeof(ipv6hdr);
    struct packet {
        ipv6hdr hdr;
        char data[kPayloadLen];
    } __attribute__((packed)) pkt = {
            .hdr =
                    {
                            .version = 6,
                            .payload_len = htons(kPayloadLen),
                            .nexthdr = 59,  // No next header.
                            .hop_limit = 64,
                            .saddr = {{{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}},
                            .daddr = {{{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
                                        0x00, 0x00, 0x0f, 0x00, 0xca, 0xfe}}},
                    },
    };
    ASSERT_EQ(1500U, sizeof(pkt));

    // Use one of the test's tun interfaces as upstream.
    // It must be part of a network or it will not have the clsact attached.
    const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
    int fd1 = sTun.getFdForTesting();
    EXPECT_TRUE(tcQdiscExists(sTun.name()));

    // Create our own tap as a downstream.
    TunInterface tap;
    ASSERT_EQ(0, tap.init(true /* isTap */));
    ASSERT_LE(tap.name().size(), static_cast<size_t>(IFNAMSIZ));
    int fd2 = tap.getFdForTesting();

    // Set it to nonblocking so that expectPacket can work.
    int flags = fcntl(fd2, F_GETFL, 0);
    fcntl(fd2, F_SETFL, flags | O_NONBLOCK);

    // Downstream interface setup. Add to local network, add directly-connected route, etc.
    binder::Status status = mNetd->networkAddInterface(INetd::LOCAL_NET_ID, tap.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    status = mNetd->tetherInterfaceAdd(tap.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    expectTetherInterfaceConfigureForIPv6Router(tap.name());
    EXPECT_TRUE(tcQdiscExists(tap.name()));

    // Can't easily use INetd::NEXTHOP_NONE because it is a String16 constant. Use "" instead.
    status = mNetd->networkAddRoute(INetd::LOCAL_NET_ID, tap.name(), kDownstreamPrefix, "");
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Set up forwarding. All methods take intIface first and extIface second.
    status = mNetd->tetherAddForward(tap.name(), sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    status = mNetd->ipfwdAddInterfaceForward(tap.name(), sTun.name());
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
    EXPECT_TRUE(tcFilterExists(sTun.name()));

    std::vector<uint8_t> kDummyMac = {02, 00, 00, 00, 00, 00};
    uint8_t* daddr = reinterpret_cast<uint8_t*>(&pkt.hdr.daddr);
    std::vector<uint8_t> dstAddr(daddr, daddr + sizeof(pkt.hdr.daddr));

    TetherOffloadRuleParcel rule = makeTetherOffloadRule(sTun.ifindex(), tap.ifindex(), dstAddr,
                                                         128, kDummyMac, kDummyMac, sizeof(pkt));
    status = mNetd->tetherOffloadRuleAdd(rule);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Set data limit to one byte less than two packets.
    // If you get rid of the '- 1' then the second packet will get forwarded
    // and the EXPECT_FALSE(expectPacket(...)) a dozen lines down will fail.
    status = mNetd->tetherOffloadSetInterfaceQuota(sTun.ifindex(), sizeof(pkt) * 2 - 1);
    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();

    // Receive a packet on sTun.
    EXPECT_EQ((ssize_t)sizeof(pkt), write(fd1, &pkt, sizeof(pkt)));

    // Expect a packet identical to pkt, except with a TTL of 63.
    struct packet pkt2 = pkt;
    ASSERT_EQ(1500U, sizeof(pkt2));
    pkt2.hdr.hop_limit = pkt.hdr.hop_limit - 1;
    EXPECT_TRUE(expectPacket(fd2, (uint8_t*)&pkt2, sizeof(pkt2)));

    // Receive a second packet on sTun.
    EXPECT_EQ((ssize_t)sizeof(pkt), write(fd1, &pkt, sizeof(pkt)));

    // Should fail to forward due to quota limit.
    EXPECT_FALSE(expectPacket(fd2, (uint8_t*)&pkt2, sizeof(pkt2)));

    // Clean up.
    EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());

    TetherStatsParcel tetherStats;
    EXPECT_TRUE(mNetd->tetherOffloadGetAndClearStats(sTun.ifindex(), &tetherStats).isOk());
    EXPECT_EQ("", tetherStats.iface);
    EXPECT_EQ(static_cast<int64_t>(sizeof(pkt)), tetherStats.rxBytes);
    EXPECT_EQ(1, tetherStats.rxPackets);
    EXPECT_EQ(0, tetherStats.txBytes);
    EXPECT_EQ(0, tetherStats.txPackets);
    EXPECT_EQ(sTun.ifindex(), tetherStats.ifIndex);

    EXPECT_TRUE(mNetd->ipfwdRemoveInterfaceForward(tap.name(), sTun.name()).isOk());
    EXPECT_TRUE(mNetd->tetherRemoveForward(tap.name(), sTun.name()).isOk());
    EXPECT_TRUE(mNetd->networkRemoveRoute(INetd::LOCAL_NET_ID, tap.name(), kDownstreamPrefix, "")
                        .isOk());
    EXPECT_TRUE(mNetd->tetherInterfaceRemove(tap.name()).isOk());
    EXPECT_TRUE(mNetd->networkRemoveInterface(INetd::LOCAL_NET_ID, tap.name()).isOk());
    EXPECT_TRUE(mNetd->networkRemoveInterface(TEST_NETID1, sTun.name()).isOk());
}

namespace {

std::vector<std::string> dumpService(const sp<IBinder>& binder) {
    unique_fd localFd, remoteFd;
    bool success = Pipe(&localFd, &remoteFd);
    EXPECT_TRUE(success) << "Failed to open pipe for dumping: " << strerror(errno);
    if (!success) return {};

    // dump() blocks until another thread has consumed all its output.
    std::thread dumpThread = std::thread([binder, remoteFd{std::move(remoteFd)}]() {
        android::status_t ret = binder->dump(remoteFd, {});
        EXPECT_EQ(android::OK, ret) << "Error dumping service: " << android::statusToString(ret);
    });

    std::string dumpContent;

    EXPECT_TRUE(ReadFdToString(localFd.get(), &dumpContent))
            << "Error during dump: " << strerror(errno);
    dumpThread.join();

    std::stringstream dumpStream(std::move(dumpContent));
    std::vector<std::string> lines;
    std::string line;
    while (std::getline(dumpStream, line)) {
        lines.push_back(line);
    }

    return lines;
}

}  // namespace

TEST_F(NetdBinderTest, TestServiceDump) {
    sp<IBinder> binder = INetd::asBinder(mNetd);
    ASSERT_NE(nullptr, binder);

    struct TestData {
        // Expected contents of the dump command.
        const std::string output;
        // A regex that might be helpful in matching relevant lines in the output.
        // Used to make it easier to add test cases for this code.
        const std::string hintRegex;
    };
    std::vector<TestData> testData;

    // Send some IPCs and for each one add an element to testData telling us what to expect.
    const auto& config = makeNativeNetworkConfig(TEST_DUMP_NETID, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    testData.push_back(
            {"networkCreate(NativeNetworkConfig{netId: 65123, networkType: PHYSICAL, "
             "permission: 0, secure: false, vpnType: PLATFORM})",
             "networkCreate.*65123"});

    EXPECT_EQ(EEXIST, mNetd->networkCreate(config).serviceSpecificErrorCode());
    testData.push_back(
            {"networkCreate(NativeNetworkConfig{netId: 65123, networkType: PHYSICAL, "
             "permission: 0, secure: false, vpnType: PLATFORM}) "
             "-> ServiceSpecificException(17, \"File exists\")",
             "networkCreate.*65123.*17"});

    EXPECT_TRUE(mNetd->networkAddInterface(TEST_DUMP_NETID, sTun.name()).isOk());
    testData.push_back({StringPrintf("networkAddInterface(65123, %s)", sTun.name().c_str()),
                        StringPrintf("networkAddInterface.*65123.*%s", sTun.name().c_str())});

    android::net::RouteInfoParcel parcel;
    parcel.ifName = sTun.name();
    parcel.destination = "2001:db8:dead:beef::/64";
    parcel.nextHop = "fe80::dead:beef";
    parcel.mtu = 1234;
    EXPECT_TRUE(mNetd->networkAddRouteParcel(TEST_DUMP_NETID, parcel).isOk());
    testData.push_back(
            {StringPrintf("networkAddRouteParcel(65123, RouteInfoParcel{destination:"
                          " 2001:db8:dead:beef::/64, ifName: %s, nextHop: fe80::dead:beef,"
                          " mtu: 1234})",
                          sTun.name().c_str()),
             "networkAddRouteParcel.*65123.*dead:beef"});

    EXPECT_TRUE(mNetd->networkDestroy(TEST_DUMP_NETID).isOk());
    testData.push_back({"networkDestroy(65123)", "networkDestroy.*65123"});

    // Send the service dump request to netd.
    std::vector<std::string> lines = dumpService(binder);

    // Basic regexp to match dump output lines. Matches the beginning and end of the line, and
    // puts the output of the command itself into the first match group.
    // Example: "      11-05 00:23:39.481 myCommand(args) <2.02ms>".
    const std::basic_regex lineRegex(
            "^      [0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[.][0-9]{3} "
            "(.*)"
            " <[0-9]+[.][0-9]{2}ms>$");

    // For each element of testdata, check that the expected output appears in the dump output.
    // If not, fail the test and use hintRegex to print similar lines to assist in debugging.
    for (const TestData& td : testData) {
        const bool found = std::any_of(lines.begin(), lines.end(), [&](const std::string& line) {
            std::smatch match;
            if (!std::regex_match(line, match, lineRegex)) return false;
            return (match.size() == 2) && (match[1].str() == td.output);
        });
        EXPECT_TRUE(found) << "Didn't find line '" << td.output << "' in dumpsys output.";
        if (found) continue;
        std::cerr << "Similar lines" << std::endl;
        for (const auto& line : lines) {
            if (std::regex_search(line, std::basic_regex(td.hintRegex))) {
                std::cerr << line << std::endl;
            }
        }
    }
}

TEST_F(NetdBinderTest, DeprecatedTetherOffloadRuleAdd) {
    TetherOffloadRuleParcel emptyRule;
    auto status = mNetd->tetherOffloadRuleAdd(emptyRule);
    ASSERT_FALSE(status.isOk());
    ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
}

TEST_F(NetdBinderTest, DeprecatedTetherOffloadRuleRemove) {
    TetherOffloadRuleParcel emptyRule;
    auto status = mNetd->tetherOffloadRuleRemove(emptyRule);
    ASSERT_FALSE(status.isOk());
    ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
}

TEST_F(NetdBinderTest, DeprecatedTetherOffloadGetStats) {
    std::vector<TetherStatsParcel> tetherStatsList;
    auto status = mNetd->tetherOffloadGetStats(&tetherStatsList);
    ASSERT_FALSE(status.isOk());
    ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
}

TEST_F(NetdBinderTest, DeprecatedTetherOffloadSetInterfaceQuota) {
    auto status = mNetd->tetherOffloadSetInterfaceQuota(0 /* ifIndex */, 0 /* quotaBytes */);
    ASSERT_FALSE(status.isOk());
    ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
}

TEST_F(NetdBinderTest, DeprecatedTetherOffloadGetAndClearStats) {
    TetherStatsParcel tetherStats;
    auto status = mNetd->tetherOffloadGetAndClearStats(0 /* ifIndex */, &tetherStats);
    ASSERT_FALSE(status.isOk());
    ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
}

namespace {

// aliases for better reading
#define SYSTEM_DEFAULT_NETID TEST_NETID1
#define APP_DEFAULT_NETID TEST_NETID2
#define VPN_NETID TEST_NETID3

void verifyAppUidRules(std::vector<bool>&& expectedResults, std::vector<UidRangeParcel>& uidRanges,
                       const std::string& iface, uint32_t subPriority) {
    ASSERT_EQ(expectedResults.size(), uidRanges.size());
    if (iface.size()) {
        std::string action = StringPrintf("lookup %s ", iface.c_str());
        for (unsigned long i = 0; i < uidRanges.size(); i++) {
            EXPECT_EQ(expectedResults[i],
                      ipRuleExistsForRange(RULE_PRIORITY_UID_EXPLICIT_NETWORK + subPriority,
                                           uidRanges[i], action));
            EXPECT_EQ(expectedResults[i],
                      ipRuleExistsForRange(RULE_PRIORITY_UID_IMPLICIT_NETWORK + subPriority,
                                           uidRanges[i], action));
            EXPECT_EQ(expectedResults[i],
                      ipRuleExistsForRange(RULE_PRIORITY_UID_DEFAULT_NETWORK + subPriority,
                                           uidRanges[i], action));
        }
    } else {
        std::string action = "unreachable";
        for (unsigned long i = 0; i < uidRanges.size(); i++) {
            EXPECT_EQ(expectedResults[i],
                      ipRuleExistsForRange(RULE_PRIORITY_UID_EXPLICIT_NETWORK + subPriority,
                                           uidRanges[i], action));
            EXPECT_EQ(expectedResults[i],
                      ipRuleExistsForRange(RULE_PRIORITY_UID_IMPLICIT_NETWORK + subPriority,
                                           uidRanges[i], action));
            EXPECT_EQ(expectedResults[i],
                      ipRuleExistsForRange(RULE_PRIORITY_UID_DEFAULT_UNREACHABLE + subPriority,
                                           uidRanges[i], action));
        }
    }
}

void verifyAppUidRules(std::vector<bool>&& expectedResults, NativeUidRangeConfig& uidRangeConfig,
                       const std::string& iface) {
    verifyAppUidRules(move(expectedResults), uidRangeConfig.uidRanges, iface,
                      uidRangeConfig.subPriority);
}

void verifyVpnUidRules(std::vector<bool>&& expectedResults, NativeUidRangeConfig& uidRangeConfig,
                       const std::string& iface, bool secure) {
    ASSERT_EQ(expectedResults.size(), uidRangeConfig.uidRanges.size());
    std::string action = StringPrintf("lookup %s ", iface.c_str());

    uint32_t priority;
    if (secure) {
        priority = RULE_PRIORITY_SECURE_VPN;
    } else {
        priority = RULE_PRIORITY_BYPASSABLE_VPN;
    }
    for (unsigned long i = 0; i < uidRangeConfig.uidRanges.size(); i++) {
        EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(priority + uidRangeConfig.subPriority,
                                                           uidRangeConfig.uidRanges[i], action));
        EXPECT_EQ(expectedResults[i],
                  ipRuleExistsForRange(RULE_PRIORITY_EXPLICIT_NETWORK + uidRangeConfig.subPriority,
                                       uidRangeConfig.uidRanges[i], action));
        EXPECT_EQ(expectedResults[i],
                  ipRuleExistsForRange(RULE_PRIORITY_OUTPUT_INTERFACE + uidRangeConfig.subPriority,
                                       uidRangeConfig.uidRanges[i], action, iface.c_str()));
    }
}

constexpr int SUB_PRIORITY_1 = UidRanges::DEFAULT_SUB_PRIORITY + 1;
constexpr int SUB_PRIORITY_2 = UidRanges::DEFAULT_SUB_PRIORITY + 2;

constexpr int IMPLICITLY_SELECT = 0;
constexpr int EXPLICITLY_SELECT = 1;
constexpr int UNCONNECTED_SOCKET = 2;

// 1. Send data with the specified UID, on a connected or unconnected socket.
// 2. Verify if data is received from the specified fd. The fd should belong to a TUN, which has
//    been assigned to the test network.
// 3. Verify if fwmark of data is correct.
// Note: This is a helper function used by per-app default network tests. It does not implement full
// fwmark logic in netd, and it's currently sufficient. Extension may be required for more
// complicated tests.
void expectPacketSentOnNetId(uid_t uid, unsigned netId, int fd, int selectionMode) {
    Fwmark fwmark;
    const bool doConnect = (selectionMode != UNCONNECTED_SOCKET);
    EXPECT_TRUE(sendIPv6PacketFromUid(uid, V6_ADDR, &fwmark, fd, doConnect));

    Fwmark expected;
    expected.netId = netId;
    expected.explicitlySelected = (selectionMode == EXPLICITLY_SELECT);
    if (uid == AID_ROOT && selectionMode == EXPLICITLY_SELECT) {
        expected.protectedFromVpn = true;
    } else {
        expected.protectedFromVpn = false;
    }
    if (selectionMode == UNCONNECTED_SOCKET) {
        expected.permission = PERMISSION_NONE;
    } else {
        expected.permission = (uid == AID_ROOT) ? PERMISSION_SYSTEM : PERMISSION_NONE;
    }

    EXPECT_EQ(expected.intValue, fwmark.intValue);
}

void expectUnreachableError(uid_t uid, unsigned netId, int selectionMode) {
    Fwmark fwmark;
    const bool doConnect = (selectionMode != UNCONNECTED_SOCKET);
    EXPECT_TRUE(sendIPv6PacketFromUidFail(uid, V6_ADDR, &fwmark, doConnect, ENETUNREACH));

    Fwmark expected;
    expected.netId = netId;
    expected.explicitlySelected = (selectionMode == EXPLICITLY_SELECT);
    if (uid == AID_ROOT && selectionMode == EXPLICITLY_SELECT) {
        expected.protectedFromVpn = true;
    } else {
        expected.protectedFromVpn = false;
    }
    if (selectionMode == UNCONNECTED_SOCKET) {
        expected.permission = PERMISSION_NONE;
    } else {
        expected.permission = (uid == AID_ROOT) ? PERMISSION_SYSTEM : PERMISSION_NONE;
    }

    EXPECT_EQ(expected.intValue, fwmark.intValue);
}

}  // namespace

// Verify whether API reject overlapped UID ranges
TEST_F(NetdBinderTest, PerAppDefaultNetwork_OverlappedUidRanges) {
    const auto& config = makeNativeNetworkConfig(APP_DEFAULT_NETID, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(APP_DEFAULT_NETID, sTun.name()).isOk());

    std::vector<UidRangeParcel> uidRanges = {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1),
                                             makeUidRangeParcel(BASE_UID + 10, BASE_UID + 12)};
    EXPECT_TRUE(mNetd->networkAddUidRanges(APP_DEFAULT_NETID, uidRanges).isOk());

    binder::Status status;
    status = mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                        {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1)});
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    status = mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                        {makeUidRangeParcel(BASE_UID + 9, BASE_UID + 10)});
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    status = mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                        {makeUidRangeParcel(BASE_UID + 11, BASE_UID + 11)});
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    status = mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                        {makeUidRangeParcel(BASE_UID + 12, BASE_UID + 13)});
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    status = mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                        {makeUidRangeParcel(BASE_UID + 9, BASE_UID + 13)});
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    std::vector<UidRangeParcel> selfOverlappedUidRanges = {
            makeUidRangeParcel(BASE_UID + 20, BASE_UID + 20),
            makeUidRangeParcel(BASE_UID + 20, BASE_UID + 21)};
    status = mNetd->networkAddUidRanges(APP_DEFAULT_NETID, selfOverlappedUidRanges);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
}

// Verify whether IP rules for app default network are correctly configured.
TEST_F(NetdBinderTest, PerAppDefaultNetwork_VerifyIpRules) {
    const auto& config = makeNativeNetworkConfig(APP_DEFAULT_NETID, NativeNetworkType::PHYSICAL,
                                                 INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(APP_DEFAULT_NETID, sTun.name()).isOk());

    std::vector<UidRangeParcel> uidRanges = {makeUidRangeParcel(BASE_UID + 8005, BASE_UID + 8012),
                                             makeUidRangeParcel(BASE_UID + 8090, BASE_UID + 8099)};

    EXPECT_TRUE(mNetd->networkAddUidRanges(APP_DEFAULT_NETID, uidRanges).isOk());
    verifyAppUidRules({true, true} /*expectedResults*/, uidRanges, sTun.name(),
                      UidRanges::DEFAULT_SUB_PRIORITY);
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(APP_DEFAULT_NETID, {uidRanges.at(0)}).isOk());
    verifyAppUidRules({false, true} /*expectedResults*/, uidRanges, sTun.name(),
                      UidRanges::DEFAULT_SUB_PRIORITY);
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(APP_DEFAULT_NETID, {uidRanges.at(1)}).isOk());
    verifyAppUidRules({false, false} /*expectedResults*/, uidRanges, sTun.name(),
                      UidRanges::DEFAULT_SUB_PRIORITY);

    EXPECT_TRUE(mNetd->networkAddUidRanges(INetd::UNREACHABLE_NET_ID, uidRanges).isOk());
    verifyAppUidRules({true, true} /*expectedResults*/, uidRanges, "",
                      UidRanges::DEFAULT_SUB_PRIORITY);
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID, {uidRanges.at(0)}).isOk());
    verifyAppUidRules({false, true} /*expectedResults*/, uidRanges, "",
                      UidRanges::DEFAULT_SUB_PRIORITY);
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID, {uidRanges.at(1)}).isOk());
    verifyAppUidRules({false, false} /*expectedResults*/, uidRanges, "",
                      UidRanges::DEFAULT_SUB_PRIORITY);
}

// Verify whether packets go through the right network with and without per-app default network.
// Meaning of Fwmark bits (from Fwmark.h):
// 0x0000ffff - Network ID
// 0x00010000 - Explicit mark bit
// 0x00020000 - VPN protect bit
// 0x000c0000 - Permission bits
TEST_F(NetdBinderTest, PerAppDefaultNetwork_ImplicitlySelectNetwork) {
    createDefaultAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID);

    int systemDefaultFd = sTun.getFdForTesting();
    int appDefaultFd = sTun2.getFdForTesting();

    // Connections go through the system default network.
    expectPacketSentOnNetId(AID_ROOT, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID1, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);

    // Add TEST_UID1 to per-app default network.
    EXPECT_TRUE(mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                           {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
    expectPacketSentOnNetId(AID_ROOT, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID1, APP_DEFAULT_NETID, appDefaultFd, IMPLICITLY_SELECT);

    // Remove TEST_UID1 from per-app default network.
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(APP_DEFAULT_NETID,
                                              {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
    expectPacketSentOnNetId(AID_ROOT, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID1, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);

    // Prohibit TEST_UID1 from using the default network.
    EXPECT_TRUE(mNetd->networkAddUidRanges(INetd::UNREACHABLE_NET_ID,
                                           {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
    expectPacketSentOnNetId(AID_ROOT, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);
    expectUnreachableError(TEST_UID1, INetd::UNREACHABLE_NET_ID, IMPLICITLY_SELECT);

    // restore IP rules
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID,
                                              {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
}

// Verify whether packets go through the right network when app explicitly selects a network.
TEST_F(NetdBinderTest, PerAppDefaultNetwork_ExplicitlySelectNetwork) {
    createDefaultAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID);

    int systemDefaultFd = sTun.getFdForTesting();
    int appDefaultFd = sTun2.getFdForTesting();

    // Explicitly select the system default network.
    setNetworkForProcess(SYSTEM_DEFAULT_NETID);
    // Connections go through the system default network.
    expectPacketSentOnNetId(AID_ROOT, SYSTEM_DEFAULT_NETID, systemDefaultFd, EXPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID1, SYSTEM_DEFAULT_NETID, systemDefaultFd, EXPLICITLY_SELECT);

    // Set TEST_UID1 to default unreachable, which won't affect the explicitly selected network.
    // Connections go through the system default network.
    EXPECT_TRUE(mNetd->networkAddUidRanges(INetd::UNREACHABLE_NET_ID,
                                           {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
    expectPacketSentOnNetId(AID_ROOT, SYSTEM_DEFAULT_NETID, systemDefaultFd, EXPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID1, SYSTEM_DEFAULT_NETID, systemDefaultFd, EXPLICITLY_SELECT);

    // restore IP rules
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID,
                                              {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());

    // Add TEST_UID1 to per-app default network, which won't affect the explicitly selected network.
    EXPECT_TRUE(mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                           {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
    expectPacketSentOnNetId(AID_ROOT, SYSTEM_DEFAULT_NETID, systemDefaultFd, EXPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID1, SYSTEM_DEFAULT_NETID, systemDefaultFd, EXPLICITLY_SELECT);

    // Explicitly select the per-app default network.
    setNetworkForProcess(APP_DEFAULT_NETID);
    // Connections go through the per-app default network.
    expectPacketSentOnNetId(AID_ROOT, APP_DEFAULT_NETID, appDefaultFd, EXPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID1, APP_DEFAULT_NETID, appDefaultFd, EXPLICITLY_SELECT);
}

// Verify whether packets go through the right network if app does not implicitly or explicitly
// select any network.
TEST_F(NetdBinderTest, PerAppDefaultNetwork_UnconnectedSocket) {
    createDefaultAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID);

    int systemDefaultFd = sTun.getFdForTesting();
    int appDefaultFd = sTun2.getFdForTesting();

    // Connections go through the system default network.
    expectPacketSentOnNetId(AID_ROOT, NETID_UNSET, systemDefaultFd, UNCONNECTED_SOCKET);
    expectPacketSentOnNetId(TEST_UID1, NETID_UNSET, systemDefaultFd, UNCONNECTED_SOCKET);

    // Add TEST_UID1 to per-app default network. Traffic should go through the per-app default
    // network if UID is in range. Otherwise, go through the system default network.
    EXPECT_TRUE(mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                           {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
    expectPacketSentOnNetId(AID_ROOT, NETID_UNSET, systemDefaultFd, UNCONNECTED_SOCKET);
    expectPacketSentOnNetId(TEST_UID1, NETID_UNSET, appDefaultFd, UNCONNECTED_SOCKET);

    // Set TEST_UID1's default network to unreachable. Its traffic should still go through the
    // per-app default network. Other traffic go through the system default network.
    // PS: per-app default network take precedence over unreachable network. This should happens
    //     only in the transition period when both rules are briefly set.
    EXPECT_TRUE(mNetd->networkAddUidRanges(INetd::UNREACHABLE_NET_ID,
                                           {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
    expectPacketSentOnNetId(AID_ROOT, NETID_UNSET, systemDefaultFd, UNCONNECTED_SOCKET);
    expectPacketSentOnNetId(TEST_UID1, NETID_UNSET, appDefaultFd, UNCONNECTED_SOCKET);

    // Remove TEST_UID1's default network from OEM-paid network. Its traffic should get ENETUNREACH
    // error. Other traffic still go through the system default network.
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(APP_DEFAULT_NETID,
                                              {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
    expectPacketSentOnNetId(AID_ROOT, NETID_UNSET, systemDefaultFd, UNCONNECTED_SOCKET);
    expectUnreachableError(TEST_UID1, NETID_UNSET, UNCONNECTED_SOCKET);

    // restore IP rules
    EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID,
                                              {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());
}

TEST_F(NetdBinderTest, PerAppDefaultNetwork_PermissionCheck) {
    createPhysicalNetwork(APP_DEFAULT_NETID, sTun2.name(), INetd::PERMISSION_SYSTEM);

    {  // uid is not in app range. Can not set network for process.
        ScopedUidChange scopedUidChange(TEST_UID1);
        EXPECT_EQ(-EACCES, setNetworkForProcess(APP_DEFAULT_NETID));
    }

    EXPECT_TRUE(mNetd->networkAddUidRanges(APP_DEFAULT_NETID,
                                           {makeUidRangeParcel(TEST_UID1, TEST_UID1)})
                        .isOk());

    {  // uid is in app range. Can set network for process.
        ScopedUidChange scopedUidChange(TEST_UID1);
        EXPECT_EQ(0, setNetworkForProcess(APP_DEFAULT_NETID));
    }
}

class VpnParameterizedTest : public NetdBinderTest, public testing::WithParamInterface<bool> {};

// Exercise secure and bypassable VPN.
INSTANTIATE_TEST_SUITE_P(PerAppDefaultNetwork, VpnParameterizedTest, testing::Bool(),
                         [](const testing::TestParamInfo<bool>& info) {
                             return info.param ? "SecureVPN" : "BypassableVPN";
                         });

// Verify per-app default network + VPN.
TEST_P(VpnParameterizedTest, ImplicitlySelectNetwork) {
    const bool isSecureVPN = GetParam();
    createVpnAndAppDefaultNetworkWithUid(
            SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID, VPN_NETID, isSecureVPN,
            {makeUidRangeParcel(TEST_UID2, TEST_UID1)} /* app range */,
            {makeUidRangeParcel(TEST_UID3, TEST_UID2)} /* VPN range */);

    int systemDefaultFd = sTun.getFdForTesting();
    int appDefaultFd = sTun2.getFdForTesting();
    int vpnFd = sTun3.getFdForTesting();

    // uid is neither in app range, nor in VPN range. Traffic goes through system default network.
    expectPacketSentOnNetId(AID_ROOT, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);
    // uid is in VPN range, not in app range. Traffic goes through VPN.
    expectPacketSentOnNetId(TEST_UID3, (isSecureVPN ? SYSTEM_DEFAULT_NETID : VPN_NETID), vpnFd,
                            IMPLICITLY_SELECT);
    // uid is in app range, not in VPN range. Traffic goes through per-app default network.
    expectPacketSentOnNetId(TEST_UID1, APP_DEFAULT_NETID, appDefaultFd, IMPLICITLY_SELECT);
    // uid is in both app and VPN range. Traffic goes through VPN.
    expectPacketSentOnNetId(TEST_UID2, (isSecureVPN ? APP_DEFAULT_NETID : VPN_NETID), vpnFd,
                            IMPLICITLY_SELECT);
}

class VpnAndSelectNetworkParameterizedTest
    : public NetdBinderTest,
      public testing::WithParamInterface<std::tuple<bool, int>> {};

// Exercise the combination of different VPN types and different user selected networks. e.g.
// secure VPN + select on system default network
// secure VPN + select on app default network
// secure VPN + select on VPN
// bypassable VPN + select on system default network
// ...
INSTANTIATE_TEST_SUITE_P(PerAppDefaultNetwork, VpnAndSelectNetworkParameterizedTest,
                         testing::Combine(testing::Bool(),
                                          testing::Values(SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID,
                                                          VPN_NETID)),
                         [](const testing::TestParamInfo<std::tuple<bool, int>>& info) {
                             const std::string vpnType = std::get<0>(info.param)
                                                                 ? std::string("SecureVPN")
                                                                 : std::string("BypassableVPN");
                             std::string selectedNetwork;
                             switch (std::get<1>(info.param)) {
                                 case SYSTEM_DEFAULT_NETID:
                                     selectedNetwork = "SystemDefaultNetwork";
                                     break;
                                 case APP_DEFAULT_NETID:
                                     selectedNetwork = "AppDefaultNetwork";
                                     break;
                                 case VPN_NETID:
                                     selectedNetwork = "VPN";
                                     break;
                                 default:
                                     selectedNetwork = "InvalidParameter";  // Should not happen.
                             }
                             return vpnType + "_select" + selectedNetwork;
                         });

TEST_P(VpnAndSelectNetworkParameterizedTest, ExplicitlySelectNetwork) {
    bool isSecureVPN;
    int selectedNetId;
    std::tie(isSecureVPN, selectedNetId) = GetParam();
    createVpnAndAppDefaultNetworkWithUid(
            SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID, VPN_NETID, isSecureVPN,
            {makeUidRangeParcel(TEST_UID2, TEST_UID1)} /* app range */,
            {makeUidRangeParcel(TEST_UID3, TEST_UID2)} /* VPN range */);

    int expectedFd = -1;
    switch (selectedNetId) {
        case SYSTEM_DEFAULT_NETID:
            expectedFd = sTun.getFdForTesting();
            break;
        case APP_DEFAULT_NETID:
            expectedFd = sTun2.getFdForTesting();
            break;
        case VPN_NETID:
            expectedFd = sTun3.getFdForTesting();
            break;
        default:
            GTEST_LOG_(ERROR) << "unexpected netId:" << selectedNetId;  // Should not happen.
    }

    // In all following permutations, Traffic should go through the specified network if a process
    // can select network for itself. The fwmark should contain process UID and the explicit select
    // bit.
    {  // uid is neither in app range, nor in VPN range. Permission bits, protect bit, and explicit
       // select bit are all set because of AID_ROOT.
        ScopedUidChange scopedUidChange(AID_ROOT);
        EXPECT_EQ(0, setNetworkForProcess(selectedNetId));
        expectPacketSentOnNetId(AID_ROOT, selectedNetId, expectedFd, EXPLICITLY_SELECT);
    }
    {  // uid is in VPN range, not in app range.
        ScopedUidChange scopedUidChange(TEST_UID3);
        // Cannot select non-VPN networks when uid is subject to secure VPN.
        if (isSecureVPN && selectedNetId != VPN_NETID) {
            EXPECT_EQ(-EPERM, setNetworkForProcess(selectedNetId));
        } else {
            EXPECT_EQ(0, setNetworkForProcess(selectedNetId));
            expectPacketSentOnNetId(TEST_UID3, selectedNetId, expectedFd, EXPLICITLY_SELECT);
        }
    }
    {  // uid is in app range, not in VPN range.
        ScopedUidChange scopedUidChange(TEST_UID1);
        // Cannot select the VPN because the VPN does not applies to the UID.
        if (selectedNetId == VPN_NETID) {
            EXPECT_EQ(-EPERM, setNetworkForProcess(selectedNetId));
        } else {
            EXPECT_EQ(0, setNetworkForProcess(selectedNetId));
            expectPacketSentOnNetId(TEST_UID1, selectedNetId, expectedFd, EXPLICITLY_SELECT);
        }
    }
    {  // uid is in both app range and VPN range.
        ScopedUidChange scopedUidChange(TEST_UID2);
        // Cannot select non-VPN networks when uid is subject to secure VPN.
        if (isSecureVPN && selectedNetId != VPN_NETID) {
            EXPECT_EQ(-EPERM, setNetworkForProcess(selectedNetId));
        } else {
            EXPECT_EQ(0, setNetworkForProcess(selectedNetId));
            expectPacketSentOnNetId(TEST_UID2, selectedNetId, expectedFd, EXPLICITLY_SELECT);
        }
    }
}

TEST_P(VpnParameterizedTest, UnconnectedSocket) {
    const bool isSecureVPN = GetParam();
    createVpnAndAppDefaultNetworkWithUid(
            SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID, VPN_NETID, isSecureVPN,
            {makeUidRangeParcel(TEST_UID2, TEST_UID1)} /* app range */,
            {makeUidRangeParcel(TEST_UID3, TEST_UID2)} /* VPN range */);

    int systemDefaultFd = sTun.getFdForTesting();
    int appDefaultFd = sTun2.getFdForTesting();
    int vpnFd = sTun3.getFdForTesting();

    // uid is neither in app range, nor in VPN range. Traffic goes through system default network.
    expectPacketSentOnNetId(AID_ROOT, NETID_UNSET, systemDefaultFd, UNCONNECTED_SOCKET);
    // uid is in VPN range, not in app range. Traffic goes through VPN.
    expectPacketSentOnNetId(TEST_UID3, NETID_UNSET, vpnFd, UNCONNECTED_SOCKET);
    // uid is in app range, not in VPN range. Traffic goes through per-app default network.
    expectPacketSentOnNetId(TEST_UID1, NETID_UNSET, appDefaultFd, UNCONNECTED_SOCKET);
    // uid is in both app and VPN range. Traffic goes through VPN.
    expectPacketSentOnNetId(TEST_UID2, NETID_UNSET, vpnFd, UNCONNECTED_SOCKET);
}

TEST_F(NetdBinderTest, NetworkCreate) {
    auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                          INetd::PERMISSION_NONE, false);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkDestroy(config.netId).isOk());

    config.networkType = NativeNetworkType::VIRTUAL;
    config.secure = true;
    config.vpnType = NativeVpnType::OEM;
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());

    // invalid network type
    auto wrongConfig = makeNativeNetworkConfig(TEST_NETID2, static_cast<NativeNetworkType>(-1),
                                               INetd::PERMISSION_NONE, false);
    EXPECT_EQ(EINVAL, mNetd->networkCreate(wrongConfig).serviceSpecificErrorCode());

    // invalid VPN type
    wrongConfig.networkType = NativeNetworkType::VIRTUAL;
    wrongConfig.vpnType = static_cast<NativeVpnType>(-1);
    EXPECT_EQ(EINVAL, mNetd->networkCreate(wrongConfig).serviceSpecificErrorCode());
}

// Verifies valid and invalid inputs on networkAddUidRangesParcel method.
TEST_F(NetdBinderTest, UidRangeSubPriority_ValidateInputs) {
    createVpnAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID, VPN_NETID,
                                     /*isSecureVPN=*/true);
    // Invalid priority -1 on a physical network.
    NativeUidRangeConfig uidRangeConfig =
            makeNativeUidRangeConfig(APP_DEFAULT_NETID, {makeUidRangeParcel(BASE_UID, BASE_UID)},
                                     UidRanges::DEFAULT_SUB_PRIORITY - 1);
    binder::Status status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    // Invalid priority 1000 on a physical network.
    uidRangeConfig.subPriority = UidRanges::LOWEST_SUB_PRIORITY + 1;
    status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    // Virtual networks support only default priority.
    uidRangeConfig.netId = VPN_NETID;
    uidRangeConfig.subPriority = SUB_PRIORITY_1;
    status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    // For a single network, identical UID ranges with different priorities are allowed.
    uidRangeConfig.netId = APP_DEFAULT_NETID;
    uidRangeConfig.subPriority = SUB_PRIORITY_1;
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig).isOk());
    uidRangeConfig.subPriority = SUB_PRIORITY_2;
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig).isOk());

    // For a single network, identical UID ranges with the same priority is invalid.
    status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());

    // Overlapping ranges is invalid.
    uidRangeConfig.uidRanges = {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1),
                                makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1)};
    status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
    EXPECT_FALSE(status.isOk());
    EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
}

// Examines whether IP rules for app default network with subsidiary priorities are correctly added
// and removed.
TEST_F(NetdBinderTest, UidRangeSubPriority_VerifyPhysicalNwIpRules) {
    createPhysicalNetwork(TEST_NETID1, sTun.name());
    EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
    createPhysicalNetwork(TEST_NETID2, sTun2.name());
    EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID2, sTun2.name(), "::/0", "").isOk());

    // Adds priority 1 setting
    NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
            TEST_NETID1, {makeUidRangeParcel(BASE_UID, BASE_UID)}, SUB_PRIORITY_1);
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
    verifyAppUidRules({true}, uidRangeConfig1, sTun.name());
    // Adds priority 2 setting
    NativeUidRangeConfig uidRangeConfig2 = makeNativeUidRangeConfig(
            TEST_NETID2, {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1)}, SUB_PRIORITY_2);
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
    verifyAppUidRules({true}, uidRangeConfig2, sTun2.name());
    // Adds another priority 2 setting
    NativeUidRangeConfig uidRangeConfig3 = makeNativeUidRangeConfig(
            INetd::UNREACHABLE_NET_ID, {makeUidRangeParcel(BASE_UID + 2, BASE_UID + 2)},
            SUB_PRIORITY_2);
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig3).isOk());
    verifyAppUidRules({true}, uidRangeConfig3, "");

    // Removes.
    EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
    verifyAppUidRules({false}, uidRangeConfig1, sTun.name());
    verifyAppUidRules({true}, uidRangeConfig2, sTun2.name());
    verifyAppUidRules({true}, uidRangeConfig3, "");
    EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig2).isOk());
    verifyAppUidRules({false}, uidRangeConfig1, sTun.name());
    verifyAppUidRules({false}, uidRangeConfig2, sTun2.name());
    verifyAppUidRules({true}, uidRangeConfig3, "");
    EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig3).isOk());
    verifyAppUidRules({false}, uidRangeConfig1, sTun.name());
    verifyAppUidRules({false}, uidRangeConfig2, sTun2.name());
    verifyAppUidRules({false}, uidRangeConfig3, "");
}

// Verify uid range rules on virtual network.
TEST_P(VpnParameterizedTest, UidRangeSubPriority_VerifyVpnIpRules) {
    const bool isSecureVPN = GetParam();
    constexpr int VPN_NETID2 = TEST_NETID2;

    // Create 2 VPNs, using sTun and sTun2.
    auto config = makeNativeNetworkConfig(VPN_NETID, NativeNetworkType::VIRTUAL,
                                          INetd::PERMISSION_NONE, isSecureVPN);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(VPN_NETID, sTun.name()).isOk());

    config = makeNativeNetworkConfig(VPN_NETID2, NativeNetworkType::VIRTUAL, INetd::PERMISSION_NONE,
                                     isSecureVPN);
    EXPECT_TRUE(mNetd->networkCreate(config).isOk());
    EXPECT_TRUE(mNetd->networkAddInterface(VPN_NETID2, sTun2.name()).isOk());

    // Assign uid ranges to different VPNs. Check if rules match.
    NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
            VPN_NETID, {makeUidRangeParcel(BASE_UID, BASE_UID)}, UidRanges::DEFAULT_SUB_PRIORITY);
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
    verifyVpnUidRules({true}, uidRangeConfig1, sTun.name(), isSecureVPN);

    NativeUidRangeConfig uidRangeConfig2 =
            makeNativeUidRangeConfig(VPN_NETID2, {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1)},
                                     UidRanges::DEFAULT_SUB_PRIORITY);
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
    verifyVpnUidRules({true}, uidRangeConfig2, sTun2.name(), isSecureVPN);

    // Remove uid configs one-by-one. Check if rules match.
    EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
    verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN);
    verifyVpnUidRules({true}, uidRangeConfig2, sTun2.name(), isSecureVPN);
    EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig2).isOk());
    verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN);
    verifyVpnUidRules({false}, uidRangeConfig2, sTun2.name(), isSecureVPN);
}

// Verify if packets go through the right network when subsidiary priority and VPN works together.
//
// Test config:
// +----------+------------------------+-------------------------------------------+
// | Priority |          UID           |             Assigned Network              |
// +----------+------------------------+-------------------------------------------+
// |        0 | TEST_UID1              | VPN bypassable (VPN_NETID)                |
// +----------+------------------------+-------------------------------------------+
// |        1 | TEST_UID1, TEST_UID2,  | Physical Network 1 (APP_DEFAULT_1_NETID)  |
// |        1 | TEST_UID3              | Physical Network 2 (APP_DEFAULT_2_NETID)  |
// |        1 | TEST_UID5              | Unreachable Network (UNREACHABLE_NET_ID)  |
// +----------+------------------------+-------------------------------------------+
// |        2 | TEST_UID3              | Physical Network 1 (APP_DEFAULT_1_NETID)  |
// |        2 | TEST_UID4, TEST_UID5   | Physical Network 2 (APP_DEFAULT_2_NETID)  |
// +----------+------------------------+-------------------------------------------+
//
// Expected results:
// +-----------+------------------------+
// |    UID    |    Using Network       |
// +-----------+------------------------+
// | TEST_UID1 | VPN                    |
// | TEST_UID2 | Physical Network 1     |
// | TEST_UID3 | Physical Network 2     |
// | TEST_UID4 | Physical Network 2     |
// | TEST_UID5 | Unreachable Network    |
// | TEST_UID6 | System Default Network |
// +-----------+------------------------+
//
// SYSTEM_DEFAULT_NETID uses sTun.
// APP_DEFAULT_1_NETID uses sTun2.
// VPN_NETID uses sTun3.
// APP_DEFAULT_2_NETID uses sTun4.
//
TEST_F(NetdBinderTest, UidRangeSubPriority_ImplicitlySelectNetwork) {
    constexpr int APP_DEFAULT_1_NETID = TEST_NETID2;
    constexpr int APP_DEFAULT_2_NETID = TEST_NETID4;

    // Creates 4 networks.
    createVpnAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_1_NETID, VPN_NETID,
                                     /*isSecureVPN=*/false);
    createPhysicalNetwork(APP_DEFAULT_2_NETID, sTun4.name());
    EXPECT_TRUE(mNetd->networkAddRoute(APP_DEFAULT_2_NETID, sTun4.name(), "::/0", "").isOk());

    // Adds VPN setting.
    NativeUidRangeConfig uidRangeConfigVpn = makeNativeUidRangeConfig(
            VPN_NETID, {makeUidRangeParcel(TEST_UID1, TEST_UID1)}, UidRanges::DEFAULT_SUB_PRIORITY);
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfigVpn).isOk());

    // Adds uidRangeConfig1 setting.
    NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
            APP_DEFAULT_1_NETID,
            {makeUidRangeParcel(TEST_UID1, TEST_UID1), makeUidRangeParcel(TEST_UID2, TEST_UID2)},
            SUB_PRIORITY_1);
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
    uidRangeConfig1.netId = APP_DEFAULT_2_NETID;
    uidRangeConfig1.uidRanges = {makeUidRangeParcel(TEST_UID3, TEST_UID3)};
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
    uidRangeConfig1.netId = INetd::UNREACHABLE_NET_ID;
    uidRangeConfig1.uidRanges = {makeUidRangeParcel(TEST_UID5, TEST_UID5)};
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());

    // Adds uidRangeConfig2 setting.
    NativeUidRangeConfig uidRangeConfig2 = makeNativeUidRangeConfig(
            APP_DEFAULT_1_NETID, {makeUidRangeParcel(TEST_UID3, TEST_UID3)}, SUB_PRIORITY_2);
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
    uidRangeConfig2.netId = APP_DEFAULT_2_NETID;
    uidRangeConfig2.uidRanges = {makeUidRangeParcel(TEST_UID4, TEST_UID4),
                                 makeUidRangeParcel(TEST_UID5, TEST_UID5)};
    EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());

    int systemDefaultFd = sTun.getFdForTesting();
    int appDefault_1_Fd = sTun2.getFdForTesting();
    int vpnFd = sTun3.getFdForTesting();
    int appDefault_2_Fd = sTun4.getFdForTesting();
    // Verify routings.
    expectPacketSentOnNetId(TEST_UID1, VPN_NETID, vpnFd, IMPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID2, APP_DEFAULT_1_NETID, appDefault_1_Fd, IMPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID3, APP_DEFAULT_2_NETID, appDefault_2_Fd, IMPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID4, APP_DEFAULT_2_NETID, appDefault_2_Fd, IMPLICITLY_SELECT);
    expectUnreachableError(TEST_UID5, INetd::UNREACHABLE_NET_ID, IMPLICITLY_SELECT);
    expectPacketSentOnNetId(TEST_UID6, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);

    // Remove test rules from the unreachable network.
    EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
}