diff options
Diffstat (limited to 'net/sched/cls_api.c')
-rw-r--r-- | net/sched/cls_api.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 9eeb3c6c82f4..87be2b2fc29a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -38,14 +38,14 @@ static DEFINE_RWLOCK(cls_mod_lock); | |||
38 | 38 | ||
39 | /* Find classifier type by string name */ | 39 | /* Find classifier type by string name */ |
40 | 40 | ||
41 | static struct tcf_proto_ops *tcf_proto_lookup_ops(struct rtattr *kind) | 41 | static struct tcf_proto_ops *tcf_proto_lookup_ops(struct nlattr *kind) |
42 | { | 42 | { |
43 | struct tcf_proto_ops *t = NULL; | 43 | struct tcf_proto_ops *t = NULL; |
44 | 44 | ||
45 | if (kind) { | 45 | if (kind) { |
46 | read_lock(&cls_mod_lock); | 46 | read_lock(&cls_mod_lock); |
47 | for (t = tcf_proto_base; t; t = t->next) { | 47 | for (t = tcf_proto_base; t; t = t->next) { |
48 | if (rtattr_strcmp(kind, t->kind) == 0) { | 48 | if (nla_strcmp(kind, t->kind) == 0) { |
49 | if (!try_module_get(t->owner)) | 49 | if (!try_module_get(t->owner)) |
50 | t = NULL; | 50 | t = NULL; |
51 | break; | 51 | break; |
@@ -118,7 +118,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp) | |||
118 | static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 118 | static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) |
119 | { | 119 | { |
120 | struct net *net = skb->sk->sk_net; | 120 | struct net *net = skb->sk->sk_net; |
121 | struct rtattr **tca; | 121 | struct nlattr *tca[TCA_MAX + 1]; |
122 | struct tcmsg *t; | 122 | struct tcmsg *t; |
123 | u32 protocol; | 123 | u32 protocol; |
124 | u32 prio; | 124 | u32 prio; |
@@ -138,7 +138,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
138 | return -EINVAL; | 138 | return -EINVAL; |
139 | 139 | ||
140 | replay: | 140 | replay: |
141 | tca = arg; | ||
142 | t = NLMSG_DATA(n); | 141 | t = NLMSG_DATA(n); |
143 | protocol = TC_H_MIN(t->tcm_info); | 142 | protocol = TC_H_MIN(t->tcm_info); |
144 | prio = TC_H_MAJ(t->tcm_info); | 143 | prio = TC_H_MAJ(t->tcm_info); |
@@ -160,6 +159,10 @@ replay: | |||
160 | if (dev == NULL) | 159 | if (dev == NULL) |
161 | return -ENODEV; | 160 | return -ENODEV; |
162 | 161 | ||
162 | err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL); | ||
163 | if (err < 0) | ||
164 | return err; | ||
165 | |||
163 | /* Find qdisc */ | 166 | /* Find qdisc */ |
164 | if (!parent) { | 167 | if (!parent) { |
165 | q = dev->qdisc_sleeping; | 168 | q = dev->qdisc_sleeping; |
@@ -202,7 +205,7 @@ replay: | |||
202 | if (tp == NULL) { | 205 | if (tp == NULL) { |
203 | /* Proto-tcf does not exist, create new one */ | 206 | /* Proto-tcf does not exist, create new one */ |
204 | 207 | ||
205 | if (tca[TCA_KIND-1] == NULL || !protocol) | 208 | if (tca[TCA_KIND] == NULL || !protocol) |
206 | goto errout; | 209 | goto errout; |
207 | 210 | ||
208 | err = -ENOENT; | 211 | err = -ENOENT; |
@@ -217,14 +220,14 @@ replay: | |||
217 | if (tp == NULL) | 220 | if (tp == NULL) |
218 | goto errout; | 221 | goto errout; |
219 | err = -EINVAL; | 222 | err = -EINVAL; |
220 | tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]); | 223 | tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]); |
221 | if (tp_ops == NULL) { | 224 | if (tp_ops == NULL) { |
222 | #ifdef CONFIG_KMOD | 225 | #ifdef CONFIG_KMOD |
223 | struct rtattr *kind = tca[TCA_KIND-1]; | 226 | struct nlattr *kind = tca[TCA_KIND]; |
224 | char name[IFNAMSIZ]; | 227 | char name[IFNAMSIZ]; |
225 | 228 | ||
226 | if (kind != NULL && | 229 | if (kind != NULL && |
227 | rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { | 230 | nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { |
228 | rtnl_unlock(); | 231 | rtnl_unlock(); |
229 | request_module("cls_%s", name); | 232 | request_module("cls_%s", name); |
230 | rtnl_lock(); | 233 | rtnl_lock(); |
@@ -263,7 +266,7 @@ replay: | |||
263 | *back = tp; | 266 | *back = tp; |
264 | qdisc_unlock_tree(dev); | 267 | qdisc_unlock_tree(dev); |
265 | 268 | ||
266 | } else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind)) | 269 | } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) |
267 | goto errout; | 270 | goto errout; |
268 | 271 | ||
269 | fh = tp->ops->get(tp, t->tcm_handle); | 272 | fh = tp->ops->get(tp, t->tcm_handle); |
@@ -333,18 +336,18 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, | |||
333 | tcm->tcm_ifindex = tp->q->dev->ifindex; | 336 | tcm->tcm_ifindex = tp->q->dev->ifindex; |
334 | tcm->tcm_parent = tp->classid; | 337 | tcm->tcm_parent = tp->classid; |
335 | tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); | 338 | tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); |
336 | RTA_PUT(skb, TCA_KIND, IFNAMSIZ, tp->ops->kind); | 339 | NLA_PUT(skb, TCA_KIND, IFNAMSIZ, tp->ops->kind); |
337 | tcm->tcm_handle = fh; | 340 | tcm->tcm_handle = fh; |
338 | if (RTM_DELTFILTER != event) { | 341 | if (RTM_DELTFILTER != event) { |
339 | tcm->tcm_handle = 0; | 342 | tcm->tcm_handle = 0; |
340 | if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0) | 343 | if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0) |
341 | goto rtattr_failure; | 344 | goto nla_put_failure; |
342 | } | 345 | } |
343 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; | 346 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; |
344 | return skb->len; | 347 | return skb->len; |
345 | 348 | ||
346 | nlmsg_failure: | 349 | nlmsg_failure: |
347 | rtattr_failure: | 350 | nla_put_failure: |
348 | nlmsg_trim(skb, b); | 351 | nlmsg_trim(skb, b); |
349 | return -1; | 352 | return -1; |
350 | } | 353 | } |
@@ -476,8 +479,8 @@ void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts) | |||
476 | } | 479 | } |
477 | EXPORT_SYMBOL(tcf_exts_destroy); | 480 | EXPORT_SYMBOL(tcf_exts_destroy); |
478 | 481 | ||
479 | int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, | 482 | int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb, |
480 | struct rtattr *rate_tlv, struct tcf_exts *exts, | 483 | struct nlattr *rate_tlv, struct tcf_exts *exts, |
481 | struct tcf_ext_map *map) | 484 | struct tcf_ext_map *map) |
482 | { | 485 | { |
483 | memset(exts, 0, sizeof(*exts)); | 486 | memset(exts, 0, sizeof(*exts)); |
@@ -487,8 +490,9 @@ int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, | |||
487 | int err; | 490 | int err; |
488 | struct tc_action *act; | 491 | struct tc_action *act; |
489 | 492 | ||
490 | if (map->police && tb[map->police-1]) { | 493 | if (map->police && tb[map->police]) { |
491 | act = tcf_action_init_1(tb[map->police-1], rate_tlv, | 494 | act = tcf_action_init_1((struct rtattr *)tb[map->police], |
495 | (struct rtattr *)rate_tlv, | ||
492 | "police", TCA_ACT_NOREPLACE, | 496 | "police", TCA_ACT_NOREPLACE, |
493 | TCA_ACT_BIND, &err); | 497 | TCA_ACT_BIND, &err); |
494 | if (act == NULL) | 498 | if (act == NULL) |
@@ -496,8 +500,9 @@ int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, | |||
496 | 500 | ||
497 | act->type = TCA_OLD_COMPAT; | 501 | act->type = TCA_OLD_COMPAT; |
498 | exts->action = act; | 502 | exts->action = act; |
499 | } else if (map->action && tb[map->action-1]) { | 503 | } else if (map->action && tb[map->action]) { |
500 | act = tcf_action_init(tb[map->action-1], rate_tlv, NULL, | 504 | act = tcf_action_init((struct rtattr *)tb[map->action], |
505 | (struct rtattr *)rate_tlv, NULL, | ||
501 | TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err); | 506 | TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err); |
502 | if (act == NULL) | 507 | if (act == NULL) |
503 | return err; | 508 | return err; |
@@ -506,8 +511,8 @@ int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, | |||
506 | } | 511 | } |
507 | } | 512 | } |
508 | #else | 513 | #else |
509 | if ((map->action && tb[map->action-1]) || | 514 | if ((map->action && tb[map->action]) || |
510 | (map->police && tb[map->police-1])) | 515 | (map->police && tb[map->police])) |
511 | return -EOPNOTSUPP; | 516 | return -EOPNOTSUPP; |
512 | #endif | 517 | #endif |
513 | 518 | ||
@@ -541,23 +546,23 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts, | |||
541 | * to work with both old and new modes of entering | 546 | * to work with both old and new modes of entering |
542 | * tc data even if iproute2 was newer - jhs | 547 | * tc data even if iproute2 was newer - jhs |
543 | */ | 548 | */ |
544 | struct rtattr *p_rta = (struct rtattr *)skb_tail_pointer(skb); | 549 | struct nlattr *p_rta = (struct nlattr *)skb_tail_pointer(skb); |
545 | 550 | ||
546 | if (exts->action->type != TCA_OLD_COMPAT) { | 551 | if (exts->action->type != TCA_OLD_COMPAT) { |
547 | RTA_PUT(skb, map->action, 0, NULL); | 552 | NLA_PUT(skb, map->action, 0, NULL); |
548 | if (tcf_action_dump(skb, exts->action, 0, 0) < 0) | 553 | if (tcf_action_dump(skb, exts->action, 0, 0) < 0) |
549 | goto rtattr_failure; | 554 | goto nla_put_failure; |
550 | p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta; | 555 | p_rta->nla_len = skb_tail_pointer(skb) - (u8 *)p_rta; |
551 | } else if (map->police) { | 556 | } else if (map->police) { |
552 | RTA_PUT(skb, map->police, 0, NULL); | 557 | NLA_PUT(skb, map->police, 0, NULL); |
553 | if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0) | 558 | if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0) |
554 | goto rtattr_failure; | 559 | goto nla_put_failure; |
555 | p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta; | 560 | p_rta->nla_len = skb_tail_pointer(skb) - (u8 *)p_rta; |
556 | } | 561 | } |
557 | } | 562 | } |
558 | #endif | 563 | #endif |
559 | return 0; | 564 | return 0; |
560 | rtattr_failure: __attribute__ ((unused)) | 565 | nla_put_failure: __attribute__ ((unused)) |
561 | return -1; | 566 | return -1; |
562 | } | 567 | } |
563 | EXPORT_SYMBOL(tcf_exts_dump); | 568 | EXPORT_SYMBOL(tcf_exts_dump); |
@@ -569,10 +574,10 @@ int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts, | |||
569 | #ifdef CONFIG_NET_CLS_ACT | 574 | #ifdef CONFIG_NET_CLS_ACT |
570 | if (exts->action) | 575 | if (exts->action) |
571 | if (tcf_action_copy_stats(skb, exts->action, 1) < 0) | 576 | if (tcf_action_copy_stats(skb, exts->action, 1) < 0) |
572 | goto rtattr_failure; | 577 | goto nla_put_failure; |
573 | #endif | 578 | #endif |
574 | return 0; | 579 | return 0; |
575 | rtattr_failure: __attribute__ ((unused)) | 580 | nla_put_failure: __attribute__ ((unused)) |
576 | return -1; | 581 | return -1; |
577 | } | 582 | } |
578 | EXPORT_SYMBOL(tcf_exts_dump_stats); | 583 | EXPORT_SYMBOL(tcf_exts_dump_stats); |