// 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 "quic/qbone/platform/netlink.h"

#include <linux/fib_rules.h>

#include <utility>

#include "absl/base/attributes.h"
#include "absl/strings/str_cat.h"
#include "quic/core/crypto/quic_random.h"
#include "quic/platform/api/quic_ip_address.h"
#include "quic/platform/api/quic_logging.h"
#include "quic/qbone/platform/rtnetlink_message.h"
#include "quic/qbone/qbone_constants.h"

namespace quic {

Netlink::Netlink(KernelInterface* kernel) : kernel_(kernel) {
  seq_ = QuicRandom::GetInstance()->RandUint64();
}

Netlink::~Netlink() {
  CloseSocket();
}

void Netlink::ResetRecvBuf(size_t size) {
  if (size != 0) {
    recvbuf_ = std::make_unique<char[]>(size);
  } else {
    recvbuf_ = nullptr;
  }
  recvbuf_length_ = size;
}

bool Netlink::OpenSocket() {
  if (socket_fd_ >= 0) {
    return true;
  }

  socket_fd_ = kernel_->socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

  if (socket_fd_ < 0) {
    QUIC_PLOG(ERROR) << "can't open netlink socket";
    return false;
  }

  QUIC_LOG(INFO) << "Opened a new netlink socket fd = " << socket_fd_;

  // bind a local address to the socket
  sockaddr_nl myaddr;
  memset(&myaddr, 0, sizeof(myaddr));
  myaddr.nl_family = AF_NETLINK;
  if (kernel_->bind(socket_fd_, reinterpret_cast<struct sockaddr*>(&myaddr),
                    sizeof(myaddr)) < 0) {
    QUIC_LOG(INFO) << "can't bind address to socket";
    CloseSocket();
    return false;
  }

  return true;
}

void Netlink::CloseSocket() {
  if (socket_fd_ >= 0) {
    QUIC_LOG(INFO) << "Closing netlink socket fd = " << socket_fd_;
    kernel_->close(socket_fd_);
  }
  ResetRecvBuf(0);
  socket_fd_ = -1;
}

namespace {

class LinkInfoParser : public NetlinkParserInterface {
 public:
  LinkInfoParser(std::string interface_name, Netlink::LinkInfo* link_info)
      : interface_name_(std::move(interface_name)), link_info_(link_info) {}

  void Run(struct nlmsghdr* netlink_message) override {
    if (netlink_message->nlmsg_type != RTM_NEWLINK) {
      QUIC_LOG(INFO) << absl::StrCat(
          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
          " expected: ", RTM_NEWLINK);
      return;
    }

    struct ifinfomsg* interface_info =
        reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));

    // make sure interface_info is what we asked for.
    if (interface_info->ifi_family != AF_UNSPEC) {
      QUIC_LOG(INFO) << absl::StrCat(
          "Unexpected ifi_family: ", interface_info->ifi_family,
          " expected: ", AF_UNSPEC);
      return;
    }

    char hardware_address[kHwAddrSize];
    size_t hardware_address_length = 0;
    char broadcast_address[kHwAddrSize];
    size_t broadcast_address_length = 0;
    std::string name;

    // loop through the attributes
    struct rtattr* rta;
    int payload_length = IFLA_PAYLOAD(netlink_message);
    for (rta = IFLA_RTA(interface_info); RTA_OK(rta, payload_length);
         rta = RTA_NEXT(rta, payload_length)) {
      int attribute_length;
      switch (rta->rta_type) {
        case IFLA_ADDRESS: {
          attribute_length = RTA_PAYLOAD(rta);
          if (attribute_length > kHwAddrSize) {
            QUIC_VLOG(2) << "IFLA_ADDRESS too long: " << attribute_length;
            break;
          }
          memmove(hardware_address, RTA_DATA(rta), attribute_length);
          hardware_address_length = attribute_length;
          break;
        }
        case IFLA_BROADCAST: {
          attribute_length = RTA_PAYLOAD(rta);
          if (attribute_length > kHwAddrSize) {
            QUIC_VLOG(2) << "IFLA_BROADCAST too long: " << attribute_length;
            break;
          }
          memmove(broadcast_address, RTA_DATA(rta), attribute_length);
          broadcast_address_length = attribute_length;
          break;
        }
        case IFLA_IFNAME: {
          name = std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
                             RTA_PAYLOAD(rta));
          // The name maybe a 0 terminated c string.
          name = name.substr(0, name.find('\0'));
          break;
        }
      }
    }

    QUIC_VLOG(2) << "interface name: " << name
                 << ", index: " << interface_info->ifi_index;

    if (name == interface_name_) {
      link_info_->index = interface_info->ifi_index;
      link_info_->type = interface_info->ifi_type;
      link_info_->hardware_address_length = hardware_address_length;
      if (hardware_address_length > 0) {
        memmove(&link_info_->hardware_address, hardware_address,
                hardware_address_length);
      }
      link_info_->broadcast_address_length = broadcast_address_length;
      if (broadcast_address_length > 0) {
        memmove(&link_info_->broadcast_address, broadcast_address,
                broadcast_address_length);
      }
      found_link_ = true;
    }
  }

  bool found_link() { return found_link_; }

 private:
  const std::string interface_name_;
  Netlink::LinkInfo* const link_info_;
  bool found_link_ = false;
};

}  // namespace

bool Netlink::GetLinkInfo(const std::string& interface_name,
                          LinkInfo* link_info) {
  auto message = LinkMessage::New(RtnetlinkMessage::Operation::GET,
                                  NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
                                  seq_, getpid(), nullptr);

  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
    QUIC_LOG(ERROR) << "send failed.";
    return false;
  }

  // Pass the parser to the receive routine. It may be called multiple times
  // since there may be multiple reply packets each with multiple reply
  // messages.
  LinkInfoParser parser(interface_name, link_info);
  if (!Recv(seq_++, &parser)) {
    QUIC_LOG(ERROR) << "recv failed.";
    return false;
  }

  return parser.found_link();
}

namespace {

class LocalAddressParser : public NetlinkParserInterface {
 public:
  LocalAddressParser(int interface_index,
                     uint8_t unwanted_flags,
                     std::vector<Netlink::AddressInfo>* local_addresses,
                     int* num_ipv6_nodad_dadfailed_addresses)
      : interface_index_(interface_index),
        unwanted_flags_(unwanted_flags),
        local_addresses_(local_addresses),
        num_ipv6_nodad_dadfailed_addresses_(
            num_ipv6_nodad_dadfailed_addresses) {}

  void Run(struct nlmsghdr* netlink_message) override {
    // each nlmsg contains a header and multiple address attributes.
    if (netlink_message->nlmsg_type != RTM_NEWADDR) {
      QUIC_LOG(INFO) << "Unexpected nlmsg_type: " << netlink_message->nlmsg_type
                     << " expected: " << RTM_NEWADDR;
      return;
    }

    struct ifaddrmsg* interface_address =
        reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(netlink_message));

    // Make sure this is for an address family we're interested in.
    if (interface_address->ifa_family != AF_INET &&
        interface_address->ifa_family != AF_INET6) {
      QUIC_VLOG(2) << absl::StrCat("uninteresting ifa family: ",
                                   interface_address->ifa_family);
      return;
    }

    // Keep track of addresses with both 'nodad' and 'dadfailed', this really
    // should't be possible and is likely a kernel bug.
    if (num_ipv6_nodad_dadfailed_addresses_ != nullptr &&
        (interface_address->ifa_flags & IFA_F_NODAD) &&
        (interface_address->ifa_flags & IFA_F_DADFAILED)) {
      ++(*num_ipv6_nodad_dadfailed_addresses_);
    }

    uint8_t unwanted_flags = interface_address->ifa_flags & unwanted_flags_;
    if (unwanted_flags != 0) {
      QUIC_VLOG(2) << absl::StrCat("unwanted ifa flags: ", unwanted_flags);
      return;
    }

