From dfb4e3233a636962b02c8ccd8b172ee8e8322d9e Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Tue, 21 Oct 2025 23:53:29 +0200 Subject: [PATCH] luci-mod-network: split PXE into dnsmasq/odhcpd functions in dhcp.js MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This makes it clearer which daemon each part belongs to. But more importantly, it lays the ground for the next patch. Signed-off-by: David Härdeman --- .../resources/view/network/dhcp.js | 268 +++++++++--------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js index 0e625a442d..30070522bc 100644 --- a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js +++ b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js @@ -242,140 +242,6 @@ return view.extend({ this.add_leases_cfg(s, hosts, duids, pools, macdata); - s.tab('pxe_tftp', _('PXE/TFTP')); - - // Begin pxe_tftp - o = s.taboption('pxe_tftp', form.Flag, 'enable_tftp', - _('Enable TFTP server'), - _('Enable the built-in single-instance TFTP server.')); - o.optional = true; - - o = s.taboption('pxe_tftp', form.Value, 'tftp_root', - _('TFTP server root'), - _('Root directory for files served via TFTP. Enable TFTP server and TFTP server root turn on the TFTP server and serve files from TFTP server root.')); - o.depends('enable_tftp', '1'); - o.optional = true; - o.placeholder = '/'; - - o = s.taboption('pxe_tftp', form.Value, 'dhcp_boot', - _('Network boot image'), - _('Filename of the boot image advertised to clients.')); - o.depends('enable_tftp', '1'); - o.optional = true; - o.placeholder = 'pxelinux.0'; - - /* PXE - https://openwrt.org/docs/guide-user/base-system/dhcp#booting_options */ - o = s.taboption('pxe_tftp', form.SectionValue, '__pxe__', form.GridSection, 'boot', null, - _('Special PXE boot options for Dnsmasq.')); - ss = o.subsection; - ss.addremove = true; - ss.anonymous = true; - ss.modaltitle = _('Edit PXE/TFTP/BOOTP Host'); - ss.nodescriptions = true; - - so = ss.option(form.Value, 'filename', - _('Filename'), - _('Host requests this filename from the boot server.')); - so.optional = false; - so.placeholder = 'pxelinux.0'; - - so = ss.option(form.Value, 'servername', - _('Server name'), - _('The hostname of the boot server')); - so.optional = false; - so.placeholder = 'myNAS'; - - so = ss.option(form.Value, 'serveraddress', - _('Server address'), - _('The IP address of the boot server')); - so.optional = false; - so.placeholder = '192.168.1.2'; - - so = ss.option(form.DynamicList, 'dhcp_option', - _('DHCP Options'), - _('Additional options to send to the below match tags.') + '
' + - _('%s means "the address of the system running dnsmasq".').format('0.0.0.0')); - so.optional = true; - so.placeholder = 'option:root-path,192.168.1.2:/data/netboot/root'; - - so = ss.option(form.Value, 'networkid', - _('Match this Tag'), - _('Only DHCP Clients with this tag are sent this boot option.')); - so.optional = true; - so.noaliases = true; - - so = ss.option(form.Flag, 'force', - _('Force'), - _('Always send the chosen DHCP options. Sometimes needed, with e.g. PXELinux.')); - so.optional = true; - - so = ss.option(form.Value, 'instance', - _('Instance'), - _('Dnsmasq instance to which this boot section is bound. If unspecified, the section is valid for all dnsmasq instances.')); - so.optional = true; - - Object.values(L.uci.sections('dhcp', 'dnsmasq')).forEach(function(val, index) { - var [name, display_str] = generateDnsmasqInstanceEntry(val); - so.value(name, display_str); - }); - - o = s.taboption('pxe_tftp', form.SectionValue, '__pxe6__', form.TableSection, 'boot6', null, - _('Special PXE boot options for odhcpd IPv6.') + ' ' + - _('The last entry absent architecture becomes the default.')); - ss = o.subsection; - ss.addremove = true; - ss.anonymous = true; - ss.nodescriptions = true; - ss.sortable = true; - - /* URL https://www.rfc-editor.org/rfc/rfc5970.html#section-3.1 i.e. https://www.rfc-editor.org/rfc/rfc3986 */ - so = ss.option(form.Value, 'url', _('URL')); - so.optional = false; - so.datatype = 'string'; - so.placeholder = 'tftp://[fd11::1]/pxe.efi'; - - // Arch https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#processor-architecture - so = ss.option(form.Value, 'arch', _('Architecture')); - so.optional = true; - so.rmempty = true; - so.datatype = 'range(0,65535)'; - so.default = ''; - so.value(''); - so.value('0', _('00: x86 BIOS')); - so.value('6', _('06: x86 UEFI (IA32)')); - so.value('7', _('07: x64 UEFI')); - so.value('10', _('10: ARM 32-bit UEFI')); - so.value('11', _('11: ARM 64-bit UEFI')); - so.value('15', _('15: x86 UEFI boot from HTTP')); - so.value('16', _('16: x64 UEFI boot from HTTP')); - so.value('17', _('17: ebc boot from HTTP')); - so.value('18', _('18: ARM UEFI 32 boot from HTTP')); - so.value('19', _('19: ARM UEFI 64 boot from HTTP')); - so.value('20', _('20: pc/at bios boot from HTTP')); - so.value('21', _('21: ARM 32 uboot')); - so.value('22', _('22: ARM 64 uboot')); - so.value('23', _('23: ARM uboot 32 boot from HTTP')); - so.value('24', _('24: ARM uboot 64 boot from HTTP')); - so.value('25', _('25: RISC-V 32-bit UEFI')); - so.value('26', _('26: RISC-V 32-bit UEFI boot from HTTP')); - so.value('27', _('27: RISC-V 64-bit UEFI')); - so.value('28', _('28: RISC-V 64-bit UEFI boot from HTTP')); - so.value('29', _('29: RISC-V 128-bit UEFI')); - so.value('30', _('30: RISC-V 128-bit UEFI boot from HTTP')); - so.value('31', _('31: s390 Basic')); - so.value('32', _('32: s390 Extended')); - so.value('33', _('33: MIPS 32-bit UEFI')); - so.value('34', _('34: MIPS 64-bit UEFI')); - so.value('35', _('35: Sunway 32-bit UEFI')); - so.value('36', _('36: Sunway 64-bit UEFI')); - so.value('37', _('37: LoongArch 32-bit UEFI')); - so.value('38', _('38: LoongArch 32-bit UEFI boot from HTTP')); - so.value('39', _('39: LoongArch 64-bit UEFI')); - so.value('39', _('40: LoongArch 64-bit UEFI boot from HTTP')); - so.value('41', _('41: ARM rpiboot')); - // End pxe_tftp - - return m.render().then(function(mapEl) { poll.add(function() { return callDHCPLeases().then(function(leaseinfo) { @@ -662,6 +528,83 @@ return view.extend({ so.placeholder = 'lan'; // End relay + // Begin pxe_tftp + s.tab('pxe_tftp', _('PXE/TFTP')); + o = s.taboption('pxe_tftp', form.Flag, 'enable_tftp', + _('Enable TFTP server'), + _('Enable the built-in single-instance TFTP server.')); + o.optional = true; + + o = s.taboption('pxe_tftp', form.Value, 'tftp_root', + _('TFTP server root'), + _('Root directory for files served via TFTP. Enable TFTP server and TFTP server root turn on the TFTP server and serve files from TFTP server root.')); + o.depends('enable_tftp', '1'); + o.optional = true; + o.placeholder = '/'; + + o = s.taboption('pxe_tftp', form.Value, 'dhcp_boot', + _('Network boot image'), + _('Filename of the boot image advertised to clients.')); + o.depends('enable_tftp', '1'); + o.optional = true; + o.placeholder = 'pxelinux.0'; + + // PXE - https://openwrt.org/docs/guide-user/base-system/dhcp#booting_options + o = s.taboption('pxe_tftp', form.SectionValue, '__pxe__', form.GridSection, 'boot', null, + _('Special PXE boot options for Dnsmasq.')); + ss = o.subsection; + ss.addremove = true; + ss.anonymous = true; + ss.modaltitle = _('Edit PXE/TFTP/BOOTP Host'); + ss.nodescriptions = true; + + so = ss.option(form.Value, 'filename', + _('Filename'), + _('Host requests this filename from the boot server.')); + so.optional = false; + so.placeholder = 'pxelinux.0'; + + so = ss.option(form.Value, 'servername', + _('Server name'), + _('The hostname of the boot server')); + so.optional = false; + so.placeholder = 'myNAS'; + + so = ss.option(form.Value, 'serveraddress', + _('Server address'), + _('The IP address of the boot server')); + so.optional = false; + so.placeholder = '192.168.1.2'; + + so = ss.option(form.DynamicList, 'dhcp_option', + _('DHCP Options'), + _('Additional options to send to the below match tags.') + '
' + + _('%s means "the address of the system running dnsmasq".').format('0.0.0.0')); + so.optional = true; + so.placeholder = 'option:root-path,192.168.1.2:/data/netboot/root'; + + so = ss.option(form.Value, 'networkid', + _('Match this Tag'), + _('Only DHCP Clients with this tag are sent this boot option.')); + so.optional = true; + so.noaliases = true; + + so = ss.option(form.Flag, 'force', + _('Force'), + _('Always send the chosen DHCP options. Sometimes needed, with e.g. PXELinux.')); + so.optional = true; + + so = ss.option(form.Value, 'instance', + _('Instance'), + _('Dnsmasq instance to which this boot section is bound. If unspecified, the section is valid for all dnsmasq instances.')); + so.optional = true; + + Object.values(L.uci.sections('dhcp', 'dnsmasq')).forEach(function(val, index) { + var [name, display_str] = generateDnsmasqInstanceEntry(val); + so.value(name, display_str); + }); + // End pxe_tftp + return s; }, @@ -707,6 +650,63 @@ return view.extend({ so.value('5', 'Notice'); so.value('6', 'Info'); so.value('7', 'Debug'); + + // Begin pxe_tftp + o = s.taboption('pxe_tftp', form.SectionValue, '__pxe6__', form.TableSection, 'boot6', null, + _('Special PXE boot options for odhcpd IPv6.') + ' ' + + _('The last entry absent architecture becomes the default.')); + ss = o.subsection; + ss.addremove = true; + ss.anonymous = true; + ss.nodescriptions = true; + ss.sortable = true; + + // URL https://www.rfc-editor.org/rfc/rfc5970.html#section-3.1 i.e. https://www.rfc-editor.org/rfc/rfc3986 + so = ss.option(form.Value, 'url', _('URL')); + so.optional = false; + so.datatype = 'string'; + so.placeholder = 'tftp://[fd11::1]/pxe.efi'; + + // Arch https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#processor-architecture + so = ss.option(form.Value, 'arch', _('Architecture')); + so.optional = true; + so.rmempty = true; + so.datatype = 'range(0,65535)'; + so.default = ''; + so.value(''); + so.value('0', _('00: x86 BIOS')); + so.value('6', _('06: x86 UEFI (IA32)')); + so.value('7', _('07: x64 UEFI')); + so.value('10', _('10: ARM 32-bit UEFI')); + so.value('11', _('11: ARM 64-bit UEFI')); + so.value('15', _('15: x86 UEFI boot from HTTP')); + so.value('16', _('16: x64 UEFI boot from HTTP')); + so.value('17', _('17: ebc boot from HTTP')); + so.value('18', _('18: ARM UEFI 32 boot from HTTP')); + so.value('19', _('19: ARM UEFI 64 boot from HTTP')); + so.value('20', _('20: pc/at bios boot from HTTP')); + so.value('21', _('21: ARM 32 uboot')); + so.value('22', _('22: ARM 64 uboot')); + so.value('23', _('23: ARM uboot 32 boot from HTTP')); + so.value('24', _('24: ARM uboot 64 boot from HTTP')); + so.value('25', _('25: RISC-V 32-bit UEFI')); + so.value('26', _('26: RISC-V 32-bit UEFI boot from HTTP')); + so.value('27', _('27: RISC-V 64-bit UEFI')); + so.value('28', _('28: RISC-V 64-bit UEFI boot from HTTP')); + so.value('29', _('29: RISC-V 128-bit UEFI')); + so.value('30', _('30: RISC-V 128-bit UEFI boot from HTTP')); + so.value('31', _('31: s390 Basic')); + so.value('32', _('32: s390 Extended')); + so.value('33', _('33: MIPS 32-bit UEFI')); + so.value('34', _('34: MIPS 64-bit UEFI')); + so.value('35', _('35: Sunway 32-bit UEFI')); + so.value('36', _('36: Sunway 64-bit UEFI')); + so.value('37', _('37: LoongArch 32-bit UEFI')); + so.value('38', _('38: LoongArch 32-bit UEFI boot from HTTP')); + so.value('39', _('39: LoongArch 64-bit UEFI')); + so.value('39', _('40: LoongArch 64-bit UEFI boot from HTTP')); + so.value('41', _('41: ARM rpiboot')); + // End pxe_tftp }, add_leases_cfg: function(s, hosts, duids, pools, macdata) { -- 2.30.2