]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3587] Updated doc, messages, parsers, and UTs
authorThomas Markwalder <tmark@isc.org>
Fri, 18 Oct 2024 16:02:04 +0000 (12:02 -0400)
committerThomas Markwalder <tmark@isc.org>
Mon, 28 Oct 2024 11:58:38 +0000 (07:58 -0400)
/doc/sphinx/arm/classify.rst
/doc/sphinx/arm/dhcp4-srv.rst
/doc/sphinx/arm/dhcp6-srv.rst
/doc/sphinx/arm/hooks-class-cmds.rst
/doc/sphinx/arm/hooks-limits.rst
/src/bin/dhcp4/dhcp4_lexer.ll
/src/bin/dhcp4/dhcp4_messages.mes
/src/bin/dhcp4/dhcp4_srv.cc
/src/bin/dhcp4/tests/classify_unittest.cc
/src/bin/dhcp4/tests/config_parser_unittest.cc
/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes
/src/bin/dhcp6/dhcp6_srv.cc
/src/bin/dhcp6/tests/classify_unittest.cc
/src/bin/dhcp6/tests/config_parser_unittest.cc
/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc
/src/share/api/class-get.json

21 files changed:
doc/sphinx/arm/classify.rst
doc/sphinx/arm/dhcp4-srv.rst
doc/sphinx/arm/dhcp6-srv.rst
doc/sphinx/arm/hooks-class-cmds.rst
doc/sphinx/arm/hooks-limits.rst
src/bin/dhcp4/dhcp4_lexer.cc
src/bin/dhcp4/dhcp4_lexer.ll
src/bin/dhcp4/dhcp4_messages.cc
src/bin/dhcp4/dhcp4_messages.h
src/bin/dhcp4/dhcp4_messages.mes
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/tests/classify_unittest.cc
src/bin/dhcp4/tests/config_parser_unittest.cc
src/bin/dhcp6/dhcp6_messages.cc
src/bin/dhcp6/dhcp6_messages.h
src/bin/dhcp6/dhcp6_messages.mes
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/tests/classify_unittest.cc
src/bin/dhcp6/tests/config_parser_unittest.cc
src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc
src/share/api/class-get.json

index d28fe3aca3415a4a71eb248487fc19d477cd17dd..f858224363a5241d8987aec1f35ea733fb5ba355 100644 (file)
@@ -736,11 +736,14 @@ A client class definition can contain the following properties:
    assigned to members of this class. In the case of a template class, these
    options are assigned to the generated spawned class.
  - The ``option-def`` list is not mandatory and is used to define custom options.
- - The ``only-if-required`` flag is not mandatory; when its value is set to
+ - The ``only-if-required`` has been replaced with ``only-in-additional-list`` and
+   is now deprecated. It will still be accepted as input for a time to allow users
+   to migrate but will eventually be unsupported.
+ - The ``only-in-additional-list`` flag is not mandatory; when its value is set to
    ``false`` (the default), membership is determined during classification and is
    available for subnet selection, for instance. When the value is set to
-   ``true``, membership is evaluated only when required and is usable only for
-   option configuration.
+   ``true``, membership is evaluated only if the class appears in an ``evaluate-
+   additional-classes`` list and is usable only for option configuration.
  - The ``user-context`` is not mandatory and represents a map with user-defined data
    and possibly configuration options for hook libraries.
  - The ``next-server`` parameter is not mandatory and configures the ``siaddr`` field in
@@ -907,18 +910,19 @@ expression for example purposes.
 Usually the ``test`` and ``template-test`` expressions are evaluated before
 subnet selection, but in some cases it is useful to evaluate it later when the
 subnet, shared network, or pools are known but output-option processing has not
-yet been done. For this purpose, the ``only-if-required`` flag, which is
+yet been done. For this purpose, the ``only-in-additional-list`` flag, which is
 ``false`` by default, allows the evaluation of the ``test`` expression or the
-``template-test`` expression only when it is required, i.e. in a
-``require-client-classes`` list of the selected pool, subnet, or shared network.
+``template-test`` expression only when it is required by the class's presence
+in the ``evaluate-additional-classes`` list of the selected pool, subnet, or
+shared network.
 
-The ``require-client-classes`` list, which is valid for pool, subnet,
+The ``evaluate-additional-classes`` list, which is valid for pool, subnet,
 and shared-network scope, specifies the classes which are evaluated in
 the second pass before output-option processing. The list is built in
-same precedence order of the option data, i.e. an option data item in
-a subnet takes precedence over one in a shared network, and also a
-required class in a subnet is added before one in a shared
-network. The mechanism is related to the ``only-if-required`` flag but
+same precedence order as the option data, i.e. an option data item in
+a subnet takes precedence over one in a shared network. An
+additional class in a subnet is added before one in a shared
+network. The mechanism is related to the ``only-in-additional-list`` flag but
 it is not mandatory that the flag be set to ``true``.
 
 .. note ::
@@ -1200,9 +1204,9 @@ value is obtained is determined as explained in the previous paragraphs.
 Option Class-Tagging
 ====================
 
-Option class-tagging allows an option value to conditionally applied 
-to the response based on the client's class membership.  The effect is 
-similar to using an if-block in ISC DHCP to conditionally include 
+Option class-tagging allows an option value to conditionally applied
+to the response based on the client's class membership.  The effect is
+similar to using an if-block in ISC DHCP to conditionally include
 options at a given scope.  Class-tagging is done by specifying a list of
 one of more class names in the option's ``client-classes`` entry.
 
@@ -1252,24 +1256,24 @@ being added to the response which occurs after lease assignment just
 before the response is to be sent to the client.
 
 
-When ``never-send`` for an option is true at any scope, all 
+When ``never-send`` for an option is true at any scope, all
 ``client-classes`` entries for that option are ignored. The
 option will not included.
 
-When ``always-send`` is true at any scope, the option will be 
-included unless, the option determined by scope specifies 
-a ``client-classes`` list that does not contain any of the 
+When ``always-send`` is true at any scope, the option will be
+included unless, the option determined by scope specifies
+a ``client-classes`` list that does not contain any of the
 client's classes.
 
-Otherwise, An option requested by the client will be included in 
+Otherwise, An option requested by the client will be included in
 the response if  the option either does not specify ``client-classes``
 or the client belongs to at least one of the classes in ``client-classes``.
 
-When an option's class-tag does not match, it is as though 
+When an option's class-tag does not match, it is as though
 the option was not specified at that scope.  In the following
 example the option "foo" is specified for both the subnet and
 the pool.  The pool specification includes a class-tag that limits
-the option to members of class "melon":  
+the option to members of class "melon":
 
 ::
 
@@ -1289,16 +1293,16 @@ the option to members of class "melon":
             }]
         }]
     }
-    
+
 
 Clients that match class "melon" will have a value of 123 for option "foo",
 while clients that do not match "melon" will have a value of 456 for option
-"foo".  
+"foo".
 
 .. note::
 
-    Though examples above are for DHCPv4, class-tagging syntax and 
-    behavior is the same for DHPCv6. 
+    Though examples above are for DHCPv4, class-tagging syntax and
+    behavior is the same for DHPCv6.
 
 Classes and Hooks
 =================
index e23ba5de13a16f5a244a33a90bf3a0f19f8ea817..2495db2a139acfe164f767a0edbe887e3852e0f2 100644 (file)
@@ -3421,26 +3421,26 @@ DNS servers set to 192.0.2.1 and 192.0.2.2.
        ...
    }
 
-.. _dhcp4-required-class:
+.. _dhcp4-additional-class:
 
-Required Classification
-~~~~~~~~~~~~~~~~~~~~~~~
+Additional Classification
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
 In some cases it is useful to limit the scope of a class to a pool,
 subnet, or shared network. There are two parameters which are used
 to limit the scope of the class by instructing the server to evaluate test
 expressions when required.
 
-The first one is the per-class ``only-if-required`` flag, which is ``false``
-by default. When it is set to ``true``, the test expression of the class
-is not evaluated at the reception of the incoming packet but later, and
-only if the class evaluation is required.
-
-The second is ``require-client-classes``, which takes a list of class
+The ``evaluate-additional-classes``, which takes a list of class
 names and is valid in pool, subnet, and shared network scope. Classes in
-these lists are marked as required and evaluated after selection of this
+these lists are marked as additional and evaluated after selection of this
 specific pool/subnet/shared network and before output-option processing.
 
