]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5374] Addressed non test comments - checkpoint before regen
authorFrancis Dupont <fdupont@isc.org>
Fri, 6 Apr 2018 14:22:09 +0000 (16:22 +0200)
committerFrancis Dupont <fdupont@isc.org>
Fri, 6 Apr 2018 14:22:09 +0000 (16:22 +0200)
26 files changed:
doc/Makefile.am
doc/examples/kea4/classify2.json [new file with mode: 0644]
doc/examples/kea6/classify2.json [new file with mode: 0644]
doc/guide/classify.xml
doc/guide/dhcp4-srv.xml
doc/guide/dhcp6-srv.xml
src/bin/dhcp4/dhcp4_lexer.ll
src/bin/dhcp4/dhcp4_parser.yy
src/bin/dhcp4/tests/classify_unittest.cc
src/bin/dhcp4/tests/parser_unittest.cc
src/bin/dhcp6/dhcp6_lexer.ll
src/bin/dhcp6/dhcp6_parser.yy
src/bin/dhcp6/tests/classify_unittests.cc
src/bin/dhcp6/tests/parser_unittest.cc
src/lib/dhcpsrv/network.cc
src/lib/dhcpsrv/network.h
src/lib/dhcpsrv/parsers/dhcp_parsers.cc
src/lib/dhcpsrv/parsers/shared_network_parser.cc
src/lib/dhcpsrv/pool.cc
src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc
src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc
src/lib/dhcpsrv/tests/pool_unittest.cc
src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc
src/lib/dhcpsrv/tests/shared_network_unittest.cc
src/lib/eval/eval.dox
src/lib/eval/eval_context.h

index 2be574a095632e7dfe8baaaaecfc26153e675e3e..c39619a79573a0b323684471404220c6e691b4df 100644 (file)
@@ -18,6 +18,7 @@ nobase_dist_doc_DATA += examples/kea4/advanced.json
 nobase_dist_doc_DATA += examples/kea4/backends.json
 nobase_dist_doc_DATA += examples/kea4/cassandra.json
 nobase_dist_doc_DATA += examples/kea4/classify.json
+nobase_dist_doc_DATA += examples/kea4/classify2.json
 nobase_dist_doc_DATA += examples/kea4/dhcpv4-over-dhcpv6.json
 nobase_dist_doc_DATA += examples/kea4/hooks.json
 nobase_dist_doc_DATA += examples/kea4/leases-expiration.json
@@ -33,6 +34,7 @@ nobase_dist_doc_DATA += examples/kea6/advanced.json
 nobase_dist_doc_DATA += examples/kea6/backends.json
 nobase_dist_doc_DATA += examples/kea6/cassandra.json
 nobase_dist_doc_DATA += examples/kea6/classify.json
+nobase_dist_doc_DATA += examples/kea6/classify2.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
diff --git a/doc/examples/kea4/classify2.json b/doc/examples/kea4/classify2.json
new file mode 100644 (file)
index 0000000..626d5c9
--- /dev/null
@@ -0,0 +1,149 @@
+// This is an example configuration file for the DHCPv4 server in Kea.
+// The purpose of this example is to showcase how clients can be classified
+// with advanced features.
+
+{ "Dhcp4": {
+
+// Kea is told to listen on ethX interface only.
+  "interfaces-config": {
+      "interfaces": [ "ethX" ]
+  },
+
+// Let's use the simplest backend: memfile and use some reasonable values
+// for timers. They are of no concern for the classification demonstration.
+  "lease-database": { "type": "memfile" },
+  "renew-timer": 1000,
+  "rebind-timer": 2000,
+  "valid-lifetime": 4000,
+
+// This list defines several classes that incoming packets can be assigned to.
+// One packet can belong to zero or more classes.
+  "client-classes": [
+
+// This class is required by the second subnet and is evaluated only
+// if it is required. The test expression returns true.
+// Note it is not possible to depend on VoIP class because it is not yet
+// defined.
+  {
+      "name": "second_subnet",
+      "only-if-required": true,
+      "test": "member('ALL')",
+      "option-data": [{
+          "name": "domain-name-servers",
+          "data": "127.0.0.1"
+      }]
+  },
+
+// Let's classify all incoming DISCOVER (message type 1) to a separate
+// class.
+  {
+      "name": "discovers",
+      "test": "pkt4.msgtype == 1"
+  },
+
+// Clients are supposed to set the transaction-id field to a random value.
+// Clients that send it with 0 are most likely broken. Let's mark them
+// as such.
+  {
+      "name": "broken",
+      "test": "pkt4.transid == 0"
+  },
+
+// Let's pick VoIP phones. Those that send their class identifiers
+// as Aastra, should belong to VoIP class. For a list of all options,
+// see www.iana.org/assignments/bootp-dhcp-parameters/.
+// In this particular class, we want to set specific values
+// of certain DHCPv4 fields. If the incoming packet matches the
+// test, those fields will be set in outgoing responses.
+// The option 43 is defined to encapsulate suboption in the aastra space.
+  {
+      "name": "VoIP",
+      "test": "substring(option[60].hex,0,6) == 'Aastra'",
+      "next-server": "192.0.2.254",
+      "server-hostname": "hal9000",
+      "boot-file-name": "/dev/null",
+      "option-def": [ {
+          "name": "vendor-encapsulated-options",
+          "code": 43,
+          "type": "empty",
+          "encapsulate": "aastra" } ]
+  },
+
+// Both a VoIP phone (by evaluation or host reservation) and has a host
+// reservation.
+  {
+      "name": "VoIP_host",
+      "test": "member('VoIP') and member('KNOWN')",
+      "server-hostname": "hal9001"
+  }
+
+  ],
+
+// The following list defines subnets. For some subnets we defined
+// a class that is allowed in that subnet. If not specified,
+// everyone is allowed. When a class is specified, only packets belonging
+// to that class are allowed for that subnet.
+  "subnet4": [
+    {
+// This one is for VoIP devices only.
+        "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
+        "subnet": "192.0.2.0/24",
+        "client-class": "VoIP",
+        "interface": "ethX"
+    },
+// This one doesn't have any client-class specified, so everyone
+// is allowed in. The normal subnet selection rules still apply,
+// though. There is also a static class reservation for a client
+// using MAC address 1a:1b:1c:1d:1e:1f. This client will always
+// be assigned to this class.
+    {
+        "pools": [ { "pool":  "192.0.3.1 - 192.0.3.200" } ],
+        "subnet": "192.0.3.0/24",
+        "reservations": [
+        {
+            "hw-address": "1a:1b:1c:1d:1e:1f",
+            "client-classes": [ "VoIP" ]
+        } ],
+        "interface": "ethX"
+    },
+
+// The following list defines a subnet with pools. For some pools
+// we defined a class that is allowed in that pool. If not specified
+// everyone is allowed. When a class is specified, only packets belonging
+// to that class are allowed for that pool.
+     {
+        "pools": [
+           {
+// This one is for VoIP devices only.
+              "pool":  "192.0.4.1 - 192.0.4.200",
+              "client-class": "VoIP"
+           },
+// This one doesn't have any client-class specified, so everyone
+// is allowed in.
+           {
+               "pool":  "192.0.5.1 - 192.0.5.200"
+           } ],
+           "subnet": "192.0.4.0/23",
+           "interface": "ethY"
+     }
+  ]
+},
+
+// The following configures logging. It assumes that messages with at
+// least informational level (info, warn, error and fatal) should be
+// logged to stdout.
+"Logging": {
+    "loggers": [
+        {
+            "name": "kea-dhcp4",
+            "output_options": [
+                {
+                    "output": "stdout"
+                }
+            ],
+            "severity": "INFO"
+        }
+    ]
+}
+
+}
diff --git a/doc/examples/kea6/classify2.json b/doc/examples/kea6/classify2.json
new file mode 100644 (file)
index 0000000..aa6a7bd
--- /dev/null
@@ -0,0 +1,121 @@
+// This is an example configuration file for the DHCPv4 server in Kea.
+// The purpose of this example is to showcase how clients can be classified.
+
+{ "Dhcp6":
+
+{
+// Kea is told to listen on ethX interface only.
+  "interfaces-config": {
+    "interfaces": [ "ethX" ]
+  },
+
+// Let's use the simplest backend: memfile and use some reasonable values
+// for timers. They are of no concern for the classification demonstration.
+  "lease-database": {
+      "type": "memfile",
+      "lfc-interval": 3600
+  },
+  "renew-timer": 1000,
+  "rebind-timer": 2000,
+  "preferred-lifetime": 3000,
+  "valid-lifetime": 4000,
+
+// This list defines several classes that incoming packets can be assigned to.
+// One packet can belong to zero or more classes.
+  "client-classes": [
+
+// This class is required by the second subnet and is evaluated only
+// if it is required. The test expression returns true.
+// Note it is not possible to depend on cable-modems class because it
+// is not yet defined.
+  {
+      "name": "second_subnet",
+      "only-if-required": true,
+      "test": "member('ALL')",
+      "option-data": [{
+          "name": "dns-servers",
+          "data": "2001:db8::1"
+      }]
+  },
+
+// Let's classify all incoming RENEW (message type 5) to a separate
+// class.
+  {
+      "name": "renews",
+      "test": "pkt6.msgtype == 5"
+  },
+
+// Let's pick cable modems. In this simple example we'll assume the device
+// is a cable modem if it sends a vendor option with enterprise-id equal
+// to 4491.
+  {
+      "name": "cable-modems",
+      "test": "vendor.enterprise == 4491"
+  },
+
+// Both a cable modem (by evaluation or host reservation) and has a host
+// reservation.
+  {
+      "name": "cable-modem-hosts",
+      "test": "member('cable-modems') and member('KNOWN')"
+  }
+
+  ],
+
+
+// The following list defines subnets. Each subnet consists of at
+// least subnet and pool entries.
+  "subnet6": [
+    {
+        "pools": [ { "pool": "2001:db8:1::/80" } ],
+        "subnet": "2001:db8:1::/64",
+        "client-class": "cable-modems",
+        "interface": "ethX"
+    },
+// The following subnet contains a class reservation for a client using
+// DUID 01:02:03:04:05:0A:0B:0C:0D:0E. This client will always be assigned
+// to this class.
+    {
+        "pools": [ { "pool": "2001:db8:2::/80" } ],
+        "subnet": "2001:db8:2::/64",
+        "reservations": [
+        {
+            "duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
+            "client-classes": [ "cable-modems" ]
+        } ],
+        "interface": "ethX"
+    },
+// The following subnet contains a pool with a class constraint: only
+// clients which belong to the class are allowed to use this pool.
+    {
+        "pools": [
+           {
+               "pool": "2001:db8:3::/80",
+               "client-class": "cable-modems"
+           } ],
+         "subnet": "2001:db8:4::/64",
+         "interface": "ethY"
+    }
+
+  ]
+},
+
+// The following configures logging. It assumes that messages with at
+// least informational level (info, warn, error and fatal) should be
+// logged to stdout.
+"Logging": {
+    "loggers": [
+        {
+            "name": "kea-dhcp6",
+            "output_options": [
+                {
+                    "output": "stdout"
+                }
+            ],
+            "debuglevel": 0,
+            "severity": "INFO"
+        }
+    ]
+}
+
+}
index 0a1b2baf2a91c3f2bd06839eb921c5c43266ed5c..06e7beebf61530b3ca2af7a5e87b4a35a8be6a7f 100644 (file)
 
       <note>
       <para>
-      Beginning with 1.4 client classes follow now the insertion order
-      (vs. alphabetical order in previous versions).
+      Beginning with Kea 1.4.0 release,  client classes follow the order
+      in which they are specified in the configuration
+      (vs. alphabetical order in previous versions), or for required
+      classes the order they are required.
       </para>
       </note>
 
       belongs to, and the KNOWN class. By convention builtin classes
       names begin with all caps.
       </para>
+
+      <para>Currently recognized builtin class names are ALL and KNOWN
+      and prefixes VENDOR_CLASS_, AFTER_ and EXTERNAL_. The AFTER_ prefix
+      is a provision for a not yet written hook, the EXTERNAL_ prefix
+      can be freely used: builtin classes are implicitly defined so
+      never raise warnings because they do not appear in the configuration.
+      </para>
+
   </section>
 
   <section id="classification-using-expressions">
@@ -788,11 +798,11 @@ concatenation of the strings</entry></row>
       subnet, shared-network or pools are known but output option
       processing not yet done. The only-if-required flag, false by default,
       allows to perform the evaluation of the test expression only
-      when it was required, i.e. in a required-client-classes list.
+      when it was required, i.e. in a require-client-classes list.
       </para>
 
       <para>
