From: Y7n05h Date: Wed, 13 Apr 2022 19:31:37 +0000 (+0800) Subject: Merge multiple parameters in newBPFFilter X-Git-Tag: auth-4.8.0-alpha0~137^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=411dccdb93d0580346eb1667df46216b2715ca85;p=thirdparty%2Fpdns.git Merge multiple parameters in newBPFFilter Signed-off-by: Y7n05h --- diff --git a/pdns/bpf-filter.cc b/pdns/bpf-filter.cc index d0ec0f6172..35769e3b3d 100644 --- a/pdns/bpf-filter.cc +++ b/pdns/bpf-filter.cc @@ -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& 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& configs, BPFFilter::MapFormat format, bool external) { } diff --git a/pdns/bpf-filter.hh b/pdns/bpf-filter.hh index a8e2f5c834..29f44275dd 100644 --- a/pdns/bpf-filter.hh +++ b/pdns/bpf-filter.hh @@ -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& configs, BPFFilter::MapFormat format, bool external); BPFFilter(const BPFFilter&) = delete; BPFFilter(BPFFilter&&) = delete; BPFFilter& operator=(const BPFFilter&) = delete; diff --git a/pdns/dnsdist-lua-bindings.cc b/pdns/dnsdist-lua-bindings.cc index 0ea0250a2f..877a6f3fe4 100644 --- a/pdns/dnsdist-lua-bindings.cc +++ b/pdns/dnsdist-lua-bindings.cc @@ -425,20 +425,27 @@ void setupLuaBindings(LuaContext& luaCtx, bool client) /* BPF Filter */ #ifdef HAVE_EBPF using bpfFilterMapParams = boost::variant>>; - luaCtx.writeFunction("newBPFFilter", [client](bpfFilterMapParams v4Params, bpfFilterMapParams v6Params, bpfFilterMapParams qnameParams, boost::optional external) { + using bpfopts_t = LuaAssociativeTable>; + luaCtx.writeFunction("newBPFFilter", [client](bpfopts_t opts) { if (client) { return std::shared_ptr(nullptr); } + std::unordered_map 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(tmp); + BPFFilter::MapConfiguration config; config.d_type = type; if (params.type() == typeid(uint32_t)) { config.d_maxItems = boost::get(params); } else if (params.type() == typeid(LuaAssociativeTable>)) { - auto map = boost::get>>(params); + const auto& map = boost::get>>(params); if (map.count("maxItems")) { config.d_maxItems = boost::get(map.at("maxItems")); } @@ -446,18 +453,24 @@ void setupLuaBindings(LuaContext& luaCtx, bool client) config.d_pinnedPath = boost::get(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(tmp))) + format = BPFFilter::MapFormat::WithActions; } - return std::make_shared(v4Config, v6Config, qnameConfig, format, external.value_or(false)); + return std::make_shared(mapsConfig, format, external); }); luaCtx.registerFunction::*)(const ComboAddress& ca, boost::optional action)>("block", [](std::shared_ptr bpf, const ComboAddress& ca, boost::optional action) { diff --git a/pdns/dnsdistdist/docs/reference/ebpf.rst b/pdns/dnsdistdist/docs/reference/ebpf.rst index 084797055e..d98180f904 100644 --- a/pdns/dnsdistdist/docs/reference/ebpf.rst +++ b/pdns/dnsdistdist/docs/reference/ebpf.rst @@ -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