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

Configuring Clients and Client-Classes

Table Of Contents

Configuring Clients and Client-Classes

Client-Class Process

Setting Up Client-Classes on Servers

Enabling Client-Class Processing

Defining Scope-Selection Tags

Defining Client-Classes and Their Properties

Defining Host Name Properties

Associating Policies

Setting Other Properties

Setting Client-Class Scope Selection Criteria

Associating Selection Tags with Scopes

Configuring Embedded Policies for Client-Classes

Setting Client Properties

Adding and Editing Clients

Configuring Embedded Policies for Clients

Setting Windows 2000 Client Properties

Settings in Windows 2000 Clients

Settings in DHCP Servers

Providing Provisional Addresses to Unknown Clients

Allocating Provisional Addresses Using One-Shot Action

Moving Clients to Other Subnets

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

Expression Datatypes

Literals in Expressions

Expressions Return Typed Values

Expressions Can Fail

Expression 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-Classes

Configuring LDAP

About LDAP Directory Servers

Configuring DHCP Client Queries in LDAP

Configuring DHCP-Server-to-LDAP Client Queries

Unprovisioning Client Entries

Configuring Embedded Policies in LDAP

Configuring DHCP LDAP Update and Create Services

Lease State Attributes

Configuring LDAP for Lease State Updates

Using LDAP Updates

Configuring LDAP State Updates

Configuring LDAP Entry Creation

Troubleshooting LDAP

LDAP Connection Optimization

Typical LDAP Attributes and Recommended Values


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.

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-Classes on Servers

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.

In the local cluster 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.


In the CLI, use the dhcp enable client-class command to enable client-class processing.

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 You might notice performance degradations with a large number of selection tags defined.


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.

In the local cluster Web UI and CLI, 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.

Defining Client-Classes and Their Properties

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

In the local cluster Web UI:


Step 1 On the Primary Navigation bar, click DHCP.

Step 2 Click Client-Classes on the Secondary Navigation bar.

Step 3 On the List DHCP Client-Classes page (see Figure 13-1), click Add Client-Class.

Figure 13-1 List DHCP Client-Classes Page

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.


In the CLI:

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

To set the properties of the clients in the client-class, use the client-class name set command.

Defining Host Name Properties

You can specify the host name that each client should adopt, using the host-name attribute of the client-class. This can be an absolute, valid DNS value to override that included in the DHCP client request, or can be any of these:

@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.

@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.

Associating Policies

You can set the appropriate policy to associate with, and the action to perform for, the client-class, using the policy-name attribute of the client-class. Use the appropriate command for each of these settings.

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.

Setting Other Properties

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.

In the CLI:

To show the properties for a particular client-class, use the client-class name [show] command.

You can also list the properties for all the client-classes created, or list just their names.

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

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

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.


Tip Avoid setting conflicting inclusion and exclusion criteria. Ensure that they are mutually exclusive.


In the local cluster Web UI:


Step 1 Create the client-class.

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.

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

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

Step 4 Click Modify Client-Class:


In 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.

Associating Selection Tags with Scopes

The next step is to associate the appropriate scope-selection tags with the scope, which must be under the server you configured.

In the local cluster Web UI:


Step 1 Create the scope.

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.

Step 4 Click Modify Scope.


In the CLI, use the scope name set selection-tags command to associate existing selection tags with a scope, then reload the server.

Configuring Embedded Policies for Client-Classes

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.

In the local cluster Web UI:


Step 1 Create the client-class.

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.


In the CLI:

To see if there are any embedded property values already set for a client-class, use the client-class-policy command, using the client-class name as the policy name.

You can enable, disable, get, set, and unset client-class attributes. Note that deleting a client-class policy unsets all of its properties.

You can also list, get, set, and unset DHCP options and vendor options.

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

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 Clients

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

In the local cluster Web UI:


Step 1 On the Primary Navigation bar, click DHCP.

Step 2 Click Clients on the Secondary Navigation bar.

Step 3 On the List/Add DHCP Clients page (see Figure 13-2), enter the MAC address of the client.

Figure 13-2 List/Add DHCP Clients Page

Step 4 Click a client-class name, if desired, from the drop-down list of predefined client-classes.

Step 5 Click Add Client. If you did not select a client-class, this opens the Add DHCP Client page (see Figure 13-3).

