mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-29 21:18:02 +00:00
[master] Merge branch 'trac3554' (mac-sources parameter added)
This commit is contained in:
commit
2e7c32e7c1
@ -9,6 +9,7 @@ nobase_dist_doc_DATA += examples/kea4/reservations.json
|
||||
nobase_dist_doc_DATA += examples/kea6/simple.json
|
||||
nobase_dist_doc_DATA += examples/kea6/several-subnets.json
|
||||
nobase_dist_doc_DATA += examples/kea6/multiple-options.json
|
||||
nobase_dist_doc_DATA += examples/kea6/advanced.json
|
||||
nobase_dist_doc_DATA += examples/ddns/sample1.json
|
||||
nobase_dist_doc_DATA += examples/ddns/template.json
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
{ "Dhcp4":
|
||||
|
||||
{
|
||||
# Kea is told to listen on eth0 interface only.
|
||||
"interfaces": [ "eth0" ],
|
||||
# Kea is told to listen on ethX interface only.
|
||||
"interfaces": [ "ethX" ],
|
||||
|
||||
# We need to specify lease type. As of May 2014, three backends are supported:
|
||||
# memfile, mysql and pgsql. We'll just use memfile, because it doesn't require
|
||||
@ -36,7 +36,7 @@
|
||||
{
|
||||
"pools": [ { "pool": "192.0.2.10 - 192.0.2.200" } ],
|
||||
"subnet": "192.0.2.0/24",
|
||||
"interface": "eth0",
|
||||
"interface": "ethX",
|
||||
"option-data": [
|
||||
{
|
||||
"name": "domain-name-servers",
|
||||
|
@ -5,8 +5,8 @@
|
||||
{ "Dhcp4":
|
||||
|
||||
{
|
||||
# Kea is told to listen on eth0 interface only.
|
||||
"interfaces": [ "eth0" ],
|
||||
# Kea is told to listen on ethX interface only.
|
||||
"interfaces": [ "ethX" ],
|
||||
|
||||
# We need to specify lease type. As of May 2014, three backends are supported:
|
||||
# memfile, mysql and pgsql. We'll just use memfile, because it doesn't require
|
||||
|
@ -5,8 +5,8 @@
|
||||
{ "Dhcp4":
|
||||
|
||||
{
|
||||
# Kea is told to listen on eth0 interface only.
|
||||
"interfaces": [ "eth0" ],
|
||||
# Kea is told to listen on ethX interface only.
|
||||
"interfaces": [ "ethX" ],
|
||||
|
||||
# We need to specify lease type. As of May 2014, three backends are supported:
|
||||
# memfile, mysql and pgsql. We'll just use memfile, because it doesn't require
|
||||
@ -35,8 +35,8 @@
|
||||
{
|
||||
"pools": [ { "pool": "192.0.2.1 - 192.0.2.200" } ],
|
||||
"subnet": "192.0.2.0/24",
|
||||
"interface": "eth0"
|
||||
}
|
||||
"interface": "ethX"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
79
doc/examples/kea6/advanced.json
Normal file
79
doc/examples/kea6/advanced.json
Normal file
@ -0,0 +1,79 @@
|
||||
# This is an example configuration file for DHCPv6 server in Kea.
|
||||
# It attempts to showcase some of the more advanced features.
|
||||
# Topology wise, it's a basic scenario with one IPv6 subnet configured.
|
||||
# It is assumed that one subnet (2001:db8:1::/64) is available directly
|
||||
# over ethX interface.
|
||||
#
|
||||
# The following features are currently showcased here:
|
||||
# 1. Configuration of MAC/hardware address sources in DHCPv6
|
||||
|
||||
{ "Dhcp6":
|
||||
|
||||
{
|
||||
# Kea is told to listen on ethX network interface only.
|
||||
"interfaces": [ "ethX" ],
|
||||
|
||||
# We need to specify lease type. As of May 2014, three backends are supported:
|
||||
# memfile, mysql and pgsql. We'll just use memfile, because it doesn't require
|
||||
# any prior set up.
|
||||
"lease-database": {
|
||||
"type": "memfile"
|
||||
},
|
||||
|
||||
# Kea 0.9.1 introduced MAC/hardware addresses support in DHCPv6. There is
|
||||
# no single reliable method of getting MAC address information in DHCPv6.
|
||||
# Kea supports several methods. Depending on your network set up, some
|
||||
# methods may be more preferable than others, hence the configuration
|
||||
# parameter. 'mac-sources' is a list of methods. Allowed parameters are:
|
||||
# any, raw, duid, ipv6-link-local, client-link-addr-option, rfc6939 (which
|
||||
# is an alias for client-link-addr-option), remote-id, rfc4649 (which is an
|
||||
# alias for remote-id, subscriber-id, rfc4580 (which is an alias for
|
||||
# subscriber-id) and docsis.
|
||||
#
|
||||
# Note that the order matters. Methods are attempted one by one in the order
|
||||
# specified until hardware address is obtained. If you don't care which method
|
||||
# is used, using 'any' is marginally faster than enumerating them all.
|
||||
#
|
||||
# If mac-sources are not specified, a default value of 'any' is used.
|
||||
"mac-sources": [ "client-link-addr-option", "duid", "ipv6-link-local" ],
|
||||
|
||||
# Addresses will be assigned with preferred and valid lifetimes
|
||||
# being 3000 and 4000, respectively. Client is told to start
|
||||
# renewing after 1000 seconds. If the server does not repond
|
||||
# after 2000 seconds since the lease was granted, client is supposed
|
||||
# to start REBIND procedure (emergency renewal that allows switching
|
||||
# to a different server).
|
||||
"preferred-lifetime": 3000,
|
||||
"valid-lifetime": 4000,
|
||||
"renew-timer": 1000,
|
||||
"rebind-timer": 2000,
|
||||
|
||||
# The following list defines subnets. Each subnet consists of at
|
||||
# least subnet and pool entries.
|
||||
"subnet6": [
|
||||
{
|
||||
"pools": [ { "pool": "2001:db8:1::/80" } ],
|
||||
"subnet": "2001:db8:1::/64",
|
||||
"interface": "ethX"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
# The following configures logging. Kea will log all debug messages
|
||||
# to /var/log/kea-debug.log file.
|
||||
"Logging": {
|
||||
"loggers": [
|
||||
{
|
||||
"name": "kea-dhcp6",
|
||||
"output_options": [
|
||||
{
|
||||
"output": "/var/log/kea-debug.log"
|
||||
}
|
||||
],
|
||||
"debuglevel": 99,
|
||||
"severity": "DEBUG"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
@ -4,8 +4,8 @@
|
||||
{ "Dhcp6":
|
||||
|
||||
{
|
||||
# Kea is told to listen on eth0 interface only.
|
||||
"interfaces": [ "eth0" ],
|
||||
# Kea is told to listen on ethX interface only.
|
||||
"interfaces": [ "ethX" ],
|
||||
|
||||
# We need to specify lease type. As of May 2014, three backends are supported:
|
||||
# memfile, mysql and pgsql. We'll just use memfile, because it doesn't require
|
||||
@ -32,7 +32,7 @@
|
||||
{
|
||||
"pools": [ { "pool": "2001:db8:1::/80" } ],
|
||||
"subnet": "2001:db8:1::/64",
|
||||
"interface": "eth0",
|
||||
"interface": "ethX",
|
||||
"option-data": [
|
||||
{
|
||||
"name": "dns-servers",
|
||||
|
@ -5,8 +5,8 @@
|
||||
{ "Dhcp6":
|
||||
|
||||
{
|
||||
# Kea is told to listen on eth0 interface only.
|
||||
"interfaces": [ "eth0" ],
|
||||
# Kea is told to listen on ethX interface only.
|
||||
"interfaces": [ "ethX" ],
|
||||
|
||||
# We need to specify lease type. As of May 2014, three backends are supported:
|
||||
# memfile, mysql and pgsql. We'll just use memfile, because it doesn't require
|
||||
|
@ -1,13 +1,13 @@
|
||||
# This is an example configuration file for DHCPv6 server in Kea.
|
||||
# It's a basic scenario with four IPv6 subnets configured. It is
|
||||
# It's a basic scenario with one IPv6 subnet configured. It is
|
||||
# assumed that one subnet (2001:db8:1::/64 is available directly
|
||||
# over eth0 interface.
|
||||
# over ethX interface.
|
||||
|
||||
{ "Dhcp6":
|
||||
|
||||
{
|
||||
# Kea is told to listen on eth0 interface only.
|
||||
"interfaces": [ "eth0" ],
|
||||
# Kea is told to listen on ethX interface only.
|
||||
"interfaces": [ "ethX" ],
|
||||
|
||||
# We need to specify lease type. As of May 2014, three backends are supported:
|
||||
# memfile, mysql and pgsql. We'll just use memfile, because it doesn't require
|
||||
@ -33,7 +33,7 @@
|
||||
{
|
||||
"pools": [ { "pool": "2001:db8:1::/80" } ],
|
||||
"subnet": "2001:db8:1::/64",
|
||||
"interface": "eth0"
|
||||
"interface": "ethX"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1838,6 +1838,117 @@ should include options from the isc option space:
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="mac-in-dhcpv6">
|
||||
<title>MAC/Hardware addresses in DHCPv6</title>
|
||||
<para>MAC/hardware addesses are available in DHCPv4 messages
|
||||
from the clients and administrators
|
||||
frequently use that information to perform certain tasks, like per host
|
||||
configuration, address reserveration for specific MAC addresses and other.
|
||||
Unfortunately, DHCPv6 protocol does not provide any completely reliable way
|
||||
to retrieve that information. To mitigate that issue a number of mechanisms
|
||||
have been implemented in Kea that attempt to gather that information. Each
|
||||
of those mechanisms works in certain cases, but may fail in other cases.
|
||||
Whether the mechanism works or not in the particular deployment is
|
||||
somewhat dependent on the network topology and the technologies used.</para>
|
||||
|
||||
<para>Kea allows for configuration which of the supported methods should be
|
||||
used and in which order. This configuration may be considered a fine tuning
|
||||
of the DHCP deployment. In a typical deployment the default
|
||||
value of <command>"any"</command> is sufficient and there is no
|
||||
need to select specific methods. Changing the value of this parameter
|
||||
is the most useful in cases when an administrator wants to disable
|
||||
certain method, e.g. if the administrator trusts the network infrastructure
|
||||
more than the information provided by the clients themselves, the
|
||||
administrator may prefer information provided by the relays over that
|
||||
provided by the clients. The format of this parameter is as follows:
|
||||
<screen>
|
||||
"Dhcp6": {
|
||||
<userinput>"mac-sources": [ "method1", "method2", "method3", ... ]</userinput>,
|
||||
|
||||
"subnet6": [ ... ],
|
||||
|
||||
...
|
||||
}
|
||||
</screen>
|
||||
|
||||
When not specified, a special value of <emphasis>any</emphasis> is used, which
|
||||
instructs the server to attempt to use all the methods in sequence and use
|
||||
value returned by the first one that succeeds.</para>
|
||||
|
||||
<para>Supported methods are:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><command>any</command> - not an actual method, just a keyword that
|
||||
instructs Kea to try all other methods and use the first one that succeeds.
|
||||
This is the default operation if no <command>mac-sources</command> are defined.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>raw</command> In principle, a DHCPv6 server could use raw
|
||||
sockets to receive incoming traffic and extract MAC/hardware address
|
||||
information. This is currently not implemented and this value has no effect.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>duid</command> - DHCPv6 uses DUID identifiers instead of
|
||||
MAC addresses. There are currently four DUID types defined, with two of them
|
||||
(DUID-LLT, which is the default one and DUID-LL) convey MAC address information.
|
||||
Although RFC3315 forbids it, it is possible to parse those DUIDs and extract
|
||||
necessary information from them. This method is not completely reliable, as
|
||||
clients may use other DUID types, namely DUID-EN or DUID-UUID.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>ipv6-link-local</command> - Another possible aquisition
|
||||
method comes from the source IPv6 address. In typical usage, clients are
|
||||
sending their packets from IPv6 link-local addresses. There's a good chance
|
||||
that those addresses are based on EUI-64, which contains MAC address. This
|
||||
method is not completely reliable, as clients may use other link-local address
|
||||
types. In particular, privacy extensions, defined in RFC4941, do not use
|
||||
MAC addresses.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>client-link-addr-option</command> - One extension defined
|
||||
to alleviate missing MAC issues is client link-layer address option, defined
|
||||
in <ulink url="http://tools.ietf.org/html/rfc6939">RFC 6939</ulink>. This is
|
||||
an option that is inserted by a relay and contains information about client's
|
||||
MAC address. This method requires a relay agent that supports the option and
|
||||
is configured to insert it. This method is useless for directly connected
|
||||
clients. This parameter can also be specified as <command>rfc6939</command>,
|
||||
which is an alias for <command>client-link-addr-option</command>.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>remote-id</command> <ulink
|
||||
url="http://tools.ietf.org/html/rfc4649">RFC 4649</ulink>
|
||||
defines remote-id option that is inserted by a relay agent. Depending
|
||||
on the relay agent configuration, the inserted option may convey client's
|
||||
MAC address information. This parameter can also be specified as
|
||||
<command>rfc4649</command>, which is an alias for <command>remote-id</command>.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>subscriber-id</command> - Another option
|
||||
that is somewhat similar to the previous one is subscriber-id,
|
||||
defined in <ulink url="http://tools.ietf.org/html/rfc4580">RFC
|
||||
4580</ulink>. It is, too, inserted by a relay agent that is
|
||||
configured to insert it. This parameter can also be specified
|
||||
as <command>rfc4580</command>, which is an alias for
|
||||
<command>subscriber-id</command>. This method is currently not
|
||||
implemented.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>docsis</command> - Yet another possible source of MAC
|
||||
address information are DOCSIS options inserted by a CMTS that acts
|
||||
as a DHCPv6 relay agent in cable networks. This method is
|
||||
currently not implemented.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="dhcp6-std">
|
||||
<title>Supported DHCPv6 Standards</title>
|
||||
|
@ -422,6 +422,21 @@
|
||||
} ]
|
||||
}
|
||||
},
|
||||
|
||||
{ "item_name": "mac-sources",
|
||||
"item_type": "list",
|
||||
"item_optional": true,
|
||||
"item_default": [ "any" ],
|
||||
"item_description": "Lists MAC/hardware address acquisition sources",
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "source",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "any"
|
||||
}
|
||||
} ,
|
||||
|
||||
{ "item_name": "dhcp-ddns",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
|
@ -1184,6 +1184,21 @@ Dhcpv6Srv::createRemovalNameChangeRequest(const Lease6Ptr& lease) {
|
||||
CfgMgr::instance().getD2ClientMgr().sendRequest(ncr);
|
||||
}
|
||||
|
||||
HWAddrPtr
|
||||
Dhcpv6Srv::getMAC(const Pkt6Ptr& pkt) {
|
||||
CfgMACSources mac_sources = CfgMgr::instance().getCurrentCfg()->
|
||||
getMACSources().get();
|
||||
HWAddrPtr hwaddr;
|
||||
for (CfgMACSources::const_iterator it = mac_sources.begin();
|
||||
it != mac_sources.end(); ++it) {
|
||||
hwaddr = pkt->getMAC(*it);
|
||||
if (hwaddr) {
|
||||
return (hwaddr);
|
||||
}
|
||||
}
|
||||
return (hwaddr);
|
||||
}
|
||||
|
||||
OptionPtr
|
||||
Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
||||
const Pkt6Ptr& query, const Pkt6Ptr& answer,
|
||||
@ -1253,10 +1268,9 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
||||
hostname = fqdn->getDomainName();
|
||||
}
|
||||
|
||||
// Attempt to get MAC address using any of available mechanisms.
|
||||
// It's ok if there response is NULL. Hardware address is optional in Lease6
|
||||
/// @todo: Make this configurable after trac 3554 is done.
|
||||
HWAddrPtr hwaddr = query->getMAC(Pkt::HWADDR_SOURCE_ANY);
|
||||
// Attempt to get MAC address using configured mechanisms.
|
||||
// It's ok if there response is NULL. Hardware address is optional in Lease6.
|
||||
HWAddrPtr hwaddr = getMAC(query);
|
||||
|
||||
// Use allocation engine to pick a lease for this client. Allocation engine
|
||||
// will try to honour the hint, but it is just a hint - some other address
|
||||
@ -1376,8 +1390,7 @@ Dhcpv6Srv::assignIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
||||
|
||||
// Attempt to get MAC address using any of available mechanisms.
|
||||
// It's ok if there response is NULL. Hardware address is optional in Lease6
|
||||
/// @todo: Make this configurable after trac 3554 is done.
|
||||
HWAddrPtr hwaddr = query->getMAC(Pkt::HWADDR_SOURCE_ANY);
|
||||
HWAddrPtr hwaddr = getMAC(query);
|
||||
|
||||
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_PROCESS_IA_PD_REQUEST)
|
||||
.arg(duid ? duid->toText() : "(no-duid)").arg(ia->getIAID())
|
||||
@ -1569,6 +1582,9 @@ Dhcpv6Srv::extendIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
||||
lease->fqdn_fwd_ = do_fwd;
|
||||
lease->fqdn_rev_ = do_rev;
|
||||
|
||||
/// @todo: check if hardware address has changed since last update.
|
||||
/// And modify lease->hwaddr_ if it did.
|
||||
|
||||
ia_rsp->setT1(subnet->getT1());
|
||||
ia_rsp->setT2(subnet->getT2());
|
||||
|
||||
|
@ -596,6 +596,14 @@ protected:
|
||||
/// @param pkt packet to be classified
|
||||
void classifyPacket(const Pkt6Ptr& pkt);
|
||||
|
||||
/// @brief Attempts to get a MAC/hardware address using configred sources
|
||||
///
|
||||
/// Tries to extract MAC/hardware address information from the packet
|
||||
/// using MAC sources configured in 'mac-sources' configuration parameter.
|
||||
///
|
||||
/// @param pkt will try to exact MAC address from this packet
|
||||
/// @return HWaddr pointer (or NULL if configured methods fail)
|
||||
static HWAddrPtr getMAC(const Pkt6Ptr& pkt);
|
||||
|
||||
/// @brief this is a prefix added to the contend of vendor-class option
|
||||
///
|
||||
|
@ -613,6 +613,9 @@ namespace dhcp {
|
||||
parser = new HooksLibrariesParser(config_id);
|
||||
} else if (config_id.compare("dhcp-ddns") == 0) {
|
||||
parser = new D2ClientConfigParser(config_id);
|
||||
} else if (config_id.compare("mac-sources") == 0) {
|
||||
parser = new MACSourcesListConfigParser(config_id,
|
||||
globalContext());
|
||||
} else {
|
||||
isc_throw(DhcpConfigError,
|
||||
"unsupported global configuration parameter: "
|
||||
|
@ -15,9 +15,6 @@
|
||||
#ifndef DHCP6_CONFIG_PARSER_H
|
||||
#define DHCP6_CONFIG_PARSER_H
|
||||
|
||||
/// @todo: This header file and its .cc counterpart are very similar between
|
||||
/// DHCPv4 and DHCPv6. They should be merged. See ticket #2355.
|
||||
|
||||
#include <cc/data.h>
|
||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
|
@ -3627,4 +3627,79 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
|
||||
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that configuration can include
|
||||
/// MAC/Hardware sources. This test also checks if the aliases are
|
||||
/// handled properly (rfc6939 = client-addr-relay, rfc4649 = remote-id,
|
||||
/// rfc4580 = subscriber-id).
|
||||
TEST_F(Dhcp6ParserTest, macSources) {
|
||||
|
||||
ConstElementPtr status;
|
||||
|
||||
EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
|
||||
Element::fromJSON("{ \"interfaces\": [ \"*\" ],"
|
||||
"\"mac-sources\": [ \"rfc6939\", \"rfc4649\", \"rfc4580\","
|
||||
"\"client-link-addr-option\", \"remote-id\", \"subscriber-id\"],"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ ], "
|
||||
"\"valid-lifetime\": 4000 }")));
|
||||
|
||||
// returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
|
||||
CfgMACSources mac_sources = CfgMgr::instance().getStagingCfg()->getMACSources().get();
|
||||
ASSERT_EQ(6, mac_sources.size());
|
||||
// Let's check the aliases. They should be recognized to their base methods.
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION, mac_sources[0]);
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_REMOTE_ID, mac_sources[1]);
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID, mac_sources[2]);
|
||||
|
||||
// Let's check if the actual methods are recognized properly.
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION, mac_sources[3]);
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_REMOTE_ID, mac_sources[4]);
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID, mac_sources[5]);
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that MAC sources configuration can be
|
||||
/// empty.
|
||||
TEST_F(Dhcp6ParserTest, macSourcesEmpty) {
|
||||
|
||||
ConstElementPtr status;
|
||||
|
||||
EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
|
||||
Element::fromJSON("{ \"interfaces\": [ \"*\" ],"
|
||||
"\"mac-sources\": [ ],"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ ], "
|
||||
"\"valid-lifetime\": 4000 }")));
|
||||
|
||||
// returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
|
||||
CfgMACSources mac_sources = CfgMgr::instance().getStagingCfg()->getMACSources().get();
|
||||
EXPECT_EQ(0, mac_sources.size());
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that MAC sources configuration can
|
||||
/// only use valid parameters.
|
||||
TEST_F(Dhcp6ParserTest, macSourcesBogus) {
|
||||
|
||||
ConstElementPtr status;
|
||||
|
||||
EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
|
||||
Element::fromJSON("{ \"interfaces\": [ \"*\" ],"
|
||||
"\"mac-sources\": [ \"from-wire\" ],"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ ], "
|
||||
"\"valid-lifetime\": 4000 }")));
|
||||
|
||||
// returned value should be 1 (failure)
|
||||
checkResult(status, 1);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ Dhcp6Client::applyRcvdConfiguration(const Pkt6Ptr& reply) {
|
||||
Opts opts = reply->options_;
|
||||
|
||||
// Let's try to get a MAC
|
||||
HWAddrPtr hwaddr = reply->getMAC(Pkt::HWADDR_SOURCE_ANY);
|
||||
HWAddrPtr hwaddr = reply->getMAC(HWAddr::HWADDR_SOURCE_ANY);
|
||||
|
||||
// Set the global status code to default: success and not received.
|
||||
config_.resetGlobalStatusCode();
|
||||
|
@ -27,6 +27,16 @@
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_ANY = 0xffffffff;
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_UNKNOWN = 0x00000000;
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_RAW = 0x00000001;
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_DUID = 0x00000002;
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL = 0x00000004;
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION = 0x00000008;
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_REMOTE_ID = 0x00000010;
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID = 0x00000020;
|
||||
const uint32_t HWAddr::HWADDR_SOURCE_DOCSIS = 0x00000040;
|
||||
|
||||
HWAddr::HWAddr()
|
||||
:htype_(HTYPE_ETHER), source_(0) {
|
||||
}
|
||||
|
@ -34,6 +34,53 @@ public:
|
||||
/// @brief Maximum size of a hardware address.
|
||||
static const size_t MAX_HWADDR_LEN = 20;
|
||||
|
||||
/// @defgroup hw_sources Specifies where a given MAC/hardware address was
|
||||
/// obtained.
|
||||
///
|
||||
/// @brief The list covers all possible MAC/hw address sources.
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Not really a type, only used in getMAC() calls.
|
||||
static const uint32_t HWADDR_SOURCE_ANY;
|
||||
|
||||
/// Used when actual origin is not known, e.g. when reading from a
|
||||
/// lease database that didn't store that information.
|
||||
static const uint32_t HWADDR_SOURCE_UNKNOWN;
|
||||
|
||||
/// Obtained first hand from raw socket (100% reliable).
|
||||
static const uint32_t HWADDR_SOURCE_RAW;
|
||||
|
||||
/// Extracted from DUID-LL or DUID-LLT (not 100% reliable as the client
|
||||
/// can send fake DUID).
|
||||
static const uint32_t HWADDR_SOURCE_DUID;
|
||||
|
||||
/// Extracted from IPv6 link-local address. Not 100% reliable, as the
|
||||
/// client can use different IID other than EUI-64, e.g. Windows supports
|
||||
/// RFC4941 and uses random values instead of EUI-64.
|
||||
static const uint32_t HWADDR_SOURCE_IPV6_LINK_LOCAL;
|
||||
|
||||
/// Get it from RFC6939 option. (A relay agent can insert client link layer
|
||||
/// address option). Note that a skilled attacker can fake that by sending
|
||||
/// his request relayed, so the legitimate relay will think it's a second
|
||||
/// relay.
|
||||
static const uint32_t HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION;
|
||||
|
||||
/// A relay can insert remote-id. In some deployments it contains a MAC
|
||||
/// address (RFC4649).
|
||||
static const uint32_t HWADDR_SOURCE_REMOTE_ID;
|
||||
|
||||
/// A relay can insert a subscriber-id option. In some deployments it
|
||||
/// contains a MAC address (RFC4580).
|
||||
static const uint32_t HWADDR_SOURCE_SUBSCRIBER_ID;
|
||||
|
||||
/// A CMTS (acting as DHCP relay agent) that supports DOCSIS standard
|
||||
/// can insert DOCSIS options that contain client's MAC address.
|
||||
/// Client in this context would be a cable modem.
|
||||
static const uint32_t HWADDR_SOURCE_DOCSIS;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @brief default constructor
|
||||
HWAddr();
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <utility>
|
||||
#include <dhcp/pkt.h>
|
||||
#include <dhcp/iface_mgr.h>
|
||||
#include <dhcp/hwaddr.h>
|
||||
#include <vector>
|
||||
|
||||
namespace isc {
|
||||
@ -129,11 +130,11 @@ Pkt::getMAC(uint32_t hw_addr_src) {
|
||||
HWAddrPtr mac;
|
||||
|
||||
// Method 1: from raw sockets.
|
||||
if (hw_addr_src & HWADDR_SOURCE_RAW) {
|
||||
if (hw_addr_src & HWAddr::HWADDR_SOURCE_RAW) {
|
||||
mac = getRemoteHWAddr();
|
||||
if (mac) {
|
||||
return (mac);
|
||||
} else if (hw_addr_src == HWADDR_SOURCE_RAW) {
|
||||
} else if (hw_addr_src == HWAddr::HWADDR_SOURCE_RAW) {
|
||||
// If we're interested only in RAW sockets as source of that info,
|
||||
// there's no point in trying other options.
|
||||
return (HWAddrPtr());
|
||||
@ -143,11 +144,11 @@ Pkt::getMAC(uint32_t hw_addr_src) {
|
||||
// Method 2: Extracted from DUID-LLT or DUID-LL
|
||||
|
||||
// Method 3: Extracted from source IPv6 link-local address
|
||||
if (hw_addr_src & HWADDR_SOURCE_IPV6_LINK_LOCAL) {
|
||||
if (hw_addr_src & HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL) {
|
||||
mac = getMACFromSrcLinkLocalAddr();
|
||||
if (mac) {
|
||||
return (mac);
|
||||
} else if (hw_addr_src == HWADDR_SOURCE_IPV6_LINK_LOCAL) {
|
||||
} else if (hw_addr_src == HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL) {
|
||||
// If we're interested only in link-local addr as source of that
|
||||
// info, there's no point in trying other options.
|
||||
return (HWAddrPtr());
|
||||
@ -155,11 +156,11 @@ Pkt::getMAC(uint32_t hw_addr_src) {
|
||||
}
|
||||
|
||||
// Method 4: From client link-layer address option inserted by a relay
|
||||
if (hw_addr_src & HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION) {
|
||||
if (hw_addr_src & HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION) {
|
||||
mac = getMACFromIPv6RelayOpt();
|
||||
if (mac) {
|
||||
return (mac);
|
||||
} else if (hw_addr_src == HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION) {
|
||||
} else if (hw_addr_src == HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION) {
|
||||
// If we're interested only in RFC6939 link layer address as source
|
||||
// of that info, there's no point in trying other options.
|
||||
return (HWAddrPtr());
|
||||
@ -223,6 +224,5 @@ Pkt::getMACFromIPv6(const isc::asiolink::IOAddress& addr) {
|
||||
return (HWAddrPtr(new HWAddr(bin, hwtype)));
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
@ -37,58 +37,6 @@ namespace dhcp {
|
||||
/// @note This is abstract class. Please instantiate derived classes
|
||||
/// such as @c Pkt4 or @c Pkt6.
|
||||
class Pkt {
|
||||
public:
|
||||
|
||||
/// @defgroup hw_sources Specifies where a given MAC/hardware address was
|
||||
/// obtained.
|
||||
///
|
||||
/// @brief The list covers all possible MAC/hw address sources.
|
||||
///
|
||||
/// @note The uncommented ones are currently supported. When you implement
|
||||
/// a new method, please uncomment appropriate line here.
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Not really a type, only used in getMAC() calls.
|
||||
static const uint32_t HWADDR_SOURCE_ANY = 0xffff;
|
||||
|
||||
/// Used when actual origin is not known, e.g. when reading from a
|
||||
/// lease database that didn't store that information.
|
||||
static const uint32_t HWADDR_SOURCE_UNKNOWN = 0x0000;
|
||||
|
||||
/// Obtained first hand from raw socket (100% reliable).
|
||||
static const uint32_t HWADDR_SOURCE_RAW = 0x0001;
|
||||
|
||||
/// Extracted from DUID-LL or DUID-LLT (not 100% reliable as the client
|
||||
/// can send fake DUID).
|
||||
//static const uint32_t HWADDR_SOURCE_DUID = 0x0002;
|
||||
|
||||
/// Extracted from IPv6 link-local address. Not 100% reliable, as the
|
||||
/// client can use different IID other than EUI-64, e.g. Windows supports
|
||||
/// RFC4941 and uses random values instead of EUI-64.
|
||||
static const uint32_t HWADDR_SOURCE_IPV6_LINK_LOCAL = 0x0004;
|
||||
|
||||
/// Get it from RFC6939 option. (A relay agent can insert client link layer
|
||||
/// address option). Note that a skilled attacker can fake that by sending
|
||||
/// his request relayed, so the legitimate relay will think it's a second
|
||||
/// relay.
|
||||
static const uint32_t HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION = 0x0008;
|
||||
|
||||
/// A relay can insert remote-id. In some deployments it contains a MAC
|
||||
/// address (RFC4649).
|
||||
//static const uint32_t HWADDR_SOURCE_REMOTE_ID = 0x0010;
|
||||
|
||||
/// A relay can insert a subscriber-id option. In some deployments it
|
||||
/// contains a MAC address (RFC4580).
|
||||
//static const uint32_t HWADDR_SOURCE_SUBSCRIBER_ID = 0x0020;
|
||||
|
||||
/// A CMTS (acting as DHCP relay agent) that supports DOCSIS standard
|
||||
/// can insert DOCSIS options that contain client's MAC address.
|
||||
/// Client in this context would be a cable modem.
|
||||
//static const uint32_t HWADDR_SOURCE_DOCSIS_OPTIONS = 0x0040;
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
|
||||
/// @brief Constructor.
|
||||
|
@ -857,8 +857,8 @@ TEST_F(Pkt4Test, getMAC) {
|
||||
Pkt4 pkt(DHCPOFFER, 1234);
|
||||
|
||||
// DHCPv4 packet by default doens't have MAC address specified.
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_ANY));
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_RAW));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_ANY));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_RAW));
|
||||
|
||||
// Let's invent a MAC
|
||||
const uint8_t hw[] = { 2, 4, 6, 8, 10, 12 }; // MAC
|
||||
@ -869,12 +869,12 @@ TEST_F(Pkt4Test, getMAC) {
|
||||
pkt.setRemoteHWAddr(dummy_hwaddr);
|
||||
|
||||
// Now we should be able to get something
|
||||
ASSERT_TRUE(pkt.getMAC(Pkt::HWADDR_SOURCE_ANY));
|
||||
ASSERT_TRUE(pkt.getMAC(Pkt::HWADDR_SOURCE_RAW));
|
||||
ASSERT_TRUE(pkt.getMAC(HWAddr::HWADDR_SOURCE_ANY));
|
||||
ASSERT_TRUE(pkt.getMAC(HWAddr::HWADDR_SOURCE_RAW));
|
||||
|
||||
// Check that the returned MAC is indeed the expected one
|
||||
ASSERT_TRUE(*dummy_hwaddr == *pkt.getMAC(Pkt::HWADDR_SOURCE_ANY));
|
||||
ASSERT_TRUE(*dummy_hwaddr == *pkt.getMAC(Pkt::HWADDR_SOURCE_RAW));
|
||||
ASSERT_TRUE(*dummy_hwaddr == *pkt.getMAC(HWAddr::HWADDR_SOURCE_ANY));
|
||||
ASSERT_TRUE(*dummy_hwaddr == *pkt.getMAC(HWAddr::HWADDR_SOURCE_RAW));
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
@ -883,20 +883,20 @@ TEST_F(Pkt6Test, getMAC) {
|
||||
Pkt6 pkt(DHCPV6_ADVERTISE, 1234);
|
||||
|
||||
// DHCPv6 packet by default doens't have MAC address specified.
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_ANY));
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_RAW));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_ANY));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_RAW));
|
||||
|
||||
// We haven't specified source IPv6 address, so this method should
|
||||
// fail, too
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
|
||||
// Let's check if setting IPv6 address improves the situation.
|
||||
IOAddress linklocal_eui64("fe80::204:06ff:fe08:0a0c");
|
||||
pkt.setRemoteAddr(linklocal_eui64);
|
||||
EXPECT_TRUE(pkt.getMAC(Pkt::HWADDR_SOURCE_ANY));
|
||||
EXPECT_TRUE(pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
EXPECT_TRUE(pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL |
|
||||
Pkt::HWADDR_SOURCE_RAW));
|
||||
EXPECT_TRUE(pkt.getMAC(HWAddr::HWADDR_SOURCE_ANY));
|
||||
EXPECT_TRUE(pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
EXPECT_TRUE(pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL |
|
||||
HWAddr::HWADDR_SOURCE_RAW));
|
||||
pkt.setRemoteAddr(IOAddress("::"));
|
||||
|
||||
// Let's invent a MAC
|
||||
@ -908,14 +908,14 @@ TEST_F(Pkt6Test, getMAC) {
|
||||
pkt.setRemoteHWAddr(dummy_hwaddr);
|
||||
|
||||
// Now we should be able to get something
|
||||
ASSERT_TRUE(pkt.getMAC(Pkt::HWADDR_SOURCE_ANY));
|
||||
ASSERT_TRUE(pkt.getMAC(Pkt::HWADDR_SOURCE_RAW));
|
||||
EXPECT_TRUE(pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL |
|
||||
Pkt::HWADDR_SOURCE_RAW));
|
||||
ASSERT_TRUE(pkt.getMAC(HWAddr::HWADDR_SOURCE_ANY));
|
||||
ASSERT_TRUE(pkt.getMAC(HWAddr::HWADDR_SOURCE_RAW));
|
||||
EXPECT_TRUE(pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL |
|
||||
HWAddr::HWADDR_SOURCE_RAW));
|
||||
|
||||
// Check that the returned MAC is indeed the expected one
|
||||
ASSERT_TRUE(*dummy_hwaddr == *pkt.getMAC(Pkt::HWADDR_SOURCE_ANY));
|
||||
ASSERT_TRUE(*dummy_hwaddr == *pkt.getMAC(Pkt::HWADDR_SOURCE_RAW));
|
||||
ASSERT_TRUE(*dummy_hwaddr == *pkt.getMAC(HWAddr::HWADDR_SOURCE_ANY));
|
||||
ASSERT_TRUE(*dummy_hwaddr == *pkt.getMAC(HWAddr::HWADDR_SOURCE_RAW));
|
||||
}
|
||||
|
||||
// Test checks whether getMACFromIPv6LinkLocal() returns the hardware (MAC)
|
||||
@ -941,11 +941,11 @@ TEST_F(Pkt6Test, getMACFromIPv6LinkLocal_direct) {
|
||||
|
||||
// If received from a global address, this method should fail
|
||||
pkt.setRemoteAddr(global);
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
|
||||
// If received from link-local that is EUI-64 based, it should succeed
|
||||
pkt.setRemoteAddr(linklocal_eui64);
|
||||
HWAddrPtr found = pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL);
|
||||
HWAddrPtr found = pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL);
|
||||
ASSERT_TRUE(found);
|
||||
|
||||
stringstream tmp;
|
||||
@ -980,15 +980,15 @@ TEST_F(Pkt6Test, getMACFromIPv6LinkLocal_singleRelay) {
|
||||
|
||||
// If received from a global address, this method should fail
|
||||
pkt.relay_info_[0].peeraddr_ = global;
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
|
||||
// If received from a link-local that does not use EUI-64, it should fail
|
||||
pkt.relay_info_[0].peeraddr_ = linklocal_noneui64;
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL));
|
||||
|
||||
// If received from link-local that is EUI-64 based, it should succeed
|
||||
pkt.relay_info_[0].peeraddr_ = linklocal_eui64;
|
||||
HWAddrPtr found = pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL);
|
||||
HWAddrPtr found = pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL);
|
||||
ASSERT_TRUE(found);
|
||||
|
||||
stringstream tmp;
|
||||
@ -1041,7 +1041,7 @@ TEST_F(Pkt6Test, getMACFromIPv6LinkLocal_multiRelay) {
|
||||
pkt.setIndex(iface->getIndex());
|
||||
|
||||
// The method should return MAC based on the first relay that was closest
|
||||
HWAddrPtr found = pkt.getMAC(Pkt::HWADDR_SOURCE_IPV6_LINK_LOCAL);
|
||||
HWAddrPtr found = pkt.getMAC(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL);
|
||||
ASSERT_TRUE(found);
|
||||
|
||||
// Let's check the info now.
|
||||
@ -1058,7 +1058,7 @@ TEST_F(Pkt6Test, getMACFromIPv6RelayOpt_singleRelay) {
|
||||
Pkt6 pkt(DHCPV6_SOLICIT, 1234);
|
||||
|
||||
// Packets that are not relayed should fail
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION));
|
||||
|
||||
// Now pretend it was relayed by a single relay.
|
||||
Pkt6::RelayInfo info;
|
||||
@ -1075,7 +1075,7 @@ TEST_F(Pkt6Test, getMACFromIPv6RelayOpt_singleRelay) {
|
||||
pkt.addRelayInfo(info);
|
||||
ASSERT_EQ(1, pkt.relay_info_.size());
|
||||
|
||||
HWAddrPtr found = pkt.getMAC(Pkt::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION);
|
||||
HWAddrPtr found = pkt.getMAC(HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION);
|
||||
ASSERT_TRUE(found);
|
||||
|
||||
stringstream tmp;
|
||||
@ -1108,7 +1108,7 @@ TEST_F(Pkt6Test, getMACFromIPv6RelayOpt_multipleRelay) {
|
||||
pkt.addRelayInfo(info2);
|
||||
ASSERT_EQ(2, pkt.relay_info_.size());
|
||||
|
||||
EXPECT_FALSE(pkt.getMAC(Pkt::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION));
|
||||
EXPECT_FALSE(pkt.getMAC(HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION));
|
||||
|
||||
// Let's envolve the packet with a third relay (now the closest to the client)
|
||||
// that inserts the correct client_linklayer_addr option.
|
||||
@ -1123,11 +1123,12 @@ TEST_F(Pkt6Test, getMACFromIPv6RelayOpt_multipleRelay) {
|
||||
ASSERT_EQ(3, pkt.relay_info_.size());
|
||||
|
||||
// Now extract the MAC address from the relayed option
|
||||
HWAddrPtr found = pkt.getMAC(Pkt::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION);
|
||||
HWAddrPtr found = pkt.getMAC(HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION);
|
||||
ASSERT_TRUE(found);
|
||||
|
||||
stringstream tmp;
|
||||
tmp << "hwtype=1 fa:30:0b:fa:c0:fe";
|
||||
EXPECT_EQ(tmp.str(), found->toText(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ 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_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
|
||||
libkea_dhcpsrv_la_SOURCES += cfgmgr.cc cfgmgr.h
|
||||
libkea_dhcpsrv_la_SOURCES += csv_lease_file4.cc csv_lease_file4.h
|
||||
libkea_dhcpsrv_la_SOURCES += csv_lease_file6.cc csv_lease_file6.h
|
||||
|
59
src/lib/dhcpsrv/cfg_mac_source.cc
Normal file
59
src/lib/dhcpsrv/cfg_mac_source.cc
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2014 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.
|
||||
|
||||
#include <config.h>
|
||||
#include <dhcpsrv/cfg_mac_source.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
#include <dhcp/hwaddr.h>
|
||||
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
CfgMACSource::CfgMACSource() {
|
||||
|
||||
// By default, use any hardware source that is available.
|
||||
mac_sources_.push_back(HWAddr::HWADDR_SOURCE_ANY);
|
||||
}
|
||||
|
||||
uint32_t CfgMACSource::MACSourceFromText(const std::string& name) {
|
||||
|
||||
struct {
|
||||
const char * name;
|
||||
uint32_t type;
|
||||
} sources[] = {
|
||||
{ "any", HWAddr::HWADDR_SOURCE_ANY },
|
||||
{ "raw", HWAddr::HWADDR_SOURCE_RAW },
|
||||
{ "duid", HWAddr::HWADDR_SOURCE_DUID },
|
||||
{ "ipv6-link-local", HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL },
|
||||
{ "client-link-addr-option", HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION },
|
||||
{ "rfc6939", HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION },
|
||||
{ "remote-id", HWAddr::HWADDR_SOURCE_REMOTE_ID },
|
||||
{ "rfc4649", HWAddr::HWADDR_SOURCE_REMOTE_ID },
|
||||
{ "subscriber-id", HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID },
|
||||
{ "rfc4580", HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID },
|
||||
{ "docsis", HWAddr::HWADDR_SOURCE_DOCSIS }
|
||||
};
|
||||
|
||||
for (int i=0; i < sizeof(sources)/sizeof(sources[0]); ++i) {
|
||||
if (name.compare(sources[i].name) == 0) {
|
||||
return (sources[i].type);
|
||||
}
|
||||
}
|
||||
|
||||
isc_throw(BadValue, "Can't convert '" << name << "' to any known MAC source.");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
88
src/lib/dhcpsrv/cfg_mac_source.h
Normal file
88
src/lib/dhcpsrv/cfg_mac_source.h
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright (C) 2014 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_MAC_SOURCE_H
|
||||
#define CFG_MAC_SOURCE_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
/// @brief Container for defined MAC/hardware address sources
|
||||
typedef std::vector<uint32_t> CfgMACSources;
|
||||
|
||||
/// @brief Wrapper class that holds MAC/hardware address sources
|
||||
///
|
||||
/// It's a simple wrapper around a vector of uint32_t, with each entry
|
||||
/// holding one MAC source.
|
||||
class CfgMACSource {
|
||||
|
||||
public:
|
||||
/// @brief Default constructor.
|
||||
///
|
||||
/// Sets source to 'any'.
|
||||
CfgMACSource();
|
||||
|
||||
/// @brief Attempts to convert known hardware address sources to uint32_t
|
||||
///
|
||||
/// Supported strings are: \li any => 0xffffffff
|
||||
/// \li raw => 0x00000001
|
||||
/// \li duid => 0x00000002
|
||||
/// \li ipv6-link-local 0x00000004
|
||||
/// \li client-link-addr-option, rfc6939 => 0x00000008
|
||||
/// \li remote-id, rfc4649 => 0x00000010
|
||||
/// \li subscriber-id, rfc4580 => 0x00000020
|
||||
/// \li docsis => 0x00000040
|
||||
///
|
||||
/// For specific constants, see @ref isc::dhcp::HWAddr class.
|
||||
///
|
||||
/// @throw BadValue if specified string is unknown
|
||||
/// @return bitmask version of a given method
|
||||
static uint32_t MACSourceFromText(const std::string& name);
|
||||
|
||||
|
||||
/// @brief Adds additional MAC/hardware address aquisition.
|
||||
///
|
||||
/// @param source MAC source (see constants in Pkt::HWADDR_SOURCE_*)
|
||||
///
|
||||
/// Specified source is being added to the mac_sources_ array.
|
||||
/// @todo implement add(string) version of this method.
|
||||
void add(uint32_t source) {
|
||||
mac_sources_.push_back(source);
|
||||
}
|
||||
|
||||
/// @brief Provides access to the configure MAC/Hardware address sources.
|
||||
///
|
||||
/// @note The const reference returned is only valid as long as the
|
||||
/// object that returned it.
|
||||
const CfgMACSources& get() const {
|
||||
return mac_sources_;
|
||||
}
|
||||
|
||||
/// @brief Removes any configured MAC/Hardware address sources.
|
||||
void clear() {
|
||||
mac_sources_.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
/// @brief Actual MAC sources storage
|
||||
CfgMACSources mac_sources_;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
@ -17,6 +17,7 @@
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/cfg_option.h>
|
||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||
#include <dhcpsrv/cfg_mac_source.h>
|
||||
#include <hooks/hooks_manager.h>
|
||||
#include <util/encode/hex.h>
|
||||
#include <util/strutil.h>
|
||||
@ -187,6 +188,7 @@ InterfaceListConfigParser(const std::string& param_name,
|
||||
void
|
||||
InterfaceListConfigParser::build(ConstElementPtr value) {
|
||||
CfgIface cfg_iface;
|
||||
|
||||
BOOST_FOREACH(ConstElementPtr iface, value->listValue()) {
|
||||
std::string iface_name = iface->stringValue();
|
||||
try {
|
||||
@ -206,6 +208,45 @@ InterfaceListConfigParser::commit() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
// ******************** MACSourcesListConfigParser *************************
|
||||
|
||||
MACSourcesListConfigParser::
|
||||
MACSourcesListConfigParser(const std::string& param_name,
|
||||
ParserContextPtr global_context)
|
||||
: param_name_(param_name), global_context_(global_context) {
|
||||
if (param_name_ != "mac-sources") {
|
||||
isc_throw(BadValue, "Internal error. MAC sources configuration "
|
||||
"parser called for the wrong parameter: " << param_name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MACSourcesListConfigParser::build(ConstElementPtr value) {
|
||||
CfgIface cfg_iface;
|
||||
uint32_t source = 0;
|
||||
|
||||
// By default, there's only one source defined: ANY.
|
||||
// If user specified anything, we need to get rid of that default.
|
||||
CfgMgr::instance().getStagingCfg()->getMACSources().clear();
|
||||
|
||||
BOOST_FOREACH(ConstElementPtr source_elem, value->listValue()) {
|
||||
std::string source_str = source_elem->stringValue();
|
||||
try {
|
||||
source = CfgMACSource::MACSourceFromText(source_str);
|
||||
CfgMgr::instance().getStagingCfg()->getMACSources().add(source);
|
||||
} catch (const std::exception& ex) {
|
||||
isc_throw(DhcpConfigError, "Failed to convert '"
|
||||
<< source_str << "' to any recognized MAC source:"
|
||||
<< ex.what() << " (" << value->getPosition() << ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MACSourcesListConfigParser::commit() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
// ******************** HooksLibrariesParser *************************
|
||||
|
||||
HooksLibrariesParser::HooksLibrariesParser(const std::string& param_name)
|
||||
|
@ -382,12 +382,10 @@ private:
|
||||
|
||||
/// @brief parser for interface list definition
|
||||
///
|
||||
/// This parser handles Dhcp4/interface entry.
|
||||
/// This parser handles Dhcp4/interfaces and Dhcp6/interfaces entries.
|
||||
/// It contains a list of network interfaces that the server listens on.
|
||||
/// In particular, it can contain an entry called "all" or "any" that
|
||||
/// designates all interfaces.
|
||||
///
|
||||
/// It is useful for parsing Dhcp4/interface parameter.
|
||||
class InterfaceListConfigParser : public DhcpConfigParser {
|
||||
public:
|
||||
|
||||
@ -422,6 +420,48 @@ private:
|
||||
ParserContextPtr global_context_;
|
||||
};
|
||||
|
||||
|
||||
/// @brief parser for MAC/hardware aquisition sources
|
||||
///
|
||||
/// This parser handles Dhcp6/mac-sources entry.
|
||||
/// It contains a list of MAC/hardware aquisition source, i.e. methods how
|
||||
/// MAC address can possibly by obtained in DHCPv6. For a currently supported
|
||||
/// methods, see @ref isc::dhcp::Pkt::getMAC.
|
||||
class MACSourcesListConfigParser : public DhcpConfigParser {
|
||||
public:
|
||||
|
||||
/// @brief constructor
|
||||
///
|
||||
/// As this is a dedicated parser, it must be used to parse
|
||||
/// "mac-sources" parameter only. All other types will throw exception.
|
||||
///
|
||||
/// @param param_name name of the configuration parameter being parsed
|
||||
/// @param global_context Global parser context.
|
||||
/// @throw BadValue if supplied parameter name is not "mac-sources"
|
||||
MACSourcesListConfigParser(const std::string& param_name,
|
||||
ParserContextPtr global_context);
|
||||
|
||||
/// @brief parses parameters value
|
||||
///
|
||||
/// Parses configuration entry (list of sources) and adds each element
|
||||
/// to the sources list.
|
||||
///
|
||||
/// @param value pointer to the content of parsed values
|
||||
virtual void build(isc::data::ConstElementPtr value);
|
||||
|
||||
/// @brief Does nothing.
|
||||
virtual void commit();
|
||||
|
||||
private:
|
||||
|
||||
// Parsed parameter name
|
||||
std::string param_name_;
|
||||
|
||||
/// Global parser context.
|
||||
ParserContextPtr global_context_;
|
||||
};
|
||||
|
||||
|
||||
/// @brief Parser for hooks library list
|
||||
///
|
||||
/// This parser handles the list of hooks libraries. This is an optional list,
|
||||
@ -1172,4 +1212,3 @@ typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr;
|
||||
}; // end of isc namespace
|
||||
|
||||
#endif // DHCP_PARSERS_H
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <dhcpsrv/srv_config.h>
|
||||
#include <log/logger_manager.h>
|
||||
#include <log/logger_specification.h>
|
||||
#include <dhcp/pkt.h> // Needed for HWADDR_SOURCE_*
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <dhcpsrv/cfg_option_def.h>
|
||||
#include <dhcpsrv/cfg_subnets4.h>
|
||||
#include <dhcpsrv/cfg_subnets6.h>
|
||||
#include <dhcpsrv/cfg_mac_source.h>
|
||||
#include <dhcpsrv/logging_info.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
@ -237,6 +238,22 @@ public:
|
||||
|
||||
//@}
|
||||
|
||||
/// @brief Returns non-const reference to an array that stores
|
||||
/// MAC/hardware address sources.
|
||||
///
|
||||
/// @return non-const reference to MAC/hardware address sources
|
||||
CfgMACSource& getMACSources() {
|
||||
return (cfg_mac_source_);
|
||||
}
|
||||
|
||||
/// @brief Returns const reference to an array that stores
|
||||
/// MAC/hardware address sources.
|
||||
///
|
||||
/// @return const reference to MAC/hardware address sources
|
||||
const CfgMACSource& getMACSources() const {
|
||||
return (cfg_mac_source_);
|
||||
}
|
||||
|
||||
/// @brief Copies the currnet configuration to a new configuration.
|
||||
///
|
||||
/// This method copies the parameters stored in the configuration to
|
||||
@ -310,6 +327,7 @@ public:
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/// @brief Sequence number identifying the configuration.
|
||||
@ -348,6 +366,8 @@ private:
|
||||
/// reservations for different IPv4 and IPv6 subnets.
|
||||
CfgHostsPtr cfg_hosts_;
|
||||
|
||||
/// @brief A list of configured MAC sources.
|
||||
CfgMACSource cfg_mac_source_;
|
||||
};
|
||||
|
||||
/// @name Pointers to the @c SrvConfig object.
|
||||
|
@ -57,6 +57,7 @@ libdhcpsrv_unittests_SOURCES += alloc_engine_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += callout_handle_store_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += cfg_hosts_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += cfg_iface_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += cfg_mac_source_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += cfg_option_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += cfg_option_def_unittest.cc
|
||||
libdhcpsrv_unittests_SOURCES += cfg_subnets4_unittest.cc
|
||||
@ -120,7 +121,8 @@ if USE_CLANGPP
|
||||
libdhcpsrv_unittests_CXXFLAGS += -Wno-unused-variable -Wno-unused-parameter
|
||||
endif
|
||||
|
||||
libdhcpsrv_unittests_LDADD = $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
|
||||
libdhcpsrv_unittests_LDADD = $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
|
||||
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
|
||||
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la
|
||||
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/dhcp/tests/libdhcptest.la
|
||||
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
|
||||
|
54
src/lib/dhcpsrv/tests/cfg_mac_source_unittest.cc
Normal file
54
src/lib/dhcpsrv/tests/cfg_mac_source_unittest.cc
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2014 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.
|
||||
|
||||
#include <dhcpsrv/cfg_mac_source.h>
|
||||
#include <dhcp/hwaddr.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace isc;
|
||||
using namespace isc::dhcp;
|
||||
|
||||
// Checks whether CfgMACSource::MACSourceFromText is working correctly.
|
||||
// Technically, this is a Pkt, not Pkt6 test, but since there is no separate
|
||||
// unit-tests for Pkt and it is abstract, so it would be tricky to test it
|
||||
// directly. Hence test is being run in Pkt6.
|
||||
TEST(CfgMACSourceTest, MACSourceFromText) {
|
||||
EXPECT_THROW(CfgMACSource::MACSourceFromText("unknown"), BadValue);
|
||||
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_ANY, CfgMACSource::MACSourceFromText("any"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_RAW, CfgMACSource::MACSourceFromText("raw"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_DUID, CfgMACSource::MACSourceFromText("duid"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL,
|
||||
CfgMACSource::MACSourceFromText("ipv6-link-local"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION,
|
||||
CfgMACSource::MACSourceFromText("client-link-addr-option"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION,
|
||||
CfgMACSource::MACSourceFromText("rfc6939"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_REMOTE_ID,
|
||||
CfgMACSource::MACSourceFromText("remote-id"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_REMOTE_ID,
|
||||
CfgMACSource::MACSourceFromText("rfc4649"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID,
|
||||
CfgMACSource::MACSourceFromText("subscriber-id"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_SUBSCRIBER_ID,
|
||||
CfgMACSource::MACSourceFromText("rfc4580"));
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_DOCSIS,
|
||||
CfgMACSource::MACSourceFromText("docsis"));
|
||||
|
||||
}
|
||||
|
||||
};
|
@ -22,6 +22,7 @@
|
||||
#include <dhcp/tests/iface_mgr_test_config.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/subnet.h>
|
||||
#include <dhcpsrv/cfg_mac_source.h>
|
||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||
#include <dhcpsrv/tests/test_libraries.h>
|
||||
#include <dhcpsrv/testutils/config_result_check.h>
|
||||
@ -212,7 +213,7 @@ TEST_F(DhcpParserTest, uint32ParserTest) {
|
||||
EXPECT_EQ(test_value, actual_value);
|
||||
}
|
||||
|
||||
/// @brief Check InterfaceListParser basic functionality
|
||||
/// @brief Check InterfaceListConfigParser basic functionality
|
||||
///
|
||||
/// Verifies that the parser:
|
||||
/// 1. Does not allow empty for storage.
|
||||
@ -270,6 +271,49 @@ TEST_F(DhcpParserTest, interfaceListParserTest) {
|
||||
EXPECT_TRUE(test_config.socketOpen("eth1", AF_INET));
|
||||
}
|
||||
|
||||
|
||||
/// @brief Check MACSourcesListConfigParser basic functionality
|
||||
///
|
||||
/// Verifies that the parser:
|
||||
/// 1. Does not allow empty for storage.
|
||||
/// 2. Does not allow name other than "mac-sources"
|
||||
/// 3. Parses list of mac sources and adds them to CfgMgr
|
||||
TEST_F(DhcpParserTest, MacSourcesListConfigParserTest) {
|
||||
|
||||
const std::string valid_name = "mac-sources";
|
||||
const std::string bogus_name = "bogus-name";
|
||||
|
||||
ParserContextPtr parser_context(new ParserContext(Option::V6));
|
||||
|
||||
// Verify that parser constructor fails if parameter name isn't "mac-sources"
|
||||
EXPECT_THROW(MACSourcesListConfigParser(bogus_name, parser_context),
|
||||
isc::BadValue);
|
||||
|
||||
// That's an equivalent of the following snippet:
|
||||
// "mac-sources: [ \"duid\", \"ipv6\" ]";
|
||||
ElementPtr config = Element::createList();
|
||||
config->add(Element::create("duid"));
|
||||
config->add(Element::create("ipv6-link-local"));
|
||||
|
||||
boost::scoped_ptr<MACSourcesListConfigParser>
|
||||
parser(new MACSourcesListConfigParser(valid_name, parser_context));
|
||||
|
||||
// This should parse the configuration and add eth0 and eth1 to the list
|
||||
// of interfaces that server should listen on.
|
||||
EXPECT_NO_THROW(parser->build(config));
|
||||
EXPECT_NO_THROW(parser->commit());
|
||||
|
||||
// Use CfgMgr instance to check if eth0 and eth1 was added, and that
|
||||
// eth2 was not added.
|
||||
SrvConfigPtr cfg = CfgMgr::instance().getStagingCfg();
|
||||
ASSERT_TRUE(cfg);
|
||||
CfgMACSources configured_sources = cfg->getMACSources().get();
|
||||
|
||||
ASSERT_EQ(2, configured_sources.size());
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_DUID, configured_sources[0]);
|
||||
EXPECT_EQ(HWAddr::HWADDR_SOURCE_IPV6_LINK_LOCAL, configured_sources[1]);
|
||||
}
|
||||
|
||||
/// @brief Test Fixture class which provides basic structure for testing
|
||||
/// configuration parsing. This is essentially the same structure provided
|
||||
/// by dhcp servers.
|
||||
|
Loading…
x
Reference in New Issue
Block a user