luci-app-firewall: extend icmpv6 types available
[project/luci.git] / applications / luci-app-firewall / htdocs / luci-static / resources / view / firewall / rules.js
index cc85e667695f13eef9a3fe700745b17bbf6fc852..6aa0173ce579d5ecc8f645b77d1104afbf7be387 100644 (file)
@@ -1,4 +1,5 @@
 'use strict';
+'require view';
 'require ui';
 'require rpc';
 'require uci';
@@ -29,7 +30,7 @@ function rule_proto_txt(s, ctHelpers) {
        } : null;
 
        m = String(uci.get('firewall', s, 'mark')).match(/^(!\s*)?(0x[0-9a-f]{1,8}|[0-9]{1,10})(?:\/(0x[0-9a-f]{1,8}|[0-9]{1,10}))?$/i);
-       var f = m ? {
+       var w = m ? {
                val:  m[0].toUpperCase().replace(/X/g, 'x'),
                inv:  m[1],
                num:  '0x%02X'.format(+m[2]),
@@ -51,7 +52,7 @@ function rule_proto_txt(s, ctHelpers) {
                dest: uci.get('firewall', s, 'dest'),
                proto: proto,
                helper: h,
-               mark:   f,
+               mark:   w,
                dscp:   d
        });
 }
@@ -61,7 +62,7 @@ function rule_src_txt(s, hosts) {
            d = (uci.get('firewall', s, 'direction') == 'in') ? uci.get('firewall', s, 'device') : null;
 
        return fwtool.fmt(_('From %{src}%{src_device?, interface <var>%{src_device}</var>}%{src_ip?, IP %{src_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{src_port?, port %{src_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}%{src_mac?, MAC %{src_mac#%{next?, }<var%{item.inv? data-tooltip="Match MACs except %{item.val}%{item.hint.name? a.k.a. %{item.hint.name}}.":%{item.hint.name? data-tooltip="%{item.hint.name}"}}>%{item.ival}</var>}}'), {
-               src: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName((z && z != '*') ? z : null) }, [(z == '*') ? E('em', _('any zone')) : (z || E('em', _('this device')))]),
+               src: E('span', { 'class': 'zonebadge', 'style': fwmodel.getZoneColorStyle(z) }, [(z == '*') ? E('em', _('any zone')) : (z ? E('strong', z) : E('em', _('this device')))]),
                src_ip: fwtool.map_invert(uci.get('firewall', s, 'src_ip'), 'toLowerCase'),
                src_mac: fwtool.map_invert(uci.get('firewall', s, 'src_mac'), 'toUpperCase').map(function(v) { return Object.assign(v, { hint: hosts[v.val] }) }),
                src_port: fwtool.map_invert(uci.get('firewall', s, 'src_port')),
@@ -74,7 +75,7 @@ function rule_dest_txt(s) {
            d = (uci.get('firewall', s, 'direction') == 'out') ? uci.get('firewall', s, 'device') : null;
 
        return fwtool.fmt(_('To %{dest}%{dest_device?, interface <var>%{dest_device}</var>}%{dest_ip?, IP %{dest_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{dest_port?, port %{dest_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), {
-               dest: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName((z && z != '*') ? z : null) }, [(z == '*') ? E('em', _('any zone')) : (z || E('em', _('this device')))]),
+               dest: E('span', { 'class': 'zonebadge', 'style': fwmodel.getZoneColorStyle(z) }, [(z == '*') ? E('em', _('any zone')) : (z ? E('strong', z) : E('em', _('this device')))]),
                dest_ip: fwtool.map_invert(uci.get('firewall', s, 'dest_ip'), 'toLowerCase'),
                dest_port: fwtool.map_invert(uci.get('firewall', s, 'dest_port')),
                dest_device: d
@@ -136,7 +137,7 @@ function rule_target_txt(s, ctHelpers) {
        }
 }
 
-return L.view.extend({
+return view.extend({
        callHostHints: rpc.declare({
                object: 'luci-rpc',
                method: 'getHostHints',
@@ -152,11 +153,19 @@ return L.view.extend({
        load: function() {
                return Promise.all([
                        this.callHostHints(),
-                       this.callConntrackHelpers()
+                       this.callConntrackHelpers(),
+                       uci.load('firewall')
                ]);
        },
 
        render: function(data) {
+               if (fwtool.checkLegacySNAT())
+                       return fwtool.renderMigration();
+               else
+                       return this.renderRules(data);
+       },
+
+       renderRules: function(data) {
                var hosts = data[0],
                    ctHelpers = data[1],
                    m, s, o;
@@ -184,13 +193,8 @@ return L.view.extend({
                s.handleAdd = function(ev) {
                        var config_name = this.uciconfig || this.map.config,
                            section_id = uci.add(config_name, this.sectiontype),
-                           opt1, opt2;
-
-                       for (var i = 0; i < this.children.length; i++)
-                               if (this.children[i].option == 'src')
-                                       opt1 = this.children[i];
-                               else if (this.children[i].option == 'dest')
-                                       opt2 = this.children[i];
+                           opt1 = this.getOption('src'),
+                           opt2 = this.getOption('dest');
 
                        opt1.default = 'wan';
                        opt2.default = 'lan';
@@ -227,7 +231,19 @@ return L.view.extend({
                o.modalonly = false;
                o.default = o.enabled;
                o.editable = true;
+               o.tooltip = function(section_id) {
+                       var weekdays = uci.get('firewall', section_id, 'weekdays');
+                       var monthdays = uci.get('firewall', section_id, 'monthdays');
+                       var start_time = uci.get('firewall', section_id, 'start_time');
+                       var stop_time = uci.get('firewall', section_id, 'stop_time');
+                       var start_date = uci.get('firewall', section_id, 'start_date');
+                       var stop_date = uci.get('firewall', section_id, 'stop_date');
+
+                       if (weekdays || monthdays || start_time || stop_time || start_date || stop_date )
+                               return _('Time restrictions are enabled for this rule');
 
+                       return null;
+               };
 
                o = s.taboption('advanced', form.ListValue, 'direction', _('Match device'));
                o.modalonly = true;
@@ -278,27 +294,50 @@ return L.view.extend({
                o.multiple = true;
                o.custom = true;
                o.cast = 'table';
-               o.placeholder = _('any');
-               o.value('', 'any');
+               o.placeholder = _('any/all');
                o.value('address-mask-reply');
                o.value('address-mask-request');
+               o.value('address-unreachable'); /* icmpv6 1:3 */
+               o.value('bad-header');  /* icmpv6 4:0 */
+               o.value('certification-path-solicitation-message'); /* icmpv6 148 */
+               o.value('certification-path-advertisement-message'); /* icmpv6 149 */
                o.value('communication-prohibited');
                o.value('destination-unreachable');
+               o.value('duplicate-address-request'); /* icmpv6 157 */
+               o.value('duplicate-address-confirmation'); /* icmpv6 158 */
                o.value('echo-reply');
                o.value('echo-request');
+               o.value('extended-echo-request'); /* icmpv6 160 */
+               o.value('extended-echo-reply'); /* icmpv6 161 */
+               o.value('fmipv6-message'); /* icmpv6 154 */
                o.value('fragmentation-needed');
+               o.value('home-agent-address-discovery-reply-message'); /* icmpv6 145 */
+               o.value('home-agent-address-discovery-request-message'); /* icmpv6 144 */
                o.value('host-precedence-violation');
                o.value('host-prohibited');
                o.value('host-redirect');
                o.value('host-unknown');
                o.value('host-unreachable');
+               o.value('ilnpv6-locator-update-message'); /* icmpv6 156 */
+               o.value('inverse-neighbour-discovery-advertisement-message'); /* icmpv6 142 */
+               o.value('inverse-neighbour-discovery-solicitation-message'); /* icmpv6 141 */
                o.value('ip-header-bad');
+               o.value('mobile-prefix-advertisement'); /* icmpv6 147 */
+               o.value('mobile-prefix-solicitation'); /* icmpv6 146 */
+               o.value('mpl-control-message'); /* icmpv6 159 */
+               o.value('multicast-router-advertisement'); /* icmpv6 151 */
+               o.value('multicast-router-solicitation'); /* icmpv6 152 */
+               o.value('multicast-router-termination'); /* icmpv6 153 */
                o.value('neighbour-advertisement');
                o.value('neighbour-solicitation');
                o.value('network-prohibited');
                o.value('network-redirect');
                o.value('network-unknown');
                o.value('network-unreachable');
+               o.value('no-route'); /* icmpv6 1:0 */
+               o.value('node-info-query'); /* icmpv6 139 */
+               o.value('node-info-response'); /* icmpv6 140 */
+               o.value('packet-too-big');
                o.value('parameter-problem');
                o.value('port-unreachable');
                o.value('precedence-cutoff');
@@ -306,7 +345,9 @@ return L.view.extend({
                o.value('redirect');
                o.value('required-option-missing');
                o.value('router-advertisement');
+               o.value('router-renumbering'); /* icmpv6 138 */
                o.value('router-solicitation');
+               o.value('rpl-control-message'); /* icmpv6 155 */
                o.value('source-quench');
                o.value('source-route-failed');
                o.value('time-exceeded');
@@ -318,6 +359,9 @@ return L.view.extend({
                o.value('TOS-network-unreachable');
                o.value('ttl-zero-during-reassembly');
                o.value('ttl-zero-during-transit');
+               o.value('v2-multicast-listener-report'); /* icmpv6 143 */
+               o.value('unknown-header-type'); /* icmpv6 4:1 */
+               o.value('unknown-option'); /* icmpv6 4:2 */
                o.depends({ proto: 'icmp', '!contains': true });
                o.depends({ proto: 'icmpv6', '!contains': true });
 
@@ -410,9 +454,11 @@ return L.view.extend({
                fwtool.addLimitOption(s);
                fwtool.addLimitBurstOption(s);
 
-               o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'),
-                       _('Passes additional arguments to iptables. Use with care!'));
-               o.modalonly = true;
+               if (!L.hasSystemFeature('firewall4')) {
+                       o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'),
+                               _('Passes additional arguments to iptables. Use with care!'));
+                       o.modalonly = true;
+               }
 
                o = s.taboption('timed', form.MultiValue, 'weekdays', _('Week Days'));
                o.modalonly = true;
@@ -441,11 +487,11 @@ return L.view.extend({
                for (var i = 1; i <= 31; i++)
                        o.value(i);
 
-               o = s.taboption('timed', form.Value, 'start_time', _('Start Time (hh.mm.ss)'));
+               o = s.taboption('timed', form.Value, 'start_time', _('Start Time (hh:mm:ss)'));
                o.modalonly = true;
                o.datatype = 'timehhmmss';
 
-               o = s.taboption('timed', form.Value, 'stop_time', _('Stop Time (hh.mm.ss)'));
+               o = s.taboption('timed', form.Value, 'stop_time', _('Stop Time (hh:mm:ss)'));
                o.modalonly = true;
                o.datatype = 'timehhmmss';