Static Assignments in your DHCP Pool: A Cautionary Tale
For the last few months, I’ve been facing head-scratching behavior on my home network. I recently noticed that my work laptop would periodically have awful packet loss. Sometimes, I’d connect to my network, and then all traffic would stop after a few seconds. The cause was unknown to me for a while, but I assumed it had something to do with a Wi-Fi driver issue that I couldn’t pin down.
One night, I was watching TV and a coworker asked me to hop on to help resolve a customer issue. Of course, it was now of all times that the issue arose. I was able to work around it by hardwiring my laptop, but I was determined to solve the issue afterwards. After several hours of troubleshooting, I gave up and went to bed. While sitting in bed, I decided to check my wireless controller to see if it might give me any hint, and I noticed something peculiar. Unifi has a “Wi-Fi Experience” metric that I’d always kind of ignored, because it seemed somewhat meaningless. With that said, the graph I saw for my work laptop was too suspicious to ignore.
The nose-dive the graph took was so dramatic, there’s no way something wasn’t going on, I just didn’t know what. The next day, though, the same thing happened. I was watching TV, needed to handle something for work, and the packet loss appeared, despite having no problem during the work day. It was at this moment, I looked more closely at the Wi-Fi experience graph… the precipitous drop took place just after I stopped working, and slowly ticked up around when I went to bed.
At this point, I knew the TV had to be the culprit, but I couldn’t prove it. My TV is hardwired via Ethernet, though, so it couldn’t be the problem… right? I suspected that my TV was emitting a hidden SSID and producing interference, but living in an apartment building, it’s difficult to know if a hidden SSID is mine or a neighbor’s. After some Googling, I found that my TV supported what is called “Device Connect,” which others had reported involved the TV emitting a hidden SSID. Even though I turned this off, nothing happened. At this point, I was getting sick of troubleshooting and just resolved I wouldn’t be able to have my TV and work laptop in use at the same time, which was fine; I’m not exactly watching TV during work hours.
A month goes by. One night, I’m debugging a connection problem with my TV. For some time, my TV intermittently had trouble connecting to my Jellyfin instance, despite both being connected to the same switch as my NAS. For a while, I chalked this up to bugginess in the Roku app; I’d already seen a bunch of weird problems so this made sense to me. Tonight, though, I was determined to get to the bottom of it.
The obvious first step in debugging a problem like this is to check to make
sure the TV actually has a connection. I navigated to settings and saw the TV
was connected to my home network with the address
192.168.1.201. This address
was familiar to me… it was the address my work laptop had earlier that day! This
could explain the packet loss; my router must be sending return traffic to the
wrong host.1 But how? Shouldn’t my DHCP server be preventing this?
Checking my OPNSense settings, I saw that I had assigned my TV a static assignment
192.168.1.201… but shouldn’t that mean my laptop will never get that address?
After complaining to a friend, he mentioned to me that he set up his static
reservations outside his DHCP pool because he was always paranoid about this
exact scenario. Sure enough, my DHCP pool was set to the range
192.168.1.254, and my static assignment was smack in the middle of
that. Googling a bit, I found this
in the PFSense (which OPNsense forks) docs:
While ISC dhcpd will allow a static mapping to be defined inside the DHCP range/pool, it can result in unexpected behavior.
ISC dhcpd only checks via ping to ensure that an IP is not actively in use when making assignments. Making a static mapping does not “reserve” that IP out of the pool. The static mapping in this case merely represents a preference for an IP and others are not prevented from taking the IP if it is not in use.
It all fell into place at this moment; I never use my TV during work, so of course my laptop could be assigned this address; the TV won’t respond to pings when it’s off. The laptop’s DHCP lease had just lived long enough that it was consistently getting the same address! I updated my DHCP pool range and static reservation to avoid the overlap, and all has worked flawlessly since.
All of this is to say: don’t fall for the same trap I did. Keep your DHCP static assignments out of your pool!
I don’t have a packet capture showing this, but I suspect that there was a bit of a race condition here with ARP. For instance, the router would send out an ARP request (“who has
192.168.1.201”), my laptop would respond with its MAC, get a short burst of traffic, and then my TV would respond with its MAC. This would cause all return traffic for that the laptop sent to go back to the TV. ↩︎