diff options
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r-- | net/sched/act_api.c | 84 |
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 | ||
107 | nla_put_failure: | 109 | nla_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; |
137 | nla_put_failure: | 140 | nla_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) | |||
459 | nla_put_failure: | 463 | nla_put_failure: |
460 | err = -EINVAL; | 464 | err = -EINVAL; |
461 | errout: | 465 | errout: |
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) |