diff options
author | Francis Dupont <fdupont@isc.org> | 2024-06-30 15:31:39 +0200 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2024-07-18 14:45:25 +0200 |
commit | 0975949b9cf133dadd2cff9e5539c973df8bb962 (patch) | |
tree | 9c5eab5fe68e1489c3a466a179973f36534890ed | |
parent | [#3094] Checkpoint: added UTs, doc to do (diff) | |
download | kea-0975949b9cf133dadd2cff9e5539c973df8bb962.tar.xz kea-0975949b9cf133dadd2cff9e5539c973df8bb962.zip |
[#3094] Finished tests and doc
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | doc/sphinx/arm/dhcp4-srv.rst | 13 | ||||
-rw-r--r-- | src/bin/dhcp4/dhcp4_srv.cc | 2 | ||||
-rw-r--r-- | src/bin/dhcp4/tests/dhcp4_srv_unittest.cc | 94 |
4 files changed, 113 insertions, 1 deletions
@@ -1,3 +1,8 @@ +2263. [func] fdupont + RFC 8925 "IPv6-Only Preferred Option for DHCPv4" is now + fully implemented: 0.0.0.0 address can be offerred. + (Gitlab #3094) + 2262. [bug] marcin Corrected a bug in storing and fetching the encapsulated DHCP options from the configuration backend. These options were diff --git a/doc/sphinx/arm/dhcp4-srv.rst b/doc/sphinx/arm/dhcp4-srv.rst index d47f55c866..3ceed35c02 100644 --- a/doc/sphinx/arm/dhcp4-srv.rst +++ b/doc/sphinx/arm/dhcp4-srv.rst @@ -3038,6 +3038,19 @@ the same option code) and to fuse the data chunks into one option. This is also supported for sub-options if each sub-option data chunk also contains the sub-option code and sub-option length. +.. _dhcp4-support-for-v6-only-preferred-option: + +Support for IPv6-Only Preferred Option +-------------------------------------- + +The ``v6-only-preferred`` (code 108) option is handled in a specific +way described in `RFC 8925 <https://tools.ietf.org/html/rfc8925>`_ +by :iscman:`kea-dhcp4` when it is configured in a subnet or a +shared network: when the client requests the option (i.e. puts +the 108 code in the DHCP parameter request list option) and +the subnet or shared network is selected the 0.0.0.0 address +is offered and the option returned in the response. + .. _dhcp4-stateless-configuration: Stateless Configuration of DHCPv4 Clients diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index b47cc74c01..88a928d1eb 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -3873,7 +3873,7 @@ Dhcpv4Srv::processRequest(Pkt4Ptr& request, AllocEngine::ClientContext4Ptr& cont if (ex.getIPv6OnlyPreferred()) { if (!response->getOption(DHO_V6_ONLY_PREFERRED)) { // Better to drop the packet than to send an insane response. - LOG_ERROR(packet4_logger, DHCP4_V6_ONLY_PREFERRED_MISSING_IN_OFFER) + LOG_ERROR(packet4_logger, DHCP4_V6_ONLY_PREFERRED_MISSING_IN_ACK) .arg(request->getLabel()); return (Pkt4Ptr()); } diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 02c8e9d51f..f9a193aa05 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -6249,6 +6249,100 @@ TEST_F(Dhcpv4SrvTest, noV6OnlyPreferredRequestGlobal) { EXPECT_EQ(v6only_wait, got_v6op_opt->getValue()); } +// Verify that when discover requesting v6-only-preferred 0.0.0.0 is offered +// but the option is not added to the response is an error case. +TEST_F(Dhcpv4SrvTest, v6OnlyPreferredDiscoverError) { + IfaceMgrTestConfig test_config(true); + IfaceMgr::instance().openSockets4(); + + NakedDhcpv4Srv srv(0); + + // Recreate subnet. + Triplet<uint32_t> unspecified; + Triplet<uint32_t> valid_lft(500, 1000, 1500); + subnet_ = Subnet4::create(IOAddress("192.0.2.0"), 24, + unspecified, + unspecified, + valid_lft, + subnet_->getID()); + // Add the v6-only-preferred option data. + const uint32_t v6only_wait(3600); + OptionUint32Ptr v6op_opt(new OptionUint32(Option::V4, + DHO_V6_ONLY_PREFERRED, + v6only_wait)); + subnet_->getCfgOption()->add(v6op_opt, false, false, DHCP4_OPTION_SPACE); + CfgMgr::instance().clear(); + CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_); + // Cancel the v6-only-preferred option at the global level. + CfgMgr::instance().getStagingCfg()->getCfgOption()-> + add(v6op_opt, false, true, DHCP4_OPTION_SPACE); + CfgMgr::instance().commit(); + + Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234)); + dis->setRemoteAddr(IOAddress("192.0.2.1")); + OptionPtr clientid = generateClientId(); + dis->addOption(clientid); + dis->setIface("eth1"); + dis->setIndex(ETH1_INDEX); + + // Add a PRL with v6-only-preferred. + OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4, + DHO_DHCP_PARAMETER_REQUEST_LIST)); + ASSERT_TRUE(prl); + prl->addValue(DHO_V6_ONLY_PREFERRED); + dis->addOption(prl); + + // No DHCPOFFER is returned. + EXPECT_FALSE(srv.processDiscover(dis)); +} + +// Verify that when request requesting v6-only-preferred 0.0.0.0 is offered +// but the option is not added to the response is an error case. +TEST_F(Dhcpv4SrvTest, v6OnlyPreferredRequestError) { + IfaceMgrTestConfig test_config(true); + IfaceMgr::instance().openSockets4(); + + NakedDhcpv4Srv srv(0); + + // Recreate subnet. + Triplet<uint32_t> unspecified; + Triplet<uint32_t> valid_lft(500, 1000, 1500); + subnet_ = Subnet4::create(IOAddress("192.0.2.0"), 24, + unspecified, + unspecified, + valid_lft, + subnet_->getID()); + // Add the v6-only-preferred option data. + const uint32_t v6only_wait(3600); + OptionUint32Ptr v6op_opt(new OptionUint32(Option::V4, + DHO_V6_ONLY_PREFERRED, + v6only_wait)); + subnet_->getCfgOption()->add(v6op_opt, false, false, DHCP4_OPTION_SPACE); + CfgMgr::instance().clear(); + CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_); + // Cancel the v6-only-preferred option at the global level. + CfgMgr::instance().getStagingCfg()->getCfgOption()-> + add(v6op_opt, false, true, DHCP4_OPTION_SPACE); + CfgMgr::instance().commit(); + + Pkt4Ptr req = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234)); + req->setRemoteAddr(IOAddress("192.0.2.1")); + OptionPtr clientid = generateClientId(); + req->addOption(clientid); + req->setIface("eth1"); + req->setIndex(ETH1_INDEX); + + // Add a PRL with v6-only-preferred. + OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4, + DHO_DHCP_PARAMETER_REQUEST_LIST)); + ASSERT_TRUE(prl); + prl->addValue(DHO_V6_ONLY_PREFERRED); + req->addOption(prl); + + // No DHCPACK is returned. + EXPECT_FALSE(srv.processRequest(req)); +} + /// @brief Test fixture for recoverStashedAgentOption. class StashAgentOptionTest : public Dhcpv4SrvTest { public: |