diff options
Diffstat (limited to 'keama')
-rw-r--r-- | keama/confparse.c | 50 | ||||
-rw-r--r-- | keama/doc.txt | 8 | ||||
-rw-r--r-- | keama/keama.h | 2 | ||||
-rw-r--r-- | keama/tests/groupclass4.in4 | 35 | ||||
-rw-r--r-- | keama/tests/groupclass4.out | 109 | ||||
-rw-r--r-- | keama/tests/grouphost4.in4 | 38 | ||||
-rw-r--r-- | keama/tests/grouphost4.out | 75 | ||||
-rw-r--r-- | keama/tests/groupsubnet4.in4 | 27 | ||||
-rw-r--r-- | keama/tests/groupsubnet4.out | 36 | ||||
-rw-r--r-- | keama/tests/groupsubnet6.in6 | 27 | ||||
-rw-r--r-- | keama/tests/groupsubnet6.out | 42 | ||||
-rw-r--r-- | keama/tests/groupsubnetif.err4 | 22 | ||||
-rw-r--r-- | keama/tests/groupsubnetif.msg | 1 | ||||
-rw-r--r-- | keama/tests/subclass4.out | 9 | ||||
-rw-r--r-- | keama/tests/subclass6.out | 9 | ||||
-rw-r--r-- | keama/tests/subclassbinsel4.out | 6 | ||||
-rw-r--r-- | keama/tests/subclassbinsel6.out | 9 |
17 files changed, 465 insertions, 40 deletions
diff --git a/keama/confparse.c b/keama/confparse.c index 0f036c9e..53933d2e 100644 --- a/keama/confparse.c +++ b/keama/confparse.c @@ -151,7 +151,7 @@ conf_file_parse(struct parse *cfile) } /* Cleanup classes */ - classes = mapGet(cfile->stack[1], "clint-classes"); + classes = mapGet(cfile->stack[1], "client-classes"); if ((classes != NULL) && (listSize(classes) > 0)) for (i = 0; i < listSize(classes); i++) { struct element *class; @@ -1261,6 +1261,8 @@ parse_class_declaration(struct parse *cfile, int type) if ((kind == GROUP_DECL) || (kind == ROOT_GROUP)) break; } + if (!group) + parse_error(cfile, "can't find root group"); if (cfile->stack[group]->kind == GROUP_DECL) { group_classes = mapGet(cfile->stack[group], "client-classes"); if (group_classes == NULL) { @@ -1946,7 +1948,9 @@ parse_subnet_declaration(struct parse *cfile) /* Find parent */ for (i = cfile->stack_top; i > 0; --i) { kind = cfile->stack[i]->kind; - if ((kind == SHARED_NET_DECL) || (kind == ROOT_GROUP)) { + if ((kind == SHARED_NET_DECL) || + (kind == GROUP_DECL) || + (kind == ROOT_GROUP)) { parent = i; break; } @@ -1958,11 +1962,11 @@ parse_subnet_declaration(struct parse *cfile) if (subnets == NULL) parse_error(cfile, "shared network without subnets"); } else { - subnets = mapGet(cfile->stack[1], "subnet4"); + subnets = mapGet(cfile->stack[parent], "subnet4"); if (subnets == NULL) { subnets = createList(); subnets->kind = SUBNET_DECL; - mapSet(cfile->stack[1], subnets, "subnet4"); + mapSet(cfile->stack[parent], subnets, "subnet4"); } } @@ -2039,7 +2043,9 @@ parse_subnet6_declaration(struct parse *cfile) /* Find parent */ for (i = cfile->stack_top; i > 0; --i) { kind = cfile->stack[i]->kind; - if ((kind == SHARED_NET_DECL) || (kind == ROOT_GROUP)) { + if ((kind == SHARED_NET_DECL) || + (kind == GROUP_DECL) || + (kind == ROOT_GROUP)) { parent = i; break; } @@ -2051,11 +2057,11 @@ parse_subnet6_declaration(struct parse *cfile) if (subnets == NULL) parse_error(cfile, "shared network without subnets"); } else { - subnets = mapGet(cfile->stack[1], "subnet6"); + subnets = mapGet(cfile->stack[parent], "subnet6"); if (subnets == NULL) { subnets = createList(); subnets->kind = SUBNET_DECL; - mapSet(cfile->stack[1], subnets, "subnet6"); + mapSet(cfile->stack[parent], subnets, "subnet6"); } } @@ -2156,17 +2162,17 @@ parse_group_declaration(struct parse *cfile) if (name != NULL) mapSet(group, createString(name), "name"); - dissolve_group(cfile, group); + close_group(cfile, group); } /* - * Dissolve a group. Called when a group is closed. + * Close a group. Called when a group is closed. * - spread parameters to children * - attach declarations at an upper level */ void -dissolve_group(struct parse *cfile, struct element *group) +close_group(struct parse *cfile, struct element *group) { struct handle *handle; struct handle *nh; @@ -2552,8 +2558,8 @@ option_data_derive(struct parse *cfile, struct handle *src, opt_list->skip = ISC_TRUE; cfile->issue_counter++; } - mapSet(item, opt_list, src->key); } + mapSet(item, opt_list, src->key); } } @@ -3585,6 +3591,7 @@ addrmask(const struct string *address, const struct string *netmask) * (reservations aka hosts must be in a subnet in Kea) * (defaulting to the last defined subnet (e.g. for reservations * without any address). + * (first step is to find an enclosing group). */ static struct element * @@ -3593,7 +3600,19 @@ find_match(struct parse *cfile, struct element *host) struct element *address; struct subnet *subnet; char addr[16]; + size_t group; size_t i, len; + int kind; + + for (group = cfile->stack_top; group > 0; --group) { + kind = cfile->stack[group]->kind; + if ((kind == GROUP_DECL) || (kind == ROOT_GROUP)) + break; + } + if (!group) + parse_error(cfile, "can't find root group"); + if (kind == GROUP_DECL) + return cfile->stack[group]; if (local_family == AF_INET) { address = mapGet(host, "ip-address"); @@ -3690,7 +3709,7 @@ get_class(struct parse *cfile, struct element *ref) struct element *param; size_t i; - classes = mapGet(cfile->stack[1], "clint-classes"); + classes = mapGet(cfile->stack[1], "client-classes"); if ((classes == NULL) || (listSize(classes) == 0)) return NULL; @@ -3723,7 +3742,7 @@ get_class(struct parse *cfile, struct element *ref) continue; if (!eqString(stringValue(name), stringValue(param))) continue; - param = mapGet(class, "string"); + param = mapGet(class, "binary"); if (param == NULL) continue; if (eqString(stringValue(selector), @@ -3732,9 +3751,6 @@ get_class(struct parse *cfile, struct element *ref) } return NULL; } - selector = mapGet(ref, "binary"); - if (selector == NULL) - return NULL; for (i = 0; i <listSize(classes); i++) { class = listGet(classes, i); param = mapGet(class, "super"); @@ -3742,7 +3758,7 @@ get_class(struct parse *cfile, struct element *ref) continue; if (!eqString(stringValue(name), stringValue(param))) continue; - param = mapGet(class, "binary"); + param = mapGet(class, "string"); if (param == NULL) continue; if (eqString(stringValue(selector), stringValue(param))) diff --git a/keama/doc.txt b/keama/doc.txt index f18ff517..0f612c51 100644 --- a/keama/doc.txt +++ b/keama/doc.txt @@ -142,6 +142,14 @@ Typically declarations use { } and are associated with a group (changed to a type) in ROOT_GROUP (global), HOST_DECL, SHARED_NET_DECL, SUBNET_DECL, CLASS_DECL, GROUP_DECL and POOL_DECL. +ROOT: parent = TOPLEVEL, children = everythig but not POOL +HOST: parent = ROOT, GROUP, warn on SHARED or SUBNET, children = none +SHARED_NET: parent = ROOT, GROUP, children = HOST (warn), SUBNET, POOL4 +SUBNET: parent = ROOT, GROUP, SHARED, children = HOST (warn), POOL +CLASS: parent = ROOT, GROUP, children = none +GROUP: parent = ROOT, SHARED, children = anything but not POOL +POOL: parent = SHARED4, SUBNET, warn on others, children = none + isc_boolean_t parse_statement(struct parse *cfile, int type, isc_boolean_t declaration); diff --git a/keama/keama.h b/keama/keama.h index d0c4fa17..a5410202 100644 --- a/keama/keama.h +++ b/keama/keama.h @@ -326,7 +326,7 @@ void parse_shared_net_declaration(struct parse *); void parse_subnet_declaration(struct parse *); void parse_subnet6_declaration(struct parse *); void parse_group_declaration(struct parse *); -void dissolve_group(struct parse *, struct element *); +void close_group(struct parse *, struct element *); struct element *parse_fixed_addr_param(struct parse *, enum dhcp_token); void parse_address_range(struct parse *, int, size_t); void parse_address_range6(struct parse *, int, size_t); diff --git a/keama/tests/groupclass4.in4 b/keama/tests/groupclass4.in4 new file mode 100644 index 00000000..ebf4f7fc --- /dev/null +++ b/keama/tests/groupclass4.in4 @@ -0,0 +1,35 @@ +# group and class declaration config + +# authoritative is mandatory +authoritative; + +# options +option mysystem code 250 = text; +option myversion code 251 = unsigned integer 16; + +# superclass declaration +class "foobar" { + match option mysystem; + option myversion 1; +} + +# simple subclass declaration +subclass "foobar" "version1"; + +group machin { + next-server 10.10.10.1; + # this option is not propagated because the superclass takes precedence + option myversion 99; + + # option setting subclass declaration + subclass "foobar" "version2" { option myversion 2; } + + # complex subclass declaration + subclass "foobar" "version3" { + option myversion 3; + next-server 192.168.0.1; + } + + # another simple subclass declaration + subclass "foobar" "version10"; +} diff --git a/keama/tests/groupclass4.out b/keama/tests/groupclass4.out new file mode 100644 index 00000000..d079d031 --- /dev/null +++ b/keama/tests/groupclass4.out @@ -0,0 +1,109 @@ +{ + # group and class declaration config + # authoritative is mandatory + "Dhcp4": { + "option-def": [ + # options + { + "space": "dhcp4", + "name": "mysystem", + "code": 250, + "type": "string" + }, + { + "space": "dhcp4", + "name": "myversion", + "code": 251, + "type": "uint16" + } + ], + "client-classes": [ + # superclass declaration + { + "name": "foobar", +// "spawning": false, +// "submatch": { +// "option": { +// "universe": "dhcp", +// "name": "mysystem" +// } +// }, + "option-data": [ + { + "space": "dhcp4", + "name": "myversion", + "code": 251, + "data": "1" + } + ] + }, + # simple subclass declaration + /// subclass selector 'version1' + { + "name": "sub#foobar#0", + "option-data": [ + { + "space": "dhcp4", + "name": "myversion", + "code": 251, + "data": "1" + } + ], + /// from: match option dhcp.mysystem + /// data: 'version1' + "test": "option[250].hex == 'version1'" + }, + # option setting subclass declaration + /// subclass selector 'version2' + { + "name": "sub#foobar#1", + "option-data": [ + { + "space": "dhcp4", + "name": "myversion", + "code": 251, + "data": "2" + } + ], + /// from: match option dhcp.mysystem + /// data: 'version2' + "test": "option[250].hex == 'version2'", + "next-server": "10.10.10.1" + }, + # complex subclass declaration + /// subclass selector 'version3' + { + "name": "sub#foobar#2", + "option-data": [ + { + "space": "dhcp4", + "name": "myversion", + "code": 251, + "data": "3" + } + ], + "next-server": "192.168.0.1", + /// from: match option dhcp.mysystem + /// data: 'version3' + "test": "option[250].hex == 'version3'" + }, + # another simple subclass declaration + /// subclass selector 'version10' + { + "name": "sub#foobar#3", + "option-data": [ + { + "space": "dhcp4", + "name": "myversion", + "code": 251, + "data": "1" + } + ], + /// from: match option dhcp.mysystem + /// data: 'version10' + "test": "option[250].hex == 'version10'", + "next-server": "10.10.10.1" + } + ] + } +} diff --git a/keama/tests/grouphost4.in4 b/keama/tests/grouphost4.in4 new file mode 100644 index 00000000..370f3baf --- /dev/null +++ b/keama/tests/grouphost4.in4 @@ -0,0 +1,38 @@ +# group and host declarations config + +# authoritative is mandatory +authoritative; + +# subnet4 declaration +subnet 10.5.5.0 netmask 255.255.255.224 { + range 10.5.5.5 10.5.5.10; +} + +# host declaration +host test1 { + hardware ethernet 00:0B:FD:32:E6:FA; + fixed-address 10.5.5.1, 10.10.10.10; +} + +# group declaration +group "foobar" { + default-lease-time 1800; + option domain-search "example.com", "example.org"; + next-server 192.168.0.1; + + # host declarations + host test2 { + hardware ethernet 00:07:0E:36:48:19; + fixed-address 10.5.5.2; + option domain-name "example.com"; + option domain-search "example.com", "com"; + } + + host test3 { + hardware fddi 00:07:0E:36:48:19; + fixed-address 10.10.10.1; + default-lease-time 3600; + } +} + +subnet 10.10.10.0 netmask 255.255.255.224 { } diff --git a/keama/tests/grouphost4.out b/keama/tests/grouphost4.out new file mode 100644 index 00000000..a6a9ccef --- /dev/null +++ b/keama/tests/grouphost4.out @@ -0,0 +1,75 @@ +{ + # group and host declarations config + # authoritative is mandatory + /// This configuration declares some subnets but has no interfaces-config + /// Reference Kea #5256 + "Dhcp4": { + "subnet4": [ + # subnet4 declaration + { + "subnet": "10.5.5.0/27", + "pools": [ + { + "pool": "10.5.5.5 - 10.5.5.10" + } + ], + "reservations": [ + # host declaration + { + "hostname": "test1", + "hw-address": "00:0b:fd:32:e6:fa", + "ip-address": "10.5.5.1" +// "extra-ip-addresses": [ +// "10.10.10.10" +// ] + }, + # host declarations + { + "hostname": "test2", + "hw-address": "00:07:0e:36:48:19", + "ip-address": "10.5.5.2", + "option-data": [ + { + "space": "dhcp4", + "name": "domain-name", + "code": 15, + "data": "example.com" + }, + { + "space": "dhcp4", + "name": "domain-search", + "code": 119, + "data": "example.com, com" + } + ], + "next-server": "192.168.0.1" + } + ] + }, + { + "subnet": "10.10.10.0/27", + "reservations": [ + { + "hostname": "test3", +// "hw-address": "fddi 00:07:0e:36:48:19", + "ip-address": "10.10.10.1", +// /// valid-lifetime in unsupported scope +// "valid-lifetime": 3600, + "option-data": [ + { + "space": "dhcp4", + "name": "domain-search", + "code": 119, + "data": "example.com, example.org" + } + ], + "next-server": "192.168.0.1" + } + ] + } + ], + "host-reservation-identifiers": [ + "hw-address" + ] + } +} diff --git a/keama/tests/groupsubnet4.in4 b/keama/tests/groupsubnet4.in4 new file mode 100644 index 00000000..a738f997 --- /dev/null +++ b/keama/tests/groupsubnet4.in4 @@ -0,0 +1,27 @@ +# Group with DHCPv4 subnet declaration config + +# authoritative is mandatory +authoritative; + +# parameter which will be changed in subnet +default-lease-time 1200; + +# group declaration +group foobar { + # option + option domain-search "example.com", "example.org"; + + # parameters + default-lease-time 3600; + ignore-client-uids false; + + # DHCPv4 subnet declaration + subnet 10.5.5.0 netmask 255.255.255.224 { + # at least one pool is required + pool { + range 10.5.5.5 10.5.5.10; + } + interface "bar"; + default-lease-time 1800; + } +} diff --git a/keama/tests/groupsubnet4.out b/keama/tests/groupsubnet4.out new file mode 100644 index 00000000..085933d5 --- /dev/null +++ b/keama/tests/groupsubnet4.out @@ -0,0 +1,36 @@ +{ + # Group with DHCPv4 subnet declaration config + # authoritative is mandatory + "Dhcp4": { + "valid-lifetime": 1200, + "interfaces-config": { + "interfaces": [ + "bar" + ] + }, + "subnet4": [ + # DHCPv4 subnet declaration + { + "subnet": "10.5.5.0/27", + "pools": [ + # at least one pool is required + { + "pool": "10.5.5.5 - 10.5.5.10" + } + ], + "interface": "bar", + "valid-lifetime": 1800, + "option-data": [ + # option + { + "space": "dhcp4", + "name": "domain-search", + "code": 119, + "data": "example.com, example.org" + } + ], + "match-client-id": true + } + ] + } +} diff --git a/keama/tests/groupsubnet6.in6 b/keama/tests/groupsubnet6.in6 new file mode 100644 index 00000000..be30b786 --- /dev/null +++ b/keama/tests/groupsubnet6.in6 @@ -0,0 +1,27 @@ +# Group with DHCPv6 subnet declaration config + +# authoritative is mandatory +authoritative; + +# parameter which will be changed in subnet +default-lease-time 1200; + +# group declaration +group foobar { + # option + option dhcp6.domain-search "example.com", "example.org"; + + # parameters + default-lease-time 3600; + + # DHCPv4 subnet declaration + subnet6 2001::/64 { + # at least one pool is required + pool6 { + range6 2001::100 2001::200; + } + interface "bar"; + default-lease-time 1800; + option dhcp6.lq-relay-data 2001::1, "foobar"; + } +} diff --git a/keama/tests/groupsubnet6.out b/keama/tests/groupsubnet6.out new file mode 100644 index 00000000..7a02e25a --- /dev/null +++ b/keama/tests/groupsubnet6.out @@ -0,0 +1,42 @@ +{ + # Group with DHCPv6 subnet declaration config + # authoritative is mandatory + "Dhcp6": { + "valid-lifetime": 1200, + "interfaces-config": { + "interfaces": [ + "bar" + ] + }, + "subnet6": [ + # DHCPv4 subnet declaration + { + "subnet": "2001::/64", + "pools": [ + # at least one pool is required + { + "pool": "2001::100 - 2001::200" + } + ], + "interface": "bar", + "valid-lifetime": 1800, + "option-data": [ + { + "space": "dhcp6", + "name": "lq-relay-data", + "code": 47, +// "original-data": "2001::1, \"foobar\"", + "data": "2001::1, foobar" + }, + # option + { + "space": "dhcp6", + "name": "domain-search", + "code": 24, + "data": "example.com, example.org" + } + ] + } + ] + } +} diff --git a/keama/tests/groupsubnetif.err4 b/keama/tests/groupsubnetif.err4 new file mode 100644 index 00000000..7c3801e9 --- /dev/null +++ b/keama/tests/groupsubnetif.err4 @@ -0,0 +1,22 @@ +# bad (interface unlnown in this cope) group declaration config + +# authoritative is mandatory +authoritative; + +# parameter which will be changed in subnet +default-lease-time 1200; + +# group declaration +group foobar { + # interface + interface "foo"; + + # DHCPv4 subnet declaration + subnet 10.5.5.0 netmask 255.255.255.224 { + # at least one pool is required + pool { + range 10.5.5.5 10.5.5.10; + } + interface "bar"; + } +} diff --git a/keama/tests/groupsubnetif.msg b/keama/tests/groupsubnetif.msg new file mode 100644 index 00000000..f89aed88 --- /dev/null +++ b/keama/tests/groupsubnetif.msg @@ -0,0 +1 @@ +groupsubnetif.err4 line 10: expecting a parameter or declaration diff --git a/keama/tests/subclass4.out b/keama/tests/subclass4.out index 716a7a6e..7113240a 100644 --- a/keama/tests/subclass4.out +++ b/keama/tests/subclass4.out @@ -38,9 +38,8 @@ ] }, # simple subclass declaration + /// subclass selector 'version1' { -// "super": "foobar", -// "string": "version1", "name": "sub#foobar#0", "option-data": [ { @@ -55,9 +54,8 @@ "test": "option[250].hex == 'version1'" }, # option setting subclass declaration + /// subclass selector 'version2' { -// "super": "foobar", -// "string": "version2", "name": "sub#foobar#1", "option-data": [ { @@ -72,9 +70,8 @@ "test": "option[250].hex == 'version2'" }, # complex subclass declaration + /// subclass selector 'version3' { -// "super": "foobar", -// "string": "version3", "name": "sub#foobar#2", "option-data": [ { diff --git a/keama/tests/subclass6.out b/keama/tests/subclass6.out index 237c20cd..2de8b63b 100644 --- a/keama/tests/subclass6.out +++ b/keama/tests/subclass6.out @@ -38,9 +38,8 @@ ] }, # simple subclass declaration + /// subclass selector 'version1' { -// "super": "foobar", -// "string": "version1", "name": "sub#foobar#0", "option-data": [ { @@ -55,9 +54,8 @@ "test": "option[1250].hex == 'version1'" }, # option setting subclass declaration + /// subclass selector 'version2' { -// "super": "foobar", -// "string": "version2", "name": "sub#foobar#1", "option-data": [ { @@ -72,9 +70,8 @@ "test": "option[1250].hex == 'version2'" }, # complex subclass declaration + /// subclass selector 'version3' { -// "super": "foobar", -// "string": "version3", "name": "sub#foobar#2", "option-data": [ { diff --git a/keama/tests/subclassbinsel4.out b/keama/tests/subclassbinsel4.out index 94b8a84c..aa70c9cd 100644 --- a/keama/tests/subclassbinsel4.out +++ b/keama/tests/subclassbinsel4.out @@ -29,9 +29,8 @@ ] }, # simple subclass declaration + /// subclass selector 0x0x0100070e364819 { -// "super": "foobar", -// "binary": "0x0100070e364819", "name": "sub#foobar#0", "option-data": [ { @@ -46,9 +45,8 @@ "test": "concat(substring(pkt4.htype,-1,all),pkt4.mac) == 0x0100070e364819" }, # option setting subclass declaration + /// subclass selector 0x0x01000bfd32e6fa { -// "super": "foobar", -// "binary": "0x01000bfd32e6fa", "name": "sub#foobar#1", "option-data": [ { diff --git a/keama/tests/subclassbinsel6.out b/keama/tests/subclassbinsel6.out index f89d99ad..300deaf3 100644 --- a/keama/tests/subclassbinsel6.out +++ b/keama/tests/subclassbinsel6.out @@ -39,9 +39,8 @@ ] }, # simple subclass declaration + /// subclass selector 0x0x0100070e364819 { -// "super": "foobar", -// "binary": "0x0100070e364819", "name": "sub#foobar#0", "option-data": [ # no harware in DHCPv6 @@ -57,9 +56,8 @@ "test": "option[1250].hex == 0x0100070e364819" }, # option setting subclass declaration + /// subclass selector 0x0x01000bfd32e6fa { -// "super": "foobar", -// "binary": "0x01000bfd32e6fa", "name": "sub#foobar#1", "option-data": [ { @@ -74,9 +72,8 @@ "test": "option[1250].hex == 0x01000bfd32e6fa" }, # complex subclass declaration + /// subclass selector 0x0x010002b388c527 { -// "super": "foobar", -// "binary": "0x010002b388c527", "name": "sub#foobar#2", "option-data": [ { |