act_skbedit.c (ed2ef29100644eabc6099cbf1a3aa9d938555ab8) act_skbedit.c (6d7a8df6dfe4d62335673fb15407d79180a33ea2)
1/*
2 * Copyright (c) 2008, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT

--- 85 unchanged lines hidden (view full) ---

94};
95
96static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
97 struct nlattr *est, struct tc_action **a,
98 int ovr, int bind, bool rtnl_held,
99 struct netlink_ext_ack *extack)
100{
101 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
1/*
2 * Copyright (c) 2008, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT

--- 85 unchanged lines hidden (view full) ---

94};
95
96static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
97 struct nlattr *est, struct tc_action **a,
98 int ovr, int bind, bool rtnl_held,
99 struct netlink_ext_ack *extack)
100{
101 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
102 struct tcf_skbedit_params *params_old, *params_new;
102 struct tcf_skbedit_params *params_new;
103 struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
104 struct tc_skbedit *parm;
105 struct tcf_skbedit *d;
106 u32 flags = 0, *priority = NULL, *mark = NULL, *mask = NULL;
107 u16 *queue_mapping = NULL, *ptype = NULL;
108 bool exists = false;
109 int ret = 0, err;
110

--- 71 unchanged lines hidden (view full) ---

182 } else {
183 d = to_skbedit(*a);
184 if (!ovr) {
185 tcf_idr_release(*a, bind);
186 return -EEXIST;
187 }
188 }
189
103 struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
104 struct tc_skbedit *parm;
105 struct tcf_skbedit *d;
106 u32 flags = 0, *priority = NULL, *mark = NULL, *mask = NULL;
107 u16 *queue_mapping = NULL, *ptype = NULL;
108 bool exists = false;
109 int ret = 0, err;
110

--- 71 unchanged lines hidden (view full) ---

182 } else {
183 d = to_skbedit(*a);
184 if (!ovr) {
185 tcf_idr_release(*a, bind);
186 return -EEXIST;
187 }
188 }
189
190 ASSERT_RTNL();
191
192 params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
193 if (unlikely(!params_new)) {
194 if (ret == ACT_P_CREATED)
195 tcf_idr_release(*a, bind);
196 return -ENOMEM;
197 }
198
199 params_new->flags = flags;

--- 5 unchanged lines hidden (view full) ---

205 params_new->mark = *mark;
206 if (flags & SKBEDIT_F_PTYPE)
207 params_new->ptype = *ptype;
208 /* default behaviour is to use all the bits */
209 params_new->mask = 0xffffffff;
210 if (flags & SKBEDIT_F_MASK)
211 params_new->mask = *mask;
212
190 params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
191 if (unlikely(!params_new)) {
192 if (ret == ACT_P_CREATED)
193 tcf_idr_release(*a, bind);
194 return -ENOMEM;
195 }
196
197 params_new->flags = flags;

--- 5 unchanged lines hidden (view full) ---

203 params_new->mark = *mark;
204 if (flags & SKBEDIT_F_PTYPE)
205 params_new->ptype = *ptype;
206 /* default behaviour is to use all the bits */
207 params_new->mask = 0xffffffff;
208 if (flags & SKBEDIT_F_MASK)
209 params_new->mask = *mask;
210
211 spin_lock_bh(&d->tcf_lock);
213 d->tcf_action = parm->action;
212 d->tcf_action = parm->action;
214 params_old = rtnl_dereference(d->params);
215 rcu_assign_pointer(d->params, params_new);
216 if (params_old)
217 kfree_rcu(params_old, rcu);
213 rcu_swap_protected(d->params, params_new,
214 lockdep_is_held(&d->tcf_lock));
215 spin_unlock_bh(&d->tcf_lock);
216 if (params_new)
217 kfree_rcu(params_new, rcu);
218
219 if (ret == ACT_P_CREATED)
220 tcf_idr_insert(tn, *a);
221 return ret;
222}
223
224static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
225 int bind, int ref)
226{
227 unsigned char *b = skb_tail_pointer(skb);
228 struct tcf_skbedit *d = to_skbedit(a);
229 struct tcf_skbedit_params *params;
230 struct tc_skbedit opt = {
231 .index = d->tcf_index,
232 .refcnt = refcount_read(&d->tcf_refcnt) - ref,
233 .bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
218
219 if (ret == ACT_P_CREATED)
220 tcf_idr_insert(tn, *a);
221 return ret;
222}
223
224static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
225 int bind, int ref)
226{
227 unsigned char *b = skb_tail_pointer(skb);
228 struct tcf_skbedit *d = to_skbedit(a);
229 struct tcf_skbedit_params *params;
230 struct tc_skbedit opt = {
231 .index = d->tcf_index,
232 .refcnt = refcount_read(&d->tcf_refcnt) - ref,
233 .bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
234 .action = d->tcf_action,
235 };
236 u64 pure_flags = 0;
237 struct tcf_t t;
238
234 };
235 u64 pure_flags = 0;
236 struct tcf_t t;
237
239 params = rtnl_dereference(d->params);
238 spin_lock_bh(&d->tcf_lock);
239 params = rcu_dereference_protected(d->params,
240 lockdep_is_held(&d->tcf_lock));
241 opt.action = d->tcf_action;
240
241 if (nla_put(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt))
242 goto nla_put_failure;
243 if ((params->flags & SKBEDIT_F_PRIORITY) &&
244 nla_put_u32(skb, TCA_SKBEDIT_PRIORITY, params->priority))
245 goto nla_put_failure;
246 if ((params->flags & SKBEDIT_F_QUEUE_MAPPING) &&
247 nla_put_u16(skb, TCA_SKBEDIT_QUEUE_MAPPING, params->queue_mapping))

