Commit b925400a authored by Francis Dupont's avatar Francis Dupont

[4097a] Introduce CfgOptionList and use it for the 3 append/getCfgOption() methods

parent 102820fc
...@@ -821,6 +821,37 @@ Dhcpv4Srv::appendServerID(Dhcpv4Exchange& ex) { ...@@ -821,6 +821,37 @@ Dhcpv4Srv::appendServerID(Dhcpv4Exchange& ex) {
ex.getResponse()->addOption(opt_srvid); ex.getResponse()->addOption(opt_srvid);
} }
void
Dhcpv4Srv::buildCfgOptionList(Dhcpv4Exchange& ex) {
CfgOptionList& co_list = ex.getCfgOptionList();
// First subnet configured options
Subnet4Ptr subnet = ex.getContext()->subnet_;
if (subnet) {
co_list.push_back(subnet->getCfgOption());
}
// Each class in the incoming packet
const ClientClasses& classes = ex.getQuery()->getClasses();
for (ClientClasses::const_iterator cclass = classes.begin();
cclass != classes.end(); ++cclass) {
// Find the client class definition for this class
const ClientClassDefPtr& ccdef = CfgMgr::instance().getCurrentCfg()->
getClientClassDictionary()->findClass(*cclass);
if (!ccdef) {
// Not found: the class is not configured
LOG_DEBUG(options4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_UNCONFIGURED)
.arg(ex.getQuery()->getLabel())
.arg(*cclass);
continue;
}
co_list.push_back(ccdef->getCfgOption());
}
// Last global options
co_list.push_back(CfgMgr::instance().getCurrentCfg()->getCfgOption());
}
void void
Dhcpv4Srv::appendRequestedOptions(Dhcpv4Exchange& ex) { Dhcpv4Srv::appendRequestedOptions(Dhcpv4Exchange& ex) {
// Get the subnet relevant for the client. We will need it // Get the subnet relevant for the client. We will need it
...@@ -854,36 +885,17 @@ Dhcpv4Srv::appendRequestedOptions(Dhcpv4Exchange& ex) { ...@@ -854,36 +885,17 @@ Dhcpv4Srv::appendRequestedOptions(Dhcpv4Exchange& ex) {
// to be returned to the client. // to be returned to the client.
for (std::vector<uint8_t>::const_iterator opt = requested_opts.begin(); for (std::vector<uint8_t>::const_iterator opt = requested_opts.begin();
opt != requested_opts.end(); ++opt) { opt != requested_opts.end(); ++opt) {
// Add nothing when it is already there
if (!resp->getOption(*opt)) { if (!resp->getOption(*opt)) {
OptionDescriptor desc = subnet->getCfgOption()->get("dhcp4", *opt); const CfgOptionList& co_list = ex.getCfgOptionList();
if (desc.option_) { // Iterate on the configured option list
resp->addOption(desc.option_); for (CfgOptionList::const_iterator copts = co_list.begin();
} copts != co_list.end(); ++copts) {
} OptionDescriptor desc = (*copts)->get("dhcp4", *opt);
} // Got it: add it and jump to the outer loop
// Process each class in the packet
const ClientClasses& classes = query->getClasses();
for (ClientClasses::const_iterator cclass = classes.begin();
cclass != classes.end(); ++cclass) {
// Find the client class definition for this class
const ClientClassDefPtr& ccdef = CfgMgr::instance().getCurrentCfg()->
getClientClassDictionary()->findClass(*cclass);
if (!ccdef) {
// Not found: the class is not configured
LOG_DEBUG(options4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_UNCONFIGURED)
.arg(query->getLabel())
.arg(*cclass);
continue;
}
// For each requested option code get the instance of the option
// in the class to be returned to the client.
for (std::vector<uint8_t>::const_iterator opt = requested_opts.begin();
opt != requested_opts.end(); ++opt) {
if (!resp->getOption(*opt)) {
OptionDescriptor desc = ccdef->getCfgOption()->get("dhcp4", *opt);
if (desc.option_) { if (desc.option_) {
resp->addOption(desc.option_); resp->addOption(desc.option_);
break;
} }
} }
} }
...@@ -932,11 +944,15 @@ Dhcpv4Srv::appendRequestedVendorOptions(Dhcpv4Exchange& ex) { ...@@ -932,11 +944,15 @@ Dhcpv4Srv::appendRequestedVendorOptions(Dhcpv4Exchange& ex) {
for (std::vector<uint8_t>::const_iterator code = requested_opts.begin(); for (std::vector<uint8_t>::const_iterator code = requested_opts.begin();
code != requested_opts.end(); ++code) { code != requested_opts.end(); ++code) {
if (!vendor_rsp->getOption(*code)) { if (!vendor_rsp->getOption(*code)) {
OptionDescriptor desc = subnet->getCfgOption()->get(vendor_id, const CfgOptionList& co_list = ex.getCfgOptionList();
*code); for (CfgOptionList::const_iterator copts = co_list.begin();
if (desc.option_) { copts != co_list.end(); ++copts) {
vendor_rsp->addOption(desc.option_); OptionDescriptor desc = (*copts)->get(vendor_id, *code);
added = true; if (desc.option_) {
vendor_rsp->addOption(desc.option_);
added = true;
break;
}
} }
} }
...@@ -973,10 +989,14 @@ Dhcpv4Srv::appendBasicOptions(Dhcpv4Exchange& ex) { ...@@ -973,10 +989,14 @@ Dhcpv4Srv::appendBasicOptions(Dhcpv4Exchange& ex) {
OptionPtr opt = resp->getOption(required_options[i]); OptionPtr opt = resp->getOption(required_options[i]);
if (!opt) { if (!opt) {
// Check whether option has been configured. // Check whether option has been configured.
OptionDescriptor desc = subnet->getCfgOption()-> const CfgOptionList& co_list = ex.getCfgOptionList();
get("dhcp4", required_options[i]); for (CfgOptionList::const_iterator copts = co_list.begin();
if (desc.option_) { copts != co_list.end(); ++copts) {
resp->addOption(desc.option_); OptionDescriptor desc = (*copts)->get("dhcp4", required_options[i]);
if (desc.option_) {
resp->addOption(desc.option_);
break;
}
} }
} }
} }
...@@ -1617,6 +1637,7 @@ Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) { ...@@ -1617,6 +1637,7 @@ Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
// Adding any other options makes sense only when we got the lease. // Adding any other options makes sense only when we got the lease.
if (!ex.getResponse()->getYiaddr().isV4Zero()) { if (!ex.getResponse()->getYiaddr().isV4Zero()) {
buildCfgOptionList(ex);
appendRequestedOptions(ex); appendRequestedOptions(ex);
appendRequestedVendorOptions(ex); appendRequestedVendorOptions(ex);
// There are a few basic options that we always want to // There are a few basic options that we always want to
...@@ -1672,6 +1693,7 @@ Dhcpv4Srv::processRequest(Pkt4Ptr& request) { ...@@ -1672,6 +1693,7 @@ Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
// Adding any other options makes sense only when we got the lease. // Adding any other options makes sense only when we got the lease.
if (!ex.getResponse()->getYiaddr().isV4Zero()) { if (!ex.getResponse()->getYiaddr().isV4Zero()) {
buildCfgOptionList(ex);
appendRequestedOptions(ex); appendRequestedOptions(ex);
appendRequestedVendorOptions(ex); appendRequestedVendorOptions(ex);
// There are a few basic options that we always want to // There are a few basic options that we always want to
...@@ -1951,6 +1973,7 @@ Dhcpv4Srv::processInform(Pkt4Ptr& inform) { ...@@ -1951,6 +1973,7 @@ Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
Pkt4Ptr ack = ex.getResponse(); Pkt4Ptr ack = ex.getResponse();
buildCfgOptionList(ex);
appendRequestedOptions(ex); appendRequestedOptions(ex);
appendRequestedVendorOptions(ex); appendRequestedVendorOptions(ex);
appendBasicOptions(ex); appendBasicOptions(ex);
...@@ -2380,15 +2403,19 @@ Dhcpv4Srv::vendorClassSpecificProcessing(const Dhcpv4Exchange& ex) { ...@@ -2380,15 +2403,19 @@ Dhcpv4Srv::vendorClassSpecificProcessing(const Dhcpv4Exchange& ex) {
// Now try to set up file field in DHCPv4 packet. We will just copy // Now try to set up file field in DHCPv4 packet. We will just copy
// content of the boot-file option, which contains the same information. // content of the boot-file option, which contains the same information.
OptionDescriptor desc = subnet->getCfgOption()-> const CfgOptionList& co_list = ex.getCfgOptionList();
get("dhcp4", DHO_BOOT_FILE_NAME); for (CfgOptionList::const_iterator copts = co_list.begin();
copts != co_list.end(); ++copts) {
if (desc.option_) { OptionDescriptor desc = (*copts)->get("dhcp4", DHO_BOOT_FILE_NAME);
boost::shared_ptr<OptionString> boot =
boost::dynamic_pointer_cast<OptionString>(desc.option_); if (desc.option_) {
if (boot) { boost::shared_ptr<OptionString> boot =
std::string filename = boot->getValue(); boost::dynamic_pointer_cast<OptionString>(desc.option_);
rsp->setFile((const uint8_t*)filename.c_str(), filename.size()); if (boot) {
std::string filename = boot->getValue();
rsp->setFile((const uint8_t*)filename.c_str(), filename.size());
break;
}
} }
} }
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <dhcpsrv/d2_client_mgr.h> #include <dhcpsrv/d2_client_mgr.h>
#include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet.h>
#include <dhcpsrv/alloc_engine.h> #include <dhcpsrv/alloc_engine.h>
#include <dhcpsrv/cfg_option.h>
#include <hooks/callout_handle.h> #include <hooks/callout_handle.h>
#include <dhcpsrv/daemon.h> #include <dhcpsrv/daemon.h>
...@@ -110,6 +111,16 @@ public: ...@@ -110,6 +111,16 @@ public:
return (context_); return (context_);
} }
/// @brief Returns the configured option list
CfgOptionList& getCfgOptionList() {
return (cfg_option_list_);
}
/// @brief Returns the configured option list
const CfgOptionList& getCfgOptionList() const {
return (cfg_option_list_);
}
private: private:
/// @brief Copies default parameters from client's to server's message /// @brief Copies default parameters from client's to server's message
...@@ -142,6 +153,8 @@ private: ...@@ -142,6 +153,8 @@ private:
Pkt4Ptr resp_; Pkt4Ptr resp_;
/// @brief Context for use with allocation engine. /// @brief Context for use with allocation engine.
AllocEngine::ClientContext4Ptr context_; AllocEngine::ClientContext4Ptr context_;
/// @brief Configured option list for appending otions.
CfgOptionList cfg_option_list_;
}; };
/// @brief Type representing the pointer to the @c Dhcpv4Exchange. /// @brief Type representing the pointer to the @c Dhcpv4Exchange.
...@@ -422,6 +435,14 @@ protected: ...@@ -422,6 +435,14 @@ protected:
/// @return DHCPACK to be sent to the client. /// @return DHCPACK to be sent to the client.
Pkt4Ptr processInform(Pkt4Ptr& inform); Pkt4Ptr processInform(Pkt4Ptr& inform);
/// @brief Build the configured option list
///
/// @note The configured option list is an *ordered* list of
/// @c CfgOption objects used to append options to the response.
///
/// @param ex The exchange where the configured option list is cached
void buildCfgOptionList(Dhcpv4Exchange& ex);
/// @brief Appends options requested by client. /// @brief Appends options requested by client.
/// ///
/// This method assigns options that were requested by client /// This method assigns options that were requested by client
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <set> #include <set>
#include <list>
namespace isc { namespace isc {
namespace dhcp { namespace dhcp {
...@@ -407,6 +408,9 @@ typedef boost::shared_ptr<CfgOption> CfgOptionPtr; ...@@ -407,6 +408,9 @@ typedef boost::shared_ptr<CfgOption> CfgOptionPtr;
/// @brief Const pointer. /// @brief Const pointer.
typedef boost::shared_ptr<const CfgOption> ConstCfgOptionPtr; typedef boost::shared_ptr<const CfgOption> ConstCfgOptionPtr;
/// @brief Const pointer list.
typedef std::list<ConstCfgOptionPtr> CfgOptionList;
//@} //@}
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment