]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Properly use eBPF when the DynBlock is not set 11544/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 15 Apr 2022 10:19:46 +0000 (12:19 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 15 Apr 2022 10:19:46 +0000 (12:19 +0200)
When the DynBlock rule does not set a specific action we use the
default one, set with `setDynBlocksAction()`, so we should follow
the same logic when determining whether to insert an eBPF block.

pdns/dnsdist.cc
pdns/dnsdistdist/dnsdist-dynblocks.cc
pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc

index 5a4a2ddaa86f99ba5515b0304e4e6ac8848b8a57..c638c21100b3dfd88463bad5d0e84502e40760e7 100644 (file)
@@ -138,9 +138,6 @@ Rings g_rings;
 QueryCount g_qcount;
 
 GlobalStateHolder<servers_t> g_dstates;
-GlobalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange>> g_dynblockNMG;
-GlobalStateHolder<SuffixMatchTree<DynBlock>> g_dynblockSMT;
-DNSAction::Action g_dynBlockAction = DNSAction::Action::Drop;
 
 bool g_servFailOnNoPolicy{false};
 bool g_truncateTC{false};
index 3aa007830822d953f8485c53ffa8268894776e2a..30d4f2ccfde21666351ae9bb95f5426f8ea79bcc 100644 (file)
@@ -2,6 +2,10 @@
 #include "dnsdist.hh"
 #include "dnsdist-dynblocks.hh"
 
+GlobalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange>> g_dynblockNMG;
+GlobalStateHolder<SuffixMatchTree<DynBlock>> g_dynblockSMT;
+DNSAction::Action g_dynBlockAction = DNSAction::Action::Drop;
+
 void DynBlockRulesGroup::apply(const struct timespec& now)
 {
   counts_t counts;
@@ -174,6 +178,18 @@ bool DynBlockRulesGroup::checkIfResponseCodeMatches(const Rings::Response& respo
   return false;
 }
 
+/* return the actual action that will be taken by that block:
+   - either the one set on that block, if any
+   - or the one set with setDynBlocksAction in g_dynBlockAction
+*/
+static DNSAction::Action getActualAction(const DynBlock& block)
+{
+  if (block.action != DNSAction::Action::None) {
+    return block.action;
+  }
+  return g_dynBlockAction;
+}
+
 void DynBlockRulesGroup::addOrRefreshBlock(boost::optional<NetmaskTree<DynBlock, AddressAndPortRange> >& blocks, const struct timespec& now, const AddressAndPortRange& requestor, const DynBlockRule& rule, bool& updated, bool warning)
 {
   /* network exclusions are address-based only (no port) */
@@ -224,14 +240,15 @@ void DynBlockRulesGroup::addOrRefreshBlock(boost::optional<NetmaskTree<DynBlock,
   db.blocks = count;
   db.warning = warning;
   if (!got || expired || wasWarning) {
+    const auto actualAction = getActualAction(db);
     if (g_defaultBPFFilter &&
         ((requestor.isIPv4() && requestor.getBits() == 32) || (requestor.isIPv6() && requestor.getBits() == 128)) &&
-        (db.action == DNSAction::Action::Drop || db.action == DNSAction::Action::Truncate)) {
+        (actualAction == DNSAction::Action::Drop || actualAction == DNSAction::Action::Truncate)) {
       try {
-        BPFFilter::MatchAction action = db.action == DNSAction::Action::Drop ? BPFFilter::MatchAction::Drop : BPFFilter::MatchAction::Truncate;
-        if (g_defaultBPFFilter->supportsMatchAction(action)) {
+        BPFFilter::MatchAction bpfAction = actualAction == DNSAction::Action::Drop ? BPFFilter::MatchAction::Drop : BPFFilter::MatchAction::Truncate;
+        if (g_defaultBPFFilter->supportsMatchAction(bpfAction)) {
           /* the current BPF filter implementation only supports full addresses (/32 or /128) and no port */
-          g_defaultBPFFilter->block(requestor.getNetwork(), action);
+          g_defaultBPFFilter->block(requestor.getNetwork(), bpfAction);
           bpf = true;
         }
       }
index bfb9c87e847a400a833cd73fa0b2c4ceb066be55..6640ef08f0b7b21f84ae06b22d3ed2dbd4c689ac 100644 (file)
@@ -9,8 +9,6 @@
 #include "dnsdist-rings.hh"
 
 Rings g_rings;
-GlobalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange>> g_dynblockNMG;
-GlobalStateHolder<SuffixMatchTree<DynBlock>> g_dynblockSMT;
 shared_ptr<BPFFilter> g_defaultBPFFilter{nullptr};
 
 BOOST_AUTO_TEST_SUITE(dnsdistdynblocks_hh)