From 03a671269dd646cc94e67b74bc8102912f05ba47 Mon Sep 17 00:00:00 2001 From: Anbang Wen Date: Tue, 14 Aug 2018 16:10:10 -0700 Subject: [PATCH] support multiple addresses in daf src/dst filter 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 | 32 ++++++++++++++++++++++++++++---- modules/daf/daf.test.lua | 7 ++++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/modules/daf/daf.lua b/modules/daf/daf.lua index 349100387..41651fb62 100644 --- a/modules/daf/daf.lua +++ b/modules/daf/daf.lua @@ -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, } diff --git a/modules/daf/daf.test.lua b/modules/daf/daf.test.lua index 8aeb045b5..06dc90883 100644 --- a/modules/daf/daf.test.lua +++ b/modules/daf/daf.test.lua @@ -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 @@ -192,4 +197,4 @@ local tests = { test_features, } -return tests \ No newline at end of file +return tests -- 2.47.2