From: Razvan Becheriu Date: Fri, 13 Jan 2023 14:11:30 +0000 (+0200) Subject: [#1518] extended unittests for v6 X-Git-Tag: Kea-2.3.6~101^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af6ff1578adcf26d8d62a3101c97c4a447d5c2d1;p=thirdparty%2Fkea.git [#1518] extended unittests for v6 --- diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 20189f09cf..b978c979ce 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -1424,15 +1424,13 @@ Dhcpv6Srv::buildCfgOptionList(const Pkt6Ptr& question, co_list.push_back(pool->getCfgOption()); } } - }; - if (ctx.subnet_) { - // Next, subnet configured options. + // Thirdly, subnet configured options. if (!ctx.subnet_->getCfgOption()->empty()) { co_list.push_back(ctx.subnet_->getCfgOption()); } - // Then, shared network specific options. + // Fourthly, shared network specific options. SharedNetwork6Ptr network; ctx.subnet_->getSharedNetwork(network); if (network && !network->getCfgOption()->empty()) { @@ -1475,7 +1473,6 @@ Dhcpv6Srv::buildCfgOptionList(const Pkt6Ptr& question, void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer, const CfgOptionList& co_list) { - // Unlikely short cut if (co_list.empty()) { return; @@ -1485,23 +1482,19 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer, // Client requests some options using ORO option. Try to // get this option from client's message. - boost::shared_ptr > option_oro = - boost::dynamic_pointer_cast > - (question->getOption(D6O_ORO)); + OptionUint16ArrayPtr option_oro = boost::dynamic_pointer_cast< + OptionUint16Array>(question->getOption(D6O_ORO)); // Get the list of options that client requested. if (option_oro) { - set oro_req_opts; for (uint16_t code : option_oro->getValues()) { - static_cast(oro_req_opts.insert(code)); + static_cast(requested_opts.insert(code)); } - requested_opts = oro_req_opts; } // Iterate on the configured option list to add persistent options - for (CfgOptionList::const_iterator copts = co_list.begin(); - copts != co_list.end(); ++copts) { - const OptionContainerPtr& opts = (*copts)->getAll(DHCP6_OPTION_SPACE); + for (auto const& copts : co_list) { + const OptionContainerPtr& opts = copts->getAll(DHCP6_OPTION_SPACE); if (!opts) { continue; } @@ -1512,21 +1505,23 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer, desc != range.second; ++desc) { // Add the persistent option code to requested options if (desc->option_) { - uint16_t code = desc->option_->getType(); - static_cast(requested_opts.insert(code)); + static_cast(requested_opts.insert(desc->option_->getType())); } } } // For each requested option code get the first instance of the option // to be returned to the client. - for (uint16_t opt : requested_opts) { + for (auto const& opt : requested_opts) { // Add nothing when it is already there. + // Skip special cases: D6O_VENDOR_CLASS and D6O_VENDOR_OPTS + if (opt == D6O_VENDOR_CLASS || opt == D6O_VENDOR_OPTS) { + continue; + } if (!answer->getOption(opt)) { // Iterate on the configured option list - for (CfgOptionList::const_iterator copts = co_list.begin(); - copts != co_list.end(); ++copts) { - OptionDescriptor desc = (*copts)->get(DHCP6_OPTION_SPACE, opt); + for (auto const& copts : co_list) { + OptionDescriptor desc = copts->get(DHCP6_OPTION_SPACE, opt); // Got it: add it and jump to the outer loop if (desc.option_) { answer->addOption(desc.option_); @@ -1545,15 +1540,13 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer, OptionVendorClassPtr vendor_class; vendor_class = boost::dynamic_pointer_cast(opt.second); if (vendor_class) { - uint32_t vendor_id = vendor_class->getVendorId(); - static_cast(vendor_ids.insert(vendor_id)); + static_cast(vendor_ids.insert(vendor_class->getVendorId())); } } // Iterate on the configured option list - for (CfgOptionList::const_iterator copts = co_list.begin(); - copts != co_list.end(); ++copts) { - for (OptionDescriptor desc : (*copts)->getList(DHCP6_OPTION_SPACE, - D6O_VENDOR_CLASS)) { + for (auto const& copts : co_list) { + for (OptionDescriptor desc : copts->getList(DHCP6_OPTION_SPACE, + D6O_VENDOR_CLASS)) { if (!desc.option_) { continue; } @@ -1581,15 +1574,13 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer, OptionVendorPtr vendor_opts; vendor_opts = boost::dynamic_pointer_cast(opt.second); if (vendor_opts) { - uint32_t vendor_id = vendor_opts->getVendorId(); - static_cast(vendor_ids.insert(vendor_id)); + static_cast(vendor_ids.insert(vendor_opts->getVendorId())); } } // Iterate on the configured option list - for (CfgOptionList::const_iterator copts = co_list.begin(); - copts != co_list.end(); ++copts) { - for (OptionDescriptor desc : (*copts)->getList(DHCP6_OPTION_SPACE, - D6O_VENDOR_OPTS)) { + for (auto const& copts : co_list) { + for (OptionDescriptor desc : copts->getList(DHCP6_OPTION_SPACE, + D6O_VENDOR_OPTS)) { if (!desc.option_) { continue; } @@ -1662,8 +1653,7 @@ Dhcpv6Srv::appendRequestedVendorOptions(const Pkt6Ptr& question, OptionVendorClassPtr vendor_class; vendor_class = boost::dynamic_pointer_cast(opt.second); if (vendor_class) { - uint32_t vendor_id = vendor_class->getVendorId(); - static_cast(vendor_ids.insert(vendor_id)); + static_cast(vendor_ids.insert(vendor_class->getVendorId())); } } @@ -1700,9 +1690,8 @@ Dhcpv6Srv::appendRequestedVendorOptions(const Pkt6Ptr& question, // Iterate on the configured option list to add persistent options for (uint32_t vendor_id : vendor_ids) { - for (CfgOptionList::const_iterator copts = co_list.begin(); - copts != co_list.end(); ++copts) { - const OptionContainerPtr& opts = (*copts)->getAll(vendor_id); + for (auto const& copts : co_list) { + const OptionContainerPtr& opts = copts->getAll(vendor_id); if (!opts) { continue; } @@ -1715,12 +1704,15 @@ Dhcpv6Srv::appendRequestedVendorOptions(const Pkt6Ptr& question, continue; } // Add the persistent option code to requested options - uint16_t code = desc->option_->getType(); - static_cast(requested_opts[vendor_id].insert(code)); + static_cast(requested_opts[vendor_id].insert(desc->option_->getType())); } } - // If there is nothing to add don't do anything then with this vendor. + // If there is nothing to add don't do anything with this vendor. + // This will explicitly not echo back vendor options from the request + // that either correspond to a vendor not known to Kea even if the + // option encapsulates data or there are no persistent options + // configured for this vendor so Kea does not send any option back. if (requested_opts[vendor_id].empty()) { continue; } @@ -1739,9 +1731,8 @@ Dhcpv6Srv::appendRequestedVendorOptions(const Pkt6Ptr& question, for (uint16_t opt : requested_opts[vendor_id]) { if (!vendor_rsp->getOption(opt)) { - for (CfgOptionList::const_iterator copts = co_list.begin(); - copts != co_list.end(); ++copts) { - OptionDescriptor desc = (*copts)->get(vendor_id, opt); + for (auto const& copts : co_list) { + OptionDescriptor desc = copts->get(vendor_id, opt); if (desc.option_) { vendor_rsp->addOption(desc.option_); added = true; diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index 71b92a5f4e..a48589547d 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -4150,7 +4151,7 @@ TEST_F(Dhcp6ParserTest, vendorOptionsHex) { // Options should be now available // Try to get the option from the vendor space 4491 OptionDescriptor desc1 = - CfgMgr::instance().getStagingCfg()->getCfgOption()->get(4491, 100); + CfgMgr::instance().getStagingCfg()->getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100); ASSERT_TRUE(desc1.option_); EXPECT_EQ(100, desc1.option_->getType()); // Try to get the option from the vendor space 1234 @@ -4209,7 +4210,7 @@ TEST_F(Dhcp6ParserTest, vendorOptionsCsv) { // Options should be now available. // Try to get the option from the vendor space 4491 OptionDescriptor desc1 = - CfgMgr::instance().getStagingCfg()->getCfgOption()->get(4491, 100); + CfgMgr::instance().getStagingCfg()->getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100); ASSERT_TRUE(desc1.option_); EXPECT_EQ(100, desc1.option_->getType()); diff --git a/src/bin/dhcp6/tests/dhcp6_client.cc b/src/bin/dhcp6/tests/dhcp6_client.cc index 487cad8f86..fce882aae0 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.cc +++ b/src/bin/dhcp6/tests/dhcp6_client.cc @@ -407,7 +407,7 @@ Dhcp6Client::createMsg(const uint8_t msg_type) { OptionUint16ArrayPtr vendor_oro(new OptionUint16Array(Option::V6, DOCSIS3_V6_ORO)); vendor_oro->setValues(docsis_oro_); - OptionPtr vendor(new OptionVendor(Option::V6, 4491)); + OptionVendorPtr vendor(new OptionVendor(Option::V6, VENDOR_ID_CABLE_LABS)); vendor->addOption(vendor_oro); msg->addOption(vendor); } diff --git a/src/bin/dhcp6/tests/host_unittest.cc b/src/bin/dhcp6/tests/host_unittest.cc index 4f9415b423..1424826cb3 100644 --- a/src/bin/dhcp6/tests/host_unittest.cc +++ b/src/bin/dhcp6/tests/host_unittest.cc @@ -1380,8 +1380,7 @@ HostTest::testOverrideVendorOptions(const uint16_t msg_type) { // Client needs to include Vendor Specific Information option // with ORO suboption, which the server will use to determine // which suboptions should be returned to the client. - OptionVendorPtr opt_vendor(new OptionVendor(Option::V6, - VENDOR_ID_CABLE_LABS)); + OptionVendorPtr opt_vendor(new OptionVendor(Option::V6, VENDOR_ID_CABLE_LABS)); // Include ORO with TFTP servers suboption code being requested. opt_vendor->addOption(OptionPtr(new OptionUint16(Option::V6, DOCSIS3_V6_ORO, DOCSIS3_V6_TFTP_SERVERS))); diff --git a/src/bin/dhcp6/tests/rebind_unittest.cc b/src/bin/dhcp6/tests/rebind_unittest.cc index 164098ee04..a58b3b9883 100644 --- a/src/bin/dhcp6/tests/rebind_unittest.cc +++ b/src/bin/dhcp6/tests/rebind_unittest.cc @@ -1068,8 +1068,7 @@ TEST_F(RebindTest, docsisORO) { opt = client.config_.findOption(D6O_VENDOR_OPTS); ASSERT_TRUE(opt); // The vendor option must be a OptionVendor object. - boost::shared_ptr vendor = - boost::dynamic_pointer_cast(opt); + OptionVendorPtr vendor = boost::dynamic_pointer_cast(opt); ASSERT_TRUE(vendor); // The vendor-id should be DOCSIS. EXPECT_EQ(VENDOR_ID_CABLE_LABS, vendor->getVendorId()); diff --git a/src/bin/dhcp6/tests/renew_unittest.cc b/src/bin/dhcp6/tests/renew_unittest.cc index 29f9c39e05..ff7a5833bf 100644 --- a/src/bin/dhcp6/tests/renew_unittest.cc +++ b/src/bin/dhcp6/tests/renew_unittest.cc @@ -649,8 +649,7 @@ TEST_F(RenewTest, docsisORO) { ASSERT_TRUE(opt); // The vendor option must be a OptionVendor object. - boost::shared_ptr vendor = - boost::dynamic_pointer_cast(opt); + OptionVendorPtr vendor = boost::dynamic_pointer_cast(opt); ASSERT_TRUE(vendor); // The vendor-id should be DOCSIS. diff --git a/src/bin/dhcp6/tests/vendor_opts_unittest.cc b/src/bin/dhcp6/tests/vendor_opts_unittest.cc index 0e241f887e..e6b7cce283 100644 --- a/src/bin/dhcp6/tests/vendor_opts_unittest.cc +++ b/src/bin/dhcp6/tests/vendor_opts_unittest.cc @@ -7,12 +7,12 @@ // This file is dedicated to testing vendor options in DHCPv6. There // are several related options: // -// client-class (15) - this specifies (as a plain string) what kind of -// device this is -// vendor-class (16) - contains an enterprise-id followed by zero or -// more of vendor-class data. -// vendor-option (17) - contains an enterprise-id followed by zero or -// more vendor suboptions +// client-class (15) - this specifies (as a plain string) what kind of device +// this is. +// vendor-class (16) - contains an enterprise-id followed by zero or more of +// vendor-class data. +// vendor-option (17) - contains an enterprise-id followed by zero or more +// vendor suboptions. #include @@ -57,48 +57,113 @@ public: IfaceMgr::instance().closeSockets(); } - void testVendorOptionsORO(int vendor_id) { - // Create a config with a custom option for Cable Labs. + /// @brief Checks if Option Request Option (ORO) in docsis (vendor-id=4491) + /// vendor options is parsed correctly and the requested options are + /// actually assigned. Also covers negative tests that options are not + /// provided when a different vendor ID is given. + /// + /// @note Kea only knows how to process VENDOR_ID_CABLE_LABS DOCSIS3_V4_ORO + /// (suboption 1). + /// + /// @param configured_vendor_ids The vendor IDs that are configured in the + /// server: 4491 or both 4491 and 3561. + /// @param requested_vendor_ids Then vendor IDs that are present in ORO. + /// @param requested_options The requested options in ORO. + void testVendorOptionsORO(std::vector configured_vendor_ids, + std::vector requested_vendor_ids, + std::vector requested_options) { + std::vector result_vendor_ids; + ASSERT_TRUE(configured_vendor_ids.size()); + ASSERT_EQ(configured_vendor_ids[0], VENDOR_ID_CABLE_LABS); + for (const auto& req : requested_vendor_ids) { + if (req == VENDOR_ID_CABLE_LABS) { + result_vendor_ids.push_back(req); + } + } + // Create a config with custom options. string config = R"( { - "interfaces-config": { - "interfaces": [ "*" ] - }, - "option-data": [ - { - "data": "normal_erouter_v6.cm", - "name": "config-file", - "space": "vendor-4491" - } - ], - "option-def": [ - { - "code": 33, - "name": "config-file", - "space": "vendor-4491", - "type": "string" - } - ], - "preferred-lifetime": 3000, - "rebind-timer": 2000, - "renew-timer": 1000, - "subnet6": [ - { - "interface": "eth0", - "interface-id": "", - "pools": [ - { - "pool": "2001:db8:1::/64" - } - ], - "preferred-lifetime": 3000, - "rebind-timer": 1000, - "renew-timer": 1000, - "subnet": "2001:db8:1::/48", - "valid-lifetime": 4000 - } - ], - "valid-lifetime": 4000 + "interfaces-config": { + "interfaces": [ "*" ] + }, + "option-data": [ + { + "code": 33, + "data": "normal_erouter_v6.cm", + "name": "config-file", + "space": "vendor-4491" + }, + { + "code": 12, + "data": "first", + "name": "payload", + "space": "vendor-4491" + )"; + if (configured_vendor_ids.size() > 1) { + config += R"( + }, + { + "code": 33, + "data": "special_erouter_v6.cm", + "name": "custom", + "space": "vendor-3561", + }, + { + "code": 12, + "data": "last", + "name": "special", + "space": "vendor-3561" + )"; + } + config += R"( + } + ], + "option-def": [ + { + "code": 12, + "name": "payload", + "space": "vendor-4491", + "type": "string" + )"; + if (configured_vendor_ids.size() > 1) { + config += R"( + }, + { + "code": 33, + "name": "custom", + "space": "vendor-3561", + "type": "string" + }, + { + "code": 12, + "name": "special", + "space": "vendor-3561", + "type": "string" + )"; + } + config += R"( + } + ], + "preferred-lifetime": 3000, + "rebind-timer": 2000, + "renew-timer": 1000, + "subnet6": [ + { + "interface": "eth0", + "interface-id": "", + "pools": [ + { + "pool": "2001:db8:1::/64" + } + ], + "preferred-lifetime": 3000, + "rebind-timer": 1000, + "renew-timer": 1000, + "subnet": "2001:db8:1::/48", + "valid-lifetime": 4000 + } + ], + "valid-lifetime": 4000 } )"; @@ -132,11 +197,16 @@ public: // 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 vendor_oro(new OptionUint16Array(Option::V6, - DOCSIS3_V6_ORO)); - vendor_oro->addValue(DOCSIS3_V6_CONFIG_FILE); // Request option 33 - OptionPtr vendor(new OptionVendor(Option::V6, vendor_id)); - vendor->addOption(vendor_oro); - sol->addOption(vendor); + DOCSIS3_V6_ORO)); + for (auto const& option : requested_options) { + vendor_oro->addValue(option); + } + + for (auto const& vendor_id : requested_vendor_ids) { + OptionVendorPtr vendor(new OptionVendor(Option::V6, vendor_id)); + vendor->addOption(vendor_oro); + sol->addOption(vendor); + } // Need to process SOLICIT again after requesting new option. AllocEngine::ClientContext6 ctx2; @@ -147,27 +217,314 @@ public: adv = srv_.processSolicit(ctx2); ASSERT_TRUE(adv); - // Check if there is (or not) a vendor option in the response. - OptionPtr tmp = adv->getOption(D6O_VENDOR_OPTS); - if (vendor_id != VENDOR_ID_CABLE_LABS) { - EXPECT_FALSE(tmp); + // Check if there is a vendor option in the response, if the Cable Labs + // vendor ID was provided in the request. Otherwise, check that there is + // no vendor and stop processing since the following checks are built on + // top of the now-absent options. + OptionCollection tmp = adv->getOptions(D6O_VENDOR_OPTS); + ASSERT_EQ(tmp.size(), result_vendor_ids.size()); + if (!result_vendor_ids.size()) { return; } - ASSERT_TRUE(tmp); - // The response should be an OptionVendor. - boost::shared_ptr vendor_resp = - boost::dynamic_pointer_cast(tmp); - ASSERT_TRUE(vendor_resp); + for (const auto& opt : tmp) { + // The response should be an OptionVendor. + OptionVendorPtr vendor_resp; + + for (auto const& vendor_id : result_vendor_ids) { + vendor_resp = boost::dynamic_pointer_cast(opt.second); + ASSERT_TRUE(vendor_resp); + if (vendor_resp->getVendorId() == vendor_id) { + break; + } + vendor_resp.reset(); + } + ASSERT_TRUE(vendor_resp); + if (vendor_resp->getVendorId() == VENDOR_ID_CABLE_LABS) { + for (auto const& option : requested_options) { + if (option == DOCSIS3_V6_CONFIG_FILE) { + // Option 33 should be present. + OptionPtr docsis33 = vendor_resp->getOption(DOCSIS3_V6_CONFIG_FILE); + ASSERT_TRUE(docsis33); + + // Check that the provided content match the one in configuration. + OptionStringPtr config_file = boost::dynamic_pointer_cast(docsis33); + ASSERT_TRUE(config_file); + EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue()); + } + + if (option == 12) { + // Option 12 should be present. + OptionPtr custom = vendor_resp->getOption(12); + ASSERT_TRUE(custom); + + // It should be an OptionString. + OptionStringPtr tag = boost::dynamic_pointer_cast(custom); + ASSERT_TRUE(tag); + + // Check that the provided value match the ones in configuration. + EXPECT_EQ(tag->getValue(), "first"); + } + } + } else { + // If explicitly sending OptionVendor and the vendor is not + // requested, options should not be present. Kea only knows how + // to process VENDOR_ID_CABLE_LABS DOCSIS3_V6_ORO (suboption 1). + // Option 33 should not be present. + OptionPtr docsis33 = vendor_resp->getOption(33); + ASSERT_FALSE(docsis33); + + // Option 12 should not be present. + OptionPtr custom = vendor_resp->getOption(12); + ASSERT_FALSE(custom); + } + } + } + + /// @brief Checks if Option Request Option (ORO) in docsis (vendor-id=4491) + /// vendor options is parsed correctly and the configured options are + /// actually assigned. + /// + /// @param configured_vendor_ids The vendor IDs that are configured in the + /// server: 4491 or both 4491 and 3561. + /// @param requested_vendor_ids Then vendor IDs that are present in ORO. + /// @param requested_options The requested options in ORO. + /// @param add_vendor_option The flag which indicates if the request should + /// contain a OptionVendor option or should the server always send all the + /// OptionVendor options and suboptions. + void testVendorOptionsPersistent(std::vector configured_vendor_ids, + std::vector requested_vendor_ids, + std::vector configured_options, + bool add_vendor_option) { + std::vector result_vendor_ids; + ASSERT_TRUE(configured_vendor_ids.size()); + ASSERT_EQ(configured_vendor_ids[0], VENDOR_ID_CABLE_LABS); + if (add_vendor_option) { + for (const auto& req : requested_vendor_ids) { + if (std::find(configured_vendor_ids.begin(), configured_vendor_ids.end(), req) != configured_vendor_ids.end()) { + result_vendor_ids.push_back(req); + } + } + } else { + result_vendor_ids = configured_vendor_ids; + } + ASSERT_TRUE(configured_options.size()); + ASSERT_EQ(configured_options[0], DOCSIS3_V6_CONFIG_FILE); + // Create a config with a custom options. + string config = R"( + { + "interfaces-config": { + "interfaces": [ "*" ] + }, + "preferred-lifetime": 3000, + "rebind-timer": 2000, + "renew-timer": 1000, + "valid-lifetime": 4000, + "option-data": [ + { + "always-send": true, + "code": 33, + "data": "normal_erouter_v6.cm", + "name": "config-file", + "space": "vendor-4491" + )"; + if (configured_options.size() > 1) { + config += R"( + }, + { + "always-send": true, + "code": 12, + "data": "first", + "name": "payload", + "space": "vendor-4491" + )"; + } + if (!add_vendor_option) { + config += R"( + }, + { + "always-send": true, + "name": "vendor-opts", + "data": "4491", + "space": "dhcp6" + )"; + } + if (configured_vendor_ids.size() > 1) { + config += R"( + }, + { + "always-send": true, + "code": 33, + "data": "special_erouter_v6.cm", + "name": "custom", + "space": "vendor-3561" + )"; + if (configured_options.size() > 1) { + config += R"( + }, + { + "always-send": true, + "code": 12, + "data": "last", + "name": "special", + "space": "vendor-3561" + )"; + } + if (!add_vendor_option) { + config += R"( + }, + { + "always-send": true, + "name": "vendor-opts", + "data": "3561", + "space": "dhcp6" + )"; + } + } + config += R"( + } + ], + "option-def": [ + { + "code": 12, + "name": "payload", + "space": "vendor-4491", + "type": "string" + )"; + if (configured_vendor_ids.size() > 1) { + config += R"( + }, + { + "code": 33, + "name": "custom", + "space": "vendor-3561", + "type": "string" + }, + { + "code": 12, + "name": "special", + "space": "vendor-3561", + "type": "string" + )"; + } + config += R"( + } + ], + "subnet6": [ + { + "interface": "eth0", + "pools": [ + { + "pool": "2001:db8:1::/64" + } + ], + "subnet": "2001:db8:1::/48", + "interface-id": "" + } + ] + } + )"; - // Option 33 should be present. - OptionPtr docsis33 = vendor_resp->getOption(DOCSIS3_V6_CONFIG_FILE); - ASSERT_TRUE(docsis33); + ASSERT_NO_THROW(configure(config)); - // Check that the provided content match the one in configuration. - OptionStringPtr config_file = boost::dynamic_pointer_cast(docsis33); - ASSERT_TRUE(config_file); - EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue()); + Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234)); + sol->setRemoteAddr(IOAddress("fe80::abcd")); + sol->setIface("eth0"); + sol->setIndex(ETH0_INDEX); + sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000)); + OptionPtr clientid = generateClientId(); + sol->addOption(clientid); + + if (add_vendor_option) { + for (auto const& vendor_id : requested_vendor_ids) { + // Let's add a vendor-option (vendor-id=4491). + OptionVendorPtr vendor(new OptionVendor(Option::V6, vendor_id)); + + sol->addOption(vendor); + } + } + + // Pass it to the server and get an advertise + AllocEngine::ClientContext6 ctx; + bool drop = !srv_.earlyGHRLookup(sol, ctx); + ASSERT_FALSE(drop); + srv_.initContext(sol, ctx, drop); + ASSERT_FALSE(drop); + Pkt6Ptr adv = srv_.processSolicit(ctx); + + // check if we get response at all + ASSERT_TRUE(adv); + + // Check if there is a vendor option response + OptionCollection tmp = adv->getOptions(D6O_VENDOR_OPTS); + ASSERT_EQ(tmp.size(), result_vendor_ids.size()); + + for (const auto& opt : tmp) { + // The response should be an OptionVendor. + OptionVendorPtr vendor_resp; + + for (auto const& vendor_id : result_vendor_ids) { + vendor_resp = boost::dynamic_pointer_cast(opt.second); + ASSERT_TRUE(vendor_resp); + if (vendor_resp->getVendorId() == vendor_id) { + break; + } + } + ASSERT_TRUE(vendor_resp); + + for (auto const& option : configured_options) { + if (add_vendor_option && + std::find(requested_vendor_ids.begin(), requested_vendor_ids.end(), + vendor_resp->getVendorId()) == requested_vendor_ids.end()) { + // If explicitly sending OptionVendor and the vendor is not + // requested, options should not be present. + if (option == DOCSIS3_V6_CONFIG_FILE) { + // Option 33 should not be present. + OptionPtr docsis33 = vendor_resp->getOption(DOCSIS3_V6_CONFIG_FILE); + ASSERT_FALSE(docsis33); + } + if (option == 12) { + // Option 12 should not be present. + OptionPtr custom = vendor_resp->getOption(12); + ASSERT_FALSE(custom); + } + } else { + if (option == DOCSIS3_V6_CONFIG_FILE) { + // Option 33 should be present. + OptionPtr docsis33 = vendor_resp->getOption(DOCSIS3_V6_CONFIG_FILE); + ASSERT_TRUE(docsis33); + + OptionStringPtr config_file = boost::dynamic_pointer_cast(docsis33); + ASSERT_TRUE(config_file); + if (vendor_resp->getVendorId() == VENDOR_ID_CABLE_LABS) { + EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue()); + } else { + EXPECT_EQ("special_erouter_v6.cm", config_file->getValue()); + } + } + + if (option == 12) { + // Option 12 should be present. + OptionPtr custom = vendor_resp->getOption(12); + ASSERT_TRUE(custom); + + // It should be an OptionString. + // The option is serialized as Option so it needs to be converted to + // OptionString. + auto const& buffer = custom->toBinary(); + OptionStringPtr tag(new OptionString(Option::V6, 12, buffer.begin(), buffer.end())); + ASSERT_TRUE(tag); + + // Check that the provided value match the ones in configuration. + if (vendor_resp->getVendorId() == VENDOR_ID_CABLE_LABS) { + EXPECT_EQ(tag->getValue(), "first"); + } else { + EXPECT_EQ(tag->getValue(), "last"); + } + } + } + } + } } /// @brief Test what options a client can use to request vendor options. @@ -192,8 +549,7 @@ public: vendor_id_); should_yield_response = true; } else if (i == D6O_VENDOR_OPTS) { - vendor_option = boost::make_shared(Option::V6, - vendor_id_); + vendor_option.reset(new OptionVendor(Option::V6, vendor_id_)); should_yield_response = true; } else { continue; @@ -224,8 +580,7 @@ public: EXPECT_EQ(vendor_id_, response_vendor_options->getVendorId()); // Check that it contains requested option with the appropriate content. - OptionPtr suboption( - response_vendor_options->getOption(option_)); + OptionPtr suboption(response_vendor_options->getOption(option_)); ASSERT_TRUE(suboption); vector binary_suboption = suboption->toBinary(false); string text(binary_suboption.begin(), binary_suboption.end()); @@ -240,7 +595,7 @@ private: int32_t option_ = 32; /// @brief Configured and requested vendor ID - int32_t vendor_id_ = 32768; + uint32_t vendor_id_ = 32768; /// @brief Server configuration string config_ = R"( @@ -317,6 +672,7 @@ TEST_F(VendorOptsTest, docsisVendorOptionsParse) { boost::shared_ptr vendor = boost::dynamic_pointer_cast(opt); ASSERT_TRUE(vendor); + ASSERT_EQ(vendor->getVendorId(), VENDOR_ID_CABLE_LABS); EXPECT_TRUE(vendor->getOption(DOCSIS3_V6_ORO)); EXPECT_TRUE(vendor->getOption(36)); @@ -346,12 +702,13 @@ TEST_F(VendorOptsTest, docsisVendorORO) { Pkt6Ptr sol = PktCaptures::captureDocsisRelayedSolicit(); ASSERT_NO_THROW(sol->unpack()); - // Check if the packet contains vendor options option + // Check if the packet contains vendor specific information option OptionPtr opt = sol->getOption(D6O_VENDOR_OPTS); ASSERT_TRUE(opt); boost::shared_ptr vendor = boost::dynamic_pointer_cast(opt); ASSERT_TRUE(vendor); + ASSERT_EQ(vendor->getVendorId(), VENDOR_ID_CABLE_LABS); opt = vendor->getOption(DOCSIS3_V6_ORO); ASSERT_TRUE(opt); @@ -362,121 +719,134 @@ TEST_F(VendorOptsTest, docsisVendorORO) { // 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(VendorOptsTest, vendorOptionsORO) { - testVendorOptionsORO(VENDOR_ID_CABLE_LABS); +TEST_F(VendorOptsTest, vendorOptionsOROOneOption) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE}); +} + +// 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(VendorOptsTest, vendorOptionsOROMultipleOptions) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE, 12}); +} + +// 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(VendorOptsTest, vendorOptionsOROOneOptionMultipleVendorsMatchOne) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE}); +} + +// 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(VendorOptsTest, vendorOptionsOROMultipleOptionsMultipleVendorsMatchOne) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE, 12}); +} + +// 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(VendorOptsTest, vendorOptionsOROOneOptionMultipleVendorsMatchAll) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS, 3561}, {DOCSIS3_V6_CONFIG_FILE}); +} + +// 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(VendorOptsTest, vendorOptionsOROMultipleOptionsMultipleVendorsMatchAll) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS, 3561}, {DOCSIS3_V6_CONFIG_FILE, 12}); } // Same as vendorOptionsORO except a different vendor ID than Cable Labs is // provided and vendor options are expected to not be present in the response. -TEST_F(VendorOptsTest, vendorOptionsORODifferentVendorID) { - testVendorOptionsORO(32768); +TEST_F(VendorOptsTest, vendorOptionsOROOneOptionDifferentVendorID) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS}, {32768}, {DOCSIS3_V6_CONFIG_FILE}); +} + +// Same as vendorOptionsORO except a different vendor ID than Cable Labs is +// provided and vendor options are expected to not be present in the response. +TEST_F(VendorOptsTest, vendorOptionsOROMultipleOptionsDifferentVendorID) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS}, {32768}, {DOCSIS3_V6_CONFIG_FILE, 12}); +} + +// Same as vendorOptionsORO except a different vendor ID than Cable Labs is +// provided and vendor options are expected to not be present in the response. +TEST_F(VendorOptsTest, vendorOptionsOROOneOptionDifferentVendorIDMultipleVendorsMatchNone) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS, 3561}, {32768, 16384}, {DOCSIS3_V6_CONFIG_FILE}); +} + +// Same as vendorOptionsORO except a different vendor ID than Cable Labs is +// provided and vendor options are expected to not be present in the response. +TEST_F(VendorOptsTest, vendorOptionsOROMultipleOptionDifferentVendorIDMultipleVendorsMatchNone) { + testVendorOptionsORO({VENDOR_ID_CABLE_LABS, 3561}, {32768, 16384}, {DOCSIS3_V6_CONFIG_FILE, 12}); } // This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) -// vendor options is parsed correctly and the persistent options are actually assigned. -TEST_F(VendorOptsTest, vendorPersistentOptions) { - string config = "{ \"interfaces-config\": {" - " \"interfaces\": [ \"*\" ]" - "}," - "\"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - " \"option-def\": [ {" - " \"name\": \"config-file\"," - " \"code\": 33," - " \"type\": \"string\"," - " \"space\": \"vendor-4491\"" - " } ]," - " \"option-data\": [ {" - " \"name\": \"config-file\"," - " \"space\": \"vendor-4491\"," - " \"data\": \"normal_erouter_v6.cm\"," - " \"always-send\": true" - " }]," - "\"subnet6\": [ { " - " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," - " \"subnet\": \"2001:db8:1::/48\", " - " \"renew-timer\": 1000, " - " \"rebind-timer\": 1000, " - " \"preferred-lifetime\": 3000," - " \"valid-lifetime\": 4000," - " \"interface-id\": \"\"," - " \"interface\": \"eth0\"" - " } ]," - "\"valid-lifetime\": 4000 }"; +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsOneOption) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE}, false); +} - ASSERT_NO_THROW(configure(config)); - - Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234)); - sol->setRemoteAddr(IOAddress("fe80::abcd")); - sol->setIface("eth0"); - sol->setIndex(ETH0_INDEX); - sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000)); - OptionPtr clientid = generateClientId(); - sol->addOption(clientid); - - // Let's add a vendor-option (vendor-id=4491). - OptionPtr vendor(new OptionVendor(Option::V6, 4491)); - sol->addOption(vendor); - - // Pass it to the server and get an advertise - AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(sol, ctx); - ASSERT_FALSE(drop); - srv_.initContext(sol, ctx, drop); - ASSERT_FALSE(drop); - Pkt6Ptr adv = srv_.processSolicit(ctx); - - // check if we get response at all - ASSERT_TRUE(adv); +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsMultipleOption) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE, 12}, false); +} - // Check if there is vendor option response - OptionPtr tmp = adv->getOption(D6O_VENDOR_OPTS); - ASSERT_TRUE(tmp); - - // The response should be OptionVendor object - boost::shared_ptr vendor_resp = - boost::dynamic_pointer_cast(tmp); - ASSERT_TRUE(vendor_resp); - - OptionPtr docsis33 = vendor_resp->getOption(33); - ASSERT_TRUE(docsis33); - - OptionStringPtr config_file = boost::dynamic_pointer_cast(docsis33); - ASSERT_TRUE(config_file); - EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue()); - - // 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. - sol->delOption(D6O_VENDOR_OPTS); - boost::shared_ptr vendor_oro(new OptionUint16Array(Option::V6, - DOCSIS3_V6_ORO)); - vendor_oro->addValue(DOCSIS3_V6_CONFIG_FILE); // Request option 33 - OptionPtr vendor2(new OptionVendor(Option::V6, 4491)); - vendor2->addOption(vendor_oro); - sol->addOption(vendor2); - - // Need to process SOLICIT again after requesting new option. - AllocEngine::ClientContext6 ctx2; - drop = !srv_.earlyGHRLookup(sol, ctx2); - ASSERT_FALSE(drop); - srv_.initContext(sol, ctx2, drop); - ASSERT_FALSE(drop); - adv = srv_.processSolicit(ctx2); - ASSERT_TRUE(adv); +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsOneOptionMultipleVendorsMatchOne) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE}, false); +} - // Check if there is vendor option response - tmp = adv->getOption(D6O_VENDOR_OPTS); - ASSERT_TRUE(tmp); +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsMultipleOptionMultipleVendorsMatchOne) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE, 12}, false); +} - // The response should be OptionVendor object - vendor_resp = boost::dynamic_pointer_cast(tmp); - ASSERT_TRUE(vendor_resp); +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsOneOptionMultipleVendorsMatchAll) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS, 3561}, {DOCSIS3_V6_CONFIG_FILE}, false); +} - // There should be only one suboption despite config-file is both - // requested and has the always-send flag. - const OptionCollection& opts = vendor_resp->getOptions(); - ASSERT_EQ(1, opts.size()); +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsMultipleOptionMultipleVendorsMatchAll) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS, 3561}, {DOCSIS3_V6_CONFIG_FILE, 12}, false); +} + +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsOneOptionAddVendorOption) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE}, true); +} + +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsMultipleOptionAddVendorOption) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE, 12}, true); +} + +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsOneOptionMultipleVendorsMatchOneAddVendorOption) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE}, true); +} + +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsMultipleOptionMultipleVendorsMatchOneAddVendorOption) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS}, {DOCSIS3_V6_CONFIG_FILE, 12}, true); +} + +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsOneOptionMultipleVendorsMatchAllAddVendorOption) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS, 3561}, {DOCSIS3_V6_CONFIG_FILE}, true); +} + +// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491) +// vendor options is parsed correctly and persistent options are actually assigned. +TEST_F(VendorOptsTest, vendorPersistentOptionsMultipleOptionMultipleVendorsMatchAllAddVendorOption) { + testVendorOptionsPersistent({VENDOR_ID_CABLE_LABS, 3561}, {VENDOR_ID_CABLE_LABS, 3561}, {DOCSIS3_V6_CONFIG_FILE, 12}, true); } // Test checks whether it is possible to use option definitions defined in @@ -877,7 +1247,7 @@ TEST_F(VendorOptsTest, threeVendors) { // Add a DOCSIS vendor-opts with an ORO. OptionUint16ArrayPtr oro(new OptionUint16Array(Option::V6, DOCSIS3_V6_ORO)); oro->addValue(DOCSIS3_V6_CONFIG_FILE); // Request option 33. - OptionPtr vendor(new OptionVendor(Option::V6, 4491)); + OptionVendorPtr vendor(new OptionVendor(Option::V6, VENDOR_ID_CABLE_LABS)); vendor->addOption(oro); client.addExtraOption(vendor); @@ -903,7 +1273,7 @@ TEST_F(VendorOptsTest, threeVendors) { opt_opts1234 = opt_opts; continue; } - if (vendor_id == 4491) { + if (vendor_id == VENDOR_ID_CABLE_LABS) { ASSERT_FALSE(opt_docsis); opt_docsis = opt_opts; continue; diff --git a/src/lib/dhcpsrv/dhcp4o6_ipc.cc b/src/lib/dhcpsrv/dhcp4o6_ipc.cc index 742b9541c6..62c54f1de9 100644 --- a/src/lib/dhcpsrv/dhcp4o6_ipc.cc +++ b/src/lib/dhcpsrv/dhcp4o6_ipc.cc @@ -238,28 +238,39 @@ void Dhcp4o6IpcBase::send(const Pkt6Ptr& pkt) { } // Check if vendor option exists. - OptionVendorPtr option_vendor = boost::dynamic_pointer_cast< - OptionVendor>(pkt->getOption(D6O_VENDOR_OPTS)); + // Vendor option is initially NULL. If we find the instance of the vendor + // option with the ISC enterprise id this pointer will point to it. + OptionVendorPtr option_vendor; + + // Get all vendor option and look for the one with the ISC enterprise id. + OptionCollection vendor_options = pkt->getOptions(D6O_VENDOR_OPTS); + for (OptionCollection::const_iterator opt = vendor_options.begin(); + opt != vendor_options.end(); ++opt) { + option_vendor = boost::dynamic_pointer_cast(opt->second); + if (option_vendor) { + if (option_vendor->getVendorId() == ENTERPRISE_ID_ISC) { + break; + } + option_vendor.reset(); + } + } // If vendor option doesn't exist or its enterprise id is not ISC's // enterprise id, let's create it. - if (!option_vendor || - (option_vendor->getVendorId() != ENTERPRISE_ID_ISC)) { + if (!option_vendor) { option_vendor.reset(new OptionVendor(Option::V6, ENTERPRISE_ID_ISC)); pkt->addOption(option_vendor); - } // Push interface name and source address in it option_vendor->addOption(OptionStringPtr(new OptionString(Option::V6, - ISC_V6_4O6_INTERFACE, - pkt->getIface()))); - option_vendor->addOption(Option6AddrLstPtr(new Option6AddrLst( - ISC_V6_4O6_SRC_ADDRESS, - pkt->getRemoteAddr()))); + ISC_V6_4O6_INTERFACE, + pkt->getIface()))); + option_vendor->addOption(Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, + pkt->getRemoteAddr()))); option_vendor->addOption(OptionUint16Ptr(new OptionUint16(Option::V6, - ISC_V6_4O6_SRC_PORT, - pkt->getRemotePort()))); + ISC_V6_4O6_SRC_PORT, + pkt->getRemotePort()))); // Get packet content OutputBuffer& buf = pkt->getBuffer(); buf.clear(); @@ -273,6 +284,5 @@ void Dhcp4o6IpcBase::send(const Pkt6Ptr& pkt) { } } -}; // namespace dhcp - -}; // namespace isc +} // namespace dhcp +} // namespace isc diff --git a/src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc b/src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc index 4fbb2a4dab..7a0f54ab41 100644 --- a/src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc +++ b/src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc @@ -466,13 +466,11 @@ TEST_F(Dhcp4o6IpcBaseTest, receiveWithoutVendorOption) { TEST_F(Dhcp4o6IpcBaseTest, receiveInvalidEnterpriseId) { Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 0)); OptionVendorPtr option_vendor(new OptionVendor(Option::V6, 1)); - option_vendor->addOption( - OptionStringPtr(new OptionString(Option::V6, ISC_V6_4O6_INTERFACE, - "eth0"))); - option_vendor->addOption( - Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, - IOAddress("2001:db8:1::1"))) - ); + option_vendor->addOption(OptionStringPtr(new OptionString(Option::V6, + ISC_V6_4O6_INTERFACE, + "eth0"))); + option_vendor->addOption(Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, + IOAddress("2001:db8:1::1")))); pkt->addOption(option_vendor); testReceiveError(pkt); @@ -482,16 +480,12 @@ TEST_F(Dhcp4o6IpcBaseTest, receiveInvalidEnterpriseId) { // interface option is not present. TEST_F(Dhcp4o6IpcBaseTest, receiveWithoutInterfaceOption) { Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 0)); - OptionVendorPtr option_vendor(new OptionVendor(Option::V6, - ENTERPRISE_ID_ISC)); - option_vendor->addOption( - Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, - IOAddress("2001:db8:1::1"))) - ); - option_vendor->addOption( - OptionUint16Ptr(new OptionUint16(Option::V6, - ISC_V6_4O6_SRC_PORT, - TEST_PORT))); + OptionVendorPtr option_vendor(new OptionVendor(Option::V6, ENTERPRISE_ID_ISC)); + option_vendor->addOption(Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, + IOAddress("2001:db8:1::1")))); + option_vendor->addOption(OptionUint16Ptr(new OptionUint16(Option::V6, + ISC_V6_4O6_SRC_PORT, + TEST_PORT))); pkt->addOption(option_vendor); testReceiveError(pkt); @@ -502,19 +496,15 @@ TEST_F(Dhcp4o6IpcBaseTest, receiveWithoutInterfaceOption) { // system. TEST_F(Dhcp4o6IpcBaseTest, receiveWithInvalidInterface) { Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 0)); - OptionVendorPtr option_vendor(new OptionVendor(Option::V6, - ENTERPRISE_ID_ISC)); - option_vendor->addOption( - OptionStringPtr(new OptionString(Option::V6, ISC_V6_4O6_INTERFACE, - "ethX"))); - option_vendor->addOption( - Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, - IOAddress("2001:db8:1::1"))) - ); - option_vendor->addOption( - OptionUint16Ptr(new OptionUint16(Option::V6, - ISC_V6_4O6_SRC_PORT, - TEST_PORT))); + OptionVendorPtr option_vendor(new OptionVendor(Option::V6, ENTERPRISE_ID_ISC)); + option_vendor->addOption(OptionStringPtr(new OptionString(Option::V6, + ISC_V6_4O6_INTERFACE, + "ethX"))); + option_vendor->addOption(Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, + IOAddress("2001:db8:1::1")))); + option_vendor->addOption(OptionUint16Ptr(new OptionUint16(Option::V6, + ISC_V6_4O6_SRC_PORT, + TEST_PORT))); pkt->addOption(option_vendor); testReceiveError(pkt); @@ -525,15 +515,13 @@ TEST_F(Dhcp4o6IpcBaseTest, receiveWithInvalidInterface) { // source address option is not present. TEST_F(Dhcp4o6IpcBaseTest, receiveWithoutSourceAddressOption) { Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 0)); - OptionVendorPtr option_vendor(new OptionVendor(Option::V6, - ENTERPRISE_ID_ISC)); - option_vendor->addOption( - OptionStringPtr(new OptionString(Option::V6, ISC_V6_4O6_INTERFACE, - "eth0"))); - option_vendor->addOption( - OptionUint16Ptr(new OptionUint16(Option::V6, - ISC_V6_4O6_SRC_PORT, - TEST_PORT))); + OptionVendorPtr option_vendor(new OptionVendor(Option::V6, ENTERPRISE_ID_ISC)); + option_vendor->addOption(OptionStringPtr(new OptionString(Option::V6, + ISC_V6_4O6_INTERFACE, + "eth0"))); + option_vendor->addOption(OptionUint16Ptr(new OptionUint16(Option::V6, + ISC_V6_4O6_SRC_PORT, + TEST_PORT))); pkt->addOption(option_vendor); testReceiveError(pkt); @@ -543,15 +531,12 @@ TEST_F(Dhcp4o6IpcBaseTest, receiveWithoutSourceAddressOption) { // source port option is not present. TEST_F(Dhcp4o6IpcBaseTest, receiveWithoutSourcePortOption) { Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 0)); - OptionVendorPtr option_vendor(new OptionVendor(Option::V6, - ENTERPRISE_ID_ISC)); - option_vendor->addOption( - OptionStringPtr(new OptionString(Option::V6, ISC_V6_4O6_INTERFACE, - "eth0"))); - option_vendor->addOption( - Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, - IOAddress("2001:db8:1::1"))) - ); + OptionVendorPtr option_vendor(new OptionVendor(Option::V6, ENTERPRISE_ID_ISC)); + option_vendor->addOption(OptionStringPtr(new OptionString(Option::V6, + ISC_V6_4O6_INTERFACE, + "eth0"))); + option_vendor->addOption(Option6AddrLstPtr(new Option6AddrLst(ISC_V6_4O6_SRC_ADDRESS, + IOAddress("2001:db8:1::1")))); pkt->addOption(option_vendor); testReceiveError(pkt);