mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[master] Merge branch 'trac2673'
This commit is contained in:
@@ -5,6 +5,10 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
|
|||||||
AM_CPPFLAGS += $(BOOST_INCLUDES)
|
AM_CPPFLAGS += $(BOOST_INCLUDES)
|
||||||
|
|
||||||
AM_CXXFLAGS = $(B10_CXXFLAGS)
|
AM_CXXFLAGS = $(B10_CXXFLAGS)
|
||||||
|
if USE_CLANGPP
|
||||||
|
# Disable unused parameter warning caused by some Boost headers when compiling with clang
|
||||||
|
AM_CXXFLAGS += -Wno-unused-parameter
|
||||||
|
endif
|
||||||
|
|
||||||
if USE_STATIC_LINK
|
if USE_STATIC_LINK
|
||||||
AM_LDFLAGS = -static
|
AM_LDFLAGS = -static
|
||||||
@@ -51,12 +55,6 @@ b10_dhcp4_SOURCES += dhcp4_srv.cc dhcp4_srv.h
|
|||||||
nodist_b10_dhcp4_SOURCES = dhcp4_messages.h dhcp4_messages.cc
|
nodist_b10_dhcp4_SOURCES = dhcp4_messages.h dhcp4_messages.cc
|
||||||
EXTRA_DIST += dhcp4_messages.mes
|
EXTRA_DIST += dhcp4_messages.mes
|
||||||
|
|
||||||
if USE_CLANGPP
|
|
||||||
# Disable unused parameter warning caused by some of the
|
|
||||||
# Boost headers when compiling with clang.
|
|
||||||
b10_dhcp4_CXXFLAGS = -Wno-unused-parameter
|
|
||||||
endif
|
|
||||||
|
|
||||||
b10_dhcp4_LDADD = $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
|
b10_dhcp4_LDADD = $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
|
||||||
b10_dhcp4_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
|
b10_dhcp4_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
|
||||||
b10_dhcp4_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la
|
b10_dhcp4_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la
|
||||||
|
@@ -967,13 +967,13 @@ public:
|
|||||||
return (new OptionDataListParser(param_name));
|
return (new OptionDataListParser(param_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pointer to options instances storage.
|
||||||
|
OptionStorage* options_;
|
||||||
/// Intermediate option storage. This storage is used by
|
/// Intermediate option storage. This storage is used by
|
||||||
/// lower level parsers to add new options. Values held
|
/// lower level parsers to add new options. Values held
|
||||||
/// in this storage are assigned to main storage (options_)
|
/// in this storage are assigned to main storage (options_)
|
||||||
/// if overall parsing was successful.
|
/// if overall parsing was successful.
|
||||||
OptionStorage local_options_;
|
OptionStorage local_options_;
|
||||||
/// Pointer to options instances storage.
|
|
||||||
OptionStorage* options_;
|
|
||||||
/// Collection of parsers;
|
/// Collection of parsers;
|
||||||
ParserCollection parsers_;
|
ParserCollection parsers_;
|
||||||
};
|
};
|
||||||
|
@@ -42,6 +42,18 @@ using namespace isc::dhcp;
|
|||||||
using namespace isc::log;
|
using namespace isc::log;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace isc {
|
||||||
|
namespace dhcp {
|
||||||
|
|
||||||
|
/// @brief file name of a server-id file
|
||||||
|
///
|
||||||
|
/// Server must store its server identifier in persistent storage that must not
|
||||||
|
/// change between restarts. This is name of the file that is created in dataDir
|
||||||
|
/// (see isc::dhcp::CfgMgr::getDataDir()). It is a text file that uses
|
||||||
|
/// regular IPv4 address, e.g. 192.0.2.1. Server will create it during
|
||||||
|
/// first run and then use it afterwards.
|
||||||
|
static const char* SERVER_ID_FILE = "b10-dhcp4-serverid";
|
||||||
|
|
||||||
// These are hardcoded parameters. Currently this is a skeleton server that only
|
// These are hardcoded parameters. Currently this is a skeleton server that only
|
||||||
// grants those options and a single, fixed, hardcoded lease.
|
// grants those options and a single, fixed, hardcoded lease.
|
||||||
|
|
||||||
@@ -98,7 +110,8 @@ Dhcpv4Srv::~Dhcpv4Srv() {
|
|||||||
IfaceMgr::instance().closeSockets();
|
IfaceMgr::instance().closeSockets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv4Srv::shutdown() {
|
void
|
||||||
|
Dhcpv4Srv::shutdown() {
|
||||||
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_SHUTDOWN_REQUEST);
|
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_SHUTDOWN_REQUEST);
|
||||||
shutdown_ = true;
|
shutdown_ = true;
|
||||||
}
|
}
|
||||||
@@ -199,7 +212,8 @@ Dhcpv4Srv::run() {
|
|||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dhcpv4Srv::loadServerID(const std::string& file_name) {
|
bool
|
||||||
|
Dhcpv4Srv::loadServerID(const std::string& file_name) {
|
||||||
|
|
||||||
// load content of the file into a string
|
// load content of the file into a string
|
||||||
fstream f(file_name.c_str(), ios::in);
|
fstream f(file_name.c_str(), ios::in);
|
||||||
@@ -233,7 +247,8 @@ bool Dhcpv4Srv::loadServerID(const std::string& file_name) {
|
|||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv4Srv::generateServerID() {
|
void
|
||||||
|
Dhcpv4Srv::generateServerID() {
|
||||||
|
|
||||||
const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
|
const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
|
||||||
|
|
||||||
@@ -270,16 +285,19 @@ void Dhcpv4Srv::generateServerID() {
|
|||||||
isc_throw(BadValue, "No suitable interfaces for server-identifier found");
|
isc_throw(BadValue, "No suitable interfaces for server-identifier found");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dhcpv4Srv::writeServerID(const std::string& file_name) {
|
bool
|
||||||
|
Dhcpv4Srv::writeServerID(const std::string& file_name) {
|
||||||
fstream f(file_name.c_str(), ios::out | ios::trunc);
|
fstream f(file_name.c_str(), ios::out | ios::trunc);
|
||||||
if (!f.good()) {
|
if (!f.good()) {
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
f << srvidToString(getServerID());
|
f << srvidToString(getServerID());
|
||||||
f.close();
|
f.close();
|
||||||
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
string Dhcpv4Srv::srvidToString(const OptionPtr& srvid) {
|
string
|
||||||
|
Dhcpv4Srv::srvidToString(const OptionPtr& srvid) {
|
||||||
if (!srvid) {
|
if (!srvid) {
|
||||||
isc_throw(BadValue, "NULL pointer passed to srvidToString()");
|
isc_throw(BadValue, "NULL pointer passed to srvidToString()");
|
||||||
}
|
}
|
||||||
@@ -298,7 +316,8 @@ string Dhcpv4Srv::srvidToString(const OptionPtr& srvid) {
|
|||||||
return (addrs[0].toText());
|
return (addrs[0].toText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
|
void
|
||||||
|
Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
|
||||||
answer->setIface(question->getIface());
|
answer->setIface(question->getIface());
|
||||||
answer->setIndex(question->getIndex());
|
answer->setIndex(question->getIndex());
|
||||||
answer->setCiaddr(question->getCiaddr());
|
answer->setCiaddr(question->getCiaddr());
|
||||||
@@ -327,7 +346,8 @@ void Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
|
void
|
||||||
|
Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
|
||||||
OptionPtr opt;
|
OptionPtr opt;
|
||||||
|
|
||||||
// add Message Type Option (type 53)
|
// add Message Type Option (type 53)
|
||||||
@@ -339,8 +359,8 @@ void Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
|
|||||||
// more options will be added here later
|
// more options will be added here later
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
void Dhcpv4Srv::appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
|
Dhcpv4Srv::appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
|
||||||
|
|
||||||
// Get the subnet relevant for the client. We will need it
|
// Get the subnet relevant for the client. We will need it
|
||||||
// to get the options associated with it.
|
// to get the options associated with it.
|
||||||
@@ -411,7 +431,8 @@ Dhcpv4Srv::appendBasicOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
|
void
|
||||||
|
Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
|
||||||
|
|
||||||
// We need to select a subnet the client is connected in.
|
// We need to select a subnet the client is connected in.
|
||||||
Subnet4Ptr subnet = selectSubnet(question);
|
Subnet4Ptr subnet = selectSubnet(question);
|
||||||
@@ -509,7 +530,8 @@ void Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionPtr Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
|
OptionPtr
|
||||||
|
Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
|
||||||
uint32_t netmask = getNetmask4(subnet->get().second);
|
uint32_t netmask = getNetmask4(subnet->get().second);
|
||||||
|
|
||||||
OptionPtr opt(new OptionInt<uint32_t>(Option::V4,
|
OptionPtr opt(new OptionInt<uint32_t>(Option::V4,
|
||||||
@@ -518,7 +540,8 @@ OptionPtr Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
|
|||||||
return (opt);
|
return (opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt4Ptr Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
|
Pkt4Ptr
|
||||||
|
Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
|
||||||
Pkt4Ptr offer = Pkt4Ptr
|
Pkt4Ptr offer = Pkt4Ptr
|
||||||
(new Pkt4(DHCPOFFER, discover->getTransid()));
|
(new Pkt4(DHCPOFFER, discover->getTransid()));
|
||||||
|
|
||||||
@@ -536,7 +559,8 @@ Pkt4Ptr Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
|
|||||||
return (offer);
|
return (offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt4Ptr Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
|
Pkt4Ptr
|
||||||
|
Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
|
||||||
Pkt4Ptr ack = Pkt4Ptr
|
Pkt4Ptr ack = Pkt4Ptr
|
||||||
(new Pkt4(DHCPACK, request->getTransid()));
|
(new Pkt4(DHCPACK, request->getTransid()));
|
||||||
|
|
||||||
@@ -554,7 +578,8 @@ Pkt4Ptr Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
|
|||||||
return (ack);
|
return (ack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
|
void
|
||||||
|
Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
|
||||||
|
|
||||||
// Try to find client-id
|
// Try to find client-id
|
||||||
ClientIdPtr client_id;
|
ClientIdPtr client_id;
|
||||||
@@ -622,11 +647,13 @@ void Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv4Srv::processDecline(Pkt4Ptr& decline) {
|
void
|
||||||
|
Dhcpv4Srv::processDecline(Pkt4Ptr& /* decline */) {
|
||||||
/// TODO: Implement this.
|
/// TODO: Implement this.
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt4Ptr Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
|
Pkt4Ptr
|
||||||
|
Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
|
||||||
/// TODO: Currently implemented echo mode. Implement this for real
|
/// TODO: Currently implemented echo mode. Implement this for real
|
||||||
return (inform);
|
return (inform);
|
||||||
}
|
}
|
||||||
@@ -662,7 +689,8 @@ Dhcpv4Srv::serverReceivedPacketName(uint8_t type) {
|
|||||||
return (UNKNOWN);
|
return (UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
Subnet4Ptr Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) {
|
Subnet4Ptr
|
||||||
|
Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) {
|
||||||
|
|
||||||
// Is this relayed message?
|
// Is this relayed message?
|
||||||
IOAddress relay = question->getGiaddr();
|
IOAddress relay = question->getGiaddr();
|
||||||
@@ -677,7 +705,8 @@ Subnet4Ptr Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
|
void
|
||||||
|
Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
|
||||||
OptionPtr server_id = pkt->getOption(DHO_DHCP_SERVER_IDENTIFIER);
|
OptionPtr server_id = pkt->getOption(DHO_DHCP_SERVER_IDENTIFIER);
|
||||||
switch (serverid) {
|
switch (serverid) {
|
||||||
case FORBIDDEN:
|
case FORBIDDEN:
|
||||||
@@ -700,3 +729,6 @@ void Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace dhcp
|
||||||
|
} // namespace isc
|
||||||
|
@@ -28,15 +28,6 @@
|
|||||||
namespace isc {
|
namespace isc {
|
||||||
namespace dhcp {
|
namespace dhcp {
|
||||||
|
|
||||||
/// @brief file name of a server-id file
|
|
||||||
///
|
|
||||||
/// Server must store its server identifier in persistent storage that must not
|
|
||||||
/// change between restarts. This is name of the file that is created in dataDir
|
|
||||||
/// (see isc::dhcp::CfgMgr::getDataDir()). It is a text file that uses
|
|
||||||
/// regular IPv4 address, e.g. 192.0.2.1. Server will create it during
|
|
||||||
/// first run and then use it afterwards.
|
|
||||||
static const char* SERVER_ID_FILE = "b10-dhcp4-serverid";
|
|
||||||
|
|
||||||
/// @brief DHCPv4 server service.
|
/// @brief DHCPv4 server service.
|
||||||
///
|
///
|
||||||
/// This singleton class represents DHCPv4 server. It contains all
|
/// This singleton class represents DHCPv4 server. It contains all
|
||||||
|
@@ -34,6 +34,10 @@ AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
|
|||||||
CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
|
CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
|
||||||
|
|
||||||
AM_CXXFLAGS = $(B10_CXXFLAGS)
|
AM_CXXFLAGS = $(B10_CXXFLAGS)
|
||||||
|
if USE_CLANGPP
|
||||||
|
# Disable unused parameter warning caused by some Boost headers when compiling with clang
|
||||||
|
AM_CXXFLAGS += -Wno-unused-parameter
|
||||||
|
endif
|
||||||
|
|
||||||
if USE_STATIC_LINK
|
if USE_STATIC_LINK
|
||||||
AM_LDFLAGS = -static
|
AM_LDFLAGS = -static
|
||||||
@@ -56,12 +60,6 @@ dhcp4_unittests_SOURCES += ctrl_dhcp4_srv_unittest.cc
|
|||||||
dhcp4_unittests_SOURCES += config_parser_unittest.cc
|
dhcp4_unittests_SOURCES += config_parser_unittest.cc
|
||||||
nodist_dhcp4_unittests_SOURCES = ../dhcp4_messages.h ../dhcp4_messages.cc
|
nodist_dhcp4_unittests_SOURCES = ../dhcp4_messages.h ../dhcp4_messages.cc
|
||||||
|
|
||||||
if USE_CLANGPP
|
|
||||||
# Disable unused parameter warning caused by some of the
|
|
||||||
# Boost headers when compiling with clang.
|
|
||||||
dhcp4_unittests_CXXFLAGS = -Wno-unused-parameter
|
|
||||||
endif
|
|
||||||
|
|
||||||
dhcp4_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
|
dhcp4_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
|
||||||
dhcp4_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
|
dhcp4_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
|
||||||
dhcp4_unittests_LDADD = $(GTEST_LDADD)
|
dhcp4_unittests_LDADD = $(GTEST_LDADD)
|
||||||
|
@@ -234,11 +234,13 @@ public:
|
|||||||
/// Check that address was returned from proper range, that its lease
|
/// Check that address was returned from proper range, that its lease
|
||||||
/// lifetime is correct, that T1 and T2 are returned properly
|
/// lifetime is correct, that T1 and T2 are returned properly
|
||||||
/// @param rsp response to be checked
|
/// @param rsp response to be checked
|
||||||
/// @param subnet subnet that should be used to verify assigned address and options
|
/// @param subnet subnet that should be used to verify assigned address
|
||||||
|
/// and options
|
||||||
/// @param t1_mandatory is T1 mandatory?
|
/// @param t1_mandatory is T1 mandatory?
|
||||||
/// @param t2_mandatory is T2 mandatory?
|
/// @param t2_mandatory is T2 mandatory?
|
||||||
void checkAddressParams(const Pkt4Ptr& rsp, const SubnetPtr subnet,
|
void checkAddressParams(const Pkt4Ptr& rsp, const SubnetPtr subnet,
|
||||||
bool t1_mandatory = false, bool t2_mandatory = false) {
|
bool t1_mandatory = false,
|
||||||
|
bool t2_mandatory = false) {
|
||||||
|
|
||||||
// Technically inPool implies inRange, but let's be on the safe
|
// Technically inPool implies inRange, but let's be on the safe
|
||||||
// side and check both.
|
// side and check both.
|
||||||
@@ -268,7 +270,7 @@ public:
|
|||||||
if (opt) {
|
if (opt) {
|
||||||
EXPECT_EQ(opt->getUint32(), subnet->getT2());
|
EXPECT_EQ(opt->getUint32(), subnet->getT2());
|
||||||
} else {
|
} else {
|
||||||
if (t1_mandatory) {
|
if (t2_mandatory) {
|
||||||
ADD_FAILURE() << "Required T2 option missing";
|
ADD_FAILURE() << "Required T2 option missing";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,10 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/lib/cc -I$(top_builddir)/src/lib/cc
|
|||||||
AM_CPPFLAGS += $(BOOST_INCLUDES)
|
AM_CPPFLAGS += $(BOOST_INCLUDES)
|
||||||
|
|
||||||
AM_CXXFLAGS = $(B10_CXXFLAGS)
|
AM_CXXFLAGS = $(B10_CXXFLAGS)
|
||||||
|
if USE_CLANGPP
|
||||||
|
# Disable unused parameter warning caused by some Boost headers when compiling with clang
|
||||||
|
AM_CXXFLAGS += -Wno-unused-parameter
|
||||||
|
endif
|
||||||
|
|
||||||
if USE_STATIC_LINK
|
if USE_STATIC_LINK
|
||||||
AM_LDFLAGS = -static
|
AM_LDFLAGS = -static
|
||||||
@@ -53,12 +57,6 @@ b10_dhcp6_SOURCES += dhcp6_srv.cc dhcp6_srv.h
|
|||||||
nodist_b10_dhcp6_SOURCES = dhcp6_messages.h dhcp6_messages.cc
|
nodist_b10_dhcp6_SOURCES = dhcp6_messages.h dhcp6_messages.cc
|
||||||
EXTRA_DIST += dhcp6_messages.mes
|
EXTRA_DIST += dhcp6_messages.mes
|
||||||
|
|
||||||
if USE_CLANGPP
|
|
||||||
# Disable unused parameter warning caused by some of the
|
|
||||||
# Boost headers when compiling with clang.
|
|
||||||
b10_dhcp6_CXXFLAGS = -Wno-unused-parameter
|
|
||||||
endif
|
|
||||||
|
|
||||||
b10_dhcp6_LDADD = $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
|
b10_dhcp6_LDADD = $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
|
||||||
b10_dhcp6_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
|
b10_dhcp6_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
|
||||||
b10_dhcp6_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
|
b10_dhcp6_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
|
||||||
|
@@ -996,13 +996,13 @@ public:
|
|||||||
return (new OptionDataListParser(param_name));
|
return (new OptionDataListParser(param_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pointer to options instances storage.
|
||||||
|
OptionStorage* options_;
|
||||||
/// Intermediate option storage. This storage is used by
|
/// Intermediate option storage. This storage is used by
|
||||||
/// lower level parsers to add new options. Values held
|
/// lower level parsers to add new options. Values held
|
||||||
/// in this storage are assigned to main storage (options_)
|
/// in this storage are assigned to main storage (options_)
|
||||||
/// if overall parsing was successful.
|
/// if overall parsing was successful.
|
||||||
OptionStorage local_options_;
|
OptionStorage local_options_;
|
||||||
/// Pointer to options instances storage.
|
|
||||||
OptionStorage* options_;
|
|
||||||
/// Collection of parsers;
|
/// Collection of parsers;
|
||||||
ParserCollection parsers_;
|
ParserCollection parsers_;
|
||||||
};
|
};
|
||||||
|
@@ -56,6 +56,16 @@ using namespace std;
|
|||||||
namespace isc {
|
namespace isc {
|
||||||
namespace dhcp {
|
namespace dhcp {
|
||||||
|
|
||||||
|
/// @brief file name of a server-id file
|
||||||
|
///
|
||||||
|
/// Server must store its duid in persistent storage that must not change
|
||||||
|
/// between restarts. This is name of the file that is created in dataDir
|
||||||
|
/// (see isc::dhcp::CfgMgr::getDataDir()). It is a text file that uses
|
||||||
|
/// double digit hex values separated by colons format, e.g.
|
||||||
|
/// 01:ff:02:03:06:80:90:ab:cd:ef. Server will create it during first
|
||||||
|
/// run and then use it afterwards.
|
||||||
|
static const char* SERVER_DUID_FILE = "b10-dhcp6-serverid";
|
||||||
|
|
||||||
Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
|
Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
|
||||||
: alloc_engine_(), serverid_(), shutdown_(true) {
|
: alloc_engine_(), serverid_(), shutdown_(true) {
|
||||||
|
|
||||||
@@ -256,7 +266,8 @@ bool Dhcpv6Srv::loadServerID(const std::string& file_name) {
|
|||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Dhcpv6Srv::duidToString(const OptionPtr& opt) {
|
std::string
|
||||||
|
Dhcpv6Srv::duidToString(const OptionPtr& opt) {
|
||||||
stringstream tmp;
|
stringstream tmp;
|
||||||
|
|
||||||
OptionBuffer data = opt->getData();
|
OptionBuffer data = opt->getData();
|
||||||
@@ -275,16 +286,19 @@ std::string Dhcpv6Srv::duidToString(const OptionPtr& opt) {
|
|||||||
return tmp.str();
|
return tmp.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dhcpv6Srv::writeServerID(const std::string& file_name) {
|
bool
|
||||||
|
Dhcpv6Srv::writeServerID(const std::string& file_name) {
|
||||||
fstream f(file_name.c_str(), ios::out | ios::trunc);
|
fstream f(file_name.c_str(), ios::out | ios::trunc);
|
||||||
if (!f.good()) {
|
if (!f.good()) {
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
f << duidToString(getServerID());
|
f << duidToString(getServerID());
|
||||||
f.close();
|
f.close();
|
||||||
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv6Srv::generateServerID() {
|
void
|
||||||
|
Dhcpv6Srv::generateServerID() {
|
||||||
|
|
||||||
/// @todo: This code implements support for DUID-LLT (the recommended one).
|
/// @todo: This code implements support for DUID-LLT (the recommended one).
|
||||||
/// We should eventually add support for other DUID types: DUID-LL, DUID-EN
|
/// We should eventually add support for other DUID types: DUID-LL, DUID-EN
|
||||||
@@ -367,7 +381,8 @@ void Dhcpv6Srv::generateServerID() {
|
|||||||
srvid.begin(), srvid.end()));
|
srvid.begin(), srvid.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
void
|
||||||
|
Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
||||||
// Add client-id.
|
// Add client-id.
|
||||||
OptionPtr clientid = question->getOption(D6O_CLIENTID);
|
OptionPtr clientid = question->getOption(D6O_CLIENTID);
|
||||||
if (clientid) {
|
if (clientid) {
|
||||||
@@ -377,7 +392,8 @@ void Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
|||||||
// TODO: Should throw if there is no client-id (except anonymous INF-REQUEST)
|
// TODO: Should throw if there is no client-id (except anonymous INF-REQUEST)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv6Srv::appendDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
void
|
||||||
|
Dhcpv6Srv::appendDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
||||||
// add server-id
|
// add server-id
|
||||||
answer->addOption(getServerID());
|
answer->addOption(getServerID());
|
||||||
|
|
||||||
@@ -393,7 +409,8 @@ void Dhcpv6Srv::appendDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
void
|
||||||
|
Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
||||||
// Get the subnet for a particular address.
|
// Get the subnet for a particular address.
|
||||||
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(question->getRemoteAddr());
|
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(question->getRemoteAddr());
|
||||||
if (!subnet) {
|
if (!subnet) {
|
||||||
@@ -420,7 +437,8 @@ void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionPtr Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
|
OptionPtr
|
||||||
|
Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
|
||||||
// @todo This function uses OptionCustom class to manage contents
|
// @todo This function uses OptionCustom class to manage contents
|
||||||
// of the data fields. Since this this option is frequently used
|
// of the data fields. Since this this option is frequently used
|
||||||
// it may be good to implement dedicated class to avoid performance
|
// it may be good to implement dedicated class to avoid performance
|
||||||
@@ -446,7 +464,8 @@ OptionPtr Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
|
|||||||
return (option_status);
|
return (option_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv6Srv::sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
|
void
|
||||||
|
Dhcpv6Srv::sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
|
||||||
RequirementLevel serverid) {
|
RequirementLevel serverid) {
|
||||||
Option::OptionCollection client_ids = pkt->getOptions(D6O_CLIENTID);
|
Option::OptionCollection client_ids = pkt->getOptions(D6O_CLIENTID);
|
||||||
switch (clientid) {
|
switch (clientid) {
|
||||||
@@ -494,7 +513,8 @@ void Dhcpv6Srv::sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Subnet6Ptr Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
|
Subnet6Ptr
|
||||||
|
Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
|
||||||
|
|
||||||
/// @todo: pass interface information only if received direct (non-relayed) message
|
/// @todo: pass interface information only if received direct (non-relayed) message
|
||||||
|
|
||||||
@@ -510,7 +530,8 @@ Subnet6Ptr Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
|
|||||||
return (subnet);
|
return (subnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
void
|
||||||
|
Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
||||||
|
|
||||||
// We need to allocate addresses for all IA_NA options in the client's
|
// We need to allocate addresses for all IA_NA options in the client's
|
||||||
// question (i.e. SOLICIT or REQUEST) message.
|
// question (i.e. SOLICIT or REQUEST) message.
|
||||||
@@ -579,7 +600,8 @@ void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionPtr Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
OptionPtr
|
||||||
|
Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
||||||
Pkt6Ptr question, boost::shared_ptr<Option6IA> ia) {
|
Pkt6Ptr question, boost::shared_ptr<Option6IA> ia) {
|
||||||
// If there is no subnet selected for handling this IA_NA, the only thing to do left is
|
// If there is no subnet selected for handling this IA_NA, the only thing to do left is
|
||||||
// to say that we are sorry, but the user won't get an address. As a convenience, we
|
// to say that we are sorry, but the user won't get an address. As a convenience, we
|
||||||
@@ -675,8 +697,9 @@ OptionPtr Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
|||||||
return (ia_rsp);
|
return (ia_rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionPtr Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
OptionPtr
|
||||||
Pkt6Ptr question, boost::shared_ptr<Option6IA> ia) {
|
Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
||||||
|
Pkt6Ptr /* question */, boost::shared_ptr<Option6IA> ia) {
|
||||||
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(*duid, ia->getIAID(),
|
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(*duid, ia->getIAID(),
|
||||||
subnet->getID());
|
subnet->getID());
|
||||||
|
|
||||||
@@ -719,7 +742,8 @@ OptionPtr Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
|||||||
return (ia_rsp);
|
return (ia_rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply) {
|
void
|
||||||
|
Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply) {
|
||||||
|
|
||||||
// We need to renew addresses for all IA_NA options in the client's
|
// We need to renew addresses for all IA_NA options in the client's
|
||||||
// RENEW message.
|
// RENEW message.
|
||||||
@@ -775,7 +799,8 @@ void Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dhcpv6Srv::releaseLeases(const Pkt6Ptr& release, Pkt6Ptr& reply) {
|
void
|
||||||
|
Dhcpv6Srv::releaseLeases(const Pkt6Ptr& release, Pkt6Ptr& reply) {
|
||||||
|
|
||||||
// We need to release addresses for all IA_NA options in the client's
|
// We need to release addresses for all IA_NA options in the client's
|
||||||
// RELEASE message.
|
// RELEASE message.
|
||||||
@@ -831,9 +856,9 @@ void Dhcpv6Srv::releaseLeases(const Pkt6Ptr& release, Pkt6Ptr& reply) {
|
|||||||
"Summary status for all processed IA_NAs"));
|
"Summary status for all processed IA_NAs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionPtr Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, Pkt6Ptr question,
|
OptionPtr
|
||||||
int& general_status,
|
Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, Pkt6Ptr /* question */,
|
||||||
boost::shared_ptr<Option6IA> ia) {
|
int& general_status, boost::shared_ptr<Option6IA> ia) {
|
||||||
// Release can be done in one of two ways:
|
// Release can be done in one of two ways:
|
||||||
// Approach 1: extract address from client's IA_NA and see if it belongs
|
// Approach 1: extract address from client's IA_NA and see if it belongs
|
||||||
// to this particular client.
|
// to this particular client.
|
||||||
@@ -942,8 +967,8 @@ OptionPtr Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, Pkt6Ptr question,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pkt6Ptr
|
||||||
Pkt6Ptr Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
|
Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
|
||||||
|
|
||||||
sanityCheck(solicit, MANDATORY, FORBIDDEN);
|
sanityCheck(solicit, MANDATORY, FORBIDDEN);
|
||||||
|
|
||||||
@@ -958,7 +983,8 @@ Pkt6Ptr Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
|
|||||||
return (advertise);
|
return (advertise);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt6Ptr Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
|
Pkt6Ptr
|
||||||
|
Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
|
||||||
|
|
||||||
sanityCheck(request, MANDATORY, MANDATORY);
|
sanityCheck(request, MANDATORY, MANDATORY);
|
||||||
|
|
||||||
@@ -973,7 +999,8 @@ Pkt6Ptr Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
|
|||||||
return (reply);
|
return (reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt6Ptr Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
|
Pkt6Ptr
|
||||||
|
Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
|
||||||
|
|
||||||
sanityCheck(renew, MANDATORY, MANDATORY);
|
sanityCheck(renew, MANDATORY, MANDATORY);
|
||||||
|
|
||||||
@@ -988,19 +1015,22 @@ Pkt6Ptr Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt6Ptr Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind) {
|
Pkt6Ptr
|
||||||
|
Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind) {
|
||||||
/// @todo: Implement this
|
/// @todo: Implement this
|
||||||
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, rebind->getTransid()));
|
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, rebind->getTransid()));
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt6Ptr Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) {
|
Pkt6Ptr
|
||||||
|
Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) {
|
||||||
/// @todo: Implement this
|
/// @todo: Implement this
|
||||||
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, confirm->getTransid()));
|
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, confirm->getTransid()));
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt6Ptr Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
|
Pkt6Ptr
|
||||||
|
Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
|
||||||
|
|
||||||
sanityCheck(release, MANDATORY, MANDATORY);
|
sanityCheck(release, MANDATORY, MANDATORY);
|
||||||
|
|
||||||
@@ -1014,13 +1044,15 @@ Pkt6Ptr Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt6Ptr Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) {
|
Pkt6Ptr
|
||||||
|
Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) {
|
||||||
/// @todo: Implement this
|
/// @todo: Implement this
|
||||||
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, decline->getTransid()));
|
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, decline->getTransid()));
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pkt6Ptr Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
|
Pkt6Ptr
|
||||||
|
Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
|
||||||
/// @todo: Implement this
|
/// @todo: Implement this
|
||||||
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, infRequest->getTransid()));
|
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, infRequest->getTransid()));
|
||||||
return reply;
|
return reply;
|
||||||
|
@@ -31,16 +31,6 @@
|
|||||||
namespace isc {
|
namespace isc {
|
||||||
namespace dhcp {
|
namespace dhcp {
|
||||||
|
|
||||||
/// @brief file name of a server-id file
|
|
||||||
///
|
|
||||||
/// Server must store its duid in persistent storage that must not change
|
|
||||||
/// between restarts. This is name of the file that is created in dataDir
|
|
||||||
/// (see isc::dhcp::CfgMgr::getDataDir()). It is a text file that uses
|
|
||||||
/// double digit hex values separated by colons format, e.g.
|
|
||||||
/// 01:ff:02:03:06:80:90:ab:cd:ef. Server will create it during first
|
|
||||||
/// run and then use it afterwards.
|
|
||||||
static const char* SERVER_DUID_FILE = "b10-dhcp6-serverid";
|
|
||||||
|
|
||||||
/// @brief DHCPv6 server service.
|
/// @brief DHCPv6 server service.
|
||||||
///
|
///
|
||||||
/// This class represents DHCPv6 server. It contains all
|
/// This class represents DHCPv6 server. It contains all
|
||||||
|
@@ -30,6 +30,10 @@ AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
|
|||||||
CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
|
CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
|
||||||
|
|
||||||
AM_CXXFLAGS = $(B10_CXXFLAGS)
|
AM_CXXFLAGS = $(B10_CXXFLAGS)
|
||||||
|
if USE_CLANGPP
|
||||||
|
# Disable unused parameter warning caused by some Boost headers when compiling with clang
|
||||||
|
AM_CXXFLAGS += -Wno-unused-parameter
|
||||||
|
endif
|
||||||
|
|
||||||
if USE_STATIC_LINK
|
if USE_STATIC_LINK
|
||||||
AM_LDFLAGS = -static
|
AM_LDFLAGS = -static
|
||||||
@@ -53,12 +57,6 @@ dhcp6_unittests_SOURCES += ../ctrl_dhcp6_srv.cc
|
|||||||
dhcp6_unittests_SOURCES += ../config_parser.cc ../config_parser.h
|
dhcp6_unittests_SOURCES += ../config_parser.cc ../config_parser.h
|
||||||
nodist_dhcp6_unittests_SOURCES = ../dhcp6_messages.h ../dhcp6_messages.cc
|
nodist_dhcp6_unittests_SOURCES = ../dhcp6_messages.h ../dhcp6_messages.cc
|
||||||
|
|
||||||
if USE_CLANGPP
|
|
||||||
# Disable unused parameter warning caused by some of the
|
|
||||||
# Boost headers when compiling with clang.
|
|
||||||
dhcp6_unittests_CXXFLAGS = -Wno-unused-parameter
|
|
||||||
endif
|
|
||||||
|
|
||||||
dhcp6_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
|
dhcp6_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
|
||||||
dhcp6_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
|
dhcp6_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
|
||||||
dhcp6_unittests_LDADD = $(GTEST_LDADD)
|
dhcp6_unittests_LDADD = $(GTEST_LDADD)
|
||||||
|
@@ -277,9 +277,9 @@ public:
|
|||||||
expected_data_len));
|
expected_data_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rcode_;
|
||||||
Dhcpv6Srv srv_;
|
Dhcpv6Srv srv_;
|
||||||
|
|
||||||
int rcode_;
|
|
||||||
ConstElementPtr comment_;
|
ConstElementPtr comment_;
|
||||||
|
|
||||||
string valid_iface_;
|
string valid_iface_;
|
||||||
|
@@ -222,7 +222,8 @@ public:
|
|||||||
// Check that generated IAADDR option contains expected address.
|
// Check that generated IAADDR option contains expected address.
|
||||||
void checkIAAddr(const boost::shared_ptr<Option6IAAddr>& addr,
|
void checkIAAddr(const boost::shared_ptr<Option6IAAddr>& addr,
|
||||||
const IOAddress& expected_addr,
|
const IOAddress& expected_addr,
|
||||||
uint32_t expected_preferred, uint32_t expected_valid) {
|
uint32_t /* expected_preferred */,
|
||||||
|
uint32_t /* expected_valid */) {
|
||||||
|
|
||||||
// Check that the assigned address is indeed from the configured pool.
|
// Check that the assigned address is indeed from the configured pool.
|
||||||
// Note that when comparing addresses, we compare the textual
|
// Note that when comparing addresses, we compare the textual
|
||||||
|
Reference in New Issue
Block a user