Kea 2.2.0
subnet.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2021 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
11#include <dhcp/option_space.h>
13#include <dhcpsrv/subnet.h>
15
16#include <boost/lexical_cast.hpp>
17#include <boost/make_shared.hpp>
18
19#include <algorithm>
20#include <sstream>
21
22using namespace isc::asiolink;
23using namespace isc::data;
24using namespace isc::dhcp;
25using namespace isc::util;
26
27namespace {
28
33bool
34prefixLessThanFirstAddress(const IOAddress& prefix, const PoolPtr& pool) {
35 return (prefix < pool->getFirstAddress());
36}
37
46bool
47comparePoolFirstAddress(const PoolPtr& pool1, const PoolPtr& pool2) {
48 return (pool1->getFirstAddress() < pool2->getFirstAddress());
49};
50
51}
52
53namespace isc {
54namespace dhcp {
55
56// This is an initial value of subnet-id. See comments in subnet.h for details.
58
59Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
60 const SubnetID id)
61 : id_(id == 0 ? generateNextID() : id), prefix_(prefix),
62 prefix_len_(len),
63 last_allocated_ia_(lastAddrInPrefix(prefix, len)),
64 last_allocated_ta_(lastAddrInPrefix(prefix, len)),
65 last_allocated_pd_(lastAddrInPrefix(prefix, len)),
66 last_allocated_time_(),
67 shared_network_name_(),
68 mutex_(new std::mutex) {
69 if ((prefix.isV6() && len > 128) ||
70 (prefix.isV4() && len > 32)) {
72 "Invalid prefix length specified for subnet: " << len);
73 }
74
75 // Initialize timestamps for each lease type to negative infinity.
76 last_allocated_time_[Lease::TYPE_V4] = boost::posix_time::neg_infin;
77 last_allocated_time_[Lease::TYPE_NA] = boost::posix_time::neg_infin;
78 last_allocated_time_[Lease::TYPE_TA] = boost::posix_time::neg_infin;
79 last_allocated_time_[Lease::TYPE_PD] = boost::posix_time::neg_infin;
80}
81
82bool
86
87 return ((first <= addr) && (addr <= last));
88}
89
91 if (MultiThreadingMgr::instance().getMode()) {
92 std::lock_guard<std::mutex> lock(*mutex_);
93 return (getLastAllocatedInternal(type));
94 } else {
95 return (getLastAllocatedInternal(type));
96 }
97}
98
99isc::asiolink::IOAddress Subnet::getLastAllocatedInternal(Lease::Type type) const {
100 // check if the type is valid (and throw if it isn't)
101 checkType(type);
102
103 switch (type) {
104 case Lease::TYPE_V4:
105 case Lease::TYPE_NA:
106 return last_allocated_ia_;
107 case Lease::TYPE_TA:
108 return last_allocated_ta_;
109 case Lease::TYPE_PD:
110 return last_allocated_pd_;
111 default:
112 isc_throw(BadValue, "Pool type " << type << " not supported");
113 }
114}
115
116boost::posix_time::ptime
118 if (MultiThreadingMgr::instance().getMode()) {
119 std::lock_guard<std::mutex> lock(*mutex_);
120 return (getLastAllocatedTimeInternal(lease_type));
121 } else {
122 return (getLastAllocatedTimeInternal(lease_type));
123 }
124}
125
126boost::posix_time::ptime
127Subnet::getLastAllocatedTimeInternal(const Lease::Type& lease_type) const {
128 auto t = last_allocated_time_.find(lease_type);
129 if (t != last_allocated_time_.end()) {
130 return (t->second);
131 }
132
133 // This shouldn't happen, because we have initialized the structure
134 // for all lease types.
135 return (boost::posix_time::neg_infin);
136}
137
139 const isc::asiolink::IOAddress& addr) {
140 if (MultiThreadingMgr::instance().getMode()) {
141 std::lock_guard<std::mutex> lock(*mutex_);
142 setLastAllocatedInternal(type, addr);
143 } else {
144 setLastAllocatedInternal(type, addr);
145 }
146}
147
148void Subnet::setLastAllocatedInternal(Lease::Type type,
149 const isc::asiolink::IOAddress& addr) {
150
151 // check if the type is valid (and throw if it isn't)
152 checkType(type);
153
154 switch (type) {
155 case Lease::TYPE_V4:
156 case Lease::TYPE_NA:
157 last_allocated_ia_ = addr;
158 break;
159 case Lease::TYPE_TA:
160 last_allocated_ta_ = addr;
161 break;
162 case Lease::TYPE_PD:
163 last_allocated_pd_ = addr;
164 break;
165 default:
166 isc_throw(BadValue, "Pool type " << type << " not supported");
167 }
168
169 // Update the timestamp of last allocation.
170 last_allocated_time_[type] = boost::posix_time::microsec_clock::universal_time();
171}
172
173std::string
175 std::stringstream tmp;
176 tmp << prefix_ << "/" << static_cast<unsigned int>(prefix_len_);
177 return (tmp.str());
178}
179
180uint64_t
182 switch (type) {
183 case Lease::TYPE_V4:
184 case Lease::TYPE_NA:
185 return sumPoolCapacity(pools_);
186 case Lease::TYPE_TA:
188 case Lease::TYPE_PD:
190 default:
191 isc_throw(BadValue, "Unsupported pool type: "
192 << static_cast<int>(type));
193 }
194}
195
196uint64_t
198 const ClientClasses& client_classes) const {
199 switch (type) {
200 case Lease::TYPE_V4:
201 case Lease::TYPE_NA:
202 return sumPoolCapacity(pools_, client_classes);
203 case Lease::TYPE_TA:
204 return sumPoolCapacity(pools_ta_, client_classes);
205 case Lease::TYPE_PD:
206 return sumPoolCapacity(pools_pd_, client_classes);
207 default:
208 isc_throw(BadValue, "Unsupported pool type: "
209 << static_cast<int>(type));
210 }
211}
212
213uint64_t
215 uint64_t sum = 0;
216 for (PoolCollection::const_iterator p = pools.begin(); p != pools.end(); ++p) {
217 uint64_t x = (*p)->getCapacity();
218
219 // Check if we can add it. If sum + x > uint64::max, then we would have
220 // overflown if we tried to add it.
221 if (x > std::numeric_limits<uint64_t>::max() - sum) {
222 return (std::numeric_limits<uint64_t>::max());
223 }
224
225 sum += x;
226 }
227
228 return (sum);
229}
230
231uint64_t
233 const ClientClasses& client_classes) const {
234 uint64_t sum = 0;
235 for (PoolCollection::const_iterator p = pools.begin(); p != pools.end(); ++p) {
236 if (!(*p)->clientSupported(client_classes)) {
237 continue;
238 }
239 uint64_t x = (*p)->getCapacity();
240
241 // Check if we can add it. If sum + x > uint64::max, then we would have
242 // overflown if we tried to add it.
243 if (x > std::numeric_limits<uint64_t>::max() - sum) {
244 return (std::numeric_limits<uint64_t>::max());
245 }
246
247 sum += x;
248 }
249
250 return (sum);
251}
252
253std::pair<IOAddress, uint8_t>
254Subnet::parsePrefixCommon(const std::string& prefix) {
255 auto pos = prefix.find('/');
256 if ((pos == std::string::npos) ||
257 (pos == prefix.size() - 1) ||
258 (pos == 0)) {
259 isc_throw(BadValue, "unable to parse invalid prefix " << prefix);
260 }
261
262 try {
263 IOAddress address(prefix.substr(0, pos));
264 int length = boost::lexical_cast<int>(prefix.substr(pos + 1));
265 return (std::make_pair(address, static_cast<int>(length)));
266
267 } catch (...) {
268 isc_throw(BadValue, "unable to parse invalid prefix " << prefix);
269 }
270}
271
272
273void Subnet4::checkType(Lease::Type type) const {
274 if (type != Lease::TYPE_V4) {
275 isc_throw(BadValue, "Only TYPE_V4 is allowed for Subnet4");
276 }
277}
278
279Subnet4::Subnet4(const IOAddress& prefix, uint8_t length,
280 const Triplet<uint32_t>& t1,
281 const Triplet<uint32_t>& t2,
282 const Triplet<uint32_t>& valid_lifetime,
283 const SubnetID id)
284 : Subnet(prefix, length, id), Network4() {
285 if (!prefix.isV4()) {
286 isc_throw(BadValue, "Non IPv4 prefix " << prefix.toText()
287 << " specified in subnet4");
288 }
289
290 // Timers.
291 setT1(t1);
292 setT2(t2);
293 setValid(valid_lifetime);
294}
295
297Subnet4::create(const IOAddress& prefix, uint8_t length,
298 const Triplet<uint32_t>& t1,
299 const Triplet<uint32_t>& t2,
300 const Triplet<uint32_t>& valid_lifetime,
301 const SubnetID id) {
302 Subnet4Ptr subnet = boost::make_shared<Subnet4>
303 (prefix, length, t1, t2, valid_lifetime, id);
304 return (subnet);
305}
306
308Subnet4::getNextSubnet(const Subnet4Ptr& first_subnet) const {
309 SharedNetwork4Ptr network;
310 getSharedNetwork(network);
311 if (network) {
312 return (network->getNextSubnet(first_subnet, getID()));
313 }
314
315 return (Subnet4Ptr());
316}
317
320 const ClientClasses& client_classes) const {
321 SharedNetwork4Ptr network;
322 getSharedNetwork(network);
323 // We can only get next subnet if shared network has been defined for
324 // the current subnet.
325 if (network) {
326 Subnet4Ptr subnet;
327 do {
328 // Use subnet identifier of this subnet if this is the first
329 // time we're calling getNextSubnet. Otherwise, use the
330 // subnet id of the previously returned subnet.
331 SubnetID subnet_id = subnet ? subnet->getID() : getID();
332 subnet = network->getNextSubnet(first_subnet, subnet_id);
333 // If client classes match the subnet, return it. Otherwise,
334 // try another subnet.
335 if (subnet && subnet->clientSupported(client_classes)) {
336 return (subnet);
337 }
338 } while (subnet);
339 }
340
341 // No subnet found.
342 return (Subnet4Ptr());
343}
344
345
346bool
348 NetworkPtr network;
349 getSharedNetwork(network);
350 if (network && !network->clientSupported(client_classes)) {
351 return (false);
352 }
353
354 return (Network4::clientSupported(client_classes));
355}
356
358 // check if the type is valid (and throw if it isn't)
359 checkType(type);
360
361 switch (type) {
362 case Lease::TYPE_V4:
363 case Lease::TYPE_NA:
364 return (pools_);
365 case Lease::TYPE_TA:
366 return (pools_ta_);
367 case Lease::TYPE_PD:
368 return (pools_pd_);
369 default:
370 isc_throw(BadValue, "Unsupported pool type: "
371 << static_cast<int>(type));
372 }
373}
374
376 // check if the type is valid (and throw if it isn't)
377 checkType(type);
378
379 switch (type) {
380 case Lease::TYPE_V4:
381 case Lease::TYPE_NA:
382 return (pools_);
383 case Lease::TYPE_TA:
384 return (pools_ta_);
385 case Lease::TYPE_PD:
386 return (pools_pd_);
387 default:
388 isc_throw(BadValue, "Invalid pool type specified: "
389 << static_cast<int>(type));
390 }
391}
392
394 bool anypool /* true */) const {
395 // check if the type is valid (and throw if it isn't)
396 checkType(type);
397
398 const PoolCollection& pools = getPools(type);
399
400 PoolPtr candidate;
401
402 if (!pools.empty()) {
403 // Pools are sorted by their first prefixes. For example: 2001::,
404 // 2001::db8::, 3000:: etc. If our hint is 2001:db8:5:: we want to
405 // find the pool with the longest matching prefix, so: 2001:db8::,
406 // rather than 2001::. upper_bound returns the first pool with a prefix
407 // that is greater than 2001:db8:5::, i.e. 3000::. To find the longest
408 // matching prefix we use decrement operator to go back by one item.
409 // If returned iterator points to begin it means that prefixes in all
410 // pools are greater than out prefix, and thus there is no match.
411 PoolCollection::const_iterator ub =
412 std::upper_bound(pools.begin(), pools.end(), hint,
413 prefixLessThanFirstAddress);
414
415 if (ub != pools.begin()) {
416 --ub;
417 if ((*ub)->inRange(hint)) {
418 candidate = *ub;
419 }
420 }
421
422 // If we don't find anything better, then let's just use the first pool
423 if (!candidate && anypool) {
424 candidate = *pools.begin();
425 }
426 }
427
428 // Return a pool or NULL if no match found.
429 return (candidate);
430}
431
433 const ClientClasses& client_classes,
434 const isc::asiolink::IOAddress& hint) const {
435 // check if the type is valid (and throw if it isn't)
436 checkType(type);
437
438 const PoolCollection& pools = getPools(type);
439
440 PoolPtr candidate;
441
442 if (!pools.empty()) {
443 PoolCollection::const_iterator ub =
444 std::upper_bound(pools.begin(), pools.end(), hint,
445 prefixLessThanFirstAddress);
446
447 if (ub != pools.begin()) {
448 --ub;
449 if ((*ub)->inRange(hint) &&
450 (*ub)->clientSupported(client_classes)) {
451 candidate = *ub;
452 }
453 }
454 }
455
456 // Return a pool or NULL if no match found.
457 return (candidate);
458}
459
460void
462 // check if the type is valid (and throw if it isn't)
463 checkType(pool->getType());
464
465 // Check that the pool is in range with a subnet only if this is
466 // not a pool of IPv6 prefixes. The IPv6 prefixes delegated for
467 // the particular subnet don't need to match the prefix of the
468 // subnet.
469 if (pool->getType() != Lease::TYPE_PD) {
470 if (!inRange(pool->getFirstAddress()) || !inRange(pool->getLastAddress())) {
471 isc_throw(BadValue, "a pool of type "
472 << Lease::typeToText(pool->getType())
473 << ", with the following address range: "
474 << pool->getFirstAddress() << "-"
475 << pool->getLastAddress() << " does not match"
476 << " the prefix of a subnet: "
477 << prefix_ << "/" << static_cast<int>(prefix_len_)
478 << " to which it is being added");
479
480 }
481 }
482
483 bool overlaps = false;
484 if (pool->getType() == Lease::TYPE_V4) {
485 overlaps = poolOverlaps(Lease::TYPE_V4, pool);
486
487 } else {
488 overlaps =
492 }
493
494 if (overlaps) {
495 isc_throw(BadValue,"a pool of type "
496 << Lease::typeToText(pool->getType())
497 << ", with the following address range: "
498 << pool->getFirstAddress() << "-"
499 << pool->getLastAddress() << " overlaps with "
500 "an existing pool in the subnet: "
501 << prefix_ << "/" << static_cast<int>(prefix_len_)
502 << " to which it is being added");
503 }
504
505 PoolCollection& pools_writable = getPoolsWritable(pool->getType());
506
507 // Add the pool to the appropriate pools collection
508 pools_writable.push_back(pool);
509
510 // Sort pools by first address.
511 std::sort(pools_writable.begin(), pools_writable.end(),
512 comparePoolFirstAddress);
513}
514
515void
517 getPoolsWritable(type).clear();
518}
519
520bool
522
523 // Let's start with checking if it even belongs to that subnet.
524 if ((type != Lease::TYPE_PD) && !inRange(addr)) {
525 return (false);
526 }
527
528 const PoolCollection& pools = getPools(type);
529
530 for (PoolCollection::const_iterator pool = pools.begin();
531 pool != pools.end(); ++pool) {
532 if ((*pool)->inRange(addr)) {
533 return (true);
534 }
535 }
536 // There's no pool that address belongs to
537 return (false);
538}
539
540bool
542 const isc::asiolink::IOAddress& addr,
543 const ClientClasses& client_classes) const {
544
545 // Let's start with checking if it even belongs to that subnet.
546 if ((type != Lease::TYPE_PD) && !inRange(addr)) {
547 return (false);
548 }
549
550 const PoolCollection& pools = getPools(type);
551
552 for (PoolCollection::const_iterator pool = pools.begin();
553 pool != pools.end(); ++pool) {
554 if (!(*pool)->clientSupported(client_classes)) {
555 continue;
556 }
557 if ((*pool)->inRange(addr)) {
558 return (true);
559 }
560 }
561 // There's no pool that address belongs to
562 return (false);
563}
564
565bool
566Subnet::poolOverlaps(const Lease::Type& pool_type, const PoolPtr& pool) const {
567 const PoolCollection& pools = getPools(pool_type);
568
569 // If no pools, we don't overlap. Nothing to do.
570 if (pools.empty()) {
571 return (false);
572 }
573
574 // We're going to insert a new pool, likely between two existing pools.
575 // So we're going to end up with the following case:
576 // |<---- pool1 ---->| |<-------- pool2 ------>| |<-- pool3 -->|
577 // F1 L1 F2 L2 F3 L3
578 // where pool1 and pool3 are existing pools, pool2 is a pool being
579 // inserted and "F"/"L" mark first and last address in the pools
580 // respectively. So the following conditions must be fulfilled:
581 // F2 > L1 and L2 < F3. Obviously, for any pool: F < L.
582
583 // Search for pool3. We use F2 and upper_bound to find the F3 (upper_bound
584 // returns first pool in the sorted container which first address is
585 // greater than F2). prefixLessThanPoolAddress with the first argument
586 // set to "true" is the custom comparison function for upper_bound, which
587 // compares F2 with the first addresses of the existing pools.
588 PoolCollection::const_iterator pool3_it =
589 std::upper_bound(pools.begin(), pools.end(), pool->getFirstAddress(),
590 prefixLessThanFirstAddress);
591
592 // upper_bound returns a first pool which first address is greater than the
593 // address F2. However, it is also possible that there is a pool which first
594 // address is equal to F2. Such pool is also in conflict with a new pool.
595 // If the returned value is pools.begin() it means that all pools have greater
596 // first address than F2, thus none of the pools can have first address equal
597 // to F2. Otherwise, we'd need to check them for equality.
598 if (pool3_it != pools.begin()) {
599 // Go back one pool and check if addresses are equal.
600 PoolPtr pool3 = *(pool3_it - 1);
601 if (pool3->getFirstAddress() == pool->getFirstAddress()) {
602 return (true);
603 }
604 }
605
606 // If returned value is unequal pools.end() it means that there is a pool3,
607 // with F3 > F2.
608 if (pool3_it != pools.end()) {
609 // Let's store the pointer to this pool.
610 PoolPtr pool3 = *pool3_it;
611 // F3 must be greater than L2, otherwise pools will overlap.
612 if (pool3->getFirstAddress() <= pool->getLastAddress()) {
613 return (true);
614 }
615 }
616
617 // If L2 is ok, we now have to find the pool1. This pool should be
618 // right before the pool3 if there is any pool before pool3.
619 if (pool3_it != pools.begin()) {
620 PoolPtr pool1 = *(pool3_it - 1);
621 // F2 must be greater than L1.
622 if (pool->getFirstAddress() <= pool1->getLastAddress()) {
623 return (true);
624 }
625 }
626
627 return (false);
628}
629
630
631Subnet6::Subnet6(const IOAddress& prefix, uint8_t length,
632 const Triplet<uint32_t>& t1,
633 const Triplet<uint32_t>& t2,
634 const Triplet<uint32_t>& preferred_lifetime,
635 const Triplet<uint32_t>& valid_lifetime,
636 const SubnetID id)
637 : Subnet(prefix, length, id), Network6() {
638 if (!prefix.isV6()) {
639 isc_throw(BadValue, "Non IPv6 prefix " << prefix
640 << " specified in subnet6");
641 }
642
643 // Timers.
644 setT1(t1);
645 setT2(t2);
646 setPreferred(preferred_lifetime);
647 setValid(valid_lifetime);
648}
649
651Subnet6::create(const IOAddress& prefix, uint8_t length,
652 const Triplet<uint32_t>& t1,
653 const Triplet<uint32_t>& t2,
654 const Triplet<uint32_t>& preferred_lifetime,
655 const Triplet<uint32_t>& valid_lifetime,
656 const SubnetID id) {
657 Subnet6Ptr subnet = boost::make_shared<Subnet6>
658 (prefix, length, t1, t2, preferred_lifetime, valid_lifetime, id);
659 return (subnet);
660}
661
662void Subnet6::checkType(Lease::Type type) const {
663 if ( (type != Lease::TYPE_NA) && (type != Lease::TYPE_TA) &&
664 (type != Lease::TYPE_PD)) {
665 isc_throw(BadValue, "Invalid Pool type: " << Lease::typeToText(type)
666 << "(" << static_cast<int>(type)
667 << "), must be TYPE_NA, TYPE_TA or TYPE_PD for Subnet6");
668 }
669}
670
672Subnet6::getNextSubnet(const Subnet6Ptr& first_subnet) const {
673 SharedNetwork6Ptr network;
674 getSharedNetwork(network);
675 if (network) {
676 return (network->getNextSubnet(first_subnet, getID()));
677 }
678
679 return (Subnet6Ptr());
680}
681
684 const ClientClasses& client_classes) const {
685 SharedNetwork6Ptr network;
686 getSharedNetwork(network);
687 // We can only get next subnet if shared network has been defined for
688 // the current subnet.
689 if (network) {
690 Subnet6Ptr subnet;
691 do {
692 // Use subnet identifier of this subnet if this is the first
693 // time we're calling getNextSubnet. Otherwise, use the
694 // subnet id of the previously returned subnet.
695 SubnetID subnet_id = subnet ? subnet->getID() : getID();
696 subnet = network->getNextSubnet(first_subnet, subnet_id);
697 // If client classes match the subnet, return it. Otherwise,
698 // try another subnet.
699 if (subnet && subnet->clientSupported(client_classes)) {
700 return (subnet);
701 }
702 } while (subnet);
703 }
704
705 // No subnet found.
706 return (Subnet6Ptr());
707}
708
709bool
711 NetworkPtr network;
712 getSharedNetwork(network);
713 if (network && !network->clientSupported(client_classes)) {
714 return (false);
715 }
716
717 return (Network6::clientSupported(client_classes));
718}
719
723
724 // Add user-context
725 contextToElement(map);
726
727 // Set subnet id
728 SubnetID id = getID();
729 map->set("id", Element::create(static_cast<long long>(id)));
730
731 // Set subnet
732 map->set("subnet", Element::create(toText()));
733
734 return (map);
735}
736
739 // Prepare the map
741 ElementPtr network_map = Network4::toElement();
742
743 merge(map, network_map);
744
745 // Set DHCP4o6
746 const Cfg4o6& d4o6 = get4o6();
747 isc::data::merge(map, d4o6.toElement());
748
749 // Set pools
750 const PoolCollection& pools = getPools(Lease::TYPE_V4);
751 ElementPtr pool_list = Element::createList();
752 for (PoolCollection::const_iterator pool = pools.cbegin();
753 pool != pools.cend(); ++pool) {
754 // Add the elementized pool to the list
755 pool_list->add((*pool)->toElement());
756 }
757 map->set("pools", pool_list);
758
759 return (map);
760}
761
762std::pair<IOAddress, uint8_t>
763Subnet4::parsePrefix(const std::string& prefix) {
764 std::pair<IOAddress, uint8_t> parsed = Subnet::parsePrefixCommon(prefix);
765 if (!parsed.first.isV4() || parsed.first.isV4Zero() ||
766 (parsed.second > 32) || (parsed.second == 0)) {
767 isc_throw(BadValue, "unable to parse invalid IPv4 prefix " << prefix);
768 }
769 return (parsed);
770}
771
774 // Prepare the map
776 ElementPtr network_map = Network6::toElement();
777
778 merge(map, network_map);
779
780 // Set pools
781 const PoolCollection& pools = getPools(Lease::TYPE_NA);
782 ElementPtr pool_list = Element::createList();
783 for (PoolCollection::const_iterator pool = pools.cbegin();
784 pool != pools.cend(); ++pool) {
785 // Add the elementized pool to the list
786 pool_list->add((*pool)->toElement());
787 }
788 map->set("pools", pool_list);
789
790 // Set pd-pools
791 const PoolCollection& pdpools = getPools(Lease::TYPE_PD);
792 ElementPtr pdpool_list = Element::createList();
793 for (PoolCollection::const_iterator pool = pdpools.cbegin();
794 pool != pdpools.cend(); ++pool) {
795 // Add the elementized pool to the list
796 pdpool_list->add((*pool)->toElement());
797 }
798 map->set("pd-pools", pdpool_list);
799
800 return (map);
801}
802
803std::pair<IOAddress, uint8_t>
804Subnet6::parsePrefix(const std::string& prefix) {
805 std::pair<IOAddress, uint8_t> parsed = Subnet::parsePrefixCommon(prefix);
806 if (!parsed.first.isV6() || parsed.first.isV6Zero() ||
807 (parsed.second > 128) || (parsed.second == 0)) {
808 isc_throw(BadValue, "unable to parse invalid IPv6 prefix " << prefix);
809 }
810 return (parsed);
811}
812
813} // end of isc::dhcp namespace
814} // end of isc namespace
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:241
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:291
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:286
Container for storing client class names.
Definition: classify.h:70
Specialization of the Network object for DHCPv4 case.
Definition: network.h:1151
virtual data::ElementPtr toElement() const
Unparses network object.
Definition: network.cc:297
Specialization of the Network object for DHCPv6 case.
Definition: network.h:1283
void setPreferred(const isc::util::Triplet< uint32_t > &preferred)
Sets new preferred lifetime for a network.
Definition: network.h:1307
virtual data::ElementPtr toElement() const
Unparses network object.
Definition: network.cc:344
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this network supports client that belongs to specified classes.
Definition: network.cc:75
void setT2(const isc::util::Triplet< uint32_t > &t2)
Sets new rebind timer for a network.
Definition: network.h:386
void setT1(const isc::util::Triplet< uint32_t > &t1)
Sets new renew timer for a network.
Definition: network.h:371
void setValid(const isc::util::Triplet< uint32_t > &valid)
Sets new valid lifetime for a network.
Definition: network.h:356
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this subnet and parent shared network supports the client that belongs to specified cl...
Definition: subnet.cc:347
Subnet4(const isc::asiolink::IOAddress &prefix, uint8_t length, const util::Triplet< uint32_t > &t1, const util::Triplet< uint32_t > &t2, const util::Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Constructor with all parameters.
Definition: subnet.cc:279
Cfg4o6 & get4o6()
Returns DHCP4o6 configuration parameters.
Definition: subnet.h:621
Subnet4Ptr getNextSubnet(const Subnet4Ptr &first_subnet) const
Returns next subnet within shared network.
Definition: subnet.cc:308
virtual data::ElementPtr toElement() const
Unparse a subnet object.
Definition: subnet.cc:738
static Subnet4Ptr create(const isc::asiolink::IOAddress &prefix, uint8_t length, const util::Triplet< uint32_t > &t1, const util::Triplet< uint32_t > &t2, const util::Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Factory function creating an instance of the Subnet4.
Definition: subnet.cc:297
static std::pair< asiolink::IOAddress, uint8_t > parsePrefix(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
Definition: subnet.cc:763
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this subnet and parent shared network supports the client that belongs to specified cl...
Definition: subnet.cc:710
Subnet6(const isc::asiolink::IOAddress &prefix, uint8_t length, const util::Triplet< uint32_t > &t1, const util::Triplet< uint32_t > &t2, const util::Triplet< uint32_t > &preferred_lifetime, const util::Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Constructor with all parameters.
Definition: subnet.cc:631
static std::pair< asiolink::IOAddress, uint8_t > parsePrefix(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
Definition: subnet.cc:804
Subnet6Ptr getNextSubnet(const Subnet6Ptr &first_subnet) const
Returns next subnet within shared network.
Definition: subnet.cc:672
virtual data::ElementPtr toElement() const
Unparse a subnet object.
Definition: subnet.cc:773
static Subnet6Ptr create(const isc::asiolink::IOAddress &prefix, uint8_t length, const util::Triplet< uint32_t > &t1, const util::Triplet< uint32_t > &t2, const util::Triplet< uint32_t > &preferred_lifetime, const util::Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Factory function creating an instance of the Subnet4.
Definition: subnet.cc:651
isc::asiolink::IOAddress prefix_
a prefix of the subnet.
Definition: subnet.h:427
SubnetID getID() const
Returns unique ID for that subnet.
Definition: subnet.h:125
uint8_t prefix_len_
a prefix length of the subnet.
Definition: subnet.h:430
std::map< Lease::Type, boost::posix_time::ptime > last_allocated_time_
Timestamp indicating when a lease of a specified type has been last allocated from this subnet.
Definition: subnet.h:457
virtual data::ElementPtr toElement() const
Unparse a subnet object.
Definition: subnet.cc:721
PoolCollection pools_ta_
collection of IPv6 temporary address pools in that subnet.
Definition: subnet.h:421
void getSharedNetwork(SharedNetworkPtrType &shared_network) const
Retrieves pointer to a shared network associated with a subnet.
Definition: subnet.h:264
void addPool(const PoolPtr &pool)
Adds a new pool for the subnet.
Definition: subnet.cc:461
bool inRange(const isc::asiolink::IOAddress &addr) const
checks if specified address is in range.
Definition: subnet.cc:83
isc::asiolink::IOAddress last_allocated_pd_
last allocated IPv6 prefix.
Definition: subnet.h:451
virtual std::string toText() const
Returns textual representation of the subnet (e.g.
Definition: subnet.cc:174
void delPools(Lease::Type type)
Deletes all pools of specified type.
Definition: subnet.cc:516
static std::pair< asiolink::IOAddress, uint8_t > parsePrefixCommon(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
Definition: subnet.cc:254
PoolCollection pools_
collection of IPv4 or non-temporary IPv6 pools in that subnet.
Definition: subnet.h:418
PoolCollection & getPoolsWritable(Lease::Type type)
Returns all pools (non-const variant).
Definition: subnet.cc:375
isc::asiolink::IOAddress getLastAllocated(Lease::Type type) const
returns the last address that was tried from this subnet.
Definition: subnet.cc:90
void setLastAllocated(Lease::Type type, const isc::asiolink::IOAddress &addr)
sets the last address that was tried from this subnet.
Definition: subnet.cc:138
const PoolPtr getPool(Lease::Type type, const isc::asiolink::IOAddress &addr, bool anypool=true) const
Returns a pool that specified address belongs to.
Definition: subnet.cc:393
isc::asiolink::IOAddress last_allocated_ia_
last allocated address.
Definition: subnet.h:441
Subnet(const isc::asiolink::IOAddress &prefix, uint8_t len, const SubnetID id)
Protected constructor.
Definition: subnet.cc:59
boost::posix_time::ptime getLastAllocatedTime(const Lease::Type &lease_type) const
Returns the timestamp when the setLastAllocated function was called.
Definition: subnet.cc:117
uint64_t sumPoolCapacity(const PoolCollection &pools) const
Returns a sum of possible leases in all pools.
Definition: subnet.cc:214
bool poolOverlaps(const Lease::Type &pool_type, const PoolPtr &pool) const
Checks if the specified pool overlaps with an existing pool.
Definition: subnet.cc:566
PoolCollection pools_pd_
collection of IPv6 prefix pools in that subnet.
Definition: subnet.h:424
const PoolCollection & getPools(Lease::Type type) const
Returns all pools (const variant).
Definition: subnet.cc:357
static SubnetID static_id_
keeps the subnet-id value.
Definition: subnet.h:334
virtual void checkType(Lease::Type type) const =0
Checks if used pool type is valid.
uint64_t getPoolCapacity(Lease::Type type) const
Returns the number of possible leases for specified lease type.
Definition: subnet.cc:181
bool inPool(Lease::Type type, const isc::asiolink::IOAddress &addr) const
checks if the specified address is in pools.
Definition: subnet.cc:521
isc::asiolink::IOAddress last_allocated_ta_
last allocated temporary address.
Definition: subnet.h:446
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
Definition: data.cc:1139
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
Definition: subnet.h:524
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
Definition: subnet.h:672
std::vector< PoolPtr > PoolCollection
a container for either IPv4 or IPv6 Pools
Definition: pool.h:508
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
Definition: pool.h:505
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:24
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
Definition: network.h:41
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
Definition: edns.h:19
Defines the logger used by the top-level component of kea-lfc.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition: user_context.cc:15
This structure contains information about DHCP4o6 (RFC7341)
Definition: cfg_4o6.h:22
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition: cfg_4o6.cc:22
Type
Type of lease or pool.
Definition: lease.h:46
@ TYPE_TA
the lease contains temporary IPv6 address
Definition: lease.h:48
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition: lease.h:49
@ TYPE_V4
IPv4 lease.
Definition: lease.h:50
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition: lease.h:47
static std::string typeToText(Type type)
returns text representation of a lease type
Definition: lease.cc:52