shodanx | 2025-01-06 07:37:32 UTC | #1 Hello, This is in response to prematurely closed thread linked below. https://forum.openwrt.org/t/luci-add-support-for-managing-tags-in-dhcp-and-dns-configuration-web-page/178467 In this thread a user @systemcrash shows off his custom made "tag matching tab" to the DHCP settings panel. I need this ability to configure the following tags in particular Set the ipxe tag for hosts already running iPXE as defined by their "PXE User Class" `dhcp-userclass=set:ipxe,iPXE` A class of devices on my network `dhcp-mac=set:customgateway,DE:AD:B0:0F:*:*` These devices will be served only a fakeinternet gateway (like this dhcp-option=tag:customgateway,option:router,192.168.1.99) This one might not be a tag properly `dhcp-range=192.168.1.0,proxy,255.255.255.0` I am not sure but I think all of the following ways can be used to set a tag to a host ``` client centric (? could be incomplete ?) these should be more straightforward to implement --dhcp-vendorclass=set:,... Tag based on DHCP vendor class --dhcp-userclass=set:,... Tag based on DHCP user class --dhcp-mac=set:,... Tag based on MAC address --dhcp-circuitid=set:,... Tag based on relay circuit ID --dhcp-remoteid=set:,... Tag based on relay remote ID --dhcp-subscrid=set:,... Tag based on subscriber ID --dhcp-match=set:,... Tag based on DHCP option values --dhcp-name-match=set:,... Tag based on DHCP client hostname --tag-if=set:,... Conditionally set tags based on other tags server centric (? could be incorrect or incomplete ?) --dhcp-host=...,set: Tag specific hosts --dhcp-range=set:,... Tag based on IP range --address=...,set: Tag specific DNS responses --server=...,set: Use specific DNS server based on tag --cname=...,set: Apply CNAME records based on tag --dhcp-option=tag:,... Provide specific DHCP options to tagged clients --dhcp-script= Use a custom script to set tags ``` ![Screenshot 2023-11-23 at 23.11.48|690x378](upload://2IzpJhRZ7oVXfY5CmC9lQm4AxeK.png) So this thread is to inquire what is the status of the "Match Tags" tabs And what series of commands can add the current test version to a fresh 23.05.5 openwrt installation for testing purposes. ------------------------- systemcrash | 2025-01-06 17:18:20 UTC | #2 See [here](https://github.com/openwrt/luci/pull/7178). ------------------------- shodanx | 2025-01-12 11:34:33 UTC | #3 Thank you, Is it possible to try it on 23.05.5 ? ------------------------- systemcrash | 2025-01-12 17:50:44 UTC | #4 Sure is. Download `dhcp.js` and replace the device copy. ------------------------- shodanx | 2025-12-27 13:53:38 UTC | #5 Hello, I just upgraded my old 23.05 router. I had this installed, and it worked great But now I’m 24.10 and I want to get this functionality back I see that the old file now lists as outdated https://github.com/openwrt/luci/pull/7178/files#diff-90caf036d2316d858be5df6b382c44d4130a66c52cc7b6fda8ee715971a4f9bd I am curious what currently is the latest version and what is the url to obtain it ? I notice it is called luci-mod-network, is there a package for it ? thanks ! ------------------------- lleachii | 2025-12-27 20:24:45 UTC | #6 [quote="shodanx, post:5, topic:220640"] I am curious what currently is the latest version and what is the url to obtain it ? I notice it is called luci-mod-network, is there a package for it ? [/quote] @systemcrash ------------------------- systemcrash | 2025-12-31 17:44:25 UTC | #7 It’s updated to align with snapshot and 25.12. DHCP was split into DHCP and DNS. It’s now merged into master and 25. ------------------------- shodanx | 2025-12-31 18:24:00 UTC | #8 Thanks ! Could you provide the link to the current file ? I will try it on my 24.10 router ------------------------- shodanx | 2026-01-02 19:57:44 UTC | #9 I upgraded my router to 24.10.5 I also upgraded luci to the latest packages `root@router:~# opkg list-installed | grep -E '^(luci|luci-app-firewall|luci-app-package-manager|luci-base|luci-light|luci-mod-admin-full|luci-mod-network|luci-mod-stat` `us|luci-mod-system|luci-proto-ipv6|luci-proto-ppp|luci-ssl|luci-theme-bootstrap)'` `luci - 25.365.52131~3ac2e08` `luci-app-firewall - 25.365.52131~3ac2e08` `luci-app-package-manager - 25.365.52131~3ac2e08` `luci-base - 25.365.52131~3ac2e08` `luci-light - 25.365.52131~3ac2e08` `luci-mod-admin-full - 25.365.52131~3ac2e08` `luci-mod-network - 25.365.52131~3ac2e08` `luci-mod-status - 25.365.52131~3ac2e08` `luci-mod-system - 25.365.52131~3ac2e08` `luci-proto-ipv6 - 25.365.52131~3ac2e08` `luci-proto-ppp - 25.365.52131~3ac2e08` `luci-ssl - 25.365.52131~3ac2e08` `luci-theme-bootstrap - 25.365.52131~3ac2e08` Still the “Tags" tab remains elusive ![image|690x130](upload://62ZB5W31Oj0M5d1t0iSxQxfmZmh.png) I searched with git for all the versions of the dhcp.js file and found this long list `git clone ``https://github.com/openwrt/luci.git` `git fetch --all` `git log --all -- modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js` https://pastebin.com/BDGnznv5 So I found the latest version of this file was commit ffa2c130f958d70e0c9bbc40629892b1568cb49e (origin/openwrt-25.12) from Date: Wed Dec 31 18:33:33 2025 +0100 So I tried downloading it and replacing my dhcp.js with it, but alas, the Tag tab did not appear either ``` root@router:~# wget https://raw.githubusercontent.com/openwrt/luci/ffa2c130f958d70e0c9bbc40629892b1568cb49e/module s/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js Downloading 'https://raw.githubusercontent.com/openwrt/luci/ffa2c130f958d70e0c9bbc40629892b1568cb49e/modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js' dhcp.js 100% |*******************************| 38916 0:00:00 ETA Download completed (38916 bytes) root@router:~# find / | grep dhcp | grep js /www/luci-static/resources/protocol/dhcp.js root@router:~# cp /www/luci-static/resources/view/network/dhcp.js dhcp.js.bak root@router:~# cp dhcp.js /www/luci-static/resources/view/network/dhcp.js root@router:~# ``` ------------------------- systemcrash | 2026-01-05 00:42:28 UTC | #10 [quote="systemcrash, post:7, topic:220640"] It’s updated to align with snapshot and 25.12. [/quote] It will only work on 25.12 and snapshot. ------------------------- lleachii | 2026-01-05 06:25:00 UTC | #11 If you (or anyone) has an opportunity, can you show a screenshot of where this is located, or a breadcrumb pseudo navigation to the LuCI page/tab? [quote="systemcrash, post:10, topic:220640"] will only work on 25.12 and snapshot. [/quote] I've been having difficulty locating it. ------------------------- shodanx | 2026-01-05 16:35:52 UTC | #12 Hi, I have updated all luci packages to 25.365.52131\~3ac2e08 ![image|411x500](upload://jMqIRxZ3J5gv6FD3jtw4g8wLGxX.png) But oopsies, this broke my router ! So for the first time I tried the snapshot firmware I got this file https://downloads.openwrt.org/releases/24.10.5/targets/ramips/mt7621/openwrt-24.10.5-ramips-mt7621-netgear_wax202-squashfs-sysupgrade.bin upgrade and wiped settings And I could not ping 192.168.1.1 I waited a long time, rebooted the rooter many times. Uh oh ! Bricked by router ? I have a spare wax202 connected it in its place, back online. I brought the snapshot flashed router to my computer, connected the router directly into my network port, set manual ip address in my computer to 192.168.1.2, still no ping from 192.168.1.1 Waited around 1 hour, rebooted the router a few times, I had ping -t 192.168.1.1 running the whole time… Really started to feel like a bricked router. Then the router started responding to pings to 192.168.1.1 ! ssh’d into it, it’s not safemode, it’s working, fine ? Try to access luci ? (depicted, a new snapshot user figuring it out) ![2026-01-05_11h21s07_2169x8064|134x500](upload://bou6kQy6RpoyNEhETn6EWnk3mOF.jpeg) Not working, long story short, luci’s not installed I ran `apk update` `apk add luci` `apk add luci-ssl` `/etc/init.d/uhttpd restart` Ran my setup script Plugged the router in the right place, internet works and ![image|556x500](upload://or1RCOeOWYCjsr7BJ9jwiioFqE5.png) yay, back in business ! @lleachii To answer your question, here is the tags tab ![image|181x500](upload://2nNT9G4rhW6in5y5Ho9v2tzLOkD.jpeg) ------------------------- lleachii | 2026-01-05 16:57:08 UTC | #13 * Your post seems to imply the tab was missing because you failed to install LuCI on a SNAPSHOT (it was difficult to follow the rationale of your arrows) [quote="shodanx, post:12, topic:220640"] yay, back in business ! [/quote] * I'm still unable to locate the tab in 25.12.0-rc1 - so I'm not sure how you resolved the issue ![image|690x171](upload://19urQXe6FWZIzxdk8HYRurL3KIO.png) [quote="shodanx, post:12, topic:220640"] I have updated all luci packages to 25.365.52131~3ac2e08 [/quote] [quote="shodanx, post:12, topic:220640"] But oopsies, this broke my router ! [/quote] (I recall other posts where it's been mentioned to you that one should not to blindly upgrade packages - but here's the warning again:) Upgrading packages (via the CLI `opkg upgrade` command or the LuCI `Upgrade...` button) can result in major problems. It is generally highly [discouraged](https://openwrt.org/meta/infobox/upgrade_packages_warning), unless you know what you are doing or if there is [specific instruction](https://openwrt.org/advisory/start) to do so. [quote="shodanx, post:12, topic:220640"] To answer your question, here is the tags tab [/quote] Thanks - I was hoping that the developers would clarify. ------------------------- shodanx | 2026-01-05 17:36:24 UTC | #14 To recap tried overwriting dhcp.js with latest, that does not work tried updating to luci 25.365, that does not work (sometimes it does) at the moment flashed router to snapshot learned that luci doesn’t come installed in snapshot, figured it out The arrows indicate my confusion figuring this out The problem is this tab ![image|689x52](upload://46IS1Hn9amOAWHCRIWudKgpbJ1q.png) “Firmware-selector” doesn’t have luci install instructions, like the other two and that leads to confusion of how do you install luci which is simply `apk update ; apk add luci ; apk add luci-ssl ; /etc/init.d/uhttpd restart` I think the reason you are not seeing the tags tab, is that you are on an older version ? The router I just flashed is on luci 26.003.60747\~0d55a89 As systemcrash stated, you should see in the network menu, that DNS and DHCP is split ![image|143x290](upload://ylxUzIet1pQTnIJCWXrvpGENP2O.png) Where you should find this, it works ! ![image|594x287](upload://3JsvIy4rhptjt6H83jAob4ZxIg4.png) And the reason for the last error I faced with “UH OH” Is because I put the “match” in “set”, so, completely the wrong syntax and that borked my router. It’s all fixed now ! Set tags ![image|690x115](upload://PVQFegUiZs7WTaHt6dpnfH0Yx8.png) ![image|483x427](upload://fyhk6v5WICxZZ1Uzj3Je76GuBbF.png) Match tags ![image|634x500](upload://c44vWO45SF86lhFudGIpCKQRvrF.png) ![image|628x376](upload://bU9PRMRHdcxpax4YOrFN45EkHgR.png) This is a per the following, the **--dhcp-mac** ![image|689x212](upload://wumvQuuIeaNbDFIIXkmQpchxyT7.png) ![image|690x204](upload://3hfDVvkZMFEKMMdJcabT0RQOF8Y.png) I am uncertain if I am doing it correctly, “Apply these DHCP Options“ … Here is the dnsmasq manual btw https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html The important parameters are **--dhcp-vendorclass** **--dhcp-userclass** **--dhcp-mac** **--dhcp-circuitid** **--dhcp-subscrid** **--dhcp-match** **--dhcp-name-match** **--tag-if** **--dhcp-ignore** **--dhcp-ignore-names** **--dhcp-generate-names** **--dhcp-broadcast** **--dhcp-boot** **--dhcp-reply-delay** **--dhcp-option** At this time, I have probably the wrong syntax in the match tags https://www.incognito.com/tutorials/dhcp-options-in-plain-english/ It appears there is no DHCP option number or name for MAC **--dhcp-match=set:,|option:|vi-encap:\[,\]** So, what I need might be … **--dhcp-mac .. .? But it used to work on my 23.05 router, I am confused !** My current objective Set option 3,10.0.0.254 and 6,10.0.0.254 to all MACs matching `de:ad:be:ef:*:*` ------------------------- systemcrash | 2026-01-06 03:00:34 UTC | #15 I did not add the MAC tab (`--dhcp-mac`) because leases already has all of that functionality. [quote="shodanx, post:14, topic:220640"] \--tag-if [/quote] This is not implemented in the dnsmasq init script. Those implemented in dmsmasq init currently are: [quote="shodanx, post:14, topic:220640"] **--dhcp-vendorclass** **--dhcp-userclass** **--dhcp-mac** **--dhcp-circuitid** **--dhcp-subscrid** **--dhcp-match** **--dhcp-ignore-names (sort of?)** **--dhcp-broadcast (sort of)** **--dhcp-boot** **--dhcp-option** [/quote] But I implemented tabs for those you’re likely to encounter nowadays. Great write-up by the way. The GUI tab naming follows functionality, not their confusingly named uci conventions. Match tags tab creates uci `tag` entries. The dnsmasq init script does `xappend "--dhcp-option${force:+-force}=tag:$tag,$o"`. Note the `tag:` Set tags tab creates uci `match` entries. The dnsmasq init script does `xappend "--dhcp-match=set:$networkid,$match"`. Note the `set:` [quote="shodanx, post:14, topic:220640"] Set option 3,10.0.0.254 and 6,10.0.0.254 to all MACs matching `de:ad:be:ef:*:*` [/quote] Match tags tab, create two. One with `3,10.0.0.254`. Name it `one`. Second with `6,10.0.0.254`. Name it `two`. Under leases, create a lease with that MAC. Set tag `one` and `two`. Under tags: ![Screenshot 2026-01-06 at 03.41.56|690x405](upload://7BLQtFW0D6AlkcinMnFblIqtJKH.png) Under leases: ![Screenshot 2026-01-06 at 03.58.00|690x105](upload://theYNtJHXDUuw9ikBwvAdLvy3Yc.png) This produces: ``` # cat /var/etc/dnsmasq.conf.cfg01411c ... dhcp-host=de:ad:be:ef:*:*,set:router,set:domain_srv,dead ... dhcp-option=tag:router,3,10.0.0.254 dhcp-option=tag:domain_srv,6,10.0.0.254 ``` Match tags: dnsmasq conditionally applies chosen DHCP options when a specific `tag` is encountered. This means that a client that sends DHCP requests that match a tag somewhere, it gets the options under this named tag applied to it. Set tags: "`match` these `option(6)`s to set this `tag`". This means that dnsmasq tags a client request that contains that option, so that you can apply additional config to it via Match tags. ------------------------- shodanx | 2026-01-06 03:22:19 UTC | #16 I’m also trying to figure out the PXE system now… WIll come back to matching tags to assign options in a bit… Example ![image|690x395](upload://fwRhSYvYaruW3xaCNfCKiDTEWW1.png) Produces a conf file like this root@router:\~# cat /tmp/etc/dnsmasq.conf.cfg01411c # auto-generated config file from /etc/config/dhcp ``` conf-file=/etc/dnsmasq.conf dhcp-authoritative domain-needed localise-queries read-ethers enable-ubus=dnsmasq expand-hosts enable-tftp bind-dynamic local-service log-dhcp cache-size=1000 edns-packet-max=1232 domain=lan local=/lan/ addn-hosts=/tmp/hosts dhcp-leasefile=/tmp/dhcp.leases tftp-root=/www resolv-file=/tmp/resolv.conf.d/resolv.conf.auto 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 dhcp-boot=tag:test2,ipxe.efi dhcp-option=test2,test1 bogus-priv conf-file=/usr/share/dnsmasq/rfc6761.conf dhcp-range=set:lan,10.0.0.100,10.0.0.249,255.255.0.0,12h no-dhcp-interface=wan root@router:~# cat /tmp/etc/dnsmasq.conf.cfg01411c | grep test1 dhcp-option=test2,test1 root@router:~# ``` So we’re getting these lines `dhcp-boot=tag:test2,ipxe.efi` `dhcp-option=test2,test1` Looking at my old notes, which worked, but maybe aren’t the only way to do this ``` dhcp-match=set:x86-legacy,option:client-arch,0 dhcp-boot=tag:x86-legacy,ipxe.x86.undionly.kpxe,router.lan,192.168.1.1 ``` https://forum.openwrt.org/t/feature-request-make-setting-up-ipxe-netbooting-easier-suggest-sane-defaults-suggest-boot-firmwares/153591 SO making some further tests ``` root@router:~# cat /tmp/etc/dnsmasq.conf.cfg01411c # auto-generated config file from /etc/config/dhcp conf-file=/etc/dnsmasq.conf dhcp-authoritative domain-needed localise-queries read-ethers enable-ubus=dnsmasq expand-hosts enable-tftp bind-dynamic local-service log-dhcp cache-size=1000 edns-packet-max=1232 domain=lan local=/lan/ addn-hosts=/tmp/hosts dhcp-leasefile=/tmp/dhcp.leases tftp-root=/www resolv-file=/tmp/resolv.conf.d/resolv.conf.auto 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 dhcp-boot=tag:test2,ipxe.efi,AAAAA,BBBBB dhcp-option=test2,test1 dhcp-option=test2,testA dhcp-option=tag:MYMATCHTAG,60,PXEClient:Arch:00000 bogus-priv conf-file=/usr/share/dnsmasq/rfc6761.conf dhcp-range=set:lan,10.0.0.100,10.0.0.249,255.255.0.0,12h no-dhcp-interface=wan root@router:~# ``` ![image|630x499](upload://tv95Nm9RgXDqytWLBHeUYQuanzd.png) ![image|690x406](upload://oq05NS3cQ6SYLYv97LnnaJECXvs.png) And here is how that works uci show ``` root@router:~# uci show dhcp dhcp.@dnsmasq[0]=dnsmasq dhcp.@dnsmasq[0].domainneeded='1' dhcp.@dnsmasq[0].boguspriv='1' dhcp.@dnsmasq[0].filterwin2k='0' dhcp.@dnsmasq[0].localise_queries='1' dhcp.@dnsmasq[0].rebind_protection='1' dhcp.@dnsmasq[0].rebind_localhost='1' dhcp.@dnsmasq[0].local='/lan/' dhcp.@dnsmasq[0].domain='lan' dhcp.@dnsmasq[0].expandhosts='1' dhcp.@dnsmasq[0].nonegcache='0' dhcp.@dnsmasq[0].cachesize='1000' dhcp.@dnsmasq[0].authoritative='1' dhcp.@dnsmasq[0].readethers='1' dhcp.@dnsmasq[0].leasefile='/tmp/dhcp.leases' dhcp.@dnsmasq[0].resolvfile='/tmp/resolv.conf.d/resolv.conf.auto' dhcp.@dnsmasq[0].localservice='1' dhcp.@dnsmasq[0].ednspacket_max='1232' dhcp.@dnsmasq[0].filter_aaaa='0' dhcp.@dnsmasq[0].filter_a='0' dhcp.@dnsmasq[0].enable_tftp='1' dhcp.@dnsmasq[0].tftp_root='/www' dhcp.@dnsmasq[0].logdhcp='1' dhcp.lan=dhcp dhcp.lan.interface='lan' dhcp.lan.start='100' dhcp.lan.limit='150' dhcp.lan.leasetime='12h' dhcp.lan.dhcpv4='server' dhcp.lan.dhcpv6='disabled' dhcp.lan.ra='disabled' dhcp.lan.ra_slaac='1' dhcp.lan.ra_flags='managed-config' 'other-config' dhcp.lan.ndp='disabled' dhcp.wan=dhcp dhcp.wan.interface='wan' dhcp.wan.ignore='1' dhcp.odhcpd=odhcpd dhcp.odhcpd.leasefile='/tmp/odhcpd.leases' dhcp.odhcpd.leasetrigger='/usr/sbin/odhcpd-update' dhcp.odhcpd.loglevel='4' dhcp.odhcpd.piodir='/tmp/odhcpd-piodir' dhcp.odhcpd.hostsdir='/tmp/hosts' dhcp.@boot[0]=boot dhcp.@boot[0].filename='ipxe.efi' dhcp.@boot[0].networkid='test2' dhcp.@boot[0].servername='AAAAA' dhcp.@boot[0].serveraddress='BBBBB' dhcp.@boot[0].dhcp_option='test1' 'testA' dhcp.MYMATCHTAG=tag dhcp.MYMATCHTAG.dhcp_option='60,PXEClient:Arch:00000' root@router:~# ``` Donc partie importante ``` dhcp.@boot[0]=boot dhcp.@boot[0].filename='ipxe.efi' dhcp.@boot[0].networkid='test2' dhcp.@boot[0].servername='AAAAA' dhcp.@boot[0].serveraddress='BBBBB' dhcp.@boot[0].dhcp_option='test1' 'testA' dhcp.MYMATCHTAG=tag dhcp.MYMATCHTAG.dhcp_option='60,PXEClient:Arch:00000' ``` What matter is the dhcp-boot, and if dhcp-boot uses tags, then they must be valid I think both dhcp-option and dhcp-match can set a tag on a client ``` dhcp-boot=[tag:,],[[,|]] ``` ``` dhcp-match=set:,