]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3572] Test that vendor specific options are overriden.
authorMarcin Siodelski <marcin@isc.org>
Mon, 23 May 2016 12:52:14 +0000 (14:52 +0200)
committerMarcin Siodelski <marcin@isc.org>
Mon, 23 May 2016 12:52:14 +0000 (14:52 +0200)
In the new test the vendor specific options are defined on the
host and global levels. Host specific options should override
globally defined options.

src/bin/dhcp4/tests/dhcp4_client.cc
src/bin/dhcp4/tests/dhcp4_client.h
src/bin/dhcp4/tests/host_options_unittest.cc
src/lib/dhcp/std_option_defs.h

index c801b57edf2c06b37ae6228e367ca1d8a2795fb1..82c78e7a60feba740dd3d6bfe40f19a784bcd548 100644 (file)
@@ -8,6 +8,7 @@
 #include <dhcp/dhcp4.h>
 #include <dhcp/option.h>
 #include <dhcp/option_int_array.h>
+#include <dhcp/option_vendor.h>
 #include <dhcpsrv/lease.h>
 #include <dhcp4/tests/dhcp4_client.h>
 #include <util/range_utilities.h>
@@ -171,6 +172,12 @@ Dhcp4Client::applyConfiguration() {
     if (opt_quotes_servers) {
         config_.quotes_servers_ = opt_quotes_servers->getAddresses();
     }
+    // Vendor Specific options
+    OptionVendorPtr opt_vendor = boost::dynamic_pointer_cast<
+        OptionVendor>(resp->getOption(DHO_VIVSO_SUBOPTIONS));
+    if (opt_vendor) {
+        config_.vendor_suboptions_ = opt_vendor->getOptions();
+    }
     // Server Identifier
     OptionCustomPtr opt_serverid = boost::dynamic_pointer_cast<
         OptionCustom>(resp->getOption(DHO_DHCP_SERVER_IDENTIFIER));
@@ -254,6 +261,8 @@ Dhcp4Client::doInform(const bool set_ciaddr) {
     context_.query_ = createMsg(DHCPINFORM);
     // Request options if any.
     appendPRL();
+    // Any other options to be sent by a client.
+    appendExtraOptions();
     // The client sending a DHCPINFORM message has an IP address obtained
     // by some other means, e.g. static configuration. The lease which we
     // are using here is most likely set by the createLease method.
@@ -368,6 +377,8 @@ Dhcp4Client::doRequest() {
     appendName();
     // Include Client Identifier
     appendClientId();
+    // Any other options to be sent by a client.
+    appendExtraOptions();
     // Send the message to the server.
     sendMsg(context_.query_);
     // Expect response.
index 71dc9544eecd8f85aae455ea4ee3163d94719851..480a8a426d7b2b8098f456adb1d3a7d1c2ca6455 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <asiolink/io_address.h>
 #include <dhcp/hwaddr.h>
+#include <dhcp/option.h>
 #include <dhcp/pkt4.h>
 #include <dhcp4/tests/dhcp4_test_utils.h>
 #include <util/optional_value.h>
@@ -73,6 +74,8 @@ public:
         Option4AddrLst::AddressContainer log_servers_;
         /// @brief Holds IP addresses received in the Quotes Servers option.
         Option4AddrLst::AddressContainer quotes_servers_;
+        /// @brief Vendor Specific options
+        OptionCollection vendor_suboptions_;
         /// @brief Holds a lease obtained by the client.
         Lease4 lease_;
         /// @brief Holds server id of the server which responded to the client's
index 090219db9595956b3adc92121e763537fb010c7e..901ec6dcc4bfb85538216f543f396f5c9d0cc5f8 100644 (file)
@@ -6,6 +6,9 @@
 
 #include <config.h>
 #include <dhcp/dhcp4.h>
+#include <dhcp/docsis3_option_defs.h>
+#include <dhcp/option_int.h>
+#include <dhcp/option_vendor.h>
 #include <dhcp/tests/iface_mgr_test_config.h>
 #include <dhcp4/tests/dhcp4_test_utils.h>
 #include <dhcp4/tests/dhcp4_client.h>
@@ -21,13 +24,50 @@ namespace {
 /// @brief Set of JSON configurations used throughout the tests.
 ///
 /// - Configuration 0:
-///   - Used for testing direct traffic
-///   - 1 subnet: 10.0.0.0/24
-///   - 1 pool: 10.0.0.10-10.0.0.100
-///   - Router option present: 10.0.0.200 and 10.0.0.201
-///   - Domain Name Server option present: 10.0.0.202, 10.0.0.203.
-///   - Log Servers option present: 192.0.2.200 and 192.0.2.201
-///   - Quotes Servers option present: 192.0.2.202, 192.0.2.203.
+///   - Used to test that host specific options override subnet specific
+///     options when these options are requested with PRL option.
+///   - Single subnet 10.0.0.0/24 with a pool of 10.0.0.10-10.0.0.100
+///   - 4 options configured within subnet scope
+///     - routers: 10.0.0.200,10.0.0.201,
+///     - domain-name-servers: 10.0.0.202,10.0.0.203,
+///     - log-servers: 10.0.0.200,10.0.0.201,
+///     - cookie-servers: 10.0.0.202,10.0.0.203
+///   - Single reservation within the subnet:
+///     - HW address: aa:bb:cc:dd:ee:ff
+///     - ip-address: 10.0.0.7
+///     - Two options overriding subnet specific options:
+///       - cookie-servers: 10.1.1.202, 10.1.1.203
+///       - log-servers: 10.1.1.200, 10.1.1.201
+///
+/// - Configuration 1:
+///   - Used to test that host specific options override subnet specific
+///     default options. Default options are those that are sent even when
+///     not requested by a client.
+///   - Single subnet 10.0.0.0/24 with a pool of 10.0.0.10-10.0.0.100
+///   - 4 options configured within subnet scope
+///     - routers: 10.0.0.200,10.0.0.201,
+///     - domain-name-servers: 10.0.0.202,10.0.0.203,
+///     - log-servers: 10.0.0.200,10.0.0.201,
+///     - cookie-servers: 10.0.0.202,10.0.0.203
+///   - Single reservation within the subnet:
+///     - HW address: aa:bb:cc:dd:ee:ff
+///     - ip-address: 10.0.0.7
+///     - Two options overriding subnet specific default options:
+///       - routers: 10.1.1.200, 10.1.1.201
+///       - domain-name-servers: 10.1.1.202, 10.1.1.203
+///
+/// - Configuration 2:
+///   - Used to test that host specific vendor options override globally
+///     specified vendor options.
+///   - Globally specified option 125 with Cable Labs vendor id.
+///     - TFTP servers sub option: 10.0.0.202,10.0.0.203
+///   - Single subnet 10.0.0.0/24 with a pool of 10.0.0.10-10.0.0.100
+///   - Single reservation within the subnet:
+///     - HW address: aa:bb:cc:dd:ee:ff
+///     - ip-adress 10.0.0.7
+///     - Vendor option for Cable Labs vendor id specified for the reservation:
+///       - TFTP servers suboption overriding globally spececified suboption:
+///         10.1.1.202,10.1.1.203
 ///
 const char* HOST_CONFIGS[] = {
 // Configuration 0
@@ -110,6 +150,41 @@ const char* HOST_CONFIGS[] = {
         "        } ]"
         "    } ]"
         " } ]"
+    "}",
+
+// Configuration 2
+    "{ \"interfaces-config\": {"
+        "      \"interfaces\": [ \"*\" ]"
+        "},"
+        "\"valid-lifetime\": 600,"
+        "\"option-data\": [ {"
+        "    \"name\": \"vivso-suboptions\","
+        "    \"data\": 4491"
+        "},"
+        "{"
+        "    \"name\": \"tftp-servers\","
+        "    \"space\": \"vendor-4491\","
+        "    \"data\": \"10.0.0.202,10.0.0.203\""
+        "} ],"
+        "\"subnet4\": [ { "
+        "    \"subnet\": \"10.0.0.0/24\", "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"
+        "    \"reservations\": [ "
+        "    {"
+        "        \"hw-address\": \"aa:bb:cc:dd:ee:ff\","
+        "        \"ip-address\": \"10.0.0.7\","
+        "        \"option-data\": [ {"
+        "            \"name\": \"vivso-suboptions\","
+        "            \"data\": 4491"
+        "        },"
+        "        {"
+        "            \"name\": \"tftp-servers\","
+        "            \"space\": \"vendor-4491\","
+        "            \"data\": \"10.1.1.202,10.1.1.203\""
+        "        } ]"
+        "    } ]"
+        " } ]"
     "}"
 };
 
@@ -142,6 +217,9 @@ public:
 
 };
 
+// This test checks that host specific options override subnet specific
+// options. Overridden options are requested with Parameter Request List
+// option.
 TEST_F(HostOptionsTest, overrideRequestedOptions) {
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.setHWAddress("aa:bb:cc:dd:ee:ff");
@@ -160,10 +238,7 @@ TEST_F(HostOptionsTest, overrideRequestedOptions) {
     Pkt4Ptr resp = client.getContext().response_;
     // Make sure that the server has responded with DHCPACK.
     ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
-    // Response must not be relayed.
-    EXPECT_FALSE(resp->isRelayed());
-    // Make sure that the server id is present.
-    EXPECT_EQ("10.0.0.1", client.config_.serverid_.toText());
+
     // Make sure that the client has got the lease for the reserved
     // address.
     ASSERT_EQ("10.0.0.7", client.config_.lease_.addr_.toText());
@@ -185,6 +260,10 @@ TEST_F(HostOptionsTest, overrideRequestedOptions) {
     EXPECT_EQ("10.1.1.201", client.config_.log_servers_[1].toText());
 }
 
+// This test checks that host specific options override subnet specific
+// options. Overridden options are the options which server sends
+// regardless if they are requested with Parameter Request List option
+// or not.
 TEST_F(HostOptionsTest, overrideDefaultOptions) {
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.setHWAddress("aa:bb:cc:dd:ee:ff");
@@ -203,10 +282,7 @@ TEST_F(HostOptionsTest, overrideDefaultOptions) {
     Pkt4Ptr resp = client.getContext().response_;
     // Make sure that the server has responded with DHCPACK.
     ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
-    // Response must not be relayed.
-    EXPECT_FALSE(resp->isRelayed());
-    // Make sure that the server id is present.
-    EXPECT_EQ("10.0.0.1", client.config_.serverid_.toText());
+
     // Make sure that the client has got the lease for the reserved
     // address.
     ASSERT_EQ("10.0.0.7", client.config_.lease_.addr_.toText());
@@ -228,5 +304,53 @@ TEST_F(HostOptionsTest, overrideDefaultOptions) {
     EXPECT_EQ("10.0.0.201", client.config_.log_servers_[1].toText());
 }
 
+// This test checks that host specific vendor options override vendor
+// options defined in the global scope.
+TEST_F(HostOptionsTest, overrideVendorOptions) {
+    Dhcp4Client client(Dhcp4Client::SELECTING);
+    client.setHWAddress("aa:bb:cc:dd:ee:ff");
+
+    // Client needs to include V-I Vendor Specific Information option
+    // to include ORO suboption, which the server will use to determine
+    // which suboptions should be returned to the client.
+    OptionVendorPtr opt_vendor(new OptionVendor(Option::V4,
+                                                VENDOR_ID_CABLE_LABS));
+    // Include ORO with TFTP servers suboption code being requested.
+    opt_vendor->addOption(OptionPtr(new OptionUint8(Option::V4, DOCSIS3_V4_ORO,
+                                                    DOCSIS3_V4_TFTP_SERVERS)));
+    client.addExtraOption(opt_vendor);
+
+    // Configure DHCP server.
+    configure(HOST_CONFIGS[2], *client.getServer());
+
+    // Perform 4-way exchange with the server.
+    ASSERT_NO_THROW(client.doDORA());
+
+    // Make sure that the server responded.
+    ASSERT_TRUE(client.getContext().response_);
+    Pkt4Ptr resp = client.getContext().response_;
+    // Make sure that the server has responded with DHCPACK.
+    ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
+
+    // Make sure that the client has got the lease for the reserved
+    // address.
+    ASSERT_EQ("10.0.0.7", client.config_.lease_.addr_.toText());
+
+    // Make sure the server has responded with a V-I Vendor Specific
+    // Information option with exactly one suboption.
+    ASSERT_EQ(1, client.config_.vendor_suboptions_.size());
+    // Assume this suboption is a TFTP servers suboption.
+    std::multimap<unsigned int, OptionPtr>::const_iterator opt =
+        client.config_.vendor_suboptions_.find(DOCSIS3_V4_TFTP_SERVERS);
+    Option4AddrLstPtr opt_tftp = boost::dynamic_pointer_cast<
+        Option4AddrLst>(opt->second);
+    ASSERT_TRUE(opt_tftp);
+    // TFTP servers suboption should contain addresses specified on host level.
+    const Option4AddrLst::AddressContainer& tftps = opt_tftp->getAddresses();
+    ASSERT_EQ(2, tftps.size());
+    EXPECT_EQ("10.1.1.202", tftps[0].toText());
+    EXPECT_EQ("10.1.1.203", tftps[1].toText());
+}
+
 
 } // end of anonymous namespace
index 9bbc29f88c619df8ef126d72104d9f7dcc64f385..1a62fd8fa706a740bccfe2de0e48fb0974f20cc0 100644 (file)
@@ -211,7 +211,7 @@ const OptionDefParams OPTION_DEF_PARAMS4[] = {
     { "domain-search", DHO_DOMAIN_SEARCH, OPT_BINARY_TYPE, false, NO_RECORD_DEF, "" },
     { "vivco-suboptions", DHO_VIVCO_SUBOPTIONS, OPT_RECORD_TYPE,
       false, RECORD_DEF(VIVCO_RECORDS), "" },
-    { "vivso-suboptions", DHO_VIVSO_SUBOPTIONS, OPT_BINARY_TYPE,
+    { "vivso-suboptions", DHO_VIVSO_SUBOPTIONS, OPT_UINT32_TYPE,
       false, NO_RECORD_DEF, "" }
 
         // @todo add definitions for all remaning options.