]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5351] Doing shared-networks
authorFrancis Dupont <fdupont@isc.org>
Tue, 28 Nov 2017 15:46:26 +0000 (16:46 +0100)
committerFrancis Dupont <fdupont@isc.org>
Tue, 28 Nov 2017 15:46:26 +0000 (16:46 +0100)
src/bin/dhcp4/dhcp4_parser.yy
src/bin/dhcp6/dhcp6_parser.yy
src/lib/dhcpsrv/network.cc
src/lib/dhcpsrv/network.h
src/lib/dhcpsrv/parsers/shared_network_parser.cc
src/lib/dhcpsrv/subnet.h
src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc
src/lib/dhcpsrv/tests/shared_network_unittest.cc
src/lib/dhcpsrv/tests/shared_networks_list_parser_unittest.cc

index 5635af158f683661ae6686271ee869bec744e97b..cd174dc4d9c86b4e1d5b8c6b553fae0529f08f51 100644 (file)
@@ -1051,6 +1051,8 @@ shared_network_param: name
                     | reservation_mode
                     | client_class
                     | valid_lifetime
+                    | user_context
+                    | comment
                     | unknown_map_entry
                     ;
 
index 8c3c78957ecb12555f691ef48a0a081d90cfa7f3..2cec6de1ceb7320ca1d919a555b8540fe74e7c9d 100644 (file)
@@ -1015,6 +1015,8 @@ shared_network_param: name
                     | preferred_lifetime
                     | rapid_commit
                     | valid_lifetime
+                    | user_context
+                    | comment
                     | unknown_map_entry
                     ;
 
