Browse Source

[3705] RSOO handling added in CfgOption

Tomek Mrugalski 10 years ago
parent
commit
a5cbfd64e1

+ 1 - 0
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 */
 

+ 22 - 0
src/lib/dhcpsrv/cfg_option.cc

@@ -15,6 +15,7 @@
 #include <dhcp/option_space.h>
 #include <dhcpsrv/cfg_option.h>
 #include <boost/lexical_cast.hpp>
+#include <dhcp/dhcp6.h>
 #include <limits>
 #include <string>
 
@@ -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<uint32_t>(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

+ 35 - 0
src/lib/dhcpsrv/cfg_option.h

@@ -26,6 +26,7 @@
 #include <boost/shared_ptr.hpp>
 #include <stdint.h>
 #include <string>
+#include <set>
 
 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<uint16_t> rsoo_options_;
 };
 
 /// @name Pointers to the @c CfgOption objects.

+ 29 - 0
src/lib/dhcpsrv/tests/cfg_option_unittest.cc

@@ -13,6 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <config.h>
+#include <dhcp/dhcp6.h>
 #include <dhcp/option.h>
 #include <dhcp/option_int.h>
 #include <dhcp/option_space.h>
@@ -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