30
30
31
31
#define FOO "/foo"
32
32
#define BAR "/foo/bar/"
33
- #define PING_CMD "ping -c1 -w1 127.0.0.1"
33
+ #define PING_CMD "ping -c1 -w1 127.0.0.1 > /dev/null "
34
34
35
35
char bpf_log_buf [BPF_LOG_BUF_SIZE ];
36
36
@@ -55,8 +55,7 @@ static int prog_load(int verdict)
55
55
return ret ;
56
56
}
57
57
58
-
59
- int main (int argc , char * * argv )
58
+ static int test_foo_bar (void )
60
59
{
61
60
int drop_prog , allow_prog , foo = 0 , bar = 0 , rc = 0 ;
62
61
@@ -189,8 +188,187 @@ int main(int argc, char **argv)
189
188
close (bar );
190
189
cleanup_cgroup_environment ();
191
190
if (!rc )
192
- printf ("PASS\n" );
191
+ printf ("### override:PASS\n" );
192
+ else
193
+ printf ("### override:FAIL\n" );
194
+ return rc ;
195
+ }
196
+
197
+ static int map_fd = -1 ;
198
+
199
+ static int prog_load_cnt (int verdict , int val )
200
+ {
201
+ if (map_fd < 0 )
202
+ map_fd = bpf_create_map (BPF_MAP_TYPE_ARRAY , 4 , 8 , 1 , 0 );
203
+ if (map_fd < 0 ) {
204
+ printf ("failed to create map '%s'\n" , strerror (errno ));
205
+ return -1 ;
206
+ }
207
+
208
+ struct bpf_insn prog [] = {
209
+ BPF_MOV32_IMM (BPF_REG_0 , 0 ),
210
+ BPF_STX_MEM (BPF_W , BPF_REG_10 , BPF_REG_0 , -4 ), /* *(u32 *)(fp - 4) = r0 */
211
+ BPF_MOV64_REG (BPF_REG_2 , BPF_REG_10 ),
212
+ BPF_ALU64_IMM (BPF_ADD , BPF_REG_2 , -4 ), /* r2 = fp - 4 */
213
+ BPF_LD_MAP_FD (BPF_REG_1 , map_fd ),
214
+ BPF_RAW_INSN (BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ),
215
+ BPF_JMP_IMM (BPF_JEQ , BPF_REG_0 , 0 , 2 ),
216
+ BPF_MOV64_IMM (BPF_REG_1 , val ), /* r1 = 1 */
217
+ BPF_RAW_INSN (BPF_STX | BPF_XADD | BPF_DW , BPF_REG_0 , BPF_REG_1 , 0 , 0 ), /* xadd r0 += r1 */
218
+ BPF_MOV64_IMM (BPF_REG_0 , verdict ), /* r0 = verdict */
219
+ BPF_EXIT_INSN (),
220
+ };
221
+ size_t insns_cnt = sizeof (prog ) / sizeof (struct bpf_insn );
222
+ int ret ;
223
+
224
+ ret = bpf_load_program (BPF_PROG_TYPE_CGROUP_SKB ,
225
+ prog , insns_cnt , "GPL" , 0 ,
226
+ bpf_log_buf , BPF_LOG_BUF_SIZE );
227
+
228
+ if (ret < 0 ) {
229
+ log_err ("Loading program" );
230
+ printf ("Output from verifier:\n%s\n-------\n" , bpf_log_buf );
231
+ return 0 ;
232
+ }
233
+ return ret ;
234
+ }
235
+
236
+
237
+ static int test_multiprog (void )
238
+ {
239
+ int cg1 = 0 , cg2 = 0 , cg3 = 0 , cg4 = 0 , cg5 = 0 , key = 0 ;
240
+ int drop_prog , allow_prog [6 ] = {}, rc = 0 ;
241
+ unsigned long long value ;
242
+ int i = 0 ;
243
+
244
+ for (i = 0 ; i < 6 ; i ++ ) {
245
+ allow_prog [i ] = prog_load_cnt (1 , 1 << i );
246
+ if (!allow_prog [i ])
247
+ goto err ;
248
+ }
249
+ drop_prog = prog_load_cnt (0 , 1 );
250
+ if (!drop_prog )
251
+ goto err ;
252
+
253
+ if (setup_cgroup_environment ())
254
+ goto err ;
255
+
256
+ cg1 = create_and_get_cgroup ("/cg1" );
257
+ if (!cg1 )
258
+ goto err ;
259
+ cg2 = create_and_get_cgroup ("/cg1/cg2" );
260
+ if (!cg2 )
261
+ goto err ;
262
+ cg3 = create_and_get_cgroup ("/cg1/cg2/cg3" );
263
+ if (!cg3 )
264
+ goto err ;
265
+ cg4 = create_and_get_cgroup ("/cg1/cg2/cg3/cg4" );
266
+ if (!cg4 )
267
+ goto err ;
268
+ cg5 = create_and_get_cgroup ("/cg1/cg2/cg3/cg4/cg5" );
269
+ if (!cg5 )
270
+ goto err ;
271
+
272
+ if (join_cgroup ("/cg1/cg2/cg3/cg4/cg5" ))
273
+ goto err ;
274
+
275
+ if (bpf_prog_attach (allow_prog [0 ], cg1 , BPF_CGROUP_INET_EGRESS , 2 )) {
276
+ log_err ("Attaching prog to cg1" );
277
+ goto err ;
278
+ }
279
+ if (!bpf_prog_attach (allow_prog [0 ], cg1 , BPF_CGROUP_INET_EGRESS , 2 )) {
280
+ log_err ("Unexpected success attaching the same prog to cg1" );
281
+ goto err ;
282
+ }
283
+ if (bpf_prog_attach (allow_prog [1 ], cg1 , BPF_CGROUP_INET_EGRESS , 2 )) {
284
+ log_err ("Attaching prog2 to cg1" );
285
+ goto err ;
286
+ }
287
+ if (bpf_prog_attach (allow_prog [2 ], cg2 , BPF_CGROUP_INET_EGRESS , 1 )) {
288
+ log_err ("Attaching prog to cg2" );
289
+ goto err ;
290
+ }
291
+ if (bpf_prog_attach (allow_prog [3 ], cg3 , BPF_CGROUP_INET_EGRESS , 2 )) {
292
+ log_err ("Attaching prog to cg3" );
293
+ goto err ;
294
+ }
295
+ if (bpf_prog_attach (allow_prog [4 ], cg4 , BPF_CGROUP_INET_EGRESS , 1 )) {
296
+ log_err ("Attaching prog to cg4" );
297
+ goto err ;
298
+ }
299
+ if (bpf_prog_attach (allow_prog [5 ], cg5 , BPF_CGROUP_INET_EGRESS , 0 )) {
300
+ log_err ("Attaching prog to cg5" );
301
+ goto err ;
302
+ }
303
+ assert (system (PING_CMD ) == 0 );
304
+ assert (bpf_map_lookup_elem (map_fd , & key , & value ) == 0 );
305
+ assert (value == 1 + 2 + 8 + 32 );
306
+
307
+ /* detach bottom program and ping again */
308
+ if (bpf_prog_detach2 (-1 , cg5 , BPF_CGROUP_INET_EGRESS )) {
309
+ log_err ("Detaching prog from cg5" );
310
+ goto err ;
311
+ }
312
+ value = 0 ;
313
+ assert (bpf_map_update_elem (map_fd , & key , & value , 0 ) == 0 );
314
+ assert (system (PING_CMD ) == 0 );
315
+ assert (bpf_map_lookup_elem (map_fd , & key , & value ) == 0 );
316
+ assert (value == 1 + 2 + 8 + 16 );
317
+
318
+ /* detach 3rd from bottom program and ping again */
319
+ errno = 0 ;
320
+ if (!bpf_prog_detach2 (0 , cg3 , BPF_CGROUP_INET_EGRESS )) {
321
+ log_err ("Unexpected success on detach from cg3" );
322
+ goto err ;
323
+ }
324
+ if (bpf_prog_detach2 (allow_prog [3 ], cg3 , BPF_CGROUP_INET_EGRESS )) {
325
+ log_err ("Detaching from cg3" );
326
+ goto err ;
327
+ }
328
+ value = 0 ;
329
+ assert (bpf_map_update_elem (map_fd , & key , & value , 0 ) == 0 );
330
+ assert (system (PING_CMD ) == 0 );
331
+ assert (bpf_map_lookup_elem (map_fd , & key , & value ) == 0 );
332
+ assert (value == 1 + 2 + 16 );
333
+
334
+ /* detach 2nd from bottom program and ping again */
335
+ if (bpf_prog_detach2 (-1 , cg4 , BPF_CGROUP_INET_EGRESS )) {
336
+ log_err ("Detaching prog from cg4" );
337
+ goto err ;
338
+ }
339
+ value = 0 ;
340
+ assert (bpf_map_update_elem (map_fd , & key , & value , 0 ) == 0 );
341
+ assert (system (PING_CMD ) == 0 );
342
+ assert (bpf_map_lookup_elem (map_fd , & key , & value ) == 0 );
343
+ assert (value == 1 + 2 + 4 );
344
+ goto out ;
345
+ err :
346
+ rc = 1 ;
347
+
348
+ out :
349
+ for (i = 0 ; i < 6 ; i ++ )
350
+ if (allow_prog [i ] > 0 )
351
+ close (allow_prog [i ]);
352
+ close (cg1 );
353
+ close (cg2 );
354
+ close (cg3 );
355
+ close (cg4 );
356
+ close (cg5 );
357
+ cleanup_cgroup_environment ();
358
+ if (!rc )
359
+ printf ("### multi:PASS\n" );
193
360
else
194
- printf ("FAIL\n" );
361
+ printf ("### multi: FAIL\n" );
195
362
return rc ;
196
363
}
364
+
365
+ int main (int argc , char * * argv )
366
+ {
367
+ int rc = 0 ;
368
+
369
+ rc = test_foo_bar ();
370
+ if (rc )
371
+ return rc ;
372
+
373
+ return test_multiprog ();
374
+ }
0 commit comments