    // loop through the attributes
    struct rtattr* rta;
    int payload_length = IFA_PAYLOAD(netlink_message);
    Netlink::AddressInfo address_info;
    for (rta = IFA_RTA(interface_address); RTA_OK(rta, payload_length);
         rta = RTA_NEXT(rta, payload_length)) {
      // There's quite a lot of confusion in Linux over the use of IFA_LOCAL and
      // IFA_ADDRESS (source and destination address). For broadcast links, such
      // as Ethernet, they are identical (see <linux/if_addr.h>), but the kernel
      // sometimes uses only one or the other. We'll return both so that the
      // caller can decide which to use.
      if (rta->rta_type != IFA_LOCAL && rta->rta_type != IFA_ADDRESS) {
        QUIC_VLOG(2) << "Ignoring uninteresting rta_type: " << rta->rta_type;
        continue;
      }

      switch (interface_address->ifa_family) {
        case AF_INET:
          ABSL_FALLTHROUGH_INTENDED;
        case AF_INET6:
          // QuicIpAddress knows how to parse ip from raw bytes as long as they
          // are in network byte order.
          if (RTA_PAYLOAD(rta) == sizeof(struct in_addr) ||
              RTA_PAYLOAD(rta) == sizeof(struct in6_addr)) {
            auto* raw_ip = reinterpret_cast<char*>(RTA_DATA(rta));
            if (rta->rta_type == IFA_LOCAL) {
              address_info.local_address.FromPackedString(raw_ip,
                                                          RTA_PAYLOAD(rta));
            } else {
              address_info.interface_address.FromPackedString(raw_ip,
                                                              RTA_PAYLOAD(rta));
            }
          }
          break;
        default:
          QUIC_LOG(ERROR) << absl::StrCat("Unknown address family: ",
                                          interface_address->ifa_family);
      }
    }

    QUIC_VLOG(2) << "local_address: " << address_info.local_address.ToString()
                 << " interface_address: "
                 << address_info.interface_address.ToString()
                 << " index: " << interface_address->ifa_index;
    if (interface_address->ifa_index != interface_index_) {
      return;
    }

    address_info.prefix_length = interface_address->ifa_prefixlen;
    address_info.scope = interface_address->ifa_scope;
    if (address_info.local_address.IsInitialized() ||
        address_info.interface_address.IsInitialized()) {
      local_addresses_->push_back(address_info);
    }
  }

 private:
  const int interface_index_;
  const uint8_t unwanted_flags_;
  std::vector<Netlink::AddressInfo>* const local_addresses_;
  int* const num_ipv6_nodad_dadfailed_addresses_;
};

}  // namespace

bool Netlink::GetAddresses(int interface_index,
                           uint8_t unwanted_flags,
                           std::vector<AddressInfo>* addresses,
                           int* num_ipv6_nodad_dadfailed_addresses) {
  // the message doesn't contain the index, we'll have to do the filtering while
  // parsing the reply. This is because NLM_F_MATCH, which only returns entries
  // that matches the request criteria, is not yet implemented (see man 3
  // netlink).
  auto message = AddressMessage::New(RtnetlinkMessage::Operation::GET,
                                     NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
                                     seq_, getpid(), nullptr);

  // the send routine returns the socket to listen on.
  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
    QUIC_LOG(ERROR) << "send failed.";
    return false;
  }

  addresses->clear();
  if (num_ipv6_nodad_dadfailed_addresses != nullptr) {
    *num_ipv6_nodad_dadfailed_addresses = 0;
  }

  LocalAddressParser parser(interface_index, unwanted_flags, addresses,
                            num_ipv6_nodad_dadfailed_addresses);
  // Pass the parser to the receive routine. It may be called multiple times
  // since there may be multiple reply packets each with multiple reply
  // messages.
  if (!Recv(seq_++, &parser)) {
    QUIC_LOG(ERROR) << "recv failed";
    return false;
  }
  return true;
}

namespace {

class UnknownParser : public NetlinkParserInterface {
 public:
  void Run(struct nlmsghdr* netlink_message) override {
    QUIC_LOG(INFO) << "nlmsg reply type: " << netlink_message->nlmsg_type;
  }
};

}  // namespace

