Browse Source

[4552] Added support for DHCPv4 message fields into config parser.

Marcin Siodelski 8 years ago
parent
commit
7ca1d77967

+ 18 - 0
src/bin/dhcp4/dhcp4.spec

@@ -507,6 +507,24 @@
                         "item_type": "string",
                         "item_type": "string",
                         "item_optional": false,
                         "item_optional": false,
                         "item_default": "0.0.0.0"
                         "item_default": "0.0.0.0"
+                      },
+                      {
+                        "item_name": "next-server",
+                        "item_type": "string",
+                        "item_optional": true,
+                        "item_default": "0.0.0.0"
+                      },
+                      {
+                        "item_name": "server-name",
+                        "item_type": "string",
+                        "item_optional": true,
+                        "item_default": ""
+                      },
+                      {
+                        "item_name": "boot-file-name",
+                        "item_type": "string",
+                        "item_optional": true,
+                        "item_default": ""
                       } ]
                       } ]
                   }
                   }
                 },
                 },

+ 5 - 2
src/lib/dhcpsrv/cfg_hosts.cc

@@ -572,10 +572,13 @@ CfgHosts::add4(const HostPtr& host) {
     DuidPtr duid = host->getDuid();
     DuidPtr duid = host->getDuid();
 
 
     // There should be at least one resource reserved: hostname, IPv4
     // There should be at least one resource reserved: hostname, IPv4
-    // address, IPv6 address or prefix.
+    // address, siaddr, sname, file or IPv6 address or prefix.
     if (host->getHostname().empty() &&
     if (host->getHostname().empty() &&
         (host->getIPv4Reservation().isV4Zero()) &&
         (host->getIPv4Reservation().isV4Zero()) &&
-        (!host->hasIPv6Reservation()) &&
+        !host->hasIPv6Reservation() &&
+        host->getNextServer().isV4Zero() &&
+        host->getServerHostname().empty() &&
+        host->getBootFileName().empty() &&
         host->getCfgOption4()->empty() &&
         host->getCfgOption4()->empty() &&
         host->getCfgOption6()->empty()) {
         host->getCfgOption6()->empty()) {
         std::ostringstream s;
         std::ostringstream s;

+ 12 - 1
src/lib/dhcpsrv/parsers/host_reservation_parser.cc

@@ -49,6 +49,9 @@ getSupportedParams4(const bool identifiers_only = false) {
         params_set.insert("hostname");
         params_set.insert("hostname");
         params_set.insert("ip-address");
         params_set.insert("ip-address");
         params_set.insert("option-data");
         params_set.insert("option-data");
+        params_set.insert("next-server");
+        params_set.insert("server-name");
+        params_set.insert("boot-file-name");
     }
     }
     return (identifiers_only ? identifiers_set : params_set);
     return (identifiers_only ? identifiers_set : params_set);
 }
 }
