BIND 10 dhcp-vendoropts, updated. fcdbac57aa38264b8fe767178703fbd66df646e9 [dhcp-vendoropts] support for vendor options in Subnet added.

BIND 10 source code commits bind10-changes at lists.isc.org
Sat Oct 12 11:30:48 UTC 2013


The branch, dhcp-vendoropts has been updated
       via  fcdbac57aa38264b8fe767178703fbd66df646e9 (commit)
      from  73ab9c6c43eb46eb3c093678e561e47265a84fb2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit fcdbac57aa38264b8fe767178703fbd66df646e9
Author: Tomek Mrugalski <tomasz at isc.org>
Date:   Sat Oct 12 13:30:25 2013 +0200

    [dhcp-vendoropts] support for vendor options in Subnet added.

-----------------------------------------------------------------------

Summary of changes:
 src/lib/dhcpsrv/cfgmgr.h                 |    2 +-
 src/lib/dhcpsrv/dhcp_parsers.h           |    4 +-
 src/lib/dhcpsrv/option_space_container.h |   13 +++---
 src/lib/dhcpsrv/subnet.cc                |   32 ++++++++++++++
 src/lib/dhcpsrv/subnet.h                 |   18 +++++++-
 src/lib/dhcpsrv/tests/subnet_unittest.cc |   70 ++++++++++++++++++++++++++++++
 6 files changed, 129 insertions(+), 10 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dhcpsrv/cfgmgr.h b/src/lib/dhcpsrv/cfgmgr.h
index 0ec51d0..a589284 100644
--- a/src/lib/dhcpsrv/cfgmgr.h
+++ b/src/lib/dhcpsrv/cfgmgr.h
@@ -355,7 +355,7 @@ private:
     /// A collection of option definitions that can be accessed
     /// using option space name they belong to.
     OptionSpaceContainer<OptionDefContainer,
-                         OptionDefinitionPtr> option_def_spaces_;
+        OptionDefinitionPtr, std::string> option_def_spaces_;
 
     /// @brief Container for defined DHCPv6 option spaces.
     OptionSpaceCollection spaces6_;
