LCOV - code coverage report
Current view: top level - core - matcher.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 64.1 % 92 59
Test Date: 2025-02-26 17:59:59 Functions: 63.6 % 11 7

            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/matcher.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/logger.h"
      15              : #include "core/marsh.h"
      16              : 
      17           41 : int bf_matcher_new(struct bf_matcher **matcher, enum bf_matcher_type type,
      18              :                    enum bf_matcher_op op, const void *payload,
      19              :                    size_t payload_len)
      20              : {
      21           39 :     _cleanup_bf_matcher_ struct bf_matcher *_matcher = NULL;
      22              : 
      23           41 :     bf_assert(matcher);
      24           40 :     bf_assert((payload && payload_len) || (!payload && !payload_len));
      25              : 
      26           39 :     _matcher = malloc(sizeof(struct bf_matcher) + payload_len);
      27           39 :     if (!_matcher)
      28              :         return -ENOMEM;
      29              : 
      30           36 :     _matcher->type = type;
      31           36 :     _matcher->op = op;
      32           36 :     _matcher->len = sizeof(struct bf_matcher) + payload_len;
      33           36 :     bf_memcpy(_matcher->payload, payload, payload_len);
      34              : 
      35           36 :     *matcher = TAKE_PTR(_matcher);
      36              : 
      37           36 :     return 0;
      38              : }
      39              : 
      40           14 : int bf_matcher_new_from_marsh(struct bf_matcher **matcher,
      41              :                               const struct bf_marsh *marsh)
      42              : {
      43              :     struct bf_marsh *child = NULL;
      44              :     enum bf_matcher_type type;
      45              :     enum bf_matcher_op op;
      46              :     size_t payload_len;
      47              :     const void *payload;
      48              :     int r;
      49              : 
      50           14 :     bf_assert(matcher);
      51           13 :     bf_assert(marsh);
      52              : 
      53           12 :     if (!(child = bf_marsh_next_child(marsh, child)))
      54              :         return -EINVAL;
      55           12 :     memcpy(&type, child->data, sizeof(type));
      56              : 
      57           12 :     if (!(child = bf_marsh_next_child(marsh, child)))
      58              :         return -EINVAL;
      59           12 :     memcpy(&op, child->data, sizeof(op));
      60              : 
      61           12 :     if (!(child = bf_marsh_next_child(marsh, child)))
      62              :         return -EINVAL;
      63           12 :     memcpy(&payload_len, child->data, sizeof(payload_len));
      64           12 :     payload_len -= sizeof(struct bf_matcher);
      65              : 
      66           12 :     if (!(child = bf_marsh_next_child(marsh, child)))
      67              :         return -EINVAL;
      68           12 :     payload = child->data;
      69              : 
      70           12 :     r = bf_matcher_new(matcher, type, op, payload, payload_len);
      71           12 :     if (r)
      72            1 :         return bf_err_r(r, "failed to restore bf_matcher from serialised data");
      73              : 
      74              :     return 0;
      75              : }
      76              : 
      77          106 : void bf_matcher_free(struct bf_matcher **matcher)
      78              : {
      79          106 :     bf_assert(matcher);
      80              : 
      81          105 :     if (!*matcher)
      82              :         return;
      83              : 
      84           36 :     free(*matcher);
      85           36 :     *matcher = NULL;
      86              : }
      87              : 
      88           15 : int bf_matcher_marsh(const struct bf_matcher *matcher, struct bf_marsh **marsh)
      89              : {
      90           13 :     _cleanup_bf_marsh_ struct bf_marsh *_marsh = NULL;
      91              :     int r;
      92              : 
      93           15 :     bf_assert(matcher);
      94           14 :     bf_assert(marsh);
      95              : 
      96           13 :     r = bf_marsh_new(&_marsh, NULL, 0);
      97           13 :     if (r < 0)
      98              :         return r;
      99              : 
     100           12 :     r |= bf_marsh_add_child_raw(&_marsh, &matcher->type, sizeof(matcher->type));
     101           12 :     r |= bf_marsh_add_child_raw(&_marsh, &matcher->op, sizeof(matcher->op));
     102           12 :     r |= bf_marsh_add_child_raw(&_marsh, &matcher->len, sizeof(matcher->len));
     103           24 :     r |= bf_marsh_add_child_raw(&_marsh, matcher->payload,
     104           12 :                                 matcher->len - sizeof(struct bf_matcher));
     105           12 :     if (r)
     106            0 :         return bf_err_r(r, "failed to serialise bf_matcher object");
     107              : 
     108           12 :     *marsh = TAKE_PTR(_marsh);
     109              : 
     110           12 :     return 0;
     111              : }
     112              : 
     113            0 : void bf_matcher_dump(const struct bf_matcher *matcher, prefix_t *prefix)
     114              : {
     115            0 :     bf_assert(matcher);
     116            0 :     bf_assert(prefix);
     117              : 
     118            0 :     DUMP(prefix, "struct bf_matcher at %p", matcher);
     119              : 
     120            0 :     bf_dump_prefix_push(prefix);
     121              : 
     122            0 :     DUMP(prefix, "type: %s", bf_matcher_type_to_str(matcher->type));
     123            0 :     DUMP(prefix, "op: %s", bf_matcher_op_to_str(matcher->op));
     124            0 :     DUMP(prefix, "len: %ld", matcher->len);
     125            0 :     DUMP(bf_dump_prefix_last(prefix), "payload:");
     126            0 :     bf_dump_prefix_push(prefix);
     127            0 :     bf_dump_hex(prefix, matcher->payload,
     128            0 :                 matcher->len - sizeof(struct bf_matcher));
     129            0 :     bf_dump_prefix_pop(prefix);
     130              : 
     131            0 :     bf_dump_prefix_pop(prefix);
     132            0 : }
     133              : 
     134              : static const char *_bf_matcher_type_strs[] = {
     135              :     [BF_MATCHER_META_IFINDEX] = "meta.ifindex",
     136              :     [BF_MATCHER_META_L3_PROTO] = "meta.l3_proto",
     137              :     [BF_MATCHER_META_L4_PROTO] = "meta.l4_proto",
     138              :     [BF_MATCHER_META_SPORT] = "meta.sport",
     139              :     [BF_MATCHER_META_DPORT] = "meta.dport",
     140              :     [BF_MATCHER_IP4_SRC_ADDR] = "ip4.saddr",
     141              :     [BF_MATCHER_IP4_DST_ADDR] = "ip4.daddr",
     142              :     [BF_MATCHER_IP4_PROTO] = "ip4.proto",
     143              :     [BF_MATCHER_IP6_SADDR] = "ip6.saddr",
     144              :     [BF_MATCHER_IP6_DADDR] = "ip6.daddr",
     145              :     [BF_MATCHER_TCP_SPORT] = "tcp.sport",
     146              :     [BF_MATCHER_TCP_DPORT] = "tcp.dport",
     147              :     [BF_MATCHER_TCP_FLAGS] = "tcp.flags",
     148              :     [BF_MATCHER_UDP_SPORT] = "udp.sport",
     149              :     [BF_MATCHER_UDP_DPORT] = "udp.dport",
     150              :     [BF_MATCHER_SET_SRCIP6PORT] = "set.srcip6port",
     151              :     [BF_MATCHER_SET_SRCIP6] = "set.srcip6",
     152              : };
     153              : 
     154              : static_assert(ARRAY_SIZE(_bf_matcher_type_strs) == _BF_MATCHER_TYPE_MAX,
     155              :               "missing entries in the matcher type array");
     156              : 
     157           19 : const char *bf_matcher_type_to_str(enum bf_matcher_type type)
     158              : {
     159           19 :     bf_assert(0 <= type && type < _BF_MATCHER_TYPE_MAX);
     160              : 
     161           17 :     return _bf_matcher_type_strs[type];
     162              : }
     163              : 
     164           21 : int bf_matcher_type_from_str(const char *str, enum bf_matcher_type *type)
     165              : {
     166           21 :     bf_assert(str);
     167           20 :     bf_assert(type);
     168              : 
     169          189 :     for (size_t i = 0; i < _BF_MATCHER_TYPE_MAX; ++i) {
     170          187 :         if (bf_streq(_bf_matcher_type_strs[i], str)) {
     171           17 :             *type = i;
     172           17 :             return 0;
     173              :         }
     174              :     }
     175              : 
     176              :     return -EINVAL;
     177              : }
     178              : 
     179              : static const char *_bf_matcher_ops_strs[] = {
     180              :     [BF_MATCHER_EQ] = "eq",   [BF_MATCHER_NE] = "not",
     181              :     [BF_MATCHER_ANY] = "any", [BF_MATCHER_ALL] = "all",
     182              :     [BF_MATCHER_IN] = "in",   [BF_MATCHER_RANGE] = "range",
     183              : };
     184              : 
     185              : static_assert(ARRAY_SIZE(_bf_matcher_ops_strs) == _BF_MATCHER_OP_MAX);
     186              : 
     187            8 : const char *bf_matcher_op_to_str(enum bf_matcher_op op)
     188              : {
     189            8 :     bf_assert(0 <= op && op < _BF_MATCHER_OP_MAX);
     190              : 
     191            6 :     return _bf_matcher_ops_strs[op];
     192              : }
     193              : 
     194            0 : int bf_matcher_op_from_str(const char *str, enum bf_matcher_op *op)
     195              : {
     196            0 :     bf_assert(str);
     197            0 :     bf_assert(op);
     198              : 
     199            0 :     for (size_t i = 0; i < _BF_MATCHER_OP_MAX; ++i) {
     200            0 :         if (bf_streq(_bf_matcher_ops_strs[i], str)) {
     201            0 :             *op = i;
     202            0 :             return 0;
     203              :         }
     204              :     }
     205              : 
     206              :     return -EINVAL;
     207              : }
     208              : 
     209              : static const char *_bf_matcher_tcp_flags_strs[] = {
     210              :     [BF_MATCHER_TCP_FLAG_FIN] = "FIN", [BF_MATCHER_TCP_FLAG_SYN] = "SYN",
     211              :     [BF_MATCHER_TCP_FLAG_RST] = "RST", [BF_MATCHER_TCP_FLAG_PSH] = "PSH",
     212              :     [BF_MATCHER_TCP_FLAG_ACK] = "ACK", [BF_MATCHER_TCP_FLAG_URG] = "URG",
     213              :     [BF_MATCHER_TCP_FLAG_ECE] = "ECE", [BF_MATCHER_TCP_FLAG_CWR] = "CWR",
     214              : };
     215              : 
     216            0 : const char *bf_matcher_tcp_flag_to_str(enum bf_matcher_tcp_flag flag)
     217              : {
     218            0 :     bf_assert(0 <= flag && flag < _BF_MATCHER_TCP_FLAG_MAX);
     219              : 
     220            0 :     return _bf_matcher_tcp_flags_strs[flag];
     221              : }
     222              : 
     223            0 : int bf_matcher_tcp_flag_from_str(const char *str,
     224              :                                  enum bf_matcher_tcp_flag *flag)
     225              : {
     226            0 :     bf_assert(str);
     227            0 :     bf_assert(flag);
     228              : 
     229            0 :     for (size_t i = 0; i < _BF_MATCHER_TCP_FLAG_MAX; ++i) {
     230            0 :         if (bf_streq(_bf_matcher_tcp_flags_strs[i], str)) {
     231            0 :             *flag = i;
     232            0 :             return 0;
     233              :         }
     234              :     }
     235              : 
     236              :     return -EINVAL;
     237              : }
        

Generated by: LCOV version 2.0-1