Figure 13-3 Add DHCP Client Page


Note If you selected a client-class for the client, this page does not appear, and the client name is listed on the List/Add Client page.


Step 6 On the Add Client page, add any attributes for the client, including scope selection criteria.

Step 7 Click Add Client at the bottom of the page.


In the CLI:

To create a client, use the client name create command, specifying 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 a client always use its MAC address for its host name.

To set the client properties, use the client name set command. These properties need not be set in any particular order, but these steps give some suggestions and provide a basic process:

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.

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

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.

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.

You can also unset any of the optional client options.

To display properties of a specific client, use the client name [show] command.

To display properties for all the clients, use the client list command, or the client listnames command to list just the names.

To delete a client, use the client name delete command.

Configuring Embedded Policies for Clients

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.

In the local cluster Web UI:


Step 1 Create the client.

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.


In the CLI, use the client-policy command, using the client MAC address (or default) as the client policy name.

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 Windows 2000 Clients

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 DHCP Servers

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

Use DHCP server attributes in the local cluster 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 Windows 2000 Clients" section, the selection tag in this example would become tagPCengineering.

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.


Step 1 Create an unknown policy.

Step 2 Use the Grace period field on the Edit DHCP Policy page of the local cluster Web UI or the policy unknown create grace-period=extended-time setting in the CLI.

Step 3 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 local cluster 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.


Allocating Provisional Addresses Using 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) by setting the action attribute to 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 Clients to Other Subnets

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 local cluster 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.

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 an authenticated and an unauthenticated client-class. Set the selection criteria for each as appropriate.

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

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

Step 4 Enable client-class processing for the server.

Step 5 Reload the server.


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 local cluster Web UI, or the dhcp set client-cache-count command in the CLI. By default, the maximum number to cache is 1000 clients.

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 local cluster Web UI, or the dhcp set client-cache-ttl command in the CLI.

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 identifier (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 attribute. 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.



Step 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.

Step 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.

Step 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.

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

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

Step 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.

Step 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 

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 

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 set client-class-lookup-id=expression 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).

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.

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.

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.

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.

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

For a policy, set the limitation-count attribute to a positive integer.

For a client-class, set the limitation-id and client-lookup-id attributes to an expression, and set the over-limit-client-class-name attribute to a client-class.

For a client, set the over-limit-client-class-name attribute to a client-class.

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:

"\"limit\"" 

Here is a slightly more extensive example to set the client-class 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 (@):

@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, in the 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 the 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 in the 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.

Expression Datatypes

The datatypes that expressions support are:

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

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

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.

Expression Functions

Table 13-1 lists the expression functions. Expressions must be enclosed in parentheses.

Table 13-1 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 13-2.)

(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 13-2.)

(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 13-2.)

(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 13-2).

(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 and attr is the attribute name. Both are converted to a string regardless of their initial datatype. The initial environment dictionary cannot be changed, but it can be shadowed (you can redefine something that is in the initial dictionary, but if you remove it, then the original initial value is still there). Note that the get keyword is not optional for a "get."

(equal expr1 expr2 expr3)
(equali expr1 expr2 expr3)

(equal (request option "vendor-class-id") "docsis") returns the string "docsis" if the value of the option vendor-class-id is a string identical to "docsis"

(equali "abc" "ABC") returns "ABC"

(equal "abc" "def") returns null

(equal "ab" (as-string 61:62)) "this is true") returns "this is true"

(equal "ab" 61:62 "this is not true") 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 expr1 and expr2. If they are equal, it returns:

1. The value of expr3, if specified, else

2. The value (and datatype, after possible string conversion) of expr2, as long as expr2 is not null, else

3. The string "*T*" (since returning null would incorrectly indicate a failed comparison).

If expr1 and expr2 are not equal, the function returns null.

The arguments can be any datatype. If different, the function converts 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 the "01" and "1" strings are not equal).

The equali function is identical to the equal function, 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 sub-option 2, and if that does not exist, returns 01:02:03:04

The or or pick-first-value function evaluates the arguments sequentially. When evaluating 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 a string

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. This shows how the datatypes in the table correspond to the datatypes returned by the request function:

blob —> blob
IP address —> 4-byte blob
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.

(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 13-2.)

(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 13-2.)

(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 13-2.)

(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 13-2.)

(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 13-2.)

