// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/quic/qbone/platform/netlink.h"

#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/container/node_hash_set.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/qbone/platform/mock_kernel.h"
#include "quiche/quic/qbone/qbone_constants.h"

namespace quic::test {
namespace {

using ::testing::_;
using ::testing::Contains;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::Unused;

const int kSocketFd = 101;

class NetlinkTest : public QuicTest {
 protected:
  NetlinkTest() {
    ON_CALL(mock_kernel_, socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE))
        .WillByDefault(Invoke([this](Unused, Unused, Unused) {
          EXPECT_CALL(mock_kernel_, close(kSocketFd)).WillOnce(Return(0));
          return kSocketFd;
        }));
  }

  void ExpectNetlinkPacket(
      uint16_t type, uint16_t flags,
      const std::function<ssize_t(void* buf, size_t len, int seq)>&
          recv_callback,
      const std::function<void(const void* buf, size_t len)>& send_callback =
          nullptr) {
    static int seq = -1;
    InSequence s;

    EXPECT_CALL(mock_kernel_, sendmsg(kSocketFd, _, _))
        .WillOnce(Invoke([type, flags, send_callback](
                             Unused, const struct msghdr* msg, int) {
          EXPECT_EQ(sizeof(struct sockaddr_nl), msg->msg_namelen);
          auto* nl_addr =
              reinterpret_cast<const struct sockaddr_nl*>(msg->msg_name);
          EXPECT_EQ(AF_NETLINK, nl_addr->nl_family);
          EXPECT_EQ(0, nl_addr->nl_pid);
          EXPECT_EQ(0, nl_addr->nl_groups);

          EXPECT_GE(msg->msg_iovlen, 1);
          EXPECT_GE(msg->msg_iov[0].iov_len, sizeof(struct nlmsghdr));

          std::string buf;
          for (int i = 0; i < msg->msg_iovlen; i++) {
            buf.append(
                std::string(reinterpret_cast<char*>(msg->msg_iov[i].iov_base),
                            msg->msg_iov[i].iov_len));
          }

          auto* netlink_message =
              reinterpret_cast<const struct nlmsghdr*>(buf.c_str());
          EXPECT_EQ(type, netlink_message->nlmsg_type);
          EXPECT_EQ(flags, netlink_message->nlmsg_flags);
          EXPECT_GE(buf.size(), netlink_message->nlmsg_len);

          if (send_callback != nullptr) {
            send_callback(buf.c_str(), buf.size());
          }

          QUICHE_CHECK_EQ(seq, -1);
          seq = netlink_message->nlmsg_seq;
          return buf.size();
        }));

    EXPECT_CALL(mock_kernel_,
                recvfrom(kSocketFd, _, 0, MSG_PEEK | MSG_TRUNC, _, _))
        .WillOnce(Invoke([this, recv_callback](Unused, Unused, Unused, Unused,
                                               struct sockaddr* src_addr,
                                               socklen_t* addrlen) {
          auto* nl_addr = reinterpret_cast<struct sockaddr_nl*>(src_addr);
          nl_addr->nl_family = AF_NETLINK;
          nl_addr->nl_pid = 0;     // from kernel
          nl_addr->nl_groups = 0;  // no multicast

          int ret = recv_callback(reply_packet_, sizeof(reply_packet_), seq);
          QUICHE_CHECK_LE(ret, sizeof(reply_packet_));
          return ret;
        }));

    EXPECT_CALL(mock_kernel_, recvfrom(kSocketFd, _, _, _, _, _))
        .WillOnce(Invoke([recv_callback](Unused, void* buf, size_t len, Unused,
                                         struct sockaddr* src_addr,
                                         socklen_t* addrlen) {
          auto* nl_addr = reinterpret_cast<struct sockaddr_nl*>(src_addr);
          nl_addr->nl_family = AF_NETLINK;
          nl_addr->nl_pid = 0;     // from kernel
          nl_addr->nl_groups = 0;  // no multicast

          int ret = recv_callback(buf, len, seq);
          EXPECT_GE(len, ret);
          seq = -1;
          return ret;
        }));
  }