@@ -120,7 +123,6 @@ HostReservationParser::build(isc::data::ConstElementPtr reservation_data) {
 
 
             } else if (element.first == "hostname") {
             } else if (element.first == "hostname") {
                 hostname = element.second->stringValue();
                 hostname = element.second->stringValue();
-
             }
             }
         } catch (const std::exception& ex) {
         } catch (const std::exception& ex) {
             // Append line number where the error occurred.
             // Append line number where the error occurred.
@@ -207,7 +209,16 @@ HostReservationParser4::build(isc::data::ConstElementPtr reservation_data) {
                 if (element.first == "ip-address") {
                 if (element.first == "ip-address") {
                     host_->setIPv4Reservation(IOAddress(element.second->
                     host_->setIPv4Reservation(IOAddress(element.second->
                                                         stringValue()));
                                                         stringValue()));
+                } else if (element.first == "next-server") {
+                host_->setNextServer(IOAddress(element.second->stringValue()));
+
+                } else if (element.first == "server-name") {
+                    host_->setServerHostname(element.second->stringValue());
+
+                } else if (element.first == "boot-file-name") {
+                    host_->setBootFileName(element.second->stringValue());
                 }
                 }
+
             } catch (const std::exception& ex) {
             } catch (const std::exception& ex) {
                 // Append line number where the error occurred.
                 // Append line number where the error occurred.
                 isc_throw(DhcpConfigError, ex.what() << " ("
                 isc_throw(DhcpConfigError, ex.what() << " ("

+ 52 - 0
src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc

@@ -299,6 +299,34 @@ TEST_F(HostReservationParserTest, dhcp4NoHostname) {
     EXPECT_TRUE(hosts[0]->getHostname().empty());
     EXPECT_TRUE(hosts[0]->getHostname().empty());
 }
 }
 
 
+// This test verifies that the parser can parse reservation entry
+// containing next-server, server-name and boot-file-name values for
+// DHCPv4 message fields.
+TEST_F(HostReservationParserTest, dhcp4MessageFields) {
+    std::string config = "{ \"hw-address\": \"1:2:3:4:5:6\","
+        "\"next-server\": \"192.0.2.11\","
+        "\"server-name\": \"some-name.example.org\","
+        "\"boot-file-name\": \"/tmp/some-file.efi\" }";
+
+    ElementPtr config_element = Element::fromJSON(config);
+
+    HostReservationParser4 parser(SubnetID(10));
+    ASSERT_NO_THROW(parser.build(config_element));
+
+    CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+    HostCollection hosts;
+    ASSERT_NO_THROW(hosts = cfg_hosts->getAll(Host::IDENT_HWADDR,
+                                              &hwaddr_->hwaddr_[0],
+                                              hwaddr_->hwaddr_.size()));
+
+    ASSERT_EQ(1, hosts.size());
+
+    EXPECT_EQ(10, hosts[0]->getIPv4SubnetID());
+    EXPECT_EQ("192.0.2.11", hosts[0]->getNextServer().toText());
+    EXPECT_EQ("some-name.example.org", hosts[0]->getServerHostname());
+    EXPECT_EQ("/tmp/some-file.efi", hosts[0]->getBootFileName());
+}
+
 
 
 // This test verifies that the configuration parser for host reservations
 // This test verifies that the configuration parser for host reservations
 // throws an exception when IPv6 address is specified for IPv4 address
 // throws an exception when IPv6 address is specified for IPv4 address
@@ -381,6 +409,30 @@ TEST_F(HostReservationParserTest, bcastAddress) {
 }
 }
 
 
 // This test verifies that the configuration parser for host reservations
 // This test verifies that the configuration parser for host reservations
+// throws an exception when invalid next server address is specified.
+TEST_F(HostReservationParserTest, malformedNextServer) {
+    std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\","
+        "\"next-server\": \"192.0.2.bogus\" }";
+    testInvalidConfig<HostReservationParser4>(config);
+}
+
+// This test verifies that the configuration parser for host reservations
+// throws an exception when zero next server address is specified.
+TEST_F(HostReservationParserTest, zeroNextServer) {
+    std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\","
+        "\"next-server\": \"0.0.0.0\" }";
+    testInvalidConfig<HostReservationParser4>(config);
+}
+
+// This test verifies that the configuration parser for host reservations
+// throws an exception when broadcast next server address is specified.
+TEST_F(HostReservationParserTest, bcastNextServer) {
+    std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\","
+        "\"next-server\": \"255.255.255.255\" }";
+    testInvalidConfig<HostReservationParser4>(config);
+}
+
+// This test verifies that the configuration parser for host reservations
 // throws an exception when unsupported parameter is specified.
 // throws an exception when unsupported parameter is specified.
 TEST_F(HostReservationParserTest, invalidParameterName) {
 TEST_F(HostReservationParserTest, invalidParameterName) {
     // The "ip-addresses" parameter name is incorrect for the DHCPv4
     // The "ip-addresses" parameter name is incorrect for the DHCPv4