s2n_quic_platform/bpf/
common.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4// https://github.com/torvalds/linux/blob/b947cc5bf6d793101135265352e205aeb30b54f0/include/uapi/linux/bpf_common.h#L49
5define!(
6    #[mask(0x08)]
7    pub enum Source {
8        K = 0x00,
9        X = 0x08,
10    }
11);
12
13macro_rules! impl_ld {
14    () => {
15        impl_ld!(ld, ldx, W);
16        impl_ld!(ldb, ldbx, B);
17        impl_ld!(ldh, ldhx, H);
18    };
19    ($ld:ident, $x:ident, $size:ident) => {
20        pub const fn $ld(k: K) -> Instruction {
21            Instruction::raw(
22                k.mode as u16 | Class::LD as u16 | Size::$size as u16,
23                0,
24                0,
25                k.value,
26            )
27        }
28
29        pub const fn $x(k: K) -> Instruction {
30            Instruction::raw(
31                k.mode as u16 | Class::LDX as u16 | Size::$size as u16,
32                0,
33                0,
34                k.value,
35            )
36        }
37    };
38}
39
40macro_rules! impl_alu {
41    () => {
42        impl_alu!(add, add_x, ADD);
43        impl_alu!(sub, sub_x, SUB);
44        impl_alu!(mul, mul_x, MUL);
45        impl_alu!(div, div_x, DIV);
46        impl_alu!(rem, rem_x, MOD);
47        impl_alu!(and, and_x, AND);
48        impl_alu!(or, or_x, OR);
49        impl_alu!(xor, xor_x, XOR);
50        impl_alu!(lsh, lsh_x, LSH);
51        impl_alu!(rsh, rsh_x, RSH);
52    };
53    ($lower:ident, $x:ident, $upper:ident) => {
54        pub const fn $lower(value: u32) -> Instruction {
55            Instruction::raw(
56                Mode::IMM as u16 | Class::ALU as u16 | Source::K as u16 | Alu::$upper as u16,
57                0,
58                0,
59                value,
60            )
61        }
62
63        pub const fn $x() -> Instruction {
64            Instruction::raw(
65                Mode::IMM as u16 | Class::ALU as u16 | Source::X as u16 | Alu::$upper as u16,
66                0,
67                0,
68                0,
69            )
70        }
71    };
72}
73
74macro_rules! impl_jmp {
75    () => {
76        pub const fn ja(value: u32) -> Instruction {
77            Instruction::raw(
78                Class::JMP as u16 | Source::K as u16 | Jump::JA as u16,
79                0,
80                0,
81                value,
82            )
83        }
84
85        impl_jmp!(jgt, jgt_x, JGT, false);
86        impl_jmp!(jle, jle_x, JGT, true);
87        impl_jmp!(jeq, jeq_x, JEQ, false);
88        impl_jmp!(jneq, jneq_x, JEQ, true);
89        impl_jmp!(jset, jset_x, JSET, false);
90    };
91    ($lower:ident, $x:ident, $upper:ident, $invert:expr) => {
92        pub const fn $lower(value: u32, mut jt: u8, mut jf: u8) -> Instruction {
93            if $invert {
94                let tmp = jt;
95                jt = jf;
96                jf = tmp;
97            }
98
99            Instruction::raw(
100                Class::JMP as u16 | Source::K as u16 | Jump::$upper as u16,
101                jt,
102                jf,
103                value,
104            )
105        }
106
107        pub const fn $x(mut jt: u8, mut jf: u8) -> Instruction {
108            if $invert {
109                let tmp = jt;
110                jt = jf;
111                jf = tmp;
112            }
113
114            Instruction::raw(
115                Class::JMP as u16 | Source::X as u16 | Jump::$upper as u16,
116                jt,
117                jf,
118                0,
119            )
120        }
121    };
122}
123
124macro_rules! impl_ret {
125    () => {
126        pub const fn ret(value: u32) -> Instruction {
127            Instruction::raw(Class::RET as u16 | Source::K as u16, 0, 0, value)
128        }
129
130        pub const fn ret_x() -> Instruction {
131            Instruction::raw(Class::RET as u16 | Source::X as u16, 0, 0, 0)
132        }
133
134        pub const fn ret_a() -> Instruction {
135            Instruction::raw(Class::RET as u16 | Size::B as u16, 0, 0, 0)
136        }
137    };
138}
139
140macro_rules! impl_ops {
141    () => {
142        #[derive(Clone, Copy)]
143        pub struct K {
144            pub mode: Mode,
145            pub value: u32,
146        }
147
148        pub const fn abs(value: u32) -> K {
149            K {
150                mode: Mode::ABS,
151                value,
152            }
153        }
154
155        pub const fn imm(value: u32) -> K {
156            K {
157                mode: Mode::IMM,
158                value,
159            }
160        }
161
162        pub const fn ind(value: u32) -> K {
163            K {
164                mode: Mode::IND,
165                value,
166            }
167        }
168
169        impl_ld!();
170        impl_alu!();
171        impl_jmp!();
172        impl_ancillary!();
173    };
174}