diff options
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r-- | net/sched/act_api.c | 34 |
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 | ||
424 | int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions, | 423 | int 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 | |||
436 | repeat: | 436 | repeat: |
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 | ||
757 | static 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 | |||
767 | static int tca_action_flush(struct net *net, struct nlattr *nla, | 757 | static 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 | } |
907 | err: | 897 | err: |
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); | ||
952 | done: | ||
953 | return ret; | ||
954 | } | 938 | } |
955 | 939 | ||
956 | static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n) | 940 | static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n) |