Kea 3.1.8
cfg_subnets6.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2026 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8#include <dhcp/dhcp6.h>
12#include <dhcpsrv/dhcpsrv_log.h>
15#include <dhcpsrv/subnet_id.h>
16#include <stats/stats_mgr.h>
17#include <boost/range/adaptor/reversed.hpp>
18#include <string.h>
19#include <sstream>
20
21using namespace isc::asiolink;
22using namespace isc::data;
23
24using namespace std;
25
26namespace isc {
27namespace dhcp {
28
29void
31 if (getBySubnetId(subnet->getID())) {
32 isc_throw(isc::dhcp::DuplicateSubnetID, "ID of the new IPv6 subnet '"
33 << subnet->getID() << "' is already in use");
34
35 } else if (getByPrefix(subnet->toText())) {
38 isc_throw(isc::dhcp::DuplicateSubnetID, "subnet with the prefix of '"
39 << subnet->toText() << "' already exists");
40 }
41
43 .arg(subnet->toText());
44 static_cast<void>(subnets_.insert(subnet));
45}
46
49 // Get the subnet with the same ID.
50 const SubnetID& subnet_id = subnet->getID();
51 auto& index = subnets_.template get<SubnetSubnetIdIndexTag>();
52 auto subnet_it = index.find(subnet_id);
53 if (subnet_it == index.end()) {
54 isc_throw(BadValue, "There is no IPv6 subnet with ID " << subnet_id);
55 }
56 Subnet6Ptr old = *subnet_it;
57 bool ret = index.replace(subnet_it, subnet);
58
60 .arg(subnet_id).arg(ret);
61 if (ret) {
62 return (old);
63 } else {
64 return (Subnet6Ptr());
65 }
66}
67
68void
70 del(subnet->getID());
71}
72
73void
74CfgSubnets6::del(const SubnetID& subnet_id) {
75 auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
76 auto subnet_it = index.find(subnet_id);
77 if (subnet_it == index.end()) {
78 isc_throw(BadValue, "no subnet with ID of '" << subnet_id
79 << "' found");
80 }
81
82 Subnet6Ptr subnet = *subnet_it;
83
84 index.erase(subnet_it);
85
87 .arg(subnet->toText());
88}
89
90void
92 CfgSubnets6& other) {
93 auto& index_id = subnets_.get<SubnetSubnetIdIndexTag>();
94 auto& index_prefix = subnets_.get<SubnetPrefixIndexTag>();
95
96 // Iterate over the subnets to be merged. They will replace the existing
97 // subnets with the same id. All new subnets will be inserted into the
98 // configuration into which we're merging.
99 auto const& other_subnets = other.getAll();
100 for (auto const& other_subnet : *other_subnets) {
101
102 // Check if there is a subnet with the same ID.
103 auto subnet_it = index_id.find(other_subnet->getID());
104 if (subnet_it != index_id.end()) {
105
106 // Subnet found.
107 auto existing_subnet = *subnet_it;
108
109 // If the existing subnet and other subnet
110 // are the same instance skip it.
111 if (existing_subnet == other_subnet) {
112 continue;
113 }
114
115 // We're going to replace the existing subnet with the other
116 // version. If it belongs to a shared network, we need
117 // remove it from that network.
118 SharedNetwork6Ptr network;
119 existing_subnet->getSharedNetwork(network);
120 if (network) {
121 network->del(existing_subnet->getID());
122 }
123
124 // Now we remove the existing subnet.
125 index_id.erase(subnet_it);
126 }
127
128 // Check if there is a subnet with the same prefix.
129 auto subnet_prefix_it = index_prefix.find(other_subnet->toText());
130 if (subnet_prefix_it != index_prefix.end()) {
131
132 // Subnet found.
133 auto existing_subnet = *subnet_prefix_it;
134
135 // Updating the id can lead to problems... e.g. reservation
136 // for the previous subnet ID.
137 // @todo: check reservations
138
139 // We're going to replace the existing subnet with the other
140 // version. If it belongs to a shared network, we need
141 // remove it from that network.
142 SharedNetwork6Ptr network;
143 existing_subnet->getSharedNetwork(network);
144 if (network) {
145 network->del(existing_subnet->getID());
146 }
147
148 // Now we remove the existing subnet.
149 index_prefix.erase(subnet_prefix_it);
150 }
151
152 // Create the subnet's options based on the given definitions.
153 other_subnet->getCfgOption()->createOptions(cfg_def);
154
155 // Encapsulate options, so that the DHCP server can effectively return
156 // them to the clients without having to encapsulate them for each request.
157 other_subnet->getCfgOption()->encapsulate();
158
159 // Create the options for pool based on the given definitions.
160 for (auto const& pool : other_subnet->getPoolsWritable(Lease::TYPE_NA)) {
161 pool->getCfgOption()->createOptions(cfg_def);
162 pool->getCfgOption()->encapsulate();
163 }
164
165 // Create the options for pd pool based on the given definitions.
166 for (auto const& pool : other_subnet->getPoolsWritable(Lease::TYPE_PD)) {
167 pool->getCfgOption()->createOptions(cfg_def);
168 pool->getCfgOption()->encapsulate();
169 }
170
171 // Add the "other" subnet to the our collection of subnets.
172 static_cast<void>(subnets_.insert(other_subnet));
173
174 // If it belongs to a shared network, find the network and
175 // add the subnet to it
176 std::string network_name = other_subnet->getSharedNetworkName();
177 if (!network_name.empty()) {
178 SharedNetwork6Ptr network = networks->getByName(network_name);
179 if (network) {
180 network->add(other_subnet);
181 } else {
182 // This implies the shared-network collection we were given
183 // is out of sync with the subnets we were given.
184 isc_throw(InvalidOperation, "Cannot assign subnet ID of "
185 << other_subnet->getID()
186 << " to shared network: " << network_name
187 << ", network does not exist");
188 }
189 }
190 // Instantiate the configured allocators and their states.
191 other_subnet->createAllocators();
192 }
193}
194
196CfgSubnets6::getByPrefix(const std::string& subnet_text) const {
197 auto const& index = subnets_.get<SubnetPrefixIndexTag>();
198 auto subnet_it = index.find(subnet_text);
199 return ((subnet_it != index.cend()) ? (*subnet_it) : ConstSubnet6Ptr());
200}
201
204 // Initialize subnet selector with the values used to select the subnet.
205 SubnetSelector selector;
206 selector.iface_name_ = query->getIface();
207 selector.remote_address_ = query->getRemoteAddr();
208 selector.first_relay_linkaddr_ = IOAddress("::");
209 selector.client_classes_ = query->classes_;
210
211 // Initialize fields specific to relayed messages.
212 if (!query->relay_info_.empty()) {
213 for (auto const& relay : boost::adaptors::reverse(query->relay_info_)) {
214 if (!relay.linkaddr_.isV6Zero() &&
215 !relay.linkaddr_.isV6LinkLocal()) {
216 selector.first_relay_linkaddr_ = relay.linkaddr_;
217 break;
218 }
219 }
220 selector.interface_id_ =
221 query->getAnyRelayOption(D6O_INTERFACE_ID,
223 }
224
225 return (selector);
226}
227
230 ConstSubnet6Ptr subnet;
231
232 // If relay agent link address is set to zero it means that we're dealing
233 // with a directly connected client.
234 if (selector.first_relay_linkaddr_ == IOAddress("::")) {
235 // If interface name is known try to match it with interface names
236 // specified for configured subnets.
237 if (!selector.iface_name_.empty()) {
238 subnet = selectSubnet(selector.iface_name_,
239 selector.client_classes_);
240 }
241
242 // If interface name didn't match, try the client's address.
243 if (!subnet && selector.remote_address_ != IOAddress("::")) {
244 subnet = selectSubnet(selector.remote_address_,
245 selector.client_classes_);
246 }
247
248 // If relay agent link address is set, we're dealing with a relayed message.
249 } else {
250 // Find the subnet using the Interface Id option, if present.
251 subnet = selectSubnet(selector.interface_id_, selector.client_classes_);
252
253 // If Interface ID option could not be matched for any subnet, try
254 // the relay agent link address.
255 if (!subnet) {
256 subnet = selectSubnet(selector.first_relay_linkaddr_,
257 selector.client_classes_,
258 true);
259 }
260 }
261
262 // Return subnet found, or NULL if not found.
263 return (subnet);
264}
265
268 const ClientClasses& client_classes,
269 const bool is_relay_address) const {
270 // If the specified address is a relay address we first need to match
271 // it with the relay addresses specified for all subnets.
272 if (is_relay_address) {
273 for (auto const& subnet : subnets_) {
274
275 // If the specified address matches a relay address, return this
276 // subnet.
277 if (subnet->hasRelays()) {
278 if (!subnet->hasRelayAddress(address)) {
279 continue;
280 }
281
282 } else {
283 SharedNetwork6Ptr network;
284 subnet->getSharedNetwork(network);
285 if (!network || !network->hasRelayAddress(address)) {
286 continue;
287 }
288 }
289
290 if (subnet->clientSupported(client_classes)) {
291 // The relay address is matching the one specified for a subnet
292 // or its shared network.
295 .arg(subnet->toText()).arg(address.toText());
296 return (subnet);
297 }
298 }
299 }
300
301 // No success so far. Check if the specified address is in range
302 // with any subnet.
303 for (auto const& subnet : subnets_) {
304 if (subnet->inRange(address) && subnet->clientSupported(client_classes)) {
306 .arg(subnet->toText()).arg(address.toText());
307 return (subnet);
308 }
309 }
310
313 .arg(address.toText());
314
315 // Nothing found.
316 return (ConstSubnet6Ptr());
317}
318
320CfgSubnets6::selectSubnet(const std::string& iface_name,
321 const ClientClasses& client_classes) const {
322 // If empty interface specified, we can't select subnet by interface.
323 if (!iface_name.empty()) {
324 for (auto const& subnet : subnets_) {
325
326 // If interface name matches with the one specified for the subnet
327 // and the client is not rejected based on the classification,
328 // return the subnet.
329 if ((subnet->getIface() == iface_name) &&
330 subnet->clientSupported(client_classes)) {
333 .arg(subnet->toText()).arg(iface_name);
334 return (subnet);
335 }
336 }
337 }
338
341 .arg(iface_name);
342
343 // No subnet found for this interface name.
344 return (ConstSubnet6Ptr());
345}
346
348CfgSubnets6::selectSubnet(const OptionPtr& interface_id,
349 const ClientClasses& client_classes) const {
350 // We can only select subnet using an interface id, if the interface
351 // id is known.
352 if (interface_id) {
353 for (auto const& subnet : subnets_) {
354
355 // If interface id matches for the subnet and the subnet is not
356 // rejected based on the classification.
357 if (subnet->getInterfaceId() &&
358 subnet->getInterfaceId()->equals(interface_id) &&
359 subnet->clientSupported(client_classes)) {
360
363 .arg(subnet->toText());
364 return (subnet);
365 }
366 }
367
370 .arg(interface_id->toText());
371 }
372
373 // No subnet found.
374 return (ConstSubnet6Ptr());
375}
376
378CfgSubnets6::getSubnet(const SubnetID subnet_id) const {
379 auto const& index = subnets_.get<SubnetSubnetIdIndexTag>();
380 auto subnet_it = index.find(subnet_id);
381 return ((subnet_it != index.cend()) ? (*subnet_it) : Subnet6Ptr());
382}
383
385CfgSubnets6::getLinks(const IOAddress& link_addr) const {
386 SubnetIDSet links;
387 for (auto const& subnet : subnets_) {
388 if (!subnet->inRange(link_addr)) {
389 continue;
390 }
391 links.insert(subnet->getID());
392 }
393 return (links);
394}
395
396void
398 using namespace isc::stats;
399
400 StatsMgr& stats_mgr = StatsMgr::instance();
401 // For each v6 subnet currently configured, remove the statistics.
402 for (auto const& subnet6 : subnets_) {
403 SubnetID subnet_id = subnet6->getID();
404 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
405 "total-nas"));
406
407 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
408 "assigned-nas"));
409
410 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
411 "cumulative-assigned-nas"));
412
413 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
414 "total-pds"));
415
416 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
417 "assigned-pds"));
418
419 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
420 "cumulative-assigned-pds"));
421
422 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
423 "declined-addresses"));
424
425 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
426 "reclaimed-declined-addresses"));
427
428 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
429 "reclaimed-leases"));
430
431 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
432 "cumulative-registered-nas"));
433
434 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
435 "registered-nas"));
436
437 for (auto const& pool : subnet6->getPools(Lease::TYPE_NA)) {
438 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
439 StatsMgr::generateName("pool", pool->getID(),
440 "total-nas")));
441
442 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
443 StatsMgr::generateName("pool", pool->getID(),
444 "assigned-nas")));
445
446 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
447 StatsMgr::generateName("pool", pool->getID(),
448 "cumulative-assigned-nas")));
449
450 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
451 StatsMgr::generateName("pool", pool->getID(),
452 "declined-addresses")));
453
454 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
455 StatsMgr::generateName("pool", pool->getID(),
456 "reclaimed-declined-addresses")));
457
458 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
459 StatsMgr::generateName("pool", pool->getID(),
460 "reclaimed-leases")));
461 }
462
463 for (auto const& pool : subnet6->getPools(Lease::TYPE_PD)) {
464 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
465 StatsMgr::generateName("pd-pool", pool->getID(),
466 "total-pds")));
467
468 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
469 StatsMgr::generateName("pd-pool", pool->getID(),
470 "assigned-pds")));
471
472 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
473 StatsMgr::generateName("pd-pool", pool->getID(),
474 "cumulative-assigned-pds")));
475
476 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
477 StatsMgr::generateName("pd-pool", pool->getID(),
478 "reclaimed-leases")));
479 }
480 }
481}
482
483void
485 using namespace isc::stats;
486
487 StatsMgr& stats_mgr = StatsMgr::instance();
488 // For each v6 subnet currently configured, calculate totals
489 for (auto const& subnet6 : subnets_) {
490 SubnetID subnet_id = subnet6->getID();
491
492 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
493 "total-nas"),
494 subnet6->getPoolCapacity(Lease::TYPE_NA));
495
496 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
497 "total-pds"),
498 subnet6->getPoolCapacity(Lease::TYPE_PD));
499
500 const std::string& name_nas(StatsMgr::generateName("subnet", subnet_id,
501 "cumulative-assigned-nas"));
502 if (!stats_mgr.getObservation(name_nas)) {
503 stats_mgr.setValue(name_nas, static_cast<int64_t>(0));
504 }
505
506 const std::string& name_pds(StatsMgr::generateName("subnet", subnet_id,
507 "cumulative-assigned-pds"));
508 if (!stats_mgr.getObservation(name_pds)) {
509 stats_mgr.setValue(name_pds, static_cast<int64_t>(0));
510 }
511
512 string const& name_ia_na_reuses(StatsMgr::generateName("subnet", subnet_id,
513 "v6-ia-na-lease-reuses"));
514 if (!stats_mgr.getObservation(name_ia_na_reuses)) {
515 stats_mgr.setValue(name_ia_na_reuses, int64_t(0));
516 }
517
518 string const& name_ia_pd_reuses(StatsMgr::generateName("subnet", subnet_id,
519 "v6-ia-pd-lease-reuses"));
520 if (!stats_mgr.getObservation(name_ia_pd_reuses)) {
521 stats_mgr.setValue(name_ia_pd_reuses, int64_t(0));
522 }
523
524 string const& name_registered(StatsMgr::generateName("subnet", subnet_id,
525 "cumulative-registered-nas"));
526
527 if (!stats_mgr.getObservation(name_registered)) {
528 stats_mgr.setValue(name_registered, static_cast<int64_t>(0));
529 }
530
531 for (auto const& pool : subnet6->getPools(Lease::TYPE_NA)) {
532 const std::string& name_total_nas(StatsMgr::generateName("subnet", subnet_id,
533 StatsMgr::generateName("pool", pool->getID(),
534 "total-nas")));
535 if (!stats_mgr.getObservation(name_total_nas)) {
536 stats_mgr.setValue(name_total_nas, pool->getCapacity());
537 } else {
538 stats_mgr.addValue(name_total_nas, pool->getCapacity());
539 }
540
541 const std::string& name_ca_nas(StatsMgr::generateName("subnet", subnet_id,
542 StatsMgr::generateName("pool", pool->getID(),
543 "cumulative-assigned-nas")));
544 if (!stats_mgr.getObservation(name_ca_nas)) {
545 stats_mgr.setValue(name_ca_nas, static_cast<int64_t>(0));
546 }
547 }
548
549 for (auto const& pool : subnet6->getPools(Lease::TYPE_PD)) {
550 const std::string& name_total_pds(StatsMgr::generateName("subnet", subnet_id,
551 StatsMgr::generateName("pd-pool", pool->getID(),
552 "total-pds")));
553 if (!stats_mgr.getObservation(name_total_pds)) {
554 stats_mgr.setValue(name_total_pds, pool->getCapacity());
555 } else {
556 stats_mgr.addValue(name_total_pds, pool->getCapacity());
557 }
558
559 const std::string& name_ca_pds(StatsMgr::generateName("subnet", subnet_id,
560 StatsMgr::generateName("pd-pool", pool->getID(),
561 "cumulative-assigned-pds")));
562 if (!stats_mgr.getObservation(name_ca_pds)) {
563 stats_mgr.setValue(name_ca_pds, static_cast<int64_t>(0));
564 }
565 }
566 }
567
568 // Only recount the stats if we have subnets.
569 if (subnets_.begin() != subnets_.end()) {
571 }
572}
573
574void
577 for (auto const& subnet : subnets_) {
578 subnet->initAllocatorsAfterConfigure();
579 }
580}
581
582void
584 subnets_.clear();
585}
586
590 // Iterate subnets
591 for (auto const& subnet : subnets_) {
592 result->add(subnet->toElement());
593 }
594 return (result);
595}
596
597} // end of namespace isc::dhcp
598} // end of namespace isc
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.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:349
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.
const Subnet6Collection * getAll() const
Returns pointer to the collection of all IPv6 subnets.
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.
Definition classify.h:110
Exception thrown upon attempt to add subnet with an ID that belongs to the subnet that already exists...
Definition subnet_id.h:36
static TrackingLeaseMgr & instance()
Return current lease manager.
void recountLeaseStats6()
Recalculates per-subnet and global stats for IPv6 leases.
Definition lease_mgr.cc:297
@ RELAY_GET_FIRST
Definition pkt6.h:77
static void setInUse(bool in_use)
Sets the global in-use flag.
Statistics Manager class.
ObservationPtr getObservation(const std::string &name) const
Returns an observation.
static StatsMgr & instance()
Statistics Manager accessor method.
static std::string generateName(const std::string &context, Type index, const std::string &stat_name)
Generates statistic name in a given context.
@ D6O_INTERFACE_ID
Definition dhcp6.h:38
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
bool del(const std::string &name)
Removes specified statistic.
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
int get(CalloutHandle &handle)
The gss-tsig-get command.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
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.
Definition subnet_id.h:43
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6_RELAY
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
Definition subnet.h:623
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.
Definition subnet.h:626
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.
Definition subnet_id.h:25
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.
Definition pkt6.h:31
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.
Definition dhcpsrv_log.h:26
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
Defines the logger used by the top-level component of kea-lfc.
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition lease.h:49
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition lease.h:47
Tag for the index for searching by subnet prefix.
Definition subnet.h:780
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.
ClientClasses client_classes_
Classes that the client belongs to.
asiolink::IOAddress remote_address_
Source address of the message.
OptionPtr interface_id_
Interface id option.
asiolink::IOAddress first_relay_linkaddr_
First relay link address.
Tag for the index for searching by subnet identifier.
Definition subnet.h:777