  char reply_packet_[4096];
  MockKernel mock_kernel_;
};

void AddRTA(struct nlmsghdr* netlink_message, uint16_t type, const void* data,
            size_t len) {
  auto* next_header_ptr = reinterpret_cast<char*>(netlink_message) +
                          NLMSG_ALIGN(netlink_message->nlmsg_len);

  auto* rta = reinterpret_cast<struct rtattr*>(next_header_ptr);
  rta->rta_type = type;
  rta->rta_len = RTA_LENGTH(len);
  memcpy(RTA_DATA(rta), data, len);

  netlink_message->nlmsg_len =
      NLMSG_ALIGN(netlink_message->nlmsg_len) + RTA_LENGTH(len);
}

void CreateIfinfomsg(struct nlmsghdr* netlink_message,
                     const std::string& interface_name, uint16_t type,
                     int index, unsigned int flags, unsigned int change,
                     uint8_t address[], int address_len, uint8_t broadcast[],
                     int broadcast_len) {
  auto* interface_info =
      reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
  interface_info->ifi_family = AF_UNSPEC;
  interface_info->ifi_type = type;
  interface_info->ifi_index = index;
  interface_info->ifi_flags = flags;
  interface_info->ifi_change = change;
  netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));

  // Add address
  AddRTA(netlink_message, IFLA_ADDRESS, address, address_len);

  // Add broadcast address
  AddRTA(netlink_message, IFLA_BROADCAST, broadcast, broadcast_len);

  // Add name
  AddRTA(netlink_message, IFLA_IFNAME, interface_name.c_str(),
         interface_name.size());
}

struct nlmsghdr* CreateNetlinkMessage(void* buf,  // NOLINT
                                      struct nlmsghdr* previous_netlink_message,
                                      uint16_t type, int seq) {
  auto* next_header_ptr = reinterpret_cast<char*>(buf);
  if (previous_netlink_message != nullptr) {
    next_header_ptr = reinterpret_cast<char*>(previous_netlink_message) +
                      NLMSG_ALIGN(previous_netlink_message->nlmsg_len);
  }
  auto* netlink_message = reinterpret_cast<nlmsghdr*>(next_header_ptr);
  netlink_message->nlmsg_len = NLMSG_LENGTH(0);
  netlink_message->nlmsg_type = type;
  netlink_message->nlmsg_flags = NLM_F_MULTI;
  netlink_message->nlmsg_pid = 0;  // from the kernel
  netlink_message->nlmsg_seq = seq;

  return netlink_message;
}

void CreateIfaddrmsg(struct nlmsghdr* nlm, int interface_index,
                     unsigned char prefixlen, unsigned char flags,
                     unsigned char scope, QuicIpAddress ip) {
  QUICHE_CHECK(ip.IsInitialized());
  unsigned char family;
  switch (ip.address_family()) {
    case IpAddressFamily::IP_V4:
      family = AF_INET;
      break;
    case IpAddressFamily::IP_V6:
      family = AF_INET6;
      break;
    default:
      QUIC_BUG(quic_bug_11034_1)
          << absl::StrCat("unexpected address family: ", ip.address_family());
      family = AF_UNSPEC;
  }
  auto* msg = reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(nlm));
  msg->ifa_family = family;
  msg->ifa_prefixlen = prefixlen;
  msg->ifa_flags = flags;
  msg->ifa_scope = scope;
  msg->ifa_index = interface_index;
  nlm->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));

  // Add local address
  AddRTA(nlm, IFA_LOCAL, ip.ToPackedString().c_str(),
         ip.ToPackedString().size());
}

void CreateRtmsg(struct nlmsghdr* nlm, unsigned char family,
                 unsigned char destination_length, unsigned char source_length,
                 unsigned char tos, unsigned char table, unsigned char protocol,
                 unsigned char scope, unsigned char type, unsigned int flags,
                 QuicIpAddress destination, int interface_index) {
  auto* msg = reinterpret_cast<struct rtmsg*>(NLMSG_DATA(nlm));
  msg->rtm_family = family;
  msg->rtm_dst_len = destination_length;
  msg->rtm_src_len = source_length;
  msg->rtm_tos = tos;
  msg->rtm_table = table;
  msg->rtm_protocol = protocol;
  msg->rtm_scope = scope;
  msg->rtm_type = type;
  msg->rtm_flags = flags;
  nlm->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));

  // Add destination
  AddRTA(nlm, RTA_DST, destination.ToPackedString().c_str(),
         destination.ToPackedString().size());

  // Add egress interface
  AddRTA(nlm, RTA_OIF, &interface_index, sizeof(interface_index));
}

