16 #include <boost/foreach.hpp>
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 other_subnets = other.
getAll();
97 for (
auto other_subnet = other_subnets->begin();
98 other_subnet != other_subnets->end();
102 auto subnet_it = index_id.find((*other_subnet)->getID());
103 if (subnet_it != index_id.end()) {
106 auto existing_subnet = *subnet_it;
110 if (existing_subnet == *other_subnet) {
118 existing_subnet->getSharedNetwork(network);
120 network->del(existing_subnet->getID());
124 index_id.erase(subnet_it);
128 auto subnet_prefix_it = index_prefix.find((*other_subnet)->toText());
129 if (subnet_prefix_it != index_prefix.end()) {
132 auto existing_subnet = *subnet_prefix_it;
142 existing_subnet->getSharedNetwork(network);
144 network->del(existing_subnet->getID());
148 index_prefix.erase(subnet_prefix_it);
152 (*other_subnet)->getCfgOption()->createOptions(cfg_def);
155 for (
auto pool : (*other_subnet)->getPoolsWritable(Lease::TYPE_NA)) {
156 pool->getCfgOption()->createOptions(cfg_def);
159 for (
auto pool : (*other_subnet)->getPoolsWritable(Lease::TYPE_PD)) {
160 pool->getCfgOption()->createOptions(cfg_def);
164 static_cast<void>(subnets_.insert(*other_subnet));
168 std::string network_name = (*other_subnet)->getSharedNetworkName();
169 if (!network_name.empty()) {
172 network->add(*other_subnet);
177 << (*other_subnet)->getID()
178 <<
" to shared network: " << network_name
179 <<
", network does not exist");
186 CfgSubnets6::getBySubnetId(
const SubnetID& subnet_id)
const {
188 auto subnet_it = index.find(subnet_id);
189 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet6Ptr());
193 CfgSubnets6::getByPrefix(
const std::string& subnet_text)
const {
195 auto subnet_it = index.find(subnet_text);
196 return ((subnet_it != index.cend()) ? (*subnet_it) :
ConstSubnet6Ptr());
200 CfgSubnets6::initSelector(
const Pkt6Ptr& query) {
209 if (!query->relay_info_.empty()) {
219 Pkt6::RELAY_GET_FIRST);
267 const bool is_relay_address)
const {
271 if (is_relay_address) {
272 for (Subnet6Collection::const_iterator subnet = subnets_.begin();
273 subnet != subnets_.end(); ++subnet) {
277 if ((*subnet)->hasRelays()) {
278 if (!(*subnet)->hasRelayAddress(address)) {
284 (*subnet)->getSharedNetwork(network);
285 if (!network || !network->hasRelayAddress(address)) {
290 if ((*subnet)->clientSupported(client_classes)) {
295 .arg((*subnet)->toText()).arg(address.
toText());
303 for (Subnet6Collection::const_iterator subnet = subnets_.begin();
304 subnet != subnets_.end(); ++subnet) {
305 if ((*subnet)->inRange(address) &&
306 (*subnet)->clientSupported(client_classes)) {
308 .arg((*subnet)->toText()).arg(address.
toText());
319 CfgSubnets6::selectSubnet(
const std::string& iface_name,
323 if (!iface_name.empty()) {
324 for (Subnet6Collection::const_iterator subnet = subnets_.begin();
325 subnet != subnets_.end(); ++subnet) {
330 if (((*subnet)->getIface() == iface_name) &&
331 (*subnet)->clientSupported(client_classes)) {
335 .arg((*subnet)->toText()).arg(iface_name);
346 CfgSubnets6::selectSubnet(
const OptionPtr& interface_id,
347 const ClientClasses& client_classes)
const {
351 for (Subnet6Collection::const_iterator subnet = subnets_.begin();
352 subnet != subnets_.end(); ++subnet) {
356 if ((*subnet)->getInterfaceId() &&
357 (*subnet)->getInterfaceId()->equals(interface_id) &&
358 (*subnet)->clientSupported(client_classes)) {
362 .arg((*subnet)->toText());
376 for (
auto subnet = subnets_.begin(); subnet != subnets_.end(); ++subnet) {
377 if ((*subnet)->getID() == id) {
385 CfgSubnets6::removeStatistics() {
388 StatsMgr& stats_mgr = StatsMgr::instance();
390 for (Subnet6Collection::const_iterator subnet6 = subnets_.begin();
391 subnet6 != subnets_.end(); ++subnet6) {
392 SubnetID subnet_id = (*subnet6)->getID();
393 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
"total-nas"));
395 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
398 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
399 "cumulative-assigned-nas"));
401 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
"total-pds"));
403 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
406 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
407 "cumulative-assigned-pds"));
409 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
410 "declined-addresses"));
412 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
413 "reclaimed-declined-addresses"));
415 stats_mgr.
del(StatsMgr::generateName(
"subnet", subnet_id,
416 "reclaimed-leases"));
421 CfgSubnets6::updateStatistics() {
424 StatsMgr& stats_mgr = StatsMgr::instance();
426 for (Subnet6Collection::const_iterator subnet6 = subnets_.begin();
427 subnet6 != subnets_.end(); ++subnet6) {
428 SubnetID subnet_id = (*subnet6)->getID();
430 stats_mgr.
setValue(StatsMgr::generateName(
"subnet", subnet_id,
433 ((*subnet6)->getPoolCapacity(Lease::TYPE_NA)));
435 stats_mgr.
setValue(StatsMgr::generateName(
"subnet", subnet_id,
438 ((*subnet6)->getPoolCapacity(Lease::TYPE_PD)));
440 const std::string& name_nas =
441 StatsMgr::generateName(
"subnet", subnet_id,
"cumulative-assigned-nas");
443 stats_mgr.
setValue(name_nas, static_cast<int64_t>(0));
446 const std::string& name_pds =
447 StatsMgr::generateName(
"subnet", subnet_id,
"cumulative-assigned-pds");
449 stats_mgr.
setValue(name_pds, static_cast<int64_t>(0));
454 if (subnets_.begin() != subnets_.end()) {
455 LeaseMgrFactory::instance().recountLeaseStats6();
460 CfgSubnets6::toElement()
const {
463 for (Subnet6Collection::const_iterator subnet = subnets_.cbegin();
464 subnet != subnets_.cend(); ++subnet) {
465 result->add((*subnet)->toElement());
Exception thrown upon attempt to add subnet with an ID that belongs to the subnet that already exists...
boost::shared_ptr< CfgSharedNetworks6 > CfgSharedNetworks6Ptr
Pointer to the configuration of IPv6 shared networks.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6
asiolink::IOAddress remote_address_
Source address of the message.
Tag for the index for searching by subnet identifier.
Holds subnets configured for the DHCPv6 server.
OptionPtr interface_id_
Interface id option.
boost::shared_ptr< Option > OptionPtr
boost::shared_ptr< Element > ElementPtr
Tag for the index for searching by subnet prefix.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
ObservationPtr getObservation(const std::string &name) const
Returns an observation.
Statistics Manager class.
ClientClasses client_classes_
Classes that the client belongs to.
asiolink::IOAddress first_relay_linkaddr_
First relay link address.
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.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
const isc::log::MessageID DHCPSRV_CFGMGR_UPDATE_SUBNET6
structure that describes a single relay information
bool del(const std::string &name)
Removes specified statistic.
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6_IFACE_ID
const isc::log::MessageID DHCPSRV_CFGMGR_DEL_SUBNET6
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6_IFACE
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
Defines the logger used by the top-level component of kea-dhcp-ddns.
const isc::log::MessageID DHCPSRV_CFGMGR_SUBNET6_RELAY
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
const Subnet6Collection * getAll() const
Returns pointer to the collection of all IPv6 subnets.
A generic exception that is thrown if a function is called in a prohibited way.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
std::string toText() const
Convert the address to a string.
std::string iface_name_
Name of the interface on which the message was received.
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
bool isV6LinkLocal() const
checks whether and address is IPv6 and is link-local
isc::asiolink::IOAddress linkaddr_
fixed field in relay-forw/relay-reply
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
const isc::log::MessageID DHCPSRV_CFGMGR_ADD_SUBNET6
The IOAddress class represents an IP addresses (version agnostic)
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)