diff options
Diffstat (limited to 'modules/luci-mod-network/htdocs/luci-static')
5 files changed, 119 insertions, 34 deletions
diff --git a/modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js b/modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js index 97bbf0ab5d..092bbbc14a 100644 --- a/modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js +++ b/modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js @@ -475,7 +475,7 @@ return baseclass.extend({ vid = this.section.formvalue(section_id, 'vid'), name = this.section.getUIElement(section_id, 'name_complex'); - if (base && vid && name && !name.isChanged()) { + if (base && vid && name && !name.isChanged() && isNew) { name.setValue('%s.%d'.format(base, vid)); name.triggerValidation(); } 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 4fd2e66bad..e1333d7954 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 @@ -764,16 +764,22 @@ return view.extend({ so.datatype = 'hostname'; o = s.taboption('leases', form.SectionValue, '__leases__', form.GridSection, 'host', null, - _('Static leases are used to assign fixed IP addresses and symbolic hostnames to DHCP clients. They are also required for non-dynamic interface configurations where only hosts with a corresponding lease are served.') + '<br />' + - _('Use the <em>Add</em> Button to add a new lease entry. The <em>MAC address</em> identifies the host, the <em>IPv4 address</em> specifies the fixed address to use, and the <em>Hostname</em> is assigned as a symbolic name to the requesting host. The optional <em>Lease time</em> can be used to set non-standard host-specific lease time, e.g. 12h, 3d or infinite.')); + _('Static leases are used to assign fixed IP addresses and symbolic hostnames to DHCP clients. They are also required for non-dynamic interface configurations where only hosts with a corresponding lease are served.') + '<br /><br />' + + _('Use the <em>Add</em> Button to add a new lease entry. The <em>MAC address</em> identifies the host, the <em>IPv4 address</em> specifies the fixed address to use, and the <em>Hostname</em> is assigned as a symbolic name to the requesting host. The optional <em>Lease time</em> can be used to set non-standard host-specific lease time, e.g. 12h, 3d or infinite.') + '<br /><br />' + + _('The tag construct filters which host directives are used; more than one tag can be provided, in this case the request must match all of them. Tagged directives are used in preference to untagged ones. Note that one of mac, duid or hostname still needs to be specified (can be a wildcard).')); ss = o.subsection; ss.addremove = true; ss.anonymous = true; ss.sortable = true; + ss.nodescriptions = true; + ss.max_cols = 8; + ss.modaltitle = _('Edit static lease'); - so = ss.option(form.Value, 'name', _('Hostname')); + so = ss.option(form.Value, 'name', + _('Hostname'), + _('Optional hostname to assign')); so.validate = validateHostname; so.rmempty = true; so.write = function(section, value) { @@ -785,20 +791,35 @@ return view.extend({ uci.unset('dhcp', section, 'dns'); }; - so = ss.option(form.Value, 'mac', _('MAC address')); - so.datatype = 'list(macaddr)'; + so = ss.option(form.Value, 'mac', + _('MAC address(es)'), + _('The hardware address(es) of this entry/host, separated by spaces.') + '<br /><br />' + + _('In DHCPv4, it is possible to include more than one mac address. This allows an IP address to be associated with multiple macaddrs, and dnsmasq abandons a DHCP lease to one of the macaddrs when another asks for a lease. It only works reliably if only one of the macaddrs is active at any time.')); + //As a special case, in DHCPv4, it is possible to include more than one hardware address. eg: --dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.2 This allows an IP address to be associated with multiple hardware addresses, and gives dnsmasq permission to abandon a DHCP lease to one of the hardware addresses when another one asks for a lease + so.validate = function(section_id, value) { + var macaddrs = L.toArray(value); + + for (var i = 0; i < macaddrs.length; i++) + if (!macaddrs[i].match(/^([a-fA-F0-9]{2}|\*):([a-fA-F0-9]{2}:|\*:){4}(?:[a-fA-F0-9]{2}|\*)$/)) + return _('Expecting a valid MAC address, optionally including wildcards'); + + return true; + }; so.rmempty = true; so.cfgvalue = function(section) { var macs = L.toArray(uci.get('dhcp', section, 'mac')), result = []; for (var i = 0, mac; (mac = macs[i]) != null; i++) - if (/^([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2})$/.test(mac)) - result.push('%02X:%02X:%02X:%02X:%02X:%02X'.format( + if (/^([0-9a-fA-F]{1,2}|\*):([0-9a-fA-F]{1,2}|\*):([0-9a-fA-F]{1,2}|\*):([0-9a-fA-F]{1,2}|\*):([0-9a-fA-F]{1,2}|\*):([0-9a-fA-F]{1,2}|\*)$/.test(mac)) { + var m = [ parseInt(RegExp.$1, 16), parseInt(RegExp.$2, 16), parseInt(RegExp.$3, 16), parseInt(RegExp.$4, 16), - parseInt(RegExp.$5, 16), parseInt(RegExp.$6, 16))); + parseInt(RegExp.$5, 16), parseInt(RegExp.$6, 16) + ]; + result.push(m.map(function(n) { return isNaN(n) ? '*' : '%02X'.format(n) }).join(':')); + } return result.length ? result.join(' ') : null; }; so.renderWidget = function(section_id, option_index, cfgvalue) { @@ -831,7 +852,8 @@ return view.extend({ so.value(mac, hint ? '%s (%s)'.format(mac, hint) : mac); }); - so = ss.option(form.Value, 'ip', _('IPv4 address')); + so = ss.option(form.Value, 'ip', _('IPv4 address'), _('The IP address to be used for this host, or <em>ignore</em> to ignore any DHCP request from this host.')); + so.value('ignore', _('Ignore')); so.datatype = 'or(ip4addr,"ignore")'; so.validate = function(section, value) { var m = this.section.formvalue(section, 'mac'), @@ -863,16 +885,60 @@ return view.extend({ so.value(ipv4, ipaddrs[ipv4] ? '%s (%s)'.format(ipv4, ipaddrs[ipv4]) : ipv4); }); - so = ss.option(form.Value, 'leasetime', _('Lease time')); + so = ss.option(form.Value, 'leasetime', + _('Lease time'), + _('Host-specific lease time, e.g. <code>5m</code>, <code>3h</code>, <code>7d</code>.')); so.rmempty = true; - - so = ss.option(form.Value, 'duid', _('DUID')); + so.value('5m', _('5m (5 minutes)')); + so.value('3h', _('3h (3 hours)')); + so.value('12h', _('12h (12 hours - default)')); + so.value('7d', _('7d (7 days)')); + so.value('infinite', _('infinite (lease does not expire)')); + + so = ss.option(form.Value, 'duid', + _('DUID'), + _('The DHCPv6-DUID (DHCP unique identifier) of this host.')); so.datatype = 'and(rangelength(20,36),hexstring)'; Object.keys(duids).forEach(function(duid) { so.value(duid, '%s (%s)'.format(duid, duids[duid].hostname || duids[duid].macaddr || duids[duid].ip6addr || '?')); }); - so = ss.option(form.Value, 'hostid', _('IPv6 suffix (hex)')); + so = ss.option(form.Value, 'hostid', + _('IPv6-Suffix (hex)'), + _('The IPv6 interface identifier (address suffix) as hexadecimal number (max. 8 chars).')); + so.datatype = 'and(rangelength(0,8),hexstring)'; + + so = ss.option(form.DynamicList, 'tag', + _('Tag'), + _('Assign new, freeform tags to this entry.')); + + so = ss.option(form.DynamicList, 'match_tag', + _('Match Tag'), + _('When a host matches an entry then the special tag <em>known</em> is set. Use <em>known</em> to match all known hosts.') + '<br /><br />' + + _('Ignore requests from unknown machines using <em>!known</em>.') + '<br /><br />' + + _('If a host matches an entry which cannot be used because it specifies an address on a different subnet, the tag <em>known-othernet</em> is set.')); + so.value('known', _('known')); + so.value('!known', _('!known (not known)')); + so.value('known-othernet', _('known-othernet (on different subnet)')); + so.optional = true; + + so = ss.option(form.Value, 'instance', + _('Instance'), + _('Dnsmasq instance to which this DHCP host 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) { + so.value(index, '%s (Domain: %s, Local: %s)'.format(index, val.domain || '?', val.local || '?')); + }); + + + so = ss.option(form.Flag, 'broadcast', + _('Broadcast'), + _('Force broadcast DHCP response.')); + + so = ss.option(form.Flag, 'dns', + _('Forward/reverse DNS'), + _('Add static forward and reverse DNS entries for this host.')); o = s.taboption('leases', CBILeaseStatus, '__status__'); diff --git a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js index 8e400fb46b..1bfa95501a 100644 --- a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js +++ b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js @@ -76,7 +76,7 @@ return view.extend({ var table = E('table', { 'class': 'table' }, [ E('tr', { 'class': 'tr' }, [ - E('td', { 'class': 'td left' }, [ + E('td', { 'class': 'td left', 'style': 'overflow:initial' }, [ E('input', { 'style': 'margin:5px 0', 'type': 'text', @@ -99,7 +99,7 @@ return view.extend({ ]) ]), - E('td', { 'class': 'td left' }, [ + E('td', { 'class': 'td left', 'style': 'overflow:initial' }, [ E('input', { 'style': 'margin:5px 0', 'type': 'text', diff --git a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js index d0ffe02ee9..82bf269e8a 100644 --- a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js +++ b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js @@ -231,6 +231,7 @@ function get_netmask(s, use_cfgvalue) { function has_peerdns(proto) { switch (proto) { case 'dhcp': + case 'dhcpv6': case 'qmi': case 'ppp': case 'pppoe': @@ -831,6 +832,13 @@ return view.extend({ } }; + so = ss.taboption('ipv6-ra', form.Value, 'ra_pref64', _('NAT64 prefix'), _('Announce NAT64 prefix in <abbr title="Router Advertisement">RA</abbr> messages.')); + so.optional = true; + so.datatype = 'cidr6'; + so.placeholder = '64:ff9b::/96'; + so.depends('ra', 'server'); + so.depends({ ra: 'hybrid', master: '0' }); + so = ss.taboption('ipv6-ra', form.Value, 'ra_maxinterval', _('Max <abbr title="Router Advertisement">RA</abbr> interval'), _('Maximum time allowed between sending unsolicited <abbr title="Router Advertisement, ICMPv6 Type 134">RA</abbr>. Default is 600 seconds.')); so.optional = true; so.datatype = 'uinteger'; @@ -901,6 +909,10 @@ return view.extend({ _('Forward DHCPv6 messages between the designated master interface and downstream interfaces.')); so.value('hybrid', _('hybrid mode'), ' '); + so = ss.taboption('ipv6', form.Value, 'dhcpv6_pd_min_len', _('<abbr title="Prefix Delegation">PD</abbr> minimum length'), + _('Configures the minimum delegated prefix length assigned to a requesting downstream router, potentially overriding a requested prefix length. If left unspecified, the device will assign the smallest available prefix greater than or equal to the requested prefix.')); + so.datatype = 'range(1,62)'; + so.depends('dhcpv6', 'server'); so = ss.taboption('ipv6', form.DynamicList, 'dns', _('Announced IPv6 DNS servers'), _('Specifies a fixed list of IPv6 DNS server addresses to announce via DHCPv6. If left unspecified, the device will announce itself as IPv6 DNS server unless the <em>Local IPv6 DNS server</em> option is disabled.')); @@ -1501,21 +1513,27 @@ return view.extend({ s.anonymous = true; o = s.option(form.ListValue, 'annex', _('Annex')); - o.value('a', _('Annex A + L + M (all)')); - o.value('b', _('Annex B (all)')); - o.value('j', _('Annex J (all)')); - o.value('m', _('Annex M (all)')); - o.value('bdmt', _('Annex B G.992.1')); - o.value('b2', _('Annex B G.992.3')); - o.value('b2p', _('Annex B G.992.5')); + if (dslModemType == 'vdsl') { + o.value('a', _('ADSL (all variants) Annex A/L/M + VDSL2 Annex A/B/C')); + o.value('b', _('ADSL (all variants) Annex B + VDSL2 Annex A/B/C')); + o.value('j', _('ADSL (all variants) Annex B/J + VDSL2 Annex A/B/C')); + } else { + o.value('a', _('ADSL (all variants) Annex A/L/M')); + o.value('b', _('ADSL (all variants) Annex B')); + o.value('j', _('ADSL (all variants) Annex B/J')); + } + o.value('m', _('ADSL (all variants) Annex M')); o.value('at1', _('ANSI T1.413')); - o.value('admt', _('Annex A G.992.1')); - o.value('alite', _('Annex A G.992.2')); - o.value('a2', _('Annex A G.992.3')); - o.value('a2p', _('Annex A G.992.5')); - o.value('l', _('Annex L G.992.3 POTS 1')); - o.value('m2', _('Annex M G.992.3')); - o.value('m2p', _('Annex M G.992.5')); + o.value('admt', _('ADSL (G.992.1) Annex A')); + o.value('bdmt', _('ADSL (G.992.1) Annex B')); + o.value('alite', _('Splitterless ADSL (G.992.2) Annex A')); + o.value('a2', _('ADSL2 (G.992.3) Annex A')); + o.value('b2', _('ADSL2 (G.992.3) Annex B')); + o.value('l', _('ADSL2 (G.992.3) Annex L')); + o.value('m2', _('ADSL2 (G.992.3) Annex M')); + o.value('a2p', _('ADSL2+ (G.992.5) Annex A')); + o.value('b2p', _('ADSL2+ (G.992.5) Annex B')); + o.value('m2p', _('ADSL2+ (G.992.5) Annex M')); o = s.option(form.ListValue, 'tone', _('Tone')); o.value('', _('auto')); diff --git a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js index 6b1bd262fb..a099746548 100644 --- a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js +++ b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js @@ -1143,7 +1143,7 @@ return view.extend({ /* https://w1.fi/cgit/hostap/commit/?id=34f7c699a6bcb5c45f82ceb6743354ad79296078 */ /* multicast_to_unicast https://github.com/openwrt/openwrt/commit/7babb978ad9d7fc29acb1ff86afb1eb343af303a */ - o = ss.taboption('advanced', form.Flag, 'multicast_to_unicast', _('Multi To Unicast'), _('ARP, IPv4 and IPv6 (even 802.1Q) with multicast destination MACs are unicast to the STA MAC address. Note: This is not Directed Multicast Service (DMS) in 802.11v. Note: might break receiver STA multicast expectations.')); + o = ss.taboption('advanced', form.Flag, 'multicast_to_unicast_all', _('Multi To Unicast'), _('ARP, IPv4 and IPv6 (even 802.1Q) with multicast destination MACs are unicast to the STA MAC address. Note: This is not Directed Multicast Service (DMS) in 802.11v. Note: might break receiver STA multicast expectations.')); o.rmempty = true; o = ss.taboption('advanced', form.Flag, 'isolate', _('Isolate Clients'), _('Prevents client-to-client communication')); @@ -1157,10 +1157,11 @@ return view.extend({ if (/^radio\d+\.network/.test(o.placeholder)) o.placeholder = ''; + var macaddr = uci.get('wireless', radioNet.getName(), 'macaddr'); o = ss.taboption('advanced', form.Value, 'macaddr', _('MAC address'), _('Override default MAC address - the range of usable addresses might be limited by the driver')); - o.optional = true; - o.placeholder = radioNet.getActiveBSSID(); - o.datatype = 'macaddr'; + o.value('', _('driver default (%s)').format(!macaddr ? radioNet.getActiveBSSID() : _('no override'))); + o.value('random', _('randomly generated')); + o.datatype = "or('random',macaddr)"; o = ss.taboption('advanced', form.Flag, 'short_preamble', _('Short Preamble')); o.default = o.enabled; |