Browse Source

[3589] Moved subnet-specific option configuration to CfgOption class.

Marcin Siodelski 10 years ago
parent
commit
08c3a4aee4

+ 7 - 8
src/bin/dhcp4/dhcp4_srv.cc

@@ -599,8 +599,7 @@ Dhcpv4Srv::appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
     for (std::vector<uint8_t>::const_iterator opt = requested_opts.begin();
          opt != requested_opts.end(); ++opt) {
         if (!msg->getOption(*opt)) {
-            OptionDescriptor desc =
-                subnet->getOptionDescriptor("dhcp4", *opt);
+            OptionDescriptor desc = subnet->getCfgOption()->get("dhcp4", *opt);
             if (desc.option && !msg->getOption(*opt)) {
                 msg->addOption(desc.option);
             }
@@ -650,8 +649,8 @@ Dhcpv4Srv::appendRequestedVendorOptions(const Pkt4Ptr& question, Pkt4Ptr& answer
     for (std::vector<uint8_t>::const_iterator code = requested_opts.begin();
          code != requested_opts.end(); ++code) {
         if  (!vendor_rsp->getOption(*code)) {
-            OptionDescriptor desc = subnet->getVendorOptionDescriptor(vendor_id,
-                                                                              *code);
+            OptionDescriptor desc = subnet->getCfgOption()->get(vendor_id,
+                                                                *code);
             if (desc.option) {
                 vendor_rsp->addOption(desc.option);
                 added = true;
@@ -689,8 +688,8 @@ Dhcpv4Srv::appendBasicOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
         OptionPtr opt = msg->getOption(required_options[i]);
         if (!opt) {
             // Check whether option has been configured.
-            OptionDescriptor desc =
-                subnet->getOptionDescriptor("dhcp4", required_options[i]);
+            OptionDescriptor desc = subnet->getCfgOption()->
+                get("dhcp4", required_options[i]);
             if (desc.option) {
                 msg->addOption(desc.option);
             }
@@ -1949,8 +1948,8 @@ bool Dhcpv4Srv::classSpecificProcessing(const Pkt4Ptr& query, const Pkt4Ptr& rsp
 
         // Now try to set up file field in DHCPv4 packet. We will just copy
         // content of the boot-file option, which contains the same information.
-        OptionDescriptor desc =
-            subnet->getOptionDescriptor("dhcp4", DHO_BOOT_FILE_NAME);
+        OptionDescriptor desc = subnet->getCfgOption()->
+            get("dhcp4", DHO_BOOT_FILE_NAME);
 
         if (desc.option) {
             boost::shared_ptr<OptionString> boot =

+ 2 - 1
src/bin/dhcp4/json_config_parser.cc

@@ -16,6 +16,7 @@
 #include <dhcp4/dhcp4_log.h>
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option_definition.h>
+#include <dhcpsrv/cfg_option.h>
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcp4/json_config_parser.h>
 #include <dhcpsrv/dbaccess_parser.h>
@@ -97,7 +98,7 @@ protected:
         } else {
             // Check if this is a vendor-option. If it is, get vendor-specific
             // definition.
-            uint32_t vendor_id = SubnetConfigParser::optionSpaceToVendorId(option_space);
+            uint32_t vendor_id = CfgOption::optionSpaceToVendorId(option_space);
             if (vendor_id) {
                 def = LibDHCP::getVendorOptionDef(Option::V4, vendor_id, option_code);
             }

+ 19 - 19
src/bin/dhcp4/tests/config_parser_unittest.cc

@@ -244,7 +244,7 @@ public:
                           << "does not exist in Config Manager";
         }
         OptionContainerPtr options =
-            subnet->getOptionDescriptors("dhcp4");
+            subnet->getCfgOption()->getAll("dhcp4");
         if (expected_options_count != options->size()) {
             ADD_FAILURE() << "The number of options in the subnet '"
                           << subnet_address.toText() << "' is different "
@@ -1797,7 +1797,7 @@ TEST_F(Dhcp4ParserTest, optionDataDefaults) {
     Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
                                                       classify_);
     ASSERT_TRUE(subnet);
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
     ASSERT_EQ(2, options->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -1884,16 +1884,16 @@ TEST_F(Dhcp4ParserTest, optionDataTwoSpaces) {
                                                       classify_);
     ASSERT_TRUE(subnet);
     // Try to get the option from the space dhcp4.
-    OptionDescriptor desc1 = subnet->getOptionDescriptor("dhcp4", 56);
+    OptionDescriptor desc1 = subnet->getCfgOption()->get("dhcp4", 56);
     ASSERT_TRUE(desc1.option);
     EXPECT_EQ(56, desc1.option->getType());
     // Try to get the option from the space isc.
-    OptionDescriptor desc2 = subnet->getOptionDescriptor("isc", 56);
+    OptionDescriptor desc2 = subnet->getCfgOption()->get("isc", 56);
     ASSERT_TRUE(desc2.option);
     EXPECT_EQ(56, desc1.option->getType());
     // Try to get the non-existing option from the non-existing
     // option space and  expect that option is not returned.
-    OptionDescriptor desc3 = subnet->getOptionDescriptor("non-existing", 56);
+    OptionDescriptor desc3 = subnet->getCfgOption()->get("non-existing", 56);
     ASSERT_FALSE(desc3.option);
 }
 
@@ -2039,12 +2039,12 @@ TEST_F(Dhcp4ParserTest, optionDataEncapsulate) {
     ASSERT_TRUE(subnet);
 
     // We should have one option available.
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
     ASSERT_TRUE(options);
     ASSERT_EQ(1, options->size());
 
     // Get the option.
-    OptionDescriptor desc = subnet->getOptionDescriptor("dhcp4", 222);
+    OptionDescriptor desc = subnet->getCfgOption()->get("dhcp4", 222);
     EXPECT_TRUE(desc.option);
     EXPECT_EQ(222, desc.option->getType());
 
@@ -2104,7 +2104,7 @@ TEST_F(Dhcp4ParserTest, optionDataInSingleSubnet) {
     Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.24"),
                                                       classify_);
     ASSERT_TRUE(subnet);
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
     ASSERT_EQ(2, options->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -2255,7 +2255,7 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
     Subnet4Ptr subnet1 = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.100"),
                                                        classify_);
     ASSERT_TRUE(subnet1);
-    OptionContainerPtr options1 = subnet1->getOptionDescriptors("dhcp4");
+    OptionContainerPtr options1 = subnet1->getCfgOption()->getAll("dhcp4");
     ASSERT_EQ(1, options1->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -2280,7 +2280,7 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
     Subnet4Ptr subnet2 = CfgMgr::instance().getSubnet4(IOAddress("192.0.3.102"),
                                                        classify_);
     ASSERT_TRUE(subnet2);
-    OptionContainerPtr options2 = subnet2->getOptionDescriptors("dhcp4");
+    OptionContainerPtr options2 = subnet2->getCfgOption()->getAll("dhcp4");
     ASSERT_EQ(1, options2->size());
 
     const OptionContainerTypeIndex& idx2 = options2->get<1>();
@@ -2358,7 +2358,7 @@ TEST_F(Dhcp4ParserTest, optionDataLowerCase) {
     Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
                                                       classify_);
     ASSERT_TRUE(subnet);
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
     ASSERT_EQ(1, options->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -2402,7 +2402,7 @@ TEST_F(Dhcp4ParserTest, stdOptionData) {
                                                       classify_);
     ASSERT_TRUE(subnet);
     OptionContainerPtr options =
-        subnet->getOptionDescriptors("dhcp4");
+        subnet->getCfgOption()->getAll("dhcp4");
     ASSERT_TRUE(options);
     ASSERT_EQ(1, options->size());
 
@@ -2611,13 +2611,13 @@ TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
     ASSERT_TRUE(subnet);
 
     // We should have one option available.
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
     ASSERT_TRUE(options);
     ASSERT_EQ(1, options->size());
 
     // Get the option.
     OptionDescriptor desc =
-        subnet->getOptionDescriptor("dhcp4", DHO_VENDOR_ENCAPSULATED_OPTIONS);
+        subnet->getCfgOption()->get("dhcp4", DHO_VENDOR_ENCAPSULATED_OPTIONS);
     EXPECT_TRUE(desc.option);
     EXPECT_EQ(DHO_VENDOR_ENCAPSULATED_OPTIONS, desc.option->getType());
 
@@ -2695,17 +2695,17 @@ TEST_F(Dhcp4ParserTest, vendorOptionsHex) {
     ASSERT_TRUE(subnet);
 
     // Try to get the option from the vendor space 4491
-    OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(VENDOR_ID_CABLE_LABS, 100);
+    OptionDescriptor desc1 = subnet->getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
     ASSERT_TRUE(desc1.option);
     EXPECT_EQ(100, desc1.option->getType());
     // Try to get the option from the vendor space 1234
-    OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(1234, 100);
+    OptionDescriptor desc2 = subnet->getCfgOption()->get(1234, 100);
     ASSERT_TRUE(desc2.option);
     EXPECT_EQ(100, desc1.option->getType());
 
     // Try to get the non-existing option from the non-existing
     // option space and  expect that option is not returned.
-    OptionDescriptor desc3 = subnet->getVendorOptionDescriptor(5678, 100);
+    OptionDescriptor desc3 = subnet->getCfgOption()->get(5678, 100);
     ASSERT_FALSE(desc3.option);
 }
 
@@ -2756,13 +2756,13 @@ TEST_F(Dhcp4ParserTest, vendorOptionsCsv) {
     ASSERT_TRUE(subnet);
 
     // Try to get the option from the vendor space 4491
-    OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(VENDOR_ID_CABLE_LABS, 100);
+    OptionDescriptor desc1 = subnet->getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
     ASSERT_TRUE(desc1.option);
     EXPECT_EQ(100, desc1.option->getType());
 
     // Try to get the non-existing option from the non-existing
     // option space and  expect that option is not returned.
-    OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(5678, 100);
+    OptionDescriptor desc2 = subnet->getCfgOption()->get(5678, 100);
     ASSERT_FALSE(desc2.option);
 }
 

+ 5 - 5
src/bin/dhcp4/tests/dhcp4_test_utils.cc

@@ -52,7 +52,7 @@ Dhcpv4SrvTest::Dhcpv4SrvTest()
     // Add Router option.
     Option4AddrLstPtr opt_routers(new Option4AddrLst(DHO_ROUTERS));
     opt_routers->setAddress(IOAddress("192.0.2.2"));
-    subnet_->addOption(opt_routers, false, "dhcp4");
+    subnet_->getCfgOption()->add(opt_routers, false, "dhcp4");
 }
 
 Dhcpv4SrvTest::~Dhcpv4SrvTest() {
@@ -86,24 +86,24 @@ void Dhcpv4SrvTest::configureRequestedOptions() {
         option_dns_servers(new Option4AddrLst(DHO_DOMAIN_NAME_SERVERS));
     option_dns_servers->addAddress(IOAddress("192.0.2.1"));
     option_dns_servers->addAddress(IOAddress("192.0.2.100"));
-    ASSERT_NO_THROW(subnet_->addOption(option_dns_servers, false, "dhcp4"));
+    ASSERT_NO_THROW(subnet_->getCfgOption()->add(option_dns_servers, false, "dhcp4"));
 
     // domain-name
     OptionDefinition def("domain-name", DHO_DOMAIN_NAME, OPT_FQDN_TYPE);
     OptionCustomPtr option_domain_name(new OptionCustom(def, Option::V4));
     option_domain_name->writeFqdn("example.com");
-    subnet_->addOption(option_domain_name, false, "dhcp4");
+    subnet_->getCfgOption()->add(option_domain_name, false, "dhcp4");
 
     // log-servers
     Option4AddrLstPtr option_log_servers(new Option4AddrLst(DHO_LOG_SERVERS));
     option_log_servers->addAddress(IOAddress("192.0.2.2"));
     option_log_servers->addAddress(IOAddress("192.0.2.10"));
-    ASSERT_NO_THROW(subnet_->addOption(option_log_servers, false, "dhcp4"));
+    ASSERT_NO_THROW(subnet_->getCfgOption()->add(option_log_servers, false, "dhcp4"));
 
     // cookie-servers
     Option4AddrLstPtr option_cookie_servers(new Option4AddrLst(DHO_COOKIE_SERVERS));
     option_cookie_servers->addAddress(IOAddress("192.0.2.1"));
-    ASSERT_NO_THROW(subnet_->addOption(option_cookie_servers, false, "dhcp4"));
+    ASSERT_NO_THROW(subnet_->getCfgOption()->add(option_cookie_servers, false, "dhcp4"));
 }
 
 void Dhcpv4SrvTest::messageCheck(const Pkt4Ptr& q, const Pkt4Ptr& a) {

+ 2 - 2
src/bin/dhcp6/dhcp6_srv.cc

@@ -731,7 +731,7 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
     // Get the list of options that client requested.
     const std::vector<uint16_t>& requested_opts = option_oro->getValues();
     BOOST_FOREACH(uint16_t opt, requested_opts) {
-        OptionDescriptor desc = subnet->getOptionDescriptor("dhcp6", opt);
+        OptionDescriptor desc = subnet->getCfgOption()->get("dhcp6", opt);
         if (desc.option) {
             answer->addOption(desc.option);
         }
@@ -777,7 +777,7 @@ Dhcpv6Srv::appendRequestedVendorOptions(const Pkt6Ptr& question, Pkt6Ptr& answer
     bool added = false;
     const std::vector<uint16_t>& requested_opts = oro->getValues();
     BOOST_FOREACH(uint16_t opt, requested_opts) {
-        OptionDescriptor desc = subnet->getVendorOptionDescriptor(vendor_id, opt);
+        OptionDescriptor desc = subnet->getCfgOption()->get(vendor_id, opt);
         if (desc.option) {
             vendor_rsp->addOption(desc.option);
             added = true;

+ 2 - 1
src/bin/dhcp6/json_config_parser.cc

@@ -19,6 +19,7 @@
 #include <dhcp6/json_config_parser.h>
 #include <dhcp6/dhcp6_log.h>
 #include <dhcp/iface_mgr.h>
+#include <dhcpsrv/cfg_option.h>
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/dbaccess_parser.h>
 #include <dhcpsrv/dhcp_config_parser.h>
@@ -112,7 +113,7 @@ protected:
         } else {
             // Check if this is a vendor-option. If it is, get vendor-specific
             // definition.
-            uint32_t vendor_id = SubnetConfigParser::optionSpaceToVendorId(option_space);
+            uint32_t vendor_id = CfgOption::optionSpaceToVendorId(option_space);
             if (vendor_id) {
                 def = LibDHCP::getVendorOptionDef(Option::V6, vendor_id, option_code);
             }

+ 18 - 19
src/bin/dhcp6/tests/config_parser_unittest.cc

@@ -256,7 +256,7 @@ public:
                           << "does not exist in Config Manager";
         }
         OptionContainerPtr options =
-            subnet->getOptionDescriptors("dhcp6");
+            subnet->getCfgOption()->getAll("dhcp6");
         if (expected_options_count != options->size()) {
             ADD_FAILURE() << "The number of options in the subnet '"
                           << subnet_address.toText() << "' is different "
@@ -2030,7 +2030,7 @@ TEST_F(Dhcp6ParserTest, optionDataDefaults) {
     Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
                                                       classify_);
     ASSERT_TRUE(subnet);
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
     ASSERT_EQ(2, options->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -2126,16 +2126,16 @@ TEST_F(Dhcp6ParserTest, optionDataTwoSpaces) {
                                                       classify_);
     ASSERT_TRUE(subnet);
     // Try to get the option from the space dhcp6.
-    OptionDescriptor desc1 = subnet->getOptionDescriptor("dhcp6", 38);
+    OptionDescriptor desc1 = subnet->getCfgOption()->get("dhcp6", 38);
     ASSERT_TRUE(desc1.option);
     EXPECT_EQ(38, desc1.option->getType());
     // Try to get the option from the space isc.
-    OptionDescriptor desc2 = subnet->getOptionDescriptor("isc", 38);
+    OptionDescriptor desc2 = subnet->getCfgOption()->get("isc", 38);
     ASSERT_TRUE(desc2.option);
     EXPECT_EQ(38, desc1.option->getType());
     // Try to get the non-existing option from the non-existing
     // option space and  expect that option is not returned.
-    OptionDescriptor desc3 = subnet->getOptionDescriptor("non-existing", 38);
+    OptionDescriptor desc3 = subnet->getCfgOption()->get("non-existing", 38);
     ASSERT_FALSE(desc3.option);
 }
 
@@ -2283,12 +2283,12 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
     ASSERT_TRUE(subnet);
 
     // We should have one option available.
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
     ASSERT_TRUE(options);
     ASSERT_EQ(1, options->size());
 
     // Get the option.
-    OptionDescriptor desc = subnet->getOptionDescriptor("dhcp6", 100);
+    OptionDescriptor desc = subnet->getCfgOption()->get("dhcp6", 100);
     EXPECT_TRUE(desc.option);
     EXPECT_EQ(100, desc.option->getType());
 
@@ -2344,7 +2344,7 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
     Subnet6Ptr subnet1 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
                                                        classify_);
     ASSERT_TRUE(subnet1);
-    OptionContainerPtr options1 = subnet1->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options1 = subnet1->getCfgOption()->getAll("dhcp6");
     ASSERT_EQ(1, options1->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -2370,7 +2370,7 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
     Subnet6Ptr subnet2 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:2::4"),
                                                        classify_);
     ASSERT_TRUE(subnet2);
-    OptionContainerPtr options2 = subnet2->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options2 = subnet2->getCfgOption()->getAll("dhcp6");
     ASSERT_EQ(1, options2->size());
 
     const OptionContainerTypeIndex& idx2 = options2->get<1>();
@@ -2541,7 +2541,7 @@ TEST_F(Dhcp6ParserTest, optionDataLowerCase) {
     Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
                                                       classify_);
     ASSERT_TRUE(subnet);
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
     ASSERT_EQ(1, options->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -2584,7 +2584,7 @@ TEST_F(Dhcp6ParserTest, stdOptionData) {
     Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
                                                       classify_);
     ASSERT_TRUE(subnet);
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
     ASSERT_EQ(1, options->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -2664,17 +2664,17 @@ TEST_F(Dhcp6ParserTest, vendorOptionsHex) {
     ASSERT_TRUE(subnet);
 
     // Try to get the option from the vendor space 4491
-    OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(4491, 100);
+    OptionDescriptor desc1 = subnet->getCfgOption()->get(4491, 100);
     ASSERT_TRUE(desc1.option);
     EXPECT_EQ(100, desc1.option->getType());
     // Try to get the option from the vendor space 1234
-    OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(1234, 100);
+    OptionDescriptor desc2 = subnet->getCfgOption()->get(1234, 100);
     ASSERT_TRUE(desc2.option);
     EXPECT_EQ(100, desc1.option->getType());
 
     // Try to get the non-existing option from the non-existing
     // option space and  expect that option is not returned.
-    OptionDescriptor desc3 = subnet->getVendorOptionDescriptor(5678, 38);
+    OptionDescriptor desc3 = subnet->getCfgOption()->get(5678, 38);
     ASSERT_FALSE(desc3.option);
 }
 
@@ -2726,13 +2726,13 @@ TEST_F(Dhcp6ParserTest, vendorOptionsCsv) {
     ASSERT_TRUE(subnet);
 
     // Try to get the option from the vendor space 4491
-    OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(4491, 100);
+    OptionDescriptor desc1 = subnet->getCfgOption()->get(4491, 100);
     ASSERT_TRUE(desc1.option);
     EXPECT_EQ(100, desc1.option->getType());
 
     // Try to get the non-existing option from the non-existing
     // option space and  expect that option is not returned.
-    OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(5678, 100);
+    OptionDescriptor desc2 = subnet->getCfgOption()->get(5678, 100);
     ASSERT_FALSE(desc2.option);
 }
 
@@ -2865,13 +2865,12 @@ TEST_F(Dhcp6ParserTest, stdOptionDataEncapsulate) {
     ASSERT_TRUE(subnet);
 
     // We should have one option available.
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
     ASSERT_TRUE(options);
     ASSERT_EQ(1, options->size());
 
     // Get the option.
-    OptionDescriptor desc =
-        subnet->getOptionDescriptor("dhcp6", D6O_VENDOR_OPTS);
+    OptionDescriptor desc = subnet->getCfgOption()->get("dhcp6", D6O_VENDOR_OPTS);
     EXPECT_TRUE(desc.option);
     EXPECT_EQ(D6O_VENDOR_OPTS, desc.option->getType());
 

+ 40 - 43
src/lib/dhcpsrv/cfg_option.cc

@@ -18,49 +18,6 @@
 #include <limits>
 #include <string>
 
-namespace {
-
-uint32_t
-optionSpaceToVendorId(const std::string& option_space) {
-    if (option_space.size() < 8) {
-        // 8 is a minimal length of "vendor-X" format
-        return (0);
-    }
-    if (option_space.substr(0,7) != "vendor-") {
-        return (0);
-    }
-
-    // text after "vendor-", supposedly numbers only
-    std::string x = option_space.substr(7);
-
-    int64_t check;
-    try {
-        check = boost::lexical_cast<int64_t>(x);
-    } catch (const boost::bad_lexical_cast &) {
-        /// @todo: Should we throw here?
-        // isc_throw(BadValue, "Failed to parse vendor-X value (" << x
-        //           << ") as unsigned 32-bit integer.");
-        return (0);
-    }
-    if (check > std::numeric_limits<uint32_t>::max()) {
-        /// @todo: Should we throw here?
-        //isc_throw(BadValue, "Value " << x << "is too large"
-        //          << " for unsigned 32-bit integer.");
-        return (0);
-    }
-    if (check < 0) {
-        /// @todo: Should we throw here?
-        // isc_throw(BadValue, "Value " << x << "is negative."
-        //       << " Only 0 or larger are allowed for unsigned 32-bit integer.");
-        return (0);
-    }
-
-    // value is small enough to fit
-    return (static_cast<uint32_t>(check));
-}
-
-}
-
 namespace isc {
 namespace dhcp {
 
@@ -160,5 +117,45 @@ CfgOption::getAll(const uint32_t vendor_id) const {
     return (vendor_options_.getItems(vendor_id));
 }
 
+uint32_t
+CfgOption::optionSpaceToVendorId(const std::string& option_space) {
+    if (option_space.size() < 8) {
+        // 8 is a minimal length of "vendor-X" format
+        return (0);
+    }
+    if (option_space.substr(0,7) != "vendor-") {
+        return (0);
+    }
+
+    // text after "vendor-", supposedly numbers only
+    std::string x = option_space.substr(7);
+
+    int64_t check;
+    try {
+        check = boost::lexical_cast<int64_t>(x);
+    } catch (const boost::bad_lexical_cast &) {
+        /// @todo: Should we throw here?
+        // isc_throw(BadValue, "Failed to parse vendor-X value (" << x
+        //           << ") as unsigned 32-bit integer.");
+        return (0);
+    }
+    if (check > std::numeric_limits<uint32_t>::max()) {
+        /// @todo: Should we throw here?
+        //isc_throw(BadValue, "Value " << x << "is too large"
+        //          << " for unsigned 32-bit integer.");
+        return (0);
+    }
+    if (check < 0) {
+        /// @todo: Should we throw here?
+        // isc_throw(BadValue, "Value " << x << "is negative."
+        //       << " Only 0 or larger are allowed for unsigned 32-bit integer.");
+        return (0);
+    }
+
+    // value is small enough to fit
+    return (static_cast<uint32_t>(check));
+}
+
+
 } // end of namespace isc::dhcp
 } // end of namespace isc

+ 13 - 0
src/lib/dhcpsrv/cfg_option.h

@@ -317,6 +317,19 @@ public:
         return (*range.first);
     }
 
+    /// @brief Converts option space name to vendor id.
+    ///
+    /// If the option space name is specified in the following format:
+    /// "vendor-X" where X is an uint32_t number, it is assumed to be
+    /// a vendor space and the uint32_t number is returned by this function.
+    ///
+    /// @todo remove this function once when the conversion is dealt by the
+    /// appropriate functions returning options by option space names.
+    ///
+    /// @param option_space Option space name.
+    /// @return vendor id.
+    static uint32_t optionSpaceToVendorId(const std::string& option_space);
+
 private:
 
     /// @brief Merges data from two option containers.

+ 6 - 61
src/lib/dhcpsrv/dhcp_parsers.cc

@@ -1163,23 +1163,15 @@ SubnetConfigParser::createSubnet() {
             // option code has been already added. If so, we want
             // to issue a warning.
             OptionDescriptor existing_desc =
-                            subnet_->getOptionDescriptor("option_space",
-                                                 desc.option->getType());
+                subnet_->getCfgOption()->get("option_space", desc.option->getType());
+
             if (existing_desc.option) {
                 duplicate_option_warning(desc.option->getType(), addr);
             }
             // Add sub-options (if any).
             appendSubOptions(option_space, desc.option);
 
-            // Check if the option space defines a vendor-option
-            uint32_t vendor_id = optionSpaceToVendorId(option_space);
-            if (vendor_id) {
-                // This is a vendor option
-                subnet_->addVendorOption(desc.option, false, vendor_id);
-            } else {
-                // This is a normal option
-                subnet_->addOption(desc.option, false, option_space);
-            }
+            subnet_->getCfgOption()->add(desc.option, false, option_space);
         }
     }
 
@@ -1202,65 +1194,18 @@ SubnetConfigParser::createSubnet() {
             // subnet scope take precedence over globally configured
             // values we don't add option from the global storage
             // if there is one already.
-            OptionDescriptor existing_desc =
-                    subnet_->getOptionDescriptor(option_space,
-                                                desc.option->getType());
+            OptionDescriptor existing_desc =  subnet_->getCfgOption()->
+                get(option_space, desc.option->getType());
             if (!existing_desc.option) {
                 // Add sub-options (if any).
                 appendSubOptions(option_space, desc.option);
 
-                uint32_t vendor_id = optionSpaceToVendorId(option_space);
-                if (vendor_id) {
-                    // This is a vendor option
-                    subnet_->addVendorOption(desc.option, false, vendor_id);
-                } else {
-                    // This is a normal option
-                    subnet_->addOption(desc.option, false, option_space);
-                }
+                subnet_->getCfgOption()->add(desc.option, false, option_space);
             }
         }
     }
 }
 
-uint32_t
-SubnetConfigParser::optionSpaceToVendorId(const std::string& option_space) {
-    if (option_space.size() < 8) {
-        // 8 is a minimal length of "vendor-X" format
-        return (0);
-    }
-    if (option_space.substr(0,7) != "vendor-") {
-        return (0);
-    }
-
-    // text after "vendor-", supposedly numbers only
-    string x = option_space.substr(7);
-
-    int64_t check;
-    try {
-        check = boost::lexical_cast<int64_t>(x);
-    } catch (const boost::bad_lexical_cast &) {
-        /// @todo: Should we throw here?
-        // isc_throw(BadValue, "Failed to parse vendor-X value (" << x
-        //           << ") as unsigned 32-bit integer.");
-        return (0);
-    }
-    if (check > std::numeric_limits<uint32_t>::max()) {
-        /// @todo: Should we throw here?
-        //isc_throw(BadValue, "Value " << x << "is too large"
-        //          << " for unsigned 32-bit integer.");
-        return (0);
-    }
-    if (check < 0) {
-        /// @todo: Should we throw here?
-        // isc_throw(BadValue, "Value " << x << "is negative."
-        //       << " Only 0 or larger are allowed for unsigned 32-bit integer.");
-        return (0);
-    }
-
-    // value is small enough to fit
-    return (static_cast<uint32_t>(check));
-}
-
 isc::dhcp::Triplet<uint32_t>
 SubnetConfigParser::getParam(const std::string& name) {
     uint32_t value = 0;

+ 3 - 95
src/lib/dhcpsrv/subnet.cc

@@ -37,7 +37,9 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
      t1_(t1), t2_(t2), valid_(valid_lifetime),
      last_allocated_ia_(lastAddrInPrefix(prefix, len)),
      last_allocated_ta_(lastAddrInPrefix(prefix, len)),
-     last_allocated_pd_(lastAddrInPrefix(prefix, len)), relay_(relay)
+     last_allocated_pd_(lastAddrInPrefix(prefix, len)), relay_(relay),
+     cfg_option_(new CfgOption())
+
       {
     if ((prefix.isV6() && len > 128) ||
         (prefix.isV4() && len > 32)) {
@@ -59,20 +61,6 @@ Subnet::inRange(const isc::asiolink::IOAddress& addr) const {
 }
 
 void
-Subnet::addOption(const OptionPtr& option, bool persistent,
-                  const std::string& option_space) {
-    // Check that the option space name is valid.
-    if (!OptionSpace::validateName(option_space)) {
-        isc_throw(isc::BadValue, "invalid option space name: '"
-                  << option_space << "'");
-    }
-    validateOption(option);
-
-    // Actually add new option descriptor.
-    option_spaces_.addItem(OptionDescriptor(option, persistent), option_space);
-}
-
-void
 Subnet::setRelayInfo(const isc::dhcp::Subnet::RelayInfo& relay) {
     relay_ = relay;
 }
@@ -99,64 +87,6 @@ Subnet::allowClientClass(const isc::dhcp::ClientClass& class_name) {
     white_list_.insert(class_name);
 }
 
-void
-Subnet::delOptions() {
-    option_spaces_.clearItems();
-}
-
-OptionContainerPtr
-Subnet::getOptionDescriptors(const std::string& option_space) const {
-    return (option_spaces_.getItems(option_space));
-}
-
-OptionDescriptor
-Subnet::getOptionDescriptor(const std::string& option_space,
-                            const uint16_t option_code) {
-    OptionContainerPtr options = getOptionDescriptors(option_space);
-    if (!options || options->empty()) {
-        return (OptionDescriptor(false));
-    }
-    const OptionContainerTypeIndex& idx = options->get<1>();
-    const OptionContainerTypeRange& range = idx.equal_range(option_code);
-    if (std::distance(range.first, range.second) == 0) {
-        return (OptionDescriptor(false));
-    }
-
-    return (*range.first);
-}
-
-void Subnet::addVendorOption(const OptionPtr& option, bool persistent,
-                             uint32_t vendor_id){
-
-    validateOption(option);
-
-    vendor_option_spaces_.addItem(OptionDescriptor(option, persistent), vendor_id);
-}
-
-OptionContainerPtr
-Subnet::getVendorOptionDescriptors(uint32_t vendor_id) const {
-    return (vendor_option_spaces_.getItems(vendor_id));
-}
-
-OptionDescriptor
-Subnet::getVendorOptionDescriptor(uint32_t vendor_id, uint16_t option_code) {
-    OptionContainerPtr options = getVendorOptionDescriptors(vendor_id);
-    if (!options || options->empty()) {
-        return (OptionDescriptor(false));
-    }
-    const OptionContainerTypeIndex& idx = options->get<1>();
-    const OptionContainerTypeRange& range = idx.equal_range(option_code);
-    if (std::distance(range.first, range.second) == 0) {
-        return (OptionDescriptor(false));
-    }
-
-    return (*range.first);
-}
-
-void Subnet::delVendorOptions() {
-    vendor_option_spaces_.clearItems();
-}
-
 isc::asiolink::IOAddress Subnet::getLastAllocated(Lease::Type type) const {
     // check if the type is valid (and throw if it isn't)
     checkType(type);
@@ -330,17 +260,6 @@ Subnet::getIface() const {
     return (iface_);
 }
 
-void
-Subnet4::validateOption(const OptionPtr& option) const {
-    if (!option) {
-        isc_throw(isc::BadValue,
-                  "option configured for subnet must not be NULL");
-    } else if (option->getUniverse() != Option::V4) {
-        isc_throw(isc::BadValue,
-                  "expected V4 option to be added to the subnet");
-    }
-}
-
 bool
 Subnet::inPool(Lease::Type type, const isc::asiolink::IOAddress& addr) const {
 
@@ -384,16 +303,5 @@ void Subnet6::checkType(Lease::Type type) const {
     }
 }
 
-void
-Subnet6::validateOption(const OptionPtr& option) const {
-    if (!option) {
-        isc_throw(isc::BadValue,
-                  "option configured for subnet must not be NULL");
-    } else if (option->getUniverse() != Option::V6) {
-        isc_throw(isc::BadValue,
-                  "expected V6 option to be added to the subnet");
-    }
-}
-
 } // end of isc::dhcp namespace
 } // end of isc namespace

+ 6 - 95
src/lib/dhcpsrv/subnet.h

@@ -72,33 +72,6 @@ public:
     /// @brief checks if specified address is in range
     bool inRange(const isc::asiolink::IOAddress& addr) const;
 
-    /// @brief Add new option instance to the collection.
-    ///
-    /// @param option option instance.
-    /// @param persistent if true, send an option regardless if client
-    /// requested it or not.
-    /// @param option_space name of the option space to add an option to.
-    ///
-    /// @throw isc::BadValue if invalid option provided.
-    void addOption(const OptionPtr& option, bool persistent,
-                   const std::string& option_space);
-
-
-    /// @brief Adds new vendor option instance to the collection.
-    ///
-    /// @param option option instance.
-    /// @param persistent if true, send an option regardless if client
-    /// requested it or not.
-    /// @param vendor_id enterprise id of the vendor space to add an option to.
-    void addVendorOption(const OptionPtr& option, bool persistent,
-                         uint32_t vendor_id);
-
-    /// @brief Delete all options configured for the subnet.
-    void delOptions();
-
-    /// @brief Deletes all vendor options configured for the subnet.
-    void delVendorOptions();
-
     /// @brief checks if the specified address is in pools
     ///
     /// Note the difference between inSubnet() and inPool(). For a given
@@ -129,42 +102,10 @@ public:
         return (t2_);
     }
 
-    /// @brief Return a collection of option descriptors.
-    ///
-    /// @param option_space name of the option space.
-    ///
-    /// @return pointer to collection of options configured for a subnet.
-    OptionContainerPtr
-    getOptionDescriptors(const std::string& option_space) const;
-
-    /// @brief Return a collection of vendor option descriptors.
-    ///
-    /// @param vendor_id enterprise id of the option space.
-    ///
-    /// @return pointer to collection of options configured for a subnet.
-    OptionContainerPtr
-    getVendorOptionDescriptors(uint32_t vendor_id) const;
-
-    /// @brief Return single option descriptor.
-    ///
-    /// @param option_space name of the option space.
-    /// @param option_code code of the option to be returned.
-    ///
-    /// @return option descriptor found for the specified option space
-    /// and option code.
-    OptionDescriptor
-    getOptionDescriptor(const std::string& option_space,
-                        const uint16_t option_code);
-
-    /// @brief Return single vendor option descriptor.
-    ///
-    /// @param vendor_id enterprise id of the option space.
-    /// @param option_code code of the option to be returned.
-    ///
-    /// @return option descriptor found for the specified option space
-    /// and option code.
-    OptionDescriptor
-    getVendorOptionDescriptor(uint32_t vendor_id, uint16_t option_code);
+    /// @brief Returns pointer to the option data configuration for this subnet.
+    CfgOptionPtr getCfgOption() {
+        return (cfg_option_);
+    }
 
     /// @brief returns the last address that was tried from this pool
     ///
@@ -408,11 +349,6 @@ protected:
     /// @throw BadValue if invalid value is used
     virtual void checkType(Lease::Type type) const = 0;
 
-    /// @brief Check if option is valid and can be added to a subnet.
-    ///
-    /// @param option option to be validated.
-    virtual void validateOption(const OptionPtr& option) const = 0;
-
     /// @brief subnet-id
     ///
     /// Subnet-id is a unique value that can be used to find or identify
@@ -489,19 +425,8 @@ protected:
 
 private:
 
-    /// A collection of option spaces grouping option descriptors.
-    typedef OptionSpaceContainer<OptionContainer,
-        OptionDescriptor, std::string> OptionSpaceCollection;
-
-    /// A collection of vendor space option descriptors.
-    typedef OptionSpaceContainer<OptionContainer,
-        OptionDescriptor, uint32_t> VendorOptionSpaceCollection;
-
-    /// Regular options are kept here
-    OptionSpaceCollection option_spaces_;
-
-    /// Vendor options are kept here
-    VendorOptionSpaceCollection vendor_option_spaces_;
+    /// @brief Pointer to the option data configuration for this subnet.
+    CfgOptionPtr cfg_option_;
 };
 
 /// @brief A generic pointer to either Subnet4 or Subnet6 object
@@ -544,13 +469,6 @@ public:
 
 protected:
 
-    /// @brief Check if option is valid and can be added to a subnet.
-    ///
-    /// @param option option to be validated.
-    ///
-    /// @throw isc::BadValue if provided option is invalid.
-    virtual void validateOption(const OptionPtr& option) const;
-
     /// @brief Returns default address for pool selection
     /// @return ANY IPv4 address
     virtual isc::asiolink::IOAddress default_pool() const {
@@ -623,13 +541,6 @@ public:
 
 protected:
 
-    /// @brief Check if option is valid and can be added to a subnet.
-    ///
-    /// @param option option to be validated.
-    ///
-    /// @throw isc::BadValue if provided option is invalid.
-    virtual void validateOption(const OptionPtr& option) const;
-
     /// @brief Returns default address for pool selection
     /// @return ANY IPv6 address
     virtual isc::asiolink::IOAddress default_pool() const {

+ 0 - 10
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc

@@ -269,16 +269,6 @@ TEST_F(DhcpParserTest, interfaceListParserTest) {
     EXPECT_TRUE(test_config.socketOpen("eth1", AF_INET));
 }
 
-// Checks whether option space can be detected as vendor-id
-TEST_F(DhcpParserTest, vendorOptionSpace) {
-    EXPECT_EQ(0, SubnetConfigParser::optionSpaceToVendorId(""));
-    EXPECT_EQ(0, SubnetConfigParser::optionSpaceToVendorId("dhcp4"));
-    EXPECT_EQ(0, SubnetConfigParser::optionSpaceToVendorId("vendor-"));
-    EXPECT_EQ(1, SubnetConfigParser::optionSpaceToVendorId("vendor-1"));
-    EXPECT_EQ(4491, SubnetConfigParser::optionSpaceToVendorId("vendor-4491"));
-    EXPECT_EQ(12345678, SubnetConfigParser::optionSpaceToVendorId("vendor-12345678"));
-}
-
 /// @brief Test Implementation of abstract OptionDataParser class. Allows
 /// testing basic option parsing.
 class UtestOptionDataParser : public OptionDataParser {

+ 20 - 81
src/lib/dhcpsrv/tests/subnet_unittest.cc

@@ -245,17 +245,12 @@ TEST(Subnet4Test, addInvalidOption) {
 
     // Some dummy option code.
     uint16_t code = 100;
-    // Create option with invalid universe (V6 instead of V4).
-    // Attempt to add this option should result in exception.
-    OptionPtr option1(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
-    EXPECT_THROW(subnet->addOption(option1, false, "dhcp4"),
-                 isc::BadValue);
 
     // Create NULL pointer option. Attempt to add NULL option
     // should result in exception.
     OptionPtr option2;
     ASSERT_FALSE(option2);
-    EXPECT_THROW(subnet->addOption(option2, false, "dhcp4"),
+    EXPECT_THROW(subnet->getCfgOption()->add(option2, false, "dhcp4"),
                  isc::BadValue);
 }
 
@@ -646,18 +641,18 @@ TEST(Subnet6Test, addOptions) {
     // Differentiate options by their codes (100-109)
     for (uint16_t code = 100; code < 110; ++code) {
         OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
-        ASSERT_NO_THROW(subnet->addOption(option, false, "dhcp6"));
+        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
     }
 
     // Add 7 options to another option space. The option codes partially overlap
     // with option codes that we have added to dhcp6 option space.
     for (uint16_t code = 105; code < 112; ++code) {
         OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
-        ASSERT_NO_THROW(subnet->addOption(option, false, "isc"));
+        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "isc"));
     }
 
     // Get options from the Subnet and check if all 10 are there.
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
     ASSERT_TRUE(options);
     ASSERT_EQ(10, options->size());
 
@@ -670,7 +665,7 @@ TEST(Subnet6Test, addOptions) {
         ++expected_code;
     }
 
-    options = subnet->getOptionDescriptors("isc");
+    options = subnet->getCfgOption()->getAll("isc");
     ASSERT_TRUE(options);
     ASSERT_EQ(7, options->size());
 
@@ -684,19 +679,7 @@ TEST(Subnet6Test, addOptions) {
     }
 
     // Try to get options from a non-existing option space.
-    options = subnet->getOptionDescriptors("abcd");
-    ASSERT_TRUE(options);
-    EXPECT_TRUE(options->empty());
-
-    // Delete options from all spaces.
-    subnet->delOptions();
-
-    // Make sure that all options have been removed.
-    options = subnet->getOptionDescriptors("dhcp6");
-    ASSERT_TRUE(options);
-    EXPECT_TRUE(options->empty());
-
-    options = subnet->getOptionDescriptors("isc");
+    options = subnet->getCfgOption()->getAll("abcd");
     ASSERT_TRUE(options);
     EXPECT_TRUE(options->empty());
 }
@@ -710,12 +693,12 @@ TEST(Subnet6Test, addNonUniqueOptions) {
         // In the inner loop we create options with unique codes (100-109).
         for (uint16_t code = 100; code < 110; ++code) {
             OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
-            ASSERT_NO_THROW(subnet->addOption(option, false, "dhcp6"));
+            ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
         }
     }
 
     // Sanity check that all options are there.
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
     ASSERT_EQ(20, options->size());
 
     // Use container index #1 to get the options by their codes.
@@ -744,29 +727,6 @@ TEST(Subnet6Test, addNonUniqueOptions) {
         idx.equal_range(non_existing_code);
     // Empty set is expected.
     EXPECT_EQ(0, distance(range.first, range.second));
-
-    subnet->delOptions();
-
-    options = subnet->getOptionDescriptors("dhcp6");
-    EXPECT_EQ(0, options->size());
-}
-
-TEST(Subnet6Test, addInvalidOption) {
-    // Create as subnet to add options to it.
-    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
-
-    // Some dummy option code.
-    uint16_t code = 100;
-    // Create option with invalid universe (V4 instead of V6).
-    // Attempt to add this option should result in exception.
-    OptionPtr option1(new Option(Option::V4, code, OptionBuffer(10, 0xFF)));
-    EXPECT_THROW(subnet->addOption(option1, false, "dhcp6"), isc::BadValue);
-
-    // Create NULL pointer option. Attempt to add NULL option
-    // should result in exception.
-    OptionPtr option2;
-    ASSERT_FALSE(option2);
-    EXPECT_THROW(subnet->addOption(option2, false, "dhcp6"), isc::BadValue);
 }
 
 TEST(Subnet6Test, addPersistentOption) {
@@ -785,11 +745,11 @@ TEST(Subnet6Test, addPersistentOption) {
         // and options with these codes will be flagged non-persistent.
         // Options with other codes will be flagged persistent.
         bool persistent = (code % 3) ? true : false;
-        ASSERT_NO_THROW(subnet->addOption(option, persistent, "dhcp6"));
+        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, persistent, "dhcp6"));
     }
 
     // Get added options from the subnet.
-    OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
 
     // options->get<2> returns reference to container index #2. This
     // index is used to access options by the 'persistent' flag.
@@ -808,20 +768,15 @@ TEST(Subnet6Test, addPersistentOption) {
         idx.equal_range(false);
     // 7 out of 10 options have been flagged persistent.
     ASSERT_EQ(3, distance(range_non_persistent.first, range_non_persistent.second));
-
-    subnet->delOptions();
-
-    options = subnet->getOptionDescriptors("dhcp6");
-    EXPECT_EQ(0, options->size());
 }
 
-TEST(Subnet6Test, getOptionDescriptor) {
+TEST(Subnet6Test, getOptions) {
     Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 56, 1, 2, 3, 4));
 
     // Add 10 options to a "dhcp6" option space in the subnet.
     for (uint16_t code = 100; code < 110; ++code) {
         OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
-        ASSERT_NO_THROW(subnet->addOption(option, false, "dhcp6"));
+        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
     }
 
     // Check that we can get each added option descriptor using
@@ -829,11 +784,11 @@ TEST(Subnet6Test, getOptionDescriptor) {
     for (uint16_t code = 100; code < 110; ++code) {
         std::ostringstream stream;
         // First, try the invalid option space name.
-        OptionDescriptor desc = subnet->getOptionDescriptor("isc", code);
+        OptionDescriptor desc = subnet->getCfgOption()->get("isc", code);
         // Returned descriptor should contain NULL option ptr.
         EXPECT_FALSE(desc.option);
         // Now, try the valid option space.
-        desc = subnet->getOptionDescriptor("dhcp6", code);
+        desc = subnet->getCfgOption()->get("dhcp6", code);
         // Test that the option code matches the expected code.
         ASSERT_TRUE(desc.option);
         EXPECT_EQ(code, desc.option->getType());
@@ -841,11 +796,7 @@ TEST(Subnet6Test, getOptionDescriptor) {
 }
 
 
-TEST(Subnet6Test, addVendorOptions) {
-
-    uint32_t vendor_id1 = 12345678;
-    uint32_t vendor_id2 = 87654321;
-    uint32_t vendor_id_bogus = 1111111;
+TEST(Subnet6Test, addVendorOption) {
 
     // Create as subnet to add options to it.
     Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
@@ -853,18 +804,18 @@ TEST(Subnet6Test, addVendorOptions) {
     // Differentiate options by their codes (100-109)
     for (uint16_t code = 100; code < 110; ++code) {
         OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
-        ASSERT_NO_THROW(subnet->addVendorOption(option, false, vendor_id1));
+        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "vendor-12345678"));
     }
 
     // Add 7 options to another option space. The option codes partially overlap
     // with option codes that we have added to dhcp6 option space.
     for (uint16_t code = 105; code < 112; ++code) {
         OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
-        ASSERT_NO_THROW(subnet->addVendorOption(option, false, vendor_id2));
+        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "vendor-87654321"));
     }
 
     // Get options from the Subnet and check if all 10 are there.
-    OptionContainerPtr options = subnet->getVendorOptionDescriptors(vendor_id1);
+    OptionContainerPtr options = subnet->getCfgOption()->getAll(12345678);
     ASSERT_TRUE(options);
     ASSERT_EQ(10, options->size());
 
@@ -877,7 +828,7 @@ TEST(Subnet6Test, addVendorOptions) {
         ++expected_code;
     }
 
-    options = subnet->getVendorOptionDescriptors(vendor_id2);
+    options = subnet->getCfgOption()->getAll(87654321);
     ASSERT_TRUE(options);
     ASSERT_EQ(7, options->size());
 
@@ -891,19 +842,7 @@ TEST(Subnet6Test, addVendorOptions) {
     }
 
     // Try to get options from a non-existing option space.
-    options = subnet->getVendorOptionDescriptors(vendor_id_bogus);
-    ASSERT_TRUE(options);
-    EXPECT_TRUE(options->empty());
-
-    // Delete options from all spaces.
-    subnet->delVendorOptions();
-
-    // Make sure that all options have been removed.
-    options = subnet->getVendorOptionDescriptors(vendor_id1);
-    ASSERT_TRUE(options);
-    EXPECT_TRUE(options->empty());
-
-    options = subnet->getVendorOptionDescriptors(vendor_id2);
+    options = subnet->getCfgOption()->getAll(1111111);
     ASSERT_TRUE(options);
     EXPECT_TRUE(options->empty());
 }