29 if (getBySubnetId(subnet->getID())) {
31 << subnet->getID() <<
"' is already in use");
33 }
else if (getByPrefix(subnet->toText())) {
37 << subnet->toText() <<
"' already exists");
41 .arg(subnet->toText());
42 static_cast<void>(subnets_.insert(subnet));
48 const SubnetID& subnet_id = subnet->getID();
49 auto& index = subnets_.template get<SubnetSubnetIdIndexTag>();
50 auto subnet_it = index.find(subnet_id);
51 if (subnet_it == index.end()) {
55 bool ret = index.replace(subnet_it, subnet);
58 .arg(subnet_id).arg(ret);
74 auto subnet_it = index.find(subnet_id);
75 if (subnet_it == index.end()) {
82 index.erase(subnet_it);
85 .arg(subnet->toText());
97 auto const& other_subnets = other.
getAll();
98 for (
auto const& other_subnet : (*other_subnets)) {
101 auto subnet_id_it = index_id.find(other_subnet->getID());
102 if (subnet_id_it != index_id.end()) {
105 auto existing_subnet = *subnet_id_it;
109 if (existing_subnet == other_subnet) {
121 existing_subnet->getSharedNetwork(network);
123 network->del(existing_subnet->getID());
127 index_id.erase(subnet_id_it);
131 auto subnet_prefix_it = index_prefix.find(other_subnet->toText());
132 if (subnet_prefix_it != index_prefix.end()) {
135 auto existing_subnet = *subnet_prefix_it;
145 existing_subnet->getSharedNetwork(network);
147 network->del(existing_subnet->getID());
151 index_prefix.erase(subnet_prefix_it);
155 other_subnet->getCfgOption()->createOptions(cfg_def);
158 for (
const auto& pool : other_subnet->getPoolsWritable(Lease::TYPE_V4)) {
159 pool->getCfgOption()->createOptions(cfg_def);
163 static_cast<void>(subnets_.insert(other_subnet));
167 std::string network_name = other_subnet->getSharedNetworkName();
168 if (!network_name.empty()) {
171 network->add(other_subnet);
176 << other_subnet->getID()
177 <<
" to shared network: " << network_name
178 <<
", network does not exist");
182 other_subnet->createAllocators();
187 CfgSubnets4::getBySubnetId(
const SubnetID& subnet_id)
const {
189 auto subnet_it = index.find(subnet_id);
190 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet4Ptr());
194 CfgSubnets4::getByPrefix(
const std::string& subnet_text)
const {
196 auto subnet_it = index.find(subnet_text);
197 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet4Ptr());
203 auto subnet_it = index.find(server_id);
204 return (subnet_it != index.cend());
208 CfgSubnets4::initSelector(
const Pkt4Ptr& query) {
210 selector.
ciaddr_ = query->getCiaddr();
211 selector.
giaddr_ = query->getGiaddr();
228 boost::dynamic_pointer_cast<OptionCustom>(rai);
233 bool ignore_link_sel = CfgMgr::instance().getCurrentCfg()->
234 getIgnoreRAILinkSelection();
235 if (!ignore_link_sel) {
240 if (link_select_buf.size() ==
sizeof(uint32_t)) {
255 boost::dynamic_pointer_cast<OptionCustom>(sbnsel);
265 for (
auto const& subnet : subnets_) {
266 Cfg4o6& cfg4o6 = subnet->get4o6();
274 std::pair<asiolink::IOAddress, uint8_t> pref = cfg4o6.
getSubnet4o6();
275 if (!pref.first.isV6Zero()) {
322 for (
auto const& subnet : subnets_) {
326 if (subnet->hasRelays()) {
327 if (!subnet->hasRelayAddress(selector.
giaddr_)) {
334 subnet->getSharedNetwork(network);
335 if (!network || !(network->hasRelayAddress(selector.
giaddr_))) {
344 .arg(subnet->toText())
385 <<
" doesn't exist and therefore it is impossible"
386 " to find a suitable subnet for its IPv4 address");
400 iface->getAddress4(address);
418 CfgSubnets4::selectSubnet(
const std::string& iface,
420 for (
auto const& subnet : subnets_) {
426 subnet_selected = subnet;
434 subnet->getSharedNetwork(network);
437 subnet_selected = subnet;
441 if (subnet_selected) {
443 if (subnet_selected->clientSupported(client_classes)) {
446 .arg(subnet->toText())
448 return (subnet_selected);
465 for (
auto const& subnet : subnets_) {
466 if (subnet->getID() ==
id) {
476 for (
auto const& subnet : subnets_) {
479 if (!subnet->inRange(address)) {
484 if (subnet->clientSupported(client_classes)) {
486 .arg(subnet->toText())
501 CfgSubnets4::getLinks(
const IOAddress& link_addr, uint8_t& link_len)
const {
503 bool link_len_set =
false;
504 for (
auto const& subnet : subnets_) {
505 if (!subnet->inRange(link_addr)) {
508 uint8_t plen = subnet->get().second;
509 if (!link_len_set || (plen < link_len)) {
513 links.insert(subnet->getID());
519 CfgSubnets4::removeStatistics() {
523 StatsMgr& stats_mgr = StatsMgr::instance();
524 for (
auto const& subnet4 : subnets_) {
525 SubnetID subnet_id = subnet4->getID();
526 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
529 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
530 "assigned-addresses"));
532 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
533 "cumulative-assigned-addresses"));
535 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
536 "declined-addresses"));
538 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
539 "reclaimed-declined-addresses"));
541 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
542 "reclaimed-leases"));
544 for (
const auto& pool : subnet4->getPools(Lease::TYPE_V4)) {
545 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
546 StatsMgr::generateName(
"pool", pool->getID(),
547 "total-addresses")));
549 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
550 StatsMgr::generateName(
"pool", pool->getID(),
551 "assigned-addresses")));
553 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
554 StatsMgr::generateName(
"pool", pool->getID(),
555 "cumulative-assigned-addresses")));
557 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
558 StatsMgr::generateName(
"pool", pool->getID(),
559 "declined-addresses")));
561 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
562 StatsMgr::generateName(
"pool", pool->getID(),
563 "reclaimed-declined-addresses")));
565 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
566 StatsMgr::generateName(
"pool", pool->getID(),
567 "reclaimed-leases")));
573 CfgSubnets4::updateStatistics() {
576 StatsMgr& stats_mgr = StatsMgr::instance();
577 for (
auto const& subnet4 : subnets_) {
578 SubnetID subnet_id = subnet4->getID();
581 generateName(
"subnet", subnet_id,
"total-addresses"),
582 int64_t(subnet4->getPoolCapacity(Lease::TYPE_V4)));
583 const std::string& name(StatsMgr::generateName(
"subnet", subnet_id,
584 "cumulative-assigned-addresses"));
586 stats_mgr.
setValue(name,
static_cast<int64_t
>(0));
589 const std::string& name_reuses(StatsMgr::generateName(
"subnet", subnet_id,
592 stats_mgr.
setValue(name_reuses, int64_t(0));
595 const std::string& name_conflicts(StatsMgr::generateName(
"subnet", subnet_id,
596 "v4-reservation-conflicts"));
598 stats_mgr.
setValue(name_conflicts,
static_cast<int64_t
>(0));
601 for (
const auto& pool : subnet4->getPools(Lease::TYPE_V4)) {
602 const std::string& name_total(StatsMgr::generateName(
"subnet", subnet_id,
603 StatsMgr::generateName(
"pool", pool->getID(),
604 "total-addresses")));
606 stats_mgr.
setValue(name_total,
static_cast<int64_t
>(pool->getCapacity()));
608 stats_mgr.
addValue(name_total,
static_cast<int64_t
>(pool->getCapacity()));
611 const std::string& name_ca(StatsMgr::generateName(
"subnet", subnet_id,
612 StatsMgr::generateName(
"pool", pool->getID(),
613 "cumulative-assigned-addresses")));
615 stats_mgr.
setValue(name_ca,
static_cast<int64_t
>(0));
621 if (subnets_.begin() != subnets_.end()) {
622 LeaseMgrFactory::instance().recountLeaseStats4();
627 CfgSubnets4::initAllocatorsAfterConfigure() {
628 for (
auto subnet : subnets_) {
629 subnet->initAllocatorsAfterConfigure();
634 CfgSubnets4::clear() {
639 CfgSubnets4::toElement()
const {
642 for (
auto const& subnet : subnets_) {
643 result->add(subnet->toElement());
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
The IOAddress class represents an IP addresses (version agnostic)
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
std::string toText() const
Convert the address to a string.
bool isV4Bcast() const
Convenience function to check if it is an IPv4 broadcast address.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
Holds subnets configured for the DHCPv4 server.
const Subnet4Collection * getAll() const
Returns pointer to the collection of all IPv4 subnets.
Container for storing client class names.
Exception thrown upon attempt to add subnet with an ID that belongs to the subnet that already exists...
Statistics Manager class.
ObservationPtr getObservation(const std::string &name) const
Returns an observation.
bool empty() const
Checks if the encapsulated value is empty.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
bool del(const std::string &name)
Removes specified statistic.
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
IOAddress firstAddrInPrefix(const IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
IOAddress lastAddrInPrefix(const IOAddress &prefix, uint8_t len)
returns a last address in a given prefix
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
boost::shared_ptr< Element > ElementPtr
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_INTERFACE_NO_MATCH
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_ADDRESS_NO_MATCH
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET4_IFACE
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
std::set< dhcp::SubnetID > SubnetIDSet
Ordered list aka set of subnetIDs.
const isc::log::MessageID DHCPSRV_CFGMGR_UPDATE_SUBNET4
const isc::log::MessageID DHCPSRV_CFGMGR_ADD_SUBNET4
const isc::log::MessageID DHCPSRV_SUBNET4O6_SELECT_FAILED
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_NO_RELAY_ADDRESS
const isc::log::MessageID DHCPSRV_CFGMGR_DEL_SUBNET4
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_NO_USABLE_ADDRESS
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET4_ADDR
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_NO_RAI_OPTIONS
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET4_RELAY
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_RELAY_ADDRESS_NO_MATCH
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
boost::shared_ptr< CfgSharedNetworks4 > CfgSharedNetworks4Ptr
Pointer to the configuration of IPv4 shared networks.
@ RAI_OPTION_LINK_SELECTION
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
boost::shared_ptr< Option > OptionPtr
Defines the logger used by the top-level component of kea-lfc.
This structure contains information about DHCP4o6 (RFC7341)
util::Optional< std::string > getIface4o6() const
Returns the DHCP4o6 interface.
util::Optional< std::pair< asiolink::IOAddress, uint8_t > > getSubnet4o6() const
Returns prefix/len for the IPv6 subnet.
bool enabled() const
Returns whether the DHCP4o6 is enabled or not.
OptionPtr getInterfaceId() const
Returns the interface-id.
Tag for the index for searching by subnet prefix.
Subnet selector used to specify parameters used to select a subnet.
asiolink::IOAddress local_address_
Address on which the message was received.
asiolink::IOAddress option_select_
RAI link select or subnet select option.
std::string iface_name_
Name of the interface on which the message was received.
asiolink::IOAddress ciaddr_
ciaddr from the client's message.
ClientClasses client_classes_
Classes that the client belongs to.
asiolink::IOAddress remote_address_
Source address of the message.
OptionPtr interface_id_
Interface id option.
asiolink::IOAddress giaddr_
giaddr from the client's message.
Tag for the index for searching by server identifier.
Tag for the index for searching by subnet identifier.