On DSL access networks that use DHCP to assign an IP address to the enduser, it is usual that some network element along the way acting as a DHCP relay stuffs a so-called 'relay agent information option' aka "option 82" into the DHCPDISCOVER packets. This option has several suboptions: "Agent Circuit ID" and "Agent Remote ID". One of those two usually uniquely identifies the 'circuit' the customer is connected to, such as a DSLAM port.
If you want to assign static IP addresses to your customers, it's very convenient to use this option as a unique identifier for that.
host client {
hardware ethernet 00:e0:4c:a7:ca:de;
fixed-address 192.168.0.6;
}
Unfortunately, you can only assign a static address based on the
mac-address of the client this way. You'd expect to be able to
say something like:
host client {
option agent.circuit-id "dslam42.port22";
fixed-address 192.168.0.6;
}
but that is not implemented. The workaround looks like this:
stash-agent-options true;
shared-network "networkname" {
subnet 192.168.0.0 netmask 255.255.255.0 {
option broadcast-address 192.168.0.255;
option routers 192.168.0.1;
option subnet-mask 255.255.255.0;
# A customer.
class "id-192.168.0.2" {
match if option agent.circuit-id = "dslam42.port22";
}
pool {
allow members of "id-192.168.0.2";
range 192.168.0.2;
}
# And yet another one.
class "id-192.168.0.5" {
match if option agent.circuit-id = "dslam42.port29";
}
pool {
allow members of "id-192.168.0.5";
range 192.168.0.5;
}
}
}
With recent hardware, this scales up to a few thousand customers.
The internal implementation in ISC DHCPD of classes is such that
it scales in a non-linar way - O(N^2) or something. So suddenly
you'll end up with dhcpd eating 100% CPU. This is ofcourse bad.
The only problem is .. you cannot assign a fixed-address based on a subclass, and there is no way to say "allow members of subclass bla" in for example a pool-statement.
I chose to implement a new syntax for the "allow members of" statement. The standard syntax is:
allow members of <class>;This is now extended to also allow this:
allow members of <class> <subclass>;So, to assign a static address to customers based on the circuit-id, you would configure the server like this:
stash-agent-options true;
class "static-1" {
spawn with option agent.circuit-id;
}
shared-network "networkname" {
subnet 192.168.0.0 netmask 255.255.255.0 {
option broadcast-address 192.168.0.255;
option routers 192.168.0.1;
option subnet-mask 255.255.255.0;
# A customer.
pool {
allow members of "static-1" "dslam42.port22";
range 192.168.0.2;
}
# And yet another one.
pool {
allow members of "static-1" "dslam42.port29";
range 192.168.0.5;
}
}
}
This has been tested on a Xeon 2.8 Ghz server, it uses just a few
percent of CPU with 40.000 DHCP clients.
Ofcourse you can, as usual, define multiple classes if you like- for example, one per DSLAM. Say that your DHCP relay agent stuffs the DSLAM name into agent.remote-id and the port number in agent.circuit-id. It is not sufficient to have one class and just spawn subclasses based on the circuit-id, you will have clashes as multiple DSLAMs use the same circuit-ids.
In that case, do something like this:
class "dslam1" {
match if (substring(option agent.remote-id,0,6) = "dslam1");
spawn with option agent.circuit-id;
}
class "dslam2" {
match if (substring(option agent.remote-id,0,6) = "dslam2");
spawn with option agent.circuit-id;
}
[....]
pool {
allow members of "dslam1" "port29";
range 192.168.10.20;
}
[....]
Another solution would be something like (syntax not tested) :
class "static-1" {
spawn with concat(option agent.remote-id,0,6), "_", agent.circuit-id);
}
[....]
pool {
allow members of "static-1" "dslam2_port29";
}
}
This means that if the customers changes this device (places a new modem or router) the new device will not be able to get a lease, since it will get assigned the same IP address and that has already been leased.
So make sure that a) you keep the lease time short enough (I recommend 2 hours or 7200 seconds), and b) your helpdesk knows about this since customers will hit this issue. Put something like this in your config:
default-lease-time 7200;
max-lease-time 7200;
patch-server::02-log-agent-options
You probably do not need this patch.
patch-server::03-reply-to-client-ip
I think the best option for support is to go to the ISC DHCP
users mailinglist at https://lists.isc.org/mailman/listinfo/dhcp-users and
mention this webpage. Perhaps there are other people there using
the same patches that can help you.
Miquel van Smoorenburg