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 : #pragma once
7 :
8 : #include <stdbool.h>
9 : #include <stddef.h>
10 : #include <stdint.h>
11 :
12 : #include <bpfilter/dump.h>
13 : #include <bpfilter/list.h>
14 : #include <bpfilter/matcher.h>
15 : #include <bpfilter/pack.h>
16 : #include <bpfilter/runtime.h>
17 : #include <bpfilter/verdict.h>
18 :
19 : #define BF_RULE_MARK_MASK (0x00000000ffffffffULL)
20 :
21 : /**
22 : * @brief Return the string representation of a `bf_pkthdr` enumeration value.
23 : *
24 : * @param hdr `bf_pkthdr` enumeration value.
25 : * @return A pointer to the C-string representation of `hdr`.
26 : */
27 : const char *bf_pkthdr_to_str(enum bf_pkthdr hdr);
28 :
29 : /**
30 : * @brief Return the `bf_pkthdr` enumeration value corresponding to a string.
31 : *
32 : * @pre
33 : * - `str` is a non-NULL pointer to a C-string.
34 : * - `hdr != NULL`
35 : * @post
36 : * - On failure, `hdr` is unchanged.
37 : *
38 : * @param str String to get the corresponding `bf_pkthdr` enumeration value for.
39 : * @param hdr On success, contains the `bf_pkthdr` enumeration value
40 : * corresponding to `str`.
41 : * @return 0 on success, or a negative error value on failure.
42 : */
43 : int bf_pkthdr_from_str(const char *str, enum bf_pkthdr *hdr);
44 :
45 : #define _free_bf_rule_ __attribute__((__cleanup__(bf_rule_free)))
46 :
47 : /**
48 : * @struct bf_rule
49 : *
50 : * Represents a rule to match against packets.
51 : *
52 : * @var bf_rule::index
53 : * Rule's index. Identifies the rule's within other rules from the same front.
54 : */
55 : struct bf_rule
56 : {
57 : uint32_t index;
58 : bf_list matchers;
59 : uint8_t log;
60 :
61 : /** Mark to set to the packet's `sk_buff`. Only support for some hooks.
62 : * The leftmost 32 bits are set to 1 if a mark is defined, or 0 otherwise.
63 : * See `bf_rule_mark_is_set`. */
64 : uint64_t mark;
65 :
66 : bool counters;
67 : enum bf_verdict verdict;
68 : };
69 :
70 : static_assert(
71 : _BF_PKTHDR_MAX < 8,
72 : "bf_pkthdr has more than 8 values, it won't fit in bf_rule.log's 8 bits");
73 :
74 : /**
75 : * Allocated and initialise a new rule.
76 : *
77 : * On failure, @p rule is left unchanged.
78 : *
79 : * @param rule On success, points to the allocated rule. Must be non NULL.
80 : * @return 0 on success, or negative errno value on error.
81 : */
82 : int bf_rule_new(struct bf_rule **rule);
83 :
84 : /**
85 : * @brief Allocate and initialize a new rule from serialized data.
86 : *
87 : * @param rule Rule object to allocate and initialize from the serialized
88 : * data. The caller will own the object. On failure, `*rule` is
89 : * unchanged. Can't be NULL.
90 : * @param node Node containing the serialized rule. Can't be NULL.
91 : * @return 0 on success, or a negative errno value on failure.
92 : */
93 : int bf_rule_new_from_pack(struct bf_rule **rule, bf_rpack_node_t node);
94 :
95 : /**
96 : * Free a rule.
97 : *
98 : * Free @p rule and set it to NULL. If @p rule is NULL, nothing is done.
99 : *
100 : * @param rule Rule to free. Must be non-NULL.
101 : */
102 : void bf_rule_free(struct bf_rule **rule);
103 :
104 : /**
105 : * @brief Serialize a rule.
106 : *
107 : * @param rule Rule to serialize. Can't be NULL.
108 : * @param pack `bf_wpack_t` object to serialize the matcher rule. Can't be NULL.
109 : * @return 0 on success, or a negative error value on failure.
110 : */
111 : int bf_rule_pack(const struct bf_rule *rule, bf_wpack_t *pack);
112 :
113 : /**
114 : * Dump a rule.
115 : *
116 : * @param rule Rule to dump. Must not be NULL.
117 : * @param prefix Prefix for each printed line.
118 : */
119 : void bf_rule_dump(const struct bf_rule *rule, prefix_t *prefix);
120 :
121 : /**
122 : * Create a new matcher and add it to the rule.
123 : *
124 : * @param rule Rule to add the matcher to. Can't be NULL.
125 : * @param type Matcher type.
126 : * @param op Comparison operator.
127 : * @param payload Payload of the matcher, its content and size depends on @p
128 : * type . Can be NULL but only if @p payload_len is 0, in which case
129 : * there is no payload.
130 : * @param payload_len Length of the payload.
131 : * @return 0 on success, or negative errno value on failure.
132 : */
133 : int bf_rule_add_matcher(struct bf_rule *rule, enum bf_matcher_type type,
134 : enum bf_matcher_op op, const void *payload,
135 : size_t payload_len);
136 :
137 : static inline void bf_rule_mark_set(struct bf_rule *rule, uint32_t mark)
138 : {
139 : bf_assert(rule);
140 :
141 : rule->mark = ~BF_RULE_MARK_MASK | mark;
142 : }
143 :
144 0 : static inline uint32_t bf_rule_mark_get(const struct bf_rule *rule)
145 : {
146 0 : bf_assert(rule);
147 :
148 0 : return rule->mark & BF_RULE_MARK_MASK;
149 : }
150 :
151 10 : static inline bool bf_rule_mark_is_set(const struct bf_rule *rule)
152 : {
153 10 : bf_assert(rule);
154 :
155 10 : return rule->mark >> 32;
156 : }
|