aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/act_api.h4
-rw-r--r--net/sched/act_api.c71
-rw-r--r--net/sched/cls_api.c14
3 files changed, 48 insertions, 41 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h
index c5ac61ada94f..565eed8fe496 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -114,8 +114,8 @@ extern int tcf_register_action(struct tc_action_ops *a);
114extern int tcf_unregister_action(struct tc_action_ops *a); 114extern int tcf_unregister_action(struct tc_action_ops *a);
115extern void tcf_action_destroy(struct tc_action *a, int bind); 115extern void tcf_action_destroy(struct tc_action *a, int bind);
116extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res); 116extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res);
117extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind, int *err); 117extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
118extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind, int *err); 118extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
119extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int); 119extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
120extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); 120extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
121extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); 121extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 2fe0345ddcb1..ea80f82dbb6a 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -18,6 +18,7 @@
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/kmod.h> 20#include <linux/kmod.h>
21#include <linux/err.h>
21#include <net/net_namespace.h> 22#include <net/net_namespace.h>
22#include <net/sock.h> 23#include <net/sock.h>
23#include <net/sch_generic.h> 24#include <net/sch_generic.h>
@@ -463,15 +464,16 @@ errout:
463} 464}
464 465
465struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, 466struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
466 char *name, int ovr, int bind, int *err) 467 char *name, int ovr, int bind)
467{ 468{
468 struct tc_action *a; 469 struct tc_action *a;
469 struct tc_action_ops *a_o; 470 struct tc_action_ops *a_o;
470 char act_name[IFNAMSIZ]; 471 char act_name[IFNAMSIZ];
471 struct nlattr *tb[TCA_ACT_MAX+1]; 472 struct nlattr *tb[TCA_ACT_MAX+1];
472 struct nlattr *kind; 473 struct nlattr *kind;
474 int err;
473 475
474 *err = -EINVAL; 476 err = -EINVAL;
475 477
476 if (name == NULL) { 478 if (name == NULL) {
477 if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) 479 if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0)
@@ -502,36 +504,35 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
502 * indicate this using -EAGAIN. 504 * indicate this using -EAGAIN.
503 */ 505 */
504 if (a_o != NULL) { 506 if (a_o != NULL) {
505 *err = -EAGAIN; 507 err = -EAGAIN;
506 goto err_mod; 508 goto err_mod;
507 } 509 }
508#endif 510#endif
509 *err = -ENOENT; 511 err = -ENOENT;
510 goto err_out; 512 goto err_out;
511 } 513 }
512 514
513 *err = -ENOMEM; 515 err = -ENOMEM;
514 a = kzalloc(sizeof(*a), GFP_KERNEL); 516 a = kzalloc(sizeof(*a), GFP_KERNEL);
515 if (a == NULL) 517 if (a == NULL)
516 goto err_mod; 518 goto err_mod;
517 519
518 /* backward compatibility for policer */ 520 /* backward compatibility for policer */
519 if (name == NULL) 521 if (name == NULL)
520 *err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind); 522 err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
521 else 523 else
522 *err = a_o->init(nla, est, a, ovr, bind); 524 err = a_o->init(nla, est, a, ovr, bind);
523 if (*err < 0) 525 if (err < 0)
524 goto err_free; 526 goto err_free;
525 527
526 /* module count goes up only when brand new policy is created 528 /* module count goes up only when brand new policy is created
527 if it exists and is only bound to in a_o->init() then 529 if it exists and is only bound to in a_o->init() then
528 ACT_P_CREATED is not returned (a zero is). 530 ACT_P_CREATED is not returned (a zero is).
529 */ 531 */
530 if (*err != ACT_P_CREATED) 532 if (err != ACT_P_CREATED)
531 module_put(a_o->owner); 533 module_put(a_o->owner);
532 a->ops = a_o; 534 a->ops = a_o;
533 535
534 *err = 0;
535 return a; 536 return a;
536 537
537err_free: 538err_free:
@@ -539,24 +540,22 @@ err_free:
539err_mod: 540err_mod:
540 module_put(a_o->owner); 541 module_put(a_o->owner);
541err_out: 542err_out:
542 return NULL; 543 return ERR_PTR(err);
543} 544}
544 545
545struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, 546struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
546 char *name, int ovr, int bind, int *err) 547 char *name, int ovr, int bind)
547{ 548{
548 struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; 549 struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
549 struct tc_action *head = NULL, *act, *act_prev = NULL; 550 struct tc_action *head = NULL, *act, *act_prev = NULL;
550 int i; 551 int i;
551 552
552 if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0) { 553 if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0)
553 *err = -EINVAL; 554 return ERR_PTR(-EINVAL);
554 return head;
555 }
556 555
557 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { 556 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
558 act = tcf_action_init_1(tb[i], est, name, ovr, bind, err); 557 act = tcf_action_init_1(tb[i], est, name, ovr, bind);
559 if (act == NULL) 558 if (IS_ERR(act))
560 goto err; 559 goto err;
561 act->order = i; 560 act->order = i;
562 561
@@ -571,7 +570,7 @@ struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
571err: 570err:
572 if (head != NULL) 571 if (head != NULL)
573 tcf_action_destroy(head, bind); 572 tcf_action_destroy(head, bind);
574 return NULL; 573 return act;
575} 574}
576 575
577int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, 576int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
@@ -668,44 +667,46 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
668} 667}
669 668
670static struct tc_action * 669static struct tc_action *
671tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int *err) 670tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
672{ 671{
673 struct nlattr *tb[TCA_ACT_MAX+1]; 672 struct nlattr *tb[TCA_ACT_MAX+1];
674 struct tc_action *a; 673 struct tc_action *a;
675 int index; 674 int index;
675 int err;
676 676
677 *err = -EINVAL; 677 err = -EINVAL;
678 if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) 678 if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0)
679 return NULL; 679 goto err_out;
680 680
681 if (tb[TCA_ACT_INDEX] == NULL || 681 if (tb[TCA_ACT_INDEX] == NULL ||
682 nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) 682 nla_len(tb[TCA_ACT_INDEX]) < sizeof(index))
683 return NULL; 683 goto err_out;
684 index = *(int *)nla_data(tb[TCA_ACT_INDEX]); 684 index = *(int *)nla_data(tb[TCA_ACT_INDEX]);
685 685
686 *err = -ENOMEM; 686 err = -ENOMEM;
687 a = kzalloc(sizeof(struct tc_action), GFP_KERNEL); 687 a = kzalloc(sizeof(struct tc_action), GFP_KERNEL);
688 if (a == NULL) 688 if (a == NULL)
689 return NULL; 689 goto err_out;
690 690
691 *err = -EINVAL; 691 err = -EINVAL;
692 a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); 692 a->ops = tc_lookup_action(tb[TCA_ACT_KIND]);
693 if (a->ops == NULL) 693 if (a->ops == NULL)
694 goto err_free; 694 goto err_free;
695 if (a->ops->lookup == NULL) 695 if (a->ops->lookup == NULL)
696 goto err_mod; 696 goto err_mod;
697 *err = -ENOENT; 697 err = -ENOENT;
698 if (a->ops->lookup(a, index) == 0) 698 if (a->ops->lookup(a, index) == 0)
699 goto err_mod; 699 goto err_mod;
700 700
701 module_put(a->ops->owner); 701 module_put(a->ops->owner);
702 *err = 0;
703 return a; 702 return a;
703
704err_mod: 704err_mod:
705 module_put(a->ops->owner); 705 module_put(a->ops->owner);
706err_free: 706err_free:
707 kfree(a); 707 kfree(a);
708 return NULL; 708err_out:
709 return ERR_PTR(err);
709} 710}
710 711
711static void cleanup_a(struct tc_action *act) 712static void cleanup_a(struct tc_action *act)
@@ -816,9 +817,11 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
816 } 817 }
817 818
818 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { 819 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
819 act = tcf_action_get_1(tb[i], n, pid, &ret); 820 act = tcf_action_get_1(tb[i], n, pid);
820 if (act == NULL) 821 if (IS_ERR(act)) {
822 ret = PTR_ERR(act);
821 goto err; 823 goto err;
824 }
822 act->order = i; 825 act->order = i;
823 826
824 if (head == NULL) 827 if (head == NULL)
@@ -912,9 +915,13 @@ tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr)
912 struct tc_action *a; 915 struct tc_action *a;
913 u32 seq = n->nlmsg_seq; 916 u32 seq = n->nlmsg_seq;
914 917
915 act = tcf_action_init(nla, NULL, NULL, ovr, 0, &ret); 918 act = tcf_action_init(nla, NULL, NULL, ovr, 0);
916 if (act == NULL) 919 if (act == NULL)
917 goto done; 920 goto done;
921 if (IS_ERR(act)) {
922 ret = PTR_ERR(act);
923 goto done;
924 }
918 925
919 /* dump then free all the actions after update; inserted policy 926 /* dump then free all the actions after update; inserted policy
920 * stays intact 927 * stays intact
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index d870478e3640..92fa1559c211 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -23,6 +23,7 @@
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> 25#include <linux/netlink.h>
26#include <linux/err.h>
26#include <net/net_namespace.h> 27#include <net/net_namespace.h>
27#include <net/sock.h> 28#include <net/sock.h>
28#include <net/netlink.h> 29#include <net/netlink.h>
@@ -487,23 +488,22 @@ int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
487 488
488#ifdef CONFIG_NET_CLS_ACT 489#ifdef CONFIG_NET_CLS_ACT
489 { 490 {
490 int err;
491 struct tc_action *act; 491 struct tc_action *act;
492 492
493 if (map->police && tb[map->police]) { 493 if (map->police && tb[map->police]) {
494 act = tcf_action_init_1(tb[map->police], rate_tlv, 494 act = tcf_action_init_1(tb[map->police], rate_tlv,
495 "police", TCA_ACT_NOREPLACE, 495 "police", TCA_ACT_NOREPLACE,
496 TCA_ACT_BIND, &err); 496 TCA_ACT_BIND);
497 if (act == NULL) 497 if (IS_ERR(act))
498 return err; 498 return PTR_ERR(act);
499 499
500 act->type = TCA_OLD_COMPAT; 500 act->type = TCA_OLD_COMPAT;
501 exts->action = act; 501 exts->action = act;
502 } else if (map->action && tb[map->action]) { 502 } else if (map->action && tb[map->action]) {
503 act = tcf_action_init(tb[map->action], rate_tlv, NULL, 503 act = tcf_action_init(tb[map->action], rate_tlv, NULL,
504 TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err); 504 TCA_ACT_NOREPLACE, TCA_ACT_BIND);
505 if (act == NULL) 505 if (IS_ERR(act))
506 return err; 506 return PTR_ERR(act);
507 507
508 exts->action = act; 508 exts->action = act;
509 } 509 }