Parcourir la source

[3316] Use OptionVendorClass to encapsulate DHCPv6 option 16.

Marcin Siodelski il y a 11 ans
Parent
commit
20784067f5

+ 2 - 2
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

@@ -1759,8 +1759,8 @@ TEST_F(Dhcpv6SrvTest, cableLabsShortVendorClass) {
     Pkt6Ptr adv = srv.fake_sent_.front();
     ASSERT_TRUE(adv);
 
-    // This is sent back to relay, so port is 547
-    EXPECT_EQ(DHCP6_SERVER_PORT, adv->getRemotePort());
+    // This is sent back to client, so port is 546
+    EXPECT_EQ(DHCP6_CLIENT_PORT, adv->getRemotePort());
 
 }
 

+ 12 - 0
src/lib/dhcp/option_definition.cc

@@ -28,6 +28,7 @@
 #include <dhcp/option_space.h>
 #include <dhcp/option_string.h>
 #include <dhcp/option_vendor.h>
+#include <dhcp/option_vendor_class.h>
 #include <util/encode/hex.h>
 #include <util/strutil.h>
 #include <boost/algorithm/string/classification.hpp>
@@ -400,6 +401,14 @@ OptionDefinition::haveVendor6Format() const {
 }
 
 bool
+OptionDefinition::haveVendorClass6Format() const {
+    return (haveType(OPT_RECORD_TYPE) &&
+            (record_fields_.size() == 2) &&
+            (record_fields_[0] == OPT_UINT32_TYPE) &&
+            (record_fields_[1] == OPT_BINARY_TYPE));
+}
+
+bool
 OptionDefinition::convertToBool(const std::string& value_str) const {
     // Case insensitve check that the input is one of: "true" or "false".
     if (boost::iequals(value_str, "true")) {
@@ -653,6 +662,9 @@ OptionDefinition::factorySpecialFormatOption(Option::Universe u,
         } else if (getCode() == D6O_VENDOR_OPTS && haveVendor6Format()) {
             // Vendor-Specific Information.
             return (OptionPtr(new OptionVendor(Option::V6, begin, end)));
+        } else if (getCode() == D6O_VENDOR_CLASS && haveVendorClass6Format()) {
+            // Vendor Class.
+            return (OptionPtr(new OptionVendorClass(Option::V6, begin, end)));
         }
     } else {
         if ((getCode() == DHO_FQDN) && haveFqdn4Format()) {

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

@@ -324,6 +324,11 @@ public:
     /// Vendor-Specific Information %Option.
     bool haveVendor6Format() const;
 
+    /// @brief Check if the option has format of DHCPv6 Vendor Class option.
+    ///
+    /// @return true if option has the format of DHCPv6 Vendor Class option.
+    bool haveVendorClass6Format() const;
+
     /// @brief Option factory.
     ///
     /// This function creates an instance of DHCP option using

+ 1 - 2
src/lib/dhcp/std_option_defs.h

@@ -230,8 +230,7 @@ RECORD_DECL(REMOTE_ID_RECORDS, OPT_UINT32_TYPE, OPT_BINARY_TYPE);
 // status-code
 RECORD_DECL(STATUS_CODE_RECORDS, OPT_UINT16_TYPE, OPT_STRING_TYPE);
 // vendor-class
-RECORD_DECL(VENDOR_CLASS_RECORDS, OPT_UINT32_TYPE, OPT_UINT16_TYPE,
-            OPT_STRING_TYPE);
+RECORD_DECL(VENDOR_CLASS_RECORDS, OPT_UINT32_TYPE, OPT_BINARY_TYPE);
 
 /// Standard DHCPv6 option definitions.
 ///

+ 19 - 13
src/lib/dhcp/tests/libdhcp++_unittest.cc

@@ -29,6 +29,7 @@
 #include <dhcp/option_int_array.h>
 #include <dhcp/option_string.h>
 #include <dhcp/option_vendor.h>
+#include <dhcp/option_vendor_class.h>
 #include <util/buffer.h>
 #include <util/encode/hex.h>
 
@@ -981,6 +982,14 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
     client_fqdn_buf.insert(client_fqdn_buf.end(), fqdn_buf.begin(),
                            fqdn_buf.end());
 
+    // Initialize test buffer for Vendor Class option.
+    const char vclass_data[] = {
+        0x00, 0x01, 0x02, 0x03,
+        0x00, 0x01, 0x02
+    };
+    std::vector<uint8_t> vclass_buf(vclass_data,
+                                    vclass_data + sizeof(vclass_data));;
+
     // The actual test starts here for all supported option codes.
     LibDhcpTest::testStdOptionDefs6(D6O_CLIENTID, begin, end,
                                     typeid(Option));
@@ -1018,8 +1027,9 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
     LibDhcpTest::testStdOptionDefs6(D6O_USER_CLASS, begin, end,
                                     typeid(Option));
 
-    LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_CLASS, begin, end,
-                                    typeid(OptionCustom));
+    LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_CLASS, vclass_buf.begin(),
+                                    vclass_buf.end(),
+                                    typeid(OptionVendorClass));
 
     LibDhcpTest::testStdOptionDefs6(D6O_VENDOR_OPTS, begin, end,
                                     typeid(OptionVendor),
@@ -1148,22 +1158,18 @@ TEST_F(LibDhcpTest, vendorClass6) {
     // Option vendor-class should be there
     ASSERT_FALSE(options.find(D6O_VENDOR_CLASS) == options.end());
 
-    // It should be of type OptionCustom
-    boost::shared_ptr<OptionCustom> vclass =
-        boost::dynamic_pointer_cast<OptionCustom> (options.begin()->second);
+    // It should be of type OptionVendorClass
+    boost::shared_ptr<OptionVendorClass> vclass =
+        boost::dynamic_pointer_cast<OptionVendorClass>(options.begin()->second);
     ASSERT_TRUE(vclass);
 
     // Let's investigate if the option content is correct
 
     // 3 fields expected: vendor-id, data-len and data
-    ASSERT_EQ(3, vclass->getDataFieldsNum());
-
-    EXPECT_EQ(4491, vclass->readInteger<uint32_t>
-              (VENDOR_CLASS_ENTERPRISE_ID_INDEX)); // vendor-id=4491
-    EXPECT_EQ(10, vclass->readInteger<uint16_t>
-              (VENDOR_CLASS_DATA_LEN_INDEX)); // data len = 10
-    EXPECT_EQ("eRouter1.0", vclass->readString
-              (VENDOR_CLASS_STRING_INDEX)); // data="eRouter1.0"
+    EXPECT_EQ(4491, vclass->getVendorId());
+    EXPECT_EQ(20, vclass->len());
+    ASSERT_EQ(1, vclass->getTuplesNum());
+    EXPECT_EQ("eRouter1.0", vclass->getTuple(0).getText());
 }
 
 } // end of anonymous space