--- /dev/null
+<?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>