Browse Source

[3070] Parse rapid-commit parameter for subnet6.

Marcin Siodelski 10 years ago
parent
commit
87d22f85c3

+ 6 - 0
src/bin/dhcp6/dhcp6.spec

@@ -245,6 +245,12 @@
                   "item_default": ""
                   "item_default": ""
                 },
                 },
 
 
+                { "item_name": "rapid-commit",
+                  "item_type": "boolean",
+                  "item_optional": false,
+                  "item_default": false
+                },
+
                 { "item_name": "renew-timer",
                 { "item_name": "renew-timer",
                   "item_type": "integer",
                   "item_type": "integer",
                   "item_optional": false,
                   "item_optional": false,

+ 14 - 5
src/bin/dhcp6/json_config_parser.cc

@@ -404,6 +404,8 @@ protected:
             parser = new PdPoolListParser(config_id, pools_);
             parser = new PdPoolListParser(config_id, pools_);
         } else if (config_id.compare("option-data") == 0) {
         } else if (config_id.compare("option-data") == 0) {
             parser = new OptionDataListParser(config_id, options_, AF_INET6);
             parser = new OptionDataListParser(config_id, options_, AF_INET6);
+        } else if (config_id.compare("rapid-commit") == 0) {
+            parser = new BooleanParser(config_id, boolean_values_);
         } else {
         } else {
             isc_throw(NotImplemented, "unsupported parameter: " << config_id);
             isc_throw(NotImplemented, "unsupported parameter: " << config_id);
         }
         }
@@ -473,12 +475,16 @@ protected:
             }
             }
         }
         }
 
 
-        stringstream tmp;
-        tmp << addr << "/" << static_cast<int>(len)
-            << " with params t1=" << t1 << ", t2=" << t2 << ", pref="
-            << pref << ", valid=" << valid;
+        bool rapid_commit = boolean_values_->getOptionalParam("rapid-commit", false);
 
 
-        LOG_INFO(dhcp6_logger, DHCP6_CONFIG_NEW_SUBNET).arg(tmp.str());
+        std::ostringstream output;
+        output << addr << "/" << static_cast<int>(len)
+               << " with params t1=" << t1 << ", t2="
+               << t2 << ", preferred-lifetime=" << pref
+               << ", valid-lifetime=" << valid
+               << ", rapid-commit is " << (rapid_commit ? "enabled" : "disabled");
+
+        LOG_INFO(dhcp6_logger, DHCP6_CONFIG_NEW_SUBNET).arg(output.str());
 
 
         // Create a new subnet.
         // Create a new subnet.
         Subnet6* subnet6 = new Subnet6(addr, len, t1, t2, pref, valid,
         Subnet6* subnet6 = new Subnet6(addr, len, t1, t2, pref, valid,
@@ -491,6 +497,9 @@ protected:
             subnet6->setInterfaceId(opt);
             subnet6->setInterfaceId(opt);
         }
         }
 
 
+        // Enable or disable Rapid Commit option support for the subnet.
+        subnet6->setRapidCommit(rapid_commit);
+
         // Try setting up client class (if specified)
         // Try setting up client class (if specified)
         try {
         try {
             string client_class = string_values_->getParam("client-class");
             string client_class = string_values_->getParam("client-class");

+ 80 - 0
src/bin/dhcp6/tests/config_parser_unittest.cc

@@ -495,6 +495,38 @@ public:
         CfgMgr::instance().clear();
         CfgMgr::instance().clear();
     }
     }
 
 
+    /// @brief Tests teh Rapid Commit configuration for a subnet.
+    ///
+    /// This test configures the server with a given configuration and
+    /// verifies if the Rapid Commit has been configured successfully
+    /// for a subnet.
+    ///
+    /// @param config Server configuration, possibly including the
+    /// 'rapid-commit' parameter.
+    /// @param exp_rapid_commit Expected value of the Rapid Commit flag
+    /// within a subnet.
+    void testRapidCommit(const std::string& config,
+                         const bool exp_rapid_commit) {
+        // Clear any existing configuration.
+        CfgMgr::instance().clear();
+
+        // Configure the server.
+        ElementPtr json = Element::fromJSON(config);
+
+        // Make sure that the configuration was successful.
+        ConstElementPtr status;
+        EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
+        checkResult(status, 0);
+
+        // Get the subnet.
+        Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
+            selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+        ASSERT_TRUE(subnet);
+
+        // Check the Rapid Commit flag for the subnet.
+        EXPECT_EQ(exp_rapid_commit, subnet->getRapidCommit());
+    }
+
     int rcode_;          ///< Return code (see @ref isc::config::parseAnswer)
     int rcode_;          ///< Return code (see @ref isc::config::parseAnswer)
     Dhcpv6Srv srv_;      ///< Instance of the Dhcp6Srv used during tests
     Dhcpv6Srv srv_;      ///< Instance of the Dhcp6Srv used during tests
     ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer)
     ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer)
