LCOV - code coverage report
Current view: top level - core - set.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 91 0
Test Date: 2025-06-20 13:16:12 Functions: 0.0 % 10 0

            Line data    Source code
       1              : // SPDX-License-Identifier: GPL-2.0-only
       2              : /*
       3              :  * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
       4              :  */
       5              : 
       6              : #include "core/set.h"
       7              : 
       8              : #include <errno.h>
       9              : #include <stdint.h>
      10              : #include <stdlib.h>
      11              : #include <string.h>
      12              : #include <time.h>
      13              : 
      14              : #include "bpfilter/cgen/prog/map.h"
      15              : #include "bpfilter/cgen/runtime.h"
      16              : #include "core/dump.h"
      17              : #include "core/helper.h"
      18              : #include "core/list.h"
      19              : #include "core/logger.h"
      20              : #include "core/marsh.h"
      21              : 
      22            0 : size_t _bf_set_type_elem_size(enum bf_set_type type)
      23              : {
      24              :     static const size_t sizes[_BF_SET_MAX] = {
      25              :         [BF_SET_IP4] = 4,
      26              :         [BF_SET_SRCIP6PORT] = 18,
      27              :         [BF_SET_SRCIP6] = 16,
      28              :         [BF_SET_IP4_SUBNET] = sizeof(struct bf_ip4_lpm_key),
      29              :         [BF_SET_IP6_SUBNET] = sizeof(struct bf_ip6_lpm_key),
      30              :     };
      31              : 
      32              :     static_assert(ARRAY_SIZE(sizes) == _BF_SET_MAX,
      33              :                   "missing entries in set elems size array");
      34              : 
      35            0 :     return sizes[type];
      36              : }
      37              : 
      38            0 : int bf_set_new(struct bf_set **set, enum bf_set_type type)
      39              : {
      40            0 :     bf_assert(set);
      41              : 
      42            0 :     *set = malloc(sizeof(**set));
      43            0 :     if (!*set)
      44              :         return -ENOMEM;
      45              : 
      46            0 :     (*set)->type = type;
      47            0 :     (*set)->elem_size = _bf_set_type_elem_size(type);
      48            0 :     bf_list_init(&(*set)->elems,
      49            0 :                  (bf_list_ops[]) {{.free = (bf_list_ops_free)freep}});
      50              : 
      51            0 :     return 0;
      52              : }
      53              : 
      54            0 : int bf_set_new_from_marsh(struct bf_set **set, const struct bf_marsh *marsh)
      55              : {
      56            0 :     _free_bf_set_ struct bf_set *_set = NULL;
      57              :     struct bf_marsh *child;
      58              :     enum bf_set_type type;
      59              :     int r;
      60              : 
      61            0 :     bf_assert(set);
      62            0 :     bf_assert(marsh);
      63              : 
      64            0 :     if (!(child = bf_marsh_next_child(marsh, NULL)))
      65              :         return -EINVAL;
      66            0 :     memcpy(&type, child->data, sizeof(type));
      67              : 
      68            0 :     r = bf_set_new(&_set, type);
      69            0 :     if (r < 0)
      70              :         return r;
      71              : 
      72            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
      73              :         return -EINVAL;
      74              : 
      75            0 :     for (size_t i = 0; i < child->data_len / _set->elem_size; ++i) {
      76            0 :         _cleanup_free_ void *elem = malloc(_set->elem_size);
      77            0 :         if (!elem)
      78              :             return -ENOMEM;
      79              : 
      80            0 :         memcpy(elem, child->data + (i * _set->elem_size), _set->elem_size);
      81            0 :         r = bf_list_add_tail(&_set->elems, elem);
      82            0 :         if (r < 0)
      83              :             return r;
      84              : 
      85              :         TAKE_PTR(elem);
      86              :     }
      87              : 
      88            0 :     *set = TAKE_PTR(_set);
      89              : 
      90            0 :     return 0;
      91              : }
      92              : 
      93            0 : void bf_set_free(struct bf_set **set)
      94              : {
      95            0 :     bf_assert(set);
      96              : 
      97            0 :     if (!*set)
      98              :         return;
      99              : 
     100            0 :     bf_list_clean(&(*set)->elems);
     101              :     freep((void *)set);
     102              : }
     103              : 
     104            0 : int bf_set_marsh(const struct bf_set *set, struct bf_marsh **marsh)
     105              : {
     106            0 :     _free_bf_marsh_ struct bf_marsh *_marsh = NULL;
     107              :     _cleanup_free_ uint8_t *data = NULL;
     108              :     size_t elem_idx = 0;
     109              :     int r;
     110              : 
     111            0 :     bf_assert(set);
     112            0 :     bf_assert(marsh);
     113              : 
     114            0 :     r = bf_marsh_new(&_marsh, NULL, 0);
     115            0 :     if (r < 0)
     116              :         return r;
     117              : 
     118            0 :     r = bf_marsh_add_child_raw(&_marsh, &set->type, sizeof(set->type));
     119            0 :     if (r < 0)
     120              :         return r;
     121              : 
     122            0 :     data = malloc(set->elem_size * bf_list_size(&set->elems));
     123            0 :     if (!data)
     124            0 :         return bf_err_r(r, "failed to allocate memory for the set's content");
     125              : 
     126            0 :     bf_list_foreach (&set->elems, elem_node) {
     127            0 :         memcpy(data + (elem_idx * set->elem_size),
     128            0 :                bf_list_node_get_data(elem_node), set->elem_size);
     129            0 :         ++elem_idx;
     130              :     }
     131              : 
     132            0 :     r = bf_marsh_add_child_raw(&_marsh, data,
     133            0 :                                set->elem_size * bf_list_size(&set->elems));
     134            0 :     if (r < 0)
     135              :         return r;
     136              : 
     137            0 :     *marsh = TAKE_PTR(_marsh);
     138              : 
     139            0 :     return 0;
     140              : }
     141              : 
     142            0 : void bf_set_dump(const struct bf_set *set, prefix_t *prefix)
     143              : {
     144            0 :     bf_assert(set && prefix);
     145              : 
     146            0 :     DUMP(prefix, "struct bf_set at %p", set);
     147            0 :     bf_dump_prefix_push(prefix);
     148              : 
     149            0 :     DUMP(prefix, "type: %s", bf_set_type_to_str(set->type));
     150            0 :     DUMP(prefix, "elem_size: %lu", set->elem_size);
     151            0 :     DUMP(bf_dump_prefix_last(prefix), "elems: bf_list<bytes>[%lu]",
     152              :          bf_list_size(&set->elems));
     153              : 
     154            0 :     bf_dump_prefix_push(prefix);
     155            0 :     bf_list_foreach (&set->elems, elem_node) {
     156            0 :         if (bf_list_is_tail(&set->elems, elem_node))
     157            0 :             bf_dump_prefix_last(prefix);
     158              : 
     159            0 :         DUMP(prefix, "void * @ %p", bf_list_node_get_data(elem_node));
     160            0 :         bf_dump_prefix_push(prefix);
     161            0 :         bf_dump_hex(prefix, bf_list_node_get_data(elem_node), set->elem_size);
     162            0 :         bf_dump_prefix_pop(prefix);
     163              :     }
     164            0 :     bf_dump_prefix_pop(prefix);
     165              : 
     166            0 :     bf_dump_prefix_pop(prefix);
     167            0 : }
     168              : 
     169            0 : int bf_set_add_elem(struct bf_set *set, void *elem)
     170              : {
     171              :     _cleanup_free_ void *_elem = NULL;
     172              :     int r;
     173              : 
     174            0 :     bf_assert(set);
     175            0 :     bf_assert(elem);
     176              : 
     177            0 :     _elem = malloc(set->elem_size);
     178            0 :     if (!_elem)
     179              :         return -ENOMEM;
     180              : 
     181            0 :     memcpy(_elem, elem, set->elem_size);
     182              : 
     183            0 :     r = bf_list_add_tail(&set->elems, _elem);
     184            0 :     if (r < 0)
     185            0 :         return r;
     186              : 
     187              :     TAKE_PTR(_elem);
     188              : 
     189              :     return 0;
     190              : }
     191              : 
     192              : static const char *_bf_set_type_strs[] = {
     193              :     [BF_SET_IP4] = "BF_SET_IP4",
     194              :     [BF_SET_SRCIP6PORT] = "BF_SET_SRCIP6PORT",
     195              :     [BF_SET_SRCIP6] = "BF_SET_SRCIP6",
     196              :     [BF_SET_IP4_SUBNET] = "BF_SET_IP4_SUBNET",
     197              :     [BF_SET_IP6_SUBNET] = "BF_SET_IP6_SUBNET",
     198              : };
     199              : 
     200              : static_assert(ARRAY_SIZE(_bf_set_type_strs) == _BF_SET_MAX, "");
     201              : 
     202            0 : const char *bf_set_type_to_str(enum bf_set_type type)
     203              : {
     204            0 :     bf_assert(0 <= type && type < _BF_SET_MAX);
     205              : 
     206            0 :     return _bf_set_type_strs[type];
     207              : }
     208              : 
     209              : static enum bf_map_bpf_type _bf_set_type_to_map_bpf_type[] = {
     210              :     [BF_SET_IP4] = BF_MAP_BPF_TYPE_HASH,
     211              :     [BF_SET_SRCIP6PORT] = BF_MAP_BPF_TYPE_HASH,
     212              :     [BF_SET_SRCIP6] = BF_MAP_BPF_TYPE_HASH,
     213              :     [BF_SET_IP4_SUBNET] = BF_MAP_BPF_TYPE_LPM_TRIE,
     214              :     [BF_SET_IP6_SUBNET] = BF_MAP_BPF_TYPE_LPM_TRIE,
     215              : };
     216              : 
     217              : static_assert(ARRAY_SIZE(_bf_set_type_to_map_bpf_type) == _BF_SET_MAX, "");
     218              : 
     219            0 : enum bf_map_bpf_type bf_set_type_to_map_bpf_type(enum bf_set_type type)
     220              : {
     221            0 :     return _bf_set_type_to_map_bpf_type[type];
     222              : }
     223              : 
     224            0 : int bf_set_type_from_str(const char *str, enum bf_set_type *type)
     225              : {
     226            0 :     bf_assert(str);
     227            0 :     bf_assert(type);
     228              : 
     229            0 :     for (size_t i = 0; i < _BF_SET_MAX; ++i) {
     230            0 :         if (bf_streq(_bf_set_type_strs[i], str)) {
     231            0 :             *type = i;
     232            0 :             return 0;
     233              :         }
     234              :     }
     235              : 
     236              :     return -EINVAL;
     237              : }
        

Generated by: LCOV version 2.0-1