Browse Source

[5364] Implemented unit tests for shared network selection by iface id.

Marcin Siodelski 7 years ago
parent
commit
b5c9582a1d

+ 18 - 2
src/bin/dhcp6/tests/dhcp6_client.cc

@@ -24,6 +24,7 @@
 #include <algorithm>
 #include <cstdlib>
 #include <time.h>
+#include <utility>
 
 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<NakedDhcpv6Srv>& srv) :
@@ -125,7 +127,8 @@ Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& 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_;
@@ -933,6 +943,12 @@ Dhcp6Client::requestPrefix(const uint32_t iaid,
 }
 
 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) {
     fqdn_.reset(new Option6ClientFqdn(flags, fqdn_name, fqdn_type));

+ 8 - 0
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

+ 224 - 6
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