diff options
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | awall/model.lua | 4 | ||||
-rw-r--r-- | awall/modules/filter.lua | 22 |
3 files changed, 38 insertions, 1 deletions
@@ -221,6 +221,19 @@ the enclosing object. For [filters](#filter), the default behavior is to apply the limit for each source address separately. For [logging classes](#log), the limit is considered absolute by default. +The packet rates contributing to the limit may be summed over multiple +[filters](#filter). This can be achieved by setting the optional +**name** attribute to equal values among the related limits. Named +limits may be specific only to fixed-size blocks of either the source +or the destination address, not both. However, the address to be +considered may vary among the rules using the limit and may be +selected by setting an attribute named **addr** to either **src** +(default) or **dest**. By default, all bits of the selected address +are taken into account, but address family–specific prefix +lengths can be set via the top-level **limit** dictionary, where the +keys correspond to limit names and values follow the syntax of +**src-mask** and **dest-mask**. + ### <a name="log"></a>Logging Classes A *logging class* specifies how packets matching certain rules are diff --git a/awall/model.lua b/awall/model.lua index 79460d8..783ad7f 100644 --- a/awall/model.lua +++ b/awall/model.lua @@ -707,6 +707,10 @@ function M.Limit:init(...) end end + self:initmask() +end + +function M.Limit:initmask() setdefault(self, 'src-mask', not self['dest-mask']) setdefault(self, 'dest-mask', false) diff --git a/awall/modules/filter.lua b/awall/modules/filter.lua index 531d776..34ac6cf 100644 --- a/awall/modules/filter.lua +++ b/awall/modules/filter.lua @@ -24,6 +24,25 @@ local RECENT_MAX_COUNT = 20 local FilterLimit = class(model.Limit) +function FilterLimit:initmask() + if self.name then + for _, attr in ipairs{'src-mask', 'dest-mask'} do + if self[attr] then + self:error('Attribute not allowed with a named limit: '..attr) + end + end + + local limits = self.root.limit + self[(self.addr or 'src')..'-mask'] = limits and limits[self.name] or true + end + + FilterLimit.super(self):initmask() + + if self.name and not self:recentofrags() then + self:error('Attribute allowed only with low-rate limits: name') + end +end + function FilterLimit:recentofrags(name) local count = self.count local interval = self.interval @@ -66,7 +85,8 @@ function FilterLimit:recentofrags(name) local rec = { { family=family, - match='-m recent --name '..name..' --r'.. + match='-m recent --name '.. + (self.name and 'user:'..self.name or name)..' --r'.. ({src='source', dest='dest'})[attr]..' --mask '..mask } } |