]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[master] Merge branch 'trac4626' (fixed fields in classification)
authorTomek Mrugalski <tomasz@isc.org>
Fri, 26 Aug 2016 11:41:15 +0000 (13:41 +0200)
committerTomek Mrugalski <tomasz@isc.org>
Fri, 26 Aug 2016 11:41:15 +0000 (13:41 +0200)
# Conflicts:
# src/bin/dhcp4/dhcp4_srv.cc

1  2 
doc/guide/dhcp4-srv.xml
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/dhcp4_srv.h

Simple merge
index 5d4b3d328d49fd6be562293307dadbdc3a7e41b9,18d3923794e15ce375895d2afa1fc713ee00f493..cbef75d5b64be8f56134287dff5aef1d016f58f1
@@@ -1945,6 -1927,72 +1942,76 @@@ Dhcpv4Srv::adjustRemoteAddr(Dhcpv4Excha
      }
  }
  
 -    // Step 1: try to set values using HR.
 -    /// @todo: Merge Marcin's code here.
 -
 -    // Step 2: if step 1 failed, try to set the values based on classes.
 -    const ClientClasses classes = query->getClasses();
 -    if (classes.empty()) {
 -        return;
 -    }
 -
 -    // Let's get class definitions
 -    const ClientClassDefMapPtr& defs = CfgMgr::instance().getCurrentCfg()->
 -        getClientClassDictionary()->getClasses();
 -
 -    // Now we need to iterate over the classes assigned to the
 -    // query packet and find corresponding class defintions for it.
 -    for (ClientClasses::const_iterator name = classes.begin();
 -         name != classes.end(); ++name) {
 -
 -        ClientClassDefMap::const_iterator cl = defs->find(*name);
 -        if (cl == defs->end()) {
 -            // Let's skip classes that don't have definitions. Currently
 -            // these are automatic classes VENDOR_CLASS_something, but there
 -            // may be other classes assigned under other circumstances, e.g.
 -            // by hooks.
 -            continue;
+ void
+ Dhcpv4Srv::setFixedFields(Dhcpv4Exchange& ex) {
+     Pkt4Ptr query = ex.getQuery();
+     Pkt4Ptr response = ex.getResponse();
 -        IOAddress next_server = cl->second->getNextServer();
 -        if (!next_server.isV4Zero()) {
 -            response->setSiaddr(next_server);
 -        }
++    // Step 1: Start with fixed fields defined on subnet level.
++    Subnet4Ptr subnet = ex.getContext()->subnet_;
++    if (subnet) {
++        IOAddress subnet_next_server = subnet->getSiaddr();
++        if (!subnet_next_server.isV4Zero()) {
++            response->setSiaddr(subnet_next_server);
+         }
++    }
 -        const string& sname = cl->second->getSname();
 -        if (!sname.empty()) {
 -            // Converting string to (const uint8_t*, size_t len) format is
 -            // tricky. reineterpret_cast is not the most elegant solution,
 -            // but it does avoid us making unnecessary copy. We will convert
 -            // sname and file fields in Pkt4 to string one day and live
 -            // will be easier.
 -            response->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
 -                               sname.size());
 -        }
++    // Step 2: Try to set the values based on classes.
++    // Any values defined in classes will override those from subnet level.
++    const ClientClasses classes = query->getClasses();
++    if (!classes.empty()) {
++
++        // Let's get class definitions
++        const ClientClassDefMapPtr& defs = CfgMgr::instance().getCurrentCfg()->
++            getClientClassDictionary()->getClasses();
++
++        // Now we need to iterate over the classes assigned to the
++        // query packet and find corresponding class defintions for it.
++        for (ClientClasses::const_iterator name = classes.begin();
++             name != classes.end(); ++name) {
++
++            ClientClassDefMap::const_iterator cl = defs->find(*name);
++            if (cl == defs->end()) {
++                // Let's skip classes that don't have definitions. Currently
++                // these are automatic classes VENDOR_CLASS_something, but there
++                // may be other classes assigned under other circumstances, e.g.
++                // by hooks.
++                continue;
++            }
 -        const string& filename = cl->second->getFilename();
 -        if (!filename.empty()) {
 -            // Converting string to (const uint8_t*, size_t len) format is
 -            // tricky. reineterpret_cast is not the most elegant solution,
 -            // but it does avoid us making unnecessary copy. We will convert
 -            // sname and file fields in Pkt4 to string one day and live
 -            // will be easier.
 -            response->setFile(reinterpret_cast<const uint8_t*>(filename.c_str()),
 -                              filename.size());
++            IOAddress next_server = cl->second->getNextServer();
++            if (!next_server.isV4Zero()) {
++                response->setSiaddr(next_server);
++            }
 -    // Step 3: Finally, set the values based on subnet values.
 -    /// @todo implement this.
 -
 -    /// @todo: We need to implement some kind of logic here that only
 -    /// the values that are not set yet in previous steps are overwritten.
++            const string& sname = cl->second->getSname();
++            if (!sname.empty()) {
++                // Converting string to (const uint8_t*, size_t len) format is
++                // tricky. reineterpret_cast is not the most elegant solution,
++                // but it does avoid us making unnecessary copy. We will convert
++                // sname and file fields in Pkt4 to string one day and live
++                // will be easier.
++                response->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
++                                   sname.size());
++            }
++            
++            const string& filename = cl->second->getFilename();
++            if (!filename.empty()) {
++                // Converting string to (const uint8_t*, size_t len) format is
++                // tricky. reineterpret_cast is not the most elegant solution,
++                // but it does avoid us making unnecessary copy. We will convert
++                // sname and file fields in Pkt4 to string one day and live
++                // will be easier.
++                response->setFile(reinterpret_cast<const uint8_t*>(filename.c_str()),
++                                  filename.size());
++            }
+         }
+     }
++    // Step 3: try to set values using HR. Any values coming from there will override
++    // the subnet or class values.
++    ex.setReservedMessageFields();
+ }
  
  OptionPtr
  Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
index 2877220d34838cfdf0c5f5306bf8e6655b95642f,b6646b4dec5150fa36e9a9acbf202618dde5da62..859a5ef2a8f27be48367c068ce0fafa8c0e3b7a5
@@@ -118,6 -118,6 +118,10 @@@ public
          return (cfg_option_list_);
      }
  
++    /// @brief Sets reserved values of siaddr, sname and file in the
++    /// server's response.
++    void setReservedMessageFields();
++
  private:
  
      /// @brief Copies default parameters from client's to server's message