ParserCollection subnets_;
};
+/// @brief parser for list of RSOO options
+///
+/// This parser handles Dhcp6/relay-supplied-options entry.
+/// It contains a list of option codes.
+class RSOOListConfigParser : public DhcpConfigParser {
+public:
+
+ /// @brief constructor
+ ///
+ /// As this is a dedicated parser, it must be used to parse
+ /// "relay-supplied-options" parameter only. All other types will throw exception.
+ ///
+ /// @param param_name name of the configuration parameter being parsed
+ /// @throw BadValue if supplied parameter name is not "relay-supplied-options"
+ RSOOListConfigParser(const std::string& param_name) {
+ if (param_name != "relay-supplied-options") {
+ isc_throw(BadValue, "Internal error. RSOO configuration "
+ "parser called for the wrong parameter: " << param_name);
+ }
+ }
+
+ /// @brief parses parameters value
+ ///
+ /// Parses configuration entry (list of sources) and adds each element
+ /// to the RSOO list.
+ ///
+ /// @param value pointer to the content of parsed values
+ virtual void build(isc::data::ConstElementPtr value) {
+
+ // 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()) {
+
+ std::string option_str = source_elem->stringValue();
+ // This option can be either code (integer) or name. Let's try code first
+ uint16_t code = 0;
+ try {
+ code = boost::lexical_cast<uint16_t>(option_str);
+ } catch (const boost::bad_lexical_cast &) {
+ // Oh well, it's not a number
+ }
+
+ if (!code) {
+ OptionDefinitionPtr def = LibDHCP::getOptionDef(Option::V6, option_str);
+ if (def) {
+ code = def->getCode();
+ } else {
+ isc_throw(BadValue, "Unable to convert '" << option_str
+ << "' to option code while parsing allowed"
+ << "relay-supplied-options");
+ }
+ }
+ CfgMgr::instance().getStagingCfg()->getCfgOption()->addRSOO(code);
+ }
+ }
+
+ /// @brief Does nothing.
+ virtual void commit() {}
+};
+
+
} // anonymous namespace
namespace isc {
} else if (config_id.compare("mac-sources") == 0) {
parser = new MACSourcesListConfigParser(config_id,
globalContext());
+ } else if (config_id.compare("relay-supplied-options") == 0) {
+ parser = new RSOOListConfigParser(config_id);
} else {
isc_throw(DhcpConfigError,
"unsupported global configuration parameter: "
EXPECT_EQ(Subnet::HR_ALL, subnet->getHostReservationMode());
}
+/// The goal of this test is to verify that configuration can include
+/// Relay Supplied options (specified as numbers).
+TEST_F(Dhcp6ParserTest, rsooNumbers) {
+
+ ConstElementPtr status;
+
+ EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
+ Element::fromJSON("{ " + genIfaceConfig() + ","
+ "\"relay-supplied-options\": [ \"10\", \"20\", \"30\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ ], "
+ "\"valid-lifetime\": 4000 }")));
+
+ // returned value should be 0 (success)
+ checkResult(status, 0);
+
+ // The following codes should be enabled now
+ EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(10));
+ EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(20));
+ EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(30));
+
+ // 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)
+ EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()
+ ->isRSOOEnabled(D6O_ERP_LOCAL_DOMAIN_NAME));
+
+ // Those options are not enabled
+ EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(25));
+ EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()->isRSOOEnabled(1));
+}
+
+/// The goal of this test is to verify that configuration can include
+/// Relay Supplied options (specified as names).
+TEST_F(Dhcp6ParserTest, rsooNames) {
+
+ ConstElementPtr status;
+
+ EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
+ Element::fromJSON("{ " + genIfaceConfig() + ","
+ "\"relay-supplied-options\": [ \"dns-servers\", \"remote-id\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ ], "
+ "\"valid-lifetime\": 4000 }")));
+
+ // returned value should be 0 (success)
+ checkResult(status, 0);
+
+ for (uint16_t code = 0; code < D6O_NAME_SERVERS; ++code) {
+ EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()
+ ->isRSOOEnabled(code)) << " for option code " << code;
+ }
+
+ // The following codes should be enabled now
+ EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()
+ ->isRSOOEnabled(D6O_NAME_SERVERS));
+
+ for (uint16_t code = D6O_NAME_SERVERS + 1; code < D6O_REMOTE_ID; ++code) {
+ EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()
+ ->isRSOOEnabled(code)) << " for option code " << code;
+ }
+
+ // Check remote-id. It should be enabled.
+ EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()
+ ->isRSOOEnabled(D6O_REMOTE_ID));
+ for (uint16_t code = D6O_REMOTE_ID + 1; code < D6O_ERP_LOCAL_DOMAIN_NAME; ++code) {
+ EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()
+ ->isRSOOEnabled(code)) << " for option code " << code;
+ }
+
+ // 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)
+ EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getCfgOption()
+ ->isRSOOEnabled(D6O_ERP_LOCAL_DOMAIN_NAME));
+
+ for (uint16_t code = D6O_ERP_LOCAL_DOMAIN_NAME + 1; code < 300; ++code) {
+ EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getCfgOption()
+ ->isRSOOEnabled(code)) << " for option code " << code;
+ }
+
+
+}
+
+
};