]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1836] get server identifier from client class value
authorRazvan Becheriu <razvan@isc.org>
Sat, 19 Jun 2021 12:38:40 +0000 (15:38 +0300)
committerRazvan Becheriu <razvan@isc.org>
Fri, 25 Jun 2021 14:08:31 +0000 (17:08 +0300)
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
src/bin/dhcp4/tests/dhcp4_test_utils.cc
src/bin/dhcp4/tests/dhcp4_test_utils.h
src/lib/dhcp/iface_mgr.cc
src/lib/dhcpsrv/cfg_subnets4.cc

index 22e525c0311959fd29e57efa23f98963b36903d3..a04dbaaf63a2799f7adb8a58e90e9c0d58d129d5 100644 (file)
@@ -3687,6 +3687,29 @@ Dhcpv4Srv::acceptServerId(const Pkt4Ptr& query) const {
         return (true);
     }
 
+    // Check if the server identifier is configured at client class level.
+    const ClientClasses& classes = query->getClasses();
+    for (ClientClasses::const_iterator cclass = classes.cbegin();
+         cclass != classes.cend(); ++cclass) {
+        // Find the client class definition for this class
+        const ClientClassDefPtr& ccdef = CfgMgr::instance().getCurrentCfg()->
+            getClientClassDictionary()->findClass(*cclass);
+        if (!ccdef) {
+            continue;
+        }
+
+        if (ccdef->getCfgOption()->empty()) {
+            // Skip classes which don't configure options
+            continue;
+        }
+
+        OptionCustomPtr context_opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
+                (ccdef->getCfgOption()->get(DHCP4_OPTION_SPACE, DHO_DHCP_SERVER_IDENTIFIER).option_);
+        if (context_opt_server_id && (context_opt_server_id->readAddress() == server_id)) {
+            return (true);
+        }
+    }
+
     // Finally, it is possible that the server identifier is specified
     // on the global level.
     ConstCfgOptionPtr cfg_global_options = cfg->getCfgOption();
index 7feda9768fec34a1de20d81f659105ed7a93c309..bcc78fabb53acc1bcb00c110850ebbdc368cce3b 100644 (file)
@@ -2337,6 +2337,62 @@ TEST_F(Dhcpv4SrvTest, RenewCache) {
     EXPECT_EQ(temp_timestamp, lease->cltt_);
 }
 
+// Exercises Dhcpv4Srv::buildCfgOptionList().
+TEST_F(Dhcpv4SrvTest, buildCfgOptionsList) {
+    configureServerIdentifier();
+    IfaceMgrTestConfig test_config(true);
+    IfaceMgr::instance().openSockets4();
+
+    Pkt4Ptr query(new Pkt4(DHCPREQUEST, 1234));
+    query->addOption(generateClientId());
+    query->setHWAddr(generateHWAddr(6));
+    query->setIface("eth0");
+    query->setIndex(ETH0_INDEX);
+
+    {
+        SCOPED_TRACE("Pool value");
+
+        // Server id should come from subnet2's first pool.
+        buildCfgOptionTest(IOAddress("192.0.2.254"), query, IOAddress("192.0.2.101"), IOAddress("192.0.2.254"));
+    }
+
+    {
+        SCOPED_TRACE("Subnet value");
+
+        // Server id should come from subnet3.
+        buildCfgOptionTest(IOAddress("192.0.3.254"), query, IOAddress("192.0.3.101"), IOAddress("192.0.3.254"));
+    }
+
+    {
+        SCOPED_TRACE("Shared-network value");
+
+        // Server id should come from subnet4's shared-network.
+        buildCfgOptionTest(IOAddress("192.0.4.254"), query, IOAddress("192.0.4.101"), IOAddress("192.0.4.254"));
+    }
+
+    {
+        SCOPED_TRACE("Client-class value");
+
+        Pkt4Ptr query_with_classes(new Pkt4(DHCPREQUEST, 1234));
+        query_with_classes->addOption(generateClientId());
+        query_with_classes->setHWAddr(generateHWAddr(6));
+        query_with_classes->setIface("eth0");
+        query_with_classes->setIndex(ETH0_INDEX);
+
+        query_with_classes->addClass("foo");
+
+        // Server id should come from subnet5's client-class value.
+        buildCfgOptionTest(IOAddress("192.0.5.254"), query_with_classes, IOAddress("192.0.5.101"), IOAddress("192.0.5.254"));
+    }
+
+    {
+        SCOPED_TRACE("Global value");
+
+        // Server id should be global value as lease is from subnet2's second pool.
+        buildCfgOptionTest(IOAddress("10.0.0.254"), query, IOAddress("192.0.2.201"), IOAddress("10.0.0.254"));
+    }
+}
+
 // This test verifies that the logic which matches server identifier in the
 // received message with server identifiers used by a server works correctly:
 // - a message with no server identifier is accepted,
