7 'require tools.widgets as widgets';
10 callOffloadSupport: rpc.declare({
12 method: 'offload_support',
13 expect: { offload_support: false }
17 return this.callOffloadSupport();
20 render: function(hasOffloading) {
21 var m, s, o, inp, out;
23 m = new form.Map('firewall', _('Firewall - Zone Settings'),
24 _('The firewall creates zones over your network interfaces to control network traffic flow.'));
26 s = m.section(form.TypedSection, 'defaults', _('General Settings'));
30 o = s.option(form.Flag, 'syn_flood', _('Enable SYN-flood protection'));
31 o = s.option(form.Flag, 'drop_invalid', _('Drop invalid packets'));
34 s.option(form.ListValue, 'input', _('Input')),
35 s.option(form.ListValue, 'output', _('Output')),
36 s.option(form.ListValue, 'forward', _('Forward'))
39 for (var i = 0; i < p.length; i++) {
40 p[i].value('REJECT', _('reject'));
41 p[i].value('DROP', _('drop'));
42 p[i].value('ACCEPT', _('accept'));
45 /* Netfilter flow offload support */
48 s = m.section(form.TypedSection, 'defaults', _('Routing/NAT Offloading'),
49 _('Experimental feature. Not fully compatible with QoS/SQM.'));
54 o = s.option(form.Flag, 'flow_offloading',
55 _('Software flow offloading'),
56 _('Software based offloading for routing/NAT'));
59 o = s.option(form.Flag, 'flow_offloading_hw',
60 _('Hardware flow offloading'),
61 _('Requires hardware NAT support. Implemented at least for mt7621'));
63 o.depends('flow_offloading', '1');
67 s = m.section(form.GridSection, 'zone', _('Zones'));
72 s.tab('general', _('General Settings'));
73 s.tab('advanced', _('Advanced Settings'));
75 o = s.taboption('general', form.DummyValue, '_generalinfo');
78 o.cfgvalue = function(section_id) {
79 var name = uci.get('firewall', section_id, 'name');
81 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.')
82 .replace(/%s/g, name).replace(/%q/g, '"' + name + '"');
85 o = s.taboption('general', form.Value, 'name', _('Name'));
86 o.placeholder = _('Unnamed zone');
88 o.datatype = 'and(uciname,maxlength(11))';
89 o.write = function(section_id, formvalue) {
90 var cfgvalue = this.cfgvalue(section_id);
92 if (cfgvalue != formvalue)
93 return firewall.renameZone(cfgvalue, formvalue);
96 o = s.option(widgets.ZoneForwards, '_info', _('Zone ⇒ Forwardings'));
99 o.cfgvalue = function(section_id) {
100 return uci.get('firewall', section_id, 'name');
104 s.taboption('general', form.ListValue, 'input', _('Input')),
105 s.taboption('general', form.ListValue, 'output', _('Output')),
106 s.taboption('general', form.ListValue, 'forward', _('Forward'))
109 for (var i = 0; i < p.length; i++) {
110 p[i].value('REJECT', _('reject'));
111 p[i].value('DROP', _('drop'));
112 p[i].value('ACCEPT', _('accept'));
113 p[i].editable = true;
116 o = s.taboption('general', form.Flag, 'masq', _('Masquerading'));
119 o = s.taboption('general', form.Flag, 'mtu_fix', _('MSS clamping'));
122 o = s.taboption('general', widgets.NetworkSelect, 'network', _('Covered networks'));
125 o.write = function(section_id, formvalue) {
126 var name = uci.get('firewall', section_id, 'name'),
127 cfgvalue = this.cfgvalue(section_id);
129 if (typeof(cfgvalue) == 'string' && Array.isArray(formvalue) && (cfgvalue == formvalue.join(' ')))
132 var tasks = [ firewall.getZone(name) ];
134 if (Array.isArray(formvalue))
135 for (var i = 0; i < formvalue.length; i++) {
136 var netname = formvalue[i];
137 tasks.push(network.getNetwork(netname).then(function(net) {
138 return net || network.addNetwork(netname, { 'proto': 'none' });
142 return Promise.all(tasks).then(function(zone_networks) {
143 if (zone_networks[0])
144 for (var i = 1; i < zone_networks.length; i++)
145 zone_networks[0].addNetwork(zone_networks[i].getName());
149 o = s.taboption('advanced', form.DummyValue, '_advancedinfo');
152 o.cfgvalue = function(section_id) {
153 var name = uci.get('firewall', section_id, 'name');
155 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.')
159 o = s.taboption('advanced', form.ListValue, 'family', _('Restrict to address family'));
160 o.value('', _('IPv4 and IPv6'));
161 o.value('ipv4', _('IPv4 only'));
162 o.value('ipv6', _('IPv6 only'));
165 o = s.taboption('advanced', form.DynamicList, 'masq_src', _('Restrict Masquerading to given source subnets'));
166 o.depends('family', '');
167 o.depends('family', 'ipv4');
168 o.datatype = 'list(neg(or(uciname,hostname,ipmask4)))';
169 o.placeholder = '0.0.0.0/0';
172 o = s.taboption('advanced', form.DynamicList, 'masq_dest', _('Restrict Masquerading to given destination subnets'));
173 o.depends('family', '');
174 o.depends('family', 'ipv4');
175 o.datatype = 'list(neg(or(uciname,hostname,ipmask4)))';
176 o.placeholder = '0.0.0.0/0';
179 o = s.taboption('advanced', form.Flag, 'conntrack', _('Force connection tracking'));
182 o = s.taboption('advanced', form.Flag, 'log', _('Enable logging on this zone'));
185 o = s.taboption('advanced', form.Value, 'log_limit', _('Limit log messages'));
186 o.depends('log', '1');
187 o.placeholder = '10/minute';
190 o = s.taboption('general', form.DummyValue, '_forwardinfo');
193 o.cfgvalue = function(section_id) {
194 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.')
195 .format(uci.get('firewall', section_id, 'name'));
198 out = o = s.taboption('general', widgets.ZoneSelect, 'out', _('Allow forward to <em>destination zones</em>:'));
202 o.filter = function(section_id, value) {
203 return (uci.get('firewall', section_id, 'name') != value);
205 o.cfgvalue = function(section_id) {
206 var out = (this.option == 'out'),
207 zone = this.lookupZone(uci.get('firewall', section_id, 'name')),
208 fwds = zone.getForwardingsBy(out ? 'src' : 'dest'),
211 for (var i = 0; i < fwds.length; i++)
212 value.push(out ? fwds[i].getDestination() : fwds[i].getSource());
216 o.write = o.remove = function(section_id, formvalue) {
217 var out = (this.option == 'out'),
218 zone = this.lookupZone(uci.get('firewall', section_id, 'name')),
219 fwds = zone.getForwardingsBy(out ? 'src' : 'dest');
221 if (formvalue == null)
224 if (Array.isArray(formvalue)) {
225 for (var i = 0; i < fwds.length; i++) {
226 var cmp = out ? fwds[i].getDestination() : fwds[i].getSource();
227 if (!formvalue.filter(function(d) { return d == cmp }).length)
228 zone.deleteForwarding(fwds[i]);
231 for (var i = 0; i < formvalue.length; i++)
233 zone.addForwardingTo(formvalue[i]);
235 zone.addForwardingFrom(formvalue[i]);
239 inp = o = s.taboption('general', widgets.ZoneSelect, 'in', _('Allow forward from <em>source zones</em>:'));
243 o.write = o.remove = out.write;
244 o.filter = out.filter;
245 o.cfgvalue = out.cfgvalue;