From: Ron Dempster (rdempste) Date: Tue, 4 Oct 2022 12:58:59 +0000 (+0000) Subject: Pull request #3609: reputation, sfrt: refactor reputation to remove global variables X-Git-Tag: 3.1.43.0~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4f3c40921bdf6e89a910370fa500390b0c618cb;p=thirdparty%2Fsnort3.git Pull request #3609: reputation, sfrt: refactor reputation to remove global variables Merge in SNORT/snort3 from ~RDEMPSTE/snort3:reputation to master Squashed commit of the following: commit ab363a193b3f5cc0696d3641050894b256b25712 Author: Ron Dempster (rdempste) Date: Thu Sep 29 13:41:26 2022 -0400 reputation, sfrt: refactor reputation to remove global variables Moved the segment_mem global variables and code into a new sfrt RtTable class. Created a parser class that holds the RtTable class during parsing. --- diff --git a/src/network_inspectors/reputation/reputation_config.h b/src/network_inspectors/reputation/reputation_config.h index 99a8fcfc7..3e4237722 100644 --- a/src/network_inspectors/reputation/reputation_config.h +++ b/src/network_inspectors/reputation/reputation_config.h @@ -22,7 +22,7 @@ #include "framework/counts.h" #include "main/thread.h" -#include "sfrt/sfrt_flat.h" +#include "sfrt/sfrt.h" #include #include @@ -109,5 +109,6 @@ struct ReputationStats extern const PegInfo reputation_peg_names[]; extern THREAD_LOCAL ReputationStats reputationstats; + #endif diff --git a/src/network_inspectors/reputation/reputation_inspect.cc b/src/network_inspectors/reputation/reputation_inspect.cc index d31924a98..c9054d275 100644 --- a/src/network_inspectors/reputation/reputation_inspect.cc +++ b/src/network_inspectors/reputation/reputation_inspect.cc @@ -552,10 +552,10 @@ ReputationData* Reputation::load_data() { ReputationData* data = new ReputationData(); if (!config.list_dir.empty()) - read_manifest(MANIFEST_FILENAME, config, *data); + ReputationParser::read_manifest(MANIFEST_FILENAME, config, *data); - add_block_allow_List(config, *data); - estimate_num_entries(*data); + ReputationParser::add_block_allow_List(config, *data); + ReputationParser::estimate_num_entries(*data); if (0 >= data->num_entries) { ParseWarning(WARN_CONF, @@ -563,8 +563,9 @@ ReputationData* Reputation::load_data() } else { - ip_list_init(data->num_entries + 1, config, *data); - reputationstats.memory_allocated = sfrt_flat_usage(data->ip_list); + ReputationParser parser; + parser.ip_list_init(data->num_entries + 1, config, *data); + reputationstats.memory_allocated = parser.get_usage(); } return data; diff --git a/src/network_inspectors/reputation/reputation_inspect.h b/src/network_inspectors/reputation/reputation_inspect.h index e8fe8908d..d43fd707e 100644 --- a/src/network_inspectors/reputation/reputation_inspect.h +++ b/src/network_inspectors/reputation/reputation_inspect.h @@ -23,6 +23,7 @@ #include "reputation_module.h" +struct table_flat_t; class ReputationData { public: diff --git a/src/network_inspectors/reputation/reputation_parse.cc b/src/network_inspectors/reputation/reputation_parse.cc index 6cee1c2bb..d6c88f267 100644 --- a/src/network_inspectors/reputation/reputation_parse.cc +++ b/src/network_inspectors/reputation/reputation_parse.cc @@ -134,8 +134,7 @@ static inline IPrepInfo* get_last_index(IPrepInfo* rep_info, uint8_t* base, int* } } -static inline int duplicate_info(IPrepInfo* dest_info,IPrepInfo* current_info, - uint8_t* base) +int ReputationParser::duplicate_info(IPrepInfo* dest_info, IPrepInfo* current_info, uint8_t* base) { int bytes_allocated = 0; @@ -145,7 +144,7 @@ static inline int duplicate_info(IPrepInfo* dest_info,IPrepInfo* current_info, *dest_info = *current_info; if (!current_info->next) break; - next_info = segment_snort_calloc(1,sizeof(IPrepInfo)); + next_info = table.segment_snort_calloc(1, sizeof(IPrepInfo)); if (!next_info) { dest_info->next = 0; @@ -163,7 +162,7 @@ static inline int duplicate_info(IPrepInfo* dest_info,IPrepInfo* current_info, return bytes_allocated; } -static int64_t update_entry_info(INFO* current, INFO new_entry, SaveDest save_dest, uint8_t* base) +int64_t ReputationParser::update_entry_info_impl(INFO* current, INFO new_entry, SaveDest save_dest, uint8_t* base) { IPrepInfo* current_info; IPrepInfo* new_info; @@ -176,7 +175,7 @@ static int64_t update_entry_info(INFO* current, INFO new_entry, SaveDest save_de if (!(*current)) { /* Copy the data to segment memory*/ - *current = segment_snort_calloc(1,sizeof(IPrepInfo)); + *current = table.segment_snort_calloc(1, sizeof(IPrepInfo)); if (!(*current)) { return -1; @@ -247,7 +246,7 @@ static int64_t update_entry_info(INFO* current, INFO new_entry, SaveDest save_de else { IPrepInfo* next_info; - MEM_OFFSET ipInfo_ptr = segment_snort_calloc(1,sizeof(IPrepInfo)); + MEM_OFFSET ipInfo_ptr = table.segment_snort_calloc(1, sizeof(IPrepInfo)); if (!ipInfo_ptr) return -1; dest_info->next = ipInfo_ptr; @@ -259,8 +258,15 @@ static int64_t update_entry_info(INFO* current, INFO new_entry, SaveDest save_de return bytes_allocated; } -static int add_ip(SfCidr* ip_addr,INFO info_ptr, const ReputationConfig& config, - ReputationData& data) +int64_t ReputationParser::update_entry_info(INFO* current, INFO new_entry, SaveDest save_dest, uint8_t* base, + void* data) +{ + assert(data); + ReputationParser* parser = static_cast(data); + return parser->update_entry_info_impl(current, new_entry, save_dest, base); +} + +int ReputationParser::add_ip(SfCidr* ip_addr,INFO info_ptr, const ReputationConfig& config) { /*This variable is used to check whether a more generic address * overrides specific address @@ -268,15 +274,15 @@ static int add_ip(SfCidr* ip_addr,INFO info_ptr, const ReputationConfig& config, uint32_t usage_before; uint32_t usage_after; - usage_before = sfrt_flat_usage(data.ip_list); + usage_before = table.sfrt_flat_usage(); int final_ret = IP_INSERT_SUCCESS; /*Check whether the same or more generic address is already in the table*/ - if (nullptr != sfrt_flat_lookup(ip_addr->get_addr(), data.ip_list)) + if (nullptr != table.sfrt_flat_lookup(ip_addr->get_addr())) final_ret = IP_INSERT_DUPLICATE; - int ret = sfrt_flat_insert(ip_addr, (unsigned char)ip_addr->get_bits(), info_ptr, RT_FAVOR_ALL, - data.ip_list, &update_entry_info); + int ret = table.sfrt_flat_insert(ip_addr, (unsigned char)ip_addr->get_bits(), info_ptr, RT_FAVOR_ALL, + &update_entry_info, this); if (RT_SUCCESS == ret) totalNumEntries++; @@ -285,7 +291,7 @@ static int add_ip(SfCidr* ip_addr,INFO info_ptr, const ReputationConfig& config, else final_ret = IP_INSERT_FAILURE; - usage_after = sfrt_flat_usage(data.ip_list); + usage_after = table.sfrt_flat_usage(); /*Compare in the same scale*/ if (usage_after > (config.memcap << 20)) final_ret = IP_MEM_ALLOC_FAILURE; @@ -435,8 +441,7 @@ static int snort_pton(char const* src, SfCidr* dest) return 1; } -static int process_line(char* line, INFO info, const ReputationConfig& config, - ReputationData& data) +int ReputationParser::process_line(char* line, INFO info, const ReputationConfig& config) { SfCidr address; @@ -446,7 +451,7 @@ static int process_line(char* line, INFO info, const ReputationConfig& config, if ( snort_pton(line, &address) < 1 ) return IP_INVALID; - return add_ip(&address, info, config, data); + return add_ip(&address, info, config); } static int update_path_to_file(char* full_filename, unsigned int max_size, const char* filename) @@ -508,7 +513,7 @@ static char* get_list_type_name(ListFile* list_info) } } -static void load_list_file(ListFile* list_info, const ReputationConfig& config, +void ReputationParser::load_list_file(ListFile* list_info, const ReputationConfig& config, ReputationData& data) { char linebuf[MAX_ADDR_LINE_LENGTH]; @@ -538,7 +543,7 @@ static void load_list_file(ListFile* list_info, const ReputationConfig& config, return; /*convert list info to ip entry info*/ - ip_info_ptr = segment_snort_calloc(1,sizeof(IPrepInfo)); + ip_info_ptr = table.segment_snort_calloc(1, sizeof(IPrepInfo)); if (!(ip_info_ptr)) return; base = (uint8_t*)data.ip_list; @@ -557,7 +562,7 @@ static void load_list_file(ListFile* list_info, const ReputationConfig& config, return; } - num_loaded_before = sfrt_flat_num_entries(data.ip_list); + num_loaded_before = table.sfrt_flat_num_entries(); while ( fgets(linebuf, MAX_ADDR_LINE_LENGTH, fp) ) { int ret; @@ -572,7 +577,7 @@ static void load_list_file(ListFile* list_info, const ReputationConfig& config, *cmt = '\0'; /* process the line */ - ret = process_line(linebuf, ip_info_ptr, config, data); + ret = process_line(linebuf, ip_info_ptr, config); if (IP_INSERT_SUCCESS == ret) { @@ -614,14 +619,14 @@ static void load_list_file(ListFile* list_info, const ReputationConfig& config, if ( SnortConfig::log_verbose() ) { LogMessage(" Reputation entries loaded: %u, invalid: %u, re-defined: %u (from file %s)\n", - sfrt_flat_num_entries(data.ip_list) - num_loaded_before, + table.sfrt_flat_num_entries() - num_loaded_before, invalid_count, duplicate_count, full_path_filename); } fclose(fp); } -void ip_list_init(uint32_t max_entries, const ReputationConfig& config, ReputationData& data) +void ReputationParser::ip_list_init(uint32_t max_entries, const ReputationConfig& config, ReputationData& data) { if ( !data.ip_list ) { @@ -629,13 +634,14 @@ void ip_list_init(uint32_t max_entries, const ReputationConfig& config, Reputati mem_size = estimate_size(max_entries, config.memcap); data.reputation_segment = (uint8_t*)snort_alloc(mem_size); - segment_meminit(data.reputation_segment, mem_size); + table.segment_meminit(data.reputation_segment, mem_size); /*DIR_16x7_4x4 for performance, but memory usage is high *Use DIR_8x16 worst case IPV4 5K, IPV6 15K (bytes) *Use DIR_16x7_4x4 worst case IPV4 500, IPV6 2.5M */ - data.ip_list = sfrt_flat_new(DIR_8x16, IPv6, max_entries, config.memcap); + table.sfrt_flat_new(DIR_8x16, IPv6, max_entries, config.memcap); + data.ip_list = table.get_table(); if ( !data.ip_list ) { @@ -720,7 +726,7 @@ static int load_file(int total_lines, const char* path) return num_lines; } -void estimate_num_entries(ReputationData& data) +void ReputationParser::estimate_num_entries(ReputationData& data) { data.num_entries = 0; @@ -728,7 +734,7 @@ void estimate_num_entries(ReputationData& data) data.num_entries += load_file(data.num_entries, file->file_name.c_str()); } -void add_block_allow_List(const ReputationConfig& config, ReputationData& data) +void ReputationParser::add_block_allow_List(const ReputationConfig& config, ReputationData& data) { if (config.blocklist_path.size()) { @@ -910,7 +916,7 @@ static bool process_line_in_manifest(ListFile* list_item, const char* manifest, return true; } -void read_manifest(const char* manifest_file, const ReputationConfig& config, ReputationData& data) +void ReputationParser::read_manifest(const char* manifest_file, const ReputationConfig& config, ReputationData& data) { char full_path_dir[PATH_MAX+1]; update_path_to_file(full_path_dir, PATH_MAX, config.list_dir.c_str()); diff --git a/src/network_inspectors/reputation/reputation_parse.h b/src/network_inspectors/reputation/reputation_parse.h index 33ba33443..b8251b720 100644 --- a/src/network_inspectors/reputation/reputation_parse.h +++ b/src/network_inspectors/reputation/reputation_parse.h @@ -22,12 +22,36 @@ #include +#include "sfrt/sfrt_flat.h" + +struct IPrepInfo; +struct ListFile; struct ReputationConfig; class ReputationData; -void ip_list_init(uint32_t max_entries, const ReputationConfig&, ReputationData&); -void estimate_num_entries(ReputationData&); -void read_manifest(const char* filename, const ReputationConfig&, ReputationData&); -void add_block_allow_List(const ReputationConfig&, ReputationData&); +class ReputationParser +{ +public: + static void read_manifest(const char* filename, const ReputationConfig&, ReputationData&); + static void add_block_allow_List(const ReputationConfig&, ReputationData&); + static void estimate_num_entries(ReputationData&); + + void load_list_file(ListFile* list_info, const ReputationConfig& config, + ReputationData& data); + void ip_list_init(uint32_t max_entries, const ReputationConfig&, ReputationData&); + + unsigned get_usage() const + { return table.sfrt_flat_usage(); } + +protected: + int duplicate_info(IPrepInfo* dest_info, IPrepInfo* current_info, uint8_t* base); + int64_t update_entry_info_impl(INFO* current, INFO new_entry, SaveDest save_dest, uint8_t* base); + int add_ip(snort::SfCidr* ip_addr,INFO info_ptr, const ReputationConfig& config); + int process_line(char* line, INFO info, const ReputationConfig& config); + + static int64_t update_entry_info(INFO* current, INFO new_entry, SaveDest save_dest, uint8_t* base, void* data); + + RtTable table; +}; #endif diff --git a/src/sfrt/sfrt.h b/src/sfrt/sfrt.h index 78bfe6576..ec1ae1c03 100644 --- a/src/sfrt/sfrt.h +++ b/src/sfrt/sfrt.h @@ -33,6 +33,7 @@ typedef unsigned long word; typedef void* GENERIC; // To be replaced with a pointer to a policy +using MEM_OFFSET = uint32_t; struct tuple_t { diff --git a/src/sfrt/sfrt_flat.cc b/src/sfrt/sfrt_flat.cc index feec86dc9..5b756749b 100644 --- a/src/sfrt/sfrt_flat.cc +++ b/src/sfrt/sfrt_flat.cc @@ -22,7 +22,7 @@ #include "config.h" #endif -#include "sfrt_flat.h" +#include "sfrt/sfrt_flat.h" #include "sfip/sf_cidr.h" @@ -36,23 +36,14 @@ using namespace snort; * @param data_size Max number of unique data entries * * Returns the new table. */ -table_flat_t* sfrt_flat_new(char table_flat_type, char ip_type, long data_size, uint32_t mem_cap) +void RtTable::sfrt_flat_new(char table_flat_type, char ip_type, long data_size, uint32_t mem_cap) { - table_flat_t* table; MEM_OFFSET table_ptr; uint8_t* base; long data_size_max = 1; table_ptr = segment_snort_alloc(sizeof(table_flat_t)); -#if 0 - /*The first allocation always return 0*/ - if (!table_ptr) - { - // return nullptr; - } -#endif - base = (uint8_t*)segment_basePtr(); table = (table_flat_t*)(&base[table_ptr]); @@ -67,7 +58,8 @@ table_flat_t* sfrt_flat_new(char table_flat_type, char ip_type, long data_size, #endif { segment_free(table_ptr); - return nullptr; + table = nullptr; + return; } /* mem_cap is specified in megabytes, but internally uses bytes. Convert */ @@ -88,7 +80,8 @@ table_flat_t* sfrt_flat_new(char table_flat_type, char ip_type, long data_size, if (!table->data) { segment_free(table_ptr); - return nullptr; + table = nullptr; + return; } table->allocated = sizeof(table_flat_t) + sizeof(INFO) * table->max_size; @@ -155,12 +148,10 @@ table_flat_t* sfrt_flat_new(char table_flat_type, char ip_type, long data_size, assert(table->rt); assert(table->rt6); - - return table; } /* Perform a lookup on value contained in "ip" */ -GENERIC sfrt_flat_lookup(const SfIp* ip, table_flat_t* table) +GENERIC RtTable::sfrt_flat_lookup(const SfIp* ip) { tuple_flat_t tuple; const uint32_t* addr; @@ -209,20 +200,9 @@ GENERIC sfrt_flat_lookup(const SfIp* ip, table_flat_t* table) } /* Insert "ip", of length "len", into "table", and have it point to "ptr" */ -int sfrt_flat_insert(SfCidr* cidr, unsigned char len, INFO ptr, - int behavior, table_flat_t* table, updateEntryInfoFunc updateEntry) +return_codes RtTable::sfrt_flat_insert(SfCidr* cidr, unsigned char len, INFO ptr, + int behavior, updateEntryInfoFunc updateEntry, void* update_entry_info_data) { - const SfIp* ip; - int index; - int res = RT_SUCCESS; - INFO* data; - tuple_flat_t tuple; - const uint32_t* addr; - int numAddrDwords; - TABLE_PTR rt; - uint8_t* base; - int64_t bytesAllocated; - if (!cidr) { return RT_INSERT_FAILURE; @@ -241,7 +221,10 @@ int sfrt_flat_insert(SfCidr* cidr, unsigned char len, INFO ptr, return RT_INSERT_FAILURE; } - ip = cidr->get_addr(); + const SfIp* ip = cidr->get_addr(); + TABLE_PTR rt; + int numAddrDwords; + const uint32_t* addr; if (ip->is_ip4()) { if (len < 96) @@ -260,11 +243,12 @@ int sfrt_flat_insert(SfCidr* cidr, unsigned char len, INFO ptr, else return RT_INSERT_FAILURE; - tuple = sfrt_dir_flat_lookup(addr, numAddrDwords, table->rt); + tuple_flat_t tuple = sfrt_dir_flat_lookup(addr, numAddrDwords, table->rt); - base = (uint8_t*)segment_basePtr(); - data = (INFO*)(&base[table->data]); + uint8_t* base = (uint8_t*)segment_basePtr(); + INFO* data = (INFO*)(&base[table->data]); + int index; if (tuple.length != len) { if ( table->num_ent >= table->max_size) @@ -282,7 +266,7 @@ int sfrt_flat_insert(SfCidr* cidr, unsigned char len, INFO ptr, index = tuple.index; } - bytesAllocated = updateEntry(&data[index], ptr, SAVE_TO_CURRENT, base); + int64_t bytesAllocated = updateEntry(&data[index], ptr, SAVE_TO_CURRENT, base, update_entry_info_data); if (bytesAllocated < 0) { @@ -295,7 +279,8 @@ int sfrt_flat_insert(SfCidr* cidr, unsigned char len, INFO ptr, /* The actual value that is looked-up is an index * into the data table. */ - res = sfrt_dir_flat_insert(addr, numAddrDwords, len, index, behavior, rt, updateEntry, data); + return_codes res = sfrt_dir_flat_insert(addr, numAddrDwords, len, index, behavior, rt, updateEntry, + update_entry_info_data, data); /* Check if we ran out of memory. If so, need to decrement * table->num_ent */ @@ -312,7 +297,7 @@ int sfrt_flat_insert(SfCidr* cidr, unsigned char len, INFO ptr, return res; } -uint32_t sfrt_flat_num_entries(table_flat_t* table) +uint32_t RtTable::sfrt_flat_num_entries() const { if (!table) { @@ -328,7 +313,7 @@ uint32_t sfrt_flat_num_entries(table_flat_t* table) return table->num_ent - 1; } -uint32_t sfrt_flat_usage(table_flat_t* table) +uint32_t RtTable::sfrt_flat_usage() const { uint32_t usage; if (!table || !table->rt || !table->allocated ) @@ -431,3 +416,51 @@ GENERIC sfrt_flat_dir8x_lookup(const SfIp* ip, table_flat_t* table) return nullptr; } +/*************************************************************************** + * allocate memory block from segment + * todo:currently, we only allocate memory continuously. Need to reuse freed + * memory in the future. + * return: + * 0: fail + * other: the offset of the allocated memory block + **************************************************************************/ +MEM_OFFSET RtTable::segment_snort_alloc(size_t size) +{ + MEM_OFFSET current_ptr = unused_ptr; + + if (unused_mem < size) + return 0; + + unused_ptr += size; + unused_mem -= size; + + return current_ptr; +} + +/*************************************************************************** + * allocate memory block from segment and initialize it to zero + * It calls segment_snort_alloc() to get memory. + * todo:currently, we only allocate memory continuously. Need to reuse freed + * memory in the future. + * return: + * 0: fail + * other: the offset of the allocated memory block + **************************************************************************/ +MEM_OFFSET RtTable::segment_snort_calloc(size_t num, size_t size) +{ + MEM_OFFSET current_ptr; + size_t total; + + if ((0 == size)||(0 == num)) + return 0; + /*Check possible overflow*/ + if (num > SIZE_MAX / size) + return 0; + total = num * size; + current_ptr = segment_snort_alloc(total); + if (0 != current_ptr) + memset((uint8_t*)base_ptr + current_ptr, 0, total); + + return current_ptr; +} + diff --git a/src/sfrt/sfrt_flat.h b/src/sfrt/sfrt_flat.h index 031b949b4..9edf205fd 100644 --- a/src/sfrt/sfrt_flat.h +++ b/src/sfrt/sfrt_flat.h @@ -29,57 +29,94 @@ // When accessing memory, it must use the base address and offset to // correctly refer to it. -#include "utils/segment_mem.h" +#include "sfrt/sfrt.h" +#include "sfrt/sfrt_flat_dir.h" typedef MEM_OFFSET INFO; /* To be replaced with a pointer to a policy */ typedef MEM_OFFSET FLAT_INDEX; typedef MEM_OFFSET TABLE_PTR; -typedef enum +enum SaveDest { SAVE_TO_NEW, SAVE_TO_CURRENT -}SaveDest; +}; + +typedef int64_t (*updateEntryInfoFunc)(INFO* entryInfo, INFO newInfo, + SaveDest saveDest, uint8_t* base, void* data); -typedef int64_t (* updateEntryInfoFunc)(INFO* entryInfo, INFO newInfo, - SaveDest saveDest, uint8_t* base); -typedef struct +struct tuple_flat_t { FLAT_INDEX index; int length; -} tuple_flat_t; - -// FIXIT-L circular include here -#include "sfrt/sfrt_flat_dir.h" +}; -/****************************************************************** - Master table struct. Abstracts DIR and LC-trie methods */ -typedef struct +// Master table struct. Abstracts DIR and LC-trie methods +struct table_flat_t { - uint32_t num_ent; /* Number of entries in the policy table */ - uint32_t max_size; /* Max size of policies array */ - char ip_type; /* Only IPs of this family will be used */ + unsigned num_ent = 0; // Number of entries in the policy table + unsigned max_size = 0; // Max size of policies array + char ip_type; // Only IPs of this family will be used char table_flat_type; char mem_type; - uint32_t allocated; - INFO data; /* data table. Each IP points to an entry here */ - TABLE_PTR rt; /* Actual "routing" table */ - TABLE_PTR rt6; /* Actual "routing" table */ - TABLE_PTR list_info; /* List file information table (entry information)*/ -} table_flat_t; + unsigned allocated; + INFO data; // data table. Each IP points to an entry here + TABLE_PTR rt; // Actual "routing" table + TABLE_PTR rt6; // Actual "routing" table + TABLE_PTR list_info; // List file information table (entry information) +}; /*******************************************************************/ -/* Abstracted routing table API */ -table_flat_t* sfrt_flat_new(char table_flat_type, char ip_type, - long data_size, uint32_t mem_cap); - -GENERIC sfrt_flat_lookup(const snort::SfIp* ip, table_flat_t* table); GENERIC sfrt_flat_dir8x_lookup(const snort::SfIp* ip, table_flat_t* table); -int sfrt_flat_insert(snort::SfCidr* cidr, unsigned char len, INFO ptr, int behavior, - table_flat_t* table, updateEntryInfoFunc updateEntry); -uint32_t sfrt_flat_usage(table_flat_t* table); -uint32_t sfrt_flat_num_entries(table_flat_t* table); +struct IPLOOKUP; +struct RtTable +{ + void sfrt_flat_new(char table_flat_type, char ip_type, long data_size, uint32_t mem_cap); + GENERIC sfrt_flat_lookup(const snort::SfIp*); + + return_codes sfrt_flat_insert(snort::SfCidr* cidr, unsigned char len, INFO ptr, int behavior, + updateEntryInfoFunc, void* update_entry_info_data); + unsigned sfrt_flat_usage() const; + unsigned sfrt_flat_num_entries() const; + table_flat_t* get_table() const + { return table; } + + void segment_meminit(uint8_t* buff, size_t mem_cap) + { + base_ptr = buff; + unused_ptr = 0; + unused_mem = mem_cap; + } + MEM_OFFSET segment_snort_calloc(size_t num, size_t size); + +protected: + TABLE_PTR sfrt_dir_flat_new(uint32_t mem_cap, int count, ...); + tuple_flat_t sfrt_dir_flat_lookup(const uint32_t* addr, int numAddrDwords, TABLE_PTR table_ptr); + return_codes sfrt_dir_flat_insert(const uint32_t* addr, int numAddrDwords, int len, word data_index, + int behavior, TABLE_PTR, updateEntryInfoFunc updateEntry, void* update_entry_info_data, INFO *data); + uint32_t sfrt_dir_flat_usage(TABLE_PTR) const; + TABLE_PTR _sub_table_flat_new(dir_table_flat_t* root, uint32_t dimension, uint32_t prefill, uint32_t bit_length); + return_codes _dir_sub_insert(IPLOOKUP* ip, int length, int cur_len, INFO ptr, + int current_depth, int behavior, SUB_TABLE_PTR sub_ptr, dir_table_flat_t* root_table, + updateEntryInfoFunc updateEntry, void* update_entry_info_data, INFO* data); + int64_t _dir_update_info(int index, int fill, word length, uint32_t val, SUB_TABLE_PTR sub_ptr, + updateEntryInfoFunc updateEntry, void* update_entry_info_data, INFO* data); + tuple_flat_t _dir_sub_flat_lookup(IPLOOKUP* ip, TABLE_PTR table_ptr); + + MEM_OFFSET segment_snort_alloc(size_t size); + void segment_free(MEM_OFFSET) + { } + size_t segment_unusedmem() const + { return unused_mem; } + void* segment_basePtr() const + { return base_ptr; } + + table_flat_t* table = nullptr; + MEM_OFFSET unused_ptr = 0; + size_t unused_mem = 0; + void* base_ptr = nullptr; +}; #endif diff --git a/src/sfrt/sfrt_flat_dir.cc b/src/sfrt/sfrt_flat_dir.cc index 363642910..2cfc5f8ce 100644 --- a/src/sfrt/sfrt_flat_dir.cc +++ b/src/sfrt/sfrt_flat_dir.cc @@ -22,32 +22,31 @@ #include "config.h" #endif -#include "sfrt_flat.h" // FIXIT-L these includes are circular -#include "sfrt_flat_dir.h" +#include "sfrt/sfrt_flat_dir.h" #include +#include "sfrt/sfrt_flat.h" + #if SIZEOF_UNSIGNED_LONG_INT == 8 #define ARCH_WIDTH 64 #else #define ARCH_WIDTH 32 #endif -typedef struct +struct IPLOOKUP { const uint32_t* addr; int bits; -} IPLOOKUP; +}; /* Create new "sub" table of 2^width entries */ -static TABLE_PTR _sub_table_flat_new(dir_table_flat_t* root, uint32_t dimension, +TABLE_PTR RtTable::_sub_table_flat_new(dir_table_flat_t* root, uint32_t dimension, uint32_t prefill, uint32_t bit_length) { int width = root->dimensions[dimension]; int len = 1 << width; int index; - dir_sub_table_flat_t* sub; - TABLE_PTR sub_ptr; uint8_t* base; DIR_Entry* entries; @@ -63,7 +62,7 @@ static TABLE_PTR _sub_table_flat_new(dir_table_flat_t* root, uint32_t dimension, } /* Set up the initial prefilled "sub table" */ - sub_ptr = segment_snort_alloc(sizeof(dir_sub_table_flat_t)); + TABLE_PTR sub_ptr = segment_snort_alloc(sizeof(dir_sub_table_flat_t)); if (!sub_ptr) { @@ -71,7 +70,7 @@ static TABLE_PTR _sub_table_flat_new(dir_table_flat_t* root, uint32_t dimension, } base = (uint8_t*)segment_basePtr(); - sub = (dir_sub_table_flat_t*)(&base[sub_ptr]); + dir_sub_table_flat_t* sub = (dir_sub_table_flat_t*)(&base[sub_ptr]); /* This keeps the width readily available rather than recalculating it * from the number of entries during an insert or lookup */ @@ -110,7 +109,7 @@ static TABLE_PTR _sub_table_flat_new(dir_table_flat_t* root, uint32_t dimension, } /* Create new dir-n-m root table with 'count' depth */ -TABLE_PTR sfrt_dir_flat_new(uint32_t mem_cap, int count,...) +TABLE_PTR RtTable::sfrt_dir_flat_new(uint32_t mem_cap, int count,...) { va_list ap; int index; @@ -261,8 +260,8 @@ static inline void _dir_fill_less_specific(int index, int fill, } #endif -static inline int64_t _dir_update_info(int index, int fill, - word length, uint32_t val, SUB_TABLE_PTR sub_ptr, updateEntryInfoFunc updateEntry, INFO* data) +int64_t RtTable::_dir_update_info(int index, int fill, word length, uint32_t val, SUB_TABLE_PTR sub_ptr, + updateEntryInfoFunc updateEntry, void* update_entry_info_data, INFO* data) { dir_sub_table_flat_t* subtable; uint8_t* base; @@ -291,7 +290,7 @@ static inline int64_t _dir_update_info(int index, int fill, int64_t bytesAllocated; dir_sub_table_flat_t* next = (dir_sub_table_flat_t*)(&base[entry[index].value]); bytesAllocated = _dir_update_info(0, 1 << next->width, length, val, - entry[index].value, updateEntry, data); + entry[index].value, updateEntry, update_entry_info_data, data); if (bytesAllocated < 0) return bytesAllocated; else @@ -303,7 +302,7 @@ static inline int64_t _dir_update_info(int index, int fill, { int64_t bytesAllocated; bytesAllocated = updateEntry(&data[entry[index].value], data[val], - SAVE_TO_NEW, base); + SAVE_TO_NEW, base, update_entry_info_data); if (bytesAllocated < 0) return bytesAllocated; else @@ -317,7 +316,7 @@ static inline int64_t _dir_update_info(int index, int fill, { int64_t bytesAllocated; bytesAllocated = updateEntry(&data[entry[index].value], data[val], - SAVE_TO_CURRENT, base); + SAVE_TO_CURRENT, base, update_entry_info_data); if (bytesAllocated < 0) return bytesAllocated; else @@ -336,10 +335,9 @@ static inline int64_t _dir_update_info(int index, int fill, * @param length Number of bits of the IP used to specify this CIDR * @param ptr Information to be associated with this IP range * @param master_table The table that describes all, returned by dir_new */ -static int _dir_sub_insert(IPLOOKUP* ip, int length, int cur_len, INFO ptr, - int current_depth, int behavior, - SUB_TABLE_PTR sub_ptr, dir_table_flat_t* root_table,updateEntryInfoFunc updateEntry, - INFO* data) +return_codes RtTable::_dir_sub_insert(IPLOOKUP* ip, int length, int cur_len, INFO ptr, + int current_depth, int behavior, SUB_TABLE_PTR sub_ptr, dir_table_flat_t* root_table, + updateEntryInfoFunc updateEntry, void* update_entry_info_data, INFO* data) { word index; uint8_t* base = (uint8_t*)segment_basePtr(); @@ -400,7 +398,7 @@ static int _dir_sub_insert(IPLOOKUP* ip, int length, int cur_len, INFO ptr, int64_t bytesAllocated; bytesAllocated = _dir_update_info(index, fill, length, (word)ptr, - sub_ptr, updateEntry, data); + sub_ptr, updateEntry, update_entry_info_data, data); if (bytesAllocated < 0) return MEM_ALLOC_FAILURE; @@ -444,15 +442,15 @@ static int _dir_sub_insert(IPLOOKUP* ip, int length, int cur_len, INFO ptr, ip->bits += sub_table->width; return (_dir_sub_insert(ip, length, cur_len - sub_table->width, ptr, current_depth+1, - behavior, entry[index].value, root_table, updateEntry, data)); + behavior, entry[index].value, root_table, updateEntry, update_entry_info_data, data)); } return RT_SUCCESS; } /* Insert entry into DIR-n-m tables */ -int sfrt_dir_flat_insert(const uint32_t* addr, int /* numAddrDwords */, int len, word data_index, - int behavior, TABLE_PTR table_ptr, updateEntryInfoFunc updateEntry, INFO* data) +return_codes RtTable::sfrt_dir_flat_insert(const uint32_t* addr, int /* numAddrDwords */, int len, word data_index, + int behavior, TABLE_PTR table_ptr, updateEntryInfoFunc updateEntry, void* update_entry_info_data, INFO* data) { dir_table_flat_t* root; uint8_t* base; @@ -497,12 +495,12 @@ int sfrt_dir_flat_insert(const uint32_t* addr, int /* numAddrDwords */, int len, /* Find the sub table in which to insert */ return _dir_sub_insert(&iplu, len, len, data_index, - 0, behavior, root->sub_table, root, updateEntry, data); + 0, behavior, root->sub_table, root, updateEntry, update_entry_info_data, data); } /* Traverse sub tables looking for match Called by dir_lookup and recursively */ -static tuple_flat_t _dir_sub_flat_lookup(IPLOOKUP* ip, TABLE_PTR table_ptr) +tuple_flat_t RtTable::_dir_sub_flat_lookup(IPLOOKUP* ip, TABLE_PTR table_ptr) { word index; uint8_t* base = (uint8_t*)segment_basePtr(); @@ -546,7 +544,7 @@ static tuple_flat_t _dir_sub_flat_lookup(IPLOOKUP* ip, TABLE_PTR table_ptr) } /* Lookup information associated with the value "ip" */ -tuple_flat_t sfrt_dir_flat_lookup(const uint32_t* addr, int numAddrDwords, TABLE_PTR table_ptr) +tuple_flat_t RtTable::sfrt_dir_flat_lookup(const uint32_t* addr, int numAddrDwords, TABLE_PTR table_ptr) { dir_table_flat_t* root; uint8_t* base = (uint8_t*)segment_basePtr(); @@ -578,7 +576,7 @@ tuple_flat_t sfrt_dir_flat_lookup(const uint32_t* addr, int numAddrDwords, TABLE return _dir_sub_flat_lookup(&iplu, root->sub_table); } -uint32_t sfrt_dir_flat_usage(TABLE_PTR table_ptr) +uint32_t RtTable::sfrt_dir_flat_usage(TABLE_PTR table_ptr) const { dir_table_flat_t* table; uint8_t* base; diff --git a/src/sfrt/sfrt_flat_dir.h b/src/sfrt/sfrt_flat_dir.h index 9dc4d7a7c..38e30d15e 100644 --- a/src/sfrt/sfrt_flat_dir.h +++ b/src/sfrt/sfrt_flat_dir.h @@ -26,17 +26,17 @@ typedef MEM_OFFSET SUB_TABLE_PTR; typedef MEM_OFFSET ENTRIES_PTR; -typedef struct +struct DIR_Entry { MEM_OFFSET value; uint8_t length; -}DIR_Entry; +}; /*******************************************************************/ /* DIR-n-m data structures * Each table in the DIR-n-m method is represented by a * dir_sub_table_t. They are managed by a dir_table_t. */ -typedef struct +struct dir_sub_table_flat_t { int num_entries; /* Number of entries in this table */ int width; /* width of this table. */ @@ -46,10 +46,10 @@ typedef struct int cur_num; /* Present number of used nodes */ ENTRIES_PTR entries; -} dir_sub_table_flat_t; +}; /* Master data structure for the DIR-n-m derivative */ -typedef struct +struct dir_table_flat_t { int dimensions[20]; /* DIR-n-m will consist of any number of arbitrarily * long tables. This variable keeps track of the @@ -64,15 +64,7 @@ typedef struct uint32_t allocated; SUB_TABLE_PTR sub_table; -} dir_table_flat_t; - -/****************************************************************** - DIR-n-m functions, these are not intended to be called directly */ -TABLE_PTR sfrt_dir_flat_new(uint32_t mem_cap, int count,...); -tuple_flat_t sfrt_dir_flat_lookup(const uint32_t* addr, int numAddrDwords, TABLE_PTR table); -int sfrt_dir_flat_insert(const uint32_t* addr, int numAddrDwords, int len, word data_index, - int behavior, TABLE_PTR, updateEntryInfoFunc updateEntry, INFO *data); -uint32_t sfrt_dir_flat_usage(TABLE_PTR); +}; #endif /* SFRT_FLAT_DIR_H */ diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 5e5ec6dbe..f69c3f00c 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -9,7 +9,6 @@ set( UTIL_INCLUDES memcap_allocator.h primed_allocator.h safec.h - segment_mem.h sflsq.h stats.h util.h @@ -38,7 +37,6 @@ add_library ( utils OBJECT js_normalizer.h js_tokenizer.h kmap.cc - segment_mem.cc sflsq.cc snort_bounds.h stats.cc diff --git a/src/utils/segment_mem.cc b/src/utils/segment_mem.cc deleted file mode 100644 index 48ba9fc57..000000000 --- a/src/utils/segment_mem.cc +++ /dev/null @@ -1,116 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2022 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2011-2013 Sourcefire, Inc. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- -// 8/7/2011 - Initial implementation ... Hui Cao - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "segment_mem.h" - -#include - -/*point to the start of the unused memory*/ -static MEM_OFFSET unused_ptr = 0; -static size_t unused_mem = 0; -static void* base_ptr = nullptr; - -size_t segment_unusedmem() -{ - return unused_mem; -} - -/*************************************************************************** - * Initialize the segment memory - * Return values: - * 1: success - * 0: fail - **************************************************************************/ -int segment_meminit(uint8_t* buff, size_t mem_cap) -{ - base_ptr = buff; - unused_ptr = 0; - unused_mem = mem_cap; - return 1; -} - -/*************************************************************************** - * allocate memory block from segment - * todo:currently, we only allocate memory continuously. Need to reuse freed - * memory in the future. - * return: - * 0: fail - * other: the offset of the allocated memory block - **************************************************************************/ -MEM_OFFSET segment_snort_alloc(size_t size) -{ - MEM_OFFSET current_ptr = unused_ptr; - - if (unused_mem < size) - return 0; - - unused_ptr += size; - unused_mem -= size; - - return current_ptr; -} - -/*************************************************************************** - * Free memory block from segment - * Todo: currently, no action for free. Need to reuse freed memory in the - * future. - **************************************************************************/ - -void segment_free(MEM_OFFSET) -{ -} - -/*************************************************************************** - * allocate memory block from segment and initialize it to zero - * It calls segment_snort_alloc() to get memory. - * todo:currently, we only allocate memory continuously. Need to reuse freed - * memory in the future. - * return: - * 0: fail - * other: the offset of the allocated memory block - **************************************************************************/ - -MEM_OFFSET segment_snort_calloc(size_t num, size_t size) -{ - MEM_OFFSET current_ptr; - size_t total; - - if ((0 == size)||(0 == num)) - return 0; - /*Check possible overflow*/ - if (num > SIZE_MAX/size) - return 0; - total = num * size; - current_ptr = segment_snort_alloc(total); - if (0 != current_ptr) - memset((uint8_t*)base_ptr + current_ptr, 0, total); - - return current_ptr; -} - -void* segment_basePtr() -{ - return base_ptr; -} - diff --git a/src/utils/segment_mem.h b/src/utils/segment_mem.h deleted file mode 100644 index e851a27d1..000000000 --- a/src/utils/segment_mem.h +++ /dev/null @@ -1,39 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2022 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2011-2013 Sourcefire, Inc. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- -// segment_mem.h author Hui Cao - -#ifndef SEGMENT_MEM_H -#define SEGMENT_MEM_H - -// Segment memory allocation used by sfrt - -#include -#include - -using MEM_OFFSET = uint32_t; - -int segment_meminit(uint8_t*, size_t); -MEM_OFFSET segment_snort_alloc(size_t size); -void segment_free(MEM_OFFSET ptr); -MEM_OFFSET segment_snort_calloc(size_t num, size_t size); -size_t segment_unusedmem(); -void* segment_basePtr(); - -#endif -