diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/cls_api.c | 23 | ||||
-rw-r--r-- | net/sched/cls_cgroup.c | 22 |
2 files changed, 28 insertions, 17 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 0759f32e9dca..09cdcdfe7e91 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -135,6 +135,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
135 | unsigned long cl; | 135 | unsigned long cl; |
136 | unsigned long fh; | 136 | unsigned long fh; |
137 | int err; | 137 | int err; |
138 | int tp_created = 0; | ||
138 | 139 | ||
139 | if (net != &init_net) | 140 | if (net != &init_net) |
140 | return -EINVAL; | 141 | return -EINVAL; |
@@ -266,10 +267,7 @@ replay: | |||
266 | goto errout; | 267 | goto errout; |
267 | } | 268 | } |
268 | 269 | ||
269 | spin_lock_bh(root_lock); | 270 | tp_created = 1; |
270 | tp->next = *back; | ||
271 | *back = tp; | ||
272 | spin_unlock_bh(root_lock); | ||
273 | 271 | ||
274 | } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) | 272 | } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) |
275 | goto errout; | 273 | goto errout; |
@@ -296,8 +294,11 @@ replay: | |||
296 | switch (n->nlmsg_type) { | 294 | switch (n->nlmsg_type) { |
297 | case RTM_NEWTFILTER: | 295 | case RTM_NEWTFILTER: |
298 | err = -EEXIST; | 296 | err = -EEXIST; |
299 | if (n->nlmsg_flags & NLM_F_EXCL) | 297 | if (n->nlmsg_flags & NLM_F_EXCL) { |
298 | if (tp_created) | ||
299 | tcf_destroy(tp); | ||
300 | goto errout; | 300 | goto errout; |
301 | } | ||
301 | break; | 302 | break; |
302 | case RTM_DELTFILTER: | 303 | case RTM_DELTFILTER: |
303 | err = tp->ops->delete(tp, fh); | 304 | err = tp->ops->delete(tp, fh); |
@@ -314,8 +315,18 @@ replay: | |||
314 | } | 315 | } |
315 | 316 | ||
316 | err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh); | 317 | err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh); |
317 | if (err == 0) | 318 | if (err == 0) { |
319 | if (tp_created) { | ||
320 | spin_lock_bh(root_lock); | ||
321 | tp->next = *back; | ||
322 | *back = tp; | ||
323 | spin_unlock_bh(root_lock); | ||
324 | } | ||
318 | tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); | 325 | tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); |
326 | } else { | ||
327 | if (tp_created) | ||
328 | tcf_destroy(tp); | ||
329 | } | ||
319 | 330 | ||
320 | errout: | 331 | errout: |
321 | if (cl) | 332 | if (cl) |
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 1ab4542e61e0..0f815cc6a3db 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -98,8 +98,7 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, | |||
98 | struct tcf_result *res) | 98 | struct tcf_result *res) |
99 | { | 99 | { |
100 | struct cls_cgroup_head *head = tp->root; | 100 | struct cls_cgroup_head *head = tp->root; |
101 | struct cgroup_cls_state *cs; | 101 | u32 classid; |
102 | int ret = 0; | ||
103 | 102 | ||
104 | /* | 103 | /* |
105 | * Due to the nature of the classifier it is required to ignore all | 104 | * Due to the nature of the classifier it is required to ignore all |
@@ -115,17 +114,18 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, | |||
115 | return -1; | 114 | return -1; |
116 | 115 | ||
117 | rcu_read_lock(); | 116 | rcu_read_lock(); |
118 | cs = task_cls_state(current); | 117 | classid = task_cls_state(current)->classid; |
119 | if (cs->classid && tcf_em_tree_match(skb, &head->ematches, NULL)) { | ||
120 | res->classid = cs->classid; | ||
121 | res->class = 0; | ||
122 | ret = tcf_exts_exec(skb, &head->exts, res); | ||
123 | } else | ||
124 | ret = -1; | ||
125 | |||
126 | rcu_read_unlock(); | 118 | rcu_read_unlock(); |
127 | 119 | ||
128 | return ret; | 120 | if (!classid) |
121 | return -1; | ||
122 | |||
123 | if (!tcf_em_tree_match(skb, &head->ematches, NULL)) | ||
124 | return -1; | ||
125 | |||
126 | res->classid = classid; | ||
127 | res->class = 0; | ||
128 | return tcf_exts_exec(skb, &head->exts, res); | ||
129 | } | 129 | } |
130 | 130 | ||
131 | static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle) | 131 | static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle) |