]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Merge multiple parameters in newBPFFilter
authorY7n05h <Y7n05h@protonmail.com>
Wed, 13 Apr 2022 19:31:37 +0000 (03:31 +0800)
committerY7n05h <Y7n05h@protonmail.com>
Thu, 14 Apr 2022 00:47:58 +0000 (08:47 +0800)
Signed-off-by: Y7n05h <Y7n05h@protonmail.com>
pdns/bpf-filter.cc
pdns/bpf-filter.hh
pdns/dnsdist-lua-bindings.cc
pdns/dnsdistdist/docs/reference/ebpf.rst

index d0ec0f617225f58cae9989bb2354fc18470fcf7f..35769e3b3d9e42cdda80c38fba851d2b158f4639 100644 (file)
@@ -313,7 +313,8 @@ static FDWrapper loadProgram(const struct bpf_insn* filter, size_t filterSize)
 }
 
 
-BPFFilter::BPFFilter(const BPFFilter::MapConfiguration& v4, const BPFFilter::MapConfiguration& v6, const BPFFilter::MapConfiguration& qnames, BPFFilter::MapFormat format, bool external): d_mapFormat(format), d_external(external)
+BPFFilter::BPFFilter(std::unordered_map<std::string, MapConfiguration>& configs, BPFFilter::MapFormat format, bool external) :
+  d_mapFormat(format), d_external(external)
 {
   if (d_mapFormat != BPFFilter::MapFormat::Legacy && !d_external) {
     throw std::runtime_error("Unsupported eBPF map format, the current internal implemenation only supports the legacy format");
@@ -321,9 +322,9 @@ BPFFilter::BPFFilter(const BPFFilter::MapConfiguration& v4, const BPFFilter::Map
 
   auto maps = d_maps.lock();
 
-  maps->d_v4 = BPFFilter::Map(v4, d_mapFormat);
-  maps->d_v6 = BPFFilter::Map(v6, d_mapFormat);
-  maps->d_qnames = BPFFilter::Map(qnames, d_mapFormat);
+  maps->d_v4 = BPFFilter::Map(configs["v4Params"], d_mapFormat);
+  maps->d_v6 = BPFFilter::Map(configs["v6Params"], d_mapFormat);
+  maps->d_qnames = BPFFilter::Map(configs["qnameParams"], d_mapFormat);
   if (!external) {
     BPFFilter::MapConfiguration filters;
     filters.d_maxItems = 1;
@@ -686,7 +687,7 @@ uint64_t BPFFilter::getHits(const ComboAddress& requestor)
 
 #else
 
-BPFFilter::BPFFilter(const BPFFilter::MapConfiguration&, const BPFFilter::MapConfiguration&, const BPFFilter::MapConfiguration&, BPFFilter::MapFormat, bool)
+BPFFilter::BPFFilter(std::unordered_map<std::string, MapConfiguration>& configs, BPFFilter::MapFormat format, bool external)
 {
 }
 
index a8e2f5c8343092027b9f174e0d1be3865a5e1d29..29f44275dd94f0c53ecf29348afd40dd226fdaa9 100644 (file)
@@ -54,7 +54,7 @@ public:
   };
 
 
-  BPFFilter(const BPFFilter::MapConfiguration& v4, const BPFFilter::MapConfiguration& v6, const BPFFilter::MapConfiguration& qnames, BPFFilter::MapFormat format, bool external);
+  BPFFilter(std::unordered_map<std::string, MapConfiguration>& configs, BPFFilter::MapFormat format, bool external);
   BPFFilter(const BPFFilter&) = delete;
   BPFFilter(BPFFilter&&) = delete;
   BPFFilter& operator=(const BPFFilter&) = delete;
index 0ea0250a2fab0078f06db3752ecc7c253e9d1fc6..877a6f3fe4b99293b843d170e67b864befe46e34 100644 (file)
@@ -425,20 +425,27 @@ void setupLuaBindings(LuaContext& luaCtx, bool client)
   /* BPF Filter */
 #ifdef HAVE_EBPF
   using bpfFilterMapParams = boost::variant<uint32_t, LuaAssociativeTable<boost::variant<uint32_t, std::string>>>;
-  luaCtx.writeFunction("newBPFFilter", [client](bpfFilterMapParams v4Params, bpfFilterMapParams v6Params, bpfFilterMapParams qnameParams, boost::optional<bool> external) {
+  using bpfopts_t = LuaAssociativeTable<boost::variant<bool, std::string, bpfFilterMapParams>>;
+  luaCtx.writeFunction("newBPFFilter", [client](bpfopts_t opts) {
       if (client) {
         return std::shared_ptr<BPFFilter>(nullptr);
       }
+      std::unordered_map<std::string, BPFFilter::MapConfiguration> mapsConfig;
 
-      BPFFilter::MapConfiguration v4Config, v6Config, qnameConfig;
-
-      auto convertParamsToConfig = [](bpfFilterMapParams& params, BPFFilter::MapType type, BPFFilter::MapConfiguration& config) {
+      const auto convertParamsToConfig = [&](const std::string name, BPFFilter::MapType type) {
+        if (!opts.count(name))
+          return;
+        const auto& tmp = opts.at(name);
+        if (tmp.type() != typeid(bpfFilterMapParams))
+          throw std::runtime_error("params is invalid");
+        const auto& params = boost::get<bpfFilterMapParams>(tmp);
+        BPFFilter::MapConfiguration config;
         config.d_type = type;
         if (params.type() == typeid(uint32_t)) {
           config.d_maxItems = boost::get<uint32_t>(params);
         }
         else if (params.type() == typeid(LuaAssociativeTable<boost::variant<uint32_t, std::string>>)) {
-          auto map = boost::get<LuaAssociativeTable<boost::variant<uint32_t, std::string>>>(params);
+          const auto& map = boost::get<LuaAssociativeTable<boost::variant<uint32_t, std::string>>>(params);
           if (map.count("maxItems")) {
             config.d_maxItems = boost::get<uint32_t>(map.at("maxItems"));
           }
@@ -446,18 +453,24 @@ void setupLuaBindings(LuaContext& luaCtx, bool client)
             config.d_pinnedPath = boost::get<std::string>(map.at("pinnedPath"));
           }
         }
+        mapsConfig[name] = config;
       };
 
-      convertParamsToConfig(v4Params, BPFFilter::MapType::IPv4, v4Config);
-      convertParamsToConfig(v6Params, BPFFilter::MapType::IPv6, v6Config);
-      convertParamsToConfig(qnameParams, BPFFilter::MapType::QNames, qnameConfig);
+      convertParamsToConfig("v4Params", BPFFilter::MapType::IPv4);
+      convertParamsToConfig("v6Params", BPFFilter::MapType::IPv6);
+      convertParamsToConfig("qnameParams", BPFFilter::MapType::QNames);
 
       BPFFilter::MapFormat format = BPFFilter::MapFormat::Legacy;
-      if (external && *external) {
-        format = BPFFilter::MapFormat::WithActions;
+      bool external = false;
+      if (opts.count("external")) {
+        const auto& tmp = opts.at("external");
+        if (tmp.type() != typeid(bool))
+          throw std::runtime_error("params is invalid");
+        if ((external = boost::get<bool>(tmp)))
+          format = BPFFilter::MapFormat::WithActions;
       }
 
-      return std::make_shared<BPFFilter>(v4Config, v6Config, qnameConfig, format, external.value_or(false));
+      return std::make_shared<BPFFilter>(mapsConfig, format, external);
     });
 
   luaCtx.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca, boost::optional<uint32_t> action)>("block", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca, boost::optional<uint32_t> action) {
index 084797055e0f05e7ba6051ed05a6b301661ec29b..d98180f904f6cf17ed4561f2a085f8edfbdaa137 100644 (file)
@@ -13,27 +13,27 @@ These are all the functions, objects and methods related to the :doc:`../advance
   :param int seconds: The number of seconds this block to expire
   :param str msg: A message to display while inserting the block
 
-.. function:: newBPFFilter(maxV4, maxV6, maxQNames) -> BPFFilter
-              newBPFFilter(v4Parameters, v6Parameters, qnamesParameters) -> BPFFilter
+.. function:: newBPFFilter(options) -> BPFFilter
 
   .. versionchanged:: 1.7.0
     This function now supports a table for each parameters, and the ability to use pinned eBPF maps.
+  .. versionchanged:: 1.8.0
+    This function now get the parameters via a table.
 
   Return a new eBPF socket filter with a maximum of maxV4 IPv4, maxV6 IPv6 and maxQNames qname entries in the block tables.
   Maps can be pinned to a filesystem path, which makes their content persistent across restarts and allows external programs to read their content and to add new entries. dnsdist will try to load maps that are pinned to a filesystem path on startups, inheriting any existing entries, and fall back to creating them if they do not exist yet. Note that the user dnsdist is running under must have the right privileges to read and write to the given file, and to go through all the directories in the path leading to that file. The pinned path must be on a filesystem of type ``BPF``, usually below ``/sys/fs/bpf/``.
 
-  :param int maxV4: Maximum number of IPv4 entries in this filter
-  :param int maxV6: Maximum number of IPv6 entries in this filter
-  :param int maxQNames: Maximum number of QName entries in this filter
-
-  :param table v4Params: A table of options for the IPv4 filter map, see below
-  :param table v6Params: A table of options for the IPv6 filter map, see below
-  :param table qnameParams: A table of options for the qnames filter map, see below
+  :param table options: A table with key: value pairs with webserver options.
 
   Options:
-
-  * ``maxItems``: int - The maximum number of entries in a given map. Default is 0 which will not allow any entry at all.
-  * ``pinnedPath``: str - The filesystem path this map should be pinned to.
+  * ``v4Params``: int or table - Maximum number of entries in this filter or a table with ``maxItems`` or ``pinnedPath`` .
+  * ``v6Params``: int or table - Maximum number of entries in this filter or a table with ``maxItems`` or ``pinnedPath`` .
+  * ``qnameParams``: int or table - Maximum number of entries in this filter or a table with ``maxItems`` or ``pinnedPath`` .
+  * ``external``: bool - If set to true, DNSDist can to load the internal eBPF program.
+
+    Options for ``v4Params`` , ``v6Params`` and ``qnameParams``:
+    * ``maxItems``: int - The maximum number of entries in a given map. Default is 0 which will not allow any entry at all.
+    * ``pinnedPath``: str - The filesystem path this map should be pinned to.
 
 .. function:: newDynBPFFilter(bpf) -> DynBPFFilter