4 Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
20 local type, pairs, ipairs, table, luci, math
21 = type, pairs, ipairs, table, luci, math
23 local lmo = require "lmo"
24 local utl = require "luci.util"
25 local uct = require "luci.model.uci.bind"
27 module "luci.model.firewall"
30 local ub = uct.bind("firewall")
34 cursor:unload("firewall")
35 cursor:load("firewall")
42 local z = ub.uci:section("firewall", "zone", nil, {
45 input = defaults:input() or "DROP",
46 forward = defaults:forward() or "DROP",
47 output = defaults:output() or "DROP"
56 ub.uci:foreach("firewall", "zone",
58 if n and s.name == n then
68 ub.uci:foreach("firewall", "zone",
71 zones[#zones+1] = zone(s['.name'])
77 function get_zones_by_network(net)
79 ub.uci:foreach("firewall", "zone",
83 for _, n in ipairs(ub:list(s.network or s.name)) do
85 zones[#zones+1] = zone(s['.name'])
96 ub.uci:foreach("firewall", "zone",
98 if n and s.name == n then
99 r = ub.uci:delete("firewall", s['.name'])
104 ub.uci:foreach("firewall", "rule",
106 if s.src == n or s.dest == n then
107 ub.uci:delete("firewall", s['.name'])
110 ub.uci:foreach("firewall", "redirect",
113 ub.uci:delete("firewall", s['.name'])
116 ub.uci:foreach("firewall", "forwarding",
119 ub.uci:delete("firewall", s['.name'])
126 function del_network(net)
129 for _, z in ipairs(get_zones()) do
136 defaults = ub:usection("defaults")
137 defaults:property_bool("syn_flood")
138 defaults:property_bool("drop_invalid")
139 defaults:property("input")
140 defaults:property("forward")
141 defaults:property("output")
144 zone = ub:section("zone")
145 zone:property_bool("masq")
146 zone:property("name")
147 zone:property("network")
148 zone:property("input")
149 zone:property("forward")
150 zone:property("output")
152 function zone.add_network(self, net)
153 if ub.uci:get("network", net) == "interface" then
154 local networks = ub:list(self:network() or self:name(), net)
155 if #networks > 0 then
156 self:network(table.concat(networks, " "))
163 function zone.del_network(self, net)
164 local networks = ub:list(self:network() or self:name(), nil, net)
165 if #networks > 0 then
166 self:network(table.concat(networks, " "))
172 function zone.get_networks(self)
173 return ub:list(self:network() or self:name())
176 function zone.get_forwardings_by(self, what)
177 local name = self:name()
179 ub.uci:foreach("firewall", "forwarding",
181 if s.src and s.dest and s[what] == name then
182 forwards[#forwards+1] = forwarding(s['.name'])
188 function zone.add_forwarding_to(self, dest, with_mtu_fix)
190 for _, forward in ipairs(self:get_forwardings_by('src')) do
191 if forward:dest() == dest then
196 if not exist and dest ~= self:name() then
197 local s = ub.uci:section("firewall", "forwarding", nil, {
200 mtu_fix = with_mtu_fix and true or false
202 return s and forwarding(s)
206 function zone.add_forwarding_from(self, src, with_mtu_fix)
208 for _, forward in ipairs(self:get_forwardings_by('dest')) do
209 if forward:src() == src then
214 if not exist and src ~= self:name() then
215 local s = ub.uci:section("firewall", "forwarding", nil, {
218 mtu_fix = with_mtu_fix and true or false
220 return s and forwarding(s)
224 function zone.add_redirect(self, options)
225 options = options or { }
226 options.src = self:name()
227 local s = ub.uci:section("firewall", "redirect", nil, options)
228 return s and redirect(s)
231 function zone.add_rule(self, options)
232 options = options or { }
233 options.src = self:name()
234 local s = ub.uci:section("firewall", "rule", nil, options)
238 function zone.get_color(self)
239 if self and self:name() == "lan" then
241 elseif self and self:name() == "wan" then
244 math.randomseed(lmo.hash(self:name()))
246 local r = math.random(128)
247 local g = math.random(128)
251 if ( r + g ) < 128 then
257 local b = min + math.floor( math.random() * ( max - min ) )
259 return "#%02x%02x%02x" % { 0xFF - r, 0xFF - g, 0xFF - b }
266 forwarding = ub:section("forwarding")
267 forwarding:property_bool("mtu_fix")
268 forwarding:property("src")
269 forwarding:property("dest")
271 function forwarding.src_zone(self)
272 return zone(self:src())
275 function forwarding.dest_zone(self)
276 return zone(self:dest())
280 rule = ub:section("rule")
282 rule:property("src_ip")
283 rule:property("src_mac")
284 rule:property("src_port")
285 rule:property("dest")
286 rule:property("dest_ip")
287 rule:property("dest_port")
288 rule:property("proto")
289 rule:property("target")
291 function rule.src_zone(self)
292 return zone(self:src())
296 redirect = ub:section("redirect")
297 redirect:property("src")
298 redirect:property("src_ip")
299 redirect:property("src_mac")
300 redirect:property("src_port")
301 redirect:property("src_dport")
302 redirect:property("dest_ip")
303 redirect:property("dest_port")
304 redirect:property("proto")
306 function redirect.src_zone(self)
307 return zone(self:src())