84 #include <linux/module.h>
85 #include <linux/slab.h>
86 #include <linux/types.h>
87 #include <linux/kernel.h>
88 #include <linux/errno.h>
89 #include <linux/rtnetlink.h>
96 static struct tcf_ematch_ops *tcf_em_lookup(
u16 kind)
98 struct tcf_ematch_ops *
e =
NULL;
102 if (kind == e->kind) {
103 if (!try_module_get(e->owner))
129 struct tcf_ematch_ops *
e;
131 if (ops->match ==
NULL)
136 if (ops->kind == e->kind)
169 return &tree->matches[
index];
173 static int tcf_em_validate(
struct tcf_proto *tp,
179 int data_len = nla_len(nla) -
sizeof(*em_hdr);
180 void *
data = (
void *) em_hdr +
sizeof(*em_hdr);
191 if (data_len <
sizeof(ref))
215 em->ops = tcf_em_lookup(em_hdr->
kind);
217 if (em->ops ==
NULL) {
219 #ifdef CONFIG_MODULES
221 request_module(
"ematch-kind-%u", em_hdr->
kind);
223 em->ops = tcf_em_lookup(em_hdr->
kind);
229 module_put(em->ops->owner);
239 if (em->ops->datalen && data_len < em->
ops->datalen)
242 if (em->ops->change) {
243 err = em->ops->change(tp, data, data_len, em);
246 }
else if (data_len > 0) {
257 if (data_len <
sizeof(
u32))
259 em->data = *(
u32 *) data;
266 em->data = (
unsigned long) v;
272 em->flags = em_hdr->
flags;
306 struct nlattr *rt_match, *rt_hdr, *rt_list;
308 struct tcf_ematch *
em;
310 memset(tree, 0,
sizeof(*tree));
322 if (rt_hdr ==
NULL || rt_list ==
NULL)
325 tree_hdr = nla_data(rt_hdr);
326 memcpy(&tree->hdr, tree_hdr,
sizeof(*tree_hdr));
328 rt_match = nla_data(rt_list);
329 list_len = nla_len(rt_list);
330 matches_len = tree_hdr->
nmatches *
sizeof(*em);
332 tree->matches = kzalloc(matches_len,
GFP_KERNEL);
333 if (tree->matches ==
NULL)
345 for (idx = 0; nla_ok(rt_match, list_len); idx++) {
348 if (rt_match->
nla_type != (idx + 1))
357 em = tcf_em_get_match(tree, idx);
359 err = tcf_em_validate(tp, tree_hdr, em, rt_match, idx);
363 rt_match = nla_next(rt_match, &list_len);
400 if (tree->matches ==
NULL)
403 for (i = 0; i < tree->hdr.nmatches; i++) {
404 struct tcf_ematch *em = tcf_em_get_match(tree, i);
407 if (em->ops->destroy)
408 em->ops->destroy(tp, em);
409 else if (!tcf_em_is_simple(em))
410 kfree((
void *) em->data);
411 module_put(em->ops->owner);
415 tree->hdr.nmatches = 0;
416 kfree(tree->matches);
417 tree->matches =
NULL;
438 struct nlattr *list_start;
440 top_start = nla_nest_start(skb, tlv);
441 if (top_start ==
NULL)
442 goto nla_put_failure;
445 goto nla_put_failure;
448 if (list_start ==
NULL)
449 goto nla_put_failure;
451 tail = skb_tail_pointer(skb);
452 for (i = 0; i < tree->hdr.nmatches; i++) {
454 struct tcf_ematch *em = tcf_em_get_match(tree, i);
457 .matchid = em->matchid,
461 if (
nla_put(skb, i + 1,
sizeof(em_hdr), &em_hdr))
462 goto nla_put_failure;
464 if (em->ops && em->ops->dump) {
465 if (em->ops->dump(skb, em) < 0)
466 goto nla_put_failure;
467 }
else if (tcf_em_is_container(em) || tcf_em_is_simple(em)) {
470 }
else if (em->datalen > 0)
473 tail = skb_tail_pointer(skb);
474 match_start->
nla_len = tail - (
u8 *)match_start;
477 nla_nest_end(skb, list_start);
478 nla_nest_end(skb, top_start);
487 static inline int tcf_em_match(
struct sk_buff *
skb,
struct tcf_ematch *em,
490 int r = em->ops->match(skb, em, info);
492 return tcf_em_is_inverted(em) ? !r :
r;
499 int stackp = 0, match_idx = 0,
res = 0;
500 struct tcf_ematch *cur_match;
501 int stack[CONFIG_NET_EMATCH_STACK];
504 while (match_idx < tree->
hdr.nmatches) {
505 cur_match = tcf_em_get_match(tree, match_idx);
507 if (tcf_em_is_container(cur_match)) {
508 if (
unlikely(stackp >= CONFIG_NET_EMATCH_STACK))
511 stack[stackp++] = match_idx;
512 match_idx = cur_match->data;
516 res = tcf_em_match(skb, cur_match, info);
518 if (tcf_em_early_end(cur_match,
res))
526 match_idx = stack[--stackp];
527 cur_match = tcf_em_get_match(tree, match_idx);
529 if (tcf_em_early_end(cur_match,
res))