BIND 10 dhcp-vendoropts, updated. 12035904417740858ad86de2cbaae044e02c590e [dhcp-vendoropts] Support for vendor options added in DHCPv6 server
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat Oct 12 16:32:13 UTC 2013
The branch, dhcp-vendoropts has been updated
via 12035904417740858ad86de2cbaae044e02c590e (commit)
from 7731dd88bdb90869fe1c463a9bdbfa682317a6b7 (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 12035904417740858ad86de2cbaae044e02c590e
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Sat Oct 12 18:31:57 2013 +0200
[dhcp-vendoropts] Support for vendor options added in DHCPv6 server
-----------------------------------------------------------------------
Summary of changes:
src/bin/dhcp6/dhcp6_srv.cc | 55 ++++++++++++++++++++
src/bin/dhcp6/dhcp6_srv.h | 9 ++++
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 80 +++++++++++++++++++++++++++++
src/lib/dhcp/std_option_defs.h | 2 +
4 files changed, 146 insertions(+)
-----------------------------------------------------------------------
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index 5cf45b5..a43c821 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -17,6 +17,7 @@
#include <asiolink/io_address.h>
#include <dhcp_ddns/ncr_msg.h>
#include <dhcp/dhcp6.h>
+#include <dhcp/docsis3_option_defs.h>
#include <dhcp/duid.h>
#include <dhcp/iface_mgr.h>
#include <dhcp/libdhcp++.h>
@@ -684,6 +685,58 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
}
}
+void
+Dhcpv6Srv::appendRequestedVendorOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
+ // Get the configured subnet suitable for the incoming packet.
+ Subnet6Ptr subnet = selectSubnet(question);
+ // Leave if there is no subnet matching the incoming packet.
+ // There is no need to log the error message here because
+ // it will be logged in the assignLease() when it fails to
+ // pick the suitable subnet. We don't want to duplicate
+ // error messages in such case.
+ if (!subnet) {
+ return;
+ }
+
+ // Try to get the vendor option
+ boost::shared_ptr<OptionVendor> vendor_req =
+ boost::dynamic_pointer_cast<OptionVendor>(question->getOption(D6O_VENDOR_OPTS));
+ if (!vendor_req) {
+ return;
+ }
+
+ uint32_t vendor_id = vendor_req->getVendorId();
+
+ // Let's try to get ORO within that vendor-option
+ /// @todo This is very specific to vendor-id=4491 (Cable Labs). Other vendors
+ /// may have different policies.
+ boost::shared_ptr<OptionUint16Array> oro =
+ boost::dynamic_pointer_cast<OptionUint16Array>(vendor_req->getOption(DOCSIS3_V6_ORO));
+
+ // Option ORO not found. Don't do anything then.
+ if (!oro) {
+ return;
+ }
+
+ boost::shared_ptr<OptionVendor> vendor_rsp(new OptionVendor(Option::V6, vendor_id));
+
+ // Get the list of options that client requested.
+ bool added = false;
+ const std::vector<uint16_t>& requested_opts = oro->getValues();
+ BOOST_FOREACH(uint16_t opt, requested_opts) {
+ Subnet::OptionDescriptor desc = subnet->getVendorOptionDescriptor(vendor_id, opt);
+ if (desc.option) {
+ vendor_rsp->addOption(desc.option);
+ added = true;
+ }
+ }
+
+ if (added) {
+ answer->addOption(vendor_rsp);
+ }
+}
+
+
OptionPtr
Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
// @todo This function uses OptionCustom class to manage contents
@@ -2115,6 +2168,7 @@ Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
copyDefaultOptions(solicit, advertise);
appendDefaultOptions(solicit, advertise);
appendRequestedOptions(solicit, advertise);
+ appendRequestedVendorOptions(solicit, advertise);
Option6ClientFqdnPtr fqdn = processClientFqdn(solicit);
assignLeases(solicit, advertise, fqdn);
@@ -2136,6 +2190,7 @@ Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
copyDefaultOptions(request, reply);
appendDefaultOptions(request, reply);
appendRequestedOptions(request, reply);
+ appendRequestedVendorOptions(request, reply);
Option6ClientFqdnPtr fqdn = processClientFqdn(request);
assignLeases(request, reply, fqdn);
diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h
index 65edd77..577c075 100644
--- a/src/bin/dhcp6/dhcp6_srv.h
+++ b/src/bin/dhcp6/dhcp6_srv.h
@@ -336,6 +336,15 @@ protected:
/// @param answer server's message (options will be added here)
void appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
+ /// @brief Appends requested vendor options to server's answer.
+ ///
+ /// This is mostly useful for Cable Labs options for now, but the method
+ /// is easily extensible to other vendors.
+ ///
+ /// @param question client's message
+ /// @param answer server's message (vendor options will be added here)
+ void appendRequestedVendorOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
+
/// @brief Assigns leases.
///
/// It supports addresses (IA_NA) only. It does NOT support temporary
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 9b04621..61e7212 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -2076,6 +2076,86 @@ TEST_F(Dhcpv6SrvTest, docsisVendorORO) {
EXPECT_TRUE(oro);
}
+// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491)
+// vendor options is parsed correctly and the requested options are actually assigned.
+TEST_F(Dhcpv6SrvTest, vendorOptionsORO) {
+ ConstElementPtr x;
+ string config = "{ \"interfaces\": [ \"all\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1::/64\" ],"
+ " \"subnet\": \"2001:db8:1::/48\", "
+ " \"option-data\": [ {"
+ " \"name\": \"dns-servers\","
+ " \"space\": \"vendor-4491\","
+ " \"code\": 5,"
+ " \"data\": \"1234567890\","
+ " \"csv-format\": False"
+ " },"
+ " {"
+ " \"name\": \"subscriber-id\","
+ " \"space\": \"vendor-4491\","
+ " \"code\": 6,"
+ " \"data\": \"abcdef\","
+ " \"csv-format\": False"
+ " } ]"
+ " } ],"
+ "\"valid-lifetime\": 4000 }";
+
+ ElementPtr json = Element::fromJSON(config);
+
+ NakedDhcpv6Srv srv(0);
+
+ EXPECT_NO_THROW(x = configureDhcp6Server(srv, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+
+ ASSERT_EQ(0, rcode_);
+
+ Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
+ sol->setRemoteAddr(IOAddress("fe80::abcd"));
+ sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
+ OptionPtr clientid = generateClientId();
+ sol->addOption(clientid);
+
+ // Pass it to the server and get an advertise
+ Pkt6Ptr adv = srv.processSolicit(sol);
+
+ // check if we get response at all
+ ASSERT_TRUE(adv);
+
+ // We did not include any vendor opts in SOLCIT, so there should be none
+ // in ADVERTISE.
+ ASSERT_FALSE(adv->getOption(D6O_VENDOR_OPTS));
+
+ // Let's add a vendor-option (vendor-id=4491) with a single sub-option.
+ // That suboption has code 1 and is a docsis ORO option.
+ boost::shared_ptr<OptionUint16Array> vendor_oro(new OptionUint16Array(Option::V6,
+ DOCSIS3_V6_ORO));
+ vendor_oro->addValue(5); // Request option 5
+ OptionPtr vendor(new OptionVendor(Option::V6, 4491));
+ vendor->addOption(vendor_oro);
+ sol->addOption(vendor);
+
+ // Need to process SOLICIT again after requesting new option.
+ adv = srv.processSolicit(sol);
+ ASSERT_TRUE(adv);
+
+ // Check if thre is vendor option response
+ OptionPtr tmp = adv->getOption(D6O_VENDOR_OPTS);
+ ASSERT_TRUE(tmp);
+
+ // The response should be OptionVendor object
+ boost::shared_ptr<OptionVendor> vendor_resp =
+ boost::dynamic_pointer_cast<OptionVendor>(tmp);
+ ASSERT_TRUE(vendor_resp);
+
+ ASSERT_TRUE(vendor_resp->getOption(5)); // We requested it
+ ASSERT_FALSE(vendor_resp->getOption(6)); // We did not request it
+}
+
// This test verifies that the following option structure can be parsed:
// - option (option space 'foobar')
// - sub option (option space 'foo')
diff --git a/src/lib/dhcp/std_option_defs.h b/src/lib/dhcp/std_option_defs.h
index 8ef33d0..df78ca4 100644
--- a/src/lib/dhcp/std_option_defs.h
+++ b/src/lib/dhcp/std_option_defs.h
@@ -16,6 +16,8 @@
#define STD_OPTION_DEFS_H
#include <dhcp/option_data_types.h>
+#include <dhcp/dhcp4.h>
+#include <dhcp/dhcp6.h>
namespace {
More information about the bind10-changes
mailing list