@@ -24,26 +24,55 @@ const (
24
24
MAXIMUM_SNAPLEN = 262144
25
25
)
26
26
27
- func CompileEbpf (expr string , opts cbpfc.EBPFOpts ) (insts asm.Instructions , err error ) {
28
- cbpfInsts , err := CompileCbpf (expr )
27
+ type StackOffset int
28
+
29
+ const (
30
+ BpfReadKernelOffset StackOffset = - 8 * (iota + 1 ) - 80
31
+ R1Offset
32
+ R2Offset
33
+ R3Offset
34
+ R4Offset
35
+ R5Offset
36
+ AvailableOffset
37
+ )
38
+
39
+ func CompileEbpf (expr string , opts Options ) (insts asm.Instructions , err error ) {
40
+ if expr == "__reject_all__" {
41
+ return asm.Instructions {
42
+ asm .Mov .Reg (asm .R4 , asm .R5 ), // r4 = r5 (data = data_end)
43
+ }, nil
44
+ }
45
+ cbpfInsts , err := CompileCbpf (expr , opts .L2Skb )
29
46
if err != nil {
30
47
return
31
48
}
32
49
33
- ebpfInsts , err := cbpfc .ToEBPF (cbpfInsts , opts )
50
+ ebpfInsts , err := cbpfc .ToEBPF (cbpfInsts , cbpfc.EBPFOpts {
51
+ PacketStart : asm .R4 ,
52
+ PacketEnd : asm .R5 ,
53
+ Result : opts .result (),
54
+ ResultLabel : opts .resultLabel (),
55
+ Working : [4 ]asm.Register {asm .R0 , asm .R1 , asm .R2 , asm .R3 },
56
+ LabelPrefix : opts .labelPrefix (),
57
+ StackOffset : - int (AvailableOffset ),
58
+ })
34
59
if err != nil {
35
60
return
36
61
}
37
62
38
63
return adjustEbpf (ebpfInsts , opts )
39
64
}
40
65
41
- func CompileCbpf (expr string ) (insts []bpf.Instruction , err error ) {
66
+ func CompileCbpf (expr string , l2 bool ) (insts []bpf.Instruction , err error ) {
42
67
if len (expr ) == 0 {
43
68
return
44
69
}
45
70
46
- pcap := C .pcap_open_dead (C .DLT_EN10MB , MAXIMUM_SNAPLEN )
71
+ pcapType := C .DLT_RAW
72
+ if l2 {
73
+ pcapType = C .DLT_EN10MB
74
+ }
75
+ pcap := C .pcap_open_dead (C .int (pcapType ), MAXIMUM_SNAPLEN )
47
76
if pcap == nil {
48
77
return nil , fmt .Errorf ("failed to pcap_open_dead: %+v\n " , C .PCAP_ERROR )
49
78
}
@@ -69,13 +98,64 @@ func CompileCbpf(expr string) (insts []bpf.Instruction, err error) {
69
98
return
70
99
}
71
100
72
- func adjustEbpf (insts asm.Instructions , opts cbpfc.EBPFOpts ) (newInsts asm.Instructions , err error ) {
73
- insts = append (insts ,
74
- asm .Mov .Imm (asm .R1 , 0 ).WithSymbol (opts .ResultLabel ),
101
+ func adjustEbpf (insts asm.Instructions , opts Options ) (newInsts asm.Instructions , err error ) {
102
+ if ! opts .DirectRead {
103
+ replaceIdx := []int {}
104
+ replaceInsts := map [int ]asm.Instructions {}
105
+ for idx , inst := range insts {
106
+ if inst .OpCode .Class ().IsLoad () {
107
+ replaceIdx = append (replaceIdx , idx )
108
+ replaceInsts [idx ] = append (replaceInsts [idx ],
109
+
110
+ asm .StoreMem (asm .RFP , int16 (R1Offset ), asm .R1 , asm .DWord ),
111
+ asm .StoreMem (asm .RFP , int16 (R2Offset ), asm .R2 , asm .DWord ),
112
+ asm .StoreMem (asm .RFP , int16 (R3Offset ), asm .R3 , asm .DWord ),
113
+
114
+ asm .Mov .Reg (asm .R1 , asm .RFP ),
115
+ asm .Add .Imm (asm .R1 , int32 (BpfReadKernelOffset )),
116
+ asm .Mov .Imm (asm .R2 , int32 (inst .OpCode .Size ().Sizeof ())),
117
+ asm .Mov .Reg (asm .R3 , inst .Src ),
118
+ asm .Add .Imm (asm .R3 , int32 (inst .Offset )),
119
+ asm .FnProbeReadKernel .Call (),
120
+
121
+ asm .LoadMem (inst .Dst , asm .RFP , int16 (BpfReadKernelOffset ), inst .OpCode .Size ()),
122
+
123
+ asm .LoadMem (asm .R4 , asm .RFP , int16 (R4Offset ), asm .DWord ),
124
+ asm .LoadMem (asm .R5 , asm .RFP , int16 (R5Offset ), asm .DWord ),
125
+ )
126
+
127
+ restoreInsts := asm.Instructions {
128
+ asm .LoadMem (asm .R1 , asm .RFP , int16 (R1Offset ), asm .DWord ),
129
+ asm .LoadMem (asm .R2 , asm .RFP , int16 (R2Offset ), asm .DWord ),
130
+ asm .LoadMem (asm .R3 , asm .RFP , int16 (R3Offset ), asm .DWord ),
131
+ }
132
+
133
+ switch inst .Dst {
134
+ case asm .R1 , asm .R2 , asm .R3 :
135
+ restoreInsts = append (restoreInsts [:inst .Dst - 1 ], restoreInsts [inst .Dst :]... )
136
+ }
137
+
138
+ replaceInsts [idx ] = append (replaceInsts [idx ], restoreInsts ... )
139
+ replaceInsts [idx ][0 ].Metadata = inst .Metadata
140
+ }
141
+ }
142
+
143
+ for i := len (replaceIdx ) - 1 ; i >= 0 ; i -- {
144
+ idx := replaceIdx [i ]
145
+ insts = append (insts [:idx ], append (replaceInsts [idx ], insts [idx + 1 :]... )... )
146
+ }
147
+
148
+ insts = append ([]asm.Instruction {
149
+ asm .StoreMem (asm .RFP , int16 (R4Offset ), asm .R4 , asm .DWord ),
150
+ asm .StoreMem (asm .RFP , int16 (R5Offset ), asm .R5 , asm .DWord ),
151
+ }, insts ... )
152
+ }
153
+
154
+ return append (insts ,
155
+ asm .Mov .Imm (asm .R1 , 0 ).WithSymbol (opts .resultLabel ()),
75
156
asm .Mov .Imm (asm .R2 , 0 ),
76
157
asm .Mov .Imm (asm .R3 , 0 ),
77
- asm .Mov .Reg (asm .R4 , opts .Result ),
158
+ asm .Mov .Reg (asm .R4 , opts .result () ),
78
159
asm .Mov .Imm (asm .R5 , 0 ),
79
- )
80
- return insts , nil
160
+ ), nil
81
161
}
0 commit comments