void
Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
- // Get the configured subnet suitable for the incoming packet.
- Subnet6Ptr subnet = selectSubnet(question);
- // Leave if there is no subnet matching the incoming packet.
- // There is no need to log the error message here because
- // it will be logged in the assignLease() when it fails to
- // pick the suitable subnet. We don't want to duplicate
- // error messages in such case.
- if (!subnet) {
- return;
- }
// Client requests some options using ORO option. Try to
// get this option from client's message.
boost::shared_ptr<OptionIntArray<uint16_t> > option_oro =
- boost::dynamic_pointer_cast<OptionIntArray<uint16_t> >(question->getOption(D6O_ORO));
- // Option ORO not found. Don't do anything then.
+ boost::dynamic_pointer_cast<OptionIntArray<uint16_t> >
+ (question->getOption(D6O_ORO));
+
+ // Option ORO not found? We're done here then.
if (!option_oro) {
return;
}
+
+ // Get global option definitions (i.e. options defined to apply to all,
+ // unless overwritten on a subnet or host level)
+ ConstCfgOptionPtr global_opts = CfgMgr::instance().getCurrentCfg()->
+ getCfgOption();
+
+ // Get the configured subnet suitable for the incoming packet.
+ // It may be NULL (if server is misconfigured or the client was rejected
+ // using client classes).
+ Subnet6Ptr subnet = selectSubnet(question);
+
// Get the list of options that client requested.
const std::vector<uint16_t>& requested_opts = option_oro->getValues();
BOOST_FOREACH(uint16_t opt, requested_opts) {
- OptionDescriptor desc = subnet->getCfgOption()->get("dhcp6", opt);
+ // If we found a subnet for this client, try subnet first.
+ if (subnet) {
+ OptionDescriptor desc = subnet->getCfgOption()->get("dhcp6", opt);
+ if (desc.option_) {
+ // Attempt to assign an option from subnet first.
+ answer->addOption(desc.option_);
+ continue;
+ }
+ }
+
+ // If subnet specific option is not there, try global.
+ OptionDescriptor desc = global_opts->get("dhcp6", opt);
if (desc.option_) {
answer->addOption(desc.option_);
}
Pkt6Ptr
Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
- /// @todo: Implement this
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, infRequest->getTransid()));
+
+ copyDefaultOptions(infRequest, reply);
+
+ appendDefaultOptions(infRequest, reply);
+
+ appendRequestedOptions(infRequest, reply);
+
return reply;
}