/// @return Generated message.
Pkt4Ptr createClientMessage(const uint16_t msg_type,
const std::string& iface,
- const uint32_t ifindex);
+ const unsigned int ifindex);
/// @brief Creates simple message from a client.
///
/// @return Configured and parsed message.
Pkt4Ptr createClientMessage(const Pkt4Ptr &msg,
const std::string& iface,
- const uint32_t ifindex);
+ const unsigned int ifindex);
/// @brief This test checks that the message from directly connected client
/// is processed and that client is offered IPv4 address from the subnet
Pkt4Ptr
DirectClientTest::createClientMessage(const uint16_t msg_type,
const std::string& iface,
- const uint32_t ifindex) {
+ const unsigned int ifindex) {
// Create a source packet.
Pkt4Ptr msg = Pkt4Ptr(new Pkt4(msg_type, 1234));
return (createClientMessage(msg, iface, ifindex));
Pkt4Ptr
DirectClientTest::createClientMessage(const Pkt4Ptr& msg,
const std::string& iface,
- const uint32_t ifindex) {
+ const unsigned int ifindex) {
msg->setRemoteAddr(IOAddress("255.255.255.255"));
msg->addOption(generateClientId());
msg->setIface(iface);
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-/// @file dhcp6_test_utils.h
+/// @file dhcp6_test_utils.h
///
/// @brief This file contains utility classes used for DHCPv6 server testing
std::string valid_iface_;
// Index of a valid network interface
- uint32_t valid_ifindex_;
+ unsigned int valid_ifindex_;
};
// We need to pass one reference to the Dhcp6Client, which is defined in
class BasePerfSocket : public dhcp::SocketInfo {
public:
/// Interface index.
- uint16_t ifindex_;
+ unsigned int ifindex_;
/// \brief Default constructor of BasePerfSocket.
BasePerfSocket() :
-// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2023 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
}
IfacePtr
-IfaceCollection::getIface(uint32_t ifindex) {
+IfaceCollection::getIface(const unsigned int ifindex) {
return (getIfaceInternal(ifindex, MultiThreadingMgr::instance().getMode()));
}
}
IfacePtr
-IfaceCollection::getIfaceInternal(uint32_t ifindex, bool need_lock) {
+IfaceCollection::getIfaceInternal(const unsigned int ifindex, const bool need_lock) {
+ if (ifindex == UNSET_IFINDEX) {
+ isc_throw(BadValue, "interface index was not set");
+ }
if (need_lock) {
lock_guard<mutex> lock(mutex_);
if (cache_ && (cache_->getIndex() == ifindex)) {
cache_ = *it;
return (cache_);
} else {
- lock_guard<mutex> lock(mutex_);
cache_ = *it;
return (cache_);
}
}
IfacePtr
-IfaceCollection::getIfaceInternal(const std::string& ifname, bool need_lock) {
+IfaceCollection::getIfaceInternal(const std::string& ifname, const bool need_lock) {
if (need_lock) {
lock_guard<mutex> lock(mutex_);
if (cache_ && (cache_->getName() == ifname)) {
cache_ = *it;
return (cache_);
} else {
- lock_guard<mutex> lock(mutex_);
cache_ = *it;
return (cache_);
}
}
IfacePtr
-IfaceMgr::getIface(int ifindex) {
- if ((ifindex < 0) || (ifindex > std::numeric_limits<int32_t>::max())) {
- return (IfacePtr()); // out of range
- }
+IfaceMgr::getIface(const unsigned int ifindex) {
return (ifaces_.getIface(ifindex));
}
return (Pkt4Ptr());
} else if (result < 0) {
// In most cases we would like to know whether select() returned
- // an error because of a signal being received or for some other
+ // an error because of a signal being received or for some other
// reason. This is because DHCP servers use signals to trigger
// certain actions, like reconfiguration or graceful shutdown.
// By catching a dedicated exception the caller will know if the
} else if (result < 0) {
// In most cases we would like to know whether select() returned
- // an error because of a signal being received or for some other
+ // an error because of a signal being received or for some other
// reason. This is because DHCP servers use signals to trigger
// certain actions, like reconfiguration or graceful shutdown.
// By catching a dedicated exception the caller will know if the
} else if (result < 0) {
// In most cases we would like to know whether select() returned
- // an error because of a signal being received or for some other
+ // an error because of a signal being received or for some other
// reason. This is because DHCP servers use signals to trigger
// certain actions, like reconfiguration or graceful shutdown.
// By catching a dedicated exception the caller will know if the
return (Pkt6Ptr());
} else if (result < 0) {
// In most cases we would like to know whether select() returned
- // an error because of a signal being received or for some other
+ // an error because of a signal being received or for some other
// reason. This is because DHCP servers use signals to trigger
// certain actions, like reconfiguration or graceful shutdown.
// By catching a dedicated exception the caller will know if the
-// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2023 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
/// @brief Returns interface index.
///
/// @return interface index
- int getIndex() const { return ifindex_; }
+ unsigned int getIndex() const { return ifindex_; }
/// @brief Returns interface name.
///
std::string name_;
/// Interface index (a value that uniquely identifies an interface).
- int ifindex_;
+ unsigned int ifindex_;
/// List of assigned addresses.
AddressCollection addrs_;
boost::multi_index::hashed_unique<
// Use the interface index as the key.
boost::multi_index::const_mem_fun<
- Iface, int, &Iface::getIndex
+ Iface, unsigned int, &Iface::getIndex
>
>,
// Start definition of index #2.
///
/// @param ifindex The index of the interface to find.
/// @return The interface with the index or null.
- IfacePtr getIface(uint32_t ifindex);
+ IfacePtr getIface(const unsigned int ifindex);
/// @brief Lookup by interface name.
///
/// @param ifindex The index of the interface to find.
/// @param need_lock True when the cache operation needs to hold the mutex.
/// @return The interface with the index or null.
- IfacePtr getIfaceInternal(uint32_t ifindex, bool need_lock);
+ IfacePtr getIfaceInternal(const unsigned int ifindex, const bool need_lock);
/// @brief Lookup by interface name.
///
/// @param ifname The name of the interface to find.
/// @param need_lock True when the cache operation needs to hold the mutex.
/// @return The interface with the name or null.
- IfacePtr getIfaceInternal(const std::string& ifname, bool need_lock);
+ IfacePtr getIfaceInternal(const std::string& ifname, const bool need_lock);
/// @brief The mutex for protecting the cache from concurrent
/// access from packet processing threads.
/// @return interface with requested index (or null if no such
/// interface is present)
///
- IfacePtr getIface(int ifindex);
+ IfacePtr getIface(const unsigned int ifindex);
/// @brief Returns interface with specified interface name
///
-// Copyright (C) 2014-2022 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2023 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
Pkt::Pkt(uint32_t transid, const isc::asiolink::IOAddress& local_addr,
const isc::asiolink::IOAddress& remote_addr, uint16_t local_port,
uint16_t remote_port)
- : transid_(transid), iface_(""), ifindex_(-1), local_addr_(local_addr),
+ : transid_(transid), iface_(""), ifindex_(UNSET_IFINDEX), local_addr_(local_addr),
remote_addr_(remote_addr), local_port_(local_port),
remote_port_(remote_port), buffer_out_(0), copy_retrieved_options_(false) {
}
Pkt::Pkt(const uint8_t* buf, uint32_t len, const isc::asiolink::IOAddress& local_addr,
const isc::asiolink::IOAddress& remote_addr, uint16_t local_port,
uint16_t remote_port)
- : transid_(0), iface_(""), ifindex_(-1), local_addr_(local_addr),
+ : transid_(0), iface_(""), ifindex_(UNSET_IFINDEX), local_addr_(local_addr),
remote_addr_(remote_addr), local_port_(local_port),
remote_port_(remote_port), buffer_out_(0), copy_retrieved_options_(false) {
if (len != 0) {
-// Copyright (C) 2014-2022 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2023 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
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/shared_ptr.hpp>
+#include <limits>
#include <utility>
namespace isc {
namespace dhcp {
+/// @brief A value used to signal that the interface index was not set.
+/// That means that more than UNSET_IFINDEX interfaces are not supported.
+/// That's fine, since it would have overflowed with UNSET_IFINDEX + 1 anyway.
+constexpr unsigned int UNSET_IFINDEX = std::numeric_limits<unsigned int>::max();
+
/// @brief RAII object enabling copying options retrieved from the
/// packet.
///
/// @brief Sets interface index.
///
/// @param ifindex specifies interface index.
- void setIndex(int ifindex) {
+ void setIndex(const unsigned int ifindex) {
ifindex_ = ifindex;
}
/// @brief Resets interface index to negative value.
void resetIndex() {
- ifindex_ = -1;
+ ifindex_ = UNSET_IFINDEX;
}
/// @brief Returns interface index.
///
/// @return true if interface index set, false otherwise.
bool indexSet() const {
- return (ifindex_ >= 0);
+ return (ifindex_ != UNSET_IFINDEX);
}
/// @brief Returns interface name.
/// Each network interface has assigned an unique ifindex.
/// It is a functional equivalent of a name, but sometimes more useful, e.g.
/// when using odd systems that allow spaces in interface names.
- int64_t ifindex_;
+ unsigned int ifindex_;
/// @brief Local IP (v4 or v6) address.
///
struct in6_addr to_addr;
memset(&to_addr, 0, sizeof(to_addr));
- int ifindex = -1;
+ unsigned int ifindex = UNSET_IFINDEX;
if (result >= 0) {
struct in6_pktinfo* pktinfo = NULL;
-// Copyright (C) 2014-2022 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2023 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
}
void
-IfaceMgrTestConfig::addIface(const std::string& name, const int ifindex) {
+IfaceMgrTestConfig::addIface(const std::string& name, const unsigned int ifindex) {
IfaceMgr::instance().addInterface(createIface(name, ifindex));
}
IfacePtr
-IfaceMgrTestConfig::createIface(const std::string &name, const int ifindex) {
+IfaceMgrTestConfig::createIface(const std::string &name, const unsigned int ifindex) {
IfacePtr iface(new Iface(name, ifindex));
if (name == "lo") {
iface->flag_loopback_ = true;
///
/// @param name Name of the new interface.
/// @param ifindex Index for a new interface.
- void addIface(const std::string& name, const int ifindex);
+ void addIface(const std::string& name, const unsigned int ifindex);
/// @brief Create an object representing interface.
///
/// @param ifindex An index of the interface to be created.
///
/// @return An object representing interface.
- static IfacePtr createIface(const std::string& name, const int ifindex);
+ static IfacePtr createIface(const std::string& name, const unsigned int ifindex);
/// @brief Creates a default (example) set of fake interfaces.
void createIfaces();
-// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2023 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
/// @param ifindex An index of the interface to be created.
///
/// @return An object representing interface.
- static IfacePtr createIface(const std::string& name, const int ifindex) {
+ static IfacePtr createIface(const std::string& name, const unsigned int ifindex) {
IfacePtr iface(new Iface(name, ifindex));
if (name == "lo") {
iface->flag_loopback_ = true;
EXPECT_EQ(66666, iface->getIndex());
}
+// This test checks the getIface by index method.
+TEST_F(IfaceMgrTest, getIfaceByIndex) {
+ NakedIfaceMgr ifacemgr;
+
+ // Create a set of fake interfaces. At the same time, remove the actual
+ // interfaces that have been detected by the IfaceMgr.
+ ifacemgr.createIfaces();
+
+ // Getting an unset index should throw.
+ EXPECT_THROW_MSG(ifacemgr.getIface(UNSET_IFINDEX), BadValue, "interface index was not set");
+
+ // Historically -1 was used as an unset value. Let's also check that it throws in case we didn't
+ // migrate all code to UNSET_IFINDEX and in case the values diverge.
+ EXPECT_THROW_MSG(ifacemgr.getIface(-1), BadValue, "interface index was not set");
+
+ // Get the first interface defined.
+ IfacePtr iface(ifacemgr.getIface(0));
+ ASSERT_TRUE(iface);
+ EXPECT_EQ("lo", iface->getName());
+
+ // Attemt to get an undefined interface.
+ iface = ifacemgr.getIface(3);
+ EXPECT_FALSE(iface);
+
+ // Check that we can go past INT_MAX.
+ unsigned int int_max(numeric_limits<int>::max());
+ iface = ifacemgr.getIface(int_max);
+ EXPECT_FALSE(iface);
+ iface = ifacemgr.createIface("wlan0", int_max);
+ ifacemgr.addInterface(iface);
+ iface = ifacemgr.getIface(int_max);
+ EXPECT_TRUE(iface);
+ iface = ifacemgr.getIface(int_max + 1);
+ EXPECT_FALSE(iface);
+ iface = ifacemgr.createIface("wlan1", int_max + 1);
+ ifacemgr.addInterface(iface);
+ iface = ifacemgr.getIface(int_max + 1);
+ EXPECT_TRUE(iface);
+}
+
// This test checks the getIface by packet method.
TEST_F(IfaceMgrTest, getIfaceByPkt) {
NakedIfaceMgr ifacemgr;
EXPECT_FALSE(pkt6->indexSet());
// Test that you can also reset the index via setIndex().
- pkt4->setIndex(-1);
+ pkt4->setIndex(UNSET_IFINDEX);
EXPECT_FALSE(pkt4->indexSet());
- pkt6->setIndex(-1);
+ pkt6->setIndex(UNSET_IFINDEX);
EXPECT_FALSE(pkt6->indexSet());
}
void testRcvdMessage(const Pkt6Ptr& rcvd_msg) const;
std::string ifname_; ///< Loopback interface name.
- uint16_t ifindex_; ///< Loopback interface index.
+ unsigned int ifindex_; ///< Loopback interface index.
uint16_t port_; ///< A port number used for the test.
isc::dhcp::SocketInfo sock_info_; ///< A structure holding socket info.
int send_msg_sock_; ///< Holds a descriptor of the socket used by
void testRcvdMessageAddressPort(const Pkt4Ptr& rcvd_msg) const;
std::string ifname_; ///< Loopback interface name
- uint16_t ifindex_; ///< Loopback interface index.
+ unsigned int ifindex_; ///< Loopback interface index.
uint16_t port_; ///< A port number used for the test.
isc::dhcp::SocketInfo sock_info_; ///< A structure holding socket info.
int send_msg_sock_; ///< Holds a descriptor of the socket used by