# HG changeset patch # User Matthew Wild # Date 1367915300 -3600 # Node ID 37af655ca575dceb0eb915580daef76161839a92 # Parent 716a2b9cc18d5b667cf28027bf211d1bcfcd7b99 mod_firewall: Cache conditions, so that they are only calculated once per chain execution diff -r 716a2b9cc18d -r 37af655ca575 mod_firewall/mod_firewall.lua --- a/mod_firewall/mod_firewall.lua Sun May 05 15:19:30 2013 +0200 +++ b/mod_firewall/mod_firewall.lua Tue May 07 09:28:20 2013 +0100 @@ -264,6 +264,7 @@ -- Loop through the chains in the parsed ruleset (e.g. incoming, outgoing) for chain_name, rules in pairs(ruleset) do local code = { included_deps = {}, global_header = {} }; + local condition_cache, n_conditions = {}, 0; -- This inner loop assumes chain is an event-based, not a filter-based -- chain (filter-based will be added later) for _, rule in ipairs(rules) do @@ -272,7 +273,22 @@ end local rule_code = table.concat(rule.actions, "\n\t"); if #rule.conditions > 0 then - rule_code = "if ("..table.concat(rule.conditions, ") and (")..") then\n\t" + for i, condition in ipairs(rule.conditions) do + local negated = condition:match("^not%b()$"); + if negated then + condition = condition:match("^not%((.+)%)$"); + end + if condition_cache[condition] then + rule.conditions[i] = (negated and "not(" or "")..condition_cache[condition]..(negated and "_" or ""); + else + n_conditions = n_conditions + 1; + local name = "condition"..n_conditions; + condition_cache[condition] = name; + table.insert(code, "local "..name.." = "..condition..";\n\t"); + rule.conditions[i] = (negated and "not(" or "")..name..(negated and ")" or ""); + end + end + rule_code = "if "..table.concat(rule.conditions, " and ").." then\n\t" ..rule_code .."\n end\n"; end