From 7e36d48268abf837d2b383bbfe341a3f4df75960 Mon Sep 17 00:00:00 2001 From: Timur Aitov Date: Tue, 13 Feb 2024 15:29:44 +0300 Subject: [PATCH] TEST. LPMv4 --- dataplane/acl.cpp | 4 +- dataplane/lpm.h | 187 +------------------------------------ dataplane/updater.h | 219 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 219 insertions(+), 191 deletions(-) diff --git a/dataplane/acl.cpp b/dataplane/acl.cpp index 2d1ded52..2918e78d 100644 --- a/dataplane/acl.cpp +++ b/dataplane/acl.cpp @@ -142,8 +142,8 @@ void module::update_after(const common::idp::update::request& request) { auto& base = generation.bases.find(socket_id)->second; - base.network_ipv4_source.free(); - base.network_ipv4_destination.free(); + base.network_ipv4_source.clear(); + base.network_ipv4_destination.clear(); base.transport_table.clear(); base.total_table.clear(); } diff --git a/dataplane/lpm.h b/dataplane/lpm.h index 0afe4ed9..a0a57b6e 100644 --- a/dataplane/lpm.h +++ b/dataplane/lpm.h @@ -1921,191 +1921,6 @@ class lpm4_24bit_8bit_id32 class lpm4_24bit_8bit_id32_dynamic { -public: - class updater - { - public: - updater() : - extended_chunks_count(1) - { - } - - void update_pointer(lpm4_24bit_8bit_id32_dynamic* lpm, - const tSocketId socket_id, - const uint32_t extended_chunks_size) - { - this->lpm = lpm; - this->socket_id = socket_id; - this->extended_chunks_size = extended_chunks_size; - } - - eResult update(const std::vector& from_chunks) - { - extended_chunks_count = 1; - remap_chunks.resize(0); - remap_chunks.resize(from_chunks.size(), 0); - return update_root_chunk<0>(from_chunks, 0, 0); - } - - public: - template ///< @todo: common::idp::limits::response - void limits(list_T& list, - const std::string& name) const - { - list.emplace_back(name + ".extended_chunks", - socket_id, - extended_chunks_count, - extended_chunks_size); - } - - template ///< @todo: nlohmann::json - void report(json_t& json) const - { - json["extended_chunks_count"] = extended_chunks_count; - } - - protected: - inline unsigned int allocate_extended_chunk() - { - if (extended_chunks_count >= extended_chunks_size) - { - return 0; - } - - unsigned int new_chunk_id = extended_chunks_count; - extended_chunks_count++; - - return new_chunk_id; - } - - template - eResult update_root_chunk(const std::vector& from_chunks, - const unsigned int from_chunk_id, - const unsigned int root_chunk_values_offset) - { - eResult result = eResult::success; - - const auto& from_chunk = from_chunks[from_chunk_id]; - for (uint32_t i = 0; - i < (1u << 8); - i++) - { - const unsigned int root_chunk_values_i = root_chunk_values_offset + (i << (bits_step1 - bits_offset - 8)); - const auto& from_chunk_value = from_chunk.values[i]; - - if (from_chunk_value.is_chunk_id()) - { - if constexpr (bits_offset < bits_step1 - bits_step2) - { - result = update_root_chunk(from_chunks, - from_chunk_value.get_chunk_id(), - root_chunk_values_i); - if (result != eResult::success) - { - return result; - } - } - else if constexpr (bits_offset < bits_step1) - { - auto& root_chunk_value = lpm->root_chunk.values[root_chunk_values_i]; - - auto& extended_chunk_id = remap_chunks[from_chunk_value.get_chunk_id()]; - if (!extended_chunk_id) - { - extended_chunk_id = allocate_extended_chunk(); - if (!extended_chunk_id) - { - YANET_LOG_ERROR("lpm is full\n"); - return eResult::isFull; - } - - result = update_extended_chunk(from_chunks, - from_chunk_value.get_chunk_id(), - extended_chunk_id); - if (result != eResult::success) - { - return result; - } - } - - root_chunk_value.id = extended_chunk_id ^ 0x80000000u; - } - else - { - YANET_LOG_ERROR("tree broken\n"); - return eResult::invalidArguments; - } - } - else - { - if constexpr (bits_offset < bits_step1) - { - for (uint32_t j = 0; - j < (1u << (bits_step1 - bits_offset - 8)); - j++) - { - lpm->root_chunk.values[root_chunk_values_i + j].id = from_chunk_value.get_group_id(); - } - } - else - { - YANET_LOG_ERROR("tree broken\n"); - return eResult::invalidArguments; - } - } - } - - return result; - } - - eResult update_extended_chunk(const std::vector& from_chunks, - const unsigned int from_chunk_id, - const unsigned int extended_chunk_id) - { - const auto& from_chunk = from_chunks[from_chunk_id]; - auto& extended_chunk = lpm->extended_chunks[extended_chunk_id]; - - for (uint32_t i = 0; - i < (1u << 8); - i++) - { - const auto& from_chunk_value = from_chunk.values[i]; - auto& extended_chunk_value = extended_chunk.values[i]; - - if (from_chunk_value.is_chunk_id()) - { - YANET_LOG_ERROR("is_chunk_id\n"); - return eResult::invalidArguments; - } - else - { - extended_chunk_value.id = from_chunk_value.get_group_id(); - } - } - - return eResult::success; - } - - public: - lpm4_24bit_8bit_id32_dynamic* lpm; - tSocketId socket_id; - uint32_t extended_chunks_size; - unsigned int extended_chunks_count; - std::vector remap_chunks; - }; - -public: - static size_t calculate_sizeof(const uint32_t extended_chunks_size) - { - if (!extended_chunks_size) - { - YANET_LOG_ERROR("wrong extended_chunks_size: %u\n", extended_chunks_size); - return 0; - } - - return sizeof(lpm4_24bit_8bit_id32_dynamic) + extended_chunks_size * sizeof(chunk_step2_t); - } - public: template inline void lookup(const ipv4_address_t (&addresses)[burst_size], @@ -2135,6 +1950,8 @@ class lpm4_24bit_8bit_id32_dynamic } protected: + friend class updater_lpm4_24bit_8bit_id32; + constexpr static unsigned int bits_step1 = 24; constexpr static unsigned int bits_step2 = 8; constexpr static uint32_t mask_full = 0xFFFFFFFFu; diff --git a/dataplane/updater.h b/dataplane/updater.h index d19cb0c1..1bd88558 100644 --- a/dataplane/updater.h +++ b/dataplane/updater.h @@ -114,21 +114,232 @@ class updater uint64_t object_size; }; -class updater_lpm4_24bit_8bit_id32 : public updater +class updater_lpm4_24bit_8bit_id32 { public: + using object_type = lpm4_24bit_8bit_id32_dynamic; + updater_lpm4_24bit_8bit_id32(const char* name, dataplane::memory_manager* memory_manager, const tSocketId socket_id) : - updater::updater(name, memory_manager, socket_id) + name(name), + memory_manager(memory_manager), + socket_id(socket_id), + extended_chunks_size(1), + extended_chunks_count(0), + pointer(nullptr) { } + static uint64_t calculate_sizeof(const uint64_t extended_chunks_size) + { + if (!extended_chunks_size) + { + YANET_LOG_ERROR("wrong extended_chunks_size: %lu\n", extended_chunks_size); + return 0; + } + + return sizeof(object_type) + extended_chunks_size * sizeof(object_type::chunk_step2_t); + } + eResult update(const std::vector& values) { - (void)values; - return eResult::dataplaneIsBroken; + extended_chunks_size = std::max((uint64_t)8, values.size() / 16); + + for (;;) + { + pointer = memory_manager->create(name.data(), + socket_id, + calculate_sizeof(extended_chunks_size)); + if (pointer == nullptr) + { + return eResult::errorAllocatingMemory; + } + + eResult result = fill(values); + if (result != eResult::success) + { + /// try again + + extended_chunks_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 + ".extended_chunks", + socket_id, + extended_chunks_count, + extended_chunks_size); + } + + void report(nlohmann::json& report) const + { + report["extended_chunks_count"] = extended_chunks_count; + } + +protected: + inline unsigned int allocate_extended_chunk() + { + if (extended_chunks_count >= extended_chunks_size) + { + return 0; + } + + unsigned int new_chunk_id = extended_chunks_count; + extended_chunks_count++; + + return new_chunk_id; + } + + eResult fill(const std::vector& values) + { + extended_chunks_count = 1; + remap_chunks.resize(0); + remap_chunks.resize(values.size(), 0); + + if (values.empty()) + { + return eResult::success; + } + + return update_root_chunk<0>(values, 0, 0); } + + template + eResult update_root_chunk(const std::vector& from_chunks, + const unsigned int from_chunk_id, + const unsigned int root_chunk_values_offset) + { + eResult result = eResult::success; + + const auto& from_chunk = from_chunks[from_chunk_id]; + for (uint32_t i = 0; + i < (1u << 8); + i++) + { + const unsigned int root_chunk_values_i = root_chunk_values_offset + (i << (object_type::bits_step1 - bits_offset - 8)); + const auto& from_chunk_value = from_chunk.values[i]; + + if (from_chunk_value.is_chunk_id()) + { + if constexpr (bits_offset < object_type::bits_step1 - object_type::bits_step2) + { + result = update_root_chunk(from_chunks, + from_chunk_value.get_chunk_id(), + root_chunk_values_i); + if (result != eResult::success) + { + return result; + } + } + else if constexpr (bits_offset < object_type::bits_step1) + { + auto& root_chunk_value = pointer->root_chunk.values[root_chunk_values_i]; + + auto& extended_chunk_id = remap_chunks[from_chunk_value.get_chunk_id()]; + if (!extended_chunk_id) + { + extended_chunk_id = allocate_extended_chunk(); + if (!extended_chunk_id) + { + YANET_LOG_ERROR("lpm is full\n"); + return eResult::isFull; + } + + result = update_extended_chunk(from_chunks, + from_chunk_value.get_chunk_id(), + extended_chunk_id); + if (result != eResult::success) + { + return result; + } + } + + root_chunk_value.id = extended_chunk_id ^ 0x80000000u; + } + else + { + YANET_LOG_ERROR("tree broken\n"); + return eResult::invalidArguments; + } + } + else + { + if constexpr (bits_offset < object_type::bits_step1) + { + for (uint32_t j = 0; + j < (1u << (object_type::bits_step1 - bits_offset - 8)); + j++) + { + pointer->root_chunk.values[root_chunk_values_i + j].id = from_chunk_value.get_group_id(); + } + } + else + { + YANET_LOG_ERROR("tree broken\n"); + return eResult::invalidArguments; + } + } + } + + return result; + } + + eResult update_extended_chunk(const std::vector& from_chunks, + const unsigned int from_chunk_id, + const unsigned int extended_chunk_id) + { + const auto& from_chunk = from_chunks[from_chunk_id]; + auto& extended_chunk = pointer->extended_chunks[extended_chunk_id]; + + for (uint32_t i = 0; + i < (1u << 8); + i++) + { + const auto& from_chunk_value = from_chunk.values[i]; + auto& extended_chunk_value = extended_chunk.values[i]; + + if (from_chunk_value.is_chunk_id()) + { + YANET_LOG_ERROR("is_chunk_id\n"); + return eResult::invalidArguments; + } + else + { + extended_chunk_value.id = from_chunk_value.get_group_id(); + } + } + + return eResult::success; + } + +protected: + std::string name; + dataplane::memory_manager* memory_manager; + tSocketId socket_id; + + uint32_t extended_chunks_size; + unsigned int extended_chunks_count; + std::vector remap_chunks; + +public: + object_type* pointer; }; template