]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Increment the "dyn blocked" counter for eBPF blocks as well 13125/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 13 Jun 2023 12:08:56 +0000 (14:08 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 14 Aug 2023 14:26:30 +0000 (16:26 +0200)
Regular, userspace blocks increment the "dyn blocked" counter for every
dropped query. The eBPF blocks are executed in kernelspace and thus do
not increment that counter at all, which makes it challenging for
reporting to do its job. On the other hand we want our eBPF code to
be as efficient as possible since it is used when performance really
matters.
This commit updates the counter when a eBPF dynamic block is removed,
which is a compromise between the performance impact and a slight
reporting delay.

(cherry picked from commit e59686d645ff5d1652f2fdef109fff5d98d70ea2)

pdns/dnsdistdist/dnsdist-dynblocks.cc

index ae9896ed273d6339ff59a56e63e149ca6e4683a8..acf85243833b86237188d177e91be10a246d4c9e 100644 (file)
@@ -429,6 +429,10 @@ void DynBlockRulesGroup::processResponseRules(counts_t& counts, StatNode& root,
 
 void DynBlockMaintenance::purgeExpired(const struct timespec& now)
 {
+  // we need to increase the dynBlocked counter when removing
+  // eBPF blocks, as otherwise it does not get incremented for these
+  // since the block happens in kernel space.
+  uint64_t bpfBlocked = 0;
   {
     auto blocks = g_dynblockNMG.getLocal();
     std::vector<AddressAndPortRange> toRemove;
@@ -436,8 +440,15 @@ void DynBlockMaintenance::purgeExpired(const struct timespec& now)
       if (!(now < entry.second.until)) {
         toRemove.push_back(entry.first);
         if (g_defaultBPFFilter && entry.second.bpf) {
+          const auto& network = entry.first.getNetwork();
           try {
-            g_defaultBPFFilter->unblock(entry.first.getNetwork());
+            bpfBlocked += g_defaultBPFFilter->getHits(network);
+          }
+          catch (const std::exception& e) {
+            vinfolog("Error while getting block count before removing eBPF dynamic block for %s: %s", entry.first.toString(), e.what());
+          }
+          try {
+            g_defaultBPFFilter->unblock(network);
           }
           catch (const std::exception& e) {
             vinfolog("Error while removing eBPF dynamic block for %s: %s", entry.first.toString(), e.what());
@@ -451,6 +462,7 @@ void DynBlockMaintenance::purgeExpired(const struct timespec& now)
         updated.erase(entry);
       }
       g_dynblockNMG.setState(std::move(updated));
+      g_stats.dynBlocked += bpfBlocked;
     }
   }