]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#553] Checkpoint: convert to use interface indexes
authorFrancis Dupont <fdupont@isc.org>
Sun, 24 May 2020 18:49:39 +0000 (20:49 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 7 Jul 2020 10:47:26 +0000 (12:47 +0200)
28 files changed:
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/tests/dhcp4_client.cc
src/bin/dhcp4/tests/dhcp4_client.h
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
src/bin/dhcp4/tests/dhcp4_test_utils.cc
src/bin/dhcp4/tests/dhcp4to6_ipc_unittest.cc
src/bin/dhcp4/tests/direct_client_unittest.cc
src/bin/dhcp4/tests/dora_unittest.cc
src/bin/dhcp4/tests/fqdn_unittest.cc
src/bin/dhcp4/tests/hooks_unittest.cc
src/bin/dhcp4/tests/host_unittest.cc
src/bin/dhcp4/tests/shared_network_unittest.cc
src/bin/dhcp4/tests/vendor_opts_unittest.cc
src/bin/dhcp6/tests/classify_unittests.cc
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/dhcp6_test_utils.cc
src/bin/dhcp6/tests/dhcp6_test_utils.h
src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc
src/bin/dhcp6/tests/fqdn_unittest.cc
src/bin/dhcp6/tests/hooks_unittest.cc
src/bin/dhcp6/tests/vendor_opts_unittest.cc
src/lib/dhcp/iface_mgr.cc
src/lib/dhcp/iface_mgr.h
src/lib/dhcp/iface_mgr_linux.cc
src/lib/dhcp/pkt_filter_inet6.cc
src/lib/dhcp/tests/iface_mgr_test_config.h
src/lib/dhcp/tests/iface_mgr_unittest.cc
src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc

index 3b68112b871e1c8310e18a6993fa2cb06918ce6b..d800f21925d41cfcac96d1c544465c31bfecedf6 100644 (file)
@@ -1601,8 +1601,7 @@ Dhcpv4Srv::appendServerID(Dhcpv4Exchange& ex) {
     Pkt4Ptr query = ex.getQuery();
 
     if (local_addr.isV4Bcast() || query->isDhcp4o6()) {
-        SocketInfo sock_info = IfaceMgr::instance().getSocket(*query);
-        local_addr = sock_info.addr_;
+        local_addr = IfaceMgr::instance().getSocket(query).addr_;
     }
 
     OptionPtr opt_srvid(new Option4AddrLst(DHO_DHCP_SERVER_IDENTIFIER,
@@ -2697,8 +2696,7 @@ Dhcpv4Srv::adjustIfaceData(Dhcpv4Exchange& ex) {
         // use this address as a source address for the response.
         // Do the same for DHCPv4-over-DHCPv6 exchanges.
         if (local_addr.isV4Bcast() || query->isDhcp4o6()) {
-            SocketInfo sock_info = IfaceMgr::instance().getSocket(*query);
-            local_addr = sock_info.addr_;
+            local_addr = IfaceMgr::instance().getSocket(query).addr_;
         }
 
         // We assume that there is an appropriate socket bound to this address
index b7e861d99eefe6bc948c871c88c93633b6ea02b1..38290bda922210a2115a2f8ba4a0e6300e90fbbc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2020 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
@@ -9,6 +9,7 @@
 #include <dhcp/option.h>
 #include <dhcp/option_int_array.h>
 #include <dhcp/option_vendor.h>
+#include <dhcp/tests/iface_mgr_test_config.h>
 #include <dhcpsrv/lease.h>
 #include <dhcp4/tests/dhcp4_client.h>
 #include <util/range_utilities.h>
@@ -23,7 +24,7 @@ namespace test {
 
 Dhcp4Client::Configuration::Configuration()
     : routers_(), dns_servers_(), log_servers_(), quotes_servers_(),
-      serverid_("0.0.0.0"), siaddr_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()) {
+      serverid_("0.0.0.0"), siaddr_(IOAddress::IPV4_ZERO_ADDRESS()) {
     reset();
 }
 
@@ -33,8 +34,8 @@ Dhcp4Client::Configuration::reset() {
     dns_servers_.clear();
     log_servers_.clear();
     quotes_servers_.clear();
-    serverid_ = asiolink::IOAddress("0.0.0.0");
-    siaddr_ = asiolink::IOAddress::IPV4_ZERO_ADDRESS();
+    serverid_ = IOAddress("0.0.0.0");
+    siaddr_ = IOAddress::IPV4_ZERO_ADDRESS();
     sname_.clear();
     boot_file_name_.clear();
     lease_ = Lease4();
@@ -48,6 +49,7 @@ Dhcp4Client::Dhcp4Client(const Dhcp4Client::State& state) :
     hwaddr_(generateHWAddr()),
     clientid_(),
     iface_name_("eth0"),
+    iface_index_(ETH0_INDEX),
     relay_addr_("192.0.2.2"),
     requested_options_(),
     server_facing_relay_addr_("10.0.0.2"),
@@ -67,6 +69,7 @@ Dhcp4Client::Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv> srv,
     hwaddr_(generateHWAddr()),
     clientid_(),
     iface_name_("eth0"),
+    iface_index_(ETH0_INDEX),
     relay_addr_("192.0.2.2"),
     requested_options_(),
     server_facing_relay_addr_("10.0.0.2"),
@@ -77,7 +80,7 @@ Dhcp4Client::Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv> srv,
 }
 
 void
-Dhcp4Client::addRequestedAddress(const asiolink::IOAddress& addr) {
+Dhcp4Client::addRequestedAddress(const IOAddress& addr) {
     if (context_.query_) {
         Option4AddrLstPtr opt(new Option4AddrLst(DHO_DHCP_REQUESTED_ADDRESS,
                                                  addr));
@@ -213,8 +216,7 @@ Dhcp4Client::applyConfiguration() {
 }
 
 void
-Dhcp4Client::createLease(const asiolink::IOAddress& addr,
-                         const uint32_t valid_lft) {
+Dhcp4Client::createLease(const IOAddress& addr, const uint32_t valid_lft) {
     Lease4 lease(addr, hwaddr_, 0, 0, valid_lft,
                  time(NULL), 0, false, false, "");
     config_.lease_ = lease;
@@ -540,6 +542,7 @@ Dhcp4Client::sendMsg(const Pkt4Ptr& msg) {
     msg_copy->setRemoteAddr(msg->getLocalAddr());
     msg_copy->setLocalAddr(dest_addr_);
     msg_copy->setIface(iface_name_);
+    msg_copy->setIndex(iface_index_);
     // Copy classes
     const ClientClasses& classes = msg->getClasses();
     for (ClientClasses::const_iterator cclass = classes.cbegin();
index e4e939cbbb339b68b5d82387c78ab06d30413d08..a7265a43ad9af306f1a5d3cfeb38f2a5e0f031f3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2020 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
@@ -337,6 +337,14 @@ public:
         iface_name_ = iface_name;
     }
 
+    /// @brief Sets the interface over which the messages should be sent.
+    ///
+    /// @param iface_index Index of the interface over which the
+    /// messages should be sent.
+    void setIfaceIndex(uint32_t iface_index) {
+        iface_index_ = iface_index;
+    }
+
     /// @brief Sets client state.
     ///
     /// Depending on the current state the client's behavior is different
@@ -483,9 +491,12 @@ private:
     /// @brief Current client identifier.
     ClientIdPtr clientid_;
 
-    /// @brief Interface to be used to send the messages.
+    /// @brief Interface to be used to send the messages (name).
     std::string iface_name_;
 
+    /// @brief Interface to be used to send the messages (index).
+    uint32_t iface_index_;
+
     /// @brief Relay address to use.
     asiolink::IOAddress relay_addr_;
 
index 1e4b9d6d4c3247ee0cecfd5712d9e8168f0c768c..9df9fef14fad22699db11e1cdf49684efb451a18 100644 (file)
@@ -159,7 +159,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) {
     req->setLocalAddr(IOAddress("192.0.2.5"));
     req->setLocalPort(1001);
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
 
     // Set remote port (it will be used in the next test).
     req->setRemotePort(1234);
@@ -188,7 +188,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) {
     // We will send response over the same interface which was used to receive
     // query.
     EXPECT_EQ("eth1", resp->getIface());
-    EXPECT_EQ(1, resp->getIndex());
+    EXPECT_EQ(ETH1_INDEX, resp->getIndex());
 
     // Let's do another test and set other fields: ciaddr and
     // flags. By doing it, we want to make sure that the relay
@@ -239,7 +239,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelayPort) {
     req->setLocalAddr(IOAddress("192.0.2.5"));
     req->setLocalPort(1001);
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
 
     // Set remote port.
     req->setRemotePort(1234);
@@ -283,7 +283,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelayPort) {
     // We will send response over the same interface which was used to receive
     // query.
     EXPECT_EQ("eth1", resp->getIface());
-    EXPECT_EQ(1, resp->getIndex());
+    EXPECT_EQ(ETH1_INDEX, resp->getIndex());
 }
 
 // This test verifies that it is possible to configure the server to use
@@ -321,7 +321,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataUseRouting) {
     req->setLocalAddr(IOAddress("192.0.2.5"));
     req->setLocalPort(1001);
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
 
     // Create the exchange using the req.
     Dhcpv4Exchange ex = createExchange(req);
@@ -367,7 +367,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataUseRouting) {
 
     EXPECT_EQ("192.0.2.5", resp->getLocalAddr().toText());
     EXPECT_EQ("eth1", resp->getIface());
-    EXPECT_EQ(1, resp->getIndex());
+    EXPECT_EQ(ETH1_INDEX, resp->getIndex());
 }
 
 // This test verifies that the destination address of the response
@@ -393,7 +393,7 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressRelaySendToSourceTestingModeEnabled) {
     req->setLocalAddr(IOAddress("192.0.2.5"));
     req->setLocalPort(1001);
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
 
     // Set remote address and port.
     req->setRemoteAddr(IOAddress("192.0.2.1"));
@@ -451,7 +451,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRenew) {
     req->setLocalPort(DHCP4_SERVER_PORT);
     // Set the interface. The response should be sent over the same interface.
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
 
     // Create the exchange using the req.
     Dhcpv4Exchange ex = createExchange(req);
@@ -481,8 +481,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRenew) {
     EXPECT_EQ(DHCP4_SERVER_PORT, resp->getLocalPort());
     // The interface data should match the data in the query.
     EXPECT_EQ("eth1", resp->getIface());
-    EXPECT_EQ(1, resp->getIndex());
-
+    EXPECT_EQ(ETH1_INDEX, resp->getIndex());
 }
 
 // This test verifies that the destination address of the response message
@@ -516,7 +515,7 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressRenewSendToSourceTestingModeEnabled) {
     req->setLocalPort(DHCP4_SERVER_PORT);
     // Set the interface. The response should be sent over the same interface.
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
     // Set remote address.
     req->setRemoteAddr(IOAddress("192.0.2.1"));
 
@@ -573,7 +572,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataSelect) {
     req->setLocalPort(DHCP4_SERVER_PORT);
     // Set the interface. The response should be sent via the same interface.
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
 
     // Create the exchange using the req.
     Dhcpv4Exchange ex = createExchange(req);
@@ -586,7 +585,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataSelect) {
     resp->setHops(req->getHops());
 
     // We want to test the case, when the server (packet filter) doesn't support
-    // ddirect responses to the client which doesn't have an address yet. In
+    // direct responses to the client which doesn't have an address yet. In
     // case, the server should send its response to the broadcast address.
     // We can control whether the current packet filter returns that its support
     // direct responses or not.
@@ -615,7 +614,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataSelect) {
     // The response should be sent via the same interface through which
     // query has been received.
     EXPECT_EQ("eth1", resp->getIface());
-    EXPECT_EQ(1, resp->getIndex());
+    EXPECT_EQ(ETH1_INDEX, resp->getIndex());
 
     // We also want to test the case when the server has capability to
     // respond directly to the client which is not configured. Server
@@ -658,7 +657,7 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressSelectSendToSourceTestingModeEnabled) {
     req->setLocalPort(DHCP4_SERVER_PORT);
     // Set the interface. The response should be sent via the same interface.
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
     // Set remote address.
     req->setRemoteAddr(IOAddress("192.0.2.1"));
 
@@ -717,7 +716,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataBroadcast) {
     req->setLocalPort(DHCP4_SERVER_PORT);
     // Set the interface. The response should be sent via the same interface.
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
 
     // Let's set the broadcast flag.
     req->setFlags(Pkt4::FLAG_BROADCAST_MASK);
@@ -749,7 +748,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataBroadcast) {
     // The response should be sent via the same interface through which
     // query has been received.
     EXPECT_EQ("eth1", resp->getIface());
-    EXPECT_EQ(1, resp->getIndex());
+    EXPECT_EQ(ETH1_INDEX, resp->getIndex());
 
 }
 
@@ -773,7 +772,7 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressBroadcastSendToSourceTestingModeEnabled
     req->setLocalPort(DHCP4_SERVER_PORT);
     // Set the interface. The response should be sent via the same interface.
     req->setIface("eth1");
-    req->setIndex(1);
+    req->setIndex(ETH1_INDEX);
     // Set remote address.
     req->setRemoteAddr(IOAddress("192.0.2.1"));
 
@@ -1186,6 +1185,7 @@ TEST_F(Dhcpv4SrvTest, DiscoverBasic) {
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
 
     // Pass it to the server and get an offer
     Pkt4Ptr offer = srv->processDiscover(dis);
@@ -1253,6 +1253,7 @@ TEST_F(Dhcpv4SrvTest, DiscoverValidLifetime) {
         OptionPtr clientid = generateClientId();
         dis->addOption(clientid);
         dis->setIface("eth1");
+        dis->setIndex(ETH1_INDEX);
 
         // Add dhcp-lease-time option.
         if (test.hint) {
@@ -1405,6 +1406,7 @@ TEST_F(Dhcpv4SrvTest, DiscoverTimers) {
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
 
     // Iterate over the test scenarios.
     for (auto test = tests.begin(); test != tests.end(); ++test) {
@@ -1521,6 +1523,7 @@ TEST_F(Dhcpv4SrvTest, calculateTeeTimers) {
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
 
     // Iterate over the test scenarios.
     for (auto test = tests.begin(); test != tests.end(); ++test) {
@@ -1593,6 +1596,7 @@ TEST_F(Dhcpv4SrvTest, DiscoverInvalidHint) {
     dis->addOption(clientid);
     dis->setYiaddr(hint);
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
 
     // Pass it to the server and get an offer
     Pkt4Ptr offer = srv->processDiscover(dis);
@@ -1638,8 +1642,11 @@ TEST_F(Dhcpv4SrvTest, ManyDiscovers) {
 
     // Assign interfaces
     dis1->setIface("eth1");
+    dis1->setIndex(ETH1_INDEX);
     dis2->setIface("eth1");
+    dis2->setIndex(ETH1_INDEX);
     dis3->setIface("eth1");
+    dis3->setIndex(ETH1_INDEX);
 
     // Different client-id sizes
     OptionPtr clientid1 = generateClientId(4); // length 4
@@ -1700,6 +1707,7 @@ TEST_F(Dhcpv4SrvTest, discoverEchoClientId) {
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
 
     // Pass it to the server and get an offer
     Pkt4Ptr offer = srv.processDiscover(dis);
@@ -1736,6 +1744,7 @@ TEST_F(Dhcpv4SrvTest, RequestNoTimers) {
     OptionPtr clientid = generateClientId();
     req->addOption(clientid);
     req->setIface("eth1");
+    req->setIndex(ETH1_INDEX);
 
     // Recreate a subnet but set T1 and T2 to "unspecified".
     subnet_.reset(new Subnet4(IOAddress("192.0.2.0"), 24,
@@ -1775,6 +1784,7 @@ TEST_F(Dhcpv4SrvTest, requestEchoClientId) {
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
 
     // Pass it to the server and get ACK
     Pkt4Ptr ack = srv.processRequest(dis);
@@ -1848,6 +1858,7 @@ TEST_F(Dhcpv4SrvTest, RenewBasic) {
     req->setYiaddr(addr);
     req->setCiaddr(addr); // client's address
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     req->setHWAddr(hwaddr2);
 
     req->addOption(clientid);
@@ -1940,6 +1951,7 @@ void prepare(struct ctx& c) {
     c.req->setYiaddr(c.addr);
     c.req->setCiaddr(c.addr); // client's address
     c.req->setIface("eth0");
+    c.req->setIndex(ETH0_INDEX);
     c.req->setHWAddr(c.hwaddr);
 
     c.req->addOption(c.clientid);
@@ -2438,6 +2450,7 @@ TEST_F(Dhcpv4SrvTest, siaddrDefault) {
     dis->addOption(clientid);
     dis->setYiaddr(hint);
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
 
     // Pass it to the server and get an offer
     Pkt4Ptr offer = srv->processDiscover(dis);
@@ -2462,6 +2475,7 @@ TEST_F(Dhcpv4SrvTest, siaddr) {
     Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
 
@@ -2519,6 +2533,7 @@ TEST_F(Dhcpv4SrvTest, nextServerOverride) {
     Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
 
@@ -2580,6 +2595,7 @@ TEST_F(Dhcpv4SrvTest, nextServerGlobal) {
     Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setIface("eth1");
+    dis->setIndex(ETH1_INDEX);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
 
@@ -2601,8 +2617,6 @@ TEST_F(Dhcpv4SrvTest, nextServerGlobal) {
     EXPECT_EQ(0, std::memcmp(filename_buf, &offer->getFile()[0], Pkt4::MAX_FILE_LEN));
 }
 
-
-
 // Checks if client packets are classified properly using match expressions.
 TEST_F(Dhcpv4SrvTest, matchClassification) {
     IfaceMgrTestConfig test_config(true);
@@ -2645,14 +2659,17 @@ TEST_F(Dhcpv4SrvTest, matchClassification) {
     query1->setRemoteAddr(IOAddress("192.0.2.1"));
     query1->addOption(clientid);
     query1->setIface("eth1");
+    query1->setIndex(ETH1_INDEX);
     Pkt4Ptr query2(new Pkt4(DHCPDISCOVER, 1234));
     query2->setRemoteAddr(IOAddress("192.0.2.1"));
     query2->addOption(clientid);
     query2->setIface("eth1");
+    query2->setIndex(ETH1_INDEX);
     Pkt4Ptr query3(new Pkt4(DHCPDISCOVER, 1234));
     query3->setRemoteAddr(IOAddress("192.0.2.1"));
     query3->addOption(clientid);
     query3->setIface("eth1");
+    query3->setIndex(ETH1_INDEX);
 
     // Create and add a PRL option to the first 2 queries
     OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -2840,6 +2857,7 @@ TEST_F(Dhcpv4SrvTest, subnetClassPriority) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a PRL option to the query
     OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -2913,6 +2931,7 @@ TEST_F(Dhcpv4SrvTest, subnetGlobalPriority) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a PRL option to the query
     OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -2985,6 +3004,7 @@ TEST_F(Dhcpv4SrvTest, classGlobalPriority) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a PRL option to the query
     OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -3067,6 +3087,7 @@ TEST_F(Dhcpv4SrvTest, classGlobalPersistency) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Do not add a PRL
     OptionPtr prl = query->getOption(DHO_DHCP_PARAMETER_REQUEST_LIST);
@@ -3131,6 +3152,7 @@ TEST_F(Dhcpv4SrvTest, clientClassify) {
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setCiaddr(IOAddress("192.0.2.1"));
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
 
@@ -3199,6 +3221,7 @@ TEST_F(Dhcpv4SrvTest, clientPoolClassify) {
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setCiaddr(IOAddress("192.0.2.1"));
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
 
@@ -3266,6 +3289,7 @@ TEST_F(Dhcpv4SrvTest, clientPoolClassifyKnown) {
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setCiaddr(IOAddress("192.0.2.1"));
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
 
@@ -3321,6 +3345,7 @@ TEST_F(Dhcpv4SrvTest, clientPoolClassifyUnknown) {
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setCiaddr(IOAddress("192.0.2.1"));
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
 
@@ -3384,6 +3409,7 @@ TEST_F(Dhcpv4SrvTest, privateOption) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a private option with code 234
     OptionBuffer buf;
@@ -3453,6 +3479,7 @@ TEST_F(Dhcpv4SrvTest, prlPersistency) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a PRL option for another option
     OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -3537,6 +3564,7 @@ TEST_F(Dhcpv4SrvTest, relayOverride) {
     Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
     dis->setHops(1);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
@@ -3622,6 +3650,7 @@ TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) {
     Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
     dis->setHops(1);
     dis->setGiaddr(IOAddress("192.0.5.1"));
     OptionPtr clientid = generateClientId();
@@ -3685,6 +3714,7 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) {
     Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
     dis->setHops(1);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
@@ -3803,6 +3833,7 @@ TEST_F(Dhcpv4SrvTest, subnetSelect) {
     Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
     dis->setHops(1);
     OptionPtr clientid = generateClientId();
     dis->addOption(clientid);
@@ -3867,6 +3898,7 @@ TEST_F(Dhcpv4SrvTest, acceptDirectRequest) {
     pkt->setRemoteAddr(IOAddress("0.0.0.0"));
     pkt->setLocalAddr(IOAddress("192.0.2.3"));
     pkt->setIface("eth1");
+    pkt->setIndex(ETH1_INDEX);
     EXPECT_TRUE(srv.accept(pkt));
 
     // Let's set hops and check that the message is still accepted as
@@ -3892,6 +3924,7 @@ TEST_F(Dhcpv4SrvTest, acceptDirectRequest) {
     // For eth0, there is no subnet configured. Such message is expected
     // to be silently dropped.
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     EXPECT_FALSE(srv.accept(pkt));
 
     // But, if the message is unicast it should be accepted, even though
index 74476abf531efeea7bcad6958435a4f164a1ba01..717fba052368e93378d446b47f2581a0e95600ff 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2020 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
@@ -483,9 +483,8 @@ Dhcpv4SrvTest::testDiscoverRequest(const uint8_t msg_type) {
     boost::shared_ptr<Pkt4> rsp;
     // Set the name of the interface on which packet is received.
     req->setIface("eth0");
-    // Set the interface index. It is just a dummy value and will
-    // not be interpreted.
-    req->setIndex(17);
+    // Set the interface index.
+    req->setIndex(ETH0_INDEX);
     // Set the target HW address. This value is normally used to
     // construct the data link layer header.
     req->setRemoteHWAddr(1, 6, dst_mac);
@@ -513,6 +512,7 @@ Dhcpv4SrvTest::testDiscoverRequest(const uint8_t msg_type) {
     ASSERT_TRUE(createPacketFromBuffer(req, received));
     // Set interface. It is required for the server to generate server id.
     received->setIface("eth0");
+    received->setIndex(ETH0_INDEX);
     if (msg_type == DHCPDISCOVER) {
         ASSERT_NO_THROW(
             rsp = srv->processDiscover(received);
@@ -548,6 +548,7 @@ Dhcpv4SrvTest::testDiscoverRequest(const uint8_t msg_type) {
 
     // Set interface. It is required for the server to generate server id.
     received->setIface("eth0");
+    received->setIndex(ETH0_INDEX);
 
     if (msg_type == DHCPDISCOVER) {
         ASSERT_NO_THROW(rsp = srv->processDiscover(received));
@@ -584,6 +585,7 @@ Dhcpv4SrvTest::testDiscoverRequest(const uint8_t msg_type) {
 
     // Set interface. It is required for the server to generate server id.
     received->setIface("eth0");
+    received->setIndex(ETH0_INDEX);
 
     if (msg_type == DHCPDISCOVER) {
         ASSERT_NO_THROW(rsp = srv->processDiscover(received));
index 13101d61f2df737a0f75b73b43266cbb1ccbf2da..2a47d718219306a0ea5ad066e73093993c99cb1c 100644 (file)
@@ -214,6 +214,7 @@ TEST_F(Dhcp4to6IpcTest, receive) {
     Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 1234));
     pkt->addOption(createDHCPv4MsgOption());
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
     ASSERT_NO_THROW(pkt->pack());
 
@@ -235,6 +236,7 @@ TEST_F(Dhcp4to6IpcTest, receive) {
     Pkt6Ptr pkt6_received = pkt_received->getPkt6();
     ASSERT_TRUE(pkt6_received);
     EXPECT_EQ("eth0", pkt6_received->getIface());
+    EXPECT_EQ(ETH0_INDEX, pkt6_received->getIndex());
     EXPECT_EQ("2001:db8:1::123", pkt6_received->getRemoteAddr().toText());
 
     // Both DHCP4o6 and encapsulated DHCPv6 packet should have the
@@ -261,6 +263,7 @@ TEST_F(Dhcp4to6IpcTest, receiveMultipleQueries) {
     pkt->addOption(createDHCPv4MsgOption());
     pkt->addOption(createDHCPv4MsgOption());
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
     ASSERT_NO_THROW(pkt->pack());
 
@@ -290,6 +293,7 @@ TEST_F(Dhcp4to6IpcTest, receiveNoQueries) {
     // Create message to be sent over IPC without DHCPv4 query option.
     Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 1234));
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
     ASSERT_NO_THROW(pkt->pack());
 
@@ -341,6 +345,7 @@ TEST_F(Dhcp4to6IpcTest, process) {
     Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 1234));
     pkt->addOption(opt_msg);
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
     ASSERT_NO_THROW(pkt->pack());
 
@@ -360,6 +365,7 @@ TEST_F(Dhcp4to6IpcTest, process) {
     Pkt6Ptr pkt6_received = pkt_received->getPkt6();
     ASSERT_TRUE(pkt6_received);
     EXPECT_EQ("eth0", pkt6_received->getIface());
+    EXPECT_EQ(ETH0_INDEX, pkt6_received->getIndex());
     EXPECT_EQ("2001:db8:1::123", pkt6_received->getRemoteAddr().toText());
 
     // Make sure that the message has been processed.
@@ -373,6 +379,7 @@ TEST_F(Dhcp4to6IpcTest, process) {
     ASSERT_TRUE(pkt6_sent);
     EXPECT_EQ(DHCPV6_DHCPV4_RESPONSE, pkt6_sent->getType());
     EXPECT_EQ("eth0", pkt6_sent->getIface());
+    EXPECT_EQ(ETH0_INDEX, pkt6_sent->getIndex());
     EXPECT_EQ("2001:db8:1::123", pkt6_sent->getRemoteAddr().toText());
 
     // Both DHCP4o6 and encapsulated DHCPv6 packet should have the
index 5c1c75687314b4b4be02e8df85d13efd68aeb003..dedb3b93860a53f539e09fa70e62870ccd0d62ee 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2020 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
@@ -77,10 +77,13 @@ public:
     /// @param msg_type Type of the message to be created.
     /// @param iface Name of the interface on which the message has been
     /// "received" by the server.
+    /// @param ifindex Index of the interface on which the message has been
+    /// "received" by the server.
     ///
     /// @return Generated message.
     Pkt4Ptr createClientMessage(const uint16_t msg_type,
-                                const std::string& iface);
+                                const std::string& iface,
+                                const uint32_t ifindex);
 
     /// @brief Creates simple message from a client.
     ///
@@ -93,9 +96,13 @@ public:
     /// not be NULL.
     /// @param iface Name of the interface on which the message has been
     /// "received" by the server.
+    /// @param ifindex Index of the interface on which the message has been
+    /// "received" by the server.
     ///
     /// @return Configured and parsed message.
-    Pkt4Ptr createClientMessage(const Pkt4Ptr &msg, const std::string& iface);
+    Pkt4Ptr createClientMessage(const Pkt4Ptr &msg,
+                                const std::string& iface,
+                                const uint32_t ifindex);
 
     /// @brief classes the client belongs to
     ///
@@ -159,20 +166,23 @@ DirectClientTest::configureTwoSubnets(const std::string& prefix1,
 }
 
 Pkt4Ptr
-DirectClientTest:: createClientMessage(const uint16_t msg_type,
-                                       const std::string& iface) {
+DirectClientTest::createClientMessage(const uint16_t msg_type,
+                                      const std::string& iface,
+                                      const uint32_t ifindex) {
     // Create a source packet.
     Pkt4Ptr msg = Pkt4Ptr(new Pkt4(msg_type, 1234));
-    return (createClientMessage(msg, iface));
+    return (createClientMessage(msg, iface, ifindex));
 
 }
 
 Pkt4Ptr
 DirectClientTest::createClientMessage(const Pkt4Ptr& msg,
-                                      const std::string& iface) {
+                                      const std::string& iface,
+                                      const uint32_t ifindex) {
     msg->setRemoteAddr(IOAddress("255.255.255.255"));
     msg->addOption(generateClientId());
     msg->setIface(iface);
+    msg->setIndex(ifindex);
 
     // Create copy of this packet by parsing its wire data. Make sure that the
     // local and remote address are set like it was a message sent from the
@@ -180,6 +190,7 @@ DirectClientTest::createClientMessage(const Pkt4Ptr& msg,
     Pkt4Ptr received;
     createPacketFromBuffer(msg, received);
     received->setIface(iface);
+    received->setIndex(ifindex);
     received->setLocalAddr(IOAddress("255.255.255.255"));
     received->setRemoteAddr(IOAddress("0.0.0.0"));
 
@@ -204,10 +215,10 @@ TEST_F(DirectClientTest,  twoSubnets) {
     // address on eth1 belongs to the first subnet.
     ASSERT_NO_FATAL_FAILURE(configureTwoSubnets("192.0.2.0", "10.0.0.0"));
     // Create Discover and simulate reception of this message through eth0.
-    Pkt4Ptr dis = createClientMessage(DHCPDISCOVER, "eth0");
+    Pkt4Ptr dis = createClientMessage(DHCPDISCOVER, "eth0", ETH0_INDEX);
     srv_.fakeReceive(dis);
     // Create Request and simulate reception of this message through eth1.
-    Pkt4Ptr req = createClientMessage(DHCPREQUEST, "eth1");
+    Pkt4Ptr req = createClientMessage(DHCPREQUEST, "eth1", ETH1_INDEX);
     srv_.fakeReceive(req);
 
     // Process clients' messages.
@@ -259,10 +270,10 @@ TEST_F(DirectClientTest, oneSubnet) {
     // connected client is received through interface eth0.
     ASSERT_NO_FATAL_FAILURE(configureSubnet("10.0.0.0"));
     // Create Discover and simulate reception of this message through eth0.
-    Pkt4Ptr dis = createClientMessage(DHCPDISCOVER, "eth0");
+    Pkt4Ptr dis = createClientMessage(DHCPDISCOVER, "eth0", ETH0_INDEX);
     srv_.fakeReceive(dis);
     // Create Request and simulate reception of this message through eth1.
-    Pkt4Ptr req = createClientMessage(DHCPDISCOVER, "eth1");
+    Pkt4Ptr req = createClientMessage(DHCPDISCOVER, "eth1", ETH1_INDEX);
     srv_.fakeReceive(req);
 
     // Process clients' messages.
@@ -347,12 +358,14 @@ TEST_F(DirectClientTest, rebind) {
     // Broadcast Request through an interface for which there is no subnet
     // configured. This message should be discarded by the server.
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
     ASSERT_NO_THROW(client.doRequest());
     EXPECT_FALSE(client.getContext().response_);
 
     // Send Rebind over the correct interface, and make sure we have obtained
     // the same address.
     client.setIfaceName("eth0");
+    client.setIfaceIndex(ETH0_INDEX);
     ASSERT_NO_THROW(client.doRequest());
     ASSERT_TRUE(client.getContext().response_);
     EXPECT_EQ(DHCPACK, static_cast<int>(client.getContext().response_->getType()));
index e97995abf6aec779ace53c7e38deaefb0d6c2495..3a18f62f5d5b03e0d347a340aa064d69acd72a99 100644 (file)
@@ -2131,6 +2131,7 @@ TEST_F(DORATest, customServerIdentifier) {
     // Repeat the test for different subnet.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
 
     ASSERT_NO_THROW(client2.doDORA());
     ASSERT_TRUE(client2.getContext().response_);
index 73b4064e57f182eca04b75d42503b45fdc815818..2853ec213cdb536997ddee06fa97511fa4e165d7 100644 (file)
@@ -434,6 +434,7 @@ public:
         Pkt4Ptr pkt = Pkt4Ptr(new Pkt4(msg_type, 1234));
         pkt->setRemoteAddr(IOAddress("192.0.2.3"));
         pkt->setIface("eth1");
+        pkt->setIndex(ETH1_INDEX);
         // For DISCOVER we don't include server id, because client broadcasts
         // the message to all servers.
         if (msg_type != DHCPDISCOVER) {
@@ -1133,6 +1134,7 @@ TEST_F(NameDhcpv4SrvTest, processRequestTopLevelHostname) {
     // Set interface for the incoming packet. The server requires it to
     // generate client id.
     req->setIface("eth1");
+    req->setIndex(ETH1_INDEX);
 
     Pkt4Ptr reply;
     ASSERT_NO_THROW(reply = srv_->processRequest(req));
@@ -1220,7 +1222,7 @@ TEST_F(NameDhcpv4SrvTest, processTwoRequestsHostname) {
     // Set interface for the incoming packet. The server requires it to
     // generate client id.
     req1->setIface("eth1");
-
+    req1->setIndex(ETH1_INDEX);
 
     Pkt4Ptr reply;
     ASSERT_NO_THROW(reply = srv_->processRequest(req1));
@@ -1243,6 +1245,7 @@ TEST_F(NameDhcpv4SrvTest, processTwoRequestsHostname) {
     // Set interface for the incoming packet. The server requires it to
     // generate client id.
     req2->setIface("eth1");
+    req2->setIndex(ETH1_INDEX);
 
     ASSERT_NO_THROW(reply = srv_->processRequest(req2));
 
@@ -1317,6 +1320,7 @@ TEST_F(NameDhcpv4SrvTest, processRequestRenewHostname) {
     // Set interface for the incoming packet. The server requires it to
     // generate client id.
     req1->setIface("eth1");
+    req1->setIndex(ETH1_INDEX);
 
     Pkt4Ptr reply;
     ASSERT_NO_THROW(reply = srv_->processRequest(req1));
@@ -1338,6 +1342,7 @@ TEST_F(NameDhcpv4SrvTest, processRequestRenewHostname) {
     // Set interface for the incoming packet. The server requires it to
     // generate client id.
     req2->setIface("eth1");
+    req2->setIndex(ETH1_INDEX);
 
     ASSERT_NO_THROW(reply = srv_->processRequest(req2));
 
@@ -2192,6 +2197,7 @@ TEST_F(NameDhcpv4SrvTest, sanitizeFqdnGlobal) {
 TEST_F(NameDhcpv4SrvTest, ddnsScopeTest) {
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth0");
+    client1.setIfaceIndex(ETH0_INDEX);
 
     // Load a configuration with D2 enabled
     ASSERT_NO_FATAL_FAILURE(configure(CONFIGS[8], *client1.getServer()));
@@ -2221,6 +2227,7 @@ TEST_F(NameDhcpv4SrvTest, ddnsScopeTest) {
     // Now let's try with a client on subnet 2.
     Dhcp4Client client2(Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
 
     // Include the Client FQDN option.
     ASSERT_NO_THROW(client2.includeFQDN((Option4ClientFqdn::FLAG_S
index a343973fe2f31aceff0a0b8d79cdd70b5b19fd14..06cc6d333df9477e711f07105cbb9aa6124d6e17 100644 (file)
@@ -217,6 +217,7 @@ public:
         // and the fake eth0 interface has IPv4 address matching the subnet
         // currently configured for this test.
         dis->setIface("eth1");
+        dis->setIndex(ETH1_INDEX);
         return (dis);
     }
 
@@ -1594,6 +1595,7 @@ TEST_F(HooksDhcpv4SrvTest, subnet4SelectSimple) {
     Pkt4Ptr sol = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     sol->setRemoteAddr(IOAddress("192.0.2.1"));
     sol->setIface("eth1");
+    sol->setIndex(ETH1_INDEX);
     OptionPtr clientid = generateClientId();
     sol->addOption(clientid);
 
@@ -1675,6 +1677,7 @@ TEST_F(HooksDhcpv4SrvTest, subnet4SelectChange) {
     Pkt4Ptr sol = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     sol->setRemoteAddr(IOAddress("192.0.2.1"));
     sol->setIface("eth0");
+    sol->setIndex(ETH0_INDEX);
     OptionPtr clientid = generateClientId();
     sol->addOption(clientid);
 
@@ -1714,6 +1717,7 @@ TEST_F(HooksDhcpv4SrvTest, leases4CommittedDiscover) {
 
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
     ASSERT_NO_THROW(client.doDiscover());
 
     // Make sure that we received a response
@@ -1789,6 +1793,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4RenewSimple) {
     req->setYiaddr(addr);
     req->setCiaddr(addr); // client's address
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     req->setHWAddr(hwaddr2);
 
     req->addOption(clientid);
@@ -1891,6 +1896,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4RenewSkip) {
     req->setYiaddr(addr);
     req->setCiaddr(addr); // client's address
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     req->setHWAddr(hwaddr2);
 
     req->addOption(clientid);
@@ -1929,6 +1935,7 @@ TEST_F(HooksDhcpv4SrvTest, leases4CommittedRequest) {
 
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
     ASSERT_NO_THROW(client.doDORA(boost::shared_ptr<IOAddress>(new IOAddress("192.0.2.100"))));
 
     // Make sure that we received a response
@@ -2048,6 +2055,7 @@ TEST_F(HooksDhcpv4SrvTest, leases4CommittedParkRequests) {
     // Create first client and perform DORA.
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
     ASSERT_NO_THROW(client1.doDORA(boost::shared_ptr<IOAddress>(new IOAddress("192.0.2.100"))));
 
     // We should be offered an address but the DHCPACK should not arrive
@@ -2086,6 +2094,7 @@ TEST_F(HooksDhcpv4SrvTest, leases4CommittedParkRequests) {
     // server while the previous packet is parked.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
     ASSERT_NO_THROW(client2.doDORA(boost::shared_ptr<IOAddress>(new IOAddress("192.0.2.101"))));
 
     // The DHCPOFFER should have been returned but not DHCPACK, as this
@@ -2283,6 +2292,7 @@ TEST_F(HooksDhcpv4SrvTest, leases4CommittedRelease) {
 
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
     ASSERT_NO_THROW(client.doDORA(boost::shared_ptr<IOAddress>(new IOAddress("192.0.2.100"))));
 
     // Make sure that we received a response
index 65cee16bfe6ba72e0ffc676db78578c66bd9eabc..85958b5de987d1b2268cf1a92837686350f4310f 100644 (file)
@@ -355,7 +355,7 @@ public:
 
         // Perform 4-way exchange with the server but to not request any
         // specific address in the DHCPDISCOVER message.
-        boost::shared_ptr<IOAddress> hint; 
+        boost::shared_ptr<IOAddress> hint;
         if (!requested_addr.empty()) {
             hint = boost::make_shared<IOAddress>(requested_addr);
         }
@@ -402,6 +402,7 @@ public:
         // client class.
         client_resrv.setHWAddress("aa:bb:cc:dd:ee:fe");
         client_resrv.setIfaceName("eth0");
+        client_resrv.setIfaceIndex(ETH0_INDEX);
 
         ASSERT_NO_FATAL_FAILURE(configure(CONFIGS[config_idx], *client_resrv.getServer()));
 
@@ -421,6 +422,7 @@ public:
         Dhcp4Client client_no_resrv(client_resrv.getServer(), Dhcp4Client::SELECTING);
         client_no_resrv.setHWAddress("aa:bb:cc:dd:ee:ff");
         client_no_resrv.setIfaceName("eth0");
+        client_no_resrv.setIfaceIndex(ETH0_INDEX);
 
         // Let's use the address of 10.0.0.10 as a hint to make sure that the
         // server refuses it in favor of the 192.0.3.10.
@@ -533,6 +535,7 @@ TEST_F(HostTest, globalOverSubnet) {
 
     // Change to subnet 20
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
 
     // Subnet 20 usses global HR mode, so the global
     // reservation should be used, rather than the subnet one.
index 5cf868c8fb7b9771940ed908463d43e0ec3a4f55..970f9a772d4777ff85b969c03c8d114bd7a2b5fc 100644 (file)
@@ -1223,6 +1223,7 @@ public:
         // Create client and set MAC address to the one that has a reservation.
         Dhcp4Client client(Dhcp4Client::SELECTING);
         client.setIfaceName("eth1");
+        client.setIfaceIndex(ETH1_INDEX);
         client.setHWAddress("aa:bb:cc:dd:ee:ff");
         // Request domain-name-servers.
         client.requestOptions(DHO_DOMAIN_NAME_SERVERS);
@@ -1366,6 +1367,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkShortage) {
     // Create client #1
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
 
     // Configure the server with one shared network including two subnets and
     // one subnet outside of the shared network.
@@ -1381,6 +1383,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkShortage) {
     // an address from the second subnet.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
     testAssigned([this, &client2]() {
         doDORA(client2, "10.0.0.16");
     });
@@ -1389,6 +1392,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkShortage) {
     // the server has no more addresses to assign.
     Dhcp4Client client3(client1.getServer(), Dhcp4Client::SELECTING);
     client3.setIfaceName("eth1");
+    client3.setIfaceIndex(ETH1_INDEX);
     testAssigned([&client3]() {
         ASSERT_NO_THROW(client3.doDiscover());
         Pkt4Ptr resp3 = client3.getContext().response_;
@@ -1397,6 +1401,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkShortage) {
 
     // Client #3 should be assigned an address if subnet 3 is selected for this client.
     client3.setIfaceName("eth0");
+    client3.setIfaceIndex(ETH0_INDEX);
     testAssigned([this, &client3]() {
         doDORA(client3, "192.0.2.65");
     });
@@ -1419,6 +1424,7 @@ TEST_F(Dhcpv4SharedNetworkTest, returningClientStartsOver) {
     // Create client.
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
     client.includeClientId("01:02:03:04");
 
     // Configure the server with one shared network including two subnets and
@@ -1506,6 +1512,7 @@ TEST_F(Dhcpv4SharedNetworkTest, hintWithinSharedNetwork) {
     // Create client.
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
 
     // Configure the server with one shared network including two subnets and
     // one subnet outside of the shared network.
@@ -1576,6 +1583,7 @@ TEST_F(Dhcpv4SharedNetworkTest, subnetInSharedNetworkSelectedByClass) {
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.useRelay(true, IOAddress("192.3.5.6"));
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
     testAssigned([this, &client2] {
         doDORA(client2, "10.0.0.16");
     });
@@ -1717,6 +1725,7 @@ TEST_F(Dhcpv4SharedNetworkTest, optionsDerivation) {
     // Client #1.
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
     client1.requestOptions(DHO_LOG_SERVERS, DHO_COOKIE_SERVERS, DHO_DOMAIN_NAME_SERVERS);
 
     configure(NETWORKS_CONFIG[7], *client1.getServer());
@@ -1746,6 +1755,7 @@ TEST_F(Dhcpv4SharedNetworkTest, optionsDerivation) {
     // Client #2.
     Dhcp4Client client2(Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
     client2.requestOptions(DHO_LOG_SERVERS, DHO_COOKIE_SERVERS, DHO_DOMAIN_NAME_SERVERS);
 
     // Request an address from the second subnet within the shared network.
@@ -1768,6 +1778,7 @@ TEST_F(Dhcpv4SharedNetworkTest, optionsDerivation) {
     // Client #3.
     Dhcp4Client client3(Dhcp4Client::SELECTING);
     client3.setIfaceName("eth0");
+    client3.setIfaceIndex(ETH0_INDEX);
     client3.requestOptions(DHO_LOG_SERVERS, DHO_COOKIE_SERVERS, DHO_DOMAIN_NAME_SERVERS);
 
     // Client 3 should get an address from the subnet defined outside of the shared network.
@@ -1792,6 +1803,7 @@ TEST_F(Dhcpv4SharedNetworkTest, initReboot) {
     // Create client #1.
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
 
     configure(NETWORKS_CONFIG[0], *client1.getServer());
 
@@ -1814,6 +1826,7 @@ TEST_F(Dhcpv4SharedNetworkTest, initReboot) {
     // Create client #2.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
 
     // Let's make sure that the behavior is the same for the other subnet within the
     // same shared network.
@@ -1837,6 +1850,7 @@ TEST_F(Dhcpv4SharedNetworkTest, variousFieldsInReservation) {
     // Create client.
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
     client.setHWAddress("11:22:33:44:55:66");
 
     // Include hostname to force the server to return hostname to
@@ -1888,6 +1902,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectionByInterface) {
     // this client.
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
 
     // Create server configuration with two shared networks selected
     // by the local interface: eth1 and eth0.
@@ -1907,6 +1922,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectionByInterface) {
     // Create client #2 which requests are received on eth0.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth0");
+    client2.setIfaceIndex(ETH0_INDEX);
 
     // Perform 4-way exchange.
     testAssigned([&client2] {
@@ -1963,6 +1979,7 @@ TEST_F(Dhcpv4SharedNetworkTest, matchClientId) {
     Dhcp4Client client(Dhcp4Client::SELECTING);
     client.includeClientId("01:02:03:04");
     client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
 
     // Create server configuration with match-client-id value initially
     // set to true. The client should be allocated a lease and the
@@ -2003,6 +2020,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectedByClass) {
    // Create client #1.
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
 
     // Add option93 which would cause the client1 to be classified as "b-devices".
     OptionPtr option93(new OptionUint16(Option::V4, 93, 0x0002));
@@ -2026,6 +2044,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectedByClass) {
     // Create another client which will belong to a different class.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
 
     // Add option93 which would cause the client1 to be classified as "a-devices".
     option93.reset(new OptionUint16(Option::V4, 93, 0x0001));
@@ -2043,6 +2062,7 @@ TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSelectedByClass) {
 TEST_F(Dhcpv4SharedNetworkTest, customServerIdentifier) {
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
 
     // Configure DHCP server.
     ASSERT_NO_THROW(configure(NETWORKS_CONFIG[15], *client1.getServer()));
@@ -2063,6 +2083,7 @@ TEST_F(Dhcpv4SharedNetworkTest, customServerIdentifier) {
     // Create another client using different interface.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth0");
+    client2.setIfaceIndex(ETH0_INDEX);
 
     testAssigned([&client2] {
         ASSERT_NO_THROW(client2.doDORA());
@@ -2084,6 +2105,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkSelectedByClass) {
     // Create client #1
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
 
     // Configure the server with one shared network including one subnet and
     // in 2 pools in it. The access to one of the pools is restricted
@@ -2114,6 +2136,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkSelectedByClass) {
     // Client 2 should be assigned an address from the unrestricted pool.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
     testAssigned([this, &client2] {
         doDORA(client2, "192.0.2.100");
     });
@@ -2144,6 +2167,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSubnetSelectedByClass) {
     // Create client #1
     Dhcp4Client client1(Dhcp4Client::SELECTING);
     client1.setIfaceName("eth1");
+    client1.setIfaceIndex(ETH1_INDEX);
 
     // Configure the server with one plain subnet including two pools.
     // The access to one of the pools is restricted by client classification.
@@ -2173,6 +2197,7 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSubnetSelectedByClass) {
     // Client 2 should be assigned an address from the unrestricted pool.
     Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
     client2.setIfaceName("eth1");
+    client2.setIfaceIndex(ETH1_INDEX);
     testAssigned([this, &client2] {
         doDORA(client2, "192.0.2.100");
     });
index f80cf08b67be07581191dabd6a0f52e1848237b8..10c09e8882041e984dc922480d1e3609fc3a1e75 100644 (file)
@@ -226,6 +226,7 @@ TEST_F(VendorOptsTest, vendorOptionsORO) {
     dis->addOption(clientid);
     // Set interface. It is required by the server to generate server id.
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
 
     // Pass it to the server and get an advertise
     Pkt4Ptr offer = srv.processDiscover(dis);
@@ -317,6 +318,7 @@ TEST_F(VendorOptsTest, vendorPersistentOptions) {
     dis->addOption(clientid);
     // Set interface. It is required by the server to generate server id.
     dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
 
     // Let's add a vendor-option (vendor-id=4491).
     OptionPtr vendor(new OptionVendor(Option::V4, 4491));
@@ -557,6 +559,7 @@ TEST_F(VendorOptsTest, option43LastResort) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a PRL option to the query
     OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -631,6 +634,7 @@ TEST_F(VendorOptsTest, option43BadRaw) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a vendor-encapsulated-options (code 43)
     // with not compatible (not parsable as suboptions) content
@@ -721,6 +725,7 @@ TEST_F(VendorOptsTest, option43FailRaw) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a vendor-encapsulated-options (code 43)
     // with not compatible (not parsable as suboptions) content
@@ -791,6 +796,7 @@ TEST_F(VendorOptsTest, option43RawGlobal) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a vendor-encapsulated-options (code 43)
     // with not compatible (not parsable as suboptions) content
@@ -883,6 +889,7 @@ TEST_F(VendorOptsTest, option43RawClass) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a vendor-encapsulated-options (code 43)
     // with not compatible (not parsable as suboptions) content
@@ -982,6 +989,7 @@ TEST_F(VendorOptsTest, option43Class) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a vendor-encapsulated-options (code 43)
     OptionBuffer buf;
@@ -1113,6 +1121,7 @@ TEST_F(VendorOptsTest, option43ClassPriority) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a vendor-encapsulated-options (code 43)
     OptionBuffer buf;
@@ -1250,6 +1259,7 @@ TEST_F(VendorOptsTest, option43Classes) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a vendor-encapsulated-options (code 43)
     OptionBuffer buf;
@@ -1594,6 +1604,7 @@ TEST_F(VendorOptsTest, vendorOpsSubOption0) {
     OptionPtr clientid = generateClientId();
     query->addOption(clientid);
     query->setIface("eth1");
+    query->setIndex(ETH1_INDEX);
 
     // Create and add a PRL option to the query
     OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
index b19372a16d8c3d42e0619dfaa01516cce0bde149..70185fc96858d46ee9eef159be1a298cc63dd38f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2020 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
@@ -366,6 +366,7 @@ public:
             query->setRemoteAddr(IOAddress(remote_addr));
             query->addOption(clientid);
             query->setIface("eth1");
+            query->setIndex(ETH1_INDEX);
             query->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
             return (query);
     }
@@ -533,16 +534,19 @@ TEST_F(ClassifyTest, required) {
     query1->setRemoteAddr(IOAddress("fe80::abcd"));
     query1->addOption(clientid);
     query1->setIface("eth1");
+    query1->setIndex(ETH1_INDEX);
     query1->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
     Pkt6Ptr query2(new Pkt6(DHCPV6_SOLICIT, 1234));
     query2->setRemoteAddr(IOAddress("fe80::abcd"));
     query2->addOption(clientid);
     query2->setIface("eth1");
+    query2->setIndex(ETH1_INDEX);
     query2->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     Pkt6Ptr query3(new Pkt6(DHCPV6_SOLICIT, 1234));
     query3->setRemoteAddr(IOAddress("fe80::abcd"));
     query3->addOption(clientid);
     query3->setIface("eth1");
+    query3->setIndex(ETH1_INDEX);
     query3->addOption(generateIA(D6O_IA_NA, 345, 1500, 3000));
 
     // Create and add an ORO option to the first 2 queries
@@ -633,16 +637,19 @@ TEST_F(ClassifyTest, requiredClassification) {
     query1->setRemoteAddr(IOAddress("fe80::abcd"));
     query1->addOption(clientid);
     query1->setIface("eth1");
+    query1->setIndex(ETH1_INDEX);
     query1->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
     Pkt6Ptr query2(new Pkt6(DHCPV6_SOLICIT, 1234));
     query2->setRemoteAddr(IOAddress("fe80::abcd"));
     query2->addOption(clientid);
     query2->setIface("eth1");
+    query2->setIndex(ETH1_INDEX);
     query2->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     Pkt6Ptr query3(new Pkt6(DHCPV6_SOLICIT, 1234));
     query3->setRemoteAddr(IOAddress("fe80::abcd"));
     query3->addOption(clientid);
     query3->setIface("eth1");
+    query3->setIndex(ETH1_INDEX);
     query3->addOption(generateIA(D6O_IA_NA, 345, 1500, 3000));
 
     // Create and add an ORO option to the first 2 queries
@@ -1162,6 +1169,7 @@ TEST_F(ClassifyTest, clientClassifyPoolKnown) {
     query1->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     query1->addOption(clientid1);
     query1->setIface("eth1");
+    query1->setIndex(ETH1_INDEX);
 
     // First pool requires reservation so the second will be used
     srv.classifyPacket(query1);
@@ -1190,6 +1198,7 @@ TEST_F(ClassifyTest, clientClassifyPoolKnown) {
     query2->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     query2->addOption(clientid2);
     query2->setIface("eth1");
+    query2->setIndex(ETH1_INDEX);
 
     // Now the first pool will be used
     srv.classifyPacket(query2);
@@ -1433,16 +1442,19 @@ TEST_F(ClassifyTest, member) {
     query1->setRemoteAddr(IOAddress("fe80::abcd"));
     query1->addOption(clientid);
     query1->setIface("eth1");
+    query1->setIndex(ETH1_INDEX);
     query1->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
     Pkt6Ptr query2(new Pkt6(DHCPV6_SOLICIT, 1234));
     query2->setRemoteAddr(IOAddress("fe80::abcd"));
     query2->addOption(clientid);
     query2->setIface("eth1");
+    query2->setIndex(ETH1_INDEX);
     query2->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     Pkt6Ptr query3(new Pkt6(DHCPV6_SOLICIT, 1234));
     query3->setRemoteAddr(IOAddress("fe80::abcd"));
     query3->addOption(clientid);
     query3->setIface("eth1");
+    query3->setIndex(ETH1_INDEX);
     query3->addOption(generateIA(D6O_IA_NA, 345, 1500, 3000));
 
     // Create and add an ORO option to queries
index 0a867497971b1614007705089fe397e226ba2cbc..65d7179ac661924c1d9062ccdd55d0405b21e5d5 100644 (file)
@@ -382,6 +382,7 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
     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);
@@ -474,6 +475,7 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) {
     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);
@@ -522,6 +524,7 @@ TEST_F(Dhcpv6SrvTest, pdSolicitBasic) {
     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_PD, 234, 1500, 3000));
     OptionPtr clientid = generateClientId();
     sol->addOption(clientid);
@@ -561,6 +564,7 @@ TEST_F(Dhcpv6SrvTest, defaultLifetimeSolicit) {
     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);
@@ -602,6 +606,7 @@ TEST_F(Dhcpv6SrvTest, hintZeroLifetimeSolicit) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface("eth0");
+    sol->setIndex(ETH0_INDEX);
     OptionPtr iapd = generateIA(D6O_IA_PD, 234, 1500, 3000);
     sol->addOption(iapd);
     OptionPtr clientid = generateClientId();
@@ -649,6 +654,7 @@ TEST_F(Dhcpv6SrvTest, hintLifetimeSolicit) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface("eth0");
+    sol->setIndex(ETH0_INDEX);
     OptionPtr iana = generateIA(D6O_IA_NA, 234, 1500, 3000);
     sol->addOption(iana);
     OptionPtr clientid = generateClientId();
@@ -696,6 +702,7 @@ TEST_F(Dhcpv6SrvTest, minLifetimeSolicit) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface("eth0");
+    sol->setIndex(ETH0_INDEX);
     OptionPtr iapd = generateIA(D6O_IA_PD, 234, 1500, 3000);
     sol->addOption(iapd);
     OptionPtr clientid = generateClientId();
@@ -744,6 +751,7 @@ TEST_F(Dhcpv6SrvTest, maxLifetimeSolicit) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface("eth0");
+    sol->setIndex(ETH0_INDEX);
     OptionPtr iana = generateIA(D6O_IA_NA, 234, 1500, 3000);
     sol->addOption(iana);
     OptionPtr clientid = generateClientId();
@@ -802,6 +810,7 @@ TEST_F(Dhcpv6SrvTest, SolicitHint) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface("eth0");
+    sol->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
 
     // with a valid hint
@@ -861,6 +870,7 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface("eth0");
+    sol->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
     IOAddress hint("2001:db8:1::cafe:babe");
     ASSERT_FALSE(subnet_->inPool(Lease::TYPE_NA, hint));
@@ -916,8 +926,11 @@ TEST_F(Dhcpv6SrvTest, ManySolicits) {
     sol3->setRemoteAddr(IOAddress("fe80::3467"));
 
     sol1->setIface("eth0");
+    sol1->setIndex(ETH0_INDEX);
     sol2->setIface("eth0");
+    sol2->setIndex(ETH0_INDEX);
     sol3->setIface("eth0");
+    sol3->setIndex(ETH0_INDEX);
 
     sol1->addOption(generateIA(D6O_IA_NA, 1, 1500, 3000));
     sol2->addOption(generateIA(D6O_IA_NA, 2, 1500, 3000));
@@ -1007,6 +1020,7 @@ TEST_F(Dhcpv6SrvTest, RequestBasic) {
     Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
     req->setRemoteAddr(IOAddress("fe80::abcd"));
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
 
     // with a valid hint
@@ -1074,6 +1088,7 @@ TEST_F(Dhcpv6SrvTest, pdRequestBasic) {
     Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
     req->setRemoteAddr(IOAddress("fe80::abcd"));
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_PD, 234, 1500, 3000);
 
     // with a valid hint
@@ -1140,8 +1155,11 @@ TEST_F(Dhcpv6SrvTest, ManyRequests) {
     req3->setRemoteAddr(IOAddress("fe80::3467"));
 
     req1->setIface("eth0");
+    req1->setIndex(ETH0_INDEX);
     req2->setIface("eth0");
+    req2->setIndex(ETH0_INDEX);
     req3->setIface("eth0");
+    req3->setIndex(ETH0_INDEX);
 
     req1->addOption(generateIA(D6O_IA_NA, 1, 1500, 3000));
     req2->addOption(generateIA(D6O_IA_NA, 2, 1500, 3000));
@@ -1725,6 +1743,7 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
 
     Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
 
     bool drop = false;
     Subnet6Ptr selected = srv.selectSubnet(pkt, drop);
@@ -1738,6 +1757,7 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
     CfgMgr::instance().commit();
 
     pkt->setIface("eth1");
+    pkt->setIndex(ETH1_INDEX);
 
     selected = srv.selectSubnet(pkt, drop);
     EXPECT_FALSE(selected);
@@ -1753,14 +1773,17 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
     CfgMgr::instance().commit();
 
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     EXPECT_EQ(subnet1, srv.selectSubnet(pkt, drop));
     EXPECT_FALSE(drop);
 
     pkt->setIface("eth3"); // no such interface
+    pkt->setIndex(3);
     EXPECT_EQ(Subnet6Ptr(), srv.selectSubnet(pkt, drop)); // nothing selected
     EXPECT_FALSE(drop);
 
     pkt->setIface("wifi1");
+    pkt->setIndex(101); // arbitrary value
     EXPECT_EQ(subnet3, srv.selectSubnet(pkt, drop));
     EXPECT_FALSE(drop);
 }
@@ -2074,6 +2097,7 @@ TEST_F(Dhcpv6SrvTest, relaySourcePort) {
     Pkt6Ptr sol(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);
@@ -2108,6 +2132,7 @@ TEST_F(Dhcpv6SrvTest, relaySourcePort) {
     query->setLocalAddr(sol->getLocalAddr());
     query->setLocalPort(sol->getLocalPort());
     query->setIface(sol->getIface());
+    query->setIndex(sol->getIndex());
 
     srv.fakeReceive(query);
 
@@ -2153,6 +2178,7 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) {
     Pkt6Ptr sol(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);
@@ -2947,6 +2973,7 @@ TEST_F(Dhcpv6SrvTest, calculateTeeTimers) {
     OptionPtr clientid = generateClientId();
     sol->addOption(clientid);
     sol->setIface("eth0");
+    sol->setIndex(ETH0_INDEX);
 
     // Iterate over the test scenarios.
     for (auto test = tests.begin(); test != tests.end(); ++test) {
index 618a1067f5271bfe58841db9f1fe07f0b9971713..3c297d97ac9c6b1d31c6fb6a892fda1f93ef5026 100644 (file)
@@ -847,6 +847,7 @@ NakedDhcpv6SrvTest::NakedDhcpv6SrvTest()
     }
 
     valid_iface_ = (*ifaces.begin())->getName();
+    valid_ifindex_ = (*ifaces.begin())->getIndex();
 
     // Let's wipe all existing statistics.
     isc::stats::StatsMgr::instance().removeAll();
index d295bb72342862981547963614bcb597ed40cf93..6b0f359780578306ef5c53412fd675813d943f48 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2020 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
@@ -468,6 +468,9 @@ public:
 
     // Name of a valid network interface
     std::string valid_iface_;
+
+    // Index of a valid network interface
+    uint32_t valid_ifindex_;
 };
 
 // We need to pass one reference to the Dhcp6Client, which is defined in
index 46beca27c8f497b575af59b6d979195080c18522..8a4616d9926d01728c223307f183b7a66fd5a0f4 100644 (file)
@@ -169,6 +169,7 @@ TEST_F(Dhcp6to4IpcTest, receive) {
     Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_RESPONSE, 1234));
     pkt->addOption(createDHCPv4MsgOption());
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
     ASSERT_NO_THROW(pkt->pack());
 
@@ -192,6 +193,7 @@ TEST_F(Dhcp6to4IpcTest, receive) {
     EXPECT_EQ(forwarded->getType(), pkt->getType());
     EXPECT_TRUE(forwarded->getOption(D6O_DHCPV4_MSG));
     EXPECT_EQ("eth0", forwarded->getIface());
+    EXPECT_EQ(ETH0_INDEX, forwarded->getIndex());
     EXPECT_EQ("2001:db8:1::123", forwarded->getRemoteAddr().toText());
 
     // Verify statistics
@@ -236,6 +238,7 @@ TEST_F(Dhcp6to4IpcTest, DISABLED_receiveRelayed) {
     relay.hop_count_ = 1;
     pkt->relay_info_.push_back(relay);
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
     ASSERT_NO_THROW(pkt->pack());
 
@@ -255,6 +258,7 @@ TEST_F(Dhcp6to4IpcTest, DISABLED_receiveRelayed) {
     EXPECT_EQ(forwarded->getType(), pkt->getType());
     EXPECT_TRUE(forwarded->getOption(D6O_DHCPV4_MSG));
     EXPECT_EQ("eth0", forwarded->getIface());
+    EXPECT_EQ(ETH0_INDEX, forwarded->getIndex());
     EXPECT_EQ("2001:db8:1::123", forwarded->getRemoteAddr().toText());
     EXPECT_EQ(DHCP6_CLIENT_PORT, forwarded->getRemotePort());
 
@@ -287,6 +291,7 @@ TEST_F(Dhcp6to4IpcTest, clientPort) {
     Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_RESPONSE, 1234));
     pkt->addOption(createDHCPv4MsgOption());
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
     ASSERT_NO_THROW(pkt->pack());
 
index 56cce1c43e29c2778128fe41721bd9fae037a88a..3263c7bfe53d766f4282a1c1f35f9f53b6d1798d 100644 (file)
@@ -186,6 +186,7 @@ public:
                             OptionPtr srvid = OptionPtr()) {
         Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(msg_type, 1234));
         pkt->setIface("eth0");
+        pkt->setIndex(ETH0_INDEX);
         Option6IAPtr ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
         if (msg_type != DHCPV6_REPLY) {
             IOAddress hint("2001:db8:1:1::dead:beef");
@@ -222,6 +223,7 @@ public:
     Pkt6Ptr generateMessageWithIds(const uint8_t msg_type) {
         Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(msg_type, 1234));
         pkt->setIface("eth0");
+        pkt->setIndex(ETH0_INDEX);
         // Generate client-id.
         OptionPtr opt_clientid = generateClientId();
         pkt->addOption(opt_clientid);
@@ -1680,4 +1682,4 @@ TEST_F(FqdnDhcpv6SrvTest, ddnsScopeTest) {
 
 }
 
-}   // end of anonymous namespace
+} // end of anonymous namespace
index 381f589cbc9cfe4611d9bced9646d535a2e06bb6..e472c3ff911634786f7e0a55275ca3672e96a1e1 100644 (file)
@@ -1670,6 +1670,7 @@ TEST_F(HooksDhcpv6SrvTest, subnet6Select) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface(valid_iface_);
+    sol->setIndex(valid_ifindex_);
     sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     OptionPtr clientid = generateClientId();
     sol->addOption(clientid);
@@ -1754,6 +1755,7 @@ TEST_F(HooksDhcpv6SrvTest, subnet6SselectChange) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface(valid_iface_);
+    sol->setIndex(valid_ifindex_);
     sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     OptionPtr clientid = generateClientId();
     sol->addOption(clientid);
@@ -2727,6 +2729,7 @@ TEST_F(HooksDhcpv6SrvTest, basicLease6Renew) {
     Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
     req->setRemoteAddr(IOAddress("fe80::abcd"));
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
 
     OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
@@ -2830,6 +2833,7 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Renew) {
     Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
     req->setRemoteAddr(IOAddress("fe80::abcd"));
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
 
     OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
@@ -2932,6 +2936,7 @@ TEST_F(HooksDhcpv6SrvTest, skipLease6Renew) {
     Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
     req->setRemoteAddr(IOAddress("fe80::abcd"));
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
 
     OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
@@ -3855,6 +3860,7 @@ TEST_F(HooksDhcpv6SrvTest, basicLease6Rebind) {
     Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REBIND, 1234));
     req->setRemoteAddr(IOAddress("fe80::abcd"));
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
 
     OptionPtr rebound_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
@@ -3953,6 +3959,7 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Rebind) {
     Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REBIND, 1234));
     req->setRemoteAddr(IOAddress("fe80::abcd"));
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
 
     OptionPtr rebound_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
@@ -4053,6 +4060,7 @@ TEST_F(HooksDhcpv6SrvTest, skipLease6Rebind) {
     Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REBIND, 1234));
     req->setRemoteAddr(IOAddress("fe80::abcd"));
     req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
     boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
 
     OptionPtr rebound_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
@@ -4762,6 +4770,7 @@ TEST_F(HooksDhcpv6SrvTest, host6Identifier) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface(valid_iface_);
+    sol->setIndex(valid_ifindex_);
     sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     OptionPtr clientid = generateClientId();
     sol->addOption(clientid);
@@ -4843,6 +4852,7 @@ TEST_F(HooksDhcpv6SrvTest, host6Identifier_hwaddr) {
     Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
     sol->setRemoteAddr(IOAddress("fe80::abcd"));
     sol->setIface(valid_iface_);
+    sol->setIndex(valid_ifindex_);
     sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
     OptionPtr clientid = generateClientId();
     sol->addOption(clientid);
index 10eb6f4bf56aff2094d8bb1b9969b46cc897f7c9..0836d0101df8c4c1b5d073a03baabb83c56cd1a6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2019-2020 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
@@ -141,6 +141,7 @@ TEST_F(VendorOptsTest, vendorOptionsORO) {
     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);
@@ -233,6 +234,7 @@ TEST_F(VendorOptsTest, vendorPersistentOptions) {
     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);
index e5fee84ffc5807bb51a023232d55bc261390b242..ab8c18e3a0c92c7d833b4d7725ab51c552ddde9f 100644 (file)
@@ -378,7 +378,7 @@ IfaceMgr::deleteAllExternalSockets() {
 
 void
 IfaceMgr::setPacketFilter(const PktFilterPtr& packet_filter) {
-    // Do not allow NULL pointer.
+    // Do not allow null pointer.
     if (!packet_filter) {
         isc_throw(InvalidPacketFilter, "NULL packet filter object specified for"
                   " DHCPv4");
@@ -748,6 +748,19 @@ IfaceMgr::startDHCPReceiver(const uint16_t family) {
     }
 }
 
+void
+IfaceMgr::addInterface(const IfacePtr& iface) {
+    for (const IfacePtr& existing : ifaces_) {
+        if ((existing->getName() == iface->getName()) ||
+            (existing->getIndex() == iface->getIndex())) {
+            isc_throw(Unexpected, "Can't add " << iface->getFullName() <<
+                      " when " << existing->getFullName() <<
+                      " already exists.");
+        }
+    }
+    ifaces_.push_back(iface);
+}
+
 void
 IfaceMgr::printIfaces(std::ostream& out /*= std::cout*/) {
     BOOST_FOREACH(IfacePtr iface, ifaces_) {
@@ -784,6 +797,7 @@ IfaceMgr::getIface(int ifindex) {
 
 IfacePtr
 IfaceMgr::getIface(const std::string& ifname) {
+    std::cerr << "getIface(name) unefficient\n";
     BOOST_FOREACH(IfacePtr iface, ifaces_) {
         if (iface->getName() == ifname)
             return (iface);
@@ -792,6 +806,15 @@ IfaceMgr::getIface(const std::string& ifname) {
     return (IfacePtr()); // not found
 }
 
+IfacePtr
+IfaceMgr::getIface(const PktPtr& pkt) {
+    IfacePtr iface = getIface(pkt->getIndex());
+    if (!iface) {
+        iface = getIface(pkt->getIface());
+    }
+    return (iface);
+}
+
 void
 IfaceMgr::clearIfaces() {
     ifaces_.clear();
@@ -965,7 +988,7 @@ IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr,
                           const uint16_t port, const bool receive_bcast,
                           const bool send_bcast) {
 
-    // Assuming that packet filter is not NULL, because its modifier checks it.
+    // Assuming that packet filter is not null, because its modifier checks it.
     SocketInfo info = packet_filter_->openSocket(iface, addr, port,
                                                  receive_bcast, send_bcast);
     iface.addSocket(info);
@@ -975,29 +998,28 @@ IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr,
 
 bool
 IfaceMgr::send(const Pkt6Ptr& pkt) {
-    IfacePtr iface = getIface(pkt->getIface());
+    IfacePtr iface = getIface(pkt);
     if (!iface) {
         isc_throw(BadValue, "Unable to send DHCPv6 message. Invalid interface ("
                   << pkt->getIface() << ") specified.");
     }
 
-    // Assuming that packet filter is not NULL, because its modifier checks it.
+    // Assuming that packet filter is not null, because its modifier checks it.
     // The packet filter returns an int but in fact it either returns 0 or throws.
-    return (packet_filter6_->send(*iface, getSocket(*pkt), pkt) == 0);
+    return (packet_filter6_->send(*iface, getSocket(pkt), pkt) == 0);
 }
 
 bool
 IfaceMgr::send(const Pkt4Ptr& pkt) {
-
-    IfacePtr iface = getIface(pkt->getIface());
+    IfacePtr iface = getIface(pkt);
     if (!iface) {
         isc_throw(BadValue, "Unable to send DHCPv4 message. Invalid interface ("
                   << pkt->getIface() << ") specified.");
     }
 
-    // Assuming that packet filter is not NULL, because its modifier checks it.
+    // Assuming that packet filter is not null, because its modifier checks it.
     // The packet filter returns an int but in fact it either returns 0 or throws.
-    return (packet_filter_->send(*iface, getSocket(*pkt).sockfd_, pkt) == 0);
+    return (packet_filter_->send(*iface, getSocket(pkt).sockfd_, pkt) == 0);
 }
 
 Pkt4Ptr IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
@@ -1055,7 +1077,7 @@ Pkt4Ptr IfaceMgr::receive4Indirect(uint32_t timeout_sec, uint32_t timeout_usec /
     // zero out the errno to be safe
     errno = 0;
 
-    int result = select(maxfd + 1, &sockets, NULL, NULL, &select_timeout);
+    int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
 
     if ((result == 0) && getPacketQueue4()->empty()) {
         // nothing received and timeout has been reached
@@ -1174,11 +1196,11 @@ Pkt4Ptr IfaceMgr::receive4Direct(uint32_t timeout_sec, uint32_t timeout_usec /*
     // zero out the errno to be safe
     errno = 0;
 
-    int result = select(maxfd + 1, &sockets, NULL, NULL, &select_timeout);
+    int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
 
     if (result == 0) {
         // nothing received and timeout has been reached
-        return (Pkt4Ptr()); // NULL
+        return (Pkt4Ptr()); // null
 
     } else if (result < 0) {
         // In most cases we would like to know whether select() returned
@@ -1249,7 +1271,7 @@ Pkt4Ptr IfaceMgr::receive4Direct(uint32_t timeout_sec, uint32_t timeout_usec /*
     }
 
     // Now we have a socket, let's get some data from it!
-    // Assuming that packet filter is not NULL, because its modifier checks it.
+    // Assuming that packet filter is not null, because its modifier checks it.
     return (packet_filter_->receive(*iface, *candidate));
 }
 
@@ -1319,11 +1341,11 @@ IfaceMgr::receive6Direct(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */ )
     // zero out the errno to be safe
     errno = 0;
 
-    int result = select(maxfd + 1, &sockets, NULL, NULL, &select_timeout);
+    int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
 
     if (result == 0) {
         // nothing received and timeout has been reached
-        return (Pkt6Ptr()); // NULL
+        return (Pkt6Ptr()); // null
 
     } else if (result < 0) {
         // In most cases we would like to know whether select() returned
@@ -1392,7 +1414,7 @@ IfaceMgr::receive6Direct(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */ )
     if (!candidate) {
         isc_throw(SocketReadError, "received data over unknown socket");
     }
-    // Assuming that packet filter is not NULL, because its modifier checks it.
+    // Assuming that packet filter is not null, because its modifier checks it.
     return (packet_filter6_->receive(*candidate));
 }
 
@@ -1444,7 +1466,7 @@ IfaceMgr::receive6Indirect(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
     // zero out the errno to be safe
     errno = 0;
 
-    int result = select(maxfd + 1, &sockets, NULL, NULL, &select_timeout);
+    int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
 
     if ((result == 0) && getPacketQueue6()->empty()) {
         // nothing received and timeout has been reached
@@ -1730,8 +1752,8 @@ IfaceMgr::receiveDHCP6Packet(const SocketInfo& socket_info) {
 }
 
 uint16_t
-IfaceMgr::getSocket(const isc::dhcp::Pkt6& pkt) {
-    IfacePtr iface = getIface(pkt.getIface());
+IfaceMgr::getSocket(const isc::dhcp::Pkt6Ptr& pkt) {
+    IfacePtr iface = getIface(pkt);
     if (!iface) {
         isc_throw(IfaceNotFound, "Tried to find socket for non-existent interface");
     }
@@ -1756,7 +1778,7 @@ IfaceMgr::getSocket(const isc::dhcp::Pkt6& pkt) {
             continue;
         }
 
-        if (s->addr_ == pkt.getLocalAddr()) {
+        if (s->addr_ == pkt->getLocalAddr()) {
             // This socket is bound to the source address. This is perfect
             // match, no need to look any further.
             return (s->sockfd_);
@@ -1769,9 +1791,9 @@ IfaceMgr::getSocket(const isc::dhcp::Pkt6& pkt) {
             // If we want to send something to link-local and the socket is
             // bound to link-local or we want to send to global and the socket
             // is bound to global, then use it as candidate
-            if ( (pkt.getRemoteAddr().isV6LinkLocal() &&
+            if ( (pkt->getRemoteAddr().isV6LinkLocal() &&
                 s->addr_.isV6LinkLocal()) ||
-                 (!pkt.getRemoteAddr().isV6LinkLocal() &&
+                 (!pkt->getRemoteAddr().isV6LinkLocal() &&
                   !s->addr_.isV6LinkLocal()) ) {
                 candidate = s;
             }
@@ -1787,9 +1809,9 @@ IfaceMgr::getSocket(const isc::dhcp::Pkt6& pkt) {
 }
 
 SocketInfo
-IfaceMgr::getSocket(isc::dhcp::Pkt4 const& pkt) {
-    IfacePtr iface = getIface(pkt.getIface());
-    if (iface == NULL) {
+IfaceMgr::getSocket(const isc::dhcp::Pkt4Ptr& pkt) {
+    IfacePtr iface = getIface(pkt);
+    if (!iface) {
         isc_throw(IfaceNotFound, "Tried to find socket for non-existent interface");
     }
 
@@ -1801,7 +1823,7 @@ IfaceMgr::getSocket(isc::dhcp::Pkt4 const& pkt) {
     Iface::SocketCollection::const_iterator s;
     for (s = socket_collection.begin(); s != socket_collection.end(); ++s) {
         if (s->family_ == AF_INET) {
-            if (s->addr_ == pkt.getLocalAddr()) {
+            if (s->addr_ == pkt->getLocalAddr()) {
                 return (*s);
             }
 
index 69309eed9e4cae7e7f973776fc46fdb01f88139f..5e1b93473252e4e8283766a8168725c9f86aaa5c 100644 (file)
@@ -371,7 +371,7 @@ public:
     /// NULL if the buffer is empty.
     uint8_t* getReadBuffer() {
         if (read_buffer_.empty()) {
-            return NULL;
+            return (0);
         }
         return (&read_buffer_[0]);
     }
@@ -576,7 +576,7 @@ public:
     ///
     /// @param ifindex index of searched interface
     ///
-    /// @return interface with requested index (or NULL if no such
+    /// @return interface with requested index (or null if no such
     ///         interface is present)
     ///
     IfacePtr getIface(int ifindex);
@@ -585,10 +585,18 @@ public:
     ///
     /// @param ifname name of searched interface
     ///
-    /// @return interface with requested name (or NULL if no such
+    /// @return interface with requested name (or null if no such
     ///         interface is present)
     IfacePtr getIface(const std::string& ifname);
 
+    /// @brief Returns interface with specified packet
+    ///
+    /// @param pkt packet with interface index and name
+    ///
+    /// @return interface with packet interface index or name
+    ///         (or null if no such interface is present)
+    IfacePtr getIface(const PktPtr& pkt);
+
     /// @brief Returns container with all interfaces.
     ///
     /// This reference is only valid as long as IfaceMgr is valid. However,
@@ -618,8 +626,8 @@ public:
 
     /// @brief Return most suitable socket for transmitting specified IPv6 packet.
     ///
-    /// This method takes Pkt6 (see overloaded implementation that takes
-    /// Pkt4) and chooses appropriate socket to send it. This method
+    /// This method takes Pkt6Ptr (see overloaded implementation that takes
+    /// Pkt4Ptr) and chooses appropriate socket to send it. This method
     /// may throw if specified packet does not have outbound interface specified,
     /// no such interface exists, or specified interface does not have any
     /// appropriate sockets open.
@@ -629,7 +637,7 @@ public:
     /// @return a socket descriptor
     /// @throw SocketNotFound If no suitable socket found.
     /// @throw IfaceNotFound If interface is not set for the packet.
-    uint16_t getSocket(const isc::dhcp::Pkt6& pkt);
+    uint16_t getSocket(const isc::dhcp::Pkt6Ptr& pkt);
 
     /// @brief Return most suitable socket for transmitting specified IPv4 packet.
     ///
@@ -644,7 +652,7 @@ public:
     ///
     /// @return A structure describing a socket.
     /// @throw SocketNotFound if no suitable socket found.
-    SocketInfo getSocket(const isc::dhcp::Pkt4& pkt);
+    SocketInfo getSocket(const isc::dhcp::Pkt4Ptr& pkt);
 
     /// Debugging method that prints out all available interfaces.
     ///
@@ -687,7 +695,7 @@ public:
     /// @param timeout_usec specifies fractional part of the timeout
     /// (in microseconds)
     ///
-    /// @return Pkt4 object representing received packet (or NULL)
+    /// @return Pkt4 object representing received packet (or null)
     Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec = 0);
 
     /// @brief Receive IPv4 packets or data from external sockets
@@ -700,7 +708,7 @@ public:
     /// @param timeout_usec specifies fractional part of the timeout
     /// (in microseconds)
     ///
-    /// @return Pkt4 object representing received packet (or NULL)
+    /// @return Pkt4 object representing received packet (or null)
     Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec = 0);
 
     /// Opens UDP/IP socket and binds it to address, interface and port.
@@ -811,7 +819,7 @@ public:
     /// to the error handler, e.g. Iface if it was really supposed to do
     /// some more sophisticated error handling.
     ///
-    /// If the error handler is not installed (is NULL), the exception is thrown
+    /// If the error handler is not installed (is null), the exception is thrown
     /// for each failure (default behavior).
     ///
     /// @warning This function does not check if there has been any sockets
@@ -824,7 +832,7 @@ public:
     /// @param port specifies port number (usually DHCP6_SERVER_PORT)
     /// @param error_handler A pointer to an error handler function which is
     /// called by the openSockets6 when it fails to open a socket. This
-    /// parameter can be NULL to indicate that the callback should not be used.
+    /// parameter can be null to indicate that the callback should not be used.
     ///
     /// @throw SocketOpenFailure if tried and failed to open socket.
     /// @return true if any sockets were open
@@ -880,7 +888,7 @@ public:
     /// to the error handler, e.g. Iface if it was really supposed to do
     /// some more sophisticated error handling.
     ///
-    /// If the error handler is not installed (is NULL), the exception is thrown
+    /// If the error handler is not installed (is null), the exception is thrown
     /// for each failure (default behavior).
     ///
     /// @warning This function does not check if there has been any sockets
@@ -894,7 +902,7 @@ public:
     /// @param use_bcast configure sockets to support broadcast messages.
     /// @param error_handler A pointer to an error handler function which is
     /// called by the openSockets4 when it fails to open a socket. This
-    /// parameter can be NULL to indicate that the callback should not be used.
+    /// parameter can be null to indicate that the callback should not be used.
     ///
     /// @throw SocketOpenFailure if tried and failed to open socket and callback
     /// function hasn't been specified.
@@ -957,7 +965,7 @@ public:
     /// @param packet_filter A pointer to the new packet filter object to be
     /// used by @c IfaceMgr.
     ///
-    /// @throw InvalidPacketFilter if provided packet filter object is NULL.
+    /// @throw InvalidPacketFilter if provided packet filter object is null.
     /// @throw PacketFilterChangeDenied if there are open IPv4 sockets.
     void setPacketFilter(const PktFilterPtr& packet_filter);
 
@@ -978,7 +986,7 @@ public:
     /// @param packet_filter A pointer to the new packet filter object to be
     /// used by @c IfaceMgr.
     ///
-    /// @throw isc::dhcp::InvalidPacketFilter if specified object is NULL.
+    /// @throw isc::dhcp::InvalidPacketFilter if specified object is null.
     /// @throw isc::dhcp::PacketFilterChangeDenied if there are open IPv6
     /// sockets.
     void setPacketFilter(const PktFilter6Ptr& packet_filter);
@@ -1006,9 +1014,8 @@ public:
     /// @param iface reference to Iface object.
     /// @note This function must be public because it has to be callable
     /// from unit tests.
-    void addInterface(const IfacePtr& iface) {
-        ifaces_.push_back(iface);
-    }
+    /// @throw Unexpected when name or index already exists.
+    void addInterface(const IfacePtr& iface);
 
     /// @brief Checks if there is at least one socket of the specified family
     /// open.
@@ -1159,7 +1166,7 @@ protected:
     /// @throw isc::dhcp::SignalInterruptOnSelect when a call to select() is
     /// interrupted by a signal.
     ///
-    /// @return Pkt4 object representing received packet (or NULL)
+    /// @return Pkt4 object representing received packet (or null)
     Pkt4Ptr receive4Direct(uint32_t timeout_sec, uint32_t timeout_usec = 0);
 
     /// @brief Receive IPv4 packets indirectly or data from external sockets.
@@ -1181,7 +1188,7 @@ protected:
     /// @throw isc::dhcp::SignalInterruptOnSelect when a call to select() is
     /// interrupted by a signal.
     ///
-    /// @return Pkt4 object representing received packet (or NULL)
+    /// @return Pkt4 object representing received packet (or null)
     Pkt4Ptr receive4Indirect(uint32_t timeout_sec, uint32_t timeout_usec = 0);
 
     /// @brief Opens IPv6 socket.
@@ -1220,7 +1227,7 @@ protected:
     /// @throw isc::dhcp::SignalInterruptOnSelect when a call to select() is
     /// interrupted by a signal.
     ///
-    /// @return Pkt6 object representing received packet (or NULL)
+    /// @return Pkt6 object representing received packet (or null)
     Pkt6Ptr receive6Direct(uint32_t timeout_sec, uint32_t timeout_usec = 0);
 
     /// @brief Receive IPv6 packets indirectly or data from external sockets.
@@ -1242,7 +1249,7 @@ protected:
     /// @throw isc::dhcp::SignalInterruptOnSelect when a call to select() is
     /// interrupted by a signal.
     ///
-    /// @return Pkt6 object representing received packet (or NULL)
+    /// @return Pkt6 object representing received packet (or null)
     Pkt6Ptr receive6Indirect(uint32_t timeout_sec, uint32_t timeout_usec = 0);
 
 
@@ -1305,7 +1312,7 @@ private:
     /// @param addr Link-local address to bind the socket to.
     /// @param port Port number to bind socket to.
     /// @param error_handler Error handler function to be called when an
-    /// error occurs during opening a socket, or NULL if exception should
+    /// error occurs during opening a socket, or null if exception should
     /// be thrown upon error.
     bool openMulticastSocket(Iface& iface,
                              const isc::asiolink::IOAddress& addr,
index 36d263d1511bccdfd7e188536f7a179253f0053d..91b68eb3faaa78c93e7345d731afbcc761ea90fd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2020 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
@@ -487,7 +487,15 @@ void IfaceMgr::detectIfaces() {
         }
 
         nl.ipaddrs_get(*iface, addr_info);
-        addInterface(iface);
+
+        // addInterface can now throw so protect against memory leaks.
+        try {
+            addInterface(iface);
+        } catch (...) {
+            nl.release_list(link_info);
+            nl.release_list(addr_info);
+            throw;
+        }
     }
 
     nl.release_list(link_info);
index ff68afa59ab6bb6aefe0301c4c4362598b2ccbe5..4cdb0e53ba790afa8f76babbdde1b597e0ec6352 100644 (file)
@@ -90,6 +90,16 @@ PktFilterInet6::openSocket(const Iface& iface,
     }
 #endif
 
+#ifdef IPV6_V6ONLY
+    // Set IPV6_V6ONLY to get only IPv6 packets.
+    if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+                   (char *)&flag, sizeof(flag)) < 0) {
+          close(sock);
+          isc_throw(SocketConfigError, "Can't set IPPROTO_IPV6 option on "
+                    "IPv6 socket.");
+    }
+#endif
+
     if (bind(sock, (struct sockaddr *)&addr6, sizeof(addr6)) < 0) {
         // Get the error message immediately after the bind because the
         // invocation to close() below would override the errno.
@@ -99,6 +109,7 @@ PktFilterInet6::openSocket(const Iface& iface,
                   << addr.toText() << "/port=" << port
                   << ": " << errmsg);
     }
+
 #ifdef IPV6_RECVPKTINFO
     // RFC3542 - a new way
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO,
index 95e704a46db6005ab0d3cf13abf3359afe97e39c..c12c6e3e3b927e8cc000bb12750976f76dcc1f92 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2020 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
@@ -15,6 +15,17 @@ namespace isc {
 namespace dhcp {
 namespace test {
 
+//@{
+/// @brief Index of the lo fake interface.
+const uint32_t LO_INDEX = 0;
+
+/// @brief Index of the eth0 fake interface.
+const uint32_t ETH0_INDEX = 1;
+
+/// @brief Index of the eth1 fake interface.
+const uint32_t ETH1_INDEX = 2;
+//@}
+
 ///
 /// @name Set of structures describing interface flags.
 ///
@@ -109,14 +120,14 @@ struct FlagInactive6 {
 /// The class allows the caller to create custom fake interfaces (with custom
 /// IPv4 and IPv6 addresses, flags etc.), but it also provides a default
 /// test configuration for interfaces as follows:
-/// - lo
+/// - lo #0
 ///   - 127.0.0.1
 ///   - ::1
-/// - eth0
+/// - eth0 #1
 ///   - 10.0.0.1
 ///   - fe80::3a60:77ff:fed5:cdef
 ///   - 2001:db8:1::1
-/// - eth1
+/// - eth1 #2
 ///   - 192.0.2.3
 ///   - fe80::3a60:77ff:fed5:abcd
 ///
index b542a2e055546556a3d2f6b99ea9e9218204d210..3d153ad233ef6f3de7d13b5e9cae8a398e28bc33 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2020 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
@@ -40,7 +40,8 @@ namespace {
 
 // Name of loopback interface detection
 const size_t BUF_SIZE = 32;
-char LOOPBACK[BUF_SIZE] = "lo";
+char LOOPBACK_NAME[BUF_SIZE] = "lo";
+uint32_t LOOPBACK_INDEX = 0;
 
 // Ports used during testing
 const uint16_t PORT1 = 10547;   // V6 socket
@@ -201,14 +202,15 @@ public:
         // Poor man's interface detection.  It will go away as soon as proper
         // interface detection is implemented
         if (if_nametoindex("lo") > 0) {
-            snprintf(LOOPBACK, BUF_SIZE - 1, "lo");
+            snprintf(LOOPBACK_NAME, BUF_SIZE - 1, "lo");
         } else if (if_nametoindex("lo0") > 0) {
-            snprintf(LOOPBACK, BUF_SIZE - 1, "lo0");
+            snprintf(LOOPBACK_NAME, BUF_SIZE - 1, "lo0");
         } else {
             cout << "Failed to detect loopback interface. Neither "
                  << "lo nor lo0 worked. I give up." << endl;
             FAIL();
         }
+        LOOPBACK_INDEX = if_nametoindex(LOOPBACK_NAME);
     }
 
     /// @brief Returns the collection of existing interfaces.
@@ -337,7 +339,6 @@ public:
             }
         }
     }
-
 };
 
 /// @brief A test fixture class for IfaceMgr.
@@ -471,8 +472,8 @@ public:
         IOAddress lo_addr("::1");
         int socket1 = 0, socket2 = 0;
         EXPECT_NO_THROW(
-            socket1 = ifacemgr->openSocket(LOOPBACK, lo_addr, 10547);
-            socket2 = ifacemgr->openSocket(LOOPBACK, lo_addr, 10546);
+            socket1 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr, 10547);
+            socket2 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr, 10546);
         );
 
         EXPECT_GE(socket1, 0);
@@ -507,8 +508,8 @@ public:
         sendPkt->repack();
         sendPkt->setRemotePort(10547);
         sendPkt->setRemoteAddr(IOAddress("::1"));
-        sendPkt->setIndex(1);
-        sendPkt->setIface(LOOPBACK);
+        sendPkt->setIndex(LOOPBACK_INDEX);
+        sendPkt->setIface(LOOPBACK_NAME);
 
         // Send the packet.
         EXPECT_EQ(true, ifacemgr->send(sendPkt));
@@ -537,7 +538,6 @@ public:
         ASSERT_FALSE(ifacemgr->isDHCPReceiverRunning());
     }
 
-
     /// @brief Tests the ability to send and receive DHCPv4 packets
     ///
     /// This test calls @r IfaceMgr::configureDHCPPacketQueue, passing in the
@@ -559,7 +559,8 @@ public:
         IOAddress lo_addr("127.0.0.1");
         int socket1 = 0;
         EXPECT_NO_THROW(
-            socket1 = ifacemgr->openSocket(LOOPBACK, lo_addr, DHCP4_SERVER_PORT + 10000);
+            socket1 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr,
+                                           DHCP4_SERVER_PORT + 10000);
         );
 
         EXPECT_GE(socket1, 0);
@@ -588,8 +589,8 @@ public:
         sendPkt->setLocalPort(DHCP4_SERVER_PORT + 10000 + 1);
         sendPkt->setRemotePort(DHCP4_SERVER_PORT + 10000);
         sendPkt->setRemoteAddr(IOAddress("127.0.0.1"));
-        sendPkt->setIndex(1);
-        sendPkt->setIface(string(LOOPBACK));
+        sendPkt->setIndex(LOOPBACK_INDEX);
+        sendPkt->setIface(string(LOOPBACK_NAME));
         sendPkt->setHops(6);
         sendPkt->setSecs(42);
         sendPkt->setCiaddr(IOAddress("192.0.2.1"));
@@ -844,7 +845,6 @@ public:
 
     /// Holds the invocation counter for ifaceMgrErrorHandler.
     int errors_count_;
-
 };
 
 // We need some known interface to work reliably. Loopback interface is named
@@ -951,7 +951,6 @@ TEST_F(IfaceMgrTest, ifaceGetAddress) {
     // This new address should now be returned.
     EXPECT_TRUE(iface.getAddress4(addr));
     EXPECT_EQ("192.0.2.3", addr.toText());
-
 }
 
 // This test checks if it is possible to check that the specific address is
@@ -998,7 +997,6 @@ TEST_F(IfaceMgrTest, getIface) {
         cout << "  " << (*iface)->getFullName() << endl;
     }
 
-
     // Check that interface can be retrieved by ifindex
     IfacePtr tmp = ifacemgr->getIface(102);
     ASSERT_TRUE(tmp);
@@ -1075,7 +1073,7 @@ TEST_F(IfaceMgrTest, receiveTimeout6) {
     IOAddress lo_addr("::1");
     int socket1 = 0;
     ASSERT_NO_THROW(
-        socket1 = ifacemgr->openSocket(LOOPBACK, lo_addr, 10547)
+        socket1 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr, 10547)
     );
     // Socket is open if result is non-negative.
     ASSERT_GE(socket1, 0);
@@ -1132,7 +1130,7 @@ TEST_F(IfaceMgrTest, receiveTimeout4) {
     IOAddress lo_addr("127.0.0.1");
     int socket1 = 0;
     ASSERT_NO_THROW(
-        socket1 = ifacemgr->openSocket(LOOPBACK, lo_addr, 10067)
+        socket1 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr, 10067)
     );
     // Socket is open if returned value is non-negative.
     ASSERT_GE(socket1, 0);
@@ -1188,7 +1186,7 @@ TEST_F(IfaceMgrTest, multipleSockets) {
     // Create socket #1
     int socket1 = 0;
     ASSERT_NO_THROW(
-        socket1 = ifacemgr->openSocketFromIface(LOOPBACK, PORT1, AF_INET);
+        socket1 = ifacemgr->openSocketFromIface(LOOPBACK_NAME, PORT1, AF_INET);
     );
     ASSERT_GE(socket1, 0);
     init_sockets.push_back(socket1);
@@ -1204,11 +1202,12 @@ TEST_F(IfaceMgrTest, multipleSockets) {
 
     // Get loopback interface. If we don't find one we are unable to run
     // this test but we don't want to fail.
-    IfacePtr iface_ptr = ifacemgr->getIface(LOOPBACK);
+    IfacePtr iface_ptr = ifacemgr->getIface(LOOPBACK_NAME);
     if (iface_ptr == NULL) {
         cout << "Local loopback interface not found. Skipping test. " << endl;
         return;
     }
+    ASSERT_EQ(LOOPBACK_INDEX, iface_ptr->getIndex());
     // Once sockets have been successfully opened, they are supposed to
     // be on the list. Here we start to test if all expected sockets
     // are on the list and no other (unexpected) socket is there.
@@ -1275,17 +1274,17 @@ TEST_F(IfaceMgrTest, sockets6) {
 
     IOAddress lo_addr("::1");
 
-    Pkt6 pkt6(DHCPV6_SOLICIT, 123);
-    pkt6.setIface(LOOPBACK);
+    Pkt6Ptr pkt6(new Pkt6(DHCPV6_SOLICIT, 123));
+    pkt6->setIface(LOOPBACK_NAME);
 
     // Bind multicast socket to port 10547
-    int socket1 = ifacemgr->openSocket(LOOPBACK, lo_addr, 10547);
+    int socket1 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr, 10547);
     EXPECT_GE(socket1, 0); // socket >= 0
 
     EXPECT_EQ(socket1, ifacemgr->getSocket(pkt6));
 
     // Bind unicast socket to port 10548
-    int socket2 = ifacemgr->openSocket(LOOPBACK, lo_addr, 10548);
+    int socket2 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr, 10548);
     EXPECT_GE(socket2, 0);
 
     // Removed code for binding socket twice to the same address/port
@@ -1298,7 +1297,7 @@ TEST_F(IfaceMgrTest, sockets6) {
     // Use address that is not assigned to LOOPBACK iface.
     IOAddress invalidAddr("::2");
     EXPECT_THROW(
-        ifacemgr->openSocket(LOOPBACK, invalidAddr, 10547),
+        ifacemgr->openSocket(LOOPBACK_NAME, invalidAddr, 10547),
         SocketConfigError
     );
 
@@ -1318,7 +1317,7 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
     // Open v6 socket on loopback interface and bind to port
     int socket1 = 0;
     EXPECT_NO_THROW(
-        socket1 = ifacemgr->openSocketFromIface(LOOPBACK, PORT1, AF_INET6);
+        socket1 = ifacemgr->openSocketFromIface(LOOPBACK_NAME, PORT1, AF_INET6);
     );
     // Socket descriptor must be non-negative integer
     EXPECT_GE(socket1, 0);
@@ -1327,7 +1326,7 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
     // Open v4 socket on loopback interface and bind to different port
     int socket2 = 0;
     EXPECT_NO_THROW(
-        socket2 = ifacemgr->openSocketFromIface(LOOPBACK, PORT2, AF_INET);
+        socket2 = ifacemgr->openSocketFromIface(LOOPBACK_NAME, PORT2, AF_INET);
     );
     // socket descriptor must be non-negative integer
     EXPECT_GE(socket2, 0);
@@ -1430,12 +1429,12 @@ TEST_F(IfaceMgrTest, DISABLED_sockets6Mcast) {
     IOAddress mcastAddr("ff02::1:2");
 
     // bind multicast socket to port 10547
-    int socket1 = ifacemgr->openSocket(LOOPBACK, mcastAddr, 10547);
+    int socket1 = ifacemgr->openSocket(LOOPBACK_NAME, mcastAddr, 10547);
     EXPECT_GE(socket1, 0); // socket > 0
 
     // expect success. This address/port is already bound, but
     // we are using SO_REUSEADDR, so we can bind it twice
-    int socket2 = ifacemgr->openSocket(LOOPBACK, mcastAddr, 10547);
+    int socket2 = ifacemgr->openSocket(LOOPBACK_NAME, mcastAddr, 10547);
     EXPECT_GE(socket2, 0);
 
     // there's no good way to test negative case here.
@@ -1508,7 +1507,8 @@ TEST_F(IfaceMgrTest, setPacketFilter) {
     IOAddress lo_addr("127.0.0.1");
     int socket1 = 0;
     EXPECT_NO_THROW(
-        socket1 = iface_mgr->openSocket(LOOPBACK, lo_addr, DHCP4_SERVER_PORT + 10000);
+        socket1 = iface_mgr->openSocket(LOOPBACK_NAME, lo_addr,
+                                        DHCP4_SERVER_PORT + 10000);
     );
 
     // Check that openSocket function was called.
@@ -1548,7 +1548,7 @@ TEST_F(IfaceMgrTest, setPacketFilter6) {
     IOAddress lo_addr("::1");
     int socket1 = 0;
     EXPECT_NO_THROW(
-        socket1 = iface_mgr->openSocket(LOOPBACK, lo_addr,
+        socket1 = iface_mgr->openSocket(LOOPBACK_NAME, lo_addr,
                                         DHCP6_SERVER_PORT + 10000);
     );
     // Check that openSocket function has been actually called on the packet
@@ -1565,10 +1565,8 @@ TEST_F(IfaceMgrTest, setPacketFilter6) {
     // So, let's close the sockets and retry. Now it should succeed.
     iface_mgr->closeSockets();
     EXPECT_NO_THROW(iface_mgr->setPacketFilter(custom_packet_filter));
-
 }
 
-
 #if defined OS_LINUX || OS_BSD
 
 // This test is only supported on Linux and BSD systems. It checks
@@ -1617,7 +1615,7 @@ TEST_F(IfaceMgrTest, checkPacketFilterRawSocket) {
     // PktFilterInet.
     EXPECT_NO_THROW(iface_mgr1->setMatchingPacketFilter(false));
     // Let's open a loopback socket with handy unpriviliged port number
-    socket1 = iface_mgr1->openSocket(LOOPBACK, lo_addr,
+    socket1 = iface_mgr1->openSocket(LOOPBACK_NAME, lo_addr,
                                      DHCP4_SERVER_PORT + 10000);
 
     EXPECT_GE(socket1, 0);
@@ -1628,7 +1626,7 @@ TEST_F(IfaceMgrTest, checkPacketFilterRawSocket) {
     // The socket is open and bound. Another attempt to open socket and
     // bind to the same address and port should result in an exception.
     EXPECT_THROW(
-        socket2 = iface_mgr2->openSocket(LOOPBACK, lo_addr,
+        socket2 = iface_mgr2->openSocket(LOOPBACK_NAME, lo_addr,
                                          DHCP4_SERVER_PORT + 10000),
         isc::dhcp::SocketConfigError
     );
@@ -1691,13 +1689,15 @@ TEST_F(IfaceMgrTest, socket4) {
     int socket1 = 0;
 
     EXPECT_NO_THROW(
-        socket1 = ifacemgr->openSocket(LOOPBACK, lo_addr, DHCP4_SERVER_PORT + 10000);
+        socket1 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr,
+                                       DHCP4_SERVER_PORT + 10000);
     );
 
     EXPECT_GE(socket1, 0);
 
-    Pkt4 pkt(DHCPDISCOVER, 1234);
-    pkt.setIface(LOOPBACK);
+    Pkt4Ptr pkt(new Pkt4(DHCPDISCOVER, 1234));
+    pkt->setIface(LOOPBACK_NAME);
+    pkt->setIndex(LOOPBACK_INDEX);
 
     // Expect that we get the socket that we just opened.
     EXPECT_EQ(socket1, ifacemgr->getSocket(pkt).sockfd_);
@@ -1725,9 +1725,12 @@ TEST_F(IfaceMgrTest, openSockets4) {
 
     // Expect that the sockets are open on both eth0 and eth1.
     EXPECT_EQ(1, ifacemgr.getIface("eth0")->getSockets().size());
+    EXPECT_EQ(1, ifacemgr.getIface(1)->getSockets().size());
     EXPECT_EQ(1, ifacemgr.getIface("eth1")->getSockets().size());
+    EXPECT_EQ(1, ifacemgr.getIface(2)->getSockets().size());
     // Socket shouldn't have been opened on loopback.
     EXPECT_TRUE(ifacemgr.getIface("lo")->getSockets().empty());
+    EXPECT_TRUE(ifacemgr.getIface(0)->getSockets().empty());
 }
 
 // This test verifies that IPv4 sockets are open on the loopback interface
@@ -1755,8 +1758,11 @@ TEST_F(IfaceMgrTest, openSockets4Loopback) {
 
     // Expect that the sockets are open on all interfaces.
     EXPECT_EQ(1, ifacemgr.getIface("eth0")->getSockets().size());
+    EXPECT_EQ(1, ifacemgr.getIface(1)->getSockets().size());
     EXPECT_EQ(1, ifacemgr.getIface("eth1")->getSockets().size());
+    EXPECT_EQ(1, ifacemgr.getIface(2)->getSockets().size());
     EXPECT_EQ(1, ifacemgr.getIface("lo")->getSockets().size());
+    EXPECT_EQ(1, ifacemgr.getIface(0)->getSockets().size());
 }
 
 // This test verifies that the socket is not open on the interface which is
@@ -1773,6 +1779,7 @@ TEST_F(IfaceMgrTest, openSockets4IfaceDown) {
                          FlagRunning(false), FlagInactive4(false),
                          FlagInactive6(false));
     ASSERT_FALSE(IfaceMgr::instance().getIface("eth0")->flag_up_);
+    ASSERT_FALSE(IfaceMgr::instance().getIface(1)->flag_up_);
 
     // Install an error handler before trying to open sockets. This handler
     // should be called when the IfaceMgr fails to open socket on an interface
@@ -1788,13 +1795,15 @@ TEST_F(IfaceMgrTest, openSockets4IfaceDown) {
 
     // There should be no socket on eth0 open, because interface was down.
     EXPECT_TRUE(IfaceMgr::instance().getIface("eth0")->getSockets().empty());
+    EXPECT_TRUE(IfaceMgr::instance().getIface(1)->getSockets().empty());
 
     // Expecting that the socket is open on eth1 because it was up, running
     // and active.
     EXPECT_EQ(2, IfaceMgr::instance().getIface("eth1")->getSockets().size());
+    EXPECT_EQ(2, IfaceMgr::instance().getIface(2)->getSockets().size());
     // Never open socket on loopback interface.
     EXPECT_TRUE(IfaceMgr::instance().getIface("lo")->getSockets().empty());
-
+    EXPECT_TRUE(IfaceMgr::instance().getIface(0)->getSockets().empty());
 }
 
 // This test verifies that the socket is not open on the interface which is
@@ -1817,15 +1826,19 @@ TEST_F(IfaceMgrTest, openSockets4IfaceInactive) {
     // - is inactive
     ifacemgr.setIfaceFlags("eth1", false, true, true, true, false);
     ASSERT_TRUE(ifacemgr.getIface("eth1")->inactive4_);
+    ASSERT_TRUE(ifacemgr.getIface(2)->inactive4_);
     ASSERT_NO_THROW(ifacemgr.openSockets4(DHCP4_SERVER_PORT, true, 0));
 
     // The socket on eth0 should be open because interface is up, running and
     // active (not disabled through DHCP configuration, for example).
     EXPECT_EQ(1, ifacemgr.getIface("eth0")->getSockets().size());
+    EXPECT_EQ(1, ifacemgr.getIface(1)->getSockets().size());
     // There should be no socket open on eth1 because it was marked inactive.
     EXPECT_TRUE(ifacemgr.getIface("eth1")->getSockets().empty());
+    EXPECT_TRUE(ifacemgr.getIface(2)->getSockets().empty());
     // Sockets are not open on loopback interfaces too.
     EXPECT_TRUE(ifacemgr.getIface("lo")->getSockets().empty());
+    EXPECT_TRUE(ifacemgr.getIface(0)->getSockets().empty());
 }
 
 // Test that exception is thrown when trying to bind a new socket to the port
@@ -1850,7 +1863,6 @@ TEST_F(IfaceMgrTest, openSockets4NoErrorHandler) {
     // and bind it to the address in use.
     EXPECT_THROW(ifacemgr.openSockets4(DHCP4_SERVER_PORT, true, 0),
                  isc::dhcp::SocketConfigError);
-
 }
 
 // Test that the external error handler is called when trying to bind a new
@@ -1890,7 +1902,6 @@ TEST_F(IfaceMgrTest, openSocket4ErrorHandler) {
     // when opening a socket on eth1.
     ASSERT_NO_THROW(ifacemgr.openSockets4(DHCP4_SERVER_PORT, true, error_handler));
     EXPECT_EQ(2, errors_count_);
-
 }
 
 // This test verifies that the function correctly checks that the v4 socket is
@@ -1912,9 +1923,12 @@ TEST_F(IfaceMgrTest, hasOpenSocketForAddress4) {
 
     // Expect that the sockets are open on both eth0 and eth1.
     ASSERT_EQ(1, ifacemgr.getIface("eth0")->getSockets().size());
+    ASSERT_EQ(1, ifacemgr.getIface(1)->getSockets().size());
     ASSERT_EQ(1, ifacemgr.getIface("eth1")->getSockets().size());
+    ASSERT_EQ(1, ifacemgr.getIface(2)->getSockets().size());
     // Socket shouldn't have been opened on loopback.
     ASSERT_TRUE(ifacemgr.getIface("lo")->getSockets().empty());
+    ASSERT_TRUE(ifacemgr.getIface(0)->getSockets().empty());
 
     // Check that there are sockets bound to addresses that we have
     // set for interfaces.
@@ -1927,7 +1941,6 @@ TEST_F(IfaceMgrTest, hasOpenSocketForAddress4) {
     // Check that v4 sockets are open, but no v6 socket is open.
     EXPECT_TRUE(ifacemgr.hasOpenSocket(AF_INET));
     EXPECT_FALSE(ifacemgr.hasOpenSocket(AF_INET6));
-
 }
 
 // This test checks that the sockets are open and bound to link local addresses
@@ -1949,8 +1962,11 @@ TEST_F(IfaceMgrTest, openSockets6LinkLocal) {
 
     // Check that the number of sockets is correct on each interface.
     checkSocketsCount6(*ifacemgr.getIface("lo"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(0), 0);
     checkSocketsCount6(*ifacemgr.getIface("eth0"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(1), 0);
     checkSocketsCount6(*ifacemgr.getIface("eth1"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(2), 0);
 
     // Sockets on eth0 should be bound to link-local and should not be bound
     // to global unicast address, even though this address is configured on
@@ -1996,6 +2012,7 @@ TEST_F(IfaceMgrTest, openSockets6Loopback) {
 
     // Check that the loopback interface has at least an open socket.
     EXPECT_EQ(1, ifacemgr.getIface("lo")->getSockets().size());
+    EXPECT_EQ(1, ifacemgr.getIface(0)->getSockets().size());
 
     // This socket should be bound to ::1
     EXPECT_TRUE(ifacemgr.isBound("lo", "::1"));
@@ -2025,10 +2042,13 @@ TEST_F(IfaceMgrTest, openSockets6NoLinkLocal) {
 
     // Check that the number of sockets is correct on each interface.
     checkSocketsCount6(*ifacemgr.getIface("lo"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(0), 0);
     // The third parameter specifies that the number of link-local
     // addresses for eth0 is equal to 0.
     checkSocketsCount6(*ifacemgr.getIface("eth0"), 0, 0);
+    checkSocketsCount6(*ifacemgr.getIface(1), 0, 0);
     checkSocketsCount6(*ifacemgr.getIface("eth1"), 0, 1);
+    checkSocketsCount6(*ifacemgr.getIface(2), 0, 1);
 
     // There should be no sockets open on eth0 because it neither has
     // link-local nor global unicast addresses.
@@ -2041,7 +2061,6 @@ TEST_F(IfaceMgrTest, openSockets6NoLinkLocal) {
 #if defined OS_LINUX
     EXPECT_FALSE(ifacemgr.isBound("eth0", ALL_DHCP_RELAY_AGENTS_AND_SERVERS));
 #endif
-
 }
 
 // This test checks that socket is open on the non-multicast-capable
@@ -2066,8 +2085,11 @@ TEST_F(IfaceMgrTest, openSockets6NotMulticast) {
 
     // Check that the number of sockets is correct on each interface.
     checkSocketsCount6(*ifacemgr.getIface("lo"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(0), 0);
     checkSocketsCount6(*ifacemgr.getIface("eth0"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(1), 0);
     checkSocketsCount6(*ifacemgr.getIface("eth1"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(2), 0);
 
     // Sockets on eth0 should be bound to link-local and should not be bound
     // to global unicast address, even though this address is configured on
@@ -2110,8 +2132,11 @@ TEST_F(IfaceMgrTest, openSockets6Unicast) {
 
     // Check that we have correct number of sockets on each interface.
     checkSocketsCount6(*ifacemgr.getIface("lo"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(0), 0);
     checkSocketsCount6(*ifacemgr.getIface("eth0"), 1); // one unicast address.
+    checkSocketsCount6(*ifacemgr.getIface(1), 1);
     checkSocketsCount6(*ifacemgr.getIface("eth1"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(2), 0);
 
     // eth0 should have two sockets, one bound to link-local, another one
     // bound to unicast address.
@@ -2125,7 +2150,6 @@ TEST_F(IfaceMgrTest, openSockets6Unicast) {
     EXPECT_TRUE(ifacemgr.isBound("eth0", ALL_DHCP_RELAY_AGENTS_AND_SERVERS));
     EXPECT_TRUE(ifacemgr.isBound("eth1", ALL_DHCP_RELAY_AGENTS_AND_SERVERS));
 #endif
-
 }
 
 // This test checks that the socket is open and bound to a global unicast
@@ -2155,8 +2179,11 @@ TEST_F(IfaceMgrTest, openSockets6UnicastOnly) {
 
     // Check that we have correct number of sockets on each interface.
     checkSocketsCount6(*ifacemgr.getIface("lo"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(0), 0);
     checkSocketsCount6(*ifacemgr.getIface("eth0"), 1, 0);
+    checkSocketsCount6(*ifacemgr.getIface(1), 1, 0);
     checkSocketsCount6(*ifacemgr.getIface("eth1"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(2), 0);
 
     // The link-local address is not present on eth0. Therefore, no socket
     // must be bound to this address, nor to multicast address.
@@ -2171,7 +2198,6 @@ TEST_F(IfaceMgrTest, openSockets6UnicastOnly) {
 #if defined OS_LINUX
     EXPECT_TRUE(ifacemgr.isBound("eth1", ALL_DHCP_RELAY_AGENTS_AND_SERVERS));
 #endif
-
 }
 
 // This test checks that no sockets are open for the interface which is down.
@@ -2213,9 +2239,12 @@ TEST_F(IfaceMgrTest, openSockets6IfaceDown) {
 
     // Check that we have correct number of sockets on each interface.
     checkSocketsCount6(*ifacemgr.getIface("lo"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(0), 0);
     // There should be no sockets on eth0 because interface is down.
     ASSERT_TRUE(ifacemgr.getIface("eth0")->getSockets().empty());
+    ASSERT_TRUE(ifacemgr.getIface(1)->getSockets().empty());
     checkSocketsCount6(*ifacemgr.getIface("eth1"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(2), 0);
 
     // eth0 should have no sockets because the interface is down.
     EXPECT_FALSE(ifacemgr.isBound("eth0", "fe80::3a60:77ff:fed5:cdef"));
@@ -2228,7 +2257,6 @@ TEST_F(IfaceMgrTest, openSockets6IfaceDown) {
 #if defined OS_LINUX
     EXPECT_TRUE(ifacemgr.isBound("eth1", ALL_DHCP_RELAY_AGENTS_AND_SERVERS));
 #endif
-
 }
 
 // This test checks that no sockets are open for the interface which is
@@ -2262,9 +2290,12 @@ TEST_F(IfaceMgrTest, openSockets6IfaceInactive) {
 
     // Check that we have correct number of sockets on each interface.
     checkSocketsCount6(*ifacemgr.getIface("lo"), 0);
+    checkSocketsCount6(*ifacemgr.getIface(0), 0);
     checkSocketsCount6(*ifacemgr.getIface("eth0"), 1); // one unicast address
+    checkSocketsCount6(*ifacemgr.getIface(1), 1);
     // There should be no sockets on eth1 because interface is inactive
     ASSERT_TRUE(ifacemgr.getIface("eth1")->getSockets().empty());
+    ASSERT_TRUE(ifacemgr.getIface(2)->getSockets().empty());
 
     // eth0 should have one socket bound to a link-local address, another one
     // bound to unicast address.
@@ -2280,7 +2311,6 @@ TEST_F(IfaceMgrTest, openSockets6IfaceInactive) {
 #if defined OS_LINUX
     EXPECT_TRUE(ifacemgr.isBound("eth0", ALL_DHCP_RELAY_AGENTS_AND_SERVERS));
 #endif
-
 }
 
 // Test that the openSockets6 function does not throw if there are no interfaces
@@ -2339,7 +2369,6 @@ TEST_F(IfaceMgrTest, openSocket6ErrorHandler) {
     // when opening a socket on eth1.
     ASSERT_NO_THROW(ifacemgr.openSockets6(DHCP6_SERVER_PORT, error_handler));
     EXPECT_EQ(2, errors_count_);
-
 }
 
 // This test verifies that the function correctly checks that the v6 socket is
@@ -2374,7 +2403,6 @@ TEST_F(IfaceMgrTest, hasOpenSocketForAddress6) {
     // Check that there is no socket bound to the address which hasn't been
     // configured on any interface.
     EXPECT_FALSE(ifacemgr.hasOpenSocket(IOAddress("fe80::3a60:77ff:feed:1")));
-
 }
 
 // Test the Iface structure itself
@@ -2478,13 +2506,13 @@ TEST_F(IfaceMgrTest, socketInfo) {
 
     // Now let's test if IfaceMgr handles socket info properly
     scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
-    IfacePtr loopback = ifacemgr->getIface(LOOPBACK);
+    IfacePtr loopback = ifacemgr->getIface(LOOPBACK_NAME);
     ASSERT_TRUE(loopback);
     loopback->addSocket(sock1);
     loopback->addSocket(sock2);
     loopback->addSocket(sock3);
 
-    Pkt6 pkt6(DHCPV6_REPLY, 123456);
+    Pkt6Ptr pkt6(new Pkt6(DHCPV6_REPLY, 123456));
 
     // pkt6 does not have interface set yet
     EXPECT_THROW(
@@ -2493,19 +2521,22 @@ TEST_F(IfaceMgrTest, socketInfo) {
     );
 
     // Try to send over non-existing interface
-    pkt6.setIface("nosuchinterface45");
+    pkt6->setIface("nosuchinterface45");
+    pkt6->setIndex(12345);
     EXPECT_THROW(
         ifacemgr->getSocket(pkt6),
         IfaceNotFound
     );
 
     // This will work
-    pkt6.setIface(LOOPBACK);
+    pkt6->setIface(LOOPBACK_NAME);
+    EXPECT_EQ(9, ifacemgr->getSocket(pkt6));
+    pkt6->setIndex(LOOPBACK_INDEX);
     EXPECT_EQ(9, ifacemgr->getSocket(pkt6));
 
     bool deleted = false;
     EXPECT_NO_THROW(
-        deleted = ifacemgr->getIface(LOOPBACK)->delSocket(9);
+        deleted = ifacemgr->getIface(LOOPBACK_NAME)->delSocket(9);
     );
     EXPECT_EQ(true, deleted);
 
@@ -2516,7 +2547,7 @@ TEST_F(IfaceMgrTest, socketInfo) {
     );
 
     // Repeat for pkt4
-    Pkt4 pkt4(DHCPDISCOVER, 1);
+    Pkt4Ptr pkt4(new Pkt4(DHCPDISCOVER, 1));
 
     // pkt4 does not have interface set yet.
     EXPECT_THROW(
@@ -2525,29 +2556,32 @@ TEST_F(IfaceMgrTest, socketInfo) {
     );
 
     // Try to send over non-existing interface.
-    pkt4.setIface("nosuchinterface45");
+    pkt4->setIface("nosuchinterface45");
+    pkt4->setIndex(12345);
     EXPECT_THROW(
         ifacemgr->getSocket(pkt4),
         IfaceNotFound
     );
 
     // Socket info is set, packet has well defined interface. It should work.
-    pkt4.setIface(LOOPBACK);
+    pkt4->setIface(LOOPBACK_NAME);
+    EXPECT_EQ(7, ifacemgr->getSocket(pkt4).sockfd_);
+    pkt4->setIndex(LOOPBACK_INDEX);
     EXPECT_EQ(7, ifacemgr->getSocket(pkt4).sockfd_);
 
     // Set the local address to check if the socket for this address will
     // be returned.
-    pkt4.setLocalAddr(IOAddress("192.0.2.56"));
+    pkt4->setLocalAddr(IOAddress("192.0.2.56"));
     EXPECT_EQ(7, ifacemgr->getSocket(pkt4).sockfd_);
 
     // Modify the local address and expect that the other socket will be
     // returned.
-    pkt4.setLocalAddr(IOAddress("192.0.2.53"));
+    pkt4->setLocalAddr(IOAddress("192.0.2.53"));
     EXPECT_EQ(8, ifacemgr->getSocket(pkt4).sockfd_);
 
     EXPECT_NO_THROW(
-        ifacemgr->getIface(LOOPBACK)->delSocket(7);
-        ifacemgr->getIface(LOOPBACK)->delSocket(8);
+        ifacemgr->getIface(LOOPBACK_NAME)->delSocket(7);
+        ifacemgr->getIface(LOOPBACK_NAME)->delSocket(8);
     );
 
     // It should throw again, there's no usable socket anymore.
@@ -3177,7 +3211,7 @@ TEST_F(IfaceMgrTest, DISABLED_openUnicastSockets) {
 TEST_F(IfaceMgrTest, unicastDuplicates) {
     NakedIfaceMgr ifacemgr;
 
-    IfacePtr iface = ifacemgr.getIface(LOOPBACK);
+    IfacePtr iface = ifacemgr.getIface(LOOPBACK_NAME);
     if (!iface) {
         cout << "Local loopback interface not found. Skipping test. " << endl;
         return;
@@ -3214,14 +3248,14 @@ TEST_F(IfaceMgrTest, DISABLED_getSocket) {
     IOAddress dst_global("2001:db8:15c::dead:beef");
 
     // Bind loopback address
-    int socket1 = ifacemgr->openSocket(LOOPBACK, lo_addr, 10547);
+    int socket1 = ifacemgr->openSocket(LOOPBACK_NAME, lo_addr, 10547);
     EXPECT_GE(socket1, 0); // socket >= 0
 
     // Bind link-local address
-    int socket2 = ifacemgr->openSocket(LOOPBACK, link_local, 10547);
+    int socket2 = ifacemgr->openSocket(LOOPBACK_NAME, link_local, 10547);
     EXPECT_GE(socket2, 0);
 
-    int socket3 = ifacemgr->openSocket(LOOPBACK, global, 10547);
+    int socket3 = ifacemgr->openSocket(LOOPBACK_NAME, global, 10547);
     EXPECT_GE(socket3, 0);
 
     // Let's make sure those sockets are unique
@@ -3230,17 +3264,18 @@ TEST_F(IfaceMgrTest, DISABLED_getSocket) {
     EXPECT_NE(socket3, socket1);
 
     // Create a packet
-    Pkt6 pkt6(DHCPV6_SOLICIT, 123);
-    pkt6.setIface(LOOPBACK);
+    Pkt6Ptr pkt6(new Pkt6(DHCPV6_SOLICIT, 123));
+    pkt6->setIface(LOOPBACK_NAME);
+    pkt6->setIndex(LOOPBACK_INDEX);
 
     // Check that packets sent to link-local will get socket bound to link local
-    pkt6.setLocalAddr(global);
-    pkt6.setRemoteAddr(dst_global);
+    pkt6->setLocalAddr(global);
+    pkt6->setRemoteAddr(dst_global);
     EXPECT_EQ(socket3, ifacemgr->getSocket(pkt6));
 
     // Check that packets sent to link-local will get socket bound to link local
-    pkt6.setLocalAddr(link_local);
-    pkt6.setRemoteAddr(dst_link_local);
+    pkt6->setLocalAddr(link_local);
+    pkt6->setRemoteAddr(dst_link_local);
     EXPECT_EQ(socket2, ifacemgr->getSocket(pkt6));
 
     // Close sockets here because the following tests will want to
index 84b6d10ae2a0345259b235fa3e000b6034f638db..8818bd53b093e6f22ae1e1ce158ae6cf5ac5245a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2020 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
@@ -167,6 +167,7 @@ Dhcp4o6IpcBaseTest::createDHCPv4o6Message(uint16_t msg_type,
     // this test includes two interfaces: "eth0" and "eth1". Therefore,
     // we pick one or another, depending on the index of the iteration.
     pkt->setIface(concatenate("eth", postfix % 2));
+    pkt->setIndex(ETH0_INDEX + postfix % 2);
 
     // The remote address of the sender of the DHCPv6 packet is carried
     // between the servers in the dedicated option. We use different
@@ -286,6 +287,7 @@ Dhcp4o6IpcBaseTest::testSendReceive(uint16_t iterations_num,
 
         // Check that the interface is correct.
         EXPECT_EQ(concatenate("eth", i % 2), pkt_received->getIface());
+        EXPECT_EQ(ETH0_INDEX + i % 2, pkt_received->getIndex());
 
         // Check that the address conveyed is correct.
         EXPECT_EQ(concatenate("2001:db8:1::", i),
@@ -327,6 +329,7 @@ Dhcp4o6IpcBaseTest::testReceiveError(const Pkt6Ptr& pkt) {
     ASSERT_NO_THROW(ipc_dest.open());
 
     pkt->setIface("eth0");
+    pkt->setIndex(ETH0_INDEX);
     pkt->setRemoteAddr(IOAddress("2001:db8:1::1"));
     pkt->setRemotePort(TEST_PORT);
     pkt->addOption(createDHCPv4MsgOption(TestIpc::ENDPOINT_TYPE_V6));