@@ -2345,6 +2401,7 @@ TEST_F(Dhcpv4SrvTest, RenewCache) {
 // - a message with a server identifier which doesn't match any server
 // identifier used by a server, is not accepted.
 TEST_F(Dhcpv4SrvTest, acceptServerId) {
+    configureServerIdentifier();
     IfaceMgrTestConfig test_config(true);
     IfaceMgr::instance().openSockets4();
 
@@ -2371,23 +2428,67 @@ TEST_F(Dhcpv4SrvTest, acceptServerId) {
     // Remove the server identifier.
     ASSERT_NO_THROW(pkt->delOption(DHO_DHCP_SERVER_IDENTIFIER));
 
+    // Add a server id being an IPv4 address configured on eth1 interface.
+    // A DHCPv4 message holding this server identifier should be accepted.
+    OptionCustomPtr eth1_serverid(new OptionCustom(def, Option::V6));
+    eth1_serverid->writeAddress(IOAddress("192.0.2.3"));
+    ASSERT_NO_THROW(pkt->addOption(eth1_serverid));
+    EXPECT_TRUE(srv.acceptServerId(pkt));
+
+    // Remove the server identifier.
+    ASSERT_NO_THROW(pkt->delOption(DHO_DHCP_SERVER_IDENTIFIER));
+
     // Add a server id being an IPv4 address configured on eth0 interface.
     // A DHCPv4 message holding this server identifier should be accepted.
     OptionCustomPtr eth0_serverid(new OptionCustom(def, Option::V6));
-    eth0_serverid->writeAddress(IOAddress("192.0.2.3"));
+    eth0_serverid->writeAddress(IOAddress("10.0.0.1"));
     ASSERT_NO_THROW(pkt->addOption(eth0_serverid));
     EXPECT_TRUE(srv.acceptServerId(pkt));
 
     // Remove the server identifier.
     ASSERT_NO_THROW(pkt->delOption(DHO_DHCP_SERVER_IDENTIFIER));
 
-    // Add a server id being an IPv4 address configured on eth1 interface.
+    // Add a server id being an IPv4 address configured on subnet3.
     // A DHCPv4 message holding this server identifier should be accepted.
-    OptionCustomPtr eth1_serverid(new OptionCustom(def, Option::V6));
-    eth1_serverid->writeAddress(IOAddress("10.0.0.1"));
-    ASSERT_NO_THROW(pkt->addOption(eth1_serverid));
+    OptionCustomPtr subnet_serverid(new OptionCustom(def, Option::V6));
+    subnet_serverid->writeAddress(IOAddress("192.0.3.254"));
+    ASSERT_NO_THROW(pkt->addOption(subnet_serverid));
+    EXPECT_TRUE(srv.acceptServerId(pkt));
+
+    // Remove the server identifier.
+    ASSERT_NO_THROW(pkt->delOption(DHO_DHCP_SERVER_IDENTIFIER));
+
+    // Add a server id being an IPv4 address configured on shared network1.
+    // A DHCPv4 message holding this server identifier should be accepted.
+    OptionCustomPtr network_serverid(new OptionCustom(def, Option::V6));
+    network_serverid->writeAddress(IOAddress("192.0.4.254"));
+    ASSERT_NO_THROW(pkt->addOption(network_serverid));
+    EXPECT_TRUE(srv.acceptServerId(pkt));
+
+    // Remove the server identifier.
+    ASSERT_NO_THROW(pkt->delOption(DHO_DHCP_SERVER_IDENTIFIER));
+
+    // Add a server id being an IPv4 address configured on client class.
+    // A DHCPv4 message holding this server identifier should be accepted.
+    Pkt4Ptr pkt_with_classes(new Pkt4(DHCPREQUEST, 1234));
+    OptionCustomPtr class_serverid(new OptionCustom(def, Option::V6));
+    class_serverid->writeAddress(IOAddress("10.0.0.254"));
+    ASSERT_NO_THROW(pkt_with_classes->addOption(class_serverid));
+    pkt_with_classes->addClass("foo");
+    EXPECT_TRUE(srv.acceptServerId(pkt_with_classes));
+
+    // Remove the server identifier.
+    ASSERT_NO_THROW(pkt_with_classes->delOption(DHO_DHCP_SERVER_IDENTIFIER));
+
+    // Add a server id being an IPv4 address configured on global level.
+    // A DHCPv4 message holding this server identifier should be accepted.
+    OptionCustomPtr global_serverid(new OptionCustom(def, Option::V6));
+    global_serverid->writeAddress(IOAddress("10.0.0.254"));
+    ASSERT_NO_THROW(pkt->addOption(global_serverid));
     EXPECT_TRUE(srv.acceptServerId(pkt));
 
+    // Remove the server identifier.
+    ASSERT_NO_THROW(pkt->delOption(DHO_DHCP_SERVER_IDENTIFIER));
 }
 
 // @todo: Implement tests for rejecting renewals
index b3de3c3e1634abaee72836a4b78f8732614cc7cc..7c3d1cfe672e6312de697a3b00db21f67f18437e 100644 (file)
@@ -118,7 +118,8 @@ void Dhcpv4SrvTest::addPrlOption(Pkt4Ptr& pkt) {
     pkt->addOption(option_prl);
 }
 
-void Dhcpv4SrvTest::configureRequestedOptions() {
+void
+Dhcpv4SrvTest::configureRequestedOptions() {
     // dns-servers
     Option4AddrLstPtr
         option_dns_servers(new Option4AddrLst(DHO_DOMAIN_NAME_SERVERS));
@@ -145,7 +146,88 @@ void Dhcpv4SrvTest::configureRequestedOptions() {
     ASSERT_NO_THROW(subnet_->getCfgOption()->add(option_cookie_servers, false, DHCP4_OPTION_SPACE));
 }
 
-void Dhcpv4SrvTest::messageCheck(const Pkt4Ptr& q, const Pkt4Ptr& a) {
+void
+Dhcpv4SrvTest::configureServerIdentifier() {
+    CfgMgr& cfg_mgr = CfgMgr::instance();
+    CfgSubnets4Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets4();
+
+    // Build and add subnet2.
+    Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"), 24, 1200, 2400, 3600, 2));
+    Pool4Ptr pool(new Pool4(IOAddress("192.0.2.100"), IOAddress("192.0.2.200")));
+    // Add server identifier to the pool.
+    OptionCustomPtr server_id = makeServerIdOption(IOAddress("192.0.2.254"));
+    CfgOptionPtr cfg_option = pool->getCfgOption();
+    cfg_option->add(server_id, false, DHCP4_OPTION_SPACE);
+    subnet2->addPool(pool);
+
+    // Add a second pool.
+    pool.reset(new Pool4(IOAddress("192.0.2.201"), IOAddress("192.0.2.220")));
+    subnet2->addPool(pool);
+
+    subnets->add(subnet2);
+
+    // Build and add subnet3.
+    Triplet<uint32_t> unspec;
+    Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.3.0"), 24, unspec, unspec, 3600, 3));
+    pool.reset(new Pool4(IOAddress("192.0.3.100"), IOAddress("192.0.3.200")));
+    subnet3->addPool(pool);
+    subnet3->setT1Percent(0.5);
+    subnet3->setT2Percent(0.75);
+    subnet3->setCalculateTeeTimes(true);
+
+    // Add server identifier.
+    server_id = makeServerIdOption(IOAddress("192.0.3.254"));
+    cfg_option = subnet3->getCfgOption();
+    cfg_option->add(server_id, false, DHCP4_OPTION_SPACE);
+
+    subnets->add(subnet3);
+
+    // Build and add subnet4.
+    Subnet4Ptr subnet4(new Subnet4(IOAddress("192.0.4.0"), 24, unspec, unspec, 3600, 4));
+    pool.reset(new Pool4(IOAddress("192.0.4.100"), IOAddress("192.0.4.200")));
+    subnet4->addPool(pool);
+    subnet4->setCalculateTeeTimes(false);
+
+    subnets->add(subnet4);
+
+    // Build and add subnet5.
+    Subnet4Ptr subnet5(new Subnet4(IOAddress("192.0.5.0"), 24, unspec, unspec, 3600, 5));
+    pool.reset(new Pool4(IOAddress("192.0.5.100"), IOAddress("192.0.5.200")));
+    subnet5->addPool(pool);
+    subnet5->setCalculateTeeTimes(false);
+
+    subnets->add(subnet5);
+
+    CfgOptionPtr options(new CfgOption());
+    OptionDescriptor desc(false);
+    desc.option_ = makeServerIdOption(IOAddress("192.0.5.254"));
+    options->add(desc, DHCP4_OPTION_SPACE);
+    CfgMgr::instance().getStagingCfg()->getClientClassDictionary()->addClass("foo", ExpressionPtr(), "", true, false, options);
+    subnet5->requireClientClass("foo");
+
+    // Build and add a shared-network.
+    CfgSharedNetworks4Ptr networks = cfg_mgr.getStagingCfg()->getCfgSharedNetworks4();
+    SharedNetwork4Ptr network1(new SharedNetwork4("one"));
+    network1->add(subnet4);
+
+    // Add server identifier.
+    server_id = makeServerIdOption(IOAddress("192.0.4.254"));
+    cfg_option = network1->getCfgOption();
+    cfg_option->add(server_id, false, DHCP4_OPTION_SPACE);
+
+    networks->add(network1);
+
+    // Add a global server identifier.
+    cfg_option = cfg_mgr.getStagingCfg()->getCfgOption();
+    server_id = makeServerIdOption(IOAddress("10.0.0.254"));
+    cfg_option->add(server_id, false, DHCP4_OPTION_SPACE);
+
+    // Commit the config.
+    cfg_mgr.commit();
+}
+
+void
+Dhcpv4SrvTest::messageCheck(const Pkt4Ptr& q, const Pkt4Ptr& a) {
     ASSERT_TRUE(q);
     ASSERT_TRUE(a);
 
@@ -256,7 +338,8 @@ Dhcpv4SrvTest::noRequestedOptions(const Pkt4Ptr& pkt) {
     return (::testing::AssertionSuccess());
 }
 
-OptionPtr Dhcpv4SrvTest::generateClientId(size_t size /*= 4*/) {
+OptionPtr
+Dhcpv4SrvTest::generateClientId(size_t size /*= 4*/) {
 
     OptionBuffer clnt_id(size);
     for (size_t i = 0; i < size; i++) {
@@ -270,7 +353,8 @@ OptionPtr Dhcpv4SrvTest::generateClientId(size_t size /*= 4*/) {
                                  clnt_id.begin() + size)));
 }
 
-HWAddrPtr Dhcpv4SrvTest::generateHWAddr(size_t size /*= 6*/) {
+HWAddrPtr
+Dhcpv4SrvTest::generateHWAddr(size_t size /*= 6*/) {
     const uint8_t hw_type = 123; // Just a fake number (typically 6=HTYPE_ETHER, see dhcp4.h)
     OptionBuffer mac(size);
     for (size_t i = 0; i < size; ++i) {
@@ -279,7 +363,17 @@ HWAddrPtr Dhcpv4SrvTest::generateHWAddr(size_t size /*= 6*/) {
     return (HWAddrPtr(new HWAddr(mac, hw_type)));
 }
 
-void Dhcpv4SrvTest::checkAddressParams(const Pkt4Ptr& rsp,
+OptionCustomPtr
+Dhcpv4SrvTest::makeServerIdOption(const IOAddress& address) {
+    OptionDefinitionPtr option_def = LibDHCP::getOptionDef(DHCP4_OPTION_SPACE,
+                                                           DHO_DHCP_SERVER_IDENTIFIER);
+    OptionCustomPtr server_id(new OptionCustom(*option_def, Option::V4));
+    server_id->writeAddress(address);
+    return (server_id);
+}
+
+void
+Dhcpv4SrvTest::checkAddressParams(const Pkt4Ptr& rsp,
                                        const Subnet4Ptr subnet,
                                        bool t1_present,
                                        bool t2_present,
@@ -331,7 +425,8 @@ void Dhcpv4SrvTest::checkAddressParams(const Pkt4Ptr& rsp,
     }
 }
 
-void Dhcpv4SrvTest::checkResponse(const Pkt4Ptr& rsp, int expected_message_type,
+void
+Dhcpv4SrvTest::checkResponse(const Pkt4Ptr& rsp, int expected_message_type,
                                   uint32_t expected_transid) {
     ASSERT_TRUE(rsp);
     EXPECT_EQ(expected_message_type,
@@ -339,7 +434,8 @@ void Dhcpv4SrvTest::checkResponse(const Pkt4Ptr& rsp, int expected_message_type,
     EXPECT_EQ(expected_transid, rsp->getTransid());
 }
 
-Lease4Ptr Dhcpv4SrvTest::checkLease(const Pkt4Ptr& rsp,
+Lease4Ptr
+Dhcpv4SrvTest::checkLease(const Pkt4Ptr& rsp,
                                     const OptionPtr& client_id,
                                     const HWAddrPtr&,
                                     const IOAddress& expected_addr) {
@@ -368,7 +464,8 @@ Lease4Ptr Dhcpv4SrvTest::checkLease(const Pkt4Ptr& rsp,
     return (lease);
 }
 
-void Dhcpv4SrvTest::checkServerId(const Pkt4Ptr& rsp, const OptionPtr& expected_srvid) {
+void
+Dhcpv4SrvTest::checkServerId(const Pkt4Ptr& rsp, const OptionPtr& expected_srvid) {
     // Check that server included its server-id
     OptionPtr opt = rsp->getOption(DHO_DHCP_SERVER_IDENTIFIER);
     ASSERT_TRUE(opt);
@@ -377,7 +474,8 @@ void Dhcpv4SrvTest::checkServerId(const Pkt4Ptr& rsp, const OptionPtr& expected_
     EXPECT_TRUE(opt->getData() == expected_srvid->getData());
 }
 
-void Dhcpv4SrvTest::checkClientId(const Pkt4Ptr& rsp, const OptionPtr& expected_clientid) {
+void
+Dhcpv4SrvTest::checkClientId(const Pkt4Ptr& rsp, const OptionPtr& expected_clientid) {
 
     bool include_clientid =
         CfgMgr::instance().getCurrentCfg()->getEchoClientId();
@@ -396,6 +494,17 @@ void Dhcpv4SrvTest::checkClientId(const Pkt4Ptr& rsp, const OptionPtr& expected_
     }
 }
 
+void
+Dhcpv4SrvTest::checkServerIdOption(const Pkt4Ptr& packet, const IOAddress& expected_address) {
+    OptionPtr opt = packet->getOption(DHO_DHCP_SERVER_IDENTIFIER);
+    ASSERT_TRUE(opt) << "no server-id option";
+
+    OptionCustomPtr server_id_opt = boost::dynamic_pointer_cast<OptionCustom>(opt);
+    ASSERT_TRUE(server_id_opt) << "server-id option is not an instance of OptionCustom";
+
+    EXPECT_EQ(expected_address, server_id_opt->readAddress());
+}
+
 ::testing::AssertionResult
 Dhcpv4SrvTest::createPacketFromBuffer(const Pkt4Ptr& src_pkt,
                                       Pkt4Ptr& dst_pkt) {
@@ -522,9 +631,7 @@ Dhcpv4SrvTest::testDiscoverRequest(const uint8_t msg_type) {
     received->setIface("eth0");
     received->setIndex(ETH0_INDEX);
     if (msg_type == DHCPDISCOVER) {
-        ASSERT_NO_THROW(
-            rsp = srv->processDiscover(received);
-        );
+        ASSERT_NO_THROW(rsp = srv->processDiscover(received));
 
         // Should return OFFER
         ASSERT_TRUE(rsp);
@@ -616,6 +723,39 @@ Dhcpv4SrvTest::testDiscoverRequest(const uint8_t msg_type) {
     }
 }
 
+void
+Dhcpv4SrvTest::buildCfgOptionTest(IOAddress expected_server_id,
+                                  Pkt4Ptr& query,
+                                  IOAddress requested,
+                                  IOAddress server_id) {
+    OptionDefinitionPtr req_addr_def = LibDHCP::getOptionDef(DHCP4_OPTION_SPACE,
+                                                             DHO_DHCP_REQUESTED_ADDRESS);
+    ASSERT_TRUE(req_addr_def);
+
+    OptionDefinitionPtr sbnsel_def = LibDHCP::getOptionDef(DHCP4_OPTION_SPACE,
+                                                           DHO_SUBNET_SELECTION);
+    ASSERT_TRUE(sbnsel_def);
+
+    OptionCustomPtr req_addr(new OptionCustom(*req_addr_def, Option::V4));
+    req_addr->writeAddress(requested);
+
+    OptionCustomPtr sbnsel(new OptionCustom(*sbnsel_def, Option::V4));
+    sbnsel->writeAddress(requested);
+
+    query->addOption(req_addr);
+    query->addOption(sbnsel);
+    query->addOption(makeServerIdOption(server_id));
+
+    Pkt4Ptr response;
+    ASSERT_NO_THROW(response = srv_.processRequest(query));
+
+    checkServerIdOption(response, expected_server_id);
+
+    ASSERT_NO_THROW(query->delOption(DHO_DHCP_REQUESTED_ADDRESS));
+    ASSERT_NO_THROW(query->delOption(DHO_SUBNET_SELECTION));
+    ASSERT_NO_THROW(query->delOption(DHO_DHCP_SERVER_IDENTIFIER));
+}
+
 void
 Dhcpv4SrvTest::configure(const std::string& config,
                          const bool commit,
index 7d35a16907ce48b4c192d3ec46575aeb9de737d8..e56175652431f6fa1e459fa1fe07890108acc0c1 100644 (file)
@@ -356,7 +356,11 @@ public:
     /// the server will not return it.
     void configureRequestedOptions();
 
+    /// @brief Configures server identifier at different levels.
+    void configureServerIdentifier();
+
     /// @brief checks that the response matches request
+    ///
     /// @param q query (client's message)
     /// @param a answer (server's message)
     void messageCheck(const Pkt4Ptr& q, const Pkt4Ptr& a);
@@ -404,6 +408,13 @@ public:
     /// @param pointer to Hardware Address object
     HWAddrPtr generateHWAddr(size_t size = 6);
 
+    /// @brief Convenience method for making a server identifier option instance.
+    ///
+    /// @param address IP address to add to the option
+    ///
+    /// @return Pointer to the newly constructed option.
+    OptionCustomPtr makeServerIdOption(const isc::asiolink::IOAddress& address);
+
     /// Check that address was returned from proper range, that its lease
     /// lifetime is correct, that T1 and T2 are returned properly
     /// @param rsp response to be checked
@@ -439,6 +450,7 @@ public:
                          const isc::asiolink::IOAddress& expected_addr);
 
     /// @brief Checks if server response (OFFER, ACK, NAK) includes proper server-id
+    ///
     /// @param rsp response packet to be validated
     /// @param expected_srvid expected value of server-id
     void checkServerId(const Pkt4Ptr& rsp, const OptionPtr& expected_srvid);
@@ -453,6 +465,12 @@ public:
     /// @param expected_clientid expected value of client-id
     void checkClientId(const Pkt4Ptr& rsp, const OptionPtr& expected_clientid);
 
+    /// @brief Checks the value of the dhcp-server-identifier option in a packet
+    ///
+    /// @param packet packet to test
+    /// @param expected_address IP address the packet's option should contain
+    void checkServerIdOption(const Pkt4Ptr& packet, const isc::asiolink::IOAddress& expected_address);
+
     /// @brief Create packet from output buffer of another packet.
     ///
     /// This function creates a packet using an output buffer from another
@@ -492,6 +510,17 @@ public:
     /// @param msg_type DHCPDISCOVER or DHCPREQUEST
     void testDiscoverRequest(const uint8_t msg_type);
 
+    /// @brief Create test which verifies server identifier.
+    ///
+    /// @param expected_server_id expected server identifier
+    /// @param query the query used to get associated client classes
+    /// @param query the requested the requested address
+    /// @param server_id server identifier
+    void buildCfgOptionTest(isc::asiolink::IOAddress expected_server_id,
+                            Pkt4Ptr& query,
+                            isc::asiolink::IOAddress requested,
+                            isc::asiolink::IOAddress server_id);
+
     /// @brief Runs DHCPv4 configuration from the JSON string.
     ///
     /// @param config String holding server configuration in JSON format.
index 40e11635abae5ce3614b4b05c7a5092ac25090b4..dfad15e4c1ebf1b8d930ba51853f8720d6917da9 100644 (file)
@@ -851,7 +851,7 @@ IfaceCollection::getIfaceInternal(const std::string& ifname, bool need_lock) {
             return (cache_);
         }
     } else {
-                if (cache_ && (cache_->getName() == ifname)) {
+        if (cache_ && (cache_->getName() == ifname)) {
             return (cache_);
         }
     }
index 3ead996142dc110fa68bb963ee194143efd55a52..b62ad159b1fa9d7e9a5c6a66236f7d5d22872b03 100644 (file)
@@ -448,7 +448,7 @@ CfgSubnets4::getSubnet(const SubnetID id) const {
 
 Subnet4Ptr
 CfgSubnets4::selectSubnet(const IOAddress& address,
-                 const ClientClasses& client_classes) const {
+                          const ClientClasses& client_classes) const {
     for (Subnet4Collection::const_iterator subnet = subnets_.begin();
          subnet != subnets_.end(); ++subnet) {