diff options
Diffstat (limited to 'applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js')
-rw-r--r-- | applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js new file mode 100644 index 000000000..3f1061a10 --- /dev/null +++ b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js @@ -0,0 +1,249 @@ +'use strict'; +'require rpc'; +'require uci'; +'require form'; +'require network'; +'require firewall'; +'require tools.widgets as widgets'; + +return L.view.extend({ + callOffloadSupport: rpc.declare({ + object: 'luci', + method: 'offload_support', + expect: { offload_support: false } + }), + + load: function() { + return this.callOffloadSupport(); + }, + + render: function(hasOffloading) { + var m, s, o, inp, out; + + m = new form.Map('firewall', _('Firewall - Zone Settings'), + _('The firewall creates zones over your network interfaces to control network traffic flow.')); + + s = m.section(form.TypedSection, 'defaults', _('General Settings')); + s.anonymous = true; + s.addremove = false; + + o = s.option(form.Flag, 'syn_flood', _('Enable SYN-flood protection')); + o = s.option(form.Flag, 'drop_invalid', _('Drop invalid packets')); + + var p = [ + s.option(form.ListValue, 'input', _('Input')), + s.option(form.ListValue, 'output', _('Output')), + s.option(form.ListValue, 'forward', _('Forward')) + ]; + + for (var i = 0; i < p.length; i++) { + p[i].value('REJECT', _('reject')); + p[i].value('DROP', _('drop')); + p[i].value('ACCEPT', _('accept')); + } + + /* Netfilter flow offload support */ + + if (hasOffloading) { + s = m.section(form.TypedSection, 'defaults', _('Routing/NAT Offloading'), + _('Experimental feature. Not fully compatible with QoS/SQM.')); + + s.anonymous = true; + s.addremove = false; + + o = s.option(form.Flag, 'flow_offloading', + _('Software flow offloading'), + _('Software based offloading for routing/NAT')); + o.optional = true; + + o = s.option(form.Flag, 'flow_offloading_hw', + _('Hardware flow offloading'), + _('Requires hardware NAT support. Implemented at least for mt7621')); + o.optional = true; + o.depends('flow_offloading', '1'); + } + + + s = m.section(form.GridSection, 'zone', _('Zones')); + s.addremove = true; + s.anonymous = true; + s.sortable = true; + + s.tab('general', _('General Settings')); + s.tab('advanced', _('Advanced Settings')); + + o = s.taboption('general', form.DummyValue, '_generalinfo'); + o.rawhtml = true; + o.modalonly = true; + o.cfgvalue = function(section_id) { + var name = uci.get('firewall', section_id, 'name'); + + return _('This section defines common properties of %q. The <em>input</em> and <em>output</em> options set the default policies for traffic entering and leaving this zone while the <em>forward</em> option describes the policy for forwarded traffic between different networks within the zone. <em>Covered networks</em> specifies which available networks are members of this zone.') + .replace(/%s/g, name).replace(/%q/g, '"' + name + '"'); + }; + + o = s.taboption('general', form.Value, 'name', _('Name')); + o.placeholder = _('Unnamed zone'); + o.modalonly = true; + o.datatype = 'and(uciname,maxlength(11))'; + o.write = function(section_id, formvalue) { + var cfgvalue = this.cfgvalue(section_id); + + if (cfgvalue != formvalue) + return firewall.renameZone(cfgvalue, formvalue); + }; + + o = s.option(widgets.ZoneForwards, '_info', _('Zone ⇒ Forwardings')); + o.editable = true; + o.modalonly = false; + o.cfgvalue = function(section_id) { + return uci.get('firewall', section_id, 'name'); + }; + + var p = [ + s.taboption('general', form.ListValue, 'input', _('Input')), + s.taboption('general', form.ListValue, 'output', _('Output')), + s.taboption('general', form.ListValue, 'forward', _('Forward')) + ]; + + for (var i = 0; i < p.length; i++) { + p[i].value('REJECT', _('reject')); + p[i].value('DROP', _('drop')); + p[i].value('ACCEPT', _('accept')); + p[i].editable = true; + } + + o = s.taboption('general', form.Flag, 'masq', _('Masquerading')); + o.editable = true; + + o = s.taboption('general', form.Flag, 'mtu_fix', _('MSS clamping')); + o.modalonly = true; + + o = s.taboption('general', widgets.NetworkSelect, 'network', _('Covered networks')); + o.modalonly = true; + o.multiple = true; + o.write = function(section_id, formvalue) { + var name = uci.get('firewall', section_id, 'name'), + cfgvalue = this.cfgvalue(section_id); + + if (typeof(cfgvalue) == 'string' && Array.isArray(formvalue) && (cfgvalue == formvalue.join(' '))) + return; + + var tasks = [ firewall.getZone(name) ]; + + if (Array.isArray(formvalue)) + for (var i = 0; i < formvalue.length; i++) { + var netname = formvalue[i]; + tasks.push(network.getNetwork(netname).then(function(net) { + return net || network.addNetwork(netname, { 'proto': 'none' }); + })); + } + + return Promise.all(tasks).then(function(zone_networks) { + if (zone_networks[0]) + for (var i = 1; i < zone_networks.length; i++) + zone_networks[0].addNetwork(zone_networks[i].getName()); + }); + }; + + o = s.taboption('advanced', form.DummyValue, '_advancedinfo'); + o.rawhtml = true; + o.modalonly = true; + o.cfgvalue = function(section_id) { + var name = uci.get('firewall', section_id, 'name'); + + return _('The options below control the forwarding policies between this zone (%s) and other zones. <em>Destination zones</em> cover forwarded traffic <strong>originating from %q</strong>. <em>Source zones</em> match forwarded traffic from other zones <strong>targeted at %q</strong>. The forwarding rule is <em>unidirectional</em>, e.g. a forward from lan to wan does <em>not</em> imply a permission to forward from wan to lan as well.') + .format(name); + }; + + o = s.taboption('advanced', form.ListValue, 'family', _('Restrict to address family')); + o.value('', _('IPv4 and IPv6')); + o.value('ipv4', _('IPv4 only')); + o.value('ipv6', _('IPv6 only')); + o.modalonly = true; + + o = s.taboption('advanced', form.DynamicList, 'masq_src', _('Restrict Masquerading to given source subnets')); + o.depends('family', ''); + o.depends('family', 'ipv4'); + o.datatype = 'list(neg(or(uciname,hostname,ipmask4)))'; + o.placeholder = '0.0.0.0/0'; + o.modalonly = true; + + o = s.taboption('advanced', form.DynamicList, 'masq_dest', _('Restrict Masquerading to given destination subnets')); + o.depends('family', ''); + o.depends('family', 'ipv4'); + o.datatype = 'list(neg(or(uciname,hostname,ipmask4)))'; + o.placeholder = '0.0.0.0/0'; + o.modalonly = true; + + o = s.taboption('advanced', form.Flag, 'conntrack', _('Force connection tracking')); + o.modalonly = true; + + o = s.taboption('advanced', form.Flag, 'log', _('Enable logging on this zone')); + o.modalonly = true; + + o = s.taboption('advanced', form.Value, 'log_limit', _('Limit log messages')); + o.depends('log', '1'); + o.placeholder = '10/minute'; + o.modalonly = true; + + o = s.taboption('general', form.DummyValue, '_forwardinfo'); + o.rawhtml = true; + o.modalonly = true; + o.cfgvalue = function(section_id) { + return _('The options below control the forwarding policies between this zone (%s) and other zones. <em>Destination zones</em> cover forwarded traffic <strong>originating from %q</strong>. <em>Source zones</em> match forwarded traffic from other zones <strong>targeted at %q</strong>. The forwarding rule is <em>unidirectional</em>, e.g. a forward from lan to wan does <em>not</em> imply a permission to forward from wan to lan as well.') + .format(uci.get('firewall', section_id, 'name')); + }; + + out = o = s.taboption('general', widgets.ZoneSelect, 'out', _('Allow forward to <em>destination zones</em>:')); + o.nocreate = true; + o.multiple = true; + o.modalonly = true; + o.filter = function(section_id, value) { + return (uci.get('firewall', section_id, 'name') != value); + }; + o.cfgvalue = function(section_id) { + var out = (this.option == 'out'), + zone = this.lookupZone(uci.get('firewall', section_id, 'name')), + fwds = zone.getForwardingsBy(out ? 'src' : 'dest'), + value = []; + + for (var i = 0; i < fwds.length; i++) + value.push(out ? fwds[i].getDestination() : fwds[i].getSource()); + + return value; + }; + o.write = o.remove = function(section_id, formvalue) { + var out = (this.option == 'out'), + zone = this.lookupZone(uci.get('firewall', section_id, 'name')), + fwds = zone.getForwardingsBy(out ? 'src' : 'dest'); + + if (formvalue == null) + formvalue = []; + + if (Array.isArray(formvalue)) { + for (var i = 0; i < fwds.length; i++) { + var cmp = out ? fwds[i].getDestination() : fwds[i].getSource(); + if (!formvalue.filter(function(d) { return d == cmp }).length) + zone.deleteForwarding(fwds[i]); + } + + for (var i = 0; i < formvalue.length; i++) + if (out) + zone.addForwardingTo(formvalue[i]); + else + zone.addForwardingFrom(formvalue[i]); + } + }; + + inp = o = s.taboption('general', widgets.ZoneSelect, 'in', _('Allow forward from <em>source zones</em>:')); + o.nocreate = true; + o.multiple = true; + o.modalonly = true; + o.write = o.remove = out.write; + o.filter = out.filter; + o.cfgvalue = out.cfgvalue; + + return m.render(); + } +}); |