I had to make just a few changes to the DHCP relaying lab topology:
- DHCP server is running on CSR 1000v. IOSv DHCP server does not support subnet selection DHCP option and thus doesn’t work with relays that do inter-VRF DHCP relaying.
- I put the link between the DHCP client and DHCP relay into a VRF.
Changes in lab topology
groups: switch: members: [ relay ] module: [ ospf,vrf ] vrfs: client: links: - user: dhcp.client: True relay: dhcp.server: srv type: lan vrf: client
Lab IPv4 addressing
Interface IPv4 address Description ================================================================================ srv (10.0.0.1/32) GigabitEthernet2 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 (VRF: client) user (10.0.0.3/32) GigabitEthernet0/1 172.16.0.3/24 user -> relay
I configured VRF-aware DHCP relay (ip dhcp relay information option vpn) and VRF-aware DHCP pools (use vrf option in ip dhcp pool). The final device configurations (with Cisco IOSv as DHCP relay) are available in netlab-examples GitHub repository.
Cisco IOS VRF-aware DHCP relay configuration
ip dhcp relay information option vpn ! interface GigabitEthernet0/2 ip helper-address global 10.0.0.1
Cisco IOS VRF-aware DHCP server configuration
ip dhcp excluded-address vrf client 172.16.0.2 ! ip dhcp pool p_172.16.0.0 vrf client network 172.16.0.0 255.255.255.0 default-router 172.16.0.2
Does It Work?
It does… once I figured out IOSv DHCP server doesn’t work well with inter-VRF DHCP relaying and switched to CSR 1000v. Let’s go into some of the interesting (cleaned up) debugging printouts on the DHCP server. Full client and server logs are available on GitHub.
Debugging printout of DHCP server discovery
DHCPD: tableid for 10.1.0.2 on GigabitEthernet2 is 0 DHCPD: found subnet_info_addr 172.16.0.0 DHCPD: Giaddr from server-id-override suboption 172.16.0.2 DHCPD: client's VPN is client. DHCPD: DHCPDISCOVER received from client 0063.6973.636f.2d35.3235.342e.3030.3539.2e64.6664.352d.4769.302f.31 through relay 10.1.0.1. DHCPD: using server-id-override 172.16.0.2 DHCPD: Option 125 not present in the msg. DHCPD: egress Interfce GigabitEthernet2 DHCPD: unicasting BOOTREPLY for client 5254.0059.dfd5 to relay 10.1.0.1.
Here’s what’s going on behind the scenes.
- Specified its global IPv4 address (10.1.0.1) as the relay IPv4 address (giaddr)
- Used link selection sub-option (option 82 sub-option 5, defined in RFC 3527) to pass the information about the VRF IP subnet in which the client resides.
- Included client VPN information (option 82 sub-option 151, defined in RFC 6607)
- Set the desired server ID to its VRF IP address (option 82 sub-option 11, defined in RFC 5107)
DHCP server therefore assigned an IP address from 172.16.0.0 pool to the client, set the server ID to 172.16.0.2, and sent the reply to 10.1.0.1. Similar processing happens for all subsequent packets.
Let’s also check the client lease:
DHCP lease on the DHCP client
user#show dhcp lease ... Temp IP addr: 172.16.0.4 for peer on Interface: GigabitEthernet0/1 Temp sub net mask: 255.255.255.0 DHCP Lease server: 172.16.0.2, state: 5 Bound DHCP transaction id: 2030 Lease: 86400 secs, Renewal: 43200 secs, Rebind: 75600 secs Next timer fires after: 11:36:39 Retry count: 0 Client-ID: cisco-5254.0059.dfd5-Gi0/1 Client-ID hex dump: 636973636F2D353235342E303035392E 646664352D4769302F31 Hostname: user
As expected, the DHCP server IP address is the VRF IP address of the DHCP relay. All subsequent DHCP packets are thus sent to the DHCP relay and not directly to the DHCP server.
Vendor Interoperability Is Fun
I tried to test a combination of Arista vEOS DHCP relay (4.28.3M) and Cisco CSR DHCP server.
Arista vEOS VRF-aware DHCP relay configuration
ip dhcp relay information option ! interface Ethernet2 ip helper-address 10.0.0.1 vrf default
It didn’t work until I removed the vrf definition from the DHCP pool – here’s the relevant part of Cisco IOS XE debugging printout:
DHCPD: Bad VPN information type: 99. DHCPD: client's VPN is .
According to RFC 6607, the VPN selection sub-option (sub-option 151) starts with Virtual Subnet Selection Type (a binary zero for VRF name), and that’s what Cisco IOS XE expects.
Arista EOS 4.29.1F documentation (section 13.1.9 – DHCP Relay Across VRF) claims that the value of sub-option 151 created by EOS contains just the VPN name (without the intervening binary zero meaning “what follows is the VPN name”). Faced with
client as the value of sub-option 151, Cisco IOS understands the VSS Type to be 99 (ASCII value of
c), which is invalid. The DHCP server on CSR 1000v thus ignores sub-option 151.
- Inter-VRF DHCP relaying is complex – it’s trying to make a simple protocol do things it was never designed to do. We’ll get back to the fun implications of this Rube Goldberg stack of kludges when we get to redundant designs.
- Two or three sub-options of option-82 are involved in inter-VRF DHCP relaying, and DHCP relays and servers have to support them perfectly for the whole thing to work.
- In particular, the DHCP relay and DHCP server MUST support server identifier override sub-options of option 82 and MUST support the same way of identifying the client subnet.
- There are at least two ways of specifying the client subnet in DHCP – link selection sub-option of option 82 and subnet selection option (option 118). In the ideal world, all relay agents and servers would use link selection sub-option – after all, it was designed to be used in DHCP relaying scenarios. I wouldn’t be surprised if the networking vendors fail to reach that level of consistency.
- Virtual Subnet Selection Suboption (option 151) it not needed for inter-VRF DHCP relaying, but is required to implement multi-tenant DHCP with overlapping address pools. At least one vendor implemented it incorrectly.
I’m positive that you’ve experienced your share of horror stories on other platforms. Please share them in the comments!
Reference: Configuration Templates
I had to make the DHCP relay and DHCP server configuration templates VRF-aware to make this lab work.
DHCP relay has to use the global parameter of the ip helper-address. It also has to be configured to insert VPN sub-option into Relay Agent DHCP option (ip dhcp relay information option vpn):
DHCP relay configuration template
% for intf in interfaces if intf.dhcp.server is defined and intf.vrf is defined % % if loop.first % ip dhcp relay information option vpn % endif % % endfor % ! % for intf in interfaces if intf.dhcp.server is defined % ipaddr('address') % interface intf.ifname % if intf.vrf is defined % ip helper-address global helper % else % ip helper-address helper % endif % % endfor %
All I had to do in the DHCP server template was to add the vrf option to ip dhcp excluded-address and ip dhcp pool configuration commands:
DHCP relay server 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 % if intf.vrf is defined %vrf intf.vrf % endif %ipaddr('address') % 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') % if intf.vrf is defined % vrf intf.vrf % endif % network intf.ipv4 intf.ipv4 default-router ipaddr('address') % endfor % % endfor %
Try It Out!
Want to run this lab on your own, or try it out with different devices? No problem:
Coming Up Next
So far so good: simple DHCP relaying works, as does (with a few quirks) inter-VRF DHCP relaying. Will they still work in VXLAN segments? That’s the topic of the next blog post in this series.