Dnsmasq bug related to multi config

Hello! I found nasty bug in dnsmasq related to multiply instances of dnsmasq an bootp protocol.

I want to setup dnsmasq as caching dns server working via several groups of dns servers. First group using private encrypted dns request, second group using public dns like 8.8.8.8 third group dns provided by my ISP.

dnsmasq config looks like this:

config dnsmasq
        option noresolv      '1'
        option strictorder   '1'
        list server '127.0.0.1#5354' # group1
        list server '127.0.0.1#5355' # group2
        list server '127.0.0.1#5356' # group3
 
config dnsmaq 'priv'
        option noresolv      '1'
        option port '5354'
        list interface 'lo'
        list server '127.0.0.1#5453' # https dns proxy 
        list server '127.0.0.1#5053' # stubby1
        list server '127.0.0.1#5054' # stubby2

                                           
config dnsmasq 'pub'                       
        option noresolv      '1'           
        option port '5355'                 
        list interface 'lo'         
        list server '8.8.8.8'       
        list server '8.8.4.4'       
        list server '1.1.1.1'       
        list server '77.88.8.8'     
        list server '77.88.1.1'     
                                                               
config dnsmasq 'auto'                                          
  option port '5356'                                           
  list interface 'lo'                                          
  option resolvfile     '/tmp/resolv.conf.d/resolv.conf.auto'  

It works as expected. Until I notices that dnsmasq stop to responds to my bootp requests and stop assign IP addeses for more then two first hosts requests an IP. So. If two machines asked for dhcp IP they will get proper respond. But third and frouth machines does request, it will be dennied. I tested all caces, it is not a cable or lost packets issues. tcpdump confirmed packed arrived but blocked by dnsmasq.

09:07:48.998913 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300
09:07:49.000319 IP w.67 > rpi.lan.68: BOOTP/DHCP, Reply, length 302
09:07:58.890442 IP mbp113.lan.68 > w.67: BOOTP/DHCP, Request from b8:e8:56:2b:4d:84 (oui Unknown), length 284
09:07:58.891925 IP w.67 > mbp113.lan.68: BOOTP/DHCP, Reply, length 305
09:08:12.220578 IP u8650.lan.68 > w.67: BOOTP/DHCP, Request from 00:90:4c:14:43:29 (oui Unknown), length 329
09:08:15.403278 IP axet-desktop.lan.68 > w.67: BOOTP/DHCP, Request from 34:5a:60:72:78:2c (oui Unknown), length 290
09:08:41.869819 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300
09:08:41.871318 IP w.67 > rpi.lan.68: BOOTP/DHCP, Reply, length 302
09:08:53.888331 IP mbp113.lan.68 > w.67: BOOTP/DHCP, Request from b8:e8:56:2b:4d:84 (oui Unknown), length 284
09:08:53.889768 IP w.67 > mbp113.lan.68: BOOTP/DHCP, Reply, length 305
09:09:15.939000 IP axet-desktop.lan.68 > w.67: BOOTP/DHCP, Request from 34:5a:60:72:78:2c (oui Unknown), length 290
09:09:16.637494 IP u8650.lan.68 > w.67: BOOTP/DHCP, Request from 00:90:4c:14:43:29 (oui Unknown), length 329
09:09:25.365728 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300
09:09:25.367090 IP w.67 > rpi.lan.68: BOOTP/DHCP, Reply, length 302
09:09:48.886711 IP mbp113.lan.68 > w.67: BOOTP/DHCP, Request from b8:e8:56:2b:4d:84 (oui Unknown), length 284
09:09:48.888066 IP w.67 > mbp113.lan.68: BOOTP/DHCP, Reply, length 305
09:10:12.757648 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300
09:10:12.759013 IP w.67 > rpi.lan.68: BOOTP/DHCP, Reply, length 302
09:10:16.297623 IP axet-desktop.lan.68 > w.67: BOOTP/DHCP, Request from 34:5a:60:72:78:2c (oui Unknown), length 290
09:10:21.110251 IP u8650.lan.68 > w.67: BOOTP/DHCP, Request from 00:90:4c:14:43:29 (oui Unknown), length 329
09:10:43.885405 IP mbp113.lan.68 > w.67: BOOTP/DHCP, Request from b8:e8:56:2b:4d:84 (oui Unknown), length 284
09:10:43.886781 IP w.67 > mbp113.lan.68: BOOTP/DHCP, Reply, length 305
09:11:00.761657 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300
09:11:00.763009 IP w.67 > rpi.lan.68: BOOTP/DHCP, Reply, length 302
09:11:17.014004 IP axet-desktop.lan.68 > w.67: BOOTP/DHCP, Request from 34:5a:60:72:78:2c (oui Unknown), length 290
09:11:25.048582 IP u8650.lan.68 > w.67: BOOTP/DHCP, Request from 00:90:4c:14:43:29 (oui Unknown), length 329
09:11:36.883864 IP mbp113.lan.68 > w.67: BOOTP/DHCP, Request from b8:e8:56:2b:4d:84 (oui Unknown), length 284
09:11:36.885231 IP w.67 > mbp113.lan.68: BOOTP/DHCP, Reply, length 305
09:11:44.193473 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300
09:11:44.194826 IP w.67 > rpi.lan.68: BOOTP/DHCP, Reply, length 302

