blob: 40b9747127c625fc65cb8914d850f290b8de532c [file] [log] [blame] [edit]
// 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 <base/logging.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 |
// | 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 plugin VMs.
} // namespace
AddressManager::AddressManager() {
for (auto g :
{GuestType::kArc0, GuestType::kArcNet, GuestType::kVmTermina,
GuestType::kVmPlugin, GuestType::kLxdContainer, GuestType::kNetns}) {
uint32_t base_addr;
uint32_t prefix_length = 30;
uint32_t subnets = 1;
switch (g) {
case GuestType::kArc0:
base_addr = Ipv4Addr(100, 115, 92, 0);
break;
case GuestType::kArcNet:
base_addr = Ipv4Addr(100, 115, 92, 4);
subnets = 5;
break;
case GuestType::kVmTermina:
base_addr = Ipv4Addr(100, 115, 92, 24);
subnets = 26;
break;
case GuestType::kNetns:
base_addr = Ipv4Addr(100, 115, 92, 128);
prefix_length = 30;
subnets = 16;
break;
case GuestType::kLxdContainer:
base_addr = Ipv4Addr(100, 115, 92, 192);
prefix_length = 28;
subnets = 4;
break;
case GuestType::kVmPlugin:
base_addr = Ipv4Addr(100, 115, 93, 0);
prefix_length = 29;
subnets = 32;
break;
}
pools_.emplace(g, SubnetPool::New(base_addr, prefix_length, subnets));
}
}
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::kVmPlugin) {
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;
}
} // namespace patchpanel