libnftnl 1.2.9
nft-expr_bitwise-test.c
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * (C) 2013 by Ana Rey Botello <anarey@gmail.com>
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#include <netinet/in.h>
11#include <netinet/ip.h>
12#include <linux/netfilter/nf_tables.h>
13#include <libmnl/libmnl.h>
14#include <libnftnl/rule.h>
15#include <libnftnl/expr.h>
16
17static int test_ok = 1;
18
19static void print_err(const char *test, const char *msg)
20{
21 test_ok = 0;
22 printf("\033[31mERROR:\e[0m [%s] %s\n", test, msg);
23}
24
25static void cmp_nftnl_expr_mask_xor(struct nftnl_expr *rule_a,
26 struct nftnl_expr *rule_b)
27{
28 uint32_t maska, maskb;
29 uint32_t xora, xorb;
30
31 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_DREG) !=
32 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_DREG))
33 print_err("mask & xor", "Expr BITWISE_DREG mismatches");
34 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG) !=
35 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG))
36 print_err("mask & xor", "Expr BITWISE_SREG mismatches");
37 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_OP) !=
38 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_OP))
39 print_err("mask & xor", "Expr BITWISE_OP mismatches");
40 if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
41 nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
42 print_err("mask & xor", "Expr BITWISE_LEN mismatches");
43 nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_MASK, &maska);
44 nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_MASK, &maskb);
45 if (maska != maskb)
46 print_err("mask & xor", "Size of BITWISE_MASK mismatches");
47 nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_XOR, &xora);
48 nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_XOR, &xorb);
49 if (xora != xorb)
50 print_err("mask & xor", "Size of BITWISE_XOR mismatches");
51}
52
53static void test_mask_xor(void)
54{
55 struct nftnl_rule *a, *b = NULL;
56 struct nftnl_expr *ex = NULL;
57 struct nlmsghdr *nlh;
58 char buf[4096];
59 struct nftnl_expr_iter *iter_a, *iter_b = NULL;
60 struct nftnl_expr *rule_a, *rule_b = NULL;
61 uint32_t mask = 0x01010101;
62 uint32_t xor = 0x12345678;
63
64 a = nftnl_rule_alloc();
65 b = nftnl_rule_alloc();
66 if (a == NULL || b == NULL)
67 print_err("mask & xor", "OOM");
68 ex = nftnl_expr_alloc("bitwise");
69 if (ex == NULL)
70 print_err("mask & xor", "OOM");
71
72 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_SREG, 0x12345678);
73 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
74 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_BOOL);
75 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_LEN, 0x56781234);
76 nftnl_expr_set(ex, NFTNL_EXPR_BITWISE_MASK, &mask, sizeof(mask));
77 nftnl_expr_set(ex, NFTNL_EXPR_BITWISE_XOR, &xor, sizeof(xor));
78
79 nftnl_rule_add_expr(a, ex);
80
81 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
82 nftnl_rule_nlmsg_build_payload(nlh, a);
83
84 if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
85 print_err("mask & xor", "parsing problems");
86
87 iter_a = nftnl_expr_iter_create(a);
88 iter_b = nftnl_expr_iter_create(b);
89 if (iter_a == NULL || iter_b == NULL)
90 print_err("mask & xor", "OOM");
91
92 rule_a = nftnl_expr_iter_next(iter_a);
93 rule_b = nftnl_expr_iter_next(iter_b);
94 if (rule_a == NULL || rule_b == NULL)
95 print_err("mask & xor", "OOM");
96
97 if (nftnl_expr_iter_next(iter_a) != NULL ||
98 nftnl_expr_iter_next(iter_b) != NULL)
99 print_err("mask & xor", "More 1 expr.");
100
101 nftnl_expr_iter_destroy(iter_a);
102 nftnl_expr_iter_destroy(iter_b);
103
104 cmp_nftnl_expr_mask_xor(rule_a,rule_b);
105
106 nftnl_rule_free(a);
107 nftnl_rule_free(b);
108}
109
110static void cmp_nftnl_expr_shift(const char *opname,
111 const struct nftnl_expr *rule_a,
112 const struct nftnl_expr *rule_b)
113{
114 uint32_t data_a, data_b;
115
116 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_DREG) !=
117 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_DREG))
118 print_err(opname, "Expr BITWISE_DREG mismatches");
119 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG) !=
120 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG))
121 print_err(opname, "Expr BITWISE_SREG mismatches");
122 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_OP) !=
123 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_OP))
124 print_err(opname, "Expr BITWISE_OP mismatches");
125 if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
126 nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
127 print_err(opname, "Expr BITWISE_LEN mismatches");
128 nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_DATA, &data_a);
129 nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_DATA, &data_b);
130 if (data_a != data_b)
131 print_err(opname, "Expr BITWISE_DATA mismatches");
132}
133
134static void test_shift(enum nft_bitwise_ops op)
135{
136 struct nftnl_rule *a, *b;
137 struct nftnl_expr *ex;
138 struct nlmsghdr *nlh;
139 char buf[4096];
140 struct nftnl_expr_iter *iter_a, *iter_b;
141 struct nftnl_expr *rule_a, *rule_b;
142 const char *opname = op == NFT_BITWISE_LSHIFT ? "lshift" : "rshift";
143
144 a = nftnl_rule_alloc();
145 b = nftnl_rule_alloc();
146 if (a == NULL || b == NULL)
147 print_err(opname, "OOM");
148 ex = nftnl_expr_alloc("bitwise");
149 if (ex == NULL)
150 print_err(opname, "OOM");
151
152 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_SREG, 0x12345678);
153 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
154 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_OP, op);
155 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_LEN, 0x56781234);
156 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DATA, 13);
157
158 nftnl_rule_add_expr(a, ex);
159
160 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
161 nftnl_rule_nlmsg_build_payload(nlh, a);
162
163 if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
164 print_err(opname, "parsing problems");
165
166 iter_a = nftnl_expr_iter_create(a);
167 iter_b = nftnl_expr_iter_create(b);
168 if (iter_a == NULL || iter_b == NULL)
169 print_err(opname, "OOM");
170
171 rule_a = nftnl_expr_iter_next(iter_a);
172 rule_b = nftnl_expr_iter_next(iter_b);
173 if (rule_a == NULL || rule_b == NULL)
174 print_err(opname, "OOM");
175
176 if (nftnl_expr_iter_next(iter_a) != NULL ||
177 nftnl_expr_iter_next(iter_b) != NULL)
178 print_err(opname, "More 1 expr.");
179
180 nftnl_expr_iter_destroy(iter_a);
181 nftnl_expr_iter_destroy(iter_b);
182
183 cmp_nftnl_expr_shift(opname, rule_a, rule_b);
184
185 nftnl_rule_free(a);
186 nftnl_rule_free(b);
187}
188
189static void test_lshift(void)
190{
191 test_shift(NFT_BITWISE_LSHIFT);
192}
193
194static void test_rshift(void)
195{
196 test_shift(NFT_BITWISE_RSHIFT);
197}
198
199static void cmp_nftnl_expr_bool(const char *opname,
200 const struct nftnl_expr *rule_a,
201 const struct nftnl_expr *rule_b)
202{
203 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_DREG) !=
204 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_DREG))
205 print_err(opname, "Expr BITWISE_DREG mismatches");
206 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG) !=
207 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG))
208 print_err(opname, "Expr BITWISE_SREG mismatches");
209 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG2) !=
210 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG2))
211 print_err(opname, "Expr BITWISE_SREG2 mismatches");
212 if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_OP) !=
213 nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_OP))
214 print_err(opname, "Expr BITWISE_OP mismatches");
215 if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
216 nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
217 print_err(opname, "Expr BITWISE_LEN mismatches");
218}
219
220static void test_bool(enum nft_bitwise_ops op)
221{
222 struct nftnl_rule *a, *b;
223 struct nftnl_expr *ex;
224 struct nlmsghdr *nlh;
225 char buf[4096];
226 struct nftnl_expr_iter *iter_a, *iter_b;
227 struct nftnl_expr *rule_a, *rule_b;
228 const char *opname =
229 op == NFT_BITWISE_AND ? "and" :
230 op == NFT_BITWISE_OR ? "or" : "xor";
231
232 a = nftnl_rule_alloc();
233 b = nftnl_rule_alloc();
234 if (a == NULL || b == NULL)
235 print_err(opname, "OOM");
236 ex = nftnl_expr_alloc("bitwise");
237 if (ex == NULL)
238 print_err(opname, "OOM");
239
240 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_SREG, 0x12345678);
241 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_SREG2, 0x90abcdef);
242 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
243 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_OP, op);
244 nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_LEN, 0x56781234);
245
246 nftnl_rule_add_expr(a, ex);
247
248 nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
249 nftnl_rule_nlmsg_build_payload(nlh, a);
250
251 if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
252 print_err(opname, "parsing problems");
253
254 iter_a = nftnl_expr_iter_create(a);
255 iter_b = nftnl_expr_iter_create(b);
256 if (iter_a == NULL || iter_b == NULL)
257 print_err(opname, "OOM");
258
259 rule_a = nftnl_expr_iter_next(iter_a);
260 rule_b = nftnl_expr_iter_next(iter_b);
261 if (rule_a == NULL || rule_b == NULL)
262 print_err(opname, "OOM");
263
264 if (nftnl_expr_iter_next(iter_a) != NULL ||
265 nftnl_expr_iter_next(iter_b) != NULL)
266 print_err(opname, "More 1 expr.");
267
268 nftnl_expr_iter_destroy(iter_a);
269 nftnl_expr_iter_destroy(iter_b);
270
271 cmp_nftnl_expr_bool(opname, rule_a, rule_b);
272
273 nftnl_rule_free(a);
274 nftnl_rule_free(b);
275}
276
277static void test_and(void)
278{
279 test_bool(NFT_BITWISE_AND);
280}
281
282static void test_or(void)
283{
284 test_bool(NFT_BITWISE_OR);
285}
286
287static void test_xor(void)
288{
289 test_bool(NFT_BITWISE_XOR);
290}
291
292int main(int argc, char *argv[])
293{
294 test_mask_xor();
295 if (!test_ok)
296 exit(EXIT_FAILURE);
297
298 test_lshift();
299 if (!test_ok)
300 exit(EXIT_FAILURE);
301
302 test_rshift();
303 if (!test_ok)
304 exit(EXIT_FAILURE);
305
306 test_and();
307 if (!test_ok)
308 exit(EXIT_FAILURE);
309
310 test_or();
311 if (!test_ok)
312 exit(EXIT_FAILURE);
313
314 test_xor();
315 if (!test_ok)
316 exit(EXIT_FAILURE);
317
318 printf("%s: \033[32mOK\e[0m\n", argv[0]);
319 return EXIT_SUCCESS;
320}