Branch data 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 : :
68 : : /** If true, skip this rule during flag calculation and code generation. */
69 : : bool disabled;
70 : :
71 : : enum bf_verdict verdict;
72 : :
73 : : /** Target interface index for REDIRECT verdict. 0 if not set. */
74 : : uint32_t redirect_ifindex;
75 : : /** Direction for REDIRECT verdict. */
76 : : enum bf_redirect_dir redirect_dir;
77 : : };
78 : :
79 : : static_assert(
80 : : _BF_PKTHDR_MAX < 8,
81 : : "bf_pkthdr has more than 8 values, it won't fit in bf_rule.log's 8 bits");
82 : :
83 : : /**
84 : : * Allocated and initialise a new rule.
85 : : *
86 : : * On failure, @p rule is left unchanged.
87 : : *
88 : : * @param rule On success, points to the allocated rule. Must be non NULL.
89 : : * @return 0 on success, or negative errno value on error.
90 : : */
91 : : int bf_rule_new(struct bf_rule **rule);
92 : :
93 : : /**
94 : : * @brief Allocate and initialize a new rule from serialized data.
95 : : *
96 : : * @param rule Rule object to allocate and initialize from the serialized
97 : : * data. The caller will own the object. On failure, `*rule` is
98 : : * unchanged. Can't be NULL.
99 : : * @param node Node containing the serialized rule. Can't be NULL.
100 : : * @return 0 on success, or a negative errno value on failure.
101 : : */
102 : : int bf_rule_new_from_pack(struct bf_rule **rule, bf_rpack_node_t node);
103 : :
104 : : /**
105 : : * Free a rule.
106 : : *
107 : : * Free @p rule and set it to NULL. If @p rule is NULL, nothing is done.
108 : : *
109 : : * @param rule Rule to free. Must be non-NULL.
110 : : */
111 : : void bf_rule_free(struct bf_rule **rule);
112 : :
113 : : /**
114 : : * @brief Serialize a rule.
115 : : *
116 : : * @param rule Rule to serialize. Can't be NULL.
117 : : * @param pack `bf_wpack_t` object to serialize the matcher rule. Can't be NULL.
118 : : * @return 0 on success, or a negative error value on failure.
119 : : */
120 : : int bf_rule_pack(const struct bf_rule *rule, bf_wpack_t *pack);
121 : :
122 : : /**
123 : : * Dump a rule.
124 : : *
125 : : * @param rule Rule to dump. Must not be NULL.
126 : : * @param prefix Prefix for each printed line.
127 : : */
128 : : void bf_rule_dump(const struct bf_rule *rule, prefix_t *prefix);
129 : :
130 : : /**
131 : : * Create a new matcher and add it to the rule.
132 : : *
133 : : * @param rule Rule to add the matcher to. Can't be NULL.
134 : : * @param type Matcher type.
135 : : * @param op Comparison operator.
136 : : * @param payload Payload of the matcher, its content and size depends on @p
137 : : * type . Can be NULL but only if @p payload_len is 0, in which case
138 : : * there is no payload.
139 : : * @param payload_len Length of the payload.
140 : : * @return 0 on success, or negative errno value on failure.
141 : : */
142 : : int bf_rule_add_matcher(struct bf_rule *rule, enum bf_matcher_type type,
143 : : enum bf_matcher_op op, const void *payload,
144 : : size_t payload_len);
145 : :
146 : : static inline void bf_rule_mark_set(struct bf_rule *rule, uint32_t mark)
147 : : {
148 : : assert(rule);
149 : :
150 : 12 : rule->mark = ~BF_RULE_MARK_MASK | mark;
151 : 12 : }
152 : :
153 : : static inline uint32_t bf_rule_mark_get(const struct bf_rule *rule)
154 : : {
155 : : assert(rule);
156 : :
157 : 10 : return rule->mark & BF_RULE_MARK_MASK;
158 : : }
159 : :
160 : : static inline bool bf_rule_mark_is_set(const struct bf_rule *rule)
161 : : {
162 : : assert(rule);
163 : :
164 [ + + ]: 1454 : return rule->mark >> 32;
165 : : }
166 : :
167 : : static inline void bf_rule_set_redirect(struct bf_rule *rule, uint32_t ifindex,
168 : : enum bf_redirect_dir dir)
169 : : {
170 : : assert(rule);
171 : :
172 : 12 : rule->redirect_ifindex = ifindex;
173 : 12 : rule->redirect_dir = dir;
174 : 12 : }
175 : :
176 : : static inline bool bf_rule_has_redirect(const struct bf_rule *rule)
177 : : {
178 : : assert(rule);
179 : :
180 [ - + ]: 13 : return rule->redirect_ifindex != 0;
181 : : }
|