]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5132] host6_identifier unit-test implemented
authorTomek Mrugalski <tomasz@isc.org>
Wed, 29 Mar 2017 15:55:53 +0000 (10:55 -0500)
committerTomek Mrugalski <tomasz@isc.org>
Wed, 29 Mar 2017 15:55:53 +0000 (10:55 -0500)
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/tests/hooks_unittest.cc
src/bin/dhcp6/tests/hooks_unittest.cc

index 50b2ca7c55a1e5bcb92ca2c8f4039cb9a01df4bb..81a3e10a7537f84cdefada0d170dffeb30f2843b 100644 (file)
@@ -289,6 +289,7 @@ void
 Dhcpv4Exchange::setHostIdentifiers() {
     const ConstCfgHostOperationsPtr cfg =
         CfgMgr::instance().getCurrentCfg()->getCfgHostOperations4();
+
     // Collect host identifiers. The identifiers are stored in order of preference.
     // The server will use them in that order to search for host reservations.
     BOOST_FOREACH(const Host::IdentifierType& id_type,
@@ -341,7 +342,11 @@ Dhcpv4Exchange::setHostIdentifiers() {
             }
             break;
         case Host::IDENT_FLEX:
-            if (HooksManager::calloutsPresent(Hooks.hook_index_host4_identifier_)) {
+            {
+                if (!HooksManager::calloutsPresent(Hooks.hook_index_host4_identifier_)) {
+                    break;
+                }
+
                 CalloutHandlePtr callout_handle = getCalloutHandle(context_->query_);
 
                 Host::IdentifierType type = Host::IDENT_FLEX;
@@ -355,25 +360,23 @@ Dhcpv4Exchange::setHostIdentifiers() {
                 callout_handle->setArgument("id_type", type);
                 callout_handle->setArgument("id_value", id);
 
-                    // Call callouts
-                    HooksManager::callCallouts(Hooks.hook_index_host4_identifier_,
-                                               *callout_handle);
+                // Call callouts
+                HooksManager::callCallouts(Hooks.hook_index_host4_identifier_,
+                                           *callout_handle);
 
-                    callout_handle->getArgument("id_type", type);
-                    callout_handle->getArgument("id_value", id);
+                callout_handle->getArgument("id_type", type);
+                callout_handle->getArgument("id_value", id);
 
-                    if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
-                        !id.empty()) {
+                if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
+                    !id.empty()) {
 
-                        LOG_DEBUG(packet4_logger, DBGLVL_TRACE_BASIC, DHCP4_FLEX_ID)
-                            .arg(Host::getIdentifierAsText(type, &id[0], id.size()));
+                    LOG_DEBUG(packet4_logger, DBGLVL_TRACE_BASIC, DHCP4_FLEX_ID)
+                        .arg(Host::getIdentifierAsText(type, &id[0], id.size()));
 
-                        context_->addHostIdentifier(type, id);
-                    }
+                    context_->addHostIdentifier(type, id);
                 }
                 break;
-
-            
+            }
         default:
             ;
         }
index 656d551b06d5ed6b7506fcbb53df1bf6cb4dbbd5..d84e291ff19c5b91ca2601617517238321d9ace4 100644 (file)
@@ -547,7 +547,7 @@ public:
         return (lease4_decline_callout(callout_handle));
     }
 
-    /// @brief Test host4_identifier by setting identifier to "foo"
+    /// @brief Test host4_identifier callout by setting identifier to "foo"
     ///
     /// @param callout_handle handle passed by the hooks framework
     /// @return always 0
