| reservation_mode
| client_class
| valid_lifetime
+ | user_context
+ | comment
| unknown_map_entry
;
| preferred_lifetime
| rapid_commit
| valid_lifetime
+ | user_context
+ | comment
| unknown_map_entry
;
Network::toElement() const {
ElementPtr map = Element::createMap();
+ // Set user-context
+ contextToElement(map);
+
// Set interface
const std::string& iface = getIface();
if (!iface.empty()) {
#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>
/// 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.
}
}
+ 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() << ")");
}
}
+ 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");
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.
/// @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:
/// @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:
/// @return Valid shared network configuration.
std::string getWorkingConfig() const {
std::string config = "{"
+ " \"user-context\": { \"comment\": \"example\" },"
" \"name\": \"bird\","
" \"interface\": \"eth1\","
" \"option-data\": ["
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);
std::string config = "{"
" \"name\": \"bird\","
" \"interface\": \"eth1\","
+ " \"user-context\": { },"
" \"option-data\": ["
" {"
" \"name\": \"dns-servers\","
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);
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)));
network->add(subnet2);
std::string expected = "{\n"
+ " \"comment\": \"foo\",\n"
" \"interface\": \"eth1\",\n"
" \"match-client-id\": false,\n"
" \"name\": \"frog\",\n"
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)));
" \"valid-lifetime\": 40\n"
" }\n"
" ],\n"
+ " \"user-context\": { \"foo\": \"bar\" },\n"
" \"valid-lifetime\": 300\n"
"}\n";
" },"
" {"
" \"name\": \"monkey\","
- " \"interface\": \"eth1\""
+ " \"interface\": \"eth1\","
+ " \"user-context\": { \"comment\": \"example\" }"
" }"
"]";
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