]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[master] Merge branch 'trac2313'
authorMarcin Siodelski <marcin@isc.org>
Wed, 9 Jan 2013 08:01:53 +0000 (09:01 +0100)
committerMarcin Siodelski <marcin@isc.org>
Wed, 9 Jan 2013 08:01:53 +0000 (09:01 +0100)
Conflicts:
src/lib/dhcpsrv/cfgmgr.cc
src/lib/dhcpsrv/cfgmgr.h

1  2 
src/lib/dhcpsrv/Makefile.am
src/lib/dhcpsrv/cfgmgr.cc
src/lib/dhcpsrv/cfgmgr.h
src/lib/dhcpsrv/tests/Makefile.am
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc

Simple merge
index ce28575537eb3398afed6f5465d13d004b304749,beb2df21575c1681326463458e8ee746acc0fafc..26ee978b1dc8cb2e9d41d0a3fd87adef43aaf088
@@@ -29,84 -27,36 +29,114 @@@ CfgMgr::instance() 
      return (cfg_mgr);
  }
  
+ void
+ CfgMgr::addOptionSpace4(const OptionSpacePtr& space) {
+     if (!space) {
+         isc_throw(InvalidOptionSpace,
+                   "provided option space object is NULL.");
+     }
+     OptionSpaceCollection::iterator it = spaces4_.find(space->getName());
+     if (it != spaces4_.end()) {
+         isc_throw(InvalidOptionSpace, "option space " << space->getName()
+                   << " already added.");
+     }
+     spaces4_.insert(std::pair<std::string,
+                               OptionSpacePtr>(space->getName(), space));
+ }
+ void
+ CfgMgr::addOptionSpace6(const OptionSpacePtr& space) {
+     if (!space) {
+         isc_throw(InvalidOptionSpace,
+                   "provided option space object is NULL.");
+     }
+     OptionSpaceCollection::iterator it = spaces6_.find(space->getName());
+     if (it != spaces6_.end()) {
+         isc_throw(InvalidOptionSpace, "option space " << space->getName()
+                   << " already added.");
+     }
+     spaces6_.insert(std::pair<std::string,
+                               OptionSpacePtr>(space->getName(), space));
+ }
 +void
 +CfgMgr::addOptionDef(const OptionDefinitionPtr& def,
 +                     const std::string& option_space) {
 +    // @todo we need better validation of the provided option space name here.
 +    // This will be implemented when #2313 is merged.
 +    if (option_space.empty()) {
 +        isc_throw(BadValue, "option space name must not be empty");
 +    } else if (!def) {
 +        // Option definition must point to a valid object.
 +        isc_throw(MalformedOptionDefinition, "option definition must not be NULL");
 +
 +    } else if (getOptionDef(option_space, def->getCode())) {
 +        // Option definition must not be overriden.
 +        isc_throw(DuplicateOptionDefinition, "option definition already added"
 +                  << " to option space " << option_space);
 +
 +    } else if ((option_space == "dhcp4" &&
 +                LibDHCP::isStandardOption(Option::V4, def->getCode())) ||
 +               (option_space == "dhcp6" &&
 +                LibDHCP::isStandardOption(Option::V6, def->getCode()))) {
 +        // We must not override standard (assigned) option. The standard options
 +        // belong to dhcp4 or dhcp6 option space.
 +        isc_throw(BadValue, "unable to override definition of option '"
 +                  << def->getCode() << "' in standard option space '"
 +                  << option_space << "'.");
 +
 +    }
 +    // Get existing option definitions for the option space.
 +    OptionDefContainerPtr defs = getOptionDefs(option_space);
 +    // getOptionDefs always returns a valid pointer to
 +    // the container. Let's make an assert to make sure.
 +    assert(defs);
 +    // Actually add the new definition.
 +    defs->push_back(def);
 +    option_def_spaces_[option_space] = defs;
 +}
 +
 +OptionDefContainerPtr
 +CfgMgr::getOptionDefs(const std::string& option_space) const {
 +    // @todo Validate the option space once the #2313 is implemented.
 +
 +    // Get all option definitions for the particular option space.
 +    const OptionDefsMap::const_iterator& defs =
 +        option_def_spaces_.find(option_space);
 +    // If there are no option definitions for the particular option space
 +    // then return empty container.
 +    if (defs == option_def_spaces_.end()) {
 +        return (OptionDefContainerPtr(new OptionDefContainer()));
 +    }
 +    // If option definitions found, return them.
 +    return (defs->second);
 +}
 +
 +OptionDefinitionPtr
 +CfgMgr::getOptionDef(const std::string& option_space,
 +                     const uint16_t option_code) const {
 +    // @todo Validate the option space once the #2313 is implemented.
 +
 +    // Get a reference to option definitions for a particular option space.
 +    OptionDefContainerPtr defs = getOptionDefs(option_space);
 +    // If there are no matching option definitions then return the empty pointer.
 +    if (!defs || defs->empty()) {
 +        return (OptionDefinitionPtr());
 +    }
 +    // If there are some option definitions for a particular option space
 +    // use an option code to get the one we want.
 +    const OptionDefContainerTypeIndex& idx = defs->get<1>();
 +    const OptionDefContainerTypeRange& range = idx.equal_range(option_code);
 +    // If there is no definition that matches option code, return empty pointer.
 +    if (std::distance(range.first, range.second) == 0) {
 +        return (OptionDefinitionPtr());
 +    }
 +    // If there is more than one definition matching an option code, return
 +    // the first one. This should not happen because we check for duplicates
 +    // when addOptionDef is called.
 +    return (*range.first);
 +}
 +
  Subnet6Ptr
  CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint) {
  
index 9628f2422511699f1939d0a345e9dc528d5168ee,523cd101fd4804b34596777f99a6041b1e3f375a..c1f1dd6e6a6b5a5c72cd631d8f29535dfd24e48f
@@@ -17,7 -17,7 +17,8 @@@
  
  #include <asiolink/io_address.h>
  #include <dhcp/option.h>
 +#include <dhcp/option_definition.h>
+ #include <dhcpsrv/option_space.h>
  #include <dhcpsrv/pool.h>
  #include <dhcpsrv/subnet.h>
  #include <util/buffer.h>
@@@ -65,7 -65,7 +66,6 @@@ namespace dhcp 
  /// Parameter inheritance is likely to be implemented in configuration handling
  /// routines, so there is no storage capability in a global scope for
  /// subnet-specific parameters.
--///
  /// @todo: Implement Subnet4 support (ticket #2237)
  /// @todo: Implement option definition support
  /// @todo: Implement parameter inheritance
@@@ -78,41 -78,36 +78,71 @@@ public
      /// accessing it.
      static CfgMgr& instance();
  
 +    /// @brief Add new option definition.
 +    ///
 +    /// @param def option definition to be added.
 +    /// @param option_space name of the option space to add definition to.
 +    ///
 +    /// @throw isc::dhcp::DuplicateOptionDefinition when the particular
 +    /// option definition already exists.
 +    /// @throw isc::dhcp::MalformedOptionDefinition when the pointer to
 +    /// an option definition is NULL.
 +    /// @throw isc::BadValue when the option space name is empty or
 +    /// when trying to override the standard option (in dhcp4 or dhcp6
 +    /// option space).
 +    void addOptionDef(const OptionDefinitionPtr& def,
 +                      const std::string& option_space);
 +
 +    /// @brief Return option definitions for particular option space.
 +    ///
 +    /// @param option_space option space.
 +    ///
 +    /// @return pointer to the collection of option definitions for
 +    /// the particular option space. The option collection is empty
 +    /// if no option exists for the option space specified.
 +    OptionDefContainerPtr
 +    getOptionDefs(const std::string& option_space) const;
 +
 +    /// @brief Return option definition for a particular option space and code.
 +    ///
 +    /// @param option_space option space.
 +    /// @param option_code option code.
 +    ///
 +    /// @return an option definition or NULL pointer if option definition
 +    /// has not been found.
 +    OptionDefinitionPtr getOptionDef(const std::string& option_space,
 +                                     const uint16_t option_code) const;
 +
+     /// @brief Adds new DHCPv4 option space to the collection.
+     ///
+     /// @param space option space to be added.
+     ///
+     /// @throw isc::dhcp::InvalidOptionSpace invalid option space
+     /// has been specified.
+     void addOptionSpace4(const OptionSpacePtr& space);
+     /// @brief Adds new DHCPv6 option space to the collection.
+     ///
+     /// @param space option space to be added.
+     ///
+     /// @throw isc::dhcp::InvalidOptionSpace invalid option space
+     /// has been specified.
+     void addOptionSpace6(const OptionSpacePtr& space);
+     /// @brief Return option spaces for DHCPv4.
+     ///
+     /// @return A collection of option spaces.
+     const OptionSpaceCollection& getOptionSpaces4() const {
+         return (spaces4_);
+     }
+     /// @brief Return option spaces for DHCPv6.
+     ///
+     /// @return A collection of option spaces.
+     const OptionSpaceCollection& getOptionSpaces6() const {
+         return (spaces6_);
+     }
      /// @brief get IPv6 subnet by address
      ///
      /// Finds a matching subnet, based on an address. This can be used
@@@ -218,18 -201,11 +248,24 @@@ protected
      /// a match is found.
      Subnet4Collection subnets4_;
  
 +private:
 +
 +    /// A map containing option definitions for various option spaces.
 +    /// They key of this map is the name of the option space. The
 +    /// value is the the option container holding option definitions
 +    /// for the particular option space.
 +    typedef std::map<std::string, OptionDefContainerPtr> OptionDefsMap;
 +
 +    /// A map containing option definitions for different option spaces.
 +    /// The map key holds an option space name.
 +    OptionDefsMap option_def_spaces_;
 +
+     /// @brief Container for defined DHCPv6 option spaces.
+     OptionSpaceCollection spaces6_;
+     /// @brief Container for defined DHCPv4 option spaces.
+     OptionSpaceCollection spaces4_;
++
  };
  
  } // namespace isc::dhcp
