From a0a0a9160a94d0e782f3ad97d838532a28a8d195 Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Sun, 24 May 2020 20:49:39 +0200 Subject: [PATCH] [#553] Checkpoint: convert to use interface indexes --- src/bin/dhcp4/dhcp4_srv.cc | 6 +- src/bin/dhcp4/tests/dhcp4_client.cc | 17 +- src/bin/dhcp4/tests/dhcp4_client.h | 15 +- src/bin/dhcp4/tests/dhcp4_srv_unittest.cc | 73 ++++++-- src/bin/dhcp4/tests/dhcp4_test_utils.cc | 10 +- src/bin/dhcp4/tests/dhcp4to6_ipc_unittest.cc | 7 + src/bin/dhcp4/tests/direct_client_unittest.cc | 35 ++-- src/bin/dhcp4/tests/dora_unittest.cc | 1 + src/bin/dhcp4/tests/fqdn_unittest.cc | 9 +- src/bin/dhcp4/tests/hooks_unittest.cc | 10 + src/bin/dhcp4/tests/host_unittest.cc | 5 +- .../dhcp4/tests/shared_network_unittest.cc | 25 +++ src/bin/dhcp4/tests/vendor_opts_unittest.cc | 11 ++ src/bin/dhcp6/tests/classify_unittests.cc | 14 +- src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 27 +++ src/bin/dhcp6/tests/dhcp6_test_utils.cc | 1 + src/bin/dhcp6/tests/dhcp6_test_utils.h | 5 +- src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc | 5 + src/bin/dhcp6/tests/fqdn_unittest.cc | 4 +- src/bin/dhcp6/tests/hooks_unittest.cc | 10 + src/bin/dhcp6/tests/vendor_opts_unittest.cc | 4 +- src/lib/dhcp/iface_mgr.cc | 74 +++++--- src/lib/dhcp/iface_mgr.h | 53 +++--- src/lib/dhcp/iface_mgr_linux.cc | 12 +- src/lib/dhcp/pkt_filter_inet6.cc | 11 ++ src/lib/dhcp/tests/iface_mgr_test_config.h | 19 +- src/lib/dhcp/tests/iface_mgr_unittest.cc | 177 +++++++++++------- src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc | 5 +- 28 files changed, 464 insertions(+), 181 deletions(-) diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 3b68112b87..d800f21925 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -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 diff --git a/src/bin/dhcp4/tests/dhcp4_client.cc b/src/bin/dhcp4/tests/dhcp4_client.cc index b7e861d99e..38290bda92 100644 --- a/src/bin/dhcp4/tests/dhcp4_client.cc +++ b/src/bin/dhcp4/tests/dhcp4_client.cc @@ -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 #include #include +#include #include #include #include @@ -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 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 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(); diff --git a/src/bin/dhcp4/tests/dhcp4_client.h b/src/bin/dhcp4/tests/dhcp4_client.h index e4e939cbbb..a7265a43ad 100644 --- a/src/bin/dhcp4/tests/dhcp4_client.h +++ b/src/bin/dhcp4/tests/dhcp4_client.h @@ -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_; diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 1e4b9d6d4c..9df9fef14f 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -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 diff --git a/src/bin/dhcp4/tests/dhcp4_test_utils.cc b/src/bin/dhcp4/tests/dhcp4_test_utils.cc index 74476abf53..717fba0523 100644 --- a/src/bin/dhcp4/tests/dhcp4_test_utils.cc +++ b/src/bin/dhcp4/tests/dhcp4_test_utils.cc @@ -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 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)); diff --git a/src/bin/dhcp4/tests/dhcp4to6_ipc_unittest.cc b/src/bin/dhcp4/tests/dhcp4to6_ipc_unittest.cc index 13101d61f2..2a47d71821 100644 --- a/src/bin/dhcp4/tests/dhcp4to6_ipc_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4to6_ipc_unittest.cc @@ -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 diff --git a/src/bin/dhcp4/tests/direct_client_unittest.cc b/src/bin/dhcp4/tests/direct_client_unittest.cc index 5c1c756873..dedb3b9386 100644 --- a/src/bin/dhcp4/tests/direct_client_unittest.cc +++ b/src/bin/dhcp4/tests/direct_client_unittest.cc @@ -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(client.getContext().response_->getType())); diff --git a/src/bin/dhcp4/tests/dora_unittest.cc b/src/bin/dhcp4/tests/dora_unittest.cc index e97995abf6..3a18f62f5d 100644 --- a/src/bin/dhcp4/tests/dora_unittest.cc +++ b/src/bin/dhcp4/tests/dora_unittest.cc @@ -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_); diff --git a/src/bin/dhcp4/tests/fqdn_unittest.cc b/src/bin/dhcp4/tests/fqdn_unittest.cc index 73b4064e57..2853ec213c 100644 --- a/src/bin/dhcp4/tests/fqdn_unittest.cc +++ b/src/bin/dhcp4/tests/fqdn_unittest.cc @@ -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 diff --git a/src/bin/dhcp4/tests/hooks_unittest.cc b/src/bin/dhcp4/tests/hooks_unittest.cc index a343973fe2..06cc6d333d 100644 --- a/src/bin/dhcp4/tests/hooks_unittest.cc +++ b/src/bin/dhcp4/tests/hooks_unittest.cc @@ -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(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(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(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(new IOAddress("192.0.2.100")))); // Make sure that we received a response diff --git a/src/bin/dhcp4/tests/host_unittest.cc b/src/bin/dhcp4/tests/host_unittest.cc index 65cee16bfe..85958b5de9 100644 --- a/src/bin/dhcp4/tests/host_unittest.cc +++ b/src/bin/dhcp4/tests/host_unittest.cc @@ -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 hint; + boost::shared_ptr hint; if (!requested_addr.empty()) { hint = boost::make_shared(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. diff --git a/src/bin/dhcp4/tests/shared_network_unittest.cc b/src/bin/dhcp4/tests/shared_network_unittest.cc index 5cf868c8fb..970f9a772d 100644 --- a/src/bin/dhcp4/tests/shared_network_unittest.cc +++ b/src/bin/dhcp4/tests/shared_network_unittest.cc @@ -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"); }); diff --git a/src/bin/dhcp4/tests/vendor_opts_unittest.cc b/src/bin/dhcp4/tests/vendor_opts_unittest.cc index f80cf08b67..10c09e8882 100644 --- a/src/bin/dhcp4/tests/vendor_opts_unittest.cc +++ b/src/bin/dhcp4/tests/vendor_opts_unittest.cc @@ -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, diff --git a/src/bin/dhcp6/tests/classify_unittests.cc b/src/bin/dhcp6/tests/classify_unittests.cc index b19372a16d..70185fc968 100644 --- a/src/bin/dhcp6/tests/classify_unittests.cc +++ b/src/bin/dhcp6/tests/classify_unittests.cc @@ -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 diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 0a86749797..65d7179ac6 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -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 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 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 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 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) { diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.cc b/src/bin/dhcp6/tests/dhcp6_test_utils.cc index 618a1067f5..3c297d97ac 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@ -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(); diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index d295bb7234..6b0f359780 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -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 diff --git a/src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc b/src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc index 46beca27c8..8a4616d992 100644 --- a/src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc @@ -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()); diff --git a/src/bin/dhcp6/tests/fqdn_unittest.cc b/src/bin/dhcp6/tests/fqdn_unittest.cc index 56cce1c43e..3263c7bfe5 100644 --- a/src/bin/dhcp6/tests/fqdn_unittest.cc +++ b/src/bin/dhcp6/tests/fqdn_unittest.cc @@ -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 diff --git a/src/bin/dhcp6/tests/hooks_unittest.cc b/src/bin/dhcp6/tests/hooks_unittest.cc index 381f589cbc..e472c3ff91 100644 --- a/src/bin/dhcp6/tests/hooks_unittest.cc +++ b/src/bin/dhcp6/tests/hooks_unittest.cc @@ -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 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 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 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 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 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 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); diff --git a/src/bin/dhcp6/tests/vendor_opts_unittest.cc b/src/bin/dhcp6/tests/vendor_opts_unittest.cc index 10eb6f4bf5..0836d0101d 100644 --- a/src/bin/dhcp6/tests/vendor_opts_unittest.cc +++ b/src/bin/dhcp6/tests/vendor_opts_unittest.cc @@ -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); diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc index e5fee84ffc..ab8c18e3a0 100644 --- a/src/lib/dhcp/iface_mgr.cc +++ b/src/lib/dhcp/iface_mgr.cc @@ -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); } diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h index 69309eed9e..5e1b934732 100644 --- a/src/lib/dhcp/iface_mgr.h +++ b/src/lib/dhcp/iface_mgr.h @@ -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, diff --git a/src/lib/dhcp/iface_mgr_linux.cc b/src/lib/dhcp/iface_mgr_linux.cc index 36d263d151..91b68eb3fa 100644 --- a/src/lib/dhcp/iface_mgr_linux.cc +++ b/src/lib/dhcp/iface_mgr_linux.cc @@ -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); diff --git a/src/lib/dhcp/pkt_filter_inet6.cc b/src/lib/dhcp/pkt_filter_inet6.cc index ff68afa59a..4cdb0e53ba 100644 --- a/src/lib/dhcp/pkt_filter_inet6.cc +++ b/src/lib/dhcp/pkt_filter_inet6.cc @@ -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, diff --git a/src/lib/dhcp/tests/iface_mgr_test_config.h b/src/lib/dhcp/tests/iface_mgr_test_config.h index 95e704a46d..c12c6e3e3b 100644 --- a/src/lib/dhcp/tests/iface_mgr_test_config.h +++ b/src/lib/dhcp/tests/iface_mgr_test_config.h @@ -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 /// diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc index b542a2e055..3d153ad233 100644 --- a/src/lib/dhcp/tests/iface_mgr_unittest.cc +++ b/src/lib/dhcp/tests/iface_mgr_unittest.cc @@ -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 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 diff --git a/src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc b/src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc index 84b6d10ae2..8818bd53b0 100644 --- a/src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc +++ b/src/lib/dhcpsrv/tests/dhcp4o6_ipc_unittest.cc @@ -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)); -- 2.47.3