16#include <boost/range/adaptor/reversed.hpp>
32 << subnet->getID() <<
"' is already in use");
38 << subnet->toText() <<
"' already exists");
42 .arg(subnet->toText());
43 static_cast<void>(subnets_.insert(subnet));
49 const SubnetID& subnet_id = subnet->getID();
50 auto& index = subnets_.template get<SubnetSubnetIdIndexTag>();
51 auto subnet_it = index.find(subnet_id);
52 if (subnet_it == index.end()) {
56 bool ret = index.replace(subnet_it, subnet);
59 .arg(subnet_id).arg(ret);
75 auto subnet_it = index.find(subnet_id);
76 if (subnet_it == index.end()) {
83 index.erase(subnet_it);
86 .arg(subnet->toText());
98 auto const& other_subnets = other.getAll();
99 for (
auto const& other_subnet : *other_subnets) {
102 auto subnet_it = index_id.find(other_subnet->getID());
103 if (subnet_it != index_id.end()) {
106 auto existing_subnet = *subnet_it;
110 if (existing_subnet == other_subnet) {
118 existing_subnet->getSharedNetwork(network);
120 network->del(existing_subnet->getID());
124 index_id.erase(subnet_it);
128 auto subnet_prefix_it = index_prefix.find(other_subnet->toText());
129 if (subnet_prefix_it != index_prefix.end()) {
132 auto existing_subnet = *subnet_prefix_it;
142 existing_subnet->getSharedNetwork(network);
144 network->del(existing_subnet->getID());
148 index_prefix.erase(subnet_prefix_it);
152 other_subnet->getCfgOption()->createOptions(cfg_def);
156 other_subnet->getCfgOption()->encapsulate();
159 for (
auto const& pool : other_subnet->getPoolsWritable(
Lease::TYPE_NA)) {
160 pool->getCfgOption()->createOptions(cfg_def);
161 pool->getCfgOption()->encapsulate();
165 for (
auto const& pool : other_subnet->getPoolsWritable(
Lease::TYPE_PD)) {
166 pool->getCfgOption()->createOptions(cfg_def);
167 pool->getCfgOption()->encapsulate();
171 static_cast<void>(subnets_.insert(other_subnet));
175 std::string network_name = other_subnet->getSharedNetworkName();
176 if (!network_name.empty()) {
179 network->add(other_subnet);
184 << other_subnet->getID()
185 <<
" to shared network: " << network_name
186 <<
", network does not exist");
190 other_subnet->createAllocators();
197 auto subnet_it = index.find(subnet_text);
198 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet6Ptr());
206 selector.remote_address_ = query->getRemoteAddr();
207 selector.first_relay_linkaddr_ =
IOAddress(
"::");
208 selector.client_classes_ = query->classes_;
211 if (!query->relay_info_.empty()) {
212 for (
auto const& relay : boost::adaptors::reverse(query->relay_info_)) {
213 if (!relay.linkaddr_.isV6Zero() &&
214 !relay.linkaddr_.isV6LinkLocal()) {
215 selector.first_relay_linkaddr_ = relay.linkaddr_;
219 selector.interface_id_ =
233 if (selector.first_relay_linkaddr_ ==
IOAddress(
"::")) {
236 if (!selector.iface_name_.empty()) {
238 selector.client_classes_);
242 if (!subnet && selector.remote_address_ !=
IOAddress(
"::")) {
244 selector.client_classes_);
250 subnet =
selectSubnet(selector.interface_id_, selector.client_classes_);
256 selector.client_classes_,
268 const bool is_relay_address)
const {
271 if (is_relay_address) {
272 for (
auto const& subnet : subnets_) {
276 if (subnet->hasRelays()) {
277 if (!subnet->hasRelayAddress(address)) {
283 subnet->getSharedNetwork(network);
284 if (!network || !network->hasRelayAddress(address)) {
289 if (subnet->clientSupported(client_classes)) {
294 .arg(subnet->toText()).arg(address.toText());
302 for (
auto const& subnet : subnets_) {
303 if (subnet->inRange(address) && subnet->clientSupported(client_classes)) {
305 .arg(subnet->toText()).arg(address.toText());
312 .arg(address.toText());
322 if (!iface_name.empty()) {
323 for (
auto const& subnet : subnets_) {
328 if ((subnet->getIface() == iface_name) &&
329 subnet->clientSupported(client_classes)) {
332 .arg(subnet->toText()).arg(iface_name);
348 const ClientClasses& client_classes)
const {
352 for (
auto const& subnet : subnets_) {
356 if (subnet->getInterfaceId() &&
357 subnet->getInterfaceId()->equals(interface_id) &&
358 subnet->clientSupported(client_classes)) {
362 .arg(subnet->toText());
369 .arg(interface_id->toText());
379 auto subnet_it = index.find(subnet_id);
380 return ((subnet_it != index.cend()) ? (*subnet_it) :
Subnet6Ptr());
386 for (
auto const& subnet : subnets_) {
387 if (!subnet->inRange(link_addr)) {
390 links.insert(subnet->getID());
399 StatsMgr& stats_mgr = StatsMgr::instance();
401 for (
auto const& subnet6 : subnets_) {
402 SubnetID subnet_id = subnet6->getID();
403 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
406 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
409 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
410 "cumulative-assigned-nas"));
412 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
415 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
418 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
419 "cumulative-assigned-pds"));
421 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
422 "declined-addresses"));
424 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
425 "reclaimed-declined-addresses"));
427 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
428 "reclaimed-leases"));
431 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
432 StatsMgr::generateName(
"pool", pool->getID(),
435 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
436 StatsMgr::generateName(
"pool", pool->getID(),
439 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
440 StatsMgr::generateName(
"pool", pool->getID(),
441 "cumulative-assigned-nas")));
443 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
444 StatsMgr::generateName(
"pool", pool->getID(),
445 "declined-addresses")));
447 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
448 StatsMgr::generateName(
"pool", pool->getID(),
449 "reclaimed-declined-addresses")));
451 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
452 StatsMgr::generateName(
"pool", pool->getID(),
453 "reclaimed-leases")));
457 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
458 StatsMgr::generateName(
"pd-pool", pool->getID(),
461 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
462 StatsMgr::generateName(
"pd-pool", pool->getID(),
465 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
466 StatsMgr::generateName(
"pd-pool", pool->getID(),
467 "cumulative-assigned-pds")));
469 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
470 StatsMgr::generateName(
"pd-pool", pool->getID(),
471 "reclaimed-leases")));
480 StatsMgr& stats_mgr = StatsMgr::instance();
482 for (
auto const& subnet6 : subnets_) {
483 SubnetID subnet_id = subnet6->getID();
485 stats_mgr.setValue(StatsMgr::generateName(
"subnet", subnet_id,
489 stats_mgr.setValue(StatsMgr::generateName(
"subnet", subnet_id,
493 const std::string& name_nas(StatsMgr::generateName(
"subnet", subnet_id,
494 "cumulative-assigned-nas"));
495 if (!stats_mgr.getObservation(name_nas)) {
496 stats_mgr.setValue(name_nas,
static_cast<int64_t
>(0));
499 const std::string& name_pds(StatsMgr::generateName(
"subnet", subnet_id,
500 "cumulative-assigned-pds"));
501 if (!stats_mgr.getObservation(name_pds)) {
502 stats_mgr.setValue(name_pds,
static_cast<int64_t
>(0));
505 string const& name_ia_na_reuses(StatsMgr::generateName(
"subnet", subnet_id,
506 "v6-ia-na-lease-reuses"));
507 if (!stats_mgr.getObservation(name_ia_na_reuses)) {
508 stats_mgr.setValue(name_ia_na_reuses, int64_t(0));
511 string const& name_ia_pd_reuses(StatsMgr::generateName(
"subnet", subnet_id,
512 "v6-ia-pd-lease-reuses"));
513 if (!stats_mgr.getObservation(name_ia_pd_reuses)) {
514 stats_mgr.setValue(name_ia_pd_reuses, int64_t(0));
518 const std::string& name_total_nas(StatsMgr::generateName(
"subnet", subnet_id,
519 StatsMgr::generateName(
"pool", pool->getID(),
521 if (!stats_mgr.getObservation(name_total_nas)) {
522 stats_mgr.setValue(name_total_nas, pool->getCapacity());
524 stats_mgr.addValue(name_total_nas, pool->getCapacity());
527 const std::string& name_ca_nas(StatsMgr::generateName(
"subnet", subnet_id,
528 StatsMgr::generateName(
"pool", pool->getID(),
529 "cumulative-assigned-nas")));
530 if (!stats_mgr.getObservation(name_ca_nas)) {
531 stats_mgr.setValue(name_ca_nas,
static_cast<int64_t
>(0));
536 const std::string& name_total_pds(StatsMgr::generateName(
"subnet", subnet_id,
537 StatsMgr::generateName(
"pd-pool", pool->getID(),
539 if (!stats_mgr.getObservation(name_total_pds)) {
540 stats_mgr.setValue(name_total_pds, pool->getCapacity());
542 stats_mgr.addValue(name_total_pds, pool->getCapacity());
545 const std::string& name_ca_pds(StatsMgr::generateName(
"subnet", subnet_id,
546 StatsMgr::generateName(
"pd-pool", pool->getID(),
547 "cumulative-assigned-pds")));
548 if (!stats_mgr.getObservation(name_ca_pds)) {
549 stats_mgr.setValue(name_ca_pds,
static_cast<int64_t
>(0));
555 if (subnets_.begin() != subnets_.end()) {
562 for (
auto const& subnet : subnets_) {
563 subnet->initAllocatorsAfterConfigure();
576 for (
auto const& subnet : subnets_) {
577 result->add(subnet->toElement());
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
The IOAddress class represents an IP addresses (version agnostic)
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Holds subnets configured for the DHCPv6 server.
SubnetIDSet getLinks(const asiolink::IOAddress &link_addr) const
Convert a link address into a link set.
ConstSubnet6Ptr selectSubnet(const SubnetSelector &selector) const
Selects a subnet using parameters specified in the selector.
void updateStatistics()
Updates statistics.
Subnet6Ptr replace(const Subnet6Ptr &subnet)
Replaces subnet in the configuration.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
void merge(CfgOptionDefPtr cfg_def, CfgSharedNetworks6Ptr networks, CfgSubnets6 &other)
Merges specified subnet configuration into this configuration.
Subnet6Ptr getSubnet(const SubnetID id) const
Returns subnet with specified subnet-id value.
void removeStatistics()
Removes statistics.
void add(const Subnet6Ptr &subnet)
Adds new subnet to the configuration.
void clear()
Clears all subnets from the configuration.
static SubnetSelector initSelector(const Pkt6Ptr &query)
Build selector from a client's message.
void del(const ConstSubnet6Ptr &subnet)
Removes subnet from the configuration.
ConstSubnet6Ptr getByPrefix(const std::string &subnet_prefix) const
Returns const pointer to a subnet which matches the specified prefix in the canonical form.
void initAllocatorsAfterConfigure()
Calls initAllocatorsAfterConfigure for each subnet.
ConstSubnet6Ptr getBySubnetId(const SubnetID &subnet_id) const
Returns const pointer to a subnet identified by the specified subnet identifier.
Container for storing client class names.
Exception thrown upon attempt to add subnet with an ID that belongs to the subnet that already exists...
static TrackingLeaseMgr & instance()
Return current lease manager.
Statistics Manager class.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< Element > ElementPtr
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6_IFACE
const isc::log::MessageID DHCPSRV_CFGMGR_ADD_SUBNET6
std::set< dhcp::SubnetID > SubnetIDSet
Ordered list aka set of subnetIDs.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6_RELAY
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
const isc::log::MessageID DHCPSRV_CFGMGR_UPDATE_SUBNET6
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
boost::shared_ptr< CfgSharedNetworks6 > CfgSharedNetworks6Ptr
Pointer to the configuration of IPv6 shared networks.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6_IFACE_ID
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
const isc::log::MessageID DHCPSRV_CFGMGR_DEL_SUBNET6
const isc::log::MessageID DHCPSRV_SUBNET6_SELECT_BY_INTERFACE_ID_NO_MATCH
const isc::log::MessageID DHCPSRV_SUBNET6_SELECT_BY_ADDRESS_NO_MATCH
const isc::log::MessageID DHCPSRV_SUBNET6_SELECT_BY_INTERFACE_NO_MATCH
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Defines the logger used by the top-level component of kea-lfc.
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
@ TYPE_NA
the lease contains non-temporary IPv6 address
Tag for the index for searching by subnet prefix.
Subnet selector used to specify parameters used to select a subnet.
std::string iface_name_
Name of the interface on which the message was received.
Tag for the index for searching by subnet identifier.