aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_api.c
diff options
context:
space:
mode:
authorWANG Cong <xiyou.wangcong@gmail.com>2016-07-25 19:09:41 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-26 00:49:19 -0400
commita85a970af265f156740977168b542234511b28a8 (patch)
tree19866c37883917b1ec6964fcbae76335f9de0139 /net/sched/act_api.c
parentb93dd49c1a35884864027abd707889b795637f7a (diff)
net_sched: move tc_action into tcf_common
struct tc_action is confusing, currently we use it for two purposes: 1) Pass in arguments and carry out results from helper functions 2) A generic representation for tc actions The first one is error-prone, since we need to make sure we don't miss anything. This patch aims to get rid of this use, by moving tc_action into tcf_common, so that they are allocated together in hashtable and can be cast'ed easily. And together with the following patch, we could really make tc_action a generic representation for all tc actions and each type of action can inherit from it. Cc: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r--net/sched/act_api.c149
1 files changed, 53 insertions, 96 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 47ec2305f920..d97419f35e7e 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -38,7 +38,7 @@ static void free_tcf(struct rcu_head *head)
38 38
39static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *a) 39static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *a)
40{ 40{
41 struct tcf_common *p = a->priv; 41 struct tcf_common *p = (struct tcf_common *)a;
42 42
43 spin_lock_bh(&hinfo->lock); 43 spin_lock_bh(&hinfo->lock);
44 hlist_del(&p->tcfc_head); 44 hlist_del(&p->tcfc_head);
@@ -54,7 +54,7 @@ static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *a)
54 54
55int __tcf_hash_release(struct tc_action *a, bool bind, bool strict) 55int __tcf_hash_release(struct tc_action *a, bool bind, bool strict)
56{ 56{
57 struct tcf_common *p = a->priv; 57 struct tcf_common *p = (struct tcf_common *)a;
58 int ret = 0; 58 int ret = 0;
59 59
60 if (p) { 60 if (p) {
@@ -67,6 +67,7 @@ int __tcf_hash_release(struct tc_action *a, bool bind, bool strict)
67 if (p->tcfc_bindcnt <= 0 && p->tcfc_refcnt <= 0) { 67 if (p->tcfc_bindcnt <= 0 && p->tcfc_refcnt <= 0) {
68 if (a->ops->cleanup) 68 if (a->ops->cleanup)
69 a->ops->cleanup(a, bind); 69 a->ops->cleanup(a, bind);
70 list_del(&a->list);
70 tcf_hash_destroy(a->hinfo, a); 71 tcf_hash_destroy(a->hinfo, a);
71 ret = ACT_P_DELETED; 72 ret = ACT_P_DELETED;
72 } 73 }
@@ -77,10 +78,8 @@ int __tcf_hash_release(struct tc_action *a, bool bind, bool strict)
77EXPORT_SYMBOL(__tcf_hash_release); 78EXPORT_SYMBOL(__tcf_hash_release);
78 79
79static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb, 80static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
80 struct netlink_callback *cb, struct tc_action *a) 81 struct netlink_callback *cb)
81{ 82{
82 struct hlist_head *head;
83 struct tcf_common *p;
84 int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; 83 int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
85 struct nlattr *nest; 84 struct nlattr *nest;
86 85
@@ -89,19 +88,20 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
89 s_i = cb->args[0]; 88 s_i = cb->args[0];
90 89
91 for (i = 0; i < (hinfo->hmask + 1); i++) { 90 for (i = 0; i < (hinfo->hmask + 1); i++) {
91 struct hlist_head *head;
92 struct tcf_common *p;
93
92 head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; 94 head = &hinfo->htab[tcf_hash(i, hinfo->hmask)];
93 95
94 hlist_for_each_entry_rcu(p, head, tcfc_head) { 96 hlist_for_each_entry_rcu(p, head, tcfc_head) {
95 index++; 97 index++;
96 if (index < s_i) 98 if (index < s_i)
97 continue; 99 continue;
98 a->priv = p;
99 a->order = n_i;
100 100
101 nest = nla_nest_start(skb, a->order); 101 nest = nla_nest_start(skb, n_i);
102 if (nest == NULL) 102 if (nest == NULL)
103 goto nla_put_failure; 103 goto nla_put_failure;
104 err = tcf_action_dump_1(skb, a, 0, 0); 104 err = tcf_action_dump_1(skb, (struct tc_action *)p, 0, 0);
105 if (err < 0) { 105 if (err < 0) {
106 index--; 106 index--;
107 nlmsg_trim(skb, nest); 107 nlmsg_trim(skb, nest);
@@ -125,27 +125,27 @@ nla_put_failure:
125} 125}
126 126
127static int tcf_del_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb, 127static int tcf_del_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
128 struct tc_action *a) 128 const struct tc_action_ops *ops)
129{ 129{
130 struct hlist_head *head;
131 struct hlist_node *n;
132 struct tcf_common *p;
133 struct nlattr *nest; 130 struct nlattr *nest;
134 int i = 0, n_i = 0; 131 int i = 0, n_i = 0;
135 int ret = -EINVAL; 132 int ret = -EINVAL;
136 133
137 nest = nla_nest_start(skb, a->order); 134 nest = nla_nest_start(skb, 0);
138 if (nest == NULL) 135 if (nest == NULL)
139 goto nla_put_failure; 136 goto nla_put_failure;
140 if (nla_put_string(skb, TCA_KIND, a->ops->kind)) 137 if (nla_put_string(skb, TCA_KIND, ops->kind))
141 goto nla_put_failure; 138 goto nla_put_failure;
142 for (i = 0; i < (hinfo->hmask + 1); i++) { 139 for (i = 0; i < (hinfo->hmask + 1); i++) {
140 struct hlist_head *head;
141 struct hlist_node *n;
142 struct tcf_common *p;
143
143 head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; 144 head = &hinfo->htab[tcf_hash(i, hinfo->hmask)];
144 hlist_for_each_entry_safe(p, n, head, tcfc_head) { 145 hlist_for_each_entry_safe(p, n, head, tcfc_head) {
145 a->priv = p; 146 ret = __tcf_hash_release((struct tc_action *)p, false, true);
146 ret = __tcf_hash_release(a, false, true);
147 if (ret == ACT_P_DELETED) { 147 if (ret == ACT_P_DELETED) {
148 module_put(a->ops->owner); 148 module_put(p->tcfc_act.ops->owner);
149 n_i++; 149 n_i++;
150 } else if (ret < 0) 150 } else if (ret < 0)
151 goto nla_put_failure; 151 goto nla_put_failure;
@@ -163,16 +163,14 @@ nla_put_failure:
163 163
164int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, 164int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
165 struct netlink_callback *cb, int type, 165 struct netlink_callback *cb, int type,
166 struct tc_action *a) 166 const struct tc_action_ops *ops)
167{ 167{
168 struct tcf_hashinfo *hinfo = tn->hinfo; 168 struct tcf_hashinfo *hinfo = tn->hinfo;
169 169
170 a->hinfo = hinfo;
171
172 if (type == RTM_DELACTION) { 170 if (type == RTM_DELACTION) {
173 return tcf_del_walker(hinfo, skb, a); 171 return tcf_del_walker(hinfo, skb, ops);
174 } else if (type == RTM_GETACTION) { 172 } else if (type == RTM_GETACTION) {
175 return tcf_dump_walker(hinfo, skb, cb, a); 173 return tcf_dump_walker(hinfo, skb, cb);
176 } else { 174 } else {
177 WARN(1, "tcf_generic_walker: unknown action %d\n", type); 175 WARN(1, "tcf_generic_walker: unknown action %d\n", type);
178 return -EINVAL; 176 return -EINVAL;
@@ -210,21 +208,20 @@ u32 tcf_hash_new_index(struct tc_action_net *tn)
210} 208}
211EXPORT_SYMBOL(tcf_hash_new_index); 209EXPORT_SYMBOL(tcf_hash_new_index);
212 210
213int tcf_hash_search(struct tc_action_net *tn, struct tc_action *a, u32 index) 211int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
214{ 212{
215 struct tcf_hashinfo *hinfo = tn->hinfo; 213 struct tcf_hashinfo *hinfo = tn->hinfo;
216 struct tcf_common *p = tcf_hash_lookup(index, hinfo); 214 struct tcf_common *p = tcf_hash_lookup(index, hinfo);
217 215
218 if (p) { 216 if (p) {
219 a->priv = p; 217 *a = &p->tcfc_act;
220 a->hinfo = hinfo;
221 return 1; 218 return 1;
222 } 219 }
223 return 0; 220 return 0;
224} 221}
225EXPORT_SYMBOL(tcf_hash_search); 222EXPORT_SYMBOL(tcf_hash_search);
226 223
227bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action *a, 224bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
228 int bind) 225 int bind)
229{ 226{
230 struct tcf_hashinfo *hinfo = tn->hinfo; 227 struct tcf_hashinfo *hinfo = tn->hinfo;
@@ -233,8 +230,7 @@ bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action *a,
233 if (bind) 230 if (bind)
234 p->tcfc_bindcnt++; 231 p->tcfc_bindcnt++;
235 p->tcfc_refcnt++; 232 p->tcfc_refcnt++;
236 a->priv = p; 233 *a = &p->tcfc_act;
237 a->hinfo = hinfo;
238 return true; 234 return true;
239 } 235 }
240 return false; 236 return false;
@@ -243,7 +239,7 @@ EXPORT_SYMBOL(tcf_hash_check);
243 239
244void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est) 240void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est)
245{ 241{
246 struct tcf_common *pc = a->priv; 242 struct tcf_common *pc = (struct tcf_common *)a;
247 if (est) 243 if (est)
248 gen_kill_estimator(&pc->tcfc_bstats, 244 gen_kill_estimator(&pc->tcfc_bstats,
249 &pc->tcfc_rate_est); 245 &pc->tcfc_rate_est);
@@ -252,9 +248,10 @@ void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est)
252EXPORT_SYMBOL(tcf_hash_cleanup); 248EXPORT_SYMBOL(tcf_hash_cleanup);
253 249
254int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est, 250int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
255 struct tc_action *a, int size, int bind, bool cpustats) 251 struct tc_action **a, const struct tc_action_ops *ops,
252 int bind, bool cpustats)
256{ 253{
257 struct tcf_common *p = kzalloc(size, GFP_KERNEL); 254 struct tcf_common *p = kzalloc(ops->size, GFP_KERNEL);
258 struct tcf_hashinfo *hinfo = tn->hinfo; 255 struct tcf_hashinfo *hinfo = tn->hinfo;
259 int err = -ENOMEM; 256 int err = -ENOMEM;
260 257
@@ -294,15 +291,17 @@ err2:
294 } 291 }
295 } 292 }
296 293
297 a->priv = (void *) p; 294 p->tcfc_act.hinfo = hinfo;
298 a->hinfo = hinfo; 295 p->tcfc_act.ops = ops;
296 INIT_LIST_HEAD(&p->tcfc_act.list);
297 *a = &p->tcfc_act;
299 return 0; 298 return 0;
300} 299}
301EXPORT_SYMBOL(tcf_hash_create); 300EXPORT_SYMBOL(tcf_hash_create);
302 301
303void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a) 302void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a)
304{ 303{
305 struct tcf_common *p = a->priv; 304 struct tcf_common *p = (struct tcf_common *)a;
306 struct tcf_hashinfo *hinfo = tn->hinfo; 305 struct tcf_hashinfo *hinfo = tn->hinfo;
307 unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); 306 unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
308 307
@@ -315,10 +314,6 @@ EXPORT_SYMBOL(tcf_hash_insert);
315void tcf_hashinfo_destroy(const struct tc_action_ops *ops, 314void tcf_hashinfo_destroy(const struct tc_action_ops *ops,
316 struct tcf_hashinfo *hinfo) 315 struct tcf_hashinfo *hinfo)
317{ 316{
318 struct tc_action a = {
319 .ops = ops,
320 .hinfo = hinfo,
321 };
322 int i; 317 int i;
323 318
324 for (i = 0; i < hinfo->hmask + 1; i++) { 319 for (i = 0; i < hinfo->hmask + 1; i++) {
@@ -328,8 +323,7 @@ void tcf_hashinfo_destroy(const struct tc_action_ops *ops,
328 hlist_for_each_entry_safe(p, n, &hinfo->htab[i], tcfc_head) { 323 hlist_for_each_entry_safe(p, n, &hinfo->htab[i], tcfc_head) {
329 int ret; 324 int ret;
330 325
331 a.priv = p; 326 ret = __tcf_hash_release((struct tc_action *)p, false, true);
332 ret = __tcf_hash_release(&a, false, true);
333 if (ret == ACT_P_DELETED) 327 if (ret == ACT_P_DELETED)
334 module_put(ops->owner); 328 module_put(ops->owner);
335 else if (ret < 0) 329 else if (ret < 0)
@@ -466,8 +460,6 @@ int tcf_action_destroy(struct list_head *actions, int bind)
466 module_put(a->ops->owner); 460 module_put(a->ops->owner);
467 else if (ret < 0) 461 else if (ret < 0)
468 return ret; 462 return ret;
469 list_del(&a->list);
470 kfree(a);
471 } 463 }
472 return ret; 464 return ret;
473} 465}
@@ -581,20 +573,13 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
581 goto err_out; 573 goto err_out;
582 } 574 }
583 575
584 err = -ENOMEM;
585 a = kzalloc(sizeof(*a), GFP_KERNEL);
586 if (a == NULL)
587 goto err_mod;
588
589 a->ops = a_o;
590 INIT_LIST_HEAD(&a->list);
591 /* backward compatibility for policer */ 576 /* backward compatibility for policer */
592 if (name == NULL) 577 if (name == NULL)
593 err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, a, ovr, bind); 578 err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind);
594 else 579 else
595 err = a_o->init(net, nla, est, a, ovr, bind); 580 err = a_o->init(net, nla, est, &a, ovr, bind);
596 if (err < 0) 581 if (err < 0)
597 goto err_free; 582 goto err_mod;
598 583
599 /* module count goes up only when brand new policy is created 584 /* module count goes up only when brand new policy is created
600 * if it exists and is only bound to in a_o->init() then 585 * if it exists and is only bound to in a_o->init() then
@@ -605,8 +590,6 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
605 590
606 return a; 591 return a;
607 592
608err_free:
609 kfree(a);
610err_mod: 593err_mod:
611 module_put(a_o->owner); 594 module_put(a_o->owner);
612err_out: 595err_out:
@@ -647,7 +630,7 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
647{ 630{
648 int err = 0; 631 int err = 0;
649 struct gnet_dump d; 632 struct gnet_dump d;
650 struct tcf_common *p = a->priv; 633 struct tcf_common *p = (struct tcf_common *)a;
651 634
652 if (p == NULL) 635 if (p == NULL)
653 goto errout; 636 goto errout;
@@ -740,24 +723,11 @@ act_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
740 return rtnl_unicast(skb, net, portid); 723 return rtnl_unicast(skb, net, portid);
741} 724}
742 725
743static struct tc_action *create_a(int i)
744{
745 struct tc_action *act;
746
747 act = kzalloc(sizeof(*act), GFP_KERNEL);
748 if (act == NULL) {
749 pr_debug("create_a: failed to alloc!\n");
750 return NULL;
751 }
752 act->order = i;
753 INIT_LIST_HEAD(&act->list);
754 return act;
755}
756
757static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla, 726static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
758 struct nlmsghdr *n, u32 portid) 727 struct nlmsghdr *n, u32 portid)
759{ 728{
760 struct nlattr *tb[TCA_ACT_MAX + 1]; 729 struct nlattr *tb[TCA_ACT_MAX + 1];
730 const struct tc_action_ops *ops;
761 struct tc_action *a; 731 struct tc_action *a;
762 int index; 732 int index;
763 int err; 733 int err;
@@ -772,26 +742,19 @@ static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
772 goto err_out; 742 goto err_out;
773 index = nla_get_u32(tb[TCA_ACT_INDEX]); 743 index = nla_get_u32(tb[TCA_ACT_INDEX]);
774 744
775 err = -ENOMEM;
776 a = create_a(0);
777 if (a == NULL)
778 goto err_out;
779
780 err = -EINVAL; 745 err = -EINVAL;
781 a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); 746 ops = tc_lookup_action(tb[TCA_ACT_KIND]);
782 if (a->ops == NULL) /* could happen in batch of actions */ 747 if (!ops) /* could happen in batch of actions */
783 goto err_free; 748 goto err_out;
784 err = -ENOENT; 749 err = -ENOENT;
785 if (a->ops->lookup(net, a, index) == 0) 750 if (ops->lookup(net, &a, index) == 0)
786 goto err_mod; 751 goto err_mod;
787 752
788 module_put(a->ops->owner); 753 module_put(ops->owner);
789 return a; 754 return a;
790 755
791err_mod: 756err_mod:
792 module_put(a->ops->owner); 757 module_put(ops->owner);
793err_free:
794 kfree(a);
795err_out: 758err_out:
796 return ERR_PTR(err); 759 return ERR_PTR(err);
797} 760}
@@ -816,8 +779,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
816 struct netlink_callback dcb; 779 struct netlink_callback dcb;
817 struct nlattr *nest; 780 struct nlattr *nest;
818 struct nlattr *tb[TCA_ACT_MAX + 1]; 781 struct nlattr *tb[TCA_ACT_MAX + 1];
782 const struct tc_action_ops *ops;
819 struct nlattr *kind; 783 struct nlattr *kind;
820 struct tc_action a;
821 int err = -ENOMEM; 784 int err = -ENOMEM;
822 785
823 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 786 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
@@ -834,10 +797,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
834 797
835 err = -EINVAL; 798 err = -EINVAL;
836 kind = tb[TCA_ACT_KIND]; 799 kind = tb[TCA_ACT_KIND];
837 memset(&a, 0, sizeof(struct tc_action)); 800 ops = tc_lookup_action(kind);
838 INIT_LIST_HEAD(&a.list); 801 if (!ops) /*some idjot trying to flush unknown action */
839 a.ops = tc_lookup_action(kind);
840 if (a.ops == NULL) /*some idjot trying to flush unknown action */
841 goto err_out; 802 goto err_out;
842 803
843 nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION, 804 nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION,
@@ -853,7 +814,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
853 if (nest == NULL) 814 if (nest == NULL)
854 goto out_module_put; 815 goto out_module_put;
855 816
856 err = a.ops->walk(net, skb, &dcb, RTM_DELACTION, &a); 817 err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops);
857 if (err < 0) 818 if (err < 0)
858 goto out_module_put; 819 goto out_module_put;
859 if (err == 0) 820 if (err == 0)
@@ -863,7 +824,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
863 824
864 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 825 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
865 nlh->nlmsg_flags |= NLM_F_ROOT; 826 nlh->nlmsg_flags |= NLM_F_ROOT;
866 module_put(a.ops->owner); 827 module_put(ops->owner);
867 err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, 828 err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
868 n->nlmsg_flags & NLM_F_ECHO); 829 n->nlmsg_flags & NLM_F_ECHO);
869 if (err > 0) 830 if (err > 0)
@@ -872,7 +833,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
872 return err; 833 return err;
873 834
874out_module_put: 835out_module_put:
875 module_put(a.ops->owner); 836 module_put(ops->owner);
876err_out: 837err_out:
877noflush_out: 838noflush_out:
878 kfree_skb(skb); 839 kfree_skb(skb);
@@ -1084,7 +1045,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1084 unsigned char *b = skb_tail_pointer(skb); 1045 unsigned char *b = skb_tail_pointer(skb);
1085 struct nlattr *nest; 1046 struct nlattr *nest;
1086 struct tc_action_ops *a_o; 1047 struct tc_action_ops *a_o;
1087 struct tc_action a;
1088 int ret = 0; 1048 int ret = 0;
1089 struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh); 1049 struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
1090 struct nlattr *kind = find_dump_kind(cb->nlh); 1050 struct nlattr *kind = find_dump_kind(cb->nlh);
@@ -1098,9 +1058,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1098 if (a_o == NULL) 1058 if (a_o == NULL)
1099 return 0; 1059 return 0;
1100 1060
1101 memset(&a, 0, sizeof(struct tc_action));
1102 a.ops = a_o;
1103
1104 nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 1061 nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
1105 cb->nlh->nlmsg_type, sizeof(*t), 0); 1062 cb->nlh->nlmsg_type, sizeof(*t), 0);
1106 if (!nlh) 1063 if (!nlh)
@@ -1114,7 +1071,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1114 if (nest == NULL) 1071 if (nest == NULL)
1115 goto out_module_put; 1072 goto out_module_put;
1116 1073
1117 ret = a_o->walk(net, skb, cb, RTM_GETACTION, &a); 1074 ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o);
1118 if (ret < 0) 1075 if (ret < 0)
1119 goto out_module_put; 1076 goto out_module_put;
1120 1077