index 46b7aabb4177e851408147c208f899dfe41263fd..c6c0ec7c15eac7b3d74d404d114946fd115eedaa 100644 (file)
@@ -47,6 +47,9 @@ ElementPtr
 Network::toElement() const {
     ElementPtr map = Element::createMap();
 
+    // Set user-context
+    contextToElement(map);
+
     // Set interface
     const std::string& iface = getIface();
     if (!iface.empty()) {
index 3909441a64df76471da8f6950a6bcf23b4ccb1d5..bd211ae1f60018851b58352b029160fdbe473d4b 100644 (file)
@@ -15,6 +15,7 @@
 #include <dhcpsrv/cfg_option.h>
 #include <dhcpsrv/cfg_4o6.h>
 #include <dhcpsrv/triplet.h>
+#include <dhcpsrv/user_context.h>
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 #include <cstdint>
@@ -41,7 +42,7 @@ namespace dhcp {
 /// class provides an abstract interface that must be implemented by derived
 /// classes and, where appropriate, implements common methods used by the
 /// derived classes.
-class Network : public data::CfgToElement {
+class Network : public virtual UserContext, public data::CfgToElement {
 public:
 
     /// @brief Holds optional information about relay.
index 8a3cb14b31893c8687f29ac5a8d33a31d10a6e72..ec6bdbbdfcec1a8da135340c2a6f04a74c93abae 100644 (file)
@@ -70,9 +70,14 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) {
             }
         }
 
+        ConstElementPtr user_context = shared_network_data->get("user-context");
+        if (user_context) {
+            shared_network->setContext(user_context);
+        }
+
     } catch (const DhcpConfigError&) {
-       // Position was already added
-       throw;
+        // Position was already added
+        throw;
     } catch (const std::exception& ex) {
         isc_throw(DhcpConfigError, ex.what() << " ("
                   << shared_network_data->getPosition() << ")");
@@ -111,6 +116,11 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
             }
         }
 
+        ConstElementPtr user_context = shared_network_data->get("user-context");
+        if (user_context) {
+            shared_network->setContext(user_context);
+        }
+
         if (shared_network_data->contains("subnet6")) {
             auto json = shared_network_data->get("subnet6");
 
index a7fc54355563bc849453e70b008a9d8495ed5165..d22e3ae12b5e7420cd964dfa069c4383c055477c 100644 (file)
@@ -28,7 +28,7 @@
 namespace isc {
 namespace dhcp {
 
-class Subnet : public UserContext, public data::CfgToElement {
+class Subnet : public virtual UserContext, public data::CfgToElement {
 
     // Assignable network is our friend to allow it to call
     // @ref Subnet::setSharedNetwork private function.
@@ -367,6 +367,8 @@ typedef boost::shared_ptr<Subnet4> Subnet4Ptr;
 /// @brief A configuration holder for IPv4 subnet.
 ///
 /// This class represents an IPv4 subnet.
+/// @note Subnet and Network use virtual inheritance to avoid
+/// a diamond issue with UserContext
 class Subnet4 : public Subnet, public Network4 {
 public:
 
@@ -523,6 +525,8 @@ typedef boost::shared_ptr<Subnet6> Subnet6Ptr;
 /// @brief A configuration holder for IPv6 subnet.
 ///
 /// This class represents an IPv6 subnet.
+/// @note Subnet and Network use virtual inheritance to avoid
+/// a diamond issue with UserContext
 class Subnet6 : public Subnet, public Network6 {
 public:
 
index 03329f87e3819ebac36161a0d6558df224e51e1c..9644fc95e4688c218d48909c93ed639238699190 100644 (file)
@@ -31,6 +31,7 @@ public:
     /// @return Valid shared network configuration.
     std::string getWorkingConfig() const {
             std::string config = "{"
+                "    \"user-context\": { \"comment\": \"example\" },"
                 "    \"name\": \"bird\","
                 "    \"interface\": \"eth1\","
                 "    \"option-data\": ["
@@ -106,6 +107,11 @@ TEST_F(SharedNetwork4ParserTest, parse) {
     EXPECT_EQ("bird", network->getName());
     EXPECT_EQ("eth1", network->getIface());
 
+    // Check user context.
+    ConstElementPtr context = network->getContext();
+    ASSERT_TRUE(context);
+    EXPECT_TRUE(context->get("comment"));
+
     // Subnet with id 1
     Subnet4Ptr subnet1 = network->getSubnet(SubnetID(1));
     ASSERT_TRUE(subnet1);
@@ -177,6 +183,7 @@ public:
             std::string config = "{"
                 "    \"name\": \"bird\","
                 "    \"interface\": \"eth1\","
+                "    \"user-context\": { },"
                 "    \"option-data\": ["
                 "        {"
                 "            \"name\": \"dns-servers\","
@@ -240,6 +247,11 @@ TEST_F(SharedNetwork6ParserTest, parse) {
     EXPECT_EQ("bird", network->getName());
     EXPECT_EQ("eth1", network->getIface());
 
+    // Check user context.
+    ConstElementPtr context = network->getContext();
+    ASSERT_TRUE(context);
+    EXPECT_EQ(0, context->size());
+
     // Subnet with id 1
     Subnet6Ptr subnet1 = network->getSubnet(SubnetID(1));
     ASSERT_TRUE(subnet1);
index 63508ec44ec92b718f8294c6d34d9487eab59ec3..cb21abba8e391bb1d998e762927c4e1d44b89bed 100644 (file)
@@ -195,6 +195,9 @@ TEST(SharedNetwork4Test, unparse) {
     network->setValid(200);
     network->setMatchClientId(false);
 
+    data::ElementPtr ctx = data::Element::fromJSON("{ \"comment\": \"foo\" }");
+    network->setContext(ctx);
+
     // Add several subnets.
     Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
                                    SubnetID(1)));
@@ -204,6 +207,7 @@ TEST(SharedNetwork4Test, unparse) {
     network->add(subnet2);
 
     std::string expected = "{\n"
+        "    \"comment\": \"foo\",\n"
         "    \"interface\": \"eth1\",\n"
         "    \"match-client-id\": false,\n"
         "    \"name\": \"frog\",\n"
@@ -480,6 +484,9 @@ TEST(SharedNetwork6Test, unparse) {
     network->setValid(300);
     network->setRapidCommit(true);
 
+    data::ElementPtr ctx = data::Element::fromJSON("{ \"foo\": \"bar\" }");
+    network->setContext(ctx);
+
     // Add several subnets.
     Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
                                    40, SubnetID(1)));
@@ -534,6 +541,7 @@ TEST(SharedNetwork6Test, unparse) {
         "        \"valid-lifetime\": 40\n"
         "      }\n"
         "    ],\n"
+        "    \"user-context\": { \"foo\": \"bar\" },\n"
         "    \"valid-lifetime\": 300\n"
         "}\n";
 
index 2ac57f84c5070dcf8b0ff35e329edb8013099f01..53289c1e9a049bc8975a56198a51e8429d3ed12f 100644 (file)
@@ -29,7 +29,8 @@ TEST(SharedNetworkListParserTest, parse) {
         "    },"
         "    {"
         "        \"name\": \"monkey\","
-        "        \"interface\": \"eth1\""
+        "        \"interface\": \"eth1\","
+        "        \"user-context\": { \"comment\": \"example\" }"
         "    }"
         "]";
 
@@ -43,11 +44,15 @@ TEST(SharedNetworkListParserTest, parse) {
     ASSERT_TRUE(network1);
     EXPECT_EQ("bird", network1->getName());
     EXPECT_EQ("eth0", network1->getIface());
+    EXPECT_FALSE(network1->getContext());
 
     SharedNetwork4Ptr network2 = cfg->getByName("monkey");
     ASSERT_TRUE(network2);
     EXPECT_EQ("monkey", network2->getName());
     EXPECT_EQ("eth1", network2->getIface());
+    ASSERT_TRUE(network2->getContext());
+    EXPECT_EQ(1, network2->getContext()->size());
+    EXPECT_TRUE(network2->getContext()->get("comment"));
 }
 
 // This test verifies that specifying two networks with the same name