// Copyright (c) 2020 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/bonnet/tun_device_controller.h"

#include <linux/rtnetlink.h>

#include "absl/time/clock.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/qbone/qbone_constants.h"
#include "quiche/common/quiche_callbacks.h"

ABSL_FLAG(bool, qbone_tun_device_replace_default_routing_rules, true,
          "If true, will define a rule that points packets sourced from the "
          "qbone interface to the qbone table. This is unnecessary in "
          "environments with no other ipv6 route.");

ABSL_FLAG(int, qbone_route_init_cwnd,
          quic::NetlinkInterface::kUnspecifiedInitCwnd,
          "If non-zero, will add initcwnd to QBONE routing rules.  Setting "
          "a value below 10 is dangerous and not recommended.");

namespace quic {

bool TunDeviceController::UpdateAddress(const IpRange& desired_range) {
  if (!setup_tun_) {
    return true;
  }

  NetlinkInterface::LinkInfo link_info{};
  if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
    return false;
  }

  std::vector<NetlinkInterface::AddressInfo> addresses;
  if (!netlink_->GetAddresses(link_info.index, 0, &addresses, nullptr)) {
    return false;
  }

  QuicIpAddress desired_address = desired_range.FirstAddressInRange();

  for (const auto& address : addresses) {
    if (!netlink_->ChangeLocalAddress(
            link_info.index, NetlinkInterface::Verb::kRemove,
            address.interface_address, address.prefix_length, 0, 0, {})) {
      return false;
    }
  }

  bool address_updated = netlink_->ChangeLocalAddress(
      link_info.index, NetlinkInterface::Verb::kAdd, desired_address,
      desired_range.prefix_length(), IFA_F_PERMANENT | IFA_F_NODAD,
      RT_SCOPE_LINK, {});

  if (address_updated) {
    current_address_ = desired_address;

    for (const auto& cb : address_update_cbs_) {
      cb(current_address_);
    }
  }

  return address_updated;
}

bool TunDeviceController::UpdateRoutes(
    const IpRange& desired_range, const std::vector<IpRange>& desired_routes) {
  if (!setup_tun_) {
    return true;
  }

  NetlinkInterface::LinkInfo link_info{};
  if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
    QUIC_LOG(ERROR) << "Could not get link info for interface <" << ifname_
                    << ">";
    return false;
  }

  std::vector<NetlinkInterface::RoutingRule> routing_rules;
  if (!netlink_->GetRouteInfo(&routing_rules)) {
    QUIC_LOG(ERROR) << "Unable to get route info";
    return false;
  }

  for (const auto& rule : routing_rules) {
    if (rule.out_interface == link_info.index &&
        rule.table == QboneConstants::kQboneRouteTableId) {
      if (!netlink_->ChangeRoute(NetlinkInterface::Verb::kRemove, rule.table,
                                 rule.destination_subnet, rule.scope,
                                 rule.preferred_source, rule.out_interface,
                                 rule.init_cwnd)) {
        QUIC_LOG(ERROR) << "Unable to remove old route to <"
                        << rule.destination_subnet.ToString() << ">";
        return false;
      }
    }
  }

  if (!UpdateRules(desired_range)) {
    return false;
  }

  QuicIpAddress desired_address = desired_range.FirstAddressInRange();

  std::vector<IpRange> routes(desired_routes.begin(), desired_routes.end());
  routes.emplace_back(*QboneConstants::TerminatorLocalAddressRange());

  for (const auto& route : routes) {
    if (!netlink_->ChangeRoute(NetlinkInterface::Verb::kReplace,
                               QboneConstants::kQboneRouteTableId, route,
                               RT_SCOPE_LINK, desired_address, link_info.index,
                               absl::GetFlag(FLAGS_qbone_route_init_cwnd))) {
      QUIC_LOG(ERROR) << "Unable to add route <" << route.ToString() << ">";
      return false;
    }
  }

  return true;
}

bool TunDeviceController::UpdateRoutesWithRetries(
    const IpRange& desired_range, const std::vector<IpRange>& desired_routes,
    int retries) {
  while (retries-- > 0) {
    if (UpdateRoutes(desired_range, desired_routes)) {
      return true;
    }
    absl::SleepFor(absl::Milliseconds(100));
  }
  return false;
}

bool TunDeviceController::UpdateRules(IpRange desired_range) {
  if (!absl::GetFlag(FLAGS_qbone_tun_device_replace_default_routing_rules)) {
    return true;
  }

  std::vector<NetlinkInterface::IpRule> ip_rules;
  if (!netlink_->GetRuleInfo(&ip_rules)) {
    QUIC_LOG(ERROR) << "Unable to get rule info";
    return false;
  }

  for (const auto& rule : ip_rules) {
    if (rule.table == QboneConstants::kQboneRouteTableId) {
      if (!netlink_->ChangeRule(NetlinkInterface::Verb::kRemove, rule.table,
                                rule.source_range)) {
        QUIC_LOG(ERROR) << "Unable to remove old rule for table <" << rule.table
                        << "> from source <" << rule.source_range.ToString()
                        << ">";
        return false;
      }
    }
  }

  if (!netlink_->ChangeRule(NetlinkInterface::Verb::kAdd,
                            QboneConstants::kQboneRouteTableId,
                            desired_range)) {
    QUIC_LOG(ERROR) << "Unable to add rule for <" << desired_range.ToString()
                    << ">";
    return false;
  }

  return true;
}

QuicIpAddress TunDeviceController::current_address() {
  return current_address_;
}

void TunDeviceController::RegisterAddressUpdateCallback(
    quiche::MultiUseCallback<void(QuicIpAddress)> cb) {
  address_update_cbs_.push_back(std::move(cb));
}

}  // namespace quic
