Cisco CNS Network Registrar User's Guide, 6.0
Configuring Clients and Client-Classes
Downloads: This chapterpdf (PDF - 548.0KB) The complete bookPDF (PDF - 7.06MB) | Feedback

Configuring Clients and Client-Classes

Table Of Contents

Configuring Clients and Client-Classes

Client-Class Process

Setting up Client-Class on the Server

Enabling Client-Class Processing

Defining Scope Selection Tags

Defining Client-Classes and Their Properties

Setting Client-Class Scope Selection Criteria

Associating a Selection Tag With a Scope

Configuring an Embedded Policy for the Client-Class

Setting Client Properties

Adding and Editing a Client

Configuring an Embedded Policy for a Client

Setting Windows 2000 Client Properties

Settings in the Windows 2000 Client

Settings in the DHCP Server

Providing Provisional Addresses to Unknown Clients

Allocating Provisional Addresses Using the One-Shot Action

Moving a Client to Another Subnet

Skipping Client Entries for Client-Classing

Limiting Client Authentication

Setting Client Caching Parameters

Subscriber Limitation Using Option 82

General Approach to Subscriber Limitation

Client-Class Lookup

Limitation Processing

Expression Processing for Subscriber Limitation

Configuring Option 82 Limitation

DHCP Renewal Processing

Administering Option 82 Limitation

Troubleshooting Option 82 Limitation

Enhanced DHCP Request Processing Using Expressions

Typical Limitation Scenario

Calculating Client-Classes and Creating Keys

Expression Use

Expression Syntax

Creating Expressions

Expression Syntax

Datatypes and Expressions

Literals in Expressions

Expressions Return Typed Values

Expressions Can Fail

Expressions Functions

Datatype Conversions

Expressions in the CLI

Expression Examples

Limitation Example 1: DOCSIS Cable Modem

Limitation Example 2: Extended DOCSIS Cable Modem

Limitation Example 3: Digital Subscriber Line Over Asynchronous Transfer Mode

Debugging Expressions

Troubleshooting Client-Class


Configuring Clients and Client-Classes


You can use Cisco CNS Network Registrar's client or client-class concept to provide differentiated services to users across a common network. You can group clients based on administrative criteria, and then ensure that each group receives its appropriate class of service. If you do not enable client-class processing, the DHCP server provides client leases based solely on their network location.

Table 10-1 lists the client-class configuration topics and the sections to go to for more information. The Network Registrar Web UI Guide explains how to accomplish these tasks using the Web-based interface.

Table 10-1 Client-Class Configuration Topics 

If you want to...
See...

Know more about why you would configure client-classes for Network Registrar servers

"Client-Class Quality of Service" section

Enable client-class processing on a DHCP server

"Enabling Client-Class Processing" section

Add, list, or delete scope selection tags

"Defining Scope Selection Tags" section

Add, edit, or remove client-classes

"Defining Client-Classes and Their Properties" section

Set the client-class scope selection criteria

"Setting Client-Class Scope Selection Criteria" section

Associate a client-class selection tag with a scope

"Associating a Selection Tag With a Scope" section

Configure an embedded client-class policy

"Configuring an Embedded Policy for the Client-Class" section

Add and edit a client

"Adding and Editing a Client" section

Set Windows 200 client properties

"Setting Windows 2000 Client Properties" section

Provide provisional addresses to unknown clients

"Providing Provisional Addresses to Unknown Clients" section

Move a client to another subnet

"Moving a Client to Another Subnet" section

Limiting subscribers using DHCP option 82

"Subscriber Limitation Using Option 82" section

Enhanced option processing to calculate client-classes and limit leases

"Enhanced DHCP Request Processing Using Expressions" section

Troubleshoot client-class

"Troubleshooting Client-Class" section


Client-Class Process

You can enable or disable client-class processing for the DHCP server and apply a set of properties to groups of clients. With client-class processing enabled, the DHCP server assigns the client to an address from a matching scope. The server acts according to the client and client-class data in each packet. To configure client-class:

1. Enable client-class processing for the DHCP server.

2. Define scope selection tags for the server (pre-6.0 only).

3. Define client-classes that include or exclude scope selection tags.

4. Apply the selection tags to specific scopes.

5. Assign clients to these classes.

Setting up Client-Class on the Server

Setting up client-classes involves enabling client-class processing on the DHCP server, creating scope selection tags (pre-6.0 only), and creating the client-classes themselves.

Enabling Client-Class Processing

The first step is to enable client-class processing for the DHCP server and its scopes.

Using the Web UI


Step 1 On the Primary Navigation bar, click DHCP.

Step 2 On the Secondary Navigation bar, click DHCP Server.

Step 3 Click the name of the server.

Step 4 On the Edit DHCP Server page, under the Client Class attribute category, set client-class to enabled.

Step 5 Click Modify Server.


Using the CLI

Use the dhcp enable client-class command to enable client-class processing.

nrcmd> dhcp enable client-class 
100 Ok
client-class=enabled

Using the GUI

In the Server Manager window, double-click the DHCP server. In the DHCP Server Properties dialog box, click the Scope Selection Tags tab. Check the Enable client-class processing box.

Defining Scope Selection Tags

When the DHCP server configures itself, it checks the scope selection tags defined for a scope network (the aggregate of all scopes related to a subnet). This includes all scopes that share a common network number, subnet mask, and primary scope. When the DHCP server reads a client entry, it checks its scope selection inclusion and exclusion criteria against the selection tags defined for the scopes. Note that you might notice performance degradations with a large number of selection tags defined.


Note In Network Registrar 5.5, you had to define these scope selection tags explicitly before you could use them as inclusion or exclusion criteria. In Network Registrar 6.0, you can simply define them in the process of setting the criteria.


The scope selection tag names are not case sensitive, so that tagPC is the same as TAGpc. If you delete a selection tag, Network Registrar removes it from the selection tag list, but does not remove it from any existing scope, client, or client-class configuration.

Using the Web UI

In the Web UI, you do not need to explicitly create scope selection tags. You can define these when setting client-class attributes, as described in the "Setting Client-Class Scope Selection Criteria" section. See the Network Registrar Web UI Guide for details.

Using the CLI

Use the scope-selection-tag name create command to create each scope selection tag. (You do not need to define them for Network Registrar 6.0.) Then, reload the DHCP server and use the scope-selection-tag list command to list all the tags.

nrcmd> scope-selection-tag tagCableModem create 
tagCableModem
100 Ok
nrcmd> dhcp reload 
100 Ok
nrcmd> scope-selection-tag list 
<none>
tagCableModem
100 Ok

Use the dhcp set log-settings command to debug selection tags, particularly the client-criteria-processing and unknown-criteria settings.

nrcmd> dhcp set log-settings=client-criteria-processing,unknown-criteria 
100 Ok
log-settings=unknown-criteria,client-criteria-processing

To delete a scope selection tag, use the scope-selection-tag name delete command.

nrcmd> scope-selection-tag tagCableModem delete 
100 Ok

Using the GUI


Step 1 On the Scope Selection Tags tab of the DHCP Server Properties dialog box, enter a name in the field at the bottom of the dialog box. (You do not need to do this for Network Registrar 6.0.) To identify it as a tag, it is best to prefix it accordingly; for example, tagCableModemUnprov. Click Clear to clear the field, if necessary.

Step 2 Click Add. The name appears under <none> in the table in the middle of the dialog box. (Using the GUI, you can only add selection tags, you cannot delete them.)

Step 3 Add more tags in the same way. If you change your mind about your entries, click Cancel.

Step 4 Click OK.

Step 5 Reload the DHCP server.


Defining Client-Classes and Their Properties

The next step is to define the client-classes themselves. Again, you do this on the server level.

Using the Web UI


Step 1 On the Primary Navigation bar, click DHCP. See the Network Registrar Web UI Guide.

Step 2 On the Secondary Navigation bar, click Client-Classes.

Step 3 On the List DHCP Client-Classes page, click Add Client-Class.

Step 4 Enter the client-class name, a client name, if you want to associate a client with the client-class, and the client-class's domain name, and click a predefined policy from the Policy name drop-down list.

Step 5 Click Add Client-Class.

Step 6 On the List DHCP Client-Classes page, click the name of the newly created client-class.

Step 7 On the Edit DHCP Client-Class page, set the attributes.

Step 8 Click Modify Client-Class.


Using the CLI


Step 1 Use the client-class name create command to create a client-class. The name should clearly identify its intent. It is not case sensitive, so that classPC is the same as Classpc.

nrcmd> client-class CableModem create 
100 Ok
CableModem:
...

Step 2 Use the client-class name set command to set the properties of the clients in the client-class. You can specify the host name that each client should adopt. This can be an absolute, valid DNS value to override that included in the DHCP client request, or can be any of those described in Step 4 of the "Using the GUI" section. To do this, use the client-class name set host-name command. You can also get any property value and unset any optional property.

nrcmd> client-class CableModem set host-name=@use-macaddress 
100 Ok
host-name=@use-macaddress
nrcmd> client-class CableModem get host-name 
100 Ok
host-name=@use-macaddress
nrcmd> client-class CableModem unset host-name 
100 Ok

Step 3 Also, set the appropriate policy to associate with, and the action to perform for, the client-class. For a description of the possible actions to perform, see the "Providing Provisional Addresses to Unknown Clients" section. Use the appropriate command for each of these settings.

nrcmd> client-class CableModem set policy-name=policyCableModem 
100 Ok
policy-name=policyCableModem
nrcmd> client-class CableModem set action=one-shot 
100 Ok
action=one-shot

If you do not want to choose an action on a global level, you can choose to include or exclude scope selection tags that you defined in the "Defining Scope Selection Tags" section. To do this, see the "Setting Client-Class Scope Selection Criteria" section.

Step 4 You can set all the other attributes for a client-class that you can for a client, such as the domain name, authenticate-until property, and the user-defined string. See the "Setting Client Properties" section for details.

Use the client-class name [show] command to show the properties for a particular client-class. You can also list the properties for all the client-classes created, or list just their names.

nrcmd> client-class CableModem 
100 Ok
CableModem:
action = one-shot
client-lookup-id =
domain-name =
...
nrcmd> client-class list 
100 Ok
...
nrcmd> client-class listnames 
100 Ok
CableModem:

Step 5 To delete the client-class, use the client-class name delete command.

nrcmd> client-class UnwantedClass delete 
100 Ok

Step 6 To debug client-class problems, use the dhcp set log-settings=client-criteria-processing command.


Using the GUI


Step 1 In the DHCP Server Properties dialog box for the appropriate server, click the Client-Classes tab.

Step 2 Click Add to open the Add Client-Class dialog box.

Step 3 Enter a name in the Client-Class field that clearly identifies its intent, such as CableModem.

Step 4 In the Host Name field, enter a host name or choose one of the predefined names.

The host-name attribute value can be in one of two general forms. The first is simply the host name string, which overrides the DHCP client request host name. When you enter a valid name, the DHCP server ignores the actual value of the host-name option in the client's DHCP packet and uses the client-entry option instead. The second form is a keyword that starts with the (@) symbol.

@host-name-option—The server uses whatever host name option the client sent.

@no-host-name-option—The server ignores the host name sent by the client. If DNS name generation is in effect, a generated name is used, if set up as such for dynamic DNS updating. See the appropriate step of the "Configuring Dynamic DNS for a Scope" section.

@use-macaddress—The server synthesizes a host name from the client's MAC address. For example, if a client's MAC address is 1-6-00-d0-ba-d3-bd-3b, the synthesized host name would be x1-6-00-d0-ba-d3-bd-3b.

<Not Specified>—Leaves the host name unspecified.

If you enter a host name, dynamic DNS updating must be in effect. See "Configuring Dynamic DNS Update." Also, enter in the adjoining Domain Name field the domain name of the DNS zone to use when performing DNS updates.

Step 5 In the Policy Name field, choose the DHCP policy that is appropriate for the client-class, such as policyCableModem. To leave the policy name unspecified, choose <Not Specified>.

Step 6 In the Action field, choose an action performed on a global level for the client-class:

exclude—The server ignores all communication with the client.

one-shot—Offers an address only once to the client, without renewing or re-offering any lease. This action allocates provisional addresses when you want unknown clients to have only short leases. See the "Providing Provisional Addresses to Unknown Clients" section.

<Not Specified>—Leaves the action unspecified.

Step 7 If you do not want to choose an action on a global level, you can include or exclude scope selection tags that you defined in the previous section. See the "Setting Client-Class Scope Selection Criteria" section.

