DHCP relay - wrong interface for relayed packet

Paul Thornton paul at prt.org
Sun Jul 10 10:16:32 UTC 2022


Hi Alan, Matthew (and anyone else following this),

I've been doing some more digging with this over the past couple of 
days, but haven't had much success.  I think I now understand the 
problem though.

On 07/07/2022 20:26, Alan DeKok wrote:

>    You can make it use port 67 by the following:
> 
> 	update reply {
> 		Packet-Dst-Port := 67
> 	}
> 
>    It will then send the packets to port 67 instead of 1067.

Firstly, updating the reply port doesn't seem to make any difference. 
The debug shows that config being treated as a no-op:

Received DHCP-Offer of Id 90779350 from 217.198.54.101:1067 to 
217.198.52.2:1067
         DHCP-Opcode = Server-Message
         DHCP-Hardware-Type = Ethernet
         DHCP-Hardware-Address-Length = 6
         DHCP-Hop-Count = 1
         DHCP-Transaction-Id = 2423755600
         DHCP-Number-of-Seconds = 0
         DHCP-Flags = 0
         DHCP-Client-IP-Address = 0.0.0.0
         DHCP-Your-IP-Address = 217.198.52.10
         DHCP-Server-IP-Address = 0.0.0.0
         DHCP-Gateway-IP-Address = 217.198.52.2
         DHCP-Client-Hardware-Address = 90:e2:ba:86:3c:24
         DHCP-Message-Type = DHCP-Offer
         DHCP-Subnet-Mask = 255.255.255.0
         DHCP-Router-Address = 217.198.52.1
         DHCP-Domain-Name-Server = 8.8.8.8
         DHCP-Domain-Name-Server = 8.8.4.4
         DHCP-Hostname = "lfc223"
         DHCP-IP-Address-Lease-Time = 1209823
         DHCP-DHCP-Server-Identifier = 217.198.54.101
         DHCP-Client-Identifier = 0x0190e2ba863c24
         DHCP-Network-Subnet = 217.198.52.2/32
(4) Received code 1026 Id 2423755600 from 217.198.54.101:1067 to 
217.198.52.2:1067 length 300
(4)   DHCP-Opcode = Server-Message
(4)   DHCP-Hardware-Type = Ethernet
(4)   DHCP-Hardware-Address-Length = 6
(4)   DHCP-Hop-Count = 1
(4)   DHCP-Transaction-Id = 2423755600
(4)   DHCP-Number-of-Seconds = 0
(4)   DHCP-Flags = 0
(4)   DHCP-Client-IP-Address = 0.0.0.0
(4)   DHCP-Your-IP-Address = 217.198.52.10
(4)   DHCP-Server-IP-Address = 0.0.0.0
(4)   DHCP-Gateway-IP-Address = 217.198.52.2
(4)   DHCP-Client-Hardware-Address = 90:e2:ba:86:3c:24
(4)   DHCP-Message-Type = DHCP-Offer
(4)   DHCP-Subnet-Mask = 255.255.255.0
(4)   DHCP-Router-Address = 217.198.52.1
(4)   DHCP-Domain-Name-Server = 8.8.8.8
(4)   DHCP-Domain-Name-Server = 8.8.4.4
(4)   DHCP-Hostname = "lfc223"
(4)   DHCP-IP-Address-Lease-Time = 1209823
(4)   DHCP-DHCP-Server-Identifier = 217.198.54.101
(4)   DHCP-Client-Identifier = 0x0190e2ba863c24
(4)   DHCP-Network-Subnet = 217.198.52.2/32
Trying sub-section dhcp DHCP-Offer {...}
(4)   dhcp DHCP-Offer {
(4)     update reply {
(4)       Packet-Dst-Port := 67
(4)     } # update reply = noop
(4)     [ok] = ok
(4)   } # dhcp DHCP-Offer = ok
(4) DHCP: response will be broadcast
         DHCP-Opcode = Server-Message
         DHCP-Hardware-Type = Ethernet
         DHCP-Hardware-Address-Length = 6
         DHCP-Hop-Count = 1
         DHCP-Transaction-Id = 2423755600
         DHCP-Number-of-Seconds = 0
         DHCP-Flags = 0
         DHCP-Client-IP-Address = 0.0.0.0
         DHCP-Your-IP-Address = 217.198.52.10
         DHCP-Server-IP-Address = 0.0.0.0
         DHCP-Gateway-IP-Address = 217.198.52.2
         DHCP-Client-Hardware-Address = 90:e2:ba:86:3c:24
         DHCP-Server-Host-Name = ""
         DHCP-Boot-Filename = ""
         DHCP-Subnet-Mask = 255.255.255.0
         DHCP-Router-Address = 217.198.52.1
         DHCP-Domain-Name-Server = 8.8.8.8
         DHCP-Domain-Name-Server = 8.8.4.4
         DHCP-Hostname = "lfc223"
         DHCP-IP-Address-Lease-Time = 1209823
         DHCP-DHCP-Server-Identifier = 217.198.54.101
         DHCP-Client-Identifier = 0x0190e2ba863c24
Sending DHCP-Offer Id 90779350 from 0.0.0.0:1067 to 255.255.255.255:1067
(4) Not sending reply to client.
(4) Finished request
(4) Cleaning up request packet ID 2423755600 with timestamp +89 due to done
Ready to process requests



The second part of the problem is that the offer that gets broadcasted 
on port 1067 goes out of the wrong interface - because the listen 
section for port 1067 doesn't have an interface configured by design as 
we're using it to receive packets from the upstream server via normal 
unicast routing.  A quick tcpdump shows that broadcast going out of the 
default route interface (which is, I suppose, one stage better than the 
kernel just throwing it away with a shrug).

My high level thoughts on "fixing" this is:

If we want to DHCP relay to another port then there needs to be a 
listener for that other port.  If we are relaying to a server not on the 
same LAN (likely) then this port cannot be bound to a particular interface.

In fr_dhcp_send (or its callers) there needs to be a way to switch to 
this listener's socket to relay DISCOVER and REQUEST towards the server; 
and there needs to be a way to switch from this socket back to the 
original interface-bound socket to relay OFFER and ACK/NAK towards the 
client.

Does this sound logical or have I missed something glaringly obvious?

I've already tested the upstream with a quick hack to just create a new 
socket and send the packet.  The downstream replies need some state 
saving whilst relaying DISCOVER or REQUEST to know what socket it was 
received on, so that when relaying the corresponding OFFER or ACK/NAK it 
can use that socket to transmit on.

Any clues as to how I can go about testing the second half of this - any 
pointers to how I should find out the socket to send on etc.?

>    We should arguably also support RFC  8357, which defines a "Remember Relay-Port" option.  If the option exists, the reply should be sent to the UDP source port of the packet.
> 
>    FreeRADIUS has always done that, because hard-coding port 67 is stupid.

Indeed.

Paul.




More information about the Freeradius-Users mailing list