luci-app-tailscale-community: prevent duplicate dnsmasq forward entries

In setup_tailscale_dns_forward(), the duplicate check used:
  uci -q show dhcp.@dnsmasq[0].server | grep -Fqx ...
However, 'uci show' expands anonymous sections into real named sections
(e.g., cfg01411c) and outputs multiple list values space-separated on
the same line, causing exact matching to always fail and appending
duplicate forward entries on every boot.

Fix this by:
- Adding runtime checks to ensure /etc/config/dhcp and /etc/init.d/dnsmasq
  exist before touching dnsmasq configuration, safely avoiding errors
  on systems without dnsmasq.
- Iterating existing 'uci get' server list values and returning early
  if the entry already exists, preserving user configuration and list
  ordering without rebuilding.

Signed-off-by: tokisaki galaxy <moebest@outlook.jp>
This commit is contained in:
tokisaki galaxy authored and Paul Donald committed 2026-10-07 19:45:03 +02:00
1 parent 7fccab79e3
commit cd65611681
1 file changed
+16 -12
@@ -23,27 +23,31 @@ version_gte() {
# Add/remove DNS forward entry in dnsmasq for MagicDNS via OpenWrt
setup_tailscale_dns_forward() {
if [ ! -f /etc/config/dhcp ] || [ ! -x /etc/init.d/dnsmasq ]; then
return 0
fi
if [ ! -x /usr/sbin/tailscale ] && [ ! -x /usr/bin/tailscale ]; then
return 0
fi
local entry="/.ts.net/100.100.100.100"
local found=0
local s
for s in $(uci -q get dhcp.@dnsmasq[0].server); do
[ "$s" = "$entry" ] && return 0
done
# Check if entry already exists in dnsmasq
if uci -q show dhcp.@dnsmasq[0].server 2>/dev/null | grep -Fqx "dhcp.@dnsmasq[0].server='$entry'"; then
found=1
fi
if [ "$found" = "0" ]; then
uci add_list dhcp.@dnsmasq[0].server="$entry"
uci commit dhcp
/etc/init.d/dnsmasq reload 2>/dev/null || /etc/init.d/dnsmasq restart 2>/dev/null
logger -t "$NAME" "Added DNS forward: $entry"
fi
uci add_list dhcp.@dnsmasq[0].server="$entry"
uci commit dhcp
/etc/init.d/dnsmasq reload 2>/dev/null || /etc/init.d/dnsmasq restart 2>/dev/null
logger -t "$NAME" "Added DNS forward: $entry"
}
remove_tailscale_dns_forward() {
if [ ! -f /etc/config/dhcp ] || [ ! -x /etc/init.d/dnsmasq ]; then
return 0
fi
local entry="/.ts.net/100.100.100.100"
local idx=0
local removed=0