Step 8 Enter a comment or keyword in the User Defined String field. You can use this to index, sort, or search for the client-classes.

Step 9 Click Apply to continue adding client-classes in the same way, or click OK to finish.

To remove a client-class from the DHCP Server Properties dialog box, choose it, then click Remove.


Setting Client-Class Scope Selection Criteria

If you omit a general action to perform on a client-class, you can specify which scope selection tags to include or exclude.

If a scope has a selection tag assigned to it and client-class assigns an:

Inclusion tag, then the client can get an address from that scope.

Exclusion tag, then the client will not get any address from that scope.

For example, assume three scopes, A, B, and C, with these attributes—A/red, B/blue, C/blue,green. If a client-class specifies inclusion of red, then the client gets an address from scope A. Inclusion of blue gives the client an address from either scope B or C. Inclusion of blue and exclusion of green gives the client an address from scope B only.

Using the Web UI


Step 1 Create the client-class, as described in the "Defining Client-Classes and Their Properties" section. See the Network Registrar Web UI Guide for details.

Step 2 On the List DHCP Client-Classes page, click the name of the client-class.

Step 3 On the Edit DHCP Client-Class page, set these two attributes:

selection-criteria—Create a scope selection tag to use to include this client-class in the scope.

selection-criteria-excluded—Create a tag to use to exclude this client-class in the scope.

Step 4 Click Modify Client-Class.


Using the CLI

Use the client-class name set selection-criteria command to set the inclusion criteria and the client-class name set selection-criteria-excluded command to set the exclusion criteria. Avoid setting conflicting inclusion and exclusion criteria. Ensure that they are mutually exclusive.

nrcmd> client-class CableModem set selection-criteria=tagPC 
selection-criteria-excluded=tagUnprovPC 
100 Ok
selection-criteria=tagPC
selection-criteria-excluded=tagUnprovPC


Note For Network Registrar 6.0 clusters, the command does not warn about noncreated scope selection tags.


Using the GUI


Step 1 In the Add Client-Class (or Edit Client-Class) dialog box, click Edit Criteria.This opens the Edit Scope Selection Criteria dialog box.

Step 2 Check the boxes for the scope selection tags that you want included and excluded in this client-class. (You cannot choose the same tags for both.)

Step 3 Click OK.


Associating a Selection Tag With a Scope

The next step is to associate the appropriate scope selection tags with the scope, which must be under the server you configured in the "Setting up Client-Class on the Server" section.

Using the Web UI


Step 1 Create the scope, as described in the "Defining and Configuring Scopes" section.

Step 2 On the List/Add DHCP Scopes page, click the name of the scope.

Step 3 On the Edit DHCP Scope page, in the Selection Tags area, include in the Selection Tag field a comma-separated list of scope selection tags created in the selection-criteria attribute for the client-class (see the "Setting Client-Class Scope Selection Criteria" section).

Step 4 Click Modify Scope. See the Network Registrar Web UI Guide for details.


Using the CLI

Use the scope name set selection-tags command to associate existing selection tags with a scope.

nrcmd> scope scopeUnprovPC create 192.168.70.0 255.255.255.0 
100 Ok
scopeUnprovPC:
addr = 192.168.70.0
bootp = disabled
deactivated =
...
nrcmd> scope scopeUnprovPC set selection-tags=tagCableModemUnprov 
100 Ok
selection-tags=tagCableModemUnprov
nrcmd> dhcp reload 
100 Ok

Using the GUI


Step 1 In the Server Manager window, double-click the scope.

Step 2 Click the Selection Tags tab.

Step 3 Click Edit Tags. This opens the Choose Scope Selection Tags dialog box.

Step 4 Check the boxes for one or more of the scope selection tags defined for the server, then click OK.

Step 5 Click OK in the Scope Properties dialog box.

Step 6 Reload the DHCP server.

Step 7 Repeat these steps for each additional scope.


Configuring an Embedded Policy for the Client-Class

Network Registrar automatically creates an embedded policy for each client-class. The embedded policy has no properties or DHCP options associated with it until you add them. This is like an embedded policy for a scope (see the "Configuring an Embedded Policy for the Scope" section).

Using the Web UI


Step 1 Create the client-class, as described in the "Defining Client-Classes and Their Properties" section. See the Network Registrar Web UI Guide for details.

Step 2 Click the name of the client-class on the List DHCP Client-Classes page.

Step 3 Click Edit Embedded Policy to open the Edit DHCP Embedded Policy for Client-Class page.

Step 4 Modify the fields, options, and attributes on this page. If necessary, unset attributes.

Step 5 Click Modify Embedded Policy.


Using the CLI

Use the client-class-policy command in the CLI, using the client-class name as the policy name.


Step 1 See if there are any embedded property values already set for a client-class.

nrcmd> client-class-policy CableModem 
100 Ok
client-class-policy:CableModem:
allow-client-a-record-update = [default=disabled]
allow-dual-zone-dns-update = [default=disabled]
allow-lease-time-override = [default=enabled]
...

Step 2 Enable or disable an attribute.

nrcmd> client-class-policy CableModem enable allow-lease-time-override 

Step 3 Get, set, and unset client-class attributes. Deleting a client-class policy unsets all its properties.

nrcmd> client-class-policy CableModem get server-lease-time 
100 Ok
allow-lease-time-override=enabled
nrcmd> client-class-policy CableModem set server-lease-time=2880 
100 Ok
server-lease-time=48m
nrcmd> client-class-policy CableModem unset server-lease-time 
100 Ok
nrcmd> client-class-policy CableModem delete 
100 Ok

Step 4 List, get, set, and unset DHCP options. You can also set, unset, and list vendor options. For vendor options, see the "Supporting Vendor-Specific DHCP Options" section.

nrcmd> client-class-policy CableModem listOptions 
nrcmd> client-class-policy CableModem setOption routers 192.168.40.1 
100 Ok
routers=192.168.40.1
nrcmd> client-class-policy CableModem getOption routers 
100 Ok
routers=192.168.40.1
nrcmd> client-class-policy CableModem unsetOption routers 
100 Ok

Step 5 If necessary, set the lease time for the embedded client-class. Verify by listing the options.

nrcmd> client-class-policy CableModem setLeaseTime 86400 
100 Ok
24h
nrcmd> client-class-policy CableModem listOptions 
100 Ok
<51>dhcp-lease-time: 86400 


Setting Client Properties

Set the DHCP client properties. These properties include the client's participating client-class, its associated policy, the action to perform, and the inclusion and exclusion criteria for scope selection tags.

Adding and Editing a Client

A client inherits the properties from its client-class, which you may choose to override or supplement by specifying different ones for the client.

Using the Web UI


Step 1 On the Primary Navigation bar, click DHCP. See the Network Registrar Web UI Guide for details.

Step 2 On the Secondary Navigation bar, click Clients.

Step 3 On the List/Add DHCP Clients page, enter the MAC address of the client and click a client-class name, if desired, from the drop-down list of predefined client-classes, as created in the "Defining Client-Classes and Their Properties" section.

Step 4 Click Add Client. This opens the Edit Client page.

Step 5 Add any attributes for the client, including scope selection criteria.

Step 6 Click Modify Client.


Using the CLI


Step 1 Use the client name create command to create a client. Specify the name by MAC address, using the prefix, if necessary. You can also create a client named default that does not have a specific client configuration. For example, you can have this client always use its MAC address for its host name:

nrcmd> client 1,6,00:d0:ba:d3:bd:3b create 
100 Ok
1,6,00:d0:ba:d3:bd:3b:
...

nrcmd> client default create host-name=@use-macaddress 
100 Ok
...
nrcmd> dhcp reload 
100 Ok

Step 2 Use the client name set command to set the client properties. These properties need not be set in any particular order, but these steps give some suggestions and provide a basic process.

Step 3 Set the host-name attribute to @no-host-name-option to provide provisional addresses to unknown clients. See the "Providing Provisional Addresses to Unknown Clients" section.

nrcmd> client 1,6,00:d0:ba:d3:bd:3b set client-class-name=CableModem 
host-name=@no-host-name-option 
100 Ok
client-class-name=CableModem
host-name=@no-host-name-option

Step 4 Set the domain name of the zone to use when performing dynamic DNS updates.

nrcmd> client 1,6,00:d0:ba:d3:bd:3b set domain-name=example.com. 

Step 5 Set the policy and action for the client. With the exclude action, the server ignores all communication from this client (no packets are shown); with the one-shot action, the server does not renew or re-offer a lease to this client.

nrcmd> client 1,6,00:d0:ba:d3:bd:3b set policy-name=policyCableModem action=exclude 
100 Ok
policy-name=policyCableModem
action=exclude

Step 6 Set the scope selection tags, as defined with the scope-selection-tag tag create command, that you want included or excluded for a client. (You do not need to do this in Network Registrar 6.0.)

nrcmd> client 1,6,00:d0:ba:d3:bd:3b set selection-criteria=tagCableModem 
selection-criteria-excluded=tagCableModemUnprov 
100 Ok
selection-criteria=tagCableModem
selection-criteria-excluded=tagCableModemUnprov

Step 7 Choose the number of time units (seconds, minutes, hours, days, weeks), or UNIX style date (such as Mar 24 12:00:00 2002) to indicate when the authentication expires, or use forever.

nrcmd> client 1,6,00:d0:ba:d3:bd:3b set authenticate-until=+100d 
100 Ok
authenticate-until="Mon Dec 02 14:31:47 2002"

Step 8 You can also unset any of the optional client options.

nrcmd> client 1,6,00:d0:ba:d3:bd:3b unset authenticate-until 
100 Ok

Step 9 Use the client name [show] command to display properties of a specific client. Use the client list command to display properties for all the clients, or the client listnames command to list just the names.

nrcmd> client 1,6,00:d0:ba:d3:bd:3b 
100 Ok
...
nrcmd> client list 
100 Ok
...
nrcmd> client listnames 
100 Ok

Step 10 Use the client name delete command to delete a client.

nrcmd> client 1,6,00:d0:ba:d3:bd:3b delete 
100 Ok
nrcmd> dhcp reload 
100 Ok


Using the GUI


Step 1 In the DHCP Server Properties dialog box, click the Clients tab.

Step 2 Click Add to open the Add Client dialog box.

Step 3 The dialog box has these fields:

MAC address—You can omit the 1,6 prefix, but you must enter the full MAC address.

Client-Class—Choose from the existing client-classes, or click New and create a new client-class.

Host Name—Choose a predefined name or enter a new name. For a description of the predefined names, see the "Defining Client-Classes and Their Properties" section.

Domain Name—Domain name of the zone to use when performing DNS updates.

Policy Name—Choose an existing policy or <Not Specified>.

Action—Exclude causes the server to ignore all communication from this client. One-shot prevents the server from renewing or re-offering any lease to this client.

Scope Selection Criteria—If necessary, click Edit Criteria to define the tags that you want included or excluded. See the "Setting Client-Class Scope Selection Criteria" section.

Authenticate Until—Choose the predefined authentication method ("forever") or enter the number of time units (seconds, minutes, hours, days, weeks), or UNIX-style date, such as Mar 24 12:00:00 2002, to indicate when the authentication expires. Note that seconds are optional.

User Defined String—Comment or keyword.

Step 4 Click OK to finish or Apply to continue adding clients. To edit a client, double-click the client in the DHCP Server Properties dialog box. To remove a client, select it, then click Remove.


Configuring an Embedded Policy for a Client

Network Registrar automatically creates an embedded policy for each client. The embedded policy has no properties or DHCP options associated with it until you enable or add them. This is like an embedded policy for a scope (see the "Configuring an Embedded Policy for the Scope" section).

Using the Web UI


Step 1 Create the client, as described in the "Adding and Editing a Client" section.

Step 2 Click the MAC address of the client on the List DHCP Clients page to open the Edit DHCP Client page.

Step 3 Click Edit Embedded Policy to open the Edit DHCP Embedded Policy for Client page.

Step 4 Modify the fields, options, and attributes on this page. If necessary, unset attributes.

Step 5 Click Modify Embedded Policy. See the Network Registrar Web UI Guide for details.


Using the CLI

Use the client-policy command in the CLI. Note that you use the client MAC address (or default) as the client policy name.


Step 1 See if there is an embedded policy for the client and what its properties are using the client-policy name show command.

Step 2 Show or get the value of any attributes.

nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b show 
100 Ok
client-policy:1,6,00:d0:ba:d3:bd:3b:
allow-client-a-record-update = [default=disabled]
allow-dual-zone-dns-update = [default=disabled]
allow-lease-time-override = [default=enabled]

Step 3 Enable or disable an attribute using the client-policy name enable or client-policy name disable command.

nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b enable allow-lease-time-override 
100 Ok
allow-lease-time-override=enabled

Step 4 Set attributes. You can unset any optional ones. Deleting the client policy unsets all its properties.

nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b set server-lease-time=2880 
100 Ok
server-lease-time=48m
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b get server-lease-time 
100 Ok
server-lease-time=48m
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b unset server-lease-time 
100 Ok
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b delete 
100 Ok

Step 5 You can also list, get, set, and unset any DHCP options, set or unset vendor options, and get and set the lease time for the embedded policy. For vendor options, see the "Supporting Vendor-Specific DHCP Options" section.

nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b setOption routers 192.168.40.1 
100 Ok
routers=192.168.40.1
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b listOptions 
100 Ok
(3)routers: 192.168.40.1
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b getOption routers 
100 Ok
routers=192.168.40.1
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b unsetOption routers 
100 Ok
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b setLeaseTime 228800 
100 Ok
2d15h33m20s


Setting Windows 2000 Client Properties

Windows 2000 clients support class-based provisioning. You can set certain properties in the CLI that relate to client-class processing. These are:

Looking up the client entry to determine the default client for client-class processing.

Mapping the user class ID to the client-class or scope selection tag.

Whether to append the class ID to the scope selection tag name.

Settings in the Windows 2000 Client

On the Windows 2000 client host, use the ipconfig /setclassid command to set the class ID. If you plan to map this client ID to a client-class or selection tag, it must have the same name. Then confirm by using the ipconfig /showclassid command.

DOS> ipconfig /setclassid adapter engineering 
DOS> ipconfig /showclassid adapter 

Settings in the DHCP Server

You must also set Windows 2000 client properties in the DHCP server.

Use DHCP server attributes in the Web UI or dhcp set command attributes in the CLI to set the Windows 2000 client properties for the server. If you set the skip-client-lookup attribute to true (the default is false), the DHCP server skips the client entry for client-class processing. See the "Skipping Client Entries for Client-Classing" section. Use one of the map-user-class-id attribute settings:

0—Ignore the user class ID (the default)

1—Map the user class ID to the scope selection tag

2—Map the user class ID to the client-class

If you map the user class ID to the scope selection tag (value=1), you can also append it to the selection name by enabling the append-user-class-id-to-selection-tag attribute. With the class ID set in the client configuration example in the "Settings in the Windows 2000 Client" section, the selection tag in this example would become tagPCengineering.

nrcmd> dhcp enable skip-client-lookup 
nrcmd> dhcp set map-user-class-id=1 
nrcmd> dhcp enable append-user-class-id-to-selection-tag 
nrcmd> dhcp reload 

Providing Provisional Addresses to Unknown Clients

The DHCP server can allocate provisional addresses to unknown clients for a short time on a one-shot basis. The server gives an address to the unknown client only as long as its lease period (which should be set short) and ignores all the client's requests during the grace period and until the address is re-allocated to another client. You can thus configure the grace period to offer the unknown client an extended time in which to register with an authority and become known.

Using the Web UI or CLI

Create an unknown policy and use the Grace period field on the Edit DHCP Policy page of the Web UI or the policy unknown create grace-period=extended-time setting in the CLI. Then use the default client to set the Policy name value to unknown, and the action attribute value to one-shot on the Edit DHCP Client page of the Web UI, or use the client default create policy-name=unknown action=one-shot commands in the CLI, to give provisional addresses to unknown clients.

nrcmd> policy unknown create grace-period=5d 
nrcmd> client default create policy-name=unknown action=one-shot 
nrcmd> dhcp reload 

Using the GUI


Step 1 Open the Add (Edit) Client dialog box. See the "Adding and Editing a Client" section.

Step 2 Enter the word default in the MAC address field.

Step 3 You have two options:

If you have a client-class that handles one-shot leases, choose it from the Client-Class field. Then, choose one-shot in the Action field.

To exclude access to all unknown clients, choose exclude in the Action field.

Step 4 Click OK.

Step 5 Reload the DHCP server.


Allocating Provisional Addresses Using the One-Shot Action

Use the one-shot action to allocate provisional addresses. This is useful when you want a client to have an address for only a short time. Configure the default client (or the client-class that the default client specifies) with the one-shot action.

nrcmd> client default set action=one-shot 
100 Ok
action=one-shot

The server then gives a lease to an unknown client, but when the lease expires, the server does not respond to that client during the lease grace period. After this period expires, the server does not respond to the client until another client gets the lease. This final period could be short or long, depending on the number of leases in the scope and clients using them. Newly available leases go on the end of a queue. Because the server allocates leases from the beginning of the queue, it might be quite some time before another client gets the lease.

You can allow the client a relatively short lease time, such as one day, and specify a long grace period, such as two weeks. This way you can offer an incentive to the client to register with some authority and become a known client, while not re-allocating the lease to another client. After the lease expires, the client cannot get another address for the two-week grace period. When another client gets the lease, the first client, whose use of the lease is no longer on record, can get another lease as an unknown client and have another opportunity to register.

You can configure the lease and grace period differently for each scope, so that provisional leases can have different lease and grace periods than nonprovisional ones. Provisional addresses are less restrictive if you use multiple DHCP servers, because each server operates its one-shot capabilities independently. With the approach described and two DHCP servers, an unregistered client can get two days of provisional address use every two weeks.

Moving a Client to Another Subnet

If you move a DHCP client to another subnet, you need to reboot the machine when it arrives on the new subnet or explicitly release and re-acquire a lease using the Windows ipconfig /release, and ipconfig /renew, utilities.

Skipping Client Entries for Client-Classing

Use the skip-client-lookup attribute on the Edit DHCP Server page of the Web UI, or the dhcp enable skip-client-lookup command in the CLI, to have the DHCP skip looking up client entries for client-class processing.

nrcmd> dhcp enable skip-client-lookup 
100 Ok
skip-client-lookup=true

Limiting Client Authentication

By default, client entries get unlimited authentication. Using the authenticate-until attribute, you can limit authenticating a client entry by specifying an expiration time.

When a client entry is no longer authenticated, the DHCP server uses the unauthenticated-client-class-
name
attribute value for the name of the client-class entry to use in answering this DHCP request. If this attribute is not set, or if there is no client-class entry in it, the DHCP server ignores the request.

Here are the valid authentication values:

+num unit—Time in the future, where num is a decimal number and unit is s, m, h, d, or w for seconds, minutes, hours, days or weeks, respectively. For example, "+3w" is three weeks in the future.

date—Month, day, 24-hour, and 2-or-4-digit-year. For example, "Jun 30 20:00:00 2002." Enter the time that is local to the nrcmd process. If the server runs in another time zone, disregard the time zone and use local time instead.

forever—Does not expire the authentication for this client.

These steps give an example of using the authenticate-until attribute to distinguish between clients that are authenticated and those that are not authenticated. After the authentication expires and the client requests another address, the DHCP server assigns the client an address from the range.


Step 1 Create two scope selection tags to tie the authenticated and unauthenticated client to a scope. (You do not need to do this in Network Registrar 6.0.)

nrcmd> scope-selection-tag AuthSelectionTag create 
AuthSelectionTag
100 Ok
nrcmd> scope-selection-tag UnauthSelectionTag create 
UnauthSelectionTag
100 Ok

Step 2 Create an authenticated and an unauthenticated client-class. Set the selection criteria for each as appropriate.

nrcmd> client-class AuthClientClass create selection-criteria=AuthSelectionTag 
100 Ok
selection-criteria=AuthSelectionTag
AuthClientClass:
...
selection-criteria = {{0 AuthSelectionTag}}
selection-criteria-excluded =
user-defined =
nrcmd> client-class UnauthClientClass create selection-criteria=UnauthSelectionTag 
100 Ok
selection-criteria=UnauthSelectionTag
UnauthClientClass:
...
selection-criteria = {{0 UnauthSelectionTag}}
selection-criteria-excluded =
user-defined =

Step 3 Create the client and include the authenticate-until expiration time. Set the client-class-name and unauthenticated-client-class-name attributes as appropriate.

nrcmd> client 00:d0:ba:d3:bd:3b create authenticate-until=+10m 
client-class-name=AuthClientClass 
unauthenticated-client-class-name=UnauthClientClass 
100 Ok
authenticate-until="Sat Aug 24 15:55:53 2002"
client-class-name=AuthClientClass
unauthenticated-client-class-name=UnauthClientClass
1,6,00:d0:ba:d3:bd:3b:
...

Step 4 Create the authenticated and unauthenticated scopes, define their address ranges, and tie them to their respective scope selection tags.

nrcmd> scope AuthScope create 192.168.2.0 255.255.255.0 selection-tags=AuthSelectionTag 
100 Ok
selection-tags=AuthSelectionTag
AuthScope:
...
selection-tags = {{0 AuthSelectionTag}} addr = 192.168.2.0
...
nrcmd> scope AuthScope addRange 192.168.2.1 192.168.2.50 
100 Ok
192.168.2.1 192.168.2.50
nrcmd> scope UnauthScope create 192.168.2.0 255.255.255.0 
selection-tags=UnauthSelectionTag 
100 Ok
selection-tags=UnauthSelectionTag
UnauthScope:
...
selection-tags = {{0 UnauthSelectionTag}}
...
nrcmd> scope UnauthScope addRange 192.168.2.51 192.168.2.100 
100 Ok
192.168.2.51 192.168.2.100

Step 5 Enable client-class processing for the server.

nrcmd> dhcp set client-class=enabled 
100 Ok
client-class=enabled

Step 6 Reload the server.

nrcmd> dhcp reload 
100 Ok


Setting Client Caching Parameters

A client's initial request for an address from a DHCP server often goes through a DHCPDISCOVER-
DHCPOFFER-DHCPREQUEST cycle. This process requires that the DHCP server must consult the database twice for client data per request. If the client caching parameters are set, the DHCP server caches client data in memory so that it only needs to consult the database once. Client caching can provide a noticeable performance improvement in systems that store client information in LDAP. Client caching is enabled by default unless you unset the applicable attributes.

You can adjust the maximum cache count and TTL parameters based on the expected rate of client requests. If you expect an onslaught of requests, you might want to increase the cache count, up to a limit based on your available memory. If you expect a longer request cycle, you might want to increase the TTL. The aim is to have the server consult the client cache once during the request cycle.

To set the limit on the number of entries that the server keeps in the client cache, use the client-cache-count attribute on the Edit DHCP Server page of the Web UI, or the dhcp set client-cache-count command in the CLI. By default, the maximum number to cache is 1000 clients.

nrcmd> dhcp set client-cache-count=1000 
100 Ok
client-cache-count=1000

The client cache is usually valid for only ten seconds, called the cache time to live (TTL). After the TTL expires, the server reads the client information right from the database. You can adjust this TTL using the client-cache-ttl attribute on the Edit DHCP Server page of the Web UI, or the dhcp set client-cache-ttl command in the CLI.

nrcmd> dhcp set client-cache-ttl=20 
100 Ok
client-cache-ttl=20

When the client cache count reaches the specified maximum, the server cannot cache any more clients until the TTL expires, after which it reads from the database and begins caching again.

Subscriber Limitation Using Option 82

In many situations, service providers want to limit the number of IP addresses the DHCP server should give out to devices on customer premises. They want these devices to have "real" addresses provided by the DHCP server, but to limit the number of these addresses. One way to accomplish this is to use the client-class capability to register (or provision) each customer device. In this scenario, IP addresses are issued only to devices that are registered in the client-entry database. The major drawback to this approach is that it requires registering every customer device, which involves knowing its MAC address. Service providers often do not want to know about each device, but simply that there are not too many of them per customer.

Limiting customer devices on a per-subscriber basis gives rise to the idea of limiting them based on values in the relay-agent-info DHCP option (option 82, as described in RFC 3046) that the DHCP relay agent sends in a DHCPDISCOVER message. This option includes data about the port on a switch over which the customer device is attached. In a cable modem scenario, one of the suboptions of the relay-agent-info option usually contains the MAC address of the cable modem when the DHCP request comes from a device attached beyond the cable modem. In general, many devices that generate option 82 data place some values in its suboptions such that the value varies per subscriber on the same upstream device. In some cases, this value is unique across all possible subscribers (such as the MAC address of the cable modem). In others, it can be a port on a switch and thus unique across the other subscribers attached to that switch, but it might not be unique across all subscribers on the switch.

