46b3744403087998a13ee65af7616c8be63b96d4
[project/luci.git] / applications / luci-app-firewall / luasrc / model / cbi / firewall / zone-details.lua
1 -- Copyright 2008 Steven Barth <steven@midlink.org>
2 -- Copyright 2010-2011 Jo-Philipp Wich <jow@openwrt.org>
3 -- Licensed to the public under the Apache License 2.0.
4
5 local nw = require "luci.model.network"
6 local fw = require "luci.model.firewall"
7 local ds = require "luci.dispatcher"
8 local ut = require "luci.util"
9
10 local m, p, i, v
11 local s, name, net, family, msrc, mdest, log, lim
12 local s2, out, inp
13
14
15 m = Map("firewall", translate("Firewall - Zone Settings"))
16 m.redirect = luci.dispatcher.build_url("admin/network/firewall/zones")
17
18 fw.init(m.uci)
19 nw.init(m.uci)
20
21
22 local zone = fw:get_zone(arg[1])
23 if not zone then
24         luci.http.redirect(dsp.build_url("admin/network/firewall/zones"))
25         return
26 else
27         m.title = "%s - %s" %{
28                 translate("Firewall - Zone Settings"),
29                 translatef("Zone %q", zone:name() or "?")
30         }
31 end
32
33
34 s = m:section(NamedSection, zone.sid, "zone",
35         translatef("Zone %q", zone:name()),
36         translatef("This section defines common properties of %q. \
37                 The <em>input</em> and <em>output</em> options set the default \
38                 policies for traffic entering and leaving this zone while the \
39                 <em>forward</em> option describes the policy for forwarded traffic \
40                 between different networks within the zone. \
41                 <em>Covered networks</em> specifies which available networks are \
42                 members of this zone.", zone:name()))
43
44 s.anonymous = true
45 s.addremove = false
46
47 m.on_commit = function(map)
48         local zone = fw:get_zone(arg[1])
49         if zone then
50                 s.section  = zone.sid
51                 s2.section = zone.sid
52         end
53 end
54
55
56 s:tab("general", translate("General Settings"))
57 s:tab("advanced", translate("Advanced Settings"))
58
59
60 name = s:taboption("general", Value, "name", translate("Name"))
61 name.optional = false
62 name.forcewrite = true
63 name.datatype = "uciname"
64
65 function name.write(self, section, value)
66         if zone:name() ~= value then
67                 fw:rename_zone(zone:name(), value)
68                 out.exclude = value
69                 inp.exclude = value
70         end
71
72         m.redirect = ds.build_url("admin/network/firewall/zones", value)
73         m.title = "%s - %s" %{
74                 translate("Firewall - Zone Settings"),
75                 translatef("Zone %q", value or "?")
76         }
77 end
78
79 function name.validate(self, value)
80         -- fw3 defines 14 as the maximum length of zone name
81         if #value > 14 then
82                 return nil, translate("Zone name is too long")
83         else
84                 return value
85         end
86 end
87
88 p = {
89         s:taboption("general", ListValue, "input", translate("Input")),
90         s:taboption("general", ListValue, "output", translate("Output")),
91         s:taboption("general", ListValue, "forward", translate("Forward"))
92 }
93
94 for i, v in ipairs(p) do
95         v:value("REJECT", translate("reject"))
96         v:value("DROP", translate("drop"))
97         v:value("ACCEPT", translate("accept"))
98 end
99
100 s:taboption("general", Flag, "masq", translate("Masquerading"))
101 s:taboption("general", Flag, "mtu_fix", translate("MSS clamping"))
102
103 net = s:taboption("general", Value, "network", translate("Covered networks"))
104 net.template = "cbi/network_netlist"
105 net.widget = "checkbox"
106 net.cast = "string"
107
108 function net.formvalue(self, section)
109         return Value.formvalue(self, section) or "-"
110 end
111
112 function net.cfgvalue(self, section)
113         return Value.cfgvalue(self, section) or name:cfgvalue(section)
114 end
115
116 function net.write(self, section, value)
117         zone:clear_networks()
118
119         local n
120         for n in ut.imatch(value) do
121                 zone:add_network(n)
122         end
123 end
124
125
126 family = s:taboption("advanced", ListValue, "family",
127         translate("Restrict to address family"))
128
129 family.rmempty = true
130 family:value("", translate("IPv4 and IPv6"))
131 family:value("ipv4", translate("IPv4 only"))
132 family:value("ipv6", translate("IPv6 only"))
133
134 msrc = s:taboption("advanced", DynamicList, "masq_src",
135         translate("Restrict Masquerading to given source subnets"))
136
137 msrc.optional = true
138 msrc.datatype = "list(neg(or(uciname,hostname,ip4addr)))"
139 msrc.placeholder = "0.0.0.0/0"
140 msrc:depends("family", "")
141 msrc:depends("family", "ipv4")
142
143 mdest = s:taboption("advanced", DynamicList, "masq_dest",
144         translate("Restrict Masquerading to given destination subnets"))
145
146 mdest.optional = true
147 mdest.datatype = "list(neg(or(uciname,hostname,ip4addr)))"
148 mdest.placeholder = "0.0.0.0/0"
149 mdest:depends("family", "")
150 mdest:depends("family", "ipv4")
151
152 s:taboption("advanced", Flag, "conntrack",
153         translate("Force connection tracking"))
154
155 log = s:taboption("advanced", Flag, "log",
156         translate("Enable logging on this zone"))
157
158 log.rmempty = true
159 log.enabled = "1"
160
161 lim = s:taboption("advanced", Value, "log_limit",
162         translate("Limit log messages"))
163
164 lim.placeholder = "10/minute"
165 lim:depends("log", "1")
166
167
168 s2 = m:section(NamedSection, zone.sid, "fwd_out",
169         translate("Inter-Zone Forwarding"),
170         translatef("The options below control the forwarding policies between \
171                 this zone (%s) and other zones. <em>Destination zones</em> cover \
172                 forwarded traffic <strong>originating from %q</strong>. \
173                 <em>Source zones</em> match forwarded traffic from other zones \
174                 <strong>targeted at %q</strong>. The forwarding rule is \
175                 <em>unidirectional</em>, e.g. a forward from lan to wan does \
176                 <em>not</em> imply a permission to forward from wan to lan as well.",
177                 zone:name(), zone:name(), zone:name()
178
179         ))
180
181 out = s2:option(Value, "out",
182         translate("Allow forward to <em>destination zones</em>:"))
183
184 out.nocreate = true
185 out.widget = "checkbox"
186 out.exclude = zone:name()
187 out.template = "cbi/firewall_zonelist"
188
189 inp = s2:option(Value, "in",
190         translate("Allow forward from <em>source zones</em>:"))
191
192 inp.nocreate = true
193 inp.widget = "checkbox"
194 inp.exclude = zone:name()
195 inp.template = "cbi/firewall_zonelist"
196
197 function out.cfgvalue(self, section)
198         local v = { }
199         local f
200         for _, f in ipairs(zone:get_forwardings_by("src")) do
201                 v[#v+1] = f:dest()
202         end
203         return table.concat(v, " ")
204 end
205
206 function inp.cfgvalue(self, section)
207         local v = { }
208         local f
209         for _, f in ipairs(zone:get_forwardings_by("dest")) do
210                 v[#v+1] = f:src()
211         end
212         return v
213 end
214
215 function out.formvalue(self, section)
216         return Value.formvalue(self, section) or "-"
217 end
218
219 function inp.formvalue(self, section)
220         return Value.formvalue(self, section) or "-"
221 end
222
223 function out.write(self, section, value)
224         zone:del_forwardings_by("src")
225
226         local f
227         for f in ut.imatch(value) do
228                 zone:add_forwarding_to(f)
229         end
230 end
231
232 function inp.write(self, section, value)
233         zone:del_forwardings_by("dest")
234
235         local f
236         for f in ut.imatch(value) do
237                 zone:add_forwarding_from(f)
238         end
239 end
240
241 return m