Commit 4b644a94 authored by Francis Dupont's avatar Francis Dupont
Browse files

[4097a] Changed classSpecificProcessing to be applied only to requested options

parent 01dd8b4f
......@@ -2374,6 +2374,18 @@ Dhcpv4Srv::classSpecificProcessing(const Dhcpv4Exchange& ex) {
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();
......@@ -2385,20 +2397,17 @@ Dhcpv4Srv::classSpecificProcessing(const Dhcpv4Exchange& ex) {
// Not found
continue;
}
// Get the configured options of this class
const OptionContainerPtr& options = ccdef->getCfgOption()->getAll("dhcp4");
if (!options || options->empty()) {
continue;
}
// Go through each OptionDescriptor
for (OptionContainer::const_iterator desc = options->begin();
desc != options->end(); ++desc) {
OptionPtr opt = desc->option_;
// Add the option if it doesn't exist yet
if (!rsp->getOption(opt->getType())) {
rsp->addOption(opt);
}
}
// 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);
......
......@@ -1711,24 +1711,39 @@ TEST_F(Dhcpv4SrvTest, matchClassification) {
query1->setRemoteAddr(IOAddress("192.0.2.1"));
Pkt4Ptr query2(new Pkt4(DHCPDISCOVER, 1234));
query2->setRemoteAddr(IOAddress("192.0.2.1"));
Pkt4Ptr query3(new Pkt4(DHCPDISCOVER, 1234));
query3->setRemoteAddr(IOAddress("192.0.2.1"));
// Create and add a host-name option to the first query
// Create and add a PRL option to the first 2 queries
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
DHO_DHCP_PARAMETER_REQUEST_LIST));
ASSERT_TRUE(prl);
prl->addValue(DHO_IP_FORWARDING);
query1->addOption(prl);
query2->addOption(prl);
// Create and add a host-name option to the first and last queries
OptionStringPtr hostname(new OptionString(Option::V4, 12, "foo"));
ASSERT_TRUE(hostname);
query1->addOption(hostname);
query3->addOption(hostname);
// Classify packets
srv.classifyPacket(query1);
srv.classifyPacket(query2);
srv.classifyPacket(query3);
// The first packet (and only the first) should be in the router class
// Packets at the exception of the second should be in the router class
EXPECT_TRUE(query1->inClass("router"));
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();
// Classification processing should add an ip-forwarding option
srv.classSpecificProcessing(ex1);
......@@ -1739,6 +1754,11 @@ TEST_F(Dhcpv4SrvTest, matchClassification) {
srv.classSpecificProcessing(ex2);
OptionPtr opt2 = response2->getOption(DHO_IP_FORWARDING);
EXPECT_FALSE(opt2);
// But only for the first exchange
srv.classSpecificProcessing(ex3);
OptionPtr opt3 = response3->getOption(DHO_IP_FORWARDING);
EXPECT_FALSE(opt3);
}
// Checks subnet options have the priority over class options
......
Supports Markdown
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