TEST_F(NetlinkTest, GetLinkInfoWorks) {
  auto netlink = std::make_unique<Netlink>(&mock_kernel_);

  uint8_t hwaddr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
  uint8_t bcaddr[] = {'c', 'b', 'a', 'f', 'e', 'd'};

  ExpectNetlinkPacket(
      RTM_GETLINK, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
      [&hwaddr, &bcaddr](void* buf, size_t len, int seq) {
        int ret = 0;

        struct nlmsghdr* netlink_message =
            CreateNetlinkMessage(buf, nullptr, RTM_NEWLINK, seq);
        CreateIfinfomsg(netlink_message, "tun0", /* type = */ 1,
                        /* index = */ 7,
                        /* flags = */ 0,
                        /* change = */ 0xFFFFFFFF, hwaddr, 6, bcaddr, 6);
        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);

        netlink_message =
            CreateNetlinkMessage(buf, netlink_message, NLMSG_DONE, seq);
        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);

        return ret;
      });

  Netlink::LinkInfo link_info;
  EXPECT_TRUE(netlink->GetLinkInfo("tun0", &link_info));

  EXPECT_EQ(7, link_info.index);
  EXPECT_EQ(1, link_info.type);

  for (int i = 0; i < link_info.hardware_address_length; ++i) {
    EXPECT_EQ(hwaddr[i], link_info.hardware_address[i]);
  }
  for (int i = 0; i < link_info.broadcast_address_length; ++i) {
    EXPECT_EQ(bcaddr[i], link_info.broadcast_address[i]);
  }
}

TEST_F(NetlinkTest, GetAddressesWorks) {
  auto netlink = std::make_unique<Netlink>(&mock_kernel_);

  absl::node_hash_set<std::string> addresses = {
      QuicIpAddress::Any4().ToString(), QuicIpAddress::Any6().ToString()};

  ExpectNetlinkPacket(
      RTM_GETADDR, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
      [&addresses](void* buf, size_t len, int seq) {
        int ret = 0;

        struct nlmsghdr* nlm = nullptr;

        for (const auto& address : addresses) {
          QuicIpAddress ip;
          ip.FromString(address);
          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 24,
                          /* flags = */ 0, /* scope = */ RT_SCOPE_UNIVERSE, ip);

          ret += NLMSG_ALIGN(nlm->nlmsg_len);
        }

        // Create IPs with unwanted flags.
        {
          QuicIpAddress ip;
          ip.FromString("10.0.0.1");
          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 16,
                          /* flags = */ IFA_F_OPTIMISTIC, /* scope = */
                          RT_SCOPE_UNIVERSE, ip);

          ret += NLMSG_ALIGN(nlm->nlmsg_len);

          ip.FromString("10.0.0.2");
          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 16,
                          /* flags = */ IFA_F_TENTATIVE, /* scope = */
                          RT_SCOPE_UNIVERSE, ip);

          ret += NLMSG_ALIGN(nlm->nlmsg_len);
        }

        nlm = CreateNetlinkMessage(buf, nlm, NLMSG_DONE, seq);
        ret += NLMSG_ALIGN(nlm->nlmsg_len);

        return ret;
      });

  std::vector<Netlink::AddressInfo> reported_addresses;
  int num_ipv6_nodad_dadfailed_addresses = 0;
  EXPECT_TRUE(netlink->GetAddresses(7, IFA_F_TENTATIVE | IFA_F_OPTIMISTIC,
                                    &reported_addresses,
                                    &num_ipv6_nodad_dadfailed_addresses));

  for (const auto& reported_address : reported_addresses) {
    EXPECT_TRUE(reported_address.local_address.IsInitialized());
    EXPECT_FALSE(reported_address.interface_address.IsInitialized());
    EXPECT_THAT(addresses, Contains(reported_address.local_address.ToString()));
    addresses.erase(reported_address.local_address.ToString());

    EXPECT_EQ(24, reported_address.prefix_length);
  }

  EXPECT_TRUE(addresses.empty());
}