Simple merge
index 7f73ee399a3847eeaad25f6eb4c19bee4027c4c8,7d3d9caa710492c586c018b3a36edb83edc2fad2..ab1d5864d4f95c0cda2c4f3cfd90efdaa55b894a
@@@ -272,13 -104,78 +272,79 @@@ TEST_F(CfgMgrTest, subnet6) 
  
      EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(IOAddress("4000::123")));
      EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("3000::dead:beef")));
 -    EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("5000::1")));
 +    EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("5000::1")));
  
 +    // Check that deletion of the subnets works.
      cfg_mgr.deleteSubnets6();
 -    EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("200::123")));
 -    EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("3000::123")));
 -    EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("4000::123")));
 +    EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("200::123")));
 +    EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("3000::123")));
 +    EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("4000::123")));
  }
  
+ // This test verifies that new DHCPv4 option spaces can be added to
+ // the configuration manager and that duplicated option space is
+ // rejected.
+ TEST_F(CfgMgrTest, optionSpace4) {
+     CfgMgr& cfg_mgr = CfgMgr::instance();
+     // Create some option spaces.
+     OptionSpacePtr space1(new OptionSpace("isc", false));
+     OptionSpacePtr space2(new OptionSpace("xyz", true));
+     // Add option spaces with different names and expect they
+     // are accepted.
+     ASSERT_NO_THROW(cfg_mgr.addOptionSpace4(space1));
+     ASSERT_NO_THROW(cfg_mgr.addOptionSpace4(space2));
+     // Validate that the option spaces have been added correctly.
+     const OptionSpaceCollection& spaces = cfg_mgr.getOptionSpaces4();
+     ASSERT_EQ(2, spaces.size());
+     EXPECT_FALSE(spaces.find("isc") == spaces.end());
+     EXPECT_FALSE(spaces.find("xyz") == spaces.end());
+     // Create another option space with the name that duplicates
+     // the existing option space.
+     OptionSpacePtr space3(new OptionSpace("isc", true));
+     // Expect that the duplicate option space is rejected.
+     ASSERT_THROW(
+         cfg_mgr.addOptionSpace4(space3), isc::dhcp::InvalidOptionSpace
+     );
+     // @todo decode if a duplicate vendor space is allowed.
+ }
+ // This test verifies that new DHCPv6 option spaces can be added to
+ // the configuration manager and that duplicated option space is
+ // rejected.
+ TEST_F(CfgMgrTest, optionSpace6) {
+     CfgMgr& cfg_mgr = CfgMgr::instance();
+     // Create some option spaces.
+     OptionSpacePtr space1(new OptionSpace("isc", false));
+     OptionSpacePtr space2(new OptionSpace("xyz", true));
+     // Add option spaces with different names and expect they
+     // are accepted.
+     ASSERT_NO_THROW(cfg_mgr.addOptionSpace6(space1));
+     ASSERT_NO_THROW(cfg_mgr.addOptionSpace6(space2));
+     // Validate that the option spaces have been added correctly.
+     const OptionSpaceCollection& spaces = cfg_mgr.getOptionSpaces6();
+     ASSERT_EQ(2, spaces.size());
+     EXPECT_FALSE(spaces.find("isc") == spaces.end());
+     EXPECT_FALSE(spaces.find("xyz") == spaces.end());
+     // Create another option space with the name that duplicates
+     // the existing option space.
+     OptionSpacePtr space3(new OptionSpace("isc", true));
+     // Expect that the duplicate option space is rejected.
+     ASSERT_THROW(
+         cfg_mgr.addOptionSpace6(space3), isc::dhcp::InvalidOptionSpace
+     );
+     // @todo decide if a duplicate vendor space is allowed.
+ }
  } // end of anonymous namespace