Kea 2.5.5
lease_cmds.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2023 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>
9#include <config/cmds_impl.h>
11#include <cc/data.h>
12#include <asiolink/io_address.h>
14#include <dhcpsrv/cfgmgr.h>
16#include <dhcpsrv/lease_mgr.h>
20#include <dhcpsrv/subnet_id.h>
22#include <dhcp/duid.h>
23#include <hooks/hooks.h>
25#include <lease_cmds.h>
27#include <lease_parser.h>
28#include <lease_cmds_log.h>
29#include <stats/stats_mgr.h>
30#include <util/encode/hex.h>
32#include <util/strutil.h>
33
34#include <boost/scoped_ptr.hpp>
35#include <boost/algorithm/string.hpp>
36#include <string>
37#include <sstream>
38
39using namespace isc::dhcp;
40using namespace isc::data;
41using namespace isc::dhcp_ddns;
42using namespace isc::config;
43using namespace isc::asiolink;
44using namespace isc::hooks;
45using namespace isc::stats;
46using namespace isc::util;
47using namespace std;
48
49namespace isc {
50namespace lease_cmds {
51
53class LeaseCmdsImpl : private CmdsImpl {
54public:
55
57 class Parameters {
58 public:
59
61 typedef enum {
67
70
73
76
79
82
92 static Type txtToType(const std::string& txt) {
93 if (txt == "address") {
94 return (Parameters::TYPE_ADDR);
95 } else if (txt == "hw-address") {
97 } else if (txt == "duid") {
98 return (Parameters::TYPE_DUID);
99 } else if (txt == "client-id") {
101 } else {
102 isc_throw(BadValue, "Incorrect identifier type: "
103 << txt << ", the only supported values are: "
104 "address, hw-address, duid");
105 }
106 }
107
110
113
115 uint32_t iaid;
116
119
122 : subnet_id(0), addr("::"), query_type(TYPE_ADDR),
123 lease_type(Lease::TYPE_NA), iaid(0), updateDDNS(false) {
124 }
125 };
126
127public:
128
137 int
139
149 int
151
160 int
162
174 int
176
192 int
194
204 int
206
216 int
218
228 int
230
241 int
243
252 int
254
263 int
265
274 int
276
285 int
287
296 int
298
307 int
309
319
329
338 int
340
352 Parameters getParameters(bool v6, const ConstElementPtr& args);
353
371 Lease6Ptr getIPv6LeaseForDelete(const Parameters& parameters) const;
372
388 const IOAddress& lease_address,
389 const DuidPtr& duid,
390 const int control_result,
391 const std::string& error_message) const;
392
403 IOAddress getAddressParam(ConstElementPtr params, const std::string name,
404 short family = AF_INET) const;
405
409 static void updateStatsOnAdd(const Lease4Ptr& lease);
410
414 static void updateStatsOnAdd(const Lease6Ptr& lease);
415
420 static void updateStatsOnUpdate(const Lease4Ptr& existing,
421 const Lease4Ptr& lease);
422
427 static void updateStatsOnUpdate(const Lease6Ptr& existing,
428 const Lease6Ptr& lease);
429
433 static void updateStatsOnDelete(const Lease4Ptr& lease);
434
438 static void updateStatsOnDelete(const Lease6Ptr& lease);
439
448 static bool addOrUpdate4(Lease4Ptr lease, bool force_create);
449
458 static bool addOrUpdate6(Lease6Ptr lease, bool force_create);
459
464 inline static ConstElementPtr getExtendedInfo6(const Lease6Ptr& lease) {
465 ConstElementPtr user_context = lease->getContext();
466 if (!user_context || (user_context->getType() != Element::map)) {
467 return (ConstElementPtr());
468 }
469 ConstElementPtr isc = user_context->get("ISC");
470 if (!isc || (isc->getType() != Element::map)) {
471 return (ConstElementPtr());
472 }
473 return (isc->get("relay-info"));
474 }
475};
476
477void
479 if (!lease->stateExpiredReclaimed()) {
480 StatsMgr::instance().addValue(
481 StatsMgr::generateName("subnet", lease->subnet_id_,
482 "assigned-addresses"),
483 static_cast<int64_t>(1));
484
485 PoolPtr pool;
486 const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(lease->subnet_id_);
487 if (subnet) {
488 pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
489 if (pool) {
490 StatsMgr::instance().addValue(
491 StatsMgr::generateName("subnet", subnet->getID(),
492 StatsMgr::generateName("pool", pool->getID(),
493 "assigned-addresses")),
494 static_cast<int64_t>(1));
495 }
496 }
497
498 if (lease->stateDeclined()) {
499 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
500
501 StatsMgr::instance().addValue(
502 StatsMgr::generateName("subnet", lease->subnet_id_,
503 "declined-addresses"),
504 static_cast<int64_t>(1));
505
506 if (pool) {
507 StatsMgr::instance().addValue(
508 StatsMgr::generateName("subnet", subnet->getID(),
509 StatsMgr::generateName("pool", pool->getID(),
510 "declined-addresses")),
511 static_cast<int64_t>(1));
512 }
513 }
514 }
515}
516
517void
519 if (!lease->stateExpiredReclaimed()) {
520 StatsMgr::instance().addValue(
521 StatsMgr::generateName("subnet", lease->subnet_id_,
522 lease->type_ == Lease::TYPE_NA ?
523 "assigned-nas" : "assigned-pds"),
524 static_cast<int64_t>(1));
525
526 PoolPtr pool;
527 const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
528 if (subnet) {
529 pool = subnet->getPool(lease->type_, lease->addr_, false);
530 if (pool) {
531 StatsMgr::instance().addValue(
532 StatsMgr::generateName("subnet", subnet->getID(),
533 StatsMgr::generateName(lease->type_ == Lease::TYPE_NA ?
534 "pool" : "pd-pool", pool->getID(),
535 lease->type_ == Lease::TYPE_NA ?
536 "assigned-nas" : "assigned-pds")),
537 static_cast<int64_t>(1));
538 }
539 }
540
541 if (lease->stateDeclined()) {
542 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
543
544 StatsMgr::instance().addValue(
545 StatsMgr::generateName("subnet", lease->subnet_id_,
546 "declined-addresses"),
547 static_cast<int64_t>(1));
548
549 if (pool) {
550 StatsMgr::instance().addValue(
551 StatsMgr::generateName("subnet", subnet->getID(),
552 StatsMgr::generateName("pool", pool->getID(),
553 "declined-addresses")),
554 static_cast<int64_t>(1));
555 }
556 }
557 }
558}
559
560void
562 const Lease4Ptr& lease) {
563 if (!existing->stateExpiredReclaimed()) {
564 ConstSubnet4Ptr subnet;
565 PoolPtr pool;
566
567 // old lease is non expired-reclaimed
568 if (existing->subnet_id_ != lease->subnet_id_) {
569 StatsMgr::instance().addValue(
570 StatsMgr::generateName("subnet", existing->subnet_id_,
571 "assigned-addresses"),
572 static_cast<int64_t>(-1));
573
574 subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(existing->subnet_id_);
575 if (subnet) {
576 pool = subnet->getPool(Lease::TYPE_V4, existing->addr_, false);
577 if (pool) {
578 StatsMgr::instance().addValue(
579 StatsMgr::generateName("subnet", subnet->getID(),
580 StatsMgr::generateName("pool", pool->getID(),
581 "assigned-addresses")),
582 static_cast<int64_t>(-1));
583 }
584 }
585 }
586
587 if (existing->stateDeclined()) {
588 // old lease is declined
589 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(-1));
590
591 StatsMgr::instance().addValue(
592 StatsMgr::generateName("subnet", existing->subnet_id_,
593 "declined-addresses"),
594 static_cast<int64_t>(-1));
595
596 if (pool) {
597 StatsMgr::instance().addValue(
598 StatsMgr::generateName("subnet", subnet->getID(),
599 StatsMgr::generateName("pool", pool->getID(),
600 "declined-addresses")),
601 static_cast<int64_t>(-1));
602 }
603 }
604
605 pool.reset();
606
607 if (!lease->stateExpiredReclaimed()) {
608 // new lease is non expired-reclaimed
609 if (existing->subnet_id_ != lease->subnet_id_) {
610 StatsMgr::instance().addValue(
611 StatsMgr::generateName("subnet", lease->subnet_id_,
612 "assigned-addresses"),
613 static_cast<int64_t>(1));
614
615 subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(lease->subnet_id_);
616 if (subnet) {
617 pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
618 if (pool) {
619 StatsMgr::instance().addValue(
620 StatsMgr::generateName("subnet", subnet->getID(),
621 StatsMgr::generateName("pool", pool->getID(),
622 "assigned-addresses")),
623 static_cast<int64_t>(1));
624 }
625 }
626 }
627
628 if (lease->stateDeclined()) {
629 // new lease is declined
630 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
631
632 StatsMgr::instance().addValue(
633 StatsMgr::generateName("subnet", lease->subnet_id_,
634 "declined-addresses"),
635 static_cast<int64_t>(1));
636
637 if (pool) {
638 StatsMgr::instance().addValue(
639 StatsMgr::generateName("subnet", subnet->getID(),
640 StatsMgr::generateName("pool", pool->getID(),
641 "declined-addresses")),
642 static_cast<int64_t>(1));
643 }
644 }
645 }
646 } else {
647 // old lease is expired-reclaimed
648 if (!lease->stateExpiredReclaimed()) {
649 // new lease is non expired-reclaimed
650 StatsMgr::instance().addValue(
651 StatsMgr::generateName("subnet", lease->subnet_id_,
652 "assigned-addresses"),
653 static_cast<int64_t>(1));
654
655 PoolPtr pool;
656 const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(lease->subnet_id_);
657 if (subnet) {
658 pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
659 if (pool) {
660 StatsMgr::instance().addValue(
661 StatsMgr::generateName("subnet", subnet->getID(),
662 StatsMgr::generateName("pool", pool->getID(),
663 "assigned-addresses")),
664 static_cast<int64_t>(1));
665 }
666 }
667
668 if (lease->stateDeclined()) {
669 // new lease is declined
670 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
671
672 StatsMgr::instance().addValue(
673 StatsMgr::generateName("subnet", lease->subnet_id_,
674 "declined-addresses"),
675 static_cast<int64_t>(1));
676
677 if (pool) {
678 StatsMgr::instance().addValue(
679 StatsMgr::generateName("subnet", subnet->getID(),
680 StatsMgr::generateName("pool", pool->getID(),
681 "declined-addresses")),
682 static_cast<int64_t>(1));
683 }
684 }
685 }
686 }
687}
688
689void
691 const Lease6Ptr& lease) {
692 if (!existing->stateExpiredReclaimed()) {
693 ConstSubnet6Ptr subnet;
694 PoolPtr pool;
695
696 // old lease is non expired-reclaimed
697 if (existing->subnet_id_ != lease->subnet_id_) {
698 StatsMgr::instance().addValue(
699 StatsMgr::generateName("subnet", existing->subnet_id_,
700 lease->type_ == Lease::TYPE_NA ?
701 "assigned-nas" : "assigned-pds"),
702 static_cast<int64_t>(-1));
703
704 subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(existing->subnet_id_);
705 if (subnet) {
706 pool = subnet->getPool(existing->type_, existing->addr_, false);
707 if (pool) {
708 StatsMgr::instance().addValue(
709 StatsMgr::generateName("subnet", subnet->getID(),
710 StatsMgr::generateName(existing->type_ == Lease::TYPE_NA ?
711 "pool" : "pd-pool", pool->getID(),
712 existing->type_ == Lease::TYPE_NA ?
713 "assigned-nas" : "assigned-pds")),
714 static_cast<int64_t>(-1));
715 }
716 }
717 }
718
719 if (existing->stateDeclined()) {
720 // old lease is declined
721 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(-1));
722
723 StatsMgr::instance().addValue(
724 StatsMgr::generateName("subnet", existing->subnet_id_,
725 "declined-addresses"),
726 static_cast<int64_t>(-1));
727
728 if (pool) {
729 StatsMgr::instance().addValue(
730 StatsMgr::generateName("subnet", subnet->getID(),
731 StatsMgr::generateName("pool", pool->getID(),
732 "declined-addresses")),
733 static_cast<int64_t>(-1));
734 }
735 }
736
737 pool.reset();
738
739 if (!lease->stateExpiredReclaimed()) {
740 // new lease is non expired-reclaimed
741 if (existing->subnet_id_ != lease->subnet_id_) {
742 StatsMgr::instance().addValue(
743 StatsMgr::generateName("subnet", lease->subnet_id_,
744 lease->type_ == Lease::TYPE_NA ?
745 "assigned-nas" : "assigned-pds"),
746 static_cast<int64_t>(1));
747
748 subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
749 if (subnet) {
750 pool = subnet->getPool(lease->type_, lease->addr_, false);
751 if (pool) {
752 StatsMgr::instance().addValue(
753 StatsMgr::generateName("subnet", subnet->getID(),
754 StatsMgr::generateName(lease->type_ == Lease::TYPE_NA ?
755 "pool" : "pd-pool", pool->getID(),
756 lease->type_ == Lease::TYPE_NA ?
757 "assigned-nas" : "assigned-pds")),
758 static_cast<int64_t>(1));
759 }
760 }
761 }
762
763 if (lease->stateDeclined()) {
764 // new lease is declined
765 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
766
767 StatsMgr::instance().addValue(
768 StatsMgr::generateName("subnet", lease->subnet_id_,
769 "declined-addresses"),
770 static_cast<int64_t>(1));
771
772 if (pool) {
773 StatsMgr::instance().addValue(
774 StatsMgr::generateName("subnet", subnet->getID(),
775 StatsMgr::generateName("pool", pool->getID(),
776 "declined-addresses")),
777 static_cast<int64_t>(1));
778 }
779 }
780 }
781 } else {
782 // old lease is expired-reclaimed
783 if (!lease->stateExpiredReclaimed()) {
784 // new lease is non expired-reclaimed
785 StatsMgr::instance().addValue(
786 StatsMgr::generateName("subnet", lease->subnet_id_,
787 lease->type_ == Lease::TYPE_NA ?
788 "assigned-nas" : "assigned-pds"),
789 static_cast<int64_t>(1));
790
791 PoolPtr pool;
792 const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
793 if (subnet) {
794 pool = subnet->getPool(lease->type_, lease->addr_, false);
795 if (pool) {
796 StatsMgr::instance().addValue(
797 StatsMgr::generateName("subnet", subnet->getID(),
798 StatsMgr::generateName(lease->type_ == Lease::TYPE_NA ?
799 "pool" : "pd-pool", pool->getID(),
800 lease->type_ == Lease::TYPE_NA ?
801 "assigned-nas" : "assigned-pds")),
802 static_cast<int64_t>(1));
803 }
804 }
805
806 if (lease->stateDeclined()) {
807 // new lease is declined
808 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
809
810 StatsMgr::instance().addValue(
811 StatsMgr::generateName("subnet", lease->subnet_id_,
812 "declined-addresses"),
813 static_cast<int64_t>(1));
814
815 if (pool) {
816 StatsMgr::instance().addValue(
817 StatsMgr::generateName("subnet", subnet->getID(),
818 StatsMgr::generateName("pool", pool->getID(),
819 "declined-addresses")),
820 static_cast<int64_t>(1));
821 }
822 }
823 }
824 }
825}
826
827void
829 if (!lease->stateExpiredReclaimed()) {
830 StatsMgr::instance().addValue(
831 StatsMgr::generateName("subnet", lease->subnet_id_,
832 "assigned-addresses"),
833 static_cast<int64_t>(-1));
834
835 PoolPtr pool;
836 const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(lease->subnet_id_);
837 if (subnet) {
838 pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
839 if (pool) {
840 StatsMgr::instance().addValue(
841 StatsMgr::generateName("subnet", subnet->getID(),
842 StatsMgr::generateName("pool", pool->getID(),
843 "assigned-addresses")),
844 static_cast<int64_t>(-1));
845 }
846 }
847
848 if (lease->stateDeclined()) {
849 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(-1));
850
851 StatsMgr::instance().addValue(
852 StatsMgr::generateName("subnet", lease->subnet_id_,
853 "declined-addresses"),
854 static_cast<int64_t>(-1));
855
856 if (pool) {
857 StatsMgr::instance().addValue(
858 StatsMgr::generateName("subnet", subnet->getID(),
859 StatsMgr::generateName("pool", pool->getID(),
860 "declined-addresses")),
861 static_cast<int64_t>(-1));
862 }
863 }
864 }
865}
866
867void
869 if (!lease->stateExpiredReclaimed()) {
870 StatsMgr::instance().addValue(
871 StatsMgr::generateName("subnet", lease->subnet_id_,
872 lease->type_ == Lease::TYPE_NA ?
873 "assigned-nas" : "assigned-pds"),
874 static_cast<int64_t>(-1));
875
876 PoolPtr pool;
877 const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(lease->subnet_id_);
878 if (subnet) {
879 pool = subnet->getPool(lease->type_, lease->addr_, false);
880 if (pool) {
881 StatsMgr::instance().addValue(
882 StatsMgr::generateName("subnet", subnet->getID(),
883 StatsMgr::generateName(lease->type_ == Lease::TYPE_NA ?
884 "pool" : "pd-pool", pool->getID(),
885 lease->type_ == Lease::TYPE_NA ?
886 "assigned-nas" : "assigned-pds")),
887 static_cast<int64_t>(-1));
888 }
889 }
890
891 if (lease->stateDeclined()) {
892 StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(-1));
893
894 StatsMgr::instance().addValue(
895 StatsMgr::generateName("subnet", lease->subnet_id_,
896 "declined-addresses"),
897 static_cast<int64_t>(-1));
898
899 if (pool) {
900 StatsMgr::instance().addValue(
901 StatsMgr::generateName("subnet", subnet->getID(),
902 StatsMgr::generateName("pool", pool->getID(),
903 "declined-addresses")),
904 static_cast<int64_t>(-1));
905 }
906 }
907 }
908}
909
910bool
911LeaseCmdsImpl::addOrUpdate4(Lease4Ptr lease, bool force_create) {
912 Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(lease->addr_);
913 if (force_create && !existing) {
914 // lease does not exist
915 if (!LeaseMgrFactory::instance().addLease(lease)) {
917 "lost race between calls to get and add");
918 }
920 return (true);
921 }
922 if (existing) {
923 // Update lease current expiration time with value received from the
924 // database. Some database backends reject operations on the lease if
925 // the current expiration time value does not match what is stored.
926 Lease::syncCurrentExpirationTime(*existing, *lease);
927 }
928 try {
929 LeaseMgrFactory::instance().updateLease4(lease);
930 } catch (const NoSuchLease&) {
931 isc_throw(LeaseCmdsConflict, "failed to update the lease with address "
932 << lease->addr_ << " either because the lease has been "
933 "deleted or it has changed in the database, in both cases a "
934 "retry might succeed");
935 }
936
937 LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
938 return (false);
939}
940
941bool
942LeaseCmdsImpl::addOrUpdate6(Lease6Ptr lease, bool force_create) {
943 Lease6Ptr existing =
944 LeaseMgrFactory::instance().getLease6(lease->type_, lease->addr_);
945 if (force_create && !existing) {
946 // lease does not exist
947 if (!LeaseMgrFactory::instance().addLease(lease)) {
949 "lost race between calls to get and add");
950 }
952 return (true);
953 }
954 if (existing) {
955 // Update lease current expiration time with value received from the
956 // database. Some database backends reject operations on the lease if
957 // the current expiration time value does not match what is stored.
958 Lease::syncCurrentExpirationTime(*existing, *lease);
959
960 // Check what is the action about extended info.
961 ConstElementPtr old_extended_info = getExtendedInfo6(existing);
962 ConstElementPtr extended_info = getExtendedInfo6(lease);
963 if ((!old_extended_info && !extended_info) ||
964 (old_extended_info && extended_info &&
965 (*old_extended_info == *extended_info))) {
966 // Leave the default Lease6::ACTION_IGNORE.
967 } else {
968 lease->extended_info_action_ = Lease6::ACTION_UPDATE;
969 }
970 }
971 try {
972 LeaseMgrFactory::instance().updateLease6(lease);
973 } catch (const NoSuchLease&) {
974 isc_throw(LeaseCmdsConflict, "failed to update the lease with address "
975 << lease->addr_ << " either because the lease has been "
976 "deleted or it has changed in the database, in both cases a "
977 "retry might succeed");
978 }
979
980 LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
981 return (false);
982}
983
984int
986 // Arbitrary defaulting to DHCPv4 or with other words extractCommand
987 // below is not expected to throw...
988 bool v4 = true;
989 stringstream resp;
990 string lease_address = "unknown";
991 try {
992 extractCommand(handle);
993 v4 = (cmd_name_ == "lease4-add");
994 if (!cmd_args_) {
995 isc_throw(isc::BadValue, "no parameters specified for the command");
996 }
997
998 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
999
1000 // This parameter is ignored for the commands adding the lease.
1001 bool force_create = false;
1002 Lease4Ptr lease4;
1003 Lease6Ptr lease6;
1004 if (v4) {
1005 Lease4Parser parser;
1006 lease4 = parser.parse(config, cmd_args_, force_create);
1007 if (lease4) {
1008 lease_address = lease4->addr_.toText();
1009 bool success;
1010 if (!MultiThreadingMgr::instance().getMode()) {
1011 // Not multi-threading.
1012 success = LeaseMgrFactory::instance().addLease(lease4);
1013 } else {
1014 // Multi-threading, try to lock first to avoid a race.
1015 ResourceHandler4 resource_handler;
1016 if (resource_handler.tryLock4(lease4->addr_)) {
1017 success = LeaseMgrFactory::instance().addLease(lease4);
1018 } else {
1020 "ResourceBusy: IP address:" << lease4->addr_
1021 << " could not be added.");
1022 }
1023 }
1024
1025 if (!success) {
1026 isc_throw(LeaseCmdsConflict, "IPv4 lease already exists.");
1027 }
1028
1030 resp << "Lease for address " << lease4->addr_.toText()
1031 << ", subnet-id " << lease4->subnet_id_ << " added.";
1032 }
1033 } else {
1034 Lease6Parser parser;
1035 lease6 = parser.parse(config, cmd_args_, force_create);
1036 if (lease6) {
1037 lease_address = lease6->addr_.toText();
1038 bool success;
1039 if (!MultiThreadingMgr::instance().getMode()) {
1040 // Not multi-threading.
1041 success = LeaseMgrFactory::instance().addLease(lease6);
1042 } else {
1043 // Multi-threading, try to lock first to avoid a race.
1044 ResourceHandler resource_handler;
1045 if (resource_handler.tryLock(lease6->type_, lease6->addr_)) {
1046 success = LeaseMgrFactory::instance().addLease(lease6);
1047 } else {
1049 "ResourceBusy: IP address:" << lease6->addr_
1050 << " could not be added.");
1051 }
1052 }
1053
1054 if (!success) {
1055 isc_throw(LeaseCmdsConflict, "IPv6 lease already exists.");
1056 }
1057
1059 if (lease6->type_ == Lease::TYPE_NA) {
1060 resp << "Lease for address " << lease6->addr_.toText()
1061 << ", subnet-id " << lease6->subnet_id_ << " added.";
1062 } else {
1063 resp << "Lease for prefix " << lease6->addr_.toText()
1064 << "/" << static_cast<int>(lease6->prefixlen_)
1065 << ", subnet-id " << lease6->subnet_id_ << " added.";
1066 }
1067 }
1068 }
1069 } catch (const LeaseCmdsConflict& ex) {
1071 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
1072 .arg(ex.what());
1074 return (0);
1075
1076 } catch (const std::exception& ex) {
1078 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
1079 .arg(ex.what());
1080 setErrorResponse(handle, ex.what());
1081 return (1);
1082 }
1083
1086 .arg(lease_address);
1087 setSuccessResponse(handle, resp.str());
1088 return (0);
1089}
1090
1093 Parameters x;
1094
1095 if (!params || params->getType() != Element::map) {
1096 isc_throw(BadValue, "Parameters missing or are not a map.");
1097 }
1098
1099 if (params->contains("update-ddns")) {
1100 ConstElementPtr tmp = params->get("update-ddns");
1101 if (tmp->getType() != Element::boolean) {
1102 isc_throw(BadValue, "'update-ddns' is not a boolean");
1103 } else {
1104 x.updateDDNS = tmp->boolValue();
1105 }
1106 }
1107
1108 // We support several sets of parameters for leaseX-get/lease-del:
1109 // lease-get(type, address)
1110 // lease-get(type, subnet-id, identifier-type, identifier)
1111
1112 if (params->contains("type")) {
1113 string t = params->get("type")->stringValue();
1114 if (t == "IA_NA" || t == "0") {
1115 x.lease_type = Lease::TYPE_NA;
1116 } else if (t == "IA_TA" || t == "1") {
1117 x.lease_type = Lease::TYPE_TA;
1118 } else if (t == "IA_PD" || t == "2") {
1119 x.lease_type = Lease::TYPE_PD;
1120 } else if (t == "V4" || t == "3") {
1121 x.lease_type = Lease::TYPE_V4;
1122 } else {
1123 isc_throw(BadValue, "Invalid lease type specified: "
1124 << t << ", only supported values are: IA_NA, IA_TA,"
1125 << " IA_PD and V4");
1126 }
1127 }
1128
1129 ConstElementPtr tmp = params->get("ip-address");
1130 if (tmp) {
1131 if (tmp->getType() != Element::string) {
1132 isc_throw(BadValue, "'ip-address' is not a string.");
1133 }
1134
1135 x.addr = IOAddress(tmp->stringValue());
1136
1137 if ((v6 && !x.addr.isV6()) || (!v6 && !x.addr.isV4())) {
1138 stringstream txt;
1139 txt << "Invalid " << (v6 ? "IPv6" : "IPv4")
1140 << " address specified: " << tmp->stringValue();
1141 isc_throw(BadValue, txt.str());
1142 }
1143
1145 return (x);
1146 }
1147
1148 tmp = params->get("subnet-id");
1149 if (!tmp) {
1150 isc_throw(BadValue, "Mandatory 'subnet-id' parameter missing.");
1151 }
1152 if (tmp->getType() != Element::integer) {
1153 isc_throw(BadValue, "'subnet-id' parameter is not integer.");
1154 }
1155 x.subnet_id = tmp->intValue();
1156
1157 if (params->contains("iaid")) {
1158 x.iaid = params->get("iaid")->intValue();
1159 }
1160
1161 // No address specified. Ok, so it must be identifier based query.
1162 // "identifier-type": "duid",
1163 // "identifier": "aa:bb:cc:dd:ee:..."
1164
1165 ConstElementPtr type = params->get("identifier-type");
1166 ConstElementPtr ident = params->get("identifier");
1167 if (!type || type->getType() != Element::string) {
1168 isc_throw(BadValue, "No 'ip-address' provided"
1169 " and 'identifier-type' is either missing or not a string.");
1170 }
1171 if (!ident || ident->getType() != Element::string) {
1172 isc_throw(BadValue, "No 'ip-address' provided"
1173 " and 'identifier' is either missing or not a string.");
1174 }
1175
1176 // Got the parameters. Let's see if their values make sense.
1177 // Try to convert identifier-type
1178 x.query_type = Parameters::txtToType(type->stringValue());
1179
1180 switch (x.query_type) {
1182 HWAddr hw = HWAddr::fromText(ident->stringValue());
1183 x.hwaddr = HWAddrPtr(new HWAddr(hw));
1184 break;
1185 }
1187 x.client_id = ClientId::fromText(ident->stringValue());
1188 break;
1189 }
1190 case Parameters::TYPE_DUID: {
1191 DUID duid = DUID::fromText(ident->stringValue());
1192 x.duid = DuidPtr(new DUID(duid));
1193 break;
1194 }
1195 case Parameters::TYPE_ADDR: {
1196 // We should never get here. The address clause should have been caught
1197 // earlier.
1198 return (x);
1199 }
1200 default: {
1201 isc_throw(BadValue, "Identifier type " << type->stringValue() <<
1202 " is not supported.");
1203 }
1204 }
1205
1206 return (x);
1207}
1208
1209int
1211 Parameters p;
1212 Lease4Ptr lease4;
1213 Lease6Ptr lease6;
1214 bool v4 = true;
1215 try {
1216 extractCommand(handle);
1217 v4 = (cmd_name_ == "lease4-get");
1218 p = getParameters(!v4, cmd_args_);
1219 switch (p.query_type) {
1220 case Parameters::TYPE_ADDR: {
1221 // Query by address
1222 if (v4) {
1223 lease4 = LeaseMgrFactory::instance().getLease4(p.addr);
1224 } else {
1225 lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, p.addr);
1226 }
1227 break;
1228 }
1230 if (v4) {
1231 if (!p.hwaddr) {
1232 isc_throw(InvalidParameter, "Program error: Query by hw-address "
1233 "requires hwaddr to be specified");
1234 }
1235
1236 lease4 = LeaseMgrFactory::instance().getLease4(*p.hwaddr, p.subnet_id);
1237 } else {
1238 isc_throw(isc::InvalidParameter, "Query by hw-address is not allowed in v6.");
1239 }
1240 break;
1241
1243 if (!v4) {
1244 if (!p.duid) {
1245 isc_throw(InvalidParameter, "Program error: Query by duid "
1246 "requires duid to be specified");
1247 }
1248
1249 lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, *p.duid,
1250 p.iaid, p.subnet_id);
1251 } else {
1252 isc_throw(InvalidParameter, "Query by duid is not allowed in v4.");
1253 }
1254 break;
1255
1257 if (v4) {
1258 if (!p.client_id) {
1259 isc_throw(InvalidParameter, "Program error: Query by client-id "
1260 "requires client-id to be specified");
1261 }
1262
1263 lease4 = LeaseMgrFactory::instance().getLease4(*p.client_id, p.subnet_id);
1264 } else {
1265 isc_throw(isc::InvalidParameter, "Query by client-id is not allowed in v6.");
1266 }
1267 break;
1268
1269 default: {
1270 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
1271 break;
1272 }
1273 }
1274 } catch (const std::exception& ex) {
1276 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
1277 .arg(ex.what());
1278 setErrorResponse(handle, ex.what());
1279 return (1);
1280 }
1281
1282 ElementPtr lease_json;
1283 if (v4 && lease4) {
1284 lease_json = lease4->toElement();
1286 "IPv4 lease found.", lease_json);
1287 setResponse(handle, response);
1288 } else if (!v4 && lease6) {
1289 lease_json = lease6->toElement();
1291 "IPv6 lease found.", lease_json);
1292 setResponse(handle, response);
1293 } else {
1294 // If we got here, the lease has not been found.
1295 setErrorResponse(handle, "Lease not found.", CONTROL_RESULT_EMPTY);
1296 }
1297
1298 return (0);
1299}
1300
1301int
1303 bool v4 = true;
1304 try {
1305 extractCommand(handle);
1306 v4 = (cmd_name_ == "lease4-get-all");
1307
1308 ElementPtr leases_json = Element::createList();
1309
1310 // The argument may contain a list of subnets for which leases should
1311 // be returned.
1312 if (cmd_args_) {
1313 ConstElementPtr subnets = cmd_args_->get("subnets");
1314 if (!subnets) {
1315 isc_throw(BadValue, "'subnets' parameter not specified");
1316 }
1317 if (subnets->getType() != Element::list) {
1318 isc_throw(BadValue, "'subnets' parameter must be a list");
1319 }
1320
1321 const std::vector<ElementPtr>& subnet_ids = subnets->listValue();
1322 for (auto subnet_id = subnet_ids.begin();
1323 subnet_id != subnet_ids.end();
1324 ++subnet_id) {
1325 if ((*subnet_id)->getType() != Element::integer) {
1326 isc_throw(BadValue, "listed subnet identifiers must be numbers");
1327 }
1328
1329 if (v4) {
1330 Lease4Collection leases =
1331 LeaseMgrFactory::instance().getLeases4((*subnet_id)->intValue());
1332 for (auto lease : leases) {
1333 ElementPtr lease_json = lease->toElement();
1334 leases_json->add(lease_json);
1335 }
1336 } else {
1337 Lease6Collection leases =
1338 LeaseMgrFactory::instance().getLeases6((*subnet_id)->intValue());
1339 for (auto lease : leases) {
1340 ElementPtr lease_json = lease->toElement();
1341 leases_json->add(lease_json);
1342 }
1343 }
1344 }
1345
1346 } else {
1347 // There is no 'subnets' argument so let's return all leases.
1348 if (v4) {
1349 Lease4Collection leases = LeaseMgrFactory::instance().getLeases4();
1350 for (auto lease : leases) {
1351 ElementPtr lease_json = lease->toElement();
1352 leases_json->add(lease_json);
1353 }
1354 } else {
1355 Lease6Collection leases = LeaseMgrFactory::instance().getLeases6();
1356 for (auto lease : leases) {
1357 ElementPtr lease_json = lease->toElement();
1358 leases_json->add(lease_json);
1359 }
1360 }
1361 }
1362
1363 std::ostringstream s;
1364 s << leases_json->size()
1365 << " IPv" << (v4 ? "4" : "6")
1366 << " lease(s) found.";
1367 ElementPtr args = Element::createMap();
1368 args->set("leases", leases_json);
1369 ConstElementPtr response =
1370 createAnswer(leases_json->size() > 0 ?
1373 s.str(), args);
1374 setResponse(handle, response);
1375
1376 } catch (const std::exception& ex) {
1377 setErrorResponse(handle, ex.what());
1378 return (CONTROL_RESULT_ERROR);
1379 }
1380
1381 return (0);
1382}
1383
1384int
1386 bool v4 = true;
1387 try {
1388 extractCommand(handle);
1389 v4 = (cmd_name_ == "lease4-get-page");
1390
1391 // arguments must always be present
1392 if (!cmd_args_) {
1393 isc_throw(BadValue, "no parameters specified for the " << cmd_name_
1394 << " command");
1395 }
1396
1397 // The 'from' argument denotes from which lease we should start the
1398 // results page. The results page excludes this lease.
1399 ConstElementPtr from = cmd_args_->get("from");
1400 if (!from) {
1401 isc_throw(BadValue, "'from' parameter not specified");
1402 }
1403
1404 // The 'from' argument is a string. It may contain a 'start' keyword or
1405 // an IP address.
1406 if (from->getType() != Element::string) {
1407 isc_throw(BadValue, "'from' parameter must be a string");
1408 }
1409
1410 boost::scoped_ptr<IOAddress> from_address;
1411 try {
1412 if (from->stringValue() == "start") {
1413 from_address.reset(new IOAddress(v4 ? "0.0.0.0" : "::"));
1414
1415 } else {
1416 // Conversion of a string to an IP address may throw.
1417 from_address.reset(new IOAddress(from->stringValue()));
1418 }
1419
1420 } catch (...) {
1421 isc_throw(BadValue, "'from' parameter value is neither 'start' keyword nor "
1422 "a valid IPv" << (v4 ? "4" : "6") << " address");
1423 }
1424
1425 // It must be either IPv4 address for lease4-get-page or IPv6 address for
1426 // lease6-get-page.
1427 if (v4 && (!from_address->isV4())) {
1428 isc_throw(BadValue, "'from' parameter value " << from_address->toText()
1429 << " is not an IPv4 address");
1430
1431 } else if (!v4 && from_address->isV4()) {
1432 isc_throw(BadValue, "'from' parameter value " << from_address->toText()
1433 << " is not an IPv6 address");
1434 }
1435
1436 // The 'limit' is a desired page size. It must always be present.
1437 ConstElementPtr page_limit = cmd_args_->get("limit");
1438 if (!page_limit) {
1439 isc_throw(BadValue, "'limit' parameter not specified");
1440 }
1441
1442 // The 'limit' must be a number.
1443 if (page_limit->getType() != Element::integer) {
1444 isc_throw(BadValue, "'limit' parameter must be a number");
1445 }
1446
1447 // Retrieve the desired page size.
1448 size_t page_limit_value = static_cast<size_t>(page_limit->intValue());
1449
1450 ElementPtr leases_json = Element::createList();
1451
1452 if (v4) {
1453 // Get page of IPv4 leases.
1454 Lease4Collection leases =
1455 LeaseMgrFactory::instance().getLeases4(*from_address,
1456 LeasePageSize(page_limit_value));
1457
1458 // Convert leases into JSON list.
1459 for (auto lease : leases) {
1460 ElementPtr lease_json = lease->toElement();
1461 leases_json->add(lease_json);
1462 }
1463
1464 } else {
1465 // Get page of IPv6 leases.
1466 Lease6Collection leases =
1467 LeaseMgrFactory::instance().getLeases6(*from_address,
1468 LeasePageSize(page_limit_value));
1469 // Convert leases into JSON list.
1470 for (auto lease : leases) {
1471 ElementPtr lease_json = lease->toElement();
1472 leases_json->add(lease_json);
1473 }
1474 }
1475
1476 // Prepare textual status.
1477 std::ostringstream s;
1478 s << leases_json->size()
1479 << " IPv" << (v4 ? "4" : "6")
1480 << " lease(s) found.";
1481 ElementPtr args = Element::createMap();
1482
1483 // Put gathered data into arguments map.
1484 args->set("leases", leases_json);
1485 args->set("count", Element::create(static_cast<int64_t>(leases_json->size())));
1486
1487 // Create the response.
1488 ConstElementPtr response =
1489 createAnswer(leases_json->size() > 0 ?
1492 s.str(), args);
1493 setResponse(handle, response);
1494
1495 } catch (const std::exception& ex) {
1496 setErrorResponse(handle, ex.what());
1497 return (CONTROL_RESULT_ERROR);
1498 }
1499
1500 return (CONTROL_RESULT_SUCCESS);
1501}
1502
1503int
1505 try {
1506 extractCommand(handle);
1507
1508 // arguments must always be present
1509 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1510 isc_throw(BadValue, "Command arguments missing or a not a map.");
1511 }
1512
1513 // the hw-address parameter is mandatory.
1514 ConstElementPtr hw_address = cmd_args_->get("hw-address");
1515 if (!hw_address) {
1516 isc_throw(BadValue, "'hw-address' parameter not specified");
1517 }
1518
1519 // The 'hw-address' argument is a string.
1520 if (hw_address->getType() != Element::string) {
1521 isc_throw(BadValue, "'hw-address' parameter must be a string");
1522 }
1523
1524 HWAddr hwaddr = HWAddr::fromText(hw_address->stringValue());
1525
1526 Lease4Collection leases =
1527 LeaseMgrFactory::instance().getLease4(hwaddr);
1528 ElementPtr leases_json = Element::createList();
1529 for (auto lease : leases) {
1530 ElementPtr lease_json = lease->toElement();
1531 leases_json->add(lease_json);
1532 }
1533
1534 std::ostringstream s;
1535 s << leases_json->size() << " IPv4 lease(s) found.";
1536 ElementPtr args = Element::createMap();
1537 args->set("leases", leases_json);
1538 ConstElementPtr response =
1539 createAnswer(leases_json->size() > 0 ?
1542 s.str(), args);
1543 setResponse(handle, response);
1544
1545 } catch (const std::exception& ex) {
1546 setErrorResponse(handle, ex.what());
1547 return (CONTROL_RESULT_ERROR);
1548 }
1549
1550 return (0);
1551}
1552
1553int
1555 try {
1556 extractCommand(handle);
1557
1558 // arguments must always be present
1559 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1560 isc_throw(BadValue, "Command arguments missing or a not a map.");
1561 }
1562
1563 // the client-id parameter is mandatory.
1564 ConstElementPtr client_id = cmd_args_->get("client-id");
1565 if (!client_id) {
1566 isc_throw(BadValue, "'client-id' parameter not specified");
1567 }
1568
1569 // The 'client-id' argument is a string.
1570 if (client_id->getType() != Element::string) {
1571 isc_throw(BadValue, "'client-id' parameter must be a string");
1572 }
1573
1574 ClientIdPtr clientid = ClientId::fromText(client_id->stringValue());
1575
1576 Lease4Collection leases =
1577 LeaseMgrFactory::instance().getLease4(*clientid);
1578 ElementPtr leases_json = Element::createList();
1579 for (auto lease : leases) {
1580 ElementPtr lease_json = lease->toElement();
1581 leases_json->add(lease_json);
1582 }
1583
1584 std::ostringstream s;
1585 s << leases_json->size() << " IPv4 lease(s) found.";
1586 ElementPtr args = Element::createMap();
1587 args->set("leases", leases_json);
1588 ConstElementPtr response =
1589 createAnswer(leases_json->size() > 0 ?
1592 s.str(), args);
1593 setResponse(handle, response);
1594
1595 } catch (const std::exception& ex) {
1596 setErrorResponse(handle, ex.what());
1597 return (CONTROL_RESULT_ERROR);
1598 }
1599
1600 return (0);
1601}
1602
1603int
1605 try {
1606 extractCommand(handle);
1607
1608 // arguments must always be present
1609 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1610 isc_throw(BadValue, "Command arguments missing or a not a map.");
1611 }
1612
1613 // the duid parameter is mandatory.
1614 ConstElementPtr duid = cmd_args_->get("duid");
1615 if (!duid) {
1616 isc_throw(BadValue, "'duid' parameter not specified");
1617 }
1618
1619 // The 'duid' argument is a string.
1620 if (duid->getType() != Element::string) {
1621 isc_throw(BadValue, "'duid' parameter must be a string");
1622 }
1623
1624 DUID duid_ = DUID::fromText(duid->stringValue());
1625
1626 Lease6Collection leases =
1627 LeaseMgrFactory::instance().getLeases6(duid_);
1628 ElementPtr leases_json = Element::createList();
1629 for (auto lease : leases) {
1630 ElementPtr lease_json = lease->toElement();
1631 leases_json->add(lease_json);
1632 }
1633
1634 std::ostringstream s;
1635 s << leases_json->size() << " IPv6 lease(s) found.";
1636 ElementPtr args = Element::createMap();
1637 args->set("leases", leases_json);
1638 ConstElementPtr response =
1639 createAnswer(leases_json->size() > 0 ?
1642 s.str(), args);
1643 setResponse(handle, response);
1644
1645 } catch (const std::exception& ex) {
1646 setErrorResponse(handle, ex.what());
1647 return (CONTROL_RESULT_ERROR);
1648 }
1649
1650 return (0);
1651}
1652
1653int
1655 bool v4 = true;
1656 try {
1657 extractCommand(handle);
1658 v4 = (cmd_name_ == "lease4-get-by-hostname");
1659
1660 // arguments must always be present
1661 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1662 isc_throw(BadValue, "Command arguments missing or a not a map.");
1663 }
1664
1665 // the hostname parameter is mandatory.
1666 ConstElementPtr hostname = cmd_args_->get("hostname");
1667 if (!hostname) {
1668 isc_throw(BadValue, "'hostname' parameter not specified");
1669 }
1670
1671 // The 'hostname' argument is a string.
1672 if (hostname->getType() != Element::string) {
1673 isc_throw(BadValue, "'hostname' parameter must be a string");
1674 }
1675
1676 std::string hostname_ = hostname->stringValue();
1678 if (hostname_.empty()) {
1679 isc_throw(BadValue, "'hostname' parameter is empty");
1680 }
1681 boost::algorithm::to_lower(hostname_);
1682
1683 ElementPtr leases_json = Element::createList();
1684 if (v4) {
1685 Lease4Collection leases =
1686 LeaseMgrFactory::instance().getLeases4(hostname_);
1687
1688 for (auto lease : leases) {
1689 ElementPtr lease_json = lease->toElement();
1690 leases_json->add(lease_json);
1691 }
1692 } else {
1693 Lease6Collection leases =
1694 LeaseMgrFactory::instance().getLeases6(hostname_);
1695
1696 for (auto lease : leases) {
1697 ElementPtr lease_json = lease->toElement();
1698 leases_json->add(lease_json);
1699 }
1700 }
1701
1702 std::ostringstream s;
1703 s << leases_json->size()
1704 << " IPv" << (v4 ? "4" : "6")
1705 << " lease(s) found.";
1706 ElementPtr args = Element::createMap();
1707 args->set("leases", leases_json);
1708 ConstElementPtr response =
1709 createAnswer(leases_json->size() > 0 ?
1712 s.str(), args);
1713 setResponse(handle, response);
1714
1715 } catch (const std::exception& ex) {
1716 setErrorResponse(handle, ex.what());
1717 return (CONTROL_RESULT_ERROR);
1718 }
1719
1720 return (0);
1721}
1722
1723int
1725 Parameters p;
1726 Lease4Ptr lease4;
1727 try {
1728 extractCommand(handle);
1729 p = getParameters(false, cmd_args_);
1730 switch (p.query_type) {
1731 case Parameters::TYPE_ADDR: {
1732 // If address was specified explicitly, let's use it as is.
1733 lease4 = LeaseMgrFactory::instance().getLease4(p.addr);
1734 if (!lease4) {
1735 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1736 return (0);
1737 }
1738 break;
1739 }
1741 if (!p.hwaddr) {
1742 isc_throw(InvalidParameter, "Program error: Query by hw-address "
1743 "requires hwaddr to be specified");
1744 }
1745
1746 // Let's see if there's such a lease at all.
1747 lease4 = LeaseMgrFactory::instance().getLease4(*p.hwaddr, p.subnet_id);
1748 if (!lease4) {
1749 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1750 return (0);
1751 }
1752 break;
1753 }
1755 if (!p.client_id) {
1756 isc_throw(InvalidParameter, "Program error: Query by client-id "
1757 "requires client-id to be specified");
1758 }
1759
1760 // Let's see if there's such a lease at all.
1761 lease4 = LeaseMgrFactory::instance().getLease4(*p.client_id, p.subnet_id);
1762 if (!lease4) {
1763 setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1764 return (0);
1765 }
1766 break;
1767 }
1768 case Parameters::TYPE_DUID: {
1769 isc_throw(InvalidParameter, "Delete by duid is not allowed in v4.");
1770 break;
1771 }
1772 default: {
1773 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
1774 break;
1775 }
1776 }
1777
1778 if (LeaseMgrFactory::instance().deleteLease(lease4)) {
1779 setSuccessResponse(handle, "IPv4 lease deleted.");
1781 } else {
1782 setErrorResponse (handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
1783 }
1784
1785 // Queue an NCR to remove DNS if configured and the lease has it.
1786 if (p.updateDDNS) {
1787 queueNCR(CHG_REMOVE, lease4);
1788 }
1789
1790 } catch (const std::exception& ex) {
1792 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
1793 .arg(ex.what());
1794 setErrorResponse(handle, ex.what());
1795 return (1);
1796 }
1798 .arg(lease4->addr_.toText());
1799 return (0);
1800}
1801
1802int
1804 try {
1805 extractCommand(handle);
1806
1807 // Arguments are mandatory.
1808 if (!cmd_args_ || (cmd_args_->getType() != Element::map)) {
1809 isc_throw(BadValue, "Command arguments missing or a not a map.");
1810 }
1811
1812 // At least one of the 'deleted-leases' or 'leases' must be present.
1813 auto deleted_leases = cmd_args_->get("deleted-leases");
1814 auto leases = cmd_args_->get("leases");
1815
1816 if (!deleted_leases && !leases) {
1817 isc_throw(BadValue, "neither 'deleted-leases' nor 'leases' parameter"
1818 " specified");
1819 }
1820
1821 // Make sure that 'deleted-leases' is a list, if present.
1822 if (deleted_leases && (deleted_leases->getType() != Element::list)) {
1823 isc_throw(BadValue, "the 'deleted-leases' parameter must be a list");
1824 }
1825
1826 // Make sure that 'leases' is a list, if present.
1827 if (leases && (leases->getType() != Element::list)) {
1828 isc_throw(BadValue, "the 'leases' parameter must be a list");
1829 }
1830
1831 // Parse deleted leases without deleting them from the database
1832 // yet. If any of the deleted leases or new leases appears to be
1833 // malformed we can easily rollback.
1834 std::list<std::pair<Parameters, Lease6Ptr> > parsed_deleted_list;
1835 if (deleted_leases) {
1836 auto leases_list = deleted_leases->listValue();
1837
1838 // Iterate over leases to be deleted.
1839 for (auto lease_params : leases_list) {
1840 // Parsing the lease may throw and it means that the lease
1841 // information is malformed.
1842 Parameters p = getParameters(true, lease_params);
1843 auto lease = getIPv6LeaseForDelete(p);
1844 parsed_deleted_list.push_back(std::make_pair(p, lease));
1845 }
1846 }
1847
1848 // Parse new/updated leases without affecting the database to detect
1849 // any errors that should cause an error response.
1850 std::list<Lease6Ptr> parsed_leases_list;
1851 if (leases) {
1852 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
1853
1854 // Iterate over all leases.
1855 auto leases_list = leases->listValue();
1856 for (auto lease_params : leases_list) {
1857
1858 Lease6Parser parser;
1859 bool force_update;
1860
1861 // If parsing the lease fails we throw, as it indicates that the
1862 // command is malformed.
1863 Lease6Ptr lease6 = parser.parse(config, lease_params, force_update);
1864 parsed_leases_list.push_back(lease6);
1865 }
1866 }
1867
1868 // Count successful deletions and updates.
1869 size_t success_count = 0;
1870
1871 ElementPtr failed_deleted_list;
1872 if (!parsed_deleted_list.empty()) {
1873
1874 // Iterate over leases to be deleted.
1875 for (auto lease_params_pair : parsed_deleted_list) {
1876
1877 // This part is outside of the try-catch because an exception
1878 // indicates that the command is malformed.
1879 Parameters p = lease_params_pair.first;
1880 auto lease = lease_params_pair.second;
1881
1882 try {
1883 if (lease) {
1884 // This may throw if the lease couldn't be deleted for
1885 // any reason, but we still want to proceed with other
1886 // leases.
1887 if (LeaseMgrFactory::instance().deleteLease(lease)) {
1888 ++success_count;
1890
1891 } else {
1892 // Lazy creation of the list of leases which failed to delete.
1893 if (!failed_deleted_list) {
1894 failed_deleted_list = Element::createList();
1895 }
1896
1897 // If the lease doesn't exist we also want to put it
1898 // on the list of leases which failed to delete. That
1899 // corresponds to the lease6-del command which returns
1900 // an error when the lease doesn't exist.
1901 failed_deleted_list->add(createFailedLeaseMap(p.lease_type,
1902 p.addr, p.duid,
1904 "lease not found"));
1905 }
1906 }
1907
1908 } catch (const std::exception& ex) {
1909 // Lazy creation of the list of leases which failed to delete.
1910 if (!failed_deleted_list) {
1911 failed_deleted_list = Element::createList();
1912 }
1913 failed_deleted_list->add(createFailedLeaseMap(p.lease_type,
1914 p.addr, p.duid,
1916 ex.what()));
1917 }
1918 }
1919 }
1920
1921 // Process leases to be added or/and updated.
1922 ElementPtr failed_leases_list;
1923 if (!parsed_leases_list.empty()) {
1924 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
1925
1926 // Iterate over all leases.
1927 for (auto lease : parsed_leases_list) {
1928
1929 auto result = CONTROL_RESULT_SUCCESS;
1930 std::ostringstream text;
1931 try {
1932 if (!MultiThreadingMgr::instance().getMode()) {
1933 // Not multi-threading.
1934 addOrUpdate6(lease, true);
1935 } else {
1936 // Multi-threading, try to lock first to avoid a race.
1937 ResourceHandler resource_handler;
1938 if (resource_handler.tryLock(lease->type_, lease->addr_)) {
1939 addOrUpdate6(lease, true);
1940 } else {
1942 "ResourceBusy: IP address:" << lease->addr_
1943 << " could not be updated.");
1944 }
1945 }
1946
1947 ++success_count;
1948 } catch (const LeaseCmdsConflict& ex) {
1949 result = CONTROL_RESULT_CONFLICT;
1950 text << ex.what();
1951
1952 } catch (const std::exception& ex) {
1953 result = CONTROL_RESULT_ERROR;
1954 text << ex.what();
1955 }
1956 // Handle an error.
1957 if (result != CONTROL_RESULT_SUCCESS) {
1958 // Lazy creation of the list of leases which failed to add/update.
1959 if (!failed_leases_list) {
1960 failed_leases_list = Element::createList();
1961 }
1962 failed_leases_list->add(createFailedLeaseMap(lease->type_,
1963 lease->addr_,
1964 lease->duid_,
1965 result,
1966 text.str()));
1967 }
1968 }
1969 }
1970
1971 // Start preparing the response.
1972 ElementPtr args;
1973
1974 if (failed_deleted_list || failed_leases_list) {
1975 // If there are any failed leases, let's include them in the response.
1976 args = Element::createMap();
1977
1978 // failed-deleted-leases
1979 if (failed_deleted_list) {
1980 args->set("failed-deleted-leases", failed_deleted_list);
1981 }
1982
1983 // failed-leases
1984 if (failed_leases_list) {
1985 args->set("failed-leases", failed_leases_list);
1986 }
1987 }
1988
1989 // Send the success response and include failed leases.
1990 std::ostringstream resp_text;
1991 resp_text << "Bulk apply of " << success_count << " IPv6 leases completed.";
1992 auto answer = createAnswer(success_count > 0 ? CONTROL_RESULT_SUCCESS :
1993 CONTROL_RESULT_EMPTY, resp_text.str(), args);
1994 setResponse(handle, answer);
1995
1998 .arg(success_count);
1999
2000 } catch (const std::exception& ex) {
2001 // Unable to parse the command and similar issues.
2003 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2004 .arg(ex.what());
2005 setErrorResponse(handle, ex.what());
2006 return (CONTROL_RESULT_ERROR);
2007 }
2008
2009 return (0);
2010}
2011
2012int
2014 Parameters p;
2015 Lease6Ptr lease6;
2016 IOAddress addr(IOAddress::IPV6_ZERO_ADDRESS());
2017 try {
2018 extractCommand(handle);
2019 p = getParameters(true, cmd_args_);
2020
2021 switch (p.query_type) {
2022 case Parameters::TYPE_ADDR: {
2023 // If address was specified explicitly, let's use it as is.
2024
2025 // Let's see if there's such a lease at all.
2026 lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, p.addr);
2027 if (!lease6) {
2028 setErrorResponse(handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
2029 return (0);
2030 }
2031 break;
2032 }
2034 isc_throw(InvalidParameter, "Delete by hw-address is not allowed in v6.");
2035 break;
2036 }
2037 case Parameters::TYPE_DUID: {
2038 if (!p.duid) {
2039 isc_throw(InvalidParameter, "Program error: Query by duid "
2040 "requires duid to be specified");
2041 }
2042
2043 // Let's see if there's such a lease at all.
2044 lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, *p.duid,
2045 p.iaid, p.subnet_id);
2046 if (!lease6) {
2047 setErrorResponse(handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
2048 return (0);
2049 }
2050 break;
2051 }
2052 default: {
2053 isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
2054 break;
2055 }
2056 }
2057
2058 if (LeaseMgrFactory::instance().deleteLease(lease6)) {
2059 setSuccessResponse(handle, "IPv6 lease deleted.");
2061 } else {
2062 setErrorResponse (handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
2063 }
2064
2065 // Queue an NCR to remove DNS if configured and the lease has it.
2066 if (p.updateDDNS) {
2067 queueNCR(CHG_REMOVE, lease6);
2068 }
2069
2070 } catch (const std::exception& ex) {
2072 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2073 .arg(ex.what());
2074 setErrorResponse(handle, ex.what());
2075 return (1);
2076 }
2077
2079 .arg(lease6->addr_.toText());
2080 return (0);
2081}
2082
2083int
2085 try {
2086 extractCommand(handle);
2087
2088 // We need the lease to be specified.
2089 if (!cmd_args_) {
2090 isc_throw(isc::BadValue, "no parameters specified for lease4-update command");
2091 }
2092
2093 // Get the parameters specified by the user first.
2094 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
2095 Lease4Ptr lease4;
2096 Lease4Parser parser;
2097 bool force_create = false;
2098
2099 // The parser does sanity checks (if the address is in scope, if
2100 // subnet-id is valid, etc)
2101 lease4 = parser.parse(config, cmd_args_, force_create);
2102 bool added = false;
2103 if (!MultiThreadingMgr::instance().getMode()) {
2104 // Not multi-threading.
2105 added = addOrUpdate4(lease4, force_create);
2106 } else {
2107 // Multi-threading, try to lock first to avoid a race.
2108 ResourceHandler4 resource_handler;
2109 if (resource_handler.tryLock4(lease4->addr_)) {
2110 added = addOrUpdate4(lease4, force_create);
2111 } else {
2113 "ResourceBusy: IP address:" << lease4->addr_
2114 << " could not be updated.");
2115 }
2116 }
2117
2118 if (added) {
2119 setSuccessResponse(handle, "IPv4 lease added.");
2120 } else {
2121 setSuccessResponse(handle, "IPv4 lease updated.");
2122 }
2125 .arg(lease4->addr_.toText());
2126
2127 } catch (const LeaseCmdsConflict& ex) {
2129 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2130 .arg(ex.what());
2132 return (0);
2133
2134 } catch (const std::exception& ex) {
2136 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2137 .arg(ex.what());
2138 setErrorResponse(handle, ex.what());
2139 return (1);
2140 }
2141
2142 return (0);
2143}
2144
2145int
2147 try {
2148 extractCommand(handle);
2149
2150 // We need the lease to be specified.
2151 if (!cmd_args_) {
2152 isc_throw(isc::BadValue, "no parameters specified for lease6-update command");
2153 }
2154
2155 // Get the parameters specified by the user first.
2156 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
2157 Lease6Ptr lease6;
2158 Lease6Parser parser;
2159 bool force_create = false;
2160
2161 // The parser does sanity checks (if the address is in scope, if
2162 // subnet-id is valid, etc)
2163 lease6 = parser.parse(config, cmd_args_, force_create);
2164 bool added = false;
2165 if (!MultiThreadingMgr::instance().getMode()) {
2166 // Not multi-threading.
2167 added = addOrUpdate6(lease6, force_create);
2168 } else {
2169 // Multi-threading, try to lock first to avoid a race.
2170 ResourceHandler resource_handler;
2171 if (resource_handler.tryLock(lease6->type_, lease6->addr_)) {
2172 added = addOrUpdate6(lease6, force_create);
2173 } else {
2175 "ResourceBusy: IP address:" << lease6->addr_
2176 << " could not be updated.");
2177 }
2178 }
2179
2180 if (added) {
2181 setSuccessResponse(handle, "IPv6 lease added.");
2182 } else {
2183 setSuccessResponse(handle, "IPv6 lease updated.");
2184 }
2187 .arg(lease6->addr_.toText());
2188
2189 } catch (const LeaseCmdsConflict& ex) {
2191 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2192 .arg(ex.what());
2194 return (0);
2195
2196 } catch (const std::exception& ex) {
2198 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2199 .arg(ex.what());
2200 setErrorResponse(handle, ex.what());
2201 return (1);
2202 }
2203
2204 return (0);
2205}
2206
2207int
2209 try {
2210 extractCommand(handle);
2211
2212 SimpleParser parser;
2213 SubnetID id = 0;
2214
2215 size_t num = 0; // number of leases deleted
2216 stringstream ids; // a text with subnet-ids being wiped
2217
2218 // The subnet-id parameter is now optional.
2219 if (cmd_args_ && cmd_args_->contains("subnet-id")) {
2220 id = parser.getUint32(cmd_args_, "subnet-id");
2221 }
2222
2223 if (id) {
2224 // Wipe a single subnet.
2225 num = LeaseMgrFactory::instance().wipeLeases4(id);
2226 ids << " " << id;
2227
2228 auto observation = StatsMgr::instance().getObservation(
2229 StatsMgr::generateName("subnet", id, "declined-addresses"));
2230
2231 int64_t previous_declined = 0;
2232
2233 if (observation) {
2234 previous_declined = observation->getInteger().first;
2235 }
2236
2237 StatsMgr::instance().setValue(
2238 StatsMgr::generateName("subnet", id, "assigned-addresses"),
2239 static_cast<int64_t>(0));
2240
2241 StatsMgr::instance().setValue(
2242 StatsMgr::generateName("subnet", id, "declined-addresses"),
2243 static_cast<int64_t>(0));
2244
2245 auto const& sub = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(id);
2246 if (sub) {
2247 for (const auto& pool : sub->getPools(Lease::TYPE_V4)) {
2248 const std::string& name_aa(StatsMgr::generateName("subnet", sub->getID(),
2249 StatsMgr::generateName("pool", pool->getID(),
2250 "assigned-addresses")));
2251 if (!StatsMgr::instance().getObservation(name_aa)) {
2252 StatsMgr::instance().setValue(name_aa, static_cast<int64_t>(0));
2253 }
2254
2255 const std::string& name_da(StatsMgr::generateName("subnet", sub->getID(),
2256 StatsMgr::generateName("pool", pool->getID(),
2257 "declined-addresses")));
2258 if (!StatsMgr::instance().getObservation(name_da)) {
2259 StatsMgr::instance().setValue(name_da, static_cast<int64_t>(0));
2260 }
2261 }
2262 }
2263
2264 StatsMgr::instance().addValue("declined-addresses", -previous_declined);
2265 } else {
2266 // Wipe them all!
2267 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
2268 ConstCfgSubnets4Ptr subnets = config->getCfgSubnets4();
2269 const Subnet4Collection* subs = subnets->getAll();
2270
2271 // Go over all subnets and wipe leases in each of them.
2272 for (auto sub : *subs) {
2273 num += LeaseMgrFactory::instance().wipeLeases4(sub->getID());
2274 ids << " " << sub->getID();
2275 StatsMgr::instance().setValue(
2276 StatsMgr::generateName("subnet", sub->getID(), "assigned-addresses"),
2277 static_cast<int64_t>(0));
2278
2279 StatsMgr::instance().setValue(
2280 StatsMgr::generateName("subnet", sub->getID(), "declined-addresses"),
2281 static_cast<int64_t>(0));
2282
2283 for (const auto& pool : sub->getPools(Lease::TYPE_V4)) {
2284 const std::string& name_aa(StatsMgr::generateName("subnet", sub->getID(),
2285 StatsMgr::generateName("pool", pool->getID(),
2286 "assigned-addresses")));
2287 if (!StatsMgr::instance().getObservation(name_aa)) {
2288 StatsMgr::instance().setValue(name_aa, static_cast<int64_t>(0));
2289 }
2290
2291 const std::string& name_da(StatsMgr::generateName("subnet", sub->getID(),
2292 StatsMgr::generateName("pool", pool->getID(),
2293 "declined-addresses")));
2294 if (!StatsMgr::instance().getObservation(name_da)) {
2295 StatsMgr::instance().setValue(name_da, static_cast<int64_t>(0));
2296 }
2297 }
2298 }
2299
2300 StatsMgr::instance().setValue("declined-addresses", static_cast<int64_t>(0));
2301 }
2302
2303 stringstream tmp;
2304 tmp << "Deleted " << num << " IPv4 lease(s) from subnet(s)" << ids.str();
2306 : CONTROL_RESULT_EMPTY, tmp.str());
2307 setResponse(handle, response);
2308 } catch (const std::exception& ex) {
2310 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2311 .arg(ex.what());
2312 setErrorResponse(handle, ex.what());
2313 return (1);
2314 }
2315
2317 .arg(cmd_args_ ? cmd_args_->str() : "<no args>");
2318 return (0);
2319}
2320
2321int
2323 try {
2324 extractCommand(handle);
2325
2326 SimpleParser parser;
2327 SubnetID id = 0;
2328
2329 size_t num = 0; // number of leases deleted
2330 stringstream ids; // a text with subnet-ids being wiped
2331
2336
2337 // The subnet-id parameter is now optional.
2338 if (cmd_args_ && cmd_args_->contains("subnet-id")) {
2339 id = parser.getUint32(cmd_args_, "subnet-id");
2340 }
2341
2342 if (id) {
2343 // Wipe a single subnet.
2344 num = LeaseMgrFactory::instance().wipeLeases6(id);
2345 ids << " " << id;
2346
2347 auto observation = StatsMgr::instance().getObservation(
2348 StatsMgr::generateName("subnet", id, "declined-addresses"));
2349
2350 int64_t previous_declined = 0;
2351
2352 if (observation) {
2353 previous_declined = observation->getInteger().first;
2354 }
2355
2356 StatsMgr::instance().setValue(
2357 StatsMgr::generateName("subnet", id, "assigned-nas" ),
2358 static_cast<int64_t>(0));
2359
2360 StatsMgr::instance().setValue(
2361 StatsMgr::generateName("subnet", id, "assigned-pds"),
2362 static_cast<int64_t>(0));
2363
2364 StatsMgr::instance().setValue(
2365 StatsMgr::generateName("subnet", id, "declined-addresses"),
2366 static_cast<int64_t>(0));
2367
2368 auto const& sub = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getBySubnetId(id);
2369 if (sub) {
2370 for (const auto& pool : sub->getPools(Lease::TYPE_NA)) {
2371 const std::string& name_anas(StatsMgr::generateName("subnet", sub->getID(),
2372 StatsMgr::generateName("pool", pool->getID(),
2373 "assigned-nas")));
2374 if (!StatsMgr::instance().getObservation(name_anas)) {
2375 StatsMgr::instance().setValue(name_anas, static_cast<int64_t>(0));
2376 }
2377
2378 const std::string& name_da(StatsMgr::generateName("subnet", sub->getID(),
2379 StatsMgr::generateName("pool", pool->getID(),
2380 "declined-addresses")));
2381 if (!StatsMgr::instance().getObservation(name_da)) {
2382 StatsMgr::instance().setValue(name_da, static_cast<int64_t>(0));
2383 }
2384 }
2385
2386 for (const auto& pool : sub->getPools(Lease::TYPE_PD)) {
2387 const std::string& name_apds(StatsMgr::generateName("subnet", sub->getID(),
2388 StatsMgr::generateName("pd-pool", pool->getID(),
2389 "assigned-pds")));
2390 if (!StatsMgr::instance().getObservation(name_apds)) {
2391 StatsMgr::instance().setValue(name_apds, static_cast<int64_t>(0));
2392 }
2393 }
2394 }
2395
2396 StatsMgr::instance().addValue("declined-addresses", -previous_declined);
2397 } else {
2398 // Wipe them all!
2399 ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
2400 ConstCfgSubnets6Ptr subnets = config->getCfgSubnets6();
2401 const Subnet6Collection* subs = subnets->getAll();
2402
2403 // Go over all subnets and wipe leases in each of them.
2404 for (auto sub : *subs) {
2405 num += LeaseMgrFactory::instance().wipeLeases6(sub->getID());
2406 ids << " " << sub->getID();
2407 StatsMgr::instance().setValue(
2408 StatsMgr::generateName("subnet", sub->getID(), "assigned-nas" ),
2409 static_cast<int64_t>(0));
2410
2411 StatsMgr::instance().setValue(
2412 StatsMgr::generateName("subnet", sub->getID(), "assigned-pds"),
2413 static_cast<int64_t>(0));
2414
2415 StatsMgr::instance().setValue(
2416 StatsMgr::generateName("subnet", sub->getID(), "declined-addresses"),
2417 static_cast<int64_t>(0));
2418
2419 for (const auto& pool : sub->getPools(Lease::TYPE_NA)) {
2420 const std::string& name_anas(StatsMgr::generateName("subnet", sub->getID(),
2421 StatsMgr::generateName("pool", pool->getID(),
2422 "assigned-nas")));
2423 if (!StatsMgr::instance().getObservation(name_anas)) {
2424 StatsMgr::instance().setValue(name_anas, static_cast<int64_t>(0));
2425 }
2426
2427 const std::string& name_da(StatsMgr::generateName("subnet", sub->getID(),
2428 StatsMgr::generateName("pool", pool->getID(),
2429 "declined-addresses")));
2430 if (!StatsMgr::instance().getObservation(name_da)) {
2431 StatsMgr::instance().setValue(name_da, static_cast<int64_t>(0));
2432 }
2433 }
2434
2435 for (const auto& pool : sub->getPools(Lease::TYPE_PD)) {
2436 const std::string& name_apds(StatsMgr::generateName("subnet", sub->getID(),
2437 StatsMgr::generateName("pd-pool", pool->getID(),
2438 "assigned-pds")));
2439 if (!StatsMgr::instance().getObservation(name_apds)) {
2440 StatsMgr::instance().setValue(name_apds, static_cast<int64_t>(0));
2441 }
2442 }
2443 }
2444
2445 StatsMgr::instance().setValue("declined-addresses", static_cast<int64_t>(0));
2446 }
2447
2448 stringstream tmp;
2449 tmp << "Deleted " << num << " IPv6 lease(s) from subnet(s)" << ids.str();
2451 : CONTROL_RESULT_EMPTY, tmp.str());
2452 setResponse(handle, response);
2453 } catch (const std::exception& ex) {
2455 .arg(cmd_args_ ? cmd_args_->str() : "<no args>")
2456 .arg(ex.what());
2457 setErrorResponse(handle, ex.what());
2458 return (1);
2459 }
2460
2462 .arg(cmd_args_ ? cmd_args_->str() : "<no args>");
2463 return (0);
2464}
2465
2468 Lease6Ptr lease6;
2469
2470 switch (parameters.query_type) {
2471 case Parameters::TYPE_ADDR: {
2472 // If address was specified explicitly, let's use it as is.
2473
2474 // Let's see if there's such a lease at all.
2475 lease6 = LeaseMgrFactory::instance().getLease6(parameters.lease_type,
2476 parameters.addr);
2477 if (!lease6) {
2478 lease6.reset(new Lease6());
2479 lease6->addr_ = parameters.addr;
2480 }
2481 break;
2482 }
2484 isc_throw(InvalidParameter, "Delete by hw-address is not allowed in v6.");
2485 break;
2486 }
2487 case Parameters::TYPE_DUID: {
2488 if (!parameters.duid) {
2489 isc_throw(InvalidParameter, "Program error: Query by duid "
2490 "requires duid to be specified");
2491 }
2492
2493 // Let's see if there's such a lease at all.
2494 lease6 = LeaseMgrFactory::instance().getLease6(parameters.lease_type,
2495 *parameters.duid,
2496 parameters.iaid,
2497 parameters.subnet_id);
2498 break;
2499 }
2500 default:
2501 isc_throw(InvalidOperation, "Unknown query type: "
2502 << static_cast<int>(parameters.query_type));
2503 }
2504
2505 return (lease6);
2506}
2507
2510 short family) const {
2511 ConstElementPtr param = params->get(name);
2512 if (!param) {
2513 isc_throw(BadValue, "'" << name << "' parameter is missing.");
2514 }
2515
2516 if (param->getType() != Element::string) {
2517 isc_throw(BadValue, "'" << name << "' is not a string.");
2518 }
2519
2520 IOAddress addr(0);
2521 try {
2522 addr = IOAddress(param->stringValue());
2523 } catch (const std::exception& ex) {
2524 isc_throw(BadValue, "'" << param->stringValue()
2525 << "' is not a valid IP address.");
2526 }
2527
2528 if (addr.getFamily() != family) {
2529 isc_throw(BadValue, "Invalid "
2530 << (family == AF_INET6 ? "IPv6" : "IPv4")
2531 << " address specified: " << param->stringValue());
2532 }
2533
2534 return (addr);
2535}
2536
2537int
2539 std::stringstream ss;
2540 int resp_code = CONTROL_RESULT_ERROR;
2541
2542 try {
2543 extractCommand(handle);
2544
2545 // Get the target lease address. Invalid value will throw.
2546 IOAddress addr = getAddressParam(cmd_args_, "ip-address", AF_INET);
2547
2548 if (!CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
2549 ss << "DDNS updating is not enabled";
2550 resp_code = CONTROL_RESULT_CONFLICT;
2551 } else {
2552 // Find the lease.
2553 Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(addr);
2554 if (!lease) {
2555 ss << "No lease found for: " << addr.toText();
2556 resp_code = CONTROL_RESULT_EMPTY;
2557 } else if (lease->hostname_.empty()) {
2558 ss << "Lease for: " << addr.toText()
2559 << ", has no hostname, nothing to update";
2560 resp_code = CONTROL_RESULT_CONFLICT;
2561 } else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
2562 ss << "Neither forward nor reverse updates enabled for lease for: "
2563 << addr.toText();
2564 resp_code = CONTROL_RESULT_CONFLICT;
2565 } else {
2566 // We have a lease with a hostname and updates in at least
2567 // one direction enabled. Queue an NCR for it.
2568 queueNCR(CHG_ADD, lease);
2569 ss << "NCR generated for: " << addr.toText()
2570 << ", hostname: " << lease->hostname_;
2571 setSuccessResponse(handle, ss.str());
2573 return (0);
2574 }
2575 }
2576 } catch (const std::exception& ex) {
2577 ss << ex.what();
2578 }
2579
2581 setErrorResponse(handle, ss.str(), resp_code);
2582 return (resp_code == CONTROL_RESULT_EMPTY || resp_code == CONTROL_RESULT_CONFLICT ? 0 : 1);
2583}
2584
2585int
2587 std::stringstream ss;
2588 int resp_code = CONTROL_RESULT_ERROR;
2589
2590 try {
2591 extractCommand(handle);
2592
2593 // Get the target lease address. Invalid value will throw.
2594 IOAddress addr = getAddressParam(cmd_args_, "ip-address", AF_INET6);
2595
2596 if (!CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
2597 ss << "DDNS updating is not enabled";
2598 resp_code = CONTROL_RESULT_CONFLICT;
2599 } else {
2600 // Find the lease.
2601 Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA, addr);
2602 if (!lease) {
2603 ss << "No lease found for: " << addr.toText();
2604 resp_code = CONTROL_RESULT_EMPTY;
2605 } else if (lease->hostname_.empty()) {
2606 ss << "Lease for: " << addr.toText()
2607 << ", has no hostname, nothing to update";
2608 resp_code = CONTROL_RESULT_CONFLICT;
2609 } else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
2610 ss << "Neither forward nor reverse updates enabled for lease for: "
2611 << addr.toText();
2612 resp_code = CONTROL_RESULT_CONFLICT;
2613 } else {
2614 // We have a lease with a hostname and updates in at least
2615 // one direction enabled. Queue an NCR for it.
2616 queueNCR(CHG_ADD, lease);
2617 ss << "NCR generated for: " << addr.toText()
2618 << ", hostname: " << lease->hostname_;
2619 setSuccessResponse(handle, ss.str());
2621 return (0);
2622 }
2623 }
2624 } catch (const std::exception& ex) {
2625 ss << ex.what();
2626 }
2627
2629 setErrorResponse(handle, ss.str(), resp_code);
2630 return (resp_code == CONTROL_RESULT_EMPTY ? 0 : 1);
2631}
2632
2635 const IOAddress& lease_address,
2636 const DuidPtr& duid,
2637 const int control_result,
2638 const std::string& error_message) const {
2639 auto failed_lease_map = Element::createMap();
2640 failed_lease_map->set("type", Element::create(Lease::typeToText(lease_type)));
2641
2642 if (!lease_address.isV6Zero()) {
2643 failed_lease_map->set("ip-address", Element::create(lease_address.toText()));
2644
2645 } else if (duid) {
2646 failed_lease_map->set("duid", Element::create(duid->toText()));
2647 }
2648
2649 // Associate the result with the lease.
2650 failed_lease_map->set("result", Element::create(control_result));
2651 failed_lease_map->set("error-message", Element::create(error_message));
2652
2653 return (failed_lease_map);
2654}
2655
2656int
2658 bool v4 = true;
2659 try {
2660 extractCommand(handle);
2661 v4 = (cmd_name_ == "lease4-write");
2662
2663 if (!cmd_args_) {
2664 isc_throw(isc::BadValue, "no parameters specified for the command");
2665 }
2666
2667 ConstElementPtr file = cmd_args_->get("filename");
2668 if (!file) {
2669 isc_throw(BadValue, "'filename' parameter not specified");
2670 }
2671 if (file->getType() != Element::string) {
2672 isc_throw(BadValue, "'filename' parameter must be a string");
2673 }
2674 string filename = file->stringValue();
2675 if (filename.empty()) {
2676 isc_throw(BadValue, "'filename' parameter is empty");
2677 }
2678
2679 if (v4) {
2680 LeaseMgrFactory::instance().writeLeases4(filename);
2681 } else {
2682 LeaseMgrFactory::instance().writeLeases6(filename);
2683 }
2684 ostringstream s;
2685 s << (v4 ? "IPv4" : "IPv6")
2686 << " lease database into '"
2687 << filename << "'.";
2689 setResponse(handle, response);
2690 } catch (const std::exception& ex) {
2691 setErrorResponse(handle, ex.what());
2692 return (CONTROL_RESULT_ERROR);
2693 }
2694
2695 return (0);
2696}
2697
2698int
2700 return (impl_->leaseAddHandler(handle));
2701}
2702
2703int
2705 return (impl_->lease6BulkApplyHandler(handle));
2706}
2707
2708int
2710 return (impl_->leaseGetHandler(handle));
2711}
2712
2713int
2715 return (impl_->leaseGetAllHandler(handle));
2716}
2717
2718int
2720 return (impl_->leaseGetPageHandler(handle));
2721}
2722
2723int
2725 return (impl_->leaseGetByHwAddressHandler(handle));
2726}
2727
2728int
2730 return (impl_->leaseGetByClientIdHandler(handle));
2731}
2732
2733int
2735 return (impl_->leaseGetByDuidHandler(handle));
2736}
2737
2738int
2740 return (impl_->leaseGetByHostnameHandler(handle));
2741}
2742
2743int
2745 return (impl_->lease4DelHandler(handle));
2746}
2747
2748int
2750 return (impl_->lease6DelHandler(handle));
2751}
2752
2753int
2755 return (impl_->lease4UpdateHandler(handle));
2756}
2757
2758int
2760 return (impl_->lease6UpdateHandler(handle));
2761}
2762
2763int
2766 return (impl_->lease4WipeHandler(handle));
2767}
2768
2769int
2772 return (impl_->lease6WipeHandler(handle));
2773}
2774
2775int
2777 return (impl_->lease4ResendDdnsHandler(handle));
2778}
2779
2780int
2782 return (impl_->lease6ResendDdnsHandler(handle));
2783}
2784
2785int
2787 return (impl_->leaseWriteHandler(handle));
2788}
2789
2791}
2792
2793} // end of namespace lease_cmds
2794} // end of namespace isc
Exception thrown when a command failed due to a conflict.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
Base class that command handler implementers may use for common tasks.
Definition: cmds_impl.h:21
std::string cmd_name_
Stores the command name extracted by a call to extractCommand.
Definition: cmds_impl.h:69
void setErrorResponse(hooks::CalloutHandle &handle, const std::string &text, int status=CONTROL_RESULT_ERROR)
Set the callout argument "response" to indicate an error.
Definition: cmds_impl.h:54
data::ConstElementPtr cmd_args_
Stores the command arguments extracted by a call to extractCommand.
Definition: cmds_impl.h:72
void extractCommand(hooks::CalloutHandle &handle)
Extracts the command name and arguments from a Callout handle.
Definition: cmds_impl.h:29
void setSuccessResponse(hooks::CalloutHandle &handle, const std::string &text)
Set the callout argument "response" to indicate success.
Definition: cmds_impl.h:43
void setResponse(hooks::CalloutHandle &handle, data::ConstElementPtr &response)
Set the callout argument "response" to the given response.
Definition: cmds_impl.h:64
uint32_t getUint32(isc::data::ConstElementPtr scope, const std::string &name)
Returns a value converted to uint32_t.
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:138
Wraps value holding size of the page with leases.
Definition: lease_mgr.h:46
Attempt to update lease that was not there.
Resource race avoidance RAII handler for DHCPv4.
bool tryLock4(const asiolink::IOAddress &addr)
Tries to acquires a resource.
Resource race avoidance RAII handler.
bool tryLock(Lease::Type type, const asiolink::IOAddress &addr)
Tries to acquires a resource.
Per-packet callout handle.
Parser for Lease4 structure.
Definition: lease_parser.h:35
virtual isc::dhcp::Lease4Ptr parse(isc::dhcp::ConstSrvConfigPtr &cfg, const isc::data::ConstElementPtr &lease_info, bool &force_create)
Parses Element tree and tries to convert to Lease4.
Definition: lease_parser.cc:30
Parser for Lease6 structure.
Definition: lease_parser.h:78
virtual isc::dhcp::Lease6Ptr parse(isc::dhcp::ConstSrvConfigPtr &cfg, const isc::data::ConstElementPtr &lease_info, bool &force_create)
Parses Element tree and tries to convert to Lease4.
Parameters specified for lease commands.
Definition: lease_cmds.cc:57
uint32_t iaid
IAID identifier used for v6 leases.
Definition: lease_cmds.cc:115
HWAddrPtr hwaddr
Specifies hardware address (used when query_type is TYPE_HWADDR)
Definition: lease_cmds.cc:75
Lease::Type lease_type
Lease type (NA,TA or PD) used for v6 leases.
Definition: lease_cmds.cc:112
Type query_type
specifies parameter types
Definition: lease_cmds.cc:109
Type
specifies type of query (by IP addr, by hwaddr, by DUID)
Definition: lease_cmds.cc:61
@ TYPE_DUID
query by DUID (v6 only)
Definition: lease_cmds.cc:64
@ TYPE_CLIENT_ID
query by client identifier (v4 only).
Definition: lease_cmds.cc:65
@ TYPE_HWADDR
query by hardware address (v4 only)
Definition: lease_cmds.cc:63
@ TYPE_ADDR
query by IP address (either v4 or v6)
Definition: lease_cmds.cc:62
isc::dhcp::ClientIdPtr client_id
Specifies identifier value (used when query_type is TYPE_CLIENT_ID)
Definition: lease_cmds.cc:81
static Type txtToType(const std::string &txt)
Attempts to covert text to one of specified types.
Definition: lease_cmds.cc:92
bool updateDDNS
Indicates whether or not DNS should be updated.
Definition: lease_cmds.cc:118
IOAddress addr
Specifies IPv4/v6 address (used when query_type is TYPE_ADDR)
Definition: lease_cmds.cc:72
SubnetID subnet_id
Specifies subnet-id (always used)
Definition: lease_cmds.cc:69
isc::dhcp::DuidPtr duid
Specifies identifier value (used when query_type is TYPE_DUID)
Definition: lease_cmds.cc:78
Wrapper class around reservation command handlers.
Definition: lease_cmds.cc:53
int lease4DelHandler(CalloutHandle &handle)
lease4-del command handler
Definition: lease_cmds.cc:1724
IOAddress getAddressParam(ConstElementPtr params, const std::string name, short family=AF_INET) const
Definition: lease_cmds.cc:2509
static void updateStatsOnUpdate(const Lease4Ptr &existing, const Lease4Ptr &lease)
Update stats when updating lease.
Definition: lease_cmds.cc:561
ElementPtr createFailedLeaseMap(const Lease::Type &lease_type, const IOAddress &lease_address, const DuidPtr &duid, const int control_result, const std::string &error_message) const
Returns a map holding brief information about a lease which failed to be deleted, updated or added.
Definition: lease_cmds.cc:2634
static bool addOrUpdate6(Lease6Ptr lease, bool force_create)
Add or update lease.
Definition: lease_cmds.cc:942
int lease6BulkApplyHandler(CalloutHandle &handle)
lease6-bulk-apply command handler
Definition: lease_cmds.cc:1803
int leaseGetByDuidHandler(hooks::CalloutHandle &handle)
lease6-get-by-duid command handler
Definition: lease_cmds.cc:1604
int lease6UpdateHandler(CalloutHandle &handle)
lease6-update handler
Definition: lease_cmds.cc:2146
int leaseGetPageHandler(hooks::CalloutHandle &handle)
lease4-get-page, lease6-get-page commands handler
Definition: lease_cmds.cc:1385
Lease6Ptr getIPv6LeaseForDelete(const Parameters &parameters) const
Convenience function fetching IPv6 address to be used to delete a lease.
Definition: lease_cmds.cc:2467
int leaseGetByHostnameHandler(hooks::CalloutHandle &handle)
lease4-get-by-hostname and lease6-get-by-hostname commands handler
Definition: lease_cmds.cc:1654
int lease6DelHandler(CalloutHandle &handle)
lease6-del command handler
Definition: lease_cmds.cc:2013
int leaseGetByHwAddressHandler(hooks::CalloutHandle &handle)
lease4-get-by-hw-address command handler
Definition: lease_cmds.cc:1504
static ConstElementPtr getExtendedInfo6(const Lease6Ptr &lease)
Get DHCPv6 extended info.
Definition: lease_cmds.cc:464
int leaseGetHandler(CalloutHandle &handle)
lease4-get, lease6-get command handler
Definition: lease_cmds.cc:1210
static bool addOrUpdate4(Lease4Ptr lease, bool force_create)
Add or update lease.
Definition: lease_cmds.cc:911
int lease6WipeHandler(CalloutHandle &handle)
lease6-wipe handler
Definition: lease_cmds.cc:2322
int leaseGetByClientIdHandler(hooks::CalloutHandle &handle)
lease4-get-by-client-id command handler
Definition: lease_cmds.cc:1554
int lease6ResendDdnsHandler(CalloutHandle &handle)
lease6-resend-ddns handler
Definition: lease_cmds.cc:2586
int leaseAddHandler(CalloutHandle &handle)
lease4-add, lease6-add command handler
Definition: lease_cmds.cc:985
int lease4ResendDdnsHandler(CalloutHandle &handle)
lease4-resend-ddns handler
Definition: lease_cmds.cc:2538
static void updateStatsOnAdd(const Lease4Ptr &lease)
Update stats when adding lease.
Definition: lease_cmds.cc:478
Parameters getParameters(bool v6, const ConstElementPtr &args)
Extracts parameters required for reservation-get and reservation-del.
Definition: lease_cmds.cc:1092
int lease4UpdateHandler(CalloutHandle &handle)
lease4-update handler
Definition: lease_cmds.cc:2084
int lease4WipeHandler(CalloutHandle &handle)
lease4-wipe handler
Definition: lease_cmds.cc:2208
int leaseGetAllHandler(CalloutHandle &handle)
lease4-get-all, lease6-get-all commands handler
Definition: lease_cmds.cc:1302
int leaseWriteHandler(CalloutHandle &handle)
lease4-write handler, lease6-write handler
Definition: lease_cmds.cc:2657
static void updateStatsOnDelete(const Lease4Ptr &lease)
Update stats when deleting lease.
Definition: lease_cmds.cc:828
int lease4ResendDdnsHandler(hooks::CalloutHandle &handle)
lease4-resend-ddns command handler
Definition: lease_cmds.cc:2776
int lease6WipeHandler(hooks::CalloutHandle &handle)
lease6-wipe handler
Definition: lease_cmds.cc:2770
int leaseGetPageHandler(hooks::CalloutHandle &handle)
lease4-get-page, lease6-get-page commands handler
Definition: lease_cmds.cc:2719
int lease6DelHandler(hooks::CalloutHandle &handle)
lease6-del command handler
Definition: lease_cmds.cc:2749
int leaseGetAllHandler(hooks::CalloutHandle &handle)
lease4-get-all, lease6-get-all commands handler
Definition: lease_cmds.cc:2714
int leaseGetByHostnameHandler(hooks::CalloutHandle &handle)
lease4-get-by-hostname and lease6-get-by-hostname commands handler
Definition: lease_cmds.cc:2739
int lease4DelHandler(hooks::CalloutHandle &handle)
lease4-del command handler
Definition: lease_cmds.cc:2744
int leaseWriteHandler(hooks::CalloutHandle &handle)
lease4-write handler, lease6-write handler
Definition: lease_cmds.cc:2786
int leaseAddHandler(hooks::CalloutHandle &handle)
lease4-add, lease6-add command handler
Definition: lease_cmds.cc:2699
int leaseGetByClientIdHandler(hooks::CalloutHandle &handle)
lease4-get-by-client-id command handler
Definition: lease_cmds.cc:2729
int lease4UpdateHandler(hooks::CalloutHandle &handle)
lease4-update handler
Definition: lease_cmds.cc:2754
int leaseGetHandler(hooks::CalloutHandle &handle)
lease4-get, lease6-get command handler
Definition: lease_cmds.cc:2709
int leaseGetByHwAddressHandler(hooks::CalloutHandle &handle)
lease4-get-by-hw-address command handler
Definition: lease_cmds.cc:2724
int lease6UpdateHandler(hooks::CalloutHandle &handle)
lease6-update handler
Definition: lease_cmds.cc:2759
int leaseGetByDuidHandler(hooks::CalloutHandle &handle)
lease6-get-by-duid command handler
Definition: lease_cmds.cc:2734
int lease6BulkApplyHandler(hooks::CalloutHandle &handle)
lease6-bulk-apply command handler
Definition: lease_cmds.cc:2704
int lease4WipeHandler(hooks::CalloutHandle &handle)
lease4-wipe handler
Definition: lease_cmds.cc:2764
int lease6ResendDdnsHandler(hooks::CalloutHandle &handle)
lease6-resend-ddns command handler
Definition: lease_cmds.cc:2781
RAII class creating a critical section.
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const isc::log::MessageID LEASE_CMDS_DEL4
const isc::log::MessageID LEASE_CMDS_WIPE4_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE6_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE4_FAILED
const isc::log::MessageID LEASE_CMDS_WIPE6_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE6_CONFLICT
const isc::log::MessageID LEASE_CMDS_UPDATE4_CONFLICT
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4_FAILED
const isc::log::MessageID LEASE_CMDS_DEL6
const isc::log::MessageID LEASE_CMDS_ADD4_FAILED
const isc::log::MessageID LEASE_CMDS_ADD6
const isc::log::MessageID LEASE_CMDS_ADD4
const isc::log::MessageID LEASE_CMDS_WIPE6
const isc::log::MessageID LEASE_CMDS_ADD6_CONFLICT
const isc::log::MessageID LEASE_CMDS_BULK_APPLY6_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE6
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4
const isc::log::MessageID LEASE_CMDS_GET6_FAILED
const isc::log::MessageID LEASE_CMDS_WIPE4
const isc::log::MessageID LEASE_CMDS_BULK_APPLY6
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6_FAILED
const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6
const isc::log::MessageID LEASE_CMDS_GET4_FAILED
const isc::log::MessageID LEASE_CMDS_ADD4_CONFLICT
const isc::log::MessageID LEASE_CMDS_DEL4_FAILED
const isc::log::MessageID LEASE_CMDS_ADD6_FAILED
const isc::log::MessageID LEASE_CMDS_UPDATE4
const isc::log::MessageID LEASE_CMDS_DEL6_FAILED
An abstract API for lease database.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
const int CONTROL_RESULT_EMPTY
Status code indicating that the specified command was completed correctly, but failed to produce any ...
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
const int CONTROL_RESULT_CONFLICT
Status code indicating that the command was unsuccessful due to a conflict between the command argume...
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
boost::shared_ptr< const SrvConfig > ConstSrvConfigPtr
Const pointer to the SrvConfig.
Definition: srv_config.h:1235
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
Definition: subnet.h:660
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
Definition: subnet.h:495
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:132
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:505
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:670
boost::multi_index_container< Subnet6Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > Subnet6Collection
A collection of Subnet6 objects.
Definition: subnet.h:974
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
Definition: pool.h:483
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > Subnet4Collection
A collection of Subnet4 objects.
Definition: subnet.h:903
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
Definition: duid.h:212
boost::shared_ptr< const CfgSubnets4 > ConstCfgSubnets4Ptr
Const pointer.
Definition: cfg_subnets4.h:354
boost::shared_ptr< const CfgSubnets6 > ConstCfgSubnets6Ptr
Const pointer.
Definition: cfg_subnets6.h:352
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
Definition: lease.h:497
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition: lease.h:292
const int LEASE_CMDS_DBG_COMMAND_DATA
Logging level used to log successful commands.
isc::log::Logger lease_cmds_logger("lease-cmds-hooks")
Definition: edns.h:19
Defines the logger used by the top-level component of kea-lfc.
Hardware type that represents information from DHCPv4 packet.
Definition: hwaddr.h:20
Structure that holds a lease for IPv6 address and/or prefix.
Definition: lease.h:513
a common structure for IPv4 and IPv6 leases
Definition: lease.h:31
Type
Type of lease or pool.
Definition: lease.h:46