Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
090f6c00
Commit
090f6c00
authored
Aug 31, 2017
by
Marcin Siodelski
Browse files
[5305] Introduced shared networks holding subnets.
parent
53bfb954
Changes
15
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcpsrv/Makefile.am
View file @
090f6c00
...
...
@@ -88,6 +88,7 @@ libkea_dhcpsrv_la_SOURCES =
libkea_dhcpsrv_la_SOURCES
+=
addr_utilities.cc addr_utilities.h
libkea_dhcpsrv_la_SOURCES
+=
alloc_engine.cc alloc_engine.h
libkea_dhcpsrv_la_SOURCES
+=
alloc_engine_log.cc alloc_engine_log.h
libkea_dhcpsrv_la_SOURCES
+=
assignable_network.h
libkea_dhcpsrv_la_SOURCES
+=
base_host_data_source.h
libkea_dhcpsrv_la_SOURCES
+=
callout_handle_store.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_4o6.cc cfg_4o6.h
...
...
@@ -101,6 +102,8 @@ libkea_dhcpsrv_la_SOURCES += cfg_host_operations.cc cfg_host_operations.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_option.cc cfg_option.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_option_def.cc cfg_option_def.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_rsoo.cc cfg_rsoo.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_shared_networks4.cc cfg_shared_networks4.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_shared_networks6.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_subnets4.cc cfg_subnets4.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_subnets6.cc cfg_subnets6.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_mac_source.cc cfg_mac_source.h
...
...
@@ -138,6 +141,7 @@ libkea_dhcpsrv_la_SOURCES += mysql_host_data_source.cc mysql_host_data_source.h
endif
libkea_dhcpsrv_la_SOURCES
+=
ncr_generator.cc ncr_generator.h
libkea_dhcpsrv_la_SOURCES
+=
network.h
if
HAVE_PGSQL
libkea_dhcpsrv_la_SOURCES
+=
pgsql_connection.cc pgsql_connection.h
...
...
@@ -150,6 +154,7 @@ libkea_dhcpsrv_la_SOURCES += cql_lease_mgr.cc cql_lease_mgr.h
libkea_dhcpsrv_la_SOURCES
+=
cql_connection.cc cql_connection.h
endif
libkea_dhcpsrv_la_SOURCES
+=
pool.cc pool.h
libkea_dhcpsrv_la_SOURCES
+=
shared_network.cc shared_network.h
libkea_dhcpsrv_la_SOURCES
+=
srv_config.cc srv_config.h
libkea_dhcpsrv_la_SOURCES
+=
subnet.cc subnet.h
libkea_dhcpsrv_la_SOURCES
+=
subnet_id.h
...
...
@@ -178,6 +183,9 @@ libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.cc
libkea_dhcpsrv_la_SOURCES
+=
parsers/ifaces_config_parser.h
libkea_dhcpsrv_la_SOURCES
+=
parsers/option_data_parser.cc
libkea_dhcpsrv_la_SOURCES
+=
parsers/option_data_parser.h
libkea_dhcpsrv_la_SOURCES
+=
parsers/shared_network_parser.cc
libkea_dhcpsrv_la_SOURCES
+=
parsers/shared_network_parser.h
libkea_dhcpsrv_la_SOURCES
+=
parsers/shared_networks_list_parser.h
libkea_dhcpsrv_la_SOURCES
+=
parsers/simple_parser4.cc
libkea_dhcpsrv_la_SOURCES
+=
parsers/simple_parser4.h
libkea_dhcpsrv_la_SOURCES
+=
parsers/simple_parser6.cc
...
...
src/lib/dhcpsrv/assignable_network.h
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef ASSIGNABLE_NETWORK_H
#define ASSIGNABLE_NETWORK_H
#include <dhcpsrv/network.h>
namespace
isc
{
namespace
dhcp
{
/// @brief Represents a network that can be associated with a subnet.
///
/// This class represents a network that can be associated with a subnet
/// using @c Subnet::setSharedNetwork method. This class is a friend
/// of a @ref Subnet class, so it can call its @c Subnet::setSharedNetwork
/// private method. Association of a network with a subnet must be always
/// conducted using this class. This prevents unwanted replacements of
/// shared networks within subnets.
class
AssignableNetwork
:
public
Network
{
protected:
/// @brief Returns shared pointer to this object.
///
/// This abstract method must be implemented by derived classes to
/// return shared pointers the derivation.
///
/// @return Pointer to this network.
virtual
NetworkPtr
sharedFromThis
()
=
0
;
/// @brief Associates a subnet with this network.
///
/// @param subnet Pointer to a subnet to be associated with the network.
///
/// @tparam SubnetPtr Type of the subnet pointer.
template
<
typename
SubnetPtr
>
void
setSharedNetwork
(
const
SubnetPtr
&
subnet
)
{
subnet
->
setSharedNetwork
(
sharedFromThis
());
}
/// @brief Removes association of a subnet with a network.
///
/// @param subnet Pointer to a subnet for which association should be
/// removed.
///
/// @tparam SubnetPtr Type of the subnet pointer.
template
<
typename
SubnetPtr
>
void
clearSharedNetwork
(
const
SubnetPtr
&
subnet
)
{
subnet
->
setSharedNetwork
(
NetworkPtr
());
}
};
}
// end of namespace isc::dhcp
}
// end of namespace isc
#endif // ASSIGNABLE_NETWORK_H
src/lib/dhcpsrv/cfg_shared_networks4.cc
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <dhcpsrv/cfg_shared_networks4.h>
namespace
isc
{
namespace
dhcp
{
void
CfgSharedNetworks4
::
add
(
const
SharedNetwork4Ptr
&
network
)
{
}
}
// end of namespace isc::dhcp
}
// end of namespace isc
src/lib/dhcpsrv/cfg_shared_networks4.h
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef CFG_SHARED_NETWORKS4_H
#define CFG_SHARED_NETWORKS4_H
#include <cc/cfg_to_element.h>
#include <dhcpsrv/shared_network.h>
#include <boost/shared_ptr.hpp>
namespace
isc
{
namespace
dhcp
{
class
CfgSharedNetworks4
:
public
data
::
CfgToElement
{
public:
void
add
(
const
SharedNetwork4Ptr
&
shared_network
);
};
typedef
boost
::
shared_ptr
<
CfgSharedNetworks4
>
CfgSharedNetworks4Ptr
;
}
// end of namespace isc::dhcp
}
// end of namespace isc
#endif // CFG_SHARED_NETWORKS4_H
src/lib/dhcpsrv/cfg_shared_networks6.h
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef CFG_SHARED_NETWORKS6_H
#define CFG_SHARED_NETWORKS6_H
#include <cc/cfg_to_element.h>
#include <boost/shared_ptr.hpp>
namespace
isc
{
namespace
dhcp
{
class
CfgSharedNetworks6
:
public
data
::
CfgToElement
{
public:
};
typedef
boost
::
shared_ptr
<
CfgSharedNetworks6
>
CfgSharedNetworks6Ptr
;
}
// end of namespace isc::dhcp
}
// end of namespace isc
#endif // CFG_SHARED_NETWORKS6_H
src/lib/dhcpsrv/network.h
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef NETWORK_H
#define NETWORK_H
#include <boost/shared_ptr.hpp>
#include <string>
namespace
isc
{
namespace
dhcp
{
/// @brief Common interface representing a network to which the DHCP clients
/// are connected.
///
/// The most common type of network, in Kea's terminology, is a subnet. The
/// @ref Subnet implements this interface. Another types of objects implementing
/// this interface are @ref SharedNetwork objects. They group multiple subnets
/// together to provide means for extending available address pools (a single
/// client may obtain IP address from any of the pools belonging to subnets in
/// the shared network), or for selecting a subnet on a given link, depending
/// on the class of the client (e.g. cable network case: different subnet is
/// selected for cable modems, different one for routers).
///
/// The subnets and shared networks share many data structures, e.g. DHCP
/// options, local interface name, address manipulation methods, thus this
/// class provides an abstract interface that must be implemented by derived
/// classes and, where appropriate, implements common methods used by the
/// derived classes.
class
Network
{
public:
/// @brief Virtual destructor.
///
/// Does nothing at the moment.
virtual
~
Network
()
{
};
/// @brief Sets local name of the interface for which this network is
/// selected.
///
/// If the interface is specified, the server will use the network
/// associated with this local interface to allocate IP addresses and
/// other resources to a client.
///
/// @param iface_name Interface name.
void
setIface
(
const
std
::
string
&
iface_name
)
{
iface_name_
=
iface_name
;
}
/// @brief Returns name of the local interface for which this network is
/// selected.
///
/// @return Interface name as text.
std
::
string
getIface
()
const
{
return
(
iface_name_
);
};
protected:
/// @brief Holds interface name for which this network is selected.
std
::
string
iface_name_
;
};
/// @brief Pointer to the @ref Network object.
typedef
boost
::
shared_ptr
<
Network
>
NetworkPtr
;
}
// end of namespace isc::dhcp
}
// end of namespace isc
#endif // NETWORK_H
src/lib/dhcpsrv/parsers/shared_network_parser.cc
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef SHARED_NETWORK_PARSER_H
#define SHARED_NETWORK_PARSER_H
#include <cc/data.h>
#include <dhcpsrv/parsers/shared_network_parser.h>
#include <dhcpsrv/shared_network.h>
using
namespace
isc
::
data
;
namespace
isc
{
namespace
dhcp
{
SharedNetworkParser
::~
SharedNetworkParser
()
{
}
SharedNetworkPtr
SharedNetworkParser
::
parse
(
const
ConstElementPtr
&
shared_network_data
)
{
return
(
SharedNetworkPtr
());
}
}
// end of namespace isc::dhcp
}
// end of namespace isc
#endif // SHARED_NETWORK_PARSER_H
src/lib/dhcpsrv/parsers/shared_network_parser.h
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef SHARED_SUBNET_PARSER_H
#define SHARED_SUBNET_PARSER_H
#include <cc/data.h>
#include <cc/simple_parser.h>
#include <dhcpsrv/shared_network.h>
namespace
isc
{
namespace
dhcp
{
class
SharedNetworkParser
:
public
isc
::
data
::
SimpleParser
{
public:
virtual
~
SharedNetworkParser
();
virtual
SharedNetworkPtr
parse
(
const
data
::
ConstElementPtr
&
shared_network_data
);
};
}
// enf of namespace isc::dhcp
}
// end of namespace isc
#endif // SHARED_SUBNET_PARSER_H
src/lib/dhcpsrv/parsers/shared_networks_list_parser.h
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef SHARED_NETWORKS_LIST_PARSER_H
#define SHARED_NETWORKS_LIST_PARSER_H
#include <cc/data.h>
#include <cc/dhcp_config_error.h>
#include <cc/simple_parser.h>
#include <exceptions/exceptions.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/parsers/shared_network_parser.h>
namespace
isc
{
namespace
dhcp
{
template
<
typename
SharedNetworkParserType
>
class
SharedNetworksListParser
:
public
data
::
SimpleParser
{
protected:
template
<
typename
CfgSharedNetworksTypePtr
>
void
parse
(
const
data
::
ConstElementPtr
&
shared_networks_list_data
,
CfgSharedNetworksTypePtr
&
cfg
)
{
if
(
shared_networks_list_data
->
getType
()
!=
Element
::
list
)
{
isc_throw
(
data
::
DhcpConfigError
,
"shared-networks value must be a list"
);
}
}
};
}
// end of namespace isc::dhcp
}
// end of namespace isc
#endif // SHARED_NETWORKS_LIST_PARSER_H
src/lib/dhcpsrv/shared_network.cc
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <dhcpsrv/shared_network.h>
using
namespace
isc
::
dhcp
;
namespace
isc
{
namespace
dhcp
{
NetworkPtr
SharedNetwork4
::
sharedFromThis
()
{
return
(
shared_from_this
());
}
void
SharedNetwork4
::
add
(
const
Subnet4Ptr
&
subnet
)
{
SharedNetwork
::
add
(
subnets_
,
subnet
);
}
void
SharedNetwork4
::
del
(
const
SubnetID
&
subnet_id
)
{
SharedNetwork
::
del
(
subnets_
,
subnet_id
);
}
Subnet4Ptr
SharedNetwork4
::
getSubnet
(
const
SubnetID
&
subnet_id
)
const
{
return
(
SharedNetwork
::
getSubnet
<
Subnet4Ptr
>
(
subnets_
,
subnet_id
));
}
Subnet4Ptr
SharedNetwork4
::
getNextSubnet
(
const
Subnet4Ptr
&
first_subnet
,
const
Subnet4Ptr
&
current_subnet
)
const
{
return
(
SharedNetwork
::
getNextSubnet
(
subnets_
,
first_subnet
,
current_subnet
));
}
NetworkPtr
SharedNetwork6
::
sharedFromThis
()
{
return
(
shared_from_this
());
}
void
SharedNetwork6
::
add
(
const
Subnet6Ptr
&
subnet
)
{
SharedNetwork
::
add
(
subnets_
,
subnet
);
}
void
SharedNetwork6
::
del
(
const
SubnetID
&
subnet_id
)
{
SharedNetwork
::
del
(
subnets_
,
subnet_id
);
}
Subnet6Ptr
SharedNetwork6
::
getSubnet
(
const
SubnetID
&
subnet_id
)
const
{
return
(
SharedNetwork
::
getSubnet
<
Subnet6Ptr
>
(
subnets_
,
subnet_id
));
}
Subnet6Ptr
SharedNetwork6
::
getNextSubnet
(
const
Subnet6Ptr
&
first_subnet
,
const
Subnet6Ptr
&
current_subnet
)
const
{
return
(
SharedNetwork
::
getNextSubnet
(
subnets_
,
first_subnet
,
current_subnet
));
}
}
// end of namespace isc::dhcp
}
// end of namespace isc
src/lib/dhcpsrv/shared_network.h
0 → 100644
View file @
090f6c00
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef SHARED_NETWORK_H
#define SHARED_NETWORK_H
#include <exceptions/exceptions.h>
#include <dhcpsrv/assignable_network.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_id.h>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
namespace
isc
{
namespace
dhcp
{
class
SharedNetwork
;
/// @brief Pointer to the @ref SharedNetwork object.
typedef
boost
::
shared_ptr
<
SharedNetwork
>
SharedNetworkPtr
;
/// @brief Represents shared network, which groups multiple subnets.
///
/// Shared networks provide means for grouping multiple subnets together.
/// There are two major use cases for such grouping:
///
/// - Extending available address pools to be allocated for clients on
/// a particular link without a need to renumber.
/// - Fulfill requirement in cable networks whereby two classes of devices
/// are connected on the same link: cable modems and routers. Such devices
/// must be assign addresses/prefixes from different pools based on client
/// classification.
///
/// Shared networks provide similar interface like subnets, thus they both
/// derive from the @ref Network class.
class
SharedNetwork
:
public
AssignableNetwork
{
protected:
/// @brief Adds a subnet to a shared network.
///
/// This is a generic method for adding a new subnet to a shared network.
///
/// @param [out] subnets Container holding subnets for this shared network.
/// @param subnet Pointer to a subnet being added to this shared network.
///
/// @tparam SubnetPtrType Type of a pointer to a subnet, i.e. Subnet4Ptr
/// or @ref Subnet6Ptr.
/// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
/// @ref Subnet4Collection or @ref Subnet6Collection.
///
/// @throw isc::BadValue if subnet is null.
/// @throw isc::DuplicateSubnetID if a subnet with the given subnet id
/// already exists in this shared network.
/// @throw InvalidOperation if a subnet is already associated with some
/// shared network.
template
<
typename
SubnetPtrType
,
typename
SubnetCollectionType
>
void
add
(
SubnetCollectionType
&
subnets
,
const
SubnetPtrType
&
subnet
)
{
// Subnet must be non-null.
if
(
!
subnet
)
{
isc_throw
(
BadValue
,
"null pointer specified when adding a subnet"
" to a shared network"
);
}
// Check if a subnet with this id already exists.
if
(
getSubnet
<
SubnetPtrType
>
(
subnets
,
subnet
->
getID
()))
{
isc_throw
(
DuplicateSubnetID
,
"attempted to add subnet with a"
" duplicated subnet identifier "
<<
subnet
->
getID
());
}
// Check if the subnet is already associated with some network.
SharedNetworkPtr
network
;
subnet
->
getSharedNetwork
(
network
);
if
(
network
)
{
isc_throw
(
InvalidOperation
,
"subnet "
<<
subnet
->
getID
()
<<
" being added to a shared network"
" already belongs to a shared network"
);
}
// Add a subnet to the collection of subnets for this shared network.
subnets
.
push_back
(
subnet
);
// Associate the subnet with this network.
setSharedNetwork
(
subnet
);
}
/// @brief Removes a subnet from the shared network.
///
/// @param [out] subnets Container holding subnets for this shared network.
/// @param subnet_id Identifier of a subnet to be removed.
///
/// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
/// @ref Subnet4Collection or @ref Subnet6Collection.
///
/// @throw BadValue if a subnet with specified identifier doesn't exist.
template
<
typename
SubnetCollectionType
>
void
del
(
SubnetCollectionType
&
subnets
,
const
SubnetID
&
subnet_id
)
{
auto
&
index
=
subnets
.
template
get
<
SubnetSubnetIdIndexTag
>();
auto
subnet_it
=
index
.
find
(
subnet_id
);
if
(
subnet_it
==
index
.
end
())
{
isc_throw
(
BadValue
,
"unable to delete subnet "
<<
subnet_id
<<
" from shared network. Subnet doesn't belong"
" to this shared network"
);
}
auto
subnet
=
*
subnet_it
;
index
.
erase
(
subnet_it
);
clearSharedNetwork
(
subnet
);
}
/// @brief Returns a subnet belonging to this network for a given subnet id.
///
/// @param subnets Container holding subnets for this shared network.
/// @param subnet_id Identifier of a subnet being retrieved.
///
/// @tparam SubnetPtrType Type of a pointer to a subnet, i.e. Subnet4Ptr
/// or @ref Subnet6Ptr.
/// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
/// @ref Subnet4Collection or @ref Subnet6Collection.
///
/// @return Pointer to the subnet or null if the subnet doesn't exist.
template
<
typename
SubnetPtrType
,
typename
SubnetCollectionType
>
SubnetPtrType
getSubnet
(
const
SubnetCollectionType
&
subnets
,
const
SubnetID
&
subnet_id
)
const
{
const
auto
&
index
=
subnets
.
template
get
<
SubnetSubnetIdIndexTag
>();
auto
subnet_it
=
index
.
find
(
subnet_id
);
if
(
subnet_it
!=
index
.
cend
())
{
return
(
*
subnet_it
);
}
// Subnet not found.
return
(
SubnetPtrType
());
}
/// @brief Retrieves next available subnet within shared network.
///
/// This method returns next available subnet within a shared network.
/// The subnets are ordered and retrieved using random access index
/// (first in/first out). The next subnet means next in turn after
/// the current subnet, which is specified as an argument. A caller
/// can iterate over all subnets starting from any of the subnets
/// belonging to a shared network. This subnet is called here as
/// a first subnet and is also specified as a method argument. When the
/// method detects that the next available subnet is a first subnet, it
/// returns a null pointer to indicate that there are no more subnets
/// available.
///
/// The typical use case for this method is to allow DHCP server's
/// allocation engine to walk over the available subnets within a shared
/// network, starting from a subnet that has been selected during the
/// "subnet selection" processing step. In some cases the allocation
/// engine is unable to allocate resources from a selected subnet due
/// to client classification restrictions or address shortage within
/// its pools. It then uses this mechanism to move to another subnet
/// belonging to the same shared network.
///
/// @param subnets Container holding subnets belonging to this shared
/// network.
/// @param first_subnet Pointer to a subnet from which the caller is
/// iterating over subnets within shared network. This is typically a
/// subnet selected during "subnet selection" step.
/// @param current_subnet Pointer to a subnet for which next subnet is
/// to be found.
///
/// @tparam SubnetPtrType Type of the pointer to a subnet, i.e.
/// @ref Subnet4Ptr or @ref Subnet6Ptr.
/// @tparam SubnetCollectionType Type of the container holding subnets, i.e.
/// @ref Subnet4Collection or @ref Subnet6Collection.
///
/// @return Pointer to next subnet or null pointer if no more subnets found.
///
/// @throw isc::BadValue if invalid arguments specified, e.g. unable to
/// find first or current subnet within the container.
template
<
typename
SubnetPtrType
,
typename
SubnetCollectionType
>
SubnetPtrType
getNextSubnet
(
const
SubnetCollectionType
&
subnets
,
const
SubnetPtrType
&
first_subnet
,
const
SubnetPtrType
&
current_subnet
)
const
{
// Current subnet must not be null. The caller must explicitly set it
// to one of the pointers that belong to this shared network, typically
// to a selected subnet.
if
(
!
current_subnet
)
{
isc_throw
(
BadValue
,
"null subnet specified for a shared"
" network while searching for next subnet is this"
" network"
);
}
// It is ok to have a shared network without any subnets, but in this
// case there is nothing else we can return but null pointer.
if
(
subnets
.
empty
())
{
return
(
SubnetPtrType
());
}
// Need to retrieve an iterator to the current subnet first. The
// subnet must exist in this container, thus we throw if the iterator
// is not found.
const
auto
&
index
=
subnets
.
template
get
<
SubnetSubnetIdIndexTag
>();
auto
subnet_id_it
=
index
.
find
(
current_subnet
->
getID
());
if
(
subnet_id_it
==
index
.
cend
())
{
isc_throw
(
BadValue
,
"no such subnet "
<<
current_subnet
->
getID
()