31 << subnet->getID() <<
"' is already in use");
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);
159 other_subnet->getCfgOption()->encapsulate();
162 for (
auto const& pool : other_subnet->getPoolsWritable(
Lease::TYPE_V4)) {
163 pool->getCfgOption()->createOptions(cfg_def);
164 pool->getCfgOption()->encapsulate();
168 static_cast<void>(subnets_.insert(other_subnet));
172 std::string network_name = other_subnet->getSharedNetworkName();
173 if (!network_name.empty()) {
176 network->add(other_subnet);
181 << other_subnet->getID()
182 <<
" to shared network: " << network_name
183 <<
", network does not exist");
187 other_subnet->createAllocators();
194 auto subnet_it = index.find(subnet_text);
195 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet4Ptr());
201 auto subnet_it = index.find(server_id);
202 return (subnet_it != index.cend());
208 selector.
ciaddr_ = query->getCiaddr();
209 selector.giaddr_ = query->getGiaddr();
210 selector.local_address_ = query->getLocalAddr();
211 selector.remote_address_ = query->getRemoteAddr();
212 selector.client_classes_ = query->classes_;
213 selector.iface_name_ = query->getIface();
226 boost::dynamic_pointer_cast<OptionCustom>(rai);
232 getIgnoreRAILinkSelection();
233 if (!ignore_link_sel) {
238 if (link_select_buf.size() ==
sizeof(uint32_t)) {
239 selector.option_select_ =
253 boost::dynamic_pointer_cast<OptionCustom>(sbnsel);
255 selector.option_select_ = oc->readAddress();
263 for (
auto const& subnet : subnets_) {
264 Cfg4o6& cfg4o6 = subnet->get4o6();
267 if (!cfg4o6.enabled()) {
272 std::pair<asiolink::IOAddress, uint8_t> pref = cfg4o6.
getSubnet4o6();
273 if (!pref.first.isV6Zero()) {
278 if ((first <= selector.remote_address_) &&
279 (selector.remote_address_ <= last)) {
285 if (cfg4o6.getInterfaceId() && selector.interface_id_ &&
286 cfg4o6.getInterfaceId()->equals(selector.interface_id_)) {
291 if (!cfg4o6.getIface4o6().empty() && !selector.iface_name_.empty()
292 && cfg4o6.getIface4o6() == selector.iface_name_) {
306 if (!selector.option_select_.isV4Zero()) {
308 selector.client_classes_));
319 if (!selector.giaddr_.isV4Zero()) {
320 for (
auto const& subnet : subnets_) {
324 if (subnet->hasRelays()) {
325 if (!subnet->hasRelayAddress(selector.giaddr_)) {
332 subnet->getSharedNetwork(network);
333 if (!network || !(network->hasRelayAddress(selector.giaddr_))) {
339 if (subnet->clientSupported(selector.client_classes_)) {
342 .arg(subnet->toText())
343 .arg(selector.giaddr_.toText());
349 .arg(selector.giaddr_.toText());
362 if (!selector.giaddr_.isV4Zero()) {
363 address = selector.giaddr_;
366 }
else if (!selector.ciaddr_.isV4Zero() &&
367 !selector.local_address_.isV4Bcast()) {
368 address = selector.ciaddr_;
371 }
else if (!selector.remote_address_.isV4Zero() &&
372 !selector.local_address_.isV4Bcast()) {
373 address = selector.remote_address_;
377 }
else if (!selector.iface_name_.empty()) {
383 <<
" doesn't exist and therefore it is impossible"
384 " to find a suitable subnet for its IPv4 address");
389 selector.client_classes_);
398 iface->getAddress4(address);
403 if (address.isV4Zero()) {
412 return (
selectSubnet(address, selector.client_classes_));
418 for (
auto const& subnet : subnets_) {
424 subnet_selected = subnet;
432 subnet->getSharedNetwork(network);
435 subnet_selected = subnet;
439 if (subnet_selected) {
441 if (subnet_selected->clientSupported(client_classes)) {
444 .arg(subnet->toText())
446 return (subnet_selected);
462 auto subnet_it = index.find(subnet_id);
463 return ((subnet_it != index.cend()) ? (*subnet_it) :
Subnet4Ptr());
469 for (
auto const& subnet : subnets_) {
472 if (!subnet->inRange(address)) {
477 if (subnet->clientSupported(client_classes)) {
479 .arg(subnet->toText())
480 .arg(address.toText());
487 .arg(address.toText());
496 for (
auto const& subnet : subnets_) {
497 if (!subnet->inRange(link_addr)) {
500 links.insert(subnet->getID());
510 StatsMgr& stats_mgr = StatsMgr::instance();
511 for (
auto const& subnet4 : subnets_) {
512 SubnetID subnet_id = subnet4->getID();
513 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
516 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
517 "assigned-addresses"));
519 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
520 "cumulative-assigned-addresses"));
522 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
523 "declined-addresses"));
525 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
526 "reclaimed-declined-addresses"));
528 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
529 "reclaimed-leases"));
532 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
533 StatsMgr::generateName(
"pool", pool->getID(),
534 "total-addresses")));
536 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
537 StatsMgr::generateName(
"pool", pool->getID(),
538 "assigned-addresses")));
540 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
541 StatsMgr::generateName(
"pool", pool->getID(),
542 "cumulative-assigned-addresses")));
544 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
545 StatsMgr::generateName(
"pool", pool->getID(),
546 "declined-addresses")));
548 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
549 StatsMgr::generateName(
"pool", pool->getID(),
550 "reclaimed-declined-addresses")));
552 stats_mgr.del(StatsMgr::generateName(
"subnet", subnet_id,
553 StatsMgr::generateName(
"pool", pool->getID(),
554 "reclaimed-leases")));
563 StatsMgr& stats_mgr = StatsMgr::instance();
564 for (
auto const& subnet4 : subnets_) {
565 SubnetID subnet_id = subnet4->getID();
568 generateName(
"subnet", subnet_id,
"total-addresses"),
570 const std::string& name(StatsMgr::generateName(
"subnet", subnet_id,
571 "cumulative-assigned-addresses"));
572 if (!stats_mgr.getObservation(name)) {
573 stats_mgr.setValue(name,
static_cast<int64_t
>(0));
576 const std::string& name_reuses(StatsMgr::generateName(
"subnet", subnet_id,
578 if (!stats_mgr.getObservation(name_reuses)) {
579 stats_mgr.setValue(name_reuses, int64_t(0));
582 const std::string& name_conflicts(StatsMgr::generateName(
"subnet", subnet_id,
583 "v4-reservation-conflicts"));
584 if (!stats_mgr.getObservation(name_conflicts)) {
585 stats_mgr.setValue(name_conflicts,
static_cast<int64_t
>(0));
589 const std::string& name_total(StatsMgr::generateName(
"subnet", subnet_id,
590 StatsMgr::generateName(
"pool", pool->getID(),
591 "total-addresses")));
592 if (!stats_mgr.getObservation(name_total)) {
593 stats_mgr.setValue(name_total,
static_cast<int64_t
>(pool->getCapacity()));
595 stats_mgr.addValue(name_total,
static_cast<int64_t
>(pool->getCapacity()));
598 const std::string& name_ca(StatsMgr::generateName(
"subnet", subnet_id,
599 StatsMgr::generateName(
"pool", pool->getID(),
600 "cumulative-assigned-addresses")));
601 if (!stats_mgr.getObservation(name_ca)) {
602 stats_mgr.setValue(name_ca,
static_cast<int64_t
>(0));
608 if (subnets_.begin() != subnets_.end()) {
615 for (
auto const& subnet : subnets_) {
616 subnet->initAllocatorsAfterConfigure();
629 for (
auto const& subnet : subnets_) {
630 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)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Holds subnets configured for the DHCPv4 server.
ConstSubnet4Ptr getBySubnetId(const SubnetID &subnet_id) const
Returns const pointer to a subnet identified by the specified subnet identifier.
SubnetIDSet getLinks(const asiolink::IOAddress &link_addr) const
Convert a link address into a link set.
ConstSubnet4Ptr selectSubnet(const SubnetSelector &selector) const
Returns a pointer to the selected subnet.
void del(const ConstSubnet4Ptr &subnet)
Removes subnet from the configuration.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
void clear()
Clears all subnets from the configuration.
bool hasSubnetWithServerId(const asiolink::IOAddress &server_id) const
Checks if specified server identifier has been specified for any subnet.
ConstSubnet4Ptr getByPrefix(const std::string &subnet_prefix) const
Returns const pointer to a subnet which matches the specified prefix in the canonical form.
void updateStatistics()
Updates statistics.
void merge(CfgOptionDefPtr cfg_def, CfgSharedNetworks4Ptr networks, CfgSubnets4 &other)
Merges specified subnet configuration into this configuration.
ConstSubnet4Ptr selectSubnet4o6(const SubnetSelector &selector) const
Attempts to do subnet selection based on DHCP4o6 information.
Subnet4Ptr getSubnet(const SubnetID id) const
Returns subnet with specified subnet-id value.
Subnet4Ptr replace(const Subnet4Ptr &subnet)
Replaces subnet in the configuration.
void initAllocatorsAfterConfigure()
Calls initAllocatorsAfterConfigure for each subnet.
void add(const Subnet4Ptr &subnet)
Adds new subnet to the configuration.
void removeStatistics()
Removes statistics.
static SubnetSelector initSelector(const Pkt4Ptr &query)
Build selector from a client's message.
Container for storing client class names.
Exception thrown upon attempt to add subnet with an ID that belongs to the subnet that already exists...
static IfaceMgr & instance()
IfaceMgr is a singleton class.
static TrackingLeaseMgr & instance()
Return current lease manager.
Statistics Manager class.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#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
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::pair< asiolink::IOAddress, uint8_t > > getSubnet4o6() const
Returns prefix/len for the IPv6 subnet.
Tag for the index for searching by subnet prefix.
Subnet selector used to specify parameters used to select a subnet.
asiolink::IOAddress ciaddr_
ciaddr from the client's message.
Tag for the index for searching by server identifier.
Tag for the index for searching by subnet identifier.