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 --- |