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