Commit 4a4c0999 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[3322] PktFilter6TestStub implemented.

parent 8174421f
......@@ -92,6 +92,7 @@ dhcp6_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/tests/libdhcptest.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libb10-dhcp_ddns.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
......
......@@ -29,6 +29,7 @@
#include <dhcp6/config_parser.h>
#include <dhcp/dhcp6.h>
#include <dhcp/docsis3_option_defs.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
......@@ -52,6 +53,7 @@ using namespace isc::config;
using namespace isc::test;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
using namespace isc::util;
using namespace isc::hooks;
using namespace std;
......@@ -283,6 +285,9 @@ TEST_F(Dhcpv6SrvTest, DUID) {
// This test checks if Option Request Option (ORO) is parsed correctly
// and the requested options are actually assigned.
TEST_F(Dhcpv6SrvTest, advertiseOptions) {
IfaceMgrTestConfig test_config(true);
ConstElementPtr x;
string config = "{ \"interfaces\": [ \"all\" ],"
"\"preferred-lifetime\": 3000,"
......@@ -291,6 +296,7 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
"\"subnet6\": [ { "
" \"pool\": [ \"2001:db8:1::/64\" ],"
" \"subnet\": \"2001:db8:1::/48\", "
" \"interface\": \"eth0\", "
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"space\": \"dhcp6\","
......@@ -307,25 +313,17 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
" } ]"
" } ],"
"\"valid-lifetime\": 4000 }";
ElementPtr json = Element::fromJSON(config);
NakedDhcpv6Srv srv(0);
EXPECT_NO_THROW(x = configureDhcp6Server(srv, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
ASSERT_NO_THROW(configure(config));
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
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);
Pkt6Ptr adv = srv_.processSolicit(sol);
// check if we get response at all
ASSERT_TRUE(adv);
......@@ -349,7 +347,7 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
sol->addOption(option_oro);
// Need to process SOLICIT again after requesting new option.
adv = srv.processSolicit(sol);
adv = srv_.processSolicit(sol);
ASSERT_TRUE(adv);
OptionPtr tmp = adv->getOption(D6O_NAME_SERVERS);
......@@ -404,6 +402,7 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) {
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
......@@ -447,6 +446,7 @@ TEST_F(Dhcpv6SrvTest, pdSolicitBasic) {
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
sol->addOption(generateIA(D6O_IA_PD, 234, 1500, 3000));
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
......@@ -492,6 +492,7 @@ TEST_F(Dhcpv6SrvTest, SolicitHint) {
// Let's create a SOLICIT
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
// with a valid hint
......@@ -546,6 +547,7 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) {
// Let's create a SOLICIT
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
IOAddress hint("2001:db8:1::cafe:babe");
ASSERT_FALSE(subnet_->inPool(Lease::TYPE_NA, hint));
......@@ -596,6 +598,10 @@ TEST_F(Dhcpv6SrvTest, ManySolicits) {
sol2->setRemoteAddr(IOAddress("fe80::1223"));
sol3->setRemoteAddr(IOAddress("fe80::3467"));
sol1->setIface("eth0");
sol2->setIface("eth0");
sol3->setIface("eth0");
sol1->addOption(generateIA(D6O_IA_NA, 1, 1500, 3000));
sol2->addOption(generateIA(D6O_IA_NA, 2, 1500, 3000));
sol3->addOption(generateIA(D6O_IA_NA, 3, 1500, 3000));
......@@ -673,6 +679,7 @@ TEST_F(Dhcpv6SrvTest, RequestBasic) {
// Let's create a REQUEST
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
req->setRemoteAddr(IOAddress("fe80::abcd"));
req->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
// with a valid hint
......@@ -737,6 +744,7 @@ TEST_F(Dhcpv6SrvTest, pdRequestBasic) {
// Let's create a REQUEST
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
req->setRemoteAddr(IOAddress("fe80::abcd"));
req->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_PD, 234, 1500, 3000);
// with a valid hint
......@@ -800,6 +808,10 @@ TEST_F(Dhcpv6SrvTest, ManyRequests) {
req2->setRemoteAddr(IOAddress("fe80::1223"));
req3->setRemoteAddr(IOAddress("fe80::3467"));
req1->setIface("eth0");
req2->setIface("eth0");
req3->setIface("eth0");
req1->addOption(generateIA(D6O_IA_NA, 1, 1500, 3000));
req2->addOption(generateIA(D6O_IA_NA, 2, 1500, 3000));
req3->addOption(generateIA(D6O_IA_NA, 3, 1500, 3000));
......@@ -1122,15 +1134,16 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), 48, 1, 2, 3, 4));
// CASE 1: We have only one subnet defined and we received local traffic.
// The only available subnet should be selected
// The only available subnet used to be picked, but not anymore
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1); // just a single subnet
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
pkt->setRemoteAddr(IOAddress("fe80::abcd"));
Subnet6Ptr selected = srv.selectSubnet(pkt);
EXPECT_EQ(selected, subnet1);
// The clause for assuming local subnet if there is only one subnet is was
// removed.
EXPECT_FALSE(srv.selectSubnet(pkt));
// CASE 2: We have only one subnet defined and we received relayed traffic.
// We should NOT select it.
......@@ -1139,7 +1152,7 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1); // just a single subnet
pkt->setRemoteAddr(IOAddress("2001:db8:abcd::2345"));
selected = srv.selectSubnet(pkt);
Subnet6Ptr selected = srv.selectSubnet(pkt);
EXPECT_FALSE(selected);
// CASE 3: We have three subnets defined and we received local traffic.
......@@ -1169,9 +1182,7 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
pkt->setRemoteAddr(IOAddress("2001:db8:4::baca"));
selected = srv.selectSubnet(pkt);
EXPECT_FALSE(selected);
EXPECT_FALSE(srv.selectSubnet(pkt));
}
// This test verifies if selectSubnet() selects proper subnet for a given
......@@ -1497,7 +1508,9 @@ TEST_F(Dhcpv6SrvTest, docsisVendorORO) {
// This test checks if Option Request Option (ORO) in docsis (vendor-id=4491)
// vendor options is parsed correctly and the requested options are actually assigned.
TEST_F(Dhcpv6SrvTest, vendorOptionsORO) {
ConstElementPtr x;
IfaceMgrTestConfig test_config(true);
string config = "{ \"interfaces\": [ \"all\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
......@@ -1526,28 +1539,21 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsORO) {
" \"preferred-lifetime\": 3000,"
" \"valid-lifetime\": 4000,"
" \"interface-id\": \"\","
" \"interface\": \"\""
" \"interface\": \"eth0\""
" } ],"
"\"valid-lifetime\": 4000 }";
ElementPtr json = Element::fromJSON(config);
NakedDhcpv6Srv srv(0);
EXPECT_NO_THROW(x = configureDhcp6Server(srv, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
EXPECT_NO_THROW(configure(config));
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
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);
Pkt6Ptr adv = srv_.processSolicit(sol);
// check if we get response at all
ASSERT_TRUE(adv);
......@@ -1566,7 +1572,7 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsORO) {
sol->addOption(vendor);
// Need to process SOLICIT again after requesting new option.
adv = srv.processSolicit(sol);
adv = srv_.processSolicit(sol);
ASSERT_TRUE(adv);
// Check if thre is vendor option response
......
......@@ -14,13 +14,39 @@
#include <gtest/gtest.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
#include <dhcp6/config_parser.h>
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::asiolink;
namespace isc {
namespace test {
Dhcpv6SrvTest::Dhcpv6SrvTest()
:srv_(0) {
subnet_ = isc::dhcp::Subnet6Ptr
(new isc::dhcp::Subnet6(isc::asiolink::IOAddress("2001:db8:1::"),
48, 1000, 2000, 3000, 4000));
subnet_->setIface("eth0");
pool_ = isc::dhcp::Pool6Ptr
(new isc::dhcp::Pool6(isc::dhcp::Lease::TYPE_NA,
isc::asiolink::IOAddress("2001:db8:1:1::"),
64));
subnet_->addPool(pool_);
isc::dhcp::CfgMgr::instance().deleteSubnets6();
isc::dhcp::CfgMgr::instance().addSubnet6(subnet_);
// configure PD pool
pd_pool_ = isc::dhcp::Pool6Ptr
(new isc::dhcp::Pool6(isc::dhcp::Lease::TYPE_PD,
isc::asiolink::IOAddress("2001:db8:1:2::"),
64, 80));
subnet_->addPool(pd_pool_);
}
// Checks that server response (ADVERTISE or REPLY) contains proper IA_NA option
// It returns IAADDR option for each chaining with checkIAAddr method.
boost::shared_ptr<Option6IAAddr>
......@@ -125,6 +151,7 @@ Dhcpv6SrvTest::createMessage(uint8_t message_type, Lease::Type lease_type,
// Let's create a RENEW
Pkt6Ptr msg = Pkt6Ptr(new Pkt6(message_type, 1234));
msg->setRemoteAddr(IOAddress("fe80::abcd"));
msg->setIface("eth0");
uint16_t code;
OptionPtr subopt;
......@@ -544,6 +571,19 @@ Dhcpv6SrvTest::testReleaseReject(Lease::Type type, const IOAddress& addr) {
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr));
}
void
Dhcpv6SrvTest::configure(const std::string& config) {
ElementPtr json = data::Element::fromJSON(config);
ConstElementPtr status;
// Configure the server and make sure the config is accepted
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
ASSERT_TRUE(status);
int rcode;
ConstElementPtr comment = config::parseAnswer(rcode, status);
ASSERT_EQ(0, rcode);
}
// Generate IA_NA option with specified parameters
boost::shared_ptr<Option6IA>
......
......@@ -339,26 +339,7 @@ public:
///
/// Sets up a single subnet6 with one pool for addresses and second
/// pool for prefixes.
Dhcpv6SrvTest() {
subnet_ = isc::dhcp::Subnet6Ptr
(new isc::dhcp::Subnet6(isc::asiolink::IOAddress("2001:db8:1::"),
48, 1000, 2000, 3000, 4000));
pool_ = isc::dhcp::Pool6Ptr
(new isc::dhcp::Pool6(isc::dhcp::Lease::TYPE_NA,
isc::asiolink::IOAddress("2001:db8:1:1::"),
64));
subnet_->addPool(pool_);
isc::dhcp::CfgMgr::instance().deleteSubnets6();
isc::dhcp::CfgMgr::instance().addSubnet6(subnet_);
// configure PD pool
pd_pool_ = isc::dhcp::Pool6Ptr
(new isc::dhcp::Pool6(isc::dhcp::Lease::TYPE_PD,
isc::asiolink::IOAddress("2001:db8:1:2::"),
64, 80));
subnet_->addPool(pd_pool_);
}
Dhcpv6SrvTest();
/// @brief destructor
///
......@@ -367,6 +348,12 @@ public:
isc::dhcp::CfgMgr::instance().deleteSubnets6();
};
/// @brief Runs DHCPv6 configuration from the JSON string.
///
/// @param config String holding server configuration in JSON format.
void
configure(const std::string& config);
/// @brief Checks that server response (ADVERTISE or REPLY) contains proper
/// IA_NA option
///
......@@ -524,6 +511,9 @@ public:
/// A prefix pool used in most tests
isc::dhcp::Pool6Ptr pd_pool_;
/// @brief Server object under test.
NakedDhcpv6Srv srv_;
};
}; // end of isc::test namespace
......
......@@ -98,6 +98,7 @@ public:
OptionPtr srvid = OptionPtr()) {
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(msg_type, 1234));
pkt->setRemoteAddr(IOAddress("fe80::abcd"));
pkt->setIface("eth0");
Option6IAPtr ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
if (msg_type != DHCPV6_REPLY) {
......@@ -844,6 +845,7 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestReuseExpiredLease) {
CfgMgr::instance().deleteSubnets6();
subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1:1::"), 56, 1, 2,
3, 4));
subnet_->setIface("eth0");
pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, addr, addr));
subnet_->addPool(pool_);
CfgMgr::instance().addSubnet6(subnet_);
......
......@@ -1066,6 +1066,7 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_renew) {
// Let's create a RENEW
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
req->setRemoteAddr(IOAddress("fe80::abcd"));
req->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
......@@ -1163,6 +1164,7 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdate_lease6_renew) {
// Let's create a RENEW
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
req->setRemoteAddr(IOAddress("fe80::abcd"));
req->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
......@@ -1254,6 +1256,7 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_renew) {
// Let's create a RENEW
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
req->setRemoteAddr(IOAddress("fe80::abcd"));
req->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, iaid, 1500, 3000);
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
......
......@@ -36,6 +36,7 @@ noinst_LTLIBRARIES = libdhcptest.la
libdhcptest_la_SOURCES = iface_mgr_test_config.cc iface_mgr_test_config.h
libdhcptest_la_SOURCES += pkt_filter_test_stub.cc pkt_filter_test_stub.h
libdhcptest_la_SOURCES += pkt_filter6_test_stub.cc pkt_filter6_test_stub.h
libdhcptest_la_CXXFLAGS = $(AM_CXXFLAGS)
libdhcptest_la_CPPFLAGS = $(AM_CPPFLAGS)
libdhcptest_la_LDFLAGS = $(AM_LDFLAGS)
......@@ -71,6 +72,7 @@ libdhcp___unittests_SOURCES += pkt_filter_unittest.cc
libdhcp___unittests_SOURCES += pkt_filter_inet_unittest.cc
libdhcp___unittests_SOURCES += pkt_filter_inet6_unittest.cc
libdhcp___unittests_SOURCES += pkt_filter_test_stub.cc pkt_filter_test_stub.h
libdhcp___unittests_SOURCES += pkt_filter6_test_stub.cc pkt_filter_test_stub.h
libdhcp___unittests_SOURCES += pkt_filter_test_utils.h pkt_filter_test_utils.cc
libdhcp___unittests_SOURCES += pkt_filter6_test_utils.h pkt_filter6_test_utils.cc
......
......@@ -16,6 +16,7 @@
#include <dhcp/pkt_filter_inet.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcp/tests/pkt_filter_test_stub.h>
#include <dhcp/tests/pkt_filter6_test_stub.h>
using namespace isc::asiolink;
......@@ -27,7 +28,9 @@ IfaceMgrTestConfig::IfaceMgrTestConfig(const bool default_config) {
IfaceMgr::instance().closeSockets();
IfaceMgr::instance().clearIfaces();
packet_filter4_ = PktFilterPtr(new PktFilterTestStub());
packet_filter6_ = PktFilter6Ptr(new PktFilter6TestStub());
IfaceMgr::instance().setPacketFilter(packet_filter4_);
IfaceMgr::instance().setPacketFilter(packet_filter6_);
// Create default set of fake interfaces: lo, eth0 and eth1.
if (default_config) {
......
......@@ -232,6 +232,8 @@ private:
/// @brief Currently used packet filter for DHCPv4.
PktFilterPtr packet_filter4_;
/// @brief Currently used packet filter for DHCPv6.
PktFilter6Ptr packet_filter6_;
};
};
......
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcp/tests/pkt_filter6_test_stub.h>
namespace isc {
namespace dhcp {
namespace test {
PktFilter6TestStub::PktFilter6TestStub() {
}
SocketInfo
PktFilter6TestStub::openSocket(const Iface&,
const isc::asiolink::IOAddress& addr,
const uint16_t port, const bool) {
return (SocketInfo(addr, port, 0));
}
Pkt6Ptr
PktFilter6TestStub::receive(const SocketInfo&) {
return Pkt6Ptr();
}
bool
PktFilter6TestStub::joinMulticast(int, const std::string&,
const std::string &) {
return (true);
}
int
PktFilter6TestStub::send(const Iface&, uint16_t, const Pkt6Ptr&) {
return (0);
}
}
}
}
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef PKT_FILTER6_TEST_STUB_H
#define PKT_FILTER6_TEST_STUB_H
#include <asiolink/io_address.h>
#include <dhcp/iface_mgr.h>
#include <dhcp/pkt_filter6.h>
#include <dhcp/pkt6.h>
namespace isc {
namespace dhcp {
namespace test {
/// @brief A stub implementation of the PktFilter6 class.
///
/// This class implements abstract methods of the @c isc::dhcp::PktFilter6
/// class. It is used by unit tests, which test protected methods of the
/// @c isc::dhcp::test::PktFilter6 class. The implemented abstract methods are
/// no-op.
class PktFilter6TestStub : public PktFilter6 {
public:
/// @brief Constructor.
PktFilter6TestStub();
/// @brief Simulate opening of the socket.
///
/// This function simulates opening a primary socket. In reality, it doesn't
/// open a socket but the socket descriptor returned in the SocketInfo
/// structure is always set to 0.
///
/// @param iface An interface descriptor.
/// @param addr Address on the interface to be used to send packets.
/// @param port Port number to bind socket to.
/// @param join_multicast A flag which indicates if the socket should be
/// configured to join multicast (if true).
///
/// @note All parameters are ignored.
///
/// @return A SocketInfo structure with the socket descriptor set to 0. The
/// fallback socket descriptor is set to a negative value.
virtual SocketInfo openSocket(const Iface& iface,
const isc::asiolink::IOAddress& addr,
const uint16_t port,
const bool join_multicast);
/// @brief Simulate reception of the DHCPv6 message.
///
/// @param socket_info A structure holding socket information.
///
/// @note All parameters are ignored.
///
/// @return always a NULL object.
virtual Pkt6Ptr receive(const SocketInfo& socket_info);
/// @brief Simulates sending a DHCPv6 message.
///
/// This function does nothing.
///
/// @param iface An interface to be used to send DHCPv6 message.
/// @param port A port used to send a message.
/// @param pkt A DHCPv6 to be sent.
///
/// @note All parameters are ignored.
///
/// @return 0.
virtual int send(const Iface& iface, uint16_t port, const Pkt6Ptr& pkt);
/// @brief Simulate joining IPv6 multicast group on a socket.
///
/// @note All parameters are ignored.
///
/// @param sock A socket descriptor (socket must be bound).
/// @param ifname An interface name (for link-scoped multicast groups).
/// @param mcast A multicast address to join (e.g. "ff02::1:2").
///
/// @return true if multicast join was successful
static bool joinMulticast(int sock, const std::string& ifname,
const std::string & mcast);
};
} // namespace isc::dhcp::test
} // namespace isc::dhcp
} // namespace isc
#endif // PKT_FILTER_TEST_STUB_H
......@@ -157,21 +157,6 @@ CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint,
const isc::dhcp::ClientClasses& classes,
const bool relay) {
// If there's only one subnet configured, let's just use it
// The idea is to keep small deployments easy. In a small network - one
// router that also runs DHCPv6 server. User specifies a single pool and
// expects it to just work. Without this, the server would complain that it
// doesn't have IP address on its interfaces that matches that
// configuration. Such requirement makes sense in IPv4, but not in IPv6.
// The server does not need to have a global address (using just link-local
// is ok for DHCPv6 server) from the pool it serves.
if ((subnets6_.size() == 1) && hint.isV6LinkLocal()) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
DHCPSRV_CFGMGR_ONLY_SUBNET6)
.arg(subnets6_[0]->toText()).arg(hint.toText());
return (subnets6_[0]);
}
// If there is more than one, we need to choose the proper one
for (Subnet6Collection::iterator subnet = subnets6_.begin();
subnet != subnets6_.end(); ++subnet) {
......