-      The required-client-classes list which is valid for shared-network,
+      The require-client-classes list which is valid for shared-network,
       subnet and pool scope specifies the classes which are evaluated
       in the second pass before output option processing.
       The list is built in the reversed precedence order of option
index 479580e11fcb62bf28489544dace52f4e5f2d445..7fed462b7b72dc703f811db747c2a7504d0714f7 100644 (file)
@@ -2064,8 +2064,9 @@ It is merely echoed by the server
       the DHCP message processing, including the assignment of leases from different
       pools, the assignment of different options (or different values of the same
       options) etc. In the current release of the software however, there are
-      only three mechanisms that take advantage of client classification:
-      subnet selection, assignment of different options, and, for cable modems, there
+      only some mechanisms that take advantage of client classification:
+      private options and option 43 deferred unpacking, subnet selection,
+      pool selection, assignment of different options, and, for cable modems, there
       are specific options for use with the TFTP server address and the boot file field.
       </para>
 
@@ -2091,19 +2092,24 @@ It is merely echoed by the server
       </para>
 
       <para>
-      The process of doing classification is conducted in five steps. The first step
+      The process of doing classification is conducted in several steps. The first step
       is to assess an incoming packet and assign it to zero or more classes.  The
       second step is to choose a subnet, possibly based on the class information.
-      The third step is to assign classes from host reservations.
-      The forth step is to build the list of required classes and perform
-      the evaluation for each class of the list.
+      The third step is to assign classes from host reservations and
+      evaluate class expressions depending on the "KNOWN" class.
+      After the list of required classes is built and each class of the list
+      has its expression evaluated: when it returns true the packet is added
+      as a member of the class.
       The last step is to assign options, again possibly based on the class
       information.
+      More complete and detailed description is available in
+      <xref linkend="classify"/>.
       </para>
 
       <para>
-      There are two methods of doing classification. The first is automatic and relies
-      on examining the values in the vendor class options. Information from these
+      There are two main methods of doing classification. The first is automatic and relies
+      on examining the values in the vendor class options or existence of a
+      host reservation. Information from these
       options is extracted and a class name is constructed from it and added to
       the class list for the packet. The second allows you to specify an expression
       that is evaluated for each packet. If the result is true the packet is
@@ -2155,11 +2161,12 @@ It is merely echoed by the server
 
           <para>
             If there are multiple classes defined and an incoming packet is matched
-            to multiple classes, the class which is defined first is used.
+            to multiple classes, the class which is evaluated first is used.
           </para>
 
           <note><para>
-            In versions before 1.4 the alphabetical order was used.
+            In Kea versions prior to 1.4.0 the alphabetical order of class names was used.
+            Starting from Kea 1.4.0 the classes are ordered as specified in the configuration.
           </para></note>
 
         </section>
@@ -2260,13 +2267,15 @@ It is merely echoed by the server
         The first one is the per-class <command>only-if-required</command>
         flag which is false by default. When it is set to
         <command>true</command> the test expression of the class is not
-        evaluated at the reception of a new incoming ticket.
+        evaluated at the reception of a new incoming ticket but
+        later and only if the class evaluation is required.
         </para>
 
         <para>
-        The second is the <command>required-client-classes</command> which
+        The second is the <command>require-client-classes</command> which
         takes a list of class names and is valid in shared-network,
-        subnet and pool scope. Classes in these lists are evaluated
+        subnet and pool scope. Classes in these lists are marked as
+        required and evaluated
         after resource assignment and before output option processing.
         </para>
 
@@ -2279,7 +2288,7 @@ It is merely echoed by the server
     "client-classes": [
        {<userinput>
            "name": "Client_foo",
-           "test": "'' == ''",
+           "test": "member('ALL')",
            "only-if-required": true</userinput>
        },
        ...
@@ -2288,7 +2297,7 @@ It is merely echoed by the server
         {
             "subnet": "192.0.2.0/24",
             "pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
-            <userinput>"required-client-classes": [ "Client_foo" ],</userinput>
+            <userinput>"require-client-classes": [ "Client_foo" ],</userinput>
             ...
         },
         ...
@@ -2296,6 +2305,23 @@ It is merely echoed by the server
     ...
 }</screen>
          </para>
+
+         <para>
+         Required evaluation can be used to express complex dependencies
+         including for instance subnet membership, and to reverse the
+         precedence: if you set an option-data in a subnet it takes
+         precedence over an option-data in a class. When you move the
+         option-data to a (only-if) required class and require it in
+         the subnet a class evaluted or set before takes precedence.
+         </para>
+
+         <para>
+         Required evaluation is also available at shared-network and
+         pool levels. The order required classes are considered is
+         shared-network, subnet and pool, i.e. the opposite order
+         option-data are processed.
+         </para>
+
        </section>
     </section>
 
@@ -3392,7 +3418,7 @@ It is merely echoed by the server
       to configure the server to assign classes to a client based on the content
       of the options that this client sends to the server. Host reservations
       mechanisms also allow for statically assigning classes to the clients.
-      The definitions of these classes must exist in the Kea
+      The definitions of these classes should exist in the Kea
       configuration. The following configuration snippet shows how to specify
       that a client belongs to classes <command>reserved-class1</command>
       and <command>reserved-class2</command>. Those classes are associated with
@@ -3438,7 +3464,18 @@ It is merely echoed by the server
 </screen>
 
     <para>Static class assignments, as shown above, can be used in conjunction
-    with classification using expressions.</para>
+    with classification using expressions. The "KNOWN" builtin class is
+    added to the packet and any class depending on it directly or indirectly
+    and not only-if-required is evaluted.
+    </para>
+
+    <note>
+     <para>If you want to force the evaluation of a class expression after
+     the host reservation lookup, for instance because of a dependency on
+     "reserved-class1" from the previous example, you should add a
+     "member('KNOWN')" in the expression.</para>
+    </note>
+
     </section>
 
     <section id="reservations4-mysql-pgsql">
index ed7e22fa5ef9dc26180b2d5682051c812187eeb4..9a671c2def06e9db834a9beb32807cf72cbf535c 100644 (file)
@@ -1924,8 +1924,8 @@ should include options from the isc option space:
       the DHCP message processing, including the assignment of leases from different
       pools, the assignment of different options (or different values of the same
       options) etc. In the current release of the software however, there are
