// 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 <utility>

#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,
                 int init_cwnd) {
  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));

  // Add initcwnd
  if (init_cwnd > 0) {
    char data[RTA_LENGTH(sizeof(uint32_t))];
    struct rtattr* rta = reinterpret_cast<struct rtattr*>(data);
    rta->rta_len = sizeof(data);
    rta->rta_type = RTA_METRICS;
    *reinterpret_cast<uint32_t*>(RTA_DATA(rta)) = init_cwnd;
    AddRTA(nlm, RTA_METRICS, data, sizeof(data));
  }
}

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, 0);
                        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);
  EXPECT_EQ(0, routing_rules[0].init_cwnd);
}

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;
  uint32_t init_cwnd = 32;
  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, init_cwnd](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;
            }
            case RTA_METRICS: {
              struct rtattr* rtax =
                  reinterpret_cast<struct rtattr*>(RTA_DATA(rta));
              ASSERT_EQ(rtax->rta_type, RTAX_INITCWND);
              ASSERT_EQ(rtax->rta_len, RTA_LENGTH(sizeof(uint32_t)));
              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rtax)),
                        init_cwnd);
              break;
            }
            default:
              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
          }
          ++num_rta;
        }
        EXPECT_EQ(6, num_rta);
      });
  EXPECT_TRUE(netlink->ChangeRoute(
      Netlink::Verb::kAdd, QboneConstants::kQboneRouteTableId, subnet,
      RT_SCOPE_LINK, preferred_ip, egress_interface_index, init_cwnd));
}

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,
      Netlink::kUnspecifiedInitCwnd));
}

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,
      Netlink::kUnspecifiedInitCwnd));
}

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