@@ -379,7 +379,7 @@ static struct tc_action_ops *tc_lookup_action_id(u32 type)
379379}
380380#endif
381381
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 ,
383383 struct tcf_result * res )
384384{
385385 const struct tc_action * a ;
@@ -390,7 +390,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act,
390390 ret = TC_ACT_OK ;
391391 goto exec_done ;
392392 }
393- while (( a = act ) != NULL ) {
393+ list_for_each_entry ( a , actions , list ) {
394394repeat :
395395 if (a -> ops ) {
396396 ret = a -> ops -> act (skb , a , res );
@@ -404,27 +404,26 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act,
404404 if (ret != TC_ACT_PIPE )
405405 goto exec_done ;
406406 }
407- act = a -> next ;
408407 }
409408exec_done :
410409 return ret ;
411410}
412411EXPORT_SYMBOL (tcf_action_exec );
413412
414- void tcf_action_destroy (struct tc_action * act , int bind )
413+ void tcf_action_destroy (struct list_head * actions , int bind )
415414{
416- struct tc_action * a ;
415+ struct tc_action * a , * tmp ;
417416
418- for ( a = act ; a ; a = act ) {
417+ list_for_each_entry_safe ( a , tmp , actions , list ) {
419418 if (a -> ops ) {
420419 if (a -> ops -> cleanup (a , bind ) == ACT_P_DELETED )
421420 module_put (a -> ops -> owner );
422- act = act -> next ;
421+ list_del ( & a -> list ) ;
423422 kfree (a );
424423 } else {
425424 /*FIXME: Remove later - catch insertion bugs*/
426425 WARN (1 , "tcf_action_destroy: BUG? destroying NULL ops\n" );
427- act = act -> next ;
426+ list_del ( & a -> list ) ;
428427 kfree (a );
429428 }
430429 }
@@ -470,14 +469,13 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
470469EXPORT_SYMBOL (tcf_action_dump_1 );
471470
472471int
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 )
474473{
475474 struct tc_action * a ;
476475 int err = - EINVAL ;
477476 struct nlattr * nest ;
478477
479- while ((a = act ) != NULL ) {
480- act = a -> next ;
478+ list_for_each_entry (a , actions , list ) {
481479 nest = nla_nest_start (skb , a -> order );
482480 if (nest == NULL )
483481 goto nla_put_failure ;
@@ -552,6 +550,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
552550 if (a == NULL )
553551 goto err_mod ;
554552
553+ INIT_LIST_HEAD (& a -> list );
555554 /* backward compatibility for policer */
556555 if (name == NULL )
557556 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,
578577 return ERR_PTR (err );
579578}
580579
581- struct tc_action * tcf_action_init (struct net * net , struct nlattr * nla ,
580+ int tcf_action_init (struct net * net , struct nlattr * nla ,
582581 struct nlattr * est , char * name , int ovr ,
583- int bind )
582+ int bind , struct list_head * actions )
584583{
585584 struct nlattr * tb [TCA_ACT_MAX_PRIO + 1 ];
586- struct tc_action * head = NULL , * act , * act_prev = NULL ;
585+ struct tc_action * act ;
587586 int err ;
588587 int i ;
589588
590589 err = nla_parse_nested (tb , TCA_ACT_MAX_PRIO , nla , NULL );
591590 if (err < 0 )
592- return ERR_PTR ( err ) ;
591+ return err ;
593592
594593 for (i = 1 ; i <= TCA_ACT_MAX_PRIO && tb [i ]; i ++ ) {
595594 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 );
597597 goto err ;
598+ }
598599 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 );
605601 }
606- return head ;
602+ return 0 ;
607603
608604err :
609- if (head != NULL )
610- tcf_action_destroy (head , bind );
611- return act ;
605+ tcf_action_destroy (actions , bind );
606+ return err ;
612607}
613608
614609int 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,
653648}
654649
655650static 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 ,
657652 u16 flags , int event , int bind , int ref )
658653{
659654 struct tcamsg * t ;
@@ -673,7 +668,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 portid, u32 seq,
673668 if (nest == NULL )
674669 goto out_nlmsg_trim ;
675670
676- if (tcf_action_dump (skb , a , bind , ref ) < 0 )
671+ if (tcf_action_dump (skb , actions , bind , ref ) < 0 )
677672 goto out_nlmsg_trim ;
678673
679674 nla_nest_end (skb , nest );
@@ -688,14 +683,14 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 portid, u32 seq,
688683
689684static int
690685act_get_notify (struct net * net , u32 portid , struct nlmsghdr * n ,
691- struct tc_action * a , int event )
686+ struct list_head * actions , int event )
692687{
693688 struct sk_buff * skb ;
694689
695690 skb = alloc_skb (NLMSG_GOODSIZE , GFP_KERNEL );
696691 if (!skb )
697692 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 ) {
699694 kfree_skb (skb );
700695 return - EINVAL ;
701696 }
@@ -726,6 +721,7 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid)
726721 if (a == NULL )
727722 goto err_out ;
728723
724+ INIT_LIST_HEAD (& a -> list );
729725 err = - EINVAL ;
730726 a -> ops = tc_lookup_action (tb [TCA_ACT_KIND ]);
731727 if (a -> ops == NULL )
@@ -745,12 +741,12 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid)
745741 return ERR_PTR (err );
746742}
747743
748- static void cleanup_a (struct tc_action * act )
744+ static void cleanup_a (struct list_head * actions )
749745{
750- struct tc_action * a ;
746+ struct tc_action * a , * tmp ;
751747
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 ) ;
754750 kfree (a );
755751 }
756752}
@@ -765,6 +761,7 @@ static struct tc_action *create_a(int i)
765761 return NULL ;
766762 }
767763 act -> order = i ;
764+ INIT_LIST_HEAD (& act -> list );
768765 return act ;
769766}
770767
@@ -852,7 +849,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
852849{
853850 int i , ret ;
854851 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 );
856854
857855 ret = nla_parse_nested (tb , TCA_ACT_MAX_PRIO , nla , NULL );
858856 if (ret < 0 )
@@ -872,16 +870,11 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
872870 goto err ;
873871 }
874872 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 );
881874 }
882875
883876 if (event == RTM_GETACTION )
884- ret = act_get_notify (net , portid , n , head , event );
877+ ret = act_get_notify (net , portid , n , & actions , event );
885878 else { /* delete */
886879 struct sk_buff * skb ;
887880
@@ -891,27 +884,27 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
891884 goto err ;
892885 }
893886
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 ,
895888 0 , 1 ) <= 0 ) {
896889 kfree_skb (skb );
897890 ret = - EINVAL ;
898891 goto err ;
899892 }
900893
901894 /* now do the delete */
902- tcf_action_destroy (head , 0 );
895+ tcf_action_destroy (& actions , 0 );
903896 ret = rtnetlink_send (skb , net , portid , RTNLGRP_TC ,
904897 n -> nlmsg_flags & NLM_F_ECHO );
905898 if (ret > 0 )
906899 return 0 ;
907900 return ret ;
908901 }
909902err :
910- cleanup_a (head );
903+ cleanup_a (& actions );
911904 return ret ;
912905}
913906
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 ,
915908 u32 portid , u32 seq , int event , u16 flags )
916909{
917910 struct tcamsg * t ;
@@ -939,7 +932,7 @@ static int tcf_add_notify(struct net *net, struct tc_action *a,
939932 if (nest == NULL )
940933 goto out_kfree_skb ;
941934
942- if (tcf_action_dump (skb , a , 0 , 0 ) < 0 )
935+ if (tcf_action_dump (skb , actions , 0 , 0 ) < 0 )
943936 goto out_kfree_skb ;
944937
945938 nla_nest_end (skb , nest );
@@ -963,26 +956,18 @@ tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
963956 u32 portid , int ovr )
964957{
965958 int ret = 0 ;
966- struct tc_action * act ;
967- struct tc_action * a ;
959+ LIST_HEAD (actions );
968960 u32 seq = n -> nlmsg_seq ;
969961
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 )
975964 goto done ;
976- }
977965
978966 /* dump then free all the actions after update; inserted policy
979967 * stays intact
980968 */
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 );
986971done :
987972 return ret ;
988973}
0 commit comments