The goal of this implementation is to allow the network administrator to configure limitations on subscriber use of the DHCP-allocated addresses without seriously impacting other capabilities of the DHCP server. In many environments, network administrators might want to use option 82 limitation for some class of devices and not others. A key aspect of this support is to allow network administrators to separate the devices for which they want to use option 82 limitation from those for which they do not.

General Approach to Subscriber Limitation

The current approach to client processing is to look up every client in the client-entry database. One of the goals of option 82 limitation is to remove the need explicitly to register (provision) every customer device in the client-entry database (either in the MCD database or LDAP). However, there is still a requirement that the specific number to which a subscriber is limited should be configurable and override the default number given to all unregistered subscribers.

A new first step was added to client-class processing to look up a client-class. At a high level, this is configured by creating an expression that is evaluated for each incoming packet and returns the name of the client-class where the packet should be placed. See the "Enhanced DHCP Request Processing Using Expressions" section for details on the use of expressions.

To handle this, each client-class allows specification of a limitation ID, a key to be determined from the incoming packet and then used by the server in a later processing step to do the actual limitation on the number of devices. All devices with the identical limitation ID (the limitation-id property) are considered to come from the same subscriber.

Client-Class Lookup

The initial client-class lookup is to allow you to decide whether the client should participate in some sort of limitation. An expression is configured server-wide with the client-class-lookup-id property. This expression is executed on every incoming packet with the goal of determining the client-class of the packet. The expression should return a string that is the client-class name to be used for the packet, or the distinguishing string <none>, which indicates that no client-class value was considered for the client request.

Returning the <none> string is equivalent to not configuring a client-class-lookup-id value and that no client-class processing should occur. If the expression returns null or there is an error evaluating the client-class-lookup-id, the packet is dropped (with a log message).

Limitation Processing

The DHCP server limits the number of IP addresses allocated to DHCP clients with the same limitation-id value in the same network or LAN segment. In cases where the server finds that allocating another address to the client would go over the limit, it places the client's packet in the overflow-client-class (if any is specified). This allows special handling for clients that are over the configured limit. Handling these clients in some self-provisioning way is one of the benefits of using limitation on the DHCP server instead of in the hardware (should it even be supported).

If there is no over-limit client-class, the server drops a packet where allocating an address for that packet would exceed the allowed limitation-count for that limitation-id. Note that the limitation is enforced only within a single network or LAN segment. This is hardly a restriction, because network managers tend to see a single subscriber connecting only over one LAN segment at a time.

Configure the limitation-count with an identical limitation-id in a DHCP policy. The limitation code searches up the policy chain for the limitation-count just as it does for any other policy item. This means that you can configure the limitation-count in a client-class's embedded or named policy, a scope's embedded or named policy, or the system's system_default_policy.

When you configure a limitation-id on a client-class, you thereby signal to pursue limitation processing for the client-class. When you do not configure a limitation-id, you thereby signal not to pursue it. When executing the expression to determine the limitation-id, if the expression returns null, this signals that limitation processing should occur and to use the limitation-id saved in the lease state database.

Expression Processing for Subscriber Limitation

There are expressions in several places in the limitation processing. Each expression either evaluates to null or to a string (typically to determine a client-class name when looking up a client-class), or evaluates to a series of bytes (a blob) when creating a limitation-id. Expressions are used in these places:

Looking up a client-class.

Creating the key to use in limiting clients of the same subscriber (the limitation-id).

Creating the key to look up in the client-entry database (the client-lookup-id).

Configuring Option 82 Limitation

There are a number of steps required to properly configure option 82 limitation:


Note If you are not registering clients explicitly, do not enable client-class as a DHCP server property when using option 82 data.


1. Determine if you want to limit some clients and not others. If you want to limit some clients:

a. Find some method to distinguish these clients from the others, based on some values contained in the DHCP requests from each class of clients.

b. Determine the names of the client-classes into which you want to put the clients that are not limited, and the selection tag and scope or scopes you want to use for these unlimited clients.

2. Decide if you want to put clients that are over-limit into a different client-class or just drop their packets. If you want to put them into an over-limit client-class, determine the client-class name and the selection tag and scope or scopes into which you want to put the over-limit clients.

3. Determine the client-class into which you want to put clients that you intend to limit and the selection tags and scope or scopes you want to use for these clients.

4. Create all these selection tags, client-classes, and scopes.

5. Configure the limitation-count in a policy, probably the named policy associated with the client-class for the clients to be limited.

6. Write the expression to separate the incoming clients into those to be limited and those not be limited. Configure it on the DHCP server by setting the client-class-lookup-id attribute.

7. Write the expression to determine the limitation ID for the devices to be limited, and configure it on the client-class for clients to be limited by setting the limitation-id.

DHCP Renewal Processing

Remember that only packets that are broadcast from the DHCP client arrive at the DHCP server with option 82 data attached. The BOOTP or DHCP relay agent adds the option 82 data in the first upstream router from the client device. A DHCPRENEW packet is unicast to the server and arrives without option 82 data. This can pose a problem when trying to configure the server for subscriber limitation.

There are generally two approaches to take when dealing with renewals. The first is to place all packets that do not have option 82 data into a client-class with no associated selection tags. This is equivalent to a wildcard selection and means that any packet with no option 82 data is accepted. The second approach is to place a renewal in the same client-class as you would place a packet that has option 82 data, and have its limitation-id evaluate to null. This is a signal that when checking for limitation, the DHCP server should use a previously stored limitation-id instead of one from the packet.

Both approaches work. The second one appears to offer more security, but in practice, it is not much better than the first. This is because you have to use an IP address for the DHCP server to respond to a DHCPRENEW, and most clients would not ever do this unless the server lost some of its state. In this case, you would want it to give the address to the client. In the case of a malicious client, it would still have to use the address to get the server to give the address to the client, thereby limiting the exposure for this case.

Administering Option 82 Limitation

Whenever a client is involved in limitation because of its inclusion in a client-class with a limitation-id, the limitation-id used is logged in the DHCP log file whenever the client data is logged. The limitation-id used appears as "... LID: nnn:nnn:nnn..." in the log file. The data is logged only for clients with active leases that are currently occupying one of the limitation-count counts.

You can determine all the clients using a limitation-id in a subnet by using the dhcp limitationList command:

nrcmd> dhcp limitationList ipaddr [limitation-id] show 
100 Ok

If you specify both the ipaddr and limitation-id, the ipaddr value is used just like a giaddr to

determine the subnet. Any IP address that could appear in any scope (primary or secondary) for the network can be used to specify a subnet. If you specify only the ipaddr, it must be an address that is served by the DHCP server, and the command returns all of the clients and corresponding leases they use.

If a client is denied service due to a limitation-count overflow, a message such as this would appear in the DHCP server log file:

Warning Server 0 05646 Could not add Client MAC: '1,6,01:02:03:04:0c:03'  with 
limitation-id: 01:02:03 using Lease: 10.0.0.23, already 3 Clients with that id. No 
over-limit client class specified! Dropping packet!

You can determine which clients are currently using up the limitation-count, thus causing a denial of service for the new client, by using the dhcp limitationList command. The ipaddr value in the command should be the "using Lease:" value, and the limitation-id should be the "limitation-id:" value, in the log file. Using the log file example, the command would be:

nrcmd> dhcp limitationList 10.0.0.23 01:02:03 show 
100 Ok

Troubleshooting Option 82 Limitation

There are several ways that you can debug limitation support. First, you might want to turn on packet tracing using the dhcp setDebug VX=1 command (dhcp setDebug VX=0 disables packet tracing). Then, you probably want to enable client-class debugging by adding client-criteria-processing and client-detail to your log settings.

There is also a server-wide expression trace level, expression-trace-level, that you can set to various levels. Setting it to 6 gives you a details trace of every expression evaluation. This can take a bit of space in the log, and slows down the server considerably as well, but is invaluable in the process of getting familiar with expression evaluation. See the "Debugging Expressions" section.

When things seem to be going strangely, or when submitting log files to report a problem, it is important to enable some additional tracing using the dhcp setDebug QR57=9 command (dhcp setDebug QR57=0 disables this tracing). Note that the Q and R are both uppercase. The Q is client-class debugging and the R is response debugging (required to get the flow of control clear in the log). The 5 is expression processing and the 7 is client-class-lookup processing. This generates a page or so of output for each packet, but the page is invaluable for understanding what is going on inside the server.

If, when configuring an expression using the CLI, the expression is not echoed back on output before the 100 Ok line, then it is probably was not entered correctly.

Enhanced DHCP Request Processing Using Expressions

Network Registrar provides enhanced client-class support. You can now place a request into a client-class based on the contents of the request, without having to register the client in the client database. Also, you can now place requests in a client-class based on the number of a subscriber's active leases, allowing limitations on the level of service offered to various subscribers. This is possible through the special DHCP options processing using expressions.

You can set the limitation on subscriber addresses based on values in the DHCP relay-agent-info option (option 82, as described in RFC 3046). These values do not need to reveal any sensitive addresses. You can create values that relate an individual to a subscriber by creating an expression that evaluates the incoming DHCPDISCOVER request packets against option 82 suboptions (remote-id or circuit-id) or other DHCP options. The expression is a series of if statements that return different values depending on what is evaluated in the packet. This, in effect, calculates the client-class in which the subscriber belongs, and limits address assignment to the scope of that client-class.

Typical Limitation Scenario

For example, an incoming packet might be evaluated such that:

1. If the remote-id suboption of option 82 matches the client hardware address (chaddr), then the subscriber is a cable modem and should be assigned to the cm-client-class.

2. If the first six bytes in the vendor-class-id option value match the string docsis, then the subscriber is a DOCSIS modem and should be assigned to the docsis-cm-client-class.

3. If the user-class option value matches the string alternative-class, then the subscriber should be assigned to the alternative-cm-client-class.

Calculating Client-Classes and Creating Keys

The expression that determines the client-class is set by the client-class-lookup-id attribute of the DHCP server in the Web UI, or the dhcp command in the CLI. Include simple expressions in the attribute definition or more complex ones in a file referenced in the attribute definition (see the "Expression Use" section):

nrcmd> dhcp set client-class-lookup-id=expression 

Client and client-classes also allow specification of a limitation-id value for the client or client-class. The server uses this identifier (ID) value to set the address limit on the number of devices with the identical ID on the same network or LAN segment. If a requesting client oversteps the limit of available addresses for that ID, the server assigns it to an over-limit-client-class-name (if set); otherwise, it drops the packet. The limitation-id, in effect, defines a subscriber.

Expression Use

Expression processing is used in several places:

Calculating a client-class—client-class-lookup-id. This expression determines the client-class based on the contents of the incoming packet.

nrcmd> dhcp set client-class-lookup-id=expression 

Creating the key to look up in the client-entry database—client-lookup-id. This accesses the client-entry database with the key resulting from the expression evaluation.

nrcmd> client name set client-lookup-id=expression 

Creating the ID to use to limit clients of the same subscriber—limitation-id. This is the ID to use to check if any other clients are associated with this subscriber.

nrcmd> client name set limitation-id=expression 

This kind of processing results in this scenario:

1. The DHCP server tries to get a client-class based on a client-class-lookup-id expression. If it cannot calculate the client-class, it uses the usual MAC address method to look up the client.

2. If the server can calculate the client-class, it determines if it needs to do a client-entry lookup, based on evaluating a client-lookup-id expression that returns a client-lookup-id. If it has such an ID, it uses it to look up the client. If it does not have such an ID, it uses the calculated client-class value to assign addresses.

3. If the server uses the client-lookup-id and finds a client-entry, it uses the data for the client. If it cannot find a client-entry, it uses the calculated or default client-class data.

You set the upper limit on assigned addresses to clients on a network or LAN segment having an identical limitation-id value on the policy level. Set this upper limit as a positive integer using the limitation-count attribute for the policy.

nrcmd> policy name set limitation-count=positive-integer 

Using the CLI

The values to set for limiting IP addresses to subscribers are.

nrcmd> policy name set limitation-count=positive-integer 
nrcmd> client-class name set limitation-id=expression 
nrcmd> client-class name set client-lookup-id=expression 
nrcmd> client name set over-limit-client-class-name=client-class-name 
nrcmd> client-class name set over-limit-client-class-name=client-class-name 

The expressions to use are described in the "Creating Expressions" section.

Expression Syntax

You can include simple expressions as such in the attribute definition, or include more complex ones in an expression file and reference the file in the attribute definition. Either way, the maximum allowable characters is 16 K. Simple expressions must adhere to these rules:

They must be limited to a single command line.

The entire expression must be enclosed in double quotes (" ").

Embedded double quotes must be escaped with a backslash (\).

Parentheses must be preceded and followed by a space character.

Here is an example of a simple expression to set the client-class-lookup-id:

nrcmd> dhcp set client-class-lookup-id="\"limit\"" 

Here is a slightly more extensive example to set the client-class limitation-id:

nrcmd> client-class cc1 set limitation-id=" ( request option 82 \"circuit-id\" ) " 

Any more complex expressions that cannot be limited to one line or that you want to format for comprehension must be entered in a file and referenced in the attribute definition prefixed by the at symbol (@):

nrcmd> dhcp set client-class-lookup-id=@cclookup.txt 

The syntax of the expression in the file does not have the extra requirements (as to spacing and escaping of characters) of the simple expression. It can also include comment lines, prefixed by the pound sign (#), double-slash (//), or a semicolon (;), and terminated at the end of line. For example:

cclookup.txt file:
// Expression to calculate client-class based on remote-id 
(try (if (equal (request option "relay-agent-info" "remote-id") (request chaddr)) 
"cm-client-class" 
"cpe-client-class") 
"<none>") 

Creating Expressions

Using DHCP expressions, you can retrieve, process, and make decisions based on data in incoming DHCP packets. You can use them for determining the client-class of an incoming packet, and create the equivalence key for option 82 limitation support. They provide a way to get information out of a packet and individual options, a variety of conditional functions to allow decisions based on information in the packet, and data synthesis capabilities where you can create a client-class name or key.

The expression to include in an expression file that would describe the example in the "Typical Limitation Scenario" section would be:

// This begins the try function 
(try 
(or (if (equal (request option "relay-agent-info" "remote-id") (request chaddr)) 
"cm-client-class") 
(if (equal (substring (option "vendor-class-id") 1 6 ) "docsis") 
	"docsis-cm-client-class") 
(if (equal (request option "user-class") "alternative-class") 
	"alternative-cm-client-class") 
) 
<none> 
) 
// This ends the try function 

This uses the or function and evaluates three if functions. In a simpler form, you can calculate a client-class and include this expression in a file.

cclookup.txt file:
// Expression to calculate client-class based on remote-id 
(try (if (equal (request option "relay-agent-info" "remote-id") (request chaddr)) 
"cm-client-class" 
"cpe-client-class") 
"<none>") 

Refer to this file to use the expression to set the client-class lookup ID for the server.

nrcmd> dhcp set client-class-lookup-id=@cclookup.txt 

You can generate a limitation key by trying to get the remote-id suboption from option 82, and if unable, to use a standard MAC blob key. Include an expression in a file and set the limitation ID to it.

cclimit.txt file:
// Expression to use remote-id or standard MAC 
(try (request option "relay-agent-info" "remote-id") 00:d0:ba:d3:bd:3b) 

nrcmd> client-class name limitation-id=@cclimit.txt 

Expression Syntax

Expressions consist solely of functions and literals. Its syntax is similar to Lisp's. It follows many of the same rules and uses Lisp functions names where possible. The basic syntax is:

(function argument-0 ... argument-n) 

A more useful example is:

(try (if (equal (request option "relay-agent-info" "remote-id") (request chaddr)) 
"cm-client-class" 
"cpe-client-class") 
"<none>") 

This example compares the remote-id suboption of the relay-agent-info option (option 82) with the MAC address in the packet, and if they are the same, returns "cm-client-class," and if they are different, returns "cpe-client-class." (If the expression cannot evaluate the data, the try function returns a "<none>" value—see the "Expressions Can Fail" section.) The intent is to determine if the device is a cable modem (where, presumably, the remote-id equals the MAC address) and, if so, put it into a separate client-class than a customer's premises equipment, or PC. Note that both functions and literals are expressions. The previous example shows a function as an expression. For literals, see the "Literals in Expressions" section.

Datatypes and Expressions

The datatypes that expressions support are:

Blob—Counted series of bytes, with a minimum supported length of 1K bytes.

String—Counted series of NVT ASCII characters, not terminated by a zero byte, with a minimum supported length of 1K bytes.

Signed integer—32-bit signed integer.

Unsigned integer—32-bit unsigned integer.

Note that there is no IP address datatype—an IP address is a 4-byte blob. See also the "Datatype Conversions" section.

Literals in Expressions

A variety of literals are included in the expression capability:

Signed integers—Normal numbers that must fit in 32 bits.

Unsigned integers—Normal unsigned numbers that must fit in 32 bits.

Blobs—Hex bytes separated by colons. For example, 01:02:03:04:05:06 is a 6-byte blob with the bytes 1 through 6 in it. This is distinct from "01:02:03:04:05:06" (a 17-byte string). The string is related to the blob by being the text representation of the blob. For example, the expression (to-blob "01:02:03") returns the blob 01:02:03. Note that you cannot create a literal representation of a one-byte blob, as 01 will turn into an integer. To get a one-byte blob containing a 1, you would use the expression (substring (to-blob 1) 3 1).

String—Characters enclosed in double quotes. For example, "example.com" is a string, as is "01:02:03:04:05:06." To place a quote in a literal string, escape it with a backslash (\), for example,
"this has one \"quote".

Integer literals (signed and unsigned) are assumed to be in base10. If they start with a 0, they are considered octal; if they start with 0x, they are considered hexadecimal.

Some examples of literals:

"hello world" is a string literal (and a perfectly valid expression).

1 is an unsigned integer literal (also a perfectly valid expression). It contains 4 bytes, the first three of which are zero, and the last of which contains a 1 in the least significant bit.

01:02:03 is a blob literal containing three bytes, 01, 02, and 03.

-10 is a signed integer literal containing four bytes with the twos-complement representation of decimal -10.

Expressions Return Typed Values

With few exceptions, the point of an expression is to return a value. The expression configured to determine a client-class is configured in the DHCP server property client-class-lookup-id. When this expression is evaluated, the DHCP server expects it to return a string containing the name of a client-class, or the string "<none>."

Every function in an expression returns a value. The datatype of the value may depend on the datatype of the argument or arguments. Some expressions only accept arguments of a certain datatype, such as
(+ argument0 argument1).

In most cases, a function that requires a certain datatype for a particular argument tries to convert the argument that it gets to the proper datatype. For example, (+ "1" 2) returns 3, because it successfully converts the string literal "1" into a numeric 1. However, (+ "one" 2) causes an error, because "one" does not convert successfully into a number. In general, the expression evaluator tries to do the right thing as much as possible when making datatype conversion decisions.

Expressions Can Fail

While some of the functions that make up an expression operate correctly on any datatype or value, many do not. In the previous section, the + function would not convert the string literal "one" into a valid number, so the evaluation of that function failed. When a function fails to evaluate, its calling function also fails, and so on, until the entire expression fails. A failed expression evaluation has different consequences depending on the expression involved. In some cases, it can cause the packet to be dropped, while in others it only generates a warning message.

You can prevent the expression evaluation from failing by using the (try expression failure-expression) function. The try function evaluates the expression and, if successful, the value of the function is the value of the expression. If the evaluation fails (for whatever reason), the value of the function is the value of the failure-expression. The only situation where a try function itself fails is if the failure-expression evaluation fails. Thus, you want to be very careful what expression you define as a failure-expression. A string literal is a safe bet.

Thus, protecting the evaluation of the client-class-lookup-id with a try function is a very good idea. The previously cited example shows how this can work:

(try (if		(equal (request option "relay-agent-info" "remote-id") (request chaddr)) 
"cm-client-class" 
"cpe-client-class") 
"<none>") 

If evaluating the if function fails in this case, the value of the client-class-lookup-id expression is <none>. It could have been a client-class name instead, of course.

Expressions Functions

Table 10-2 lists the expression functions. Expressions must be enclosed in parentheses.

Table 10-2 Expression Functions 

Function
Example
Description

(and arg1 ... argn)

(and "hello" "world") returns "world" 
(and (request option 82 1) (request option 82 2)) returns 
option-82 sub-option 2 if both option-82 sub-option 1 and 
sub-option 2 are present in the request

The and function returns a value that is the datatype of argn or null. It evaluates its arguments in order from left to right (the arguments can evaluate to a datatype). If any argument evaluates to null, it stops evaluating the arguments and returns null. Otherwise, it returns the value of the last argument, argn.

(as-blob expr)

(as-blob "hello world") returns the blob 
68:65:6c:6c:6f:20:77:6f:72:6c:64 

The as-blob function treats expr as if it were a blob. If expr evaluates to a string, the bytes that make up the string become the bytes of the blob that is returned. If expr evaluates to a blob, that blob is returned unmodified. If expr evaluates to either kind of integer, a 4-byte blob containing the bytes of the integer is returned. (See Table 10-3.)

(as-sint expr)

(as-sint ff:ff:ff:ff) returns -1 
(as-sint 2147483648) returns an error 

The as-sint function treats expr as if it were a signed integer. If expr evaluates to a string or blob of 4 bytes or less, the function returns a signed integer constructed out of those bytes (if longer than 4 bytes, it returns an error). If expr evaluates to a signed integer, it returns the value unchanged; if an unsigned integer, it returns a signed integer with the same bit value. (See Table 10-3.)

(as-string expr)

(as-string 97) returns "a" 
(as-string 68:65:6c:6c:6f:20:77:6f:72:6c:64) returns "hello 
world" 
(as-string 0) returns an error.

The as-string function treats expr as if it were a string. If expr evaluates to a string, it returns that string. If expr evaluates to a blob, it returns a string constructed from the bytes in the blob, unless they are nonprintable ASCII values, which returns an error. If expr evaluates to an integer, it considers its value to be the ASCII value for a single character and returns a string consisting of that one character, unless it is nonprintable, which returns an error. (See Table 10-3.)

(as-uint expr)

(as-uint -2147483648) returns the unsigned integer 2147483648 
(as-uint -1) returns the unsigned integer 4294967295 
(as-uint ff:ff:ff:ff) returns the unsigned integer 4294967295 

The as-uint function treats expr as if it were an integer. If expr evaluates to a string or blob of 4 bytes or less, it returns an unsigned integer constructed from those bytes; if longer than 4 bytes, it returns an error. If the result is an unsigned integer, it returns the argument unchanged; if a signed integer, it returns an unsigned integer with the same bit value (see Table 10-3).

(ash expr shift)

(ash 00:01:00 1) returns the blob 00:02:00 
(ash 00:01:00 -1) returns the blob 00:00:80 
(ash 1) returns the unsigned integer 2 

The ash function returns an integer or blob with the bits shifted by the shift amount. The expr can evaluate to an integer, blob or string. If expr evaluates to a string, this function tries to convert it to a signed integer, and if that fails, to a blob. If both fail, it returns an error. The shift must evaluate to something that is convertible to a signed integer. If shift is positive, the shift is to the left; if negative, the shift is to the right. If expr results in a signed integer, the right shift is with sign extension. If expr results in an unsigned integer or blob, a right shift shifts zero bits in on the most significant bits.

(bit-and arg1 arg2)
(bit-or
arg1 arg2)
(bit-xor
arg1 arg2)
(bit-eqv
arg1 arg2)
(bit-andc1
arg1 arg2)
(bit-andc2
arg1 arg2)
(bit-orc1
arg1 arg2)
(bit-orc2
arg1 arg2)

(bit-and 00:20 00:ff) returns 00:20
(bit-or 00:20 00:ff) returns 00:ff
(bit-xor 00:20 00:ff) returns 00:df
(bit-andc1 00:20 00:ff) returns 00:df

These bit functions return the result of a bit-wise boolean operation on the two arguments. The data type of the result is a signed integer if both arguments result in either kind of integer, otherwise the result is a blob. The arg1 and arg2 arguments must evaluate to two integers, two blobs of equal length, or one integer and one blob of length 4. If either argument evaluates to a string, the function tries to convert the string to a signed integer, and if that fails, to a blob. After this conversion, the results must match the criteria mentioned above. If these conditions are not met, it returns an error.

Operations with c1 and c2 indicate that the first and second arguments, respectively, are complemented before the operation.

(bit-not expr)

(bit-not ff:ff) returns 00:00
(bit-not 1) returns 4294967295
(bit-not "hello world") returns an error

The bit-not function returns a value that is the bit-by-bit complement of expr. The datatype of the result is the same as the result of evaluating expr and any subsequent conversions, if the result was a string. The expression must evaluate to an integer of either type, or a blob. If it evaluates to a string, the function tries to convert it to a signed integer; if that fails, to a blob, and if that fails, returns an error.

(comment comment expr1... exprn)

(comment "this is a comment that won't get lost" (request option 
82 1))

This function ignores the comment argument, but evaluates the remaining arguments and returns the value of exprn. Use this function for inserting a comment string into an expression.

(concat arg1 ... argn)

(concat "hello " "world") returns "hello world"
(concat -1 "world") returns an error
(concat -1 00:01:02) returns the blob ff:ff:ff:ff:00:01:02

This function concatenates the values of the arguments into a string or blob. It ignores null arguments. The first nonnull argument must evaluate to a string or a blob. If it evaluates to an integer, the function converts it to a blob. The datatype of this first nonnull argument (after any conversion) determines the datatype of the result. The function converts all subsequent arguments to the datatype of the result, and if this conversion fails, returns an error.

(dotimes (var count-expr [result-expr]) exp1 ... expn)

 
(let (x y) (setq x 01:02:03) (dotimes (i (length x)) (setq y 
(concat (substring x i 1) y)))) returns null, but after the 
dotimes y is the reverse of x 
(dotimes (i 10) (setq i 1)) loops forever!

The dotimes function creates an environment with a single local integer variable, var, which is initially set to zero, and evaluates exp1 through expn. It then increments var by one, and if it is less than count-expr, evaluates exp1 through expn again. When var is equal to or greater than count-expr, the function evaluates result-expr and returns it as the result of the entire dotimes. If there is no result-expr, the function returns null.

The var defines a local variable, and must be an alphabetic name. The count-expr must evaluate to an integer or be convertible to one. The exp1 through expn are expressions that can evaluate to any data type. The result-expr is optional, and if it appears, it can evaluate to any data type. When the function evaluates count-expr, var is not bound and cannot appear in count-expr. Alternatively, var is bound for the evaluation of result-expr and has the value of count-expr. If result-expr is omitted, the function returns null.

Note Be careful changing the value of var in exp1 through expn, because you can easily create an infinite loop (see the example).

(environmentdictionary {get | put val | delete} attr)

nrcmd> dhcp set initial-environment-dictionary=first=one,second=2 
(environmentdictionary get "first") returns "one" 
(environmentdictionary get "second") returns "2" (note string 2) 
(environmentdictionary put "two" "second") returns "second" 
(environmentdictionary delete "first") returns null 

The environmentdictionary function gets, puts, or deletes a DHCP extension environment dictionary attribute value. The val is the value of the attribute. The attr is the attribute name. Both are converted to a string regardless of their initial datatype. Note that the get keyword is not optional for a "get."

(equal expr1 expr2)
(equali
expr1 expr2)

(equal (request option "vendor-class-id") "docsis") returns 
true if the value of the option vendor-class-id is a string like 
"docsis"
(equali "abc" "ABC") returns "ABC"
(equal "abc" "def") returns null
(equal "ab" (as-string 61:62)) returns "ab"
(equal "ab" 61:62) returns null
(equal 01:02:03 01:02:03) returns 01:02:03
(equal (as-blob "ab") 61:62) returns null
(equal 1 (to-blob 1)) returns null
(equal (null) (request option 20)) returns "*T*" if there is no 
option 20 in the packet

The equal function evaluates the equivalency of the result of evaluating the two arguments and returns the value of the second argument, exp2, if they are equal, or null if they are not. If the arguments are equal, it returns the value and datatype resulting from evaluating expr2 (prior to any conversion to string, if necessary). If the arguments are equal, but expr2 is null, it returns the "*A*" string, because returning null would incorrectly indicate a failed comparison.

The two equal function arguments can be any datatype. If the datatypes are different, the function converts both of them to strings (which cannot fail) before comparing them. Note that any string conversion is performed using the equivalent of (to-string ...). Thus, the blob 61:62 is not equal to the "ab" string. Note also that a one-byte blob 01 is not equal to a literal integer 1; both are converted to strings, and "01" does not equal the "1" string.

The equali function is identical, except that if the comparison is for strings (either because string arguments were used or because the arguments were converted to strings), a case insensitive comparison is used.

(error)

The error function returns a "no recovery" error that causes the entire expression evaluation to fail unless there is a try function above the error function evaluation.

(if cond [then else])

(if (equali (substring (request option "vendor-class-id") 0 6) 
"docsis") (request option 82 1)) returns sub-option 1 of option 
82 if the first six characters of the vendor-class-id are 
"docsis" in any case; otherwise returns null

The if function evaluates the condition expression cond in an if-then-else sense. If cond evaluates to a value that is nonnull, it returns the result of evaluating the then argument, else it returns the result of evaluating the else argument. Both then and else are optional arguments. If you omit the then and else arguments, the function simply returns the results of evaluating the cond argument. If you omit the else argument and cond evaluates to null, the function returns null. There are no restrictions on the data types of any of the three arguments.

(ip-string blob)

(ip-string 01:02:03:04) returns "1.2.3.4"
(ip-string -1) returns "255.255.255.255"
(ip-string "hello world") returns "104.101.108.108"

The ip-string function returns the string representation of the four-byte IP address blob in the form "a.b.c.d". The single argument blob must evaluate to a blob or be convertible into one. If the blob exceeds four bytes, the function uses only the first four to create the IP address string. If the blob has fewer bytes, the function considers the right-most bytes as zero when it creates the IP address string.

(is-string expr)

(is-string 01:02:03:04) returns null
(is-string "hello world") returns "hello world"
(is-string 68:65:6c:6c:6f:20:77:6f:72:6c:64) returns the blob

The is-string function returns the value of expr, if the result of evaluating expr is a string or can be used as a string, this function, otherwise it returns null. That is, if as-string does not return an error, then is-string returns the value of expr.

(length expr)

(length 1) returns 4
(length 01:02:03) returns 3
(length "hello world") returns 11

The length function returns an integer whose value is the length in bytes of the value of expr. The argument expr can evaluate to any datatype. Integers always have length 4. The length of a string does not include any zero byte that may terminate the string.

(let (var1 ... varn) expr1 ... expn)

(let (x) (setq x (substring (request option "vendor-class-id") 0 6)) 
(if (equali x "docsis") "client-class-1") 
(if (equali x "something else") "client-class-2")) 

The let function creates an environment with local variables var1 through varn, which are initialized to a null value (you can give them other values by using the setq function). Once the local variables are initialized to null, the function evaluates expressions expr1 through exprn in order. It then returns the value of its last expression, exprn. The benefit of this function is that you can use it to calculate a value once, assign it to a local variable, then re-use that value in other expressions without having to recalculate it. Variables are case sensitive.

(log severity expr)

The log function logs the result of converting expr to a string. The severity and expr must be a string and are converted to one if they do not evaluate to one. The severity can also be null; if a string, it must have one of these values:

"debug"
"activity" (the default if severity is null)
"info"
"warning"
"error"

Note Logging consumes considerable server resources, so limit the number of log function evaluations you put in an expression. Even if "error" severity is logged, the log function does not return an error. This only tags the log message with an error indication. See the error function to return an error as part of a function evaluation.

(mask-blob mask-size length)

(mask-blob 1 4) yields 80:00:00:00
(mask-blob 4 2) yields f0:00

(mask-blob 31 4) yields ff:ff:ff:fe

The mask-blob function returns a blob that contains the mask of length mask-size starting from the high-order bit of the blob, with a blob length of length. The mask-size is an expression that evaluates to an integer or must be convertible to one. Likewise the length, which cannot be smaller than the mask-size, but has no fixed limit except that it must be zero or positive. If mask-size is less than zero, it denotes a mask length calculated from the right end of the blob.

(mask-int mask-size)

(mask-int 1) yields 0x80000000
(mask-int 4) yields 0xf0000000
(mask-int 31) yields 0xfffffffe
(mask-int -1) yields 0x00000001

The mask-int function returns an integer mask of length mask-size bits starting from the high-order bit of the integer. The mask-size is an expression that evaluates to an integer or must be convertible to one. Any number over 32 is meaningless and is treated as though a value of 32 was used. If mask-size is less than zero, it denotes a mask length calculated from the right end of the integer.

(not expr)

(not "hello world") return null

The not function evaluates a string, blob, or integer expression to nonnull if it is null, and null if it is nonnull. The nonnull value returned when the value of expr is null is not guaranteed to remain the same over two calls.

(null [expr1 ... exprn])

 

The null function returns null and does not evaluate any of its arguments.

(or arg1 ... argn)
(pick-first-value arg1 ... argn)


(or (request option 82 1) (request option 82 2) 01:02:03:04) 
returns the value of sub-option 1 in option 82, and if that does 
not exist, returns the value of option 82 sub-option 2, and if 
that does not exist, returns null

The or or pick-first-value function evaluates the arguments sequentially. When the evaluation of an arg returns a nonnull value, it returns the value of that first nonnull argument. Otherwise, it returns the value of the last argument, argn. The datatypes need not be the same.

(progn arg ... argn)

(progn (log (null) "I was here") (request option 82 1)) 

The progn function evaluates arguments sequentially and returns the value of the last argument, argn.

(request [get | get-blob] option opt [subopt [subsubopt]] [index number] [count])

 
(request option 82) returns the entire option-82 value as a blob
(request option 82 1) returns just the option-82 circuit-id as a 
blob
(request option 82 "circuit-id") returns the option-82 circuit-id 
as a blob
(request option "domain-name-servers" count) returns the number 
of IP addresses in the domain-name-servers option
(request option "domain-name-servers" index 0) returns the first 
IP address from the domain-name-servers option
(request option "domain-name-servers") returns the first IP 
address from the domain-name-servers option
(request get-blob option "dhcp-class-identifier") returns the 
vendor class ID as a blob, not as a string as listed in Table F-2

The request option function returns the value of the option from the packet. The get keyword is optional and assumed if omitted. The index keyword is only valid with the option keyword, which accesses the nth value in an option that contains multiple values in the option. Options are specified with the opt argument, which must evaluate to an integer or a string. If it does not evaluate to one of these, the function does not convert it and returns an error. Valid string values for the opt specifier are the same as those used for extensions.

The only string-valued suboption names defined for the subopt suboption specifier are for the relay-agent-info option (option 82) and are:

1—"circuit-id"
2—"remote-id"
4—"device-class"
180—"subnet-selection"
181—"vpn-id"
182—"server-id-override"
150—"cisco-subnet-selection"
151—"cisco-vpn-id"
152—"cisco-server-id-override"

The request option function returns a value with a datatype dependent on the option requested. The option datatypes appear in Table F-2. This shows how the datatypes in the table correspond to the datatypes returned by the request function:

blob —> blob
IP address —> string
string —> string
8-bit unsigned integer —> uint
16-bit unsigned integer —> uint
32-bit unsigned integer —> uint
integer —> sint
byte-valued boolean —> sint=1 if true, null if false

If you want to get direct access to the option bytes, use the get-blob keyword, such as (request get-blob option 82), which returns a blob regardless of the option datatype in Table F-2.

(request [get] packetfield)

(request get ciaddr) returns the ciaddr if it exists, else it 
returns null
(request ciaddr) is the same as (request get ciaddr) 
(request giaddr) 

Valid values for packetfield are:

op (blob 1)

htype (blob 1)

hlen (blob 1)

hops (blob 1)

xid (uint)

secs (uint)

flags (uint)

ciaddr (blob 4)

yiaddr (blob 4)

siaddr (blob 4)

giaddr (blob 4)

chaddr (blob, length hlen)

sname (string)

file (string)

The request packetfield function returns the value of the named field from the request packet. DHCP request packets contain named fields as well as options in an option area. This form of the request function is used to retrieve specific named fields from the request packet.

The packetfield values defined in RFC 2131 are listed at the left. There are several packetfield values that can be requested which do not appear in exactly these ways in the raw DHCP packet. These take data that appears in the packet and combine it in commonly used ways. In these explanations, the packet contents assumed are:

hlen = 1
htype = 6
chaddr = 01:02:03:04:05:06

macaddress-string (string)—Returns the MAC address in hlen,htype,chaddr format (such as "1,6,01:02:03:04:05:06")

macaddress-blob (blob)—Returns the MAC address in hlen:htype:chaddr format (such as 01:06:01:02:03:04:05:06)

macaddress-clientid (blob)—Returns a client-id created from the MAC address in the Microsoft htype:chaddr client-id format (such as 01:01:02:03:04:05:06)

(request dump)

 

The request dump function dumps the current request packet to the log file after the function evaluates the expression. Note that not all expression evaluations support the dump keyword, but when it is not supported, it is ignored.

(setq var expr)

see the let function for examples

The setq function sets var to the value of expr. You must precede it with the let function.

(starts-with expr prefix-expr)

(starts-with "abcdefghijklmnop" "abc") returns "abcdefghijklmnop"
(starts-with "abcdefgji" "bcd") returns null
(starts-with 01:02:03:04:05:06 01:02:03) returns 
01:02:03:04:05:06
(starts-with "abcd" (as-string 61:62)) returns "abcd"
(starts-with "abcd" 61:62) returns null
(starts-with "abcd" (to-string 61:62)) returns null

The starts-with function returns the value of expr if the prefix-expr value matches the beginning of expr, otherwise null. If prefix-expr is longer than expr, it returns null. The function returns an error if prefix-expr cannot be converted to the same datatype as expr (string or blob), or if expr evaluates to an integer. (See Table 10-3.)

(substring expr offset len)

(substring "abcdefg" 1 6) returns bcdefg 
(substring 01:02:03:04:05:06 3 2) returns 04:05

The substring function returns len bytes of expression expr, starting at offset. The expr can be a string or blob; if an integer, converts to a blob. The result is a string or a blob, or null if any argument evaluates to null. If offset is greater than the length len, the result is null. If offset plus len is data beyond the end of expr, the function returns the rest of the data in expr. If offset is less than zero, the offset is from the end of the data (the last character is index -1, because -0=0, which references the first character). If this references data beyond the beginning of data, the offset is considered to be zero.

(to-blob expr)

(to-blob 1) returns 00:00:00:01
(to-blob "01:02") returns 01:02
(to-blob 02:03) returns 02:03
(to-blob "this is not in blob format") return an error

The to-blob function converts an expression to a blob. If expr evaluates to a string it must be in "nn:nn:nn" format. This function returns a blob that is the result of converting the string to a blob. If the function cannot convert the string to a blob, it returns an error. If expr evaluates to a blob, it returns that blob. If expr evaluates to an integer, it returns a four-byte blob representing the bytes of the integer in network order. (See Table 10-3.)

(to-lower expr)


The to-lower function takes a string and produces a lowercase string from it. When using the client-lookup-id attribute to calculate a client-specifier to look up a client-entry in the MCD local store (as opposed to LDAP), the resulting string must be lowercase. Use this function to easily make the result of the client-lookup-id a lowercase string. You may or may not wish to use this function when accessing LDAP using the client-lookup-id.

(to-sint expr)

(to-sint "1") returns 1
(to-sint -1) returns -1
(to-sint 00:02) returns 2
(to-sint "00:02") returns an error
(to-sint "4294967295") returns an error

The to-sint function converts an expression to a signed integer. If expr evaluates to a string, it must be in a format that can be converted into a signed integer, else the function returns an error. If expr evaluates to a blob of one to four bytes, the function returns it as a signed integer. If expr evaluates to a blob of more than 4 bytes in length, it returns an error. If expr evaluates to an unsigned integer, it returns a signed integer with the same value, unless the value of the unsigned integer was greater than the largest positive signed integer, in which case it returns an error. If expr evaluates to a signed integer, it returns that value. (See Table 10-3.)

(to-uint expr)

(to-uint "1") returns 1
(to-uint 00:02) returns 2
(to-uint "4294967295") returns 4294967295
(to-uint "00:02") returns an error
(to-uint -1) returns an error

The to-uint function converts an expression to an unsigned integer. If expr evaluates to a string, it must be in a format that can be converted into an unsigned integer, else the function returns an error. If expr evaluates to a blob of one to four bytes, it returns it as an unsigned integer. If expr evaluates to a blob of more than 4 bytes in length, it returns an error. If expr evaluates to a signed integer, it returns an unsigned integer with the same value, unless the value of the signed integer less than zero, in which case it returns an error. If expr evaluates to an unsigned integer, the function returns that value. (See Table 10-3.)

(to-string expr)

(to-string "hello world") returns "hello world"
(to-string -1) returns "-1"
(to-string 02:04:06) returns "02:04:06"

The to-string function converts an expression to a string. If expr evaluates to a string, it returns it; if a blob or integer, it returns its printable representation. It never returns an error if expr itself evaluates without error, because every value has a printable representation. (See Table 10-3.)

(try expr failure-expr)

(try (try (expr) (complex-failure-expr)) "string-constant") 
ensures that the outer try never returns an error (because 
evaluating "string-constant" cannot fail).
(try (error) 01:02:03) always returns 01:02:03
(try 1 01:02:03) always returns 1
(try (request option 82) "failure") never returns "failure" 
because (request option 82) turns null if there is no option-82 
in the packet and does not return an error
(try (request option "junk") "failure") returns "failure" because 
"junk" is not a valid option-name.

The try function evaluates expr and returns the result of that evaluation if there were no errors encountered during the evaluation. If an error occurs while evaluating expr then:

If there is a failure-expr and it evaluates without error, it returns the result of that evaluation as the result of the try function.

If there is a failure-expr and the function encounters an error while evaluating failure-expr, it returns that error.

If there is no failure-expr, the try returns null.

(+ arg1 ... argn)
(- arg1 ... argn)
(* arg1 ... argn)
(/ arg1 ... argn)

(+ 1 2 3 4) returns 10
(- 10 5 2) returns 3
(* 3 4 5) returns 60
(/ 20 2 5) returns 2
(/ 20 0) returns an error

These functions do arithmetic operations on a signed integer or an expression that can be converted to a signed integer. Any argument that cannot be converted to a signed integer (and is not null) causes an error to be returned. Any arguments that evaluate to null are ignored (except that the first argument for - and / must not evaluate to null). These functions always return signed integers as a result:

+ sums the arguments; if no arguments, the value is 0.

- negates the value of a single argument or, if multiple arguments, successively subtracts the values of the remaining ones from the first one; for example, (- 3 4 5) becomes -6.

* takes the product of the argument values; if no arguments, the result is 1.

/ successively divides the first argument by all of the others; for example, (/ 100 4 5) becomes 5. If any argument other than the first equals 0, an error is returned.

Note Overflow and underflow are currently not caught.


Datatype Conversions

When a function needs an argument of a particular datatype, it tries to convert a value into that datatype. Sometimes this can fail, often causing the entire function to fail. Datatype conversion is also performed by the to-string, to-blob, to-sint, and to-uint functions. Whenever a function needs an argument in a specific datatype, it calls the internal version of these externally available functions.

There are also as-string, as-blob, as-sint, and as-uint conversion functions, where the data in a value are simply relabeled as the desired datatype, although some checking does go on. The conversion matrix for both function sets appears in Table 10-3.

Table 10-3 Datatype Conversion Functions 

Argument Type:
Function:
String
Blob
Signed Integer
Unsigned Integer

to-string

Cannot fail

Cannot fail

Cannot fail

as-string

Relabels as string bytes, if printable characters

Converts to a 4-byte blob, then processes it as a blob (which fails except for a few special integers)

Converts to a 4-byte blob, then processes as a blob (which fails except for a few special integers)

to-blob

Must be in the form "01:02:03"

Cannot fail; produces a 4-byte blob from the 4 bytes of the integer.

Cannot fail; produces a 4-byte blob from the 4 bytes of the integer.

as-blob

Cannot fail; relabels ASCII characters as blob bytes.

Cannot fail;
produces 4-byte blob from the 4 bytes of the integer.

Cannot fail;
produces 4-byte blob from the 4 bytes of the integer.

to-sint

Must be in the form n or -n.

1-, 2-, 3-, or 4-byte blobs only.

Converts only if it is not too big to fit into a signed integer.

as-sint

Not usually useful; converts a 1-, 2-, 3-, or 4-byte string to a blob and then packs it up into a signed integer.

Not usually useful; converts only 1-, 2-, 3-, or 4-byte blobs.

Cannot fail; converts to a signed integer, negative if a larger unsigned integer would fit into a positive signed integer.

to-uint

Must be in the form n.

1-, 2-, 3-, or 4-byte blobs only.

Nonnegative only.

as-uint

Not usually useful; converts a 1-, 2-, 3-, or 4-byte string to a blob and then a signed integer.

Not usually useful; converts only 1-, 2-, 3-, or 4-byte blobs.

Cannot fail; converts to an unsigned integer, and a negative signed integer becomes a large unsigned integer.


Expressions in the CLI

You must include the expression in a text file if you want to include it with a CLI attribute setting. The default path of this file is the current working directory. Do not enclose the expression in quotes. You can add comment lines prefixed by #, //, or ;.

expressionfile1.txt:
// Expression to set client-class based on remote-id 
(if (equal			(request option "relay-agent-info" "remote-id") (request chaddr)) 
	"no-limit" "limit") 

The file is read when the command is processed. An example of a command to include this file is:

nrcmd> dhcp set client-class-lookup-id=@expressionfile1.txt 

Expression Examples

These examples provide the maximum support for option 82 processing. They set up clients to limit, those not to limit, and those that exceed configuration limits and should be assigned to an over-limit client-class. There are separate scopes and scope selection tags for each of the three classes of clients:

Client-classes—limit, no-limit, and over-limit.

Scopes—10.0.1.0 (primary), 10.0.2.0 and 10.0.3.0 (secondaries), named for their subnets.

Scope selection tags—limit-tag, no-limit-tag, and over-limit-tag. The scopes are named for the address pools that they represent. The selection tags are allocated to the scopes with 10.0.1.0 getting limit-tag, 10.0.2.0 getting no-limit-tag, and 10.0.3.0 getting over-limit-tag.

Limitation Example 1: DOCSIS Cable Modem

The test is to determine whether the device is considered a DOCSIS cable modem, and limit the number of customer devices behind every cable modem. The limitation ID for the limit client-class is the cable modem's MAC address, included in the remote-id suboption of the relay-agent-info option.

The expression for the client-class-lookup-id attribute on the server is:

// Expression to set client-class to no-limit or limit based on remote-id 
(if (equal			(request option "relay-agent-info" "remote-id") 
(request chaddr)) 
"no-limit" 
"limit") 

The above expression indicates that if the contents of the remote-id suboption (2) of the relay-agent-info option is the same as the chaddr of the packet, then the client-class is no-limit, otherwise limit.

The limitation-id expression for the limit client-class is:

(request option "relay-agent-info" "remote-id") 

This expression should return a blob containing the bytes of the cable modem's MAC address.

Use these steps in the CLI.


Step 1 Define the scope selection tags. (You do not need to do this in Network Registrar 6.0.)

nrcmd> scope-selection-tag limit-tag create 
limit-tag
100 Ok
nrcmd> scope-selection-tag no-limit-tag create 
no-limit-tag
100 Ok
nrcmd> scope-selection-tag over-limit-tag create 
over-limit-tag
100 Ok

Step 2 Define the client-classes.

nrcmd> client-class limit create 
100 Ok
limit:
...
nrcmd> client-class limit set selection-criteria=limit-tag 
100 Ok
selection-criteria=limit-tag
nrcmd> client-class limit set over-limit-client-class-name=over-limit 
100 Ok
over-limit-client-class-name=over-limit
nrcmd> client-class no-limit create 
100 Ok
no-limit:
...
nrcmd> client-class no-limit set selection-criteria=no-limit-tag 
100 Ok
selection-criteria=no-limit-tag
nrcmd> client-class over-limit create 
100 Ok
over-limit:
...
nrcmd> client-class over-limit set selection-criteria=over-limit-tag 
100 Ok
selection-criteria=over-limit-tag

Step 3 Define the scopes, their ranges and tags, and if they are primary or secondary. Note the host range for each scope, which is less likely to be misread than if they all have the same host number.

nrcmd> scope 10.0.1.0 create 10.0.1.0 255.255.255.0 
100 Ok
10.0.1.0:
...
nrcmd> scope 10.0.1.0 addRange 10.0.1.1 10.0.1.50 
100 Ok
10.0.1.1 10.0.1.50
nrcmd> scope 10.0.1.0 set selection-tags=limit-tag 
100 Ok
selection-tags=limit-tag
nrcmd> scope 10.0.2.0 create 10.0.2.0 255.255.255.0 
100 Ok
10.0.2.0:
...
nrcmd> scope 10.0.2.0 addRange 10.0.2.60 10.0.2.100 
100 Ok
10.0.2.60 10.0.2.100
nrcmd> scope 10.0.2.0 set selection-tags=no-limit-tag 
100 Ok
selection-tags=no-limit-tag
nrcmd> scope 10.0.2.0 set primary-scope=10.0.1.0 
100 Ok
primary-scope=10.0.1.0
nrcmd> scope 10.0.3.0 create 10.0.3.0 255.255.255.0 
100 Ok
10.0.3.0:
...
nrcmd> scope 10.0.3.0 addRange 10.0.3.110 10.0.3.160 
100 Ok
10.0.3.110 10.0.3.160
nrcmd> scope 10.0.3.0 set selection-tags=over-limit-tag 
100 Ok
selection-tags=over-limit-tag
nrcmd> scope 10.0.3.0 set primary-scope=10.0.1.0 
100 Ok
primary-scope=10.0.1.0

Step 4 Define the limitation count. It can go in the default policy; if the request does not show a limitation ID, the count is not checked.

nrcmd> policy default set limitation-count=2 
100 Ok
limitation-count=2

Step 5 Add an expression in an expression file, cclookup1.txt, for the purpose.

cclookup1.txt file:
// Expression to set limitation count based on remote-id 
(if (equal			(request option "relay-agent-info" "remote-id") 
	(request chaddr)) "no-limit" "limit") 

Step 6 Refer to the expression file when setting the client-class lookup identifier (ID) on the server level.

nrcmd> dhcp set client-class-lookup-id=@cclookup1.txt 
100 Ok
client-class-lookup-id="(if (equal (option \"relay-agent-info\" \"remote-id\") 
(packet \"chaddr\")) \"no-limit\" \"limit\")"

Step 7 Add another expression for the limitation ID for the client in a cclimit1.txt file.

cclimit1.txt file:
// Expression to set limitation ID based on remote-id 
(request option relay-agent-info "remote-id") 

Step 8 Refer to this expression file when setting the client-class limitation ID.

nrcmd> client-class limit set limitation-id=@cclimit1.txt 
100 Ok
limitation-id="(option \"relay-agent-info\" \"remote-id\")"

Step 9 Reload the server.

nrcmd> dhcp reload 
100 Ok


The result of doing this for a previously unused configuration would be to put the first two DHCP clients with a common remote-id option 82 suboption value in the limit client-class. The third client with the same value would go in the over-limit client-class. There are no limits to the number of devices a subscriber can have in the no-limit client-class, because it has no configured limitation ID. Any device with a MAC address equal to the value of the remote-id suboption is ignored for the purposes of limitation, and goes in the no-limit client class, for which there is no limitation ID configured.

Limitation Example 2: Extended DOCSIS Cable Modem

This example is an extension to the example described in the "Limitation Example 1: DOCSIS Cable Modem" section. In the latter example, all of the cable modems allowed only two client devices beyond them, since a limitation count of two was defined for the default policy. In this example, specific cable-modems are configured to allow a different number of devices to be granted IP addresses from the scopes that use the limit-tag scope selection tag.

In this case, you need to explicitly configure any cable modem with more than two addresses behind it in the client-class database. This requires enabling client-class processing server-wide, so that you can look up the client entry for a cable modem in the Network Registrar or LDAP database. Not finding the cable modem limits the number of devices to two; finding it uses the limitation count from the policy configured for the cable modem.

This example requires just one additional policy, five, which allows five devices. Here are the steps:


Step 1 Enable client-class processing server-wide.

nrcmd> dhcp enable client-class 
100 Ok
client-class=enabled

Step 2 Create the five policy with a limitation count of five devices.

nrcmd> policy five create limitation-count=5 
100 Ok
limitation-count=5
five:
...

Step 3 As in the previous example, use an expression to set a limitation ID for the limit client-class. Put the limitation ID in a cclimit2.txt file, and the lookup ID in a cclookup2.txt file.

cclimit2.txt file:
// Expression to set limitation ID 
(request option relay-agent-info "remote-id") 

cclookup2.txt file:
// Expression to set client-class lookup ID 
(concat "1,6," (to-string (request option relay-agent-info "remote-id"))) 

Step 4 Refer to these files when setting the appropriate attributes.

nrcmd> client-class limit set limitation-id=@cclimit2.txt 
100 Ok
limitation-id="(option \"relay-agent-info\" \"remote-id\")"
nrcmd> client-class limit set client-lookup-id=@cclookup2.txt 
100 Ok
client-lookup-id="(concat \"1,6,\" 
(to-string (option \"relay-agent-info\" \"remote-id\")))"

Step 5 Define some cable modem clients and apply the five policy to them.

nrcmd> client 1,6,00:d0:ba:d3:bd:3b create policy-name=five 
100 Ok
policy-name=five
1,6,00:d0:ba:d3:bd:3b:
...
nrcmd> client 1,6,00:d0:ba:d3:bd:3c create policy-name=five 
100 Ok
...

Step 6 Reload the server.

nrcmd> dhcp reload 
100 Ok


Limitation Example 3: Digital Subscriber Line Over Asynchronous Transfer Mode

This example shows how to use expressions to configure Digital Subscriber Line (DSL) access for a subscriber to a service provider using asynchronous transfer mode (ATM) routed bridge encapsulation (RBE). Service providers are increasingly using ATM RBE to configure a DSL subscriber. The DHCP Option 82 support for routed bridge encapsulation feature as of Cisco IOS Release 12.2(2)T enables those service providers to use DHCP to assign IP addresses and option 82 to implement security and IP address assignment policies.

In this scenario, DSL subscribers are identified as individual ATM subinterfaces on a Cisco 7401ASR router. Each customer has their own subinterface in the router and each subinterface has its own virtual channel identifier (VCI) and virtual path identifier (VPI) to identify the next destination of an ATM cell as it passes through ATM switches. The 7401ASR router routes up to a Cisco 7206 gateway router.

Here are the steps to provision subscribers in this scenario:


Step 1 Set up the DHCP server and interfaces for the router using IOS. This is a typical IOS configuration.

Router#ip dhcp-server 170.16.1.2 
Router#interface Loopback0 
Loopback0(config)#ip address 11.1.1.129 255.255.255.192 
Loopback0(config)#exit 
Router#interface ATM4/0 
ATM4/0(config)#no ip address 
ATM4/0(config)#exit 
Router#interface ATM4/0.1 point-to-point 
ATM4/0.1(config)#ip unnumbered Loopback0 
ATM4/0.1(config)#ip helper-address 170.16.1.2 
ATM4/0.1(config)#atm route-bridged ip 
ATM4/0.1(config)#pvc 88/800 
ATM4/0.1(config)#encapsulation aal5snap 
ATM4/0.1(config)#exit 
Router#interface Ethernet5/1 
Ethernet5/1(config)#ip address 170.16.1.1 255.255.0.0 
Ethernet5/1(config)#exit 
Router#router eigrp 100 
eigrp(config)#network 11.0.0.0 
eigrp(config)#network 170.16.0.0 
eigrp(config)#exit 

Step 2 In IOS, enable the system to insert the DHCP option 82 data in forwarded BOOTREQUEST messages to a Cisco IOS DHCP server.

Router#ip dhcp relay information option 

Step 3 In IOS, specify the IP address of the loopback interface on the DHCP relay agent that is sent to the DHCP server using the option 82 remote-id suboption (2).

Router#rbe nasip Loopback0 

Step 4 Enable client-class processing server-wide.

nrcmd> dhcp enable client-class 
100 Ok
client-class=enabled

Step 5 Create the one policy with a limitation count of one device.

nrcmd> policy one create limitation-count=1 
100 Ok

Step 6 Put the packets in the right client-class. All the packets should be in the limit client-class. Create a lookup file containing just the value limit, then set the client-class lookup ID.

cclookup3.txt file:
// Sets client-class to limit 
limit 

nrcmd> dhcp set client-class-lookup-id=@cclookup3.txt 
100 Ok
client-class-lookup-id=limit

Step 7 Use an expression to ensure that those packets that are limited have the right limitation ID. Put the expression in a file and refer to that file to set the limitation ID. The substring function sets the offset in option 82 suboption 2 (remote-id) data field of nine bytes to include the three bytes of the VPI/VCI.

cclimit3.txt file:
// Sets limitation ID 
(substring (request option 82 2) 9 3) 

nrcmd> client-class limit set limitation-id=@cclimit3.txt 
100 Ok
limitation-id="(substring (option 82 2) 9 3)"

Step 8 Reload the server.

nrcmd> dhcp reload 
100 Ok


Debugging Expressions

If you are having trouble with expressions, examine the DHCP log file at server startup. The expression is printed in such a way as to clarify the nesting of functions, and can help in confirming your intentions. Pay special attention to the equal function and any datatype conversions of arguments. If the arguments are not the same datatype, they are converted to strings using code similar to the to-string function.

You can set various debug levels for expressions by using the expression-trace-level attribute for the DHCP server. All executed expressions are traced to the degree set by the attribute. The highest trace level is 10. If you set the level to at least 2, any nonworking expression is retried again at level 10.

nrcmd> dhcp set expression-trace-level=6 
100 Ok
expression-trace-level=6

The trace levels for expression-trace-level are (use the number or string value; gaps in the numbering are to accommodate future level additions):

0—[no tracing]

1—exp_trace_failures

2—exp_trace_failure_retry

3—exp_trace_calls_returns

5—exp_trace_args

6—exp_trace_print_args

8—exp_trace_conversions

10—exp_trace_all

The trace levels for expression-configuration-trace-level are (number or string; gaps in the numbering are to accommodate future level additions):

0—[no tracing]

2—exp_config_trace_failure_retry

4—exp_config_trace_defns

5—exp_config_trace_defn_args

7—exp_config_trace_find

8—exp_config_trace_literal

10—exp_config_trace_all

To trace expressions you have trouble configuring, there is also an expression-configuration-trace-level attribute that you can set to any level from 1 through 10. If you set the level to at least a 2, any expression that does not configure is retried again with the level set to 6. Gaps in the numbering are to accommodate future level additions.

nrcmd> dhcp set expression-configuration-trace-level=6 
100 Ok
expression-configuration-trace-level=6

Troubleshooting Client-Class

To troubleshoot client-class, enable this logging using the log-settings attribute on the Edit DHCP Server page of the Web UI, or the dhcp set log-settings= command in the CLI, then reload the DHCP server:

client-detail—Logs a single line at the end of every client-class client lookup operation. This line shows all the data found for the client as well as the data that was found in the client's client-class.

client-criteria-processing—Logs a message whenever the server examines a scope to find an available lease or to determine if a lease is still acceptable for a client that already has one.

ldap-query-detail—Logs messages whenever the DHCP server initiates a lease state entry creation to an LDAP server, receives a response from an LDAP server, or retrieves a result or error message from an LDAP server.

If the problem could be related to your LDAP server, also enable the LDAP can-query setting.

These logs will help answer these questions:

Is the server reading the client entry from the expected database?

The server can read the client entry from LDAP or MCD (the Network Registrar internal database). The client-detail log shows you from where the server is reading the client entry.

Is client-class enabled?

If client-class is enabled, but you are getting unexpected results, verify the database that your Network Registrar server is reading. Is it reading from LDAP or MCD? The ldap-query-detail log tells you if it is reading from LDAP. If not, enable the DHCP use-ldap-client-data property.


Note Using LDAP requires configuring the LDAP server for queries. Set the LDAP can-query attribute to true. You also must configure the DHCP server to use LDAP for queries.


Is the server providing clients the right data, but you are seeing the wrong results from that data—for example, clients are not receiving the expected IP addresses?

Verify the explicit relationships on your network. The client-criteria-processing log shows from what scopes the server is getting addresses. If it is not getting them from the expected scopes, explicit relationships might be incorrectly defined. A scope that you thought was a secondary scope might not be defined that way.

Did you set the include and exclude for scope selection tags properly?

If you define a series of scope selection tags to include, a scope's tags must match those of the client. If you define a series to exclude, a scope must have none of these tags defined so that the client can get configuration parameters from it. Avoid complex inclusion and exclusion scenarios as you begin working with selection tags.