@@ -379,7 +379,7 @@ static struct tc_action_ops *tc_lookup_action_id(u32 type)
379
379
}
380
380
#endif
381
381
382
- int tcf_action_exec (struct sk_buff * skb , const struct tc_action * act ,
382
+ int tcf_action_exec (struct sk_buff * skb , const struct list_head * actions ,
383
383
struct tcf_result * res )
384
384
{
385
385
const struct tc_action * a ;
@@ -390,7 +390,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act,
390
390
ret = TC_ACT_OK ;
391
391
goto exec_done ;
392
392
}
393
- while (( a = act ) != NULL ) {
393
+ list_for_each_entry ( a , actions , list ) {
394
394
repeat :
395
395
if (a -> ops ) {
396
396
ret = a -> ops -> act (skb , a , res );
@@ -404,27 +404,26 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act,
404
404
if (ret != TC_ACT_PIPE )
405
405
goto exec_done ;
406
406
}
407
- act = a -> next ;
408
407
}
409
408
exec_done :
410
409
return ret ;
411
410
}
412
411
EXPORT_SYMBOL (tcf_action_exec );
413
412
414
- void tcf_action_destroy (struct tc_action * act , int bind )
413
+ void tcf_action_destroy (struct list_head * actions , int bind )
415
414
{
416
- struct tc_action * a ;
415
+ struct tc_action * a , * tmp ;
417
416
418
- for ( a = act ; a ; a = act ) {
417
+ list_for_each_entry_safe ( a , tmp , actions , list ) {
419
418
if (a -> ops ) {
420
419
if (a -> ops -> cleanup (a , bind ) == ACT_P_DELETED )
421
420
module_put (a -> ops -> owner );
422
- act = act -> next ;
421
+ list_del ( & a -> list ) ;
423
422
kfree (a );
424
423
} else {
425
424
/*FIXME: Remove later - catch insertion bugs*/
426
425
WARN (1 , "tcf_action_destroy: BUG? destroying NULL ops\n" );
427
- act = act -> next ;
426
+ list_del ( & a -> list ) ;
428
427
kfree (a );
429
428
}
430
429
}
@@ -470,14 +469,13 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
470
469
EXPORT_SYMBOL (tcf_action_dump_1 );
471
470
472
471
int
473
- tcf_action_dump (struct sk_buff * skb , struct tc_action * act , int bind , int ref )
472
+ tcf_action_dump (struct sk_buff * skb , struct list_head * actions , int bind , int ref )
474
473
{
475
474
struct tc_action * a ;
476
475
int err = - EINVAL ;
477
476
struct nlattr * nest ;
478
477
479
- while ((a = act ) != NULL ) {
480
- act = a -> next ;
478
+ list_for_each_entry (a , actions , list ) {
481
479
nest = nla_nest_start (skb , a -> order );
482
480
if (nest == NULL )
483
481
goto nla_put_failure ;
@@ -552,6 +550,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
552
550
if (a == NULL )
553
551
goto err_mod ;
554
552
553
+ INIT_LIST_HEAD (& a -> list );
555
554
/* backward compatibility for policer */
556
555
if (name == NULL )
557
556
err = a_o -> init (net , tb [TCA_ACT_OPTIONS ], est , a , ovr , bind );
@@ -578,37 +577,33 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
578
577
return ERR_PTR (err );
579
578
}
580
579
581
- struct tc_action * tcf_action_init (struct net * net , struct nlattr * nla ,
580
+ int tcf_action_init (struct net * net , struct nlattr * nla ,
582
581
struct nlattr * est , char * name , int ovr ,
583
- int bind )
582
+ int bind , struct list_head * actions )
584
583
{
585
584
struct nlattr * tb [TCA_ACT_MAX_PRIO + 1 ];
586
- struct tc_action * head = NULL , * act , * act_prev = NULL ;
585
+ struct tc_action * act ;
587
586
int err ;
588
587
int i ;
589
588
590
589
err = nla_parse_nested (tb , TCA_ACT_MAX_PRIO , nla , NULL );
591
590
if (err < 0 )
592
- return ERR_PTR ( err ) ;
591
+ return err ;
593
592
594
593
for (i = 1 ; i <= TCA_ACT_MAX_PRIO && tb [i ]; i ++ ) {
595
594
act = tcf_action_init_1 (net , tb [i ], est , name , ovr , bind );
596
- if (IS_ERR (act ))
595
+ if (IS_ERR (act )) {
596
+ err = PTR_ERR (act );
597
597
goto err ;
598
+ }
598
599
act -> order = i ;
599
-
600
- if (head == NULL )
601
- head = act ;
602
- else
603
- act_prev -> next = act ;
604
- act_prev = act ;
600
+ list_add_tail (& act -> list , actions );
605
601
}
606
- return head ;
602
+ return 0 ;
607
603
608
604
err :
609
- if (head != NULL )
610
- tcf_action_destroy (head , bind );
611
- return act ;
605
+ tcf_action_destroy (actions , bind );
606
+ return err ;
612
607
}
613
608
614
609
int tcf_action_copy_stats (struct sk_buff * skb , struct tc_action * a ,
@@ -653,7 +648,7 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
653
648
}
654
649
655
650
static int
656
- tca_get_fill (struct sk_buff * skb , struct tc_action * a , u32 portid , u32 seq ,
651
+ tca_get_fill (struct sk_buff * skb , struct list_head * actions , u32 portid , u32 seq ,
657
652
u16 flags , int event , int bind , int ref )
658
653
{
659
654
struct tcamsg * t ;
@@ -673,7 +668,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 portid, u32 seq,
673
668
if (nest == NULL )
674
669
goto out_nlmsg_trim ;
675
670
676
- if (tcf_action_dump (skb , a , bind , ref ) < 0 )
671
+ if (tcf_action_dump (skb , actions , bind , ref ) < 0 )
677
672
goto out_nlmsg_trim ;
678
673
679
674
nla_nest_end (skb , nest );
@@ -688,14 +683,14 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 portid, u32 seq,
688
683
689
684
static int
690
685
act_get_notify (struct net * net , u32 portid , struct nlmsghdr * n ,
691
- struct tc_action * a , int event )
686
+ struct list_head * actions , int event )
692
687
{
693
688
struct sk_buff * skb ;
694
689
695
690
skb = alloc_skb (NLMSG_GOODSIZE , GFP_KERNEL );
696
691
if (!skb )
697
692
return - ENOBUFS ;
698
- if (tca_get_fill (skb , a , portid , n -> nlmsg_seq , 0 , event , 0 , 0 ) <= 0 ) {
693
+ if (tca_get_fill (skb , actions , portid , n -> nlmsg_seq , 0 , event , 0 , 0 ) <= 0 ) {
699
694
kfree_skb (skb );
700
695
return - EINVAL ;
701
696
}
@@ -726,6 +721,7 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid)
726
721
if (a == NULL )
727
722
goto err_out ;
728
723
724
+ INIT_LIST_HEAD (& a -> list );
729
725
err = - EINVAL ;
730
726
a -> ops = tc_lookup_action (tb [TCA_ACT_KIND ]);
731
727
if (a -> ops == NULL )
@@ -745,12 +741,12 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid)
745
741
return ERR_PTR (err );
746
742
}
747
743
748
- static void cleanup_a (struct tc_action * act )
744
+ static void cleanup_a (struct list_head * actions )
749
745
{
750
- struct tc_action * a ;
746
+ struct tc_action * a , * tmp ;
751
747
752
- for ( a = act ; a ; a = act ) {
753
- act = a -> next ;
748
+ list_for_each_entry_safe ( a , tmp , actions , list ) {
749
+ list_del ( & a -> list ) ;
754
750
kfree (a );
755
751
}
756
752
}
@@ -765,6 +761,7 @@ static struct tc_action *create_a(int i)
765
761
return NULL ;
766
762
}
767
763
act -> order = i ;
764
+ INIT_LIST_HEAD (& act -> list );
768
765
return act ;
769
766
}
770
767
@@ -852,7 +849,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
852
849
{
853
850
int i , ret ;
854
851
struct nlattr * tb [TCA_ACT_MAX_PRIO + 1 ];
855
- struct tc_action * head = NULL , * act , * act_prev = NULL ;
852
+ struct tc_action * act ;
853
+ LIST_HEAD (actions );
856
854
857
855
ret = nla_parse_nested (tb , TCA_ACT_MAX_PRIO , nla , NULL );
858
856
if (ret < 0 )
@@ -872,16 +870,11 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
872
870
goto err ;
873
871
}
874
872
act -> order = i ;
875
-
876
- if (head == NULL )
877
- head = act ;
878
- else
879
- act_prev -> next = act ;
880
- act_prev = act ;
873
+ list_add_tail (& act -> list , & actions );
881
874
}
882
875
883
876
if (event == RTM_GETACTION )
884
- ret = act_get_notify (net , portid , n , head , event );
877
+ ret = act_get_notify (net , portid , n , & actions , event );
885
878
else { /* delete */
886
879
struct sk_buff * skb ;
887
880
@@ -891,27 +884,27 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
891
884
goto err ;
892
885
}
893
886
894
- if (tca_get_fill (skb , head , portid , n -> nlmsg_seq , 0 , event ,
887
+ if (tca_get_fill (skb , & actions , portid , n -> nlmsg_seq , 0 , event ,
895
888
0 , 1 ) <= 0 ) {
896
889
kfree_skb (skb );
897
890
ret = - EINVAL ;
898
891
goto err ;
899
892
}
900
893
901
894
/* now do the delete */
902
- tcf_action_destroy (head , 0 );
895
+ tcf_action_destroy (& actions , 0 );
903
896
ret = rtnetlink_send (skb , net , portid , RTNLGRP_TC ,
904
897
n -> nlmsg_flags & NLM_F_ECHO );
905
898
if (ret > 0 )
906
899
return 0 ;
907
900
return ret ;
908
901
}
909
902
err :
910
- cleanup_a (head );
903
+ cleanup_a (& actions );
911
904
return ret ;
912
905
}
913
906
914
- static int tcf_add_notify (struct net * net , struct tc_action * a ,
907
+ static int tcf_add_notify (struct net * net , struct list_head * actions ,
915
908
u32 portid , u32 seq , int event , u16 flags )
916
909
{
917
910
struct tcamsg * t ;
@@ -939,7 +932,7 @@ static int tcf_add_notify(struct net *net, struct tc_action *a,
939
932
if (nest == NULL )
940
933
goto out_kfree_skb ;
941
934
942
- if (tcf_action_dump (skb , a , 0 , 0 ) < 0 )
935
+ if (tcf_action_dump (skb , actions , 0 , 0 ) < 0 )
943
936
goto out_kfree_skb ;
944
937
945
938
nla_nest_end (skb , nest );
@@ -963,26 +956,18 @@ tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
963
956
u32 portid , int ovr )
964
957
{
965
958
int ret = 0 ;
966
- struct tc_action * act ;
967
- struct tc_action * a ;
959
+ LIST_HEAD (actions );
968
960
u32 seq = n -> nlmsg_seq ;
969
961
970
- act = tcf_action_init (net , nla , NULL , NULL , ovr , 0 );
971
- if (act == NULL )
972
- goto done ;
973
- if (IS_ERR (act )) {
974
- ret = PTR_ERR (act );
962
+ ret = tcf_action_init (net , nla , NULL , NULL , ovr , 0 , & actions );
963
+ if (ret )
975
964
goto done ;
976
- }
977
965
978
966
/* dump then free all the actions after update; inserted policy
979
967
* stays intact
980
968
*/
981
- ret = tcf_add_notify (net , act , portid , seq , RTM_NEWACTION , n -> nlmsg_flags );
982
- for (a = act ; a ; a = act ) {
983
- act = a -> next ;
984
- kfree (a );
985
- }
969
+ ret = tcf_add_notify (net , & actions , portid , seq , RTM_NEWACTION , n -> nlmsg_flags );
970
+ cleanup_a (& actions );
986
971
done :
987
972
return ret ;
988
973
}
0 commit comments