From: Marcin Siodelski Date: Tue, 26 Jul 2016 16:36:11 +0000 (+0200) Subject: [github24] Ported PD exclude option code from 'andreipavelQ/master' X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18649746b52c7e3290db352c6eb3a626d37d1af9;p=thirdparty%2Fkea.git [github24] Ported PD exclude option code from 'andreipavelQ/master' --- diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am index ccdb74b2ab..c4edf45193 100644 --- a/src/lib/dhcp/Makefile.am +++ b/src/lib/dhcp/Makefile.am @@ -25,6 +25,7 @@ libkea_dhcp___la_SOURCES += option4_client_fqdn.cc option4_client_fqdn.h libkea_dhcp___la_SOURCES += option6_ia.cc option6_ia.h libkea_dhcp___la_SOURCES += option6_iaaddr.cc option6_iaaddr.h libkea_dhcp___la_SOURCES += option6_iaprefix.cc option6_iaprefix.h +libkea_dhcp___la_SOURCES += option6_pdexclude.cc option6_pdexclude.h libkea_dhcp___la_SOURCES += option6_addrlst.cc option6_addrlst.h libkea_dhcp___la_SOURCES += option6_client_fqdn.cc option6_client_fqdn.h libkea_dhcp___la_SOURCES += option6_status_code.cc option6_status_code.h diff --git a/src/lib/dhcp/dhcp6.h b/src/lib/dhcp/dhcp6.h index 12fc18baaa..d5775ef19b 100644 --- a/src/lib/dhcp/dhcp6.h +++ b/src/lib/dhcp/dhcp6.h @@ -79,10 +79,10 @@ #define D6O_CLIENT_ARCH_TYPE 61 /* RFC5970 */ #define D6O_NII 62 /* RFC5970 */ //#define D6O_GEOLOCATION 63 /* RFC6225 */ -//#define D6O_AFTR_NAME 64 /* RFC6334 */ +#define D6O_AFTR_NAME 64 /* RFC6334 */ #define D6O_ERP_LOCAL_DOMAIN_NAME 65 /* RFC6440 */ #define D6O_RSOO 66 /* RFC6422 */ -//#define D6O_PD_EXCLUDE 67 /* RFC6603 */ +#define D6O_PD_EXCLUDE 67 /* RFC6603 */ //#define D6O_VSS 68 /* RFC6607 */ //#define D6O_MIP6_IDINF 69 /* RFC6610 */ //#define D6O_MIP6_UDINF 70 /* RFC6610 */ @@ -104,14 +104,14 @@ //#define D6O_V6_PCP_SERVER 86 /* RFC7291 */ #define D6O_DHCPV4_MSG 87 /* RFC7341 */ #define D6O_DHCPV4_O_DHCPV6_SERVER 88 /* RFC7341 */ -//#define D6O_S46_RULE 89 /* RFC7598 */ -//#define D6O_S46_BR 90 /* RFC7598 */ -//#define D6O_S46_DMR 91 /* RFC7598 */ -//#define D6O_S46_V4V6BIND 92 /* RFC7598 */ -//#define D6O_S46_PORTPARAMS 93 /* RFC7598 */ -//#define D6O_S46_CONT_MAPE 94 /* RFC7598 */ -//#define D6O_S46_CONT_MAPT 95 /* RFC7598 */ -//#define D6O_S46_CONT_LW 96 /* RFC7598 */ +#define D6O_S46_RULE 89 /* RFC7598 */ +#define D6O_S46_BR 90 /* RFC7598 */ +#define D6O_S46_DMR 91 /* RFC7598 */ +#define D6O_S46_V4V6BIND 92 /* RFC7598 */ +#define D6O_S46_PORTPARAMS 93 /* RFC7598 */ +#define D6O_S46_CONT_MAPE 94 /* RFC7598 */ +#define D6O_S46_CONT_MAPT 95 /* RFC7598 */ +#define D6O_S46_CONT_LW 96 /* RFC7598 */ //#define D6O_4RD 97 /* RFC7600 */ //#define D6O_4RD_MAP_RULE 98 /* RFC7600 */ //#define D6O_4RD_NON_MAP_RULE 99 /* RFC7600 */ diff --git a/src/lib/dhcp/option6_ia.cc b/src/lib/dhcp/option6_ia.cc index 44fa22178e..1000efd72b 100644 --- a/src/lib/dhcp/option6_ia.cc +++ b/src/lib/dhcp/option6_ia.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/src/lib/dhcp/option6_iaaddr.cc b/src/lib/dhcp/option6_iaaddr.cc index 627ed52da5..33affd8bdd 100644 --- a/src/lib/dhcp/option6_iaaddr.cc +++ b/src/lib/dhcp/option6_iaaddr.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/src/lib/dhcp/option6_iaprefix.cc b/src/lib/dhcp/option6_iaprefix.cc index 0549c76987..4bfa672f9b 100644 --- a/src/lib/dhcp/option6_iaprefix.cc +++ b/src/lib/dhcp/option6_iaprefix.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/src/lib/dhcp/option6_pdexclude.cc b/src/lib/dhcp/option6_pdexclude.cc new file mode 100644 index 0000000000..6e90e8e4c0 --- /dev/null +++ b/src/lib/dhcp/option6_pdexclude.cc @@ -0,0 +1,95 @@ +// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +// +// Author: Cristian Secareanu +// +// 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 +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +using namespace std; +using namespace isc; +using namespace isc::dhcp; +using namespace isc::asiolink; +using namespace isc::util; + +namespace isc { +namespace dhcp { + +Option6PDExclude::Option6PDExclude( + const isc::asiolink::IOAddress& delegated_address, + uint8_t delegated_prefix_length, + const isc::asiolink::IOAddress& excluded_address, + uint8_t excluded_prefix_length) : + Option(V6, D6O_PD_EXCLUDE), delegated_address_(delegated_address), + delegated_prefix_length_(delegated_prefix_length), + excluded_address_(excluded_address), + excluded_prefix_length_(excluded_prefix_length) { +} + +void Option6PDExclude::pack(isc::util::OutputBuffer& buf) const { + // Header = option code and length. + packHeader(buf); + + buf.writeData(&excluded_prefix_length_, sizeof(excluded_prefix_length_)); + + std::vector excluded_address_bytes = excluded_address_.toBytes(); + boost::dynamic_bitset bits(excluded_address_bytes.rbegin(), excluded_address_bytes.rend()); + bits = bits << delegated_prefix_length_; + + const uint8_t subtractedPrefixesOctetLength = getSubtractedPrefixesOctetLength(); + for (uint8_t i = 0U; i < subtractedPrefixesOctetLength; i++) { + const boost::dynamic_bitset tmp = bits >> 120; + + uint8_t val = static_cast(tmp.to_ulong()); + + //Zero padded bits follow when excluded_prefix_length_ is not divided exactly by 8 + if (i == subtractedPrefixesOctetLength - 1U) { + uint8_t subtractedPrefixesBitLength = excluded_prefix_length_ - + delegated_prefix_length_; + uint8_t zeroPaddingBitLength = (8 - (subtractedPrefixesBitLength % 8)) % 8; + val <<= zeroPaddingBitLength; + } + bits = bits << 8; + buf.writeData(&val, sizeof(val)); + } +} + +void Option6PDExclude::unpack(OptionBufferConstIter begin, + OptionBufferConstIter end) { + delegated_prefix_length_ = 0; + excluded_prefix_length_ = *begin; + begin += sizeof(uint8_t); + delegated_address_ = IOAddress::IPV6_ZERO_ADDRESS(); + excluded_address_ = IOAddress::IPV6_ZERO_ADDRESS(); + begin = end; +} + +uint16_t Option6PDExclude::len() const { + return getHeaderLen() + sizeof(excluded_prefix_length_) + + getSubtractedPrefixesOctetLength(); +} + +uint8_t Option6PDExclude::getSubtractedPrefixesOctetLength() const { + // Promote what is less than 8 bits to 1 octet. + uint8_t subtractedPrefixesBitLength = excluded_prefix_length_ + - delegated_prefix_length_ - 1; + uint8_t subtractedPrefixesOctetLength = (subtractedPrefixesBitLength / 8) + 1; + return subtractedPrefixesOctetLength; +} + +} // end of namespace isc::dhcp +} // end of namespace isc diff --git a/src/lib/dhcp/option6_pdexclude.h b/src/lib/dhcp/option6_pdexclude.h new file mode 100644 index 0000000000..b83a9450e7 --- /dev/null +++ b/src/lib/dhcp/option6_pdexclude.h @@ -0,0 +1,111 @@ +// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +// +// Author: Cristian Secareanu +// +// 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 +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef OPTION6_PDEXCLUDE_H +#define OPTION6_PDEXCLUDE_H + +#include + +#include +#include + +namespace isc { +namespace dhcp { + +/// @brief DHCPv6 Option class for handling list of IPv6 addresses. +/// +/// This class handles a list of IPv6 addresses. An example of such option +/// is dns-servers option. It can also be used to handle single address. +class Option6PDExclude: public Option { + +public: + + Option6PDExclude(const isc::asiolink::IOAddress& delegated_address, + uint8_t delegated_prefix_length, + const isc::asiolink::IOAddress& excluded_address, + uint8_t excluded_prefix_length); + + /// @brief Writes option in wire-format to a buffer. + /// + /// Writes option in wire-format to buffer, returns pointer to first unused + /// byte after stored option (that is useful for writing options one after + /// another). + /// + /// @param buf pointer to a buffer + /// + /// @throw BadValue Universe of the option is neither V4 nor V6. + virtual void pack(isc::util::OutputBuffer& buf) const; + + /// @brief Parses received buffer. + /// + /// @param begin iterator to first byte of option data + /// @param end iterator to end of option data (first byte after option end) + virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end); + + /// @brief Returns length of the complete option (data length + DHCPv6 + /// option header) + /// + /// @return length of the option + virtual uint16_t len() const; + + /// @brief Returns the address of the delegated address space. + /// + /// @return address of delegated address space + isc::asiolink::IOAddress getDelegatedAddress() const { + return delegated_address_; + } + + /// @brief Returns the prefix length of the delegated address space. + /// + /// @return prefix length of delegated address space + uint8_t getDelegatedPrefixLength() const { + return delegated_prefix_length_; + } + + /// @brief Returns the address of the excluded address space. + /// + /// @return address of excluded address space + isc::asiolink::IOAddress getExcludedAddress() const { + return excluded_address_; + } + + /// @brief Returns the prefix length of the excluded address space. + /// + /// @return prefix length of excluded address space + uint8_t getExcludedPrefixLength() const { + return excluded_prefix_length_; + } + +protected: + /// @brief Returns the prefix length of the excluded prefix. + /// + /// @return prefix length of excluded prefix + uint8_t getSubtractedPrefixesOctetLength() const; + + /// @brief The address and prefix length identifying the delegated IPV6 + /// prefix. + /// { + isc::asiolink::IOAddress delegated_address_; + uint8_t delegated_prefix_length_; + /// } + + /// @brief The address and prefix length identifying the excluded IPV6 + /// prefix. + /// { + isc::asiolink::IOAddress excluded_address_; + uint8_t excluded_prefix_length_; + /// } +}; + +/// @brief Pointer to the @c Option6PDExclude object. +typedef boost::shared_ptr Option6PDExcludePtr; + +} // isc::dhcp namespace +} // isc namespace + +#endif // OPTION6_PDEXCLUDE_H diff --git a/src/lib/dhcp/option_int.h b/src/lib/dhcp/option_int.h index 329bf11922..05224307f1 100644 --- a/src/lib/dhcp/option_int.h +++ b/src/lib/dhcp/option_int.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/src/lib/dhcp/option_space.h b/src/lib/dhcp/option_space.h index c1867d930d..6fe92e48f3 100644 --- a/src/lib/dhcp/option_space.h +++ b/src/lib/dhcp/option_space.h @@ -13,8 +13,16 @@ #include #include -#define DHCP4_OPTION_SPACE "dhcp4" -#define DHCP6_OPTION_SPACE "dhcp6" +#define DHCP4_OPTION_SPACE "dhcp4" +#define DHCP6_OPTION_SPACE "dhcp6" +#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" namespace isc { namespace dhcp { @@ -174,7 +182,7 @@ public: void setVendorSpace(const uint32_t enterprise_number); private: - + uint32_t enterprise_number_; ///< IANA assigned enterprise number. }; diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc index 25afd44469..bb6c9723ec 100644 --- a/src/lib/dhcp/pkt6.cc +++ b/src/lib/dhcp/pkt6.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/src/lib/dhcp/tests/Makefile.am b/src/lib/dhcp/tests/Makefile.am index caf369ac81..8993829733 100644 --- a/src/lib/dhcp/tests/Makefile.am +++ b/src/lib/dhcp/tests/Makefile.am @@ -54,6 +54,7 @@ libdhcp___unittests_SOURCES += option6_client_fqdn_unittest.cc libdhcp___unittests_SOURCES += option6_ia_unittest.cc libdhcp___unittests_SOURCES += option6_iaaddr_unittest.cc libdhcp___unittests_SOURCES += option6_iaprefix_unittest.cc +libdhcp___unittests_SOURCES += option6_pdexclude_unittest.cc libdhcp___unittests_SOURCES += option6_status_code_unittest.cc libdhcp___unittests_SOURCES += option_int_unittest.cc libdhcp___unittests_SOURCES += option_int_array_unittest.cc diff --git a/src/lib/dhcp/tests/option6_pdexclude_unittest.cc b/src/lib/dhcp/tests/option6_pdexclude_unittest.cc new file mode 100644 index 0000000000..5203cbed10 --- /dev/null +++ b/src/lib/dhcp/tests/option6_pdexclude_unittest.cc @@ -0,0 +1,77 @@ +// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +// +// Author: Andrei Pavel +// +// 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 +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include +#include +#include +#include + +using namespace isc; +using namespace isc::dhcp; +using namespace asiolink; + +namespace { + +const IOAddress empty("::"); +const IOAddress beef("2001:db8:dead:beef::"); // /48 prefix length +const IOAddress cafe("2001:db8:dead:cafe::"); // /48 prefix length +const IOAddress beef01("2001:db8:dead:beef::01"); // /56 prefix length + +// Description +TEST(Option6PDExcludeTest, constructor) { + Option6PDExclude option = Option6PDExclude(beef, 56, beef01, 60); + + EXPECT_EQ(option.getDelegatedAddress(), beef); + EXPECT_EQ(option.getDelegatedPrefixLength(), 56); + EXPECT_EQ(option.getExcludedAddress(), beef01); + EXPECT_EQ(option.getExcludedPrefixLength(), 60); + EXPECT_EQ(option.len(), Option::OPTION6_HDR_LEN + + /* excluded_prefix_length_ AKA prefix-len is 1B */ 1 + + /* [delegated_prefix_length_ - excluded_prefix_length_](bytes) */ 1); +} + +TEST(Option6PDExcludeTest, packing_and_unpacking) { + EXPECT_NO_THROW(isc_throw(Exception, "Not implemented yet.")); + + /* + OptionBuffer data(option.getData()); + + util::OutputBuffer buf(128); + option.pack(buf); + + Option6PDExclude unpackedOption(empty, 0, empty, 0); + + unpackedOption.unpack(data.begin(), data.end()); + + EXPECT_EQ(option.getDelegatedAddress(), + unpackedOption.getDelegatedAddress()); + EXPECT_EQ(option.getDelegatedPrefixLength(), + unpackedOption.getDelegatedPrefixLength()); + EXPECT_EQ(option.getExcludedAddress(), unpackedOption.getExcludedAddress()); + EXPECT_EQ(option.getExcludedPrefixLength(), + unpackedOption.getExcludedPrefixLength()); + //*/ +} + +TEST(Option6PDExcludeTest, pool) { + EXPECT_NO_THROW(isc_throw(Exception, "Not implemented yet.")); + + /* + Pool6Ptr pool6Ptr = Pool6Ptr(new Pool6(Lease::TYPE_PD, beef, cafe)); + ASSERT_TRUE(pool6Ptr); + ASSERT_GT(pool6Ptr->getPrefixExcludedLength(), 0); + OptionPtr opt( + new Option6PDExclude((*l)->addr_, (*l)->prefixlen_, + pool->getPrefixExcluded(), + pool->getPrefixExcludedLength())); + //*/ +} + +} // anonymous namespace diff --git a/src/lib/dhcp/tests/option_unittest.cc b/src/lib/dhcp/tests/option_unittest.cc index ef031fd7aa..416589d715 100644 --- a/src/lib/dhcp/tests/option_unittest.cc +++ b/src/lib/dhcp/tests/option_unittest.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include