- 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:
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.
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
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
| 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) | | |
+-----------------------+-------------------------------+-----------------------+
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,
- 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
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 ::
SPAWN_<template-class-name-used-to-activate-this-regular-class>_<evaluated-value-filtering-this-regular-class>
-::
+..code-block:: json
"Dhcp6": {
"client-classes": [
{
"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
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.
::
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.
::
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:
::
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:
::