}
-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");
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;
#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)
{
}
};
- 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;
/* 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"));
}
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) {
: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