IPFW Why do ipfw rules have no effect on dhclient?

I've run a simple experiment on FreeBSD 14.0 and the results are quite unexpected to me. Could you explain these results to me?
Warning! The experiment MUST be run from console. Do not try to reproduce it over SSH as it will make the host inaccessible!

Console log, with comments:
Bash:
# killall dhclient

# sysctl net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose: 0 -> 1

# rm -f /var/db/dhclient.leases.em0         # remove all recorded DHCP leases. Force dhclient to perform full negotiation.
                                            # em0 is my gateway-facing upstream interface

# ipfw -f flush
Flushed all rules.

# ipfw add deny log via any
00100 deny log

# ipfw show                                 # Make sure the firewall is configured to block everything
00100 0 0 deny log
65535 0 0 deny ip from any to any

# tcpdump -ni em0 -w dump -U &              # Start capturing the packets on em0 in the background
tcpdump: listening on em0, link-type EN10MB (Ethernet), snapshot length 262144 bytes

# dhclient em0                              # Initiate communication with DHCP server
DHCPDISCOVER on em0 to 255.255.255.255 port 67 interval 7
DHCPOFFER from 192.168.26.1
DHCPREQUEST on em0 to 255.255.255.255 port 67
DHCPACK from 192.168.26.1
bound to 192.168.26.11 -- renewal in 1800 seconds.   # All requests and replies are successful

# ipfw show
00100 2 698 deny log                        # The firewall has seen only 2 packets and dropped them, supposedly
65535 0   0 deny ip from any to any

# tcpdump -nr dump                          # Let's see what packets were actually transmitted and received
reading from file dump, link-type EN10MB (Ethernet), snapshot length 262144
07:32:12.386501 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 80:ee:73:f5:f8:bd, length 300
07:32:12.386880 IP 192.168.26.1.67 > 192.168.26.11.68: BOOTP/DHCP, Reply, length 321
07:32:14.395085 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 80:ee:73:f5:f8:bd, length 300
07:32:14.395436 IP 192.168.26.1.67 > 192.168.26.11.68: BOOTP/DHCP, Reply, length 321
07:32:14.536375 ARP, Request who-has 192.168.26.11 tell 192.168.26.11, length 28

# killall tcpdump                           # Stop capturing the packets

# tail -n 2 /var/log/security               # See the log of packets dropped by the firewall
Mar  8 06:45:15 site-03 kernel: ipfw: Accounting cleared.
Mar  8 07:32:12 site-03 kernel: ipfw: 100 Deny UDP 192.168.26.1:67 192.168.26.11:68 in via em0

# service ipfw restart                      # Restore your usual working firewall rules
Stopping natd.
Waiting for PIDS: 1542.
Firewall rules loaded.
Firewall logging enabled.
Starting natd.

What surprises me here is:
1. ipfw is configured to block any packet, yet dhclient has successfully communicated with the upstream dhcpd. How come dhclient has received those packets blocked by the firewall?
2. There were 4 IP packets total, yet only 2 of them were processed by the firewall. Aren't broadcast outgoing packets subject to the firewall rules too?
 
My understanding, from recent limited exposure to IPFW, is that DHCP packets are filtered at layer 2 and your rules are filtering at layer 3.
The IPFW man page talks about layer 2/3 under heading PACKET FLOW.

HTH
 
Back
Top