aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/cls_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/cls_api.c')
-rw-r--r--net/sched/cls_api.c65
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
41static struct tcf_proto_ops *tcf_proto_lookup_ops(struct rtattr *kind) 41static 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)
118static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 118static 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
140replay: 140replay:
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
346nlmsg_failure: 349nlmsg_failure:
347rtattr_failure: 350nla_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}
477EXPORT_SYMBOL(tcf_exts_destroy); 480EXPORT_SYMBOL(tcf_exts_destroy);
478 481
479int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, 482int 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;
560rtattr_failure: __attribute__ ((unused)) 565nla_put_failure: __attribute__ ((unused))
561 return -1; 566 return -1;
562} 567}
563EXPORT_SYMBOL(tcf_exts_dump); 568EXPORT_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;
575rtattr_failure: __attribute__ ((unused)) 580nla_put_failure: __attribute__ ((unused))
576 return -1; 581 return -1;
577} 582}
578EXPORT_SYMBOL(tcf_exts_dump_stats); 583EXPORT_SYMBOL(tcf_exts_dump_stats);