]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2606] updated documentation
authorRazvan Becheriu <razvan@isc.org>
Thu, 17 Nov 2022 13:41:59 +0000 (15:41 +0200)
committerRazvan Becheriu <razvan@isc.org>
Fri, 18 Nov 2022 11:08:47 +0000 (11:08 +0000)
doc/sphinx/arm/classify.rst
src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc

index 8776c783efc59970a306b4cec4d26463cb19180c..c319e6570fd5ebbc7c85b76b06e1ef29f77cd78e 100644 (file)
@@ -35,12 +35,27 @@ ways:
 -  Using a hook.
 
 Client classification can be used to change the behavior of almost any
-part of the DHCP message processing. There are currently six
-mechanisms that take advantage of client classification: dropping
-queries, subnet selection, pool selection, definition of DHCPv4
-private (codes 224-254) and code 43 options, assignment of different
-options, and, for DHCPv4 cable modems, the setting of specific options
-for use with the TFTP server address and the boot file field.
+part of the DHCP message processing. There are currently nine
+mechanisms that take advantage of client classification:
+
+- dropping queries
+
+- subnet selection
+
+- pool selection
+
+- lease limiting
+
+- rate limiting
+
+- DDNS tuning
+
+- definition of DHCPv4 private (codes 224-254) and code 43 options
+
+- assignment of different options
+
+- for DHCPv4 cable modems, the setting of specific options for use with the TFTP
+  server address and the boot file field
 
 .. _classify-classification-steps:
 
@@ -73,7 +88,7 @@ The classification process is conducted in several steps:
     The ``pkt4_receive`` and ``pkt6_receive`` callouts are called here.
 
 6.  When the ``early-global-reservations-lookup`` global parameter is
-    configured to true global reservations are looked for and the 8, 9
+    configured to ``true`` global reservations are looked for and the 8, 9
     and 10 steps are partially performed: the lookup is limited to
     global reservations, if one is found the ``KNOWN`` class is set
     but if none is found the ``UNKNOWN`` class is **not** set.
@@ -97,16 +112,16 @@ The classification process is conducted in several steps:
     packet is assigned to the ``UNKNOWN`` class.
 
 9.  Classes with matching expressions - directly, or indirectly using the
