Browse Source

[3467] Added new index to search for option definitions using a name.

Marcin Siodelski 10 years ago
parent
commit
0dc3cad052

+ 35 - 0
src/lib/dhcp/libdhcp++.cc

@@ -130,6 +130,41 @@ LibDHCP::getOptionDef(const Option::Universe u, const uint16_t code) {
 }
 
 OptionDefinitionPtr
+LibDHCP::getOptionDef(const Option::Universe u, const std::string& name) {
+    const OptionDefContainer& defs = getOptionDefs(u);
+    const OptionDefContainerNameIndex& idx = defs.get<2>();
+    const OptionDefContainerNameRange& range = idx.equal_range(name);
+    if (range.first != range.second) {
+        return (*range.first);
+    }
+    return (OptionDefinitionPtr());
+
+}
+
+
+OptionDefinitionPtr
+LibDHCP::getVendorOptionDef(const Option::Universe u, const uint32_t vendor_id,
+                            const std::string& name) {
+    const OptionDefContainer* defs = NULL;
+    if (u == Option::V4) {
+        defs = getVendorOption4Defs(vendor_id);
+    } else if (u == Option::V6) {
+        defs = getVendorOption6Defs(vendor_id);
+    }
+
+    if (!defs) {
+        return (OptionDefinitionPtr());
+    }
+
+    const OptionDefContainerNameIndex& idx = defs->get<2>();
+    const OptionDefContainerNameRange& range = idx.equal_range(name);
+    if (range.first != range.second) {
+        return (*range.first);
+    }
+    return (OptionDefinitionPtr());
+}
+
+OptionDefinitionPtr
 LibDHCP::getVendorOptionDef(const Option::Universe u, const uint32_t vendor_id,
                             const uint16_t code) {
     const OptionDefContainer* defs = NULL;

+ 24 - 0
src/lib/dhcp/libdhcp++.h

@@ -20,6 +20,7 @@
 #include <util/buffer.h>
 
 #include <iostream>
+#include <string>
 
 namespace isc {
 namespace dhcp {
@@ -55,6 +56,16 @@ public:
     static OptionDefinitionPtr getOptionDef(const Option::Universe u,
                                             const uint16_t code);
 
+    /// @brief Return the definition of option having a specified name.
+    ///
+    /// @param u universe (v4 or V6)
+    /// @param name Option name.
+    ///
+    /// @return Pointer the option definition or NULL pointer it option
+    /// definition has not been found.
+    static OptionDefinitionPtr getOptionDef(const Option::Universe u,
+                                            const std::string& name);
+
     /// @brief Returns vendor option definition for a given vendor-id and code
     ///
     /// @param u universe (V4 or V6)
@@ -66,6 +77,19 @@ public:
                                                   const uint32_t vendor_id,
                                                   const uint16_t code);
 
+    /// @brief Returns vendor option definition for a given vendor-id and
+    /// option name.
+    ///
+    /// @param u Universe (V4 or V6)
+    /// @param vendor_id Enterprise-id for a given vendor
+    /// @param name Option name.
+    ///
+    /// @return A pointer to an option definition or NULL pointer if
+    /// no option definition found.
+    static OptionDefinitionPtr getVendorOptionDef(const Option::Universe u,
+                                                  const uint32_t vendor_id,
+                                                  const std::string& name);
+
     /// @brief Check if the specified option is a standard option.
     ///
     /// @param u universe (V4 or V6)

+ 20 - 0
src/lib/dhcp/option_definition.h

@@ -717,6 +717,17 @@ typedef boost::multi_index_container<
                 uint16_t,
                 &OptionDefinition::getCode
             >
+        >,
+        // Start definition of index #2
+        boost::multi_index::hashed_non_unique<
+            // Use option name as the index key. This value is
+            // returned by the @c OptionDefinition::getName
+            // method.
+            boost::multi_index::const_mem_fun<
+                OptionDefinition,
+                std::string,
+                &OptionDefinition::getName
+            >
         >
     >
 > OptionDefContainer;
@@ -736,6 +747,15 @@ typedef OptionDefContainer::nth_index<1>::type OptionDefContainerTypeIndex;
 typedef std::pair<OptionDefContainerTypeIndex::const_iterator,
                   OptionDefContainerTypeIndex::const_iterator> OptionDefContainerTypeRange;
 
+/// Type of the index #2 - option name.
+typedef OptionDefContainer::nth_index<2>::type OptionDefContainerNameIndex;
+/// Pair of iterators to represent the range of options definitions
+/// having the same option name. The first element in this pair
+/// represents the beginning of the range, the second element
+/// represents the end.
+typedef std::pair<OptionDefContainerNameIndex::const_iterator,
+                  OptionDefContainerNameIndex::const_iterator> OptionDefContainerNameRange;
+
 
 } // namespace isc::dhcp
 } // namespace isc

