isc-dhcp 4.4.2-p1 shared-network confusion

Simon dhcp1 at thehobsons.co.uk
Wed Jul 6 18:48:40 UTC 2022


Philippe Maechler <plcmaechler at gmail.com> wrote:

> Today we had a little network hiccup which lead me to some confusion about our dhcp configs
>  
>  
> Should a shared-network config, have a subnet section in it?

Generally yes - otherwise it’s a bit redundant !

> how does the dhcpd knows fromm which shared-network the addresses are given out? routing-table?

By default, all subnets within a shared network are considered equal. So in your example, 10.1.1.0/24 and 10.2.1.0/24 are considered equal and a client can have an address in either subnet. If you need clients to get an address in a specific subnet/pool then you need to use allow statements to manage that.
If clients have any need to communicate with each other, then you need to arrange for the router in each subnet to provide a route back out the same interface back to the other subnet(s) on the network segment.

But in the general case, I’d suggest just making a subnet larger rather than creating a shared network just to add another subnet for more clients. E.g. have 10.1.0.0/22 or 10.1.4.0/22 and so on.

> We have to following scenario:
>  
> DHCP Server running on a FreeBSD host, which has four network interfaces. On the local network there is no dhcpd used, all dhcpd traffic is from relay-agents
>  
> Networks directly on the server:
> 1.1.1.10/24 for management
> 2.2.2.10/24 for cpe
> 3.3.3.10/24 for voice
> 4.4.4.10/24 for iptv
>  
> (I think its easier to talk about 1.1.1.1 and 2.2.2.2 than 10.254.255.0/29 and so on)
>  
> The client networks 6, 7, 10 and 20 are all behind different relay-agents.
>  
> renewals from the clients where received on bce2 and the reply went out on bce2
> but the discovers from the relay agent arrived on interface bce2 (2.2.2.10) and the replies went out on bce3 (3.3.3.10)
> that was not a problem at all until today when a new firewall was deployed which had no route/firewalled that traffic.

The server (where clients are relayed rather than directly attached) doesn’t care which interface the packets arrive on. See below ...

> the problem was solved as soon as we installed the missing route for that relay-agent.
>  
> but this made me thinking about the pool-selection. in our case, it's mostly done by allow-statements
> but for the shared-network part, shouldn't there be at least one physically connected interface in the config?

No, the server doesn’t need any subnets or clients directly connected - though you do need a subnet declaration (can be empty) for all local interfaces the server listens on (the parser can’t know if you have or haven’t directly connected clients - so it needs subnet declarations in case you have.

It will probably help to explain how two different types of packets are handled where a relay is concerned.

Assume a remote client has no lease and connects to the network. It broadcasts a DHCP-Discover packet which will be picked up by any locally attached DHCP servers or relay agents. In your case, it’s picked up by a relay agent. So that the server knows where the client is, the relay agent inserts the IP address (or, **an** IP address) which is attached to the interface it received the broadcast packet on into the forwarded packet, in the GI-Addr (Gateway Interface Address) field. Note that the relay agent does not have to be within a router - but for convenience they typically are.
The relay agent then sends the modified packet, typically via unicast, to the server address(es) it’s been configured with. Based on the  GI-Addr, the server picks a suitable subnet/shared network and then applies any rules (such as allow statements in pools) in order to pick an address to offer the client.
Assuming it was able to allocate an address, the server then sends a response by unicast to the GI-Addr. The relay agent then broadcasts the packet on it’s local network where the client will pick it up.
The same process follows for the DHCP-Request, DHCP-Ack exchange.

You will see that the key things here are :
The relay agent has an IP address in the same shared-network as the client - this is one use for a shared network, allowing the relay agent to use (e.g.) separate management addresses to those used by the clients.
There must be routing in place that allows packets from the relay agent to the server(s), and from the servers to the GI-Addr of the relay agent.

Once a client has a working lease, then things change.
When the lease needs renewing (by default, when it’s half way through) then the client unicast a packet directly to the server address from which it received the lease. Note that this can be any address the server possesses, and it’s a configurable option. The server will unicast a response back to the client. The relay agent is not involved at all.
For this to work, there must be routing in place for unicast packets from the client to the server and from the server to the client. It sounds like you did not have this in place when you had the hiccup.

The dhcp server process doesn’t care about packet routing. It simply receives packets via the OS network stack, and it sends packets out via the network stack - thus using whatever routing rules the OS has in place.

>  
> The configuration dhcpd.conf network part is:
>  
> # define local networks and suppress an error/warning at startup
> subnet 1.1.1.0 netmask 255.255.255.0 {
>  # no dhcpd service in this subnet
> }
> subnet 2.2.2.0 netmask 255.255.255.0 {
>  # no dhcpd service in this subnet
> }
> subnet 3.3.3.0 netmask 255.255.255.0 {
>  # no dhcpd service in this subnet
> }
> subnet 4.4.4.0 netmask 255.255.255.0 {
>  # no dhcpd service in this subnet
> }
>  
> subnet 6.6.6.0 netmask 255.255.255.0 {
>   option routers 6.6.6.1;
>   option subnet-mask 255.255.255.0;
>   pool {
>     range 6.6.6.10 6.6.6.254;
>       allow members of "cpes";
>     deny dynamic bootp clients;
>   }
> }
>  
> subnet 7.7.7.0 netmask 255.255.255.0 {
>   option routers 7.7.7.1;
>   option subnet-mask 255.255.255.0;
>   pool {
>     range 7.7.7.10 7.7.7.254;
>       allow members of "voice";
>     deny dynamic bootp clients;
>   }
> }
>  
> shared-network “abc” {
>   subnet 10.1.1.0 netmask 255.255.255.0 {
>     option routers 10.1.0.1;
>     option subnet-mask 255.255.255.0;
>     pool {
>       range 10.1.0.10 10.1.0.254;
>         allow members of "iptv-group1";
>       deny dynamic bootp clients;
>     }
>   }
>   subnet 10.2.1.0 netmask 255.255.255.0 {
>     option routers 10.2.0.1;
>     option subnet-mask 255.255.255.0;
>     pool {
>       range 10.2.0.10 10.2.0.254;
>         allow members of "iptv-group1";
>       deny dynamic bootp clients;
>     }
>   }
> }
>  
> shared-network “xyz” {
>   subnet 20.1.1.0 netmask 255.255.255.0 {
>     option routers 20.1.0.1;
>     option subnet-mask 255.255.255.0;
>     pool {
>       range 20.1.0.10 20.1.0.254;
>         allow members of "iptv-group2";
>       deny dynamic bootp clients;
>     }
>   }
>   subnet 20.2.1.0 netmask 255.255.255.0 {
>     option routers 20.2.0.1;
>     option subnet-mask 255.255.255.0;
>     pool {
>       range 20.2.0.10 20.2.0.254;
>       allow members of "iptv-group2";
>       deny dynamic bootp clients;
>     }
>   }
> }

Assuming that 10.1.1.0/24 and 10.2.1.0/24 are both on the same network segment (same bit of wire); and 20.1.1.0/24 and 20.2.1.0/24 are both on the same network segment - but a different one to the 10.1.1.0 & 10.2.1.0 one; then things should just work automagically as long as you have the right routing in place.


Simon


More information about the dhcp-users mailing list