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 : : #include "cgen/matcher/set.h"
7 : :
8 : : #include <limits.h>
9 : : #include <stdint.h>
10 : :
11 : : #include <bpfilter/chain.h>
12 : : #include <bpfilter/matcher.h>
13 : : #include <bpfilter/set.h>
14 : :
15 : : #include "cgen/matcher/cmp.h"
16 : : #include "cgen/program.h"
17 : : #include "cgen/stub.h"
18 : :
19 : 340 : int bf_set_generate_map_lookup(struct bf_program *program,
20 : : const struct bf_matcher *matcher, int key_offset)
21 : : {
22 : : const struct bf_set *set;
23 : : size_t bit_index;
24 : : int r;
25 : :
26 : : assert(program);
27 : : assert(matcher);
28 : :
29 : 340 : set = bf_chain_get_set_for_matcher(program->runtime.chain, matcher);
30 [ - + ]: 340 : if (!set) {
31 [ # # ]: 0 : return bf_err_r(-ENOENT, "matcher set not found in %s",
32 : : program->runtime.chain->name);
33 : : }
34 : :
35 : 340 : r = bf_program_set_bit_index(program, set, &bit_index);
36 [ - + ]: 340 : if (r) {
37 [ # # # # ]: 0 : return bf_err_r(r, "set '%s' not assigned to any group",
38 : : set->name ?: "<anonymous>");
39 : : }
40 : :
41 [ + - + - ]: 680 : EMIT_LOAD_SET_FD_FIXUP(program, BPF_REG_1, set);
42 [ + - ]: 340 : EMIT(program, BPF_MOV64_REG(BPF_REG_2, BPF_REG_10));
43 [ + - ]: 340 : EMIT(program, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, key_offset));
44 [ + - ]: 340 : EMIT(program, BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem));
45 : :
46 : : /* On lookup miss skip the bitmask byte load; r0 stays 0, which the
47 : : * final cmp-against-0 below treats as "bit not set". */
48 [ + - ]: 340 : EMIT(program, BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2));
49 [ + - ]: 340 : EMIT(program, BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0,
50 : : (int16_t)(bit_index / CHAR_BIT)));
51 [ + - ]: 340 : EMIT(program,
52 : : BPF_ALU32_IMM(BPF_AND, BPF_REG_0, 1U << (bit_index % CHAR_BIT)));
53 : :
54 [ - + ]: 340 : EMIT_FIXUP_JMP_NEXT_RULE(
55 : : program, BPF_JMP_IMM(bf_cmp_get_jmp_ins(matcher), BPF_REG_0, 0, 0));
56 : :
57 : 340 : return 0;
58 : : }
59 : :
60 : 45 : int bf_set_generate_trie_lookup(struct bf_program *program,
61 : : const struct bf_matcher *matcher,
62 : : size_t src_offset, size_t addr_size)
63 : : {
64 : : int r;
65 : :
66 : : assert(program);
67 : : assert(matcher);
68 : :
69 [ + - ]: 45 : EMIT(program, BPF_MOV64_IMM(BPF_REG_1, (uint32_t)(addr_size * 8)));
70 [ + - ]: 45 : EMIT(program,
71 : : BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_1, BF_PROG_SCR_OFF(4)));
72 : :
73 : 45 : r = bf_stub_load(program, src_offset, addr_size, BF_PROG_SCR_OFF(8));
74 [ + - ]: 45 : if (r)
75 : : return r;
76 : :
77 : 45 : return bf_set_generate_map_lookup(program, matcher, BF_PROG_SCR_OFF(4));
78 : : }
|