diff --git a/src/lib/dhcpsrv/dhcp_parsers.h b/src/lib/dhcpsrv/dhcp_parsers.h
index 0829b21..89e4fff 100644
--- a/src/lib/dhcpsrv/dhcp_parsers.h
+++ b/src/lib/dhcpsrv/dhcp_parsers.h
@@ -34,14 +34,14 @@ namespace dhcp {
 
 /// @brief Storage for option definitions.
 typedef OptionSpaceContainer<OptionDefContainer,
-                             OptionDefinitionPtr> OptionDefStorage;
+    OptionDefinitionPtr, std::string> OptionDefStorage;
 /// @brief Shared pointer to option definitions storage.
 typedef boost::shared_ptr<OptionDefStorage> OptionDefStoragePtr;
 
 /// Collection of containers holding option spaces. Each container within
 /// a particular option space holds so-called option descriptors.
 typedef OptionSpaceContainer<Subnet::OptionContainer,
-                             Subnet::OptionDescriptor> OptionStorage;
+    Subnet::OptionDescriptor, std::string> OptionStorage;
 /// @brief Shared pointer to option storage.
 typedef boost::shared_ptr<OptionStorage> OptionStoragePtr;
 
diff --git a/src/lib/dhcpsrv/option_space_container.h b/src/lib/dhcpsrv/option_space_container.h
index ba16fbb..6417207 100644
--- a/src/lib/dhcpsrv/option_space_container.h
+++ b/src/lib/dhcpsrv/option_space_container.h
@@ -31,7 +31,8 @@ namespace dhcp {
 /// @tparam ContainerType of the container holding items within
 /// option space.
 /// @tparam ItemType type of the item being held by the container.
-template<typename ContainerType, typename ItemType>
+/// @tparam Selector a string (for option spaces) or uint32_t (for vendor options)
+template<typename ContainerType, typename ItemType, typename Selector>
 class OptionSpaceContainer {
 public:
 
@@ -42,7 +43,7 @@ public:
     ///
     /// @param item reference to the item being added.
     /// @param option_space name of the option space.
-    void addItem(const ItemType& item, const std::string& option_space) {
+    void addItem(const ItemType& item, const Selector& option_space) {
         ItemsContainerPtr items = getItems(option_space);
         items->push_back(item);
         option_space_map_[option_space] = items;
@@ -57,7 +58,7 @@ public:
     /// @param option_space name of the option space.
     ///
     /// @return pointer to the container holding items.
-    ItemsContainerPtr getItems(const std::string& option_space) const {
+    ItemsContainerPtr getItems(const Selector& option_space) const {
         const typename OptionSpaceMap::const_iterator& items =
             option_space_map_.find(option_space);
         if (items == option_space_map_.end()) {
@@ -73,8 +74,8 @@ public:
     /// @todo This function is likely to be removed once
     /// we create a structore of OptionSpaces defined
     /// through the configuration manager.
-    std::list<std::string> getOptionSpaceNames() {
-        std::list<std::string> names;
+    std::list<Selector> getOptionSpaceNames() {
+        std::list<Selector> names;
         for (typename OptionSpaceMap::const_iterator space =
                  option_space_map_.begin();
              space != option_space_map_.end(); ++space) {
@@ -91,7 +92,7 @@ public:
 private:
 
     /// A map holding container (option space name is the key).
-    typedef std::map<std::string, ItemsContainerPtr> OptionSpaceMap;
+    typedef std::map<Selector, ItemsContainerPtr> OptionSpaceMap;
     OptionSpaceMap option_space_map_;
 };
 
diff --git a/src/lib/dhcpsrv/subnet.cc b/src/lib/dhcpsrv/subnet.cc
index 4320733..d01fb3d 100644
--- a/src/lib/dhcpsrv/subnet.cc
+++ b/src/lib/dhcpsrv/subnet.cc
@@ -88,6 +88,38 @@ Subnet::getOptionDescriptor(const std::string& option_space,
     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);
+}
+
+Subnet::OptionContainerPtr
+Subnet::getVendorOptionDescriptors(uint32_t vendor_id) const {
+    return (vendor_option_spaces_.getItems(vendor_id));
+}
+
+Subnet::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);
diff --git a/src/lib/dhcpsrv/subnet.h b/src/lib/dhcpsrv/subnet.h
index ac6de03..f6714d1 100644
--- a/src/lib/dhcpsrv/subnet.h
+++ b/src/lib/dhcpsrv/subnet.h
@@ -180,9 +180,14 @@ public:
     void addOption(const OptionPtr& option, bool persistent,
                    const std::string& option_space);
 
+    void addVendorOption(const OptionPtr& option, bool persistent,
+                         uint32_t vendor_id);
+
     /// @brief Delete all options configured for the subnet.
     void delOptions();
 
+    void delVendorOptions();
+
     /// @brief checks if the specified address is in pools
     ///
     /// Note the difference between inSubnet() and inPool(). For a given
@@ -221,6 +226,9 @@ public:
     OptionContainerPtr
     getOptionDescriptors(const std::string& option_space) const;
 
+    OptionContainerPtr
+    getVendorOptionDescriptors(uint32_t vendor_id) const;
+
     /// @brief Return single option descriptor.
     ///
     /// @param option_space name of the option space.
@@ -232,6 +240,9 @@ public:
     getOptionDescriptor(const std::string& option_space,
                         const uint16_t option_code);
 
+    OptionDescriptor
+    getVendorOptionDescriptor(uint32_t vendor_id, uint16_t option_code);
+
     /// @brief returns the last address that was tried from this pool
     ///
     /// This method returns the last address that was attempted to be allocated
@@ -440,9 +451,14 @@ private:
 
     /// A collection of option spaces grouping option descriptors.
     typedef OptionSpaceContainer<OptionContainer,
-                                 OptionDescriptor> OptionSpaceCollection;
+        OptionDescriptor, std::string> OptionSpaceCollection;
+
+    typedef OptionSpaceContainer<OptionContainer,
+        OptionDescriptor, uint32_t> VendorOptionSpaceCollection;
+
     OptionSpaceCollection option_spaces_;
 
+    VendorOptionSpaceCollection vendor_option_spaces_;
 };
 
 /// @brief A generic pointer to either Subnet4 or Subnet6 object
diff --git a/src/lib/dhcpsrv/tests/subnet_unittest.cc b/src/lib/dhcpsrv/tests/subnet_unittest.cc
index 0af8191..f872ed9 100644
--- a/src/lib/dhcpsrv/tests/subnet_unittest.cc
+++ b/src/lib/dhcpsrv/tests/subnet_unittest.cc
@@ -597,6 +597,76 @@ TEST(Subnet6Test, getOptionDescriptor) {
     }
 }
 
+
+TEST(Subnet6Test, addVendorOptions) {
+
+    uint32_t vendor_id1 = 12345678;
+    uint32_t vendor_id2 = 87654321;
+    uint32_t vendor_id_bogus = 1111111;
+
+    // Create as subnet to add options to it.
+    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
+
+    // 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));
+    }
+
+    // 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));
+    }
+
+    // Get options from the Subnet and check if all 10 are there.
+    Subnet::OptionContainerPtr options = subnet->getVendorOptionDescriptors(vendor_id1);
+    ASSERT_TRUE(options);
+    ASSERT_EQ(10, options->size());
+
+    // Validate codes of options added to dhcp6 option space.
+    uint16_t expected_code = 100;
+    for (Subnet::OptionContainer::const_iterator option_desc = options->begin();
+         option_desc != options->end(); ++option_desc) {
+        ASSERT_TRUE(option_desc->option);
+        EXPECT_EQ(expected_code, option_desc->option->getType());
+        ++expected_code;
+    }
+
+    options = subnet->getVendorOptionDescriptors(vendor_id2);
+    ASSERT_TRUE(options);
+    ASSERT_EQ(7, options->size());
+
+    // Validate codes of options added to isc option space.
+    expected_code = 105;
+    for (Subnet::OptionContainer::const_iterator option_desc = options->begin();
+         option_desc != options->end(); ++option_desc) {
+        ASSERT_TRUE(option_desc->option);
+        EXPECT_EQ(expected_code, option_desc->option->getType());
+        ++expected_code;
+    }
+
+    // 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);
+    ASSERT_TRUE(options);
+    EXPECT_TRUE(options->empty());
+}
+
+
+
 // This test verifies that inRange() and inPool() methods work properly.
 TEST(Subnet6Test, inRangeinPool) {
     Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));



More information about the bind10-changes mailing list