Commit 1ed4f636 authored by Francis Dupont's avatar Francis Dupont
Browse files

[master] Merged trac5443 (NEXT_STEP_DROP)

parents 6ed7380d 84d4aad0
// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -61,15 +61,15 @@ to the end of this list.
are set yet. Callouts installed on this hook point can modify the data
in the received buffer. The server will parse the buffer afterwards.
- <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 DROP, the server
will drop the packet and start processing the next one.
If any callout sets the status to SKIP, the server will
skip the buffer parsing. In this case there is an expectation that
the callout will parse the options carried in the buffer, create
@c isc::dhcp::Option objects (or derived) and add them to the "query4"
object using the @c isc::dhcp::Pkt4::addOption.
Otherwise the server will find out that some mandatory options are
missing (e.g. DHCP Message Type) and will drop the message. If you
want to have the capability to drop a message, it is better to use
the skip flag in the "pkt4_receive" callout.
missing (e.g. DHCP Message Type) and will drop the message.
@subsection dhcpv4HooksPkt4Receive pkt4_receive
......@@ -87,7 +87,7 @@ to the end of this list.
field has been already parsed and stored in other fields. Therefore,
the modification in the data_ field has 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 +107,9 @@ to the end of this list.
not be modified.
- <b>Next step status</b>: If any callout installed on the "subnet4_select" hook
sets the next step status to SKIP, the server will not select any subnet.
sets the next step status to DROP, the server cancels current processing,
drop the packet and start processing the next one.
If any callout sets the status to SKIP, the server will not select any subnet.
Packet processing will continue, but will be severely limited.
@subsection dhcpv4HooksHost4Identifier host4_identifier
......@@ -186,7 +188,7 @@ to the end of this list.
be released. It doesn't make sense to modify it at this time.
- <b>Next step status</b>: If any callout installed on the "lease4_release" hook
sets the next step action to SKIP, the server will not delete the lease.
sets the next step action to SKIP or DROP, the server will not delete the lease.
It will be kept in the database and will go through the regular expiration/reuse
process.
......@@ -206,8 +208,8 @@ to the end of this list.
modify it at this time. All the information will be removed from the lease
before it is updated in the database.
- <b>Next step status</b>: If any callout installed on the "lease4_release" hook
sets the next step action to DROP, the server will not decline the lease.
- <b>Next step status</b>: If any callout installed on the "lease4_decline" hook
sets the next step action to SKIP or DROP, the server will not decline the lease.
Care should be taken when setting this status. The lease will be kept in
the database as it is and the client will incorrectly assume that the server
marked this lease as unavailable. If the client restarts its configuration,
......@@ -233,7 +235,7 @@ to the end of this list.
cannot be modified.
- <b>Next step action</b>: if any callout installed on the "pkt4_send" hook
sets the next step action to SKIP, the server will not construct the raw
sets the next step action to SKIP or DROP, the server will not construct the raw
buffer. The expectation is that if the callout set skip flag, it is
responsible for constructing raw form on its own. Otherwise the output
packet will be sent with zero length.
......@@ -254,7 +256,7 @@ to the end of this list.
time, because they were already used to construct on-wire buffer. Their
modification would have no effect.
- <b>Next step status</b>: if any callout sets the next step action to SKIP,
- <b>Next step status</b>: if any callout sets the next step action to SKIP or DROP,
the server will drop this response packet. However, the original request
packet from a client was processed, so server's state most likely has changed
(e.g. lease was allocated). Setting this flag merely stops the change
......
# Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -238,17 +238,25 @@ 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.
% DHCP4_HOOK_BUFFER_RCVD_SKIP received buffer from %1 to %2 over interface %3 was dropped because a callout set the skip flag
% DHCP4_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 buffer4_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 IPv4 address as well as
the name of the interface over which the buffer has been received.
% DHCP4_HOOK_BUFFER_SEND_SKIP %1: prepared response is dropped because a callout set the skip flag.
% DHCP4_HOOK_BUFFER_RCVD_SKIP received buffer from %1 to %2 over interface %3 is not parsed because a callout set the next step to SKIP.
This debug message is printed when a callout installed on
buffer4_receive hook point set the next step to SKIP. For this particular hook
point, this value set 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 IPv4 address as well as
the name of the interface over which the buffer has been received.
% DHCP4_HOOK_BUFFER_SEND_SKIP %1: prepared response is dropped because a callout set the next step to SKIP.
This debug message is printed when a callout installed on buffer4_send
hook point set the skip flag. For this particular hook point, the
setting of the flag by a callout instructs the server to drop the packet.
hook point set the next step to SKIP. For this particular hook point, the
SKIP value set by a callout instructs the server to drop the packet.
Server completed all the processing (e.g. may have assigned, updated
or released leases), but the response will not be send to the client.
......@@ -259,27 +267,33 @@ for decline4 hook point and one of the callouts set next step status to DROP.
The server will now abort processing of the packet as if it was never
received. The lease will continue to be assigned to this client.
% DHCP4_HOOK_LEASE4_RELEASE_SKIP %1: lease was not released because a callout set the skip flag.
% DHCP4_HOOK_LEASE4_RELEASE_SKIP %1: lease was not released because a callout set the next step to SKIP
This debug message is printed when a callout installed on lease4_release
hook point set the skip flag. For this particular hook point, the
setting of the flag by a callout instructs the server to not release
a lease.
hook point set the next step status to SKIP. For this particular hook point, the
value set by a callout instructs the server to not release a lease.
% DHCP4_HOOK_PACKET_RCVD_SKIP %1: packet is dropped, because a callout set the skip flag.
% DHCP4_HOOK_PACKET_RCVD_SKIP %1: packet is dropped, because a callout set the next step to SKIP
This debug message is printed when a callout installed on the pkt4_receive
hook point sets the skip flag. For this particular hook point, the
setting of the flag instructs the server to drop the packet.
hook point sets the next step to SKIP. For this particular hook point, the
value setting of the flag instructs the server to drop the packet.
% DHCP4_HOOK_PACKET_SEND_SKIP %1: prepared response is not sent, because a callout set skip flag.
% DHCP4_HOOK_PACKET_SEND_SKIP %1: prepared response is not sent, because a callout set the next stp to SKIP
This debug message is printed when a callout installed on the pkt4_send
hook point sets the skip flag. For this particular hook point, the setting
of the flag instructs the server to drop the packet. This means that
hook point sets the next step to SKIP. For this particular hook point, this
setting instructs the server to drop the packet. This 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).
% DHCP4_HOOK_SUBNET4_SELECT_SKIP %1: no subnet was selected, because a callout set skip flag.
% DHCP4_HOOK_SUBNET4_SELECT_DROP %1: packet was dropped, because a callout set the next step to 'drop'
This debug message is printed when a callout installed on the
subnet4_select hook point sets the next step to 'drop' value. For this particular hook
point, the setting to that value instructs the server to drop the received
packet. The argument specifies the client and transaction identification
information.
% DHCP4_HOOK_SUBNET4_SELECT_SKIP %1: no subnet was selected, because a callout set the next skip flag
This debug message is printed when a callout installed on the
subnet4_select hook point sets the skip flag. For this particular hook
subnet4_select hook point sets the next step to SKIP value. For this particular hook
point, the setting of the flag instructs the server not to choose a
subnet, an action that severely limits further processing; the server
will be only able to offer global options - no addresses will be assigned.
......
......@@ -483,11 +483,11 @@ Dhcpv4Srv::shutdown() {
}
isc::dhcp::Subnet4Ptr
Dhcpv4Srv::selectSubnet(const Pkt4Ptr& query) const {
Dhcpv4Srv::selectSubnet(const Pkt4Ptr& query, bool& drop) const {
// DHCPv4-over-DHCPv6 is a special (and complex) case
if (query->isDhcp4o6()) {
return (selectSubnet4o6(query));
return (selectSubnet4o6(query, drop));
}
Subnet4Ptr subnet;
......@@ -569,7 +569,15 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& query) const {
return (Subnet4Ptr());
}
/// @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_DHCP4_HOOKS,
DHCP4_HOOK_SUBNET4_SELECT_DROP)
.arg(query->getLabel());
drop = true;
return (Subnet4Ptr());
}
// Use whatever subnet was specified by the callout
callout_handle->getArgument("subnet4", subnet);
......@@ -596,7 +604,7 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& query) const {
}
isc::dhcp::Subnet4Ptr
Dhcpv4Srv::selectSubnet4o6(const Pkt4Ptr& query) const {
Dhcpv4Srv::selectSubnet4o6(const Pkt4Ptr& query, bool& drop) const {
Subnet4Ptr subnet;
......@@ -673,7 +681,15 @@ Dhcpv4Srv::selectSubnet4o6(const Pkt4Ptr& query) const {
return (Subnet4Ptr());
}
/// @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_DHCP4_HOOKS,
DHCP4_HOOK_SUBNET4_SELECT_DROP)
.arg(query->getLabel());
drop = true;
return (Subnet4Ptr());
}
// Use whatever subnet was specified by the callout
callout_handle->getArgument("subnet4", subnet);
......@@ -809,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);
}
......@@ -841,15 +858,14 @@ Dhcpv4Srv::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_DHCP4_HOOKS,
DHCP4_HOOK_BUFFER_SEND_SKIP)
.arg(rsp->getLabel());
return;
}
/// @todo: Add support for DROP status.
callout_handle->getArgument("response4", rsp);
}
......@@ -911,6 +927,18 @@ Dhcpv4Srv::processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp) {
HooksManager::callCallouts(Hooks.hook_index_buffer4_receive_,
*callout_handle);
// 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_DHCP4_DETAIL,
DHCP4_HOOK_BUFFER_RCVD_DROP)
.arg(query->getRemoteAddr().toText())
.arg(query->getLocalAddr().toText())
.arg(query->getIface());
return;
}
// Callouts decided to skip the next processing step. The next
// processing step would to parse the packet, so skip at this
// stage means that callouts did the parsing already, so server
......@@ -925,8 +953,6 @@ Dhcpv4Srv::processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp) {
}
callout_handle->getArgument("query4", query);
/// @todo: add support for DROP status
}
// Unpack the packet information unless the buffer4_receive callouts
......@@ -1010,15 +1036,14 @@ Dhcpv4Srv::processPacket(Pkt4Ptr& query, Pkt4Ptr& 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_DHCP4_HOOKS,
DHCP4_HOOK_PACKET_RCVD_SKIP)
.arg(query->getLabel());
return;
}
/// @todo: Add support for DROP status
callout_handle->getArgument("query4", query);
}
......@@ -1106,14 +1131,13 @@ Dhcpv4Srv::processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp) {
// 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)) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS,
DHCP4_HOOK_PACKET_SEND_SKIP)
.arg(query->getLabel());
skip_pack = true;
}
/// @todo: Add support for DROP status
}
if (!skip_pack) {
......@@ -2316,7 +2340,13 @@ Pkt4Ptr
Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
sanityCheck(discover, FORBIDDEN);
Dhcpv4Exchange ex(alloc_engine_, discover, selectSubnet(discover));
bool drop = false;
Dhcpv4Exchange ex(alloc_engine_, discover, selectSubnet(discover, drop));
// Stop here if selectSubnet decided to drop the packet
if (drop) {
return (Pkt4Ptr());
}
// If DHCPDISCOVER message contains the FQDN or Hostname option, server
// may respond to the client with the appropriate FQDN or Hostname
......@@ -2368,7 +2398,13 @@ Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
/// @todo Uncomment this (see ticket #3116)
/// sanityCheck(request, MANDATORY);
Dhcpv4Exchange ex(alloc_engine_, request, selectSubnet(request));
bool drop = false;
Dhcpv4Exchange ex(alloc_engine_, request, selectSubnet(request, drop));
// Stop here if selectSubnet decided to drop the packet
if (drop) {
return (Pkt4Ptr());
}
// If DHCPREQUEST message contains the FQDN or Hostname option, server
// should respond to the client with the appropriate FQDN or Hostname
......@@ -2478,14 +2514,13 @@ Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
// 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_DHCP4_HOOKS,
DHCP4_HOOK_LEASE4_RELEASE_SKIP)
.arg(release->getLabel());
}
/// @todo add support for DROP status
}
// Callout didn't indicate to skip the release process. Let's release
......@@ -2619,9 +2654,10 @@ Dhcpv4Srv::declineLease(const Lease4Ptr& lease, const Pkt4Ptr& decline) {
HooksManager::callCallouts(Hooks.hook_index_lease4_decline_,
*callout_handle);
// Check if callouts decided to drop the packet. If any of them did,
// we will drop the packet.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
// Check if callouts decided to skip the next processing step.
// If any of them did, we will drop the packet.
if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) ||
(callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP)) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS, DHCP4_HOOK_DECLINE_SKIP)
.arg(decline->getLabel()).arg(lease->addr_.toText());
return;
......@@ -2669,7 +2705,13 @@ Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
// DHCPINFORM MUST not include server identifier.
sanityCheck(inform, FORBIDDEN);
Dhcpv4Exchange ex(alloc_engine_, inform, selectSubnet(inform));
bool drop = false;
Dhcpv4Exchange ex(alloc_engine_, inform, selectSubnet(inform, drop));
// Stop here if selectSubnet decided to drop the packet
if (drop) {
return (Pkt4Ptr());
}
Pkt4Ptr ack = ex.getResponse();
......@@ -2762,7 +2804,13 @@ Dhcpv4Srv::acceptDirectRequest(const Pkt4Ptr& pkt) const {
// we validate the message type prior to calling this function.
return (false);
}
return (!pkt->getLocalAddr().isV4Bcast() || selectSubnet(pkt));
bool drop = false;
bool result = (!pkt->getLocalAddr().isV4Bcast() || selectSubnet(pkt, drop));
if (drop) {
// The packet must be dropped.
return (false);
}
return (result);
}
bool
......
......@@ -767,14 +767,18 @@ protected:
/// @brief Selects a subnet for a given client's packet.
///
/// @param query 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::Subnet4Ptr selectSubnet(const Pkt4Ptr& query) const;
isc::dhcp::Subnet4Ptr selectSubnet(const Pkt4Ptr& query,
bool& drop) const;
/// @brief Selects a subnet for a given client's DHCP4o6 packet.
///
/// @param query 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::Subnet4Ptr selectSubnet4o6(const Pkt4Ptr& query) const;
isc::dhcp::Subnet4Ptr selectSubnet4o6(const Pkt4Ptr& query,
bool& drop) const;
/// indicates if shutdown is in progress. Setting it to true will
/// initiate server shutdown procedure.
......
......@@ -133,15 +133,14 @@ void Dhcp4to6Ipc::handler() {
// 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_DHCP4_HOOKS,
DHCP4_HOOK_BUFFER_SEND_SKIP)
.arg(rsp->getLabel());
return;
}
/// @todo: Add support for DROP status.
callout_handle->getArgument("response4", rsp);
}
......
......@@ -2303,19 +2303,23 @@ TEST_F(Dhcpv4SrvTest, clientClassify) {
// This discover does not belong to foo class, so it will not
// be serviced
EXPECT_FALSE(srv_.selectSubnet(dis));
bool drop = false;
EXPECT_FALSE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Let's add the packet to bar class and try again.
dis->addClass("bar");
// Still not supported, because it belongs to wrong class.
EXPECT_FALSE(srv_.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Let's add it to matching class.
dis->addClass("foo");
// This time it should work
EXPECT_TRUE(srv_.selectSubnet(dis));
EXPECT_TRUE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
}
// Verifies last resort option 43 is backward compatible
......@@ -3493,31 +3497,38 @@ TEST_F(Dhcpv4SrvTest, relayOverride) {
// This is just a sanity check, we're using regular method: ciaddr 192.0.2.1
// belongs to the first subnet, so it is selected
dis->setGiaddr(IOAddress("192.0.2.1"));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
bool drop = false;
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Relay belongs to the second subnet, so it should be selected.
dis->setGiaddr(IOAddress("192.0.3.1"));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Now let's check if the relay override for the first subnets works
dis->setGiaddr(IOAddress("192.0.5.1"));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// The same check for the second subnet...
dis->setGiaddr(IOAddress("192.0.5.2"));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// And finally, let's check if mis-matched relay address will end up
// in not selecting a subnet at all
dis->setGiaddr(IOAddress("192.0.5.3"));
EXPECT_FALSE(srv_.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Finally, check that the relay override works only with relay address
// (GIADDR) and does not affect client address (CIADDR)
dis->setGiaddr(IOAddress("0.0.0.0"));
dis->setHops(0);
dis->setCiaddr(IOAddress("192.0.5.1"));
EXPECT_FALSE(srv_.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
}
// Checks if relay IP address specified in the relay-info structure can be
......@@ -3573,12 +3584,15 @@ TEST_F(Dhcpv4SrvTest, 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(dis));
bool drop = false;
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, 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.
dis->addClass("foo");
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
}
// Checks if a RAI link selection sub-option works as expected
......@@ -3644,16 +3658,20 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) {
// This is just a sanity check, we're using regular method: ciaddr 192.0.3.1
// belongs to the second subnet, so it is selected
dis->setGiaddr(IOAddress("192.0.3.1"));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
bool drop = false;
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Setup a relay override for the first subnet as it has a high precedence
dis->setGiaddr(IOAddress("192.0.5.1"));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Put a RAI to select back the second subnet as it has
// the highest precedence
dis->addOption(rai);
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Subnet select option has a lower precedence
OptionDefinitionPtr sbnsel_def = LibDHCP::getOptionDef(DHCP4_OPTION_SPACE,
......@@ -3663,7 +3681,8 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) {
ASSERT_TRUE(sbnsel);
sbnsel->writeAddress(IOAddress("192.0.2.3"));
dis->addOption(sbnsel);
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
dis->delOption(DHO_SUBNET_SELECTION);
// Check client-classification still applies
......@@ -3675,10 +3694,12 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) {
rai->addOption(ols);
dis->addOption(rai);
// Note it shall fail (vs. try the next criterion).
EXPECT_FALSE(srv_.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Add the packet to the class and check again: now it shall succeed
dis->addClass("foo");
EXPECT_TRUE(subnet3 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet3 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Check it fails with a bad address in the sub-option
IOAddress addr_bad("10.0.0.1");
......@@ -3688,7 +3709,8 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) {
dis->delOption(DHO_DHCP_AGENT_OPTIONS);
rai->addOption(ols);
dis->addOption(rai);
EXPECT_FALSE(srv_.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
}
// Checks if a subnet selection option works as expected
......@@ -3749,28 +3771,35 @@ TEST_F(Dhcpv4SrvTest, subnetSelect) {
// This is just a sanity check, we're using regular method: ciaddr 192.0.3.1
// belongs to the second subnet, so it is selected
dis->setGiaddr(IOAddress("192.0.3.1"));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
bool drop = false;
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Setup a relay override for the first subnet as it has a high precedence
dis->setGiaddr(IOAddress("192.0.5.1"));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Put a subnet select option to select back the second subnet as
// it has the second highest precedence
dis->addOption(sbnsel);
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Check client-classification still applies
sbnsel->writeAddress(IOAddress("192.0.4.2"));
// Note it shall fail (vs. try the next criterion).
EXPECT_FALSE(srv_.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Add the packet to the class and check again: now it shall succeed
dis->addClass("foo");
EXPECT_TRUE(subnet3 == srv_.selectSubnet(dis));
EXPECT_TRUE(subnet3 == srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
// Check it fails with a bad address in the sub-option
sbnsel->writeAddress(IOAddress("10.0.0.1"));
EXPECT_FALSE(srv_.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis, drop));
EXPECT_FALSE(drop);
}
// This test verifies that the direct message is dropped when it has been
......