Lines Matching +full:in +full:- +full:tree

1 // SPDX-License-Identifier: GPL-2.0-or-later
18 * causing the current position in the sequence to be pushed onto a stack
20 * in the special ematch. Matching continues in the new sequence until a
26 * ------->-PUSH-------
27 * -->-- / -->-- \ -->--
29 * +-------+-------+-------+-------+-------+--------+
31 * +-------+-------+-------+-------+-------+--------+
33 * --------<-POP---------
39 * How to write an ematch in 60 seconds
40 * ------------------------------------
46 * struct mydata *d = (struct mydata *) m->data;
98 if (kind == e->kind) { in tcf_em_lookup()
99 if (!try_module_get(e->owner)) in tcf_em_lookup()
111 * tcf_em_register - register an extended match
120 * Returns -EEXISTS if an ematch of the same kind has already registered.
124 int err = -EEXIST; in tcf_em_register()
127 if (ops->match == NULL) in tcf_em_register()
128 return -EINVAL; in tcf_em_register()
132 if (ops->kind == e->kind) in tcf_em_register()
135 list_add_tail(&ops->link, &ematch_ops); in tcf_em_register()
144 * tcf_em_unregister - unregister and extended match
152 * Returns -ENOENT if no matching ematch was found.
157 list_del(&ops->link); in tcf_em_unregister()
162 static inline struct tcf_ematch *tcf_em_get_match(struct tcf_ematch_tree *tree, in tcf_em_get_match() argument
165 return &tree->matches[index]; in tcf_em_get_match()
173 int err = -EINVAL; in tcf_em_validate()
175 int data_len = nla_len(nla) - sizeof(*em_hdr); in tcf_em_validate()
177 struct net *net = tp->chain->block->net; in tcf_em_validate()
179 if (!TCF_EM_REL_VALID(em_hdr->flags)) in tcf_em_validate()
182 if (em_hdr->kind == TCF_EM_CONTAINER) { in tcf_em_validate()
192 if (ref >= tree_hdr->nmatches) in tcf_em_validate()
202 em->data = ref; in tcf_em_validate()
205 * of the ematch module referenced. In case of a failure, in tcf_em_validate()
212 em->ops = tcf_em_lookup(em_hdr->kind); in tcf_em_validate()
214 if (em->ops == NULL) { in tcf_em_validate()
215 err = -ENOENT; in tcf_em_validate()
218 request_module("ematch-kind-%u", em_hdr->kind); in tcf_em_validate()
220 em->ops = tcf_em_lookup(em_hdr->kind); in tcf_em_validate()
221 if (em->ops) { in tcf_em_validate()
222 /* We dropped the RTNL mutex in order to in tcf_em_validate()
226 module_put(em->ops->owner); in tcf_em_validate()
227 em->ops = NULL; in tcf_em_validate()
228 err = -EAGAIN; in tcf_em_validate()
237 if (em->ops->datalen && data_len < em->ops->datalen) in tcf_em_validate()
240 if (em->ops->change) { in tcf_em_validate()
241 err = -EINVAL; in tcf_em_validate()
242 if (em_hdr->flags & TCF_EM_SIMPLE) in tcf_em_validate()
244 err = em->ops->change(net, data, data_len, em); in tcf_em_validate()
257 if (em_hdr->flags & TCF_EM_SIMPLE) { in tcf_em_validate()
258 if (em->ops->datalen > 0) in tcf_em_validate()
262 em->data = *(u32 *) data; in tcf_em_validate()
266 err = -ENOBUFS; in tcf_em_validate()
269 em->data = (unsigned long) v; in tcf_em_validate()
271 em->datalen = data_len; in tcf_em_validate()
275 em->matchid = em_hdr->matchid; in tcf_em_validate()
276 em->flags = em_hdr->flags; in tcf_em_validate()
277 em->net = net; in tcf_em_validate()
290 * tcf_em_tree_validate - validate ematch config TLV and build ematch tree
293 * @nla: ematch tree configuration TLV
294 * @tree: destination ematch tree variable to store the resulting
295 * ematch tree.
298 * ematch tree in @tree. The resulting tree must later be copied into
300 * provide the ematch tree variable of the private classifier data directly,
306 struct tcf_ematch_tree *tree) in tcf_em_tree_validate() argument
314 memset(tree, 0, sizeof(*tree)); in tcf_em_tree_validate()
323 err = -EINVAL; in tcf_em_tree_validate()
331 memcpy(&tree->hdr, tree_hdr, sizeof(*tree_hdr)); in tcf_em_tree_validate()
335 matches_len = tree_hdr->nmatches * sizeof(*em); in tcf_em_tree_validate()
337 tree->matches = kzalloc(matches_len, GFP_KERNEL); in tcf_em_tree_validate()
338 if (tree->matches == NULL) in tcf_em_tree_validate()
345 * The array of rt attributes is parsed in the order as they are in tcf_em_tree_validate()
348 * to this policy will result in parsing failure. in tcf_em_tree_validate()
351 err = -EINVAL; in tcf_em_tree_validate()
353 if (rt_match->nla_type != (idx + 1)) in tcf_em_tree_validate()
356 if (idx >= tree_hdr->nmatches) in tcf_em_tree_validate()
362 em = tcf_em_get_match(tree, idx); in tcf_em_tree_validate()
376 if (idx != tree_hdr->nmatches) { in tcf_em_tree_validate()
377 err = -EINVAL; in tcf_em_tree_validate()
386 tcf_em_tree_destroy(tree); in tcf_em_tree_validate()
392 * tcf_em_tree_destroy - destroy an ematch tree
394 * @tree: ematch tree to be deleted
396 * This functions destroys an ematch tree previously created by
398 * the ematch tree is not in use before calling this function.
400 void tcf_em_tree_destroy(struct tcf_ematch_tree *tree) in tcf_em_tree_destroy() argument
404 if (tree->matches == NULL) in tcf_em_tree_destroy()
407 for (i = 0; i < tree->hdr.nmatches; i++) { in tcf_em_tree_destroy()
408 struct tcf_ematch *em = tcf_em_get_match(tree, i); in tcf_em_tree_destroy()
410 if (em->ops) { in tcf_em_tree_destroy()
411 if (em->ops->destroy) in tcf_em_tree_destroy()
412 em->ops->destroy(em); in tcf_em_tree_destroy()
414 kfree((void *) em->data); in tcf_em_tree_destroy()
415 module_put(em->ops->owner); in tcf_em_tree_destroy()
419 tree->hdr.nmatches = 0; in tcf_em_tree_destroy()
420 kfree(tree->matches); in tcf_em_tree_destroy()
421 tree->matches = NULL; in tcf_em_tree_destroy()
426 * tcf_em_tree_dump - dump ematch tree into a rtnl message
429 * @tree: ematch tree to be dumped
430 * @tlv: TLV type to be used to encapsulate the tree
432 * This function dumps a ematch tree into a rtnl message. It is valid to
433 * call this function while the ematch tree is in use.
435 * Returns -1 if the skb tailroom is insufficient.
437 int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv) in tcf_em_tree_dump() argument
448 if (nla_put(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr)) in tcf_em_tree_dump()
456 for (i = 0; i < tree->hdr.nmatches; i++) { in tcf_em_tree_dump()
458 struct tcf_ematch *em = tcf_em_get_match(tree, i); in tcf_em_tree_dump()
460 .kind = em->ops ? em->ops->kind : TCF_EM_CONTAINER, in tcf_em_tree_dump()
461 .matchid = em->matchid, in tcf_em_tree_dump()
462 .flags = em->flags in tcf_em_tree_dump()
468 if (em->ops && em->ops->dump) { in tcf_em_tree_dump()
469 if (em->ops->dump(skb, em) < 0) in tcf_em_tree_dump()
472 u32 u = em->data; in tcf_em_tree_dump()
474 } else if (em->datalen > 0) in tcf_em_tree_dump()
475 nla_put_nohdr(skb, em->datalen, (void *) em->data); in tcf_em_tree_dump()
478 match_start->nla_len = tail - (u8 *)match_start; in tcf_em_tree_dump()
487 return -1; in tcf_em_tree_dump()
494 int r = em->ops->match(skb, em, info); in tcf_em_match()
500 int __tcf_em_tree_match(struct sk_buff *skb, struct tcf_ematch_tree *tree, in __tcf_em_tree_match() argument
508 while (match_idx < tree->hdr.nmatches) { in __tcf_em_tree_match()
509 cur_match = tcf_em_get_match(tree, match_idx); in __tcf_em_tree_match()
516 match_idx = cur_match->data; in __tcf_em_tree_match()
530 match_idx = stack[--stackp]; in __tcf_em_tree_match()
531 cur_match = tcf_em_get_match(tree, match_idx); in __tcf_em_tree_match()
548 return -1; in __tcf_em_tree_match()