bool Netlink::ChangeLocalAddress(
    uint32_t interface_index,
    Verb verb,
    const QuicIpAddress& address,
    uint8_t prefix_length,
    uint8_t ifa_flags,
    uint8_t ifa_scope,
    const std::vector<struct rtattr*>& additional_attributes) {
  if (verb == Verb::kReplace) {
    return false;
  }
  auto operation = verb == Verb::kAdd ? RtnetlinkMessage::Operation::NEW
                                      : RtnetlinkMessage::Operation::DEL;
  uint8_t address_family;
  if (address.address_family() == IpAddressFamily::IP_V4) {
    address_family = AF_INET;
  } else if (address.address_family() == IpAddressFamily::IP_V6) {
    address_family = AF_INET6;
  } else {
    return false;
  }

  struct ifaddrmsg address_header = {address_family, prefix_length, ifa_flags,
                                     ifa_scope, interface_index};

  auto message = AddressMessage::New(operation, NLM_F_REQUEST | NLM_F_ACK, seq_,
                                     getpid(), &address_header);

  for (const auto& attribute : additional_attributes) {
    if (attribute->rta_type == IFA_LOCAL) {
      continue;
    }
    message.AppendAttribute(attribute->rta_type, RTA_DATA(attribute),
                            RTA_PAYLOAD(attribute));
  }

  message.AppendAttribute(IFA_LOCAL, address.ToPackedString().c_str(),
                          address.ToPackedString().size());

  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
    QUIC_LOG(ERROR) << "send failed";
    return false;
  }

  UnknownParser parser;
  if (!Recv(seq_++, &parser)) {
    QUIC_LOG(ERROR) << "receive failed.";
    return false;
  }
  return true;
}

namespace {

class RoutingRuleParser : public NetlinkParserInterface {
 public:
  explicit RoutingRuleParser(std::vector<Netlink::RoutingRule>* routing_rules)
      : routing_rules_(routing_rules) {}

  void Run(struct nlmsghdr* netlink_message) override {
    if (netlink_message->nlmsg_type != RTM_NEWROUTE) {
      QUIC_LOG(WARNING) << absl::StrCat(
          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
          " expected: ", RTM_NEWROUTE);
      return;
    }

    auto* route = reinterpret_cast<struct rtmsg*>(NLMSG_DATA(netlink_message));
    int payload_length = RTM_PAYLOAD(netlink_message);

    if (route->rtm_family != AF_INET && route->rtm_family != AF_INET6) {
      QUIC_VLOG(2) << absl::StrCat("Uninteresting family: ", route->rtm_family);
      return;
    }

    Netlink::RoutingRule rule;
    rule.scope = route->rtm_scope;
    rule.table = route->rtm_table;

    struct rtattr* rta;
    for (rta = RTM_RTA(route); RTA_OK(rta, payload_length);
         rta = RTA_NEXT(rta, payload_length)) {
      switch (rta->rta_type) {
        case RTA_TABLE: {
          rule.table = *reinterpret_cast<uint32_t*>(RTA_DATA(rta));
          break;
        }
        case RTA_DST: {
          QuicIpAddress destination;
          destination.FromPackedString(reinterpret_cast<char*> RTA_DATA(rta),
                                       RTA_PAYLOAD(rta));
          rule.destination_subnet = IpRange(destination, route->rtm_dst_len);
          break;
        }
        case RTA_PREFSRC: {
          QuicIpAddress preferred_source;
          rule.preferred_source.FromPackedString(
              reinterpret_cast<char*> RTA_DATA(rta), RTA_PAYLOAD(rta));
          break;
        }
        case RTA_OIF: {
          rule.out_interface = *reinterpret_cast<int*>(RTA_DATA(rta));
          break;
        }
        default: {
          QUIC_VLOG(2) << absl::StrCat("Uninteresting attribute: ",
                                       rta->rta_type);
        }
      }
    }
    routing_rules_->push_back(rule);
  }

 private:
  std::vector<Netlink::RoutingRule>* routing_rules_;
};

}  // namespace

bool Netlink::GetRouteInfo(std::vector<Netlink::RoutingRule>* routing_rules) {
  rtmsg route_message{};
  // Only manipulate main routing table.
  route_message.rtm_table = RT_TABLE_MAIN;

  auto message = RouteMessage::New(RtnetlinkMessage::Operation::GET,
                                   NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH,
                                   seq_, getpid(), &route_message);

  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
    QUIC_LOG(ERROR) << "send failed";
    return false;
  }

  RoutingRuleParser parser(routing_rules);
  if (!Recv(seq_++, &parser)) {
    QUIC_LOG(ERROR) << "recv failed";
    return false;
  }

  return true;
}

