28 if (getBySubnetId(subnet->getID())) {
30 << subnet->getID() <<
"' is already in use");
32 }
else if (getByPrefix(subnet->toText())) {
36 << subnet->toText() <<
"' already exists");
40 .arg(subnet->toText());
41 static_cast<void>(subnets_.insert(subnet));
47 const SubnetID& subnet_id = subnet->getID();
48 auto& index = subnets_.template get<SubnetSubnetIdIndexTag>();
49 auto subnet_it = index.find(subnet_id);
50 if (subnet_it == index.end()) {
54 bool ret = index.replace(subnet_it, subnet);
57 .arg(subnet_id).arg(ret);
73 auto subnet_it = index.find(subnet_id);
74 if (subnet_it == index.end()) {
81 index.erase(subnet_it);
84 .arg(subnet->toText());
96 auto const& other_subnets = other.
getAll();
97 for (
auto const& other_subnet : (*other_subnets)) {
100 auto subnet_id_it = index_id.find(other_subnet->getID());
101 if (subnet_id_it != index_id.end()) {
104 auto existing_subnet = *subnet_id_it;
108 if (existing_subnet == other_subnet) {
120 existing_subnet->getSharedNetwork(network);
122 network->del(existing_subnet->getID());
126 index_id.erase(subnet_id_it);
130 auto subnet_prefix_it = index_prefix.find(other_subnet->toText());
131 if (subnet_prefix_it != index_prefix.end()) {
134 auto existing_subnet = *subnet_prefix_it;
144 existing_subnet->getSharedNetwork(network);
146 network->del(existing_subnet->getID());
150 index_prefix.erase(subnet_prefix_it);
154 other_subnet->getCfgOption()->createOptions(cfg_def);
157 for (
auto const& pool : other_subnet->getPoolsWritable(Lease::TYPE_V4)) {
158 pool->getCfgOption()->createOptions(cfg_def);
162 static_cast<void>(subnets_.insert(other_subnet));
166 std::string network_name = other_subnet->getSharedNetworkName();
167 if (!network_name.empty()) {
170 network->add(other_subnet);
175 << other_subnet->getID()
176 <<
" to shared network: " << network_name
177 <<
", network does not exist");
184 CfgSubnets4::getBySubnetId(
const SubnetID& subnet_id)
const {
186 auto subnet_it = index.find(subnet_id);
187 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet4Ptr());
191 CfgSubnets4::getByPrefix(
const std::string& subnet_text)
const {
193 auto subnet_it = index.find(subnet_text);
194 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet4Ptr());
200 auto subnet_it = index.find(server_id);
201 return (subnet_it != index.cend());
205 CfgSubnets4::initSelector(
const Pkt4Ptr& query) {
207 selector.
ciaddr_ = query->getCiaddr();
208 selector.
giaddr_ = query->getGiaddr();
228 rai_custom->
getOption(RAI_OPTION_LINK_SELECTION);
231 if (link_select_buf.size() ==
sizeof(uint32_t)) {
255 for (
auto const& subnet : subnets_) {
256 Cfg4o6& cfg4o6 = subnet->get4o6();
264 std::pair<asiolink::IOAddress, uint8_t> pref = cfg4o6.
getSubnet4o6();
265 if (!pref.first.isV6Zero()) {
312 for (
auto const& subnet : subnets_) {
316 if (subnet->hasRelays()) {
317 if (!subnet->hasRelayAddress(selector.
giaddr_)) {
324 subnet->getSharedNetwork(network);
325 if (!network || !(network->hasRelayAddress(selector.
giaddr_))) {
334 .arg(subnet->toText())
375 <<
" doesn't exist and therefore it is impossible" 376 " to find a suitable subnet for its IPv4 address");
390 iface->getAddress4(address);
408 CfgSubnets4::selectSubnet(
const std::string& iface,
410 for (
auto const& subnet : subnets_) {
416 subnet_selected = subnet;
424 subnet->getSharedNetwork(network);
427 subnet_selected = subnet;
431 if (subnet_selected) {
433 if (subnet_selected->clientSupported(client_classes)) {
436 .arg(subnet->toText())
438 return (subnet_selected);
455 for (
auto const& subnet : subnets_) {
456 if (subnet->getID() == id) {
466 for (
auto const& subnet : subnets_) {
469 if (!subnet->inRange(address)) {
474 if (subnet->clientSupported(client_classes)) {
476 .arg(subnet->toText())
491 CfgSubnets4::removeStatistics() {
495 StatsMgr& stats_mgr = StatsMgr::instance();
496 for (
auto const& subnet4 : subnets_) {
497 SubnetID subnet_id = subnet4->getID();
498 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
501 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
502 "assigned-addresses"));
504 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
505 "cumulative-assigned-addresses"));
507 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
508 "declined-addresses"));
510 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
511 "reclaimed-declined-addresses"));
513 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
514 "reclaimed-leases"));
519 CfgSubnets4::updateStatistics() {
522 StatsMgr& stats_mgr = StatsMgr::instance();
523 for (
auto const& subnet4 : subnets_) {
524 SubnetID subnet_id = subnet4->getID();
527 generateName(
"subnet", subnet_id,
"total-addresses"),
529 (subnet4->getPoolCapacity(Lease::TYPE_V4)));
530 const std::string& name =
531 StatsMgr::generateName(
"subnet", subnet_id,
"cumulative-assigned-addresses");
533 stats_mgr.
setValue(name, static_cast<int64_t>(0));
538 if (subnets_.begin() != subnets_.end()) {
539 LeaseMgrFactory::instance().recountLeaseStats4();
544 CfgSubnets4::toElement()
const {
547 for (
auto const& subnet : subnets_) {
548 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.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_ADDRESS_FAILED
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.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_RELAY_ADDRESS_FAILED
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.
Subnet selector used to specify parameters used to select a subnet.
#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_FAILED_NO_RELAY_ADDRESS
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_FAILED_NO_RAI_OPTIONS_ADDRESS
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.
OptionPtr getOption(uint16_t type) const
Returns shared_ptr to suboption of specific type.
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.
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
Defines the logger used by the top-level component of kea-lfc.
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.
const isc::log::MessageID DHCPSRV_SUBNET4_SELECT_FAILED_NO_ADDRESS
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 isc::log::MessageID DHCPSRV_SUBNET4_SELECT_BY_INTERFACE_FAILED
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.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET4_ADDR