diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/act_api.c | 2 | ||||
-rw-r--r-- | net/sched/act_csum.c | 39 | ||||
-rw-r--r-- | net/sched/act_ipt.c | 33 | ||||
-rw-r--r-- | net/sched/cls_api.c | 14 | ||||
-rw-r--r-- | net/sched/cls_flow.c | 2 | ||||
-rw-r--r-- | net/sched/em_ipset.c | 2 | ||||
-rw-r--r-- | net/sched/sch_api.c | 44 | ||||
-rw-r--r-- | net/sched/sch_htb.c | 31 |
8 files changed, 106 insertions, 61 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 8579c4bb20c9..fd7072827a40 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -982,7 +982,7 @@ done: | |||
982 | return ret; | 982 | return ret; |
983 | } | 983 | } |
984 | 984 | ||
985 | static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 985 | static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n) |
986 | { | 986 | { |
987 | struct net *net = sock_net(skb->sk); | 987 | struct net *net = sock_net(skb->sk); |
988 | struct nlattr *tca[TCA_ACT_MAX + 1]; | 988 | struct nlattr *tca[TCA_ACT_MAX + 1]; |
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 08fa1e8a4ca4..3a4c0caa1f7d 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
@@ -166,15 +166,17 @@ static int tcf_csum_ipv4_igmp(struct sk_buff *skb, | |||
166 | return 1; | 166 | return 1; |
167 | } | 167 | } |
168 | 168 | ||
169 | static int tcf_csum_ipv6_icmp(struct sk_buff *skb, struct ipv6hdr *ip6h, | 169 | static int tcf_csum_ipv6_icmp(struct sk_buff *skb, |
170 | unsigned int ihl, unsigned int ipl) | 170 | unsigned int ihl, unsigned int ipl) |
171 | { | 171 | { |
172 | struct icmp6hdr *icmp6h; | 172 | struct icmp6hdr *icmp6h; |
173 | const struct ipv6hdr *ip6h; | ||
173 | 174 | ||
174 | icmp6h = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmp6h)); | 175 | icmp6h = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmp6h)); |
175 | if (icmp6h == NULL) | 176 | if (icmp6h == NULL) |
176 | return 0; | 177 | return 0; |
177 | 178 | ||
179 | ip6h = ipv6_hdr(skb); | ||
178 | icmp6h->icmp6_cksum = 0; | 180 | icmp6h->icmp6_cksum = 0; |
179 | skb->csum = csum_partial(icmp6h, ipl - ihl, 0); | 181 | skb->csum = csum_partial(icmp6h, ipl - ihl, 0); |
180 | icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, | 182 | icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, |
@@ -186,15 +188,17 @@ static int tcf_csum_ipv6_icmp(struct sk_buff *skb, struct ipv6hdr *ip6h, | |||
186 | return 1; | 188 | return 1; |
187 | } | 189 | } |
188 | 190 | ||
189 | static int tcf_csum_ipv4_tcp(struct sk_buff *skb, struct iphdr *iph, | 191 | static int tcf_csum_ipv4_tcp(struct sk_buff *skb, |
190 | unsigned int ihl, unsigned int ipl) | 192 | unsigned int ihl, unsigned int ipl) |
191 | { | 193 | { |
192 | struct tcphdr *tcph; | 194 | struct tcphdr *tcph; |
195 | const struct iphdr *iph; | ||
193 | 196 | ||
194 | tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph)); | 197 | tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph)); |
195 | if (tcph == NULL) | 198 | if (tcph == NULL) |
196 | return 0; | 199 | return 0; |
197 | 200 | ||
201 | iph = ip_hdr(skb); | ||
198 | tcph->check = 0; | 202 | tcph->check = 0; |
199 | skb->csum = csum_partial(tcph, ipl - ihl, 0); | 203 | skb->csum = csum_partial(tcph, ipl - ihl, 0); |
200 | tcph->check = tcp_v4_check(ipl - ihl, | 204 | tcph->check = tcp_v4_check(ipl - ihl, |
@@ -205,15 +209,17 @@ static int tcf_csum_ipv4_tcp(struct sk_buff *skb, struct iphdr *iph, | |||
205 | return 1; | 209 | return 1; |
206 | } | 210 | } |
207 | 211 | ||
208 | static int tcf_csum_ipv6_tcp(struct sk_buff *skb, struct ipv6hdr *ip6h, | 212 | static int tcf_csum_ipv6_tcp(struct sk_buff *skb, |
209 | unsigned int ihl, unsigned int ipl) | 213 | unsigned int ihl, unsigned int ipl) |
210 | { | 214 | { |
211 | struct tcphdr *tcph; | 215 | struct tcphdr *tcph; |
216 | const struct ipv6hdr *ip6h; | ||
212 | 217 | ||
213 | tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph)); | 218 | tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph)); |
214 | if (tcph == NULL) | 219 | if (tcph == NULL) |
215 | return 0; | 220 | return 0; |
216 | 221 | ||
222 | ip6h = ipv6_hdr(skb); | ||
217 | tcph->check = 0; | 223 | tcph->check = 0; |
218 | skb->csum = csum_partial(tcph, ipl - ihl, 0); | 224 | skb->csum = csum_partial(tcph, ipl - ihl, 0); |
219 | tcph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, | 225 | tcph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, |
@@ -225,10 +231,11 @@ static int tcf_csum_ipv6_tcp(struct sk_buff *skb, struct ipv6hdr *ip6h, | |||
225 | return 1; | 231 | return 1; |
226 | } | 232 | } |
227 | 233 | ||
228 | static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph, | 234 | static int tcf_csum_ipv4_udp(struct sk_buff *skb, |
229 | unsigned int ihl, unsigned int ipl, int udplite) | 235 | unsigned int ihl, unsigned int ipl, int udplite) |
230 | { | 236 | { |
231 | struct udphdr *udph; | 237 | struct udphdr *udph; |
238 | const struct iphdr *iph; | ||
232 | u16 ul; | 239 | u16 ul; |
233 | 240 | ||
234 | /* | 241 | /* |
@@ -242,6 +249,7 @@ static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph, | |||
242 | if (udph == NULL) | 249 | if (udph == NULL) |
243 | return 0; | 250 | return 0; |
244 | 251 | ||
252 | iph = ip_hdr(skb); | ||
245 | ul = ntohs(udph->len); | 253 | ul = ntohs(udph->len); |
246 | 254 | ||
247 | if (udplite || udph->check) { | 255 | if (udplite || udph->check) { |
@@ -276,10 +284,11 @@ ignore_obscure_skb: | |||
276 | return 1; | 284 | return 1; |
277 | } | 285 | } |
278 | 286 | ||
279 | static int tcf_csum_ipv6_udp(struct sk_buff *skb, struct ipv6hdr *ip6h, | 287 | static int tcf_csum_ipv6_udp(struct sk_buff *skb, |
280 | unsigned int ihl, unsigned int ipl, int udplite) | 288 | unsigned int ihl, unsigned int ipl, int udplite) |
281 | { | 289 | { |
282 | struct udphdr *udph; | 290 | struct udphdr *udph; |
291 | const struct ipv6hdr *ip6h; | ||
283 | u16 ul; | 292 | u16 ul; |
284 | 293 | ||
285 | /* | 294 | /* |
@@ -293,6 +302,7 @@ static int tcf_csum_ipv6_udp(struct sk_buff *skb, struct ipv6hdr *ip6h, | |||
293 | if (udph == NULL) | 302 | if (udph == NULL) |
294 | return 0; | 303 | return 0; |
295 | 304 | ||
305 | ip6h = ipv6_hdr(skb); | ||
296 | ul = ntohs(udph->len); | 306 | ul = ntohs(udph->len); |
297 | 307 | ||
298 | udph->check = 0; | 308 | udph->check = 0; |
@@ -328,7 +338,7 @@ ignore_obscure_skb: | |||
328 | 338 | ||
329 | static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags) | 339 | static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags) |
330 | { | 340 | { |
331 | struct iphdr *iph; | 341 | const struct iphdr *iph; |
332 | int ntkoff; | 342 | int ntkoff; |
333 | 343 | ||
334 | ntkoff = skb_network_offset(skb); | 344 | ntkoff = skb_network_offset(skb); |
@@ -353,19 +363,19 @@ static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags) | |||
353 | break; | 363 | break; |
354 | case IPPROTO_TCP: | 364 | case IPPROTO_TCP: |
355 | if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) | 365 | if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) |
356 | if (!tcf_csum_ipv4_tcp(skb, iph, iph->ihl * 4, | 366 | if (!tcf_csum_ipv4_tcp(skb, iph->ihl * 4, |
357 | ntohs(iph->tot_len))) | 367 | ntohs(iph->tot_len))) |
358 | goto fail; | 368 | goto fail; |
359 | break; | 369 | break; |
360 | case IPPROTO_UDP: | 370 | case IPPROTO_UDP: |
361 | if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) | 371 | if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) |
362 | if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4, | 372 | if (!tcf_csum_ipv4_udp(skb, iph->ihl * 4, |
363 | ntohs(iph->tot_len), 0)) | 373 | ntohs(iph->tot_len), 0)) |
364 | goto fail; | 374 | goto fail; |
365 | break; | 375 | break; |
366 | case IPPROTO_UDPLITE: | 376 | case IPPROTO_UDPLITE: |
367 | if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) | 377 | if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) |
368 | if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4, | 378 | if (!tcf_csum_ipv4_udp(skb, iph->ihl * 4, |
369 | ntohs(iph->tot_len), 1)) | 379 | ntohs(iph->tot_len), 1)) |
370 | goto fail; | 380 | goto fail; |
371 | break; | 381 | break; |
@@ -377,7 +387,7 @@ static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags) | |||
377 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) | 387 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) |
378 | goto fail; | 388 | goto fail; |
379 | 389 | ||
380 | ip_send_check(iph); | 390 | ip_send_check(ip_hdr(skb)); |
381 | } | 391 | } |
382 | 392 | ||
383 | return 1; | 393 | return 1; |
@@ -456,6 +466,7 @@ static int tcf_csum_ipv6(struct sk_buff *skb, u32 update_flags) | |||
456 | ixhl = ipv6_optlen(ip6xh); | 466 | ixhl = ipv6_optlen(ip6xh); |
457 | if (!pskb_may_pull(skb, hl + ixhl + ntkoff)) | 467 | if (!pskb_may_pull(skb, hl + ixhl + ntkoff)) |
458 | goto fail; | 468 | goto fail; |
469 | ip6xh = (void *)(skb_network_header(skb) + hl); | ||
459 | if ((nexthdr == NEXTHDR_HOP) && | 470 | if ((nexthdr == NEXTHDR_HOP) && |
460 | !(tcf_csum_ipv6_hopopts(ip6xh, ixhl, &pl))) | 471 | !(tcf_csum_ipv6_hopopts(ip6xh, ixhl, &pl))) |
461 | goto fail; | 472 | goto fail; |
@@ -464,25 +475,25 @@ static int tcf_csum_ipv6(struct sk_buff *skb, u32 update_flags) | |||
464 | break; | 475 | break; |
465 | case IPPROTO_ICMPV6: | 476 | case IPPROTO_ICMPV6: |
466 | if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP) | 477 | if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP) |
467 | if (!tcf_csum_ipv6_icmp(skb, ip6h, | 478 | if (!tcf_csum_ipv6_icmp(skb, |
468 | hl, pl + sizeof(*ip6h))) | 479 | hl, pl + sizeof(*ip6h))) |
469 | goto fail; | 480 | goto fail; |
470 | goto done; | 481 | goto done; |
471 | case IPPROTO_TCP: | 482 | case IPPROTO_TCP: |
472 | if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) | 483 | if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) |
473 | if (!tcf_csum_ipv6_tcp(skb, ip6h, | 484 | if (!tcf_csum_ipv6_tcp(skb, |
474 | hl, pl + sizeof(*ip6h))) | 485 | hl, pl + sizeof(*ip6h))) |
475 | goto fail; | 486 | goto fail; |
476 | goto done; | 487 | goto done; |
477 | case IPPROTO_UDP: | 488 | case IPPROTO_UDP: |
478 | if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) | 489 | if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) |
479 | if (!tcf_csum_ipv6_udp(skb, ip6h, hl, | 490 | if (!tcf_csum_ipv6_udp(skb, hl, |
480 | pl + sizeof(*ip6h), 0)) | 491 | pl + sizeof(*ip6h), 0)) |
481 | goto fail; | 492 | goto fail; |
482 | goto done; | 493 | goto done; |
483 | case IPPROTO_UDPLITE: | 494 | case IPPROTO_UDPLITE: |
484 | if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) | 495 | if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) |
485 | if (!tcf_csum_ipv6_udp(skb, ip6h, hl, | 496 | if (!tcf_csum_ipv6_udp(skb, hl, |
486 | pl + sizeof(*ip6h), 1)) | 497 | pl + sizeof(*ip6h), 1)) |
487 | goto fail; | 498 | goto fail; |
488 | goto done; | 499 | goto done; |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index e0f6de64afec..60d88b6b9560 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | * Copyright: Jamal Hadi Salim (2002-4) | 11 | * Copyright: Jamal Hadi Salim (2002-13) |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
@@ -303,17 +303,44 @@ static struct tc_action_ops act_ipt_ops = { | |||
303 | .walk = tcf_generic_walker | 303 | .walk = tcf_generic_walker |
304 | }; | 304 | }; |
305 | 305 | ||
306 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); | 306 | static struct tc_action_ops act_xt_ops = { |
307 | .kind = "xt", | ||
308 | .hinfo = &ipt_hash_info, | ||
309 | .type = TCA_ACT_IPT, | ||
310 | .capab = TCA_CAP_NONE, | ||
311 | .owner = THIS_MODULE, | ||
312 | .act = tcf_ipt, | ||
313 | .dump = tcf_ipt_dump, | ||
314 | .cleanup = tcf_ipt_cleanup, | ||
315 | .lookup = tcf_hash_search, | ||
316 | .init = tcf_ipt_init, | ||
317 | .walk = tcf_generic_walker | ||
318 | }; | ||
319 | |||
320 | MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); | ||
307 | MODULE_DESCRIPTION("Iptables target actions"); | 321 | MODULE_DESCRIPTION("Iptables target actions"); |
308 | MODULE_LICENSE("GPL"); | 322 | MODULE_LICENSE("GPL"); |
323 | MODULE_ALIAS("act_xt"); | ||
309 | 324 | ||
310 | static int __init ipt_init_module(void) | 325 | static int __init ipt_init_module(void) |
311 | { | 326 | { |
312 | return tcf_register_action(&act_ipt_ops); | 327 | int ret1, ret2; |
328 | ret1 = tcf_register_action(&act_xt_ops); | ||
329 | if (ret1 < 0) | ||
330 | printk("Failed to load xt action\n"); | ||
331 | ret2 = tcf_register_action(&act_ipt_ops); | ||
332 | if (ret2 < 0) | ||
333 | printk("Failed to load ipt action\n"); | ||
334 | |||
335 | if (ret1 < 0 && ret2 < 0) | ||
336 | return ret1; | ||
337 | else | ||
338 | return 0; | ||
313 | } | 339 | } |
314 | 340 | ||
315 | static void __exit ipt_cleanup_module(void) | 341 | static void __exit ipt_cleanup_module(void) |
316 | { | 342 | { |
343 | tcf_unregister_action(&act_xt_ops); | ||
317 | tcf_unregister_action(&act_ipt_ops); | 344 | tcf_unregister_action(&act_ipt_ops); |
318 | } | 345 | } |
319 | 346 | ||
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 964f5e4f4b8a..8e118af90973 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/skbuff.h> | 22 | #include <linux/skbuff.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/kmod.h> | 24 | #include <linux/kmod.h> |
25 | #include <linux/netlink.h> | ||
26 | #include <linux/err.h> | 25 | #include <linux/err.h> |
27 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
28 | #include <net/net_namespace.h> | 27 | #include <net/net_namespace.h> |
@@ -118,7 +117,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp) | |||
118 | 117 | ||
119 | /* Add/change/delete/get a filter node */ | 118 | /* Add/change/delete/get a filter node */ |
120 | 119 | ||
121 | static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 120 | static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n) |
122 | { | 121 | { |
123 | struct net *net = sock_net(skb->sk); | 122 | struct net *net = sock_net(skb->sk); |
124 | struct nlattr *tca[TCA_MAX + 1]; | 123 | struct nlattr *tca[TCA_MAX + 1]; |
@@ -141,7 +140,12 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
141 | 140 | ||
142 | if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN)) | 141 | if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN)) |
143 | return -EPERM; | 142 | return -EPERM; |
143 | |||
144 | replay: | 144 | replay: |
145 | err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL); | ||
146 | if (err < 0) | ||
147 | return err; | ||
148 | |||
145 | t = nlmsg_data(n); | 149 | t = nlmsg_data(n); |
146 | protocol = TC_H_MIN(t->tcm_info); | 150 | protocol = TC_H_MIN(t->tcm_info); |
147 | prio = TC_H_MAJ(t->tcm_info); | 151 | prio = TC_H_MAJ(t->tcm_info); |
@@ -164,10 +168,6 @@ replay: | |||
164 | if (dev == NULL) | 168 | if (dev == NULL) |
165 | return -ENODEV; | 169 | return -ENODEV; |
166 | 170 | ||
167 | err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL); | ||
168 | if (err < 0) | ||
169 | return err; | ||
170 | |||
171 | /* Find qdisc */ | 171 | /* Find qdisc */ |
172 | if (!parent) { | 172 | if (!parent) { |
173 | q = dev->qdisc; | 173 | q = dev->qdisc; |
@@ -427,7 +427,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) | |||
427 | const struct Qdisc_class_ops *cops; | 427 | const struct Qdisc_class_ops *cops; |
428 | struct tcf_dump_args arg; | 428 | struct tcf_dump_args arg; |
429 | 429 | ||
430 | if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) | 430 | if (nlmsg_len(cb->nlh) < sizeof(*tcm)) |
431 | return skb->len; | 431 | return skb->len; |
432 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | 432 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); |
433 | if (!dev) | 433 | if (!dev) |
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index aa36a8c8b33b..7881e2fccbc2 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c | |||
@@ -393,7 +393,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, | |||
393 | return -EOPNOTSUPP; | 393 | return -EOPNOTSUPP; |
394 | 394 | ||
395 | if ((keymask & (FLOW_KEY_SKUID|FLOW_KEY_SKGID)) && | 395 | if ((keymask & (FLOW_KEY_SKUID|FLOW_KEY_SKGID)) && |
396 | sk_user_ns(NETLINK_CB(in_skb).ssk) != &init_user_ns) | 396 | sk_user_ns(NETLINK_CB(in_skb).sk) != &init_user_ns) |
397 | return -EOPNOTSUPP; | 397 | return -EOPNOTSUPP; |
398 | } | 398 | } |
399 | 399 | ||
diff --git a/net/sched/em_ipset.c b/net/sched/em_ipset.c index 3130320997e2..938b7cbf5627 100644 --- a/net/sched/em_ipset.c +++ b/net/sched/em_ipset.c | |||
@@ -83,7 +83,7 @@ static int em_ipset_match(struct sk_buff *skb, struct tcf_ematch *em, | |||
83 | opt.dim = set->dim; | 83 | opt.dim = set->dim; |
84 | opt.flags = set->flags; | 84 | opt.flags = set->flags; |
85 | opt.cmdflags = 0; | 85 | opt.cmdflags = 0; |
86 | opt.timeout = ~0u; | 86 | opt.ext.timeout = ~0u; |
87 | 87 | ||
88 | network_offset = skb_network_offset(skb); | 88 | network_offset = skb_network_offset(skb); |
89 | skb_pull(skb, network_offset); | 89 | skb_pull(skb, network_offset); |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index c297e2a8e2a1..2b935e7cfe7b 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -971,13 +971,13 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w) | |||
971 | * Delete/get qdisc. | 971 | * Delete/get qdisc. |
972 | */ | 972 | */ |
973 | 973 | ||
974 | static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 974 | static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n) |
975 | { | 975 | { |
976 | struct net *net = sock_net(skb->sk); | 976 | struct net *net = sock_net(skb->sk); |
977 | struct tcmsg *tcm = nlmsg_data(n); | 977 | struct tcmsg *tcm = nlmsg_data(n); |
978 | struct nlattr *tca[TCA_MAX + 1]; | 978 | struct nlattr *tca[TCA_MAX + 1]; |
979 | struct net_device *dev; | 979 | struct net_device *dev; |
980 | u32 clid = tcm->tcm_parent; | 980 | u32 clid; |
981 | struct Qdisc *q = NULL; | 981 | struct Qdisc *q = NULL; |
982 | struct Qdisc *p = NULL; | 982 | struct Qdisc *p = NULL; |
983 | int err; | 983 | int err; |
@@ -985,14 +985,15 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
985 | if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN)) | 985 | if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN)) |
986 | return -EPERM; | 986 | return -EPERM; |
987 | 987 | ||
988 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | ||
989 | if (!dev) | ||
990 | return -ENODEV; | ||
991 | |||
992 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 988 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
993 | if (err < 0) | 989 | if (err < 0) |
994 | return err; | 990 | return err; |
995 | 991 | ||
992 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | ||
993 | if (!dev) | ||
994 | return -ENODEV; | ||
995 | |||
996 | clid = tcm->tcm_parent; | ||
996 | if (clid) { | 997 | if (clid) { |
997 | if (clid != TC_H_ROOT) { | 998 | if (clid != TC_H_ROOT) { |
998 | if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) { | 999 | if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) { |
@@ -1038,7 +1039,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1038 | * Create/change qdisc. | 1039 | * Create/change qdisc. |
1039 | */ | 1040 | */ |
1040 | 1041 | ||
1041 | static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 1042 | static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n) |
1042 | { | 1043 | { |
1043 | struct net *net = sock_net(skb->sk); | 1044 | struct net *net = sock_net(skb->sk); |
1044 | struct tcmsg *tcm; | 1045 | struct tcmsg *tcm; |
@@ -1053,6 +1054,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1053 | 1054 | ||
1054 | replay: | 1055 | replay: |
1055 | /* Reinit, just in case something touches this. */ | 1056 | /* Reinit, just in case something touches this. */ |
1057 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | ||
1058 | if (err < 0) | ||
1059 | return err; | ||
1060 | |||
1056 | tcm = nlmsg_data(n); | 1061 | tcm = nlmsg_data(n); |
1057 | clid = tcm->tcm_parent; | 1062 | clid = tcm->tcm_parent; |
1058 | q = p = NULL; | 1063 | q = p = NULL; |
@@ -1061,9 +1066,6 @@ replay: | |||
1061 | if (!dev) | 1066 | if (!dev) |
1062 | return -ENODEV; | 1067 | return -ENODEV; |
1063 | 1068 | ||
1064 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | ||
1065 | if (err < 0) | ||
1066 | return err; | ||
1067 | 1069 | ||
1068 | if (clid) { | 1070 | if (clid) { |
1069 | if (clid != TC_H_ROOT) { | 1071 | if (clid != TC_H_ROOT) { |
@@ -1372,7 +1374,7 @@ done: | |||
1372 | 1374 | ||
1373 | 1375 | ||
1374 | 1376 | ||
1375 | static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 1377 | static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n) |
1376 | { | 1378 | { |
1377 | struct net *net = sock_net(skb->sk); | 1379 | struct net *net = sock_net(skb->sk); |
1378 | struct tcmsg *tcm = nlmsg_data(n); | 1380 | struct tcmsg *tcm = nlmsg_data(n); |
@@ -1382,22 +1384,22 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1382 | const struct Qdisc_class_ops *cops; | 1384 | const struct Qdisc_class_ops *cops; |
1383 | unsigned long cl = 0; | 1385 | unsigned long cl = 0; |
1384 | unsigned long new_cl; | 1386 | unsigned long new_cl; |
1385 | u32 portid = tcm->tcm_parent; | 1387 | u32 portid; |
1386 | u32 clid = tcm->tcm_handle; | 1388 | u32 clid; |
1387 | u32 qid = TC_H_MAJ(clid); | 1389 | u32 qid; |
1388 | int err; | 1390 | int err; |
1389 | 1391 | ||
1390 | if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN)) | 1392 | if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN)) |
1391 | return -EPERM; | 1393 | return -EPERM; |
1392 | 1394 | ||
1393 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | ||
1394 | if (!dev) | ||
1395 | return -ENODEV; | ||
1396 | |||
1397 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 1395 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
1398 | if (err < 0) | 1396 | if (err < 0) |
1399 | return err; | 1397 | return err; |
1400 | 1398 | ||
1399 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | ||
1400 | if (!dev) | ||
1401 | return -ENODEV; | ||
1402 | |||
1401 | /* | 1403 | /* |
1402 | parent == TC_H_UNSPEC - unspecified parent. | 1404 | parent == TC_H_UNSPEC - unspecified parent. |
1403 | parent == TC_H_ROOT - class is root, which has no parent. | 1405 | parent == TC_H_ROOT - class is root, which has no parent. |
@@ -1413,6 +1415,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1413 | 1415 | ||
1414 | /* Step 1. Determine qdisc handle X:0 */ | 1416 | /* Step 1. Determine qdisc handle X:0 */ |
1415 | 1417 | ||
1418 | portid = tcm->tcm_parent; | ||
1419 | clid = tcm->tcm_handle; | ||
1420 | qid = TC_H_MAJ(clid); | ||
1421 | |||
1416 | if (portid != TC_H_ROOT) { | 1422 | if (portid != TC_H_ROOT) { |
1417 | u32 qid1 = TC_H_MAJ(portid); | 1423 | u32 qid1 = TC_H_MAJ(portid); |
1418 | 1424 | ||
@@ -1636,7 +1642,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) | |||
1636 | struct net_device *dev; | 1642 | struct net_device *dev; |
1637 | int t, s_t; | 1643 | int t, s_t; |
1638 | 1644 | ||
1639 | if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) | 1645 | if (nlmsg_len(cb->nlh) < sizeof(*tcm)) |
1640 | return 0; | 1646 | return 0; |
1641 | dev = dev_get_by_index(net, tcm->tcm_ifindex); | 1647 | dev = dev_get_by_index(net, tcm->tcm_ifindex); |
1642 | if (!dev) | 1648 | if (!dev) |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 571f1d211f4d..79b1876b6cd2 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -981,6 +981,7 @@ static const struct nla_policy htb_policy[TCA_HTB_MAX + 1] = { | |||
981 | [TCA_HTB_INIT] = { .len = sizeof(struct tc_htb_glob) }, | 981 | [TCA_HTB_INIT] = { .len = sizeof(struct tc_htb_glob) }, |
982 | [TCA_HTB_CTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | 982 | [TCA_HTB_CTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, |
983 | [TCA_HTB_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | 983 | [TCA_HTB_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, |
984 | [TCA_HTB_DIRECT_QLEN] = { .type = NLA_U32 }, | ||
984 | }; | 985 | }; |
985 | 986 | ||
986 | static void htb_work_func(struct work_struct *work) | 987 | static void htb_work_func(struct work_struct *work) |
@@ -994,7 +995,7 @@ static void htb_work_func(struct work_struct *work) | |||
994 | static int htb_init(struct Qdisc *sch, struct nlattr *opt) | 995 | static int htb_init(struct Qdisc *sch, struct nlattr *opt) |
995 | { | 996 | { |
996 | struct htb_sched *q = qdisc_priv(sch); | 997 | struct htb_sched *q = qdisc_priv(sch); |
997 | struct nlattr *tb[TCA_HTB_INIT + 1]; | 998 | struct nlattr *tb[TCA_HTB_MAX + 1]; |
998 | struct tc_htb_glob *gopt; | 999 | struct tc_htb_glob *gopt; |
999 | int err; | 1000 | int err; |
1000 | int i; | 1001 | int i; |
@@ -1002,20 +1003,16 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) | |||
1002 | if (!opt) | 1003 | if (!opt) |
1003 | return -EINVAL; | 1004 | return -EINVAL; |
1004 | 1005 | ||
1005 | err = nla_parse_nested(tb, TCA_HTB_INIT, opt, htb_policy); | 1006 | err = nla_parse_nested(tb, TCA_HTB_MAX, opt, htb_policy); |
1006 | if (err < 0) | 1007 | if (err < 0) |
1007 | return err; | 1008 | return err; |
1008 | 1009 | ||
1009 | if (tb[TCA_HTB_INIT] == NULL) { | 1010 | if (!tb[TCA_HTB_INIT]) |
1010 | pr_err("HTB: hey probably you have bad tc tool ?\n"); | ||
1011 | return -EINVAL; | 1011 | return -EINVAL; |
1012 | } | 1012 | |
1013 | gopt = nla_data(tb[TCA_HTB_INIT]); | 1013 | gopt = nla_data(tb[TCA_HTB_INIT]); |
1014 | if (gopt->version != HTB_VER >> 16) { | 1014 | if (gopt->version != HTB_VER >> 16) |
1015 | pr_err("HTB: need tc/htb version %d (minor is %d), you have %d\n", | ||
1016 | HTB_VER >> 16, HTB_VER & 0xffff, gopt->version); | ||
1017 | return -EINVAL; | 1015 | return -EINVAL; |
1018 | } | ||
1019 | 1016 | ||
1020 | err = qdisc_class_hash_init(&q->clhash); | 1017 | err = qdisc_class_hash_init(&q->clhash); |
1021 | if (err < 0) | 1018 | if (err < 0) |
@@ -1027,10 +1024,13 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) | |||
1027 | INIT_WORK(&q->work, htb_work_func); | 1024 | INIT_WORK(&q->work, htb_work_func); |
1028 | skb_queue_head_init(&q->direct_queue); | 1025 | skb_queue_head_init(&q->direct_queue); |
1029 | 1026 | ||
1030 | q->direct_qlen = qdisc_dev(sch)->tx_queue_len; | 1027 | if (tb[TCA_HTB_DIRECT_QLEN]) |
1031 | if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */ | 1028 | q->direct_qlen = nla_get_u32(tb[TCA_HTB_DIRECT_QLEN]); |
1032 | q->direct_qlen = 2; | 1029 | else { |
1033 | 1030 | q->direct_qlen = qdisc_dev(sch)->tx_queue_len; | |
1031 | if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */ | ||
1032 | q->direct_qlen = 2; | ||
1033 | } | ||
1034 | if ((q->rate2quantum = gopt->rate2quantum) < 1) | 1034 | if ((q->rate2quantum = gopt->rate2quantum) < 1) |
1035 | q->rate2quantum = 1; | 1035 | q->rate2quantum = 1; |
1036 | q->defcls = gopt->defcls; | 1036 | q->defcls = gopt->defcls; |
@@ -1056,7 +1056,8 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
1056 | nest = nla_nest_start(skb, TCA_OPTIONS); | 1056 | nest = nla_nest_start(skb, TCA_OPTIONS); |
1057 | if (nest == NULL) | 1057 | if (nest == NULL) |
1058 | goto nla_put_failure; | 1058 | goto nla_put_failure; |
1059 | if (nla_put(skb, TCA_HTB_INIT, sizeof(gopt), &gopt)) | 1059 | if (nla_put(skb, TCA_HTB_INIT, sizeof(gopt), &gopt) || |
1060 | nla_put_u32(skb, TCA_HTB_DIRECT_QLEN, q->direct_qlen)) | ||
1060 | goto nla_put_failure; | 1061 | goto nla_put_failure; |
1061 | nla_nest_end(skb, nest); | 1062 | nla_nest_end(skb, nest); |
1062 | 1063 | ||
@@ -1311,7 +1312,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1311 | struct htb_sched *q = qdisc_priv(sch); | 1312 | struct htb_sched *q = qdisc_priv(sch); |
1312 | struct htb_class *cl = (struct htb_class *)*arg, *parent; | 1313 | struct htb_class *cl = (struct htb_class *)*arg, *parent; |
1313 | struct nlattr *opt = tca[TCA_OPTIONS]; | 1314 | struct nlattr *opt = tca[TCA_OPTIONS]; |
1314 | struct nlattr *tb[__TCA_HTB_MAX]; | 1315 | struct nlattr *tb[TCA_HTB_MAX + 1]; |
1315 | struct tc_htb_opt *hopt; | 1316 | struct tc_htb_opt *hopt; |
1316 | 1317 | ||
1317 | /* extract all subattrs from opt attr */ | 1318 | /* extract all subattrs from opt attr */ |