Browse Source

[2949] Inf-request support implemented.

Tomek Mrugalski 10 years ago
parent
commit
916efc406a
1 changed files with 34 additions and 14 deletions
  1. 34 14
      src/bin/dhcp6/dhcp6_srv.cc

+ 34 - 14
src/bin/dhcp6/dhcp6_srv.cc

@@ -724,29 +724,43 @@ Dhcpv6Srv::appendDefaultOptions(const Pkt6Ptr&, Pkt6Ptr& answer) {
 
 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_);
         }
@@ -2450,8 +2464,14 @@ Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) {
 
 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;
 }