LCOV - code coverage report
Current view: top level - core - rule.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 75.0 % 84 63
Test Date: 2025-02-26 17:59:59 Functions: 83.3 % 6 5

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-2.0-only */
       2              : /*
       3              :  * Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
       4              :  */
       5              : 
       6              : #include "core/rule.h"
       7              : 
       8              : #include <errno.h>
       9              : #include <stdlib.h>
      10              : #include <string.h>
      11              : 
      12              : #include "core/dump.h"
      13              : #include "core/helper.h"
      14              : #include "core/list.h"
      15              : #include "core/logger.h"
      16              : #include "core/marsh.h"
      17              : #include "core/matcher.h"
      18              : #include "core/verdict.h"
      19              : 
      20            7 : int bf_rule_new(struct bf_rule **rule)
      21              : {
      22              :     struct bf_rule *_rule;
      23              : 
      24            7 :     bf_assert(rule);
      25              : 
      26            6 :     _rule = calloc(1, sizeof(*_rule));
      27            6 :     if (!_rule)
      28              :         return -ENOMEM;
      29              : 
      30            5 :     bf_list_init(
      31              :         &_rule->matchers,
      32            5 :         (bf_list_ops[]) {{.free = (bf_list_ops_free)bf_matcher_free,
      33              :                           .marsh = (bf_list_ops_marsh)bf_matcher_marsh}});
      34              : 
      35            5 :     *rule = _rule;
      36              : 
      37            5 :     return 0;
      38              : }
      39              : 
      40           10 : void bf_rule_free(struct bf_rule **rule)
      41              : {
      42           10 :     bf_assert(rule);
      43              : 
      44            9 :     if (!*rule)
      45              :         return;
      46              : 
      47            5 :     bf_list_clean(&(*rule)->matchers);
      48              : 
      49            5 :     free(*rule);
      50            5 :     *rule = NULL;
      51              : }
      52              : 
      53            4 : int bf_rule_marsh(const struct bf_rule *rule, struct bf_marsh **marsh)
      54              : {
      55            2 :     _cleanup_bf_marsh_ struct bf_marsh *_marsh = NULL;
      56              :     int r;
      57              : 
      58            4 :     bf_assert(rule);
      59            3 :     bf_assert(marsh);
      60              : 
      61            2 :     r = bf_marsh_new(&_marsh, NULL, 0);
      62            2 :     if (r < 0)
      63              :         return r;
      64              : 
      65            1 :     r = bf_marsh_add_child_raw(&_marsh, &rule->index, sizeof(rule->index));
      66            1 :     if (r < 0)
      67              :         return r;
      68              : 
      69              :     {
      70            1 :         _cleanup_bf_marsh_ struct bf_marsh *child = NULL;
      71              : 
      72            1 :         r = bf_list_marsh(&rule->matchers, &child);
      73            1 :         if (r < 0)
      74              :             return r;
      75              : 
      76            1 :         r = bf_marsh_add_child_obj(&_marsh, child);
      77            1 :         if (r)
      78              :             return r;
      79              :     }
      80              : 
      81            1 :     r |= bf_marsh_add_child_raw(&_marsh, &rule->counters,
      82              :                                 sizeof(rule->counters));
      83            1 :     r |= bf_marsh_add_child_raw(&_marsh, &rule->verdict,
      84              :                                 sizeof(enum bf_verdict));
      85            1 :     if (r)
      86            0 :         return bf_err_r(r, "Failed to serialize rule");
      87              : 
      88            1 :     *marsh = TAKE_PTR(_marsh);
      89              : 
      90            1 :     return 0;
      91              : }
      92              : 
      93            3 : int bf_rule_unmarsh(const struct bf_marsh *marsh, struct bf_rule **rule)
      94              : {
      95            1 :     _cleanup_bf_rule_ struct bf_rule *_rule = NULL;
      96              :     struct bf_marsh *rule_elem = NULL;
      97              :     int r;
      98              : 
      99            3 :     bf_assert(marsh);
     100            2 :     bf_assert(rule);
     101              : 
     102            1 :     r = bf_rule_new(&_rule);
     103            1 :     if (r < 0)
     104              :         return r;
     105              : 
     106            1 :     if (!(rule_elem = bf_marsh_next_child(marsh, NULL)))
     107              :         return -EINVAL;
     108            1 :     memcpy(&_rule->index, rule_elem->data, sizeof(_rule->index));
     109              : 
     110            1 :     if (!(rule_elem = bf_marsh_next_child(marsh, rule_elem)))
     111              :         return -EINVAL;
     112              : 
     113              :     {
     114              :         struct bf_marsh *matcher_elem = NULL;
     115              : 
     116           11 :         while ((matcher_elem = bf_marsh_next_child(rule_elem, matcher_elem))) {
     117            0 :             _cleanup_bf_matcher_ struct bf_matcher *matcher = NULL;
     118              : 
     119           10 :             r = bf_matcher_new_from_marsh(&matcher, matcher_elem);
     120           10 :             if (r)
     121              :                 return r;
     122              : 
     123           10 :             r = bf_list_add_tail(&_rule->matchers, matcher);
     124           10 :             if (r)
     125              :                 return r;
     126              : 
     127           10 :             TAKE_PTR(matcher);
     128              :         }
     129              :     }
     130              : 
     131            1 :     if (!(rule_elem = bf_marsh_next_child(marsh, rule_elem)))
     132              :         return -EINVAL;
     133            1 :     memcpy(&_rule->counters, rule_elem->data, sizeof(_rule->counters));
     134              : 
     135            1 :     if (!(rule_elem = bf_marsh_next_child(marsh, rule_elem)))
     136              :         return -EINVAL;
     137            1 :     memcpy(&_rule->verdict, rule_elem->data, sizeof(_rule->verdict));
     138              : 
     139            1 :     if (bf_marsh_next_child(marsh, rule_elem))
     140            0 :         bf_warn("codegen marsh has more children than expected");
     141              : 
     142            1 :     *rule = TAKE_PTR(_rule);
     143              : 
     144            1 :     return 0;
     145              : }
     146              : 
     147            0 : void bf_rule_dump(const struct bf_rule *rule, prefix_t *prefix)
     148              : {
     149            0 :     bf_assert(rule);
     150            0 :     bf_assert(prefix);
     151              : 
     152            0 :     DUMP(prefix, "struct bf_rule at %p", rule);
     153              : 
     154            0 :     bf_dump_prefix_push(prefix);
     155              : 
     156            0 :     DUMP(prefix, "index: %u", rule->index);
     157              : 
     158              :     // Matchers
     159            0 :     DUMP(prefix, "matchers: %lu", bf_list_size(&rule->matchers));
     160            0 :     bf_dump_prefix_push(prefix);
     161            0 :     bf_list_foreach (&rule->matchers, matcher_node) {
     162            0 :         struct bf_matcher *matcher = bf_list_node_get_data(matcher_node);
     163              : 
     164            0 :         if (bf_list_is_tail(&rule->matchers, matcher_node))
     165            0 :             bf_dump_prefix_last(prefix);
     166              : 
     167            0 :         bf_matcher_dump(matcher, prefix);
     168              :     }
     169            0 :     bf_dump_prefix_pop(prefix);
     170              : 
     171            0 :     DUMP(prefix, "counters: %s", rule->counters ? "yes" : "no");
     172            0 :     DUMP(bf_dump_prefix_last(prefix), "verdict: %s",
     173              :          bf_verdict_to_str(rule->verdict));
     174              : 
     175            0 :     bf_dump_prefix_pop(prefix);
     176            0 : }
     177              : 
     178           20 : int bf_rule_add_matcher(struct bf_rule *rule, enum bf_matcher_type type,
     179              :                         enum bf_matcher_op op, const void *payload,
     180              :                         size_t payload_len)
     181              : {
     182           20 :     _cleanup_bf_matcher_ struct bf_matcher *matcher = NULL;
     183              :     int r;
     184              : 
     185           20 :     bf_assert(rule);
     186              : 
     187           20 :     r = bf_matcher_new(&matcher, type, op, payload, payload_len);
     188           20 :     if (r)
     189              :         return r;
     190              : 
     191           20 :     r = bf_list_add_tail(&rule->matchers, matcher);
     192           20 :     if (r)
     193              :         return r;
     194              : 
     195           20 :     TAKE_PTR(matcher);
     196              : 
     197           20 :     return 0;
     198              : }
        

Generated by: LCOV version 2.0-1