diff --git a/doc/Makefile.am b/doc/Makefile.am index d035b46514..2be574a095 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -36,6 +36,7 @@ nobase_dist_doc_DATA += examples/kea6/classify.json nobase_dist_doc_DATA += examples/kea6/dhcpv4-over-dhcpv6.json nobase_dist_doc_DATA += examples/kea6/duid.json nobase_dist_doc_DATA += examples/kea6/hooks.json +nobase_dist_doc_DATA += examples/kea6/iPXE.json nobase_dist_doc_DATA += examples/kea6/leases-expiration.json nobase_dist_doc_DATA += examples/kea6/multiple-options.json nobase_dist_doc_DATA += examples/kea6/mysql-reservations.json diff --git a/doc/examples/kea6/iPXE.json b/doc/examples/kea6/iPXE.json new file mode 100644 index 0000000000..b9c3cceca1 --- /dev/null +++ b/doc/examples/kea6/iPXE.json @@ -0,0 +1,69 @@ +// This is and example configuration for iPXE boot in Kea6. + +{ + "Dhcp6": { + // mandatory part of the config that list interfaces on which + // kea will listen to incoming traffic + "interfaces-config": { + "interfaces": [ + "ethX" + ] + }, + +// Two classes are migrated form ISC-DHCP example: +// if exists dhcp6.client-arch-type and +// option dhcp6.client-arch-type = 00:07 { +// option dhcp6.bootfile-url "http://[2001:db8::1]/ipxe.efi"; +// } else if exists dhcp6.user-class and +// substring(option dhcp6.user-class, 2, 4) = "iPXE" { +// option dhcp6.bootfile-url "http://[2001:db8::1]/ubuntu.cfg"; +// } +// +// In example shown below incoming packet will receive value +// http://[2001:db8::1]/ubuntu.cfg if incoming packet will include user +// class option with "iPXE" in it and value http://[2001:db8::1]/ipxe.efi +// if option client architecture type will be 7. +// If incoming packet will include both of those options with matching +// values it will be assigned to class "a-ipxe" because it was first +// matching class. If you want to change that order names of the classes +// have to have different alphabetical order. In Kea 1.3.0 (and previous +// versions) alphabetical order is used in classification. Note this +// should change in next versions, for instance to keep the definition +// order. + "client-classes": [ + { + "name": "a-ipxe", + // user-class option (code 15) is a tuple array + // so we need to skip the length (tuple first element) + "test": "substring(option[15].hex, 2, 4) == 'iPXE'", + "option-data": [ + { + "space": "dhcp6", + "name": "bootfile-url", + "code": 59, + "data": "http://[2001:db8::1]/ubuntu.cfg" + } + ] + }, + { + "name": "b-efi", + // please consider to add a not a-ipxe here to enforce + // the "else"? + "test": "option[61].hex == 0x0007", + "option-data": [ + { + "space": "dhcp6", + "name": "bootfile-url", + "code": 59, + "data": "http://[2001:db8::1]/ipxe.efi" + } + ] + } + ], + "subnet6": [ + { + "subnet": "2001:db8::/64" + } + ] + } +} diff --git a/src/bin/dhcp4/tests/parser_unittest.cc b/src/bin/dhcp4/tests/parser_unittest.cc index d687c09ad6..adadbe9676 100644 --- a/src/bin/dhcp4/tests/parser_unittest.cc +++ b/src/bin/dhcp4/tests/parser_unittest.cc @@ -242,8 +242,8 @@ void testFile(const std::string& fname) { TEST(ParserTest, file) { vector configs = { "advanced.json" , "backends.json", - "classify.json", "cassandra.json", + "classify.json", "dhcpv4-over-dhcpv6.json", "hooks.json", "leases-expiration.json", diff --git a/src/bin/dhcp6/tests/parser_unittest.cc b/src/bin/dhcp6/tests/parser_unittest.cc index b3ef2adb1f..fdc9c85f38 100644 --- a/src/bin/dhcp6/tests/parser_unittest.cc +++ b/src/bin/dhcp6/tests/parser_unittest.cc @@ -246,10 +246,12 @@ TEST(ParserTest, file) { vector configs; configs.push_back("advanced.json"); configs.push_back("backends.json"); + configs.push_back("cassandra.json"); configs.push_back("classify.json"); configs.push_back("dhcpv4-over-dhcpv6.json"); configs.push_back("duid.json"); configs.push_back("hooks.json"); + configs.push_back("iPXE.json"); configs.push_back("leases-expiration.json"); configs.push_back("multiple-options.json"); configs.push_back("mysql-reservations.json"); @@ -258,6 +260,7 @@ TEST(ParserTest, file) { configs.push_back("several-subnets.json"); configs.push_back("shared-network.json"); configs.push_back("simple.json"); + configs.push_back("softwire46.json"); configs.push_back("stateless.json"); configs.push_back("with-ddns.json"); diff --git a/src/lib/testutils/io_utils.cc b/src/lib/testutils/io_utils.cc index 0081707e97..93558a4d46 100644 --- a/src/lib/testutils/io_utils.cc +++ b/src/lib/testutils/io_utils.cc @@ -69,8 +69,11 @@ std::string decommentJSONfile(const std::string& input_file) { } // Second, let's get rid of the // comments + // at the beginning or after a control character. size_t dblslash_pos = line.find("//"); - if (dblslash_pos != string::npos) { + if ((dblslash_pos != string::npos) && + ((dblslash_pos == 0) || + ((unsigned) line[dblslash_pos - 1] <= 32))) { line = line.substr(0, dblslash_pos); } diff --git a/src/lib/testutils/io_utils.h b/src/lib/testutils/io_utils.h index ce4b57ccf2..58fd015706 100644 --- a/src/lib/testutils/io_utils.h +++ b/src/lib/testutils/io_utils.h @@ -32,7 +32,7 @@ std::string readFile(const std::string& file_path); /// token locations should remain unaffected. This is rather naive /// implementation, but it's probably sufficient for testing. It won't be able /// to pick any trickier cases, like # or // appearing in strings, nested C++ -/// comments etc. +/// comments etc at the exception of // in URLs. /// /// @param input_file file to be stripped of comments /// @return filename of a new file that has comments stripped from it