+ 64 - 0
src/lib/dhcp/tests/libdhcp++_unittest.cc

@@ -16,6 +16,7 @@
 
 #include <dhcp/dhcp4.h>
 #include <dhcp/dhcp6.h>
+#include <dhcp/docsis3_option_defs.h>
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option4_addrlst.h>
 #include <dhcp/option4_client_fqdn.h>
@@ -1141,6 +1142,69 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
                                     typeid(Option6AddrLst));
 }
 
+// This test checks if the DHCPv6 option definition can be searched by
+// an option name.
+TEST_F(LibDhcpTest, getOptionDefByName6) {
+    // Get all definitions.
+    const OptionDefContainer& defs = LibDHCP::getOptionDefs(Option::V6);
+    // For each definition try to find it using option name.
+    for (OptionDefContainer::const_iterator def = defs.begin();
+         def != defs.end(); ++def) {
+        OptionDefinitionPtr def_by_name =
+            LibDHCP::getOptionDef(Option::V6, (*def)->getName());
+        ASSERT_TRUE(def_by_name);
+        ASSERT_TRUE(**def == *def_by_name);
+    }
+}
+
+
+// This test checks if the DHCPv4 option definition can be searched by
+// an option name.
+TEST_F(LibDhcpTest, getOptionDefByName4) {
+    // Get all definitions.
+    const OptionDefContainer& defs = LibDHCP::getOptionDefs(Option::V4);
+    // For each definition try to find it using option name.
+    for (OptionDefContainer::const_iterator def = defs.begin();
+         def != defs.end(); ++def) {
+        OptionDefinitionPtr def_by_name =
+            LibDHCP::getOptionDef(Option::V4, (*def)->getName());
+        ASSERT_TRUE(def_by_name);
+        ASSERT_TRUE(**def == *def_by_name);
+    }
+}
+
+// This test checks if the definition of the DHCPv6 vendor option can
+// be searched by option name.
+TEST_F(LibDhcpTest, getVendorOptionDefByName6) {
+    const OptionDefContainer* defs =
+        LibDHCP::getVendorOption6Defs(VENDOR_ID_CABLE_LABS);
+    ASSERT_TRUE(defs != NULL);
+    for (OptionDefContainer::const_iterator def = defs->begin();
+         def != defs->end(); ++def) {
+        OptionDefinitionPtr def_by_name =
+            LibDHCP::getVendorOptionDef(Option::V6, VENDOR_ID_CABLE_LABS,
+                                        (*def)->getName());
+        ASSERT_TRUE(def_by_name);
+        ASSERT_TRUE(**def == *def_by_name);
+    }
+}
+
+// This test checks if the definition of the DHCPv4 vendor option can
+// be searched by option name.
+TEST_F(LibDhcpTest, getVendorOptionDefByName4) {
+    const OptionDefContainer* defs =
+        LibDHCP::getVendorOption4Defs(VENDOR_ID_CABLE_LABS);
+    ASSERT_TRUE(defs != NULL);
+    for (OptionDefContainer::const_iterator def = defs->begin();
+         def != defs->end(); ++def) {
+        OptionDefinitionPtr def_by_name =
+            LibDHCP::getVendorOptionDef(Option::V4, VENDOR_ID_CABLE_LABS,
+                                        (*def)->getName());
+        ASSERT_TRUE(def_by_name);
+        ASSERT_TRUE(**def == *def_by_name);
+    }
+}
+
 // tests whether v6 vendor-class option can be parsed properly.
 TEST_F(LibDhcpTest, vendorClass6) {