+The second one is the per-class ``only-in-additional-list`` flag, which is
+``false`` by default. When it is set to ``true``, the test expression of
+the class is not evaluated at the reception of the incoming packet but later,
+and only if the class is present in an ``evaluate-additional-classes`` list.
+
 In this example, a class is assigned to the incoming packet when the
 specified subnet is used:
 
@@ -3451,7 +3451,7 @@ specified subnet is used:
           {
               "name": "Client_foo",
               "test": "member('ALL')",
-              "only-if-required": true
+              "only-in-additional-list": true
           },
           ...
        ],
@@ -3459,7 +3459,7 @@ specified subnet is used:
            {
                "subnet": "192.0.2.0/24",
                "pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
-               "require-client-classes": [ "Client_foo" ],
+               "evaluate-additional-classes": [ "Client_foo" ],
                ...
            },
            ...
@@ -3467,22 +3467,29 @@ specified subnet is used:
        ...
    }
 
-Required evaluation can be used to express complex dependencies like
+Additional evaluation can be used to express complex dependencies like
 subnet membership. It can also be used to reverse the
 precedence; if ``option-data`` is set in a subnet, it takes precedence
 over ``option-data`` in a class. If ``option-data`` is moved to a
 required class and required in the subnet, a class evaluated earlier
 may take precedence.
 
-Required evaluation is also available at the shared network and pool levels.
-The order in which required classes are considered is: pool, subnet,
+Additional evaluation is also available at the shared network and pool levels.
+The order in which additional classes are considered is: pool, subnet,
 and shared network, i.e. in the same order from the way in which
 ``option-data`` is processed.
 
-Since Kea version 2.7.4 required client classes configured without
+Since Kea version 2.7.4 additional client classes configured without
 a test expression are unconditionally added, i.e. they are considered
 to always be evaluated to ``true``.
 
+.. note::
+
+   As of Kea version 2.7.4, ``only-if-required`` and ``require-client-classes``
+   have been renamed to ``only-in-additional-list`` and ``evaluate-additional-classes``
+   respectivley.  The original names will still be accepted as input to allow
+   users to migrate but will eventually be unsupported.
+
 .. note::
 
    Vendor-Identifying Vendor Options are a special case: for all other
@@ -5366,12 +5373,12 @@ For example:
             {
                 "name": "dependent-class",
                 "test": "member('KNOWN')",
-                "only-if-required": true
+                "only-in-additional-list": true
             }
         ]
     }
 
-The ``only-if-required`` parameter is needed here to force evaluation
+The ``only-in-additional-list`` parameter is needed here to force evaluation
 of the class after the lease has been allocated, and thus the reserved
 class has been also assigned.
 
@@ -5379,21 +5386,21 @@ class has been also assigned.
 
    The classes specified in non-global host reservations
    are assigned to the processed packet after all classes with the
-   ``only-if-required`` parameter set to ``false`` have been evaluated.
+   ``only-in-additional-list`` parameter set to ``false`` have been evaluated.
    This means that these classes must not depend on the
    statically assigned classes from the host reservations. If
-   such a dependency is needed, the ``only-if-required`` parameter must
+   such a dependency is needed, the ``only-in-additional-list`` parameter must
    be set to ``true`` for the dependent classes. Such classes are
    evaluated after the static classes have been assigned to the packet.
    This, however, imposes additional configuration overhead, because
-   all classes marked as ``only-if-required`` must be listed in the
-   ``require-client-classes`` list for every subnet where they are used.
+   all classes marked as ``only-in-additional-list`` must be listed in the
+   ``evaluate-additional-classes`` list for every subnet where they are used.
 
 .. note::
 
    Client classes specified within the Kea configuration file may
    depend on the classes specified within the global host reservations.
-   In such a case the ``only-if-required`` parameter is not needed.
+   In such a case the ``only-in-additional-list`` parameter is not needed.
    Refer to :ref:`pool-selection-with-class-reservations4` and
    :ref:`subnet-selection-with-class-reservations4`
    for specific use cases.
@@ -6806,10 +6813,10 @@ the ``dhcp-server-identifier`` option. This option configuration is only
 supported at the subnet, shared network, client class, and global levels. It
 must not be specified at the host-reservation level.
 When configuring the ``dhcp-server-identifier`` option at client-class level, the
-class must not set the ``only-if-required`` flag, because this class would not
+class must not set the ``only-in-additional-list`` flag, because this class would not
 be evaluated before the server determines if the received DHCP message should
 be accepted for processing. Such classes are evaluated after subnet selection.
-See :ref:`dhcp4-required-class` for details.
+See :ref:`dhcp4-additional-class` for details.
 
 The following example demonstrates how to override the server identifier
 for a subnet:
index 54827cfd0926fecda53ad1a847914b5e029b723b..90f33167d23d5a36e6bfdefd5736e095db6ddebd 100644 (file)
@@ -3153,26 +3153,26 @@ eRouter1.0 client class are allowed to use that pool.
        ...
    }
 
-.. _dhcp6-required-class:
+.. _dhcp6-additional-class:
 
-Required Classification
-~~~~~~~~~~~~~~~~~~~~~~~
+Additional Classification
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
 In some cases it is useful to limit the scope of a class to a pool,
 subnet, or shared network. There are two parameters which are used
 to limit the scope of the class by instructing the server to evaluate test
 expressions when required.
 
-The first one is the per-class ``only-if-required`` flag, which is ``false``
-by default. When it is set to ``true``, the test expression of the class
-is not evaluated at the reception of the incoming packet but later, and
-only if the class evaluation is required.
-
-The second is ``require-client-classes``, which takes a list of class
+The ``evaluate-additional-classes``, which takes a list of class
 names and is valid in pool, subnet, and shared network scope. Classes in
-these lists are marked as required and evaluated after selection of this
+these lists are marked as additional and evaluated after selection of this
 specific pool/subnet/shared network and before output-option processing.
 
+The second one is the per-class ``only-in-additional-list`` flag, which is
+``false`` by default. When it is set to ``true``, the test expression of
+the class is not evaluated at the reception of the incoming packet but later,
+and only if the class is present in an ``evaluate-additional-classes`` list.
+
 In this example, a class is assigned to the incoming packet when the
 specified subnet is used:
 
@@ -3183,7 +3183,7 @@ specified subnet is used:
           {
               "name": "Client_foo",
               "test": "member('ALL')",
-              "only-if-required": true
+              "only-in-additional-list": true
           },
           ...
        ],
@@ -3195,7 +3195,7 @@ specified subnet is used:
                         "pool": "2001:db8:1::-2001:db8:1::ffff"
                     }
                ],
-               "require-client-classes": [ "Client_foo" ],
+               "evaluate-additional-classes": [ "Client_foo" ],
                ...
            },
            ...
@@ -3203,22 +3203,29 @@ specified subnet is used:
        ...
    }
 
-Required evaluation can be used to express complex dependencies like
+Additional evaluation can be used to express complex dependencies like
 subnet membership. It can also be used to reverse the
 precedence; if ``option-data`` is set in a subnet, it takes precedence
 over ``option-data`` in a class. If ``option-data`` is moved to a
 required class and required in the subnet, a class evaluated earlier
 may take precedence.
 
-Required evaluation is also available at shared network and pool/pd-pool
-levels. The order in which required classes are considered is:
+Additional evaluation is also available at shared network and pool/pd-pool
+levels. The order in which additional classes are considered is:
 (pd-)pool, subnet, and shared network, i.e. in the same order from the
 way in which ``option-data`` is processed.
 
-Since Kea version 2.7.4 required client classes configured without
+Since Kea version 2.7.4 additional classes configured without
 a test expression are unconditionally added, i.e. they are considered
 to always be evaluated to ``true``.
 
+.. note::
+
+   As of Kea version 2.7.4, ``only-if-required`` and ``require-client-classes``
+   have been renamed to ``only-in-additional-list`` and ``evaluate-additional-classes``
+   respectivley.  The original names will still be accepted as input to allow
+   users to migrate but will eventually be unsupported.
+
 .. _dhcp6-ddns-config:
 
 DDNS for DHCPv6
@@ -4656,12 +4663,12 @@ For example:
             {
                 "name": "dependent-class",
                 "test": "member('KNOWN')",
-                "only-if-required": true
+                "only-in-additional-list": true
             }
         ]
     }
 