I'm using openwrt 25.12.4, self build from original repo.

Can you reproduce it on latest upstream dnsmasq ?

same for 2.93test4

Is it an issue with how the dnsmasq conf is generated ? Or is it an upstream bug?

Could be that, 3 instances of dhcpd:

# /etc/init.d/dnsmasq restart
udhcpc: started, v1.37.0
udhcpc: broadcasting discover
udhcpc: no lease, failing
udhcpc: started, v1.37.0
udhcpc: broadcasting discover
udhcpc: no lease, failing
udhcpc: started, v1.37.0
udhcpc: broadcasting discover
udhcpc: no lease, failing
root@OpenWrt:~# ps |grep dhcp
 1471 root      1848 S    /usr/sbin/odhcpd
 3319 root      1324 S    odhcp6c -s /lib/netifd/dhcpv6.script -P0 -c0004b89d198390114ee09b6fbaec11c0d682 -t120 pppoe-wan
20935 root      1332 S    grep dhcp
root@OpenWrt:~# 

Can we see the complete DHCP config?

Add option logdhcp '1' to the main instance to see what’s happening.

# auto-generated config file from /etc/config/dhcp                                                                                                                                                                 
conf-file=/etc/dnsmasq.conf                                                                                                                                                                                        
dhcp-authoritative                                                                                                                                                                                                 
domain-needed                                                                                                                                                                                                      
strict-order                                                                                                                                                                                                       
no-resolv                                                                                                                                                                                                          
localise-queries                                                                                                                                                                                                   
read-ethers                                                                                                                                                                                                        
enable-ubus=dnsmasq                                                                                                                                                                                                
expand-hosts                                                                                                                                                                                                       
bind-dynamic                                                                                                                                                                                                       
quiet-dhcp                                                                                                                                                                                                         
domain=lan                                                                                                                                                                                                         
local=/lan/                                                                                                                                                                                                        
server=127.0.0.1#5354                                                                                                                                                                                              
server=127.0.0.1#5355                                                                                                                                                                                              
server=127.0.0.1#5356                                                                                                                                                                                              
interface=br-lan                                                                                                                                                                                                   
interface=wg0                                                                                                                                                                                                      
addn-hosts=/tmp/hosts                                                                                                                                                                                              
dhcp-leasefile=/tmp/dhcp.leases                                                                                                                                                                                    
stop-dns-rebind                                                                                                                                                                                                    
rebind-localhost-ok                                                                                                                                                                                                
dhcp-broadcast=tag:needs-broadcast                                                                                                                                                                                 
conf-dir=/tmp/dnsmasq.cfg01411c.d                                                                                                                                                                                  
user=dnsmasq                                                                                                                                                                                                       
group=dnsmasq                                                                                                                                                                                                      
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
dhcp-ignore-names=tag:dhcp_bogus_hostname                                                                                                                                                                          
conf-file=/usr/share/dnsmasq/dhcpbogushostname.conf                                                                                                                                                                
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
bogus-priv                                                                                                                                                                                                         
conf-file=/usr/share/dnsmasq/rfc6761.conf                                                                                                                                                                          
dhcp-range=set:lan,10.10.5.50,10.10.5.98,255.255.255.0,7d                                                                                                                                                          
dhcp-option=lan,58,60                                                                                                                                                                                              
no-dhcp-interface=pppoe-wan           