-      only two mechanisms that take advantage of client classification:
-      subnet selection and assignment of different options.
+      only some mechanisms that take advantage of client classification:
+      subnet selection, pool selection, and assignment of different options.
       </para>
 
       <para>
@@ -1951,19 +1951,24 @@ should include options from the isc option space:
       </para>
 
       <para>
-      The process of doing classification is conducted in five steps. The first step
+      The process of doing classification is conducted in several steps. The first step
       is to assess an incoming packet and assign it to zero or more classes.  The
       second step is to choose a subnet, possibly based on the class information.
-      The third step is to assign classes from host reservations.
-      The forth step is to build the list of required classes and perform
-      the evaluation for each class of the list.
+      The third step is to assign classes from host reservations and
+      evaluate class expressions depending on the "KNOWN" class.
+      After the list of required classes is built and each class of the list
+      has its expression evaluated: when it returns true the packet is added
+      as a member of the class.
       The last step is to assign options again possibly based on the class
       information.
+      More complete and detailed description is available in
+      <xref linkend="classify"/>.
       </para>
 
       <para>
-      There are two methods of doing classification. The first is automatic and relies
-      on examining the values in the vendor class options. Information from these
+      There are two main methods of doing classification. The first is automatic and relies
+      on examining the values in the vendor class options or existence of a
+      host reservation. Information from these
       options is extracted and a class name is constructed from it and added to
       the class list for the packet. The second allows you to specify an expression
       that is evaluated for each packet. If the result is true the packet is
@@ -2053,13 +2058,15 @@ should include options from the isc option space:
         The first one is the per-class <command>only-if-required</command>
         flag which is false by default. When it is set to
         <command>true</command> the test expression of the class is not
-        evaluated at the reception of a new incoming ticket.
+        evaluated at the reception of a new incoming ticket but
+        later and only if the class evaluation is required.
         </para>
 
         <para>
-        The second is the <command>required-client-classes</command> which
+        The second is the <command>require-client-classes</command> which
         takes a list of class names and is valid in shared-network,
-        subnet and pool scope. Classes in these lists are evaluated
+        subnet and pool scope. Classes in these lists are marked as
+        required and evaluated
         after resource assignment and before output option processing.
         </para>
 
@@ -2072,7 +2079,7 @@ should include options from the isc option space:
     "client-classes": [
        {<userinput>
            "name": "Client_foo",
-           "test": "'' == ''",
+           "test": "member('ALL')",
            "only-if-required": true</userinput>
        },
        ...
@@ -2085,7 +2092,7 @@ should include options from the isc option space:
                      "pool": "2001:db8:1::-2001:db8:1::ffff"
                  }
              ],
-            <userinput>"required-client-classes": [ "Client_foo" ],</userinput>
+            <userinput>"require-client-classes": [ "Client_foo" ],</userinput>
             ...
         },
         ...
@@ -2093,6 +2100,23 @@ should include options from the isc option space:
     ...
 }</screen>
          </para>
+
+         <para>
+         Required evaluation can be used to express complex dependencies
+         including for instance subnet membership, and to reverse the
+         precedence: if you set an option-data in a subnet it takes
+         precedence over an option-data in a class. When you move the
+         option-data to a (only-if) required class and require it in
+         the subnet a class evaluted or set before takes precedence.
+         </para>
+
+         <para>
+         Required evaluation is also available at shared-network and
+         pool/pd-pool levels. The order required classes are considered is
+         shared-network, subnet and (pd-)pool, i.e. the opposite order
+         option-data are processed.
+         </para>
+
        </section>
     </section>
 
@@ -2960,7 +2984,18 @@ should include options from the isc option space:
 
 </screen>
     <para>Static class assignments, as shown above, can be used in conjunction
-    with classification using expressions.</para>
+    with classification using expressions. The "KNOWN" builtin class is
+    added to the packet and any class depending on it directly or indirectly
+    and not only-if-required is evaluted.
+    </para>
+
+    <note>
+     <para>If you want to force the evaluation of a class expression after
+     the host reservation lookup, for instance because of a dependency on
+     "reserved-class1" from the previous example, you should add a
+     "member('KNOWN')" in the expression.</para>
+    </note>
+
     </section>
 
     <section id="reservations6-mysql-pgsql">
index 1e68cde4ce0df80f2b846b95179125be2987ca65..74570b2b231a66547d4cf6d540768968e15c7210 100644 (file)
@@ -795,14 +795,14 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     }
 }
 
-\"required-client-classes\" {
+\"require-client-classes\" {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::SUBNET4:
     case isc::dhcp::Parser4Context::POOLS:
     case isc::dhcp::Parser4Context::SHARED_NETWORK:
-        return isc::dhcp::Dhcp4Parser::make_REQUIRED_CLIENT_CLASSES(driver.loc_);
+        return isc::dhcp::Dhcp4Parser::make_REQUIRE_CLIENT_CLASSES(driver.loc_);
     default:
-        return isc::dhcp::Dhcp4Parser::make_STRING("required-client-classes", driver.loc_);
+        return isc::dhcp::Dhcp4Parser::make_STRING("require-client-classes", driver.loc_);
     }
 }
 
index 498bddf91e7e61b37462c6acb5f4e3777827feea..d503708e29e6e22c6ae9f03115d5f6175eaba48a 100644 (file)
@@ -123,7 +123,7 @@ using namespace std;
   HOST_RESERVATION_IDENTIFIERS "host-reservation-identifiers"
 
   CLIENT_CLASSES "client-classes"
-  REQUIRED_CLIENT_CLASSES "required-client-classes"
+  REQUIRE_CLIENT_CLASSES "require-client-classes"
   TEST "test"
   ONLY_IF_REQUIRED "only-if-required"
   CLIENT_CLASS "client-class"
@@ -911,7 +911,7 @@ subnet4_param: valid_lifetime
              | id
              | rapid_commit
              | client_class
-             | required_client_classes
+             | require_client_classes
              | reservations
              | reservation_mode
              | relay
@@ -982,9 +982,9 @@ client_class: CLIENT_CLASS {
     ctx.leave();
 };
 
