From: Francis Dupont Date: Fri, 7 Jul 2017 18:10:25 +0000 (+0200) Subject: [5241] Added the function in DHCPv4 and 6 servers X-Git-Tag: trac5124a_base~23^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4650a9224873bf9414abfb82a5dc549d435899ae;p=thirdparty%2Fkea.git [5241] Added the function in DHCPv4 and 6 servers --- diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 231e826f18..08a31439bb 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -1226,21 +1226,37 @@ Dhcpv4Srv::appendRequestedOptions(Dhcpv4Exchange& ex) { } Pkt4Ptr query = ex.getQuery(); + Pkt4Ptr resp = ex.getResponse(); + std::vector requested_opts; // try to get the 'Parameter Request List' option which holds the // codes of requested options. OptionUint8ArrayPtr option_prl = boost::dynamic_pointer_cast< OptionUint8Array>(query->getOption(DHO_DHCP_PARAMETER_REQUEST_LIST)); - // If there is no PRL option in the message from the client then - // there is nothing to do. - if (!option_prl) { - return; + // Get the codes of requested options. + if (option_prl) { + requested_opts = option_prl->getValues(); + } + // 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(DHCP4_OPTION_SPACE); + if (!opts) { + continue; + } + // Get persistent options + const OptionContainerPersistIndex& idx = opts->get<2>(); + const OptionContainerPersistRange& range = idx.equal_range(true); + for (OptionContainerPersistIndex::const_iterator desc = range.first; + desc != range.second; ++desc) { + // Add the persistent option code to requested options + if (desc->option_) { + uint8_t code = static_cast(desc->option_->getType()); + requested_opts.push_back(code); + } + } } - Pkt4Ptr resp = ex.getResponse(); - - // Get the codes of requested options. - const std::vector& requested_opts = option_prl->getValues(); // For each requested option code get the instance of the option // to be returned to the client. for (std::vector::const_iterator opt = requested_opts.begin(); @@ -1288,15 +1304,39 @@ Dhcpv4Srv::appendRequestedVendorOptions(Dhcpv4Exchange& ex) { } uint32_t vendor_id = vendor_req->getVendorId(); + std::vector requested_opts; // 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. OptionUint8ArrayPtr oro = boost::dynamic_pointer_cast(vendor_req->getOption(DOCSIS3_V4_ORO)); + // Get the list of options that client requested. + if (oro) { + requested_opts = oro->getValues(); + } + // 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(vendor_id); + if (!opts) { + continue; + } + // Get persistent options + const OptionContainerPersistIndex& idx = opts->get<2>(); + const OptionContainerPersistRange& range = idx.equal_range(true); + for (OptionContainerPersistIndex::const_iterator desc = range.first; + desc != range.second; ++desc) { + // Add the persistent option code to requested options + if (desc->option_) { + uint8_t code = static_cast(desc->option_->getType()); + requested_opts.push_back(code); + } + } + } - // Option ORO not found. Don't do anything then. - if (!oro) { + // If there is nothing to add don't do anything then. + if (requested_opts.empty()) { return; } @@ -1304,8 +1344,6 @@ Dhcpv4Srv::appendRequestedVendorOptions(Dhcpv4Exchange& ex) { // Get the list of options that client requested. bool added = false; - const std::vector& requested_opts = oro->getValues(); - for (std::vector::const_iterator code = requested_opts.begin(); code != requested_opts.end(); ++code) { if (!vendor_rsp->getOption(*code)) { diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index 7097fd055a..beaf07dccb 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -2820,7 +2820,7 @@ TEST_F(Dhcp4ParserTest, optionDataSinglePool) { // Expect a single option with the code equal to 100. ASSERT_EQ(1, std::distance(range.first, range.second)); const uint8_t foo_expected[] = { - 0xAB, 0xCD, 0xEF, 0x01, 0x05 + 0xAB, 0xCD, 0xEF, 0x01, 0x05 }; // Check if option is valid in terms of code and carried data. testOption(*range.first, 56, foo_expected, sizeof(foo_expected)); @@ -2893,7 +2893,7 @@ TEST_F(Dhcp4ParserTest, optionDataMultiplePools) { // Expect a single option with the code equal to 100. ASSERT_EQ(1, std::distance(range1.first, range1.second)); const uint8_t foo_expected[] = { - 0xAB, 0xCD, 0xEF, 0x01, 0x05 + 0xAB, 0xCD, 0xEF, 0x01, 0x05 }; // Check if option is valid in terms of code and carried data. testOption(*range1.first, 56, foo_expected, sizeof(foo_expected)); @@ -2909,8 +2909,8 @@ TEST_F(Dhcp4ParserTest, optionDataMultiplePools) { const OptionContainerTypeIndex& idx2 = options2->get<1>(); std::pair range2 = - idx2.equal_range(23); + OptionContainerTypeIndex::const_iterator> range2 = + idx2.equal_range(23); ASSERT_EQ(1, std::distance(range2.first, range2.second)); const uint8_t foo2_expected[] = { 0x01 diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 6c5c25265c..16ddfa54ae 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -1451,6 +1451,89 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsORO) { EXPECT_EQ("192.0.2.2", addrs[1].toText()); } +// 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(Dhcpv4SrvTest, vendorPersistentOptions) { + IfaceMgrTestConfig test_config(true); + IfaceMgr::instance().openSockets4(); + + NakedDhcpv4Srv srv(0); + + ConstElementPtr x; + string config = "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "}," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + " \"option-data\": [ {" + " \"name\": \"tftp-servers\"," + " \"space\": \"vendor-4491\"," + " \"code\": 2," + " \"data\": \"192.0.2.1, 192.0.2.2\"," + " \"csv-format\": true," + " \"persistent\": true" + " }]," + "\"subnet4\": [ { " + " \"pools\": [ { \"pool\": \"192.0.2.0/25\" } ]," + " \"subnet\": \"192.0.2.0/24\", " + " \"rebind-timer\": 2000, " + " \"renew-timer\": 1000, " + " \"valid-lifetime\": 4000," + " \"interface\": \"eth0\" " + " } ]," + "\"valid-lifetime\": 4000 }"; + + ConstElementPtr json; + ASSERT_NO_THROW(json = parseDHCP4(config)); + + EXPECT_NO_THROW(x = configureDhcp4Server(srv, json)); + ASSERT_TRUE(x); + comment_ = isc::config::parseAnswer(rcode_, x); + ASSERT_EQ(0, rcode_); + + CfgMgr::instance().commit(); + + boost::shared_ptr dis(new Pkt4(DHCPDISCOVER, 1234)); + // Set the giaddr and hops to non-zero address as if it was relayed. + dis->setGiaddr(IOAddress("192.0.2.1")); + dis->setHops(1); + + OptionPtr clientid = generateClientId(); + dis->addOption(clientid); + // Set interface. It is required by the server to generate server id. + dis->setIface("eth0"); + + // Let's add a vendor-option (vendor-id=4491). + OptionPtr vendor(new OptionVendor(Option::V4, 4491)); + dis->addOption(vendor); + + // Pass it to the server and get an advertise + Pkt4Ptr offer = srv.processDiscover(dis); + + // check if we get response at all + ASSERT_TRUE(offer); + + // Check if there is a vendor option response + OptionPtr tmp = offer->getOption(DHO_VIVSO_SUBOPTIONS); + ASSERT_TRUE(tmp); + + // The response should be OptionVendor object + boost::shared_ptr vendor_resp = + boost::dynamic_pointer_cast(tmp); + ASSERT_TRUE(vendor_resp); + + OptionPtr docsis2 = vendor_resp->getOption(DOCSIS3_V4_TFTP_SERVERS); + ASSERT_TRUE(docsis2); + + Option4AddrLstPtr tftp_srvs = boost::dynamic_pointer_cast(docsis2); + ASSERT_TRUE(tftp_srvs); + + Option4AddrLst::AddressContainer addrs = tftp_srvs->getAddresses(); + ASSERT_EQ(2, addrs.size()); + EXPECT_EQ("192.0.2.1", addrs[0].toText()); + EXPECT_EQ("192.0.2.2", addrs[1].toText()); +} + // Test checks whether it is possible to use option definitions defined in // src/lib/dhcp/docsis3_option_defs.h. TEST_F(Dhcpv4SrvTest, vendorOptionsDocsisDefinitions) { @@ -1952,6 +2035,85 @@ TEST_F(Dhcpv4SrvTest, classGlobalPriority) { EXPECT_NE(0, opt->getUint8()); } +// Checks class options have the priority over global persistent options +TEST_F(Dhcpv4SrvTest, classGlobalPersistency) { + IfaceMgrTestConfig test_config(true); + IfaceMgr::instance().openSockets4(); + + NakedDhcpv4Srv srv(0); + + // A global ip-forwarding option is set in the response. + // The router class matches incoming packets with foo in a host-name + // option (code 12) and sets an ip-forwarding option in the response. + // Note the persistency flag follows a "OR" semantic so to set + // it to false (or to leave the default) has no effect. + string config = "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ] }, " + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"valid-lifetime\": 4000, " + "\"subnet4\": [ " + "{ \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ], " + " \"subnet\": \"192.0.2.0/24\" } ], " + "\"option-data\": [" + " { \"name\": \"ip-forwarding\", " + " \"data\": \"false\", " + " \"persistent\": true } ], " + "\"client-classes\": [ " + "{ \"name\": \"router\"," + " \"option-data\": [" + " { \"name\": \"ip-forwarding\", " + " \"data\": \"true\", " + " \"persistent\": false } ], " + " \"test\": \"option[12].text == 'foo'\" } ] }"; + + ConstElementPtr json; + ASSERT_NO_THROW(json = parseDHCP4(config)); + ConstElementPtr status; + + // Configure the server and make sure the config is accepted + EXPECT_NO_THROW(status = configureDhcp4Server(srv, json)); + ASSERT_TRUE(status); + comment_ = config::parseAnswer(rcode_, status); + ASSERT_EQ(0, rcode_); + + CfgMgr::instance().commit(); + + // Create a packet with enough to select the subnet and go through + // the DISCOVER processing + Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 1234)); + query->setRemoteAddr(IOAddress("192.0.2.1")); + OptionPtr clientid = generateClientId(); + query->addOption(clientid); + query->setIface("eth1"); + + // Do not add a PRL + OptionPtr prl = query->getOption(DHO_DHCP_PARAMETER_REQUEST_LIST); + EXPECT_FALSE(prl); + + // Create and add a host-name option to the query + OptionStringPtr hostname(new OptionString(Option::V4, 12, "foo")); + ASSERT_TRUE(hostname); + query->addOption(hostname); + + // Classify the packet + srv.classifyPacket(query); + + // The packet should be in the router class + EXPECT_TRUE(query->inClass("router")); + + // Process the query + Pkt4Ptr response = srv.processDiscover(query); + + // Processing should add an ip-forwarding option + OptionPtr opt = response->getOption(DHO_IP_FORWARDING); + ASSERT_TRUE(opt); + ASSERT_GT(opt->len(), opt->getHeaderLen()); + // Classification sets the value to true/1, global to false/0 + // Here class has the priority + EXPECT_NE(0, opt->getUint8()); +} + // Checks if the client-class field is indeed used for subnet selection. // Note that packet classification is already checked in Dhcpv4SrvTest // .*Classification above. diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index ae730c380d..4660c795d5 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -918,20 +918,39 @@ void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer, const CfgOptionList& co_list) { + // Unlikely short cut + if (co_list.empty()) { + return; + } + + std::vector requested_opts; + // 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)); - // If there is no ORO option, there is nothing more to do. - if (!option_oro) { - return; - - } - // Get the list of options that client requested. - const std::vector& requested_opts = option_oro->getValues(); + if (option_oro) { + requested_opts = option_oro->getValues(); + } + // 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); + if (!opts) { + continue; + } + // Get persistent options + const OptionContainerPersistIndex& idx = opts->get<2>(); + const OptionContainerPersistRange& range = idx.equal_range(true); + for (OptionContainerPersistIndex::const_iterator desc = range.first; + desc != range.second; ++desc) { + // Add the persistent option code to requested options + requested_opts.push_back(desc->option_->getType()); + } + } BOOST_FOREACH(uint16_t opt, requested_opts) { // Iterate on the configured option list @@ -969,24 +988,44 @@ Dhcpv6Srv::appendRequestedVendorOptions(const Pkt6Ptr& question, return; } + uint32_t vendor_id = vendor_req->getVendorId(); + std::vector requested_opts; + // 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 oro = boost::dynamic_pointer_cast(vendor_req->getOption(DOCSIS3_V6_ORO)); + if (oro) { + requested_opts = oro->getValues(); + } + // 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(vendor_id); + if (!opts) { + continue; + } + // Get persistent options + const OptionContainerPersistIndex& idx = opts->get<2>(); + const OptionContainerPersistRange& range = idx.equal_range(true); + for (OptionContainerPersistIndex::const_iterator desc = range.first; + desc != range.second; ++desc) { + // Add the persistent option code to requested options + requested_opts.push_back(desc->option_->getType()); + } + } - // Option ORO not found. Don't do anything then. - if (!oro) { + // If there is nothing to add don't do anything then. + if (requested_opts.empty()) { return; } - uint32_t vendor_id = vendor_req->getVendorId(); - boost::shared_ptr vendor_rsp(new OptionVendor(Option::V6, vendor_id)); // Get the list of options that client requested. bool added = false; - const std::vector& requested_opts = oro->getValues(); + BOOST_FOREACH(uint16_t opt, requested_opts) { for (CfgOptionList::const_iterator copts = co_list.begin(); copts != co_list.end(); ++copts) { diff --git a/src/bin/dhcp6/tests/classify_unittests.cc b/src/bin/dhcp6/tests/classify_unittests.cc index c86652d453..22b0953f21 100644 --- a/src/bin/dhcp6/tests/classify_unittests.cc +++ b/src/bin/dhcp6/tests/classify_unittests.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -518,6 +518,74 @@ TEST_F(ClassifyTest, classGlobalPriority) { EXPECT_NE(0, opt->getUint8()); } +// Checks class options have the priority over global persistent options +TEST_F(ClassifyTest, classGlobalPersistency) { + IfaceMgrTestConfig test_config(true); + + NakedDhcpv6Srv srv(0); + + // Subnet sets an ipv6-forwarding option in the response. + // The router class matches incoming packets with foo in a host-name + // option (code 1234) and sets an ipv6-forwarding option in the response. + // Note the persistency flag follows a "OR" semantic so to set + // it to false (or to leave the default) has no effect. + std::string config = "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ] }, " + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"valid-lifetime\": 4000, " + "\"option-def\": [ " + "{ \"name\": \"host-name\"," + " \"code\": 1234," + " \"type\": \"string\" }," + "{ \"name\": \"ipv6-forwarding\"," + " \"code\": 2345," + " \"type\": \"boolean\" }]," + "\"option-data\": [" + " { \"name\": \"ipv6-forwarding\", " + " \"data\": \"false\", " + " \"persistent\": true } ], " + "\"subnet6\": [ " + "{ \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ], " + " \"subnet\": \"2001:db8:1::/48\", " + " \"interface\": \"eth1\", " + " \"option-data\": [" + " { \"name\": \"ipv6-forwarding\", " + " \"data\": \"false\", " + " \"persistent\": false } ] } ] }"; + ASSERT_NO_THROW(configure(config)); + + // Create a packet with enough to select the subnet and go through + // the SOLICIT processing + Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 1234)); + query->setRemoteAddr(IOAddress("fe80::abcd")); + OptionPtr clientid = generateClientId(); + query->addOption(clientid); + query->setIface("eth1"); + query->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000)); + + // Do not add an ORO. + OptionPtr oro = query->getOption(D6O_ORO); + EXPECT_FALSE(oro); + + // Create and add a host-name option to the query + OptionStringPtr hostname(new OptionString(Option::V6, 1234, "foo")); + ASSERT_TRUE(hostname); + query->addOption(hostname); + + // Process the query + Pkt6Ptr response = srv.processSolicit(query); + + // Processing should add an ip-forwarding option + OptionPtr opt = response->getOption(2345); + ASSERT_TRUE(opt); + ASSERT_GT(opt->len(), opt->getHeaderLen()); + // Global sets the value to true/1, subnet to false/0 + // Here subnet has the priority + EXPECT_EQ(0, opt->getUint8()); +} + // Checks if the client-class field is indeed used for subnet selection. // Note that packet classification is already checked in ClassifyTest // .*Classification above. diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 1c38b463a4..da00093443 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -1666,6 +1666,78 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsORO) { EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue()); } +// 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(Dhcpv6SrvTest, vendorPersistentOptions) { + + IfaceMgrTestConfig test_config(true); + + 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\"," + " \"persistent\": 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 }"; + + ASSERT_NO_THROW(configure(config)); + + Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234)); + sol->setRemoteAddr(IOAddress("fe80::abcd")); + sol->setIface("eth0"); + 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 + Pkt6Ptr adv = srv_.processSolicit(sol); + + // check if we get response at all + ASSERT_TRUE(adv); + + // 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()); +} + // Test checks whether it is possible to use option definitions defined in // src/lib/dhcp/docsis3_option_defs.h. TEST_F(Dhcpv6SrvTest, vendorOptionsDocsisDefinitions) { diff --git a/src/lib/dhcpsrv/cfg_option.h b/src/lib/dhcpsrv/cfg_option.h index 2e3f78aa6f..3827a7efd1 100644 --- a/src/lib/dhcpsrv/cfg_option.h +++ b/src/lib/dhcpsrv/cfg_option.h @@ -184,6 +184,11 @@ typedef std::pair OptionContainerTypeRange; /// Type of the index #2 - option persistency flag. typedef OptionContainer::nth_index<2>::type OptionContainerPersistIndex; +/// Pair of iterators to represent the range of options having the +/// same persistency flag. The first element in this pair represents +/// the beginning of the range, the second element represents the end. +typedef std::pair OptionContainerPersistRange; /// @brief Represents option data configuration for the DHCP server. /// diff --git a/src/lib/dhcpsrv/tests/cfg_option_unittest.cc b/src/lib/dhcpsrv/tests/cfg_option_unittest.cc index 7a566a243b..8f2f6dfd96 100644 --- a/src/lib/dhcpsrv/tests/cfg_option_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_option_unittest.cc @@ -449,9 +449,7 @@ TEST_F(CfgOptionTest, addNonUniqueOptions) { // Look for the codes 100-109. for (uint16_t code = 100; code < 110; ++ code) { // For each code we should get two instances of options-> - std::pair range = - idx.equal_range(code); + OptionContainerTypeRange range = idx.equal_range(code); // Distance between iterators indicates how many options // have been returned for the particular code. ASSERT_EQ(2, distance(range.first, range.second)); @@ -465,9 +463,7 @@ TEST_F(CfgOptionTest, addNonUniqueOptions) { // Let's try to find some non-exiting option. const uint16_t non_existing_code = 150; - std::pair range = - idx.equal_range(non_existing_code); + OptionContainerTypeRange range = idx.equal_range(non_existing_code); // Empty set is expected. EXPECT_EQ(0, distance(range.first, range.second)); } @@ -501,17 +497,13 @@ TEST(Subnet6Test, addPersistentOption) { OptionContainerPersistIndex& idx = options->get<2>(); // Get all persistent options-> - std::pair range_persistent = - idx.equal_range(true); - // 3 out of 10 options have been flagged persistent. + OptionContainerPersistRange range_persistent = idx.equal_range(true); + // 7 out of 10 options have been flagged persistent. ASSERT_EQ(7, distance(range_persistent.first, range_persistent.second)); // Get all non-persistent options-> - std::pair range_non_persistent = - idx.equal_range(false); - // 7 out of 10 options have been flagged persistent. + OptionContainerPersistRange range_non_persistent = idx.equal_range(false); + // 3 out of 10 options have been flagged not persistent. ASSERT_EQ(3, distance(range_non_persistent.first, range_non_persistent.second)); } diff --git a/src/lib/dhcpsrv/tests/subnet_unittest.cc b/src/lib/dhcpsrv/tests/subnet_unittest.cc index d7a8c97ab9..eb24713d66 100644 --- a/src/lib/dhcpsrv/tests/subnet_unittest.cc +++ b/src/lib/dhcpsrv/tests/subnet_unittest.cc @@ -944,9 +944,7 @@ TEST(Subnet6Test, addNonUniqueOptions) { // Look for the codes 100-109. for (uint16_t code = 100; code < 110; ++ code) { // For each code we should get two instances of options-> - std::pair range = - idx.equal_range(code); + OptionContainerTypeRange range = idx.equal_range(code); // Distance between iterators indicates how many options // have been returned for the particular code. ASSERT_EQ(2, distance(range.first, range.second)); @@ -960,9 +958,7 @@ TEST(Subnet6Test, addNonUniqueOptions) { // Let's try to find some non-exiting option. const uint16_t non_existing_code = 150; - std::pair range = - idx.equal_range(non_existing_code); + OptionContainerTypeRange range = idx.equal_range(non_existing_code); // Empty set is expected. EXPECT_EQ(0, distance(range.first, range.second)); } @@ -994,17 +990,13 @@ TEST(Subnet6Test, addPersistentOption) { OptionContainerPersistIndex& idx = options->get<2>(); // Get all persistent options-> - std::pair range_persistent = - idx.equal_range(true); - // 3 out of 10 options have been flagged persistent. + OptionContainerPersistRange range_persistent = idx.equal_range(true); + // 7 out of 10 options have been flagged persistent. ASSERT_EQ(7, distance(range_persistent.first, range_persistent.second)); // Get all non-persistent options-> - std::pair range_non_persistent = - idx.equal_range(false); - // 7 out of 10 options have been flagged persistent. + OptionContainerPersistRange range_non_persistent = idx.equal_range(false); + // 3 out of 10 options have been flagged not persistent. ASSERT_EQ(3, distance(range_non_persistent.first, range_non_persistent.second)); }