Lines Matching +full:unlock +full:- +full:keys
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Authors: Jamal Hadi Salim (2002-4)
44 int err = -EINVAL; in tcf_pedit_keys_ex_parse()
52 return ERR_PTR(-ENOMEM); in tcf_pedit_keys_ex_parse()
60 err = -EINVAL; in tcf_pedit_keys_ex_parse()
63 n--; in tcf_pedit_keys_ex_parse()
66 err = -EINVAL; in tcf_pedit_keys_ex_parse()
78 err = -EINVAL; in tcf_pedit_keys_ex_parse()
82 k->htype = nla_get_u16(tb[TCA_PEDIT_KEY_EX_HTYPE]); in tcf_pedit_keys_ex_parse()
83 k->cmd = nla_get_u16(tb[TCA_PEDIT_KEY_EX_CMD]); in tcf_pedit_keys_ex_parse()
85 if (k->htype > TCA_PEDIT_HDR_TYPE_MAX || in tcf_pedit_keys_ex_parse()
86 k->cmd > TCA_PEDIT_CMD_MAX) { in tcf_pedit_keys_ex_parse()
87 err = -EINVAL; in tcf_pedit_keys_ex_parse()
95 err = -EINVAL; in tcf_pedit_keys_ex_parse()
114 for (; n > 0; n--) { in tcf_pedit_key_ex_dump()
121 if (nla_put_u16(skb, TCA_PEDIT_KEY_EX_HTYPE, keys_ex->htype) || in tcf_pedit_key_ex_dump()
122 nla_put_u16(skb, TCA_PEDIT_KEY_EX_CMD, keys_ex->cmd)) in tcf_pedit_key_ex_dump()
135 return -EINVAL; in tcf_pedit_key_ex_dump()
147 struct tc_pedit_key *keys = NULL; in tcf_pedit_init() local
158 return -EINVAL; in tcf_pedit_init()
171 return -EINVAL; in tcf_pedit_init()
175 if (!parm->nkeys) { in tcf_pedit_init()
176 NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed"); in tcf_pedit_init()
177 return -EINVAL; in tcf_pedit_init()
179 ksize = parm->nkeys * sizeof(struct tc_pedit_key); in tcf_pedit_init()
182 return -EINVAL; in tcf_pedit_init()
185 keys_ex = tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys); in tcf_pedit_init()
189 index = parm->index; in tcf_pedit_init()
203 ret = -EEXIST; in tcf_pedit_init()
211 err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack); in tcf_pedit_init()
217 spin_lock_bh(&p->tcf_lock); in tcf_pedit_init()
220 (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys)) { in tcf_pedit_init()
221 keys = kmalloc(ksize, GFP_ATOMIC); in tcf_pedit_init()
222 if (!keys) { in tcf_pedit_init()
223 spin_unlock_bh(&p->tcf_lock); in tcf_pedit_init()
224 ret = -ENOMEM; in tcf_pedit_init()
227 kfree(p->tcfp_keys); in tcf_pedit_init()
228 p->tcfp_keys = keys; in tcf_pedit_init()
229 p->tcfp_nkeys = parm->nkeys; in tcf_pedit_init()
231 memcpy(p->tcfp_keys, parm->keys, ksize); in tcf_pedit_init()
232 p->tcfp_off_max_hint = 0; in tcf_pedit_init()
233 for (i = 0; i < p->tcfp_nkeys; ++i) { in tcf_pedit_init()
234 u32 cur = p->tcfp_keys[i].off; in tcf_pedit_init()
237 p->tcfp_keys[i].shift = min_t(size_t, BITS_PER_TYPE(int) - 1, in tcf_pedit_init()
238 p->tcfp_keys[i].shift); in tcf_pedit_init()
243 cur += (0xff & p->tcfp_keys[i].offmask) >> p->tcfp_keys[i].shift; in tcf_pedit_init()
246 p->tcfp_off_max_hint = max(p->tcfp_off_max_hint, cur + 4); in tcf_pedit_init()
249 p->tcfp_flags = parm->flags; in tcf_pedit_init()
250 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); in tcf_pedit_init()
252 kfree(p->tcfp_keys_ex); in tcf_pedit_init()
253 p->tcfp_keys_ex = keys_ex; in tcf_pedit_init()
255 spin_unlock_bh(&p->tcf_lock); in tcf_pedit_init()
274 struct tc_pedit_key *keys = p->tcfp_keys; in tcf_pedit_cleanup() local
276 kfree(keys); in tcf_pedit_cleanup()
277 kfree(p->tcfp_keys_ex); in tcf_pedit_cleanup()
282 if (offset > 0 && offset > skb->len) in offset_valid()
285 if (offset < 0 && -offset > skb_headroom(skb)) in offset_valid()
294 int ret = -EINVAL; in pedit_skb_hdr_offset()
317 ret = -EINVAL; in pedit_skb_hdr_offset()
331 spin_lock(&p->tcf_lock); in tcf_pedit_act()
336 p->tcfp_off_max_hint; in tcf_pedit_act()
337 if (skb_ensure_writable(skb, min(skb->len, max_offset))) in tcf_pedit_act()
338 goto unlock; in tcf_pedit_act()
340 tcf_lastuse_update(&p->tcf_tm); in tcf_pedit_act()
342 if (p->tcfp_nkeys > 0) { in tcf_pedit_act()
343 struct tc_pedit_key *tkey = p->tcfp_keys; in tcf_pedit_act()
344 struct tcf_pedit_key_ex *tkey_ex = p->tcfp_keys_ex; in tcf_pedit_act()
349 for (i = p->tcfp_nkeys; i > 0; i--, tkey++) { in tcf_pedit_act()
351 int offset = tkey->off; in tcf_pedit_act()
357 htype = tkey_ex->htype; in tcf_pedit_act()
358 cmd = tkey_ex->cmd; in tcf_pedit_act()
370 if (tkey->offmask) { in tcf_pedit_act()
373 if (!offset_valid(skb, hoffset + tkey->at)) { in tcf_pedit_act()
375 hoffset + tkey->at); in tcf_pedit_act()
378 d = skb_header_pointer(skb, hoffset + tkey->at, in tcf_pedit_act()
382 offset += (*d & tkey->offmask) >> tkey->shift; in tcf_pedit_act()
403 val = tkey->val; in tcf_pedit_act()
406 val = (*ptr + tkey->val) & ~tkey->mask; in tcf_pedit_act()
414 *ptr = ((*ptr & tkey->mask) ^ val); in tcf_pedit_act()
421 WARN(1, "pedit BUG: index %d\n", p->tcf_index); in tcf_pedit_act()
425 p->tcf_qstats.overlimits++; in tcf_pedit_act()
427 bstats_update(&p->tcf_bstats, skb); in tcf_pedit_act()
428 unlock: in tcf_pedit_act()
429 spin_unlock(&p->tcf_lock); in tcf_pedit_act()
430 return p->tcf_action; in tcf_pedit_act()
437 struct tcf_t *tm = &d->tcf_tm; in tcf_pedit_stats_update()
440 tm->lastuse = max_t(u64, tm->lastuse, lastuse); in tcf_pedit_stats_update()
452 s = struct_size(opt, keys, p->tcfp_nkeys); in tcf_pedit_dump()
454 /* netlink spinlocks held above us - must use ATOMIC */ in tcf_pedit_dump()
457 return -ENOBUFS; in tcf_pedit_dump()
459 spin_lock_bh(&p->tcf_lock); in tcf_pedit_dump()
460 memcpy(opt->keys, p->tcfp_keys, flex_array_size(opt, keys, p->tcfp_nkeys)); in tcf_pedit_dump()
461 opt->index = p->tcf_index; in tcf_pedit_dump()
462 opt->nkeys = p->tcfp_nkeys; in tcf_pedit_dump()
463 opt->flags = p->tcfp_flags; in tcf_pedit_dump()
464 opt->action = p->tcf_action; in tcf_pedit_dump()
465 opt->refcnt = refcount_read(&p->tcf_refcnt) - ref; in tcf_pedit_dump()
466 opt->bindcnt = atomic_read(&p->tcf_bindcnt) - bind; in tcf_pedit_dump()
468 if (p->tcfp_keys_ex) { in tcf_pedit_dump()
470 p->tcfp_keys_ex, in tcf_pedit_dump()
471 p->tcfp_nkeys)) in tcf_pedit_dump()
481 tcf_tm_dump(&t, &p->tcf_tm); in tcf_pedit_dump()
484 spin_unlock_bh(&p->tcf_lock); in tcf_pedit_dump()
487 return skb->len; in tcf_pedit_dump()
490 spin_unlock_bh(&p->tcf_lock); in tcf_pedit_dump()
493 return -1; in tcf_pedit_dump()
546 MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");