-required_client_classes: REQUIRED_CLIENT_CLASSES {
+require_client_classes: REQUIRE_CLIENT_CLASSES {
     ElementPtr c(new ListElement(ctx.loc2pos(@1)));
-    ctx.stack_.back()->set("required-client-classes", c);
+    ctx.stack_.back()->set("require-client-classes", c);
     ctx.stack_.push_back(c);
     ctx.enter(ctx.NO_KEYWORD);
 } COLON list_strings {
@@ -1061,7 +1061,7 @@ shared_network_param: name
                     | relay
                     | reservation_mode
                     | client_class
-                    | required_client_classes
+                    | require_client_classes
                     | valid_lifetime
                     | unknown_map_entry
                     ;
@@ -1344,7 +1344,7 @@ pool_params: pool_param
 pool_param: pool_entry
           | option_data_list
           | client_class
-          | required_client_classes
+          | require_client_classes
           | user_context
           | unknown_map_entry
           ;
index 504ed6a577b75d42ae15ea4bc70c6e72862be89f..7e9e2d8f3298151c77989994ab9267c8762e8ec0 100644 (file)
@@ -209,7 +209,7 @@ const char* CONFIGS[] = {
         "    \"subnet\": \"10.0.0.0/24\", "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"
-        "    \"required-client-classes\": [ \"pxe2\" ]"
+        "    \"require-client-classes\": [ \"pxe2\" ]"
         " } ]"
     "}"
 
@@ -754,7 +754,7 @@ TEST_F(ClassifyTest, precedencePool) {
         "        \"id\": 1,"
         "        \"pools\": [ { "
         "            \"pool\": \"10.0.0.10-10.0.0.100\","
-        "            \"required-client-classes\": [ \"for-pool\" ]"
+        "            \"require-client-classes\": [ \"for-pool\" ]"
         "         } ]"
         "    } ]"
         "} ]"
@@ -831,10 +831,10 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "    \"subnet4\": [ { "
         "        \"subnet\": \"10.0.0.0/24\","
         "        \"id\": 1,"
-        "        \"required-client-classes\": [ \"for-subnet\" ],"
+        "        \"require-client-classes\": [ \"for-subnet\" ],"
         "        \"pools\": [ { "
         "            \"pool\": \"10.0.0.10-10.0.0.100\","
-        "            \"required-client-classes\": [ \"for-pool\" ]"
+        "            \"require-client-classes\": [ \"for-pool\" ]"
         "         } ]"
         "    } ]"
         "} ]"
@@ -908,14 +908,14 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "],"
         "\"shared-networks\": [ {"
         "    \"name\": \"frog\","
-        "    \"required-client-classes\": [ \"for-network\" ],"
+        "    \"require-client-classes\": [ \"for-network\" ],"
         "    \"subnet4\": [ { "
         "        \"subnet\": \"10.0.0.0/24\","
         "        \"id\": 1,"
-        "        \"required-client-classes\": [ \"for-subnet\" ],"
+        "        \"require-client-classes\": [ \"for-subnet\" ],"
         "        \"pools\": [ { "
         "            \"pool\": \"10.0.0.10-10.0.0.100\","
-        "            \"required-client-classes\": [ \"for-pool\" ]"
+        "            \"require-client-classes\": [ \"for-pool\" ]"
         "         } ]"
         "    } ]"
         "} ]"
index adadbe9676e9d8d97448fe45bf61f9902def2ec0..eefc89cab1cb3ab546188cb734e4f9b3700c42e8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -244,6 +244,7 @@ TEST(ParserTest, file) {
                                "backends.json",
                                "cassandra.json",
                                "classify.json",
+                               "classify2.json",
                                "dhcpv4-over-dhcpv6.json",
                                "hooks.json",
                                "leases-expiration.json",
index d8c8afd79dbc77dcc4364b53146c490998c7625a..c9a52e69130c83e12ee06e5f7ed9c853d1a269f5 100644 (file)
@@ -1047,15 +1047,15 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     }
 }
 
-\"required-client-classes\" {
+\"require-client-classes\" {
     switch(driver.ctx_) {
     case isc::dhcp::Parser6Context::SUBNET6:
     case isc::dhcp::Parser6Context::POOLS:
     case isc::dhcp::Parser6Context::PD_POOLS:
     case isc::dhcp::Parser6Context::SHARED_NETWORK:
-        return isc::dhcp::Dhcp6Parser::make_REQUIRED_CLIENT_CLASSES(driver.loc_);
+        return isc::dhcp::Dhcp6Parser::make_REQUIRE_CLIENT_CLASSES(driver.loc_);
     default:
-        return isc::dhcp::Dhcp6Parser::make_STRING("required-client-classes", driver.loc_);
+        return isc::dhcp::Dhcp6Parser::make_STRING("require-client-classes", driver.loc_);
     }
 }
 
index 9bfaa141d5dd10696400d0361e6c002327f43045..ab3f2b3109d343e326254a520a92404d22ffa1e1 100644 (file)
@@ -116,7 +116,7 @@ using namespace std;
   HOST_RESERVATION_IDENTIFIERS "host-reservation-identifiers"
 
   CLIENT_CLASSES "client-classes"
-  REQUIRED_CLIENT_CLASSES "required-client-classes"
+  REQUIRE_CLIENT_CLASSES "require-client-classes"
   TEST "test"
   ONLY_IF_REQUIRED "only-if-required"
   CLIENT_CLASS "client-class"
@@ -906,7 +906,7 @@ subnet6_param: preferred_lifetime
              | id
              | rapid_commit
              | client_class
-             | required_client_classes
+             | require_client_classes
              | reservations
              | reservation_mode
              | relay
@@ -946,9 +946,9 @@ client_class: CLIENT_CLASS {
     ctx.leave();
 };
 
-required_client_classes: REQUIRED_CLIENT_CLASSES {
+require_client_classes: REQUIRE_CLIENT_CLASSES {
     ElementPtr c(new ListElement(ctx.loc2pos(@1)));
-    ctx.stack_.back()->set("required-client-classes", c);
+    ctx.stack_.back()->set("require-client-classes", c);
     ctx.stack_.push_back(c);
     ctx.enter(ctx.NO_KEYWORD);
 } COLON list_strings {
@@ -1023,7 +1023,7 @@ shared_network_param: name
                     | relay
                     | reservation_mode
                     | client_class
-                    | required_client_classes
+                    | require_client_classes
                     | preferred_lifetime
                     | rapid_commit
                     | valid_lifetime
@@ -1307,7 +1307,7 @@ pool_params: pool_param
 pool_param: pool_entry
           | option_data_list
           | client_class
-          | required_client_classes
+          | require_client_classes
           | user_context
           | unknown_map_entry
           ;
@@ -1383,7 +1383,7 @@ pd_pool_param: pd_prefix
              | pd_delegated_len
              | option_data_list
              | client_class
-             | required_client_classes
+             | require_client_classes
              | excluded_prefix
              | excluded_prefix_len
              | user_context
index 573738c15b27a50ae80dbeb8f6cf055d1910484e..99611da61e1c9401f3aa54d32f798955f27e1721 100644 (file)
@@ -415,7 +415,7 @@ TEST_F(ClassifyTest, requiredClassification) {
         "\"subnet6\": [ "
         "{   \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ], "
         "    \"subnet\": \"2001:db8:1::/48\", "
-        "    \"required-client-classes\": [ \"router\" ], "
+        "    \"require-client-classes\": [ \"router\" ], "
         "    \"interface\": \"eth1\" } ],"
         "\"client-classes\": [ "
         "{   \"name\": \"router\", "
@@ -1349,7 +1349,7 @@ TEST_F(ClassifyTest, precedencePool) {
         "        \"id\": 1,"
         "        \"pools\": [ { "
         "            \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\","
-        "            \"required-client-classes\": [ \"for-pool\" ]"
+        "            \"require-client-classes\": [ \"for-pool\" ]"
         "        } ]"
         "    } ]"
         "} ],"
@@ -1430,10 +1430,10 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "    \"subnet6\": [ { "
         "        \"subnet\": \"2001:db8:1::/64\","
         "        \"id\": 1,"
-        "        \"required-client-classes\": [ \"for-subnet\" ],"
+        "        \"require-client-classes\": [ \"for-subnet\" ],"
         "        \"pools\": [ { "
         "            \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\","
-        "            \"required-client-classes\": [ \"for-pool\" ]"
+        "            \"require-client-classes\": [ \"for-pool\" ]"
         "        } ]"
         "    } ]"
         "} ],"
@@ -1511,14 +1511,14 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "\"shared-networks\": [ {"
         "    \"name\": \"frog\","
         "    \"interface\": \"eth1\","
-        "    \"required-client-classes\": [ \"for-network\" ],"
+        "    \"require-client-classes\": [ \"for-network\" ],"
         "    \"subnet6\": [ { "
         "        \"subnet\": \"2001:db8:1::/64\","
         "        \"id\": 1,"
-        "        \"required-client-classes\": [ \"for-subnet\" ],"
+        "        \"require-client-classes\": [ \"for-subnet\" ],"
         "        \"pools\": [ { "
         "            \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\","
-        "            \"required-client-classes\": [ \"for-pool\" ]"
+        "            \"require-client-classes\": [ \"for-pool\" ]"
         "        } ]"
         "    } ]"
         "} ],"
index fdc9c85f3865dc0ae16531a17407cde9dfed5bd0..b221dd760e0f9fa3d5049814d5e9f973eca1272a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -248,6 +248,7 @@ TEST(ParserTest, file) {
     configs.push_back("backends.json");
     configs.push_back("cassandra.json");
     configs.push_back("classify.json");
+    configs.push_back("classify2.json");
     configs.push_back("dhcpv4-over-dhcpv6.json");
     configs.push_back("duid.json");
     configs.push_back("hooks.json");
index 0c48dba822cbf03eedcf93accd3086b90b9dd2dc..78b289810ee2f6239425b38e41d2b3b8ef0a2a7c 100644 (file)
@@ -70,7 +70,7 @@ Network::toElement() const {
         map->set("client-class", Element::create(cclass));
     }
 
-    // Set required-client-classes
+    // Set require-client-classes
     const ClientClasses& classes = getRequiredClasses();
     if (!classes.empty()) {
         ElementPtr class_list = Element::createList();
@@ -78,7 +78,7 @@ Network::toElement() const {
              it != classes.cend(); ++it) {
             class_list->add(Element::create(*it));
         }
-        map->set("required-client-classes", class_list);
+        map->set("require-client-classes", class_list);
     }
 
     // Set renew-timer
index 40ffe93010edd717085b6cbd5d22ba8e88d8f94c..dacaa317ca76b0e472e162af7a74663d9b6e4433 100644 (file)
@@ -277,7 +277,7 @@ protected:
     /// @brief Optional definition of a client class
     ///
     /// If defined, only clients belonging to that class will be allowed to use
-    /// this particular network. The default value for this is an empty list,
+    /// this particular network. The default value for this is an empty string,
     /// which means that any client is allowed, regardless of its class.
     ClientClass client_class_;
 
index ce1879f97c6dd7664efd647f1440dbc5507df4c8..d064b123dced86d071f115f6f2a41bfa0dc59900 100644 (file)
@@ -389,7 +389,7 @@ PoolParser::parse(PoolStoragePtr pools,
     }
 
     // Try setting up required client classes.
-    ConstElementPtr class_list = pool_structure->get("required-client-classes");
+    ConstElementPtr class_list = pool_structure->get("require-client-classes");
     if (class_list) {
         const std::vector<data::ElementPtr>& classes = class_list->listValue();
         for (auto cclass = classes.cbegin();
@@ -712,7 +712,7 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
     }
 
     // Try setting up required client classes.
-    ConstElementPtr class_list = params->get("required-client-classes");
+    ConstElementPtr class_list = params->get("require-client-classes");
     if (class_list) {
         const std::vector<data::ElementPtr>& classes = class_list->listValue();
         for (auto cclass = classes.cbegin();
@@ -891,7 +891,7 @@ PdPoolParser::parse(PoolStoragePtr pools, ConstElementPtr pd_pool_) {
         client_class_ = client_class;
     }
 
-    ConstElementPtr class_list = pd_pool_->get("required-client-classes");
+    ConstElementPtr class_list = pd_pool_->get("require-client-classes");
 
     // Check the pool parameters. It will throw an exception if any
     // of the required parameters are invalid.
@@ -1112,7 +1112,7 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
     }
 
     // Try setting up required client classes.
-    ConstElementPtr class_list = params->get("required-client-classes");
+    ConstElementPtr class_list = params->get("require-client-classes");
     if (class_list) {
         const std::vector<data::ElementPtr>& classes = class_list->listValue();
         for (auto cclass = classes.cbegin();
index 5a04e6cd207d4530fa49a5582b52f7c4ae3b331c..727069900279206a93c5f03c00e1c1843f6c7eb5 100644 (file)
@@ -70,9 +70,9 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) {
             }
         }
 
-        if (shared_network_data->contains("required-client-classes")) {
+        if (shared_network_data->contains("require-client-classes")) {
             const std::vector<data::ElementPtr>& class_list =
-                shared_network_data->get("required-client-classes")->listValue();
+                shared_network_data->get("require-client-classes")->listValue();
             for (auto cclass = class_list.cbegin();
                  cclass != class_list.cend(); ++cclass) {
                 if (((*cclass)->getType() != Element::string) ||
@@ -125,9 +125,9 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
             }
         }
 
-        if (shared_network_data->contains("required-client-classes")) {
+        if (shared_network_data->contains("require-client-classes")) {
             const std::vector<data::ElementPtr>& class_list =
-                shared_network_data->get("required-client-classes")->listValue();
+                shared_network_data->get("require-client-classes")->listValue();
             for (auto cclass = class_list.cbegin();
                  cclass != class_list.cend(); ++cclass) {
                 if (((*cclass)->getType() != Element::string) ||
index 2e96ee1ded6f283660a2d7547e8bc212a82e8574..e2d239938d50086f78676751554c7966748b243c 100644 (file)
@@ -27,14 +27,7 @@ bool Pool::inRange(const isc::asiolink::IOAddress& addr) const {
 }
 
 bool Pool::clientSupported(const ClientClasses& classes) const {
-    if (client_class_.empty()) {
-        // There is no class defined for this pool, so we do
-        // support everyone.
-        return (true);
-    } else if (classes.contains(client_class_)) {
-        return (true);
-    }
-    return (false);
+    return (client_class_.empty() || classes.contains(client_class_));
 }
 
 void Pool::allowClientClass(const ClientClass& class_name) {
@@ -112,7 +105,7 @@ Pool::toElement() const {
         map->set("client-class", Element::create(cclass));
     }
 
-    // Set required-client-classes
+    // Set require-client-classes
     const ClientClasses& classes = getRequiredClasses();
     if (!classes.empty()) {
         ElementPtr class_list =Element::createList();
@@ -120,7 +113,7 @@ Pool::toElement() const {
              it != classes.cend(); ++it) {
             class_list->add(Element::create(*it));
         }
-        map->set("required-client-classes", class_list);
+        map->set("require-client-classes", class_list);
     }
 
     return (map);
index 8f8c691d87abab0858da012d1a52b4220d25b1b2..cb6a96626c571b1a8937ea2a6d227ade46533c83 100644 (file)
@@ -802,7 +802,7 @@ TEST(CfgSubnets4Test, unparseSubnet) {
         "    \"reservation-mode\": \"all\",\n"
         "    \"option-data\": [ ],\n"
         "    \"pools\": [ ]\n,"
-        "    \"required-client-classes\": [ \"foo\", \"bar\" ]\n"
+        "    \"require-client-classes\": [ \"foo\", \"bar\" ]\n"
         "} ]\n";
     runToElementTest<CfgSubnets4>(expected, cfg);
 }
@@ -848,7 +848,7 @@ TEST(CfgSubnets4Test, unparsePool) {
         "            \"option-data\": [ ],\n"
         "            \"pool\": \"192.0.2.64/26\",\n"
         "            \"client-class\": \"bar\",\n"
-        "            \"required-client-classes\": [ \"foo\" ]\n"
+        "            \"require-client-classes\": [ \"foo\" ]\n"
         "        }\n"
         "    ]\n"
         "} ]\n";
index 6d1f6baad4c48f5128c4d71cda197ba067314518..227c60e1753745fd653736d1ad411d6104f23e6d 100644 (file)
@@ -490,7 +490,7 @@ TEST(CfgSubnets6Test, unparseSubnet) {
         "    \"pools\": [ ],\n"
         "    \"pd-pools\": [ ],\n"
         "    \"option-data\": [ ],\n"
-        "    \"required-client-classes\": [ \"foo\", \"bar\" ]\n"
+        "    \"require-client-classes\": [ \"foo\", \"bar\" ]\n"
         "} ]\n";
     runToElementTest<CfgSubnets6>(expected, cfg);
 }
@@ -533,7 +533,7 @@ TEST(CfgSubnets6Test, unparsePool) {
         "            \"pool\": \"2001:db8:1:1::/64\",\n"
         "            \"option-data\": [ ],\n"
         "            \"client-class\": \"bar\",\n"
-        "            \"required-client-classes\": [ \"foo\" ]\n"
+        "            \"require-client-classes\": [ \"foo\" ]\n"
         "        }\n"
         "    ],\n"
         "    \"pd-pools\": [ ],\n"
@@ -580,7 +580,7 @@ TEST(CfgSubnets6Test, unparsePdPool) {
         "            \"prefix-len\": 48,\n"
         "            \"delegated-len\": 64,\n"
         "            \"option-data\": [ ],\n"
-        "            \"required-client-classes\": [ \"bar\" ]\n"
+        "            \"require-client-classes\": [ \"bar\" ]\n"
         "        },{\n"
         "            \"prefix\": \"2001:db8:3::\",\n"
         "            \"prefix-len\": 48,\n"
index a0e113668b19a5818d17cbdc633288f2edccb4c7..494e40663b80e3495baf8a62fc116719d19212f4 100644 (file)
@@ -230,7 +230,7 @@ TEST(Pool4Test, clientClass) {
     EXPECT_TRUE(pool->clientSupported(three_classes));
 }
 
-// This test checks that handling for required-client-classes is valid.
+// This test checks that handling for require-client-classes is valid.
 TEST(Pool4Test, requiredClasses) {
     // Create a pool.
     Pool4Ptr pool(new Pool4(IOAddress("192.0.2.0"),
@@ -625,7 +625,7 @@ TEST(Pool6Test, clientClass) {
     EXPECT_TRUE(pool.clientSupported(three_classes));
 }
 
-// This test checks that handling for required-client-classes is valid.
+// This test checks that handling for require-client-classes is valid.
 TEST(Pool6Test, requiredClasses) {
     // Create a pool.
     Pool6 pool(Lease::TYPE_NA, IOAddress("2001:db8::1"),
index dfb3a9db9cba381b0d2ae74c6723ca01841302eb..193428ac24644344fff12e63bdd808678f198c2b 100644 (file)
@@ -52,7 +52,7 @@ public:
                 "            \"server-hostname\": \"\","
                 "            \"boot-file-name\": \"\","
                 "            \"client-class\": \"\","
-                "            \"required-client-classes\": []\n,"
+                "            \"require-client-classes\": []\n,"
                 "            \"reservation-mode\": \"all\","
                 "            \"4o6-interface\": \"\","
                 "            \"4o6-interface-id\": \"\","
@@ -73,7 +73,7 @@ public:
                 "            \"server-hostname\": \"\","
                 "            \"boot-file-name\": \"\","
                 "            \"client-class\": \"\","
-                "            \"required-client-classes\": []\n,"
+                "            \"require-client-classes\": []\n,"
                 "            \"reservation-mode\": \"all\","
                 "            \"4o6-interface\": \"\","
                 "            \"4o6-interface-id\": \"\","
@@ -194,7 +194,7 @@ public:
                 "            \"preferred-lifetime\": 300,"
                 "            \"valid-lifetime\": 400,"
                 "            \"client-class\": \"\","
-                "            \"required-client-classes\": []\n,"
+                "            \"require-client-classes\": []\n,"
                 "            \"reservation-mode\": \"all\","
                 "            \"decline-probation-period\": 86400,"
                 "            \"dhcp4o6-port\": 0,"
@@ -210,7 +210,7 @@ public:
                 "            \"preferred-lifetime\": 30,"
                 "            \"valid-lifetime\": 40,"
                 "            \"client-class\": \"\","
-                "            \"required-client-classes\": []\n,"
+                "            \"require-client-classes\": []\n,"
                 "            \"reservation-mode\": \"all\","
                 "            \"decline-probation-period\": 86400,"
                 "            \"dhcp4o6-port\": 0,"
@@ -283,7 +283,7 @@ TEST_F(SharedNetwork6ParserTest, clientClass) {
     EXPECT_EQ("alpha", network->getClientClass());
 }
 
-// This test verifies that it's possible to specify required-client-classes
+// This test verifies that it's possible to specify require-client-classes
 // on shared-network level.
 TEST_F(SharedNetwork6ParserTest, evalClientClasses) {
     std::string config = getWorkingConfig();
@@ -292,7 +292,7 @@ TEST_F(SharedNetwork6ParserTest, evalClientClasses) {
     ElementPtr class_list = Element::createList();
     class_list->add(Element::create("alpha"));
     class_list->add(Element::create("beta"));
-    config_element->set("required-client-classes", class_list);
+    config_element->set("require-client-classes", class_list);
 
     // Parse configuration specified above.
     SharedNetwork6Parser parser;
@@ -305,7 +305,7 @@ TEST_F(SharedNetwork6ParserTest, evalClientClasses) {
     EXPECT_EQ("alpha, beta", classes.toText());
 }
 
-// This test verifies that bad required-client-classes configs raise
+// This test verifies that bad require-client-classes configs raise
 // expected errors.
 TEST_F(SharedNetwork6ParserTest, badEvalClientClasses) {
     std::string config = getWorkingConfig();
@@ -315,7 +315,7 @@ TEST_F(SharedNetwork6ParserTest, badEvalClientClasses) {
     ElementPtr class_list = Element::createList();
     class_list->add(Element::create("alpha"));
     class_list->add(Element::create(1234));
-    config_element->set("required-client-classes", class_list);
+    config_element->set("require-client-classes", class_list);
 
     // Parse configuration specified above.
     SharedNetwork6Parser parser;
index aefe3bc39899d90f2f10cf47388167a648bb172d..9b74d3a5913b2931c126c5bd9aac90797eb11763 100644 (file)
@@ -258,7 +258,7 @@ TEST(SharedNetwork4Test, unparse) {
         "        \"valid-lifetime\": 30\n"
         "      }\n"
         "    ],\n"
-        "    \"required-client-classes\": [ \"foo\" ],\n"
+        "    \"require-client-classes\": [ \"foo\" ],\n"
         "    \"valid-lifetime\": 200\n"
         "}\n";
 
@@ -538,7 +538,7 @@ TEST(SharedNetwork6Test, unparse) {
         "        \"valid-lifetime\": 40\n"
         "      }\n"
         "    ],\n"
-        "    \"required-client-classes\": [ \"foo\" ],\n"
+        "    \"require-client-classes\": [ \"foo\" ],\n"
         "    \"valid-lifetime\": 300\n"
         "}\n";
 
index db29baa9aa19db30b130dccbe72dbc1c60195937..64efbb4c87a4434d1b8f2779f7a10a419df660ca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
   EvalContext::expression.
 
   Parameters to the @ref isc::eval::EvalContext class constructor are
-  the universe to choose between DHCPv4 and DHCPv6 for dependent expressions,
-  and a closure which checks if a client class is already known used
+  the universe to choose between DHCPv4 and DHCPv6 for DHCP version
+  dependent expressions, and a function used
   by the parser to accept only already known or built-in client
-  class names in client class membership expressions. This closure defaults
+  class names in client class membership expressions. This function defaults
   to accept all client class names.
 
   Internally, the parser code is generated by flex and bison. These two
index 7690db15047ad47fdf20779ffa9b7ad0903f1d26..dac140510dc7e76d1d6f4a8e8023f58e37986777 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -41,17 +41,19 @@ public:
         PARSER_STRING ///< expression is expected to evaluate to string
     } ParserType;
 
+    /// @brief Type of the check known function.
+    typedef std::function<bool(const ClientClass&)> CheckKnown;
 
     /// @brief Default constructor.
     ///
     /// @param option_universe Option universe: DHCPv4 or DHCPv6. This is used
     /// by the parser to determine which option definitions set should be used
     /// to map option names to option codes.
-    /// @param check_known A closure called to check if a client class
+    /// @param check_known A function called to check if a client class
     /// used for membership is already known. If it is not the parser
     /// will fail: only backward or built-in references are accepted.
     EvalContext(const Option::Universe& option_universe,
-                std::function<bool(const ClientClass&)> check_known = acceptAll);
+                CheckKnown check_known = acceptAll);
 
     /// @brief destructor
     virtual ~EvalContext();
@@ -198,8 +200,8 @@ public:
     /// set should be used to map option name to option code.
     Option::Universe option_universe_;
 
-    /// @brief Closure to check if a client class is already known
-    std::function<bool(const ClientClass&)> check_known_;
+    /// @brief Function to check if a client class is already known
+    CheckKnown check_known_;
 
 };