Commit 4d759e30 authored by Francis Dupont's avatar Francis Dupont

[5443] Checkpoint: updated DHCPv6 (todo hook tests)

parent ec9cc33e
......@@ -288,7 +288,7 @@ client's request and acted on it (e.g. possibly allocated a lease).
% DHCP4_HOOK_SUBNET4_SELECT_DROP %1: packet was dropped, because a callout set drop flag
This debug message is printed when a callout installed on the
subnet4_select hook point sets the drop flag. For this particular hook
point, the setting of the flag instructs the server to drop the receive
point, the setting of the flag instructs the server to drop the received
packet. The argument specifies the client and transaction identification
information.
......
......@@ -825,6 +825,7 @@ Dhcpv4Srv::run_one() {
LOG_DEBUG(bad_packet4_logger, DBG_DHCP4_BASIC,
DHCP4_PACKET_DROP_0008)
.arg(query->getLabel());
return;
} else {
processPacket(query, rsp);
}
......
......@@ -64,7 +64,9 @@ to the end of this list.
in their raw form. Unless you need to access to the raw data, it is
usually better to install your callout on the "pkt6_receive" hook point.
- <b>Next step status</b>: If any callout sets the status to SKIP, the
- <b>Next step status</b>: If any callout sets the status to DROP, the server
will drop the packet and start processing the next one.
If any callout sets the status to SKIP, the
server will assume that the callout parsed the buffer and added the
necessary option objects to the @c options_ field; the server will not
do any parsing. If the callout sets the skip flag but does not parse
......@@ -89,7 +91,7 @@ to the end of this list.
other fields in the Pkt6 object. For this reason, modification of the
@c data_ field would have no effect.)
- <b>Next step status</b>: If any callout sets the status to SKIP, the server will
- <b>Next step status</b>: If any callout sets the status to SKIP (or DROP), the server will
drop the packet and start processing the next one. The reason for the drop
will be logged if logging is set to the appropriate debug level.
......@@ -107,7 +109,9 @@ to the end of this list.
configured being provided as "subnet6collection". The list itself must
not be modified.
- <b>Next step status</b>: If any callout installed on "subnet6_select"
- <b>Next step status</b>: If any callout installed on "subnet6_select" sets
the status to DROP, the server will drop the packet and start processing
the next one. If any callout installed on "subnet6_select"
sets the status to SKIP, the server will not select any subnet. Packet processing
will continue, but will be severely limited.
......@@ -258,7 +262,7 @@ to the end of this list.
finish execution.
- <b>Next step status</b>: If any callout installed on "lease6_release"
sets the status to SKIP, the server will not delete the lease, which will
sets the status to SKIP (or DROP), the server will not delete the lease, which will
remain in the database until it expires. However, the server will send out
the response back to the client as if it did.
......@@ -283,8 +287,8 @@ to the end of this list.
and option objects into the @c buffer_out_ field and will skip packing part.
Note that if the callout sets skip flag, but did not prepare the
output buffer, the server will send a zero sized message that will be
ignored by the client. If you want to drop the packet, please see
skip flag in the "buffer6_send" hook point.
ignored by the client. If any callout sets the status to DROP,
the server will drop the prepared response.
@subsection dhcpv6HooksBuffer6Send buffer6_send
......@@ -302,7 +306,7 @@ to the end of this list.
to modify that data, it will probably be found easier to modify the
option objects in a callout attached to the "pkt6_send" hook).
- <b>Next step status</b>: If any callout sets the status to SKIP, the server
- <b>Next step status</b>: If any callout sets the status to SKIP (or DROP), the server
will drop this response packet. However, the original request packet
from a client has been processed, so server's state has most likely changed
(e.g. lease was allocated). Setting this flag merely stops the change
......
......@@ -246,13 +246,21 @@ A "libreload" command was issued to reload the hooks libraries but for
some reason the reload failed. Other error messages issued from the
hooks framework will indicate the nature of the problem.
% DHCP6_HOOK_BUFFER_RCVD_SKIP received buffer from %1 to %2 over interface %3 was dropped because a callout set the skip flag
% DHCP6_HOOK_BUFFER_RCVD_DROP received buffer from %1 to %2 over interface %3 was dropped because a callout set the drop flag
This debug message is printed when a callout installed on buffer6_receive
hook point set the skip flag. For this particular hook point, the
hook point set the drop flag. For this particular hook point, the
setting of the flag by a callout instructs the server to drop the packet.
The arguments specify the source and destination address as well as
the name of the interface over which the buffer has been received.
% DHCP6_HOOK_BUFFER_RCVD_SKIP received buffer from %1 to %2 over interface %3 is not parsed because a callout set the skip flag
This debug message is printed when a callout installed on
buffer6_receive hook point set the skip flag. For this particular hook
point, the setting of the flag by a callout instructs the server to
not parse the buffer because it was already parsed by the hook. The
arguments specify the source and destination address as well as the
name of the interface over which the buffer has been received.
% DHCP6_HOOK_BUFFER_SEND_SKIP %1: prepared DHCPv6 response was dropped because a callout set the skip flag
This debug message is printed when a callout installed on buffer6_send
hook point set the skip flag. For this particular hook point, the
......@@ -300,15 +308,23 @@ This debug message is printed when a callout installed on the pkt6_receive
hook point sets the skip flag. For this particular hook point, the
setting of the flag instructs the server to drop the packet.
% DHCP6_HOOK_PACKET_SEND_SKIP %1: prepared DHCPv6 response was not sent because a callout set the skip flag
% DHCP6_HOOK_PACKET_SEND_DROP %1: prepared DHCPv6 response was not sent because a callout set the drop flag
This debug message is printed when a callout installed on the pkt6_send
hook point set the skip flag. For this particular hook point, the setting
hook point set the drop flag. For this particular hook point, the setting
of the flag by a callout instructs the server to drop the packet. This
effectively means that the client will not get any response, even though
the server processed client's request and acted on it (e.g. possibly
allocated a lease). The argument specifies the client and transaction
identification information.
% DHCP6_HOOK_PACKET_SEND_SKIP %1: prepared DHCPv6 response is not built because a callout set the skip flag
This debug message is printed when a callout installed on the
pkt6_send hook point set the skip flag. For this particular hook
point, the setting of the flag by a callout instructs the server to
not build the wire data (pack) because it was already done by the
book. The argument specifies the client and transaction identification
information.
% DHCP6_HOOK_SUBNET6_SELECT_SKIP %1: no subnet was selected because a callout set the skip flag
This debug message is printed when a callout installed on the
subnet6_select hook point set the skip flag. For this particular hook
......@@ -318,6 +334,13 @@ will be only able to offer global options - no addresses or prefixes
will be assigned. The argument holds the client and transaction
identification information.
% DHCP6_HOOK_SUBNET6_SELECT_DROP %1: packet was dropped because a callout set the drop flag
This debug message is printed when a callout installed on the
subnet6_select hook point set the drop flag. For this particular hook
point, the setting of the flag instructs the server to drop the
received packet. The argument holds the client and transaction
identification information.
% DHCP6_INIT_FAIL failed to initialize Kea server: %1
The server has failed to establish communication with the rest of Kea,
failed to read JSON configuration file or encountered any other critical
......
......@@ -296,8 +296,10 @@ Dhcpv6Srv::testUnicast(const Pkt6Ptr& pkt) const {
}
void
Dhcpv6Srv::initContext(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx) {
ctx.subnet_ = selectSubnet(pkt);
Dhcpv6Srv::initContext(const Pkt6Ptr& pkt,
AllocEngine::ClientContext6& ctx,
bool& drop) {
ctx.subnet_ = selectSubnet(pkt, drop);
ctx.duid_ = pkt->getClientId(),
ctx.fwd_dns_update_ = false;
ctx.rev_dns_update_ = false;
......@@ -306,6 +308,11 @@ Dhcpv6Srv::initContext(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx) {
ctx.callout_handle_ = getCalloutHandle(pkt);
ctx.hwaddr_ = getMAC(pkt);
if (drop) {
// Caller will immediately drop the packet so simply return now.
return;
}
// Collect host identifiers if host reservations enabled. The identifiers
// are stored in order of preference. The server will use them in that
// order to search for host reservations.
......@@ -473,6 +480,7 @@ void Dhcpv6Srv::run_one() {
LOG_DEBUG(bad_packet6_logger, DBG_DHCP6_DETAIL_DATA,
DHCP6_PACKET_DROP_DHCP_DISABLED)
.arg(query->getLabel());
return;
} else {
processPacket(query, rsp);
}
......@@ -505,14 +513,13 @@ void Dhcpv6Srv::run_one() {
// Callouts decided to skip the next processing step. The next
// processing step would to parse the packet, so skip at this
// stage means drop.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
(callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_SEND_SKIP)
.arg(rsp->getLabel());
return;
}
/// @todo: Add support for DROP status
callout_handle->getArgument("response6", rsp);
}
......@@ -562,7 +569,20 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) {
skip_unpack = true;
}
/// @todo: Add support for DROP status.
// Callouts decided to drop the received packet
// The response (rsp) is null so the caller (run_one) will
// immediately return too.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
LOG_DEBUG(hooks_logger, DBG_DHCP6_DETAIL, DHCP6_HOOK_BUFFER_RCVD_DROP)
.arg(query->getRemoteAddr().toText())
.arg(query->getLocalAddr().toText())
.arg(query->getIface());
// Increase the statistic of dropped packets.
StatsMgr::instance().addValue("pkt6-receive-drop",
static_cast<int64_t>(1));
return;
}
callout_handle->getArgument("query6", query);
}
......@@ -648,14 +668,16 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) {
// Callouts decided to skip the next processing step. The next
// processing step would to process the packet, so skip at this
// stage means drop.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
(callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_RCVD_SKIP)
.arg(query->getLabel());
// Increase the statistic of dropped packets.
StatsMgr::instance().addValue("pkt6-receive-drop",
static_cast<int64_t>(1));
return;
}
/// @todo: Add support for DROP status.
callout_handle->getArgument("query6", query);
}
......@@ -807,7 +829,13 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) {
skip_pack = true;
}
/// @todo: Add support for DROP status
/// Callouts decided to drop the packet.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_SEND_DROP)
.arg(rsp->getLabel());
rsp.reset();
return;
}
}
if (!skip_pack) {
......@@ -1114,7 +1142,7 @@ Dhcpv6Srv::sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
}
Subnet6Ptr
Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question, bool& drop) {
// Initialize subnet selector with the values used to select the subnet.
SubnetSelector selector;
selector.iface_name_ = question->getIface();
......@@ -1174,7 +1202,14 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
return (Subnet6Ptr());
}
/// @todo: Add support for DROP status.
// Callouts decided to drop the packet. It is a superset of the
// skip case so no subnet will be selected.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_SUBNET6_SELECT_DROP)
.arg(question->getLabel());
drop = true;
return (Subnet6Ptr());
}
// Use whatever subnet was specified by the callout
callout_handle->getArgument("subnet6", subnet);
......@@ -2257,13 +2292,12 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
// Callouts decided to skip the next processing step. The next
// processing step would to send the packet, so skip at this
// stage means "drop response".
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
(callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
skip = true;
LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP)
.arg(query->getLabel());
}
/// @todo: Add support for DROP status
}
// Ok, we've passed all checks. Let's release this address.
......@@ -2473,7 +2507,13 @@ Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
initContext(solicit, ctx);
bool drop = false;
initContext(solicit, ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
}
Pkt6Ptr response(new Pkt6(DHCPV6_ADVERTISE, solicit->getTransid()));
......@@ -2522,7 +2562,13 @@ Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
initContext(request, ctx);
bool drop = false;
initContext(request, ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
}
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, request->getTransid()));
......@@ -2552,7 +2598,13 @@ Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
initContext(renew, ctx);
bool drop = false;
initContext(renew, ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
}
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, renew->getTransid()));
......@@ -2582,7 +2634,13 @@ Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
initContext(rebind, ctx);
bool drop = false;
initContext(rebind, ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
}
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, rebind->getTransid()));
......@@ -2612,7 +2670,14 @@ Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
initContext(confirm, ctx);
bool drop = false;
initContext(confirm, ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
}
setReservedClientClasses(confirm, ctx);
// Get IA_NAs from the Confirm. If there are none, the message is
......@@ -2705,7 +2770,14 @@ Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
initContext(release, ctx);
bool drop = false;
initContext(release, ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
}
setReservedClientClasses(release, ctx);
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, release->getTransid()));
......@@ -2734,7 +2806,14 @@ Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
initContext(decline, ctx);
bool drop = false;
initContext(decline, ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
}
setReservedClientClasses(decline, ctx);
// Copy client options (client-id, also relay information if present)
......@@ -3015,7 +3094,14 @@ Dhcpv6Srv::processInfRequest(const Pkt6Ptr& inf_request) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
initContext(inf_request, ctx);
bool drop = false;
initContext(inf_request, ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
}
setReservedClientClasses(inf_request, ctx);
// Create a Reply packet, with the same trans-id as the client's.
......
......@@ -313,8 +313,9 @@ protected:
/// @brief Selects a subnet for a given client's packet.
///
/// @param question client's message
/// @param drop if it is true the packet will be dropped
/// @return selected subnet (or NULL if no suitable subnet was found)
isc::dhcp::Subnet6Ptr selectSubnet(const Pkt6Ptr& question);
isc::dhcp::Subnet6Ptr selectSubnet(const Pkt6Ptr& question, bool& drop);
/// @brief Processes IA_NA option (and assigns addresses if necessary).
///
......@@ -688,7 +689,10 @@ protected:
///
/// @param pkt pointer to a packet for which context will be created.
/// @param [out] ctx reference to context object to be initialized.
void initContext(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx);
/// @param [out] drop if it is true the packet will be dropped.
void initContext(const Pkt6Ptr& pkt,
AllocEngine::ClientContext6& ctx,
bool& drop);
/// @brief this is a prefix added to the content of vendor-class option
///
......
......@@ -628,19 +628,23 @@ TEST_F(ClassifyTest, clientClassifySubnet) {
// This discover does not belong to foo class, so it will not
// be serviced
EXPECT_FALSE(srv_.selectSubnet(sol));
bool drop = false;
EXPECT_FALSE(srv_.selectSubnet(sol, drop));
EXPECT_FALSE(drop);
// Let's add the packet to bar class and try again.
sol->addClass("bar");
// Still not supported, because it belongs to wrong class.
EXPECT_FALSE(srv_.selectSubnet(sol));
EXPECT_FALSE(srv_.selectSubnet(sol, drop));
EXPECT_FALSE(drop);
// Let's add it to matching class.
sol->addClass("foo");
// This time it should work
EXPECT_TRUE(srv_.selectSubnet(sol));
EXPECT_TRUE(srv_.selectSubnet(sol, drop));
EXPECT_FALSE(drop);
}
// Tests whether a packet with custom vendor-class (not erouter or docsis)
......@@ -733,12 +737,15 @@ TEST_F(ClassifyTest, relayOverrideAndClientClass) {
// subnet[0], even though the relay-ip matches. It should be accepted in
// subnet[1], because the subnet matches and there are no class
// requirements.
EXPECT_TRUE(subnet2 == srv_.selectSubnet(sol));
bool drop = false;
EXPECT_TRUE(subnet2 == srv_.selectSubnet(sol, drop));
EXPECT_FALSE(drop);
// Now let's add this packet to class foo and recheck. This time it should
// be accepted in the first subnet, because both class and relay-ip match.
sol->addClass("foo");
EXPECT_TRUE(subnet1 == srv_.selectSubnet(sol));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(sol, drop));
EXPECT_FALSE(drop);
}
// This test checks that it is possible to specify static reservations for
......
......@@ -1233,7 +1233,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
// The clause for assuming local subnet if there is only one subnet is was
// removed.
EXPECT_FALSE(srv.selectSubnet(pkt));
bool drop = false;
EXPECT_FALSE(srv.selectSubnet(pkt, drop));
EXPECT_FALSE(drop);
// CASE 2: We have only one subnet defined and we received relayed traffic.
// We should NOT select it.
......@@ -1243,8 +1245,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1); // just a single subnet
CfgMgr::instance().commit();
pkt->setRemoteAddr(IOAddress("2001:db8:abcd::2345"));
Subnet6Ptr selected = srv.selectSubnet(pkt);
Subnet6Ptr selected = srv.selectSubnet(pkt, drop);
EXPECT_FALSE(selected);
EXPECT_FALSE(drop);
// CASE 3: We have three subnets defined and we received local traffic.
// Nothing should be selected.
......@@ -1254,8 +1257,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
pkt->setRemoteAddr(IOAddress("fe80::abcd"));
selected = srv.selectSubnet(pkt);
selected = srv.selectSubnet(pkt, drop);
EXPECT_FALSE(selected);
EXPECT_FALSE(drop);
// CASE 4: We have three subnets defined and we received relayed traffic
// that came out of subnet 2. We should select subnet2 then
......@@ -1265,8 +1269,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
pkt->setRemoteAddr(IOAddress("2001:db8:2::baca"));
selected = srv.selectSubnet(pkt);
selected = srv.selectSubnet(pkt, drop);
EXPECT_EQ(selected, subnet2);
EXPECT_FALSE(drop);
// CASE 5: We have three subnets defined and we received relayed traffic
// that came out of undefined subnet. We should select nothing
......@@ -1276,7 +1281,8 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
pkt->setRemoteAddr(IOAddress("2001:db8:4::baca"));
EXPECT_FALSE(srv.selectSubnet(pkt));
EXPECT_FALSE(srv.selectSubnet(pkt, drop));
EXPECT_FALSE(drop);
}
// This test verifies if selectSubnet() selects proper subnet for a given
......@@ -1300,8 +1306,10 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
pkt->setIface("eth0");
Subnet6Ptr selected = srv.selectSubnet(pkt);
bool drop = false;
Subnet6Ptr selected = srv.selectSubnet(pkt, drop);
EXPECT_EQ(selected, subnet1);
EXPECT_FALSE(drop);
// CASE 2: We have only one subnet defined and it is available via eth0.
// Packet came from eth1. We should not select it
......@@ -1311,8 +1319,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
pkt->setIface("eth1");
selected = srv.selectSubnet(pkt);
selected = srv.selectSubnet(pkt, drop);
EXPECT_FALSE(selected);
EXPECT_FALSE(drop);
// CASE 3: We have only 3 subnets defined, one over eth0, one remote and
// one over wifi1.
......@@ -1324,13 +1333,16 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
CfgMgr::instance().commit();
pkt->setIface("eth0");
EXPECT_EQ(subnet1, srv.selectSubnet(pkt));
EXPECT_EQ(subnet1, srv.selectSubnet(pkt, drop));
EXPECT_FALSE(drop);
pkt->setIface("eth3"); // no such interface
EXPECT_EQ(Subnet6Ptr(), srv.selectSubnet(pkt)); // nothing selected
EXPECT_EQ(Subnet6Ptr(), srv.selectSubnet(pkt, drop)); // nothing selected
EXPECT_FALSE(drop);
pkt->setIface("wifi1");
EXPECT_EQ(subnet3, srv.selectSubnet(pkt));
EXPECT_EQ(subnet3, srv.selectSubnet(pkt, drop));
EXPECT_FALSE(drop);
}
// This test verifies if selectSubnet() selects proper subnet for a given
......@@ -1355,8 +1367,10 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
pkt->relay_info_.push_back(relay);
Subnet6Ptr selected = srv.selectSubnet(pkt);
bool drop = false;
Subnet6Ptr selected = srv.selectSubnet(pkt, drop);
EXPECT_FALSE(selected);
EXPECT_FALSE(drop);
// CASE 2: We have three subnets defined and we received relayed traffic
// that came out of subnet 2. We should select subnet2 then
......@@ -1365,22 +1379,25 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
selected = srv.selectSubnet(pkt);
selected = srv.selectSubnet(pkt, drop);
EXPECT_EQ(selected, subnet2);
EXPECT_FALSE(drop);
// Source of the packet should have no meaning. Selection is based
// on linkaddr field in the relay
pkt->setRemoteAddr(IOAddress("2001:db8:1::baca"));
selected = srv.selectSubnet(pkt);
selected = srv.selectSubnet(pkt, drop);
EXPECT_EQ(selected, subnet2);
EXPECT_FALSE(drop);
// But not when this linkaddr field is not usable.
Pkt6::RelayInfo relay2;
relay2.peeraddr_ = IOAddress("fe80::1");
pkt->relay_info_.clear();
pkt->relay_info_.push_back(relay2);
selected = srv.selectSubnet(pkt);
selected = srv.selectSubnet(pkt, drop);
EXPECT_EQ(selected, subnet1);
EXPECT_FALSE(drop);
// CASE 3: We have three subnets defined and we received relayed traffic
// that came out a layer 2 relay on subnet 2. We should select subnet2 then
......@@ -1393,8 +1410,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
pkt->relay_info_.push_back(relay);
relay2.hop_count_ = 1;
pkt->relay_info_.push_back(relay2);
selected = srv.selectSubnet(pkt);
selected = srv.selectSubnet(pkt, drop);
EXPECT_EQ(selected, subnet2);
EXPECT_FALSE(drop);
// The number of level 2 relay doesn't matter
pkt->relay_info_.clear();
......@@ -1415,8 +1433,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
relay23.peeraddr_ = IOAddress("fe80::1");
relay23.hop_count_ = 4;
pkt->relay_info_.push_back(relay23);
selected = srv.selectSubnet(pkt);
selected = srv.selectSubnet(pkt, drop);
EXPECT_EQ(selected, subnet2);
EXPECT_FALSE(drop);
// Only the inner/last relay with a usable address matters