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
Sebastian Schrader
Kea
Commits
b1217e69
Commit
b1217e69
authored
Sep 17, 2013
by
Tomek Mrugalski
🛰
Browse files
[master] Merge branch 'trac3150' (DHCP::CfgMgr support for PD)
Conflicts: ChangeLog
parents
7430591b
e6f0e891
Changes
12
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
b1217e69
677. [func] tomek
libdhcpsrv: CfgMgr is now able to store IA, TA and PD pools in
Subnet6 structures.
(Trac #3150, git e6f0e89162bac0adae3ce3141437a282d5183162)
676. [bug] muks
We now also allow the short name ("hmac-md5"), along with the long
name ("hmac-md5.sig-alg.reg.int") that was allowed before for
...
...
@@ -21,7 +26,7 @@
for IAPREFIX (Option6_IAPrefix) has been added.
(Trac #3145, git 3a844e85ecc3067ccd1c01841f4a61366cb278f4)
672. [func] tmark
672. [func]
tmark
Added b10-dhcp-ddnsupdate transaction base class, NameChangeTransaction.
This class provides the common structure and methods to implement the state
models described in the DHCP_DDNS design, plus integration with DNSClient
...
...
src/bin/dhcp4/dhcp4_srv.cc
View file @
b1217e69
...
...
@@ -135,7 +135,8 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig, const bool use_bcast,
.
arg
(
LeaseMgrFactory
::
instance
().
getName
());
// Instantiate allocation engine
alloc_engine_
.
reset
(
new
AllocEngine
(
AllocEngine
::
ALLOC_ITERATIVE
,
100
));
alloc_engine_
.
reset
(
new
AllocEngine
(
AllocEngine
::
ALLOC_ITERATIVE
,
100
,
false
/* false = IPv4 */
));
// Register hook points
hook_index_pkt4_receive_
=
Hooks
.
hook_index_pkt4_receive_
;
...
...
src/bin/dhcp6/config_parser.cc
View file @
b1217e69
...
...
@@ -141,13 +141,13 @@ protected:
///
/// @param addr is the IPv6 prefix of the pool.
/// @param len is the prefix length.
/// @param ptype is the type of IPv6 pool (Pool
6
::Pool
6
Type). Note this is
/// passed in as an int32_t and cast to Pool
6
Type to accommodate a
/// @param ptype is the type of IPv6 pool (Pool::PoolType). Note this is
/// passed in as an int32_t and cast to PoolType to accommodate a
/// polymorphic interface.
/// @return returns a PoolPtr to the new Pool4 object.
PoolPtr
poolMaker
(
IOAddress
&
addr
,
uint32_t
len
,
int32_t
ptype
)
{
return
(
PoolPtr
(
new
Pool6
(
static_cast
<
isc
::
dhcp
::
Pool
6
::
Pool
6
Type
>
return
(
PoolPtr
(
new
Pool6
(
static_cast
<
isc
::
dhcp
::
Pool
::
PoolType
>
(
ptype
),
addr
,
len
)));
}
...
...
@@ -155,13 +155,13 @@ protected:
///
/// @param min is the first IPv6 address in the pool.
/// @param max is the last IPv6 address in the pool.
/// @param ptype is the type of IPv6 pool (Pool
6
::Pool
6
Type). Note this is
/// passed in as an int32_t and cast to Pool
6
Type to accommodate a
/// @param ptype is the type of IPv6 pool (Pool::PoolType). Note this is
/// passed in as an int32_t and cast to PoolType to accommodate a
/// polymorphic interface.
/// @return returns a PoolPtr to the new Pool4 object.
PoolPtr
poolMaker
(
IOAddress
&
min
,
IOAddress
&
max
,
int32_t
ptype
)
{
return
(
PoolPtr
(
new
Pool6
(
static_cast
<
isc
::
dhcp
::
Pool
6
::
Pool
6
Type
>
return
(
PoolPtr
(
new
Pool6
(
static_cast
<
isc
::
dhcp
::
Pool
::
PoolType
>
(
ptype
),
min
,
max
)));
}
};
...
...
src/lib/dhcpsrv/alloc_engine.cc
View file @
b1217e69
...
...
@@ -53,8 +53,8 @@ AllocEngineHooks Hooks;
namespace
isc
{
namespace
dhcp
{
AllocEngine
::
IterativeAllocator
::
IterativeAllocator
()
:
Allocator
()
{
AllocEngine
::
IterativeAllocator
::
IterativeAllocator
(
Pool
::
PoolType
lease_type
)
:
Allocator
(
lease_type
)
{
}
isc
::
asiolink
::
IOAddress
...
...
@@ -94,9 +94,9 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
// Let's get the last allocated address. It is usually set correctly,
// but there are times when it won't be (like after removing a pool or
// perhaps restarting the server).
IOAddress
last
=
subnet
->
getLastAllocated
();
IOAddress
last
=
subnet
->
getLastAllocated
(
pool_type_
);
const
PoolCollection
&
pools
=
subnet
->
getPools
();
const
PoolCollection
&
pools
=
subnet
->
getPools
(
pool_type_
);
if
(
pools
.
empty
())
{
isc_throw
(
AllocFailed
,
"No pools defined in selected subnet"
);
...
...
@@ -117,7 +117,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
if
(
it
==
pools
.
end
())
{
// ok to access first element directly. We checked that pools is non-empty
IOAddress
next
=
pools
[
0
]
->
getFirstAddress
();
subnet
->
setLastAllocated
(
next
);
subnet
->
setLastAllocated
(
pool_type_
,
next
);
return
(
next
);
}
...
...
@@ -126,7 +126,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
IOAddress
next
=
increaseAddress
(
last
);
// basically addr++
if
((
*
it
)
->
inRange
(
next
))
{
// the next one is in the pool as well, so we haven't hit pool boundary yet
subnet
->
setLastAllocated
(
next
);
subnet
->
setLastAllocated
(
pool_type_
,
next
);
return
(
next
);
}
...
...
@@ -136,18 +136,18 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
// Really out of luck today. That was the last pool. Let's rewind
// to the beginning.
next
=
pools
[
0
]
->
getFirstAddress
();
subnet
->
setLastAllocated
(
next
);
subnet
->
setLastAllocated
(
pool_type_
,
next
);
return
(
next
);
}
// there is a next pool, let's try first address from it
next
=
(
*
it
)
->
getFirstAddress
();
subnet
->
setLastAllocated
(
next
);
subnet
->
setLastAllocated
(
pool_type_
,
next
);
return
(
next
);
}
AllocEngine
::
HashedAllocator
::
HashedAllocator
()
:
Allocator
()
{
AllocEngine
::
HashedAllocator
::
HashedAllocator
(
Pool
::
PoolType
lease_type
)
:
Allocator
(
lease_type
)
{
isc_throw
(
NotImplemented
,
"Hashed allocator is not implemented"
);
}
...
...
@@ -159,8 +159,8 @@ AllocEngine::HashedAllocator::pickAddress(const SubnetPtr&,
isc_throw
(
NotImplemented
,
"Hashed allocator is not implemented"
);
}
AllocEngine
::
RandomAllocator
::
RandomAllocator
()
:
Allocator
()
{
AllocEngine
::
RandomAllocator
::
RandomAllocator
(
Pool
::
PoolType
lease_type
)
:
Allocator
(
lease_type
)
{
isc_throw
(
NotImplemented
,
"Random allocator is not implemented"
);
}
...
...
@@ -173,17 +173,21 @@ AllocEngine::RandomAllocator::pickAddress(const SubnetPtr&,
}
AllocEngine
::
AllocEngine
(
AllocType
engine_type
,
unsigned
int
attempts
)
AllocEngine
::
AllocEngine
(
AllocType
engine_type
,
unsigned
int
attempts
,
bool
ipv6
)
:
attempts_
(
attempts
)
{
Pool
::
PoolType
pool_type
=
ipv6
?
Pool
::
TYPE_IA
:
Pool
::
TYPE_V4
;
switch
(
engine_type
)
{
case
ALLOC_ITERATIVE
:
allocator_
=
boost
::
shared_ptr
<
Allocator
>
(
new
IterativeAllocator
());
allocator_
.
reset
(
new
IterativeAllocator
(
pool_type
));
break
;
case
ALLOC_HASHED
:
allocator_
=
boost
::
shared_ptr
<
Allocator
>
(
new
HashedAllocator
());
allocator_
.
reset
(
new
HashedAllocator
(
pool_type
));
break
;
case
ALLOC_RANDOM
:
allocator_
=
boost
::
shared_ptr
<
Allocator
>
(
new
RandomAllocator
());
allocator_
.
reset
(
new
RandomAllocator
(
pool_type
));
break
;
default:
...
...
src/lib/dhcpsrv/alloc_engine.h
View file @
b1217e69
...
...
@@ -77,10 +77,21 @@ protected:
pickAddress
(
const
SubnetPtr
&
subnet
,
const
DuidPtr
&
duid
,
const
isc
::
asiolink
::
IOAddress
&
hint
)
=
0
;
/// @brief Default constructor.
///
/// Specifies which type of leases this allocator will assign
/// @param pool_type specifies pool type (addresses, temp. addr or prefixes)
Allocator
(
Pool
::
PoolType
pool_type
)
:
pool_type_
(
pool_type
)
{
}
/// @brief virtual destructor
virtual
~
Allocator
()
{
}
protected:
/// @brief defines lease type allocation
Pool
::
PoolType
pool_type_
;
};
/// @brief Address/prefix allocator that iterates over all addresses
...
...
@@ -95,7 +106,8 @@ protected:
/// @brief default constructor
///
/// Does not do anything
IterativeAllocator
();
/// @param type - specifies allocation type
IterativeAllocator
(
Pool
::
PoolType
type
);
/// @brief returns the next address from pools in a subnet
///
...
...
@@ -123,7 +135,8 @@ protected:
public:
/// @brief default constructor (does nothing)
HashedAllocator
();
/// @param type - specifies allocation type
HashedAllocator
(
Pool
::
PoolType
type
);
/// @brief returns an address based on hash calculated from client's DUID.
///
...
...
@@ -145,7 +158,8 @@ protected:
public:
/// @brief default constructor (does nothing)
RandomAllocator
();
/// @param type - specifies allocation type
RandomAllocator
(
Pool
::
PoolType
type
);
/// @brief returns an random address from pool of specified subnet
///
...
...
@@ -180,7 +194,8 @@ protected:
/// @param engine_type selects allocation algorithm
/// @param attempts number of attempts for each lease allocation before
/// we give up (0 means unlimited)
AllocEngine
(
AllocType
engine_type
,
unsigned
int
attempts
);
/// @param ipv6 specifies if the engine should work for IPv4 or IPv6
AllocEngine
(
AllocType
engine_type
,
unsigned
int
attempts
,
bool
ipv6
=
true
);
/// @brief Returns IPv4 lease.
///
...
...
src/lib/dhcpsrv/pool.cc
View file @
b1217e69
...
...
@@ -21,9 +21,9 @@ using namespace isc::asiolink;
namespace
isc
{
namespace
dhcp
{
Pool
::
Pool
(
const
isc
::
asiolink
::
IOAddress
&
first
,
Pool
::
Pool
(
PoolType
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
)
:
id_
(
getNextID
()),
first_
(
first
),
last_
(
last
)
{
:
id_
(
getNextID
()),
first_
(
first
),
last_
(
last
)
,
type_
(
type
)
{
}
bool
Pool
::
inRange
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
{
...
...
@@ -32,7 +32,7 @@ bool Pool::inRange(const isc::asiolink::IOAddress& addr) const {
Pool4
::
Pool4
(
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
)
:
Pool
(
first
,
last
)
{
:
Pool
(
Pool
::
TYPE_V4
,
first
,
last
)
{
// check if specified address boundaries are sane
if
(
!
first
.
isV4
()
||
!
last
.
isV4
())
{
isc_throw
(
BadValue
,
"Invalid Pool4 address boundaries: not IPv4"
);
...
...
@@ -43,9 +43,8 @@ Pool4::Pool4(const isc::asiolink::IOAddress& first,
}
}
Pool4
::
Pool4
(
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
)
:
Pool
(
prefix
,
IOAddress
(
"0.0.0.0"
))
{
Pool4
::
Pool4
(
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
)
:
Pool
(
Pool
::
TYPE_V4
,
prefix
,
IOAddress
(
"0.0.0.0"
))
{
// check if the prefix is sane
if
(
!
prefix
.
isV4
())
{
...
...
@@ -62,15 +61,21 @@ Pool4::Pool4(const isc::asiolink::IOAddress& prefix,
}
Pool6
::
Pool6
(
Pool
6
Type
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
Pool6
::
Pool6
(
PoolType
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
)
:
Pool
(
first
,
last
),
type_
(
type
)
{
:
Pool
(
type
,
first
,
last
),
prefix_len_
(
128
)
{
// check if specified address boundaries are sane
if
(
!
first
.
isV6
()
||
!
last
.
isV6
())
{
isc_throw
(
BadValue
,
"Invalid Pool6 address boundaries: not IPv6"
);
}
if
(
(
type
!=
Pool
::
TYPE_IA
)
&&
(
type
!=
Pool
::
TYPE_TA
)
&&
(
type
!=
Pool
::
TYPE_PD
))
{
isc_throw
(
BadValue
,
"Invalid Pool6 type: "
<<
static_cast
<
int
>
(
type
)
<<
", must be TYPE_IA, TYPE_TA or TYPE_PD"
);
}
if
(
last
<
first
)
{
isc_throw
(
BadValue
,
"Upper boundary is smaller than lower boundary."
);
// This check is a bit strict. If we decide that it is too strict,
...
...
@@ -88,23 +93,34 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& first,
// parameters are for IA and TA only. There is another dedicated
// constructor for that (it uses prefix/length)
if
((
type
!=
TYPE_IA
)
&&
(
type
!=
TYPE_TA
))
{
isc_throw
(
BadValue
,
"Invalid Pool6 type specified"
);
isc_throw
(
BadValue
,
"Invalid Pool6 type specified:"
<<
static_cast
<
int
>
(
type
));
}
}
Pool6
::
Pool6
(
Pool6Type
type
,
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
)
:
Pool
(
prefix
,
IOAddress
(
"::"
)),
type_
(
type
)
{
Pool6
::
Pool6
(
PoolType
type
,
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
,
uint8_t
delegated_len
/* = 128 */
)
:
Pool
(
type
,
prefix
,
IOAddress
(
"::"
)),
prefix_len_
(
delegated_len
)
{
// check if the prefix is sane
if
(
!
prefix
.
isV6
())
{
isc_throw
(
BadValue
,
"Invalid Pool6 address boundaries: not IPv6"
);
}
// check if the prefix length is sane
// check if the prefix length is sane
if
(
prefix_len
==
0
||
prefix_len
>
128
)
{
isc_throw
(
BadValue
,
"Invalid prefix length"
);
isc_throw
(
BadValue
,
"Invalid prefix length: "
<<
prefix_len
);
}
if
(
prefix_len
>
delegated_len
)
{
isc_throw
(
BadValue
,
"Delegated length ("
<<
static_cast
<
int
>
(
delegated_len
)
<<
") must be longer than prefix length ("
<<
static_cast
<
int
>
(
prefix_len
)
<<
")"
);
}
if
(
(
(
type
==
TYPE_IA
)
||
(
type
==
TYPE_TA
))
&&
(
delegated_len
!=
128
))
{
isc_throw
(
BadValue
,
"For IA or TA pools, delegated prefix length must "
<<
" be 128."
);
}
/// @todo: We should probably implement checks against weird addresses
...
...
src/lib/dhcpsrv/pool.h
View file @
b1217e69
...
...
@@ -32,6 +32,25 @@ class Pool {
public:
/// @brief specifies Pool type
///
/// Currently there are 3 pool types defined in DHCPv6:
/// - Non-temporary addresses (conveyed in IA_NA)
/// - Temporary addresses (conveyed in IA_TA)
/// - Delegated Prefixes (conveyed in IA_PD)
///
/// The fourth one (TYPE_V4) is used in DHCPv4 use cases when getPool()
/// code is shared between v4 and v6 code.
///
/// There is a new one being worked on (IA_PA, see draft-ietf-dhc-host-gen-id), but
/// support for it is not planned for now.
typedef
enum
{
TYPE_IA
,
TYPE_TA
,
TYPE_PD
,
TYPE_V4
}
PoolType
;
/// @brief returns Pool-id
///
/// @return pool-id value
...
...
@@ -58,6 +77,20 @@ public:
/// @return true, if the address is in pool
bool
inRange
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
;
/// @brief Returns pool type (v4, v6 non-temporary, v6 temp, v6 prefix)
/// @return returns pool type
PoolType
getType
()
const
{
return
(
type_
);
}
/// @brief virtual destructor
///
/// We need Pool to be a polymorphic class, so we could dynamic cast
/// from PoolPtr to Pool6Ptr if we need to. A class becomes polymorphic,
/// when there is at least one virtual method.
virtual
~
Pool
()
{
}
protected:
/// @brief protected constructor
...
...
@@ -65,7 +98,12 @@ protected:
/// This constructor is protected to prevent anyone from instantiating
/// Pool class directly. Instances of Pool4 and Pool6 should be created
/// instead.
Pool
(
const
isc
::
asiolink
::
IOAddress
&
first
,
///
/// @param type type of the pool
/// @param first first address of a range
/// @param last last address of a range
Pool
(
PoolType
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
);
/// @brief returns the next unique Pool-ID
...
...
@@ -91,6 +129,9 @@ protected:
///
/// @todo: This field is currently not used.
std
::
string
comments_
;
/// @brief defines a pool type
PoolType
type_
;
};
/// @brief Pool information for IPv4 addresses
...
...
@@ -117,9 +158,6 @@ public:
/// @brief a pointer an IPv4 Pool
typedef
boost
::
shared_ptr
<
Pool4
>
Pool4Ptr
;
/// @brief a container for IPv4 Pools
typedef
std
::
vector
<
Pool4Ptr
>
Pool4Collection
;
/// @brief Pool information for IPv6 addresses and prefixes
///
/// It holds information about pool6, i.e. a range of IPv6 address space that
...
...
@@ -127,55 +165,70 @@ typedef std::vector<Pool4Ptr> Pool4Collection;
class
Pool6
:
public
Pool
{
public:
/// @brief specifies Pool type
///
/// Currently there are 3 pool types defined in DHCPv6:
/// - Non-temporary addresses (conveyed in IA_NA)
/// - Temporary addresses (conveyed in IA_TA)
/// - Delegated Prefixes (conveyed in IA_PD)
/// There is a new one being worked on (IA_PA, see draft-ietf-dhc-host-gen-id), but
/// support for it is not planned for now.
typedef
enum
{
TYPE_IA
,
TYPE_TA
,
TYPE_PD
}
Pool6Type
;
/// @brief the constructor for Pool6 "min-max" style definition
///
/// @param type type of the pool (IA, TA or PD)
/// @throw BadValue if PD is define (PD can be only prefix/len)
///
/// @param type type of the pool (IA or TA)
/// @param first the first address in a pool
/// @param last the last address in a pool
Pool6
(
Pool
6
Type
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
Pool6
(
PoolType
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
);
/// @brief the constructor for Pool6 "prefix/len" style definition
///
/// For addressed, this is just a prefix/len definition. For prefixes,
/// there is one extra additional parameter delegated_len. It specifies
/// a size of delegated prefixes that the pool will be split into. For
/// example pool 2001:db8::/56, delegated_len=64 means that there is a
/// pool 2001:db8::/56. It will be split into 256 prefixes of length /64,
/// e.g. 2001:db8:0:1::/64, 2001:db8:0:2::/64 etc.
///
/// Naming convention:
/// A smaller prefix length yields a shorter prefix which describes a larger
/// set of addresses. A larger length yields a longer prefix which describes
/// a smaller set of addresses.
///
/// Obviously, prefix_len must define shorter or equal prefix length than
/// delegated_len, so prefix_len <= delegated_len. Note that it is slightly
/// confusing: bigger (larger) prefix actually has smaller prefix length,
/// e.g. /56 is a bigger prefix than /64, but has shorter (smaller) prefix
/// length.
///
/// @throw BadValue if delegated_len is defined for non-PD types or
/// when delegated_len < prefix_len
///
/// @param type type of the pool (IA, TA or PD)
/// @param prefix specifies prefix of the pool
/// @param prefix_len specifies length of the prefix of the pool
Pool6
(
Pool6Type
type
,
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
);
/// @param prefix_len specifies prefix length of the pool
/// @param delegated_len specifies lenght of the delegated prefixes
Pool6
(
PoolType
type
,
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
,
uint8_t
delegated_len
=
128
);
/// @brief returns pool type
///
/// @return pool type
Pool
6
Type
getType
()
const
{
PoolType
getType
()
const
{
return
(
type_
);
}
private:
/// @brief defines a pool type
Pool6Type
type_
;
/// @brief returns delegated prefix length
///
/// This may be useful for "prefix/len" style definition for
/// addresses, but is mostly useful for prefix pools.
/// @return prefix length (1-128)
uint8_t
getLength
()
{
return
(
prefix_len_
);
}
private:
/// @brief Defines prefix length (for TYPE_PD only)
uint8_t
prefix_len_
;
};
/// @brief a pointer an IPv6 Pool
typedef
boost
::
shared_ptr
<
Pool6
>
Pool6Ptr
;
/// @brief a container for IPv6 Pools
typedef
std
::
vector
<
Pool6Ptr
>
Pool6Collection
;
/// @brief a pointer to either IPv4 or IPv6 Pool
typedef
boost
::
shared_ptr
<
Pool
>
PoolPtr
;
...
...
src/lib/dhcpsrv/subnet.cc
View file @
b1217e69
...
...
@@ -30,15 +30,17 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
const
Triplet
<
uint32_t
>&
valid_lifetime
)
:
id_
(
getNextID
()),
prefix_
(
prefix
),
prefix_len_
(
len
),
t1_
(
t1
),
t2_
(
t2
),
valid_
(
valid_lifetime
),
last_allocated_
(
lastAddrInPrefix
(
prefix
,
len
))
{
last_allocated_ia_
(
lastAddrInPrefix
(
prefix
,
len
)),
last_allocated_ta_
(
lastAddrInPrefix
(
prefix
,
len
)),
last_allocated_pd_
(
lastAddrInPrefix
(
prefix
,
len
))
{
if
((
prefix
.
isV6
()
&&
len
>
128
)
||
(
prefix
.
isV4
()
&&
len
>
32
))
{
isc_throw
(
BadValue
,
isc_throw
(
BadValue
,
"Invalid prefix length specified for subnet: "
<<
len
);
}
}
bool
bool
Subnet
::
inRange
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
{
IOAddress
first
=
firstAddrInPrefix
(
prefix_
,
prefix_len_
);
IOAddress
last
=
lastAddrInPrefix
(
prefix_
,
prefix_len_
);
...
...
@@ -86,13 +88,58 @@ Subnet::getOptionDescriptor(const std::string& option_space,
return
(
*
range
.
first
);
}
std
::
string
isc
::
asiolink
::
IOAddress
Subnet
::
getLastAllocated
(
Pool
::
PoolType
type
)
const
{
// check if the type is valid (and throw if it isn't)
checkType
(
type
);
switch
(
type
)
{
case
Pool
::
TYPE_V4
:
case
Pool
::
TYPE_IA
:
return
last_allocated_ia_
;
case
Pool
::
TYPE_TA
:
return
last_allocated_ta_
;
case
Pool
::
TYPE_PD
:
return
last_allocated_pd_
;
default:
isc_throw
(
BadValue
,
"Pool type "
<<
type
<<
" not supported"
);
}
}
void
Subnet
::
setLastAllocated
(
Pool
::
PoolType
type
,
const
isc
::
asiolink
::
IOAddress
&
addr
)
{
// check if the type is valid (and throw if it isn't)
checkType
(
type
);
switch
(
type
)
{
case
Pool
::
TYPE_V4
:
case
Pool
::
TYPE_IA
:
last_allocated_ia_
=
addr
;
return
;
case
Pool
::
TYPE_TA
:
last_allocated_ta_
=
addr
;
return
;
case
Pool
::
TYPE_PD
:
last_allocated_pd_
=
addr
;
return
;
default:
isc_throw
(
BadValue
,
"Pool type "
<<
type
<<
" not supported"
);
}
}
std
::
string
Subnet
::
toText
()
const
{
std
::
stringstream
tmp
;
tmp
<<
prefix_
.
toText
()
<<
"/"
<<
static_cast
<
unsigned
int
>
(
prefix_len_
);
return
(
tmp
.
str
());
}
void
Subnet4
::
checkType
(
Pool
::
PoolType
type
)
const
{
if
(
type
!=
Pool
::
TYPE_V4
)
{
isc_throw
(
BadValue
,
"Only TYPE_V4 is allowed for Subnet4"
);
}
}
Subnet4
::
Subnet4
(
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
length
,
const
Triplet
<
uint32_t
>&
t1
,
const
Triplet
<
uint32_t
>&
t2
,
...
...
@@ -104,35 +151,55 @@ Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
}
}
void
Subnet
::
addPool
(
const
PoolPtr
&
pool
)
{
IOAddress
first_addr
=
pool
->
getFirstAddress
();
IOAddress
last_addr
=
pool
->
getLastAddress
();
if
(
!
inRange
(
first_addr
)
||
!
inRange
(
last_addr
))
{
isc_throw
(
BadValue
,
"Pool ("
<<
first_addr
.
toText
()
<<
"-"
<<
last_addr
.
toText
()
<<
" does not belong in this ("
<<
prefix_
.
toText
()
<<
"/"
<<
static_cast
<
int
>
(
prefix_len_
)
<<
") subnet4"
);
const
PoolCollection
&
Subnet
::
getPools
(
Pool
::
PoolType
type
)
const
{
// check if the type is valid (and throw if it isn't)
checkType
(
type
);
switch
(
type
)
{
case
Pool
::
TYPE_V4
:
case
Pool
::
TYPE_IA
:
return
(
pools_
);
case
Pool
::
TYPE_TA
:
return
(
pools_ta_
);
case
Pool
::
TYPE_PD
:
return
(
pools_pd_
);
default:
isc_throw
(
BadValue
,
"Unsupported pool type: "
<<
type
);
}
/// @todo: Check that pools do not overlap
pools_
.
push_back
(
pool
);
}
PoolPtr
Subnet
::
getPool
(
isc
::
asiolink
::
IOAddress
hint
)
{
PoolPtr
Subnet
::
getPool
(
Pool
::
PoolType
type
,
isc
::
asiolink
::
IOAddress
hint
)
{
// check if the type is valid (and throw if it isn't)
checkType
(
type
);
PoolCollection
*
pools
=
NULL
;
switch
(
type
)
{
case
Pool
::
TYPE_V4
:
case
Pool
::
TYPE_IA
:
pools
=
&
pools_
;
break
;
case
Pool
::
TYPE_TA
:
pools
=
&
pools_ta_