From 8f0943390420723039d3a00f77a199ce5e0f5d10 Mon Sep 17 00:00:00 2001 From: Marcin Siodelski Date: Fri, 13 Nov 2015 21:01:11 +0100 Subject: [PATCH] [3874] Implemented generation of DUID-EN and DUID-LL. --- src/lib/dhcp/duid_factory.cc | 207 +++++++++++++++++-- src/lib/dhcp/duid_factory.h | 137 ++++++++++++- src/lib/dhcp/tests/duid_factory_unittest.cc | 216 +++++++++++++++++++- src/lib/dhcp/tests/iface_mgr_test_config.cc | 1 + 4 files changed, 536 insertions(+), 25 deletions(-) diff --git a/src/lib/dhcp/duid_factory.cc b/src/lib/dhcp/duid_factory.cc index 19cb9082c3..e77e7b8c5e 100644 --- a/src/lib/dhcp/duid_factory.cc +++ b/src/lib/dhcp/duid_factory.cc @@ -14,11 +14,14 @@ #include #include +#include #include #include #include #include #include +#include +#include #include #include @@ -27,8 +30,18 @@ using namespace isc::util::str; namespace { +/// @brief Length of the DUID type field. +const size_t DUID_TYPE_LEN = 2; + +/// @brief Minimal length of the MAC address. const size_t MIN_MAC_LEN = 6; +/// @brief Length of the enterprise if field. +const size_t ENTERPRISE_ID_LEN = 4; + +/// @brief Default length of the variable length identifier in the DUID-EN. +const size_t DUID_EN_IDENTIFIER_LEN = 6; + } namespace isc { @@ -47,41 +60,107 @@ void DUIDFactory::createLLT(const uint16_t htype, const uint32_t time_in, const std::vector& ll_identifier) { uint32_t time_out = time_in; + // If time unspecified, use current time. if (time_out == 0) { time_out = static_cast(time(NULL) - DUID_TIME_EPOCH); } + std::vector ll_identifier_out = ll_identifier; uint16_t htype_out = htype; - if (htype_out == 0) { - htype_out = HTYPE_ETHER; - } - std::vector ll_identifier_out = ll_identifier; + // If link layer address unspecified, use address of one of the + // interfaces present in the system. Also, update the link + // layer type accordingly. if (ll_identifier_out.empty()) { - createLinkLayerId(ll_identifier_out); + createLinkLayerId(ll_identifier_out, htype_out); + + } else if (htype_out == 0) { + // If link layer type unspecified and link layer adddress + // is specified, use HTYPE_ETHER. + htype_out = HTYPE_ETHER; + } - std::vector duid_out(2 + sizeof(time_out) + sizeof(htype_out)); + // Render DUID. + std::vector duid_out(DUID_TYPE_LEN + sizeof(time_out) + + sizeof(htype_out)); writeUint16(DUID::DUID_LLT, &duid_out[0], 2); writeUint16(htype_out, &duid_out[2], 2); writeUint32(time_out, &duid_out[4], 4); duid_out.insert(duid_out.end(), ll_identifier_out.begin(), ll_identifier_out.end()); - duid_.reset(new DUID(duid_out)); + // Set new DUID and persist in a file. + set(duid_out); } -/*void +void DUIDFactory::createEN(const uint32_t enterprise_id, - const std::vector& identifier) { -}*/ + const std::vector& identifier) { + // Enterprise id 0 means "unspecified". In this case use the ISC + // enterprise id. + uint32_t enterprise_id_out = enterprise_id != 0 ? + enterprise_id : ENTERPRISE_ID_ISC; + + // Render DUID. + std::vector duid_out(DUID_TYPE_LEN + ENTERPRISE_ID_LEN); + writeUint16(DUID::DUID_EN, &duid_out[0], 2); + writeUint32(enterprise_id_out, &duid_out[2], ENTERPRISE_ID_LEN); + + if (identifier.empty()) { + // Identifier is empty, so we have to extend the DUID by 6 bytes + // to fit the random identifier. + duid_out.resize(DUID_TYPE_LEN + ENTERPRISE_ID_LEN + + DUID_EN_IDENTIFIER_LEN); + // Variable length identifier consists of random numbers. The generated + // identifier is always 6 bytes long. + ::srandom(time(NULL)); + fillRandom(&duid_out[DUID_TYPE_LEN + ENTERPRISE_ID_LEN], + &duid_out[DUID_TYPE_LEN + ENTERPRISE_ID_LEN + + DUID_EN_IDENTIFIER_LEN]); + + } else { + // Append the specified identifier to the end of DUID. + duid_out.insert(duid_out.end(), identifier.begin(), identifier.end()); + } + + // Set new DUID and persist in a file. + set(duid_out); +} + +void +DUIDFactory::createLL(const uint16_t htype, + const std::vector& ll_identifier) { + std::vector ll_identifier_out = ll_identifier; + uint16_t htype_out = htype; + + // If link layer address unspecified, use address of one of the + // interfaces present in the system. Also, update the link + // layer type accordingly. + if (ll_identifier_out.empty()) { + createLinkLayerId(ll_identifier_out, htype_out); + + } else if (htype_out == 0) { + // If link layer type unspecified and link layer adddress + // is specified, use HTYPE_ETHER. + htype_out = HTYPE_ETHER; + + } + + // Render DUID. + std::vector duid_out(DUID_TYPE_LEN + sizeof(htype_out)); + writeUint16(DUID::DUID_LL, &duid_out[0], 2); + writeUint16(htype_out, &duid_out[2], 2); + duid_out.insert(duid_out.end(), ll_identifier_out.begin(), + ll_identifier_out.end()); -/*void -DUIDFactory::createLL(const uint16_t htype, const std::vector& ll_identifier) { -} */ + // Set new DUID and persist in a file. + set(duid_out); +} void -DUIDFactory::createLinkLayerId(std::vector& identifier) const { +DUIDFactory::createLinkLayerId(std::vector& identifier, + uint16_t& htype) const { const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces(); // Let's find suitable interface. @@ -121,12 +200,112 @@ DUIDFactory::createLinkLayerId(std::vector& identifier) const { continue; } + // Assign link layer address and type. identifier.assign(iface->getMac(), iface->getMac() + iface->getMacLen()); + htype = iface->getHWType(); + } + + // We failed to find an interface which link layer address could be + // used for generating DUID-LLT. + if (identifier.empty()) { + isc_throw(Unexpected, "unable to find suitable interface for " + " generating a DUID-LLT"); } } +void +DUIDFactory::set(const std::vector& duid_vector) { + // Check the minimal length. + if (duid_vector.size() < DUID::MIN_DUID_LEN) { + isc_throw(BadValue, "generated DUID must have at least " + << DUID::MIN_DUID_LEN << " bytes"); + } + + // Persist DUID in a file if file location specified. + if (isPersisted()) { + std::ofstream ofs; + try { + ofs.open(storage_location_, std::ofstream::out | + std::ofstream::trunc); + if (!ofs.good()) { + isc_throw(InvalidOperation, "unable to open DUID file " + << storage_location_ << " for writing"); + } + + // Create temporary DUID object. + DUID duid(duid_vector); + + // Write DUID to file. + ofs << duid.toText(); + if (!ofs.good()) { + isc_throw(InvalidOperation, "unable to write to DUID file " + << storage_location_); + } + } catch (...) { + // Close stream before leaving the function. + ofs.close(); + throw; + } + ofs.close(); + } + + duid_.reset(new DUID(duid_vector)); +} + DuidPtr DUIDFactory::get() { + // If DUID is initialized, return it. + if (duid_) { + return (duid_); + } + + // If DUID object hasn't been initialized then we need to retrieve a + // DUID from the file or create one. + std::ostringstream duid_str; + if (isPersisted()) { + std::ifstream ifs; + ifs.open(storage_location_, std::ifstream::in); + if (ifs.good()) { + std::string read_contents; + while (!ifs.eof() && ifs.good()) { + ifs >> read_contents; + duid_str << read_contents; + } + } + ifs.close(); + + // If we have read anything from the file, let's try to use it to + // create a DUID. + if (duid_str.tellp() != 0) { + try { + duid_.reset(new DUID(DUID::fromText(duid_str.str()))); + return (duid_); + + } catch (...) { + // The contents of this file don't represent a valid DUID. + // We'll need to generate it. + } + } + + } + + try { + // There is no file with a DUID or the DUID stored in the file is + // invalid. We need to generate a new DUID. + createLLT(0, 0, std::vector()); + + } catch (...) { + // It is possible that the creation of the DUID-LLT failed if there + // are no suitable interfaces present in the system. + } + + if (!duid_) { + // Fall back to creation of DUID enterprise. If that fails we allow + // for propagating exception to indicate a fatal error. This may + // be the case if we failed to write it to a file. + createEN(0, std::vector()); + } + return (duid_); } diff --git a/src/lib/dhcp/duid_factory.h b/src/lib/dhcp/duid_factory.h index f0b705f9fc..db9182b9a3 100644 --- a/src/lib/dhcp/duid_factory.h +++ b/src/lib/dhcp/duid_factory.h @@ -16,6 +16,7 @@ #define DUID_FACTORY_H #include +#include #include #include #include @@ -23,28 +24,150 @@ namespace isc { namespace dhcp { -class DUIDFactory { +/// @brief Factory for generating DUIDs (DHCP Unique Identifiers). +/// +/// DHCPv6 clients and servers are identified by DUIDs (see RFC3315). +/// DUIDs are unique identifiers carried in the appropriate DHCP +/// options. RFC3315 defines 3 types of DUIDs: +/// -# DUID-LLT +/// -# DUID-EN +/// -# DUID-LL +/// +/// of which the DUID-LLT is recommended for all general purpose computing +/// devices. RFC6355 defines new DUID-UUID and any future specifications may +/// define new DUID types. The current implementation of the class only +/// supports DUID types defined in RFC3315. +/// +/// In most cases DUIDs can be generated automatically, i.e. no manual +/// configuration is required. For example, DUID-LLT is composed of the +/// current time and link layer address and type of one of the network +/// interfaces. Once the DUID is generated it should be stored in the persistent +/// storage and used by a server or client even when the network interface which +/// address had been used to generate the DUID is removed. +/// +/// In some cases administrators may elect to use other types of DUIDs, which +/// are easier to generate (in case of lack of persistent storage or when +/// specifics of the device favors some generation methods), e.g. DUID-EN +/// doesn't rely on the link layer addresses of interfaces present in the +/// system. +/// +/// In some cases administrators may want to influence the value of the +/// generated DUID. For example, DUID-EN includes enterprise identifier and +/// the administrator may want to select this identifier. +/// +/// This class allows for selecting a type of DUID to be generated. It also +/// allows for setting desired values for the components of the DUIDs +/// being generated, while leaving other components unspecified. For example +/// an administrator may elect to set the enterprise id for the DUID-EN +/// and leave the variable length identifier unspecified. The variable +/// length identifier will be autogenerated. +/// +/// This class is also responsible for storing the generated DUID in a +/// file. The location of this file is specified in the class constructor. +/// If this location is not specified the DUID is not persisted, i.e. is +/// lost when the server or client shuts down. However, the DUID may be +/// reconstructed according to the configuration of the client or server +/// when they are back online. +class DUIDFactory : public boost::noncopyable { public: + /// @brief Constructor. + /// + /// @param storage_location Absolute path to the file where DUID is + /// stored. DUIDFactory(const std::string& storage_location = ""); + /// @brief Checks if generated DUID will be persisted in the file. + /// + /// @return true if generated DUIDs are persisted in a file, false + /// otherwise. bool isPersisted() const; + /// @brief Generates DUID-LLT. + /// + /// This method generates DUID-LLT. + /// + /// @param htype Link layer type. If this is set to 0 and link layer + /// address is empty a default value of @c HTYPE_ETHER is used. + /// Otherwise a link layer type of selected interface is used. + /// @param time_in Explicit value of time for the DUID. If this is + /// set to 0 a current time is used, otherwise a value specified is + /// used. + /// @param ll_identifier Data to be used as link layer address. If + /// this is an empty vector this method will iterate over all + /// active interfaces and will pick link layer address of one of them. + /// + /// @throw isc::Unexpected if none of the interfaces includes has a + /// suitable link layer address. void createLLT(const uint16_t htype, const uint32_t time_in, const std::vector& ll_identifier); - void createEN(const uint32_t enterprise_id, const std::vector& identifier); - - void createLL(const uint16_t htype, const std::vector& ll_identifier); - + /// @brief Generates DUID-EN. + /// + /// @param enterprise_id Enterprise id. If this value is 0, the ISC's + /// enterprise id is used. + /// @param identifier Data to be used as variable length identifier. + /// If this is an empty vector, the 6-bytes long vector with random + /// values is generated. + void createEN(const uint32_t enterprise_id, + const std::vector& identifier); + + /// @brief Generates DUID-LL. + /// + /// @param htype Link layer type. If this is set to 0 and link layer + /// address is empty a default value of @c HTYPE_ETHER is used. + /// Otherwise a link layer type of selected interface is used. + /// @param ll_identifier Data to be used as link layer address. If + /// this is an empty vector this method will iterate over all + /// active interfaces and will pick link layer address of one of them. + /// + /// @throw isc::Unexpected if none of the interfaces includes has a + /// suitable link layer address. + void createLL(const uint16_t htype, + const std::vector& ll_identifier); + + /// @brief Returns current DUID. + /// + /// This method first checks if the DUID has been generated, i.e. as a + /// result of calling DUIDFactory::createLLT. If the DUID hasn't been + /// generated, this method will try to read the DUID from the persistent + /// storage. If the DUID is found in persistent storage it is returned. + /// Otherwise, the DUID-LLT is generated and returned. In some cases the + /// generation of the DUID-LLT may fail, e.g. when there are no interfaces + /// with a suitable link layer address. In this case, this method will + /// generate DUID-EN, with the ISC enterprise id. If this fails, e.g. as a + /// result of error while persisting the generated DUID-EN, exception + /// is thrown. + /// + /// @return Instance of the DUID read from file, or generated. DuidPtr get(); private: - void createLinkLayerId(std::vector& identifier) const; - + /// @brief Creates link layer identifier. + /// + /// This method iterates over existing network interfaces and finds the + /// one with a suitable link layer address to generate a DUID-LLT or + /// DUID-LL. It uses selected link layer address to generate identifier + /// held in those DUID types. + /// + /// @param [out] identifier Link layer address for the DUID. + /// @param [out] htype Link layer type to be included in the DUID. + void createLinkLayerId(std::vector& identifier, + uint16_t& htype) const; + + /// @brief Sets a new DUID as current. + /// + /// The generated DUID is persisted in the file, if such file is specified. + /// The new DUID will be returned when @c DUIDFactory::get is called. + /// + /// @param duid_vector New DUID represented as vector of bytes. + void set(const std::vector& duid_vector); + + /// @brief Location of the file holding generated DUID (if specified). std::string storage_location_; + /// @brief Pointer to generated DUID. DuidPtr duid_; }; diff --git a/src/lib/dhcp/tests/duid_factory_unittest.cc b/src/lib/dhcp/tests/duid_factory_unittest.cc index 919e02c286..cb377ab926 100644 --- a/src/lib/dhcp/tests/duid_factory_unittest.cc +++ b/src/lib/dhcp/tests/duid_factory_unittest.cc @@ -17,9 +17,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -29,41 +31,97 @@ using namespace isc; using namespace isc::dhcp; using namespace isc::dhcp::test; +using namespace isc::util; namespace { +/// @brief Name of the file holding DUID generated during a test. const std::string DEFAULT_DUID_FILE = "duid-factory-test.duid"; +/// @brief Test fixture class for @c DUIDFactory. class DUIDFactoryTest : public ::testing::Test { public: + /// @brief Constructor. + /// + /// Creates fake interface configuration. It also creates an instance + /// of the @c DUIDFactory object used throughout the tests. DUIDFactoryTest(); + /// @brief Destructor. virtual ~DUIDFactoryTest(); + /// @brief Returns absolute path to a test DUID storage. + /// + /// @param duid_file_name Name of the file holding test DUID. std::string absolutePath(const std::string& duid_file_path) const; + /// @brief Removes default DUID file used in the tests. + /// + /// This method is called from both constructor and destructor. void removeDefaultFile() const; + /// @brief Returns contents of the DUID file. + std::string readDefaultFile() const; + + /// @brief Converts string of hexadecimal digits to vector. + /// + /// @param hex String representation. + /// @return Vector created from the converted string. std::vector toVector(const std::string& hex) const; + /// @brief Converts vector to string of hexadecimal digits. + /// + /// @param vec Input vector. + /// @return String of hexadecimal digits converted from vector. std::string toString(const std::vector& vec) const; + /// @brief Converts current time to a string of hexadecimal digits. + /// + /// @return Time represented as text. std::string timeAsHexString() const; + /// @brief Tests creation of a DUID-LLT. + /// + /// @param expected_htype Expected link layer type as string. + /// @param expected_time Expected time as string. + /// @param time_equal Indicates if @c expected time should be + /// compared for equality with the time being part of a DUID + /// (if true), or the time being part of the DUID should be + /// less or equal current time (if false). + /// @param expected_hwaddr Expected link layer type as string. void testLLT(const std::string& expected_htype, const std::string& expected_time, const bool time_equal, const std::string& expected_hwaddr); + /// @brief Tests creation of a DUID-EN. + /// + /// @param expected_enterprise_id Expected enterprise id as string. + /// @param expected_identifier Expected variable length identifier + /// as string. + void testEN(const std::string& expected_enterprise_id, + const std::string& expected_identifier = ""); + + /// @brief Tests creation of a DUID-LL. + /// + /// @param expected_htype Expected link layer type as string. + /// @param expected_hwaddr Expected link layer type as string. + void testLL(const std::string& expected_htype, + const std::string& expected_hwaddr); + + /// @brief Returns reference to a default factory. DUIDFactory& factory() { return (factory_); } private: + /// @brief Creates fake interface configuration. IfaceMgrTestConfig iface_mgr_test_config_; + /// @brief Holds default instance of the @c DUIDFactory class, being + /// used throughout the tests. DUIDFactory factory_; }; @@ -90,6 +148,24 @@ DUIDFactoryTest::removeDefaultFile() const { static_cast(remove(absolutePath(DEFAULT_DUID_FILE).c_str())); } +std::string +DUIDFactoryTest::readDefaultFile() const { + std::ifstream ifs; + ifs.open(absolutePath(DEFAULT_DUID_FILE), std::ifstream::in); + if (!ifs.good()) { + return (std::string()); + } + std::string buf; + std::ostringstream output; + while (!ifs.eof() && ifs.good()) { + ifs >> buf; + output << buf; + } + ifs.close(); + + return (output.str()); +} + std::vector DUIDFactoryTest::toVector(const std::string& hex) const { std::vector vec; @@ -148,6 +224,56 @@ DUIDFactoryTest::testLLT(const std::string& expected_htype, // MAC address of the interface. EXPECT_EQ(expected_hwaddr, duid_text.substr(16)); + + // Compare DUID with the one stored in the file. + EXPECT_EQ(duid->toText(), readDefaultFile()); +} + +void +DUIDFactoryTest::testEN(const std::string& expected_enterprise_id, + const std::string& expected_identifier) { + DuidPtr duid = factory().get(); + ASSERT_TRUE(duid); + ASSERT_GE(duid->getDuid().size(), 8); + std::string duid_text = toString(duid->getDuid()); + + // DUID type EN. + EXPECT_EQ("0002", duid_text.substr(0, 4)); + // Verify enterprise ID. + EXPECT_EQ(expected_enterprise_id, duid_text.substr(4, 8)); + + // If no expecyed identifier, we should at least check that the + // generated identifier contains some random non-zero digits. + if (expected_identifier.empty()) { + EXPECT_FALSE(isRangeZero(duid->getDuid().begin(), + duid->getDuid().end())); + } else { + // Check if identifier matches. + EXPECT_EQ(expected_identifier, duid_text.substr(12)); + } + + // Compare DUID with the one stored in the file. + EXPECT_EQ(duid->toText(), readDefaultFile()); +} + +void +DUIDFactoryTest::testLL(const std::string& expected_htype, + const std::string& expected_hwaddr) { + DuidPtr duid = factory().get(); + ASSERT_TRUE(duid); + ASSERT_GE(duid->getDuid().size(), 8); + std::string duid_text = toString(duid->getDuid()); + + // DUID type LL + EXPECT_EQ("0003", duid_text.substr(0, 4)); + // Link layer type HTYPE_ETHER + EXPECT_EQ(expected_htype, duid_text.substr(4, 4)); + + // MAC address of the interface. + EXPECT_EQ(expected_hwaddr, duid_text.substr(8)); + + // Compare DUID with the one stored in the file. + EXPECT_EQ(duid->toText(), readDefaultFile()); } @@ -171,12 +297,12 @@ TEST_F(DUIDFactoryTest, createLLTExplicitTime) { testLLT("0001", "00ABCDEF", true, "010101010101"); } -// This test verifies that the factory class creates DUID-LLT from -// the explcitly specified link layer type, when the time and link -// layer address are generated. +// This test verifies that the factory class creates DUID-LLT with +// the link layer type of the interface which link layer address +// is used to generate the DUID. TEST_F(DUIDFactoryTest, createLLTExplicitHtype) { ASSERT_NO_THROW(factory().createLLT(HTYPE_FDDI, 0, std::vector())); - testLLT("0008", timeAsHexString(), false, "010101010101"); + testLLT("0001", timeAsHexString(), false, "010101010101"); } // This test verifies that the factory class creates DUID-LLT from @@ -195,4 +321,86 @@ TEST_F(DUIDFactoryTest, createLLTAllExplcitParameters) { testLLT("0008", "FAFAFAFA", true, "24242424242424242424"); } +// This test verifies that the DUID-EN can be generated entirely. Such +// generated DUID contains ISC enterprise id and the random identifier. +TEST_F(DUIDFactoryTest, createEN) { + ASSERT_NO_THROW(factory().createEN(0, std::vector())); + testEN("000009BF"); +} + +// This test verifies that the DUID-EN may contain custom enterprise id. +TEST_F(DUIDFactoryTest, createENExplicitEnterpriseId) { + ASSERT_NO_THROW(factory().createEN(0xABCDEFAB, std::vector())); + testEN("ABCDEFAB"); +} + +// This test verifies that DUID-EN may contain custom variable length +// identifier and default enterprise id. +TEST_F(DUIDFactoryTest, createENExplicitIdentifier) { + ASSERT_NO_THROW(factory().createEN(0, toVector("1212121212121212"))); + testEN("000009BF", "1212121212121212"); +} + +// This test verifies that DUID-EN can be created from explicit enterprise id +// and identifier. +TEST_F(DUIDFactoryTest, createENAllExplicitParameters) { + ASSERT_NO_THROW(factory().createEN(0x01020304, toVector("ABCD"))); + testEN("01020304", "ABCD"); +} + +// This test verifies that the DUID-LL is generated when neither link layer +// type nor address is specified. +TEST_F(DUIDFactoryTest, createLL) { + ASSERT_NO_THROW(factory().createLL(0, std::vector())); + testLL("0001", "010101010101"); +} + +// This test verifies that the DUID-LL is generated and the link layer type +// used is taken from the interface used to generate link layer address. +TEST_F(DUIDFactoryTest, createLLExplicitHtype) { + ASSERT_NO_THROW(factory().createLL(HTYPE_FDDI, std::vector())); + testLL("0001", "010101010101"); +} + +// This test verifies that DUID-LL is created from explicitly provided +// link layer type and address. +TEST_F(DUIDFactoryTest, createLLAllExplicitParameters) { + ASSERT_NO_THROW(factory().createLL(HTYPE_FDDI, toVector("242424242424"))); + testLL("0008", "242424242424"); +} + +// This test verifies that DUID-LLT is created when caller wants to obtain +// it and it doesn't exist. +TEST_F(DUIDFactoryTest, createLLTIfNotExists) { + DuidPtr duid; + ASSERT_NO_THROW(duid = factory().get()); + ASSERT_TRUE(duid); + EXPECT_EQ(DUID::DUID_LLT, duid->getType()); +} + +// This test verifies that DUID-EN when there is no suitable interface to +// use to create DUID-LLT. +TEST_F(DUIDFactoryTest, createENIfNotExists) { + // Remove interfaces. The DUID-LLT is a default type but it requires + // that an interface with a suitable link-layer address is present + // in the system. By removing the interfaces we cause the factory + // to fail to generate DUID-LLT. It should fall back to DUID-EN. + IfaceMgr::instance().clearIfaces(); + + DuidPtr duid; + ASSERT_NO_THROW(duid = factory().get()); + ASSERT_TRUE(duid); + EXPECT_EQ(DUID::DUID_EN, duid->getType()); +} + +// This test verifies that it is possible to override a DUID. +TEST_F(DUIDFactoryTest, override) { + // Create default DUID-LLT. + ASSERT_NO_THROW(static_cast(factory().get())); + testLLT("0001", timeAsHexString(), false, "010101010101"); + + ASSERT_NO_THROW(factory().createEN(0, toVector("12131415"))); + testEN("000009BF", "12131415"); +} + } // End anonymous namespace diff --git a/src/lib/dhcp/tests/iface_mgr_test_config.cc b/src/lib/dhcp/tests/iface_mgr_test_config.cc index f173ae62a8..333e11c1ca 100644 --- a/src/lib/dhcp/tests/iface_mgr_test_config.cc +++ b/src/lib/dhcp/tests/iface_mgr_test_config.cc @@ -99,6 +99,7 @@ IfaceMgrTestConfig::createIface(const std::string &name, const int ifindex) { // Set MAC address to 01:01:01:01:01:01. std::vector mac_vec(6, 1); iface->setMac(&mac_vec[0], mac_vec.size()); + iface->setHWType(HTYPE_ETHER); return (iface); } -- 2.47.3