Test DHCP Relaying with netlab « ipSpace.net blog

[ad_1]

After figuring out how DHCP relaying works, I decided to test it out in a lab. netlab has no DHCP configuration module (at the moment); the easiest way forward seemed to be custom configuration templates combined with a few extra attributes.

Lab Topology

This is how I set up the lab:

  • I created simple lab topology with DHCP server (IOSv), DHCP client (another IOSv), and a relaying node that could be anything that supports DHCP relaying.
lab topology

lab topology

Lab IP addressing

  Interface                  IPv4 address  Description
=========================================================
srv (10.0.0.1/32)
  GigabitEthernet0/1          10.1.0.2/30  srv -> relay

relay (10.0.0.2/32)
  GigabitEthernet0/1          10.1.0.1/30  relay -> srv
  GigabitEthernet0/2        172.16.0.2/24  relay -> user

user (10.0.0.3/32)
  GigabitEthernet0/1        172.16.0.3/24  user -> relay
  • I used interface attribute dhcp.client (boolean) on the client and dhcp.server (node name, string) on the relay node. This is how I defined those attributes:

Extra DHCP attributes

defaults.attributes:
  link.dhcp:
    client: bool
    server: str

DHCP client, relay, and server groups

groups:
  dhcp_server:
    members: [ srv ]
    module: [ ospf ]
    config: [ dhcp-server ]
    device: iosv
  dhcp_client:
    members: [ user ]
    config: [ dhcp-client ]
    device: iosv
  switch:
    members: [ relay ]
    module: [ ospf ]
    config: [ dhcp-relay ]
  • I’m running OSPF between DHCP relay and DHCP server. While that’s not how you’d set up a typical DHCP server, it allows me to relay DHCP requests to the DHCP server loopback interface.
  • Finally, I had to define the nodes and the links:

Nodes and links

nodes: [ srv, relay, user ]

links:
- relay-srv
- user:
    dhcp.client: True
  relay:
    dhcp.server: srv
  type: lan

I set the link type on the link between user and relay switch to LAN to ensure it gets a /24 prefix. Doing DHCP on a /30 prefix is boring.

As always, you can find the final topology file on GitHub.

Configuration Templates

Now for the fun part: custom configuration templates (also on GitHub). The client template was trivial:

  • Find interfaces with dhcp.client attribute
  • Remove static IPv4 address from them
  • Enable DHCP client on the interface

DHCP client configuration template

% for intf in interfaces if intf.dhcp.client is defined and intf.dhcp.client %
interface  intf.ifname 
 no ip address
 ip address dhcp
% endfor %

The relaying template was already a bit more convoluted. I had to find the interfaces with dhcp.server attribute and then find the loopback IP address of the DHCP server to use in the helper-address command. Interestingly, I could use identical template for Cisco IOSv and Arista vEOS.

DHCP relay configuration template

% for intf in interfaces if intf.dhcp.server is defined %
interface  intf.ifname 
 ip helper-address  hostvars[intf.dhcp.server].loopback.ipv4
% endfor %

Finally the DHCP server template. This one is a beast:

  • It iterates over all other nodes in the Ansible inventory and finds interfaces with dhcp.server attribute (relaying interfaces)
  • For each relaying interface, the template excludes its IPv4 address from the DHCP pool, and creates a corresponding pool with the relaying interface IPv4 address as the default router.
  • I also turned on debugging in the configuration template so I could log into the DHCP server and inspect the logs immediately after netlab up completes its job.

DHCP server configuration template

logging buffered
no service timestamp debug
!
do debug ip dhcp server packet
do debug ip dhcp server event
!
% for h,v in hostvars.items() %
%   for intf in v.interfaces if intf.dhcp.server is defined and intf.ipv4 is defined %
ip dhcp excluded-address  intf.ipv4
%   endfor %
% endfor %
!
% for h,v in hostvars.items() %
%   for intf in v.interfaces if intf.dhcp.server is defined and intf.ipv4 is defined %
!
ip dhcp pool p_ipaddr('network') 
 network ipaddr('network')   intf.ipv4 
 default-router ipaddr('address') 
%   endfor %
% endfor %

Here are the extra configuration commands generated by these templates:

Cisco IOS DHCP client configuration

interface GigabitEthernet0/1
 no ip address
 ip address dhcp

Cisco IOS DHCP relay configuration

interface GigabitEthernet0/2
 ip helper-address 10.0.0.1

Cisco IOS DHCP server configuration (including debugging commands)

logging buffered
no service timestamp debug
!
do debug ip dhcp server packet
do debug ip dhcp server event
!
ip dhcp excluded-address 172.16.0.2
!
!
ip dhcp pool p_172.16.0.0
 network 172.16.0.0 255.255.255.0
 default-router 172.16.0.2

You can find the final device configurations using Arista EOS on the DHCP relay in the GitHub netlab-example repository.

Does It Work?

You bet. Here’s the printout from the client router:

user#show dhcp lease
...
Temp IP addr: 172.16.0.3  for peer on Interface: GigabitEthernet0/1
Temp  sub net mask: 255.255.255.0
   DHCP Lease server: 10.1.0.2, state: 5 Bound
   DHCP transaction id: EAB
   Lease: 86400 secs,  Renewal: 43200 secs,  Rebind: 75600 secs
Temp default-gateway addr: 172.16.0.2
   Next timer fires after: 11:59:35
   Retry count: 0   Client-ID: cisco-5254.002c.2b7b-Gi0/1
   Client-ID hex dump: 636973636F2D353235342E303032632E
                       326237622D4769302F31
   Hostname: user

There seems to be a tiny glitch in the printout: the DHCP relay is forwarding DHCP requests to 10.0.0.1, but the DHCP client claims it’s talking with DHCP server with IP address 10.1.0.2 – the LAN interface IPv4 address of the DHCP server. The change of IP address is a perfect implementation of RFC 2131 which says:

If the server has received a message through a DHCP relay agent, the server SHOULD choose an address from the interface on which the message was recieved [sic] as the ‘server identifier’ (unless the server has other, better information on which to make its choice).

It’s nice to see things working exactly the way they should 😉

Fighting Repeatability Crisis One Lab at a Time

Want to run this lab on your own, or try it out with different devices? No problem:

Coming Up Next

Simple DHCP relaying works, but what about inter-VRF DHCP relaying? That’s the topic of the next blog post in this series.

[ad_2]

Source link