-The ``only-if-required`` parameter is needed here to force
+The ``only-in-additional-list`` parameter is needed here to force
 evaluation of the class after the lease has been allocated and thus the
 reserved class has been also assigned.
 
@@ -4669,21 +4676,21 @@ reserved class has been also assigned.
 
    The classes specified in non-global host reservations
    are assigned to the processed packet after all classes with the
-   ``only-if-required`` parameter set to ``false`` have been evaluated.
+   ``only-in-additional-list` parameter set to ``false`` have been evaluated.
    This means that these classes must not depend on the
    statically assigned classes from the host reservations. If
-   such a dependency is needed, the ``only-if-required`` must
+   such a dependency is needed, the ``only-in-addtional-list`` must
    be set to ``true`` for the dependent classes. Such classes are
    evaluated after the static classes have been assigned to the packet.
    This, however, imposes additional configuration overhead, because
-   all classes marked as ``only-if-required`` must be listed in the
-   ``require-client-classes`` list for every subnet where they are used.
+   all classes marked as ``only-in-addtional-list`` must be listed in the
+   ``evaluate-additional-classes`` list for every subnet where they are used.
 
 .. note::
 
    Client classes specified within the Kea configuration file may
    depend on the classes specified within the global host reservations.
-   In such a case the ``only-if-required`` parameter is not needed.
+   In such a case the ``only-in-additional-list`` parameter is not needed.
    Refer to the :ref:`pool-selection-with-class-reservations6` and
    :ref:`subnet-selection-with-class-reservations6`
    for specific use cases.
index afaac5a57614a56b3511cd32f5c9caab3a5e3fb7..071ac93321bb03454c7758f1c2cb4710e4506776 100644 (file)
@@ -229,7 +229,7 @@ are returned in the following format:
            "client-classes": [
                {
                    "name": "pxeclient",
-                   "only-if-required": true,
+                   "only-in-additional-list": true,
                    "test": "option[vendor-class-identifier].text == 'PXEClient'",
                    "option-def": [
                        {
@@ -251,5 +251,13 @@ Note that the example above is DHCPv4-specific; the last three
 parameters are only returned by the DHCPv4 server and are never returned
 by the DHCPv6 server. Also, some of the parameters provided in this
 example may not be returned if they are not specified for the class.
-Specifically, ``only-if-required``, ``test``, and ``option-def`` are not
+Specifically, ``only-in-additional-list``, ``test``, and ``option-def`` are not
 returned if they are not specified for the class.
+
+.. note::
+
+  As of Kea version 2.7.4, ``only-if-required`` has been replaced with
+  ``only-in-additional-list`` and deprecated. In order to allow users time
+  to migrate class commands will still accept it as input but translate it
+  to ``only-in-additional-list`` on output.  Eventually support for the
+  old name wil be removed.
index 73c6d2773b22281b1e9507d2532818c738d9821b..105d4bd6aba0b3c4df98b7dbbfc4369d92973416 100644 (file)
@@ -142,7 +142,7 @@ checked against the configured limits - are updated for each lease in the follow
 * ``lease6_renew``
 * ``lease6_rebind``
 
-As a result, classes for which ``"only-if-required"`` is "true" cannot be lease-limited.
+As a result, classes for which ``"only-in-additional-list"`` is "true" cannot be lease-limited.
 Please refer to :ref:`the classification steps <classify-classification-steps>` for more information on which
 client classes can be used to limit the number of leases.
 
@@ -185,7 +185,7 @@ In terms of rate limiting, client classes are evaluated at the ``pkt4_receive``
 ``pkt6_receive`` callout, respectively, so that rate limits are checked as early as possible in the
 packet-processing cycle. Thus, only those classes which are assigned to the packet solely via an
 independent test expression can be used. Classes that depend on host reservations or the special
-``BOOTP`` or ``KNOWN`` classes, and classes that are marked with ``"only-if-required": true``,
+``BOOTP`` or ``KNOWN`` classes, and classes that are marked with ``"only-in-additional-list": true``,
 cannot be rate limited. See :ref:`the classification steps <classify-classification-steps>` for
 more details on which client classes can be used to limit the packet rate.
 
index 61cacbb1b22628e67ca4c6dd0800f079277da3d2..0ed9e3a7c53583cd279a2b9c264743780d36078c 100644 (file)
@@ -4326,7 +4326,7 @@ YY_RULE_SETUP
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
         return isc::dhcp::Dhcp4Parser::make_ONLY_IN_ADDITIONAL_LIST(driver.loc_);
     default:
-        return isc::dhcp::Dhcp4Parser::make_STRING("in-additional-list", driver.loc_);
+        return isc::dhcp::Dhcp4Parser::make_STRING("only-in-additional-list", driver.loc_);
     }
 }
        YY_BREAK
index 13ce15442138774d440e16eeea51f9d78cba003d..12f2eb352421284d317171f631b9288f9df821e6 100644 (file)
@@ -1383,7 +1383,7 @@ ControlCharacterFill            [^"\\]|\\["\\/bfnrtu]
     case isc::dhcp::Parser4Context::CLIENT_CLASSES:
         return isc::dhcp::Dhcp4Parser::make_ONLY_IN_ADDITIONAL_LIST(driver.loc_);
     default:
-        return isc::dhcp::Dhcp4Parser::make_STRING("in-additional-list", driver.loc_);
+        return isc::dhcp::Dhcp4Parser::make_STRING("only-in-additional-list", driver.loc_);
     }
 }
 
index fdfec234930d8b84f42d35b7aa37662868b59afb..e9a0ef32e544a083ada4717d33d5c45246cb4a54 100644 (file)
@@ -7,6 +7,10 @@
 namespace isc {
 namespace dhcp {
 
+extern const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_EVAL_ERROR = "DHCP4_ADDITIONAL_CLASS_EVAL_ERROR";
+extern const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_EVAL_RESULT = "DHCP4_ADDITIONAL_CLASS_EVAL_RESULT";
+extern const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_NO_TEST = "DHCP4_ADDITIONAL_CLASS_NO_TEST";
+extern const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_UNDEFINED = "DHCP4_ADDITIONAL_CLASS_UNDEFINED";
 extern const isc::log::MessageID DHCP4_ALREADY_RUNNING = "DHCP4_ALREADY_RUNNING";
 extern const isc::log::MessageID DHCP4_BUFFER_RECEIVED = "DHCP4_BUFFER_RECEIVED";
 extern const isc::log::MessageID DHCP4_BUFFER_RECEIVE_FAIL = "DHCP4_BUFFER_RECEIVE_FAIL";
@@ -146,10 +150,6 @@ extern const isc::log::MessageID DHCP4_RELEASE_FAIL = "DHCP4_RELEASE_FAIL";
 extern const isc::log::MessageID DHCP4_RELEASE_FAIL_NO_LEASE = "DHCP4_RELEASE_FAIL_NO_LEASE";
 extern const isc::log::MessageID DHCP4_RELEASE_FAIL_WRONG_CLIENT = "DHCP4_RELEASE_FAIL_WRONG_CLIENT";
 extern const isc::log::MessageID DHCP4_REQUEST = "DHCP4_REQUEST";
-extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_ERROR = "DHCP4_REQUIRED_CLASS_EVAL_ERROR";
-extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_RESULT = "DHCP4_REQUIRED_CLASS_EVAL_RESULT";
-extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_NO_TEST = "DHCP4_REQUIRED_CLASS_NO_TEST";
-extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_UNDEFINED = "DHCP4_REQUIRED_CLASS_UNDEFINED";
 extern const isc::log::MessageID DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED = "DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED";
 extern const isc::log::MessageID DHCP4_RESERVED_HOSTNAME_ASSIGNED = "DHCP4_RESERVED_HOSTNAME_ASSIGNED";
 extern const isc::log::MessageID DHCP4_RESPONSE_DATA = "DHCP4_RESPONSE_DATA";
@@ -185,6 +185,10 @@ extern const isc::log::MessageID DHCP4_V6_ONLY_PREFERRED_MISSING_IN_OFFER = "DHC
 namespace {
 
 const char* values[] = {
+    "DHCP4_ADDITIONAL_CLASS_EVAL_ERROR", "%1: Expression '%2' evaluated to %3",
+    "DHCP4_ADDITIONAL_CLASS_EVAL_RESULT", "%1: Expression '%2' evaluated to %3",
+    "DHCP4_ADDITIONAL_CLASS_NO_TEST", "additional class %1 has no test expression, adding it to client's classes unconditionally",
+    "DHCP4_ADDITIONAL_CLASS_UNDEFINED", "additional class %1 has no definition",
     "DHCP4_ALREADY_RUNNING", "%1 already running? %2",
     "DHCP4_BUFFER_RECEIVED", "received buffer from %1:%2 to %3:%4 over interface %5",
     "DHCP4_BUFFER_RECEIVE_FAIL", "error on attempt to receive packet: %1",
@@ -324,10 +328,6 @@ const char* values[] = {
     "DHCP4_RELEASE_FAIL_NO_LEASE", "%1: client is trying to release non-existing lease %2",
     "DHCP4_RELEASE_FAIL_WRONG_CLIENT", "%1: client is trying to release the lease %2 which belongs to a different client",
     "DHCP4_REQUEST", "%1: server is processing DHCPREQUEST with hint=%2",
-    "DHCP4_REQUIRED_CLASS_EVAL_ERROR", "%1: Expression '%2' evaluated to %3",
-    "DHCP4_REQUIRED_CLASS_EVAL_RESULT", "%1: Expression '%2' evaluated to %3",
-    "DHCP4_REQUIRED_CLASS_NO_TEST", "required class %1 has no test expression, adding it to client's classes unconditionally",
-    "DHCP4_REQUIRED_CLASS_UNDEFINED", "required class %1 has no definition",
     "DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED", "Multi-threading is enabled and host reservations lookup is always performed first.",
     "DHCP4_RESERVED_HOSTNAME_ASSIGNED", "%1: server assigned reserved hostname %2",
     "DHCP4_RESPONSE_DATA", "%1: responding with packet %2 (type %3), packet details: %4",
index 56795aec23f362c0a2991ec9515304a7f23fbef8..01c8c9130881c5049c643e61b2b61895a0200a2e 100644 (file)
@@ -8,6 +8,10 @@
 namespace isc {
 namespace dhcp {
 
+extern const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_EVAL_ERROR;
+extern const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_EVAL_RESULT;
+extern const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_NO_TEST;
+extern const isc::log::MessageID DHCP4_ADDITIONAL_CLASS_UNDEFINED;
 extern const isc::log::MessageID DHCP4_ALREADY_RUNNING;
 extern const isc::log::MessageID DHCP4_BUFFER_RECEIVED;
 extern const isc::log::MessageID DHCP4_BUFFER_RECEIVE_FAIL;
@@ -147,10 +151,6 @@ extern const isc::log::MessageID DHCP4_RELEASE_FAIL;
 extern const isc::log::MessageID DHCP4_RELEASE_FAIL_NO_LEASE;
 extern const isc::log::MessageID DHCP4_RELEASE_FAIL_WRONG_CLIENT;
 extern const isc::log::MessageID DHCP4_REQUEST;
-extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_ERROR;
-extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_RESULT;
-extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_NO_TEST;
-extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_UNDEFINED;
 extern const isc::log::MessageID DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED;
 extern const isc::log::MessageID DHCP4_RESERVED_HOSTNAME_ASSIGNED;
 extern const isc::log::MessageID DHCP4_RESPONSE_DATA;
index 98e285b7d148b506c9a9ee13b11ab30cde56b5b9..86be2e668df1fc3c8140d5bcbb8a25586f871f34 100644 (file)
@@ -968,26 +968,26 @@ about the address that the client would like to have allocated.
 If there is no hint, the argument should provide the text indicating
 that the hint hasn't been sent.
 
-% DHCP4_REQUIRED_CLASS_EVAL_ERROR %1: Expression '%2' evaluated to %3
+% DHCP4_ADDITIONAL_CLASS_EVAL_ERROR %1: Expression '%2' evaluated to %3
 This error message indicates that there a problem was encountered while
-evaluating an expression of a required client class that was marked as required.
+evaluating an expression of a additional client class that was marked as additional.
 A description of the problem is printed.
 
-% DHCP4_REQUIRED_CLASS_EVAL_RESULT %1: Expression '%2' evaluated to %3
+% DHCP4_ADDITIONAL_CLASS_EVAL_RESULT %1: Expression '%2' evaluated to %3
 Logged at debug log level 50.
-This debug message indicates that the expression of a required client class has
+This debug message indicates that the expression of a additional client class has
 been successfully evaluated. The client class name and the result value of the
 evaluation are printed.
 
-% DHCP4_REQUIRED_CLASS_NO_TEST required class %1 has no test expression, adding it to client's classes unconditionally
+% DHCP4_ADDITIONAL_CLASS_NO_TEST additional class %1 has no test expression, adding it to client's classes unconditionally
 Logged at debug log level 40.
-This debug message informs that a class was listed for required evaluation but
+This debug message informs that a class was listed for additional evaluation but
 its definition does not include a test expression to evaluate. The class is
 unconditionally added to the query.
 
-% DHCP4_REQUIRED_CLASS_UNDEFINED required class %1 has no definition
+% DHCP4_ADDITIONAL_CLASS_UNDEFINED additional class %1 has no definition
 Logged at debug log level 40.
-This debug message informs that a class is listed for required evaluation but
+This debug message informs that a class is listed for additional evaluation but
 has no definition. The class is ignored.
 
 % DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED Multi-threading is enabled and host reservations lookup is always performed first.
index 5e11dfd39d12d430168b7afd3071c2aca5042f37..a26de8b15f0764369dc8f4f38d3f408314acc1a2 100644 (file)
@@ -2523,7 +2523,6 @@ Dhcpv4Srv::appendBasicOptions(Dhcpv4Exchange& ex) {
             // Check whether option has been configured.
             for (auto const& copts : co_list) {
                 OptionDescriptor desc = copts->get(DHCP4_OPTION_SPACE, required);
-                /// @todo TKM - not sure if otion class-tagging should be allowed here?
                 if (desc.option_ && desc.allowedForClientClasses(cclasses)) {
                     resp->addOption(desc.option_);
                     break;
@@ -4939,7 +4938,7 @@ void Dhcpv4Srv::evaluateAdditionalClasses(Dhcpv4Exchange& ex) {
         const ClientClassDefPtr class_def = dict->findClass(cclass);
         if (!class_def) {
             LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC,
-                      DHCP4_REQUIRED_CLASS_UNDEFINED)
+                      DHCP4_ADDITIONAL_CLASS_UNDEFINED)
                 .arg(cclass);
             // Ignore it as it can't have an attached action
             continue;
@@ -4948,7 +4947,7 @@ void Dhcpv4Srv::evaluateAdditionalClasses(Dhcpv4Exchange& ex) {
         // Add a class without an expression to evaluate
         if (!expr_ptr) {
             LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC,
-                      DHCP4_REQUIRED_CLASS_NO_TEST)
+                      DHCP4_ADDITIONAL_CLASS_NO_TEST)
                 .arg(cclass);
             query->addClass(cclass);
             continue;
@@ -4957,7 +4956,7 @@ void Dhcpv4Srv::evaluateAdditionalClasses(Dhcpv4Exchange& ex) {
         // true (match) or raise an exception (error)
         try {
             bool status = evaluateBool(*expr_ptr, *query);
-            LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_REQUIRED_CLASS_EVAL_RESULT)
+            LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_ADDITIONAL_CLASS_EVAL_RESULT)
                 .arg(query->getLabel())
                 .arg(cclass)
                 .arg(status ? "true" : "false");
@@ -4966,7 +4965,7 @@ void Dhcpv4Srv::evaluateAdditionalClasses(Dhcpv4Exchange& ex) {
                 query->addClass(cclass);
             }
         } catch (const Exception& ex) {
-            LOG_ERROR(dhcp4_logger, DHCP4_REQUIRED_CLASS_EVAL_ERROR)
+            LOG_ERROR(dhcp4_logger, DHCP4_ADDITIONAL_CLASS_EVAL_ERROR)
                 .arg(query->getLabel())
                 .arg(cclass)
                 .arg(ex.what());
index 34b55d83b62cc314770ed3f2b445b4ca7190b7eb..6fb882baf297b421dc264af24be2afd31c64952b 100644 (file)
@@ -246,19 +246,19 @@ const char* CONFIGS[] = {
         "{"
         "   \"name\": \"pxe1\","
         "   \"test\": \"option[93].hex == 0x0009\","
-        "   \"only-if-required\": true,"
+        "   \"only-in-additional-list\": true,"
         "   \"next-server\": \"1.2.3.4\""
         "},"
         "{"
         "   \"name\": \"pxe2\","
         "   \"test\": \"option[93].hex == 0x0007\","
-        "   \"only-if-required\": true,"
+        "   \"only-in-additional-list\": true,"
         "   \"server-hostname\": \"deneb\""
         "},"
         "{"
         "   \"name\": \"pxe3\","
         "   \"test\": \"option[93].hex == 0x0006\","
-        "   \"only-if-required\": false,"
+        "   \"only-in-additional-list\": false,"
         "   \"boot-file-name\": \"pxelinux.0\""
         "},"
         "{"
@@ -778,7 +778,7 @@ TEST_F(ClassifyTest, fixedFieldsInformNoClasses3) {
     testFixedFields(CONFIGS[3], DHCPINFORM, OptionPtr(), "0.0.0.0", "", "");
 }
 
-// Class 'pxe1' is only-if-required and not subject to required evaluation
+// Class 'pxe1' is only-in-additional-list and not subject to additional evaluation
 TEST_F(ClassifyTest, fixedFieldsDiscoverNextServer3) {
     OptionPtr pxe(new OptionInt<uint16_t>(Option::V4, 93, 0x0009));
 
@@ -795,7 +795,7 @@ TEST_F(ClassifyTest, fixedFieldsInformNextServer3) {
     testFixedFields(CONFIGS[3], DHCPINFORM, pxe, "0.0.0.0", "", "");
 }
 
-// Class pxe2 is only-if-required but the subnet requires its evaluation
+// Class pxe2 is only-in-additional-list but the subnet requires its evaluation
 TEST_F(ClassifyTest, fixedFieldsDiscoverHostname3) {
     OptionPtr pxe(new OptionInt<uint16_t>(Option::V4, 93, 0x0007));
 
@@ -944,7 +944,7 @@ TEST_F(ClassifyTest, server2computer) {
     EXPECT_EQ("10.0.0.160", resp->getYiaddr().toText());
 }
 
-// This test checks the precedence order in required evaluation.
+// This test checks the precedence order in additional evaluation.
 // This order is: pools > subnet > shared-network
 TEST_F(ClassifyTest, precedenceNone) {
     std::string config =
@@ -957,7 +957,7 @@ TEST_F(ClassifyTest, precedenceNone) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.1\""
@@ -966,7 +966,7 @@ TEST_F(ClassifyTest, precedenceNone) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.2\""
@@ -975,7 +975,7 @@ TEST_F(ClassifyTest, precedenceNone) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.3\""
@@ -1025,7 +1025,7 @@ TEST_F(ClassifyTest, precedencePool) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.1\""
@@ -1034,7 +1034,7 @@ TEST_F(ClassifyTest, precedencePool) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.2\""
@@ -1043,7 +1043,7 @@ TEST_F(ClassifyTest, precedencePool) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.3\""
@@ -1102,7 +1102,7 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.1\""
@@ -1111,7 +1111,7 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.2\""
@@ -1120,7 +1120,7 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.3\""
@@ -1178,7 +1178,7 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.1\""
@@ -1187,7 +1187,7 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.2\""
@@ -1196,7 +1196,7 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"domain-name-servers\","
         "           \"data\": \"10.0.0.3\""
index 5af406ca6253bd03b7a754d5db24b71b27a5e7b3..161b175fe285e751f9b08361bd5574a32b111366 100644 (file)
@@ -8121,11 +8121,18 @@ TEST_F(Dhcp4ParserTest, deprecatedRequireClientClassesCheck) {
         R"^(
         "rebind-timer": 2000,
         "renew-timer": 1000,
-        "subnet4": [{
-            "require-client-classes": [ "foo" ],
-            "pools": [{ "pool":  "192.0.2.0/28" }],
-            "id": 1,
-            "subnet": "192.0.2.0/24"
+        "shared-networks":[{
+            "name": "net1",
+            "require-client-classes": [ "one" ],
+            "subnet4": [{
+                "require-client-classes": [ "two" ],
+                "pools": [{
+                    "pool":  "192.0.2.0/28",
+                    "require-client-classes": [ "three" ]
+                }],
+                "id": 1,
+                "subnet": "192.0.2.0/24"
+            }],
         }],
         "valid-lifetime": 400
         })^";
@@ -8138,14 +8145,31 @@ TEST_F(Dhcp4ParserTest, deprecatedRequireClientClassesCheck) {
     ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json));
     checkResult(status, 0);
 
+    SharedNetwork4Ptr network = CfgMgr::instance().getStagingCfg()->
+                                getCfgSharedNetworks4()->getByName("net1");
+    ASSERT_TRUE(network);
+
+    auto& net_class_list = network->getAdditionalClasses();
+    EXPECT_EQ(1, net_class_list.size());
+    auto cclasses = net_class_list.begin();
+    EXPECT_EQ(*cclasses, "one");
+
     Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
                             getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.0"));
     ASSERT_TRUE(subnet);
 
-    const auto& cclass_list = subnet->getAdditionalClasses();
-    EXPECT_EQ(1, cclass_list.size());
-    auto cclasses = cclass_list.begin();
-    EXPECT_EQ(*cclasses, "foo");
+    auto& sub_class_list = subnet->getAdditionalClasses();
+    EXPECT_EQ(1, sub_class_list.size());
+    cclasses = sub_class_list.begin();
+    EXPECT_EQ(*cclasses, "two");
+
+    PoolPtr pool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.0"), false);
+    ASSERT_TRUE(pool);
+
+    auto& pool_class_list = pool->getAdditionalClasses();
+    EXPECT_EQ(1, pool_class_list.size());
+    cclasses = pool_class_list.begin();
+    EXPECT_EQ(*cclasses, "three");
 
     // Now verify that users cannot specify both.
     config = "{ " + genIfaceConfig() + ","
index 452a4aefa843a0ccde376602738317f3eb99b3c8..24cdc04676e80f7d9899752e64cb738fb6a77740 100644 (file)
@@ -8,6 +8,10 @@ namespace isc {
 namespace dhcp {
 
 extern const isc::log::MessageID DHCP4_HOOK_SUBNET6_SELECT_PARKING_LOT_FULL = "DHCP4_HOOK_SUBNET6_SELECT_PARKING_LOT_FULL";
+extern const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_EVAL_ERROR = "DHCP6_ADDITIONAL_CLASS_EVAL_ERROR";
+extern const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_EVAL_RESULT = "DHCP6_ADDITIONAL_CLASS_EVAL_RESULT";
+extern const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_NO_TEST = "DHCP6_ADDITIONAL_CLASS_NO_TEST";
+extern const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_UNDEFINED = "DHCP6_ADDITIONAL_CLASS_UNDEFINED";
 extern const isc::log::MessageID DHCP6_ADD_GLOBAL_STATUS_CODE = "DHCP6_ADD_GLOBAL_STATUS_CODE";
 extern const isc::log::MessageID DHCP6_ADD_STATUS_CODE_FOR_IA = "DHCP6_ADD_STATUS_CODE_FOR_IA";
 extern const isc::log::MessageID DHCP6_ALREADY_RUNNING = "DHCP6_ALREADY_RUNNING";
@@ -145,10 +149,6 @@ extern const isc::log::MessageID DHCP6_RELEASE_PD_EXPIRED = "DHCP6_RELEASE_PD_EX
 extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL = "DHCP6_RELEASE_PD_FAIL";
 extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_DUID = "DHCP6_RELEASE_PD_FAIL_WRONG_DUID";
 extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_IAID = "DHCP6_RELEASE_PD_FAIL_WRONG_IAID";
-extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_ERROR = "DHCP6_REQUIRED_CLASS_EVAL_ERROR";
-extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_RESULT = "DHCP6_REQUIRED_CLASS_EVAL_RESULT";
-extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_NO_TEST = "DHCP6_REQUIRED_CLASS_NO_TEST";
-extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_UNDEFINED = "DHCP6_REQUIRED_CLASS_UNDEFINED";
 extern const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL = "DHCP6_REQUIRED_OPTIONS_CHECK_FAIL";
 extern const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED = "DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED";
 extern const isc::log::MessageID DHCP6_RESPONSE_DATA = "DHCP6_RESPONSE_DATA";
@@ -175,6 +175,10 @@ namespace {
 
 const char* values[] = {
     "DHCP4_HOOK_SUBNET6_SELECT_PARKING_LOT_FULL", "The parked-packet-limit %1, has been reached, dropping query: %2",
+    "DHCP6_ADDITIONAL_CLASS_EVAL_ERROR", "%1: Expression '%2' evaluated to %3",
+    "DHCP6_ADDITIONAL_CLASS_EVAL_RESULT", "%1: Expression '%2' evaluated to %3",
+    "DHCP6_ADDITIONAL_CLASS_NO_TEST", "additional class %1 has no test expression, adding it to client's classes unconditionally",
+    "DHCP6_ADDITIONAL_CLASS_UNDEFINED", "additional class %1 has no definition",
     "DHCP6_ADD_GLOBAL_STATUS_CODE", "%1: adding Status Code to DHCPv6 packet: %2",
     "DHCP6_ADD_STATUS_CODE_FOR_IA", "%1: adding Status Code to IA with iaid=%2: %3",
     "DHCP6_ALREADY_RUNNING", "%1 already running? %2",
@@ -312,10 +316,6 @@ const char* values[] = {
     "DHCP6_RELEASE_PD_FAIL", "%1: failed to release prefix %2/%3 for iaid=%4",
     "DHCP6_RELEASE_PD_FAIL_WRONG_DUID", "%1: client tried to release prefix %2/%3, but it belongs to another client (duid=%4)",
     "DHCP6_RELEASE_PD_FAIL_WRONG_IAID", "%1: client tried to release prefix %2/%3, but it used wrong IAID (expected %4, but got %5)",
-    "DHCP6_REQUIRED_CLASS_EVAL_ERROR", "%1: Expression '%2' evaluated to %3",
-    "DHCP6_REQUIRED_CLASS_EVAL_RESULT", "%1: Expression '%2' evaluated to %3",
-    "DHCP6_REQUIRED_CLASS_NO_TEST", "required class %1 has no test expression, adding it to client's classes unconditionally",
-    "DHCP6_REQUIRED_CLASS_UNDEFINED", "required class %1 has no definition",
     "DHCP6_REQUIRED_OPTIONS_CHECK_FAIL", "%1: %2 message received from %3 failed the following check: %4",
     "DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED", "Multi-threading is enabled and host reservations lookup is always performed first.",
     "DHCP6_RESPONSE_DATA", "%1: responding with packet %2 (type %3), packet details: %4",
index 3afab08b5a3a4c47b6ca7f7addc97888b0ba3d17..3cb2b2b6cc47553d6355a7291a98b3505dac62d1 100644 (file)
@@ -9,6 +9,10 @@ namespace isc {
 namespace dhcp {
 
 extern const isc::log::MessageID DHCP4_HOOK_SUBNET6_SELECT_PARKING_LOT_FULL;
+extern const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_EVAL_ERROR;
+extern const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_EVAL_RESULT;
+extern const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_NO_TEST;
+extern const isc::log::MessageID DHCP6_ADDITIONAL_CLASS_UNDEFINED;
 extern const isc::log::MessageID DHCP6_ADD_GLOBAL_STATUS_CODE;
 extern const isc::log::MessageID DHCP6_ADD_STATUS_CODE_FOR_IA;
 extern const isc::log::MessageID DHCP6_ALREADY_RUNNING;
@@ -146,10 +150,6 @@ extern const isc::log::MessageID DHCP6_RELEASE_PD_EXPIRED;
 extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL;
 extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_DUID;
 extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_IAID;
-extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_ERROR;
-extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_RESULT;
-extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_NO_TEST;
-extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_UNDEFINED;
 extern const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL;
 extern const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED;
 extern const isc::log::MessageID DHCP6_RESPONSE_DATA;
index 50cf131024b27a0bdda48c92a7f8749b2be1589c..0dedfbc3b050265b1ffd80b66193fc73f5311072 100644 (file)
@@ -973,26 +973,26 @@ client and transaction identification information. The second and third
 argument identify the prefix. The fourth and fifth argument hold the
 expected IAID and IAID found respectively.
 
-% DHCP6_REQUIRED_CLASS_EVAL_ERROR %1: Expression '%2' evaluated to %3
-This error message indicates that there a problem was encountered while
-evaluating an expression of a required client class that was marked as required.
+% DHCP6_ADDITIONAL_CLASS_EVAL_ERROR %1: Expression '%2' evaluated to %3
+This error message indicates that a problem was encountered while
+evaluating the expression of an additional client class.
 A description of the problem is printed.
 
-% DHCP6_REQUIRED_CLASS_EVAL_RESULT %1: Expression '%2' evaluated to %3
+% DHCP6_ADDITIONAL_CLASS_EVAL_RESULT %1: Expression '%2' evaluated to %3
 Logged at debug log level 50.
-This debug message indicates that the expression of a required client class has
+This debug message indicates that the expression of an additional client class has
 been successfully evaluated. The client class name and the result value of the
 evaluation are printed.
 
-% DHCP6_REQUIRED_CLASS_NO_TEST required class %1 has no test expression, adding it to client's classes unconditionally
+% DHCP6_ADDITIONAL_CLASS_NO_TEST additional class %1 has no test expression, adding it to client's classes unconditionally
 Logged at debug log level 40.
-This debug message informs that a class was listed for required evaluation but
+This debug message informs that a class was listed for additional evaluation but
 its definition does not include a test expression to evaluate. The class is
 unconditionally added to the query.
 
-% DHCP6_REQUIRED_CLASS_UNDEFINED required class %1 has no definition
+% DHCP6_ADDITIONAL_CLASS_UNDEFINED additional class %1 has no definition
 Logged at debug log level 40.
-This debug message informs that a class is listed for required evaluation but
+This debug message informs that a class is listed for additional evaluation but
 has no definition. The class is ignored.
 
 % DHCP6_REQUIRED_OPTIONS_CHECK_FAIL %1: %2 message received from %3 failed the following check: %4
index 84e8d61f03d0ba91a42eea788c31d53f7083f6e8..a926897f88e4d899f3531e2c3a3b0b8d862b99a9 100644 (file)
@@ -4575,7 +4575,7 @@ Dhcpv6Srv::evaluateAdditionalClasses(const Pkt6Ptr& pkt, AllocEngine::ClientCont
         const ClientClassDefPtr class_def = dict->findClass(cclass);
         if (!class_def) {
             LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC,
-                      DHCP6_REQUIRED_CLASS_UNDEFINED)
+                      DHCP6_ADDITIONAL_CLASS_UNDEFINED)
                 .arg(cclass);
             // Ignore it as it can't have an attached action
             continue;
@@ -4584,7 +4584,7 @@ Dhcpv6Srv::evaluateAdditionalClasses(const Pkt6Ptr& pkt, AllocEngine::ClientCont
         // Add a class without an expression to evaluate
         if (!expr_ptr) {
             LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC,
-                      DHCP6_REQUIRED_CLASS_NO_TEST)
+                      DHCP6_ADDITIONAL_CLASS_NO_TEST)
                 .arg(cclass);
             pkt->addClass(cclass);
             continue;
@@ -4593,7 +4593,7 @@ Dhcpv6Srv::evaluateAdditionalClasses(const Pkt6Ptr& pkt, AllocEngine::ClientCont
         // true (match) or raise an exception (error)
         try {
             bool status = evaluateBool(*expr_ptr, *pkt);
-            LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_REQUIRED_CLASS_EVAL_RESULT)
+            LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_ADDITIONAL_CLASS_EVAL_RESULT)
                 .arg(pkt->getLabel())
                 .arg(cclass)
                 .arg(status ? "true" : "false");
@@ -4602,7 +4602,7 @@ Dhcpv6Srv::evaluateAdditionalClasses(const Pkt6Ptr& pkt, AllocEngine::ClientCont
                 pkt->addClass(cclass);
             }
         } catch (const Exception& ex) {
-            LOG_ERROR(dhcp6_logger, DHCP6_REQUIRED_CLASS_EVAL_ERROR)
+            LOG_ERROR(dhcp6_logger, DHCP6_ADDITIONAL_CLASS_EVAL_ERROR)
                 .arg(pkt->getLabel())
                 .arg(cclass)
                 .arg(ex.what());
index 9963193774b8ebbc3652d644e80b804f2ed598b6..dc1a8b500f2daff0b2406b22ac35b8deacfd5b8b 100644 (file)
@@ -706,8 +706,8 @@ TEST_F(ClassifyTest, matchClassification) {
     EXPECT_FALSE(opt3);
 }
 
-// Check that only-if-required classes are not evaluated by classifyPacket
-TEST_F(ClassifyTest, required) {
+// Check that only-in-additional-list classes are not evaluated by classifyPacket
+TEST_F(ClassifyTest, additional) {
     IfaceMgrTestConfig test_config(true);
 
     NakedDhcpv6Srv srv(0);
@@ -734,7 +734,7 @@ TEST_F(ClassifyTest, required) {
         "    \"interface\": \"eth1\" } ],"
         "\"client-classes\": [ "
         "{   \"name\": \"router\", "
-        "    \"only-if-required\": true, "
+        "    \"only-in-additional-list\": true, "
         "    \"option-data\": ["
         "        {    \"name\": \"ipv6-forwarding\", "
         "             \"data\": \"true\" } ], "
@@ -820,8 +820,8 @@ TEST_F(ClassifyTest, required) {
     EXPECT_FALSE(opt3);
 }
 
-// Checks that when only-if-required classes are still evaluated
-TEST_F(ClassifyTest, requiredClassification) {
+// Checks that when only-in-additional-list classes are still evaluated
+TEST_F(ClassifyTest, additionalClassification) {
     IfaceMgrTestConfig test_config(true);
 
     NakedDhcpv6Srv srv(0);
@@ -845,11 +845,11 @@ TEST_F(ClassifyTest, requiredClassification) {
         "{   \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ], "
         "    \"id\": 1, "
         "    \"subnet\": \"2001:db8:1::/48\", "
-        "    \"require-client-classes\": [ \"router\" ], "
+        "    \"evaluate-additional-classes\": [ \"router\" ], "
         "    \"interface\": \"eth1\" } ],"
         "\"client-classes\": [ "
         "{   \"name\": \"router\", "
-        "    \"only-if-required\": true, "
+        "    \"only-in-additional-list\": true, "
         "    \"option-data\": ["
         "        {    \"name\": \"ipv6-forwarding\", "
         "             \"data\": \"true\" } ], "
@@ -1890,7 +1890,7 @@ TEST_F(ClassifyTest, member) {
     EXPECT_FALSE(ipf3->readBoolean());
 }
 
-// This test checks the precedence order in required evaluation.
+// This test checks the precedence order in additional evaluation.
 // This order is: pools > subnet > shared-network
 TEST_F(ClassifyTest, precedenceNone) {
     std::string config =
@@ -1905,7 +1905,7 @@ TEST_F(ClassifyTest, precedenceNone) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::1\""
@@ -1914,7 +1914,7 @@ TEST_F(ClassifyTest, precedenceNone) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::2\""
@@ -1923,7 +1923,7 @@ TEST_F(ClassifyTest, precedenceNone) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::3\""
@@ -1964,7 +1964,7 @@ TEST_F(ClassifyTest, precedenceNone) {
     EXPECT_FALSE(opt);
 }
 
-// This test checks the precedence order in required evaluation.
+// This test checks the precedence order in additional evaluation.
 // This order is: pools > subnet > shared-network
 TEST_F(ClassifyTest, precedencePool) {
     std::string config =
@@ -1976,7 +1976,7 @@ TEST_F(ClassifyTest, precedencePool) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::1\""
@@ -1985,7 +1985,7 @@ TEST_F(ClassifyTest, precedencePool) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::2\""
@@ -1994,7 +1994,7 @@ TEST_F(ClassifyTest, precedencePool) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::3\""
@@ -2004,14 +2004,14 @@ TEST_F(ClassifyTest, precedencePool) {
         "\"shared-networks\": [ {"
         "    \"name\": \"frog\","
         "    \"interface\": \"eth1\","
-        "    \"require-client-classes\": [ \"for-network\" ],"
+        "    \"evaluate-additional-classes\": [ \"for-network\" ],"
         "    \"subnet6\": [ { "
         "        \"subnet\": \"2001:db8:1::/64\","
         "        \"id\": 1,"
-        "        \"require-client-classes\": [ \"for-subnet\" ],"
+        "        \"evaluate-additional-classes\": [ \"for-subnet\" ],"
         "        \"pools\": [ { "
         "            \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\","
-        "            \"require-client-classes\": [ \"for-pool\" ]"
+        "            \"evaluate-additional-classes\": [ \"for-pool\" ]"
         "        } ]"
         "    } ]"
         "} ],"
@@ -2044,7 +2044,7 @@ TEST_F(ClassifyTest, precedencePool) {
     EXPECT_EQ("2001:db8:1::1", addrs[0].toText());
 }
 
-// This test checks the precedence order in required evaluation.
+// This test checks the precedence order in additional evaluation.
 // This order is: pools > subnet > shared-network
 TEST_F(ClassifyTest, precedencePdPool) {
     std::string config =
@@ -2056,7 +2056,7 @@ TEST_F(ClassifyTest, precedencePdPool) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::1\""
@@ -2065,7 +2065,7 @@ TEST_F(ClassifyTest, precedencePdPool) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::2\""
@@ -2074,7 +2074,7 @@ TEST_F(ClassifyTest, precedencePdPool) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::3\""
@@ -2084,15 +2084,15 @@ TEST_F(ClassifyTest, precedencePdPool) {
         "\"shared-networks\": [ {"
         "    \"name\": \"frog\","
         "    \"interface\": \"eth1\","
-        "    \"require-client-classes\": [ \"for-network\" ],"
+        "    \"evaluate-additional-classes\": [ \"for-network\" ],"
         "    \"subnet6\": [ { "
         "        \"subnet\": \"2001:db8:1::/64\","
         "        \"id\": 1,"
-        "        \"require-client-classes\": [ \"for-subnet\" ],"
+        "        \"evaluate-additional-classes\": [ \"for-subnet\" ],"
         "        \"pd-pools\": [ { "
         "            \"prefix\": \"2001:db8:1::\","
         "            \"prefix-len\": 48, \"delegated-len\": 64,"
-        "            \"require-client-classes\": [ \"for-pool\" ]"
+        "            \"evaluate-additional-classes\": [ \"for-pool\" ]"
         "        } ]"
         "    } ]"
         "} ],"
@@ -2125,7 +2125,7 @@ TEST_F(ClassifyTest, precedencePdPool) {
     EXPECT_EQ("2001:db8:1::1", addrs[0].toText());
 }
 
-// This test checks the precedence order in required evaluation.
+// This test checks the precedence order in additional evaluation.
 // This order is: pools > subnet > shared-network
 TEST_F(ClassifyTest, precedenceSubnet) {
     std::string config =
@@ -2137,7 +2137,7 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::1\""
@@ -2146,7 +2146,7 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::2\""
@@ -2155,7 +2155,7 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::3\""
@@ -2165,11 +2165,11 @@ TEST_F(ClassifyTest, precedenceSubnet) {
         "\"shared-networks\": [ {"
         "    \"name\": \"frog\","
         "    \"interface\": \"eth1\","
-        "    \"require-client-classes\": [ \"for-network\" ],"
+        "    \"evaluate-additional-classes\": [ \"for-network\" ],"
         "    \"subnet6\": [ { "
         "        \"subnet\": \"2001:db8:1::/64\","
         "        \"id\": 1,"
-        "        \"require-client-classes\": [ \"for-subnet\" ],"
+        "        \"evaluate-additional-classes\": [ \"for-subnet\" ],"
         "        \"pools\": [ { "
         "            \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\""
         "        } ]"
@@ -2204,7 +2204,7 @@ TEST_F(ClassifyTest, precedenceSubnet) {
     EXPECT_EQ("2001:db8:1::2", addrs[0].toText());
 }
 
-// This test checks the precedence order in required evaluation.
+// This test checks the precedence order in additional evaluation.
 // This order is: pools > subnet > shared-network
 TEST_F(ClassifyTest, precedenceNetwork) {
     std::string config =
@@ -2216,7 +2216,7 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "    {"
         "       \"name\": \"for-pool\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::1\""
@@ -2225,7 +2225,7 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "    {"
         "       \"name\": \"for-subnet\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::2\""
@@ -2234,7 +2234,7 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "    {"
         "       \"name\": \"for-network\","
         "       \"test\": \"member('ALL')\","
-        "       \"only-if-required\": true,"
+        "       \"only-in-additional-list\": true,"
         "       \"option-data\": [ {"
         "           \"name\": \"dns-servers\","
         "           \"data\": \"2001:db8:1::3\""
@@ -2244,7 +2244,7 @@ TEST_F(ClassifyTest, precedenceNetwork) {
         "\"shared-networks\": [ {"
         "    \"name\": \"frog\","
         "    \"interface\": \"eth1\","
-        "    \"require-client-classes\": [ \"for-network\" ],"
+        "    \"evaluate-additional-classes\": [ \"for-network\" ],"
         "    \"subnet6\": [ { "
         "        \"subnet\": \"2001:db8:1::/64\","
         "        \"id\": 1,"
@@ -2282,9 +2282,9 @@ TEST_F(ClassifyTest, precedenceNetwork) {
     EXPECT_EQ("2001:db8:1::3", addrs[0].toText());
 }
 
-// This test checks a required class without a test entry can be
+// This test checks a additional class without a test entry can be
 // unconditionally added.
-TEST_F(ClassifyTest, requiredNoTest) {
+TEST_F(ClassifyTest, additionalNoTest) {
     std::string config =
         "{"
         "\"interfaces-config\": {"
@@ -2302,7 +2302,7 @@ TEST_F(ClassifyTest, requiredNoTest) {
         "\"shared-networks\": [ {"
         "    \"name\": \"frog\","
         "    \"interface\": \"eth1\","
-        "    \"require-client-classes\": [ \"for-network\" ],"
+        "    \"evaluate-additional-classes\": [ \"for-network\" ],"
         "    \"subnet6\": [ { "
         "        \"subnet\": \"2001:db8:1::/64\","
         "        \"id\": 1,"
@@ -2340,10 +2340,10 @@ TEST_F(ClassifyTest, requiredNoTest) {
     EXPECT_EQ("2001:db8:1::3", addrs[0].toText());
 }
 
-// This test checks a required class which is not defined is ignored.
+// This test checks a additional class which is not defined is ignored.
 // Please set KEA_LOGGER_DESTINATION to stderr or stdout and check
 // that DHCP6_REQUIRED_CLASS_UNDEFINED is logged,
-TEST_F(ClassifyTest, requiredNotDefined) {
+TEST_F(ClassifyTest, additionalNotDefined) {
     std::string config =
         "{"
         "\"interfaces-config\": {"
@@ -2352,7 +2352,7 @@ TEST_F(ClassifyTest, requiredNotDefined) {
         "\"shared-networks\": [ {"
         "    \"name\": \"frog\","
         "    \"interface\": \"eth1\","
-        "    \"require-client-classes\": [ \"for-network\" ],"
+        "    \"evaluate-additional-classes\": [ \"for-network\" ],"
         "    \"subnet6\": [ { "
         "        \"subnet\": \"2001:db8:1::/64\","
         "        \"id\": 1,"
index 0d542609b3be1ba96898c39b848720c164580636..3bfceee751d08f5264fb60ac6f9e7dc183f32917 100644 (file)
@@ -9105,11 +9105,24 @@ TEST_F(Dhcp6ParserTest, deprecatedRequireClientClassesCheck) {
         R"^(
         "rebind-timer": 2000,
         "renew-timer": 1000,
-        "subnet6": [{
-            "require-client-classes": [ "foo" ],
-            "pools": [{ "pool":  "2001:db8::/64" }],
-            "id": 1,
-            "subnet": "2001:db8::/64"
+        "shared-networks":[{
+            "name": "net1",
+            "require-client-classes": [ "one" ],
+            "subnet6": [{
+                "require-client-classes": [ "two" ],
+                "pools": [{
+                    "pool":  "2001:db8::/64",
+                    "require-client-classes": [ "three" ],
+                }],
+                "pd-pools": [{ 
+                    "prefix": "3001:db8::",
+                    "prefix-len": 56,
+                    "delegated-len": 64,
+                    "require-client-classes": [ "four" ],
+                }],
+                "id": 1,
+                "subnet": "2001:db8::/64"
+            }],
         }],
         "valid-lifetime": 400
         })^";
@@ -9122,14 +9135,39 @@ TEST_F(Dhcp6ParserTest, deprecatedRequireClientClassesCheck) {
     ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
     checkResult(status, 0);
 
+    SharedNetwork6Ptr network = CfgMgr::instance().getStagingCfg()->
+                                getCfgSharedNetworks6()->getByName("net1");
+    ASSERT_TRUE(network);
+
+    auto& net_class_list = network->getAdditionalClasses();
+    EXPECT_EQ(1, net_class_list.size());
+    auto cclasses = net_class_list.begin();
+    EXPECT_EQ(*cclasses, "one");
+
     Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
                             getCfgSubnets6()->selectSubnet(IOAddress("2001:db8::"));
     ASSERT_TRUE(subnet);
 
-    const auto& cclass_list = subnet->getAdditionalClasses();
-    EXPECT_EQ(1, cclass_list.size());
-    auto cclasses = cclass_list.begin();
-    EXPECT_EQ(*cclasses, "foo");
+    const auto& sub_class_list = subnet->getAdditionalClasses();
+    EXPECT_EQ(1, sub_class_list.size());
+    cclasses = sub_class_list.begin();
+    EXPECT_EQ(*cclasses, "two");
+
+    PoolPtr pool = subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8::"), false);
+    ASSERT_TRUE(pool);
+
+    auto& pool_class_list = pool->getAdditionalClasses();
+    EXPECT_EQ(1, pool_class_list.size());
+    cclasses = pool_class_list.begin();
+    EXPECT_EQ(*cclasses, "three");
+
+    pool = subnet->getPool(Lease::TYPE_PD, IOAddress("3001:db8::"), false);
+    ASSERT_TRUE(pool);
+
+    auto& pd_pool_class_list = pool->getAdditionalClasses();
+    EXPECT_EQ(1, pd_pool_class_list.size());
+    cclasses = pd_pool_class_list.begin();
+    EXPECT_EQ(*cclasses, "four");
 
     // Now verify that users cannot specify both.
     config = "{ " + genIfaceConfig() + ","
index c0fb848903004ee0000cb9f7735123e79f7f016d..af764e8e987d4b7967f844b9a27c5fb51a8b7728 100644 (file)
@@ -2149,7 +2149,7 @@ TEST_F(ClientClassDefParserTest, offerLftInvalid) {
 }
 
 TEST_F(ClientClassDefParserTest, deprecatedOnlyIfRequired) {
-    // Valid entry.
+    // Valid entry using only-if-required.
     std::string cfg_text =
        R"^({
             "name": "foo",
@@ -2164,6 +2164,20 @@ TEST_F(ClientClassDefParserTest, deprecatedOnlyIfRequired) {
     EXPECT_EQ("foo", cclass->getName());
     ASSERT_TRUE(cclass->getAdditional());
 
+    // Valid entry using only-in-additional-list.
+    cfg_text =
+       R"^({
+            "name": "foo",
+            "only-in-additional-list": true
+        })^";
+
+    ASSERT_NO_THROW(cclass = parseClientClassDef(cfg_text, AF_INET));
+
+    // Class should exist.
+    ASSERT_TRUE(cclass);
+    EXPECT_EQ("foo", cclass->getName());
+    ASSERT_TRUE(cclass->getAdditional());
+
     // Invalid entry specifies both parameters. 
     std::string cfg_text2 =
        R"^({
index 1d7c5b2906e4b213ade688825cf0933901b08f21..b2c0bb15d2d8c38b04ae44eca8cbfcca68fbdf2e 100644 (file)
@@ -26,7 +26,7 @@
         "        \"client-classes\": [",
         "            {",
         "                \"name\": <name of the class>,",
-        "                \"only-if-required\": <only if required boolean value>,",
+        "                \"only-in-additional-list\": <only in additional list boolean value>,",
         "                \"test\": <test expression to be evaluated on incoming packets>,",
         "                \"option-data\": [ <option values here> ],",
         "                \"option-def\": [ <option definitions here> ],",