}
}
}
+
+ // 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_) {
+ resp->addOption(desc.option_);
+ }
+ }
+ }
+ }
}
void
/// @todo: decide whether we want to add a new hook point for
/// doing class specific processing.
- if (!classSpecificProcessing(ex)) {
+ if (!vendorClassSpecificProcessing(ex)) {
/// @todo add more verbosity here
LOG_DEBUG(options4_logger, DBG_DHCP4_DETAIL, DHCP4_DISCOVER_CLASS_PROCESSING_FAILED)
.arg(discover->getLabel());
/// @todo: decide whether we want to add a new hook point for
/// doing class specific processing.
- if (!classSpecificProcessing(ex)) {
+ if (!vendorClassSpecificProcessing(ex)) {
/// @todo add more verbosity here
LOG_DEBUG(options4_logger, DBG_DHCP4_DETAIL, DHCP4_REQUEST_CLASS_PROCESSING_FAILED)
.arg(ex.getQuery()->getLabel());
/// @todo: decide whether we want to add a new hook point for
/// doing class specific processing.
- if (!classSpecificProcessing(ex)) {
+ if (!vendorClassSpecificProcessing(ex)) {
LOG_DEBUG(options4_logger, DBG_DHCP4_DETAIL,
DHCP4_INFORM_CLASS_PROCESSING_FAILED)
.arg(inform->getLabel());
}
bool
-Dhcpv4Srv::classSpecificProcessing(const Dhcpv4Exchange& ex) {
+Dhcpv4Srv::vendorClassSpecificProcessing(const Dhcpv4Exchange& ex) {
Subnet4Ptr subnet = ex.getContext()->subnet_;
Pkt4Ptr query = ex.getQuery();
return (true);
}
- // DOCSIS3 class modem specific processing
if (query->inClass(VENDOR_CLASS_PREFIX + DOCSIS3_CLASS_MODEM)) {
// Set next-server. This is TFTP server address. Cable modems will
}
}
- // DOCSIS3 class erouter specific processing
if (query->inClass(VENDOR_CLASS_PREFIX + DOCSIS3_CLASS_EROUTER)) {
// Do not set TFTP server address for eRouter devices.
rsp->setSiaddr(IOAddress::IPV4_ZERO_ADDRESS());
}
- // try to get the 'Parameter Request List' option which holds the
- // codes of requested options.
- OptionUint8ArrayPtr option_prl = boost::dynamic_pointer_cast<
- OptionUint8Array>(query->getOption(DHO_DHCP_PARAMETER_REQUEST_LIST));
- // If there is no PRL option in the message from the client then
- // there is nothing to do.
- if (!option_prl) {
- return (true);
- }
- // Get the codes of requested options.
- const std::vector<uint8_t>& requested_opts = option_prl->getValues();
-
- // 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 (!rsp->getOption(*opt)) {
- OptionDescriptor desc = ccdef->getCfgOption()->get("dhcp4", *opt);
- if (desc.option_) {
- rsp->addOption(desc.option_);
- }
- }
- }
- }
-
return (true);
}
// Checks if client packets are classified properly using match expressions.
TEST_F(Dhcpv4SrvTest, matchClassification) {
+ IfaceMgrTestConfig test_config(true);
+ IfaceMgr::instance().openSockets4();
+
NakedDhcpv4Srv srv(0);
// The router class matches incoming packets with foo in a host-name
CfgMgr::instance().commit();
// Create packets with enough to select the subnet
+ OptionPtr clientid = generateClientId();
Pkt4Ptr query1(new Pkt4(DHCPDISCOVER, 1234));
query1->setRemoteAddr(IOAddress("192.0.2.1"));
+ query1->addOption(clientid);
+ query1->setIface("eth1");
Pkt4Ptr query2(new Pkt4(DHCPDISCOVER, 1234));
query2->setRemoteAddr(IOAddress("192.0.2.1"));
+ query2->addOption(clientid);
+ query2->setIface("eth1");
Pkt4Ptr query3(new Pkt4(DHCPDISCOVER, 1234));
query3->setRemoteAddr(IOAddress("192.0.2.1"));
+ query3->addOption(clientid);
+ query3->setIface("eth1");
// Create and add a PRL option to the first 2 queries
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
EXPECT_FALSE(query2->inClass("router"));
EXPECT_TRUE(query3->inClass("router"));
- Dhcpv4Exchange ex1 = createExchange(query1);
- Pkt4Ptr response1 = ex1.getResponse();
- Dhcpv4Exchange ex2 = createExchange(query2);
- Pkt4Ptr response2 = ex2.getResponse();
- Dhcpv4Exchange ex3 = createExchange(query3);
- Pkt4Ptr response3 = ex3.getResponse();
+ // Process queries
+ Pkt4Ptr response1 = srv.processDiscover(query1);
+ Pkt4Ptr response2 = srv.processDiscover(query2);
+ Pkt4Ptr response3 = srv.processDiscover(query3);
// Classification processing should add an ip-forwarding option
- srv.classSpecificProcessing(ex1);
OptionPtr opt1 = response1->getOption(DHO_IP_FORWARDING);
EXPECT_TRUE(opt1);
- // But only for the first exchange
- srv.classSpecificProcessing(ex2);
+ // But only for the first exchange: second was not classified
OptionPtr opt2 = response2->getOption(DHO_IP_FORWARDING);
EXPECT_FALSE(opt2);
- // But only for the first exchange
- srv.classSpecificProcessing(ex3);
+ // But only for the first exchange: third has no PRL
OptionPtr opt3 = response3->getOption(DHO_IP_FORWARDING);
EXPECT_FALSE(opt3);
}