(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 13-2.

Table 13-2 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 ;, such as:

// 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:


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

Step 2 Define the client-classes.

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.

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.

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

// 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-id attribute on the server level.

Step 7 Add another expression for the limitation ID for the client in a 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 limitation-id attribute for the client-class.

Step 9 Reload the server.


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.

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

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.

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

Step 6 Reload the server.


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 In Network Registrar, enable client-class processing server-wide.

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

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. In the cclookup3.txt file:

// Sets client-class to limit 
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. In the cclimit3.txt file:

// Sets limitation ID 
(substring (request option 82 2) 9 3) 

Step 8 Reload the server.


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.

The trace levels for expression-trace-level are (use the number value):

0—No tracing

1—Failures, including those protected by (try ...)

2—Total failure retries (with trace level = 6 for retry)

3—Function calls and returns

4—Function arguments evaluated

5—Print function arguments

6—Datatype conversions (everything)

The trace levels for expression-configuration-trace-level are (use the number value):

0—No additional tracing

1—No additional tracing

2—Failure retry (the default)

3—Function definitions

4—Function arguments

5—Variable lookups and literal details

6—Everything

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.

Troubleshooting Client-Classes

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=setting command in the CLI, then reload the DHCP server. The recommended settings are:

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.

Configuring LDAP

This section describes the Lightweight Directory Access Protocol (LDAP) with which you can use directory services to integrate Cisco CNS Network Registrar client and lease information. By building on your existing standard schema for objects stored in LDAP directories, you can handle information about DHCP client entries. Thus, instead of maintaining client information in the DHCP server's database, you can ask the Network Registrar DHCP server to issue queries to one or more LDAP servers for information in response to DHCP client requests.

Network Registrar now uses the iPlanet LDAP Software Development Kit (SDK) version 5.0. Previous releases used SDK version 3.0.

About LDAP Directory Servers

LDAP directory servers provide a way to name, manage, and access collections of attribute/value pairs. You can enter information into your LDAP server in any number of ways, because Network Registrar is not dependent on any specific LDAP object classes or schema:

You can store DHCP client information in unused attributes. For example, you could use the givenname attribute to hold the DHCP client-class name value.

You can add new attributes to an object class if you disable schema checking. For example, you could add the client-class-name attribute to the organizational person object class.

You can create a new object class and define the appropriate attributes. For example, you could create the DHCP client object class and define the client attributes that you want to use.

When you configure the DHCP server to read from LDAP, a query dictionary tells the server which LDAP attributes to query for. The server converts the resulting data into DHCP client data attributes.


Tip You can configure Network Registrar to generate SNMP traps when an LDAP server stops responding or resumes responding to requests from the Network Registrar DHCP server (see the trap command in the Network Registrar CLI Reference).


Configuring DHCP Client Queries in LDAP

You can configure and unprovision DHCP client queries, and configure embedded policies, in an LDAP client entry.

Configuring DHCP-Server-to-LDAP Client Queries

To enable the DHCP server to query your LDAP server for client data, perform the following steps. Like local client entries, LDAP client entries are keyed by the client's MAC address.


Note When connecting to an LDAP server, specify the user's distinguished name. The distinguished name is the way to uniquely identify an object in the LDAP schema. It is like a unique key in a database or a fully qualified path name for a file. For example, a distinguished name for a person might be dn: cn=Beth Jones, ou=Marketing, o=Example Corporation. In this company, there may be many people named Beth and many people named Jones, but no one else named Beth Jones works in Marketing at Example Corporation.



Step 1 Tell DHCP about your LDAP server. Supply a host name:

nrcmd> ldap myserver create myserver.example.com 

Later, if you need to delete the server, use the ldap server delete command.

Step 2 Configure the connection credentials. Use the distinguished name for the user:

nrcmd> ldap myserver set username="cn=joe,o=Example Corp,c=US" password=access 

Step 3 Set the search path (and, if necessary, the search scope). The search path is a point in the directory from which to start searches. If you specify the search scope to be SUBTREE, the server searches all the children of the search path; if you specify ONELEVEL, the server searches only the immediate children of the base object. and if you specify BASE, the server searches only the base object itself. This example sets the base of the search to be the organization Example Corp and the country US, with a subtree search scope:

nrcmd> ldap myserver set search-path="o=Example Corp,c=US" search-scope=SUBTREE 

Step 4 Set the search filter to be the attribute for which DHCP will substitute the clients' MAC addresses. In this example, the attribute is the common name (cn).

nrcmd> ldap myserver set search-filter=(cn=%s) 

Step 5 Configure a query dictionary, which contains all the LDAP-to-DHCP mappings. Use the ldap servername setEntry command to set these mappings:

a. Retrieve the DHCP surname from the sn LDAP attribute:

nrcmd> ldap myserver setEntry query-dictionary sn=host-name 

b. Retrieve the client-class name from the first givenname LDAP attribute:

nrcmd> ldap myserver setEntry query-dictionary givenname=client-class-name 

c. Retrieve the domain name from the localityname LDAP attribute:

nrcmd> ldap myserver setEntry query-dictionary localityname=domain-name 

d. If you need to unset any of the entries, use the ldap server unsetEntry attribute key command. You can also check any of the settings using the ldap server getEntry attribute key command.

Step 6 Enable queries for the LDAP server. This example enables queries for myserver:

nrcmd> ldap myserver enable can-query 

Step 7 Enable client-class processing for the DHCP server:

nrcmd> dhcp enable client-class 

Step 8 Enable the DHCP server to use LDAP for client entry queries:

nrcmd> dhcp enable use-ldap-client-data 

Step 9 If you have more than one LDAP server configured, you can also set them to operate in round-robin or failover mode:

round-robin—The servers' preference values are ignored and all LDAP servers that are configured to handle client queries are treated equally, as are all servers configured to accept lease-state updates.

failover—The DHCP server always uses the active LDAP server with the lowest preference. If the preferred server loses its connection or fails, DHCP uses the next server in preference order, except that LDAP servers with equal preference are treated as being in round-robin mode. You set the LDAP server preference (the lower the number, the higher the preference) using the ldap server set preference command and the LDAP mode using the dhcp set ldap-mode command:

nrcmd> ldap myserver set preference=1 
nrcmd> ldap anotherserver set preference=2 
nrcmd> dhcp set ldap-mode=failover 

Step 10 Show or list the LDAP configuration:

nrcmd> ldap myserver 
nrcmd> ldap list 
nrcmd> ldap listnames 

Step 11 Reload the DHCP server:

nrcmd> dhcp reload 


For details about the ldap command, see the Network Registrar CLI Reference Guide.

Unprovisioning Client Entries

You can unprovision LDAP client entries so that the client information remains in LDAP, but the DHCP server treats the client as if that information does not exist. The DHCP server then supplies the client with the default behavior.

Configure the search filter set in Step 4 of the preceding section so that the LDAP server does not return a client entry containing a specified attribute with a value.

For example, if you want to unprovision the LDAP entry givenname, configure this search filter:

nrcmd> ldap myserver set search-filter=(&(cn=%s)(!(givenname=unprovision))) 

Whenever the givenname attribute in the LDAP client entry is set to the unprovision string, the LDAP server does not return the client entry to the DHCP server. In other words, the DHCP server treats the client as if it has no LDAP client entry.


Note This procedure has no measurable performance impact on either the DHCP or the LDAP server.


Configuring Embedded Policies in LDAP

You can configure embedded policies in LDAP.


Step 1 Configure an LDAP server for the DHCP server, naming it myserver, for example.

Step 2 Map the LDAP attribute that you want the DHCP server to interpret as the embedded policy to the internal embedded-policy property. This example maps the businessCategory LDAP attribute:

nrcmd> ldap myserver setEntry query-dictionary businessCategory=embedded-policy 

Step 3 Add a string to the LDAP attribute that the DHCP server can interpret as an embedded policy. The most practical way to determine what this string should look like is to create a dummy client in the Network Registrar database and use the mcdadmin utility to determine the proper string to add to the LDAP attribute. Note that this dummy client will never be used, because you are using LDAP, and you can subsequently delete it. Have the embedded policy include the option data types that you need.

a. For example, create an embedded client policy for client 1,6,00:d0:ba:d3:bd:3b. Add some reply options and a multivalue option (routers) with an IP address data type:

nrcmd> client 1,6,00:d0:ba:d3:bd:3b create 
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b 
	set dhcp-reply-options=packet-file-name, packet-server-name 
nrcmd> client-policy 1,6,00:d0:ba:d3:bd:3b setOption routers 1.2.3.4,5.6.7.8 
nrcmd> save 

b. Use the mcdadmin utility to redirect the database client entries into a file:

mcdadmin -p /servers/name/dhcp/1/cliententry -e exportfile 

c. Open the file in an editor and search for the appropriate client entry:

1,6,00:d0:ba:d3:bd:3b = bin:[256] ((ClassName ClientEntry)
(embedded-policy 
((ClassName Policy) 
(name client-policy:1,6,00:d0:ba:d3:bd:3b) 
(vendoroptions ()) 
(version 1) 
(dhcp-reply-options [packet-file-name packet-server-name ]) 
(dhcp-reply-options-number [257 258 ]) 
(options ((routers 01:03:01:02:03:04:05:06:07:08)))) 
)) 

The ClassName Policy entry is the start of the embedded policy string, with a single closing parentheses ending the string. (The entire entry normally runs together. It is presented here for clarity as parenthesized groupings on separate lines. The final three parentheses close, respectively, the ClassName Policy, embedded policy, and ClassName Client Entry groupings.)

d. Add the embedded policy string, which appears boldface in substep (c) to the LDAP attribute (businessCategory in the example):

businessCategory:((ClassName Policy)(name 
client-policy:1,6,00:d0:ba:d3:bd:3b)(vendoroptions ())(version 1)(dhcp-reply-options 
[packet-file-name packet-server-name ])(dhcp-reply-options-number [257 258 ])(options 
((routers 01:03:01:02:03:04:05:06:07:08)))) 

The option values are translated into hexadecimal field syntax, including multiple values that were originally comma-separated. For example, "setOption routers 1.2.3.4, 5.6.7.8" translates into "(options ((routers 01:03:01:02:03:04:05:06:07:08)))." The first field of the option value is the number of bytes in the option number (01 or 02). The second field is the option number itself in hex (option 03, routers, in the example).

e. Use the syntax as a model for each new embedded policy entry in LDAP. To see how other option data types appear in the LDAP string, add these options to the client or create further dummy clients with them. Once you extract the data, you can use the CLI to delete the dummy client:

nrcmd> client 1,6,00:d0:ba:d3:bd:3b delete 
nrcmd> save 


Configuring DHCP LDAP Update and Create Services

You can configure the DHCP LDAP service to copy lease state data to existing attributes in the LDAP server. The service converts the lease state data to string form, and uses an update dictionary to map the LDAP attributes to the DHCP data values.

Each time the state of a lease changes, the DHCP server makes a copy of the data and then transfers it to the LDAP server that you have configured to store lease state data.

Lease State Attributes

You can store any of these attributes about the lease's state information in your LDAP server:

address—IP address of this lease.

client-dns-name—Name the DHCP server attempted to enter into the DNS server for this client.

client-domain-name—Domain into which to put the client's name.

client-flags—A variety of flags relating to the client.

client-host-name—DNS name that the client requested the DHCP server to place in the DNS server.

client-id—Client-id specified by the client, or one synthesized by the DHCP server for this client.

client-mac-addr—MAC address that the client presented to the DHCP server.


Note Although the MAC addresses in LDAP have to be formatted exactly the way they are formatted by Network Registrar when it creates local client-entries, they are separate instances and thus unique to lease data.


expiration—The time at which the lease expires.

flags—Flags for the lease (reserved or de-activated).

lease-renewal-time—The earliest time in which the client is expected to issue a lease renewal. You can have Network Registrar save this as part of the lease state by using the dhcp enable save-lease-renewal-time command (it is not saved by default).

start-time-of-state—The time at which the state last changed to its current value.

state—Represented as either available, leased, expired, or unavailable.

vendor-class-identifier—The name of the vendor, used by clients and servers to exchange vendor-specific information.

Not every lease has all these attributes. The client-mac-addr and client-id lease state attribute are not present if a client releases its lease or is forced available through Network Registrar. In addition, the lease-renewal-time attribute may not be present if the save-lease-renewal-time property is disabled through DHCP. Similarly, the vendor-class-identifier property may not be present if the save-vendor-class-id property is disabled through DHCP, using the CLI.

Configuring LDAP for Lease State Updates

Follow this procedure to configure lease state updates:


Step 1 Choose the lease state update scheme.

Step 2 Add entries to the directory or modify existing entries to store the lease state information. You may need to extend entries through the addition of attributes or custom object classes.

Step 3 Configure Network Registrar to perform the updates.

Given the flexibility of directories, there are many different ways in which you could choose to store a copy of lease state attributes in a directory. For example, you could choose to store the lease state data as part of an existing entry, or you could store the lease state data independently.


Storing Lease State Data as Part of Existing Entries

You can store lease state data as part of an existing entry. It is even possible to store the client entry, lease state, and employee data in the same entry. As part of the setup for this method, you must decide how you want to store the lease data attributes. You can store data attributes using these methods:

Map attributes from the entry

Add attributes to the entry

Extend the entry by creating a new object class

The advantage to this method is that lease data is stored directly with other associated client information. The disadvantage is that there are scenarios, albeit unlikely, related to client-class and reservations that could result in stale data being in the directory for a short period of time when a client is moved off a lease by the server.


Note If the lease whose state is being updated does not have a client, it will not have an associated MAC address. This situation occurs when a client gets a lease, and then is moved off that lease by client-class processing. It can also occur when a client has a pre-existing lease and a reservation for a different lease in the same LAN segment. When the reserved lease is available, the server moves the client off its existing lease and onto the reservation. Both of these transfers result in an LDAP update for the old lease without a client MAC address. This is generally not a problem, because the update for the client's new lease (which has an associated MAC address) should come through.


Also, this method requires two LDAP interactions to write the lease information. When updating lease state information, the DHCP LDAP service contacts the directory twice because when updating an entry it is not enough just to know how to find the entry. You must specifically know the entry's distinguished name.

The DHCP LDAP service first finds the appropriate entry in the directory by using one of the lease state attributes that you chose (preferably the MAC address) as the search criteria. This is necessary because none of the lease state attributes is part of the distinguished name of the entry. When the DHCP LDAP service locates the entry, the distinguished name is returned. The DHCP LDAP service then updates that same entry with the appropriate information. For an example how to use this method, see the "Configuring LDAP State Updates" section.

Storing Lease State Data Independently

You can store lease state data by IP address in its own entries. This method results in a copy of the server lease database in a directory, and is the most straightforward way to configure the database. As part of the setup for this method, create new entries for each IP address that the server can serve. The advantage to this method is that there are no scenarios in which the lease state data in the directory will be stale. The disadvantage is that lease data is not stored directly with other associated client information.

To update the lease state information, the DHCP LDAP service contacts the directory service once. When performing the update, the service uses the IP address to construct the distinguished name.

Using LDAP Updates

There are two ways you can use the LDAP update feature, to:

Keep track of clients that use LDAP client entry information and to associate some of the attributes of that LDAP host with lease state attributes.

Create and update objects that can be located by their IP address. When Network Registrar creates these objects, it can make a level of LDAP objects that matches (or is) the DHCP server's lease state.

When using Network Registrar, you should be aware that:

The DHCP server only reads from a single object and writes to a single object. You can use separate objects to hold the client entry data read and the lease state date written, but Network Registrar cannot read some attributes from one object and some from another.

The performance of LDAP queries, like all database access, depends on indexed attributes. If you did not index the attributes that you configure to use in query filters, you will experience poor performance.

When configured for update, Network Registrar does not create new objects in the directory. The DHCP server only writes to existing objects. However, if you configure for update and create, it does create new objects (if no object exists).

Configuring LDAP State Updates

There are two options available for performing a lease state update to an LDAP server.

Using the update-search-path option—The DHCP server first queries to locate the dn (distinguished name) for an update.

Using the dn-format option—The server is provided with the distinguished name for an update. In other words, the DHCP performs a direct update without having to query before an update.

Option 1: Using update-search-path Option

The following example illustrates the first option, update-search-path. It shows what to do when the LDAP object's distinguished name (dn) cannot be constructed from data that is available in the lease state. The DHCP server creates an LDAP query based on the update-search-xxx information, locates the LDAP object, and uses its distinguished name to issue an LDAP update.

The example shown in Table 13-3 assumes you are using the standard LDAP organizational person object class attributes to hold lease update data.

Table 13-3 LDAP-to-DHCP Mapping, Example 2

Attribute
DHCP Lease Entry Mapping

uid

address (IP address)

carlicense

state (lease state)



Step 1 Tell DHCP about your LDAP server by supplying the server's host name:

nrcmd> ldap myserver create myserver.example.com 

Step 2 Configure the credentials to use when connecting to the LDAP server. This example sets the admin to be joe and his password to be access. Use the distinguished name for the user:

nrcmd> ldap myserver set username="cn=joe,o=Example Corporation,c=US" password=access 

Step 3 Configure the update-search-path attribute, which is the starting point in the directory for the objects that the DHCP server will update. You can also set the update search scope.

This example sets the search path to begin at the organizational unit (ou) IT, the organization Example Corporation, and country US. The update search scope is set to SUBTREE:

nrcmd> ldap myserver set update-search-path="ou=IT,o=Example Corp,c=US" 
update-search-scope=SUBTREE 

Step 4 Set the ID of the attribute you want to use to search for the LDAP object that will be updated. This example sets the search attribute to be the client's MAC address:

nrcmd> ldap myserver set update-search-attribute=client-mac-addr 

Step 5 Configure a filter expression into which the update-search-attribute attribute should be formatted. This expression must contain a "%s," which indicates where the search attribute's data should be substituted.:

nrcmd> ldap myserver set update-search-filter=(cn=%s) 

Step 6 Configure the update-dictionary attribute, which allows you to identify the LDAP attributes that you want set with the values of the corresponding lease state attributes.

This example specifies that the LDAP uid should be updated to contain the IP address, and that the carlicense attribute should be updated to contain the DHCP lease state information:

nrcmd> ldap myserver setEntry update-dictionary uid=address carlicense=state 

Step 7 Enable updates for the new LDAP server:

nrcmd> ldap myserver enable can-update 

Step 8 Reload the LDAP server.


Option 2: Using dn-format Option

This example illustrates using the second option, dn-format.


Step 1 Tell DHCP about your LDAP server:

nrcmd> ldap myserver_option2 create myserver.example.com 

Step 2 Configure the credentials to use when connecting to the LDAP server. This example sets the admin to be joe and his password to be access. Use the distinguished name for the user:

nrcmd> ldap myserver_option2 set username="cn=joe,o=Example Corporation,c=US" 
password=access 

Step 3 Use the dn-format string to specify where in the LDAP server database hierarchy you want to begin searching for the update:

nrcmd> ldap myserver_option2 set dn-format="cn=\"%s\",ou=IT,o=Example Corp,c=US" 

Step 4 Set the dn-attribute attribute to which you want the dn-format string to refer. This example sets the dn-attribute to be the client's MAC address:

nrcmd> ldap myserver_option2 set dn-attribute=client-mac-addr 

Step 5 Specify the entries to be updated:

nrcmd> ldap myserver_option2 setEntry update-dictionary uid=address carlicense=state 

Step 6 Enable the can-update attribute:

nrcmd> ldap myserver_option2 enable can-update 

Step 7 Reload the LDAP server.


Configuring LDAP Entry Creation

This section explains how to create LDAP entries. LDAP entry creation provides the ability to locate entries and update them with current lease information. Entries are created only if a state update operation fails because it cannot locate an entry.

After performing the steps in the previous example, follow these steps in the CLI to configure LDAP entry creation.


Step 1 Set the dn-attribute property for the LDAP server for the lease object attribute, such as the client-mac-addr field, and set the dn-format string:

nrcmd> ldap myserver set dn-attribute=client-mac-addr 
dn-format="cn=\"%s\",ou=IT,o=Example Corp,c=US" 

This step is required only if you configure the lease state updates using the update-search-path option. (See "Option 1: Using update-search-path Option" section). Skip this step if you configure lease state updates using the dn-format string. (See "Option 2: Using dn-format Option" section.)

Step 2 Specify the distinguished name of the entry to be created when combined with the existing dn-attribute property:

nrcmd> ldap myserver set dn-create-format="cn=\"%s\",ou=IT,o=Example Corp,c=US" 

Network Registrar's client-mac-addr field uses the form 1,6:xx:xx:xx:xx:xx:xx. Since the comma character is a special separator in LDAP, you must use the \" characters to quote distinguished names.

Step 3 Using the create-dictionary property, establish mappings between LDAP attributes and lease state attributes by entering a series of name=value pairs.

The LDAP attributes indicate the entry attributes set to the value of their corresponding lease state attributes:

nrcmd> ldap myserver setEntry create-dictionary sn=client-host-name 
nrcmd> ldap myserver setEntry create-dictionary givenname=client-class-name 
nrcmd> ldap myserver setEntry create-dictionary localityname=client-domain-name 

Step 4 Using the create-object-classes property, specify the object classes to be used when creating the entry:

nrcmd> ldap myserver set create-object-classes= 
"top,person,organizationalPerson,inetorgperson" 

Step 5 Enable entry creation for the LDAP server myserver:

nrcmd> ldap myserver enable can-create 


Note Enable the can-update attribute before you enable the can-create attribute. For an example, see the "Configuring LDAP State Updates" section.


Step 6 Reload the LDAP server:

nrcmd> ldap reload 

Step 7 To see if creation, queries, and updates were successful, view the LDAP log settings. For details, see the ldap command section in the CLI Reference Guide.


Troubleshooting LDAP

The following sections include some advice on fine-tuning and detecting failures of the LDAP server.

LDAP Connection Optimization

You can optimize LDAP connections by using separately tunable read and write objects. This example tunes write (create and update) operations, which require longer server processing:

nrcmd> ldap LDAP-Write create csrc-ldap password=changeme port=389 preference=1 
nrcmd> ldap LDAP-Write setEntry query-dictionary csrcclientclasas=client-class-name 
nrcmd> ldap LDAP-Write set 
search-filter=(&(macaddress=%s)(|(crscclassname=Computer)(csrcclassname=Modem))) 
nrcmd> ldap LDAP-Write set search-path=csrcprogramname=csrc,o=NetscapeRoot 
nrcmd> ldap LDAP-Write set 
username=uid=admin,ou=Administrators,ou=TopologyManagement,o=NetscapeRoot 
nrcmd> ldap LDAP-Write disable can-query 
nrcmd> ldap LDAP-Write enable can-create 
nrcmd> ldap LDAP-Write enable can-update 
nrcmd> ldap LDAP-Write enable limit-requests 
nrcmd> ldap LDAP-Write set connections=2 max-requests=8 timeout=10s 

This example tunes read (query) operations, which require shorter server processing:

nrcmd> ldap LDAP-Read create csrc-ldap password=changeme port=389 preference=1 
nrcmd> ldap LDAP-Read setEntry query-dictionary csrcclientclasas=client-class-name 
nrcmd> ldap LDAP-Read set 
search-filter=(&(macaddress=%s)(|(crscclassname=Computer)(csrcclassname=Modem))) 
nrcmd> ldap LDAP-Read set search-path=csrcprogramname=csrc,o=NetscapeRoot 
nrcmd> ldap LDAP-Read set 
username=uid=admin,ou=Administrators,ou=TopologyManagement,o=NetscapeRoot 
nrcmd> ldap LDAP-Read enable can-query 
nrcmd> ldap LDAP-Read disable can-create 
nrcmd> ldap LDAP-Read disable can-update 
nrcmd> ldap LDAP-Read enable limit-requests 
nrcmd> ldap LDAP-Read set connections=3 max-requests=12 timeout=4s 

Typical LDAP Attributes and Recommended Values

Table 13-4 shows typical values for the LDAP attributes.

Table 13-4 LDAP Parameters and Recommended Values 

Recommended Setting
Description

ldap name set connections=
5
to 25

Number of connections that the server should make to an LDAP server. This is primarily a performance tuning parameter. The default is one connection. In some cases, more than one connection can improve overall throughput. The amount depends on the load on the LDAP server. With many applications using LDAP, five connections would be appropriate; with just Network Registrar using LDAP, 25 would be appropriate.

ldap name set threadwaittime=2

Interval (in milliseconds) at which each LDAP client connection polls for results, if it has outstanding queries or updates.

ldap name set timeout=3

Number of seconds an LDAP request remains on a connection queue before being declared stale and timing out. The default setting of 3 seconds is recommended. Any response the DHCP client receives after the client's timeout period is stale.

Network Registrar DHCP servers fail over at the timeout interval if dhcp set ldap-mode=failover and dhcp enable can-update or dhcp enable can-create are set.

ldap name set query-timeout=3

Network Registrar DHCP servers fail over at the query-timeout interval if dhcp set ldap-mode=failover and dhcp enable can-query are set. The default setting is 3 seconds and is recommended.