luci-app-firewall: redirect to overview page on zone details save
[project/luci.git] / applications / luci-app-firewall / luasrc / model / cbi / firewall / rule-details.lua
1 -- Copyright 2008 Steven Barth <steven@midlink.org>
2 -- Copyright 2010-2012 Jo-Philipp Wich <jow@openwrt.org>
3 -- Licensed to the public under the Apache License 2.0.
4
5 local sys = require "luci.sys"
6 local utl = require "luci.util"
7 local dsp = require "luci.dispatcher"
8 local nxo = require "nixio"
9
10 local ft = require "luci.tools.firewall"
11 local nw = require "luci.model.network"
12 local m, s, o, k, v
13
14 arg[1] = arg[1] or ""
15
16 m = Map("firewall",
17         translate("Firewall - Traffic Rules"),
18         translate("This page allows you to change advanced properties of the \
19                    traffic rule entry, such as matched source and destination \
20                            hosts."))
21
22 m.redirect = dsp.build_url("admin/network/firewall/rules")
23
24 nw.init(m.uci)
25
26 local rule_type = m.uci:get("firewall", arg[1])
27 if rule_type == "redirect" and m:get(arg[1], "target") ~= "SNAT" then
28         rule_type = nil
29 end
30
31 if not rule_type then
32         luci.http.redirect(m.redirect)
33         return
34
35 --
36 -- SNAT
37 --
38 elseif rule_type == "redirect" then
39
40         local name = m:get(arg[1], "name") or m:get(arg[1], "_name")
41         if not name or #name == 0 then
42                 name = translate("(Unnamed SNAT)")
43         else
44                 name = "SNAT %s" % name
45         end
46
47         m.title = "%s - %s" %{ translate("Firewall - Traffic Rules"), name }
48
49         local wan_zone = nil
50
51         m.uci:foreach("firewall", "zone",
52                 function(s)
53                         local n = s.network or s.name
54                         if n then
55                                 local i
56                                 for i in utl.imatch(n) do
57                                         if i == "wan" then
58                                                 wan_zone = s.name
59                                                 return false
60                                         end
61                                 end
62                         end
63                 end)
64
65         s = m:section(NamedSection, arg[1], "redirect", "")
66         s.anonymous = true
67         s.addremove = false
68
69
70         ft.opt_enabled(s, Button)
71         ft.opt_name(s, Value, translate("Name"))
72
73
74         o = s:option(Value, "proto",
75                 translate("Protocol"),
76                 translate("You may specify multiple by selecting \"-- custom --\" and \
77                            then entering protocols separated by space."))
78
79         o:value("all", "All protocols")
80         o:value("tcp udp", "TCP+UDP")
81         o:value("tcp", "TCP")
82         o:value("udp", "UDP")
83         o:value("icmp", "ICMP")
84
85         function o.cfgvalue(...)
86                 local v = Value.cfgvalue(...)
87                 if not v or v == "tcpudp" then
88                         return "tcp udp"
89                 end
90                 return v
91         end
92
93
94         o = s:option(Value, "src", translate("Source zone"))
95         o.nocreate = true
96         o.default = "wan"
97         o.template = "cbi/firewall_zonelist"
98
99
100         o = s:option(Value, "src_ip", translate("Source IP address"))
101         o.rmempty = true
102         o.datatype = "neg(ipmask4)"
103         o.placeholder = translate("any")
104
105         luci.sys.net.ipv4_hints(function(ip, name)
106                 o:value(ip, "%s (%s)" %{ ip, name })
107         end)
108
109
110         o = s:option(Value, "src_port",
111                 translate("Source port"),
112                 translate("Match incoming traffic originating from the given source \
113                         port or port range on the client host."))
114         o.rmempty = true
115         o.datatype = "neg(portrange)"
116         o.placeholder = translate("any")
117
118
119         o = s:option(Value, "dest", translate("Destination zone"))
120         o.nocreate = true
121         o.default = "lan"
122         o.template = "cbi/firewall_zonelist"
123
124
125         o = s:option(Value, "dest_ip", translate("Destination IP address"))
126         o.datatype = "neg(ipmask4)"
127
128         luci.sys.net.ipv4_hints(function(ip, name)
129                 o:value(ip, "%s (%s)" %{ ip, name })
130         end)
131
132
133         o = s:option(Value, "dest_port",
134                 translate("Destination port"),
135                 translate("Match forwarded traffic to the given destination port or \
136                         port range."))
137
138         o.rmempty = true
139         o.placeholder = translate("any")
140         o.datatype = "neg(portrange)"
141
142
143         o = s:option(Value, "src_dip",
144                 translate("SNAT IP address"),
145                 translate("Rewrite matched traffic to the given address."))
146         o.rmempty = false
147         o.datatype = "ip4addr"
148
149         for k, v in ipairs(nw:get_interfaces()) do
150                 local a
151                 for k, a in ipairs(v:ipaddrs()) do
152                         o:value(a:host():string(), '%s (%s)' %{
153                                 a:host():string(), v:shortname()
154                         })
155                 end
156         end
157
158
159         o = s:option(Value, "src_dport", translate("SNAT port"),
160                 translate("Rewrite matched traffic to the given source port. May be \
161                         left empty to only rewrite the IP address."))
162         o.datatype = "portrange"
163         o.rmempty = true
164         o.placeholder = translate('Do not rewrite')
165
166
167         s:option(Value, "extra",
168                 translate("Extra arguments"),
169                 translate("Passes additional arguments to iptables. Use with care!"))
170
171
172 --
173 -- Rule
174 --
175 else
176         local name = m:get(arg[1], "name") or m:get(arg[1], "_name")
177         if not name or #name == 0 then
178                 name = translate("(Unnamed Rule)")
179         end
180
181         m.title = "%s - %s" %{ translate("Firewall - Traffic Rules"), name }
182
183
184         s = m:section(NamedSection, arg[1], "rule", "")
185         s.anonymous = true
186         s.addremove = false
187
188         ft.opt_enabled(s, Button)
189         ft.opt_name(s, Value, translate("Name"))
190
191
192         o = s:option(ListValue, "family", translate("Restrict to address family"))
193         o.rmempty = true
194         o:value("", translate("IPv4 and IPv6"))
195         o:value("ipv4", translate("IPv4 only"))
196         o:value("ipv6", translate("IPv6 only"))
197
198
199         o = s:option(Value, "proto", translate("Protocol"))
200         o:value("all", translate("Any"))
201         o:value("tcp udp", "TCP+UDP")
202         o:value("tcp", "TCP")
203         o:value("udp", "UDP")
204         o:value("icmp", "ICMP")
205
206         function o.cfgvalue(...)
207                 local v = Value.cfgvalue(...)
208                 if not v or v == "tcpudp" then
209                         return "tcp udp"
210                 end
211                 return v
212         end
213
214
215         o = s:option(DynamicList, "icmp_type", translate("Match ICMP type"))
216         o:value("", "any")
217         o:value("echo-reply")
218         o:value("destination-unreachable")
219         o:value("network-unreachable")
220         o:value("host-unreachable")
221         o:value("protocol-unreachable")
222         o:value("port-unreachable")
223         o:value("fragmentation-needed")
224         o:value("source-route-failed")
225         o:value("network-unknown")
226         o:value("host-unknown")
227         o:value("network-prohibited")
228         o:value("host-prohibited")
229         o:value("TOS-network-unreachable")
230         o:value("TOS-host-unreachable")
231         o:value("communication-prohibited")
232         o:value("host-precedence-violation")
233         o:value("precedence-cutoff")
234         o:value("source-quench")
235         o:value("redirect")
236         o:value("network-redirect")
237         o:value("host-redirect")
238         o:value("TOS-network-redirect")
239         o:value("TOS-host-redirect")
240         o:value("echo-request")
241         o:value("router-advertisement")
242         o:value("router-solicitation")
243         o:value("time-exceeded")
244         o:value("ttl-zero-during-transit")
245         o:value("ttl-zero-during-reassembly")
246         o:value("parameter-problem")
247         o:value("ip-header-bad")
248         o:value("required-option-missing")
249         o:value("timestamp-request")
250         o:value("timestamp-reply")
251         o:value("address-mask-request")
252         o:value("address-mask-reply")
253
254
255         o = s:option(Value, "src", translate("Source zone"))
256         o.nocreate = true
257         o.allowany = true
258         o.default = "wan"
259         o.template = "cbi/firewall_zonelist"
260
261
262         o = s:option(Value, "src_mac", translate("Source MAC address"))
263         o.datatype = "list(macaddr)"
264         o.placeholder = translate("any")
265
266         luci.sys.net.mac_hints(function(mac, name)
267                 o:value(mac, "%s (%s)" %{ mac, name })
268         end)
269
270
271         o = s:option(Value, "src_ip", translate("Source address"))
272         o.datatype = "neg(ipmask)"
273         o.placeholder = translate("any")
274
275         luci.sys.net.ipv4_hints(function(ip, name)
276                 o:value(ip, "%s (%s)" %{ ip, name })
277         end)
278
279
280         o = s:option(Value, "src_port", translate("Source port"))
281         o.datatype = "list(neg(portrange))"
282         o.placeholder = translate("any")
283
284
285         o = s:option(Value, "dest", translate("Destination zone"))
286         o.nocreate = true
287         o.allowany = true
288         o.allowlocal = true
289         o.template = "cbi/firewall_zonelist"
290
291
292         o = s:option(Value, "dest_ip", translate("Destination address"))
293         o.datatype = "neg(ipmask)"
294         o.placeholder = translate("any")
295
296         luci.sys.net.ipv4_hints(function(ip, name)
297                 o:value(ip, "%s (%s)" %{ ip, name })
298         end)
299
300
301         o = s:option(Value, "dest_port", translate("Destination port"))
302         o.datatype = "list(neg(portrange))"
303         o.placeholder = translate("any")
304
305
306         o = s:option(ListValue, "target", translate("Action"))
307         o.default = "ACCEPT"
308         o:value("DROP", translate("drop"))
309         o:value("ACCEPT", translate("accept"))
310         o:value("REJECT", translate("reject"))
311         o:value("NOTRACK", translate("don't track"))
312
313
314         s:option(Value, "extra",
315                 translate("Extra arguments"),
316                 translate("Passes additional arguments to iptables. Use with care!"))
317 end
318
319 o = s:option(MultiValue, "weekdays", translate("Week Days"))
320 o.oneline = true
321 o.widget = "checkbox"
322 o:value("Sun", translate("Sunday"))
323 o:value("Mon", translate("Monday"))
324 o:value("Tue", translate("Tuesday"))
325 o:value("Wed", translate("Wednesday"))
326 o:value("Thu", translate("Thursday"))
327 o:value("Fri", translate("Friday"))
328 o:value("Sat", translate("Saturday"))
329
330 o = s:option(MultiValue, "monthdays", translate("Month Days"))
331 o.oneline = true
332 o.widget = "checkbox"
333 for i = 1,31 do
334         o:value(translate(i))
335 end
336
337 o = s:option(Value, "start_time", translate("Start Time (hh:mm:ss)"))
338 o.datatype = "timehhmmss"
339 o = s:option(Value, "stop_time", translate("Stop Time (hh:mm:ss)"))
340 o.datatype = "timehhmmss"
341 o = s:option(Value, "start_date", translate("Start Date (yyyy-mm-dd)"))
342 o.datatype = "dateyyyymmdd"
343 o = s:option(Value, "stop_date", translate("Stop Date (yyyy-mm-dd)"))
344 o.datatype = "dateyyyymmdd"
345
346 o = s:option(Flag, "utc_time", translate("Time in UTC"))
347 o.default = o.disabled
348
349 return m