Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
38a25c7c
Commit
38a25c7c
authored
Nov 01, 2015
by
Tomek Mrugalski
🛰
Browse files
[4112] selectSubnet4o6 implemented + one unit-test
parent
3e7e0917
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcpsrv/Makefile.am
View file @
38a25c7c
...
...
@@ -85,6 +85,7 @@ 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
+=
base_host_data_source.h
libkea_dhcpsrv_la_SOURCES
+=
callout_handle_store.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_4o6.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_db_access.cc cfg_db_access.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_duid.cc cfg_duid.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_hosts.cc cfg_hosts.h
...
...
src/lib/dhcpsrv/cfg_4o6.h
0 → 100644
View file @
38a25c7c
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef CFG_4OVER6_H
#define CFG_4OVER6_H
#include <string>
#include <asiolink/io_address.h>
namespace
isc
{
namespace
dhcp
{
/// @brief This structure contains information about DHCP4o6 (RFC7341)
///
/// DHCP4o6 is completely optional. If it is not enabled, this structure
/// does not contain any information.
struct
Cfg4o6
{
/// the default constructor.
///
/// Initializes fields to their default value.
Cfg4o6
()
:
enabled_
(
false
),
subnet4o6_
(
std
::
make_pair
(
asiolink
::
IOAddress
(
"::"
),
128u
))
{
}
/// @brief Returns whether the DHCP4o6 is enabled or not.
/// @return true if enabled
bool
enabled
()
const
{
return
(
enabled_
);
}
/// @brief Sets the DHCP4o6 enabled status.
/// @param enabled specifies if the DHCP4o6 should be enabled or not
void
enabled
(
bool
enabled
)
{
enabled_
=
enabled
;
}
/// @brief Returns the DHCP4o6 interface.
/// @return value of the 4o6-interface parameter.
std
::
string
getIface4o6
()
const
{
return
(
iface4o6_
);
}
/// @brief Sets the 4o6-interface.
/// @param iface name of the network interface the 4o6 traffic is received on
void
setIface4o6
(
const
std
::
string
&
iface
)
{
iface4o6_
=
iface
;
enabled_
=
true
;
}
/// @brief Returns prefix/len for the IPv6 subnet.
/// @return prefix/length pair
std
::
pair
<
asiolink
::
IOAddress
,
uint8_t
>
getSubnet4o6
()
const
{
return
(
subnet4o6_
);
}
/// @brief Sets the prefix/length information (content of the 4o6-subnet).
/// @param subnet IOAddress that represents a prefix
/// @param prefix specifies prefix length
void
setSubnet4o6
(
const
asiolink
::
IOAddress
&
subnet
,
uint8_t
prefix
)
{
subnet4o6_
=
std
::
make_pair
(
subnet
,
prefix
);
enabled_
=
true
;
}
/// @brief Returns the interface-id.
/// @return the option representing interface-id (or NULL)
OptionPtr
getInterfaceId
()
const
{
return
(
interface_id_
);
}
/// @brief Sets the interface-id
/// @param opt option to be used as interface-id match
void
setInterfaceId
(
const
OptionPtr
&
opt
)
{
interface_id_
=
opt
;
enabled_
=
true
;
}
private:
/// Specifies if 4o6 is enabled on this subnet.
bool
enabled_
;
/// Specifies the network interface used as v4 subnet selector.
std
::
string
iface4o6_
;
/// Specifies the IPv6 subnet used for v4 subnet selection.
std
::
pair
<
asiolink
::
IOAddress
,
uint8_t
>
subnet4o6_
;
/// Specifies the v6 interface-id used for v4 subnet selection.
OptionPtr
interface_id_
;
};
}
// end of isc::dhcp namespace
}
// end of isc namespace
#endif
src/lib/dhcpsrv/cfg_subnets4.cc
View file @
38a25c7c
...
...
@@ -9,6 +9,8 @@
#include <dhcpsrv/cfg_subnets4.h>
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/addr_utilities.h>
#include <asiolink/io_address.h>
#include <stats/stats_mgr.h>
using
namespace
isc
::
asiolink
;
...
...
@@ -29,8 +31,55 @@ CfgSubnets4::add(const Subnet4Ptr& subnet) {
subnets_
.
push_back
(
subnet
);
}
Subnet4Ptr
CfgSubnets4
::
selectSubnet4o6
(
const
SubnetSelector
&
selector
)
const
{
for
(
Subnet4Collection
::
const_iterator
subnet
=
subnets_
.
begin
();
subnet
!=
subnets_
.
end
();
++
subnet
)
{
Cfg4o6
&
cfg4o6
=
(
*
subnet
)
->
get4o6
();
// Is this an 4o6 subnet at all?
if
(
!
cfg4o6
.
enabled
())
{
continue
;
// No? Let's try the next one.
}
// First match criteria: check if we have a prefix/len defined.
std
::
pair
<
asiolink
::
IOAddress
,
uint8_t
>
pref
=
cfg4o6
.
getSubnet4o6
();
if
(
pref
.
first
!=
IOAddress
::
IPV6_ZERO_ADDRESS
())
{
// Let's check if the IPv6 address is in range
IOAddress
first
=
firstAddrInPrefix
(
pref
.
first
,
pref
.
second
);
IOAddress
last
=
lastAddrInPrefix
(
pref
.
first
,
pref
.
second
);
if
((
first
<=
selector
.
remote_address_
)
&&
(
selector
.
remote_address_
<=
last
))
{
return
(
*
subnet
);
}
}
// Second match criteria: check if the interface-id matches
if
(
cfg4o6
.
getInterfaceId
()
&&
selector
.
interface_id_
&&
cfg4o6
.
getInterfaceId
()
->
equals
(
selector
.
interface_id_
))
{
return
(
*
subnet
);
}
// Third match criteria: check if the interface name matches
if
(
!
cfg4o6
.
getIface4o6
().
empty
()
&&
!
selector
.
iface_name_
.
empty
()
&&
cfg4o6
.
getIface4o6
()
==
selector
.
iface_name_
)
{
return
(
*
subnet
);
}
}
// Ok, wasn't able to find any matching subnet.
return
(
Subnet4Ptr
());
}
Subnet4Ptr
CfgSubnets4
::
selectSubnet
(
const
SubnetSelector
&
selector
)
const
{
if
(
selector
.
dhcp4o6_
)
{
return
selectSubnet4o6
(
selector
);
}
// First use RAI link select sub-option or subnet select option
if
(
!
selector
.
option_select_
.
isV4Zero
())
{
return
(
selectSubnet
(
selector
.
option_select_
,
...
...
src/lib/dhcpsrv/cfg_subnets4.h
View file @
38a25c7c
...
...
@@ -147,6 +147,27 @@ private:
/// @return true if the duplicate subnet exists.
bool
isDuplicate
(
const
Subnet4
&
subnet
)
const
;
/// @brief Attempts to do subnet selection based on DHCP4o6 information
///
/// The algorithm implemented is as follows:
///
/// - First: try to match IPv6 subnet (4o6-subnet parameter) with the
/// remote IPv6 address of the incoming packet
/// - Second: try to match interface-id (4o6-interface-id parameter)
/// with the interface-id option in the incoming 4o6 packet
/// - Third: try to match interface-name (4o6-interface parameter)
/// with the name of the interface the incoming 4o6 packet was
/// received over.
///
/// @todo: Add additional selection criteria. See
/// http://kea.isc.org/wiki/ISC-DHCP4o6-Design for details.
///
/// @param selector
/// @return selected IPv4 subnet
Subnet4Ptr
selectSubnet4o6
(
const
SubnetSelector
&
selector
)
const
;
/// @brief A container for IPv4 subnets.
Subnet4Collection
subnets_
;
...
...
src/lib/dhcpsrv/subnet.h
View file @
38a25c7c
...
...
@@ -12,6 +12,7 @@
#include <dhcp/classify.h>
#include <dhcp/option_space_container.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/cfg_4o6.h>
#include <dhcpsrv/pool.h>
#include <dhcpsrv/triplet.h>
#include <dhcpsrv/lease.h>
...
...
@@ -499,82 +500,6 @@ private:
/// @brief A generic pointer to either Subnet4 or Subnet6 object
typedef
boost
::
shared_ptr
<
Subnet
>
SubnetPtr
;
/// @brief This structure contains information about DHCP4o6 (RFC7341)
///
/// DHCP4o6 is completely optional. If it is not enabled, this structure
/// does not contain any information.
struct
Cfg4o6
{
/// the default constructor.
///
/// Initializes fields to their default value.
Cfg4o6
()
:
enabled_
(
false
),
subnet4o6_
(
std
::
make_pair
(
asiolink
::
IOAddress
(
"::"
),
128u
))
{
}
/// @brief Returns whether the DHCP4o6 is enabled or not.
/// @return true if enabled
bool
enabled
()
const
{
return
(
enabled_
);
}
/// @brief Sets the DHCP4o6 enabled status.
/// @param enabled specifies if the DHCP4o6 should be enabled or not
void
enabled
(
bool
enabled
)
{
enabled_
=
enabled
;
}
/// @brief Returns the DHCP4o6 interface.
/// @return value of the 4o6-interface parameter.
std
::
string
getIface4o6
()
const
{
return
(
iface4o6_
);
}
/// @brief Sets the 4o6-interface.
/// @param iface name of the network interface the 4o6 traffic is received on
void
setIface4o6
(
const
std
::
string
&
iface
)
{
iface4o6_
=
iface
;
}
/// @brief Returns prefix/len for the IPv6 subnet.
/// @return prefix/length pair
std
::
pair
<
asiolink
::
IOAddress
,
uint8_t
>
getSubnet4o6
()
const
{
return
(
subnet4o6_
);
}
/// @brief Sets the prefix/length information (content of the 4o6-subnet).
/// @param subnet IOAddress that represents a prefix
/// @param prefix specifies prefix length
void
setSubnet4o6
(
const
asiolink
::
IOAddress
&
subnet
,
uint8_t
prefix
)
{
subnet4o6_
=
std
::
make_pair
(
subnet
,
prefix
);
}
/// @brief Returns the interface-id.
/// @return the option representing interface-id (or NULL)
OptionPtr
getInterfaceId
()
const
{
return
(
interface_id_
);
}
/// @brief Sets the interface-id
/// @param opt option to be used as interface-id match
void
setInterfaceId
(
const
OptionPtr
&
opt
)
{
interface_id_
=
opt
;
}
private:
/// Specifies if 4o6 is enabled on this subnet.
bool
enabled_
;
/// Specifies the network interface used as v4 subnet selector.
std
::
string
iface4o6_
;
/// Specifies the IPv6 subnet used for v4 subnet selection.
std
::
pair
<
asiolink
::
IOAddress
,
uint8_t
>
subnet4o6_
;
/// Specifies the v6 interface-id used for v4 subnet selection.
OptionPtr
interface_id_
;
};
/// @brief A configuration holder for IPv4 subnet.
///
...
...
src/lib/dhcpsrv/subnet_selector.h
View file @
38a25c7c
...
...
@@ -48,6 +48,9 @@ struct SubnetSelector {
/// @brief Name of the interface on which the message was received.
std
::
string
iface_name_
;
/// @brief Specifies if the packet is DHCP4o6
bool
dhcp4o6_
;
/// @brief Default constructor.
///
/// Sets the default values for the @c Selector.
...
...
@@ -59,7 +62,8 @@ struct SubnetSelector {
first_relay_linkaddr_
(
asiolink
::
IOAddress
(
"::"
)),
local_address_
(
asiolink
::
IOAddress
(
"0.0.0.0"
)),
remote_address_
(
asiolink
::
IOAddress
(
"0.0.0.0"
)),
client_classes_
(),
iface_name_
(
std
::
string
())
{
client_classes_
(),
iface_name_
(
std
::
string
()),
dhcp4o6_
(
false
)
{
}
};
...
...
src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc
View file @
38a25c7c
...
...
@@ -318,5 +318,28 @@ TEST(CfgSubnets4Test, duplication) {
EXPECT_THROW
(
cfg
.
add
(
subnet3
),
isc
::
dhcp
::
DuplicateSubnetID
);
}
// This test checks if the IPv4 subnet can be selected based on the IPv6 address.
TEST
(
CfgSubnets4Test
,
4
o6subnet
)
{
CfgSubnets4
cfg
;
Subnet4Ptr
subnet1
(
new
Subnet4
(
IOAddress
(
"192.0.2.0"
),
26
,
1
,
2
,
3
,
123
));
Subnet4Ptr
subnet2
(
new
Subnet4
(
IOAddress
(
"192.0.2.64"
),
26
,
1
,
2
,
3
,
124
));
Subnet4Ptr
subnet3
(
new
Subnet4
(
IOAddress
(
"192.0.2.128"
),
26
,
1
,
2
,
3
,
125
));
subnet2
->
get4o6
().
setSubnet4o6
(
IOAddress
(
"2001:db8:1::"
),
48
);
subnet3
->
get4o6
().
setSubnet4o6
(
IOAddress
(
"2001:db8:2::"
),
48
);
cfg
.
add
(
subnet1
);
cfg
.
add
(
subnet2
);
cfg
.
add
(
subnet3
);
SubnetSelector
selector
;
selector
.
dhcp4o6_
=
true
;
selector
.
remote_address_
=
IOAddress
(
"2001:db8:1::dead:beef"
);
EXPECT_EQ
(
subnet2
,
cfg
.
selectSubnet
(
selector
));
}
}
// end of anonymous namespace
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment