luci-mod-network: change ULA explanation
[project/luci.git] / modules / luci-mod-network / htdocs / luci-static / resources / view / network / interfaces.js
index 82bf269e8abad2f79b79add2c620b6b041a56670..fd7487b3dea51a8af81b390032a23bdd62920a01 100644 (file)
@@ -245,6 +245,24 @@ function has_peerdns(proto) {
        return false;
 }
 
+function has_sourcefilter(proto) {
+       switch (proto) {
+       case '3g':
+       case 'dhcpv6':
+       case 'directip':
+       case 'mbim':
+       case 'ncm':
+       case 'ppp':
+       case 'pppoa':
+       case 'pppoe':
+       case 'pptp':
+       case 'qmi':
+               return true;
+       }
+
+       return false;
+}
+
 var cbiRichListValue = form.ListValue.extend({
        renderWidget: function(section_id, option_index, cfgvalue) {
                var choices = this.transformChoices();
@@ -537,6 +555,11 @@ return view.extend({
                                tdEl.lastChild.childNodes[3].disabled = true;
                        }
 
+                       if (dynamic) {
+                               //disable the 'Edit' button on dynamic interfaces
+                               tdEl.lastChild.childNodes[2].disabled = true;
+                       }
+
                        return tdEl;
                };
 
@@ -588,6 +611,10 @@ return view.extend({
                                o.nobridges = false;
                                o.optional = false;
                                o.network = ifc.getName();
+                               o.exclude = '@' + ifc.getName();
+
+                               o = s.taboption('general', form.Flag, 'disabled', _('Disable this interface'));
+                               o.modalonly = true;
 
                                o = s.taboption('general', form.Flag, 'auto', _('Bring up on boot'));
                                o.modalonly = true;
@@ -740,12 +767,35 @@ return view.extend({
                                                var hybrid_downstream_desc = _('Operate in <em>relay mode</em> if a designated master interface is configured and active, otherwise fall back to <em>server mode</em>.'),
                                                    ndp_downstream_desc = _('Operate in <em>relay mode</em> if a designated master interface is configured and active, otherwise disable <abbr title="Neighbour Discovery Protocol">NDP</abbr> proxying.'),
                                                    hybrid_master_desc = _('Operate in <em>relay mode</em> if an upstream IPv6 prefix is present, otherwise disable service.'),
+                                                   ra_server_allowed = true,
                                                    checked = this.formvalue(section_id),
                                                    dhcpv6 = this.section.getOption('dhcpv6').getUIElement(section_id),
                                                    ndp = this.section.getOption('ndp').getUIElement(section_id),
                                                    ra = this.section.getOption('ra').getUIElement(section_id);
 
-                                               if (checked == '1' || protoval != 'static') {
+                                               /* Assume that serving RAs by default is fine, but disallow it for certain
+                                                  interface protocols such as DHCP, DHCPv6 or the various PPP flavors.
+                                                  The intent is to only allow RA serving for interface protocols doing
+                                                  some kind of static IP config over something resembling a layer 2
+                                                  ethernet device. */
+                                               switch (protoval) {
+                                               case 'dhcp':
+                                               case 'dhcpv6':
+                                               case '3g':
+                                               case 'l2tp':
+                                               case 'ppp':
+                                               case 'pppoa':
+                                               case 'pppoe':
+                                               case 'pptp':
+                                               case 'pppossh':
+                                               case 'ipip':
+                                               case 'gre':
+                                               case 'grev6':
+                                                       ra_server_allowed = false;
+                                                       break;
+                                               }
+
+                                               if (checked == '1' || !ra_server_allowed) {
                                                        dhcpv6.node.querySelector('li[data-value="server"]').setAttribute('unselectable', '');
 
                                                        if (dhcpv6.getValue() == 'server')
@@ -763,7 +813,7 @@ return view.extend({
                                                        ndp.node.querySelector('li[data-value="hybrid"] > div > span').innerHTML = hybrid_master_desc;
                                                }
                                                else {
-                                                       if (protoval == 'static') {
+                                                       if (ra_server_allowed) {
                                                                dhcpv6.node.querySelector('li[data-value="server"]').removeAttribute('unselectable');
                                                                ra.node.querySelector('li[data-value="server"]').removeAttribute('unselectable');
                                                        }
@@ -948,7 +998,7 @@ return view.extend({
                                        so.value('hybrid', _('hybrid mode'), ' ');
 
 
-                                       so = ss.taboption('ipv6', form.Flag, 'ndproxy_routing', _('Learn routes'), _('Setup routes for proxied IPv6 neighbours.'));
+                                       so = ss.taboption('ipv6', form.Flag, 'ndproxy_routing', _('Learn routes'), _('Set up routes for proxied IPv6 neighbours.'));
                                        so.default = so.enabled;
                                        so.depends('ndp', 'relay');
                                        so.depends('ndp', 'hybrid');
@@ -956,6 +1006,18 @@ return view.extend({
                                        so = ss.taboption('ipv6', form.Flag, 'ndproxy_slave', _('NDP-Proxy slave'), _('Set interface as NDP-Proxy external slave. Default is off.'));
                                        so.depends({ ndp: 'relay', master: '0' });
                                        so.depends({ ndp: 'hybrid', master: '0' });
+
+                                       so = ss.taboption('ipv6', form.Value, 'preferred_lifetime', _('IPv6 Prefix Lifetime'), _('Preferred lifetime for a prefix.'));
+                                       so.optional = true;
+                                       so.placeholder = '12h';
+                                       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)'));
+
+                                       //This is a ra_* setting, but its placement is more logical/findable under IPv6 settings.
+                                       so = ss.taboption('ipv6', form.Flag, 'ra_useleasetime', _('Follow IPv4 Lifetime'), _('DHCPv4 <code>leasetime</code> is used as limit and preferred lifetime of the IPv6 prefix.'));
+                                       so.optional = true;
                                }
 
                                ifc.renderFormOptions(s);
@@ -997,7 +1059,7 @@ return view.extend({
                                for (var i = 0; i < rtTables.length; i++)
                                        o.value(rtTables[i][1], '%s (%d)'.format(rtTables[i][1], rtTables[i][0]));
 
-                               if (protoval == 'dhcpv6') {
+                               if (has_sourcefilter(protoval)) {
                                        o = nettools.replaceOption(s, 'advanced', form.Flag, 'sourcefilter', _('IPv6 source routing'), _('Automatically handle multiple uplink interfaces using source-based policy routing.'));
                                        o.default = o.enabled;
                                }
@@ -1501,7 +1563,10 @@ return view.extend({
                s.addremove = false;
                s.anonymous = true;
 
-               o = s.option(form.Value, 'ula_prefix', _('IPv6 ULA-Prefix'), _('Unique Local Address - in the range <code>fc00::/7</code>.  Typically only within the &#8216;local&#8217; half <code>fd00::/8</code>. ULA for IPv6 is analogous to IPv4 private network addressing. This prefix is randomly generated at first install.'));
+               o = s.option(form.Value, 'ula_prefix', _('IPv6 ULA-Prefix'),
+                       _('Unique Local Address (%s) - prefix <code>fd00::/8</code> (the L bit is always 1).').format('<a href="%s" target="_blank">RFC4193</a>').format('https://datatracker.ietf.org/doc/html/rfc4193#section-3') + ' ' +
+                       _('ULA for IPv6 is analogous to IPv4 private network addressing.') + ' ' +
+                       _('This prefix is randomly generated at first install.'));
                o.datatype = 'cidr6';
 
                o = s.option(form.Flag, 'packet_steering', _('Packet Steering'), _('Enable packet steering across all CPUs. May help or hinder network speed.'));