diff options
author | Francis Dupont <fdupont@isc.org> | 2017-11-15 09:22:47 +0100 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2018-11-29 16:42:21 +0100 |
commit | 07994e434750b4ae771e31b03608bb7649c11c43 (patch) | |
tree | 9a68b5f31d8ce237cf05300219f98447243f3817 /keama | |
parent | cd03f0656eb74f61f3cd443a98eaf4d7b115574c (diff) | |
download | isc-dhcp-07994e434750b4ae771e31b03608bb7649c11c43.tar.gz |
Added #5073 improvements
Diffstat (limited to 'keama')
-rw-r--r-- | keama/doc.txt | 1 | ||||
-rw-r--r-- | keama/options.c | 20 | ||||
-rw-r--r-- | keama/parse.c | 122 | ||||
-rw-r--r-- | keama/tests/README | 1 | ||||
-rw-r--r-- | keama/tests/czb/kea.json | 25 | ||||
-rw-r--r-- | keama/tests/dhcp3/kea.json | 42 | ||||
-rw-r--r-- | keama/tests/fordhcp/kea.json | 71 | ||||
-rw-r--r-- | keama/tests/gcet/kea.json | 25 | ||||
-rw-r--r-- | keama/tests/vendorspace4.in4 | 14 | ||||
-rw-r--r-- | keama/tests/vendorspace4.out | 42 |
10 files changed, 261 insertions, 102 deletions
diff --git a/keama/doc.txt b/keama/doc.txt index e11bbb9c..2ea51e24 100644 --- a/keama/doc.txt +++ b/keama/doc.txt @@ -525,4 +525,3 @@ TODO: - match if *and* spawn with - host set class & setReservedClientClasses - shared network 5306, 5307 - - vendor/site 5073 diff --git a/keama/options.c b/keama/options.c index 7067897d..6ec3bb79 100644 --- a/keama/options.c +++ b/keama/options.c @@ -321,9 +321,9 @@ struct option_def configs[] = { { "server-name", "t", "server", 16, 3}, { "next-server", "I", "server", 17, 3}, { "authoritative", "f", "server", 18, 3}, - { "vendor-option-space", "U", "server", 19, 0}, + { "vendor-option-space", "U", "server", 19, 3}, { "always-reply-rfc1048", "f", "server", 20, 0}, - { "site-option-space", "X", "server", 21, 0}, + { "site-option-space", "X", "server", 21, 3}, { "always-broadcast", "f", "server", 22, 0}, { "ddns-domainname", "t", "server", 23, 3}, { "ddns-hostname", "t", "server", 24, 0}, @@ -766,25 +766,9 @@ get_config_comments(unsigned code) TAILQ_INSERT_TAIL(&comments, comment); break; - case 19: /* vendor-option-space */ - comment = createComment("/// vendor-option-space is not " - "(yet?) supported"); - TAILQ_INSERT_TAIL(&comments, comment); - comment = createComment("/// Reference Kea #5073"); - TAILQ_INSERT_TAIL(&comments, comment); - break; - case 20: /* always-reply-rfc1048 */ goto no_bootp; - case 21: /* site-option-space */ - comment = createComment("/// site-option-space is not " - "supported"); - TAILQ_INSERT_TAIL(&comments, comment); - comment = createComment("/// Reference Kea #5240"); - TAILQ_INSERT_TAIL(&comments, comment); - break; - case 22: /* always-broadcast */ comment = createComment("/// always-broadcast is not " "supported"); diff --git a/keama/parse.c b/keama/parse.c index 7352bfb4..a76fe2af 100644 --- a/keama/parse.c +++ b/keama/parse.c @@ -34,6 +34,8 @@ static void config_valid_lifetime(struct element *, struct parse *); static void config_file(struct element *, struct parse *); static void config_sname(struct element *, struct parse *); static void config_next_server(struct element *, struct parse *); +static void config_vendor_option_space(struct element *, struct parse *); +static void config_site_option_space(struct element *, struct parse *); static struct element *default_qualifying_suffix(void); static void config_qualifying_suffix(struct element *, struct parse *); static void config_enable_updates(struct element *, struct parse *); @@ -1996,10 +1998,8 @@ parse_executable_statement(struct element *result, skip_token(&val, NULL, cfile); parse_semi(cfile); - st = createNull(); - st->skip = ISC_TRUE; - cfile->issue_counter++; - mapSet(result, st, "parse-vendor-option"); + /* Done by Kea after classification so this statement + * silently does not translate */ break; /* Not really a statement, but we parse it here anyway @@ -4958,6 +4958,12 @@ parse_config_statement(struct element *result, case 18: /* authoritative */ parse_error(cfile, "authoritative is a statement, " "here it is used as a config option"); + case 19: /* vendor-option-space */ + config_vendor_option_space(config, cfile); + break; + case 21: /* site-option-space */ + config_site_option_space(config, cfile); + break; case 23: /* ddns-domainname */ config_qualifying_suffix(config, cfile); break; @@ -5131,6 +5137,114 @@ config_next_server(struct element *config, struct parse *cfile) mapSet(cfile->stack[scope], value, "next-server"); } +static void +config_vendor_option_space(struct element *config, struct parse *cfile) +{ + struct element *defs; + struct element *def; + struct element *opts; + struct element *opt; + struct element *space; + + if (local_family != AF_INET) + parse_error(cfile, "vendor-option-space is DHCPv4 only"); + + /* create local option definition */ + def = createMap(); + mapSet(def, + createString(makeString(-1, "vendor-encapsulated-options")), + "name"); + mapSet(def, createInt(43), "code"); + mapSet(def, createString(makeString(-1, "empty")), "type"); + space = mapGet(config, "value"); + if (space == NULL) + parse_error(cfile, "vendor-option-space has no value"); + if (space->type != ELEMENT_STRING) + parse_error(cfile, + "vendor-option-space value is not a string"); + mapSet(def, space, "encapsulate"); + + /* add it */ + defs = mapGet(cfile->stack[cfile->stack_top], "option-def"); + if (defs == NULL) { + defs = createList(); + mapSet(cfile->stack[cfile->stack_top], defs, "option-def"); + } else { + size_t i; + + /* Look for duplicate */ + for (i = 0; i < listSize(defs); i++) { + struct element *item; + struct element *code; + struct element *old; + + item = listGet(defs, i); + if ((item == NULL) || (item->type != ELEMENT_MAP)) + continue; + code = mapGet(item, "code"); + if ((code == NULL) || + (code->type != ELEMENT_INTEGER) || + (intValue(code) != 43)) + continue; + old = mapGet(item, "encapsulate"); + if ((old == NULL) || (old->type != ELEMENT_STRING)) + continue; + if (eqString(stringValue(space), stringValue(old))) + return; + } + } + listPush(defs, def); + + /* add a data too assuming at least one suboption exists */ + opt = createMap(); + mapSet(opt, + createString(makeString(-1, "vendor-encapsulated-options")), + "name"); + mapSet(opt, createInt(43), "code"); + opts = mapGet(cfile->stack[cfile->stack_top], "option-data"); + if (opts == NULL) { + opts = createList(); + mapSet(cfile->stack[cfile->stack_top], opts, "option-data"); + } + listPush(opts, opt); +} + +static void +config_site_option_space(struct element *config, struct parse *cfile) +{ + struct element *defs; + struct element *space; + struct string *msg; + struct comment *comment; + + if (local_family != AF_INET) + parse_error(cfile, "site-option-space is DHCPv4 only"); + + space = mapGet(config, "value"); + if (space == NULL) + parse_error(cfile, "site-option-space has no value"); + if (space->type != ELEMENT_STRING) + parse_error(cfile, "site-option-space value is not a string"); + + defs = mapGet(cfile->stack[cfile->stack_top], "option-def"); + if (defs == NULL) { + defs = createList(); + mapSet(cfile->stack[cfile->stack_top], defs, "option-def"); + } + + msg = makeString(-1, "/// site-option-space '"); + concatString(msg, stringValue(space)); + appendString(msg, "'"); + comment = createComment(msg->content); + TAILQ_INSERT_TAIL(&defs->comments, comment); + msg = makeString(-1, "/// Please to move private (code 224..254)"); + appendString(msg, " option definitions from '"); + concatString(msg, stringValue(space)); + appendString(msg, "' to 'dhcp4' space"); + comment = createComment(msg->content); + TAILQ_INSERT_TAIL(&defs->comments, comment); +} + static struct element * default_qualifying_suffix(void) { diff --git a/keama/tests/README b/keama/tests/README index 55ddb858..36526d87 100644 --- a/keama/tests/README +++ b/keama/tests/README @@ -27,6 +27,7 @@ Check output syntax with kea-dhcp4 and kea-dhcp6 Set KEA4 and KEA6 environment variables to kea-dhcp4 and kea-dhcp6 The en0 interface is supposed to exist (or replace "en0" in all files) +Note that runall.sh must be run before checkall.sh checkone.sh xyz.out -> check the syntax of xyz.out diff --git a/keama/tests/czb/kea.json b/keama/tests/czb/kea.json index f4511495..98b8d6ac 100644 --- a/keama/tests/czb/kea.json +++ b/keama/tests/czb/kea.json @@ -281,16 +281,21 @@ { "name": "SunRay", /// from: match if (option dhcp.vendor-class-identifier) = 'SUNW.NewT.SUNW' - "test": "option[60].hex == 'SUNW.NewT.SUNW'" -// "config": [ -// /// vendor-option-space is not (yet?) supported -// /// Reference Kea #5073 -// { -// "name": "vendor-option-space", -// "code": 19, -// "value": "SunRay" -// } -// ] + "test": "option[60].hex == 'SUNW.NewT.SUNW'", + "option-def": [ + { + "name": "vendor-encapsulated-options", + "code": 43, + "type": "empty", + "encapsulate": "SunRay" + } + ], + "option-data": [ + { + "name": "vendor-encapsulated-options", + "code": 43 + } + ] // "statement": { // "log": { // "priority": "info", diff --git a/keama/tests/dhcp3/kea.json b/keama/tests/dhcp3/kea.json index 93e84302..16ad1c53 100644 --- a/keama/tests/dhcp3/kea.json +++ b/keama/tests/dhcp3/kea.json @@ -866,17 +866,20 @@ "name": "ruckus", /// from: match if ((option dhcp.vendor-class-identifier) = 'Ruckus CPE') or ((option dhcp.vendor-class-identifier) = 'Ruckus') "test": "(option[60].hex == 'Ruckus CPE') or (option[60].hex == 'Ruckus')", -// "config": [ -// /// vendor-option-space is not (yet?) supported -// /// Reference Kea #5073 -// { -// "name": "vendor-option-space", -// "code": 19, -// "value": "VendorInfo" -// } -// ], + "option-def": [ + { + "name": "vendor-encapsulated-options", + "code": 43, + "type": "empty", + "encapsulate": "VendorInfo" + } + ], "option-data": [ { + "name": "vendor-encapsulated-options", + "code": 43 + }, + { "space": "VendorInfo", "name": "acsurl", "code": 1, @@ -906,21 +909,24 @@ "data": "ubnt" }, { + "name": "vendor-encapsulated-options", + "code": 43 + }, + { "space": "ubnt", "name": "unifi-address", "code": 1, "data": "66.253.253.32" } + ], + "option-def": [ + { + "name": "vendor-encapsulated-options", + "code": 43, + "type": "empty", + "encapsulate": "ubnt" + } ] -// "config": [ -// /// vendor-option-space is not (yet?) supported -// /// Reference Kea #5073 -// { -// "name": "vendor-option-space", -// "code": 19, -// "value": "ubnt" -// } -// ] }, { "name": "unifi", diff --git a/keama/tests/fordhcp/kea.json b/keama/tests/fordhcp/kea.json index d22bf1bf..2e53726e 100644 --- a/keama/tests/fordhcp/kea.json +++ b/keama/tests/fordhcp/kea.json @@ -799,16 +799,21 @@ { "name": "APC", /// from: match if (substring(option dhcp.vendor-class-identifier, 0, 3)) = 'APC' - "test": "substring(option[60].hex,0,3) == 'APC'" -// "config": [ -// /// vendor-option-space is not (yet?) supported -// /// Reference Kea #5073 -// { -// "name": "vendor-option-space", -// "code": 19, -// "value": "APC" -// } -// ] + "test": "substring(option[60].hex,0,3) == 'APC'", + "option-def": [ + { + "name": "vendor-encapsulated-options", + "code": 43, + "type": "empty", + "encapsulate": "APC" + } + ], + "option-data": [ + { + "name": "vendor-encapsulated-options", + "code": 43 + } + ] }, { "name": "MSFT", @@ -855,6 +860,10 @@ "code": 60, "data": "PXEClient" }, + { + "name": "vendor-encapsulated-options", + "code": 43 + }, # Some PXE clients refuse to tftp if mtftp fails. Others take # longer. { @@ -901,36 +910,18 @@ "data": "30" } ], -// "config": [ -// /// vendor-option-space is not (yet?) supported -// /// Reference Kea #5073 -// { -// "name": "vendor-option-space", -// "code": 19, -// "value": "PXE" -// }, -// /// site-option-space is not supported -// /// Reference Kea #5240 -// { -// "name": "site-option-space", -// "code": 21, -// "value": "pxelinux" -// }, -// /// vendor-option-space is not (yet?) supported -// /// Reference Kea #5073 -// { -// "name": "vendor-option-space", -// "code": 19, -// "value": "PXE" -// }, -// /// site-option-space is not supported -// /// Reference Kea #5240 -// { -// "name": "site-option-space", -// "code": 21, -// "value": "pxelinux" -// } -// ], + /// site-option-space 'pxelinux' + /// Please to move private (code 224..254) option definitions from 'pxelinux' to 'dhcp4' space + /// site-option-space 'pxelinux' + /// Please to move private (code 224..254) option definitions from 'pxelinux' to 'dhcp4' space + "option-def": [ + { + "name": "vendor-encapsulated-options", + "code": 43, + "type": "empty", + "encapsulate": "PXE" + } + ], // /// Only global enable-updates is supported // "enable-updates": false, "boot-file-name": "pxelinux.0", diff --git a/keama/tests/gcet/kea.json b/keama/tests/gcet/kea.json index 4b0d0dba..6edf1636 100644 --- a/keama/tests/gcet/kea.json +++ b/keama/tests/gcet/kea.json @@ -71,6 +71,10 @@ "data": "Ruckus CPE" }, { + "name": "vendor-encapsulated-options", + "code": 43 + }, + { "space": "RKUS", "name": "fm-address", "code": 1, @@ -88,18 +92,17 @@ "code": 6, "data": "https://192.168.11.200/wsg/ap" } - ] + ], // /// valid-lifetime in unsupported scope -// "valid-lifetime": 86400 -// "config": [ -// /// vendor-option-space is not (yet?) supported -// /// Reference Kea #5073 -// { -// "name": "vendor-option-space", -// "code": 19, -// "value": "RKUS" -// } -// ] +// "valid-lifetime": 86400, + "option-def": [ + { + "name": "vendor-encapsulated-options", + "code": 43, + "type": "empty", + "encapsulate": "RKUS" + } + ] } ] } diff --git a/keama/tests/vendorspace4.in4 b/keama/tests/vendorspace4.in4 new file mode 100644 index 00000000..7f9306b0 --- /dev/null +++ b/keama/tests/vendorspace4.in4 @@ -0,0 +1,14 @@ +# vendor option space config + +# authoritative is mandatory +authoritative; + +option space foo; +option foo.bar code 1 = text; + +# class declaration +class "foobar" { + match if option vendor-class-identifier = "foo"; + vendor-option-space foo; + option foo.bar "foobar"; +} diff --git a/keama/tests/vendorspace4.out b/keama/tests/vendorspace4.out new file mode 100644 index 00000000..6c5e8d85 --- /dev/null +++ b/keama/tests/vendorspace4.out @@ -0,0 +1,42 @@ +{ + # vendor option space config + # authoritative is mandatory + "Dhcp4": { + "option-def": [ + { + "space": "foo", + "name": "bar", + "code": 1, + "type": "string" + } + ], + "client-classes": [ + # class declaration + { + "name": "foobar", + /// from: match if (option dhcp.vendor-class-identifier) = 'foo' + "test": "option[60].hex == 'foo'", + "option-def": [ + { + "name": "vendor-encapsulated-options", + "code": 43, + "type": "empty", + "encapsulate": "foo" + } + ], + "option-data": [ + { + "name": "vendor-encapsulated-options", + "code": 43 + }, + { + "space": "foo", + "name": "bar", + "code": 1, + "data": "foobar" + } + ] + } + ] + } +} |