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