@@ -142,3 +142,118 @@ func TestFilter(t *testing.T) {
142142 })
143143 }
144144}
145+
146+ func TestFilterIPv6 (t * testing.T ) {
147+ RegisterTestingT (t )
148+
149+ _ , _ , _ , _ , bytes , _ := testPacketV6 (
150+ & layers.Ethernet {
151+ SrcMAC : []byte {0 , 0 , 0 , 0 , 0 , 1 },
152+ DstMAC : []byte {0 , 0 , 0 , 0 , 0 , 2 },
153+ EthernetType : layers .EthernetTypeIPv6 ,
154+ },
155+ & layers.IPv6 {
156+ Version : 6 ,
157+ HopLimit : 64 ,
158+ SrcIP : net .IP ([]byte {0x20 , 0x1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 }),
159+ DstIP : net .IP ([]byte {0x20 , 0x1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 }),
160+ NextHeader : layers .IPProtocolUDP ,
161+ },
162+ & layers.UDP {
163+ SrcPort : 1234 ,
164+ DstPort : 666 ,
165+ },
166+ make ([]byte , 36 ),
167+ )
168+
169+ type testCase struct {
170+ expression string
171+ match bool
172+ }
173+
174+ tests := []testCase {
175+ // L2
176+ {"ip" , false },
177+ {"ip6" , true },
178+ {"ip6 and tcp" , false },
179+ // L2 + L3
180+ {"" , true },
181+ {"udp" , true },
182+ {"host 2001::1 or host 2001::5" , true },
183+ {"host 2001::1 and host 2001::5" , false },
184+ {"src 2001::1 and dst 2001::2" , true },
185+ {"dst 2001::1 and src 2001::2" , false },
186+ {"(host 2001::1 or host 2001::5) and (udp port 666)" , true },
187+ {"(host 2001::1 or host 2001::5) and (udp port 1212)" , false },
188+ {"len >= 64" , true },
189+ {"len < 64" , false },
190+ {"len >= 500" , false },
191+ {"portrange 600-700" , true },
192+ {"tcp portrange 600-700" , false },
193+ {"portrange 700-800" , false },
194+ }
195+
196+ links := []struct {
197+ level string
198+ typ layers.LinkType
199+ data []byte
200+ tests []testCase
201+ }{
202+ {"L2" , layers .LinkTypeEthernet , bytes , tests },
203+ {"L3" , layers .LinkTypeIPv6 , bytes [14 :], tests [3 :]},
204+ }
205+
206+ for _ , link := range links {
207+ for _ , tc := range link .tests {
208+ t .Run (link .level + "_" + tc .expression , func (t * testing.T ) {
209+
210+ insns , err := filter .NewStandAlone (link .typ , 64 , tc .expression )
211+ Expect (err ).NotTo (HaveOccurred ())
212+ fd , err := bpf .LoadBPFProgramFromInsns (insns , "filter" , "Apache-2.0" , unix .BPF_PROG_TYPE_SCHED_CLS )
213+ Expect (err ).NotTo (HaveOccurred ())
214+ Expect (fd ).NotTo (BeZero ())
215+ defer func () {
216+ Expect (fd .Close ()).NotTo (HaveOccurred ())
217+ }()
218+
219+ rc , err := bpf .RunBPFProgram (fd , link .data , 1 )
220+ Expect (err ).NotTo (HaveOccurred ())
221+ erc := - 1
222+ if ! tc .match {
223+ erc = 2
224+ }
225+ Expect (rc .RC ).To (BeNumerically ("==" , erc ))
226+ })
227+ }
228+ }
229+
230+ link := links [0 ]
231+
232+ for _ , tc := range link .tests {
233+ if tc .expression == "" {
234+ continue
235+ }
236+
237+ neg := "not ( " + tc .expression + " )"
238+
239+ t .Run (link .level + "_" + neg , func (t * testing.T ) {
240+
241+ insns , err := filter .NewStandAlone (layers .LinkTypeEthernet , 64 , neg )
242+ Expect (err ).NotTo (HaveOccurred ())
243+ fd , err := bpf .LoadBPFProgramFromInsns (insns , "filter" , "Apache-2.0" , unix .BPF_PROG_TYPE_SCHED_CLS )
244+ Expect (err ).NotTo (HaveOccurred ())
245+ Expect (fd ).NotTo (BeZero ())
246+ defer func () {
247+ Expect (fd .Close ()).NotTo (HaveOccurred ())
248+ }()
249+
250+ rc , err := bpf .RunBPFProgram (fd , link .data , 1 )
251+ Expect (err ).NotTo (HaveOccurred ())
252+ erc := 2
253+ if ! tc .match {
254+ erc = - 1
255+ }
256+ Expect (rc .RC ).To (BeNumerically ("==" , erc ))
257+ })
258+ }
259+ }
0 commit comments