--- 11 unchanged lines hidden (view full) ---

259 pure_flags |= SKBEDIT_F_INHERITDSFIELD;
260 if (pure_flags != 0 &&
261 nla_put(skb, TCA_SKBEDIT_FLAGS, sizeof(pure_flags), &pure_flags))
262 goto nla_put_failure;
263
264 tcf_tm_dump(&t, &d->tcf_tm);
265 if (nla_put_64bit(skb, TCA_SKBEDIT_TM, sizeof(t), &t, TCA_SKBEDIT_PAD))
266 goto nla_put_failure;
242
243 if (nla_put(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt))
244 goto nla_put_failure;
245 if ((params->flags & SKBEDIT_F_PRIORITY) &&
246 nla_put_u32(skb, TCA_SKBEDIT_PRIORITY, params->priority))
247 goto nla_put_failure;
248 if ((params->flags & SKBEDIT_F_QUEUE_MAPPING) &&
249 nla_put_u16(skb, TCA_SKBEDIT_QUEUE_MAPPING, params->queue_mapping))

--- 11 unchanged lines hidden (view full) ---

261 pure_flags |= SKBEDIT_F_INHERITDSFIELD;
262 if (pure_flags != 0 &&
263 nla_put(skb, TCA_SKBEDIT_FLAGS, sizeof(pure_flags), &pure_flags))
264 goto nla_put_failure;
265
266 tcf_tm_dump(&t, &d->tcf_tm);
267 if (nla_put_64bit(skb, TCA_SKBEDIT_TM, sizeof(t), &t, TCA_SKBEDIT_PAD))
268 goto nla_put_failure;
269 spin_unlock_bh(&d->tcf_lock);
270
267 return skb->len;
268
269nla_put_failure:
271 return skb->len;
272
273nla_put_failure:
274 spin_unlock_bh(&d->tcf_lock);
270 nlmsg_trim(skb, b);
271 return -1;
272}
273
274static void tcf_skbedit_cleanup(struct tc_action *a)
275{
276 struct tcf_skbedit *d = to_skbedit(a);
277 struct tcf_skbedit_params *params;

--- 8 unchanged lines hidden (view full) ---

286 const struct tc_action_ops *ops,
287 struct netlink_ext_ack *extack)
288{
289 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
290
291 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
292}
293
275 nlmsg_trim(skb, b);
276 return -1;
277}
278
279static void tcf_skbedit_cleanup(struct tc_action *a)
280{
281 struct tcf_skbedit *d = to_skbedit(a);
282 struct tcf_skbedit_params *params;

--- 8 unchanged lines hidden (view full) ---

291 const struct tc_action_ops *ops,
292 struct netlink_ext_ack *extack)
293{
294 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
295
296 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
297}
298
294static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index,
295 struct netlink_ext_ack *extack)
299static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index)
296{
297 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
298
299 return tcf_idr_search(tn, a, index);
300}
301
302static struct tc_action_ops act_skbedit_ops = {
303 .kind = "skbedit",

--- 46 unchanged lines hidden ---
300{
301 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
302
303 return tcf_idr_search(tn, a, index);
304}
305
306static struct tc_action_ops act_skbedit_ops = {
307 .kind = "skbedit",

--- 46 unchanged lines hidden ---