@@ -39,6 +39,9 @@ const (
3939
4040 // payload size
4141 structRawPacketEventDataSize = 256
42+
43+ dropStatsKeyStackOffset = int16 (- 8 )
44+ dropStatsValStackOffset = int16 (- 16 )
4245)
4346
4447// ProgOpts defines options
@@ -60,6 +63,7 @@ type ProgOpts struct {
6063 ctxSaveReg asm.Register
6164 tailCallMapFd int
6265 hasGetCurrentCgroupId bool
66+ dropStatsMapFd int
6367}
6468
6569// DefaultProgOpts default options
@@ -97,6 +101,60 @@ func (opts *ProgOpts) WithGetCurrentCgroupID(hasGetCurrentCgroupId bool) *ProgOp
97101 return opts
98102}
99103
104+ // WithDropStatsMapFd sets the map fd used to count dropped packets per filter index.
105+ func (opts * ProgOpts ) WithDropStatsMapFd (fd int ) * ProgOpts {
106+ opts .dropStatsMapFd = fd
107+ return opts
108+ }
109+
110+ func dropStatsIncrementInsts (filterIndex int , dropStatsMapFd int , nextLabel string ) asm.Instructions {
111+ incLabel := fmt .Sprintf ("inc_drop_stat_%d" , filterIndex )
112+ initLabel := fmt .Sprintf ("init_drop_stat_%d" , filterIndex )
113+
114+ return asm.Instructions {
115+ asm .Mov .Reg (asm .R1 , asm .RFP ).WithSymbol (incLabel ),
116+ asm .Add .Imm (asm .R1 , int32 (dropStatsKeyStackOffset )),
117+ asm .Mov .Imm (asm .R2 , int32 (filterIndex )),
118+ asm .StoreMem (asm .R1 , 0 , asm .R2 , asm .DWord ),
119+ asm .StoreImm (asm .R1 , 4 , 0 , asm .DWord ),
120+
121+ asm .LoadMapPtr (asm .R1 , dropStatsMapFd ),
122+ asm .Mov .Reg (asm .R2 , asm .RFP ),
123+ asm .Add .Imm (asm .R2 , int32 (dropStatsKeyStackOffset )),
124+ asm .FnMapLookupElem .Call (),
125+ asm .JEq .Imm (asm .R0 , 0 , initLabel ),
126+
127+ asm .Mov .Reg (asm .R5 , asm .R0 ),
128+ asm .LoadMem (asm .R6 , asm .R5 , 0 , asm .DWord ),
129+ asm .Add .Imm (asm .R6 , 1 ),
130+ asm .StoreMem (asm .R5 , 0 , asm .R6 , asm .DWord ),
131+
132+ asm.Instruction {
133+ OpCode : asm .Ja .Op (asm .ImmSource ),
134+ Constant : 0 ,
135+ }.WithReference (nextLabel ),
136+
137+ asm .Mov .Reg (asm .R3 , asm .RFP ).WithSymbol (initLabel ),
138+ asm .Add .Imm (asm .R3 , int32 (dropStatsValStackOffset )),
139+ asm .Mov .Imm (asm .R4 , 1 ),
140+ asm .StoreMem (asm .R3 , 0 , asm .R4 , asm .DWord ),
141+ asm .StoreImm (asm .R3 , 4 , 0 , asm .DWord ),
142+
143+ asm .LoadMapPtr (asm .R1 , dropStatsMapFd ),
144+ asm .Mov .Reg (asm .R2 , asm .RFP ),
145+ asm .Add .Imm (asm .R2 , int32 (dropStatsKeyStackOffset )),
146+ asm .Mov .Reg (asm .R3 , asm .RFP ),
147+ asm .Add .Imm (asm .R3 , int32 (dropStatsValStackOffset )),
148+ asm .Mov .Imm (asm .R4 , 0 ),
149+ asm .FnMapUpdateElem .Call (),
150+
151+ asm.Instruction {
152+ OpCode : asm .Ja .Op (asm .ImmSource ),
153+ Constant : 0 ,
154+ }.WithReference (nextLabel ),
155+ }
156+ }
157+
100158// FilterToInsts compile a bpf filter expression
101159func FilterToInsts (index int , filter Filter , opts ProgOpts ) (asm.Instructions , error ) {
102160 pcapBPF , err := pcap .CompileBPFFilter (layers .LinkTypeEthernet , 256 , filter .BPFFilter )
@@ -133,6 +191,10 @@ func FilterToInsts(index int, filter Filter, opts ProgOpts) (asm.Instructions, e
133191 }
134192
135193 mismatchLabel := fmt .Sprintf ("mismatch_%d_" , index )
194+ matchLabel := opts .onMatchLabel
195+ if opts .dropStatsMapFd != 0 {
196+ matchLabel = fmt .Sprintf ("inc_drop_stat_%d" , index )
197+ }
136198
137199 if filter .Pid != 0 {
138200 insts = append (insts ,
@@ -142,7 +204,7 @@ func FilterToInsts(index int, filter Filter, opts ProgOpts) (asm.Instructions, e
142204 // check the pid
143205 // load the pid from the packet
144206 asm .LoadMem (asm .R7 , opts .eventPtrReg , structRawPacketEventPidOffset , asm .Word ),
145- asm .JEq .Imm (asm .R7 , int32 (filter .Pid ), opts . onMatchLabel ),
207+ asm .JEq .Imm (asm .R7 , int32 (filter .Pid ), matchLabel ),
146208 asm .Mov .Imm (asm .R4 , 0 ).WithSymbol (mismatchLabel ), // nop instruction, just hold the symbol
147209 )
148210 } else if ! filter .CGroupPathKey .IsNull () {
@@ -169,14 +231,19 @@ func FilterToInsts(index int, filter Filter, opts ProgOpts) (asm.Instructions, e
169231
170232 // check the cgroup id
171233 asm .LoadImm (asm .R4 , int64 (filter .CGroupPathKey .Inode ), asm .DWord ),
172- asm .JEq .Reg (asm .R7 , asm .R4 , opts . onMatchLabel ),
234+ asm .JEq .Reg (asm .R7 , asm .R4 , matchLabel ),
173235 asm .Mov .Imm (asm .R4 , 0 ).WithSymbol (mismatchLabel ), // nop instruction, just hold the symbol
174236 )
175237 } else {
176238 insts = append (insts ,
177- asm .JNE .Imm (cbpfcOpts .Result , 0 , opts . onMatchLabel ).WithSymbol (resultLabel ),
239+ asm .JNE .Imm (cbpfcOpts .Result , 0 , matchLabel ).WithSymbol (resultLabel ),
178240 )
179241 }
242+
243+ if opts .dropStatsMapFd != 0 {
244+ insts = append (insts , dropStatsIncrementInsts (index , opts .dropStatsMapFd , opts .onMatchLabel )... )
245+ }
246+
180247 return insts , nil
181248}
182249
0 commit comments