From: Marcin Siodelski Date: Mon, 23 Sep 2013 11:43:02 +0000 (+0200) Subject: [3173] It is possible to request IA_NA and IA_PD in a single message. X-Git-Tag: bind10-1.2.0beta1-release~201^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ef4ae0b32f759f25ba8fc20f1213406115fc6502;p=thirdparty%2Fkea.git [3173] It is possible to request IA_NA and IA_PD in a single message. --- diff --git a/tests/tools/perfdhcp/command_options.cc b/tests/tools/perfdhcp/command_options.cc index 34c0eaa5af..f23a4338e8 100644 --- a/tests/tools/perfdhcp/command_options.cc +++ b/tests/tools/perfdhcp/command_options.cc @@ -45,6 +45,11 @@ CommandOptions::LeaseType::is(const Type lease_type) const { return (lease_type == type_); } +bool +CommandOptions::LeaseType::includes(const Type lease_type) const { + return (is(ADDRESS_AND_PREFIX) || (lease_type == type_)); +} + void CommandOptions::LeaseType::set(const Type lease_type) { type_ = lease_type; @@ -58,6 +63,9 @@ CommandOptions::LeaseType::fromCommandLine(const std::string& cmd_line_arg) { } else if (cmd_line_arg == "prefix-only") { type_ = PREFIX_ONLY; + } else if (cmd_line_arg == "address-and-prefix") { + type_ = ADDRESS_AND_PREFIX; + } else { isc_throw(isc::InvalidParameter, "value of lease-type: -e," " must be one of the following: 'address-only' or" @@ -72,6 +80,9 @@ CommandOptions::LeaseType::toText() const { return ("address-only (IA_NA option added to the client's request)"); case PREFIX_ONLY: return ("prefix-only (IA_PD option added to the client's request)"); + case ADDRESS_AND_PREFIX: + return ("address-and-prefix (Both IA_NA and IA_PD options added to the" + " client's request)"); default: isc_throw(Unexpected, "internal error: undefined lease type code when" " returning textual representation of the lease type"); @@ -903,10 +914,13 @@ CommandOptions::usage() const { " having been lost. The value is given in seconds and may contain a\n" " fractional component. The default is 1 second.\n" "-e: A type of lease being requested from the server. It\n" - " may be one of the following: address-only or prefix-only. The\n" - " former indicates that the regular IP (v4 or v6) will be requested,\n" - " the latter indicates that the IPv6 prefixes will be requested. The\n" - " '-e prefix-only' must not be used with -4.\n" + " may be one of the following: address-only, prefix-only or\n" + " address-and-prefix. The address-only indicates that the regular\n" + " address (v4 or v6) will be requested. The prefix-only indicates\n" + " that the IPv6 prefix will be requested. The address-and-prefix\n" + " indicates that both IPv6 address and prefix will be requested.\n" + " The '-e prefix-only' and -'e address-and-prefix' must not be\n" + " used with -4.\n" "-E: Offset of the (DHCPv4) secs field / (DHCPv6)\n" " elapsed-time option in the (second/request) template.\n" " The value 0 disables it.\n" diff --git a/tests/tools/perfdhcp/command_options.h b/tests/tools/perfdhcp/command_options.h index 4a10a18b15..242d1a5f98 100644 --- a/tests/tools/perfdhcp/command_options.h +++ b/tests/tools/perfdhcp/command_options.h @@ -43,7 +43,8 @@ public: /// The lease type code. enum Type { ADDRESS_ONLY, - PREFIX_ONLY + PREFIX_ONLY, + ADDRESS_AND_PREFIX }; LeaseType(); @@ -60,6 +61,23 @@ public: /// \return true if lease type is matched with the specified code. bool is(const Type lease_type) const; + /// \brief Checks if lease type implies request for the address, + /// prefix (or both) as specified by the function argument. + /// + /// This is a convenience function to check that, for the lease type + /// specified from the command line, the address or prefix + /// (IA_NA or IA_PD) option should be sent to the server. + /// For example, if user specified '-e address-and-prefix' in the + /// command line this function will return true for both ADDRESS_ONLY + /// and PREFIX_ONLY, because both address and prefix is requested from + /// the server. + /// + /// \param lease_type A lease type. + /// + /// \return true if the lease type implies creation of the address, + /// prefix or both as specified by the argument. + bool includes(const Type lease_type) const; + /// \brief Sets the lease type code. /// /// \param lease_type A lease type code. diff --git a/tests/tools/perfdhcp/test_control.cc b/tests/tools/perfdhcp/test_control.cc index 7fc1a7733a..acbc619751 100644 --- a/tests/tools/perfdhcp/test_control.cc +++ b/tests/tools/perfdhcp/test_control.cc @@ -103,22 +103,27 @@ TestControl::copyIaOptions(const Pkt6Ptr& pkt_from, Pkt6Ptr& pkt_to) { isc_throw(BadValue, "NULL pointers must not be specified as arguments" " for the copyIaOptions function"); } - OptionPtr option; + // IA_NA if (CommandOptions::instance().getLeaseType() - .is(CommandOptions::LeaseType::ADDRESS_ONLY)) { - option = pkt_from->getOption(D6O_IA_NA); + .includes(CommandOptions::LeaseType::ADDRESS_ONLY)) { + OptionPtr option = pkt_from->getOption(D6O_IA_NA); if (!option) { isc_throw(OptionNotFound, "IA_NA option not found in the" " server's response"); } - } else { - option = pkt_from->getOption(D6O_IA_PD); + pkt_to->addOption(option); + } + // IA_PD + if (CommandOptions::instance().getLeaseType() + .includes(CommandOptions::LeaseType::PREFIX_ONLY)) { + OptionPtr option = pkt_from->getOption(D6O_IA_PD); if (!option) { isc_throw(OptionNotFound, "IA_PD option not found in the" " server's response"); } + pkt_to->addOption(option); } - pkt_to->addOption(option); + } @@ -635,15 +640,15 @@ TestControl::openSocket() const { uint16_t port = options.getLocalPort(); int sock = 0; - uint8_t family = (options.getIpVersion() == 6) ? AF_INET6 : AF_INET; + uint8_t family = (options.getIpVersion() == 6) ? AF_INET6 : AF_INET; IOAddress remoteaddr(servername); - + // Check for mismatch between IP option and server address if (family != remoteaddr.getFamily()) { - isc_throw(InvalidParameter, - "Values for IP version: " << + isc_throw(InvalidParameter, + "Values for IP version: " << static_cast(options.getIpVersion()) << - " and server address: " << servername << " are mismatched."); + " and server address: " << servername << " are mismatched."); } if (port == 0) { @@ -1780,11 +1785,16 @@ TestControl::sendSolicit6(const TestControlSocket& socket, pkt6->addOption(Option::factory(Option::V6, D6O_ORO)); // Depending on the lease-type option specified, we should request - // IPv6 address (with IA_NA) or IPv6 prefix (IA_PD). + // IPv6 address (with IA_NA) or IPv6 prefix (IA_PD) or both. + + // IA_NA if (CommandOptions::instance().getLeaseType() - .is(CommandOptions::LeaseType::ADDRESS_ONLY)) { + .includes(CommandOptions::LeaseType::ADDRESS_ONLY)) { pkt6->addOption(Option::factory(Option::V6, D6O_IA_NA)); - } else { + } + // IA_PD + if (CommandOptions::instance().getLeaseType() + .includes(CommandOptions::LeaseType::PREFIX_ONLY)) { pkt6->addOption(Option::factory(Option::V6, D6O_IA_PD)); } diff --git a/tests/tools/perfdhcp/tests/command_options_unittest.cc b/tests/tools/perfdhcp/tests/command_options_unittest.cc index 0fa100194a..3b14527d78 100644 --- a/tests/tools/perfdhcp/tests/command_options_unittest.cc +++ b/tests/tools/perfdhcp/tests/command_options_unittest.cc @@ -52,6 +52,33 @@ TEST(LeaseTypeTest, set) { EXPECT_TRUE(lease_type.is(CommandOptions::LeaseType::PREFIX_ONLY)); } +TEST(LeaseTypeTest, includes) { + CommandOptions::LeaseType + lease_type(CommandOptions::LeaseType::ADDRESS_ONLY); + ASSERT_TRUE(lease_type.is(CommandOptions::LeaseType::ADDRESS_ONLY)); + EXPECT_TRUE(lease_type.includes(CommandOptions::LeaseType::ADDRESS_ONLY)); + EXPECT_FALSE(lease_type.includes(CommandOptions::LeaseType::PREFIX_ONLY)); + EXPECT_FALSE( + lease_type.includes(CommandOptions::LeaseType::ADDRESS_AND_PREFIX) + ); + + lease_type.set(CommandOptions::LeaseType::PREFIX_ONLY); + EXPECT_FALSE(lease_type.includes(CommandOptions::LeaseType::ADDRESS_ONLY)); + EXPECT_TRUE(lease_type.includes(CommandOptions::LeaseType::PREFIX_ONLY)); + EXPECT_FALSE( + lease_type.includes(CommandOptions::LeaseType::ADDRESS_AND_PREFIX) + ); + + lease_type.set(CommandOptions::LeaseType::ADDRESS_AND_PREFIX); + EXPECT_TRUE(lease_type.includes(CommandOptions::LeaseType::ADDRESS_ONLY)); + EXPECT_TRUE(lease_type.includes(CommandOptions::LeaseType::PREFIX_ONLY)); + EXPECT_TRUE( + lease_type.includes(CommandOptions::LeaseType::ADDRESS_AND_PREFIX) + ); + +} + + TEST(LeaseTypeTest, fromCommandLine) { CommandOptions::LeaseType lease_type(CommandOptions::LeaseType::ADDRESS_ONLY); diff --git a/tests/tools/perfdhcp/tests/test_control_unittest.cc b/tests/tools/perfdhcp/tests/test_control_unittest.cc index ea9aac2cd0..5f7ecd518c 100644 --- a/tests/tools/perfdhcp/tests/test_control_unittest.cc +++ b/tests/tools/perfdhcp/tests/test_control_unittest.cc @@ -524,7 +524,8 @@ public: /* ASSERT_NO_THROW(tc.processReceivedPacket6(sock, advertise_pkt6)); */ try { - tc.processReceivedPacket6(sock, advertise_pkt6); + tc.processReceivedPacket6(sock, + advertise_pkt6); } catch (const Exception& ex) { std::cout << ex.what() << std::endl; } @@ -652,20 +653,24 @@ private: /// \return instance of the packet. boost::shared_ptr createAdvertisePkt6(uint32_t transid) const { - OptionPtr opt_ia; + boost::shared_ptr advertise(new Pkt6(DHCPV6_ADVERTISE, transid)); + // Add IA_NA if requested by the client. + if (CommandOptions::instance().getLeaseType() + .includes(CommandOptions::LeaseType::ADDRESS_ONLY)) { + OptionPtr opt_ia_na = Option::factory(Option::V6, D6O_IA_NA); + advertise->addOption(opt_ia_na); + } + // Add IA_PD if requested by the client. if (CommandOptions::instance().getLeaseType() - .is(CommandOptions::LeaseType::ADDRESS_ONLY)) { - opt_ia = Option::factory(Option::V6, D6O_IA_NA); - } else { - opt_ia = Option::factory(Option::V6, D6O_IA_PD); + .includes(CommandOptions::LeaseType::PREFIX_ONLY)) { + OptionPtr opt_ia_pd = Option::factory(Option::V6, D6O_IA_PD); + advertise->addOption(opt_ia_pd); } OptionPtr opt_serverid(new Option(Option::V6, D6O_SERVERID)); NakedTestControl tc; uint8_t randomized = 0; std::vector duid(tc.generateDuid(randomized)); OptionPtr opt_clientid(Option::factory(Option::V6, D6O_CLIENTID, duid)); - boost::shared_ptr advertise(new Pkt6(DHCPV6_ADVERTISE, transid)); - advertise->addOption(opt_ia); advertise->addOption(opt_serverid); advertise->addOption(opt_clientid); advertise->updateTimestamp(); @@ -1041,6 +1046,32 @@ TEST_F(TestControlTest, Packet6ExchangePrefixDelegation) { EXPECT_EQ(10, iterations_performed); } +TEST_F(TestControlTest, Packet6ExchangeAddressAndPrefix) { + // Get the local loopback interface to open socket on + // it and test packets exchanges. We don't want to fail + // the test if interface is not available. + std::string loopback_iface(getLocalLoopback()); + if (loopback_iface.empty()) { + std::cout << "Unable to find the loopback interface. Skip test." + << std::endl; + return; + } + + const int iterations_num = 100; + // Set number of iterations to 10. + processCmdLine("perfdhcp -l " + loopback_iface + + " -e address-and-prefix" + + " -6 -r 100 -n 10 -R 20 -L 10547 ::1"); + int iterations_performed = 0; + // Set number of received packets equal to number of iterations. + // This simulates no packet drops. + bool use_templates = false; + testPkt6Exchange(iterations_num, iterations_num, use_templates, + iterations_performed); + // Actual number of iterations should be 10. + EXPECT_EQ(10, iterations_performed); +} + TEST_F(TestControlTest, PacketTemplates) { std::vector template1(256); std::string file1("test1.hex");