]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
add BPFFilter::getRangeStats()
authorY7n05h <Y7n05h@protonmail.com>
Thu, 21 Apr 2022 15:12:20 +0000 (23:12 +0800)
committerY7n05h <Y7n05h@protonmail.com>
Fri, 22 Apr 2022 18:32:33 +0000 (02:32 +0800)
add BPF_MAP_TYPE_LPM_TRIE support in getStats()

Signed-off-by: Y7n05h <Y7n05h@protonmail.com>
pdns/bpf-filter.cc
pdns/bpf-filter.hh
pdns/dnsdist-lua-bindings.cc
pdns/iputils.hh

index ce75b0a230a776b28521c07b19ee8d222d7ddf23..c7912fd39fdc0b25a72bbbe9737b802d345a3a82 100644 (file)
@@ -740,6 +740,50 @@ std::vector<std::pair<ComboAddress, uint64_t> > BPFFilter::getAddrStats()
   return result;
 }
 
+std::vector<std::pair<Netmask, uint64_t>> BPFFilter::getRangeStats()
+{
+  CIDR4 cidr4[2];
+  CIDR6 cidr6[2];
+  std::vector<std::pair<Netmask, uint64_t>> result;
+
+  sockaddr_in v4Addr;
+  sockaddr_in6 v6Addr;
+  CounterAndActionValue value;
+
+  memset(cidr4, 0, sizeof(cidr4));
+  memset(cidr6, 0, sizeof(cidr6));
+  memset(&v4Addr, 0, sizeof(v4Addr));
+  memset(&v6Addr, 0, sizeof(v6Addr));
+  auto maps = d_maps.lock();
+  result.reserve(maps->d_cidr4.d_count + maps->d_cidr6.d_count);
+  {
+    auto& map = maps->d_cidr4;
+    int res = bpf_get_next_key(map.d_fd.getHandle(), &cidr4[0], &cidr4[1]);
+    while (res == 0) {
+      if (bpf_lookup_elem(map.d_fd.getHandle(), &cidr4[1], &value) == 0) {
+        v4Addr.sin_addr.s_addr = cidr4[1].addr.s_addr;
+        result.emplace_back(Netmask(&v4Addr, cidr4[1].cidr), value.counter);
+      }
+
+      res = bpf_get_next_key(map.d_fd.getHandle(), &cidr4[1], &cidr4[1]);
+    }
+  }
+
+  {
+    auto& map = maps->d_cidr6;
+    int res = bpf_get_next_key(map.d_fd.getHandle(), &cidr6[0], &cidr6[1]);
+    while (res == 0) {
+      if (bpf_lookup_elem(map.d_fd.getHandle(), &cidr6[1], &value) == 0) {
+        v6Addr.sin6_addr = cidr6[0].addr;
+        result.emplace_back(Netmask(&v6Addr, cidr6[1].cidr), value.counter);
+      }
+
+      res = bpf_get_next_key(map.d_fd.getHandle(), &cidr6[1], &cidr6[1]);
+    }
+  }
+  return result;
+}
+
 std::vector<std::tuple<DNSName, uint16_t, uint64_t> > BPFFilter::getQNameStats()
 {
   std::vector<std::tuple<DNSName, uint16_t, uint64_t> > result;
index 5fc991e47a596ce2ace549b0cc613b6ed675bb85..87e4a415574c230e23f1d147e30ffb40340ea938 100644 (file)
@@ -76,6 +76,7 @@ public:
   void unblock(const DNSName& qname, uint16_t qtype=255);
 
   std::vector<std::pair<ComboAddress, uint64_t> > getAddrStats();
+  std::vector<std::pair<Netmask,uint64_t>> getRangeStats();
   std::vector<std::tuple<DNSName, uint16_t, uint64_t> > getQNameStats();
 
   uint64_t getHits(const ComboAddress& requestor);
index f09b7a22acd70cd58d8aab459ea89ad87cf7bb24..d9b84e6342d622f48c9dbe502849fd5696dfa03f 100644 (file)
@@ -580,6 +580,15 @@ void setupLuaBindings(LuaContext& luaCtx, bool client)
             res += "[" + value.first.toString() + "]: " + std::to_string(value.second) + "\n";
           }
         }
+        const auto rangeStat = bpf->getRangeStats();
+        for (const auto& value : rangeStat) {
+          if (value.first.isIPv4()) {
+            res += value.first.toString() + ": " + std::to_string(value.second) + "\n";
+          }
+          else if (value.first.isIPv6()) {
+            res += "[" + value.first.toString() + "]: " + std::to_string(value.second) + "\n";
+          }
+        }
         auto qstats = bpf->getQNameStats();
         for (const auto& value : qstats) {
           res += std::get<0>(value).toString() + " " + std::to_string(std::get<1>(value)) + ": " + std::to_string(std::get<2>(value)) + "\n";
index dc7ed626247ac9a2193b8ab0bc4ef7b16a2f7d0a..7a949f6f2a3829c3246e537978e1ac30bfb8923c 100644 (file)
@@ -460,6 +460,16 @@ public:
     setBits(network.isIPv4() ? std::min(bits, static_cast<uint8_t>(32)) : std::min(bits, static_cast<uint8_t>(128)));
   }
 
+  Netmask(const sockaddr_in* network, uint8_t bits = 0xff): d_network(network)
+  {
+    d_network.sin4.sin_port = 0;
+    setBits(std::min(bits, static_cast<uint8_t>(32)));
+  }
+  Netmask(const sockaddr_in6* network, uint8_t bits = 0xff): d_network(network)
+  {
+    d_network.sin4.sin_port = 0;
+    setBits(std::min(bits, static_cast<uint8_t>(128)));
+  }
   void setBits(uint8_t value)
   {
     d_bits = value;