blob: 47ad948ab996d7a04bedbf63964e85d94097bab2 [file] [log] [blame]
// 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.
#ifndef PATCHPANEL_ADDRESS_MANAGER_H_
#define PATCHPANEL_ADDRESS_MANAGER_H_
#include <map>
#include <memory>
#include <optional>
#include <base/containers/flat_set.h>
#include <base/functional/callback.h>
#include <base/memory/weak_ptr.h>
#include <brillo/brillo_export.h>
#include <net-base/ipv6_address.h>
#include "patchpanel/mac_address_generator.h"
#include "patchpanel/subnet.h"
#include "patchpanel/subnet_pool.h"
namespace patchpanel {
// Responsible for address provisioning for guest networks.
class BRILLO_EXPORT AddressManager {
public:
// Enum reprensenting the different types of downstream guests managed by
// patchpanel that requires assignment of IPv4 subnets.
enum class GuestType {
// ARC++ or ARCVM management interface.
kArc0,
// ARC++ or ARCVM virtual networks connected to shill Devices.
kArcNet,
/// Crostini VM root namespace.
kTerminaVM,
// Parallels VMs.
kParallelsVM,
// Crostini VM user containers.
kLXDContainer,
// Other network namespaces hosting minijailed host processes.
kNetns,
};
AddressManager();
AddressManager(const AddressManager&) = delete;
AddressManager& operator=(const AddressManager&) = delete;
virtual ~AddressManager() = default;
// Generates a MAC address guaranteed to be unique for the lifetime of this
// object.
// If |index| is provided, a MAC address will be returned that is stable
// across all invocations and instantions.
// Virtual for testing only.
virtual MacAddress GenerateMacAddress(uint32_t index = kAnySubnetIndex);
// Allocates a subnet from the specified guest network pool if available.
// Returns nullptr if the guest was configured or no more subnets are
// available for allocation.
// |index| is used to acquire a particular subnet from the pool, if supported
// for |guest|, it is 1-based, so 0 indicates no preference.
std::unique_ptr<Subnet> AllocateIPv4Subnet(GuestType guest_type,
uint32_t index = kAnySubnetIndex);
// Allocates an IPv6 ULA subnet with a fixed prefix length of 64. The caller
// is responsible to release the subnet through ReleaseIPv6Subnet().
net_base::IPv6CIDR AllocateIPv6Subnet();
// Releases previously allocated IPv6 subnet through AllocateIPv6Subnet().
void ReleaseIPv6Subnet(const net_base::IPv6CIDR& subnet);
// Gets randomized IPv6 address inside |subnet|. Caller is responsible to
// handle possible duplicated addresses. This method guarantess that the base
// address of |subnet| is not returned.
static std::optional<net_base::IPv6CIDR> GetRandomizedIPv6Address(
const net_base::IPv6CIDR& subnet);
// Generates IPv6 subnet of |prefix_length| inside |net_block|. This method
// guarantees that the subnet address created is not equal to the base
// |net_block| address.
std::optional<net_base::IPv6CIDR> GenerateIPv6Subnet(
const net_base::IPv6CIDR& net_block, int prefix_length);
private:
MacAddressGenerator mac_addrs_;
std::map<GuestType, std::unique_ptr<SubnetPool>> pools_;
base::flat_set<net_base::IPv6CIDR> allocated_ipv6_subnets_;
base::WeakPtrFactory<AddressManager> weak_ptr_factory_{this};
};
std::ostream& operator<<(std::ostream& stream,
const AddressManager::GuestType guest_type);
} // namespace patchpanel
#endif // PATCHPANEL_ADDRESS_MANAGER_H_