logs

listening on br-lan, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:14:51.257155 IP u8650.lan.68 > w.67: BOOTP/DHCP, Request from 00:90:4c:14:43:29 (oui Unknown), length 329
14:14:53.341368 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300
14:15:02.678400 IP axet-desktop.lan.68 > w.67: BOOTP/DHCP, Request from 34:5a:60:72:78:2c (oui Unknown), length 290
14:15:04.809465 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300


it does not log anything to 'logread' ignores packets completely.

The quiet-dhcp option hinders troubleshooting.

it is off obviously

option quietdhcp '0'

Let's try again:

Can you provide the full /etc/config/dhcp file (to verify no parsing issue)?

It was there in the dnsmasq config file you posted.

config dnsmasq
	option domainneeded '1'
	option boguspriv '1'
	option filterwin2k '0'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option nonegcache '0'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
        option noresolv      '1'
	option nonwildcard '1'
	list interface 'lan'
	list interface 'wg0'
	option quietdhcp '0'
        option logdhcp '1'
        option strictorder   '1'
        list server '127.0.0.1#5354'
        list server '127.0.0.1#5355'
        list server '127.0.0.1#5356'

config dnsmasq 'priv'
        option noresolv      '1'
        option port '5354'
	list interface 'lo'
	list server '127.0.0.1#5453'
	list server '127.0.0.1#5053'
	list server '127.0.0.1#5054'
	list server '127.0.0.1#9053'

config dnsmasq 'pub'
        option noresolv      '1'
	option port '5355'
	list interface 'lo'
	list server '8.8.8.8'
	list server '8.8.4.4'
	list server '1.1.1.1'
	list server '77.88.8.8'
	list server '77.88.1.1'

config dnsmasq 'auto'
	option port '5356'
	list interface 'lo'
	option resolvfile     '/tmp/resolv.conf.d/resolv.conf.auto'

config dhcp 'lan'
	option interface 'lan'
	option start '50'
	option limit '49'
	list dhcp_option '58,60'
	option leasetime '7d'
	option dhcpv6 'server'
	option ra 'server'
	option ra_management '1'
	option ra_default '1'
	option ndp 'hybrid'
	option dhcpv4 'server'
	option ra_slaac '1'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'

config dhcp 'wan'
	option ignore '1'
	option interface 'wan'

config dhcp 'wan6'
	option ignore '1'
	option interface 'wan6'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/odhcpd.leases'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '4'
	option piodir '/tmp/odhcpd-piodir'
	option hostsdir '/tmp/hosts'

new logs, no entries for missing packets

5:08:05.219312 IP rpi.lan.68 > w.67: BOOTP/DHCP, Request from b8:27:eb:a2:b6:94 (oui Unknown), length 300
15:08:05.226322 IP w.67 > rpi.lan.68: BOOTP/DHCP, Reply, length 302
15:08:13.795334 IP u8650.lan.68 > w.67: BOOTP/DHCP, Request from 00:90:4c:14:43:29 (oui Unknown), length 329


Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 available DHCP range: 10.10.5.50 -- 10.10.5.98
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 client provides name: rpi
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 DHCPREQUEST(br-lan) 10.10.5.69 b8:27:eb:a2:b6:94
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 tags: lan, br-lan
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 DHCPACK(br-lan) 10.10.5.69 b8:27:eb:a2:b6:94 rpi
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 requested options: 1:netmask, 28:broadcast, 2:time-offset, 3:router,
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 requested options: 15:domain-name, 6:dns-server, 119:domain-search,
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 requested options: 12:hostname, 44:netbios-ns, 47:netbios-scope,
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 requested options: 26:mtu, 121:classless-static-route, 42:ntp-server
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 next server: 10.10.5.1
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  1 option: 53 message-type  5
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  4 option: 54 server-identifier  10.10.5.1
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  4 option: 51 lease-time  7d
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  4 option: 58 T1  54s
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  4 option: 59 T2  6d2h59m54s
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  4 option:  1 netmask  255.255.255.0
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  4 option: 28 broadcast  10.10.5.255
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  4 option:  3 router  10.10.5.1
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  4 option:  6 dns-server  10.10.5.1
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  3 option: 15 domain-name  lan
Sat Jun 27 15:08:05 2026 daemon.info dnsmasq-dhcp[18476]: 2445542153 sent size:  3 option: 12 hostname  rpi

Is dhcp only listening on the main instance?

netstat -nlup | grep ":67 "
root@OpenWrt:~# netstat -nlup | grep ":67 "
udp        0      0 0.0.0.0:67              0.0.0.0:*                           18477/dnsmasq
udp        0      0 0.0.0.0:67              0.0.0.0:*                           18479/dnsmasq
udp        0      0 0.0.0.0:67              0.0.0.0:*                           18476/dnsmasq
udp        0      0 0.0.0.0:67              0.0.0.0:*                           18478/dnsmasq

But I have no idea how to disable dhcp for specified secondary instance:

# cat /var/etc/dnsmasq.conf.priv
# auto-generated config file from /etc/config/dhcp
conf-file=/etc/dnsmasq.conf
no-resolv
enable-ubus=dnsmasq.priv
bind-dynamic
port=5354
server=127.0.0.1#5453
server=127.0.0.1#5053
server=127.0.0.1#5054
server=127.0.0.1#9053
interface=lo
addn-hosts=/tmp/hosts
dhcp-leasefile=/tmp/dhcp.leases
stop-dns-rebind
dhcp-broadcast=tag:needs-broadcast
conf-dir=/tmp/dnsmasq.priv.d
user=dnsmasq
group=dnsmasq


dhcp-ignore-names=tag:dhcp_bogus_hostname
conf-file=/usr/share/dnsmasq/dhcpbogushostname.conf


bogus-priv
conf-file=/usr/share/dnsmasq/rfc6761.conf
dhcp-range=set:lan,10.10.5.50,10.10.5.98,255.255.255.0,7d
dhcp-option=lan,58,60
no-dhcp-interface=pppoe-wan



Here is my patch


diff --git a/dnsmasq.init b/dnsmasq.init
index 61dc396..e6b47af 100755
--- a/dnsmasq.init
+++ b/dnsmasq.init
@@ -1228,13 +1228,13 @@ dnsmasq_start()
                # Enable RA feature for when/if it is constructed,
                # and RA is selected per interface pool (RA, DHCP, or both),
                # but no one (should) want RA broadcast in syslog
-               [ -n "$BOOT" ] || config_foreach filter_dnsmasq dhcp dhcp_add "$cfg"
+               [ "$cfg" != "$first_instance" ] || [ -n "$BOOT" ] || config_foreach filter_dnsmasq dhcp dhcp_add "$cfg"
                xappend "--enable-ra"
                xappend "--quiet-ra"
                append_bool "$cfg" quietdhcp "--quiet-dhcp6"
 
        elif [ "$DNSMASQ_DHCP_VER" -gt 0 ] ; then
-               [ -n "$BOOT" ] || config_foreach filter_dnsmasq dhcp dhcp_add "$cfg"
+               [ "$cfg" != "$first_instance" ] || [ -n "$BOOT" ] || config_foreach filter_dnsmasq dhcp dhcp_add "$cfg"
        fi
 
 

You probably need to add an instance filter to the dhcp sections. See the wiki.

instance : Dnsmasq instance to which the dhcp section is bound; if not specified the section is valid for all dnsmasq instances.

You are right. Here is 'instance option' which I can use. And this is proper solution to the problem.

But isn't that wrong to start dhcp on all instances by default? This default behaivour makes dhcp unusable without and log warning and errros.