Skip to content

Commit 0975949

Browse files
committed
[#3094] Finished tests and doc
1 parent 6901b0f commit 0975949

File tree

4 files changed

+113
-1
lines changed

4 files changed

+113
-1
lines changed

ChangeLog

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2263. [func] fdupont
2+
RFC 8925 "IPv6-Only Preferred Option for DHCPv4" is now
3+
fully implemented: 0.0.0.0 address can be offerred.
4+
(Gitlab #3094)
5+
16
2262. [bug] marcin
27
Corrected a bug in storing and fetching the encapsulated DHCP
38
options from the configuration backend. These options were

doc/sphinx/arm/dhcp4-srv.rst

+13
Original file line numberDiff line numberDiff line change
@@ -3038,6 +3038,19 @@ the same option code) and to fuse the data chunks into one option. This is
30383038
also supported for sub-options if each sub-option data chunk also contains the
30393039
sub-option code and sub-option length.
30403040

3041+
.. _dhcp4-support-for-v6-only-preferred-option:
3042+
3043+
Support for IPv6-Only Preferred Option
3044+
--------------------------------------
3045+
3046+
The ``v6-only-preferred`` (code 108) option is handled in a specific
3047+
way described in `RFC 8925 <https://tools.ietf.org/html/rfc8925>`_
3048+
by :iscman:`kea-dhcp4` when it is configured in a subnet or a
3049+
shared network: when the client requests the option (i.e. puts
3050+
the 108 code in the DHCP parameter request list option) and
3051+
the subnet or shared network is selected the 0.0.0.0 address
3052+
is offered and the option returned in the response.
3053+
30413054
.. _dhcp4-stateless-configuration:
30423055

30433056
Stateless Configuration of DHCPv4 Clients

src/bin/dhcp4/dhcp4_srv.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -3873,7 +3873,7 @@ Dhcpv4Srv::processRequest(Pkt4Ptr& request, AllocEngine::ClientContext4Ptr& cont
38733873
if (ex.getIPv6OnlyPreferred()) {
38743874
if (!response->getOption(DHO_V6_ONLY_PREFERRED)) {
38753875
// Better to drop the packet than to send an insane response.
3876-
LOG_ERROR(packet4_logger, DHCP4_V6_ONLY_PREFERRED_MISSING_IN_OFFER)
3876+
LOG_ERROR(packet4_logger, DHCP4_V6_ONLY_PREFERRED_MISSING_IN_ACK)
38773877
.arg(request->getLabel());
38783878
return (Pkt4Ptr());
38793879
}

src/bin/dhcp4/tests/dhcp4_srv_unittest.cc

+94
Original file line numberDiff line numberDiff line change
@@ -6249,6 +6249,100 @@ TEST_F(Dhcpv4SrvTest, noV6OnlyPreferredRequestGlobal) {
62496249
EXPECT_EQ(v6only_wait, got_v6op_opt->getValue());
62506250
}
62516251

6252+
// Verify that when discover requesting v6-only-preferred 0.0.0.0 is offered
6253+
// but the option is not added to the response is an error case.
6254+
TEST_F(Dhcpv4SrvTest, v6OnlyPreferredDiscoverError) {
6255+
IfaceMgrTestConfig test_config(true);
6256+
IfaceMgr::instance().openSockets4();
6257+
6258+
NakedDhcpv4Srv srv(0);
6259+
6260+
// Recreate subnet.
6261+
Triplet<uint32_t> unspecified;
6262+
Triplet<uint32_t> valid_lft(500, 1000, 1500);
6263+
subnet_ = Subnet4::create(IOAddress("192.0.2.0"), 24,
6264+
unspecified,
6265+
unspecified,
6266+
valid_lft,
6267+
subnet_->getID());
6268+
// Add the v6-only-preferred option data.
6269+
const uint32_t v6only_wait(3600);
6270+
OptionUint32Ptr v6op_opt(new OptionUint32(Option::V4,
6271+
DHO_V6_ONLY_PREFERRED,
6272+
v6only_wait));
6273+
subnet_->getCfgOption()->add(v6op_opt, false, false, DHCP4_OPTION_SPACE);
6274+
CfgMgr::instance().clear();
6275+
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_);
6276+
// Cancel the v6-only-preferred option at the global level.
6277+
CfgMgr::instance().getStagingCfg()->getCfgOption()->
6278+
add(v6op_opt, false, true, DHCP4_OPTION_SPACE);
6279+
CfgMgr::instance().commit();
6280+
6281+
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
6282+
dis->setRemoteAddr(IOAddress("192.0.2.1"));
6283+
OptionPtr clientid = generateClientId();
6284+
dis->addOption(clientid);
6285+
dis->setIface("eth1");
6286+
dis->setIndex(ETH1_INDEX);
6287+
6288+
// Add a PRL with v6-only-preferred.
6289+
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
6290+
DHO_DHCP_PARAMETER_REQUEST_LIST));
6291+
ASSERT_TRUE(prl);
6292+
prl->addValue(DHO_V6_ONLY_PREFERRED);
6293+
dis->addOption(prl);
6294+
6295+
// No DHCPOFFER is returned.
6296+
EXPECT_FALSE(srv.processDiscover(dis));
6297+
}
6298+
6299+
// Verify that when request requesting v6-only-preferred 0.0.0.0 is offered
6300+
// but the option is not added to the response is an error case.
6301+
TEST_F(Dhcpv4SrvTest, v6OnlyPreferredRequestError) {
6302+
IfaceMgrTestConfig test_config(true);
6303+
IfaceMgr::instance().openSockets4();
6304+
6305+
NakedDhcpv4Srv srv(0);
6306+
6307+
// Recreate subnet.
6308+
Triplet<uint32_t> unspecified;
6309+
Triplet<uint32_t> valid_lft(500, 1000, 1500);
6310+
subnet_ = Subnet4::create(IOAddress("192.0.2.0"), 24,
6311+
unspecified,
6312+
unspecified,
6313+
valid_lft,
6314+
subnet_->getID());
6315+
// Add the v6-only-preferred option data.
6316+
const uint32_t v6only_wait(3600);
6317+
OptionUint32Ptr v6op_opt(new OptionUint32(Option::V4,
6318+
DHO_V6_ONLY_PREFERRED,
6319+
v6only_wait));
6320+
subnet_->getCfgOption()->add(v6op_opt, false, false, DHCP4_OPTION_SPACE);
6321+
CfgMgr::instance().clear();
6322+
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_);
6323+
// Cancel the v6-only-preferred option at the global level.
6324+
CfgMgr::instance().getStagingCfg()->getCfgOption()->
6325+
add(v6op_opt, false, true, DHCP4_OPTION_SPACE);
6326+
CfgMgr::instance().commit();
6327+
6328+
Pkt4Ptr req = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234));
6329+
req->setRemoteAddr(IOAddress("192.0.2.1"));
6330+
OptionPtr clientid = generateClientId();
6331+
req->addOption(clientid);
6332+
req->setIface("eth1");
6333+
req->setIndex(ETH1_INDEX);
6334+
6335+
// Add a PRL with v6-only-preferred.
6336+
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
6337+
DHO_DHCP_PARAMETER_REQUEST_LIST));
6338+
ASSERT_TRUE(prl);
6339+
prl->addValue(DHO_V6_ONLY_PREFERRED);
6340+
req->addOption(prl);
6341+
6342+
// No DHCPACK is returned.
6343+
EXPECT_FALSE(srv.processRequest(req));
6344+
}
6345+
62526346
/// @brief Test fixture for recoverStashedAgentOption.
62536347
class StashAgentOptionTest : public Dhcpv4SrvTest {
62546348
public:

0 commit comments

Comments
 (0)