]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix eBPF metrics in the internal web server 13310/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 29 Sep 2023 13:52:10 +0000 (15:52 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 29 Sep 2023 13:55:49 +0000 (15:55 +0200)
We used to only display eBPF dynamic blocks for the Dynamic BPF
registered via `registerDynBPFFilter()`, which does not play well
with the new DynBlockRulesGroup approach.
This commit fixes it by making exporting / displaying metric for
the default BPF filter (`setDefaultBPFFilter`) as well.

pdns/dnsdist-web.cc
pdns/dnsdistdist/docs/advanced/ebpf.rst
pdns/dnsdistdist/html/local.js

index 50379859725ce33c9434bdf4483cd1c471275adf..58053aa045c4a8da0df3afdde0fcabda034a6968 100644 (file)
@@ -964,33 +964,42 @@ static void handleJSONStats(const YaHTTP::Request& req, YaHTTP::Response& resp)
     auto nmg = g_dynblockNMG.getLocal();
     struct timespec now;
     gettime(&now);
-    for (const auto& e: *nmg) {
-      if(now < e.second.until ) {
-        Json::object thing{
-          {"reason", e.second.reason},
-          {"seconds", (double)(e.second.until.tv_sec - now.tv_sec)},
-          {"blocks", (double)e.second.blocks},
-          {"action", DNSAction::typeToString(e.second.action != DNSAction::Action::None ? e.second.action : g_dynBlockAction) },
-          {"warning", e.second.warning }
-        };
-        obj.emplace(e.first.toString(), thing);
+    for (const auto& entry: *nmg) {
+      if (!(now < entry.second.until)) {
+        continue;
+      }
+      uint64_t counter = entry.second.blocks;
+      if (entry.second.bpf && g_defaultBPFFilter) {
+        counter += g_defaultBPFFilter->getHits(entry.first.getNetwork());
       }
+      Json::object thing{
+        {"reason", entry.second.reason},
+        {"seconds", static_cast<double>(entry.second.until.tv_sec - now.tv_sec)},
+        {"blocks", static_cast<double>(counter)},
+        {"action", DNSAction::typeToString(entry.second.action != DNSAction::Action::None ? entry.second.action : g_dynBlockAction)},
+        {"warning", entry.second.warning},
+        {"ebpf", entry.second.bpf}
+      };
+      obj.emplace(entry.first.toString(), thing);
     }
 
     auto smt = g_dynblockSMT.getLocal();
     smt->visit([&now,&obj](const SuffixMatchTree<DynBlock>& node) {
-      if(now <node.d_value.until) {
-        string dom("empty");
-        if(!node.d_value.domain.empty())
-          dom = node.d_value.domain.toString();
-        Json::object thing{
-          {"reason", node.d_value.reason},
-          {"seconds", (double)(node.d_value.until.tv_sec - now.tv_sec)},
-          {"blocks", (double)node.d_value.blocks},
-          {"action", DNSAction::typeToString(node.d_value.action != DNSAction::Action::None ? node.d_value.action : g_dynBlockAction) }
-        };
-        obj.emplace(dom, thing);
+      if (!(now < node.d_value.until)) {
+        return;
       }
+      string dom("empty");
+      if (!node.d_value.domain.empty()) {
+        dom = node.d_value.domain.toString();
+      }
+      Json::object thing{
+        {"reason", node.d_value.reason},
+        {"seconds", static_cast<double>(node.d_value.until.tv_sec - now.tv_sec)},
+        {"blocks", static_cast<double>(node.d_value.blocks)},
+        {"action", DNSAction::typeToString(node.d_value.action != DNSAction::Action::None ? node.d_value.action : g_dynBlockAction)},
+        {"ebpf", node.d_value.bpf}
+      };
+      obj.emplace(dom, thing);
     });
 #endif /* DISABLE_DYNBLOCKS */
     Json my_json = obj;
@@ -1013,6 +1022,23 @@ static void handleJSONStats(const YaHTTP::Request& req, YaHTTP::Response& resp)
         obj.emplace(std::get<0>(entry).toString(), thing );
       }
     }
+    if (g_defaultBPFFilter) {
+      auto nmg = g_dynblockNMG.getLocal();
+      for (const auto& entry: *nmg) {
+        if (!(now < entry.second.until) || !entry.second.bpf) {
+          continue;
+        }
+        uint64_t counter = entry.second.blocks + g_defaultBPFFilter->getHits(entry.first.getNetwork());
+        Json::object thing{
+          {"reason", entry.second.reason},
+          {"seconds", static_cast<double>(entry.second.until.tv_sec - now.tv_sec)},
+          {"blocks", static_cast<double>(counter)},
+          {"action", DNSAction::typeToString(entry.second.action != DNSAction::Action::None ? entry.second.action : g_dynBlockAction)},
+          {"warning", entry.second.warning},
+        };
+        obj.emplace(entry.first.toString(), thing);
+      }
+    }
 #endif /* HAVE_EBPF */
     Json my_json = obj;
     resp.body = my_json.dump();
index e50dfbf47258e91fe3ed2fc487189a42e770bde9..2905b95e96c9259f696ee44d87ea0a052a8178d6 100644 (file)
@@ -93,6 +93,7 @@ The dynamic eBPF blocks and the number of queries they blocked can be seen in th
   registerDynBPFFilter(dbpf)
 
 They can be unregistered at a later point using the :func:`unregisterDynBPFFilter` function.
+Since 1.8.2, the metrics for the BPF filter registered via :func:`setDefaultBPFFilter` are exported as well.
 
 Requirements
 ------------
index 81c1b061faae45a8f272d001f384be8e0be3123a..cefb0a4d9650f08f0474db8388379330652c17c8 100644 (file)
@@ -237,10 +237,10 @@ $(document).ready(function() {
 
         $.ajax({ url: 'jsonstat?command=dynblocklist', type: 'GET', dataType: 'json', jsonp: false,
                  success: function(data) {
-                     var bouw='<table width="100%"><tr align=left><th>Dyn blocked netmask</th><th>Seconds</th><th>Blocks</th><th align=left>Reason</th></tr>';
+                     var bouw='<table width="100%"><tr align=left><th>Dyn blocked netmask</th><th>Seconds</th><th>Blocks</th><th>eBPF</th><th align=left>Reason</th></tr>';
                     var gotsome=false;
                      $.each(data, function(a,b) {
-                         bouw=bouw+("<tr><td>"+a+"</td><td>"+b.seconds+"</td><td>"+b.blocks+"</td><td>"+b.reason+"</td></tr>");
+                         bouw=bouw+("<tr><td>"+a+"</td><td>"+b.seconds+"</td><td>"+b.blocks+"</td><td>"+b.ebpf+"</td><td>"+b.reason+"</td></tr>");
                         gotsome=true;
                      });