]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[github24] It is now possible to specify excluded prefix for a pool.
authorMarcin Siodelski <marcin@isc.org>
Tue, 27 Sep 2016 17:43:42 +0000 (19:43 +0200)
committerMarcin Siodelski <marcin@isc.org>
Tue, 27 Sep 2016 17:43:42 +0000 (19:43 +0200)
This is to facilitate the use of Prefix Exclude option (RFC 6603).

src/bin/dhcp6/dhcp6.spec
src/bin/dhcp6/json_config_parser.cc
src/bin/dhcp6/tests/config_parser_unittest.cc

index 3571b8e2ac35a2d04cb418200258277970ab6d48..6c0b169b93fe5ed0dea8e909403c0e8f19859db5 100644 (file)
                            "item_type": "integer",
                            "item_optional": false,
                            "item_default": 128
+                       },
+                       {
+                          "item_name": "excluded-prefix",
+                          "item_type": "string",
+                          "item_optional": true,
+                          "item_default": ""
+                       },
+                       {
+                           "item_name": "excluded-prefix-len",
+                           "item_type": "integer",
+                           "item_optional": true,
+                           "item_default": 128
                        }]
                     }
                 },
index 4cf6bb6204abc5a147a71e1a6d19e1054a264128..99f8bed7f45340b0e1065a6686c067c99d8c1dd6 100644 (file)
@@ -172,11 +172,12 @@ public:
         BOOST_FOREACH(ConfigPair param, pd_pool_->mapValue()) {
             std::string entry(param.first);
             ParserPtr parser;
-            if (entry == "prefix") {
+            if (entry == "prefix" || entry =="excluded-prefix") {
                 StringParserPtr str_parser(new StringParser(entry,
                                                             string_values_));
                 parser = str_parser;
-            } else if (entry == "prefix-len" || entry == "delegated-len") {
+            } else if (entry == "prefix-len" || entry == "delegated-len" ||
+                       entry == "excluded-prefix-len") {
                 Uint32ParserPtr code_parser(new Uint32Parser(entry,
                                                              uint32_values_));
                 parser = code_parser;
@@ -192,13 +193,18 @@ public:
         // Try to obtain the pool parameters. It will throw an exception if any
         // of the required parameters are not present or invalid.
         try {
-            std::string addr_str = string_values_->getParam("prefix");
-            uint32_t prefix_len = uint32_values_->getParam("prefix-len");
-            uint32_t delegated_len = uint32_values_->getParam("delegated-len");
+            const std::string addr_str = string_values_->getParam("prefix");
+            const uint32_t prefix_len = uint32_values_->getParam("prefix-len");
+            const uint32_t delegated_len = uint32_values_->getParam("delegated-len");
+            const std::string excluded_prefix_str =
+                string_values_->getOptionalParam("excluded-prefix", "::");
+            const uint32_t excluded_prefix_len =
+                uint32_values_->getOptionalParam("excluded-prefix-len", 0);
 
             // Attempt to construct the local pool.
-            pool_.reset(new Pool6(Lease::TYPE_PD, IOAddress(addr_str),
-                                  prefix_len, delegated_len));
+            pool_.reset(new Pool6(IOAddress(addr_str), prefix_len,
+                                  delegated_len, IOAddress(excluded_prefix_str),
+                                  excluded_prefix_len));
         } catch (const std::exception& ex) {
             // Some parameters don't exist or are invalid. Since we are not
             // aware whether they don't exist or are invalid, let's append
@@ -621,7 +627,8 @@ public:
                 }
 
                 if (!code) {
-                    OptionDefinitionPtr def = LibDHCP::getOptionDef(Option::V6, option_str);
+                    const OptionDefinitionPtr def = LibDHCP::getOptionDef(Option::V6,
+                                                                          option_str);
                     if (def) {
                         code = def->getCode();
                     } else {
index cdee579cc1b28a34d08e89f81e63505c76d1ae26..92b2ee0bd6313f555f0a06ae91e151730b30a86b 100644 (file)
@@ -1378,6 +1378,60 @@ TEST_F(Dhcp6ParserTest, pdPoolBasics) {
     EXPECT_EQ(lastAddrInPrefix(prefixAddress, 64), p6->getLastAddress());
 }
 
+// This test verifies that it is possible to specify a prefix pool with an
+// excluded prefix (see RFC6603).
+TEST_F(Dhcp6ParserTest, pdPoolPrefixExclude) {
+
+    ConstElementPtr x;
+
+    // Define a single valid pd pool.
+    string config =
+        "{ " + genIfaceConfig() + ","
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"subnet\": \"2001:db8:1::/64\","
+        "    \"pd-pools\": ["
+        "        { \"prefix\": \"3000::\", "
+        "          \"prefix-len\": 48, "
+        "          \"delegated-len\": 64,"
+        "          \"excluded-prefix\": \"3000:1::\","
+        "          \"excluded-prefix-len\": 72"
+        "        } ],"
+        "\"valid-lifetime\": 4000 }"
+        "] }";
+
+    // Convert the JSON string into Elements.
+    ElementPtr json;
+    ASSERT_NO_THROW(json = Element::fromJSON(config));
+
+    // Verify that DHCP6 configuration processing succeeds.
+    // Returned value must be non-empty ConstElementPtr to config result.
+    // rcode should be 0 which indicates successful configuration processing.
+    EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
+    checkResult(x, 0);
+
+    // Test that we can retrieve the subnet.
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
+        selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    ASSERT_TRUE(subnet);
+
+    // Fetch the collection of PD pools.  It should have 1 entry.
+    PoolCollection pc;
+    ASSERT_NO_THROW(pc = subnet->getPools(Lease::TYPE_PD));
+    EXPECT_EQ(1, pc.size());
+
+    // Get a pointer to the pd pool instance, and verify its contents.
+    Pool6Ptr p6;
+    ASSERT_NO_THROW(p6 = boost::dynamic_pointer_cast<Pool6>(pc[0]));
+    ASSERT_TRUE(p6);
+    EXPECT_EQ("3000::", p6->getFirstAddress().toText());
+    EXPECT_EQ(64, p6->getLength());
+    EXPECT_EQ("3000:1::", p6->getExcludedPrefix().toText());
+    EXPECT_EQ(72, static_cast<unsigned>(p6->getExcludedPrefixLength()));
+}
+
 // Goal of this test is verify that a list of PD pools can be configured.
 // It also verifies that a subnet may be configured with both regular pools
 // and pd pools.