-    ``KNOWN``/``UNKNOWN`` built-in classes and not marked for later evaluation ("on
-    request") - are processed in the order they are defined
+    ``KNOWN``/``UNKNOWN`` built-in classes and not marked for later evaluation
+    ("on request") - are processed in the order they are defined
     in the configuration; the boolean expression is evaluated and, if it
     returns ``true`` (a match), the incoming packet is associated with the
     class. After a subnet is selected, the server determines whether
     there is a reservation for a given client. Therefore, it is not
     possible to use the ``UNKNOWN`` class to select a shared network or
-    a subnet. For the ``KNOWN`` class only global reservations only
-    global reservations are used and the ``early-global-reservations-lookup``
-    parameter must be configured to true
+    a subnet. For the ``KNOWN`` class, only global reservations are used and the
+    ``early-global-reservations-lookup`` parameter must be configured to
+    ``true``.
 
 10. When the incoming packet belongs to the special class ``DROP``, it is
     dropped and an informational message is logged with the packet
@@ -184,7 +199,7 @@ be found in :ref:`hooks-high-availability`.
 The ``SPAWN_`` prefix is used by template classes to generate spawn classes
 names at runtime. The spawned class name is constructed by prepending the
 ``SPAWN_`` prefix to the template class name and the evaluated value:
-"SPAWN_<template-class-name>_<evaluated-value>".
+``SPAWN_<template-class-name>_<evaluated-value>``.
 The details can be found in :ref:`classification-configuring`.
 
 The ``BOOTP`` class is used by the BOOTP hook library to classify and
@@ -322,28 +337,28 @@ This does not apply to the ``KNOWN`` or ``UNKNOWN`` classes.
    | Transaction ID in     | pkt6.transid                  | 12345                 |
    | DHCPv6 packet         |                               |                       |
    +-----------------------+-------------------------------+-----------------------+
-   | Vendor option         | vendor[*].exists              | true                  |
+   | Vendor option         | vendor[*].exists              | 'true'                |
    | existence (any        |                               |                       |
    | vendor)               |                               |                       |
    +-----------------------+-------------------------------+-----------------------+
-   | Vendor option         | vendor[4491].exists           | true                  |
+   | Vendor option         | vendor[4491].exists           | 'true'                |
    | existence (specific   |                               |                       |
    | vendor)               |                               |                       |
    +-----------------------+-------------------------------+-----------------------+
    | Enterprise-id from    | vendor.enterprise             | 4491                  |
    | vendor option         |                               |                       |
    +-----------------------+-------------------------------+-----------------------+
-   | Vendor sub-option     | vendor[4491].option[1].exists | true                  |
+   | Vendor sub-option     | vendor[4491].option[1].exists | 'true'                |
    | existence             |                               |                       |
    +-----------------------+-------------------------------+-----------------------+
    | Vendor sub-option     | vendor[4491].option[1].hex    | docsis3.0             |
    | content               |                               |                       |
    +-----------------------+-------------------------------+-----------------------+
-   | Vendor class option   | vendor-class[*].exist         | true                  |
-   | existence (any        | s                             |                       |
+   | Vendor class option   | vendor-class[*].exists        | 'true'                |
+   | existence (any        |                               |                       |
    | vendor)               |                               |                       |
    +-----------------------+-------------------------------+-----------------------+
-   | Vendor class option   | vendor-class[4491].exists     | true                  |
+   | Vendor class option   | vendor-class[4491].exists     | 'true'                |
    | existence (specific   |                               |                       |
    | vendor)               |                               |                       |
    +-----------------------+-------------------------------+-----------------------+
@@ -361,7 +376,7 @@ This does not apply to the ``KNOWN`` or ``UNKNOWN`` classes.
 Notes:
 
 -  Hexadecimal strings are converted into a string as expected. The
-   starting "0X" or "0x" is removed, and if the string is an odd number
+   starting ``0X`` or ``0x`` is removed, and if the string is an odd number
    of characters a "0" is prepended to it.
 
 -  IP addresses are converted into strings of length 4 or 16. IPv4,
@@ -370,14 +385,14 @@ Notes:
 
 -  Integers in an expression are converted to 32-bit unsigned integers
    and are represented as four-byte strings; for example, 123 is
-   represented as 0x0000007b. All expressions that return numeric values
+   represented as ``0x0000007b``. All expressions that return numeric values
    use 32-bit unsigned integers, even if the field in the packet is
    smaller. In general, it is easier to use decimal notation to
    represent integers, but it is also possible to use hexadecimal
    notation. When writing an integer in hexadecimal, care should be
    taken to make sure the value is represented as 32 bits, e.g. use
-   0x00000001 instead of 0x1 or 0x01. Also, make sure the value is
-   specified in network order, e.g. 1 is represented as 0x00000001.
+   ``0x00000001`` instead of ``0x1`` or ``0x01``. Also, make sure the value is
+   specified in network order, e.g. 1 is represented as ``0x00000001``.
 
 -  ``option[code].hex`` extracts the value of the option with the code
    ``code`` from the incoming packet. If the packet does not contain the
@@ -678,66 +693,64 @@ digits separated by the separator, e.g ``':'``, ``'-'``, ``''`` (empty separator
 Configuring Classes
 ===================
 
-A class can contains the following items:
+A client class definition can contain the following properties:
  - ``name`` parameter is mandatory and must be unique among all classes.
  - ``test`` expression is not mandatory and represents a string containing the
    logical expression used to determine membership in the class. The entire
-   expression is included in double quotes ("). The result should evaluate to a
-   boolean value (``true`` or ``false``).
+   expression is included in double quotes (``"``). The result should evaluate
+   to a boolean value (``true`` or ``false``).
  - ``template-test`` expression is not mandatory and represents a string
    containing the logical expression used to generate a spawning class. The
-   entire expression is included in double quotes ("). The result should
+   entire expression is included in double quotes (``"``). The result should
    evaluate to a string value representing the variable part of the spawned
    class name. If the resulting string is empty, no spawning class is generated.
    The resulting spawned class has the following generated name format:
-   "SPAWN_<template-class-name>_<evaluated-value>".
+   ``SPAWN_<template-class-name>_<evaluated-value>``.
    After classes are evaluated and spawned class is generated, the corresponding
    template class name is also associated with the packet.
  - ``option-data`` list is not mandatory and contains options that should be
    assigned to members of this class. In the case of a template class, these
    options are assigned to the generated spawning class.
  - ``option-def`` list is not mandatory and is used to define custom options.
- - ``only-if-required`` flag is not mandatory and when the value is set to false
-   (the default) membership is determined during classification so is
-   available for instance for subnet selection. When the value is set to true,
-   membership is evaluated only when required and is usable only for option
-   configuration.
+ - ``only-if-required`` flag is not mandatory and when the value is set to
+   ``false`` (the default) membership is determined during classification so is
+   available for instance for subnet selection. When the value is set to
+   ``true``, membership is evaluated only when required and is usable only for
+   option configuration.
  - ``user-context`` is not mandatory and represents a map with user defined data
    and possibly configuration options for hooks libraries.
- - ``next-server`` is not mandatory and configures the 'siaddr' field in
-   packets associated with this class. It is used in DHCP4 only.
- - ``server-hostname`` is not mandatory and configures the 'sname' field in
-   packets associated with this class. It is used in DHCP4 only
- - ``boot-file-name`` is not mandatory and configures the 'file' field in
-   packets associated with this class. It is used in DHCP4 only.
+ - ``next-server`` is not mandatory and configures the ``siaddr`` field in
+   packets associated with this class. It is used in DHCPv4 only.
+ - ``server-hostname`` is not mandatory and configures the ``sname`` field in
+   packets associated with this class. It is used in DHCPv4 only
+ - ``boot-file-name`` is not mandatory and configures the ``file`` field in
+   packets associated with this class. It is used in DHCPv4 only.
  - ``valid-lifetime``, ``min-valid-lifetime``, and ``max-valid-lifetime`` are
    not mandatory and configure the valid lifetime fields for this client class.
  - ``preferred-lifetime``, ``min-preferred-lifetime`` and
    ``max-preferred-lifetime`` are not mandatory and configure the preferred
-   lifetime fields for this client class. It is used in DHCP6 only.
+   lifetime fields for this client class. It is used in DHCPv6 only.
 
 A valid configuration contains at most one of ``test`` or ``template-test``
 parameters. The ``template-test`` parameter also indicates if the class is a
 template class. If both are provided, the configuration is rejected.
 
-::
+..code-block:: json
 
    "Dhcp4": {
        "client-classes": [
            {
                "name": "Client-ID",
                "template-test": "substring(option[61].hex,0,3)",
-           },
-           ...
-       ],
-       ...
+           }
+       ]
    }
 
-If the received DHCP4 packet contans option 61, then the first 3 bytes represent
-value 'foo' in ASCII, then the spawned class will used the
-"SPAWN_Client-ID_foo" name.
-Both "SPAWN_Client-ID_foo" and "Client-ID" classes will be associated with the
-packet.
+If the received DHCPv4 packet contains option 61, then the first 3 bytes represent
+value ``foo`` in ASCII, then the spawned class will used the
+``SPAWN_Client-ID_foo`` name.
+Both ``SPAWN_Client-ID_foo`` and ``Client-ID`` classes will be associated with
+the packet.
 
 .. note ::
 
@@ -748,7 +761,7 @@ packet.
 
    SPAWN_<template-class-name-used-to-activate-this-regular-class>_<evaluated-value-filtering-this-regular-class>
 
-::
+..code-block:: json
 
    "Dhcp6": {
        "client-classes": [
@@ -759,30 +772,28 @@ packet.
            {
                "name": "Client-ID",
                "template-test": "substring(option[1].hex,0,6)",
-           },
-           ...
-       ],
-       ...
+           }
+       ]
    }
 
-If the received DHCP6 packet contans option 1 (client identifier) with hex value
-`0x0002AABBCCDD`, then the "SPAWN_Client-ID_foobar" will be associated with the
-packet. Moreover, if the first 6 bytes represent value 'foobar' in ASCII, then
-the spawned class will use the "SPAWN_Client-ID_foobar" name effectively
-associating the regular class to the packet. In this second case, both
-"SPAWN_Client-ID_foobar" and "Client-ID" classes will be associated with the
-packet.
-The ``test`` expression on the regular classs "SPAWN_Client-ID_foobar" is not
+If the received DHCPv6 packet contains option 1 (client identifier) with hex
+value ``0x0002AABBCCDD``, then the ``SPAWN_Client-ID_foobar`` will be associated
+with the packet. Moreover, if the first 6 bytes represent value ``foobar`` in
+ASCII, then the spawned class will use the ``SPAWN_Client-ID_foobar`` name
+effectively associating the regular class to the packet. In this second case,
+both ``SPAWN_Client-ID_foobar`` and ``Client-ID`` classes will be associated
+with the packet.
+The ``test`` expression on the regular classs ``SPAWN_Client-ID_foobar`` is not
 mandatory and can be omitted, but it is used here with a different match
 expression for example purposes.
 
-Usually the ``test`` and ``template-test`` expression are evaluated before
+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. The ``only-if-required`` 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 subnet, shared network, or pool.
+yet been done.  For this purpose, the ``only-if-required`` 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 subnet, shared network, or pool.
 
 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
@@ -798,50 +809,51 @@ is not mandatory that the flag be set to ``true``.
    classes, so that they are created only when needed by using the `ifelse`
    instruction.
 
-::
+..code-block:: json
 
    "Dhcp4": {
        "client-classes": [
            {
                "name": "Client-ID",
                "template-test": "ifelse(substring(option[61].hex,4,3) == 'foo', substring(option[12].hex,0,12), '')",
-           },
-           ...
-       ],
-       ...
+           }
+       ]
    }
 
 .. note ::
 
-   The template classes can be used to configure limits which, just like options,
-   are associated with the spawned class. This permits configuring limits which
-   apply for all packets associated with a class spawned at runtime, according
-   to the ``template-test`` expression in the parent template class.
-   For a more detaild description on how to configure limits using the limits
-   hooks library see the :ref:`hooks-limits-configuration`.
+   The template classes can be used to configure limits which, just like
+   options, are associated with the spawned class. This permits configuring
+   limits which apply for all packets associated with a class spawned at
+   runtime, according to the ``template-test`` expression in the parent template
+   class. For a more detaild description on how to configure limits using the
+   limits hooks library see the :ref:`hooks-limits-configuration`.
+   For example, using the configuration below, ingress DHCPv6 packets that have
+   client ID values (in the format expressed by the Kea evaluator) ``foobar``
+   and ``foofoo`` both amount to the same limit of 60 packets per day, while
+   other packets that have the first three hextets different than `foo` are put
+   in separate rate limiting buckets.
 
-::
+..code-block:: json
 
    "Dhcp6": {
        "client-classes": [
            {
                "name": "Client-ID",
-               "template-test": "substring(option[1].hex,0,6)",
+               "template-test": "substring(option[1].hex,0,3)",
                "user-context" : {
                    "limits": {
                       "rate-limit": "60 packets per day"
                    }
                }
-           },
-           ...
-       ],
-       ...
+           }
+       ]
    }
 
