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 91a3db4a76f8..cc29b44b1500 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -104,8 +104,7 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, | |||
104 | struct tcf_result *res) | 104 | struct tcf_result *res) |
105 | { | 105 | { |
106 | struct cls_cgroup_head *head = tp->root; | 106 | struct cls_cgroup_head *head = tp->root; |
107 | struct cgroup_cls_state *cs; | 107 | u32 classid; |
108 | int ret = 0; | ||
109 | 108 | ||
110 | /* | 109 | /* |
111 | * Due to the nature of the classifier it is required to ignore all | 110 | * Due to the nature of the classifier it is required to ignore all |
@@ -121,17 +120,18 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, | |||
121 | return -1; | 120 | return -1; |
122 | 121 | ||
123 | rcu_read_lock(); | 122 | rcu_read_lock(); |
124 | cs = task_cls_state(current); | 123 | classid = task_cls_state(current)->classid; |
125 | if (cs->classid && tcf_em_tree_match(skb, &head->ematches, NULL)) { | ||
126 | res->classid = cs->classid; | ||
127 | res->class = 0; | ||
128 | ret = tcf_exts_exec(skb, &head->exts, res); | ||
129 | } else | ||
130 | ret = -1; | ||
131 | |||
132 | rcu_read_unlock(); | 124 | rcu_read_unlock(); |
133 | 125 | ||
134 | return ret; | 126 | if (!classid) |
127 | return -1; | ||
128 | |||
129 | if (!tcf_em_tree_match(skb, &head->ematches, NULL)) | ||
130 | return -1; | ||
131 | |||
132 | res->classid = classid; | ||
133 | res->class = 0; | ||
134 | return tcf_exts_exec(skb, &head->exts, res); | ||
135 | } | 135 | } |
136 | 136 | ||
137 | static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle) | 137 | static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle) |