BIND 10 dhcp-vendoropts, updated. 7731dd88bdb90869fe1c463a9bdbfa682317a6b7 [dhcp-vendoropts] vendor-options can now be parsed.
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat Oct 12 15:50:47 UTC 2013
The branch, dhcp-vendoropts has been updated
via 7731dd88bdb90869fe1c463a9bdbfa682317a6b7 (commit)
from fcdbac57aa38264b8fe767178703fbd66df646e9 (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 7731dd88bdb90869fe1c463a9bdbfa682317a6b7
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Sat Oct 12 17:50:28 2013 +0200
[dhcp-vendoropts] vendor-options can now be parsed.
-----------------------------------------------------------------------
Summary of changes:
src/bin/dhcp6/tests/config_parser_unittest.cc | 114 +++++++++++++++++++++++++
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 1 +
src/lib/dhcpsrv/dhcp_parsers.cc | 69 +++++++++++++--
src/lib/dhcpsrv/dhcp_parsers.h | 8 ++
4 files changed, 187 insertions(+), 5 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc
index acfc270..9e0401e 100644
--- a/src/bin/dhcp6/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp6/tests/config_parser_unittest.cc
@@ -2049,6 +2049,120 @@ TEST_F(Dhcp6ParserTest, stdOptionData) {
EXPECT_EQ(1516, optionIA->getT2());
}
+// This test checks if vendor options can be specified in the config file
+// (in hex format), and later retrieved from configured subnet
+TEST_F(Dhcp6ParserTest, vendorOptionsHex) {
+
+ // This configuration string is to configure two options
+ // sharing the code 1 and belonging to the different vendor spaces.
+ // (different vendor-id values).
+ string config = "{ \"interfaces\": [ \"*\" ],"
+ "\"rebind-timer\": 2000,"
+ "\"renew-timer\": 1000,"
+ "\"option-data\": [ {"
+ " \"name\": \"option-one\","
+ " \"space\": \"vendor-4491\","
+ " \"code\": 1,"
+ " \"data\": \"AB CDEF0105\","
+ " \"csv-format\": False"
+ " },"
+ " {"
+ " \"name\": \"option-two\","
+ " \"space\": \"vendor-1234\","
+ " \"code\": 1,"
+ " \"data\": \"1234\","
+ " \"csv-format\": False"
+ " } ],"
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1::/80\" ],"
+ " \"subnet\": \"2001:db8:1::/64\""
+ " } ]"
+ "}";
+
+ ConstElementPtr status;
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
+ ASSERT_TRUE(status);
+ checkResult(status, 0);
+
+ // Options should be now available for the subnet.
+ Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
+ ASSERT_TRUE(subnet);
+
+ // Try to get the option from the vendor space 4491
+ Subnet::OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(4491, 1);
+ ASSERT_TRUE(desc1.option);
+ EXPECT_EQ(1, desc1.option->getType());
+ // Try to get the option from the vendor space 1234
+ Subnet::OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(1234, 1);
+ ASSERT_TRUE(desc2.option);
+ EXPECT_EQ(1, desc1.option->getType());
+
+ // Try to get the non-existing option from the non-existing
+ // option space and expect that option is not returned.
+ Subnet::OptionDescriptor desc3 = subnet->getVendorOptionDescriptor(5678, 38);
+ ASSERT_FALSE(desc3.option);
+}
+
+// This test checks if vendor options can be specified in the config file,
+// (in csv format), and later retrieved from configured subnet
+TEST_F(Dhcp6ParserTest, DISABLED_vendorOptionsCsv) {
+
+ // This configuration string is to configure two options
+ // sharing the code 1 and belonging to the different vendor spaces.
+ // (different vendor-id values).
+ string config = "{ \"interfaces\": [ \"*\" ],"
+ "\"rebind-timer\": 2000,"
+ "\"renew-timer\": 1000,"
+ "\"option-data\": [ {"
+ " \"name\": \"option-one\","
+ " \"space\": \"vendor-4491\","
+ " \"code\": 1,"
+ " \"data\": \"AB CDEF0105\","
+ " \"csv-format\": True"
+ " },"
+ " {"
+ " \"name\": \"option-two\","
+ " \"space\": \"vendor-1234\","
+ " \"code\": 1,"
+ " \"data\": \"1234\","
+ " \"csv-format\": True"
+ " } ],"
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1::/80\" ],"
+ " \"subnet\": \"2001:db8:1::/64\""
+ " } ]"
+ "}";
+
+ ConstElementPtr status;
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
+ ASSERT_TRUE(status);
+ checkResult(status, 0);
+
+ // Options should be now available for the subnet.
+ Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
+ ASSERT_TRUE(subnet);
+
+ // Try to get the option from the vendor space 4491
+ Subnet::OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(4491, 1);
+ ASSERT_TRUE(desc1.option);
+ EXPECT_EQ(1, desc1.option->getType());
+ // Try to get the option from the vendor space 1234
+ Subnet::OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(1234, 1);
+ ASSERT_TRUE(desc2.option);
+ EXPECT_EQ(1, desc1.option->getType());
+
+ // Try to get the non-existing option from the non-existing
+ // option space and expect that option is not returned.
+ Subnet::OptionDescriptor desc3 = subnet->getVendorOptionDescriptor(5678, 38);
+ ASSERT_FALSE(desc3.option);
+}
+
// The goal of this test is to verify that the standard option can
// be configured to encapsulate multiple other options.
TEST_F(Dhcp6ParserTest, stdOptionDataEncapsulate) {
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 908ef12..9b04621 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -30,6 +30,7 @@
#include <dhcp/iface_mgr.h>
#include <dhcp6/config_parser.h>
#include <dhcp/dhcp6.h>
+#include <dhcp/docsis3_option_defs.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
diff --git a/src/lib/dhcpsrv/dhcp_parsers.cc b/src/lib/dhcpsrv/dhcp_parsers.cc
index e03d13f..7ace4e4 100644
--- a/src/lib/dhcpsrv/dhcp_parsers.cc
+++ b/src/lib/dhcpsrv/dhcp_parsers.cc
@@ -429,6 +429,8 @@ OptionDataParser::createOption() {
<< "')");
}
+ const bool csv_format = boolean_values_->getParam("csv-format");
+
// Find the Option Definition for the option by its option code.
// findOptionDefinition will throw if not found, no need to test.
OptionDefinitionPtr def;
@@ -449,7 +451,10 @@ OptionDataParser::createOption() {
if (std::distance(range.first, range.second) > 0) {
def = *range.first;
}
- if (!def) {
+
+ // It's ok if we don't have option format if the option is
+ // specified as hex
+ if (!def && csv_format) {
isc_throw(DhcpConfigError, "definition for the option '"
<< option_space << "." << option_name
<< "' having code '" << option_code
@@ -459,7 +464,6 @@ OptionDataParser::createOption() {
// Get option data from the configuration database ('data' field).
const std::string option_data = string_values_->getParam("data");
- const bool csv_format = boolean_values_->getParam("csv-format");
// Transform string of hexadecimal digits into binary format.
std::vector<uint8_t> binary;
@@ -1047,8 +1051,16 @@ SubnetConfigParser::createSubnet() {
}
// Add sub-options (if any).
appendSubOptions(option_space, desc.option);
- // In any case, we add the option to the subnet.
- subnet_->addOption(desc.option, false, option_space);
+
+ // thomson
+ 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);
+ }
}
}
@@ -1077,12 +1089,59 @@ SubnetConfigParser::createSubnet() {
if (!existing_desc.option) {
// Add sub-options (if any).
appendSubOptions(option_space, desc.option);
- subnet_->addOption(desc.option, false, option_space);
+
+ 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);
+ }
}
}
}
}
+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;
diff --git a/src/lib/dhcpsrv/dhcp_parsers.h b/src/lib/dhcpsrv/dhcp_parsers.h
index 89e4fff..ff1fe3d 100644
--- a/src/lib/dhcpsrv/dhcp_parsers.h
+++ b/src/lib/dhcpsrv/dhcp_parsers.h
@@ -828,6 +828,14 @@ protected:
/// @throw DhcpConfigError when requested parameter is not present
isc::dhcp::Triplet<uint32_t> getParam(const std::string& name);
+ /// @brief tries to convert option_space string to numeric vendor_id
+ ///
+ /// This will work if the option_space has format "vendor-1234".
+ /// This is used to detect whether a given option-space is a vendor
+ /// space or not. Returns 0 if the format is different.
+ /// @return numeric vendor-id (or 0 if the format does not match)
+ uint32_t optionSpaceToVendorId(const std::string& option_space);
+
private:
/// @brief Append sub-options to an option.
More information about the bind10-changes
mailing list