From: Tomek Mrugalski Date: Fri, 26 Aug 2016 11:41:15 +0000 (+0200) Subject: [master] Merge branch 'trac4626' (fixed fields in classification) X-Git-Tag: trac4631_base~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89cf54524d8b55cc982ab2146915c0a90fc6efe2;p=thirdparty%2Fkea.git [master] Merge branch 'trac4626' (fixed fields in classification) # Conflicts: # src/bin/dhcp4/dhcp4_srv.cc --- 89cf54524d8b55cc982ab2146915c0a90fc6efe2 diff --cc src/bin/dhcp4/dhcp4_srv.cc index 5d4b3d328d,18d3923794..cbef75d5b6 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@@ -1945,6 -1927,72 +1942,76 @@@ Dhcpv4Srv::adjustRemoteAddr(Dhcpv4Excha } } + void + Dhcpv4Srv::setFixedFields(Dhcpv4Exchange& ex) { + Pkt4Ptr query = ex.getQuery(); + Pkt4Ptr response = ex.getResponse(); + - // 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; ++ // 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); + } ++ } + - IOAddress next_server = cl->second->getNextServer(); - if (!next_server.isV4Zero()) { - response->setSiaddr(next_server); - } ++ // 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& 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(sname.c_str()), - sname.size()); - } ++ IOAddress next_server = cl->second->getNextServer(); ++ if (!next_server.isV4Zero()) { ++ response->setSiaddr(next_server); ++ } + - 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(filename.c_str()), - filename.size()); ++ 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(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(filename.c_str()), ++ filename.size()); ++ } + } + } + - // 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. ++ // 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) { diff --cc src/bin/dhcp4/dhcp4_srv.h index 2877220d34,b6646b4dec..859a5ef2a8 --- a/src/bin/dhcp4/dhcp4_srv.h +++ b/src/bin/dhcp4/dhcp4_srv.h @@@ -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