From d3a6e81ce4fefc8dea79e4d82c90848eccbac362 Mon Sep 17 00:00:00 2001 From: Marcin Siodelski Date: Tue, 27 Sep 2016 13:02:43 +0200 Subject: [PATCH] [github24] Added option definitions for RFC7598. --- src/lib/dhcp/libdhcp++.cc | 46 +++++++++++++++-- src/lib/dhcp/libdhcp++.h | 13 +++++ src/lib/dhcp/option_definition.h | 4 ++ src/lib/dhcp/option_space.h | 12 ++--- src/lib/dhcp/std_option_defs.h | 7 +-- src/lib/dhcp/tests/libdhcp++_unittest.cc | 66 +++++++++++++++++++++--- 6 files changed, 125 insertions(+), 23 deletions(-) diff --git a/src/lib/dhcp/libdhcp++.cc b/src/lib/dhcp/libdhcp++.cc index 116c61dc26..c4b64c5d8d 100644 --- a/src/lib/dhcp/libdhcp++.cc +++ b/src/lib/dhcp/libdhcp++.cc @@ -45,8 +45,13 @@ OptionDefContainerPtr LibDHCP::v4option_defs_(new OptionDefContainer()); // Static container with DHCPv6 option definitions. OptionDefContainerPtr LibDHCP::v6option_defs_(new OptionDefContainer()); +// Static container with option definitions grouped by option space. +OptionDefContainers LibDHCP::option_defs_; + +// Static container with vendor option definitions for DHCPv4. VendorOptionDefContainers LibDHCP::vendor4_defs_; +// Static container with vendor option definitions for DHCPv6. VendorOptionDefContainers LibDHCP::vendor6_defs_; // Static container with option definitions created in runtime. @@ -89,6 +94,22 @@ LibDHCP::getOptionDefs(const Option::Universe u) { } } +const OptionDefContainerPtr& +LibDHCP::getOptionDefs(const std::string& space) { + if (space == DHCP4_OPTION_SPACE) { + return (getOptionDefs(Option::V4)); + + } else if (space == DHCP6_OPTION_SPACE) { + return (getOptionDefs(Option::V6)); + } + + OptionDefContainers::const_iterator container = option_defs_.find(space); + if (container != option_defs_.end()) { + return (container->second); + } + return (null_option_def_container_); +} + const OptionDefContainerPtr& LibDHCP::getVendorOption4Defs(const uint32_t vendor_id) { @@ -832,27 +853,42 @@ void LibDHCP::OptionFactoryRegister(Option::Universe u, void LibDHCP::initStdOptionDefs4() { - initOptionSpace(v4option_defs_, OPTION_DEF_PARAMS4, OPTION_DEF_PARAMS_SIZE4); + initOptionSpace(v4option_defs_, STANDARD_V4_OPTION_DEFINITIONS, + STANDARD_V4_OPTION_DEFINITIONS_SIZE); } void LibDHCP::initStdOptionDefs6() { - initOptionSpace(v6option_defs_, OPTION_DEF_PARAMS6, OPTION_DEF_PARAMS_SIZE6); + initOptionSpace(v6option_defs_, STANDARD_V6_OPTION_DEFINITIONS, + STANDARD_V6_OPTION_DEFINITIONS_SIZE); + initOptionSpace(option_defs_[MAPE_V6_OPTION_SPACE], MAPE_V6_OPTION_DEFINITIONS, + MAPE_V6_OPTION_DEFINITIONS_SIZE); + initOptionSpace(option_defs_[MAPT_V6_OPTION_SPACE], MAPT_V6_OPTION_DEFINITIONS, + MAPT_V6_OPTION_DEFINITIONS_SIZE); + initOptionSpace(option_defs_[LW_V6_OPTION_SPACE], LW_V6_OPTION_DEFINITIONS, + LW_V6_OPTION_DEFINITIONS_SIZE); + initOptionSpace(option_defs_[V4V6_RULE_OPTION_SPACE], V4V6_RULE_OPTION_DEFINITIONS, + V4V6_RULE_OPTION_DEFINITIONS_SIZE); + initOptionSpace(option_defs_[V4V6_BIND_OPTION_SPACE], V4V6_BIND_OPTION_DEFINITIONS, + V4V6_BIND_OPTION_DEFINITIONS_SIZE); } void LibDHCP::initVendorOptsDocsis4() { - initOptionSpace(vendor4_defs_[VENDOR_ID_CABLE_LABS], DOCSIS3_V4_DEFS, DOCSIS3_V4_DEFS_SIZE); + initOptionSpace(vendor4_defs_[VENDOR_ID_CABLE_LABS], DOCSIS3_V4_DEFS, + DOCSIS3_V4_DEFS_SIZE); } void LibDHCP::initVendorOptsDocsis6() { - initOptionSpace(vendor6_defs_[VENDOR_ID_CABLE_LABS], DOCSIS3_V6_DEFS, DOCSIS3_V6_DEFS_SIZE); + initOptionSpace(vendor6_defs_[VENDOR_ID_CABLE_LABS], DOCSIS3_V6_DEFS, + DOCSIS3_V6_DEFS_SIZE); } void LibDHCP::initVendorOptsIsc6() { - initOptionSpace(vendor6_defs_[ENTERPRISE_ID_ISC], ISC_V6_DEFS, ISC_V6_DEFS_SIZE); + initOptionSpace(vendor6_defs_[ENTERPRISE_ID_ISC], ISC_V6_OPTION_DEFINITIONS, + ISC_V6_OPTION_DEFINITIONS_SIZE); } uint32_t diff --git a/src/lib/dhcp/libdhcp++.h b/src/lib/dhcp/libdhcp++.h index 2ac6ea49c0..4d9179aba3 100644 --- a/src/lib/dhcp/libdhcp++.h +++ b/src/lib/dhcp/libdhcp++.h @@ -40,6 +40,16 @@ public: /// @return Pointer to a collection of option definitions. static const OptionDefContainerPtr& getOptionDefs(const Option::Universe u); + /// @brief Returns collection of option definitions. + /// + /// This method returns a collection of option definitions for a specified + /// option space. + /// + /// @param space Option space. + /// + /// @return Pointer to a collection of option definitions. + static const OptionDefContainerPtr& getOptionDefs(const std::string& space); + /// @brief Return the first option definition matching a /// particular option code. /// @@ -377,6 +387,9 @@ private: /// Container with DHCPv6 option definitions. static OptionDefContainerPtr v6option_defs_; + /// Container that holds option definitions for various option spaces. + static OptionDefContainers option_defs_; + /// Container for v4 vendor option definitions static VendorOptionDefContainers vendor4_defs_; diff --git a/src/lib/dhcp/option_definition.h b/src/lib/dhcp/option_definition.h index f495a0244e..b90f5d5a79 100644 --- a/src/lib/dhcp/option_definition.h +++ b/src/lib/dhcp/option_definition.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace isc { namespace dhcp { @@ -719,6 +720,9 @@ typedef boost::multi_index_container< /// Pointer to an option definition container. typedef boost::shared_ptr OptionDefContainerPtr; +/// Container that holds option definitions for various option spaces. +typedef std::map OptionDefContainers; + /// Container that holds various vendor option containers typedef std::map VendorOptionDefContainers; diff --git a/src/lib/dhcp/option_space.h b/src/lib/dhcp/option_space.h index 6fe92e48f3..374898b309 100644 --- a/src/lib/dhcp/option_space.h +++ b/src/lib/dhcp/option_space.h @@ -1,4 +1,4 @@ -// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -18,11 +18,11 @@ #define DOCSIS3_V4_OPTION_SPACE "docsis3_v4" #define DOCSIS3_V6_OPTION_SPACE "docsis3_v6" #define ISC_V6_OPTION_SPACE "4o6" -#define MAPE_V6_OPTION_SPACE "4over6-mape" -#define MAPT_V6_OPTION_SPACE "4over6-mapt" -#define LW_V6_OPTION_SPACE "4over6-lw" -#define V4V6_RULE_OPTION_SPACE "v4v6rule" -#define V4V6_BIND_OPTION_SPACE "v4v6bind" +#define MAPE_V6_OPTION_SPACE "s46-cont-mape-options" +#define MAPT_V6_OPTION_SPACE "s46-cont-mapt-options" +#define LW_V6_OPTION_SPACE "s46-cont-lw-options" +#define V4V6_RULE_OPTION_SPACE "s46-rule-options" +#define V4V6_BIND_OPTION_SPACE "s46-v4v6bind-options" namespace isc { namespace dhcp { diff --git a/src/lib/dhcp/std_option_defs.h b/src/lib/dhcp/std_option_defs.h index fa7414c63f..c40c2e5332 100644 --- a/src/lib/dhcp/std_option_defs.h +++ b/src/lib/dhcp/std_option_defs.h @@ -247,7 +247,7 @@ RECORD_DECL(LQ_RELAY_DATA_RECORDS, OPT_IPV6_ADDRESS_TYPE, OPT_BINARY_TYPE); RECORD_DECL(REMOTE_ID_RECORDS, OPT_UINT32_TYPE, OPT_BINARY_TYPE); // s46-rule RECORD_DECL(S46_RULE, OPT_UINT8_TYPE, OPT_UINT8_TYPE, OPT_UINT8_TYPE, - OPT_IPV4_ADDRESS_TYPE, OPT_IPV6_PREFIX_TYPE); + OPT_IPV4_ADDRESS_TYPE, OPT_IPV6_PREFIX_TYPE); // s46-v4v6bind RECORD_DECL(S46_V4V6BIND, OPT_IPV4_ADDRESS_TYPE, OPT_IPV6_PREFIX_TYPE); // s46-portparams @@ -419,7 +419,6 @@ const int ISC_V6_OPTION_DEFINITIONS_SIZE = sizeof(ISC_V6_OPTION_DEFINITIONS[0]); /// @brief MAPE option definitions -/// @todo: Maybe move this to a separate file, e.g. mape_option_defs.h const OptionDefParams MAPE_V6_OPTION_DEFINITIONS[] = { OPTION_DEF_PARAMS_S46_BR, OPTION_DEF_PARAMS_S46_RULE @@ -430,7 +429,6 @@ const int MAPE_V6_OPTION_DEFINITIONS_SIZE = sizeof(MAPE_V6_OPTION_DEFINITIONS[0]); /// @brief MAPT option definitions -/// @todo: Maybe move this to a separate file, e.g. mapt_option_defs.h const OptionDefParams MAPT_V6_OPTION_DEFINITIONS[] = { OPTION_DEF_PARAMS_S46_RULE, { "s46-dmr", D6O_S46_DMR, OPT_IPV6_PREFIX_TYPE, false, NO_RECORD_DEF, "" } @@ -441,7 +439,6 @@ const int MAPT_V6_OPTION_DEFINITIONS_SIZE = sizeof(MAPT_V6_OPTION_DEFINITIONS[0]); /// @brief LW option definitions -/// @todo: Maybe move this to a separate file, e.g. lw_option_defs.h const OptionDefParams LW_V6_OPTION_DEFINITIONS[] = { OPTION_DEF_PARAMS_S46_BR, { "s46-v4v6bind", D6O_S46_V4V6BIND, OPT_RECORD_TYPE, false, @@ -453,7 +450,6 @@ const int LW_V6_OPTION_DEFINITIONS_SIZE = sizeof(LW_V6_OPTION_DEFINITIONS[0]); /// @brief Rule option definitions -/// @todo: Maybe move this to a separate file, e.g. rule_option_defs.h const OptionDefParams V4V6_RULE_OPTION_DEFINITIONS[] = { OPTION_DEF_PARAMS_S46_PORTPARAMS }; @@ -463,7 +459,6 @@ const int V4V6_RULE_OPTION_DEFINITIONS_SIZE = sizeof(V4V6_RULE_OPTION_DEFINITIONS[0]); /// @brief Bind option definitions -/// @todo: Maybe move this to a separate file, e.g. bind_option_defs.h const OptionDefParams V4V6_BIND_OPTION_DEFINITIONS[] = { OPTION_DEF_PARAMS_S46_PORTPARAMS }; diff --git a/src/lib/dhcp/tests/libdhcp++_unittest.cc b/src/lib/dhcp/tests/libdhcp++_unittest.cc index 6b3f98e8e6..45889d327c 100644 --- a/src/lib/dhcp/tests/libdhcp++_unittest.cc +++ b/src/lib/dhcp/tests/libdhcp++_unittest.cc @@ -101,8 +101,8 @@ public: const std::type_info& expected_type, const std::string& encapsulates = "") { // Use V4 universe. - testStdOptionDefs(Option::V4, code, begin, end, expected_type, - encapsulates); + testStdOptionDefs(Option::V4, DHCP4_OPTION_SPACE, code, begin, end, + expected_type, encapsulates); } /// @brief Test DHCPv6 option definition. @@ -125,8 +125,33 @@ public: const std::type_info& expected_type, const std::string& encapsulates = "") { // Use V6 universe. - testStdOptionDefs(Option::V6, code, begin, end, expected_type, - encapsulates); + testStdOptionDefs(Option::V6, DHCP6_OPTION_SPACE, code, begin, + end, expected_type, encapsulates); + } + + /// @brief Test DHCPv6 option definition in a given option space. + /// + /// This function tests if option definition for an option from a + /// given option space has been initialized correctly. + /// + /// @param option_space option space. + /// @param code option code. + /// @param begin iterator pointing at beginning of a buffer to + /// be used to create option instance. + /// @param end iterator pointing at end of a buffer to be + /// used to create option instance. + /// @param expected_type type of the option created by the + /// factory function returned by the option definition. + /// @param encapsulates name of the option space being encapsulated + /// by the option. + static void testOptionDefs6(const std::string& option_space, + const uint16_t code, + const OptionBufferConstIter begin, + const OptionBufferConstIter end, + const std::type_info& expected_type, + const std::string& encapsulates = "") { + testStdOptionDefs(Option::V6, option_space, code, begin, + end, expected_type, encapsulates); } /// @brief Create a sample DHCPv4 option 43 with suboptions. @@ -216,6 +241,7 @@ private: /// This function tests if option definition for standard /// option has been initialized correctly. /// + /// @param option_space option space. /// @param code option code. /// @param begin iterator pointing at beginning of a buffer to /// be used to create option instance. @@ -225,7 +251,8 @@ private: /// factory function returned by the option definition. /// @param encapsulates name of the option space being encapsulated /// by the option. - static void testStdOptionDefs(const Option::Universe u, + static void testStdOptionDefs(const Option::Universe& u, + const std::string& option_space, const uint16_t code, const OptionBufferConstIter begin, const OptionBufferConstIter end, @@ -235,7 +262,7 @@ private: // the definition for a particular option code. // We don't have to initialize option definitions here because they // are initialized in the class's constructor. - OptionDefContainerPtr options = LibDHCP::getOptionDefs(u); + OptionDefContainerPtr options = LibDHCP::getOptionDefs(option_space); // Get the container index #1. This one allows for searching // option definitions using option code. const OptionDefContainerTypeIndex& idx = options->get<1>(); @@ -1619,6 +1646,33 @@ TEST_F(LibDhcpTest, stdOptionDefs6) { LibDhcpTest::testStdOptionDefs6(D6O_TIMESTAMP, begin, begin + 8, typeid(Option)); + + // RFC7598 options + LibDhcpTest::testOptionDefs6(MAPE_V6_OPTION_SPACE, D6O_S46_RULE, begin, end, + typeid(OptionCustom), "s46-rule-options"); + LibDhcpTest::testOptionDefs6(MAPT_V6_OPTION_SPACE, D6O_S46_RULE, begin, end, + typeid(OptionCustom), "s46-rule-options"); + LibDhcpTest::testOptionDefs6(MAPE_V6_OPTION_SPACE, D6O_S46_BR, begin, end, + typeid(OptionCustom)); + LibDhcpTest::testOptionDefs6(LW_V6_OPTION_SPACE, D6O_S46_BR, begin, end, + typeid(OptionCustom)); + LibDhcpTest::testOptionDefs6(MAPT_V6_OPTION_SPACE, D6O_S46_DMR, begin, end, + typeid(OptionCustom)); + LibDhcpTest::testOptionDefs6(LW_V6_OPTION_SPACE, D6O_S46_V4V6BIND, begin, + end, typeid(OptionCustom), + "s46-v4v6bind-options"); + LibDhcpTest::testOptionDefs6(V4V6_RULE_OPTION_SPACE, D6O_S46_PORTPARAMS, + begin, end, typeid(OptionCustom), ""); + LibDhcpTest::testStdOptionDefs6(D6O_S46_CONT_MAPE, begin, end, + typeid(OptionCustom), + "s46-cont-mape-options"); + LibDhcpTest::testStdOptionDefs6(D6O_S46_CONT_MAPT, begin, end, + typeid(OptionCustom), + "s46-cont-mapt-options"); + LibDhcpTest::testStdOptionDefs6(D6O_S46_CONT_LW, begin, end, + typeid(OptionCustom), + "s46-cont-lw-options"); + } // This test checks if the DHCPv6 option definition can be searched by -- 2.47.2