Skip to content

Commit ff7fa21

Browse files
Merge pull request #7 from jschwinger233/gray/cleanup
Use the same offset constants for all packet access mode
2 parents 8c59958 + 36bc294 commit ff7fa21

File tree

4 files changed

+74
-79
lines changed

4 files changed

+74
-79
lines changed

adjust.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package elibpcap
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/cilium/ebpf/asm"
7+
)
8+
9+
const (
10+
// Negative offsets from RFP (Frame Pointer R10)
11+
BpfDataReadOffset StackOffset = -8 * (iota + 1) // -8: Temporary buffer to store data read by bpf_skb_load_bytes
12+
R1LiveSavedOffset // -16: Slot to save the live value of R1 before a helper function call
13+
R2LiveSavedOffset // -24: Slot to save the live value of R2 before a helper function call
14+
R3LiveSavedOffset // -32: Slot to save the live value of R3 before a helper function call
15+
16+
// These slots are used for values that are present at the entry of the cbpfc-generated code block
17+
// or are set up by it. They are saved once at the beginning of the adjusted eBPF code block
18+
// if needed by helper function calls or for restoration.
19+
PacketStartSavedOnStack // -40: Slot to save R4 (data/PacketStart), saved at the beginning of the adjusted eBPF code block.
20+
PacketEndSavedOnStack // -48: Slot to save R5 (data_end/PacketEnd), saved at the beginning of the adjusted eBPF code block.
21+
22+
// Slot to store the original _skb argument (R1) of the eBPF filter function.
23+
SkbPtrOriginalArgSlot // -56: Slot to save the original R1 (_skb pointer).
24+
25+
// AvailableOffset defines the start of the stack space that cbpfc can use (deepest known negative offset).
26+
// cbpfc.EBPFOpts.StackOffset will be calculated based on this.
27+
AvailableOffset // -64 (this value itself is negative, representing the size of the stack frame above cbpfc's own usage)
28+
)
29+
30+
/*
31+
If PacketAccessMode != Direct, We have to adjust the ebpf instructions because verifier prevents us from
32+
directly loading data from memory.
33+
*/
34+
func adjustEbpf(insts asm.Instructions, opts Options) (newInsts asm.Instructions, err error) {
35+
switch opts.PacketAccessMode {
36+
case BpfProbeReadKernel:
37+
insts, err = adjustEbpfWithBpfProbeReadKernel(insts, opts)
38+
if err != nil {
39+
return nil, err
40+
}
41+
break
42+
case BpfSkbLoadBytes:
43+
insts, err = adjustEbpfWithBpfSkbLoadBytes(insts, opts)
44+
if err != nil {
45+
return nil, err
46+
}
47+
break
48+
case Direct:
49+
break
50+
default:
51+
return nil, fmt.Errorf("unsupported packet access mode: %v", opts.PacketAccessMode)
52+
}
53+
54+
return append(insts,
55+
asm.Mov.Imm(asm.R1, 0).WithSymbol(opts.resultLabel()), // r1 = 0 (_skb)
56+
asm.Mov.Imm(asm.R2, 0), // r2 = 0 (__skb)
57+
asm.Mov.Imm(asm.R3, 0), // r3 = 0 (___skb)
58+
asm.Mov.Reg(asm.R4, opts.result()), // r4 = $result (data)
59+
asm.Mov.Imm(asm.R5, 0), // r5 = 0 (data_end)
60+
), nil
61+
}

