mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-29 13:07:50 +00:00
[trac4101] Add classify.xml file
Add the chapter about classification
This commit is contained in:
parent
192e415b74
commit
e7e89d34b7
309
doc/guide/classify.xml
Normal file
309
doc/guide/classify.xml
Normal file
@ -0,0 +1,309 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
<!ENTITY mdash "—" >
|
||||
]>
|
||||
|
||||
<chapter id="classify">
|
||||
<title>Client Classification</title>
|
||||
|
||||
<section>
|
||||
<title>Client Classification Overview</title>
|
||||
<para>
|
||||
In certain cases it is useful to differentiate between different
|
||||
types of clients and treat them differently. There are many reasons
|
||||
why one might want to treat clients different some common reasons
|
||||
include:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
The clients represent different pieces of topology, for example a cable
|
||||
modem vs the clients behind that modem.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
The clients have different behavior, for example a smart phone vs a lapttop
|
||||
vs a desktop.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
The clients require different values for some options, for example a docsis3.0
|
||||
cable modem vs a docsis2.0 cable modem.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is envisaged that client classification will be used for changing the
|
||||
behavior of almost any part of the DHCP message processing, including assigning
|
||||
leases from different pools, assigning different options (or different values of
|
||||
the same options) etc. For now, there are only two mechanisms that take
|
||||
advantage of client classification: subnet selection and assigning different
|
||||
options. For cable modems there are specific options for use with the TFTP
|
||||
server address and the boot file field.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The process of doing classification is conducted in three steps. The first step
|
||||
is to assess an incoming packet and assign it to zero or more classes. The
|
||||
second step is to choose a subnet, possibly based on the class information.
|
||||
The third step is to assign options again possibly based on the class
|
||||
information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Options will be included from all of the assigned classes. In the case two
|
||||
or more classes include an option the value from the first class will be used.
|
||||
Similarly if two or more classes are associated with a subnet the first subnet
|
||||
will be used. In the future the processing order of the various classes may
|
||||
be specified but for now it is being left unspecified and may change in
|
||||
future releases.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are two methods of doing classification. The first is automatic and relies
|
||||
on examining the values in the vendor class options. Information from these
|
||||
options is extracted and a class name is constructed from it and added to
|
||||
the class list for the packet. The second allows you to specify an expression
|
||||
that is evaluated for each packet. If the result is true the packet is
|
||||
a member of the class.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
The power of the expressions in the classification step is deliberately
|
||||
limited in order to minimize the amount of time required to process each
|
||||
expression. The expression for each class must be executed on each packet,
|
||||
if they are overly complex or time consuming they may impact the performance
|
||||
of the server. If you require complex or time consuming expressions you
|
||||
should write a hook to perform the necessary work.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Care should be taken with client classification as it is easy for
|
||||
clients that do not meet class criteria to be denied any service altogether.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section id="classification-using-vendor">
|
||||
<title>Using Vendor Class Information In Classification</title>
|
||||
<para>
|
||||
The server checks whether an incoming DHCPv4 packet includes
|
||||
the vendor class identifier option (60) or an incoming DHCPv6 packet
|
||||
includes the vendor class option (16). If it does, the content of that
|
||||
option is prepended with "VENDOR_CLASS_" then it is interpreted
|
||||
as a class. For example, modern cable modems will send this option with
|
||||
value "docsis3.0" and as a result the packet will belong to
|
||||
class "VENDOR_CLASS_docsis3.0".
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="classification-using-expressions">
|
||||
<title>Using Expressions In Classification</title>
|
||||
<para>
|
||||
The expression portion of classification contains operators and values.
|
||||
Values are currently strings and operators take a string or strings and
|
||||
return another string. When all the operations have completed
|
||||
the result should be a value of "true" or "false".
|
||||
The packet belongs to
|
||||
the class (and the class name is added to the list of classes) if the result
|
||||
is "true". Expressions are written in standard format and can be nested.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Expressions are pre-processed during the parsing of the configuration file
|
||||
and converted to an internal representation. This allows certain types of
|
||||
errors (such as incorrect syntax) to be caught and logged. Other errors
|
||||
(for example mistakes when setting up the values for a substring) won't be
|
||||
caught and may affect the classification. In general if an expression has
|
||||
a problem a log message will be emitted at the debug level and the result
|
||||
will be an empty string.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The expressions are a work in progress and the supported operators and
|
||||
values are limited. The expectation is that additional operators and values
|
||||
will be added over time, however it is expected the basic mechanisms will
|
||||
remain the same.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<table frame="all" id="classification-values-list">
|
||||
<title>List of Classification Values</title>
|
||||
<tgroup cols='3'>
|
||||
<colspec colname='name' />
|
||||
<colspec colname='example' />
|
||||
<colspec colname='description' />
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Name</entry>
|
||||
<entry>Example</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row><entry>String</entry><entry>'example'</entry><entry>A string</entry></row>
|
||||
<row><entry>Hex String</entry><entry>'0XABCD'</entry><entry>A hexadecimal string</entry></row>
|
||||
<row><entry>Option</entry><entry>option[code]</entry><entry>The value of the option with code "code" from the packet</entry></row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Hex Strings are converted into a string as expected. The starting "0X" or
|
||||
"0x" is removed and if the string is an odd number of characters a
|
||||
"0" is prepended to it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Option extracts the value of the given option from the incoming packet. If the
|
||||
packet doesn't contain the option it returns an empty string.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<table frame="all" id="classification-expressions-list">
|
||||
<title>List of Classification Expressions</title>
|
||||
<tgroup cols='3'>
|
||||
<colspec colname='name' />
|
||||
<colspec colname='example' />
|
||||
<colspec colname='description' />
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Name</entry>
|
||||
<entry>Example</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row><entry>Equal</entry> <entry>'foo' == 'bar'</entry><entry>Compare the two values and return "true" or "false"</entry></row>
|
||||
<row><entry>Substring</entry><entry>substring('foobar',0,3)</entry><entry>Return the requested substring</entry></row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The substring operator substring(value, start, length) accepts both positive and
|
||||
negative values for the starting position and the length. For start a value of
|
||||
0 is the first byte in the string while -1 is the last byte. If the starting
|
||||
point is outside of the original string an empty string is returned. Length
|
||||
is the number of bytes to extract. A negative number means to count towards
|
||||
the beginning of the string but doesn't include the byte pointed to by start.
|
||||
The special value "all" means to return all bytes from start to the end of the
|
||||
string. If length is longer than the remaining portion of the string then
|
||||
the entire remaining portion is returned.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="classification-configuring">
|
||||
<title>Configuring Classes</title>
|
||||
<para>
|
||||
A class contains three items: a name, a test expression and option data.
|
||||
The name must exist and must be unique amongst all classes. The test
|
||||
expression and option data are optional.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The test expression is a string containing the logical expression used to
|
||||
determine membership in the class. The entire expression is in double
|
||||
quotes.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The option data is a list which defines any options that should be assigned
|
||||
to members of this class.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<screen>
|
||||
"Dhcp4": {
|
||||
"subnet4": [
|
||||
{
|
||||
"subnet": "192.0.2.0/24",
|
||||
"pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
|
||||
"client-class": "Client_foo"
|
||||
}
|
||||
],
|
||||
"client-class": [
|
||||
<userinput>
|
||||
{
|
||||
"name": "Client_foo",
|
||||
"test": "substring(option[61],0,3) == 'foo'",
|
||||
"option-data": [
|
||||
{
|
||||
"name": "doamin-name-servers",
|
||||
"code": 6,
|
||||
"space": "dhcp4",
|
||||
"csv-format": true,
|
||||
"data": "192.0.2.1, 192.0.2.2"
|
||||
}
|
||||
]
|
||||
}
|
||||
</userinput>
|
||||
...
|
||||
}</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In this example the class named "Client_foo" is defined. It is comprised
|
||||
of all clients who's client ids (option 61) start with the string "foo".
|
||||
They will be given an address from 192.0.2.10 to 192.0.2.20 and 192.0.2.1
|
||||
and 192.0.2.2 as their domain name servers.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="classification-subnets">
|
||||
<title>Configuring Subnets With Class Information</title>
|
||||
<para>
|
||||
In certain cases it beneficial to restrict access to certain subnets
|
||||
only to clients that belong to a given subnet. For details on client
|
||||
classes, see <xref linkend="classification-using-vendor"/> and
|
||||
<xref linkend="classification-using-expressions"/>
|
||||
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 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
|
||||
example_class are allowed to use this subnet. Such a
|
||||
configuration can be achieved in the following way:
|
||||
<screen>
|
||||
"Dhcp4": {
|
||||
"subnet4": [
|
||||
{
|
||||
<userinput>"subnet": "192.0.2.0/24",
|
||||
"pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
|
||||
"client-class": "example_class"</userinput>
|
||||
}
|
||||
],
|
||||
...
|
||||
}</screen>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Using Classes</title>
|
||||
<para>
|
||||
Currently classes can be used for two functions. They can supply options
|
||||
to the members class and they can choose a subnet for the members of the class.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When supplying options class options defined as part of the class definition
|
||||
are considred "class globals". They will override any global options that
|
||||
may be defined and in turn will be overridden by any options defined for an
|
||||
individual subnet.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Classes and Hooks</title>
|
||||
<para>
|
||||
You may use a hook to classify your packets. This may be useful if the
|
||||
expression would either be complex or time consuming and be easier or
|
||||
better to write as code. Once the hook has added the proper class name
|
||||
to the packet the rest of the classification system will work as normal
|
||||
in choosing a subnet and selecting options.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
Loading…
x
Reference in New Issue
Block a user