TEST_F(NetlinkTest, ChangeLocalAddressAdd) {
  auto netlink = std::make_unique<Netlink>(&mock_kernel_);

  QuicIpAddress ip = QuicIpAddress::Any6();
  ExpectNetlinkPacket(
      RTM_NEWADDR, NLM_F_ACK | NLM_F_REQUEST,
      [](void* buf, size_t len, int seq) {
        struct nlmsghdr* netlink_message =
            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
        auto* err =
            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
        // Ack the request
        err->error = 0;
        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
        return netlink_message->nlmsg_len;
      },
      [ip](const void* buf, size_t len) {
        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
        auto* ifa = reinterpret_cast<const struct ifaddrmsg*>(
            NLMSG_DATA(netlink_message));
        EXPECT_EQ(19, ifa->ifa_prefixlen);
        EXPECT_EQ(RT_SCOPE_UNIVERSE, ifa->ifa_scope);
        EXPECT_EQ(IFA_F_PERMANENT, ifa->ifa_flags);
        EXPECT_EQ(7, ifa->ifa_index);
        EXPECT_EQ(AF_INET6, ifa->ifa_family);

        const struct rtattr* rta;
        int payload_length = IFA_PAYLOAD(netlink_message);
        int num_rta = 0;
        for (rta = IFA_RTA(ifa); RTA_OK(rta, payload_length);
             rta = RTA_NEXT(rta, payload_length)) {
          switch (rta->rta_type) {
            case IFA_LOCAL: {
              EXPECT_EQ(ip.ToPackedString().size(), RTA_PAYLOAD(rta));
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(ip, address);
              break;
            }
            case IFA_CACHEINFO: {
              EXPECT_EQ(sizeof(struct ifa_cacheinfo), RTA_PAYLOAD(rta));
              const auto* cache_info =
                  reinterpret_cast<const struct ifa_cacheinfo*>(RTA_DATA(rta));
              EXPECT_EQ(8, cache_info->ifa_prefered);  // common_typos_disable
              EXPECT_EQ(6, cache_info->ifa_valid);
              EXPECT_EQ(4, cache_info->cstamp);
              EXPECT_EQ(2, cache_info->tstamp);
              break;
            }
            default:
              EXPECT_TRUE(false) << "Seeing rtattr that should not exist";
          }
          ++num_rta;
        }
        EXPECT_EQ(2, num_rta);
      });

  struct {
    struct rtattr rta;
    struct ifa_cacheinfo cache_info;
  } additional_rta;

  additional_rta.rta.rta_type = IFA_CACHEINFO;
  additional_rta.rta.rta_len = RTA_LENGTH(sizeof(struct ifa_cacheinfo));
  additional_rta.cache_info.ifa_prefered = 8;
  additional_rta.cache_info.ifa_valid = 6;
  additional_rta.cache_info.cstamp = 4;
  additional_rta.cache_info.tstamp = 2;

  EXPECT_TRUE(netlink->ChangeLocalAddress(7, Netlink::Verb::kAdd, ip, 19,
                                          IFA_F_PERMANENT, RT_SCOPE_UNIVERSE,
                                          {&additional_rta.rta}));
}

TEST_F(NetlinkTest, ChangeLocalAddressRemove) {
  auto netlink = std::make_unique<Netlink>(&mock_kernel_);

  QuicIpAddress ip = QuicIpAddress::Any4();
  ExpectNetlinkPacket(
      RTM_DELADDR, NLM_F_ACK | NLM_F_REQUEST,
      [](void* buf, size_t len, int seq) {
        struct nlmsghdr* netlink_message =
            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
        auto* err =
            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
        // Ack the request
        err->error = 0;
        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
        return netlink_message->nlmsg_len;
      },
      [ip](const void* buf, size_t len) {
        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
        auto* ifa = reinterpret_cast<const struct ifaddrmsg*>(
            NLMSG_DATA(netlink_message));
        EXPECT_EQ(32, ifa->ifa_prefixlen);
        EXPECT_EQ(RT_SCOPE_UNIVERSE, ifa->ifa_scope);
        EXPECT_EQ(0, ifa->ifa_flags);
        EXPECT_EQ(7, ifa->ifa_index);
        EXPECT_EQ(AF_INET, ifa->ifa_family);

        const struct rtattr* rta;
        int payload_length = IFA_PAYLOAD(netlink_message);
        int num_rta = 0;
        for (rta = IFA_RTA(ifa); RTA_OK(rta, payload_length);
             rta = RTA_NEXT(rta, payload_length)) {
          switch (rta->rta_type) {
            case IFA_LOCAL: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(in_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(ip, address);
              break;
            }
            default:
              EXPECT_TRUE(false) << "Seeing rtattr that should not exist";
          }
          ++num_rta;
        }
        EXPECT_EQ(1, num_rta);
      });

  EXPECT_TRUE(netlink->ChangeLocalAddress(7, Netlink::Verb::kRemove, ip, 32, 0,
                                          RT_SCOPE_UNIVERSE, {}));
}

