From a5cbfd64e176b5d4056dd92f627c0d79eead14b5 Mon Sep 17 00:00:00 2001 From: Tomek Mrugalski Date: Tue, 3 Mar 2015 23:08:38 +0100 Subject: [PATCH] [3705] RSOO handling added in CfgOption --- src/lib/dhcp/dhcp6.h | 1 + src/lib/dhcpsrv/cfg_option.cc | 22 ++++++++++++ src/lib/dhcpsrv/cfg_option.h | 35 ++++++++++++++++++++ src/lib/dhcpsrv/tests/cfg_option_unittest.cc | 29 ++++++++++++++++ 4 files changed, 87 insertions(+) diff --git a/src/lib/dhcp/dhcp6.h b/src/lib/dhcp/dhcp6.h index 554b295431..2cef8a7e7c 100644 --- a/src/lib/dhcp/dhcp6.h +++ b/src/lib/dhcp/dhcp6.h @@ -65,6 +65,7 @@ #define D6O_CLT_TIME 46 /* RFC5007 */ #define D6O_LQ_RELAY_DATA 47 /* RFC5007 */ #define D6O_LQ_CLIENT_LINK 48 /* RFC5007 */ +#define D6O_ERP_LOCAL_DOMAIN_NAME 65 /* RFC6440 */ #define D6O_RSOO 66 /* RFC6422 */ #define D6O_CLIENT_LINKLAYER_ADDR 79 /* RFC6939 */ diff --git a/src/lib/dhcpsrv/cfg_option.cc b/src/lib/dhcpsrv/cfg_option.cc index c7ca44f3a8..c5a3150eb3 100644 --- a/src/lib/dhcpsrv/cfg_option.cc +++ b/src/lib/dhcpsrv/cfg_option.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,13 @@ OptionDescriptor::equals(const OptionDescriptor& other) const { option_->equals(other.option_)); } +CfgOption::CfgOption() { + + // By default, the only allowed Relay-Supplied Options option is + // ERP local domain name. Other options may be added in configuration. + rsoo_options_.insert(D6O_ERP_LOCAL_DOMAIN_NAME); +} + bool CfgOption::equals(const CfgOption& other) const { return (options_.equals(other.options_) && @@ -190,6 +198,20 @@ CfgOption::optionSpaceToVendorId(const std::string& option_space) { return (static_cast(check)); } +void CfgOption::clearRSOO() { + rsoo_options_.clear(); +} + +bool CfgOption::isRSOOEnabled(uint16_t code) const { + return (rsoo_options_.find(code) != rsoo_options_.end()); +} + +void CfgOption::addRSOO(uint16_t code) { + if (rsoo_options_.find(code) == rsoo_options_.end()) { + // If there's no such code added yet, let's add it + rsoo_options_.insert(code); + } +} } // end of namespace isc::dhcp } // end of namespace isc diff --git a/src/lib/dhcpsrv/cfg_option.h b/src/lib/dhcpsrv/cfg_option.h index d0dfc7eee7..8f2312fc94 100644 --- a/src/lib/dhcpsrv/cfg_option.h +++ b/src/lib/dhcpsrv/cfg_option.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace isc { namespace dhcp { @@ -194,9 +195,17 @@ typedef OptionContainer::nth_index<2>::type OptionContainerPersistIndex; /// options is useful when the client requests stateless configuration from /// the DHCP server and no subnet is selected for this client. This client /// will only receive global options. +/// +/// isRSSOEnabled(), addRSOO(), clearRSOO() are methods related to +/// Relay-Supplied Options option. This information does not provide any values +/// about the options themselves, but rather contain a list of options that +/// are allowed in RSOO ("RSOO-enabled"). class CfgOption { public: + /// @brief default constructor + CfgOption(); + /// @name Methods and operators used for comparing objects. /// //@{ @@ -348,6 +357,23 @@ public: /// @return vendor id. static uint32_t optionSpaceToVendorId(const std::string& option_space); + /// @brief Removes designation of all options as RSOO-enabled. + /// + /// This method removes all designations of all options as being RSOO-enabled. + /// Note that the list is maintained by IANA and option 65 is officially + /// RSOO-enabled. This list may be extended in the future. Also, the user may + /// add extra options here. + void clearRSOO(); + + /// @brief Returns whether specific option code is RSOO-enabled. + /// @param code option code to check + /// @return true, if it is allowed in Relay-Supplied Options option + bool isRSOOEnabled(uint16_t code) const; + + /// @brief Marks specified option code as RSOO-enabled. + /// @param code option to be enabled in RSOO + void addRSOO(uint16_t code); + private: /// @brief Appends encapsulated options to the options in an option space. @@ -393,6 +419,15 @@ private: uint32_t> VendorOptionSpaceCollection; /// @brief Container holding options grouped by vendor id. VendorOptionSpaceCollection vendor_options_; + + /// @brief Contains a list of options that are allowed in RSOO option + /// + /// RSOO stands for Relay-Supplied Options option. This is an option that + /// is inserted by the relay agent with the intention that the server will + /// echo those options back to the client. Only those options marked as + /// RSOO-enabled may appear in the RSOO. Currently only option 65 is marked + /// as such, but more options may be added in the future. See RFC6422 for details. + std::set rsoo_options_; }; /// @name Pointers to the @c CfgOption objects. diff --git a/src/lib/dhcpsrv/tests/cfg_option_unittest.cc b/src/lib/dhcpsrv/tests/cfg_option_unittest.cc index cc99f250af..54e7d3e83d 100644 --- a/src/lib/dhcpsrv/tests/cfg_option_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_option_unittest.cc @@ -13,6 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include +#include #include #include #include @@ -476,5 +477,33 @@ TEST(CfgOptionTest, addVendorOptions) { EXPECT_TRUE(options->empty()); } +// This test verifies that Relay-Supplied Options option (RSOO) is handled +// properly. +TEST(CfgOptionTest, rsoo) { + CfgOption cfg; + + // All options from 0..64 are not RSOO-enabled + for (uint16_t code = 0; code < D6O_ERP_LOCAL_DOMAIN_NAME; ++code) { + EXPECT_FALSE(cfg.isRSOOEnabled(code)); + } + + // Option 65 is the only one so far that is enabled + EXPECT_TRUE(cfg.isRSOOEnabled(D6O_ERP_LOCAL_DOMAIN_NAME)); + + // Let's check other options. They should not be enabled. + for (uint16_t code = D6O_ERP_LOCAL_DOMAIN_NAME + 1; code < 300; ++code) { + EXPECT_FALSE(cfg.isRSOOEnabled(code)) << " for option code " << code; + } + + // Let's clear it. + cfg.clearRSOO(); + + // Now not even option 65 is enabled. + EXPECT_FALSE(cfg.isRSOOEnabled(D6O_ERP_LOCAL_DOMAIN_NAME)); + + // Should be possible to specify that an option is RSOO-enabled + EXPECT_NO_THROW(cfg.addRSOO(200)); + EXPECT_TRUE(cfg.isRSOOEnabled(200)); +} } // end of anonymous namespace -- 2.47.3