bpf_probe_read_kernel.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,31 @@ func adjustEbpfWithBpfProbeReadKernel(insts asm.Instructions, opts Options) (new
2929
replaceInsts[idx] = append(replaceInsts[idx],
3030

3131
// Store R1, R2, R3 on stack.
32-
asm.StoreMem(asm.RFP, int16(R1Offset), asm.R1, asm.DWord),
33-
asm.StoreMem(asm.RFP, int16(R2Offset), asm.R2, asm.DWord),
34-
asm.StoreMem(asm.RFP, int16(R3Offset), asm.R3, asm.DWord),
32+
asm.StoreMem(asm.RFP, int16(R1LiveSavedOffset), asm.R1, asm.DWord),
33+
asm.StoreMem(asm.RFP, int16(R2LiveSavedOffset), asm.R2, asm.DWord),
34+
asm.StoreMem(asm.RFP, int16(R3LiveSavedOffset), asm.R3, asm.DWord),
3535

3636
// bpf_probe_read_kernel(RFP-8, size, inst.Src)
3737
asm.Mov.Reg(asm.R1, asm.RFP),
38-
asm.Add.Imm(asm.R1, int32(BpfReadKernelOffset)),
38+
asm.Add.Imm(asm.R1, int32(BpfDataReadOffset)),
3939
asm.Mov.Imm(asm.R2, int32(inst.OpCode.Size().Sizeof())),
4040
asm.Mov.Reg(asm.R3, inst.Src),
4141
asm.Add.Imm(asm.R3, int32(inst.Offset)),
4242
asm.FnProbeReadKernel.Call(),
4343

4444
// inst.Dst = *(RFP-8)
45-
asm.LoadMem(inst.Dst, asm.RFP, int16(BpfReadKernelOffset), inst.OpCode.Size()),
45+
asm.LoadMem(inst.Dst, asm.RFP, int16(BpfDataReadOffset), inst.OpCode.Size()),
4646

4747
// Restore R4, R5 from stack. This is needed because bpf_probe_read_kernel always resets R4 and R5 even if they are not used by bpf_probe_read_kernel.
48-
asm.LoadMem(asm.R4, asm.RFP, int16(R4Offset), asm.DWord),
49-
asm.LoadMem(asm.R5, asm.RFP, int16(R5Offset), asm.DWord),
48+
asm.LoadMem(asm.R4, asm.RFP, int16(PacketStartSavedOnStack), asm.DWord),
49+
asm.LoadMem(asm.R5, asm.RFP, int16(PacketEndSavedOnStack), asm.DWord),
5050
)
5151

5252
// Restore R1, R2, R3 from stack
5353
restoreInsts := asm.Instructions{
54-
asm.LoadMem(asm.R1, asm.RFP, int16(R1Offset), asm.DWord),
55-
asm.LoadMem(asm.R2, asm.RFP, int16(R2Offset), asm.DWord),
56-
asm.LoadMem(asm.R3, asm.RFP, int16(R3Offset), asm.DWord),
54+
asm.LoadMem(asm.R1, asm.RFP, int16(R1LiveSavedOffset), asm.DWord),
55+
asm.LoadMem(asm.R2, asm.RFP, int16(R2LiveSavedOffset), asm.DWord),
56+
asm.LoadMem(asm.R3, asm.RFP, int16(R3LiveSavedOffset), asm.DWord),
5757
}
5858

5959
switch inst.Dst {
@@ -79,8 +79,8 @@ func adjustEbpfWithBpfProbeReadKernel(insts asm.Instructions, opts Options) (new
7979

8080
// Store R4, R5 on stack.
8181
insts = append([]asm.Instruction{
82-
asm.StoreMem(asm.RFP, int16(R4Offset), asm.R4, asm.DWord),
83-
asm.StoreMem(asm.RFP, int16(R5Offset), asm.R5, asm.DWord),
82+
asm.StoreMem(asm.RFP, int16(PacketStartSavedOnStack), asm.R4, asm.DWord),
83+
asm.StoreMem(asm.RFP, int16(PacketEndSavedOnStack), asm.R5, asm.DWord),
8484
}, insts...)
8585
return insts, err
8686
}

bpf_skb_load_bytes.go

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,8 @@ package elibpcap
22

33
import (
44
"fmt"
5-
"github.com/cilium/ebpf/asm"
6-
)
75

8-
const (
9-
// Negative offsets from RFP (Frame Pointer R10)
10-
BpfDataReadOffset StackOffset = -8 * (iota + 1) // -8: Temporary buffer to store data read by bpf_skb_load_bytes
11-
R1LiveSavedOffset // -16: Slot to save the live value of R1 before a helper function call
12-
R2LiveSavedOffset // -24: Slot to save the live value of R2 before a helper function call
13-
R3LiveSavedOffset // -32: Slot to save the live value of R3 before a helper function call
14-
R4LiveSavedOffset // -40: Slot to save the live value of R4 before a helper function call (e.g., saving original R4/PacketStart before R4 is used as 'len' argument)
15-
16-
// These slots are used for values that are present at the entry of the cbpfc-generated code block
17-
// or are set up by it. They are saved once at the beginning of the adjusted eBPF code block
18-
// if needed by helper function calls or for restoration.
19-
PacketStartSavedOnStack // -48: Slot to save R4 (data/PacketStart), saved at the beginning of the adjusted eBPF code block.
20-
PacketEndSavedOnStack // -56: Slot to save R5 (data_end/PacketEnd), saved at the beginning of the adjusted eBPF code block.
21-
22-
// Slot to store the original _skb argument (R1) of the eBPF filter function.
23-
SkbPtrOriginalArgSlot // -64: Slot to save the original R1 (_skb pointer).
24-
25-
// AvailableOffset defines the start of the stack space that cbpfc can use (deepest known negative offset).
26-
// cbpfc.EBPFOpts.StackOffset will be calculated based on this.
27-
AvailableOffset // -72 (this value itself is negative, representing the size of the stack frame above cbpfc's own usage)
6+
"github.com/cilium/ebpf/asm"
287
)
298

309
/*
@@ -83,7 +62,6 @@ func adjustEbpfWithBpfSkbLoadBytes(insts asm.Instructions, opts Options) (newIns
8362
asm.StoreMem(asm.RFP, int16(R1LiveSavedOffset), asm.R1, asm.DWord),
8463
asm.StoreMem(asm.RFP, int16(R2LiveSavedOffset), asm.R2, asm.DWord),
8564
asm.StoreMem(asm.RFP, int16(R3LiveSavedOffset), asm.R3, asm.DWord),
86-
asm.StoreMem(asm.RFP, int16(R4LiveSavedOffset), asm.R4, asm.DWord),
8765
)
8866

8967
// --- Setup arguments for bpf_skb_load_bytes ---
@@ -189,7 +167,6 @@ func adjustEbpfWithBpfSkbLoadBytes(insts asm.Instructions, opts Options) (newIns
189167
if inst.Dst != asm.R3 {
190168
restoreLiveRegs = append(restoreLiveRegs, asm.LoadMem(asm.R3, asm.RFP, int16(R3LiveSavedOffset), asm.DWord))
191169
}
192-
// R4 was restored from PacketStartSavedOnStack, not R4LiveSavedOffset, which is correct.
193170
currentReplacement = append(currentReplacement, restoreLiveRegs...)
194171

195172
currentReplacement[0].Metadata = inst.Metadata

compile.go

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,6 @@ const (
2929

3030
type StackOffset int
3131

32-
const (
33-
BpfReadKernelOffset StackOffset = -8 * (iota + 1)
34-
R1Offset
35-
R2Offset
36-
R3Offset
37-
R4Offset
38-
R5Offset
39-
//AvailableOffset
40-
)
41-
4232
/*
4333
Steps:
4434
1. Compile pcap expresion to cbpf using libpcap
@@ -112,36 +102,3 @@ func CompileCbpf(expr string, l2 bool) (insts []bpf.Instruction, err error) {
112102
}
113103
return
114104
}
115-
116-
/*
117-
If PacketAccessMode != Direct, We have to adjust the ebpf instructions because verifier prevents us from
118-
directly loading data from memory.
119-
*/
120-
func adjustEbpf(insts asm.Instructions, opts Options) (newInsts asm.Instructions, err error) {
121-
switch opts.PacketAccessMode {
122-
case BpfProbeReadKernel:
123-
insts, err = adjustEbpfWithBpfProbeReadKernel(insts, opts)
124-
if err != nil {
125-
return nil, err
126-
}
127-
break
128-
case BpfSkbLoadBytes:
129-
insts, err = adjustEbpfWithBpfSkbLoadBytes(insts, opts)
130-
if err != nil {
131-
return nil, err
132-
}
133-
break
134-
case Direct:
135-
break
136-
default:
137-
return nil, fmt.Errorf("unsupported packet access mode: %v", opts.PacketAccessMode)
138-
}
139-
140-
return append(insts,
141-
asm.Mov.Imm(asm.R1, 0).WithSymbol(opts.resultLabel()), // r1 = 0 (_skb)
142-
asm.Mov.Imm(asm.R2, 0), // r2 = 0 (__skb)
143-
asm.Mov.Imm(asm.R3, 0), // r3 = 0 (___skb)
144-
asm.Mov.Reg(asm.R4, opts.result()), // r4 = $result (data)
145-
asm.Mov.Imm(asm.R5, 0), // r5 = 0 (data_end)
146-
), nil
147-
}

0 commit comments

Comments
 (0)