TEST_F(NetlinkTest, GetRouteInfoWorks) {
  auto netlink = std::make_unique<Netlink>(&mock_kernel_);

  QuicIpAddress destination;
  ASSERT_TRUE(destination.FromString("f800::2"));
  ExpectNetlinkPacket(RTM_GETROUTE, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
                      [destination](void* buf, size_t len, int seq) {
                        int ret = 0;
                        struct nlmsghdr* netlink_message = CreateNetlinkMessage(
                            buf, nullptr, RTM_NEWROUTE, seq);
                        CreateRtmsg(netlink_message, AF_INET6, 48, 0, 0,
                                    RT_TABLE_MAIN, RTPROT_STATIC, RT_SCOPE_LINK,
                                    RTN_UNICAST, 0, destination, 7);
                        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);

                        netlink_message = CreateNetlinkMessage(
                            buf, netlink_message, NLMSG_DONE, seq);
                        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);

                        QUIC_LOG(INFO) << "ret: " << ret;
                        return ret;
                      });

  std::vector<Netlink::RoutingRule> routing_rules;
  EXPECT_TRUE(netlink->GetRouteInfo(&routing_rules));

  ASSERT_EQ(1, routing_rules.size());
  EXPECT_EQ(RT_SCOPE_LINK, routing_rules[0].scope);
  EXPECT_EQ(IpRange(destination, 48).ToString(),
            routing_rules[0].destination_subnet.ToString());
  EXPECT_FALSE(routing_rules[0].preferred_source.IsInitialized());
  EXPECT_EQ(7, routing_rules[0].out_interface);
}