-In the following example, the class named "Client_foo" is defined. It is
-comprised of all clients whose client IDs (option 61) start with the
-string "foo". Members of this class will be given 192.0.2.1 and
-192.0.2.2 as their domain name servers.
+In the following example, the class named ``Client_foo`` is defined. It is
+comprised of all clients whose client IDs (option 61) start with the string
+``foo``. Members of this class will be given 192.0.2.1 and 192.0.2.2 as their
+domain name servers.
 
 ::
 
@@ -869,7 +881,7 @@ The next example shows a client class being defined for use by the DHCPv6
 server. In it the class named "Client_enterprise" is defined. It is
 comprised of all clients whose client identifiers start with the given
 hex string (which would indicate a DUID based on an enterprise ID of
-0xAABBCCDD). Members of this class will be given 2001:db8:0::1 and
+``0x0002AABBCCDD``). Members of this class will be given 2001:db8:0::1 and
 2001:db8:2::1 as their domain name servers.
 
 ::
@@ -919,12 +931,11 @@ In certain cases it is beneficial to restrict access to certain subnets
 only to clients that belong to a given class, using the ``client-class``
 keyword when defining the subnet.
 
-Let's assume that the server is connected to a network segment that uses
-the 192.0.2.0/24 prefix. The administrator of that network has decided
-that addresses from the range 192.0.2.10 to 192.0.2.20 will be
-managed by the DHCP4 server. Only clients belonging to client class
-"Client_foo" are allowed to use this subnet. Such a configuration can be
-achieved in the following way:
+Let's assume that the server is connected to a network segment that uses the
+192.0.2.0/24 prefix. The administrator of that network has decided that
+addresses from the range 192.0.2.10 to 192.0.2.20 will be managed by the DHCPv4
+server. Only clients belonging to client class ``Client_foo`` are allowed to use
+this subnet. Such a configuration can be achieved in the following way:
 
 ::
 
