Commit 88555d8f authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[master] Merge branch 'trac5208a' (preparations for host_cmds hook)

parents 56e0b075 5d8cf0e3
......@@ -118,124 +118,7 @@ AC_CHECK_DECL([__clang__], [CLANGPP="yes"], [CLANGPP="no"])
AM_CONDITIONAL(USE_CLANGPP, test "X${CLANGPP}" = "Xyes")
# Check for C++11 features support
CXX_SAVED=$CXX
feature=
for retry in "none" "--std=c++11" "--std=c++0x" "--std=c++1x" "fail"; do
if test "$retry" = "fail"; then
AC_MSG_ERROR([$feature (a C++11 feature) is not supported])
fi
if test "$retry" != "none"; then
AC_MSG_WARN([unsupported C++11 feature])
AC_MSG_NOTICE([retrying by adding $retry to $CXX])
CXX="$CXX_SAVED $retry"
AC_MSG_CHECKING($retry support)
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[],
[int myincr = 1;])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
fi
AC_MSG_CHECKING(std::unique_ptr support)
feature="std::unique_ptr"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <memory>],
[std::unique_ptr<int> a;])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(cbegin/cend support)
feature="cbegin/cend"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <string>],
[const std::string& s = "abcd";
unsigned count = 0;
for (std::string::const_iterator i = s.cbegin();
i != s.cend(); ++i)
if (*i == 'b')
++count;])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(final method support)
feature="final method"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[class Foo {
public:
virtual ~Foo() {};
virtual void bar() final;
};],[])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(aggregate initialization support)
feature="aggregate initialization"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <vector>],
[std::vector<int> foo = { 1, 2, 3};])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(variadic template support)
feature="variadic template"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[template<typename ... Args>
struct A {
void foo(Args... myargs) { return; };
};],
[A<> a;
a.foo();])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(static_assert support)
feature="static_assert"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[static_assert(1 + 1 == 2, "");],
[])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(template alias)
feature="template alias"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[template<int i>
class I {
public: int get() { return i; };
};
using Zero = I<0>;],
[Zero Z;
return Z.get();])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(lambda support)
feature="lambda"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[],
[auto myincr = [[]](int x) { return x + 1; };])],
[AC_MSG_RESULT([yes])
break],
[AC_MSG_RESULT([no])
continue])
done
AX_ISC_CPP11
# Check for std::is_base_of support
AC_MSG_CHECKING([for std::is_base_of])
......
This diff is collapsed.
EXTRA_DIST = ax_boost_for_kea.m4 ax_isc_rpath.m4
EXTRA_DIST = ax_boost_for_kea.m4 ax_isc_rpath.m4 ax_cpp11.m4
AC_DEFUN([AX_ISC_CPP11], [
CXX_SAVED=$CXX
feature=
for retry in "none" "--std=c++11" "--std=c++0x" "--std=c++1x" "fail"; do
if test "$retry" = "fail"; then
AC_MSG_ERROR([$feature (a C++11 feature) is not supported])
fi
if test "$retry" != "none"; then
AC_MSG_WARN([unsupported C++11 feature])
AC_MSG_NOTICE([retrying by adding $retry to $CXX])
CXX="$CXX_SAVED $retry"
AC_MSG_CHECKING($retry support)
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[],
[int myincr = 1;])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
fi
AC_MSG_CHECKING(std::unique_ptr support)
feature="std::unique_ptr"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <memory>],
[std::unique_ptr<int> a;])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(cbegin/cend support)
feature="cbegin/cend"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <string>],
[const std::string& s = "abcd";
unsigned count = 0;
for (std::string::const_iterator i = s.cbegin();
i != s.cend(); ++i)
if (*i == 'b')
++count;])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(final method support)
feature="final method"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[class Foo {
public:
virtual ~Foo() {};
virtual void bar() final;
};],[])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(aggregate initialization support)
feature="aggregate initialization"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <vector>],
[std::vector<int> foo = { 1, 2, 3};])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(variadic template support)
feature="variadic template"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[template<typename ... Args>
struct A {
void foo(Args... myargs) { return; };
};],
[A<> a;
a.foo();])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(static_assert support)
feature="static_assert"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[static_assert(1 + 1 == 2, "");],
[])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(template alias)
feature="template alias"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[template<int i>
class I {
public: int get() { return i; };
};
using Zero = I<0>;],
[Zero Z;
return Z.get();])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
continue])
AC_MSG_CHECKING(lambda support)
feature="lambda"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[],
[auto myincr = [[]](int x) { return x + 1; };])],
[AC_MSG_RESULT([yes])
break],
[AC_MSG_RESULT([no])
continue])
done
])dnl AX_ISC_RPATH
......@@ -247,6 +247,46 @@ public:
/// @param host Pointer to the new @c Host object being added.
virtual void add(const HostPtr& host) = 0;
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identfier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) = 0;
/// @brief Attempts to delete a host by (subnet-id4, identifier, identifier-type)
///
/// This method supports both v4 hosts only.
///
/// @param subnet_id IPv4 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) = 0;
/// @brief Attempts to delete a host by (subnet-id6, identifier, identifier-type)
///
/// This method supports both v6 hosts only.
///
/// @param subnet_id IPv6 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) = 0;
/// @brief Return backend type
///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
......
......@@ -688,6 +688,33 @@ CfgHosts::add6(const HostPtr& host) {
}
}
bool
CfgHosts::del(const SubnetID& /*subnet_id*/, const asiolink::IOAddress& /*addr*/) {
/// @todo: Implement host removal
isc_throw(NotImplemented, "sorry, not implemented");
return (false);
}
bool
CfgHosts::del4(const SubnetID& /*subnet_id*/,
const Host::IdentifierType& /*identifier_type*/,
const uint8_t* /*identifier_begin*/,
const size_t /*identifier_len*/) {
/// @todo: Implement host removal
isc_throw(NotImplemented, "sorry, not implemented");
return (false);
}
bool
CfgHosts::del6(const SubnetID& /*subnet_id*/,
const Host::IdentifierType& /*identifier_type*/,
const uint8_t* /*identifier_begin*/,
const size_t /*identifier_len*/) {
/// @todo: Implement host removal
isc_throw(NotImplemented, "sorry, not implemented");
return (false);
}
ElementPtr
CfgHosts::toElement() const {
uint16_t family = CfgMgr::instance().getFamily();
......@@ -708,60 +735,12 @@ CfgHosts::toElement4() const {
const HostContainerIndex0& idx = hosts_.get<0>();
for (HostContainerIndex0::const_iterator host = idx.begin();
host != idx.end(); ++host) {
// Get the subnet ID
// Convert host to element representation
ElementPtr map = (*host)->toElement4();
// Push it on the list
SubnetID subnet_id = (*host)->getIPv4SubnetID();
// Prepare the map
ElementPtr map = Element::createMap();
// Set the identifier
Host::IdentifierType id_type = (*host)->getIdentifierType();
if (id_type == Host::IDENT_HWADDR) {
HWAddrPtr hwaddr = (*host)->getHWAddress();
map->set("hw-address", Element::create(hwaddr->toText(false)));
} else if (id_type == Host::IDENT_DUID) {
DuidPtr duid = (*host)->getDuid();
map->set("duid", Element::create(duid->toText()));
} else if (id_type == Host::IDENT_CIRCUIT_ID) {
const std::vector<uint8_t>& bin = (*host)->getIdentifier();
std::string circuit_id = util::encode::encodeHex(bin);
map->set("circuit-id", Element::create(circuit_id));
} else if (id_type == Host::IDENT_CLIENT_ID) {
const std::vector<uint8_t>& bin = (*host)->getIdentifier();
std::string client_id = util::encode::encodeHex(bin);
map->set("client-id", Element::create(client_id));
} else if (id_type == Host::IDENT_FLEX) {
const std::vector<uint8_t>& bin = (*host)->getIdentifier();
std::string flex = util::encode::encodeHex(bin);
map->set("flex-id", Element::create(flex));
} else {
isc_throw(ToElementError, "invalid identifier type: " << id_type);
}
// Set the reservation
const IOAddress& address = (*host)->getIPv4Reservation();
map->set("ip-address", Element::create(address.toText()));
// Set the hostname
const std::string& hostname = (*host)->getHostname();
map->set("hostname", Element::create(hostname));
// Set next-server
const IOAddress& next_server = (*host)->getNextServer();
map->set("next-server", Element::create(next_server.toText()));
// Set server-hostname
const std::string& server_hostname = (*host)->getServerHostname();
map->set("server-hostname", Element::create(server_hostname));
// Set boot-file-name
const std::string& boot_file_name = (*host)->getBootFileName();
map->set("boot-file-name", Element::create(boot_file_name));
// Set client-classes
const ClientClasses& cclasses = (*host)->getClientClasses4();
ElementPtr classes = Element::createList();
for (ClientClasses::const_iterator cclass = cclasses.cbegin();
cclass != cclasses.end(); ++cclass) {
classes->add(Element::create(*cclass));
}
map->set("client-classes", classes);
// Set option-data
ConstCfgOptionPtr opts = (*host)->getCfgOption4();
map->set("option-data", opts->toElement());
// Push the map on the list
result.add(subnet_id, map);
}
return (result.externalize());
......@@ -774,62 +753,12 @@ CfgHosts::toElement6() const {
const HostContainerIndex0& idx = hosts_.get<0>();
for (HostContainerIndex0::const_iterator host = idx.begin();
host != idx.end(); ++host) {
// Get the subnet ID
// Convert host to Element representation
ElementPtr map = (*host)->toElement6();
// Push it on the list
SubnetID subnet_id = (*host)->getIPv6SubnetID();
// Prepare the map
ElementPtr map = Element::createMap();
// Set the identifier
Host::IdentifierType id_type = (*host)->getIdentifierType();
if (id_type == Host::IDENT_HWADDR) {
HWAddrPtr hwaddr = (*host)->getHWAddress();
map->set("hw-address", Element::create(hwaddr->toText(false)));
} else if (id_type == Host::IDENT_DUID) {
DuidPtr duid = (*host)->getDuid();
map->set("duid", Element::create(duid->toText()));
} else if (id_type == Host::IDENT_CIRCUIT_ID) {
isc_throw(ToElementError, "unexpected circuit-id DUID type");
} else if (id_type == Host::IDENT_CLIENT_ID) {
isc_throw(ToElementError, "unexpected client-id DUID type");
} else if (id_type == Host::IDENT_FLEX) {
const std::vector<uint8_t>& bin = (*host)->getIdentifier();
std::string flex = util::encode::encodeHex(bin);
map->set("flex-id", Element::create(flex));
} else {
isc_throw(ToElementError, "invalid DUID type: " << id_type);
}
// Set reservations (ip-addresses)
IPv6ResrvRange na_resv =
(*host)->getIPv6Reservations(IPv6Resrv::TYPE_NA);
ElementPtr resvs = Element::createList();
for (IPv6ResrvIterator resv = na_resv.first;
resv != na_resv.second; ++resv) {
resvs->add(Element::create(resv->second.toText()));
}
map->set("ip-addresses", resvs);
// Set reservations (prefixes)
IPv6ResrvRange pd_resv =
(*host)->getIPv6Reservations(IPv6Resrv::TYPE_PD);
resvs = Element::createList();
for (IPv6ResrvIterator resv = pd_resv.first;
resv != pd_resv.second; ++resv) {
resvs->add(Element::create(resv->second.toText()));
}
map->set("prefixes", resvs);
// Set the hostname
const std::string& hostname = (*host)->getHostname();
map->set("hostname", Element::create(hostname));
// Set client-classes
const ClientClasses& cclasses = (*host)->getClientClasses6();
ElementPtr classes = Element::createList();
for (ClientClasses::const_iterator cclass = cclasses.cbegin();
cclass != cclasses.end(); ++cclass) {
classes->add(Element::create(*cclass));
}
map->set("client-classes", classes);
// Set option-data
ConstCfgOptionPtr opts = (*host)->getCfgOption6();
map->set("option-data", opts->toElement());
// Push the map on the list
result.add(subnet_id, map);
}
return (result.externalize());
......
......@@ -322,6 +322,45 @@ public:
/// has already been added to the IPv4 or IPv6 subnet.
virtual void add(const HostPtr& host);
/// @brief Attempts to delete a host by address.
///
/// This method supports both v4 and v6.
/// @todo: Not implemented.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
/// @brief Attempts to delete a host by (subnet4-id, identifier, identifier-type)
///
/// This method supports v4 only.
/// @todo: Not implemented.
///
/// @param subnet_id IPv4 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false otherwise.
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Attempts to delete a host by (subnet6-id, identifier, identifier-type)
///
/// This method supports v6 only.
/// @todo: Not implemented.
///
/// @param subnet_id IPv6 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false otherwise.
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Return backend type
///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
......
......@@ -9,9 +9,13 @@
#include <dhcpsrv/host.h>
#include <util/encode/hex.h>
#include <util/strutil.h>
#include <asiolink/io_address.h>
#include <exceptions/exceptions.h>
#include <sstream>
using namespace isc::data;
using namespace isc::asiolink;
namespace isc {
namespace dhcp {
......@@ -400,6 +404,122 @@ Host::setBootFileName(const std::string& boot_file_name) {
boot_file_name_ = boot_file_name;
}
ElementPtr
Host::toElement4() const {
// Prepare the map
ElementPtr map = Element::createMap();
// Set the identifier
Host::IdentifierType id_type = getIdentifierType();
if (id_type == Host::IDENT_HWADDR) {
HWAddrPtr hwaddr = getHWAddress();
map->set("hw-address", Element::create(hwaddr->toText(false)));
} else if (id_type == Host::IDENT_DUID) {
DuidPtr duid = getDuid();
map->set("duid", Element::create(duid->toText()));
} else if (id_type == Host::IDENT_CIRCUIT_ID) {
const std::vector<uint8_t>& bin = getIdentifier();
std::string circuit_id = util::encode::encodeHex(bin);
map->set("circuit-id", Element::create(circuit_id));
} else if (id_type == Host::IDENT_CLIENT_ID) {
const std::vector<uint8_t>& bin = getIdentifier();
std::string client_id = util::encode::encodeHex(bin);
map->set("client-id", Element::create(client_id));
} else if (id_type == Host::IDENT_FLEX) {
const std::vector<uint8_t>& bin = getIdentifier();
std::string flex = util::encode::encodeHex(bin);
map->set("flex-id", Element::create(flex));
} else {
isc_throw(ToElementError, "invalid identifier type: " << id_type);
}
// Set the reservation
const IOAddress& address = getIPv4Reservation();
map->set("ip-address", Element::create(address.toText()));
// Set the hostname
const std::string& hostname = getHostname();
map->set("hostname", Element::create(hostname));
// Set next-server
const IOAddress& next_server = getNextServer();
map->set("next-server", Element::create(next_server.toText()));
// Set server-hostname
const std::string& server_hostname = getServerHostname();
map->set("server-hostname", Element::create(server_hostname));
// Set boot-file-name
const std::string& boot_file_name = getBootFileName();
map->set("boot-file-name", Element::create(boot_file_name));
// Set client-classes
const ClientClasses& cclasses = getClientClasses4();
ElementPtr classes = Element::createList();
for (ClientClasses::const_iterator cclass = cclasses.cbegin();
cclass != cclasses.end(); ++cclass) {
classes->add(Element::create(*cclass));
}
map->set("client-classes", classes);
// Set option-data
ConstCfgOptionPtr opts = getCfgOption4();
map->set("option-data", opts->toElement());
return (map);
}
ElementPtr
Host::toElement6() const {
// Prepare the map
ElementPtr map = Element::createMap();
// Set the identifier
Host::IdentifierType id_type = getIdentifierType();
if (id_type == Host::IDENT_HWADDR) {
HWAddrPtr hwaddr = getHWAddress();
map->set("hw-address", Element::create(hwaddr->toText(false)));
} else if (id_type == Host::IDENT_DUID) {
DuidPtr duid = getDuid();
map->set("duid", Element::create(duid->toText()));
} else if (id_type == Host::IDENT_CIRCUIT_ID) {
isc_throw(ToElementError, "unexpected circuit-id DUID type");
} else if (id_type == Host::IDENT_CLIENT_ID) {
isc_throw(ToElementError, "unexpected client-id DUID type");
} else if (id_type == Host::IDENT_FLEX) {
const std::vector<uint8_t>& bin = getIdentifier();
std::string flex = util::encode::encodeHex(bin);
map->set("flex-id", Element::create(flex));
} else {
isc_throw(ToElementError, "invalid DUID type: " << id_type);
}
// Set reservations (ip-addresses)