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 subnets_.push_back(subnet);
47 auto subnet_it = index.find(subnet->getID());
48 if (subnet_it == index.end()) {
52 index.erase(subnet_it);
55 .arg(subnet->toText());
59 CfgSubnets4::getBySubnetId(
const SubnetID& subnet_id)
const {
61 auto subnet_it = index.find(subnet_id);
62 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet4Ptr());
66 CfgSubnets4::getByPrefix(
const std::string& subnet_text)
const {
68 auto subnet_it = index.find(subnet_text);
69 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet4Ptr());
75 auto subnet_it = index.find(server_id);
76 return (subnet_it != index.cend());
80 CfgSubnets4::initSelector(
const Pkt4Ptr& query) {
82 selector.
ciaddr_ = query->getCiaddr();
83 selector.
giaddr_ = query->getGiaddr();
100 boost::dynamic_pointer_cast<OptionCustom>(rai);
103 rai_custom->getOption(RAI_OPTION_LINK_SELECTION);
106 if (link_select_buf.size() ==
sizeof(uint32_t)) {
117 boost::dynamic_pointer_cast<OptionCustom>(sbnsel);
130 for (Subnet4Collection::const_iterator subnet = subnets_.begin();
131 subnet != subnets_.end(); ++subnet) {
132 Cfg4o6& cfg4o6 = (*subnet)->get4o6();
140 std::pair<asiolink::IOAddress, uint8_t> pref = cfg4o6.
getSubnet4o6();
141 if (!pref.first.isV6Zero()) {
184 for (Subnet4Collection::const_iterator subnet = subnets_.begin();
185 subnet != subnets_.end(); ++subnet) {
189 if ((*subnet)->hasRelays()) {
190 if (!(*subnet)->hasRelayAddress(selector.
giaddr_)) {
197 (*subnet)->getSharedNetwork(network);
198 if (!network || !(network->hasRelayAddress(selector.
giaddr_))) {
238 <<
" doesn't exist and therefore it is impossible" 239 " to find a suitable subnet for its IPv4 address");
253 iface->getAddress4(address);
268 CfgSubnets4::selectSubnet(
const std::string& iface,
270 for (Subnet4Collection::const_iterator subnet = subnets_.begin();
271 subnet != subnets_.end(); ++subnet) {
276 if (!(*subnet)->getIface().empty()) {
277 if ((*subnet)->getIface() == iface) {
278 subnet_selected = (*subnet);
286 (*subnet)->getSharedNetwork(network);
287 if (network && !network->getIface().empty() &&
288 (network->getIface() == iface)) {
289 subnet_selected = (*subnet);
293 if (subnet_selected) {
296 if (subnet_selected->clientSupported(client_classes)) {
298 DHCPSRV_CFGMGR_SUBNET4_IFACE)
299 .arg((*subnet)->toText())
301 return (subnet_selected);
315 for (
auto subnet = subnets_.begin(); subnet != subnets_.end(); ++subnet) {
316 if ((*subnet)->getID() == id) {
326 for (Subnet4Collection::const_iterator subnet = subnets_.begin();
327 subnet != subnets_.end(); ++subnet) {
330 if (!(*subnet)->inRange(address)) {
335 if ((*subnet)->clientSupported(client_classes)) {
337 .arg((*subnet)->toText())
348 CfgSubnets4::removeStatistics() {
352 StatsMgr& stats_mgr = StatsMgr::instance();
353 for (Subnet4Collection::const_iterator subnet4 = subnets_.begin();
354 subnet4 != subnets_.end(); ++subnet4) {
355 SubnetID subnet_id = (*subnet4)->getID();
356 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
359 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
360 "assigned-addresses"));
362 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
363 "declined-addresses"));
365 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
366 "declined-reclaimed-addresses"));
368 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
369 "reclaimed-leases"));
374 CfgSubnets4::updateStatistics() {
377 StatsMgr& stats_mgr = StatsMgr::instance();
378 for (Subnet4Collection::const_iterator subnet4 = subnets_.begin();
379 subnet4 != subnets_.end(); ++subnet4) {
380 SubnetID subnet_id = (*subnet4)->getID();
383 generateName(
"subnet", subnet_id,
"total-addresses"),
385 ((*subnet4)->getPoolCapacity(
Lease::
390 if (subnets_.begin() != subnets_.end()) {
391 LeaseMgrFactory::instance().recountLeaseStats4();
396 CfgSubnets4::toElement()
const {
399 for (Subnet4Collection::const_iterator subnet = subnets_.cbegin();
400 subnet != subnets_.cend(); ++subnet) {
401 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.
std::string getIface4o6() const
Returns the DHCP4o6 interface.
asiolink::IOAddress remote_address_
Source address of the message.
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.
boost::shared_ptr< Iface > IfacePtr
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.
boost::shared_ptr< Element > ElementPtr
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.
isc::asiolink::IOAddress firstAddrInPrefix(const isc::asiolink::IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
isc::asiolink::IOAddress lastAddrInPrefix(const isc::asiolink::IOAddress &prefix, uint8_t len)
returns a last address in a given prefix
Statistics Manager class.
ClientClasses client_classes_
Classes that the client belongs to.
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...
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
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.
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
Defines the logger used by the top-level component of kea-dhcp-ddns.
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
std::string toText() const
Convert the address to a string.
a common structure for IPv4 and IPv6 leases
#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)
std::pair< asiolink::IOAddress, uint8_t > getSubnet4o6() const
Returns prefix/len for the IPv6 subnet.
Container for storing client class names.
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)