bool Netlink::ChangeRoute(Netlink::Verb verb,
                          uint32_t table,
                          const IpRange& destination_subnet,
                          uint8_t scope,
                          QuicIpAddress preferred_source,
                          int32_t interface_index) {
  if (!destination_subnet.prefix().IsInitialized()) {
    return false;
  }
  if (destination_subnet.address_family() != IpAddressFamily::IP_V4 &&
      destination_subnet.address_family() != IpAddressFamily::IP_V6) {
    return false;
  }
  if (preferred_source.IsInitialized() &&
      preferred_source.address_family() !=
          destination_subnet.address_family()) {
    return false;
  }

  RtnetlinkMessage::Operation operation;
  uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
  switch (verb) {
    case Verb::kAdd:
      operation = RtnetlinkMessage::Operation::NEW;
      // Setting NLM_F_EXCL so that an existing entry for this subnet will fail
      // the request. NLM_F_CREATE is necessary to indicate this is trying to
      // create a new entry - simply having RTM_NEWROUTE is not enough even the
      // name suggests so.
      flags |= NLM_F_EXCL | NLM_F_CREATE;
      break;
    case Verb::kRemove:
      operation = RtnetlinkMessage::Operation::DEL;
      break;
    case Verb::kReplace:
      operation = RtnetlinkMessage::Operation::NEW;
      // Setting NLM_F_REPLACE to tell the kernel that existing entry for this
      // subnet should be replaced.
      flags |= NLM_F_REPLACE | NLM_F_CREATE;
      break;
  }

  struct rtmsg route_message;
  memset(&route_message, 0, sizeof(route_message));
  route_message.rtm_family =
      destination_subnet.address_family() == IpAddressFamily::IP_V4 ? AF_INET
                                                                    : AF_INET6;
  // rtm_dst_len and rtm_src_len are actually the subnet prefix lengths. Poor
  // naming.
  route_message.rtm_dst_len = destination_subnet.prefix_length();
  // 0 means no source subnet for this rule.
  route_message.rtm_src_len = 0;
  // Only program the main table. Other tables are intended for the kernel to
  // manage.
  route_message.rtm_table = RT_TABLE_MAIN;
  // Use RTPROT_UNSPEC to match all the different protocol. Rules added by
  // kernel have RTPROT_KERNEL. Rules added by the root user have RTPROT_STATIC
  // instead.
  route_message.rtm_protocol =
      verb == Verb::kRemove ? RTPROT_UNSPEC : RTPROT_STATIC;
  route_message.rtm_scope = scope;
  // Only add unicast routing rule.
  route_message.rtm_type = RTN_UNICAST;
  auto message =
      RouteMessage::New(operation, flags, seq_, getpid(), &route_message);

  message.AppendAttribute(RTA_TABLE, &table, sizeof(table));

  // RTA_OIF is the target interface for this rule.
  message.AppendAttribute(RTA_OIF, &interface_index, sizeof(interface_index));
  // The actual destination subnet must be truncated of all the tailing zeros.
  message.AppendAttribute(
      RTA_DST,
      reinterpret_cast<const void*>(
          destination_subnet.prefix().ToPackedString().c_str()),
      destination_subnet.prefix().ToPackedString().size());
  // This is the source address to use in the IP packet should this routing rule
  // is used.
  if (preferred_source.IsInitialized()) {
    auto src_str = preferred_source.ToPackedString();
    message.AppendAttribute(RTA_PREFSRC,
                            reinterpret_cast<const void*>(src_str.c_str()),
                            src_str.size());
  }

  if (verb != Verb::kRemove) {
    auto gateway_str = QboneConstants::GatewayAddress()->ToPackedString();
    message.AppendAttribute(RTA_GATEWAY,
                            reinterpret_cast<const void*>(gateway_str.c_str()),
                            gateway_str.size());
  }

  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
    QUIC_LOG(ERROR) << "send failed";
    return false;
  }

  UnknownParser parser;
  if (!Recv(seq_++, &parser)) {
    QUIC_LOG(ERROR) << "receive failed.";
    return false;
  }
  return true;
}

