Browse Source

[2314] Added encapsulated option space name to option definition.

Marcin Siodelski 12 years ago
parent
commit
656b5d1cb0

+ 1 - 0
src/lib/dhcp/Makefile.am

@@ -32,6 +32,7 @@ libb10_dhcp___la_SOURCES += option.cc option.h
 libb10_dhcp___la_SOURCES += option_custom.cc option_custom.h
 libb10_dhcp___la_SOURCES += option_data_types.cc option_data_types.h
 libb10_dhcp___la_SOURCES += option_definition.cc option_definition.h
+libb10_dhcp___la_SOURCES += option_space.cc option_space.h
 libb10_dhcp___la_SOURCES += pkt6.cc pkt6.h
 libb10_dhcp___la_SOURCES += pkt4.cc pkt4.h
 libb10_dhcp___la_SOURCES += std_option_defs.h

+ 36 - 2
src/lib/dhcp/option_definition.cc

@@ -21,6 +21,7 @@
 #include <dhcp/option_definition.h>
 #include <dhcp/option_int.h>
 #include <dhcp/option_int_array.h>
+#include <dhcp/option_space.h>
 #include <util/encode/hex.h>
 #include <util/strutil.h>
 #include <boost/algorithm/string/classification.hpp>
@@ -40,7 +41,8 @@ OptionDefinition::OptionDefinition(const std::string& name,
     : name_(name),
       code_(code),
       type_(OPT_UNKNOWN_TYPE),
-      array_type_(array_type) {
+      array_type_(array_type),
+      encapsulated_space_("") {
     // Data type is held as enum value by this class.
     // Use the provided option type string to get the
     // corresponding enum value.
@@ -54,7 +56,34 @@ OptionDefinition::OptionDefinition(const std::string& name,
     : name_(name),
       code_(code),
       type_(type),
-      array_type_(array_type) {
+      array_type_(array_type),
+      encapsulated_space_("") {
+}
+
+OptionDefinition::OptionDefinition(const std::string& name,
+                                   const uint16_t code,
+                                   const std::string& type,
+                                   const char* encapsulated_space)
+    : name_(name),
+      code_(code),
+      type_(OPT_UNKNOWN_TYPE),
+      array_type_(false),
+      encapsulated_space_(encapsulated_space) {
+    // Data type is held as enum value by this class.
+    // Use the provided option type string to get the
+    // corresponding enum value.
+    type_ = OptionDataTypeUtil::getDataType(type);
+}
+
+OptionDefinition::OptionDefinition(const std::string& name,
+                                   const uint16_t code,
+                                   const OptionDataType type,
+                                   const char* encapsulated_space)
+    : name_(name),
+      code_(code),
+      type_(type),
+      array_type_(false),
+      encapsulated_space_(encapsulated_space) {
 }
 
 void
@@ -228,6 +257,11 @@ OptionDefinition::validate() const {
         all(find_tail(name_, 1), boost::is_any_of(std::string("-_")))) {
         err_str << "invalid option name '" << name_ << "'";
 
+    } else if (!encapsulated_space_.empty() &&
+               !OptionSpace::validateName(encapsulated_space_)) {
+        err_str << "invalid encapsulated option space name: '"
+                << encapsulated_space_ << "'";
+
     } else if (type_ >= OPT_UNKNOWN_TYPE) {
         // Option definition must be of a known type.
         err_str << "option type value " << type_ << " is out of range.";

+ 56 - 8
src/lib/dhcp/option_definition.h

@@ -146,10 +146,10 @@ public:
     /// @param type option data type as string.
     /// @param array_type array indicator, if true it indicates that the
     /// option fields are the array.
-    OptionDefinition(const std::string& name,
-                     const uint16_t code,
-                     const std::string& type,
-                     const bool array_type = false);
+    explicit OptionDefinition(const std::string& name,
+                              const uint16_t code,
+                              const std::string& type,
+                              const bool array_type = false);
 
     /// @brief Constructor.
     ///
@@ -158,10 +158,49 @@ public:
     /// @param type option data type.
     /// @param array_type array indicator, if true it indicates that the
     /// option fields are the array.
-    OptionDefinition(const std::string& name,
-                     const uint16_t code,
-                     const OptionDataType type,
-                     const bool array_type = false);
+    explicit OptionDefinition(const std::string& name,
+                              const uint16_t code,
+                              const OptionDataType type,
+                              const bool array_type = false);
+
+    /// @brief Constructor.
+    ///
+    /// This constructor sets the name of the option space that is
+    /// encapsulated by this option. The encapsulated option space
+    /// indentifies sub-options that are carried within this option.
+    /// This constructor does not allow to set array indicator
+    /// because options comprising an array of data fields must
+    /// not be used with sub-options.
+    ///
+    /// @param name option name.
+    /// @param code option code.
+    /// @param type option data type given as string.
+    /// @param encapsulated_space name of the option space being
+    /// encapsulated by this option.
+    explicit OptionDefinition(const std::string& name,
+                              const uint16_t code,
+                              const std::string& type,
+                              const char* encapsulated_space);
+
+    /// @brief Constructor.
+    ///
+    /// This constructor sets the name of the option space that is
+    /// encapsulated by this option. The encapsulated option space
+    /// indentifies sub-options that are carried within this option.
+    /// This constructor does not allow to set array indicator
+    /// because options comprising an array of data fields must
+    /// not be used with sub-options.
+    ///
+    /// @param name option name.
+    /// @param code option code.
+    /// @param type option data type.
+    /// @param encapsulated_space name of the option space being
+    /// encapsulated by this option.
+    explicit OptionDefinition(const std::string& name,
+                              const uint16_t code,
+                              const OptionDataType type,
+                              const char* encapsulated_space);
+
 
     /// @brief Adds data field to the record.
     ///
@@ -192,6 +231,13 @@ public:
     /// @return option code.
     uint16_t getCode() const { return (code_); }
 
+    /// @brief Return name of the encapsulated option space.
+    ///
+    /// @return name of the encapsulated option space.
+    const std::string& getEncapsulatedSpace() const {
+        return (encapsulated_space_);
+    }
+
     /// @brief Return option name.
     ///
     /// @return option name.
@@ -456,6 +502,8 @@ private:
     OptionDataType type_;
     /// Indicates wheter option is a single value or array.
     bool array_type_;
+    /// Name of the space being encapsulated by this option.
+    std::string encapsulated_space_;
     /// Collection of data fields within the record.
     RecordFieldsCollection record_fields_;
 };

+ 1 - 1
src/lib/dhcpsrv/option_space.cc

@@ -12,7 +12,7 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <dhcpsrv/option_space.h>
+#include <dhcp/option_space.h>
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 

src/lib/dhcpsrv/option_space.h → src/lib/dhcp/option_space.h


+ 1 - 0
src/lib/dhcp/tests/Makefile.am

@@ -40,6 +40,7 @@ libdhcp___unittests_SOURCES += option_data_types_unittest.cc
 libdhcp___unittests_SOURCES += option_definition_unittest.cc
 libdhcp___unittests_SOURCES += option_custom_unittest.cc
 libdhcp___unittests_SOURCES += option_unittest.cc
+libdhcp___unittests_SOURCES += option_space_unittest.cc
 libdhcp___unittests_SOURCES += pkt4_unittest.cc
 libdhcp___unittests_SOURCES += pkt6_unittest.cc
 libdhcp___unittests_SOURCES += duid_unittest.cc

+ 39 - 10
src/lib/dhcp/tests/option_definition_unittest.cc

@@ -53,38 +53,62 @@ public:
 TEST_F(OptionDefinitionTest, constructor) {
     // Specify the option data type as string. This should get converted
     // to enum value returned by getType().
-    OptionDefinition opt_def1("OPTION_CLIENTID", 1, "string");
+    OptionDefinition opt_def1("OPTION_CLIENTID", D6O_CLIENTID, "string");
     EXPECT_EQ("OPTION_CLIENTID", opt_def1.getName());
 
     EXPECT_EQ(1, opt_def1.getCode());
     EXPECT_EQ(OPT_STRING_TYPE,  opt_def1.getType());
     EXPECT_FALSE(opt_def1.getArrayType());
+    EXPECT_TRUE(opt_def1.getEncapsulatedSpace().empty());
     EXPECT_NO_THROW(opt_def1.validate());
 
     // Specify the option data type as an enum value.
-    OptionDefinition opt_def2("OPTION_RAPID_COMMIT", 14,
+    OptionDefinition opt_def2("OPTION_RAPID_COMMIT", D6O_RAPID_COMMIT,
                               OPT_EMPTY_TYPE);
     EXPECT_EQ("OPTION_RAPID_COMMIT", opt_def2.getName());
     EXPECT_EQ(14, opt_def2.getCode());
     EXPECT_EQ(OPT_EMPTY_TYPE, opt_def2.getType());
     EXPECT_FALSE(opt_def2.getArrayType());
-    EXPECT_NO_THROW(opt_def1.validate());
+    EXPECT_TRUE(opt_def2.getEncapsulatedSpace().empty());
+    EXPECT_NO_THROW(opt_def2.validate());
+
+    // Specify encapsulated option space name and option data type
+    // as enum value.
+    OptionDefinition opt_def3("OPTION_VENDOR_OPTS", D6O_VENDOR_OPTS,
+                              OPT_UINT32_TYPE, "isc");
+    EXPECT_EQ("OPTION_VENDOR_OPTS", opt_def3.getName());
+    EXPECT_EQ(D6O_VENDOR_OPTS, opt_def3.getCode());
+    EXPECT_EQ(OPT_UINT32_TYPE, opt_def3.getType());
+    EXPECT_FALSE(opt_def3.getArrayType());
+    EXPECT_EQ("isc", opt_def3.getEncapsulatedSpace());
+    EXPECT_NO_THROW(opt_def3.validate());
+
+    // Specify encapsulated option space name and option data type
+    // as string value.
+    OptionDefinition opt_def4("OPTION_VENDOR_OPTS", D6O_VENDOR_OPTS,
+                              "uint32", "isc");
+    EXPECT_EQ("OPTION_VENDOR_OPTS", opt_def4.getName());
+    EXPECT_EQ(D6O_VENDOR_OPTS, opt_def4.getCode());
+    EXPECT_EQ(OPT_UINT32_TYPE, opt_def4.getType());
+    EXPECT_FALSE(opt_def4.getArrayType());
+    EXPECT_EQ("isc", opt_def4.getEncapsulatedSpace());
+    EXPECT_NO_THROW(opt_def4.validate());
 
     // Check if it is possible to set that option is an array.
-    OptionDefinition opt_def3("OPTION_NIS_SERVERS", 27,
+    OptionDefinition opt_def5("OPTION_NIS_SERVERS", 27,
                               OPT_IPV6_ADDRESS_TYPE,
                               true);
-    EXPECT_EQ("OPTION_NIS_SERVERS", opt_def3.getName());
-    EXPECT_EQ(27, opt_def3.getCode());
-    EXPECT_EQ(OPT_IPV6_ADDRESS_TYPE, opt_def3.getType());
-    EXPECT_TRUE(opt_def3.getArrayType());
-    EXPECT_NO_THROW(opt_def3.validate());
+    EXPECT_EQ("OPTION_NIS_SERVERS", opt_def5.getName());
+    EXPECT_EQ(27, opt_def5.getCode());
+    EXPECT_EQ(OPT_IPV6_ADDRESS_TYPE, opt_def5.getType());
+    EXPECT_TRUE(opt_def5.getArrayType());
+    EXPECT_NO_THROW(opt_def5.validate());
 
     // The created object is invalid if invalid data type is specified but
     // constructor shouldn't throw exception. The object is validated after
     // it has been created.
     EXPECT_NO_THROW(
-        OptionDefinition opt_def4("OPTION_SERVERID",
+        OptionDefinition opt_def6("OPTION_SERVERID",
                                   OPT_UNKNOWN_TYPE + 10,
                                   OPT_STRING_TYPE);
     );
@@ -213,6 +237,11 @@ TEST_F(OptionDefinitionTest, validate) {
                                "record");
     opt_def16.addRecordField("uint8");
     opt_def16.addRecordField("string");
+
+    // Check invalid encapsulated option space name.
+    OptionDefinition opt_def17("OPTION_VENDOR_OPTS", D6O_VENDOR_OPTS,
+                               "uint32", "invalid%space%name");
+    EXPECT_THROW(opt_def17.validate(), MalformedOptionDefinition);
 }
 
 

+ 1 - 1
src/lib/dhcpsrv/tests/option_space_unittest.cc

@@ -14,7 +14,7 @@
 
 #include <config.h>
 
-#include <dhcpsrv/option_space.h>
+#include <dhcp/option_space.h>
 
 #include <gtest/gtest.h>
 

+ 0 - 1
src/lib/dhcpsrv/Makefile.am

@@ -42,7 +42,6 @@ libb10_dhcpsrv_la_SOURCES += memfile_lease_mgr.cc memfile_lease_mgr.h
 if HAVE_MYSQL
 libb10_dhcpsrv_la_SOURCES += mysql_lease_mgr.cc mysql_lease_mgr.h
 endif
-libb10_dhcpsrv_la_SOURCES += option_space.cc option_space.h
 libb10_dhcpsrv_la_SOURCES += option_space_container.h
 libb10_dhcpsrv_la_SOURCES += pool.cc pool.h
 libb10_dhcpsrv_la_SOURCES += subnet.cc subnet.h

+ 1 - 1
src/lib/dhcpsrv/cfgmgr.h

@@ -18,7 +18,7 @@
 #include <asiolink/io_address.h>
 #include <dhcp/option.h>
 #include <dhcp/option_definition.h>
-#include <dhcpsrv/option_space.h>
+#include <dhcp/option_space.h>
 #include <dhcpsrv/option_space_container.h>
 #include <dhcpsrv/pool.h>
 #include <dhcpsrv/subnet.h>

+ 0 - 1
src/lib/dhcpsrv/tests/Makefile.am

@@ -36,7 +36,6 @@ libdhcpsrv_unittests_SOURCES += memfile_lease_mgr_unittest.cc
 if HAVE_MYSQL
 libdhcpsrv_unittests_SOURCES += mysql_lease_mgr_unittest.cc
 endif
-libdhcpsrv_unittests_SOURCES += option_space_unittest.cc
 libdhcpsrv_unittests_SOURCES += pool_unittest.cc
 libdhcpsrv_unittests_SOURCES += schema_copy.h
 libdhcpsrv_unittests_SOURCES += subnet_unittest.cc