Commit 0a037d60 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[4497] Enable retrieved options copying for remaining DHCPv6 hooks.

buffer6_send and lease6_release (PD case) hook points didn't set
copying retrieved options flag for a packet passed to callouts.
parent c97c2e0e
......@@ -438,6 +438,9 @@ void Dhcpv6Srv::run_one() {
// Delete previously set arguments
callout_handle->deleteAllArguments();
// Enable copying options from the packet within hook library.
ScopedEnableOptionsCopy<Pkt6> response6_options_copy(rsp);
// Pass incoming packet as argument
callout_handle->setArgument("response6", rsp);
......@@ -2199,6 +2202,9 @@ Dhcpv6Srv::releaseIA_PD(const DuidPtr& duid, const Pkt6Ptr& query,
// Delete all previous arguments
callout_handle->deleteAllArguments();
// Enable copying options from the packet within hook library.
ScopedEnableOptionsCopy<Pkt6> query6_options_copy(query);
// Pass the original packet
callout_handle->setArgument("query6", query);
......
......@@ -356,6 +356,24 @@ public:
return pkt6_send_callout(callout_handle);
}
/// @brief Test callback that stores reponse packet.
/// @param callout_handle handle passed by the hooks framework.
/// @return always 0
static int
buffer6_send_callout(CalloutHandle& callout_handle) {
callback_name_ = string("buffer6_send");
callback_argument_names_ = callout_handle.getArgumentNames();
callout_handle.getArgument("response6", callback_resp_pkt6_);
if (callback_resp_pkt6_) {
callback_resp_options_copy_ = callback_resp_pkt6_->isCopyRetrievedOptions();
}
return (0);
}
/// Test callback that stores received callout name and subnet6 values
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
......@@ -1113,6 +1131,46 @@ TEST_F(HooksDhcpv6SrvTest, skipPkt6Send) {
EXPECT_EQ(0, sent->getBuffer().getLength());
}
// Checks if callouts installed on buffer6_send are indeed called and the
// all necessary parameters are passed.
TEST_F(HooksDhcpv6SrvTest, simpleBuffer6Send) {
// Install pkt6_receive_callout
EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
"buffer6_send", buffer6_send_callout));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(PktCaptures::captureSimpleSolicit());
// Simulate that we have received that traffic
srv_->fakeReceive(sol);
// Server will now process to run its normal loop, but instead of calling
// IfaceMgr::receive6(), it will read all packets from the list set by
// fakeReceive()
// In particular, it should call registered pkt6_receive callback.
srv_->run();
// Check that the callback called is indeed the one we installed
EXPECT_EQ("buffer6_send", callback_name_);
// Check that there is one packet sent
ASSERT_EQ(1, srv_->fake_sent_.size());
Pkt6Ptr adv = srv_->fake_sent_.front();
// Check that pkt6 argument passing was successful and returned proper
// values
EXPECT_TRUE(callback_resp_pkt6_.get() == adv.get());
// Check that all expected parameters are there
vector<string> expected_argument_names;
expected_argument_names.push_back(string("response6"));
EXPECT_TRUE(expected_argument_names == callback_argument_names_);
// Pkt passed to a callout must be configured to copy retrieved options.
EXPECT_TRUE(callback_resp_options_copy_);
}
// This test checks if subnet6_select callout is triggered and reports
// valid parameters
TEST_F(HooksDhcpv6SrvTest, subnet6Select) {
......@@ -1613,6 +1671,85 @@ TEST_F(HooksDhcpv6SrvTest, basicLease6Release) {
EXPECT_TRUE(callback_qry_options_copy_);
}
// This is a variant of the previous test that tests that callouts are
// properly invoked for the prefix release case.
TEST_F(HooksDhcpv6SrvTest, basicLease6ReleasePD) {
NakedDhcpv6Srv srv(0);
// Install pkt6_receive_callout
EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
"lease6_release", lease6_release_callout));
const IOAddress prefix("2001:db8:1:2:1::");
const uint32_t iaid = 234;
// Generate client-id also duid_
OptionPtr clientid = generateClientId();
// Check that the prefix we are about to use is indeed in pool
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_PD, prefix));
// Note that preferred, valid, T1 and T2 timers and CLTT are set to invalid
// value on purpose. They should be updated during RENEW.
Lease6Ptr lease(new Lease6(Lease::TYPE_PD, prefix, duid_, iaid,
501, 502, 503, 504, subnet_->getID(),
HWAddrPtr(), 80));
lease->cltt_ = 1234;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD,
prefix);
ASSERT_TRUE(l);
// Let's create a RELEASE
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
req->setRemoteAddr(IOAddress("fe80::abcd"));
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_PD, iaid, 1500, 3000);
OptionPtr released_addr_opt(new Option6IAPrefix(D6O_IAPREFIX, prefix, 80,
300, 500));
ia->addOption(released_addr_opt);
req->addOption(ia);
req->addOption(clientid);
// Server-id is mandatory in RELEASE
req->addOption(srv.getServerID());
// Pass it to the server and hope for a REPLY
Pkt6Ptr reply = srv.processRelease(req);
ASSERT_TRUE(reply);
// Check that the callback called is indeed the one we installed
EXPECT_EQ("lease6_release", callback_name_);
// Check that appropriate parameters are passed to the callouts
EXPECT_TRUE(callback_qry_pkt6_);
EXPECT_TRUE(callback_lease6_);
// Check if all expected parameters were really received
vector<string> expected_argument_names;
expected_argument_names.push_back("query6");
expected_argument_names.push_back("lease6");
sort(callback_argument_names_.begin(), callback_argument_names_.end());
sort(expected_argument_names.begin(), expected_argument_names.end());
EXPECT_TRUE(callback_argument_names_ == expected_argument_names);
// Check that the lease is really gone in the database
// get lease by address
l = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD, prefix);
ASSERT_FALSE(l);
// Get lease by subnetid/duid/iaid combination
l = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD, *duid_, iaid,
subnet_->getID());
ASSERT_FALSE(l);
// Pkt passed to a callout must be configured to copy retrieved options.
EXPECT_TRUE(callback_qry_options_copy_);
}
// This test verifies that incoming (positive) RELEASE can be handled properly,
// that a REPLY is generated, that the response has status code and that the
// lease is indeed removed from the database.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment