aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r--net/sched/act_api.c34
1 files changed, 9 insertions, 25 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index e4a5f2607ffa..d09d0687594b 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -64,7 +64,6 @@ int __tcf_hash_release(struct tc_action *p, bool bind, bool strict)
64 if (p->tcfa_bindcnt <= 0 && p->tcfa_refcnt <= 0) { 64 if (p->tcfa_bindcnt <= 0 && p->tcfa_refcnt <= 0) {
65 if (p->ops->cleanup) 65 if (p->ops->cleanup)
66 p->ops->cleanup(p, bind); 66 p->ops->cleanup(p, bind);
67 list_del(&p->list);
68 tcf_hash_destroy(p->hinfo, p); 67 tcf_hash_destroy(p->hinfo, p);
69 ret = ACT_P_DELETED; 68 ret = ACT_P_DELETED;
70 } 69 }
@@ -421,18 +420,19 @@ static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
421 return res; 420 return res;
422} 421}
423 422
424int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions, 423int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
425 struct tcf_result *res) 424 int nr_actions, struct tcf_result *res)
426{ 425{
427 const struct tc_action *a; 426 int ret = -1, i;
428 int ret = -1;
429 427
430 if (skb->tc_verd & TC_NCLS) { 428 if (skb->tc_verd & TC_NCLS) {
431 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); 429 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
432 ret = TC_ACT_OK; 430 ret = TC_ACT_OK;
433 goto exec_done; 431 goto exec_done;
434 } 432 }
435 list_for_each_entry(a, actions, list) { 433 for (i = 0; i < nr_actions; i++) {
434 const struct tc_action *a = actions[i];
435
436repeat: 436repeat:
437 ret = a->ops->act(skb, a, res); 437 ret = a->ops->act(skb, a, res);
438 if (ret == TC_ACT_REPEAT) 438 if (ret == TC_ACT_REPEAT)
@@ -754,16 +754,6 @@ err_out:
754 return ERR_PTR(err); 754 return ERR_PTR(err);
755} 755}
756 756
757static void cleanup_a(struct list_head *actions)
758{
759 struct tc_action *a, *tmp;
760
761 list_for_each_entry_safe(a, tmp, actions, list) {
762 list_del(&a->list);
763 kfree(a);
764 }
765}
766
767static int tca_action_flush(struct net *net, struct nlattr *nla, 757static int tca_action_flush(struct net *net, struct nlattr *nla,
768 struct nlmsghdr *n, u32 portid) 758 struct nlmsghdr *n, u32 portid)
769{ 759{
@@ -905,7 +895,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
905 return ret; 895 return ret;
906 } 896 }
907err: 897err:
908 cleanup_a(&actions); 898 tcf_action_destroy(&actions, 0);
909 return ret; 899 return ret;
910} 900}
911 901
@@ -942,15 +932,9 @@ tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
942 932
943 ret = tcf_action_init(net, nla, NULL, NULL, ovr, 0, &actions); 933 ret = tcf_action_init(net, nla, NULL, NULL, ovr, 0, &actions);
944 if (ret) 934 if (ret)
945 goto done; 935 return ret;
946 936
947 /* dump then free all the actions after update; inserted policy 937 return tcf_add_notify(net, n, &actions, portid);
948 * stays intact
949 */
950 ret = tcf_add_notify(net, n, &actions, portid);
951 cleanup_a(&actions);
952done:
953 return ret;
954} 938}
955 939
956static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n) 940static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n)