2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-05 00:15:17 +00:00

[5443] Checkpoint: proposed code for dhcp4, todo new tests and dhcp6 port

This commit is contained in:
Francis Dupont
2017-12-15 00:53:20 +01:00
parent 6bb0172d6d
commit 1d7c894188
7 changed files with 115 additions and 49 deletions

View File

@@ -483,7 +483,7 @@ Dhcpv4Srv::shutdown() {
}
isc::dhcp::Subnet4Ptr
Dhcpv4Srv::selectSubnet(const Pkt4Ptr& query) const {
Dhcpv4Srv::selectSubnet(Pkt4Ptr& query) {
// DHCPv4-over-DHCPv6 is a special (and complex) case
if (query->isDhcp4o6()) {
@@ -569,7 +569,16 @@ 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. For the caller to
// know it has to drop the packet the query pointer is cleared.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS,
DHCP4_HOOK_SUBNET4_SELECT_DROP)
.arg(query->getLabel());
query.reset();
return (Subnet4Ptr());
}
// Use whatever subnet was specified by the callout
callout_handle->getArgument("subnet4", subnet);
@@ -596,7 +605,7 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& query) const {
}
isc::dhcp::Subnet4Ptr
Dhcpv4Srv::selectSubnet4o6(const Pkt4Ptr& query) const {
Dhcpv4Srv::selectSubnet4o6(Pkt4Ptr& query) {
Subnet4Ptr subnet;
@@ -673,7 +682,16 @@ 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. For the caller to
// know it has to drop the packet the query pointer is cleared.
if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
LOG_DEBUG(hooks_logger, DBG_DHCP4_HOOKS,
DHCP4_HOOK_SUBNET4_SELECT_DROP)
.arg(query->getLabel());
query.reset();
return (Subnet4Ptr());
}
// Use whatever subnet was specified by the callout
callout_handle->getArgument("subnet4", subnet);
@@ -841,15 +859,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 +928,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 +954,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 +1037,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 +1132,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) {
@@ -2318,6 +2343,11 @@ Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
Dhcpv4Exchange ex(alloc_engine_, discover, selectSubnet(discover));
// Stop here if selectSubnet decided to drop the packet
if (!discover) {
return (Pkt4Ptr());
}
// If DHCPDISCOVER message contains the FQDN or Hostname option, server
// may respond to the client with the appropriate FQDN or Hostname
// option to indicate that whether it will take responsibility for
@@ -2370,6 +2400,11 @@ Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
Dhcpv4Exchange ex(alloc_engine_, request, selectSubnet(request));
// Stop here if selectSubnet decided to drop the packet
if (!request) {
return (Pkt4Ptr());
}
// If DHCPREQUEST message contains the FQDN or Hostname option, server
// should respond to the client with the appropriate FQDN or Hostname
// option to indicate if it takes responsibility for the DNS updates.
@@ -2478,14 +2513,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 +2653,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;
@@ -2671,6 +2706,11 @@ Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
Dhcpv4Exchange ex(alloc_engine_, inform, selectSubnet(inform));
// Stop here if selectSubnet decided to drop the packet
if (!inform) {
return (Pkt4Ptr());
}
Pkt4Ptr ack = ex.getResponse();
ex.setReservedClientClasses();
@@ -2707,7 +2747,7 @@ Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
}
bool
Dhcpv4Srv::accept(const Pkt4Ptr& query) const {
Dhcpv4Srv::accept(Pkt4Ptr& query) {
// Check that the message type is accepted by the server. We rely on the
// function called to log a message if needed.
if (!acceptMessageType(query)) {
@@ -2735,7 +2775,7 @@ Dhcpv4Srv::accept(const Pkt4Ptr& query) const {
}
bool
Dhcpv4Srv::acceptDirectRequest(const Pkt4Ptr& pkt) const {
Dhcpv4Srv::acceptDirectRequest(Pkt4Ptr& pkt) {
// Accept all relayed messages.
if (pkt->isRelayed()) {
return (true);
@@ -2762,7 +2802,12 @@ 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 result = (!pkt->getLocalAddr().isV4Bcast() || selectSubnet(pkt));
if (!pkt) {
// The packet must be dropped.
return (false);
}
return (result);
}
bool