namespace {

class IpRuleParser : public NetlinkParserInterface {
 public:
  explicit IpRuleParser(std::vector<Netlink::IpRule>* ip_rules)
      : ip_rules_(ip_rules) {}

  void Run(struct nlmsghdr* netlink_message) override {
    if (netlink_message->nlmsg_type != RTM_NEWRULE) {
      QUIC_LOG(WARNING) << absl::StrCat(
          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
          " expected: ", RTM_NEWRULE);
      return;
    }

    auto* rule = reinterpret_cast<rtmsg*>(NLMSG_DATA(netlink_message));
    int payload_length = RTM_PAYLOAD(netlink_message);

    if (rule->rtm_family != AF_INET6) {
      QUIC_LOG(ERROR) << absl::StrCat("Unexpected family: ", rule->rtm_family);
      return;
    }

    Netlink::IpRule ip_rule;
    ip_rule.table = rule->rtm_table;

    struct rtattr* rta;
    for (rta = RTM_RTA(rule); RTA_OK(rta, payload_length);
         rta = RTA_NEXT(rta, payload_length)) {
      switch (rta->rta_type) {
        case RTA_TABLE: {
          ip_rule.table = *reinterpret_cast<uint32_t*>(RTA_DATA(rta));
          break;
        }
        case RTA_SRC: {
          QuicIpAddress src_addr;
          src_addr.FromPackedString(reinterpret_cast<char*>(RTA_DATA(rta)),
                                    RTA_PAYLOAD(rta));
          IpRange src_range(src_addr, rule->rtm_src_len);
          ip_rule.source_range = src_range;
          break;
        }
        default: {
          QUIC_VLOG(2) << absl::StrCat("Uninteresting attribute: ",
                                       rta->rta_type);
        }
      }
    }
    ip_rules_->emplace_back(ip_rule);
  }

 private:
  std::vector<Netlink::IpRule>* ip_rules_;
};

}  // namespace

bool Netlink::GetRuleInfo(std::vector<Netlink::IpRule>* ip_rules) {
  rtmsg rule_message{};
  rule_message.rtm_family = AF_INET6;

  auto message = RuleMessage::New(RtnetlinkMessage::Operation::GET,
                                  NLM_F_REQUEST | NLM_F_DUMP, seq_, getpid(),
                                  &rule_message);

  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
    QUIC_LOG(ERROR) << "send failed";
    return false;
  }

  IpRuleParser parser(ip_rules);
  if (!Recv(seq_++, &parser)) {
    QUIC_LOG(ERROR) << "receive failed.";
    return false;
  }
  return true;
}

bool Netlink::ChangeRule(Verb verb, uint32_t table, IpRange source_range) {
  RtnetlinkMessage::Operation operation;
  uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;

  rtmsg rule_message{};
  rule_message.rtm_family = AF_INET6;
  rule_message.rtm_protocol = RTPROT_STATIC;
  rule_message.rtm_scope = RT_SCOPE_UNIVERSE;
  rule_message.rtm_table = RT_TABLE_UNSPEC;

  rule_message.rtm_flags |= FIB_RULE_FIND_SADDR;

  switch (verb) {
    case Verb::kAdd:
      if (!source_range.IsInitialized()) {
        QUIC_LOG(ERROR) << "Source range must be initialized.";
        return false;
      }
      operation = RtnetlinkMessage::Operation::NEW;
      flags |= NLM_F_EXCL | NLM_F_CREATE;
      rule_message.rtm_type = FRA_DST;
      rule_message.rtm_src_len = source_range.prefix_length();
      break;
    case Verb::kRemove:
      operation = RtnetlinkMessage::Operation::DEL;
      break;
    case Verb::kReplace:
      QUIC_LOG(ERROR) << "Unsupported verb: kReplace";
      return false;
  }
  auto message =
      RuleMessage::New(operation, flags, seq_, getpid(), &rule_message);

  message.AppendAttribute(RTA_TABLE, &table, sizeof(table));

  if (source_range.IsInitialized()) {
    std::string packed_src = source_range.prefix().ToPackedString();
    message.AppendAttribute(RTA_SRC,
                            reinterpret_cast<const void*>(packed_src.c_str()),
                            packed_src.size());
  }

  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
    QUIC_LOG(ERROR) << "send failed";
    return false;
  }

  UnknownParser parser;
  if (!Recv(seq_++, &parser)) {
    QUIC_LOG(ERROR) << "receive failed.";
    return false;
  }
  return true;
}

