]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
support multiple addresses in daf src/dst filter cflare-daf-policy
authorAnbang Wen <anbang@cloudflare.com>
Tue, 14 Aug 2018 23:10:10 +0000 (16:10 -0700)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 28 Nov 2018 14:29:14 +0000 (15:29 +0100)
This enables using syntax like "src { CIDR-a CIDR-b } deny" to specify
multiple addresses to filter. All the conditions are ORed together
like qname/ns.

modules/daf/daf.lua
modules/daf/daf.test.lua

index 349100387056ca4aebf2f24607bc974f0ffe1f62..41651fb629f576f52753dfc3a4916910e60fa308 100644 (file)
@@ -190,13 +190,37 @@ M.filters = {
        end,
        -- Filter on source address
        src = function (op, arg)
-               if op ~= '=' or #arg ~= 1 then error('address supports only "=" operator with single argument') end
-               return view.rule_src(true, arg[1])
+               if op ~= '=' or #arg == 0 then
+                       error('address supports only "=" operator with one or more arguments')
+               end
+
+               local f
+               for _, v in ipairs(arg) do
+                       local fa, fb = f, view.rule_src(true, v)
+                       if f == nil then
+                               f = fb
+                       else
+                               f = function (req, qry) return fa(req, qry) or fb(req, qry) end
+                       end
+               end
+               return f
        end,
        -- Filter on destination address
        dst = function (op, arg)
-               if op ~= '=' or #arg ~= 1 then error('address supports only "=" operator with single argument') end
-               return view.rule_dst(true, arg[1])
+               if op ~= '=' or #arg == 0 then
+                       error('address supports only "=" operator with one or more arguments')
+               end
+
+               local f
+               for _, v in ipairs(arg) do
+                       local fa, fb = f, view.rule_dst(true, v)
+                       if f == nil then
+                               f = fb
+                       else
+                               f = function (req, qry) return fa(req, qry) or fb(req, qry) end
+                       end
+               end
+               return f
        end,
 }
 
index 10db2fb4dbc87f671b04ada9642f884f6ee4e29c..9f534ef8678e9836ccf80223f4050f803d818048 100644 (file)
@@ -104,6 +104,11 @@ local function test_parser()
        nok(daf.compile('qname ~ {A AAAA} deny'), 'rejects "qname ~ {A AAAA} deny"')
        nok(daf.compile('qname and'), 'rejects "qname and"')
        nok(daf.compile('qname A or'), 'rejects "qname A or"')
+       nok(daf.compile('src ~ 192.0.2.0'), 'src only support =')
+
+       -- valid rules
+       ok(daf.compile('src = 192.0.2.0/24 deny'), 'filter on CIDR')
+       ok(daf.compile('dst { 192.0.2.0/32 192.0.2.1 } deny'), 'filter on multiple addresses')
 
        local filters = {
                -- test catch all