Showing results for 
Search instead for 
Did you mean: 
F5 Employee
F5 Employee
Prepared with Mark Quevedo, F5 Principal Software Engineer
May, 2020

Sectional Navigation links
Important Version Notes   ||  Installation Guide   ||  What Is Going On Here?   ||  Parameters You Set In Your APM Access Policy   ||  Results of DHCP Request You Use in Access Policy   ||  Compatibility Tips and Troubleshooting

Alert: This solution currently does not install on BIG-IP v.16+ - we are currently investigating solutions


Ordinarily you assign an IP address to the “inside end” of an APM Network Tunnel (full VPN connection) from an address Lease Pool, from a static list, or from an LDAP or RADIUS attribute.

However, you may wish to assign an IP address you get from a DHCP server.  Perhaps the DHCP server manages all available client addresses.  Perhaps it handles dynamic DNS for named client workstations.  Or perhaps the DHCP server assigns certain users specific IP addresses (for security filtering).  Your DHCP server may even assign client DNS settings as well as IP addresses.

APM lacks DHCP address assignment support (though f5's old Firepass VPN had it ).  We will use f5 iRules to enable DHCP with APM.  We will send data from APM session variables to the DHCP server so it can issue the “right” IP address to each VPN tunnel based on user identity, client info, etc.

Important Version Notes

Version v4b includes important improvements and bug fixes.  If you are using an older version, you should upgrade.  Just import the template with “Overwrite existing templates” checked, then “reconfigure” your APM-DHCP Application Service—you can simply click “Finished” without changing any options to update the iRules in place.

Installation Guide

First install the APM-DHCP iApp template (file DHCP_for_APM.tmpl). Create a new Application Service as shown (choose any name you wish).  Use the iApp to manage the APM-DHCP virtual servers you need.  (The iApp will also install necessary iRules.)

You must define at least one APM-DHCP virtual server to receive and send DHCP packets.  Usually an APM-DHCP virtual server needs an IP address on the subnet on which you expect your DHCP server(s) to assign client addresses.  You may define additional APM-DHCP virtual servers to request IP addresses on additional subnets from DHCP.  However, if your DHCP server(s) support subnet-selection (see session.dhcp.subnet below) then you may only need a single APM-DHCP virtual server and it may use any IP that can talk to your DHCP server(s).
It is best to give each APM-DHCP virtual server a unique IP address but you may use an BIG-IP Self IP as per SOL13896 .  Ensure your APM and APM-DHCP virtual servers are in the same TMOS Traffic Group (if that is impossible set TMOS db key tmm.sessiondb.match_ha_unit to false).
Ensure that your APM-DHCP virtual server(s) and DHCP server(s) or relay(s) are reachable via the same BIG-IP route domain.  Specify in your IP addresses any non-zero route-domains you are using (e.g., “”)—this is essential.

(It is not mandatory to put your DHCP-related Access Policy Items into a Macro—but doing so makes the below screenshot less wide!)


Into your APM Access Policy, following your Logon Page and AD Auth (or XYZ Auth) Items (etc.) but before any (Full/Advanced/simple) Resource Assign Item which assigns the Network Access Resource (VPN), insert both Machine Info and Windows Info Items.  (The Windows Info Item will not bother non-Windows clients.)

Next insert a Variable Assign Item and name it “DHCP Setup”.  In your “DHCP Setup” Item, set any DHCP parameters (explained below) that you need as custom session variables.  You must set session.dhcp.servers.  You must also set session.dhcp.virtIP to the IP address of an APM-DHCP virtual server (either here or at some point before the “DHCP_Req” iRule Event Item).

Finally, insert an iRule Event Item (name it “DHCP Req”) and set its Agent ID to DHCP_req.  Give it a Branch Rule “Got IP” using the expression “expr {[mcget {session.dhcp.address}] ne ""}” as illustrated. You must attach iRule ir-apm-policy-dhcp to your APM virtual server (the virtual server to which your clients connect).

Neither the Machine Info Item nor the Windows Info Item is mandatory.  However, each gathers data which common DHCP servers want to see.  By default DHCP_req will send that data, when available, to your DHCP servers.

See below for advanced options:  DHCP protocol settings, data sent to DHCP server(s), etc.  Typically your requests will include a user identifier from session.dhcp.subscriber_ID and client (machine or connection) identifiers from other parameters.

The client IP address assigned by DHCP will appear in session.dhcp.address.  By default, the DHCP_req iRule Event handler will also copy that IP address into session.requested.clientip where the Network Access Resource will find it.  You may override that behavior by setting session.dhcp.copy2var (see below).

Any “vendor-specific information” supplied by the DHCP server1 (keyed by the value of session.dhcp.vendor_class) will appear in variables session.dhcp.vinfo.N  where N is a tag number (1-254).  You may assign meanings to tag numbers.

Any DNS parameters the DHCP server supplies2 are in session.dhcp.dns_servers and session.dhcp.dns_suffix.   If you want clients to use those DNS server(s) and/or DNS default search domain, put the name of every Network Access Resource your Access Policy may assign to the client into the session.dhcp.dns_na_list option.

NB:  this solution does not renew DHCP address leases automatically, but it does release IP addresses obtained from DHCP after APM access sessions terminate.3 Please configure your DHCP server(s) for an address lease time longer than your APM Maximum Session Timeout.

Do not configure APM-DHCP virtual servers in different BIG-IP route domains so they share any part of a DHCP client IP range (address lease pool).  For example, do not use two different APM-DHCP virtual servers and with one DHCP client IP range—  APM-DHCP won’t recognize when two VPN sessions in different route domains get the same client IP from a non-route-domain-aware DHCP server, so it may not release their IP’s in proper sequence.

This solution releases DHCP address leases for terminated APM sessions every once in a while, when a new connection comes in to the APM virtual server (because the BIG IP only executes the relevant iRules on the “event” of each new connection).  When traffic is sparse (say, in the middle of the night) there may be some delay in releasing addresses for dead sessions.

If ever you think this solution isn’t working properly, be sure to check the BIG IP’s LTM log for warning and error messages.

DHCP Setup (a Variable Assign Item) will look like:

Put the IP of (one of) your APM-DHCP virtual server(s) in session.dhcp.virtIP.

Your DHCP server list may contain addresses of DHCP servers or relays.  You may list a directed broadcast address (e.g., “”) instead of server addresses but that will generate extra network chatter.

To log information about DHCP processing for the current APM session you may set variable session.dhcp.debug to true (don’t leave it enabled when not debugging).

DHCP Req (an iRule Event Item) will look like:


Note DHCP Req branch rules:


If DHCP fails, you may wish to warn the user:

(It is not mandatory to Deny access after DHCP failure—you may substitute another address into session.requested.clientip or let the Network Access Resource use a Lease Pool.)

What is going on here?

We may send out DHCP request packets easily enough using iRules’ SIDEBAND functions, but it is difficult to collect DHCP replies using SIDEBAND.4 Instead, we must set up a distinct LTM virtual server to receive DHCP replies on UDP port 67 at a fixed address. We tell the DHCP server(s) we are a DHCP relay device so replies will come back to us directly (no broadcasting).5 For a nice explanation of the DHCP request process see At this time, we support only IPv4, though adding IPv6 would require only toil, not genius.

By default, a DHCP server will assign a client IP on the subnet where the DHCP relay device (that is, your APM-DHCP virtual server) is homed. For example, if your APM-DHCP virtual server’s address were the DHCP server would typically lease out a client IP on subnet  Moreover, the DHCP server will communicate directly with the relay-device IP so appropriate routes must exist and firewall rules must permit.  If you expect to assign client IP’s to APM tunnel endpoints on multiple subnets you may need multiple APM-DHCP virtual servers (one per subnet).  Alternatively, some but not all DHCP servers6 support the rfc3011 “subnet selection” or rfc3527 “subnet/link-selection sub-option” so you can request a client IP on a specified subnet using a single APM-DHCP virtual server (relay device) IP which is not homed on the target subnet but which can communicate easily with the DHCP server(s):  see parameter session.dhcp.subnet below.

NOTE: The subnet(s) on which APM Network Access (VPN) tunnels are homed need not exist on any actual VLAN so long as routes to any such subnet(s) lead to your APM (BIG-IP) device.  Suppose you wish to support 1000 simultaneous VPN connections and most of your corporate subnets are /24’s—but you don’t want to set up four subnets for VPN users.  You could define a virtual subnet—say,—tell your DHCP server(s) to assign addresses from thru to clients, put an APM-DHCP virtual server on, and so long as your Layer-3 network knows that your APM BIG-IP is the gateway to, you’re golden.

When an APM Access Policy wants an IP address from DHCP, it will first set some parameters into APM session variables (especially the IP address(es) of one or more DHCP server(s)) using a Variable Assign Item, then use an iRule Event Item to invoke iRule Agent DHCP_req in ir apm policy dhcp.  DHCP_req will send DHCPDISCOVERY packets to the specified DHCP server(s).  The DHCP server(s) will reply to those packets via the APM-DHCP virtual-server, to which iRule ir apm dhcp must be attached.  That iRule will finish the 4-packet DHCP handshake to lease an IP address. DHCP_req handles timeouts/retransmissions and copies the client IP address assigned by the DHCP server into APM session variables for the Access Policy to use.

We use the APM Session-ID as the DHCP transaction-ID XID and also (by default) in the value of chaddr to avert collisions and facilitate log tracing.

Parameters You Set In Your APM Access Policy

Required Parameters

  • IP address of an APM-DHCP virtual-server (on UDP port 67) with iRule ir-apm-dhcp.
  • This IP must be reachable from your DHCP server(s).
  • A DHCP server will usually assign a client IP on the same subnet as this IP, though you may be able to override that by setting session.dhcp.subnet.
  • You may create APM-DHCP virtual servers on different subnets, then set session.dhcp.virtIP in your Access Policy (or branch) to any one of them as a way to request a client IP on a particular subnet.
  • No default.
  • Examples (“Custom Expression” format):  expr {""} or expr {""}
  • A TCL list of one or more IP addresses for DHCP servers (or DHCP relays, such as a nearby IP router).
  • When requesting a client IP address, DHCP packets will be sent to every server on this list.
  • NB:  IP broadcast addresses like may be specified but it is better to list specific servers (or relays).
  • Default: none.
  • Examples (“Custom Expression” format):
    • expr {[list "" ""]}  or
    • expr {[list ""]}

Optional Parameters (including some DHCP Options)

NOTE:  when you leave a parameter undefined or empty, a suitable value from the APM session environment may be substituted (see details below).  The defaults produce good results in most cases.  Unless otherwise noted, set parameters as Text values.  To exclude a parameter entirely set its Text value to '' [two ASCII single-quotes] (equivalent to Custom Expression return {''} ).  White-space and single-quotes are trimmed from the ends of parameter values, so '' indicates a nil value.

It is best to put “Machine Info” and “Windows Info” Items into your Access Policy ahead of your iRule Event “DHCP_req” Item (both are safe for all clients).

  • Set to 1 or “true” to log DHCP-processing details for the current APM session.
  • Default:  false.
  • Leave this undefined or empty (or set to “false”) to use APM defaults (better in nearly all cases).
  • Set to “true” to activate “Firepass mode” which alters the default values of several other options to make DHCP messages from this Access Policy resemble messages from the old F5 Firepass product.
  • Leave this undefined or empty (the default) and the client IP address from DHCP will be copied into the Access Policy session variable session.requested.clientip, thereby setting the Network Access (VPN) tunnel’s inside IP address.  To override the default, name another session variable here or set this to (Text) '' to avert copying the IP address to any variable.
  • To set the client's DNS server(s) and/or DNS default search domain from DHCP, put here a Custom Expression TCL list of the name(s) of the Network Access Resource(s) you may assign to the client session.
  • Default:  none.
  • Example:  expr {[list "/Common/NA" "/Common/alt-NA"]}
  • Set to “true” to set the DHCP broadcast flag (you almost certainly should not use this).
Option 60
  • A short string (32 characters max) identifying your VPN server.
  • Default: “f5 APM”.
  • Based on this value the DHCP server may send data to session.dhcp.vinfo.N (see below).
Option 77
  • A Custom Expression TCL list of strings by which the DHCP server may recognize the class of the client device (e.g., “kiosk”).
  • Default:  none (do not put '' here).
  • Example:  expr {[list "mobile" "tablet"]}
Option 61
  • A unique identifier for the remote client device. Microsoft Windows DHCP servers expect a representation of the MAC address of the client's primary NIC.
  • If left undefined or empty the primary MAC address discovered by the Access Policy Machine Info Item (if any) will be used.
  • If no value is set and no Machine Info is available then no client_ID will be sent and the DHCP server will distinguish clients by APM-assigned ephemeral addresses (in session.dhcp.hwcode).
  • If you supply a client_ID value you may specify a special code, a MAC address, a binary string, or a text string.
  • Set the special code “NONE” (or '') to avoid sending any client_ID, whether Machine Info is available or not.
  • Set the special code “XIDMAC” to send a unique MAC address for each APM VPN session—that will satisfy DHCP servers desiring client_ID‘s while averting IP collisions due to conflicting Machine Info MAC’s like Apple Mac Pro’s sometimes provide.
  • A value containing twelve hexadecimal digits, possibly separated by hyphens or colons into six groups of two or by periods into three groups of four, will be encoded as a MAC address.
  • Values consisting only of hexadecimal digits, of any length other than twelve hexits, will be encoded as a binary string.
  • A value which contains chars other than [0-9A-Fa-f] and doesn't seem to be a MAC address will be encoded as a text string.
  • You may enclose a text string in ASCII single-quotes (') to avert interpretation as hex/binary (the quotes are not part of the text value).
  • On the wire, MAC-addresses and text-strings will be prefixed by type codes 0x01 and 0x00 respectively; if you specify a binary string (in hex format) you must include any needed codes. 
  • Default:  client MAC from Machine Info, otherwise none.
  • Example (Text value): “08-00-2b-2e-d8-5e”.
Option 12 
  • A hostname for the client.
  • If left undefined or empty, the short computer name discovered by the APM Access Policy Windows Info Item (if any) will be used.
Sub-option 6 of Option 82 
  • An identifier for the VPN user.
  • If undefined or empty, the value of APM session variable session.logon.last.username will be used (generally the user's UID or SAMAccountName).
Sub-option 1 of Option 82
  • An identifier for the “circuit” or network endpoint to which client connected.
  • If left undefined or empty, the IP address of the (current) APM virtual server will be used.
Sub-option 2 of Option 82
  • An identifier for the client's end of the connection.
  • If left undefined or empty, the client’s IP address + port will be used.
Option 118
Sub-option 5 of Option 82
  • The address (e.g., of the IP subnet on which you desire a client address.
  • With this option you may home session.dhcp.virtIP on another (more convenient) subnet.  MS Windows Server 2016 added support for this but some other DHCP servers still lack support.
  • Default: none.
  • Controls content of BOOTP htype, hlen, and chaddr fields.
  • If left undefined or empty, a per-session value optimal in most situations will be used (asserting that chaddr, a copy of XID, identifies a “serial line”).
  • If your DHCP server will not accept the default, you may set this to “MAC” and chaddr will be a locally-administered Ethernet MAC (embedding XID).
  • When neither of those work you may force any value you wish by concatenating hexadecimal digits setting the value of htype (2 hexits) and chaddr (a string of 0–32 hexits).  E.g., a 6-octet Ethernet address resembles “01400c2925ea88”.
  • Most useful in the last case is the MAC address of session.dhcp.virtIP (i.e., a specific BIG-IP MAC) since broken DHCP servers may send Layer 2 packets directly to that address.


Results of DHCP Request For Use In Access Policy

session.dhcp.address  <-- client IP address assigned by DHCP!
session.dhcp.server, session.dhcp.relay
session.dhcp.expires, session.dhcp.issued, session.dhcp.rebind, session.dhcp.renew
session.dhcp.dns_servers, session.dhcp.dns_suffix
session.dhcp.xid, session.dhcp.hex_client_id, session.dhcp.hwx

If a DHCP request succeeds the client IP address appears in session.dhcp.address. If that is empty look in session.dhcp.message for an error message. The IP address of the DHCP server which issued (or refused) the client IP is in session.dhcp.server (if session.dhcp.relay differs then DHCP messages were relayed). Lease expiration time is in session.dhcp.expires.  Variables session.dhcp.{lease, rebind, renew} indicate the duration of the address lease, plus the rebind and renew times, in seconds relative to the clock value in session.dhcp.issued (issued time).

See session.dhcp.vinfo.N  where N is tag number for Option 43 vendor-specific information.
If the DHCP server sends client DNS server(s) and/or default search domain, those appear in session.dhcp.dns_servers and/or session.dhcp.dns_suffix.

To assist in log analysis and debugging, session.dhcp.xid contains the XID code used in the DHCP request.  The client_ID value (if any) sent to the DHCP server(s) is in session.dhcp.hex_client_id.  The DHCP request’s htype and chaddr values (in hex) are concatenated in session.dhcp.hwx.

Compatibility Tips and Troubleshooting

Concern Response
My custom parameter seems to be ignored. 
You should set most custom parameters as Text values (they may morph to Custom Expressions).
My users with Apple Mac Pro’s sometimes get no DHCP IP or a conflicting one.
A few Apple laptops sometimes give the Machine Info Item bogus MAC addresses.  Set session.dhcp.client_ID to “XIDMAC“ to use unique per-session identifiers for clients.
After a VPN session ends, I expect the very next session to reuse the same DHCP IP but that doesn’t happen. Many DHCP servers cycle through all the client IP’s available for one subnet before reusing any.  Also, after a session ends APM-DHCP takes a few minutes to release its DHCP IP.
When I test APM-DHCP with APM VE running on VMware Workstation, none of my sessions gets an IP from DHCP. VMware Workstation’s built-in DHCP server sends bogus DHCP packets.  Use another DHCP server for testing (Linux dhcpd(8) is cheap and reliable).
I use BIG-IP route domains and I notice that some of my VPN clients are getting duplicate DHCP IP addresses. Decorate the IP addresses of your APM-DHCP virtual servers, both in the iApp and in session.dhcp.virtIP, with their route-domain ID’s in “percent notation” like “”.
APM-DHCP is not working. Double-check your configuration.  Look for errors in the LTM log.  Set session.dhcp.debug to “true” before trying to start a VPN session, then examine DHCP debugging messages in the LTM log to see if you can figure out the problem.
Even after looking at debugging messages in the log I still don’t know why APM-DHCP is not working.  Run “tcpdump –ne -i 0.0 -s0 port 67” to see where the DHCP handshake fails.
Are DISCOVER packets sent?
Do any DHCP servers reply with OFFER packets?
Is a REQUEST sent to accept an OFFER?
Does the DHCP server ACK that REQUEST?
If you see an OFFER but no REQUEST, check for bogus multicast MAC addresses in the OFFER packet.
If no OFFER follows DISCOVER, what does the DHCP server’s log show?
Is there a valid zone/lease-pool for you?
Check the network path for routing errors, hostile firewall rules, or DHCP relay issues.


  1. In DHCP Option 43 (rfc2132).
  2. In DHCP Options 6 and 15 (rfc2132).
  3. Prior to version v3h, under certain circumstances with some DHCP servers, address-release delays could cause two active sessions to get the same IP address.
  4. And even more difficult using [listen], for those of you in the back of the room.
  5. A bug in some versions of VMware Workstation’s DHCP server makes this solution appear to fail. The broken DHCP server sends messages to DHCP relays in unicast IP packets encapsulated in broadcast MAC frames.  A normal BIG-IP virtual server will not receive such packets.
  6. As of Winter 2017 the ISC, Cisco, and MS Windows Server 2016 DHCP servers support the subnet/link selection options but older Windows Server and Infoblox DHCP servers do not.

Supporting Files - Download attached ZIP File Here.

F5 Employee
F5 Employee

Is there any plan to extend to DHCPv6 or ND6?

F5 Employee
F5 Employee

  Are you referring to the iApp & sample code content or underlying parameters and commands?

Hi. Other than me that experience it does not release IP's? Tested in 2 different environments on v13x and v14x.


Any suggestions would be appreciated as we experience overlapping IPs from time to time, when a user makes a new session and is getting a IP from an earlier session. then max session time will exceed the lease time in same cases.



We setup the DHCP like described.

We have the issue that the DHCP sends a Discover with a Client HW address with a length of 4 bytes instead of 6 bytes.

Our DHCP does not accept wrong Client HW address.


Does someone already had this issue?

Do you have a Solution?



We are testing this solution to handle our DHCP requests but have run into an issue where duplicate IPs are being distributed. 


Here is the scenario:

User1 connects and gets an IP address.

For whatever reason user1 disconnects, which queues up a DHCP release for their IP on the APM, and then before anybody else connects user1 reconnects and gets the same IP address they had previously. For some reason when user1 reconnects this does not trigger the APM to release the “DHCP release” for user1’s IP address.

User2 connects which triggers the DHCP release for user1’s IP address and user2 gets their own IP address

User3 connects and is assigned user1’s IP address, even though user1 is still using it, because DHCP thinks it is available.


It is mentioned in the article that “You can force the release of unused leases simply by configuring a BIG-IP service monitor to connect to your APM virtual server periodically.” I tried this with a health monitor, HTTP and icmp, checking the pool with the virtual server in it every 5 seconds to force the release of the queued up “DHCP releases” but that didn’t seem to work. I figured every 5 seconds would be plenty of time to release the address of a user who disconnects and reconnects right away.


Can you elaborate on this solution from the article:” You can force the release of unused leases simply by configuring a BIG-IP service monitor to connect to your APM virtual server periodically—the monitor doesn’t need to log in or anything, it’s just used to provoke a “connection event” to force the iRule to run.”

Or can you provide another solution to forcing the queued up “DHCP releases” to be releases?  


Hi  :


Thank you for the clear problem description. I will explain in detail below, but to summarize first, in the APM-DHCP version you have (v3d+) you have discovered one outright error in the documentation and one awkwardness (not a strictly a bug) in the code that handles DHCPRELEASE. (The documentation error is fixed in version v3f and later.)


Since you described two different users getting the same IP address, here is an simple, instant fix for you: in your Access Policy, in your DHCP_Setup Variable Assign Item, add the following setting

session.dhcp.client_ID = '' (that is, two single-quotes, no spaces)


That change will almost certainly fix your current problem because you are not assigning IP's to specific users (if you were, then User1 and User2 would not get the same IP, regardless of the problem with delayed DHCPRELEASE messages).


Right now your DHCP server gives User1 the same IP for both his first and second APM VPN sessions because your DHCP server sees the MAC address of his device (laptop or whatever) in the DHCP requests for both of his VPN sessions. The DHCP server thinks "it's the same client device, might as well give it the same IP address." When you set session.dhcp.client_ID to '' (two single-quotes) as I recommend, APM-DHCP will start sending your DHCP server a unique client-device identifier for each session, so the DHCP server will give User1 different IP's for his first and second sessions. That way User2 will not get an IP which conflicts with User1's IP even when the DHCPRELEASE for User1's first session is tardy.


If you actually did wish to tie specific static IP addresses to specific users then the quick fix would not be applicable, but the problem would never appear (because each user would always get his/her own static IP). However, for F5 customers whose DHCP servers reserve certain IP's for certain groups of users there could still be a problem...


Here's the long explanation. FIrst, the error in the documentation. I regret that you were misled. That advice-- to use a monitor to prompt release of DHCP IP's-- has been outdated and ineffective since I changed the actual code in the solution several years ago. I just failed to notice and remove that line or two in the doc at that time.


Second, the awkwardness in the code. Currently (that is, up to and including version v3g -- I do realize you have v3d+) for good reasons the code which sends DHCPRELEASE messages after APM VPN sessions end can delay up to four minutes even on a busy APM device, and will send the DHCPRELEASE for a terminated session even if the actual IP has since been assigned to a new session.


The reason for the delay in sending DHCPRELEASE after a session ends is that no iRule can send any messages just at the moment when a VPN session ends. APM does fire an iRule event then called ACCESS_SESSION_CLOSED, but no network messages can be sent from that event, nor can any shared-memory locations be updated. The APM-DHCP solution has to wait for some other iRule event to check which APM sessions have recently ended and then send DHCPRELEASE messages for those recently-terminated sessions.


APM-DHCP uses the CLIENT_ACCEPTED event for the next client connection to clean up after recently-ended sessions. However, APM-DHCP cannot just transmit each DHCPRELEASE message from CLIENT_ACCEPTED. Every possible local-and-remote IP:port combination is mapped to just one of several TMM processes on the BIG-IP by the "DAG" (traffic disaggregator) which distributes network connections evenly to TMM processes. That means that only one TMM can actually send DHCP messages from the BIG-IP's UDP port 67 (on the proper IP address) to a particular DHCP server's port 67. Therefore, APM-DHCP queues up DHCPRELEASE messages to be sent from the "right" TMM the next time that TMM handles some DHCPREQUEST traffic to the target DHCP server (many customer environments have multiple DHCP servers-- this is normal-- and each one may be mapped to a different TMM process).


Worse yet, if APM-DHCP were actually to check on all VPN sessions upon every client connection it would harm the performance of busy APM devices. Suppose that some (rather modest) APM device supports 1,500 simultaneous VPN sessions and the average duration of each session is 4 hours. Then by Little's Law that APM device accepts about ten connections per second on average. If APM-DHCP tried to poll APM for the status of 1,500 sessions 10 times per second neither the APM administrator nor the APM users would be pleased. To avert performance problems, APM-DHCP currently polls for the status of any given session only once every four minutes. That means the average delay between a session ending and APM-DHCP noticing is two minutes. Awkwardly, per your report that seems to be enough time for a user to log in, drop his session, then log in again before APM-DHCP notices his first session has ended-- meaning the DHCPRELEASE for his first session may be sent out after his second session has begun.


But wait (says Ron Popeil), there's more! Even when APM-DHCP is finally about to transmit a DHCPRELEASE message, it (currently) has no good way to know whether the client IP inside that message has been leased to a new VPN session. APM-DHCP knows the session-ID of the old, closed session and the IP that the old session had, but there is no easy way for APM-DHCP to ask APM whether any active session (with an new, different session-ID) is using that IP.


To avert the race condition you described  it will be necessary for APM-DHCP to track all the DHCP IP's in use. It could do that by rummaging through the DHCPRELEASE messages it has stashed waiting for their corresponding sessions to end, but that would be inefficient since those are indexed by session-ID, not IP. I will look into this and try to supply an update to APM-DHCP that alleviates the difficulty you described.


Hi  ,


I regret that I did not become aware of your inquiry sooner, but here's the answer anyway 🙂.


You seem to have missed the explanation of client hardware addresses on page 11 of the APM-DHCP documentation. Some DHCP servers (though not any of the popular ones) demand six-octet hardware addresses. You seem to have such a DHCP server. APM-DHCP has always been able to work with such DHCP servers...


Just set the value of variable session.dhcp.hwcode to "MAC" in your Access Policy's DHCP_Setup Variable Assign Item. When you do that, APM-DHCP will generate and send six-octet hardware addresses rather than four-octet ones.


(You may wonder why six-octet addresses are not the default. The main reason is to fend off attempts by very old or broken DHCP servers or promiscuous network monitoring devices to send Ethernet packets directly to any six-octet "hardware addresses" they see in DHCP requests. Sadly, there are still devices lurking on corporate networks which don't understand DHCP relay.)


Hi  ,


It sounds like you hit the same problem as  , in which the DHCPRELEASE for one session goes to the DHCP server after it has issued the same IP to the same client for a second (different) session, which causes the DHCP server to think the second session has released that IP, so the DHCP server then issues that IP to a different client (even though the first client is actually still using it), causing an IP conflict.


Until a new version of the APM-DHCP iApp appears with a fix, try this very easy workaround: in your Access Policy's DHCP_Setup Variable Assign Item, set session.dhcp.client_ID to [a "Text" value of] '' (two single quotes, no spaces). That will cause APM-DHCP to send the DHCP server a unique client ID for each VPN session which should avert the duplicate-leasing of IP's due to DHCPRELEASE delays. You can read a long explanation in one of the comments above.

Hi @M Quevedo thanks for your response. From my understanding that variable is just setting the MAC address as an identifier, but this is already working. After I wrote on this thread I found that the issue was only happening on OSX and further digging showed it was only happening on Mac Pro with touchbars. Sometimes Macs presents their touchbar adapter as its primary NIC and since Apple has chosen to use the same MAC addr for every single touchbar the Mac addresses collide. I have not found a workaround for this, as changing the irule to use the 2nd NIC on the list will do the same as it seems random how the Mac presents its NICs and therefor I will still see the issues by changing the iRule to use the second NIC. It is a very strange behavior by Apple.


Thanks very much @M Quevedo,

That was very informative information as to what is going on behind the scenes. I tried setting session.dhcp.client_ID to value '' in my DHCP_Setup Variable Assign Item but it doesn't seem to be working, see attached for one example of how i was trying to define the variable. Am i doing this wrong?


(Note: this answer has been revised to help later readers. The original poster did not have the benefit of this later edit.)


 , don’t put the word “value” in the “Custom Expression,” just put two single-quotes in a row in a "Text" value (not a "Custom Expression").



 I wrote this solution so I understand it pretty well. I encourage you to follow my suggestion. If you set session.dhcp.client_ID to ‘’ then the solution will ignore all MAC addresses from clients. It will send the DHCP server a unique identifier for each session. The DHCP server will accept that and issue each client a different IP. (That means the same client device may get a different IP on Tuesday than on Monday, but that is better than an IP collision.)



  Okay but when I set it I see no difference, it is still using the clients MAC address, the only variable I see set that looks like it, is session.dhcp.hex_client_id but this has also set the MAC. Any ideas? And big thanks for your support. 0691T000008svICQAY.png






 Until I can look into this further (I am not at PC right now, it is midnight in Seattle) please try this: for a test, remove Machine Info Item from your Access Policy. It is only used to get MAC addresses from clients, and if it is missing then APM-DHCP solution cannot possibly send those MAC’s to DHCP server.

25 minutes

 Then it is just failing, nothing is being set and the DHCP sends a DHCPNACK.



a big thanks from me also for your support on this. If we could get this working it would be a huge WIN!!

Unfortunately I am seeing the same results as . I removed the work "value" from the "Custom Expression" but that didn't help, My client got the same IP address over multiple disconnects/reconnects. I removed the Machine Info item from the Access Policy and that just made it fail with DHCP returning the DHCPNACK.


Hi  and  ,


THE CORRECT ANSWER IS: You have to set the value of session.dhcp.client_ID to a "Text" value of '' (two-single-quotes). If the type of the value remains "Custom Expression" then two single-quotes standing-alone are ignored (to input a valid "Custom Expression" one would have to put return {''} instead).




I do not know (yet!) why setting session.dhcp.client_ID to '' (i.e., two single-quotes) fails to prevent sending a client MAC address from the Machine Info Item as "client ID" (DHCP Option 61) on your respective BIG-IP's. That certainly used to work and the iRules code hasn't changed so it ought to still work.


Leaving aside the single-quote problem for a moment, it seems that your DHCP servers demand that Option 61 "client ID" be populated in DHCP requests. That is not mandated by the DHCP RFC's, it is just some administrative policy in your respective environments.


Anyway, you need Option 61 to be populated but you also need it to be different for every client and every session to prevent duplicate IP leases (for  you need this until I can ship a new version of the solution which handles the User1-login-logout-login_again vs. User2-login race-condition).


So please, each of you try this: In your DHCP_Setup Variable Assign Item set session.dhcp.client_ID to the following...


expr { "0AF5[string range [mcget {session.user.sessionid}] end-7 end]" }

(Do not add any space(s) around the double-quotes (") or between the "5" and the left-square-bracket "[" inside that expression. The code-snippet line-number "1" that appears on the left is not part of the expression, which starts with "expr".)


The meaning of this is to set client_ID to a unique "locally-administered MAC address" for each APM session. The DHCP server will think each session comes from a different client device. Since you are not reserving specific IP's for specific clients based on MAC address, this should not cause any conflicts.


Please let me know if this helps!


, It's late here but needed to give this a quick try and it looks like it's working. I applied your suggestion and did three disconnects/reconnects with my client and received a different IP address each time. I will do some more extensive testing tomorrow and let you know the results. Thanks again for your help with this issue, you ROCK!!

 It works here as well, tested 4 times, which is awesome! - My concern is that I don't see any on of them being released, tried waiting 6 minutes before a new connect and they are still all leased out. The reason for my concern is this environment supports around 3300 users, which potentially could use a great deal of IPs depending on their behavior. So do you have any idea of what could be wrong, since no IPs is released?


 I don’t have enough information to say why you might not be seeing addresses getting released. Do you mean your DHCP server shows all the IP’s are still leased-out, or are you just not seeing them get reused? The DHCP server may just be cycling through the available range before reissuing IP’s.


If the situation persists, to debug it I will ask for a QKVIEW with debug logs from APM-DHCP (can be enabled in iApp) and a packet capture (tcpdump). You can contact your F5 sales team to facilitate.

 Just a update, the IPs leased by the sessionID constructed MACs has disappeared so seems the release is working for those, but not the ones leased with the original MAC of the PC. So your WA seems to be solving both issues. I will do some more testing. Thanks!


Edit: Some additional testing shows that a session there is still active disappears on the DHCP server. So that will for sure give issues with duplicate addresses.


Edit 2: I see new leases appears in the DHCP with only 1 hour lease, despite the pool is set to 8 days. Strange why this is changing when using your WA. I will see if I can dig into that.


Edit 3: I found the reason, but I haven't found the why. The DHCP in this case is running in failover hotswap. So for some reason when setting this variable the client only gets offered 1 hour lease (Maximum Client Lead Time set on the failover relationship). I have confirmed this by changing it from 1 hour to 8 and voila the client gets a 8 hour lease. When I revert back to connect with out the variable set the client gets the 8 days defined on the scope. Very strange. I have failed to find the reason for this, as I am not able to see an differences in my captures other than the constructed MAC address.


  If you wish, you can test another config trick. Perhaps your DHCP servers only demand Option 61 client-ID because they do not like the 32-bit "serial line" client-hardware-address that APM-DHCP uses by default (sort of like RBTJNR's problem). You could run a test with variable session.dhcp.hwcode set to "MAC" with no Machine Info Item, and not placing the sessionID-constructed-MAC from session.dhcp.client_ID. With that configuration, the DHCP requests will not contain Option 61 but they will have the sessionID-derived MAC in the client-hardware-address field. That may be more pleasing to your DHCP servers.

 I tried doing as described, but I am not receiving a address. I see that the DHCP is sending a lease offer, but when the irule returns its request for that IP the DHCP sends a NAK. I cannot see the reason for this, but the "Client hardware address" being send in the DHCP Request is really long and ends with a bunch of zeroes(0), not sure if thats the reason for the NAK respond.


 The zeroes are just padding--the client-hardware-address field in the DHCP message has a fixed length of 16 octets. Does the DHCP server put any information into Option 53 (0x35)? Or maybe the DHCP server's own logs will show something. For now I will just guess that the server really wants Option 61.


How about this... run tcpdump -vne -s0 -i int port 67 on your BIG-IP while you try to get an address, then post the relevant packet data here. Maybe I can spot something wrong with APM-DHCP's DHCPREQUEST packet.

  I have a dump with a little different parameters to get the full flow, hope that is okay - Else just say so.

I have removed the chatter to/from the other hot-standby DHCP server. > [bad udp cksum 0x63ac -> 0x261c!] BOOTP/DHCP, Request from 0a:f5:fd:5d:d2:48, length 324, hops 1, xid 0xfd5dd248, Flags [none] (0x0000) Gateway-IP Client-Ethernet-Address 0a:f5:fd:5d:d2:48 Vendor-rfc1048 Extensions Magic Cookie 0x63825363 DHCP-Message Option 53, length 1: Discover Vendor-Class Option 60, length 6: "f5-APM" Hostname Option 12, length 12: "WIN10" MSZ Option 57, length 2: 1344 Lease-Time Option 51, length 4: 4294967295 Agent-Information Option 82, length 46: Circuit-ID SubOption 1, length 14: Remote-ID SubOption 2, length 20: Subscriber-ID SubOption 6, length 6: sonicz out slot1/tmm3 lis= flowtype=137 flowid=5600F8E19100 peerid=0 conflags=24 inslot=0 inport=0 haunit=0 priority=2 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0 10:16:03.797232 IP (tos 0x0, ttl 128, id 25241, offset 0, flags [none], proto UDP (17), length 350) > [udp sum ok] BOOTP/DHCP, Reply, length 322, xid 0xfd5dd248, Flags [none] (0x0000) Your-IP Server-IP Gateway-IP Client-Ethernet-Address 0a:f5:fd:5d:d2:48 Vendor-rfc1048 Extensions Magic Cookie 0x63825363 DHCP-Message Option 53, length 1: Offer Subnet-Mask Option 1, length 4: RN Option 58, length 4: 1800 RB Option 59, length 4: 3150 Lease-Time Option 51, length 4: 3600 Server-ID Option 54, length 4: Agent-Information Option 82, length 46: Circuit-ID SubOption 1, length 14: Remote-ID SubOption 2, length 20: Subscriber-ID SubOption 6, length 6: sonicz in slot1/tmm0 lis= flowtype=0 flowid=0 peerid=0 conflags=0 inslot=63 inport=23 haunit=3 priority=0 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0 10:16:03.798794 IP (tos 0x0, ttl 255, id 4151, offset 0, flags [DF], proto UDP (17), length 364) > [bad udp cksum 0x3d95 -> 0xeafa!] BOOTP/DHCP, Request, length 336, hlen 16, hops 1, xid 0xfd5dd248, Flags [none] (0x0000) Gateway-IP Vendor-rfc1048 Extensions Magic Cookie 0x63825363 DHCP-Message Option 53, length 1: Request Server-ID Option 54, length 4: Requested-IP Option 50, length 4: Vendor-Class Option 60, length 6: "f5-APM" Hostname Option 12, length 12: "WIN10" MSZ Option 57, length 2: 1344 Lease-Time Option 51, length 4: 4294967295 Agent-Information Option 82, length 46: Circuit-ID SubOption 1, length 14: Remote-ID SubOption 2, length 20: Subscriber-ID SubOption 6, length 6: sonicz out slot1/tmm0 lis=/SecureAccess/DHCP_SA flowtype=64 flowid=560001721F00 peerid=0 conflags=100200004000324 inslot=63 inport=23 haunit=1 priority=2 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0 10:16:03.799864 IP (tos 0x0, ttl 128, id 25242, offset 0, flags [none], proto UDP (17), length 328) > [udp sum ok] BOOTP/DHCP, Reply, length 300, hlen 16, xid 0xfd5dd248, Flags [Broadcast] (0x8000) Gateway-IP Vendor-rfc1048 Extensions Magic Cookie 0x63825363 DHCP-Message Option 53, length 1: NACK Server-ID Option 54, length 4: Agent-Information Option 82, length 46: Circuit-ID SubOption 1, length 14: Remote-ID SubOption 2, length 20: Subscriber-ID SubOption 6, length 6: sonicz in slot1/tmm0 lis= flowtype=0 flowid=0 peerid=0 conflags=0 inslot=63 inport=23 haunit=3 priority=0 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0




 , thank you very much. Based on your packet trace I have found the bug in APM-DHCP which explains why your DHCP server sends sends NAK when Option 61 client-id is not being used.


In each DHCP message there is a fixed-width field of 16 octets to hold the client-hardware-address value. The true length of the client-hardware-address is put into a "length" field of 1 octet. A classic (Ethernet-like) MAC address is 6 octets long, and the remaining 10 octets in the client-hardware-address field are filled with zeroes.


The APM-DHCP bug is to set the "length" field correctly in the DHCPDISCOVER message but set it (incorrectly) to 16 always in the DHCPREQUEST message. Many DHCP servers ignore that "length" field, but not yours!


I have fixed this bug in the forthcoming version v4b of the DHCP iApp.


 and  , I have figured out why your attempts to set session.dhcp.client_IP to '' (two single quotes) did not work as expected.


In the Visual Policy Editor, when you edited the value of session.dhcp.client_ID in the Variable Assign Item, you must have left the value-type as "Custom Expression" instead of "Text". Since a pair of single-quotes, standing alone, is not a valid "Custom Expression" that value was essentially discarded.


When I read your notes I forgot about the difference between "Custom Expression" and "Text". Sorry about that!


It appears that the default value-type is "Custom Expression" now. I have not checked, but I think the default might have been "Text" in old versions of APM. Anyway, I have updated the documentation to clarify this point in the next version v4b of the APM-DHCP solution.


To set the value of an APM-DHCP custom parameter to '' (two single quotes) select the value-type "Text" or if you leave the value-type as "Custom Expression" then insert the following: return {''} (that is, the word "return" followed by one blank space then curly-braces enclosing two single-quotes, with no additional spaces).

  Thanks for the info, the next version will that handle DHCPRELEASE differently because I havent seen the current way working and that is currently my biggest concern.

I have tried setting session.dhcp.client_IP = return {''} and removed the session.dhcp.hwcode. Which gives the following result:


Session variable 'session.dhcp.client_ID' set to ''''


Thanks for your inputs, very appreciated, but still not working Im afraid.



When de Session timeout, the APM removes the session but does not send a DHCP Release to the DHCP server.

I could no information / no error in the LTM or APM Log.


Any idea why no Release is sent?

Thank in advance



The DHCP RELEASE message will be sent the next time a user gets a DHCP address from that DHCP server. If the APM device is not busy you may see several RELEASE messages sent seriatim when a new session begins.


The DHCP iRule sends RELEASE messages as UDP "responses" to messages from the DHCP server so that the source and destination ports will be correct. The BIG-IP traffic disaggregator (DAG) only allows one of the TMM instances to send messages to any particular DHCP server with correct source and destination ports. Because an APM session may be attached to any of the TMM instances, when any session ends its RELEASE message is simply queued until the TMM selected by the DAG gets a packet flow going with the proper DHCP server. That DAG-favored TMM instance then sends all of the RELEASE messages queued for that DHCP server.




I was setting up DHCP under APM but getting below errors from LTM logs. Not sure if I need to make any changes under virtual server configuration?


ACCESS_SESSION_STARTED event in rule (/Common/ir-apm-dhcp-policy) requires an associated ACCESS profile on the virtual-server (/Common/


thanks in advance,





have you entered the access profile in the vserver that exposes the APM service?








Thanks Simone for your assistance. Yes, I have entered access profile in the vserver that is configured for SSL vpn. However, I do not see an option for Access Profile under DHCP vserver that was being created using  iApp template (file DHCP_for_APM.tmpl).



thanks in advance !





Any idea if this iApp is compatible with recent tmos version? 14 or higher ?

  I have been using it on both 14.1.x and 15.1.x.


The solution is working like a charm, however I cannot retrieve neither dns servers list nor dns suffix.


Any insights ?

 You still need to deliver DNS information via the network access profile like you would normally do.


  My principal need is to retrieve dns address from DHCP for my vpn users.


I get all needed informations except DNS.


is there anything I can do to get DNS addresses ?


 Perform a login with DHCP request, then look at the value of the session variable 'session.dhcp.dns_servers' (you can look at session variables in the APM console). If the hostnames of your DNS servers are not there, then your DHCP server is not sending them. If the names are there, but have not been sent to your client, make sure you have put the name of your Network Access Profile into 'session.dhcp.dns_na_list' before your Access Policy calls the 'DHCP_req' iRule event (example value: expr {[list "/Common/my-NA"]}



It looks like Microsoft DHCP server needs option 81 to register the clients DNS records.

is there a way this could be added to this template ?



I managed to get it done myself, by adding the following code to proc dhcpmsg in ir-apm-dhcp.

# Option 81, FQDN if { [set len [expr {$len + 3}]] > 3 } { set msg [binary format a*H2 $msg "51"] set msg [binary format a*c $msg $len] set msg [binary format a*ccca* $msg 0 0 0 $host] }

Maybe this should be added by default to the iApp.



We are experiencing issue with DHCP Leases not being released on a consistent basis. We are seeing over a 1500 leases in less than a week that aren't being released causing our DHCP pool to fill up.

Lease pool: 4090 IPs, active users: 2400, user normally login in the morning and logout at end of workday. Next user to connect mat not be until the next morning.


Is there a limitation on the number of DHCP Release requests that the F5 will hold until it processes the Release requests or is there some sort of timeout before it drops these requests before processing them? 


You must attach iRule ir-apm-policy-dhcp to your APM virtual server (the virtual server to which your clients connect).

The iRule is now called "ir-apm-dhcp-policy". From a quick glance I saw dhcp at the end in the documentation and spent an inappropriate amount of time trying to figure out how to connect my VPN clients to UDP....


Soon as I saw my mistake everything worked great. Thanks guys.


I'm getting the following TCL error, i'm using this on v16.1.0:


Oct 10 22:43:20 bigip1 info tmm1[31525]: Rule /Common/ir-apm-policy-dhcp <ACCESS_POLICY_AGENT_EVENT>: sending DHCPDISCOVER to for 895d4cdd, last try

Oct 10 22:43:20 bigip1 info tmm[31525]: Rule /Common/ir-apm-dhcp <CLIENT_ACCEPTED>: about to parse 332-octet UDP msg from for DHCP

Oct 10 22:43:20 bigip1 err tmm[31525]: 01220001:3: TCL error: /Common/ir-apm-dhcp <CLIENT_ACCEPTED> - can't read "dhcp_state": no such variable   while executing "log "${me}: discarding surplus BOOTREPLY for ${xid} from ${relay}, dhcp_state=${dhcp_state}""

Oct 10 22:43:28 bigip1 err tmm1[31525]: Rule /Common/ir-apm-policy-dhcp <ACCESS_POLICY_AGENT_EVENT>: Timed out waiting for DHCPOFFER from DHCP server for 895d4cdd


DHCP server is seeing the request and replying:

Oct 11 05:46:35 ubuntu dhcpd[22648]: DHCPDISCOVER from 00:7f:dd:b9 (DESKTOP-O1H6UEP) via

Oct 11 05:46:35 ubuntu dhcpd[22648]: DHCPOFFER on to 00:7f:dd:b9 (DESKTOP-O1H6UEP) via


BIG-IP is also getting the reply:

22:45:41.503847 IP localhost.localdomain.bootps > BOOTP/DHCP, Request, length 328 out slot1/tmm0 lis= port=1.0 trunk=

22:45:42.506830 IP > BOOTP/DHCP, Reply, length 332 in slot1/tmm0 lis= port=1.0 trunk=


DHCP server ==; Virtual Server on BIG=IP is


Any pointers as to what might be going wrong?






This comes from a bug which was fixed in v4c (failure to initialize dhcp_state at line 617 in iRule ir_apm_dhcp).



Is it possible to apply this APM-DHCP access policy with APM machine tunnel service ?

Kind regards,




i have also installed a virtual F5, that is running version I also get the same error message: TCL error: /Common/ir-apm-dhcp <CLIENT_ACCEPTED> - can't read "dhcp_state": no such variable   while executing "log "${me}: discarding surplus BOOTREPLY for ${xid} from ${relay}, dhcp_state=${dhcp_state}""

any idea how to solve it or is the new version available?





I've had success installing and configuring the necessary items to end up with a functional implementation on version 14.1*. However, I've also got an F5 VE running Build 0.0.28 Point Release 2 that will not install the template which appears to be related to compatibility issues based on the error (see below).

----Loading configuration... Data Input Error:(/tmp/upload_template.tmpl at line: 0) Invalid version:12.0.0: Supported cli versions: 14.0.0 14.0.1 14.1.0 14.1.1 14.1.2 14.1.3 14.1.4 15.0.0 15.0.1 15.1.0 15.1.1 15.1.2 15.1.3 16.0.0 16.0.1 16.1.0 16.1.1 16.1.2 -----

On the VE running, I've manually created the necessary items that are created using the template and the client is being issued DHCP from the external source as expected. However, the client will not complete the connection and build the tunnel resulting in the session looping during the connection with this error in the session logs.



Has anyone had success with this version and build?


F5 Employee
F5 Employee

@JHDUKE and @Man_Yau, thanks for the heads up on this.

We checked it out and are working on a solution for v16+. I updated the article to prevent others from running into the same issue and we'll update the article when we have a working solution for this. It may take a bit but we know where the issues are. If you haven't already, subscribe to this article so you're notified when it's updated.

Thanks again!

-ChaseA & MarkQ


@Chase_Abbott Awesome write up. I was wondering if there was any word on this being supported on v16? This looks to be exactly what I need to support a project I'm working on. Are there other alternatives known at this time to get this working on v16?

Also to echo @JulienL question, is it known if this will work with a machine tunnel? I wouldn't think this would be an issue, but can't verify for myself as I'm on V16 🙂.

Version history
Last update:
‎13-Jul-2022 14:10
Updated by: