Dnsmasq and setting IPV6 DNS servers to certain clients

In the process of getting Nintendo Switch 2 consoles working, I had to change DNS. For whatever reason, the console reports major connectivity problems ittermittently, if I use my local DNS (fully resolving, DNSSEC, etc.). I suspect the Nintendo issue is excessively short resolution timeouts (original Switch works fine), but that leads my to my OpenWRT + DNS issue....

I've been running dnsmasq on openwrt for around 16 years now, but finally took the plunge with tagging. Tagging itself is working, as I have the the custom IPv4 DNS servers only for my tagged devices. However, I can't seem to get the IPv6 DNS servers to go through. I've tried a few different syntax options, but have only gotten the IPV6 DNS to work properly when I set it at the zone level, and then that messed up the local resolution I want for all but these few exceptions.

This device happens to be running TurrisOS 9 (based on 24.10), but I do plan to put the equivalent rules on a couple other devices like an Archer C7.

I've stripped out some unrelated zones, but my /etc/config/dhcp otherwise looks like this:

config dnsmasq
        option logfacility '/var/log/dnsmasq.log'
        option logdhcp '1'
        option logqueries '1'
        option domainneeded '1'
        option boguspriv '0'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option domain 'mydomain.tld'
        option authoritative '1'
        option readethers '1'
        option nonegcache '1'
        option leasefile '/tmp/dhcp.leases'
        list addnhosts '/etc/hosts'
        option expandhosts '1'
        option localservice '1'
        option nonwildcard '1'
        list notinterface 'eth1'
        list interface 'br-wifi'
        option port '0'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'

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

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option piofolder '/tmp/odhcpd-piofolder'

config dhcp 'wifi'
        option start '100'
        option interface 'wifi'
        option limit '79'
        option leasetime '72h'
        option force '1'
        option ra_flags 'other-config'
        option ra_mtu '1500'
        option ra 'server'
        option dhcpv6 'server'
        list dhcp_option 'tag:!googledns,option:dns-server,192.168.6.1'

config host
        option name 'my-switch2'
        list mac '98:E2:55:##:##:##''
        list tag 'googledns'

config tag 'googledns'
        list dhcp_option 'option:dns-server,8.8.8.8,8.8.4.4'
        list dhcp_option 'option6:dns-server,[2001:4860:4860::8888],[2001:4860:4860::8844]'

If I instead use the "list dns" syntax in the config tag block, nothing happens. If I use those same lines in the wifi zone, if gets applied to everything. If I put it in both places, but negate it with a negative match on the tag in the zone, or put both in the zone, one matching the tag, and one rejecting it, it still doesn't work.

I wasn't able to figure out the conflict playing with similar rules in ra_dns. I tried generating the corresponding rules with the list dns syntax in the UI, and experienced the same behavior, as well.

Am I missing something fundamental? Any hints would be greatly appreciated.

I use this:

config tag 'tag1'  
    list dhcp_option '6,8.8.8.8,8.8.4.4'  
    # for IPv6
    list dhcp_option 'option6:23,[2001:4860:4860::8888],[2001:4860:4860::8844]' 

But I am pretty sure that option6:dns-server is option 23

Are you sure the switch is using the tag i.e. is the MAC address correct? Maybe it uses random MAC addresses?
Set an IP address in the config host to check

Edit: I am not at home so cannot check if it actually works

Could not one just use this?

config dhcp 'guest'
⋮
	list dns '2001:4860:4860::6464'
	list dns '2001:4860:4860::64'

Not sure if it was available with dnsmasq or if you need dnsmasq-full but you can dump all DHCP and dhcpv6 config options to map the id to its name.

This is about tagging individual clients so a per tag/client DNS server

Could not just use this one?

config dhcp 'guest'
⋮
	list dns '2001:4860:4860::6464'
	list dns '2001:4860:4860::64'

This syntax does apply the DNS entry to the switch2. However, it applies it to all hosts in the zone. I have local resolutions in my DNS that I need to keep, with a few exceptions like this Switch. I'm limited by the number of SSID my APs can provide (and need those for vlan isolation), so unable to give a whole config section to this host.

Are you sure the switch is using the tag i.e. is the MAC address correct? Maybe it uses random MAC addresses?
Set an IP address in the config host to check

Yes, I'm sure. I'm using the MAC via /etc/ethers and getting a consistent IP back. Additionally, the IPV4 dns server setting via dhcp_option option:dns-server (or dhcp_option 6) does apply and work on the switch. My issue is specific to getting the IPv6 equivalent working.

The option6:dns-server is option 23, but I have never tried this specific syntax. I'll give it a shot tonight.

I really wonder if I haven't had a valid syntax several times, but conflicting with another feature. The IPv6 server settings seem to stick for some time on this console, even when hopping back and forth between different SSIDs.

If you have used syntax similar to this this, are you also running SLAAC on your network? I have a bunch of IPv6 IOT devices that I'm pretty sure don't support DHCPv6.

Since you have logdhcp enabled, what do you see happening in the log when this client connects?

@Azlinon remove or disable odhcpd and instad install dnsmasq-full and use dnsmasq for DHCP and dhcpv6. I assume that's the root cause here.

1 Like

documented in https://openwrt.org/docs/guide-user/base-system/dhcp_configuration#client_classifying_and_individual_options

Damn is this gem well hidden in the man page but here it goes:

Option numbers are specified in RFC2132 and subsequent RFCs. The set of option-names known by dnsmasq can be discovered by running dnsmasq --help dhcp.

And dnsmasq --help dhcp6 if the full variant is installed.

I think this is going to end up being my answer, as it seemed something else was interfering. I had thought odhcpd was just used for SLAAC/RA, but this totally explains why I was seeing prompt updates for ipv4 dns servers, and long delays on ipv6 even when restarting dnsmasq.

I'll try going back to the list dns syntax tonight, restarting odhcpd first, and seeing if that kicks things where I want them. If not, I'll look into moving that all to dnsmasq. I'll follow up afterwards.

Thank you so much!

1 Like