aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r--net/sched/act_api.c84
1 files changed, 46 insertions, 38 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 87818d7fb623..36022605fc16 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -69,7 +69,7 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
69{ 69{
70 struct tcf_common *p; 70 struct tcf_common *p;
71 int err = 0, index = -1,i = 0, s_i = 0, n_i = 0; 71 int err = 0, index = -1,i = 0, s_i = 0, n_i = 0;
72 struct nlattr *r ; 72 struct nlattr *nest;
73 73
74 read_lock_bh(hinfo->lock); 74 read_lock_bh(hinfo->lock);
75 75
@@ -84,15 +84,17 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
84 continue; 84 continue;
85 a->priv = p; 85 a->priv = p;
86 a->order = n_i; 86 a->order = n_i;
87 r = (struct nlattr *)skb_tail_pointer(skb); 87
88 NLA_PUT(skb, a->order, 0, NULL); 88 nest = nla_nest_start(skb, a->order);
89 if (nest == NULL)
90 goto nla_put_failure;
89 err = tcf_action_dump_1(skb, a, 0, 0); 91 err = tcf_action_dump_1(skb, a, 0, 0);
90 if (err < 0) { 92 if (err < 0) {
91 index--; 93 index--;
92 nlmsg_trim(skb, r); 94 nlmsg_trim(skb, nest);
93 goto done; 95 goto done;
94 } 96 }
95 r->nla_len = skb_tail_pointer(skb) - (u8 *)r; 97 nla_nest_end(skb, nest);
96 n_i++; 98 n_i++;
97 if (n_i >= TCA_ACT_MAX_PRIO) 99 if (n_i >= TCA_ACT_MAX_PRIO)
98 goto done; 100 goto done;
@@ -105,7 +107,7 @@ done:
105 return n_i; 107 return n_i;
106 108
107nla_put_failure: 109nla_put_failure:
108 nlmsg_trim(skb, r); 110 nla_nest_cancel(skb, nest);
109 goto done; 111 goto done;
110} 112}
111 113
@@ -113,11 +115,12 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
113 struct tcf_hashinfo *hinfo) 115 struct tcf_hashinfo *hinfo)
114{ 116{
115 struct tcf_common *p, *s_p; 117 struct tcf_common *p, *s_p;
116 struct nlattr *r ; 118 struct nlattr *nest;
117 int i= 0, n_i = 0; 119 int i= 0, n_i = 0;
118 120
119 r = (struct nlattr *)skb_tail_pointer(skb); 121 nest = nla_nest_start(skb, a->order);
120 NLA_PUT(skb, a->order, 0, NULL); 122 if (nest == NULL)
123 goto nla_put_failure;
121 NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); 124 NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
122 for (i = 0; i < (hinfo->hmask + 1); i++) { 125 for (i = 0; i < (hinfo->hmask + 1); i++) {
123 p = hinfo->htab[tcf_hash(i, hinfo->hmask)]; 126 p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
@@ -131,11 +134,11 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
131 } 134 }
132 } 135 }
133 NLA_PUT(skb, TCA_FCNT, 4, &n_i); 136 NLA_PUT(skb, TCA_FCNT, 4, &n_i);
134 r->nla_len = skb_tail_pointer(skb) - (u8 *)r; 137 nla_nest_end(skb, nest);
135 138
136 return n_i; 139 return n_i;
137nla_put_failure: 140nla_put_failure:
138 nlmsg_trim(skb, r); 141 nla_nest_cancel(skb, nest);
139 return -EINVAL; 142 return -EINVAL;
140} 143}
141 144
@@ -415,7 +418,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
415{ 418{
416 int err = -EINVAL; 419 int err = -EINVAL;
417 unsigned char *b = skb_tail_pointer(skb); 420 unsigned char *b = skb_tail_pointer(skb);
418 struct nlattr *r; 421 struct nlattr *nest;
419 422
420 if (a->ops == NULL || a->ops->dump == NULL) 423 if (a->ops == NULL || a->ops->dump == NULL)
421 return err; 424 return err;
@@ -423,10 +426,11 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
423 NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); 426 NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
424 if (tcf_action_copy_stats(skb, a, 0)) 427 if (tcf_action_copy_stats(skb, a, 0))
425 goto nla_put_failure; 428 goto nla_put_failure;
426 r = (struct nlattr *)skb_tail_pointer(skb); 429 nest = nla_nest_start(skb, TCA_OPTIONS);
427 NLA_PUT(skb, TCA_OPTIONS, 0, NULL); 430 if (nest == NULL)
431 goto nla_put_failure;
428 if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) { 432 if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) {
429 r->nla_len = skb_tail_pointer(skb) - (u8 *)r; 433 nla_nest_end(skb, nest);
430 return err; 434 return err;
431 } 435 }
432 436
@@ -441,17 +445,17 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
441{ 445{
442 struct tc_action *a; 446 struct tc_action *a;
443 int err = -EINVAL; 447 int err = -EINVAL;
444 unsigned char *b = skb_tail_pointer(skb); 448 struct nlattr *nest;
445 struct nlattr *r ;
446 449
447 while ((a = act) != NULL) { 450 while ((a = act) != NULL) {
448 r = (struct nlattr *)skb_tail_pointer(skb);
449 act = a->next; 451 act = a->next;
450 NLA_PUT(skb, a->order, 0, NULL); 452 nest = nla_nest_start(skb, a->order);
453 if (nest == NULL)
454 goto nla_put_failure;
451 err = tcf_action_dump_1(skb, a, bind, ref); 455 err = tcf_action_dump_1(skb, a, bind, ref);
452 if (err < 0) 456 if (err < 0)
453 goto errout; 457 goto errout;
454 r->nla_len = skb_tail_pointer(skb) - (u8 *)r; 458 nla_nest_end(skb, nest);
455 } 459 }
456 460
457 return 0; 461 return 0;
@@ -459,7 +463,7 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
459nla_put_failure: 463nla_put_failure:
460 err = -EINVAL; 464 err = -EINVAL;
461errout: 465errout:
462 nlmsg_trim(skb, b); 466 nla_nest_cancel(skb, nest);
463 return err; 467 return err;
464} 468}
465 469
@@ -627,7 +631,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
627 struct tcamsg *t; 631 struct tcamsg *t;
628 struct nlmsghdr *nlh; 632 struct nlmsghdr *nlh;
629 unsigned char *b = skb_tail_pointer(skb); 633 unsigned char *b = skb_tail_pointer(skb);
630 struct nlattr *x; 634 struct nlattr *nest;
631 635
632 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); 636 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
633 637
@@ -636,13 +640,14 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
636 t->tca__pad1 = 0; 640 t->tca__pad1 = 0;
637 t->tca__pad2 = 0; 641 t->tca__pad2 = 0;
638 642
639 x = (struct nlattr *)skb_tail_pointer(skb); 643 nest = nla_nest_start(skb, TCA_ACT_TAB);
640 NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); 644 if (nest == NULL)
645 goto nla_put_failure;
641 646
642 if (tcf_action_dump(skb, a, bind, ref) < 0) 647 if (tcf_action_dump(skb, a, bind, ref) < 0)
643 goto nla_put_failure; 648 goto nla_put_failure;
644 649
645 x->nla_len = skb_tail_pointer(skb) - (u8 *)x; 650 nla_nest_end(skb, nest);
646 651
647 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 652 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
648 return skb->len; 653 return skb->len;
@@ -743,7 +748,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
743 struct nlmsghdr *nlh; 748 struct nlmsghdr *nlh;
744 struct tcamsg *t; 749 struct tcamsg *t;
745 struct netlink_callback dcb; 750 struct netlink_callback dcb;
746 struct nlattr *x; 751 struct nlattr *nest;
747 struct nlattr *tb[TCA_ACT_MAX+1]; 752 struct nlattr *tb[TCA_ACT_MAX+1];
748 struct nlattr *kind; 753 struct nlattr *kind;
749 struct tc_action *a = create_a(0); 754 struct tc_action *a = create_a(0);
@@ -779,14 +784,15 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
779 t->tca__pad1 = 0; 784 t->tca__pad1 = 0;
780 t->tca__pad2 = 0; 785 t->tca__pad2 = 0;
781 786
782 x = (struct nlattr *)skb_tail_pointer(skb); 787 nest = nla_nest_start(skb, TCA_ACT_TAB);
783 NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); 788 if (nest == NULL)
789 goto nla_put_failure;
784 790
785 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); 791 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
786 if (err < 0) 792 if (err < 0)
787 goto nla_put_failure; 793 goto nla_put_failure;
788 794
789 x->nla_len = skb_tail_pointer(skb) - (u8 *)x; 795 nla_nest_end(skb, nest);
790 796
791 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 797 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
792 nlh->nlmsg_flags |= NLM_F_ROOT; 798 nlh->nlmsg_flags |= NLM_F_ROOT;
@@ -875,7 +881,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
875 struct tcamsg *t; 881 struct tcamsg *t;
876 struct nlmsghdr *nlh; 882 struct nlmsghdr *nlh;
877 struct sk_buff *skb; 883 struct sk_buff *skb;
878 struct nlattr *x; 884 struct nlattr *nest;
879 unsigned char *b; 885 unsigned char *b;
880 int err = 0; 886 int err = 0;
881 887
@@ -891,13 +897,14 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
891 t->tca__pad1 = 0; 897 t->tca__pad1 = 0;
892 t->tca__pad2 = 0; 898 t->tca__pad2 = 0;
893 899
894 x = (struct nlattr *)skb_tail_pointer(skb); 900 nest = nla_nest_start(skb, TCA_ACT_TAB);
895 NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); 901 if (nest == NULL)
902 goto nla_put_failure;
896 903
897 if (tcf_action_dump(skb, a, 0, 0) < 0) 904 if (tcf_action_dump(skb, a, 0, 0) < 0)
898 goto nla_put_failure; 905 goto nla_put_failure;
899 906
900 x->nla_len = skb_tail_pointer(skb) - (u8 *)x; 907 nla_nest_end(skb, nest);
901 908
902 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 909 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
903 NETLINK_CB(skb).dst_group = RTNLGRP_TC; 910 NETLINK_CB(skb).dst_group = RTNLGRP_TC;
@@ -1025,7 +1032,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1025 struct net *net = skb->sk->sk_net; 1032 struct net *net = skb->sk->sk_net;
1026 struct nlmsghdr *nlh; 1033 struct nlmsghdr *nlh;
1027 unsigned char *b = skb_tail_pointer(skb); 1034 unsigned char *b = skb_tail_pointer(skb);
1028 struct nlattr *x; 1035 struct nlattr *nest;
1029 struct tc_action_ops *a_o; 1036 struct tc_action_ops *a_o;
1030 struct tc_action a; 1037 struct tc_action a;
1031 int ret = 0; 1038 int ret = 0;
@@ -1060,18 +1067,19 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1060 t->tca__pad1 = 0; 1067 t->tca__pad1 = 0;
1061 t->tca__pad2 = 0; 1068 t->tca__pad2 = 0;
1062 1069
1063 x = (struct nlattr *)skb_tail_pointer(skb); 1070 nest = nla_nest_start(skb, TCA_ACT_TAB);
1064 NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); 1071 if (nest == NULL)
1072 goto nla_put_failure;
1065 1073
1066 ret = a_o->walk(skb, cb, RTM_GETACTION, &a); 1074 ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
1067 if (ret < 0) 1075 if (ret < 0)
1068 goto nla_put_failure; 1076 goto nla_put_failure;
1069 1077
1070 if (ret > 0) { 1078 if (ret > 0) {
1071 x->nla_len = skb_tail_pointer(skb) - (u8 *)x; 1079 nla_nest_end(skb, nest);
1072 ret = skb->len; 1080 ret = skb->len;
1073 } else 1081 } else
1074 nlmsg_trim(skb, x); 1082 nla_nest_cancel(skb, nest);
1075 1083
1076 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 1084 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1077 if (NETLINK_CB(cb->skb).pid && ret) 1085 if (NETLINK_CB(cb->skb).pid && ret)