@@ -406,66 +406,19 @@ static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog,
406
406
return 0 ;
407
407
}
408
408
409
- static int cls_bpf_set_parms (struct net * net , struct tcf_proto * tp ,
410
- struct cls_bpf_prog * prog , unsigned long base ,
411
- struct nlattr * * tb , struct nlattr * est , u32 flags ,
412
- struct netlink_ext_ack * extack )
413
- {
414
- bool is_bpf , is_ebpf , have_exts = false;
415
- u32 gen_flags = 0 ;
416
- int ret ;
417
-
418
- is_bpf = tb [TCA_BPF_OPS_LEN ] && tb [TCA_BPF_OPS ];
419
- is_ebpf = tb [TCA_BPF_FD ];
420
- if ((!is_bpf && !is_ebpf ) || (is_bpf && is_ebpf ))
421
- return - EINVAL ;
422
-
423
- ret = tcf_exts_validate (net , tp , tb , est , & prog -> exts , flags ,
424
- extack );
425
- if (ret < 0 )
426
- return ret ;
427
-
428
- if (tb [TCA_BPF_FLAGS ]) {
429
- u32 bpf_flags = nla_get_u32 (tb [TCA_BPF_FLAGS ]);
430
-
431
- if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT )
432
- return - EINVAL ;
433
-
434
- have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT ;
435
- }
436
- if (tb [TCA_BPF_FLAGS_GEN ]) {
437
- gen_flags = nla_get_u32 (tb [TCA_BPF_FLAGS_GEN ]);
438
- if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS ||
439
- !tc_flags_valid (gen_flags ))
440
- return - EINVAL ;
441
- }
442
-
443
- prog -> exts_integrated = have_exts ;
444
- prog -> gen_flags = gen_flags ;
445
-
446
- ret = is_bpf ? cls_bpf_prog_from_ops (tb , prog ) :
447
- cls_bpf_prog_from_efd (tb , prog , gen_flags , tp );
448
- if (ret < 0 )
449
- return ret ;
450
-
451
- if (tb [TCA_BPF_CLASSID ]) {
452
- prog -> res .classid = nla_get_u32 (tb [TCA_BPF_CLASSID ]);
453
- tcf_bind_filter (tp , & prog -> res , base );
454
- }
455
-
456
- return 0 ;
457
- }
458
-
459
409
static int cls_bpf_change (struct net * net , struct sk_buff * in_skb ,
460
410
struct tcf_proto * tp , unsigned long base ,
461
411
u32 handle , struct nlattr * * tca ,
462
412
void * * arg , u32 flags ,
463
413
struct netlink_ext_ack * extack )
464
414
{
465
415
struct cls_bpf_head * head = rtnl_dereference (tp -> root );
416
+ bool is_bpf , is_ebpf , have_exts = false;
466
417
struct cls_bpf_prog * oldprog = * arg ;
467
418
struct nlattr * tb [TCA_BPF_MAX + 1 ];
419
+ bool bound_to_filter = false;
468
420
struct cls_bpf_prog * prog ;
421
+ u32 gen_flags = 0 ;
469
422
int ret ;
470
423
471
424
if (tca [TCA_OPTIONS ] == NULL )
@@ -504,11 +457,51 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
504
457
goto errout ;
505
458
prog -> handle = handle ;
506
459
507
- ret = cls_bpf_set_parms (net , tp , prog , base , tb , tca [TCA_RATE ], flags ,
508
- extack );
460
+ is_bpf = tb [TCA_BPF_OPS_LEN ] && tb [TCA_BPF_OPS ];
461
+ is_ebpf = tb [TCA_BPF_FD ];
462
+ if ((!is_bpf && !is_ebpf ) || (is_bpf && is_ebpf )) {
463
+ ret = - EINVAL ;
464
+ goto errout_idr ;
465
+ }
466
+
467
+ ret = tcf_exts_validate (net , tp , tb , tca [TCA_RATE ], & prog -> exts ,
468
+ flags , extack );
469
+ if (ret < 0 )
470
+ goto errout_idr ;
471
+
472
+ if (tb [TCA_BPF_FLAGS ]) {
473
+ u32 bpf_flags = nla_get_u32 (tb [TCA_BPF_FLAGS ]);
474
+
475
+ if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT ) {
476
+ ret = - EINVAL ;
477
+ goto errout_idr ;
478
+ }
479
+
480
+ have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT ;
481
+ }
482
+ if (tb [TCA_BPF_FLAGS_GEN ]) {
483
+ gen_flags = nla_get_u32 (tb [TCA_BPF_FLAGS_GEN ]);
484
+ if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS ||
485
+ !tc_flags_valid (gen_flags )) {
486
+ ret = - EINVAL ;
487
+ goto errout_idr ;
488
+ }
489
+ }
490
+
491
+ prog -> exts_integrated = have_exts ;
492
+ prog -> gen_flags = gen_flags ;
493
+
494
+ ret = is_bpf ? cls_bpf_prog_from_ops (tb , prog ) :
495
+ cls_bpf_prog_from_efd (tb , prog , gen_flags , tp );
509
496
if (ret < 0 )
510
497
goto errout_idr ;
511
498
499
+ if (tb [TCA_BPF_CLASSID ]) {
500
+ prog -> res .classid = nla_get_u32 (tb [TCA_BPF_CLASSID ]);
501
+ tcf_bind_filter (tp , & prog -> res , base );
502
+ bound_to_filter = true;
503
+ }
504
+
512
505
ret = cls_bpf_offload (tp , prog , oldprog , extack );
513
506
if (ret )
514
507
goto errout_parms ;
@@ -530,6 +523,8 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
530
523
return 0 ;
531
524
532
525
errout_parms :
526
+ if (bound_to_filter )
527
+ tcf_unbind_filter (tp , & prog -> res );
533
528
cls_bpf_free_parms (prog );
534
529
errout_idr :
535
530
if (!oldprog )
0 commit comments