@@ -998,12 +1009,11 @@ Similar to subnets, in certain cases access to certain address or prefix
 pools must be restricted to only clients that belong to a given class,
 using the ``client-class`` when defining the pool.
 
-Let's assume that the server is connected to a network segment that uses
-the 192.0.2.0/24 prefix. The administrator of that network has decided
-that addresses from the range 192.0.2.10 to 192.0.2.20 are going to be
-managed by the DHCP4 server. Only clients belonging to client class
-"Client_foo" are allowed to use this pool. Such a configuration can be
-achieved in the following way:
+Let's assume that the server is connected to a network segment that uses the
+192.0.2.0/24 prefix. The administrator of that network has decided that
+addresses from the range 192.0.2.10 to 192.0.2.20 are going to be managed by the
+DHCPv4 server. Only clients belonging to client class ``Client_foo`` are allowed
+to use this pool. Such a configuration can be achieved in the following way:
 
 ::
 
index 390b73b8dd21ae5ee427351f5e968b3d1cd1f0d4..83235a9f9f99eb699bfa26b784d9cf3002d992fe 100644 (file)
@@ -4783,7 +4783,7 @@ TEST_F(AllocEngine4Test, getTemplateClassValidLft4) {
                 if (class_name == "BOOTP") {
                     ctx.query_->addClass(class_name);
                 } else {
-                    string subclass("SPAWN_");
+                    string subclass(TemplateClientClassDef::SPAWN_CLASS_PREFIX);
                     subclass += class_name;
                     subclass += "_value";
                     ctx.query_->addSubClass(class_name, subclass);
index 4524f40357f12d3b7554c5f713499cec51bb8ab1..e07193bc1515510c077b66af84a1a9d13b5eff6c 100644 (file)
@@ -5803,7 +5803,7 @@ TEST_F(AllocEngine6Test, getPreferredLifetime) {
                                             Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234)));
             // Add client classes (if any)
             for (auto class_name : scenario.classes_) {
-                string subclass("SPAWN_");
+                string subclass(TemplateClientClassDef::SPAWN_CLASS_PREFIX);
                 subclass += class_name;
                 subclass += "_value";
                 ctx.query_->addSubClass(class_name, subclass);
@@ -5944,7 +5944,7 @@ TEST_F(AllocEngine6Test, getTemplateClassPreferredLifetime) {
                                             Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234)));
             // Add client classes (if any)
             for (auto class_name : scenario.classes_) {
-                string subclass("SPAWN_");
+                string subclass(TemplateClientClassDef::SPAWN_CLASS_PREFIX);
                 subclass += class_name;
                 subclass += "_value";
                 ctx.query_->addSubClass(class_name, subclass);