Kea 3.2.0
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 // Note that a link local address is useless so skip it.
215 if (!relay.linkaddr_.isV6Zero() &&
216 !relay.linkaddr_.isV6LinkLocal()) {
217 selector.first_relay_linkaddr_ = relay.linkaddr_;
218 break;
219 }
220 }
221 selector.interface_id_ =
222 query->getAnyRelayOption(D6O_INTERFACE_ID,
224 }
225
226 return (selector);
227}
228
231 ConstSubnet6Ptr subnet;
232
233 // If relay agent link address is set to zero and there is no interface id
234 // it means that we're dealing with a directly connected client.
235 if ((selector.first_relay_linkaddr_ == IOAddress("::")) &&
236 !selector.interface_id_) {
237 // If interface name is known try to match it with interface names
238 // specified for configured subnets.
239 if (!selector.iface_name_.empty()) {
240 subnet = selectSubnet(selector.iface_name_,
241 selector.client_classes_);
242 }
243
244 // If interface name didn't match, try the client's address.
245 if (!subnet && selector.remote_address_ != IOAddress("::")) {
246 subnet = selectSubnet(selector.remote_address_,
247 selector.client_classes_);
248 }
249
250 // If relay agent link address is set, we're dealing with a relayed message.
251 } else {
252 // Find the subnet using the Interface Id option, if present.
253 subnet = selectSubnet(selector.interface_id_, selector.client_classes_);
254
255 // If Interface ID option could not be matched for any subnet, try
256 // the relay agent link address.
257 if (!subnet && (selector.first_relay_linkaddr_ != IOAddress("::"))) {
258 subnet = selectSubnet(selector.first_relay_linkaddr_,
259 selector.client_classes_,
260 true);
261 }
262 }
263
264 // Return subnet found, or NULL if not found.
265 return (subnet);
266}
267
270 const ClientClasses& client_classes,
271 const bool is_relay_address) const {
272 // If the specified address is a relay address we first need to match
273 // it with the relay addresses specified for all subnets.
274 if (is_relay_address) {
275 for (auto const& subnet : subnets_) {
276
277 // If the specified address matches a relay address, return this
278 // subnet.
279 if (subnet->hasRelays()) {
280 if (!subnet->hasRelayAddress(address)) {
281 continue;
282 }
283
284 } else {
285 SharedNetwork6Ptr network;
286 subnet->getSharedNetwork(network);
287 if (!network || !network->hasRelayAddress(address)) {
288 continue;
289 }
290 }
291
292 if (subnet->clientSupported(client_classes)) {
293 // The relay address is matching the one specified for a subnet
294 // or its shared network.
297 .arg(subnet->toText()).arg(address.toText());
298 return (subnet);
299 }
300 }
301 }
302
303 // No success so far. Check if the specified address is in range
304 // with any subnet.
305 for (auto const& subnet : subnets_) {
306 if (subnet->inRange(address) && subnet->clientSupported(client_classes)) {
308 .arg(subnet->toText()).arg(address.toText());
309 return (subnet);
310 }
311 }
312
315 .arg(address.toText());
316
317 // Nothing found.
318 return (ConstSubnet6Ptr());
319}
320
322CfgSubnets6::selectSubnet(const std::string& iface_name,
323 const ClientClasses& client_classes) const {
324 // If empty interface specified, we can't select subnet by interface.
325 if (!iface_name.empty()) {
326 for (auto const& subnet : subnets_) {
327
328 // If interface name matches with the one specified for the subnet
329 // and the client is not rejected based on the classification,
330 // return the subnet.
331 if ((subnet->getIface() == iface_name) &&
332 subnet->clientSupported(client_classes)) {
335 .arg(subnet->toText()).arg(iface_name);
336 return (subnet);
337 }
338 }
339 }
340
343 .arg(iface_name);
344
345 // No subnet found for this interface name.
346 return (ConstSubnet6Ptr());
347}
348
350CfgSubnets6::selectSubnet(const OptionPtr& interface_id,
351 const ClientClasses& client_classes) const {
352 // We can only select subnet using an interface id, if the interface
353 // id is known.
354 if (interface_id) {
355 for (auto const& subnet : subnets_) {
356
357 // If interface id matches for the subnet and the subnet is not
358 // rejected based on the classification.
359 if (subnet->getInterfaceId() &&
360 subnet->getInterfaceId()->equals(interface_id) &&
361 subnet->clientSupported(client_classes)) {
362
365 .arg(subnet->toText());
366 return (subnet);
367 }
368 }
369
372 .arg(interface_id->toText());
373 }
374
375 // No subnet found.
376 return (ConstSubnet6Ptr());
377}
378
380CfgSubnets6::getSubnet(const SubnetID subnet_id) const {
381 auto const& index = subnets_.get<SubnetSubnetIdIndexTag>();
382 auto subnet_it = index.find(subnet_id);
383 return ((subnet_it != index.cend()) ? (*subnet_it) : Subnet6Ptr());
384}
385
387CfgSubnets6::getLinks(const IOAddress& link_addr) const {
388 SubnetIDSet links;
389 for (auto const& subnet : subnets_) {
390 if (!subnet->inRange(link_addr)) {
391 continue;
392 }
393 links.insert(subnet->getID());
394 }
395 return (links);
396}
397
398void
400 using namespace isc::stats;
401
402 StatsMgr& stats_mgr = StatsMgr::instance();
403 // For each v6 subnet currently configured, remove the statistics.
404 for (auto const& subnet6 : subnets_) {
405 SubnetID subnet_id = subnet6->getID();
406 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
407 "total-nas"));
408
409 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
410 "assigned-nas"));
411
412 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
413 "cumulative-assigned-nas"));
414
415 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
416 "total-pds"));
417
418 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
419 "assigned-pds"));
420
421 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
422 "cumulative-assigned-pds"));
423
424 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
425 "declined-addresses"));
426
427 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
428 "reclaimed-declined-addresses"));
429
430 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
431 "reclaimed-leases"));
432
433 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
434 "cumulative-registered-nas"));
435
436 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
437 "registered-nas"));
438
439 for (auto const& pool : subnet6->getPools(Lease::TYPE_NA)) {
440 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
441 StatsMgr::generateName("pool", pool->getID(),
442 "total-nas")));
443
444 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
445 StatsMgr::generateName("pool", pool->getID(),
446 "assigned-nas")));
447
448 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
449 StatsMgr::generateName("pool", pool->getID(),
450 "cumulative-assigned-nas")));
451
452 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
453 StatsMgr::generateName("pool", pool->getID(),
454 "declined-addresses")));
455
456 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
457 StatsMgr::generateName("pool", pool->getID(),
458 "reclaimed-declined-addresses")));
459
460 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
461 StatsMgr::generateName("pool", pool->getID(),
462 "reclaimed-leases")));
463 }
464
465 for (auto const& pool : subnet6->getPools(Lease::TYPE_PD)) {
466 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
467 StatsMgr::generateName("pd-pool", pool->getID(),
468 "total-pds")));
469
470 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
471 StatsMgr::generateName("pd-pool", pool->getID(),
472 "assigned-pds")));
473
474 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
475 StatsMgr::generateName("pd-pool", pool->getID(),
476 "cumulative-assigned-pds")));
477
478 stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
479 StatsMgr::generateName("pd-pool", pool->getID(),
480 "reclaimed-leases")));
481 }
482 }
483}
484
485void
487 using namespace isc::stats;
488
489 StatsMgr& stats_mgr = StatsMgr::instance();
490 // For each v6 subnet currently configured, calculate totals
491 for (auto const& subnet6 : subnets_) {
492 SubnetID subnet_id = subnet6->getID();
493
494 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
495 "total-nas"),
496 subnet6->getPoolCapacity(Lease::TYPE_NA));
497
498 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
499 "total-pds"),
500 subnet6->getPoolCapacity(Lease::TYPE_PD));
501
502 const std::string& name_nas(StatsMgr::generateName("subnet", subnet_id,
503 "cumulative-assigned-nas"));
504 if (!stats_mgr.getObservation(name_nas)) {
505 stats_mgr.setValue(name_nas, static_cast<int64_t>(0));
506 }
507
508 const std::string& name_pds(StatsMgr::generateName("subnet", subnet_id,
509 "cumulative-assigned-pds"));
510 if (!stats_mgr.getObservation(name_pds)) {
511 stats_mgr.setValue(name_pds, static_cast<int64_t>(0));
512 }
513
514 string const& name_ia_na_reuses(StatsMgr::generateName("subnet", subnet_id,
515 "v6-ia-na-lease-reuses"));
516 if (!stats_mgr.getObservation(name_ia_na_reuses)) {
517 stats_mgr.setValue(name_ia_na_reuses, int64_t(0));
518 }
519
520 string const& name_ia_pd_reuses(StatsMgr::generateName("subnet", subnet_id,
521 "v6-ia-pd-lease-reuses"));
522 if (!stats_mgr.getObservation(name_ia_pd_reuses)) {
523 stats_mgr.setValue(name_ia_pd_reuses, int64_t(0));
524 }
525
526 string const& name_registered(StatsMgr::generateName("subnet", subnet_id,
527 "cumulative-registered-nas"));
528
529 if (!stats_mgr.getObservation(name_registered)) {
530 stats_mgr.setValue(name_registered, static_cast<int64_t>(0));
531 }
532
533 for (auto const& pool : subnet6->getPools(Lease::TYPE_NA)) {
534 const std::string& name_total_nas(StatsMgr::generateName("subnet", subnet_id,
535 StatsMgr::generateName("pool", pool->getID(),
536 "total-nas")));
537 if (!stats_mgr.getObservation(name_total_nas)) {
538 stats_mgr.setValue(name_total_nas, pool->getCapacity());
539 } else {
540 stats_mgr.addValue(name_total_nas, pool->getCapacity());
541 }
542
543 const std::string& name_ca_nas(StatsMgr::generateName("subnet", subnet_id,
544 StatsMgr::generateName("pool", pool->getID(),
545 "cumulative-assigned-nas")));
546 if (!stats_mgr.getObservation(name_ca_nas)) {
547 stats_mgr.setValue(name_ca_nas, static_cast<int64_t>(0));
548 }
549 }
550
551 for (auto const& pool : subnet6->getPools(Lease::TYPE_PD)) {
552 const std::string& name_total_pds(StatsMgr::generateName("subnet", subnet_id,
553 StatsMgr::generateName("pd-pool", pool->getID(),
554 "total-pds")));
555 if (!stats_mgr.getObservation(name_total_pds)) {
556 stats_mgr.setValue(name_total_pds, pool->getCapacity());
557 } else {
558 stats_mgr.addValue(name_total_pds, pool->getCapacity());
559 }
560
561 const std::string& name_ca_pds(StatsMgr::generateName("subnet", subnet_id,
562 StatsMgr::generateName("pd-pool", pool->getID(),
563 "cumulative-assigned-pds")));
564 if (!stats_mgr.getObservation(name_ca_pds)) {
565 stats_mgr.setValue(name_ca_pds, static_cast<int64_t>(0));
566 }
567 }
568 }
569
570 // Only recount the stats if we have subnets.
571 if (subnets_.begin() != subnets_.end()) {
573 }
574}
575
576void
579 for (auto const& subnet : subnets_) {
580 subnet->initAllocatorsAfterConfigure();
581 }
582}
583
584void
586 subnets_.clear();
587}
588
592 // Iterate subnets
593 for (auto const& subnet : subnets_) {
594 result->add(subnet->toElement());
595 }
596 return (result);
597}
598
599} // end of namespace isc::dhcp
600} // 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:620
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:623
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:777
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:774