// Copyright 2019 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "patchpanel/address_manager.h"

#include <climits>
#include <optional>
#include <vector>

#include <base/containers/contains.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <chromeos/net-base/ipv6_address.h>
#include <chromeos/net-base/mac_address.h>

#include "patchpanel/net_util.h"

namespace patchpanel {

namespace {

// The 100.115.92.0/24 subnet is reserved and not publicly routable. This subnet
// is sliced into the following IP pools for use among the various usages:
// +---------------+------------+----------------------------------------------+
// |   IP Range    |    Guest   |                                              |
// +---------------+------------+----------------------------------------------+
// | 0       (/30) | ARC/ARCVM  | Used for ARC management interface arc0       |
// | 4-20    (/30) | ARC/ARCVM  | Used to expose multiple host networks to ARC |
// | 24-124  (/30) | Termina VM | Used by Crostini, Bruschetta and Borealis    |
// | 128-188 (/30) | Host netns | Used for netns hosting minijailed services   |
// | 192-252 (/28) | Containers | Used by Crostini LXD user containers         |
// +---------------+------------+----------------------------------------------+
//
// The 100.115.93.0/24 subnet is reserved for Parallels VMs.

// Prefix length of allocated subnet for static ULA IPv6 addresses.
constexpr int kStaticIPv6PrefixLength = 64;

// RFC4193: IPv6 prefix of fd00::/8 is defined for locally assigned unique local
// addresses (ULA).
const net_base::IPv6CIDR kULASubnet =
    *net_base::IPv6CIDR::CreateFromStringAndPrefix("fd00::", 8);

}  // namespace

AddressManager::AddressManager() {
  pools_.emplace(
      GuestType::kArc0,
      SubnetPool::New(
          *net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.0/30"), 1));
  pools_.emplace(
      GuestType::kArcNet,
      SubnetPool::New(
          *net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.4/30"), 5));
  pools_.emplace(
      GuestType::kTerminaVM,
      SubnetPool::New(
          *net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.24/30"), 26));
  pools_.emplace(
      GuestType::kNetns,
      SubnetPool::New(
          *net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.128/30"), 16));
  pools_.emplace(
      GuestType::kLXDContainer,
      SubnetPool::New(
          *net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.192/28"), 4));
  pools_.emplace(
      GuestType::kParallelsVM,
      SubnetPool::New(
          *net_base::IPv4CIDR::CreateFromCIDRString("100.115.93.0/29"), 32));
}

net_base::MacAddress AddressManager::GenerateMacAddress(uint32_t index) {
  return index == kAnySubnetIndex ? mac_addrs_.Generate()
                                  : mac_addrs_.GetStable(index);
}

std::unique_ptr<Subnet> AddressManager::AllocateIPv4Subnet(GuestType guest,
                                                           uint32_t index) {
  if (index > 0 && guest != GuestType::kParallelsVM) {
    LOG(ERROR) << "Subnet indexing not supported for guest";
    return nullptr;
  }
  const auto it = pools_.find(guest);
  return (it != pools_.end()) ? it->second->Allocate(index) : nullptr;
}

net_base::IPv6CIDR AddressManager::AllocateIPv6Subnet() {
  net_base::IPv6CIDR subnet;
  do {
    subnet = *GenerateIPv6Subnet(kULASubnet, kStaticIPv6PrefixLength);
  } while (base::Contains(allocated_ipv6_subnets_, subnet));
  allocated_ipv6_subnets_.insert(subnet);

  return subnet;
}

void AddressManager::ReleaseIPv6Subnet(const net_base::IPv6CIDR& subnet) {
  if (allocated_ipv6_subnets_.erase(subnet) == 0) {
    LOG(ERROR) << "Releasing unallocated subnet: " << subnet;
  }
}

std::optional<net_base::IPv6CIDR> AddressManager::GetRandomizedIPv6Address(
    const net_base::IPv6CIDR& subnet) {
  if (subnet.prefix_length() >= 128) {
    LOG(ERROR) << "Subnet must at least holds 1 IPv6 address, excluding the "
                  "base address. Got "
               << subnet;
    return std::nullopt;
  }

  net_base::IPv6Address::DataType addr = {};
  do {
    base::RandBytes(addr);
    std::vector<uint8_t> mask =
        net_base::IPv6CIDR::GetNetmask(subnet.prefix_length())->ToBytes();
    std::vector<uint8_t> subnet_addr = subnet.address().ToBytes();
    for (size_t i = 0; i < net_base::IPv6Address::kAddressLength; ++i) {
      addr[i] = subnet_addr[i] | (~mask[i] & addr[i]);
    }
  } while (net_base::IPv6Address(addr) == subnet.address());

  return net_base::IPv6CIDR::CreateFromAddressAndPrefix(
      net_base::IPv6Address(addr), subnet.prefix_length());
}

std::optional<net_base::IPv6CIDR> AddressManager::GenerateIPv6Subnet(
    const net_base::IPv6CIDR& net_block, int prefix_length) {
  // Avoid invalid |net_block| and |prefix_length| combination.
  if (prefix_length <= net_block.prefix_length() || prefix_length > 128) {
    LOG(ERROR) << "Given prefix length " << prefix_length
               << " must be less than network block prefix length "
               << net_block.prefix_length();
    return std::nullopt;
  }

  // Generates randomized subnet that is not equal to the base |net_block|
  // address.
  net_base::IPv6Address::DataType addr = {};
  do {
    base::RandBytes(addr);
    std::vector<uint8_t> mask =
        net_base::IPv6CIDR::GetNetmask(net_block.prefix_length())->ToBytes();
    std::vector<uint8_t> net_block_addr = net_block.address().ToBytes();
    for (size_t i = 0; i < net_base::IPv6Address::kAddressLength; ++i) {
      addr[i] = net_block_addr[i] | (~mask[i] & addr[i]);
    }
  } while (net_base::IPv6Address(addr) == net_block.address());

  return net_base::IPv6CIDR::CreateFromAddressAndPrefix(
             net_base::IPv6Address(addr), prefix_length)
      ->GetPrefixCIDR();
}

std::ostream& operator<<(std::ostream& stream,
                         const AddressManager::GuestType guest_type) {
  switch (guest_type) {
    case AddressManager::GuestType::kArc0:
      return stream << "ARC0";
    case AddressManager::GuestType::kArcNet:
      return stream << "ARC_NET";
    case AddressManager::GuestType::kTerminaVM:
      return stream << "TERMINA_VM";
    case AddressManager::GuestType::kParallelsVM:
      return stream << "PARALLELS_VM";
    case AddressManager::GuestType::kLXDContainer:
      return stream << "LXD_CONTAINER";
    case AddressManager::GuestType::kNetns:
      return stream << "MINIJAIL_NETNS";
  }
}

}  // namespace patchpanel