TEST_F(NetlinkTest, ChangeRouteAdd) {
  auto netlink = std::make_unique<Netlink>(&mock_kernel_);

  QuicIpAddress preferred_ip;
  preferred_ip.FromString("ff80:dead:beef::1");
  IpRange subnet;
  subnet.FromString("ff80:dead:beef::/48");
  int egress_interface_index = 7;
  ExpectNetlinkPacket(
      RTM_NEWROUTE, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL,
      [](void* buf, size_t len, int seq) {
        struct nlmsghdr* netlink_message =
            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
        auto* err =
            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
        // Ack the request
        err->error = 0;
        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
        return netlink_message->nlmsg_len;
      },
      [preferred_ip, subnet, egress_interface_index](const void* buf,
                                                     size_t len) {
        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
        auto* rtm =
            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
        EXPECT_EQ(AF_INET6, rtm->rtm_family);
        EXPECT_EQ(48, rtm->rtm_dst_len);
        EXPECT_EQ(0, rtm->rtm_src_len);
        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
        EXPECT_EQ(RTPROT_STATIC, rtm->rtm_protocol);
        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);

        const struct rtattr* rta;
        int payload_length = RTM_PAYLOAD(netlink_message);
        int num_rta = 0;
        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
             rta = RTA_NEXT(rta, payload_length)) {
          switch (rta->rta_type) {
            case RTA_PREFSRC: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(preferred_ip, address);
              break;
            }
            case RTA_GATEWAY: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(*QboneConstants::GatewayAddress(), address);
              break;
            }
            case RTA_OIF: {
              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
              const auto* interface_index =
                  reinterpret_cast<const int*>(RTA_DATA(rta));
              EXPECT_EQ(egress_interface_index, *interface_index);
              break;
            }
            case RTA_DST: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(subnet.ToString(),
                        IpRange(address, rtm->rtm_dst_len).ToString());
              break;
            }
            case RTA_TABLE: {
              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
                        QboneConstants::kQboneRouteTableId);
              break;
            }
            default:
              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
          }
          ++num_rta;
        }
        EXPECT_EQ(5, num_rta);
      });
  EXPECT_TRUE(netlink->ChangeRoute(
      Netlink::Verb::kAdd, QboneConstants::kQboneRouteTableId, subnet,
      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
}

TEST_F(NetlinkTest, ChangeRouteRemove) {
  auto netlink = std::make_unique<Netlink>(&mock_kernel_);

  QuicIpAddress preferred_ip;
  preferred_ip.FromString("ff80:dead:beef::1");
  IpRange subnet;
  subnet.FromString("ff80:dead:beef::/48");
  int egress_interface_index = 7;
  ExpectNetlinkPacket(
      RTM_DELROUTE, NLM_F_ACK | NLM_F_REQUEST,
      [](void* buf, size_t len, int seq) {
        struct nlmsghdr* netlink_message =
            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
        auto* err =
            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
        // Ack the request
        err->error = 0;
        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
        return netlink_message->nlmsg_len;
      },
      [preferred_ip, subnet, egress_interface_index](const void* buf,
                                                     size_t len) {
        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
        auto* rtm =
            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
        EXPECT_EQ(AF_INET6, rtm->rtm_family);
        EXPECT_EQ(48, rtm->rtm_dst_len);
        EXPECT_EQ(0, rtm->rtm_src_len);
        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
        EXPECT_EQ(RTPROT_UNSPEC, rtm->rtm_protocol);
        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);

        const struct rtattr* rta;
        int payload_length = RTM_PAYLOAD(netlink_message);
        int num_rta = 0;
        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
             rta = RTA_NEXT(rta, payload_length)) {
          switch (rta->rta_type) {
            case RTA_PREFSRC: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(preferred_ip, address);
              break;
            }
            case RTA_OIF: {
              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
              const auto* interface_index =
                  reinterpret_cast<const int*>(RTA_DATA(rta));
              EXPECT_EQ(egress_interface_index, *interface_index);
              break;
            }
            case RTA_DST: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(subnet.ToString(),
                        IpRange(address, rtm->rtm_dst_len).ToString());
              break;
            }
            case RTA_TABLE: {
              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
                        QboneConstants::kQboneRouteTableId);
              break;
            }
            default:
              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
          }
          ++num_rta;
        }
        EXPECT_EQ(4, num_rta);
      });
  EXPECT_TRUE(netlink->ChangeRoute(
      Netlink::Verb::kRemove, QboneConstants::kQboneRouteTableId, subnet,
      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
}

TEST_F(NetlinkTest, ChangeRouteReplace) {
  auto netlink = std::make_unique<Netlink>(&mock_kernel_);

  QuicIpAddress preferred_ip;
  preferred_ip.FromString("ff80:dead:beef::1");
  IpRange subnet;
  subnet.FromString("ff80:dead:beef::/48");
  int egress_interface_index = 7;
  ExpectNetlinkPacket(
      RTM_NEWROUTE, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE,
      [](void* buf, size_t len, int seq) {
        struct nlmsghdr* netlink_message =
            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
        auto* err =
            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
        // Ack the request
        err->error = 0;
        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
        return netlink_message->nlmsg_len;
      },
      [preferred_ip, subnet, egress_interface_index](const void* buf,
                                                     size_t len) {
        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
        auto* rtm =
            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
        EXPECT_EQ(AF_INET6, rtm->rtm_family);
        EXPECT_EQ(48, rtm->rtm_dst_len);
        EXPECT_EQ(0, rtm->rtm_src_len);
        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
        EXPECT_EQ(RTPROT_STATIC, rtm->rtm_protocol);
        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);

        const struct rtattr* rta;
        int payload_length = RTM_PAYLOAD(netlink_message);
        int num_rta = 0;
        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
             rta = RTA_NEXT(rta, payload_length)) {
          switch (rta->rta_type) {
            case RTA_PREFSRC: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(preferred_ip, address);
              break;
            }
            case RTA_GATEWAY: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(*QboneConstants::GatewayAddress(), address);
              break;
            }
            case RTA_OIF: {
              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
              const auto* interface_index =
                  reinterpret_cast<const int*>(RTA_DATA(rta));
              EXPECT_EQ(egress_interface_index, *interface_index);
              break;
            }
            case RTA_DST: {
              const auto* raw_address =
                  reinterpret_cast<const char*>(RTA_DATA(rta));
              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
              QuicIpAddress address;
              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
              EXPECT_EQ(subnet.ToString(),
                        IpRange(address, rtm->rtm_dst_len).ToString());
              break;
            }
            case RTA_TABLE: {
              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
                        QboneConstants::kQboneRouteTableId);
              break;
            }
            default:
              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
          }
          ++num_rta;
        }
        EXPECT_EQ(5, num_rta);
      });
  EXPECT_TRUE(netlink->ChangeRoute(
      Netlink::Verb::kReplace, QboneConstants::kQboneRouteTableId, subnet,
      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
}

}  // namespace
}  // namespace quic::test
