blob: d8310d8bb661145be225de26e5f64aeed2b0d76e [file] [log] [blame]
Garrick Evans0dbd4182019-03-07 08:38:38 +09001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/address_manager.h"
Garrick Evans0dbd4182019-03-07 08:38:38 +09006
Garrick Evans3388a032020-03-24 11:25:55 +09007#include "patchpanel/net_util.h"
Hugo Benichi2ac4d072019-05-28 14:51:23 +09008
Garrick Evans3388a032020-03-24 11:25:55 +09009namespace patchpanel {
Garrick Evans0dbd4182019-03-07 08:38:38 +090010
11namespace {
12
13// The 100.115.92.0/24 subnet is reserved and not publicly routable. This subnet
Hugo Benichiadf1ec52020-01-17 16:23:58 +090014// is sliced into the following IP pools for use among the various usages:
Garrick Evans0dbd4182019-03-07 08:38:38 +090015// +---------------+------------+----------------------------------------------+
16// | IP Range | Guest | |
17// +---------------+------------+----------------------------------------------+
18// | 0 (/30) | ARC | Also used for legacy single network ARC++ |
19// | 4 (/30) | ARCVM | Currently a hard-coded reservation |
20// | 8-20 (/30) | ARC | Used to expose multiple host networks to ARC |
21// | 24-124 (/30) | Termina VM | Used by Crostini |
Hugo Benichiadf1ec52020-01-17 16:23:58 +090022// | 128-160 (/30) | Host netns | Used for netns hosting minijailed services |
23// | 164-192 | Reserved | |
Garrick Evans0dbd4182019-03-07 08:38:38 +090024// | 192-252 (/28) | Containers | Used by Crostini |
25// +---------------+------------+----------------------------------------------+
Garrick Evansbdc22672019-12-10 16:03:55 +090026//
27// The 100.115.93.0/24 subnet is reserved for plugin VMs.
Garrick Evans0dbd4182019-03-07 08:38:38 +090028
Garrick Evans0dbd4182019-03-07 08:38:38 +090029} // namespace
30
Garrick Evans4ee5ce22020-03-18 07:05:17 +090031AddressManager::AddressManager() {
32 for (auto g : {Guest::ARC, Guest::ARC_NET, Guest::VM_ARC, Guest::VM_TERMINA,
Hugo Benichiadf1ec52020-01-17 16:23:58 +090033 Guest::VM_PLUGIN, Guest::CONTAINER, Guest::MINIJAIL_NETNS}) {
Hugo Benichi6c63ae22019-05-29 11:19:15 +090034 uint32_t base_addr;
35 uint32_t prefix_length = 30;
Garrick Evansf4a93292019-03-13 14:19:43 +090036 uint32_t subnets = 1;
Garrick Evans0dbd4182019-03-07 08:38:38 +090037 switch (g) {
38 case Guest::ARC:
Hugo Benichi6c63ae22019-05-29 11:19:15 +090039 base_addr = Ipv4Addr(100, 115, 92, 0);
Garrick Evans0dbd4182019-03-07 08:38:38 +090040 break;
41 case Guest::VM_ARC:
Hugo Benichi6c63ae22019-05-29 11:19:15 +090042 base_addr = Ipv4Addr(100, 115, 92, 4);
Garrick Evans0dbd4182019-03-07 08:38:38 +090043 break;
44 case Guest::ARC_NET:
Hugo Benichi6c63ae22019-05-29 11:19:15 +090045 base_addr = Ipv4Addr(100, 115, 92, 8);
Garrick Evans0dbd4182019-03-07 08:38:38 +090046 subnets = 4;
47 break;
48 case Guest::VM_TERMINA:
Hugo Benichi6c63ae22019-05-29 11:19:15 +090049 base_addr = Ipv4Addr(100, 115, 92, 24);
Garrick Evans0dbd4182019-03-07 08:38:38 +090050 subnets = 26;
51 break;
Hugo Benichiadf1ec52020-01-17 16:23:58 +090052 case Guest::MINIJAIL_NETNS:
53 base_addr = Ipv4Addr(100, 115, 92, 128);
54 prefix_length = 30;
55 subnets = 8;
Garrick Evansbdc22672019-12-10 16:03:55 +090056 break;
Garrick Evans0dbd4182019-03-07 08:38:38 +090057 case Guest::CONTAINER:
Hugo Benichi6c63ae22019-05-29 11:19:15 +090058 base_addr = Ipv4Addr(100, 115, 92, 192);
Hugo Benichibd8ec4d2019-05-28 12:52:49 +090059 prefix_length = 28;
Garrick Evans0dbd4182019-03-07 08:38:38 +090060 subnets = 4;
61 break;
Hugo Benichiadf1ec52020-01-17 16:23:58 +090062 case Guest::VM_PLUGIN:
63 base_addr = Ipv4Addr(100, 115, 93, 0);
64 prefix_length = 29;
65 subnets = 32;
66 break;
Garrick Evans0dbd4182019-03-07 08:38:38 +090067 }
Hugo Benichibd8ec4d2019-05-28 12:52:49 +090068 pools_.emplace(g, SubnetPool::New(base_addr, prefix_length, subnets));
Garrick Evans0dbd4182019-03-07 08:38:38 +090069 }
70}
71
Garrick Evans7d9a2322020-04-02 11:59:56 +090072MacAddress AddressManager::GenerateMacAddress(uint8_t index) {
73 return index == kAnySubnetIndex ? mac_addrs_.Generate()
74 : mac_addrs_.GetStable(index);
Garrick Evansf4a93292019-03-13 14:19:43 +090075}
76
Garrick Evans0dbd4182019-03-07 08:38:38 +090077std::unique_ptr<Subnet> AddressManager::AllocateIPv4Subnet(
Garrick Evans53a2a982020-02-05 10:53:35 +090078 AddressManager::Guest guest, uint32_t index) {
Garrick Evans1fa4e642020-03-13 11:43:41 +090079 if (index > 0 && guest != AddressManager::Guest::VM_PLUGIN) {
Garrick Evans43b4e2d2019-12-11 13:43:08 +090080 LOG(ERROR) << "Subnet indexing not supported for guest";
81 return nullptr;
82 }
Garrick Evansf4a93292019-03-13 14:19:43 +090083 const auto it = pools_.find(guest);
Garrick Evans43b4e2d2019-12-11 13:43:08 +090084 return (it != pools_.end()) ? it->second->Allocate(index) : nullptr;
Garrick Evans0dbd4182019-03-07 08:38:38 +090085}
86
Garrick Evans3388a032020-03-24 11:25:55 +090087} // namespace patchpanel