From: Marcin Siodelski Date: Fri, 29 Sep 2017 14:44:02 +0000 (+0200) Subject: [5364] Implemented unit tests for shared network selection by iface id. X-Git-Tag: trac5297_base~6^2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b5c9582a1dcd111846b0073476916e6525f0b1de;p=thirdparty%2Fkea.git [5364] Implemented unit tests for shared network selection by iface id. --- diff --git a/src/bin/dhcp6/tests/dhcp6_client.cc b/src/bin/dhcp6/tests/dhcp6_client.cc index 61cc51fe74..ec3f204be1 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.cc +++ b/src/bin/dhcp6/tests/dhcp6_client.cc @@ -24,6 +24,7 @@ #include #include #include +#include using namespace isc::asiolink; using namespace isc::dhcp; @@ -108,7 +109,8 @@ Dhcp6Client::Dhcp6Client() : use_client_id_(true), use_rapid_commit_(false), client_ias_(), - fqdn_() { + fqdn_(), + interface_id_() { } Dhcp6Client::Dhcp6Client(boost::shared_ptr& srv) : @@ -125,7 +127,8 @@ Dhcp6Client::Dhcp6Client(boost::shared_ptr& srv) : use_client_id_(true), use_rapid_commit_(false), client_ias_(), - fqdn_() { + fqdn_(), + interface_id_() { } void @@ -899,7 +902,14 @@ Dhcp6Client::sendMsg(const Pkt6Ptr& msg) { relay.peeraddr_ = asiolink::IOAddress("fe80::1"); relay.msg_type_ = DHCPV6_RELAY_FORW; relay.hop_count_ = 1; + + // Interface identifier, if specified. + if (interface_id_) { + relay.options_.insert(std::make_pair(D6O_INTERFACE_ID, interface_id_)); + } + msg->relay_info_.push_back(relay); + } else { // The test provided relay_info_, let's use that. msg->relay_info_ = relay_info_; @@ -932,6 +942,12 @@ Dhcp6Client::requestPrefix(const uint32_t iaid, client_ias_.push_back(ClientIA(Lease::TYPE_PD, iaid, prefix, prefix_len)); } +void +Dhcp6Client::useInterfaceId(const std::string& interface_id) { + OptionBuffer buf(interface_id.begin(), interface_id.end()); + interface_id_.reset(new Option(Option::V6, D6O_INTERFACE_ID, buf)); +} + void Dhcp6Client::useFQDN(const uint8_t flags, const std::string& fqdn_name, Option6ClientFqdn::DomainNameType fqdn_type) { diff --git a/src/bin/dhcp6/tests/dhcp6_client.h b/src/bin/dhcp6/tests/dhcp6_client.h index 4d957dc934..b3c41123cf 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.h +++ b/src/bin/dhcp6/tests/dhcp6_client.h @@ -639,6 +639,11 @@ public: relay_link_addr_ = link_addr; } + /// @brief Sets interface id value to be inserted into relay agent option. + /// + /// @param interface_id Value of the interface id as string. + void useInterfaceId(const std::string& interface_id); + /// @brief Controls whether the client should send a client-id or not /// @param send should the client-id be sent? void useClientId(const bool send) { @@ -909,6 +914,9 @@ private: /// @brief FQDN requested by the client. Option6ClientFqdnPtr fqdn_; + + /// @brief Interface id. + OptionPtr interface_id_; }; } // end of namespace isc::dhcp::test diff --git a/src/bin/dhcp6/tests/shared_network_unittest.cc b/src/bin/dhcp6/tests/shared_network_unittest.cc index 8b6e16a92d..bd7c2945cd 100644 --- a/src/bin/dhcp6/tests/shared_network_unittest.cc +++ b/src/bin/dhcp6/tests/shared_network_unittest.cc @@ -741,6 +741,149 @@ const char* NETWORKS_CONFIG[] = { " ]" " }" " ]" + "}", + +// Configuration #13. + "{" + " \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + " }," + " \"preferred-lifetime\": 3000," + " \"rebind-timer\": 2000, " + " \"renew-timer\": 1000, " + " \"shared-networks\": [" + " {" + " \"name\": \"frog\"," + " \"subnet6\": [" + " {" + " \"subnet\": \"2001:db8:1::/64\"," + " \"id\": 10," + " \"relay\": {" + " \"ip-address\": \"3001::1\"" + " }," + " \"pools\": [" + " {" + " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\"" + " }" + " ]" + " }," + " {" + " \"subnet\": \"2001:db8:2::/64\"," + " \"id\": 100," + " \"relay\": {" + " \"ip-address\": \"3001::1\"" + " }," + " \"pools\": [" + " {" + " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\"" + " }" + " ]" + " }" + " ]" + " }" + " ]," + " \"subnet6\": [" + " {" + " \"subnet\": \"2001:db8:3::/64\"," + " \"id\": 1000," + " \"relay\": {" + " \"ip-address\": \"3001::2\"" + " }," + " \"pools\": [" + " {" + " \"pool\": \"2001:db8:3::20 - 2001:db8:3::20\"" + " }" + " ]" + " }" + " ]" + "}", + +// Configuration #14. + "{" + " \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + " }," + " \"preferred-lifetime\": 3000," + " \"rebind-timer\": 2000, " + " \"renew-timer\": 1000, " + " \"shared-networks\": [" + " {" + " \"name\": \"frog\"," + " \"interface-id\": \"vlan10\"," + " \"subnet6\": [" + " {" + " \"subnet\": \"2001:db8:1::/64\"," + " \"id\": 10," + " \"pools\": [" + " {" + " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\"" + " }" + " ]" + " }" + " ]" + " }" + " ]," + " \"subnet6\": [" + " {" + " \"subnet\": \"2001:db8:2::/64\"," + " \"id\": 1000," + " \"interface-id\": \"vlan1000\"," + " \"pools\": [" + " {" + " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\"" + " }" + " ]" + " }" + " ]" + "}", + +// Configuration #15. + "{" + " \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + " }," + " \"preferred-lifetime\": 3000," + " \"rebind-timer\": 2000, " + " \"renew-timer\": 1000, " + " \"shared-networks\": [" + " {" + " \"name\": \"frog\"," + " \"subnet6\": [" + " {" + " \"subnet\": \"2001:db8:1::/64\"," + " \"id\": 10," + " \"interface-id\": \"vlan10\"," + " \"pools\": [" + " {" + " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\"" + " }" + " ]" + " }," + " {" + " \"subnet\": \"2001:db8:2::/64\"," + " \"id\": 10," + " \"interface-id\": \"vlan10\"," + " \"pools\": [" + " {" + " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\"" + " }" + " ]" + " }" + " ]" + " }" + " ]," + " \"subnet6\": [" + " {" + " \"subnet\": \"2001:db8:2::/64\"," + " \"id\": 1000," + " \"interface-id\": \"vlan1000\"," + " \"pools\": [" + " {" + " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\"" + " }" + " ]" + " }" + " ]" "}" }; @@ -1494,11 +1637,86 @@ TEST_F(Dhcpv6SharedNetworkTest, reservedAddressAndPrefix) { ASSERT_NE("1234::", leases_2222[0].addr_.toText()); } -/// @todo: Add a test for relay information specified for shared network. -/// @todo: Add a test for relay information specified on each subnet -/// in a shared network. -/// @todo: Add a test for interface-id specified for shared network. -/// @todo: Add a test for interface-id on each subnet in a shared network. -/// Also, see http://kea.isc.org/ticket/5364 for more ideas. +// Relay address is specified for each subnet within shared network. +TEST_F(Dhcpv6SharedNetworkTest, relaySpecifiedForEachSubnet) { + // Create client. + Dhcp6Client client; + client.useRelay(true, IOAddress("3001::1")); + + // Client will request two addresses. + client.requestAddress(0xabcd); + client.requestAddress(0x1234); + + // Configure the server with three subnets. Two of them belong to a shared network. + // Each subnet is configured with relay info, i.e. IP address of the relay agent + // for which the shared network is used. + ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[13], *client.getServer())); + + // 4-way exchange. + ASSERT_NO_THROW(client.doSARR()); + ASSERT_EQ(2, client.getLeaseNum()); + + // The client should have got two leases, one from each subnet within the + // shared network. + ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::20"))); + ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::20"))); +} + +// Shared network is selected based on interface id. +TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByInterfaceId) { + // Create client #1. This is a relayed client for which interface id + // has been spefified and this interface id is matching the one specified + // for the shared network. + Dhcp6Client client1; + client1.useRelay(true, IOAddress("3001::1")); + client1.useInterfaceId("vlan10"); + + // Configure the server with one shared network and one subnet outside of the + // shared network. + ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[14], *client1.getServer())); + + // Client #1 should be assigned an address from shared network. + ASSERT_NO_THROW(client1.requestAddress(0xabca0)); + ASSERT_NO_THROW(client1.doSARR()); + ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); + + // Create client #2. This is a relayed client which is using interface id + // matching a subnet outside of the shared network. + Dhcp6Client client2(client1.getServer()); + client2.useRelay(true, IOAddress("3001::2")); + client2.useInterfaceId("vlan1000"); + ASSERT_NO_THROW(client2.requestAddress(0xabca0)); + ASSERT_NO_THROW(client2.doSARR()); + ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20"))); +} + +// Shared network is selected based on interface id specified for a subnet +// belonging to a shared network. +TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByInterfaceIdInSubnet) { + // Create client #1. This is a relayed client for which interface id + // has been spefified and this interface id is matching the one specified + // for the shared network. + Dhcp6Client client1; + client1.useRelay(true, IOAddress("3001::1")); + client1.useInterfaceId("vlan10"); + + // Configure the server with one shared network and one subnet outside of the + // shared network. + ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[15], *client1.getServer())); + + // Client #1 should be assigned an address from shared network. + ASSERT_NO_THROW(client1.requestAddress(0xabca0)); + ASSERT_NO_THROW(client1.doSARR()); + ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20"))); + + // Create client #2. This is a relayed client which is using interface id + // matching a subnet outside of the shared network. + Dhcp6Client client2(client1.getServer()); + client2.useRelay(true, IOAddress("3001::2")); + client2.useInterfaceId("vlan1000"); + ASSERT_NO_THROW(client2.requestAddress(0xabca0)); + ASSERT_NO_THROW(client2.doSARR()); + ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20"))); +} } // end of anonymous namespace