bool Netlink::Send(struct iovec* iov, size_t iovlen) {
  if (!OpenSocket()) {
    QUIC_LOG(ERROR) << "can't open socket";
    return false;
  }

  // an address for communicating with the kernel netlink code
  sockaddr_nl netlink_address;
  memset(&netlink_address, 0, sizeof(netlink_address));
  netlink_address.nl_family = AF_NETLINK;
  netlink_address.nl_pid = 0;     // destination is kernel
  netlink_address.nl_groups = 0;  // no multicast

  struct msghdr msg = {
      &netlink_address, sizeof(netlink_address), iov, iovlen, nullptr, 0, 0};

  if (kernel_->sendmsg(socket_fd_, &msg, 0) < 0) {
    QUIC_LOG(ERROR) << "sendmsg failed";
    CloseSocket();
    return false;
  }

  return true;
}

bool Netlink::Recv(uint32_t seq, NetlinkParserInterface* parser) {
  sockaddr_nl netlink_address;

  // replies can span multiple packets
  for (;;) {
    socklen_t address_length = sizeof(netlink_address);

    // First, call recvfrom with buffer size of 0 and MSG_PEEK | MSG_TRUNC set
    // so that we know the size of the incoming packet before actually receiving
    // it.
    int next_packet_size = kernel_->recvfrom(
        socket_fd_, recvbuf_.get(), /* len = */ 0, MSG_PEEK | MSG_TRUNC,
        reinterpret_cast<struct sockaddr*>(&netlink_address), &address_length);
    if (next_packet_size < 0) {
      QUIC_LOG(ERROR)
          << "error recvfrom with MSG_PEEK | MSG_TRUNC to get packet length.";
      CloseSocket();
      return false;
    }
    QUIC_VLOG(3) << "netlink packet size: " << next_packet_size;
    if (next_packet_size > recvbuf_length_) {
      QUIC_VLOG(2) << "resizing recvbuf to " << next_packet_size;
      ResetRecvBuf(next_packet_size);
    }

    // Get the packet for real.
    memset(recvbuf_.get(), 0, recvbuf_length_);
    int len = kernel_->recvfrom(
        socket_fd_, recvbuf_.get(), recvbuf_length_, /* flags = */ 0,
        reinterpret_cast<struct sockaddr*>(&netlink_address), &address_length);
    QUIC_VLOG(3) << "recvfrom returned: " << len;
    if (len < 0) {
      QUIC_LOG(INFO) << "can't receive netlink packet";
      CloseSocket();
      return false;
    }

    // there may be multiple nlmsg's in each reply packet
    struct nlmsghdr* netlink_message;
    for (netlink_message = reinterpret_cast<struct nlmsghdr*>(recvbuf_.get());
         NLMSG_OK(netlink_message, len);
         netlink_message = NLMSG_NEXT(netlink_message, len)) {
      QUIC_VLOG(3) << "netlink_message->nlmsg_type = "
                   << netlink_message->nlmsg_type;
      // make sure this is to us
      if (netlink_message->nlmsg_seq != seq) {
        QUIC_LOG(INFO) << "netlink_message not meant for us."
                       << " seq: " << seq
                       << " nlmsg_seq: " << netlink_message->nlmsg_seq;
        continue;
      }

      // done with this whole reply (not just this particular packet)
      if (netlink_message->nlmsg_type == NLMSG_DONE) {
        return true;
      }
      if (netlink_message->nlmsg_type == NLMSG_ERROR) {
        struct nlmsgerr* err =
            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
        if (netlink_message->nlmsg_len <
            NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
          QUIC_LOG(INFO) << "netlink_message ERROR truncated";
        } else {
          // an ACK
          if (err->error == 0) {
            QUIC_VLOG(3) << "Netlink sent an ACK";
            return true;
          }
          QUIC_LOG(INFO) << "netlink_message ERROR: " << err->error;
        }
        return false;
      }

      parser->Run(netlink_message);
    }
  }
}

}  // namespace quic
