diff options
Diffstat (limited to 'net/sched/act_mirred.c')
-rw-r--r-- | net/sched/act_mirred.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 70cfbbf96af2..6038c85d92f5 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -52,9 +52,10 @@ static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | static int mirred_net_id; | 54 | static int mirred_net_id; |
55 | static struct tc_action_ops act_mirred_ops; | ||
55 | 56 | ||
56 | static int tcf_mirred_init(struct net *net, struct nlattr *nla, | 57 | static int tcf_mirred_init(struct net *net, struct nlattr *nla, |
57 | struct nlattr *est, struct tc_action *a, int ovr, | 58 | struct nlattr *est, struct tc_action **a, int ovr, |
58 | int bind) | 59 | int bind) |
59 | { | 60 | { |
60 | struct tc_action_net *tn = net_generic(net, mirred_net_id); | 61 | struct tc_action_net *tn = net_generic(net, mirred_net_id); |
@@ -84,14 +85,14 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, | |||
84 | break; | 85 | break; |
85 | default: | 86 | default: |
86 | if (exists) | 87 | if (exists) |
87 | tcf_hash_release(a, bind); | 88 | tcf_hash_release(*a, bind); |
88 | return -EINVAL; | 89 | return -EINVAL; |
89 | } | 90 | } |
90 | if (parm->ifindex) { | 91 | if (parm->ifindex) { |
91 | dev = __dev_get_by_index(net, parm->ifindex); | 92 | dev = __dev_get_by_index(net, parm->ifindex); |
92 | if (dev == NULL) { | 93 | if (dev == NULL) { |
93 | if (exists) | 94 | if (exists) |
94 | tcf_hash_release(a, bind); | 95 | tcf_hash_release(*a, bind); |
95 | return -ENODEV; | 96 | return -ENODEV; |
96 | } | 97 | } |
97 | switch (dev->type) { | 98 | switch (dev->type) { |
@@ -115,16 +116,16 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, | |||
115 | if (dev == NULL) | 116 | if (dev == NULL) |
116 | return -EINVAL; | 117 | return -EINVAL; |
117 | ret = tcf_hash_create(tn, parm->index, est, a, | 118 | ret = tcf_hash_create(tn, parm->index, est, a, |
118 | sizeof(*m), bind, true); | 119 | &act_mirred_ops, bind, true); |
119 | if (ret) | 120 | if (ret) |
120 | return ret; | 121 | return ret; |
121 | ret = ACT_P_CREATED; | 122 | ret = ACT_P_CREATED; |
122 | } else { | 123 | } else { |
123 | tcf_hash_release(a, bind); | 124 | tcf_hash_release(*a, bind); |
124 | if (!ovr) | 125 | if (!ovr) |
125 | return -EEXIST; | 126 | return -EEXIST; |
126 | } | 127 | } |
127 | m = to_mirred(a); | 128 | m = to_mirred(*a); |
128 | 129 | ||
129 | ASSERT_RTNL(); | 130 | ASSERT_RTNL(); |
130 | m->tcf_action = parm->action; | 131 | m->tcf_action = parm->action; |
@@ -142,7 +143,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, | |||
142 | spin_lock_bh(&mirred_list_lock); | 143 | spin_lock_bh(&mirred_list_lock); |
143 | list_add(&m->tcfm_list, &mirred_list); | 144 | list_add(&m->tcfm_list, &mirred_list); |
144 | spin_unlock_bh(&mirred_list_lock); | 145 | spin_unlock_bh(&mirred_list_lock); |
145 | tcf_hash_insert(tn, a); | 146 | tcf_hash_insert(tn, *a); |
146 | } | 147 | } |
147 | 148 | ||
148 | return ret; | 149 | return ret; |
@@ -151,7 +152,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, | |||
151 | static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, | 152 | static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, |
152 | struct tcf_result *res) | 153 | struct tcf_result *res) |
153 | { | 154 | { |
154 | struct tcf_mirred *m = a->priv; | 155 | struct tcf_mirred *m = to_mirred(a); |
155 | struct net_device *dev; | 156 | struct net_device *dev; |
156 | struct sk_buff *skb2; | 157 | struct sk_buff *skb2; |
157 | int retval, err; | 158 | int retval, err; |
@@ -206,7 +207,7 @@ out: | |||
206 | static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | 207 | static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) |
207 | { | 208 | { |
208 | unsigned char *b = skb_tail_pointer(skb); | 209 | unsigned char *b = skb_tail_pointer(skb); |
209 | struct tcf_mirred *m = a->priv; | 210 | struct tcf_mirred *m = to_mirred(a); |
210 | struct tc_mirred opt = { | 211 | struct tc_mirred opt = { |
211 | .index = m->tcf_index, | 212 | .index = m->tcf_index, |
212 | .action = m->tcf_action, | 213 | .action = m->tcf_action, |
@@ -232,14 +233,14 @@ nla_put_failure: | |||
232 | 233 | ||
233 | static int tcf_mirred_walker(struct net *net, struct sk_buff *skb, | 234 | static int tcf_mirred_walker(struct net *net, struct sk_buff *skb, |
234 | struct netlink_callback *cb, int type, | 235 | struct netlink_callback *cb, int type, |
235 | struct tc_action *a) | 236 | const struct tc_action_ops *ops) |
236 | { | 237 | { |
237 | struct tc_action_net *tn = net_generic(net, mirred_net_id); | 238 | struct tc_action_net *tn = net_generic(net, mirred_net_id); |
238 | 239 | ||
239 | return tcf_generic_walker(tn, skb, cb, type, a); | 240 | return tcf_generic_walker(tn, skb, cb, type, ops); |
240 | } | 241 | } |
241 | 242 | ||
242 | static int tcf_mirred_search(struct net *net, struct tc_action *a, u32 index) | 243 | static int tcf_mirred_search(struct net *net, struct tc_action **a, u32 index) |
243 | { | 244 | { |
244 | struct tc_action_net *tn = net_generic(net, mirred_net_id); | 245 | struct tc_action_net *tn = net_generic(net, mirred_net_id); |
245 | 246 | ||
@@ -284,6 +285,7 @@ static struct tc_action_ops act_mirred_ops = { | |||
284 | .init = tcf_mirred_init, | 285 | .init = tcf_mirred_init, |
285 | .walk = tcf_mirred_walker, | 286 | .walk = tcf_mirred_walker, |
286 | .lookup = tcf_mirred_search, | 287 | .lookup = tcf_mirred_search, |
288 | .size = sizeof(struct tcf_mirred), | ||
287 | }; | 289 | }; |
288 | 290 | ||
289 | static __net_init int mirred_init_net(struct net *net) | 291 | static __net_init int mirred_init_net(struct net *net) |