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 (
auto const& 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");
185 CfgSubnets4::getBySubnetId(
const SubnetID& subnet_id)
const {
187 auto subnet_it = index.find(subnet_id);
188 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet4Ptr());
192 CfgSubnets4::getByPrefix(
const std::string& subnet_text)
const {
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());
206 CfgSubnets4::initSelector(
const Pkt4Ptr& query) {
208 selector.
ciaddr_ = query->getCiaddr();
209 selector.
giaddr_ = query->getGiaddr();
231 bool ignore_link_sel = CfgMgr::instance().getCurrentCfg()->
232 getIgnoreRAILinkSelection();
233 if (!ignore_link_sel) {
238 if (link_select_buf.size() ==
sizeof(uint32_t)) {
263 for (
auto const& subnet : subnets_) {
264 Cfg4o6& cfg4o6 = subnet->get4o6();
272 std::pair<asiolink::IOAddress, uint8_t> pref = cfg4o6.
getSubnet4o6();
273 if (!pref.first.isV6Zero()) {
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_))) {
342 .arg(subnet->toText())
383 <<
" doesn't exist and therefore it is impossible" 384 " to find a suitable subnet for its IPv4 address");
398 iface->getAddress4(address);
416 CfgSubnets4::selectSubnet(
const std::string& iface,
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);
463 for (
auto const& subnet : subnets_) {
464 if (subnet->getID() == id) {
474 for (
auto const& subnet : subnets_) {
477 if (!subnet->inRange(address)) {
482 if (subnet->clientSupported(client_classes)) {
484 .arg(subnet->toText())
499 CfgSubnets4::getLinks(
const IOAddress& link_addr, uint8_t& link_len)
const {
501 bool link_len_set =
false;
502 for (
auto const& subnet : subnets_) {
503 if (!subnet->inRange(link_addr)) {
506 uint8_t plen = subnet->get().second;
507 if (!link_len_set || (plen < link_len)) {
511 links.insert(subnet->getID());
517 CfgSubnets4::removeStatistics() {
521 StatsMgr& stats_mgr = StatsMgr::instance();
522 for (
auto const& subnet4 : subnets_) {
523 SubnetID subnet_id = subnet4->getID();
524 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
527 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
528 "assigned-addresses"));
530 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
531 "cumulative-assigned-addresses"));
533 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
534 "declined-addresses"));
536 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
537 "reclaimed-declined-addresses"));
539 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
540 "reclaimed-leases"));
545 CfgSubnets4::updateStatistics() {
548 StatsMgr& stats_mgr = StatsMgr::instance();
549 for (
auto const& subnet4 : subnets_) {
550 SubnetID subnet_id = subnet4->getID();
553 generateName(
"subnet", subnet_id,
"total-addresses"),
555 (subnet4->getPoolCapacity(Lease::TYPE_V4)));
557 StatsMgr::generateName(
"subnet", subnet_id,
"cumulative-assigned-addresses");
559 stats_mgr.
setValue(name, static_cast<int64_t>(0));
562 name = StatsMgr::generateName(
"subnet", subnet_id,
"v4-reservation-conflicts");
564 stats_mgr.
setValue(name, static_cast<int64_t>(0));
569 if (subnets_.begin() != subnets_.end()) {
570 LeaseMgrFactory::instance().recountLeaseStats4();
575 CfgSubnets4::initAllocatorsAfterConfigure() {
576 for (
auto subnet : subnets_) {
577 subnet->initAllocatorsAfterConfigure();
582 CfgSubnets4::toElement()
const {
585 for (
auto const& subnet : subnets_) {
586 result->add(subnet->toElement());
Exception thrown upon attempt to add subnet with an ID that belongs to the subnet that already exists...
asiolink::IOAddress ciaddr_
ciaddr from the client's message.
asiolink::IOAddress remote_address_
Source address of the message.
ObservationPtr getObservation(const std::string &name) const
Returns an observation.
util::Optional< std::string > getIface4o6() const
Returns the DHCP4o6 interface.
bool enabled() const
Returns whether the DHCP4o6 is enabled or not.
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
Tag for the index for searching by subnet identifier.
const isc::log::MessageID DHCPSRV_CFGMGR_ADD_SUBNET4
const isc::log::MessageID DHCPSRV_SUBNET4O6_SELECT_FAILED
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
asiolink::IOAddress option_select_
RAI link select or subnet select option.
OptionPtr interface_id_
Interface id option.
boost::shared_ptr< Option > OptionPtr
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
const isc::log::MessageID DHCPSRV_CFGMGR_UPDATE_SUBNET4
boost::shared_ptr< Element > ElementPtr
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET4_RELAY
asiolink::IOAddress giaddr_
giaddr from the client's message.
Tag for the index for searching by subnet prefix.
OptionPtr getInterfaceId() const
Returns the interface-id.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
util::Optional< std::pair< asiolink::IOAddress, uint8_t > > getSubnet4o6() const
Returns prefix/len for the IPv6 subnet.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Statistics Manager class.
ClientClasses client_classes_
Classes that the client belongs to.
IOAddress firstAddrInPrefix(const IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
std::set< dhcp::SubnetID > SubnetIDSet
Ordered list aka set of subnetIDs.
Subnet selector used to specify parameters used to select a subnet.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_NO_RELAY_ADDRESS
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Tag for the index for searching by server identifier.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
boost::shared_ptr< CfgSharedNetworks4 > CfgSharedNetworks4Ptr
Pointer to the configuration of IPv4 shared networks.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_ADDRESS_NO_MATCH
This structure contains information about DHCP4o6 (RFC7341)
bool isV4Bcast() const
Convenience function to check if it is an IPv4 broadcast address.
bool del(const std::string &name)
Removes specified statistic.
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
asiolink::IOAddress local_address_
Address on which the message was received.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
const isc::log::MessageID DHCPSRV_CFGMGR_DEL_SUBNET4
Holds subnets configured for the DHCPv4 server.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_RELAY_ADDRESS_NO_MATCH
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
Defines the logger used by the top-level component of kea-lfc.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_INTERFACE_NO_MATCH
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
std::string toText() const
Convert the address to a string.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET4_IFACE
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
A generic exception that is thrown if a function is called in a prohibited way.
IOAddress lastAddrInPrefix(const IOAddress &prefix, uint8_t len)
returns a last address in a given prefix
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
std::string iface_name_
Name of the interface on which the message was received.
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
The IOAddress class represents an IP addresses (version agnostic)
Option with defined data fields represented as buffers that can be accessed using data field index...
bool empty() const
Checks if the encapsulated value is empty.
const Subnet4Collection * getAll() const
Returns pointer to the collection of all IPv4 subnets.
Container for storing client class names.
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_NO_USABLE_ADDRESS
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET4_ADDR
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_NO_RAI_OPTIONS