diff options
author | Francis Dupont <fdupont@isc.org> | 2017-04-25 11:51:55 +0200 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2018-11-29 16:42:15 +0100 |
commit | 07f4ee1db226a3508bca0d7317ffb4d56c2a6090 (patch) | |
tree | d713d782a6dcec51d9b7a9f2a8660c2cbfda144b | |
parent | 1535eb39453eb84d63c3a9f7ae1835d02e58e934 (diff) | |
download | isc-dhcp-07f4ee1db226a3508bca0d7317ffb4d56c2a6090.tar.gz |
Checkpoint (debugged shared networks)
-rw-r--r-- | keama/confparse.c | 40 | ||||
-rw-r--r-- | keama/data.c | 3 | ||||
-rw-r--r-- | keama/doc.txt | 26 | ||||
-rw-r--r-- | keama/parse.c | 23 | ||||
-rw-r--r-- | keama/tests/hostuid4.in4 | 2 | ||||
-rw-r--r-- | keama/tests/optdatagrouppool4.in4 | 2 | ||||
-rw-r--r-- | keama/tests/optiondatapool4.in4 | 2 | ||||
-rw-r--r-- | keama/tests/optiondatapool6.in6 | 2 | ||||
-rw-r--r-- | keama/tests/orphan6.in6 | 2 | ||||
-rw-r--r-- | keama/tests/orphan6.out | 4 | ||||
-rw-r--r-- | keama/tests/pool4.in4 | 2 | ||||
-rw-r--r-- | keama/tests/pool6.in6 | 2 | ||||
-rw-r--r-- | keama/tests/range4.in4 | 2 | ||||
-rw-r--r-- | keama/tests/range6.in6 | 2 | ||||
-rw-r--r-- | keama/tests/shareempty.err | 6 | ||||
-rw-r--r-- | keama/tests/shareempty.msg | 1 | ||||
-rw-r--r-- | keama/tests/shareone4.in4 | 25 | ||||
-rw-r--r-- | keama/tests/shareone4.out | 39 | ||||
-rw-r--r-- | keama/tests/shareone6.in6 | 22 | ||||
-rw-r--r-- | keama/tests/shareone6.out | 33 | ||||
-rw-r--r-- | keama/tests/sharetwo4.notyet | 30 | ||||
-rw-r--r-- | keama/tests/tautology.err | 12 | ||||
-rw-r--r-- | keama/tests/tautology.msg | 1 | ||||
-rw-r--r-- | keama/tests/tautologyhexa.notyet | 12 | ||||
-rw-r--r-- | keama/tests/tautologysub.err | 12 | ||||
-rw-r--r-- | keama/tests/tautologysub.msg | 1 | ||||
-rw-r--r-- | keama/tests/unknownspace.err | 2 |
27 files changed, 290 insertions, 20 deletions
diff --git a/keama/confparse.c b/keama/confparse.c index 5a99a932..1c980dbc 100644 --- a/keama/confparse.c +++ b/keama/confparse.c @@ -1480,6 +1480,11 @@ subclass_inherit(struct parse *cfile, appendString(dmsg, print_data_expression(data, &lose)); reduced = reduce_boolean_expression(expr); + if ((reduced != NULL) && (reduced->type == ELEMENT_BOOLEAN)) + parse_error(cfile, "class matching rule reduced to a " + "constant boolean expression: %s = %s", + print_data_expression(submatch, &lose), + print_data_expression(data, &lose)); if ((reduced == NULL) || (reduced->type != ELEMENT_STRING)) return; if (!lose) { @@ -1507,6 +1512,10 @@ add_match_class(struct parse *cfile, comment = createComment(msg->content); reduced = reduce_boolean_expression(expr); + if ((reduced != NULL) && (reduced->type == ELEMENT_BOOLEAN)) + parse_error(cfile, "'match if' with a constant boolean " + "expression %s", + print_boolean_expression(expr, &lose)); if ((reduced == NULL) || (reduced->type != ELEMENT_STRING)) { expr->skip = ISC_TRUE; cfile->issue_counter++; @@ -1613,6 +1622,37 @@ parse_shared_net_declaration(struct parse *cfile) listRemove(subnets, 0); mapRemove(share, "name"); mapRemove(share, "subnets"); + /* specific case before calling generic merge */ + if (mapContains(share, "pools") && + mapContains(subnet, "pools")) { + struct element *pools; + struct element *sub; + + pools = mapGet(share, "pools"); + mapRemove(share, "pools"); + sub = mapGet(subnet, "pools"); + concat(sub, pools); + } + if (mapContains(share, "pd-pools") && + mapContains(subnet, "pd-pools")) { + struct element *pools; + struct element *sub; + + pools = mapGet(share, "pd-pools"); + mapRemove(share, "pd-pools"); + sub = mapGet(subnet, "pd-pools"); + concat(sub, pools); + } + if (mapContains(share, "option-data") && + mapContains(subnet, "option-data")) { + struct element *opt_list; + struct element *sub; + + opt_list = mapGet(share, "option-data"); + mapRemove(share, "option-data"); + sub = mapGet(subnet, "option-data"); + merge_option_data(opt_list, sub); + } merge(subnet, share); if (local_family == AF_INET) { diff --git a/keama/data.c b/keama/data.c index f9ccd7cc..6e37d3cc 100644 --- a/keama/data.c +++ b/keama/data.c @@ -584,13 +584,14 @@ void merge(struct element *m, struct element *o) { struct element *elem; + struct element *ne; assert(m != NULL); assert(m->type == ELEMENT_MAP); assert(o != NULL); assert(o->type == ELEMENT_MAP); - TAILQ_FOREACH(elem, &o->value.map_value) { + TAILQ_FOREACH_SAFE(elem, &o->value.map_value, ne) { assert(elem->key != NULL); TAILQ_REMOVE(&o->value.map_value, elem); if (!mapContains(m, elem->key)) { diff --git a/keama/doc.txt b/keama/doc.txt index f0393cc5..4557e2f3 100644 --- a/keama/doc.txt +++ b/keama/doc.txt @@ -455,3 +455,29 @@ Dynamic DNS: ------------ Details are very different so the MA maps only basic parameters at the global scope. + +Expressions: +------------ +TODO check if data really includes numeric + ISC DHCP expressions are typed: boolean, numeric, and data which includes + strings and numeric. The default for a literal is to be a string so + literal numbers are interpreted in hexadecimal (for a strange consequence + https://kb.isc.org/article/AA-00334/56/Do-the-list-of-parameters-in-the-dhcp-parameter-request-list-need-to-be-in-hex.html ). + String literals are converted to string elements, hexadecimal literals + are converted to const-data maps. +TODO reduce more hexa aka const-data + As booleans are not data there is no way to fix this: + /tmp/bool line 9: Expecting a data expression. + option ip-forwarding = foo = foo; + ^ + The tautology 'foo = foo' is not a data expression so is rejected by + both the MA and dhcpd (BTW the role of the MA is not to fix ISC DHCP + shortcomings so it does what it is expected to do here). + Note this does not work too: + option ip-forwarding = true; + because "true" is not a keyword and it is converted into a variable + reference... And I expect ISC DHCP makes this true a false at runtime + because the variable "true" is not defined by default. + Reduced expressions are pretty printed to allow an extra check. +TODO use precedence to minimize parentheses + diff --git a/keama/parse.c b/keama/parse.c index 808b7352..8e4a8cf6 100644 --- a/keama/parse.c +++ b/keama/parse.c @@ -4884,8 +4884,11 @@ putUChar(unsigned char *obuf, uint32_t val) isc_boolean_t is_boolean_expression(struct element *expr) { - return ((expr->type == ELEMENT_BOOLEAN) || - mapContains(expr, "check") || + if (expr->type == ELEMENT_BOOLEAN) + return ISC_TRUE; + if (expr->type != ELEMENT_MAP) + return ISC_FALSE; + return (mapContains(expr, "check") || mapContains(expr, "exists") || mapContains(expr, "variable-exists") || mapContains(expr, "equal") || @@ -4902,9 +4905,12 @@ is_boolean_expression(struct element *expr) isc_boolean_t is_data_expression(struct element *expr) { - return ((expr->type == ELEMENT_INTEGER) || - (expr->type == ELEMENT_STRING) || - mapContains(expr, "substring") || + if ((expr->type == ELEMENT_INTEGER) || + (expr->type == ELEMENT_STRING)) + return ISC_TRUE; + if (expr->type != ELEMENT_MAP) + return ISC_FALSE; + return (mapContains(expr, "substring") || mapContains(expr, "suffix") || mapContains(expr, "lowercase") || mapContains(expr, "uppercase") || @@ -4934,8 +4940,11 @@ is_data_expression(struct element *expr) isc_boolean_t is_numeric_expression(struct element *expr) { - return ((expr->type == ELEMENT_INTEGER) || - mapContains(expr, "extract-int8") || + if (expr->type == ELEMENT_INTEGER) + return ISC_TRUE; + if (expr->type != ELEMENT_MAP) + return ISC_FALSE; + return (mapContains(expr, "extract-int8") || mapContains(expr, "extract-int16") || mapContains(expr, "extract-int32") || mapContains(expr, "const-int") || diff --git a/keama/tests/hostuid4.in4 b/keama/tests/hostuid4.in4 index 801e7010..3b8238d5 100644 --- a/keama/tests/hostuid4.in4 +++ b/keama/tests/hostuid4.in4 @@ -14,7 +14,7 @@ ignore-client-uids false; # host declarations host test1 { uid 01:02:03:04:05:0a:0b:0c:0d:0e:0f; - option domain-search example.com, example.org; + option domain-search "example.com", "example.org"; default-lease-time 1800; fixed-address 10.5.5.1, 10.10.10.10; } diff --git a/keama/tests/optdatagrouppool4.in4 b/keama/tests/optdatagrouppool4.in4 index 103a4123..886a279e 100644 --- a/keama/tests/optdatagrouppool4.in4 +++ b/keama/tests/optdatagrouppool4.in4 @@ -15,7 +15,7 @@ subnet 10.5.5.0 netmask 255.255.255.224 { # for a silly reason option-data is not allowed in DHCPv4 pools # try to fool this rule using a group group fool { - option domain-search example.com, example.org; + option domain-search "example.com", "example.org"; } } } diff --git a/keama/tests/optiondatapool4.in4 b/keama/tests/optiondatapool4.in4 index 0a143fac..c51887d0 100644 --- a/keama/tests/optiondatapool4.in4 +++ b/keama/tests/optiondatapool4.in4 @@ -10,6 +10,6 @@ subnet 10.5.5.0 netmask 255.255.255.224 { # avoid empty pool range 10.5.5.5 10.5.5.10; # for a silly reason option-data is not allowed in DHCPv4 pools - option domain-search example.com, example.org; + option domain-search "example.com", "example.org"; } } diff --git a/keama/tests/optiondatapool6.in6 b/keama/tests/optiondatapool6.in6 index 0cf20522..179c2f5c 100644 --- a/keama/tests/optiondatapool6.in6 +++ b/keama/tests/optiondatapool6.in6 @@ -11,6 +11,6 @@ subnet6 2001::/64 { range6 2001::100 2001::200; # for a silly reason option-data is not allowed in DHCPv4 pools # but allowed in DHCPv6 pools - option dhcp6.domain-search example.com, example.org; + option dhcp6.domain-search "example.com", "example.org"; } } diff --git a/keama/tests/orphan6.in6 b/keama/tests/orphan6.in6 index 711bb73d..ed303790 100644 --- a/keama/tests/orphan6.in6 +++ b/keama/tests/orphan6.in6 @@ -9,5 +9,5 @@ default-lease-time 1800; # orphan reservation host foobar { hardware ethernet 00:0B:FD:32:E6:FA; - option dhcp6.domain-search 2a01:e00::2, 2a01:e00::1; + option dhcp6.name-servers 2a01:e00::2, 2a01:e00::1; } diff --git a/keama/tests/orphan6.out b/keama/tests/orphan6.out index cf70d0c1..8be6cd2d 100644 --- a/keama/tests/orphan6.out +++ b/keama/tests/orphan6.out @@ -15,8 +15,8 @@ // "option-data": [ // { // "space": "dhcp6", -// "name": "domain-search", -// "code": 24, +// "name": "dns-servers", +// "code": 23, // "data": "2a01:e00::2, 2a01:e00::1" // } // ] diff --git a/keama/tests/pool4.in4 b/keama/tests/pool4.in4 index f834bbc1..db8bc59e 100644 --- a/keama/tests/pool4.in4 +++ b/keama/tests/pool4.in4 @@ -7,7 +7,7 @@ authoritative; subnet 10.5.5.0 netmask 255.255.255.224 { # pool declaration pool { - option domain-search example.com, example.org; + option domain-search "example.com", "example.org"; default-lease-time 1800; range 10.5.5.5 10.5.5.10; } diff --git a/keama/tests/pool6.in6 b/keama/tests/pool6.in6 index 6f52d94f..70c9c709 100644 --- a/keama/tests/pool6.in6 +++ b/keama/tests/pool6.in6 @@ -7,7 +7,7 @@ authoritative; subnet6 2001::/64 { # pool declaration pool6 { - option dhcp6.domain-search example.com, example.org; + option dhcp6.domain-search "example.com", "example.org"; default-lease-time 1800; range6 2001::100 2001::200; } diff --git a/keama/tests/range4.in4 b/keama/tests/range4.in4 index 833da20c..57af6f2c 100644 --- a/keama/tests/range4.in4 +++ b/keama/tests/range4.in4 @@ -6,7 +6,7 @@ authoritative; # subnet declaration subnet 10.5.5.0 netmask 255.255.255.224 { # range declaration - option domain-search example.com, example.org; + option domain-search "example.com", "example.org"; default-lease-time 1800; range 10.5.5.5 10.5.5.10; } diff --git a/keama/tests/range6.in6 b/keama/tests/range6.in6 index 2c141ad7..813b20b5 100644 --- a/keama/tests/range6.in6 +++ b/keama/tests/range6.in6 @@ -6,7 +6,7 @@ authoritative; # subnet declaration subnet6 2001::/64 { # range declaration - option dhcp6.domain-search example.com, example.org; + option dhcp6.domain-search "example.com", "example.org"; default-lease-time 1800; range6 2001::100 2001::200; } diff --git a/keama/tests/shareempty.err b/keama/tests/shareempty.err new file mode 100644 index 00000000..2e9e3a12 --- /dev/null +++ b/keama/tests/shareempty.err @@ -0,0 +1,6 @@ +# bad (no subnet) shared-network declaration config + +# shared-network declaration +shared-network "foobar" { + interface "foo"; +} diff --git a/keama/tests/shareempty.msg b/keama/tests/shareempty.msg new file mode 100644 index 00000000..fb74cc62 --- /dev/null +++ b/keama/tests/shareempty.msg @@ -0,0 +1 @@ +shareempty.err line 6: empty shared-network decl diff --git a/keama/tests/shareone4.in4 b/keama/tests/shareone4.in4 new file mode 100644 index 00000000..430f7531 --- /dev/null +++ b/keama/tests/shareone4.in4 @@ -0,0 +1,25 @@ +# DHCPv4 one-subnet shared-network declaration config + +# authoritative is mandatory +authoritative; + +# shared-network declaration +shared-network "foobar" { + # interface + interface "foo"; + # option + option domain-search "example.com", "example.org"; + # parameter + default-lease-time 1800; + # subnet declaration + subnet 10.5.5.0 netmask 255.255.255.224 { + # redefined parameter + default-lease-time 3600; + # another option + option ip-forwarding true; + } + # pool (must be after the subnet) + pool { + range 10.5.5.5 10.5.5.10; + } +} diff --git a/keama/tests/shareone4.out b/keama/tests/shareone4.out new file mode 100644 index 00000000..bb5a0165 --- /dev/null +++ b/keama/tests/shareone4.out @@ -0,0 +1,39 @@ +{ + "Dhcp4": { + "interfaces-config": { + "interfaces": [ + "foo" + ] + }, + "subnet4": [ + # subnet declaration + { + "subnet": "10.5.5.0/27", + "valid-lifetime": 3600, + "option-data": [ + # another option + { + "space": "dhcp4", + "name": "ip-forwarding", + "code": 19, + "data": "true" + }, + # interface + { + "space": "dhcp4", + "name": "domain-search", + "code": 119, + "data": "example.com, example.org" + } + ], + "interface": "foo", + "pools": [ + # pool (must be after the subnet) + { + "pool": "10.5.5.5 - 10.5.5.10" + } + ] + } + ] + } +} diff --git a/keama/tests/shareone6.in6 b/keama/tests/shareone6.in6 new file mode 100644 index 00000000..8ac35056 --- /dev/null +++ b/keama/tests/shareone6.in6 @@ -0,0 +1,22 @@ +# DHCPv6 one-subnet shared-network declaration config + +# authoritative is mandatory +authoritative; + +# shared-network declaration +shared-network "foobar" { + # interface + interface "foo"; + # option + option dhcp6.domain-search "example.com", "example.org"; + # parameter + default-lease-time 1800; + # subnet declaration + subnet6 2001::/64 { + # redefined parameter + default-lease-time 3600; + # pool + range6 2001::1000 2001::2000; + } + # tried another pool here but DHCPv6 pools are allowed only in subnets +} diff --git a/keama/tests/shareone6.out b/keama/tests/shareone6.out new file mode 100644 index 00000000..a3649c18 --- /dev/null +++ b/keama/tests/shareone6.out @@ -0,0 +1,33 @@ +{ + "Dhcp6": { + "interfaces-config": { + "interfaces": [ + "foo" + ] + }, + "subnet6": [ + # subnet declaration + { + "subnet": "2001::/64", + "valid-lifetime": 3600, + "pools": [ + { + # pool + "pool": "2001::1000 - 2001::2000" + } + ], + "interface": "foo", + "option-data": [ + # interface + # option + { + "space": "dhcp6", + "name": "domain-search", + "code": 24, + "data": "example.com, example.org" + } + ] + } + ] + } +} diff --git a/keama/tests/sharetwo4.notyet b/keama/tests/sharetwo4.notyet new file mode 100644 index 00000000..fa9c1eb1 --- /dev/null +++ b/keama/tests/sharetwo4.notyet @@ -0,0 +1,30 @@ +# DHCPv4 two-subnet shared-network declaration config + +# authoritative is mandatory +authoritative; + +# shared-network declaration +shared-network "foobar" { + # interface + interface "foo"; + # option + option domain-search "example.com", "example.org"; + # parameter + default-lease-time 1800; + # subnet declaration + subnet 10.5.5.0 netmask 255.255.255.224 { + # redefined parameter + default-lease-time 3600; + # another option + option ip-forwarding true; + } + # second subnet declaration + subnet 10.10.10.0 netmask 255.255.255.224 { } + # pools (must be after the subnet) + pool { + range 10.5.5.5 10.5.5.10; + } + pool { + range 0.10.10.5 0.10.10.10; + } +} diff --git a/keama/tests/tautology.err b/keama/tests/tautology.err new file mode 100644 index 00000000..d3a12cec --- /dev/null +++ b/keama/tests/tautology.err @@ -0,0 +1,12 @@ +# bad (tautology) class declaration config + +# authoritative is mandatory +authoritative; + +# class declaration +class "tautology" { + # tautology + # note that true does not work as it is a variable reference + # and for the same reason quotes are needed (or one can use hexa) + match if "foo" = "foo"; +} diff --git a/keama/tests/tautology.msg b/keama/tests/tautology.msg new file mode 100644 index 00000000..569a2339 --- /dev/null +++ b/keama/tests/tautology.msg @@ -0,0 +1 @@ +tautology.err line 11: 'match if' with a constant boolean expression ('foo') = ('foo') diff --git a/keama/tests/tautologyhexa.notyet b/keama/tests/tautologyhexa.notyet new file mode 100644 index 00000000..d73ed53c --- /dev/null +++ b/keama/tests/tautologyhexa.notyet @@ -0,0 +1,12 @@ +# bad (tautology) class declaration config + +# authoritative is mandatory +authoritative; + +# class declaration +class "tautology" { + # tautology + # note that true does not work as it is a variable reference + # and for the same reason quotes are needed (or one can use hexa) + match if 12:34 = 56:78:9a; +} diff --git a/keama/tests/tautologysub.err b/keama/tests/tautologysub.err new file mode 100644 index 00000000..0004af40 --- /dev/null +++ b/keama/tests/tautologysub.err @@ -0,0 +1,12 @@ +# bad (tautology) class declaration config + +# authoritative is mandatory +authoritative; + +# superclass declaration +class "constant" { + match "foo"; +} + +# subclass declaration +subclass "constant" "bar"; diff --git a/keama/tests/tautologysub.msg b/keama/tests/tautologysub.msg new file mode 100644 index 00000000..05f524bd --- /dev/null +++ b/keama/tests/tautologysub.msg @@ -0,0 +1 @@ +tautologysub.err line 12: class matching rule reduced to a constant boolean expression: 'foo' = 'bar' diff --git a/keama/tests/unknownspace.err b/keama/tests/unknownspace.err index 29d695cb..8165a972 100644 --- a/keama/tests/unknownspace.err +++ b/keama/tests/unknownspace.err @@ -1,4 +1,4 @@ # unknown option config # unknown option -option this-space-does-not-exist.domain-search example.com; +option this-space-does-not-exist.domain-search "example.com"; |