index 8a550c8de1fa90cb124469cf8f7f8eb5543a06b6..82753f4e28153a9f412430ca0e5cbfeba26f0291 100644 (file)
@@ -62,6 +62,8 @@ TEST_F(Dhcpv6SrvTest, Hooks) {
     int hook_index_pkt6_received   = -1;
     int hook_index_select_subnet   = -1;
     int hook_index_pkt6_send       = -1;
+    int hook_index_host6_identifier= -1;
+
 
     // check if appropriate indexes are set
     EXPECT_NO_THROW(hook_index_buffer6_receive = ServerHooks::getServerHooks()
@@ -82,6 +84,9 @@ TEST_F(Dhcpv6SrvTest, Hooks) {
                     .getIndex("subnet6_select"));
     EXPECT_NO_THROW(hook_index_pkt6_send     = ServerHooks::getServerHooks()
                     .getIndex("pkt6_send"));
+    EXPECT_NO_THROW(hook_index_host6_identifier = ServerHooks::getServerHooks()
+                    .getIndex("host6_identifier"));
+
 
     EXPECT_TRUE(hook_index_pkt6_received   > 0);
     EXPECT_TRUE(hook_index_select_subnet   > 0);
@@ -92,6 +97,7 @@ TEST_F(Dhcpv6SrvTest, Hooks) {
     EXPECT_TRUE(hook_index_lease6_release  > 0);
     EXPECT_TRUE(hook_index_lease6_rebind   > 0);
     EXPECT_TRUE(hook_index_lease6_decline  > 0);
+    EXPECT_TRUE(hook_index_host6_identifier > 0);
 }
 
 /// @brief a class dedicated to Hooks testing in DHCPv6 server
@@ -644,6 +650,25 @@ public:
         return (lease6_decline_callout(callout_handle));
     }
 
+    /// @brief Test host6_identifier by setting identifier to "foo"
+    ///
+    /// @param callout_handle handle passed by the hooks framework
+    /// @return always 0
+    static int
+    host6_identifier_foo_callout(CalloutHandle& handle) {
+        callback_name_ = string("host4_identifier");
+
+        std::vector<uint8_t> id(3);
+        id[0] = 0x66; // f
+        id[1] = 0x6f; // o
+        id[2] = 0x6f; // o
+        handle.setArgument("id_value", id);
+        handle.setArgument("id_type", Host::IDENT_FLEX);
+
+        return (0);
+    }
+
+
     /// Resets buffers used to store data received by callouts
     void resetCalloutBuffers() {
         callback_name_ = string("");
@@ -2228,6 +2253,80 @@ TEST_F(HooksDhcpv6SrvTest, lease6DeclineDrop) {
     EXPECT_EQ(Lease::STATE_DEFAULT, from_mgr->state_);
 }
 
+
+// Checks if callout installed on host6_identifier can generate an
+// identifier and whether that identifier is actually used.
+TEST_F(HooksDhcpv6SrvTest, host6Identifier) {
+
+    // Configure 2 subnets, both directly reachable over local interface
+    // (let's not complicate the matter with relays)
+    string config = "{ \"interfaces-config\": {"
+        "  \"interfaces\": [ \"*\" ]"
+        "},"
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
+        "    \"subnet\": \"2001:db8::/48\", "
+        "    \"interface\": \"" + valid_iface_ + "\", "
+        "    \"reservations\": ["
+        "        {"
+        "            \"flex-id\": \"'foo'\","
+        "            \"ip-addresses\": \"2001:db8::f00\""
+        "        }"
+        "    ]"
+        " } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    EXPECT_NO_THROW(json = parseDHCP6(config));
+    ConstElementPtr status;
+
+    // Configure the server and make sure the config is accepted
+    EXPECT_NO_THROW(status = configureDhcp6Server(*srv_, json));
+    ASSERT_TRUE(status);
+    comment_ = isc::config::parseAnswer(rcode_, status);
+    ASSERT_EQ(0, rcode_);
+
+    CfgMgr::instance().commit();
+
+    // Install host6_identifier_foo_callout
+    EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+                        "host6_identifier", host6_identifier_foo_callout));
+
+    // Prepare solicit packet. Server should select first subnet for it
+    Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
+    sol->setRemoteAddr(IOAddress("fe80::abcd"));
+    sol->setIface(valid_iface_);
+    sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
+    OptionPtr clientid = generateClientId();
+    sol->addOption(clientid);
+
+    // Pass it to the server and get an advertise
+    Pkt6Ptr adv = srv_->processSolicit(sol);
+
+    // Check if we get response at all
+    ASSERT_TRUE(adv);
+
+    // Check that the callback called is indeed the one we installed
+    EXPECT_EQ("host6_identifier", callback_name_);
+
+    // Check that pkt6 argument passing was successful and returned proper value
+    EXPECT_TRUE(callback_qry_pkt6_.get() == sol.get());
+
+    // Now check if we got the reserved address
+    OptionPtr tmp = adv->getOption(D6O_IA_NA);
+    ASSERT_TRUE(tmp);
+
+    // Check that IA_NA was returned and that there's an address included
+    boost::shared_ptr<Option6IAAddr> addr_opt = checkIA_NA(adv, 234, 1000, 2000);
+
+    ASSERT_TRUE(addr_opt);
+    ASSERT_EQ("2001:db8::f00", addr_opt->getAddress().toText());
+}
+
+
 // Verifies that libraries are unloaded by server destruction
 // The callout libraries write their library index number to a marker
 // file upon load and unload, making it simple to test whether or not