mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-01 06:25:34 +00:00
[3705] Address review comments.
This commit is contained in:
@@ -885,6 +885,9 @@ temporarily override a list of interface names and listen on all interfaces.
|
|||||||
<row><entry>clt-time</entry><entry>46</entry><entry>uint32</entry><entry>false</entry></row>
|
<row><entry>clt-time</entry><entry>46</entry><entry>uint32</entry><entry>false</entry></row>
|
||||||
<row><entry>lq-relay-data</entry><entry>47</entry><entry>record</entry><entry>false</entry></row>
|
<row><entry>lq-relay-data</entry><entry>47</entry><entry>record</entry><entry>false</entry></row>
|
||||||
<row><entry>lq-client-link</entry><entry>48</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
<row><entry>lq-client-link</entry><entry>48</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||||||
|
<row><entry>erp-local-domain-name</entry><entry>65</entry><entry>fqdn</entry><entry>false</entry></row>
|
||||||
|
<row><entry>rsoo</entry><entry>66</entry><entry>empty</entry><entry>false</entry></row>
|
||||||
|
<row><entry>client-linklayer-addr</entry><entry>79</entry><entry>binary</entry><entry>false</entry></row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
@@ -1371,7 +1374,7 @@ should include options from the isc option space:
|
|||||||
<section id="dhcp6-rsoo">
|
<section id="dhcp6-rsoo">
|
||||||
<title>Relay-Supplied Options</title>
|
<title>Relay-Supplied Options</title>
|
||||||
<para><ulink url="http://tools.ietf.org/html/rfc6422">RFC 6422</ulink>
|
<para><ulink url="http://tools.ietf.org/html/rfc6422">RFC 6422</ulink>
|
||||||
defines a mechanism called Relay supplied options. In certain cases relay
|
defines a mechanism called Relay-Supplied DHCP Options. In certain cases relay
|
||||||
agents are the only entities that may have specific information. They can
|
agents are the only entities that may have specific information. They can
|
||||||
insert options when relaying messages from the client to the server. The
|
insert options when relaying messages from the client to the server. The
|
||||||
server will then do certain checks and copy those options to the response
|
server will then do certain checks and copy those options to the response
|
||||||
@@ -1381,11 +1384,11 @@ should include options from the isc option space:
|
|||||||
included. First, the server must not provide the option by itself. In
|
included. First, the server must not provide the option by itself. In
|
||||||
other words, if both relay and server provide an option, the server always
|
other words, if both relay and server provide an option, the server always
|
||||||
takes precedence. Second, the option must be RSOO-enabled. IANA mantains a
|
takes precedence. Second, the option must be RSOO-enabled. IANA mantains a
|
||||||
list of RSOO-enabled options here: <ulink url="http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#options-relay-supplied">List of RSOO-enabled options</ulink>.
|
list of RSOO-enabled options <ulink url="http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#options-relay-supplied">here</ulink>.
|
||||||
However, there may cases when system administrators want to echo other
|
However, there may be cases when system administrators want to echo other
|
||||||
options. Kea can be instructed to treat other options as RSOO-enabled.
|
options. Kea can be instructed to treat other options as RSOO-enabled.
|
||||||
For example, to mark options 110, 120 and 130 as RSOO-enabled, the following
|
For example, to mark options 110, 120 and 130 as RSOO-enabled, the following
|
||||||
syntax may be used:
|
syntax should be used:
|
||||||
<screen>
|
<screen>
|
||||||
"Dhcp6": {
|
"Dhcp6": {
|
||||||
<userinput>"relay-supplied-options": [ "110", "120", "130" ],</userinput>
|
<userinput>"relay-supplied-options": [ "110", "120", "130" ],</userinput>
|
||||||
|
@@ -2739,41 +2739,30 @@ void Dhcpv6Srv::processRSOO(const Pkt6Ptr& query, const Pkt6Ptr& rsp) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the global options info. We'll use it to check whether an
|
// Get RSOO configuration.
|
||||||
// option is RSOO-enabled or not.
|
ConstCfgRSOOPtr cfg_rsoo = CfgMgr::instance().getCurrentCfg()->getCfgRSOO();
|
||||||
ConstCfgOptionPtr global_opts = CfgMgr::instance().getCurrentCfg()->
|
|
||||||
getCfgOption();
|
|
||||||
|
|
||||||
// Let's get over all relays (encapsulation levels). We need to do
|
// Let's get over all relays (encapsulation levels). We need to do
|
||||||
// it in the same order as the client packet traversed the relays.
|
// it in the same order as the client packet traversed the relays.
|
||||||
for (int i = query->relay_info_.size(); i > 0 ; --i) {
|
for (int i = query->relay_info_.size(); i > 0 ; --i) {
|
||||||
OptionPtr rsoo_container = query->getRelayOption(D6O_RSOO, i - 1);
|
OptionPtr rsoo_container = query->getRelayOption(D6O_RSOO, i - 1);
|
||||||
if (!rsoo_container) {
|
if (rsoo_container) {
|
||||||
// No relay-supplied options by this relay? Ok, carry on.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// There are RSOO options. Let's get through them one by one
|
// There are RSOO options. Let's get through them one by one
|
||||||
// and if it's RSOO-enabled and there's no such option provided yet,
|
// and if it's RSOO-enabled and there's no such option provided yet,
|
||||||
// copy it to the server's response
|
// copy it to the server's response
|
||||||
const OptionCollection& rsoo = rsoo_container->getOptions();
|
const OptionCollection& rsoo = rsoo_container->getOptions();
|
||||||
for (OptionCollection::const_iterator opt = rsoo.begin(); opt != rsoo.end();
|
for (OptionCollection::const_iterator opt = rsoo.begin();
|
||||||
++opt) {
|
opt != rsoo.end(); ++opt) {
|
||||||
if (!global_opts->isRSOOEnabled(opt->second->getType())) {
|
|
||||||
// We didn't copy this option, because it's not RSOO-enabled.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsp->getOption(opt->second->getType())) {
|
// Echo option if it is RSOO enabled option and there is no such
|
||||||
// There is such an option in the server's response already,
|
// option added yet.
|
||||||
// we'll skip relay's option
|
if (cfg_rsoo->enabled(opt->second->getType()) &&
|
||||||
continue;
|
!rsp->getOption(opt->second->getType())) {
|
||||||
}
|
|
||||||
|
|
||||||
// All checks went ok, let's add this option.
|
|
||||||
rsp->addOption(opt->second);
|
rsp->addOption(opt->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -575,10 +576,14 @@ public:
|
|||||||
ParserCollection subnets_;
|
ParserCollection subnets_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief parser for list of RSOO options
|
/// @brief Parser for list of RSOO options
|
||||||
///
|
///
|
||||||
/// This parser handles Dhcp6/relay-supplied-options entry.
|
/// This parser handles Dhcp6/relay-supplied-options entry. It contains a
|
||||||
/// It contains a list of option codes.
|
/// list of RSOO-enabled options which should be sent back to the client.
|
||||||
|
///
|
||||||
|
/// The option on this list can be specified using an option code or option
|
||||||
|
/// name. Therefore, the values on the list should always be enclosed in
|
||||||
|
/// "quotes".
|
||||||
class RSOOListConfigParser : public DhcpConfigParser {
|
class RSOOListConfigParser : public DhcpConfigParser {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -603,19 +608,26 @@ public:
|
|||||||
///
|
///
|
||||||
/// @param value pointer to the content of parsed values
|
/// @param value pointer to the content of parsed values
|
||||||
virtual void build(isc::data::ConstElementPtr value) {
|
virtual void build(isc::data::ConstElementPtr value) {
|
||||||
|
try {
|
||||||
// By default, there's only one RSOO option defined: 65
|
|
||||||
// http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml
|
|
||||||
CfgMgr::instance().getStagingCfg()->getCfgOption()->clearRSOO();
|
|
||||||
CfgMgr::instance().getStagingCfg()->getCfgOption()->addRSOO(D6O_ERP_LOCAL_DOMAIN_NAME);
|
|
||||||
|
|
||||||
BOOST_FOREACH(ConstElementPtr source_elem, value->listValue()) {
|
BOOST_FOREACH(ConstElementPtr source_elem, value->listValue()) {
|
||||||
|
|
||||||
std::string option_str = source_elem->stringValue();
|
std::string option_str = source_elem->stringValue();
|
||||||
// This option can be either code (integer) or name. Let's try code first
|
// This option can be either code (integer) or name. Let's try code first
|
||||||
uint16_t code = 0;
|
int64_t code = 0;
|
||||||
try {
|
try {
|
||||||
code = boost::lexical_cast<uint16_t>(option_str);
|
code = boost::lexical_cast<int64_t>(option_str);
|
||||||
|
// Protect against the negative value and too high value.
|
||||||
|
if (code < 0) {
|
||||||
|
isc_throw(BadValue, "invalid option code value specified '"
|
||||||
|
<< option_str << "', the option code must be a"
|
||||||
|
" non-negative value");
|
||||||
|
|
||||||
|
} else if (code > std::numeric_limits<uint16_t>::max()) {
|
||||||
|
isc_throw(BadValue, "invalid option code value specified '"
|
||||||
|
<< option_str << "', the option code must not be"
|
||||||
|
" greater than '" << std::numeric_limits<uint16_t>::max()
|
||||||
|
<< "'");
|
||||||
|
}
|
||||||
|
|
||||||
} catch (const boost::bad_lexical_cast &) {
|
} catch (const boost::bad_lexical_cast &) {
|
||||||
// Oh well, it's not a number
|
// Oh well, it's not a number
|
||||||
}
|
}
|
||||||
@@ -625,12 +637,18 @@ public:
|
|||||||
if (def) {
|
if (def) {
|
||||||
code = def->getCode();
|
code = def->getCode();
|
||||||
} else {
|
} else {
|
||||||
isc_throw(BadValue, "Unable to convert '" << option_str
|
isc_throw(BadValue, "unable to find option code for the "
|
||||||
<< "' to option code while parsing allowed"
|
" specified option name '" << option_str << "'"
|
||||||
<< "relay-supplied-options");
|
" while parsing the list of enabled"
|
||||||
|
" relay-supplied-options");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CfgMgr::instance().getStagingCfg()->getCfgOption()->addRSOO(code);
|
CfgMgr::instance().getStagingCfg()->getCfgRSOO()->enable(code);
|
||||||
|
}
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
// Rethrow exception with the appended position of the parsed
|
||||||
|
// element.
|
||||||
|
isc_throw(DhcpConfigError, ex.what() << " (" << value->getPosition() << ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3798,18 +3798,18 @@ TEST_F(Dhcp6ParserTest, rsooNumbers) {
|
|||||||
checkResult(status, 0);
|
checkResult(status, 0);
|
||||||
|
|
||||||
// The following codes should be enabled now
|
// The following codes should be enabled now
|
||||||
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(10));
|
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()->enabled(10));
|
||||||
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(20));
|
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()->enabled(20));
|
||||||
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(30));
|
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()->enabled(30));
|
||||||
|
|
||||||
// This option is on the IANA list, so it should be allowed all the time
|
// This option is on the IANA list, so it should be allowed all the time
|
||||||
// (http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml)
|
// (http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml)
|
||||||
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()
|
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()
|
||||||
->isRSOOEnabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
->enabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
|
||||||
// Those options are not enabled
|
// Those options are not enabled
|
||||||
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(25));
|
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()->enabled(25));
|
||||||
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(1));
|
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()->enabled(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The goal of this test is to verify that configuration can include
|
/// The goal of this test is to verify that configuration can include
|
||||||
@@ -3831,39 +3831,68 @@ TEST_F(Dhcp6ParserTest, rsooNames) {
|
|||||||
checkResult(status, 0);
|
checkResult(status, 0);
|
||||||
|
|
||||||
for (uint16_t code = 0; code < D6O_NAME_SERVERS; ++code) {
|
for (uint16_t code = 0; code < D6O_NAME_SERVERS; ++code) {
|
||||||
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()
|
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()
|
||||||
->isRSOOEnabled(code)) << " for option code " << code;
|
->enabled(code)) << " for option code " << code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following codes should be enabled now
|
// The following codes should be enabled now
|
||||||
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()
|
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()
|
||||||
->isRSOOEnabled(D6O_NAME_SERVERS));
|
->enabled(D6O_NAME_SERVERS));
|
||||||
|
|
||||||
for (uint16_t code = D6O_NAME_SERVERS + 1; code < D6O_REMOTE_ID; ++code) {
|
for (uint16_t code = D6O_NAME_SERVERS + 1; code < D6O_REMOTE_ID; ++code) {
|
||||||
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()
|
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()
|
||||||
->isRSOOEnabled(code)) << " for option code " << code;
|
->enabled(code)) << " for option code " << code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check remote-id. It should be enabled.
|
// Check remote-id. It should be enabled.
|
||||||
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()
|
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()
|
||||||
->isRSOOEnabled(D6O_REMOTE_ID));
|
->enabled(D6O_REMOTE_ID));
|
||||||
for (uint16_t code = D6O_REMOTE_ID + 1; code < D6O_ERP_LOCAL_DOMAIN_NAME; ++code) {
|
for (uint16_t code = D6O_REMOTE_ID + 1; code < D6O_ERP_LOCAL_DOMAIN_NAME; ++code) {
|
||||||
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()
|
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()
|
||||||
->isRSOOEnabled(code)) << " for option code " << code;
|
->enabled(code)) << " for option code " << code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This option is on the IANA list, so it should be allowed all the time
|
// This option is on the IANA list, so it should be allowed all the time
|
||||||
// (http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml)
|
// (http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml)
|
||||||
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()
|
EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()
|
||||||
->isRSOOEnabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
->enabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
|
||||||
for (uint16_t code = D6O_ERP_LOCAL_DOMAIN_NAME + 1; code < 300; ++code) {
|
for (uint16_t code = D6O_ERP_LOCAL_DOMAIN_NAME + 1; code < 300; ++code) {
|
||||||
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()
|
EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgRSOO()
|
||||||
->isRSOOEnabled(code)) << " for option code " << code;
|
->enabled(code)) << " for option code " << code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(Dhcp6ParserTest, rsooNegativeNumber) {
|
||||||
|
ConstElementPtr status;
|
||||||
|
EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
|
||||||
|
Element::fromJSON("{ " + genIfaceConfig() + ","
|
||||||
|
"\"relay-supplied-options\": [ \"80\", \"-2\" ],"
|
||||||
|
"\"preferred-lifetime\": 3000,"
|
||||||
|
"\"rebind-timer\": 2000, "
|
||||||
|
"\"renew-timer\": 1000, "
|
||||||
|
"\"subnet6\": [ ], "
|
||||||
|
"\"valid-lifetime\": 4000 }")));
|
||||||
|
|
||||||
|
// returned value should be 0 (success)
|
||||||
|
checkResult(status, 1);
|
||||||
|
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Dhcp6ParserTest, rsooBogusName) {
|
||||||
|
ConstElementPtr status;
|
||||||
|
EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
|
||||||
|
Element::fromJSON("{ " + genIfaceConfig() + ","
|
||||||
|
"\"relay-supplied-options\": [ \"bogus\", \"dns-servers\" ],"
|
||||||
|
"\"preferred-lifetime\": 3000,"
|
||||||
|
"\"rebind-timer\": 2000, "
|
||||||
|
"\"renew-timer\": 1000, "
|
||||||
|
"\"subnet6\": [ ], "
|
||||||
|
"\"valid-lifetime\": 4000 }")));
|
||||||
|
|
||||||
|
// returned value should be 0 (success)
|
||||||
|
checkResult(status, 1);
|
||||||
|
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -110,6 +110,21 @@ public:
|
|||||||
status_code_ = 0;
|
status_code_ = 0;
|
||||||
received_status_code_ = false;
|
received_status_code_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Finds an option with the specific code in the received
|
||||||
|
/// configuration.
|
||||||
|
///
|
||||||
|
/// @param code Option code.
|
||||||
|
///
|
||||||
|
/// @return Pointer to the option if the option exists, or NULL if
|
||||||
|
/// the option doesn't exist.
|
||||||
|
OptionPtr findOption(const uint16_t code) const {
|
||||||
|
std::multimap<unsigned int, OptionPtr>::const_iterator it = options_.find(code);
|
||||||
|
if (it != options_.end()) {
|
||||||
|
return (it->second);
|
||||||
|
}
|
||||||
|
return (OptionPtr());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Holds the DHCPv6 messages taking part in transaction between
|
/// @brief Holds the DHCPv6 messages taking part in transaction between
|
||||||
|
@@ -2277,6 +2277,80 @@ TEST_F(Dhcpv6SrvTest, rsoo2relays) {
|
|||||||
EXPECT_EQ(expected, opt120->getData());
|
EXPECT_EQ(expected, opt120->getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that the server will send the option for which it
|
||||||
|
// has a candidate, rather than the option sent by the relay in the RSOO.
|
||||||
|
TEST_F(Dhcpv6SrvTest, rsooOverride) {
|
||||||
|
Dhcp6Client client;
|
||||||
|
// The client will be requesting specific options.
|
||||||
|
client.useORO(true);
|
||||||
|
|
||||||
|
// The following configuration enables RSOO options: 110 and 120.
|
||||||
|
// It also configures the server with option 120 which should
|
||||||
|
// "override" the option 120 sent in the RSOO by the relay.
|
||||||
|
string config =
|
||||||
|
"{"
|
||||||
|
" \"relay-supplied-options\": [ \"110\", \"120\" ],"
|
||||||
|
" \"option-def\": [ {"
|
||||||
|
" \"name\": \"foo\","
|
||||||
|
" \"code\": 120,"
|
||||||
|
" \"type\": \"binary\","
|
||||||
|
" \"array\": False,"
|
||||||
|
" \"record-types\": \"\","
|
||||||
|
" \"space\": \"dhcp6\","
|
||||||
|
" \"encapsulate\": \"\""
|
||||||
|
" } ],"
|
||||||
|
" \"option-data\": [ {"
|
||||||
|
" \"code\": 120,"
|
||||||
|
" \"data\": \"05\""
|
||||||
|
" } ],"
|
||||||
|
" \"preferred-lifetime\": 3000,"
|
||||||
|
" \"rebind-timer\": 2000, "
|
||||||
|
" \"renew-timer\": 1000, "
|
||||||
|
" \"subnet6\": [ { "
|
||||||
|
" \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
|
||||||
|
" \"subnet\": \"2001:db8::/48\" "
|
||||||
|
" } ],"
|
||||||
|
" \"valid-lifetime\": 4000"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(configure(config, *client.getServer()));
|
||||||
|
|
||||||
|
// Fabricate the relay.
|
||||||
|
Pkt6::RelayInfo relay;
|
||||||
|
relay.msg_type_ = DHCPV6_RELAY_FORW;
|
||||||
|
relay.hop_count_ = 1;
|
||||||
|
relay.linkaddr_ = IOAddress("2001:db8::1");
|
||||||
|
relay.peeraddr_ = IOAddress("fe80::1");
|
||||||
|
vector<uint16_t> rsoo;
|
||||||
|
// The relay will send 2 options: 110, 120
|
||||||
|
rsoo.push_back(110);
|
||||||
|
rsoo.push_back(120);
|
||||||
|
// Use 0x1 as payload
|
||||||
|
OptionPtr opt = createRSOO(rsoo, 1);
|
||||||
|
relay.options_.insert(make_pair(opt->getType(), opt));
|
||||||
|
client.relay_info_.push_back(relay);
|
||||||
|
|
||||||
|
// Client should request option 120 in the ORO so as the server
|
||||||
|
// sends the configured option 120 to the client.
|
||||||
|
client.requestOption(120);
|
||||||
|
client.doSARR();
|
||||||
|
|
||||||
|
// The option 110 should be the one injected by the relay.
|
||||||
|
opt = client.config_.findOption(110);
|
||||||
|
ASSERT_TRUE(opt);
|
||||||
|
// We check that this is the option injected by the relay by
|
||||||
|
// checking option length. It should has 10 bytes long payload.
|
||||||
|
ASSERT_EQ(10, opt->getData().size());
|
||||||
|
|
||||||
|
// The second option should be the one configured on the server,
|
||||||
|
// rather than the one injected by the relay.
|
||||||
|
opt = client.config_.findOption(120);
|
||||||
|
ASSERT_TRUE(opt);
|
||||||
|
// It should have the size of 1.
|
||||||
|
ASSERT_EQ(1, opt->getData().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
|
/// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
|
||||||
/// to call processX() methods.
|
/// to call processX() methods.
|
||||||
|
|
||||||
|
@@ -327,7 +327,7 @@ const OptionDefParams OPTION_DEF_PARAMS6[] = {
|
|||||||
RECORD_DEF(LQ_RELAY_DATA_RECORDS), "" },
|
RECORD_DEF(LQ_RELAY_DATA_RECORDS), "" },
|
||||||
{ "lq-client-link", D6O_LQ_CLIENT_LINK, OPT_IPV6_ADDRESS_TYPE, true,
|
{ "lq-client-link", D6O_LQ_CLIENT_LINK, OPT_IPV6_ADDRESS_TYPE, true,
|
||||||
NO_RECORD_DEF, "" },
|
NO_RECORD_DEF, "" },
|
||||||
{ "rsoo", D6O_RSOO, OPT_EMPTY_TYPE, false, NO_RECORD_DEF, "dhcp4" },
|
{ "rsoo", D6O_RSOO, OPT_EMPTY_TYPE, false, NO_RECORD_DEF, "rsoo-opts" },
|
||||||
{ "client-linklayer-addr", D6O_CLIENT_LINKLAYER_ADDR, OPT_BINARY_TYPE, false,
|
{ "client-linklayer-addr", D6O_CLIENT_LINKLAYER_ADDR, OPT_BINARY_TYPE, false,
|
||||||
NO_RECORD_DEF, "" }
|
NO_RECORD_DEF, "" }
|
||||||
|
|
||||||
|
@@ -351,6 +351,7 @@ Pkt6Ptr isc::test::PktCaptures::captureCableLabsShortVendorClass() {
|
|||||||
/// - rsoo (66)
|
/// - rsoo (66)
|
||||||
/// - option 255 (len 4)
|
/// - option 255 (len 4)
|
||||||
/// - option 256 (len 9)
|
/// - option 256 (len 9)
|
||||||
|
/// - remote-id option (37)
|
||||||
/// - RELAY-FORW
|
/// - RELAY-FORW
|
||||||
/// - SOLICIT
|
/// - SOLICIT
|
||||||
/// - client-id option
|
/// - client-id option
|
||||||
|
@@ -70,6 +70,7 @@ libkea_dhcpsrv_la_SOURCES += cfg_hosts.cc cfg_hosts.h
|
|||||||
libkea_dhcpsrv_la_SOURCES += cfg_iface.cc cfg_iface.h
|
libkea_dhcpsrv_la_SOURCES += cfg_iface.cc cfg_iface.h
|
||||||
libkea_dhcpsrv_la_SOURCES += cfg_option.cc cfg_option.h
|
libkea_dhcpsrv_la_SOURCES += cfg_option.cc cfg_option.h
|
||||||
libkea_dhcpsrv_la_SOURCES += cfg_option_def.cc cfg_option_def.h
|
libkea_dhcpsrv_la_SOURCES += cfg_option_def.cc cfg_option_def.h
|
||||||
|
libkea_dhcpsrv_la_SOURCES += cfg_rsoo.cc cfg_rsoo.h
|
||||||
libkea_dhcpsrv_la_SOURCES += cfg_subnets4.cc cfg_subnets4.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_subnets6.cc cfg_subnets6.h
|
||||||
libkea_dhcpsrv_la_SOURCES += cfg_mac_source.cc cfg_mac_source.h
|
libkea_dhcpsrv_la_SOURCES += cfg_mac_source.cc cfg_mac_source.h
|
||||||
|
@@ -29,10 +29,6 @@ OptionDescriptor::equals(const OptionDescriptor& other) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CfgOption::CfgOption() {
|
CfgOption::CfgOption() {
|
||||||
|
|
||||||
// By default, the only allowed Relay-Supplied Options option is
|
|
||||||
// ERP local domain name. Other options may be added in configuration.
|
|
||||||
rsoo_options_.insert(D6O_ERP_LOCAL_DOMAIN_NAME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -198,20 +194,5 @@ CfgOption::optionSpaceToVendorId(const std::string& option_space) {
|
|||||||
return (static_cast<uint32_t>(check));
|
return (static_cast<uint32_t>(check));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CfgOption::clearRSOO() {
|
|
||||||
rsoo_options_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CfgOption::isRSOOEnabled(uint16_t code) const {
|
|
||||||
return (rsoo_options_.find(code) != rsoo_options_.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CfgOption::addRSOO(uint16_t code) {
|
|
||||||
if (rsoo_options_.find(code) == rsoo_options_.end()) {
|
|
||||||
// If there's no such code added yet, let's add it
|
|
||||||
rsoo_options_.insert(code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of namespace isc::dhcp
|
} // end of namespace isc::dhcp
|
||||||
} // end of namespace isc
|
} // end of namespace isc
|
||||||
|
@@ -195,11 +195,6 @@ typedef OptionContainer::nth_index<2>::type OptionContainerPersistIndex;
|
|||||||
/// options is useful when the client requests stateless configuration from
|
/// options is useful when the client requests stateless configuration from
|
||||||
/// the DHCP server and no subnet is selected for this client. This client
|
/// the DHCP server and no subnet is selected for this client. This client
|
||||||
/// will only receive global options.
|
/// will only receive global options.
|
||||||
///
|
|
||||||
/// isRSSOEnabled(), addRSOO(), clearRSOO() are methods related to
|
|
||||||
/// Relay-Supplied Options option. This information does not provide any values
|
|
||||||
/// about the options themselves, but rather contain a list of options that
|
|
||||||
/// are allowed in RSOO ("RSOO-enabled").
|
|
||||||
class CfgOption {
|
class CfgOption {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -357,23 +352,6 @@ public:
|
|||||||
/// @return vendor id.
|
/// @return vendor id.
|
||||||
static uint32_t optionSpaceToVendorId(const std::string& option_space);
|
static uint32_t optionSpaceToVendorId(const std::string& option_space);
|
||||||
|
|
||||||
/// @brief Removes designation of all options as RSOO-enabled.
|
|
||||||
///
|
|
||||||
/// This method removes all designations of all options as being RSOO-enabled.
|
|
||||||
/// Note that the list is maintained by IANA and option 65 is officially
|
|
||||||
/// RSOO-enabled. This list may be extended in the future. Also, the user may
|
|
||||||
/// add extra options here.
|
|
||||||
void clearRSOO();
|
|
||||||
|
|
||||||
/// @brief Returns whether specific option code is RSOO-enabled.
|
|
||||||
/// @param code option code to check
|
|
||||||
/// @return true, if it is allowed in Relay-Supplied Options option
|
|
||||||
bool isRSOOEnabled(uint16_t code) const;
|
|
||||||
|
|
||||||
/// @brief Marks specified option code as RSOO-enabled.
|
|
||||||
/// @param code option to be enabled in RSOO
|
|
||||||
void addRSOO(uint16_t code);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// @brief Appends encapsulated options to the options in an option space.
|
/// @brief Appends encapsulated options to the options in an option space.
|
||||||
@@ -419,15 +397,6 @@ private:
|
|||||||
uint32_t> VendorOptionSpaceCollection;
|
uint32_t> VendorOptionSpaceCollection;
|
||||||
/// @brief Container holding options grouped by vendor id.
|
/// @brief Container holding options grouped by vendor id.
|
||||||
VendorOptionSpaceCollection vendor_options_;
|
VendorOptionSpaceCollection vendor_options_;
|
||||||
|
|
||||||
/// @brief Contains a list of options that are allowed in RSOO option
|
|
||||||
///
|
|
||||||
/// RSOO stands for Relay-Supplied Options option. This is an option that
|
|
||||||
/// is inserted by the relay agent with the intention that the server will
|
|
||||||
/// echo those options back to the client. Only those options marked as
|
|
||||||
/// RSOO-enabled may appear in the RSOO. Currently only option 65 is marked
|
|
||||||
/// as such, but more options may be added in the future. See RFC6422 for details.
|
|
||||||
std::set<uint16_t> rsoo_options_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @name Pointers to the @c CfgOption objects.
|
/// @name Pointers to the @c CfgOption objects.
|
||||||
|
46
src/lib/dhcpsrv/cfg_rsoo.cc
Normal file
46
src/lib/dhcpsrv/cfg_rsoo.cc
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#include <dhcp/dhcp6.h>
|
||||||
|
#include <dhcpsrv/cfg_rsoo.h>
|
||||||
|
|
||||||
|
namespace isc {
|
||||||
|
namespace dhcp {
|
||||||
|
|
||||||
|
CfgRSOO::CfgRSOO()
|
||||||
|
: rsoo_options_() {
|
||||||
|
rsoo_options_.insert(D6O_ERP_LOCAL_DOMAIN_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CfgRSOO::clear() {
|
||||||
|
rsoo_options_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CfgRSOO::enabled(const uint16_t code) const {
|
||||||
|
return (rsoo_options_.find(code) != rsoo_options_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CfgRSOO::enable(const uint16_t code) {
|
||||||
|
if (rsoo_options_.find(code) == rsoo_options_.end()) {
|
||||||
|
// If there's no such code added yet, let's add it
|
||||||
|
rsoo_options_.insert(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
82
src/lib/dhcpsrv/cfg_rsoo.h
Normal file
82
src/lib/dhcpsrv/cfg_rsoo.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
// 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_RSOO_H
|
||||||
|
#define CFG_RSOO_H
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace isc {
|
||||||
|
namespace dhcp {
|
||||||
|
|
||||||
|
/// @brief Represents configuration of the RSOO options for the DHCP server.
|
||||||
|
///
|
||||||
|
/// This class holds the set of RSOO-enabled options (see RFC6422). The list
|
||||||
|
/// of RSOO-enabled options is maintained by IANA and currently the option
|
||||||
|
/// 65 is officially RSSO-enabled. The list may be extended in the future
|
||||||
|
/// and this class allows for specifying any future RSOO-enabled options.
|
||||||
|
/// The administrator may also use existing options as RSOO-enabled.
|
||||||
|
class CfgRSOO {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// @brief Constructor.
|
||||||
|
///
|
||||||
|
/// It adds the default (officially) RSOO-enabled options:
|
||||||
|
/// - OPTION_ERP_LOCAL_DOMAIN_NAME
|
||||||
|
CfgRSOO();
|
||||||
|
|
||||||
|
/// @brief Removes designation of all options as RSOO_enabled.
|
||||||
|
///
|
||||||
|
/// This method removes all designations of all options as being RSOO-enabled.
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/// @brief Returns whether specific option code is RSOO-enabled.
|
||||||
|
///
|
||||||
|
/// @param code Option code to check
|
||||||
|
/// @return true, if it is allowed in Relay-Supplied Options option
|
||||||
|
bool enabled(const uint16_t code) const;
|
||||||
|
|
||||||
|
/// @brief Marks specified option code as RSOO-enabled.
|
||||||
|
///
|
||||||
|
/// @param code option to be enabled in RSOO
|
||||||
|
void enable(const uint16_t code);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// @brief Contains a set of options that are allowed in RSOO option
|
||||||
|
///
|
||||||
|
/// RSOO stands for Relay-Supplied Options option. This is an option that
|
||||||
|
/// is inserted by the relay agent with the intention that the server will
|
||||||
|
/// echo those options back to the client. Only those options marked as
|
||||||
|
/// RSOO-enabled may appear in the RSOO. Currently only option 65 is marked
|
||||||
|
/// as such, but more options may be added in the future. See RFC6422 for details.
|
||||||
|
std::set<uint16_t> rsoo_options_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @name Pointers to the @c CfgRSOO objects.
|
||||||
|
//@{
|
||||||
|
/// @brief Pointer to the Non-const object.
|
||||||
|
typedef boost::shared_ptr<CfgRSOO> CfgRSOOPtr;
|
||||||
|
|
||||||
|
/// @brief Pointer to the const object.
|
||||||
|
typedef boost::shared_ptr<const CfgRSOO> ConstCfgRSOOPtr;
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CFG_RSOO_H
|
@@ -29,14 +29,14 @@ SrvConfig::SrvConfig()
|
|||||||
: sequence_(0), cfg_iface_(new CfgIface()),
|
: sequence_(0), cfg_iface_(new CfgIface()),
|
||||||
cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
|
cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
|
||||||
cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
|
cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
|
||||||
cfg_hosts_(new CfgHosts()) {
|
cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SrvConfig::SrvConfig(const uint32_t sequence)
|
SrvConfig::SrvConfig(const uint32_t sequence)
|
||||||
: sequence_(sequence), cfg_iface_(new CfgIface()),
|
: sequence_(sequence), cfg_iface_(new CfgIface()),
|
||||||
cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
|
cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
|
||||||
cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
|
cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
|
||||||
cfg_hosts_(new CfgHosts()) {
|
cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <dhcpsrv/cfg_iface.h>
|
#include <dhcpsrv/cfg_iface.h>
|
||||||
#include <dhcpsrv/cfg_option.h>
|
#include <dhcpsrv/cfg_option.h>
|
||||||
#include <dhcpsrv/cfg_option_def.h>
|
#include <dhcpsrv/cfg_option_def.h>
|
||||||
|
#include <dhcpsrv/cfg_rsoo.h>
|
||||||
#include <dhcpsrv/cfg_subnets4.h>
|
#include <dhcpsrv/cfg_subnets4.h>
|
||||||
#include <dhcpsrv/cfg_subnets6.h>
|
#include <dhcpsrv/cfg_subnets6.h>
|
||||||
#include <dhcpsrv/cfg_mac_source.h>
|
#include <dhcpsrv/cfg_mac_source.h>
|
||||||
@@ -239,6 +240,24 @@ public:
|
|||||||
return (cfg_hosts_);
|
return (cfg_hosts_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Returns pointer to the non-const object representing
|
||||||
|
/// set of RSOO-enabled options.
|
||||||
|
///
|
||||||
|
/// @return Pointer to the non-const object holding RSOO-enabled
|
||||||
|
/// options.
|
||||||
|
CfgRSOOPtr getCfgRSOO() {
|
||||||
|
return (cfg_rsoo_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns pointer to the const object representing set
|
||||||
|
/// of RSOO-enabled options.
|
||||||
|
///
|
||||||
|
/// @return Pointer to the const object holding RSOO-enabled
|
||||||
|
/// options.
|
||||||
|
ConstCfgRSOOPtr getCfgRSOO() const {
|
||||||
|
return (cfg_rsoo_);
|
||||||
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// @brief Returns non-const reference to an array that stores
|
/// @brief Returns non-const reference to an array that stores
|
||||||
@@ -371,6 +390,12 @@ private:
|
|||||||
|
|
||||||
/// @brief A list of configured MAC sources.
|
/// @brief A list of configured MAC sources.
|
||||||
CfgMACSource cfg_mac_source_;
|
CfgMACSource cfg_mac_source_;
|
||||||
|
|
||||||
|
/// @brief Pointer to the configuration for RSOO-enabled options.
|
||||||
|
///
|
||||||
|
/// This object holds a set of RSOO-enabled options. See the
|
||||||
|
/// RFC 6422 for the definition of RSOO-enabled option.
|
||||||
|
CfgRSOOPtr cfg_rsoo_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @name Pointers to the @c SrvConfig object.
|
/// @name Pointers to the @c SrvConfig object.
|
||||||
|
@@ -64,6 +64,7 @@ libdhcpsrv_unittests_SOURCES += cfg_iface_unittest.cc
|
|||||||
libdhcpsrv_unittests_SOURCES += cfg_mac_source_unittest.cc
|
libdhcpsrv_unittests_SOURCES += cfg_mac_source_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += cfg_option_unittest.cc
|
libdhcpsrv_unittests_SOURCES += cfg_option_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += cfg_option_def_unittest.cc
|
libdhcpsrv_unittests_SOURCES += cfg_option_def_unittest.cc
|
||||||
|
libdhcpsrv_unittests_SOURCES += cfg_rsoo_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += cfg_subnets4_unittest.cc
|
libdhcpsrv_unittests_SOURCES += cfg_subnets4_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += cfg_subnets6_unittest.cc
|
libdhcpsrv_unittests_SOURCES += cfg_subnets6_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += cfgmgr_unittest.cc
|
libdhcpsrv_unittests_SOURCES += cfgmgr_unittest.cc
|
||||||
|
@@ -477,33 +477,5 @@ TEST(CfgOptionTest, addVendorOptions) {
|
|||||||
EXPECT_TRUE(options->empty());
|
EXPECT_TRUE(options->empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test verifies that Relay-Supplied Options option (RSOO) is handled
|
|
||||||
// properly.
|
|
||||||
TEST(CfgOptionTest, rsoo) {
|
|
||||||
CfgOption cfg;
|
|
||||||
|
|
||||||
// All options from 0..64 are not RSOO-enabled
|
|
||||||
for (uint16_t code = 0; code < D6O_ERP_LOCAL_DOMAIN_NAME; ++code) {
|
|
||||||
EXPECT_FALSE(cfg.isRSOOEnabled(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option 65 is the only one so far that is enabled
|
|
||||||
EXPECT_TRUE(cfg.isRSOOEnabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
|
||||||
|
|
||||||
// Let's check other options. They should not be enabled.
|
|
||||||
for (uint16_t code = D6O_ERP_LOCAL_DOMAIN_NAME + 1; code < 300; ++code) {
|
|
||||||
EXPECT_FALSE(cfg.isRSOOEnabled(code)) << " for option code " << code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's clear it.
|
|
||||||
cfg.clearRSOO();
|
|
||||||
|
|
||||||
// Now not even option 65 is enabled.
|
|
||||||
EXPECT_FALSE(cfg.isRSOOEnabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
|
||||||
|
|
||||||
// Should be possible to specify that an option is RSOO-enabled
|
|
||||||
EXPECT_NO_THROW(cfg.addRSOO(200));
|
|
||||||
EXPECT_TRUE(cfg.isRSOOEnabled(200));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
99
src/lib/dhcpsrv/tests/cfg_rsoo_unittest.cc
Normal file
99
src/lib/dhcpsrv/tests/cfg_rsoo_unittest.cc
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <dhcp/dhcp6.h>
|
||||||
|
#include <dhcpsrv/cfg_rsoo.h>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
using namespace isc;
|
||||||
|
using namespace isc::dhcp;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// This test verifies that the RSOO configuration holds the default
|
||||||
|
// RSOO-enabled options.
|
||||||
|
TEST(CfgRSOOTest, defaults) {
|
||||||
|
CfgRSOO rsoo;
|
||||||
|
EXPECT_TRUE(rsoo.enabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
for (uint16_t code = 0; code < 200; ++code) {
|
||||||
|
if (code != D6O_ERP_LOCAL_DOMAIN_NAME) {
|
||||||
|
EXPECT_FALSE(rsoo.enabled(code))
|
||||||
|
<< "expected that the option with code "
|
||||||
|
<< code << " is by default RSOO-disabled, but"
|
||||||
|
" it is enabled";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, let's see if we can remove the default options.
|
||||||
|
ASSER_NO_THROW(rsoo.clear());
|
||||||
|
EXPECT_FALSE(rsoo.enabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
|
||||||
|
// Make sure it can be added again.
|
||||||
|
ASSERT_NO_THROW(rsoo.enable(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
EXPECT_TRUE(rsoo.enabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verifies that it is possible to enable more RSOO options
|
||||||
|
// and later remove all of them.
|
||||||
|
TEST(CfgRSOOTest, enableAndClear) {
|
||||||
|
CfgRSOO rsoo;
|
||||||
|
EXPECT_TRUE(rsoo.enabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
|
||||||
|
// Enable option 88.
|
||||||
|
ASSERT_FALSE(rsoo.enabled(88));
|
||||||
|
ASSERT_NO_THROW(rsoo.enable(88));
|
||||||
|
EXPECT_TRUE(rsoo.enabled(88));
|
||||||
|
|
||||||
|
// Enable option 89.
|
||||||
|
ASSERT_FALSE(rsoo.enabled(89));
|
||||||
|
ASSERT_NO_THROW(rsoo.enable(89));
|
||||||
|
EXPECT_TRUE(rsoo.enabled(89));
|
||||||
|
|
||||||
|
// Remove them and make sure they have been removed.
|
||||||
|
ASSERT_NO_THROW(rsoo.clear());
|
||||||
|
for (uint16_t code = 0; code < 200; ++code) {
|
||||||
|
EXPECT_FALSE(rsoo.enabled(code))
|
||||||
|
<< "expected that the option with code "
|
||||||
|
<< code << " is RSOO-disabled after clearing"
|
||||||
|
" the RSOO configuration, but it is not";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verfies that the same option may be specified
|
||||||
|
// multiple times and that the code doesn't fail.
|
||||||
|
TEST(CfgRSOOTest, enableTwice) {
|
||||||
|
CfgRSOO rsoo;
|
||||||
|
// By default there should be the default option enabled.
|
||||||
|
// Let's try to enable it again. It should pass.
|
||||||
|
ASSERT_NO_THROW(rsoo.enable(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
EXPECT_TRUE(rsoo.enabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
|
||||||
|
// Enable option 88.
|
||||||
|
ASSERT_FALSE(rsoo.enabled(88));
|
||||||
|
ASSERT_NO_THROW(rsoo.enable(88));
|
||||||
|
EXPECT_TRUE(rsoo.enabled);
|
||||||
|
|
||||||
|
// And enable it again.
|
||||||
|
ASSERT_NO_THROW(rsoo.enabled(88));
|
||||||
|
EXPECT_TRUE(rsoo.enabled(88));
|
||||||
|
|
||||||
|
// Remove all.
|
||||||
|
ASSERT_NO_THROW(rsoo.clear());
|
||||||
|
ASSERT_FALSE(rsoo.enabled(D6O_ERP_LOCAL_DOMAIN_NAME));
|
||||||
|
ASSERT_FALSE(rsoo.enabled(88));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of anonymous namespace
|
Reference in New Issue
Block a user