Commit 6278daf2 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[master] Merge branch 'trac2320' (DHCPv4 allocation engine)

Conflicts:
	ChangeLog
	src/bin/dhcp4/config_parser.cc
	src/bin/dhcp6/config_parser.cc
	src/lib/dhcpsrv/lease_mgr.cc
	src/lib/dhcpsrv/lease_mgr.h
	src/lib/dhcpsrv/memfile_lease_mgr.cc
	src/lib/dhcpsrv/subnet.cc
	src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
parents 1c54eac8 60606cab
544. [func] tomek
b10-dhcp4: Allocation engine support for IPv4 added. Currently
supported operations are server selection (Discover/Offer),
address assignment (Request/Ack), address renewal (Request/Ack),
and address release (Release). Expired leases can be reused.
Some options (e.g. Router Option) are still hardcoded, so the
DHCPv4 server is not yet usable, although its address allocation
is operational.
(Trac #2320, git 60606cabb1c9584700b1f642bf2af21a35c64573)
543. [func]* jelte
When calling getFullConfig() as a module, , the configuration is now
returned as properly-structured JSON. Previously, the structure had
......
......@@ -3343,23 +3343,21 @@ then change those defaults with config set Resolver/forward_addresses[0]/address
<note>
<para>
As of November 2012, the DHCPv4 component is a
skeleton server. That means that while it is capable of
performing DHCP configuration, it is not fully functional.
In particular, it does not have a functional lease
database. This means that they will assign the same, fixed,
hardcoded addresses to any client that will ask. See <xref
linkend="dhcp4-limit"/> for a
detailed description.
As of January 2013, the DHCPv4 component is a work in progress.
That means that while it is capable of performing DHCP configuration,
it is not fully functional. The server is able to offer,
assign, renew, release and reuse expired leases, but some of the
options are not configurable yet. In particular Router option is hardcoded.
This means that the server is not really usable in actual deployments
yet. See <xref linkend="dhcp4-limit"/> for a detailed description.
</para>
</note>
<section id="dhcp4-usage">
<title>DHCPv4 Server Usage</title>
<para>BIND 10 has provided the DHCPv4 server component since December
2011. It is a skeleton server and can be described as an early
prototype that is not fully functional yet. It is mature enough
to conduct first tests in lab environment, but it has
2011. It is current experimental implementation and is not fully functional
yet. It is mature enough to conduct tests in lab environment, but it has
significant limitations. See <xref linkend="dhcp4-limit"/> for
details.
</para>
......@@ -3480,9 +3478,10 @@ Dhcp4/subnet4 [] list (default)</screen>
</para>
<para>
Note: Although configuration is now accepted, it is not internally used
by they server yet. At this stage of development, the only way to alter
server configuration is to modify its source code. To do so, please edit
Note: Although configuration is now accepted, some parts of it is not internally used
by they server yet. Address pools are used, but option definitons are not.
The only way to alter some options (e.g. Router Option or DNS servers and Domain name)
is to modify source code. To do so, please edit
src/bin/dhcp6/dhcp4_srv.cc file, modify the following parameters and
recompile:
<screen>
......@@ -3505,7 +3504,7 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
<itemizedlist>
<listitem>
<simpara>RFC2131: Supported messages are DISCOVER, OFFER,
REQUEST, and ACK.</simpara>
REQUEST, ACK, NAK, RELEASE.</simpara>
</listitem>
<listitem>
<simpara>RFC2132: Supported options are: PAD (0),
......@@ -3513,6 +3512,10 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
Domain Name (15), DNS Servers (6), IP Address Lease Time
(51), Subnet mask (1), and Routers (3).</simpara>
</listitem>
<listitem>
<simpara>RFC6842: Server responses include client-id option
if client sent it in its message.</simpara>
</listitem>
</itemizedlist>
</section>
......@@ -3532,20 +3535,6 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
relayed traffic only (that is, normal point to point
communication).</simpara>
</listitem>
<listitem>
<simpara><command>b10-dhcp4</command> provides a single,
fixed, hardcoded lease to any client that asks. There is
no lease manager implemented. If two clients request
addresses, they will both get the same fixed
address.</simpara>
</listitem>
<listitem>
<simpara><command>b10-dhcp4</command> does not support any
configuration mechanisms yet. The whole configuration is
currently hardcoded. The only way to tweak configuration
is to directly modify source code. See see <xref
linkend="dhcp4-config"/> for details.</simpara>
</listitem>
<listitem>
<simpara>Upon start, the server will open sockets on all
interfaces that are not loopback, are up and running and
......@@ -3574,9 +3563,9 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
sending ICMP echo request.</simpara>
</listitem>
<listitem>
<simpara>Address renewal (RENEW), rebinding (REBIND),
confirmation (CONFIRM), duplication report (DECLINE) and
release (RELEASE) are not supported yet.</simpara>
<simpara>Address rebinding (REQUEST/Rebinding), confirmation
(CONFIRM) and duplication report (DECLINE) are not supported
yet.</simpara>
</listitem>
<listitem>
<simpara>DNS Update is not supported yet.</simpara>
......
......@@ -1114,7 +1114,7 @@ private:
subnet_.reset(new Subnet4(addr, len, t1, t2, valid));
for (PoolStorage::iterator it = pools_.begin(); it != pools_.end(); ++it) {
subnet_->addPool4(*it);
subnet_->addPool(*it);
}
Subnet::OptionContainerPtr options = subnet_->getOptionDescriptors("dhcp4");
......
......@@ -26,12 +26,6 @@ to establish a session with the BIND 10 control channel.
A debug message listing the command (and possible arguments) received
from the BIND 10 control system by the IPv4 DHCP server.
% DHCP4_CONFIG_COMPLETE DHCPv4 server has completed configuration: %1
This is an informational message announcing the successful processing of a
new configuration. it is output during server startup, and when an updated
configuration is committed by the administrator. Additional information
may be provided.
% DHCP4_CONFIG_LOAD_FAIL failed to load configuration: %1
This critical error message indicates that the initial DHCPv4
configuration has failed. The server will start, but nothing will be
......@@ -41,19 +35,52 @@ served until the configuration has been corrected.
This is an informational message reporting that the configuration has
been extended to include the specified IPv4 subnet.
% DHCP4_CONFIG_OPTION_DUPLICATE multiple options with the code %1 added to the subnet %2
This warning message is issued on an attempt to configure multiple options
with the same option code for a particular subnet. Adding multiple options
is uncommon for DHCPv4, but is not prohibited.
% DHCP4_CONFIG_UPDATE updated configuration received: %1
A debug message indicating that the IPv4 DHCP server has received an
updated configuration from the BIND 10 configuration system.
% DHCP4_CONFIG_START DHCPv4 server is processing the following configuration: %1
This is a debug message that is issued every time the server receives a
configuration. That happens at start up and also when a server configuration
change is committed by the administrator.
% DHCP4_CONFIG_UPDATE updated configuration received: %1
A debug message indicating that the IPv4 DHCP server has received an
updated configuration from the BIND 10 configuration system.
% DHCP4_CONFIG_COMPLETE DHCPv4 server has completed configuration: %1
This is an informational message announcing the successful processing of a
new configuration. It is output during server startup, and when an updated
configuration is committed by the administrator. Additional information
may be provided.
% DHCP4_CONFIG_OPTION_DUPLICATE multiple options with the code: %1 added to the subnet: %2
This warning message is issued on an attempt to configure multiple options with the
same option code for the particular subnet. Adding multiple options is uncommon
for DHCPv4, but it is not prohibited.
% DHCP4_DB_BACKEND_STARTED lease database started (type: %1, name: %2)
This informational message is printed every time DHCPv4 server is started
and gives both the type and name of the database being used to store
lease and other information.
% DHCP4_LEASE_ADVERT lease %1 advertised (client client-id %2, hwaddr %3)
This debug message indicates that the server successfully advertised
a lease. It is up to the client to choose one server out of othe advertised
and continue allocation with that server. This is a normal behavior and
indicates successful operation.
% DHCP4_LEASE_ADVERT_FAIL failed to advertise a lease for client client-id %1, hwaddr %2
This message indicates that the server has failed to offer a lease to
the specified client after receiving a DISCOVER message from it. There are
many possible reasons for such a failure.
% DHCP4_LEASE_ALLOC lease %1 has been allocated for client-id %2, hwaddr %3
This debug message indicates that the server successfully granted a lease
in response to client's REQUEST message. This is a normal behavior and
incicates successful operation.
% DHCP4_LEASE_ALLOC_FAIL failed to grant a lease for client-id %1, hwaddr %2
This message indicates that the server failed to grant a lease to the
specified client after receiving a REQUEST message from it. There are many
possible reasons for such a failure. Additional messages will indicate the
reason.
% DHCP4_NOT_RUNNING IPv4 DHCP server is not running
A warning message is issued when an attempt is made to shut down the
......@@ -91,6 +118,43 @@ to be a programming error: please raise a bug report.
% DHCP4_QUERY_DATA received packet type %1, data is <%2>
A debug message listing the data received from the client.
% DHCP4_RELEASE address %1 belonging to client-id %2, hwaddr %3 was released properly.
This debug message indicates that an address was released properly. It
is a normal operation during client shutdown.
% DHCP4_RELEASE_EXCEPTION exception %1 while trying to release address %2
This message is output when an error was encountered during an attempt
to process a RELEASE message. The error will not affect the client,
which does not expect any response from the server for RELEASE
messages. Depending on the nature of problem, it may affect future
server operation.
% DHCP4_RELEASE_FAIL failed to remove lease for address %1 for duid %2, hwaddr %3
This error message indicates that the software failed to remove a
lease from the lease database. It is probably due to an error during a
database operation: resolution will most likely require administrator
intervention (e.g. check if DHCP process has sufficient privileges to
update the database). It may also be triggered if a lease was manually
removed from the database during RELEASE message processing.
% DHCP4_RELEASE_FAIL_NO_LEASE client (client-id %2) tried to release address %1, but there is no lease for such address.
This warning message is printed when client attempts to release a lease,
but no such lease is known to the server.
% DHCP4_RELEASE_FAIL_WRONG_CLIENT_ID client (client-id %2) tried to release address %1, but it belongs to client (client-id %3)
This warning message indicates that client tried to release an address
that belongs to a different client. This should not happen in normal
circumstances and may indicate a misconfiguration of the client. However,
since the client releasing the address will stop using it anyway, there
is a good chance that the situation will correct itself.
% DHCP4_RELEASE_FAIL_WRONG_HWADDR client (client-id %2) tried to release address %1, but sent from a wrong hardware address (%3)
This warning message indicates that client tried to release an address
that does belong to it, but the lease information was associated with
a different hardware address. One possible reason for using different
hardware address is that a cloned virtual machine was not updated and
both clones use the same client-id.
% DHCP4_RESPONSE_DATA responding with packet type %1, data is <%2>
A debug message listing the data returned to the client.
......@@ -131,3 +195,13 @@ processed any command-line switches and is starting.
This is a debug message issued during the IPv4 DHCP server startup.
It lists some information about the parameters with which the server
is running.
% DHCP4_SUBNET_SELECTED the %1 subnet was selected for client assignment
This is a debug message noting the selection of a subnet to be used for
address and option assignment. Subnet selection is one of the early
steps in the processing of incoming client message.
% DHCP4_SUBNET_SELECTION_FAILED failed to select a subnet for incoming packet, src: %1, type: %2
This warning message is output when a packet was received from a subnet
for which the DHCPv4 server has not been configured. The most probable
cause is a misconfiguration of the server.
......@@ -16,9 +16,19 @@
#include <dhcp/dhcp4.h>
#include <dhcp/iface_mgr.h>
#include <dhcp/option4_addrlst.h>
#include <dhcp/option_int.h>
#include <dhcp/pkt4.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
#include <dhcp4/dhcp4_log.h>
#include <dhcp4/dhcp4_srv.h>
#include <dhcpsrv/utils.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/utils.h>
#include <dhcpsrv/addr_utilities.h>
using namespace isc;
using namespace isc::asiolink;
......@@ -28,26 +38,35 @@ using namespace std;
// These are hardcoded parameters. Currently this is a skeleton server that only
// grants those options and a single, fixed, hardcoded lease.
const std::string HARDCODED_LEASE = "192.0.2.222"; // assigned lease
const std::string HARDCODED_NETMASK = "255.255.255.0";
const uint32_t HARDCODED_LEASE_TIME = 60; // in seconds
const std::string HARDCODED_GATEWAY = "192.0.2.1";
const std::string HARDCODED_DNS_SERVER = "192.0.2.2";
const std::string HARDCODED_DOMAIN_NAME = "isc.example.com";
const std::string HARDCODED_SERVER_ID = "192.0.2.1";
Dhcpv4Srv::Dhcpv4Srv(uint16_t port) {
Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig) {
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_OPEN_SOCKET).arg(port);
try {
// First call to instance() will create IfaceMgr (it's a singleton)
// it may throw something if things go wrong
IfaceMgr::instance();
/// @todo: instantiate LeaseMgr here once it is imlpemented.
IfaceMgr::instance().openSockets4(port);
if (port) {
// open sockets only if port is non-zero. Port 0 is used
// for non-socket related testing.
IfaceMgr::instance().openSockets4(port);
}
setServerID();
// Instantiate LeaseMgr
LeaseMgrFactory::create(dbconfig);
LOG_INFO(dhcp4_logger, DHCP4_DB_BACKEND_STARTED)
.arg(LeaseMgrFactory::instance().getType())
.arg(LeaseMgrFactory::instance().getName());
// Instantiate allocation engine
alloc_engine_.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100));
} catch (const std::exception &e) {
LOG_ERROR(dhcp4_logger, DHCP4_SRV_CONSTRUCT_ERROR).arg(e.what());
shutdown_ = true;
......@@ -167,18 +186,11 @@ Dhcpv4Srv::run() {
void
Dhcpv4Srv::setServerID() {
/// TODO implement this for real once interface detection (ticket 1237)
/// is done. Use hardcoded server-id for now.
#if 0
// uncomment this once ticket 1350 is merged.
IOAddress srvId("127.0.0.1");
serverid_ = OptionPtr(
new Option4AddrLst(Option::V4, DHO_DHCP_SERVER_IDENTIFIER, srvId));
#endif
/// @todo: implement this for real (see ticket #2588)
serverid_ = OptionPtr(new Option4AddrLst(DHO_DHCP_SERVER_IDENTIFIER,
IOAddress(HARDCODED_SERVER_ID)));
}
void Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
answer->setIface(question->getIface());
answer->setIndex(question->getIndex());
......@@ -188,9 +200,7 @@ void Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
answer->setHops(question->getHops());
// copy MAC address
vector<uint8_t> mac(question->getChaddr(),
question->getChaddr() + Pkt4::MAX_CHADDR_LEN);
answer->setHWAddr(question->getHtype(), question->getHlen(), mac);
answer->setHWAddr(question->getHWAddr());
// relay address
answer->setGiaddr(question->getGiaddr());
......@@ -203,21 +213,21 @@ void Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
answer->setRemoteAddr(question->getRemoteAddr());
}
// Let's copy client-id to response. See RFC6842.
OptionPtr client_id = question->getOption(DHO_DHCP_CLIENT_IDENTIFIER);
if (client_id) {
answer->addOption(client_id);
}
}
void Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
OptionPtr opt;
// add Message Type Option (type 53)
std::vector<uint8_t> tmp;
tmp.push_back(static_cast<uint8_t>(msg_type));
opt = OptionPtr(new Option(Option::V4, DHO_DHCP_MESSAGE_TYPE, tmp));
msg->addOption(opt);
msg->setType(msg_type);
// DHCP Server Identifier (type 54)
opt = OptionPtr
(new Option4AddrLst(DHO_DHCP_SERVER_IDENTIFIER, IOAddress(HARDCODED_SERVER_ID)));
msg->addOption(opt);
msg->addOption(getServerID());
// more options will be added here later
}
......@@ -237,25 +247,109 @@ void Dhcpv4Srv::appendRequestedOptions(Pkt4Ptr& msg) {
msg->addOption(opt);
}
void Dhcpv4Srv::tryAssignLease(Pkt4Ptr& msg) {
OptionPtr opt;
void Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
// We need to select a subnet the client is connected in.
Subnet4Ptr subnet = selectSubnet(question);
if (!subnet) {
// This particular client is out of luck today. We do not have
// information about the subnet he is connected to. This likely means
// misconfiguration of the server (or some relays). We will continue to
// process this message, but our response will be almost useless: no
// addresses or prefixes, no subnet specific configuration etc. The only
// thing this client can get is some global information (like DNS
// servers).
// perhaps this should be logged on some higher level? This is most likely
// configuration bug.
LOG_ERROR(dhcp4_logger, DHCP4_SUBNET_SELECTION_FAILED)
.arg(question->getRemoteAddr().toText())
.arg(serverReceivedPacketName(question->getType()));
answer->setType(DHCPNAK);
answer->setYiaddr(IOAddress("0.0.0.0"));
return;
}
// TODO: Implement actual lease assignment here
msg->setYiaddr(IOAddress(HARDCODED_LEASE));
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL_DATA, DHCP4_SUBNET_SELECTED)
.arg(subnet->toText());
// IP Address Lease time (type 51)
opt = OptionPtr(new Option(Option::V4, DHO_DHCP_LEASE_TIME));
opt->setUint32(HARDCODED_LEASE_TIME);
msg->addOption(opt);
// TODO: create Option_IntArray that holds list of integers, similar to Option4_AddrLst
// Get client-id option
ClientIdPtr client_id;
OptionPtr opt = question->getOption(DHO_DHCP_CLIENT_IDENTIFIER);
if (opt) {
client_id = ClientIdPtr(new ClientId(opt->getData()));
}
// client-id is not mandatory in DHCPv4
IOAddress hint = question->getYiaddr();
HWAddrPtr hwaddr = question->getHWAddr();
// "Fake" allocation is processing of DISCOVER message. We pretend to do an
// allocation, but we do not put the lease in the database. That is ok,
// because we do not guarantee that the user will get that exact lease. If
// the user selects this server to do actual allocation (i.e. sends REQUEST)
// it should include this hint. That will help us during the actual lease
// allocation.
bool fake_allocation = (question->getType() == DHCPDISCOVER);
// Use allocation engine to pick a lease for this client. Allocation engine
// will try to honour the hint, but it is just a hint - some other address
// may be used instead. If fake_allocation is set to false, the lease will
// be inserted into the LeaseMgr as well.
Lease4Ptr lease = alloc_engine_->allocateAddress4(subnet, client_id, hwaddr,
hint, fake_allocation);
if (lease) {
// We have a lease! Let's set it in the packet and send it back to
// the client.
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, fake_allocation?
DHCP4_LEASE_ADVERT:DHCP4_LEASE_ALLOC)
.arg(lease->addr_.toText())
.arg(client_id?client_id->toText():"(no client-id)")
.arg(hwaddr?hwaddr->toText():"(no hwaddr info)");
answer->setYiaddr(lease->addr_);
// IP Address Lease time (type 51)
opt = OptionPtr(new Option(Option::V4, DHO_DHCP_LEASE_TIME));
opt->setUint32(lease->valid_lft_);
answer->addOption(opt);
// @todo: include real router information here
// Router (type 3)
opt = OptionPtr(new Option4AddrLst(DHO_ROUTERS, IOAddress(HARDCODED_GATEWAY)));
answer->addOption(opt);
// Subnet mask (type 1)
answer->addOption(getNetmaskOption(subnet));
// @todo: send renew timer option (T1, option 58)
// @todo: send rebind timer option (T2, option 59)
// Subnet mask (type 1)
opt = OptionPtr(new Option4AddrLst(DHO_SUBNET_MASK, IOAddress(HARDCODED_NETMASK)));
msg->addOption(opt);
} else {
// Allocation engine did not allocate a lease. The engine logged
// cause of that failure. The only thing left is to insert
// status code to pass the sad news to the client.
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, fake_allocation?
DHCP4_LEASE_ADVERT_FAIL:DHCP4_LEASE_ALLOC_FAIL)
.arg(client_id?client_id->toText():"(no client-id)")
.arg(hwaddr?hwaddr->toText():"(no hwaddr info)")
.arg(hint.toText());
answer->setType(DHCPNAK);
answer->setYiaddr(IOAddress("0.0.0.0"));
}
}
// Router (type 3)
opt = OptionPtr(new Option4AddrLst(DHO_ROUTERS, IOAddress(HARDCODED_GATEWAY)));
msg->addOption(opt);
OptionPtr Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
uint32_t netmask = getNetmask4(subnet->get().second);
OptionPtr opt(new OptionInt<uint32_t>(Option::V4,
DHO_SUBNET_MASK, netmask));
return (opt);
}
Pkt4Ptr Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
......@@ -266,7 +360,7 @@ Pkt4Ptr Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
appendDefaultOptions(offer, DHCPOFFER);
appendRequestedOptions(offer);
tryAssignLease(offer);
assignLease(discover, offer);
return (offer);
}
......@@ -279,13 +373,77 @@ Pkt4Ptr Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
appendDefaultOptions(ack, DHCPACK);
appendRequestedOptions(ack);
tryAssignLease(ack);
assignLease(request, ack);
return (ack);
}
void Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
/// TODO: Implement this.
// Try to find client-id
ClientIdPtr client_id;
OptionPtr opt = release->getOption(DHO_DHCP_CLIENT_IDENTIFIER);
if (opt) {
client_id = ClientIdPtr(new ClientId(opt->getData()));
}
try {
// Do we have a lease for that particular address?
Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(release->getYiaddr());
if (!lease) {
// No such lease - bogus release
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_RELEASE_FAIL_NO_LEASE)
.arg(release->getYiaddr().toText())
.arg(release->getHWAddr()->toText())
.arg(client_id ? client_id->toText() : "(no client-id)");
return;
}
// Does the hardware address match? We don't want one client releasing
// second client's leases.
if (lease->hwaddr_ != release->getHWAddr()->hwaddr_) {
// @todo: Print hwaddr from lease as part of ticket #2589
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_RELEASE_FAIL_WRONG_HWADDR)
.arg(release->getYiaddr().toText())
.arg(client_id ? client_id->toText() : "(no client-id)")
.arg(release->getHWAddr()->toText());
return;
}
// Does the lease have client-id info? If it has, then check it with what
// the client sent us.
if (lease->client_id_ && client_id && *lease->client_id_ != *client_id) {
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_RELEASE_FAIL_WRONG_CLIENT_ID)
.arg(release->getYiaddr().toText())
.arg(client_id->toText())
.arg(lease->client_id_->toText());
return;
}
// Ok, hw and client-id match - let's release the lease.
if (LeaseMgrFactory::instance().deleteLease(lease->addr_)) {
// Release successful - we're done here
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_RELEASE)
.arg(lease->addr_.toText())
.arg(client_id ? client_id->toText() : "(no client-id)")
.arg(release->getHWAddr()->toText());
} else {
// Release failed -
LOG_ERROR(dhcp4_logger, DHCP4_RELEASE_FAIL)
.arg(lease->addr_.toText())
.arg(client_id ? client_id->toText() : "(no client-id)")
.arg(release->getHWAddr()->toText());
}
} catch (const isc::Exception& ex) {
// Rethrow the exception with a bit more data.
LOG_ERROR(dhcp4_logger, DHCP4_RELEASE_EXCEPTION)
.arg(ex.what())
.arg(release->getYiaddr());
}
}
void Dhcpv4Srv::processDecline(Pkt4Ptr& decline) {
......@@ -327,3 +485,42 @@ Dhcpv4Srv::serverReceivedPacketName(uint8_t type) {
}
return (UNKNOWN);
}
Subnet4Ptr Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) {
// Is this relayed message?
IOAddress relay = question->getGiaddr();
if (relay.toText() == "0.0.0.0") {
// Yes: Use relay address to select subnet
return (CfgMgr::instance().getSubnet4(relay));
} else {
// No: Use client's address to select subnet
return (CfgMgr::instance().getSubnet4(question->getRemoteAddr()));
}
}
void Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
OptionPtr server_id = pkt->getOption(DHO_DHCP_SERVER_IDENTIFIER);
switch (serverid) {
case FORBIDDEN:
if (server_id) {
isc_throw(RFCViolation, "Server-id option was not expected, but "
<< "received in " << serverReceivedPacketName(pkt->getType()));
}
break;
case MANDATORY:
if (!server_id) {
isc_throw(RFCViolation, "Server-id option was expected, but not "
" received in message "
<< serverReceivedPacketName(pkt->getType()));
}
break;
case OPTIONAL:
// do nothing here
;
}
}
......@@ -18,14 +18,16 @@
#include <dhcp/dhcp4.h>
#include <dhcp/pkt4.h>
#include <dhcp/option.h>