summaryrefslogtreecommitdiff
path: root/keama
diff options
context:
space:
mode:
authorFrancis Dupont <fdupont@isc.org>2017-11-15 09:22:47 +0100
committerFrancis Dupont <fdupont@isc.org>2019-11-12 09:57:39 +0100
commit76a85fef33fa8a08f4533ba15b833ced57252eec (patch)
tree5289dfe00ad2ff2123f09f198887ac3b6a15e471 /keama
parent96a5bb0bda0668422202086bca401eb325f71097 (diff)
downloadisc-dhcp-76a85fef33fa8a08f4533ba15b833ced57252eec.tar.gz
Added #5073 improvements
Diffstat (limited to 'keama')
-rw-r--r--keama/doc.txt1
-rw-r--r--keama/options.c20
-rw-r--r--keama/parse.c122
-rw-r--r--keama/tests/README1
-rw-r--r--keama/tests/czb/kea.json25
-rw-r--r--keama/tests/dhcp3/kea.json42
-rw-r--r--keama/tests/fordhcp/kea.json71
-rw-r--r--keama/tests/gcet/kea.json25
-rw-r--r--keama/tests/vendorspace4.in414
-rw-r--r--keama/tests/vendorspace4.out42
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"
+ }
+ ]
+ }
+ ]
+ }
+}