@@ -1088,6 +1120,54 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceAndInterfaceId) {
     EXPECT_TRUE(errorContainsPosition(status, "<string>"));
     EXPECT_TRUE(errorContainsPosition(status, "<string>"));
 }
 }
 
 
+// This test checks the configuration of the Rapid Commit option
+// support for the subnet.
+TEST_F(Dhcp6ParserTest, subnetRapidCommit) {
+    {
+        // rapid-commit implicitly set to false.
+        SCOPED_TRACE("Default Rapid Commit setting");
+        testRapidCommit("{ \"preferred-lifetime\": 3000,"
+                        "\"rebind-timer\": 2000, "
+                        "\"renew-timer\": 1000, "
+                        "\"subnet6\": [ { "
+                        "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - "
+                        "2001:db8:1::ffff\" } ],"
+                        "    \"subnet\": \"2001:db8:1::/64\" } ],"
+                        "\"valid-lifetime\": 4000 }",
+                        false);
+    }
+
+    {
+        SCOPED_TRACE("Enable Rapid Commit");
+        // rapid-commit explicitly set to true.
+        testRapidCommit("{ \"preferred-lifetime\": 3000,"
+                        "\"rebind-timer\": 2000, "
+                        "\"renew-timer\": 1000, "
+                        "\"subnet6\": [ { "
+                        "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - "
+                        "2001:db8:1::ffff\" } ],"
+                        "    \"rapid-commit\": True,"
+                        "    \"subnet\": \"2001:db8:1::/64\" } ],"
+                        "\"valid-lifetime\": 4000 }",
+                        true);
+    }
+
+    {
+        SCOPED_TRACE("Disable Rapid Commit");
+        // rapid-commit explicitly set to false.
+        testRapidCommit("{ \"preferred-lifetime\": 3000,"
+                        "\"rebind-timer\": 2000, "
+                        "\"renew-timer\": 1000, "
+                        "\"subnet6\": [ { "
+                        "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - "
+                        "2001:db8:1::ffff\" } ],"
+                        "    \"rapid-commit\": False,"
+                        "    \"subnet\": \"2001:db8:1::/64\" } ],"
+                        "\"valid-lifetime\": 4000 }",
+                        false);
+    }
+}
+
 // This test checks that multiple pools can be defined and handled properly.
 // This test checks that multiple pools can be defined and handled properly.
 // The test defines 2 subnets, each with 2 pools.
 // The test defines 2 subnets, each with 2 pools.
 TEST_F(Dhcp6ParserTest, multiplePools) {
 TEST_F(Dhcp6ParserTest, multiplePools) {

+ 3 - 4
src/lib/dhcpsrv/parsers/dhcp_parsers.cc

@@ -1030,10 +1030,9 @@ PoolParser::commit() {
 SubnetConfigParser::SubnetConfigParser(const std::string&,
 SubnetConfigParser::SubnetConfigParser(const std::string&,
                                        ParserContextPtr global_context,
                                        ParserContextPtr global_context,
                                        const isc::asiolink::IOAddress& default_addr)
                                        const isc::asiolink::IOAddress& default_addr)
-    : uint32_values_(new Uint32Storage()),
-      string_values_(new StringStorage()),
-      boolean_values_(new BooleanStorage()),
-      pools_(new PoolStorage()), global_context_(global_context),
+    : boolean_values_(new BooleanStorage()), uint32_values_(new Uint32Storage()),
+      string_values_(new StringStorage()), pools_(new PoolStorage()),
+      global_context_(global_context),
       relay_info_(new isc::dhcp::Subnet::RelayInfo(default_addr)),
       relay_info_(new isc::dhcp::Subnet::RelayInfo(default_addr)),
       options_(new CfgOption()) {
       options_(new CfgOption()) {
     // The first parameter should always be "subnet", but we don't check
     // The first parameter should always be "subnet", but we don't check

+ 3 - 0
src/lib/dhcpsrv/parsers/dhcp_parsers.h

@@ -1057,6 +1057,9 @@ private:
 
 
 protected:
 protected:
 
 
+    /// Storage for subnet-specific boolean values.
+    BooleanStoragePtr boolean_values_;
+
     /// Storage for subnet-specific integer values.
     /// Storage for subnet-specific integer values.
     Uint32StoragePtr uint32_values_;
     Uint32StoragePtr uint32_values_;