From 04e64513ae57d990bd375dadf59c37512b9cca54 Mon Sep 17 00:00:00 2001 From: Timur Aitov Date: Fri, 9 Feb 2024 17:21:41 +0300 Subject: [PATCH] TEST --- common/acl.h | 14 +- common/idp.h | 14 +- controlplane/acl.h | 8 +- controlplane/acl_transport_table.h | 2 +- controlplane/configconverter.cpp | 6 +- dataplane/acl.cpp | 67 ++++-- dataplane/acl.h | 12 +- dataplane/base.h | 8 +- dataplane/controlplane.cpp | 4 +- dataplane/dataplane.cpp | 21 -- dataplane/globalbase.cpp | 50 +---- dataplane/globalbase.h | 15 -- dataplane/hashtable.h | 234 ++------------------- dataplane/memory_manager.cpp | 13 +- dataplane/memory_manager.h | 26 ++- dataplane/report.cpp | 3 - dataplane/updater.h | 326 ++++++++++++++++++++++++++++- dataplane/worker.cpp | 33 +-- 18 files changed, 486 insertions(+), 370 deletions(-) diff --git a/common/acl.h b/common/acl.h index 052824e0..50f8b860 100644 --- a/common/acl.h +++ b/common/acl.h @@ -300,11 +300,15 @@ using ranges_uint16_t = ranges_t; namespace idp { -using acl_transport_table = std::vector>; -using acl_total_table = std::vector>; - -using request = std::tuple; +using network_ipv4_source = std::vector; +using network_ipv4_destination = std::vector; +using transport_table = std::vector>; +using total_table = std::vector>; + +using request = std::tuple; using response = eResult; diff --git a/common/idp.h b/common/idp.h index 8de1c5d2..b7a7a991 100644 --- a/common/idp.h +++ b/common/idp.h @@ -144,8 +144,6 @@ enum class requestType : uint32_t route_tunnel_weight_update, route_tunnel_value_update, early_decap_flags, - acl_network_ipv4_source, - acl_network_ipv4_destination, acl_network_ipv6_source, acl_network_ipv6_destination_ht, acl_network_ipv6_destination, @@ -306,16 +304,6 @@ namespace update_early_decap_flags using request = bool; } -namespace acl_network_ipv4_source -{ -using request = std::vector; -} - -namespace acl_network_ipv4_destination -{ -using request = std::vector; -} - namespace acl_network_ipv6_source { using request = std::vector; @@ -508,7 +496,7 @@ using requestVariant = std::variant, update_balancer::request, update_balancer_services::request, route_tunnel_weight_update::request, - acl_network_ipv4_source::request, /// + acl_network_ipv4_destination, acl_network_ipv6_source, acl_network_ipv6_destination + acl_network_ipv6_source::request, /// + acl_network_ipv4_destination, acl_network_ipv6_source, acl_network_ipv6_destination acl_network_ipv6_destination_ht::request, acl_network_table::request, /// + aclTransportDestination acl_network_flags::request, diff --git a/controlplane/acl.h b/controlplane/acl.h index 30ac5404..3a8a8ade 100644 --- a/controlplane/acl.h +++ b/controlplane/acl.h @@ -17,16 +17,16 @@ typedef std::vector ids_t; struct result_t { - common::idp::updateGlobalBase::acl_network_ipv4_source::request acl_network_ipv4_source; - common::idp::updateGlobalBase::acl_network_ipv4_destination::request acl_network_ipv4_destination; + common::acl::idp::network_ipv4_source acl_network_ipv4_source; + common::acl::idp::network_ipv4_destination acl_network_ipv4_destination; common::idp::updateGlobalBase::acl_network_ipv6_source::request acl_network_ipv6_source; common::idp::updateGlobalBase::acl_network_ipv6_destination_ht::request acl_network_ipv6_destination_ht; common::idp::updateGlobalBase::acl_network_ipv6_destination::request acl_network_ipv6_destination; common::idp::updateGlobalBase::acl_network_table::request acl_network_table; common::idp::updateGlobalBase::acl_network_flags::request acl_network_flags; common::idp::updateGlobalBase::acl_transport_layers::request acl_transport_layers; - std::vector acl_transport_tables; - common::acl::idp::acl_total_table acl_total_table; + std::vector acl_transport_tables; + common::acl::idp::total_table acl_total_table; common::idp::updateGlobalBase::acl_values::request acl_values; std::vector ids_map; diff --git a/controlplane/acl_transport_table.h b/controlplane/acl_transport_table.h index a1de3bd2..23a0c662 100644 --- a/controlplane/acl_transport_table.h +++ b/controlplane/acl_transport_table.h @@ -69,7 +69,7 @@ class thread_t std::map> group_id_filter_ids; std::vector> transport_table_filter_id_group_ids; - common::acl::idp::acl_transport_table acl_transport_table; + common::acl::idp::transport_table acl_transport_table; std::optional exception; }; diff --git a/controlplane/configconverter.cpp b/controlplane/configconverter.cpp index 5bf7c40b..e8bc9595 100644 --- a/controlplane/configconverter.cpp +++ b/controlplane/configconverter.cpp @@ -1885,8 +1885,6 @@ void config_converter_t::buildAcl() throw std::runtime_error("support multithread here"); } - globalbase.emplace_back(common::idp::updateGlobalBase::requestType::acl_network_ipv4_source, std::move(result.acl_network_ipv4_source)); - globalbase.emplace_back(common::idp::updateGlobalBase::requestType::acl_network_ipv4_destination, std::move(result.acl_network_ipv4_destination)); globalbase.emplace_back(common::idp::updateGlobalBase::requestType::acl_network_ipv6_source, std::move(result.acl_network_ipv6_source)); globalbase.emplace_back(common::idp::updateGlobalBase::requestType::acl_network_ipv6_destination_ht, std::move(result.acl_network_ipv6_destination_ht)); globalbase.emplace_back(common::idp::updateGlobalBase::requestType::acl_network_ipv6_destination, std::move(result.acl_network_ipv6_destination)); @@ -1894,7 +1892,9 @@ void config_converter_t::buildAcl() globalbase.emplace_back(common::idp::updateGlobalBase::requestType::acl_network_flags, std::move(result.acl_network_flags)); globalbase.emplace_back(common::idp::updateGlobalBase::requestType::acl_transport_layers, std::move(result.acl_transport_layers)); - acl_request = {std::move(result.acl_transport_tables[0]), + acl_request = {std::move(result.acl_network_ipv4_source), + std::move(result.acl_network_ipv4_destination), + std::move(result.acl_transport_tables[0]), std::move(result.acl_total_table)}; globalbase.emplace_back(common::idp::updateGlobalBase::requestType::acl_values, std::move(result.acl_values)); diff --git a/dataplane/acl.cpp b/dataplane/acl.cpp index 29a32332..2d1ded52 100644 --- a/dataplane/acl.cpp +++ b/dataplane/acl.cpp @@ -4,6 +4,15 @@ using namespace dataplane::acl; +base::base(memory_manager* memory_manager, + const tSocketId socket_id) : + network_ipv4_source("acl.network.v4.source.lpm", memory_manager, socket_id), + network_ipv4_destination("acl.network.v4.destination.lpm", memory_manager, socket_id), + transport_table("acl.transport.ht", memory_manager, socket_id), + total_table("acl.total.ht", memory_manager, socket_id) +{ +} + module::module() : dataplane(nullptr) { @@ -18,10 +27,7 @@ eResult module::init(cDataPlane* dataplane) generations.fill([&](acl::generation& generation) { for (const auto socket_id : dataplane->get_socket_ids()) { - auto& base = generation.bases[socket_id]; - - base.transport_table_updater.init("acl.transport.ht", &dataplane->memory_manager, socket_id); - base.total_table_updater.init("acl.total.ht", &dataplane->memory_manager, socket_id); + generation.bases.try_emplace(socket_id, &dataplane->memory_manager, socket_id); } }); @@ -40,15 +46,27 @@ void module::update_worker_base(const std::vectorsecond; - worker_base->acl_transport_table = base.transport_table_updater.get_pointer(); - worker_base->acl_total_table = base.total_table_updater.get_pointer(); + worker_base->acl_network_ipv4_source = base.network_ipv4_source.pointer; + worker_base->acl_network_ipv4_destination = base.network_ipv4_destination.pointer; + worker_base->acl_transport_table = base.transport_table.pointer; + worker_base->acl_total_table = base.total_table.pointer; } } void module::report(nlohmann::json& json) { - /// XXX - (void)json; + auto lock = generations.current_lock_guard(); + + const auto& generation = generations.current(); + for (const auto socket_id : dataplane->get_socket_ids()) + { + const auto& base = generation.bases.find(socket_id)->second; + + base.network_ipv4_source.report(json["acl"]["network"]["ipv4"]["source"]); + base.network_ipv4_destination.report(json["acl"]["network"]["ipv4"]["destination"]); + base.transport_table.report(json["acl"]["transport_table"]); + base.total_table.report(json["acl"]["total_table"]); + } } void module::limits(common::idp::limits::response& response) @@ -60,8 +78,10 @@ void module::limits(common::idp::limits::response& response) { const auto& base = generation.bases.find(socket_id)->second; - base.transport_table_updater.limits(response); - base.total_table_updater.limits(response); + base.network_ipv4_source.limits(response); + base.network_ipv4_destination.limits(response); + base.transport_table.limits(response); + base.total_table.limits(response); } } @@ -122,8 +142,10 @@ void module::update_after(const common::idp::update::request& request) { auto& base = generation.bases.find(socket_id)->second; - base.transport_table_updater.free(); - base.total_table_updater.free(); + base.network_ipv4_source.free(); + base.network_ipv4_destination.free(); + base.transport_table.clear(); + base.total_table.clear(); } generations.next_unlock(); @@ -132,20 +154,35 @@ void module::update_after(const common::idp::update::request& request) eResult module::acl_update(const common::acl::idp::request& request_acl) { eResult result = eResult::success; - const auto& [request_transport_table, request_total_table] = request_acl; + const auto& [request_network_ipv4_source, + request_network_ipv4_destination, + request_transport_table, + request_total_table] = request_acl; auto& generation = generations.next(); for (const auto socket_id : dataplane->get_socket_ids()) { auto& base = generation.bases.find(socket_id)->second; - result = base.transport_table_updater.update(request_transport_table); + result = base.network_ipv4_source.update(request_network_ipv4_source); + if (result != eResult::success) + { + return result; + } + + result = base.network_ipv4_destination.update(request_network_ipv4_destination); + if (result != eResult::success) + { + return result; + } + + result = base.transport_table.update(request_transport_table); if (result != eResult::success) { return result; } - result = base.total_table_updater.update(request_total_table); + result = base.total_table.update(request_total_table); if (result != eResult::success) { return result; diff --git a/dataplane/acl.h b/dataplane/acl.h index 7e466f88..65f1fee5 100644 --- a/dataplane/acl.h +++ b/dataplane/acl.h @@ -8,20 +8,28 @@ #include "common/generation.h" #include "common/idp.h" +#include "lpm.h" #include "type.h" #include "updater.h" namespace dataplane::acl { +using network_ipv4_source = dataplane::updater_lpm4_24bit_8bit_id32; +using network_ipv4_destination = dataplane::updater_lpm4_24bit_8bit_id32; using transport_table = dataplane::updater_hashtable_mod_id32; using total_table = dataplane::updater_hashtable_mod_id32; class base { public: - acl::transport_table transport_table_updater; - acl::total_table total_table_updater; + base(dataplane::memory_manager* memory_manager, const tSocketId socket_id); + +public: + acl::network_ipv4_source network_ipv4_source; + acl::network_ipv4_destination network_ipv4_destination; + acl::transport_table transport_table; + acl::total_table total_table; }; class generation diff --git a/dataplane/base.h b/dataplane/base.h index eab88d57..7c8e4372 100644 --- a/dataplane/base.h +++ b/dataplane/base.h @@ -88,9 +88,11 @@ class generation } dataplane::globalBase::generation* globalBase; - dataplane::neighbor::hashtable const* neighbor_hashtable; - dataplane::acl::transport_table::hashtable_t const* acl_transport_table; - dataplane::acl::total_table::hashtable_t const* acl_total_table; + const dataplane::neighbor::hashtable* neighbor_hashtable; + const dataplane::acl::network_ipv4_source::object_type* acl_network_ipv4_source; + const dataplane::acl::network_ipv4_destination::object_type* acl_network_ipv4_destination; + const dataplane::acl::transport_table::object_type* acl_transport_table; + const dataplane::acl::total_table::object_type* acl_total_table; } __rte_aligned(2 * RTE_CACHE_LINE_SIZE); } diff --git a/dataplane/controlplane.cpp b/dataplane/controlplane.cpp index b543cef5..a58b6502 100644 --- a/dataplane/controlplane.cpp +++ b/dataplane/controlplane.cpp @@ -933,8 +933,6 @@ common::idp::limits::response cControlPlane::limits() YANET_CONFIG_ROUTE_TUNNEL_LPM6_EXTENDED_SIZE); globalBase->updater.acl.network_table.limits(response, "acl.network.ht"); - globalBase->updater.acl.network_ipv4_source.limits(response, "acl.network.v4.source.lpm"); - globalBase->updater.acl.network_ipv4_destination.limits(response, "acl.network.v4.destination.lpm"); globalBase->updater.acl.network_ipv6_source.limits(response, "acl.network.v6.source.lpm"); /// globalBase->acl.network_ipv6_destination_ht is not critical @@ -961,6 +959,8 @@ common::idp::limits::response cControlPlane::limits() } dregress.limits(response); + ///XXX dataPlane->memory_manager.limits(response); + ///XXX dataPlane->neighbor.limits(response); dataPlane->acl_module.limits(response); return response; diff --git a/dataplane/dataplane.cpp b/dataplane/dataplane.cpp index 1d121f3e..d45e0817 100644 --- a/dataplane/dataplane.cpp +++ b/dataplane/dataplane.cpp @@ -684,30 +684,12 @@ eResult cDataPlane::initGlobalBases() } { - auto* acl_network_ipv4_source = hugepage_create_dynamic(socket_id, getConfigValue(eConfigType::acl_network_lpm4_chunks_size), globalbase->updater.acl.network_ipv4_source); - if (!acl_network_ipv4_source) - { - return nullptr; - } - - auto* acl_network_ipv4_destination = hugepage_create_dynamic(socket_id, getConfigValue(eConfigType::acl_network_lpm4_chunks_size), globalbase->updater.acl.network_ipv4_destination); - if (!acl_network_ipv4_destination) - { - return nullptr; - } - auto* acl_network_ipv6_source = hugepage_create_dynamic(socket_id, getConfigValue(eConfigType::acl_network_source_lpm6_chunks_size), globalbase->updater.acl.network_ipv6_source); if (!acl_network_ipv6_source) { return nullptr; } - auto* acl_network_ipv6_destination_ht = hugepage_create_dynamic(socket_id, getConfigValue(eConfigType::acl_network_destination_ht_size), globalbase->updater.acl.network_ipv6_destination_ht); - if (!acl_network_ipv6_destination_ht) - { - return nullptr; - } - auto* acl_network_ipv6_destination = hugepage_create_dynamic(socket_id, getConfigValue(eConfigType::acl_network_destination_lpm6_chunks_size), globalbase->updater.acl.network_ipv6_destination); if (!acl_network_ipv6_destination) { @@ -753,10 +735,7 @@ eResult cDataPlane::initGlobalBases() return nullptr; } - globalbase->acl.network.ipv4.source = acl_network_ipv4_source; - globalbase->acl.network.ipv4.destination = acl_network_ipv4_destination; globalbase->acl.network.ipv6.source = acl_network_ipv6_source; - globalbase->acl.network.ipv6.destination_ht = acl_network_ipv6_destination_ht; globalbase->acl.network.ipv6.destination = acl_network_ipv6_destination; globalbase->acl.network_table = acl_network_table; globalbase->acl.transport_layers_mask = acl_transport_layers_size - 1; diff --git a/dataplane/globalbase.cpp b/dataplane/globalbase.cpp index a3ad64db..fe2fb999 100644 --- a/dataplane/globalbase.cpp +++ b/dataplane/globalbase.cpp @@ -141,14 +141,6 @@ eResult generation::update(const common::idp::updateGlobalBase::request& request { result = update_early_decap_flags(std::get(data)); } - else if (type == common::idp::updateGlobalBase::requestType::acl_network_ipv4_source) - { - result = acl_network_ipv4_source(std::get(data)); - } - else if (type == common::idp::updateGlobalBase::requestType::acl_network_ipv4_destination) - { - result = acl_network_ipv4_destination(std::get(data)); - } else if (type == common::idp::updateGlobalBase::requestType::acl_network_ipv6_source) { result = acl_network_ipv6_source(std::get(data)); @@ -411,7 +403,6 @@ eResult generation::clear() sampler_enabled = 0; serial = 0; - updater.acl.network_ipv6_destination_ht.clear(); acl.values[0] = {}; tun64mappingsTable.clear(); @@ -1847,34 +1838,6 @@ eResult generation::update_early_decap_flags(const common::idp::updateGlobalBase return result; } -eResult generation::acl_network_ipv4_source(const common::idp::updateGlobalBase::acl_network_ipv4_source::request& request) -{ - eResult result = eResult::success; - - result = updater.acl.network_ipv4_source.update(request); - if (result != eResult::success) - { - YANET_LOG_ERROR("acl.network.ipv4.source.update(): %s\n", result_to_c_str(result)); - return result; - } - - return result; -} - -eResult generation::acl_network_ipv4_destination(const common::idp::updateGlobalBase::acl_network_ipv4_destination::request& request) -{ - eResult result = eResult::success; - - result = updater.acl.network_ipv4_destination.update(request); - if (result != eResult::success) - { - YANET_LOG_ERROR("acl.network.ipv4.destination.update(): %s\n", result_to_c_str(result)); - return result; - } - - return result; -} - eResult generation::acl_network_ipv6_source(const common::idp::updateGlobalBase::acl_network_ipv6_source::request& request) { eResult result = eResult::success; @@ -1891,11 +1854,14 @@ eResult generation::acl_network_ipv6_source(const common::idp::updateGlobalBase: eResult generation::acl_network_ipv6_destination_ht(const common::idp::updateGlobalBase::acl_network_ipv6_destination_ht::request& request) { - auto result = updater.acl.network_ipv6_destination_ht.update(request); - if (result != eResult::success) - { - /// dont panic. this is fine - } + /// XXX + (void)request; + + // auto result = updater.acl.network_ipv6_destination_ht.update(request); + // if (result != eResult::success) + // { + // /// dont panic. this is fine + // } return eResult::success; } diff --git a/dataplane/globalbase.h b/dataplane/globalbase.h index aef62bbc..84dc0f79 100644 --- a/dataplane/globalbase.h +++ b/dataplane/globalbase.h @@ -61,10 +61,7 @@ struct transport_layer_t }; /// @todo: move to config -using network_ipv4_source = lpm4_24bit_8bit_id32_dynamic; -using network_ipv4_destination = lpm4_24bit_8bit_id32_dynamic; using network_ipv6_source = YANET_CONFIG_ACL_NETWORK_LPM6_TYPE; -using network_ipv6_destination_ht = hashtable_mod_id32_dynamic; using network_ipv6_destination = YANET_CONFIG_ACL_NETWORK_LPM6_TYPE; using network_table = dynamic_table; } @@ -157,8 +154,6 @@ class generation eResult route_tunnel_weight_update(const common::idp::updateGlobalBase::route_tunnel_weight_update::request& request); eResult route_tunnel_value_update(const common::idp::updateGlobalBase::route_tunnel_value_update::request& request); eResult update_early_decap_flags(const common::idp::updateGlobalBase::update_early_decap_flags::request& request); - eResult acl_network_ipv4_source(const common::idp::updateGlobalBase::acl_network_ipv4_source::request& request); - eResult acl_network_ipv4_destination(const common::idp::updateGlobalBase::acl_network_ipv4_destination::request& request); eResult acl_network_ipv6_source(const common::idp::updateGlobalBase::acl_network_ipv6_source::request& request); eResult acl_network_ipv6_destination_ht(const common::idp::updateGlobalBase::acl_network_ipv6_destination_ht::request& request); eResult acl_network_ipv6_destination(const common::idp::updateGlobalBase::acl_network_ipv6_destination::request& request); @@ -189,10 +184,7 @@ class generation { struct { - acl::network_ipv4_source::updater network_ipv4_source; - acl::network_ipv4_destination::updater network_ipv4_destination; acl::network_ipv6_source::updater network_ipv6_source; - acl::network_ipv6_destination_ht::updater network_ipv6_destination_ht; acl::network_ipv6_destination::updater network_ipv6_destination; acl::network_table::updater network_table; } acl; @@ -249,16 +241,9 @@ class generation { struct { - struct - { - acl::network_ipv4_source* source; - acl::network_ipv4_destination* destination; - } ipv4; - struct { acl::network_ipv6_source* source; - acl::network_ipv6_destination_ht* destination_ht; acl::network_ipv6_destination* destination; } ipv6; } network; diff --git a/dataplane/hashtable.h b/dataplane/hashtable.h index fb894884..194bc292 100644 --- a/dataplane/hashtable.h +++ b/dataplane/hashtable.h @@ -174,7 +174,7 @@ class hashtable_chain_t } inline bool lookup(const TKey& key, - TValue*& value) + TValue*& value) const { lookup(&key, &value, 1); return (value != nullptr); @@ -1752,220 +1752,18 @@ class hashtable_mod_id32_dynamic static_assert(valid_bit_offset < 32); public: - class updater + hashtable_mod_id32_dynamic(const uint32_t keys_size) { - public: - updater() : - hashtable(nullptr) - { - } - - void update_pointer(hashtable_t* hashtable, - const tSocketId socket_id, - const uint32_t total_size) - { - this->hashtable = hashtable; - this->socket_id = socket_id; - this->total_size = total_size; - - hashtable->total_mask = total_size - 1; - } - - hashtable_t* get_pointer() - { - return hashtable; - } - - const hashtable_t* get_pointer() const - { - return hashtable; - } - - template - eResult update(const std::vector>& keys) - { - eResult result = eResult::success; - - keys_count = 0; - keys_in_chunks.fill(0); - longest_chain = 0; - insert_failed = 0; - rewrites = 0; - - for (const auto& [key, value] : keys) - { - eResult insert_result; - if constexpr (std::is_same_v) - { - insert_result = insert(key, value); - } - else - { - insert_result = insert(key_t::convert(key), value); - } + total_mask = keys_size - 1; - if (insert_result != eResult::success) - { - result = insert_result; - } - } - - for (uint32_t chunk_i = 0; - chunk_i < total_size / chunk_size; - chunk_i++) - { - unsigned int count = 0; - - for (uint32_t pair_i = 0; - pair_i < chunk_size; - pair_i++) - { - if (hashtable->is_valid(chunk_i * chunk_size + pair_i)) - { - count++; - } - } - - keys_in_chunks[count]++; - } - - return result; - } - - void clear() - { - for (uint32_t i = 0; - i < total_size; - i++) - { - hashtable->pairs[i].value = 0; - } - } - - /// @todo: remove - template ///< @todo: common::idp::limits::response - void limits(list_T& list, - const std::string& name) const - { - list.emplace_back(name + ".keys", - socket_id, - keys_count, - total_size); - list.emplace_back(name + ".longest_collision", - socket_id, - longest_chain, - chunk_size); - } - - template ///< @todo: common::idp::limits::response - void limits(list_T& list) const - { - list.emplace_back(name + ".keys", - socket_id, - keys_count, - total_size); - list.emplace_back(name + ".longest_collision", - socket_id, - longest_chain, - chunk_size); - } - - template ///< @todo: nlohmann::json - void report(json_t& json) const - { - json["total_size"] = total_size; - json["keys_count"] = keys_count; - for (unsigned int i = 0; - i < keys_in_chunks.size(); - i++) - { - json["keys_in_chunks"][i] = keys_in_chunks[i]; - } - json["longest_chain"] = longest_chain; - json["insert_failed"] = insert_failed; - json["rewrites"] = rewrites; - } - - protected: - eResult insert(const key_t& key, - const uint32_t value) - { - const uint32_t hash = calculate_hash(key) & (total_size - 1); - - for (unsigned int try_i = 0; - try_i < chunk_size; - try_i++) - { - const uint32_t index = (hash + try_i) % total_size; - - if (!hashtable->is_valid(index)) - { - memcpy(&hashtable->pairs[index].key, &key, sizeof(key_t)); - hashtable->pairs[index].value = value; - hashtable->pairs[index].value |= 1u << shift_valid; - - keys_count++; - - uint64_t longest_chain = try_i + 1; - if (this->longest_chain < longest_chain) - { - this->longest_chain = longest_chain; - } - - return eResult::success; - } - else if (hashtable->is_valid_and_equal(index, key)) - { - hashtable->pairs[index].value = value; - hashtable->pairs[index].value |= 1u << shift_valid; - - rewrites++; - - return eResult::success; - } - } - - insert_failed++; - - return eResult::isFull; - } - - public: - std::string name; - hashtable_t* hashtable; - tSocketId socket_id; - uint32_t total_size; - uint32_t keys_count; - std::array keys_in_chunks; - uint32_t longest_chain; - uint64_t insert_failed; - uint64_t rewrites; - }; - -public: - static size_t calculate_sizeof(const uint64_t keys_count) - { - if (!keys_count) - { - YANET_LOG_ERROR("wrong keys_count: %lu\n", keys_count); - return 0; - } - else if (keys_count > 0xFFFFFFFFull) - { - YANET_LOG_ERROR("wrong keys_count: %lu\n", keys_count); - return 0; - } - - if (__builtin_popcount(keys_count) != 1) + for (uint32_t i = 0; + i < keys_size; + i++) { - YANET_LOG_ERROR("wrong keys_count: %lu is non power of 2\n", keys_count); - return 0; + pairs[i].value = 0; } - - return sizeof(hashtable_t) + (size_t)keys_count * sizeof(pair); } -public: /// value: /// valid invalid /// = 0VV = 1VV @@ -2083,15 +1881,6 @@ class hashtable_mod_id32_dynamic template friend class updater_hashtable_mod_id32; - uint32_t total_mask; - - struct pair - { - key_t key; - uint32_t value; - } pairs[]; - -protected: inline bool is_valid(const uint32_t index) const { return (pairs[index].value >> shift_valid) & 1; @@ -2106,6 +1895,15 @@ class hashtable_mod_id32_dynamic { return is_valid(index) && is_equal(index, key); } + +protected: + uint32_t total_mask; + + struct pair + { + key_t key; + uint32_t value; + } pairs[]; }; class hashtable_mod_spinlock_stats ///< @todo: move to class::updater diff --git a/dataplane/memory_manager.cpp b/dataplane/memory_manager.cpp index a0c3c718..1770f82c 100644 --- a/dataplane/memory_manager.cpp +++ b/dataplane/memory_manager.cpp @@ -62,9 +62,11 @@ eResult memory_manager::memory_manager_update(const common::idp::memory_manager_ return eResult::success; } -void* memory_manager::alloc(const char* name, - const tSocketId socket_id, - uint64_t size) +void* memory_manager::alloc( + const char* name, + const tSocketId socket_id, + uint64_t size, + const std::function& destructor) { if (!size) { @@ -98,7 +100,10 @@ void* memory_manager::alloc(const char* name, { std::lock_guard guard(pointers_mutex); - pointers.try_emplace(pointer, name, socket_id, size, pointer, rte_free); + pointers.try_emplace(pointer, name, socket_id, size, pointer, [destructor](void* pointer) { + destructor(pointer); + rte_free(pointer); + }); } return pointer; diff --git a/dataplane/memory_manager.h b/dataplane/memory_manager.h index c126b4e7..425cc7aa 100644 --- a/dataplane/memory_manager.h +++ b/dataplane/memory_manager.h @@ -35,10 +35,34 @@ class memory_manager void report(nlohmann::json& json); eResult memory_manager_update(const common::idp::memory_manager_update::request& request); - void* alloc(const char* name, const tSocketId socket_id, const uint64_t size); + void* alloc( + const char* name, + const tSocketId socket_id, + const uint64_t size, + const std::function& destructor = [](void*) {}); + void free(void* pointer); void debug(tSocketId socket_id); + template + type* create(const char* name, + const tSocketId socket_id, + const uint64_t size, + const args_t&... args) + { + void* pointer = alloc(name, socket_id, size, [](void* pointer) { + reinterpret_cast(pointer)->~type(); + }); + + if (pointer == nullptr) + { + return nullptr; + } + + return new (reinterpret_cast(pointer)) type(args...); + } + protected: cDataPlane* dataplane; common::memory_manager::memory_group root_memory_group; diff --git a/dataplane/report.cpp b/dataplane/report.cpp index 7967681d..330d2e0c 100644 --- a/dataplane/report.cpp +++ b/dataplane/report.cpp @@ -680,10 +680,7 @@ nlohmann::json cReport::convertGlobalBase(const dataplane::globalBase::generatio } globalBase->updater.acl.network_table.report(json["acl"]["network_table"]); - globalBase->updater.acl.network_ipv4_source.report(json["acl"]["network"]["ipv4"]["source"]); - globalBase->updater.acl.network_ipv4_destination.report(json["acl"]["network"]["ipv4"]["destination"]); globalBase->updater.acl.network_ipv6_source.report(json["acl"]["network"]["ipv6"]["source"]); - globalBase->updater.acl.network_ipv6_destination_ht.report(json["acl"]["network"]["ipv6"]["destination_ht"]); globalBase->updater.acl.network_ipv6_destination.report(json["acl"]["network"]["ipv6"]["destination"]); json["serial"] = globalBase->serial; diff --git a/dataplane/updater.h b/dataplane/updater.h index 94c57762..d19cb0c1 100644 --- a/dataplane/updater.h +++ b/dataplane/updater.h @@ -1,15 +1,28 @@ #pragma once #include - +#include #include #include "common.h" #include "hashtable.h" +#include "lpm.h" +#include "memory_manager.h" namespace dataplane { +/// XXX: MOVE +namespace limits +{ +using limit = std::tuple, + uint64_t, ///< current + uint64_t>; ///< maximum + +using response = std::vector; +} + class updater_base { public: @@ -29,10 +42,319 @@ class updater_base void* pointer; }; +template +class updater +{ +public: + using object_type = type; + + updater(const char* name, dataplane::memory_manager* memory_manager, const tSocketId socket_id) : + name(name), + memory_manager(memory_manager), + socket_id(socket_id), + pointer(nullptr), + object_size(0) + { + } + + virtual ~updater() + { + free(); + } + + // template + // object_type* create(const uint64_t size, + // const args_t&... args) + // { + // if (alloc(size) != eResult::success) + // { + // return nullptr; + // } + + // object_type* result = new (get_pointer()) object_type(args...); + // /// XXX:destructor + // // { + // // result->~type(); + // // } + // return result; + // } + + virtual void limits(limits::response& limits) const + { + (void)limits; + } + + virtual void report(nlohmann::json& report) const + { + (void)report; + } + + eResult allocddd(const uint64_t memory_size) + { + (void)memory_size; + return eResult::success; + } + + void free() + { + if (pointer) + { + memory_manager->free(pointer); + pointer = nullptr; + } + } + +protected: + std::string name; + dataplane::memory_manager* memory_manager; + tSocketId socket_id; + +public: + object_type* pointer; + uint64_t object_size; +}; + +class updater_lpm4_24bit_8bit_id32 : public updater +{ +public: + updater_lpm4_24bit_8bit_id32(const char* name, + dataplane::memory_manager* memory_manager, + const tSocketId socket_id) : + updater::updater(name, memory_manager, socket_id) + { + } + + eResult update(const std::vector& values) + { + (void)values; + return eResult::dataplaneIsBroken; + } +}; + +template +class updater_hashtable_mod_id32 +{ +public: + using object_type = hashtable_mod_id32_dynamic; + + updater_hashtable_mod_id32(const char* name, + dataplane::memory_manager* memory_manager, + const tSocketId socket_id) : + name(name), + memory_manager(memory_manager), + socket_id(socket_id), + keys_count(0), + keys_size(0), + pointer(nullptr) + { + } + + static uint64_t calculate_sizeof(const uint64_t keys_size) + { + if (!keys_size) + { + YANET_LOG_ERROR("wrong keys_size: %lu\n", keys_size); + return 0; + } + else if (keys_size > 0xFFFFFFFFull) + { + YANET_LOG_ERROR("wrong keys_size: %lu\n", keys_size); + return 0; + } + + if (__builtin_popcount(keys_size) != 1) + { + YANET_LOG_ERROR("wrong keys_size: %lu is non power of 2\n", keys_size); + return 0; + } + + return sizeof(object_type) + keys_size * sizeof(typename object_type::pair); + } + + eResult update(const std::vector>& values) + { + constexpr uint64_t keys_size_min = 128; + + keys_size = 1; + { + uint64_t keys_size_need = std::max(keys_size_min, + (uint64_t)(4ull * values.size())); + while (keys_size < keys_size_need) + { + keys_size <<= 1; + } + } + + for (;;) + { + pointer = memory_manager->create(name.data(), + socket_id, + calculate_sizeof(keys_size), + keys_size); + if (pointer == nullptr) + { + return eResult::errorAllocatingMemory; + } + + eResult result = fill(values); + if (result != eResult::success) + { + /// try again + + keys_size <<= 1; + continue; + } + + break; + } + + return eResult::success; + } + + void clear() + { + if (pointer) + { + memory_manager->free(pointer); + pointer = nullptr; + } + } + + void limits(limits::response& limits) const + { + limits.emplace_back(name + ".keys", + socket_id, + keys_count, + keys_size); + limits.emplace_back(name + ".longest_collision", + socket_id, + longest_chain, + chunk_size); + } + + void report(nlohmann::json& report) const + { + report["pointer"] = (uint64_t)pointer; ///< XXX: TO_HEX + report["keys_count"] = keys_count; + report["keys_size"] = keys_size; + for (unsigned int i = 0; + i < keys_in_chunks.size(); + i++) + { + report["keys_in_chunks"][i] = keys_in_chunks[i]; + } + report["longest_chain"] = longest_chain; + report["insert_failed"] = insert_failed; + report["rewrites"] = rewrites; + } + +protected: + eResult fill(const std::vector>& values) + { + eResult result = eResult::success; + + keys_count = 0; + keys_in_chunks.fill(0); + longest_chain = 0; + insert_failed = 0; + rewrites = 0; + + for (const auto& [key, value] : values) + { + eResult insert_result = insert(key, value); + if (insert_result != eResult::success) + { + result = insert_result; + } + } + + for (uint32_t chunk_i = 0; + chunk_i < keys_size / chunk_size; + chunk_i++) + { + unsigned int count = 0; + + for (uint32_t pair_i = 0; + pair_i < chunk_size; + pair_i++) + { + if (pointer->is_valid(chunk_i * chunk_size + pair_i)) + { + count++; + } + } + + keys_in_chunks[count]++; + } + + return result; + } + + eResult insert(const key_t& key, + const uint32_t value) + { + const uint32_t hash = object_type::calculate_hash(key) & pointer->total_mask; + + for (unsigned int try_i = 0; + try_i < chunk_size; + try_i++) + { + const uint32_t index = (hash + try_i) & pointer->total_mask; + + if (!pointer->is_valid(index)) + { + memcpy(&pointer->pairs[index].key, &key, sizeof(key_t)); + pointer->pairs[index].value = value; + pointer->pairs[index].value |= 1u << object_type::shift_valid; + + keys_count++; + + uint64_t longest_chain = try_i + 1; + if (this->longest_chain < longest_chain) + { + this->longest_chain = longest_chain; + } + + return eResult::success; + } + else if (pointer->is_valid_and_equal(index, key)) + { + pointer->pairs[index].value = value; + pointer->pairs[index].value |= 1u << object_type::shift_valid; + + rewrites++; + + return eResult::success; + } + } + + insert_failed++; + + return eResult::isFull; + } + +protected: + std::string name; + dataplane::memory_manager* memory_manager; + tSocketId socket_id; + + uint32_t keys_count; + uint32_t keys_size; + std::array keys_in_chunks; + uint32_t longest_chain; + uint64_t insert_failed; + uint64_t rewrites; + +public: + object_type* pointer; +}; + template -class updater_hashtable_mod_id32 : public updater_base +class updater123321123_hashtable_mod_id32 : public updater_base { public: using hashtable_t = hashtable_mod_id32_dynamic; diff --git a/dataplane/worker.cpp b/dataplane/worker.cpp index 54cc4777..3c67d8e6 100644 --- a/dataplane/worker.cpp +++ b/dataplane/worker.cpp @@ -1421,14 +1421,14 @@ inline void cWorker::acl_ingress_handle4() key_acl.ipv4_destinations[mbuf_i].address = ipv4Header->dst_addr; } - acl.network.ipv4.source->lookup(key_acl.ipv4_sources, - value_acl.ipv4_sources, - acl_ingress_stack4.mbufsCount); - - acl.network.ipv4.destination->lookup(key_acl.ipv4_destinations, - value_acl.ipv4_destinations, + base.acl_network_ipv4_source->lookup(key_acl.ipv4_sources, + value_acl.ipv4_sources, acl_ingress_stack4.mbufsCount); + base.acl_network_ipv4_destination->lookup(key_acl.ipv4_destinations, + value_acl.ipv4_destinations, + acl_ingress_stack4.mbufsCount); + acl.network_table->lookup(value_acl.ipv4_sources, value_acl.ipv4_destinations, value_acl.networks, @@ -1610,10 +1610,11 @@ inline void cWorker::acl_ingress_handle6() acl_ingress_stack6.mbufsCount); { - uint32_t mask = acl.network.ipv6.destination_ht->lookup(hashes, - key_acl.ipv6_destinations, - value_acl.ipv6_destinations, - acl_ingress_stack6.mbufsCount); + // uint32_t mask = acl.network.ipv6.destination_ht->lookup(hashes, + // key_acl.ipv6_destinations, + // value_acl.ipv6_destinations, + // acl_ingress_stack6.mbufsCount); + uint32_t mask = 0; acl.network.ipv6.destination->lookup(mask, key_acl.ipv6_destinations, value_acl.ipv6_destinations, @@ -5126,14 +5127,14 @@ inline void cWorker::acl_egress_handle4() key_acl.ipv4_destinations[mbuf_i].address = ipv4Header->dst_addr; } - acl.network.ipv4.source->lookup(key_acl.ipv4_sources, - value_acl.ipv4_sources, - acl_egress_stack4.mbufsCount); - - acl.network.ipv4.destination->lookup(key_acl.ipv4_destinations, - value_acl.ipv4_destinations, + base.acl_network_ipv4_source->lookup(key_acl.ipv4_sources, + value_acl.ipv4_sources, acl_egress_stack4.mbufsCount); + base.acl_network_ipv4_destination->lookup(key_acl.ipv4_destinations, + value_acl.ipv4_destinations, + acl_egress_stack4.mbufsCount); + acl.network_table->lookup(value_acl.ipv4_sources, value_acl.ipv4_destinations, value_acl.networks,