// 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/bonnet/tun_device.h"

#include <fcntl.h>
#include <linux/if_tun.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#include "quic/platform/api/quic_bug_tracker.h"
#include "quic/platform/api/quic_logging.h"
#include "quic/qbone/platform/kernel_interface.h"

namespace quic {

const char kTapTunDevicePath[] = "/dev/net/tun";
const int kInvalidFd = -1;

TunDevice::TunDevice(const std::string& interface_name,
                     int mtu,
                     bool persist,
                     bool setup_tun,
                     KernelInterface* kernel)
    : interface_name_(interface_name),
      mtu_(mtu),
      persist_(persist),
      setup_tun_(setup_tun),
      file_descriptor_(kInvalidFd),
      kernel_(*kernel) {}

TunDevice::~TunDevice() {
  if (!persist_) {
    Down();
  }
  CleanUpFileDescriptor();
}

bool TunDevice::Init() {
  if (interface_name_.empty() || interface_name_.size() >= IFNAMSIZ) {
    QUIC_BUG_V2(quic_bug_10995_1)
        << "interface_name must be nonempty and shorter than " << IFNAMSIZ;
    return false;
  }

  if (!OpenDevice()) {
    return false;
  }

  if (!ConfigureInterface()) {
    return false;
  }

  return true;
}

// TODO(pengg): might be better to use netlink socket, once we have a library to
// use
bool TunDevice::Up() {
  if (setup_tun_ && !is_interface_up_) {
    struct ifreq if_request;
    memset(&if_request, 0, sizeof(if_request));
    // copy does not zero-terminate the result string, but we've memset the
    // entire struct.
    interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
    if_request.ifr_flags = IFF_UP;

    is_interface_up_ =
        NetdeviceIoctl(SIOCSIFFLAGS, reinterpret_cast<void*>(&if_request));
    return is_interface_up_;
  } else {
    return true;
  }
}

// TODO(pengg): might be better to use netlink socket, once we have a library to
// use
bool TunDevice::Down() {
  if (setup_tun_ && is_interface_up_) {
    struct ifreq if_request;
    memset(&if_request, 0, sizeof(if_request));
    // copy does not zero-terminate the result string, but we've memset the
    // entire struct.
    interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
    if_request.ifr_flags = 0;

    is_interface_up_ =
        !NetdeviceIoctl(SIOCSIFFLAGS, reinterpret_cast<void*>(&if_request));
    return !is_interface_up_;
  } else {
    return true;
  }
}

int TunDevice::GetFileDescriptor() const {
  return file_descriptor_;
}

bool TunDevice::OpenDevice() {
  struct ifreq if_request;
  memset(&if_request, 0, sizeof(if_request));
  // copy does not zero-terminate the result string, but we've memset the entire
  // struct.
  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);

  // Always set IFF_MULTI_QUEUE since a persistent device does not allow this
  // flag to be flipped when re-opening it. The only way to flip this flag is to
  // destroy the device and create a new one, but that deletes any existing
  // routing associated with the interface, which makes the meaning of the
  // 'persist' bit ambiguous.
  if_request.ifr_flags = IFF_TUN | IFF_MULTI_QUEUE | IFF_NO_PI;

  // TODO(pengg): port MakeCleanup to quic/platform? This makes the call to
  // CleanUpFileDescriptor nicer and less error-prone.
  // When the device is running with IFF_MULTI_QUEUE set, each call to open will
  // create a queue which can be used to read/write packets from/to the device.
  int fd = kernel_.open(kTapTunDevicePath, O_RDWR);
  if (fd < 0) {
    QUIC_PLOG(WARNING) << "Failed to open " << kTapTunDevicePath;
    CleanUpFileDescriptor();
    return false;
  }
  file_descriptor_ = fd;
  if (!CheckFeatures(fd)) {
    CleanUpFileDescriptor();
    return false;
  }

  if (kernel_.ioctl(fd, TUNSETIFF, reinterpret_cast<void*>(&if_request)) != 0) {
    QUIC_PLOG(WARNING) << "Failed to TUNSETIFF on fd(" << fd << ")";
    CleanUpFileDescriptor();
    return false;
  }

  if (kernel_.ioctl(
          fd, TUNSETPERSIST,
          persist_ ? reinterpret_cast<void*>(&if_request) : nullptr) != 0) {
    QUIC_PLOG(WARNING) << "Failed to TUNSETPERSIST on fd(" << fd << ")";
    CleanUpFileDescriptor();
    return false;
  }

  return true;
}

// TODO(pengg): might be better to use netlink socket, once we have a library to
// use
bool TunDevice::ConfigureInterface() {
  if (!setup_tun_) {
    return true;
  }

  struct ifreq if_request;
  memset(&if_request, 0, sizeof(if_request));
  // copy does not zero-terminate the result string, but we've memset the entire
  // struct.
  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
  if_request.ifr_mtu = mtu_;

  if (!NetdeviceIoctl(SIOCSIFMTU, reinterpret_cast<void*>(&if_request))) {
    CleanUpFileDescriptor();
    return false;
  }

  return true;
}

bool TunDevice::CheckFeatures(int tun_device_fd) {
  unsigned int actual_features;
  if (kernel_.ioctl(tun_device_fd, TUNGETFEATURES, &actual_features) != 0) {
    QUIC_PLOG(WARNING) << "Failed to TUNGETFEATURES";
    return false;
  }
  unsigned int required_features = IFF_TUN | IFF_NO_PI;
  if ((required_features & actual_features) != required_features) {
    QUIC_LOG(WARNING)
        << "Required feature does not exist. required_features: 0x" << std::hex
        << required_features << " vs actual_features: 0x" << std::hex
        << actual_features;
    return false;
  }
  return true;
}

bool TunDevice::NetdeviceIoctl(int request, void* argp) {
  int fd = kernel_.socket(AF_INET6, SOCK_DGRAM, 0);
  if (fd < 0) {
    QUIC_PLOG(WARNING) << "Failed to create AF_INET6 socket.";
    return false;
  }

  if (kernel_.ioctl(fd, request, argp) != 0) {
    QUIC_PLOG(WARNING) << "Failed ioctl request: " << request;
    kernel_.close(fd);
    return false;
  }
  kernel_.close(fd);
  return true;
}

void TunDevice::CleanUpFileDescriptor() {
  if (file_descriptor_ != kInvalidFd) {
    kernel_.close(file_descriptor_);
    file_descriptor_ = kInvalidFd;
  }
}

}  // namespace quic
