endif
libkea_dhcpsrv_la_SOURCES += ncr_generator.cc ncr_generator.h
-libkea_dhcpsrv_la_SOURCES += network.h
+libkea_dhcpsrv_la_SOURCES += network.cc network.h
if HAVE_PGSQL
libkea_dhcpsrv_la_SOURCES += pgsql_connection.cc pgsql_connection.h
--- /dev/null
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <dhcpsrv/network.h>
+
+using namespace isc::data;
+
+namespace isc {
+namespace dhcp {
+
+ElementPtr
+Network::toElement() const {
+ ElementPtr map = Element::createMap();
+
+ // Set interface
+ const std::string& iface = getIface();
+ if (!iface.empty()) {
+ map->set("interface", Element::create(iface));
+ }
+
+ // Set options
+ ConstCfgOptionPtr opts = getCfgOption();
+ map->set("option-data", opts->toElement());
+
+ return (map);
+}
+
+} // end of namespace isc::dhcp
+} // end of namespace isc
#ifndef NETWORK_H
#define NETWORK_H
+#include <cc/cfg_to_element.h>
+#include <cc/data.h>
+#include <dhcpsrv/cfg_option.h>
+#include <dhcpsrv/cfg_4o6.h>
#include <boost/shared_ptr.hpp>
#include <string>
/// 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 {
+class Network : public data::CfgToElement {
public:
+ /// @brief Constructor.
+ Network()
+ : iface_name_(), cfg_option_(new CfgOption()) {
+ }
+
/// @brief Virtual destructor.
///
/// Does nothing at the moment.
return (iface_name_);
};
+ /// @brief Returns pointer to the option data configuration for this subnet.
+ CfgOptionPtr getCfgOption() {
+ return (cfg_option_);
+ }
+
+ /// @brief Returns const pointer to the option data configuration for this
+ /// subnet.
+ ConstCfgOptionPtr getCfgOption() const {
+ return (cfg_option_);
+ }
+
+ /// @brief Unparses network object.
+ ///
+ /// @return A pointer to unparsed network configuration.
+ virtual data::ElementPtr toElement() const;
+
protected:
/// @brief Holds interface name for which this network is selected.
std::string iface_name_;
+ /// @brief Pointer to the option data configuration for this subnet.
+ CfgOptionPtr cfg_option_;
};
/// @brief Pointer to the @ref Network object.
#include <dhcpsrv/shared_network.h>
+using namespace isc::data;
using namespace isc::dhcp;
namespace isc {
namespace dhcp {
+ElementPtr
+SharedNetwork::toElement() const {
+ ElementPtr map = Network::toElement();
+
+ // Set shared network name.
+ if (!name_.empty()) {
+ map->set("name", Element::create(name_));
+ }
+
+ return (map);
+}
+
NetworkPtr
SharedNetwork4::sharedFromThis() {
return (shared_from_this());
current_subnet));
}
+ElementPtr
+SharedNetwork4::toElement() const {
+ ElementPtr map = SharedNetwork::toElement();
+
+ ElementPtr subnet4 = Element::createList();
+ for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
+ subnet4->add((*subnet)->toElement());
+ }
+
+ map->set("subnet4", subnet4);
+
+ return (map);
+}
+
NetworkPtr
SharedNetwork6::sharedFromThis() {
return (shared_from_this());
current_subnet));
}
+ElementPtr
+SharedNetwork6::toElement() const {
+ ElementPtr map = SharedNetwork::toElement();
+
+ ElementPtr subnet6 = Element::createList();
+ for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
+ subnet6->add((*subnet)->toElement());
+ }
+
+ map->set("subnet6", subnet6);
+
+ return (map);
+}
+
} // end of namespace isc::dhcp
} // end of namespace isc
#ifndef SHARED_NETWORK_H
#define SHARED_NETWORK_H
+#include <cc/data.h>
#include <exceptions/exceptions.h>
#include <dhcpsrv/assignable_network.h>
#include <dhcpsrv/subnet.h>
return (*subnet_it);
}
-protected:
+ /// @brief Unparses shared network object.
+ ///
+ /// @return A pointer to unparsed shared network configuration.
+ virtual data::ElementPtr toElement() const;
/// @brief Holds a name of a shared network.
std::string name_;
Subnet4Ptr getNextSubnet(const Subnet4Ptr& first_subnet,
const Subnet4Ptr& current_subnet) const;
+ /// @brief Unparses shared network object.
+ ///
+ /// @return A pointer to unparsed shared network configuration.
+ virtual data::ElementPtr toElement() const;
+
private:
/// @brief Collection of IPv4 subnets within shared network.
Subnet6Ptr getNextSubnet(const Subnet6Ptr& first_subnet,
const Subnet6Ptr& current_subnet) const;
+ /// @brief Unparses shared network object.
+ ///
+ /// @return A pointer to unparsed shared network configuration.
+ virtual data::ElementPtr toElement() const;
+
private:
/// @brief Collection of IPv6 subnets within shared network.
const Triplet<uint32_t>& valid_lifetime,
const isc::dhcp::Subnet::RelayInfo& relay,
const SubnetID id)
- :id_(id == 0 ? generateNextID() : id), prefix_(prefix), prefix_len_(len),
- t1_(t1), t2_(t2), valid_(valid_lifetime),
- last_allocated_ia_(lastAddrInPrefix(prefix, len)),
- last_allocated_ta_(lastAddrInPrefix(prefix, len)),
- last_allocated_pd_(lastAddrInPrefix(prefix, len)), relay_(relay),
- host_reservation_mode_(HR_ALL), cfg_option_(new CfgOption())
- {
+ : Network(), id_(id == 0 ? generateNextID() : id), prefix_(prefix),
+ prefix_len_(len),
+ t1_(t1), t2_(t2), valid_(valid_lifetime),
+ last_allocated_ia_(lastAddrInPrefix(prefix, len)),
+ last_allocated_ta_(lastAddrInPrefix(prefix, len)),
+ last_allocated_pd_(lastAddrInPrefix(prefix, len)), relay_(relay),
+ host_reservation_mode_(HR_ALL) {
if ((prefix.isV6() && len > 128) ||
(prefix.isV4() && len > 32)) {
isc_throw(BadValue,
data::ElementPtr
Subnet::toElement() const {
- // Prepare the map
- ElementPtr map = Element::createMap();
+ ElementPtr map = Network::toElement();
// Set subnet id
SubnetID id = getID();
// Set subnet
map->set("subnet", Element::create(toText()));
- // Set interface
- const std::string& iface = getIface();
- if (!iface.empty()) {
- map->set("interface", Element::create(iface));
- }
-
// Set renew-timer
map->set("renew-timer",
Element::create(static_cast<long long>
map->set("client-class", Element::create(*cclasses.cbegin()));
}
- // Set options
- ConstCfgOptionPtr opts = getCfgOption();
- map->set("option-data", opts->toElement());
-
return (map);
}
#include <dhcp/classify.h>
#include <dhcp/option_space_container.h>
#include <dhcpsrv/assignable_network.h>
-#include <dhcpsrv/cfg_option.h>
-#include <dhcpsrv/cfg_4o6.h>
#include <dhcpsrv/lease.h>
#include <dhcpsrv/pool.h>
#include <dhcpsrv/subnet_id.h>
return (t2_);
}
- /// @brief Returns pointer to the option data configuration for this subnet.
- CfgOptionPtr getCfgOption() {
- return (cfg_option_);
- }
-
- /// @brief Returns const pointer to the option data configuration for this
- /// subnet.
- ConstCfgOptionPtr getCfgOption() const {
- return (cfg_option_);
- }
-
/// @brief returns the last address that was tried from this pool
///
/// This method returns the last address that was attempted to be allocated
/// See @ref HRMode type for details.
HRMode host_reservation_mode_;
- /// @brief Pointer to the option data configuration for this subnet.
- CfgOptionPtr cfg_option_;
-
NetworkPtr shared_network_;
};
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#include <config.h>
#include <asiolink/io_address.h>
#include <dhcpsrv/shared_network.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/triplet.h>
#include <exceptions/exceptions.h>
+#include <testutils/test_to_element.h>
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
}
}
+// This test verifies that unparsing shared network returns valid structure.
+TEST(SharedNetwork4Test, unparse) {
+ SharedNetwork4Ptr network(new SharedNetwork4("frog"));
+
+ // Set interface name.
+ network->setIface("eth1");
+
+ // Add several subnets.
+ Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
+ SubnetID(1)));
+ Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"), 24, 10, 20, 30,
+ SubnetID(2)));
+ network->add(subnet1);
+ network->add(subnet2);
+
+ std::string expected = "{\n"
+ " \"interface\": \"eth1\",\n"
+ " \"name\": \"frog\",\n"
+ " \"option-data\": [ ],\n"
+ " \"subnet4\": [\n"
+ " {\n"
+ " \"4o6-interface\": \"\",\n"
+ " \"4o6-interface-id\": \"\",\n"
+ " \"4o6-subnet\": \"\",\n"
+ " \"id\": 1,\n"
+ " \"match-client-id\": true,\n"
+ " \"next-server\": \"0.0.0.0\",\n"
+ " \"option-data\": [ ],\n"
+ " \"pools\": [ ],\n"
+ " \"rebind-timer\": 20,\n"
+ " \"relay\": {\n"
+ " \"ip-address\": \"0.0.0.0\"\n"
+ " },\n"
+ " \"renew-timer\": 10,\n"
+ " \"reservation-mode\": \"all\",\n"
+ " \"subnet\": \"10.0.0.0/8\",\n"
+ " \"valid-lifetime\": 30\n"
+ " },\n"
+ " {\n"
+ " \"4o6-interface\": \"\",\n"
+ " \"4o6-interface-id\": \"\",\n"
+ " \"4o6-subnet\": \"\",\n"
+ " \"id\": 2,\n"
+ " \"match-client-id\": true,\n"
+ " \"next-server\": \"0.0.0.0\",\n"
+ " \"option-data\": [ ],\n"
+ " \"pools\": [ ],\n"
+ " \"rebind-timer\": 20,\n"
+ " \"relay\": {\n"
+ " \"ip-address\": \"0.0.0.0\"\n"
+ " },\n"
+ " \"renew-timer\": 10,\n"
+ " \"reservation-mode\": \"all\",\n"
+ " \"subnet\": \"192.0.2.0/24\",\n"
+ " \"valid-lifetime\": 30\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+
+ test::runToElementTest<SharedNetwork4>(expected, *network);
+}
+
// This test verifies that shared network can be given a name and that
// this name can be retrieved.
TEST(SharedNetwork6Test, getName) {
}
}
+// This test verifies that unparsing shared network returns valid structure.
+TEST(SharedNetwork6Test, unparse) {
+ SharedNetwork6Ptr network(new SharedNetwork6("frog"));
+ network->setIface("eth1");
+
+ // Add several subnets.
+ Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
+ 40, SubnetID(1)));
+ Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 16, 10, 20, 30, 40,
+ SubnetID(2)));
+ network->add(subnet1);
+ network->add(subnet2);
+
+ std::string expected = "{\n"
+ " \"interface\": \"eth1\",\n"
+ " \"name\": \"frog\",\n"
+ " \"option-data\": [ ],\n"
+ " \"subnet6\": [\n"
+ " {\n"
+ " \"id\": 1,\n"
+ " \"option-data\": [ ],\n"
+ " \"pd-pools\": [ ],\n"
+ " \"pools\": [ ],\n"
+ " \"preferred-lifetime\": 30,\n"
+ " \"rapid-commit\": false,\n"
+ " \"rebind-timer\": 20,\n"
+ " \"relay\": {\n"
+ " \"ip-address\": \"::\"\n"
+ " },\n"
+ " \"renew-timer\": 10,\n"
+ " \"reservation-mode\": \"all\",\n"
+ " \"subnet\": \"2001:db8:1::/64\",\n"
+ " \"valid-lifetime\": 40\n"
+ " },\n"
+ " {\n"
+ " \"id\": 2,\n"
+ " \"option-data\": [ ],\n"
+ " \"pd-pools\": [ ],\n"
+ " \"pools\": [ ],\n"
+ " \"preferred-lifetime\": 30,\n"
+ " \"rapid-commit\": false,\n"
+ " \"rebind-timer\": 20,\n"
+ " \"relay\": {\n"
+ " \"ip-address\": \"::\"\n"
+ " },\n"
+ " \"renew-timer\": 10,\n"
+ " \"reservation-mode\": \"all\",\n"
+ " \"subnet\": \"3000::/16\",\n"
+ " \"valid-lifetime\": 40\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+
+ test::runToElementTest<SharedNetwork6>(expected, *network);
+}
+
} // end of anonymous namespace