2 * net/sched/em_text.c Textsearch ematch
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Thomas Graf <tgraf@suug.ch>
12 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <linux/kernel.h>
15 #include <linux/string.h>
16 #include <linux/skbuff.h>
17 #include <linux/textsearch.h>
18 #include <linux/tc_ematch/tc_em_text.h>
19 #include <net/pkt_cls.h>
27 struct ts_config
*config
;
30 #define EM_TEXT_PRIV(m) ((struct text_match *) (m)->data)
32 static int em_text_match(struct sk_buff
*skb
, struct tcf_ematch
*m
,
33 struct tcf_pkt_info
*info
)
35 struct text_match
*tm
= EM_TEXT_PRIV(m
);
37 struct ts_state state
;
39 from
= tcf_get_base_ptr(skb
, tm
->from_layer
) - skb
->data
;
40 from
+= tm
->from_offset
;
42 to
= tcf_get_base_ptr(skb
, tm
->to_layer
) - skb
->data
;
45 return skb_find_text(skb
, from
, to
, tm
->config
, &state
) != UINT_MAX
;
48 static int em_text_change(struct tcf_proto
*tp
, void *data
, int len
,
51 struct text_match
*tm
;
52 struct tcf_em_text
*conf
= data
;
53 struct ts_config
*ts_conf
;
56 if (len
< sizeof(*conf
) || len
< (sizeof(*conf
) + conf
->pattern_len
))
59 if (conf
->from_layer
> conf
->to_layer
)
62 if (conf
->from_layer
== conf
->to_layer
&&
63 conf
->from_offset
> conf
->to_offset
)
67 ts_conf
= textsearch_prepare(conf
->algo
, (u8
*) conf
+ sizeof(*conf
),
68 conf
->pattern_len
, GFP_KERNEL
, flags
);
70 if (flags
& TS_AUTOLOAD
)
73 if (IS_ERR(ts_conf
)) {
74 if (PTR_ERR(ts_conf
) == -ENOENT
&& !(flags
& TS_AUTOLOAD
)) {
79 return PTR_ERR(ts_conf
);
80 } else if (flags
& TS_AUTOLOAD
) {
81 textsearch_destroy(ts_conf
);
85 tm
= kmalloc(sizeof(*tm
), GFP_KERNEL
);
87 textsearch_destroy(ts_conf
);
91 tm
->from_offset
= conf
->from_offset
;
92 tm
->to_offset
= conf
->to_offset
;
93 tm
->from_layer
= conf
->from_layer
;
94 tm
->to_layer
= conf
->to_layer
;
97 m
->datalen
= sizeof(*tm
);
98 m
->data
= (unsigned long) tm
;
103 static void em_text_destroy(struct tcf_proto
*tp
, struct tcf_ematch
*m
)
105 textsearch_destroy(EM_TEXT_PRIV(m
)->config
);
108 static int em_text_dump(struct sk_buff
*skb
, struct tcf_ematch
*m
)
110 struct text_match
*tm
= EM_TEXT_PRIV(m
);
111 struct tcf_em_text conf
;
113 strncpy(conf
.algo
, tm
->config
->ops
->name
, sizeof(conf
.algo
) - 1);
114 conf
.from_offset
= tm
->from_offset
;
115 conf
.to_offset
= tm
->to_offset
;
116 conf
.from_layer
= tm
->from_layer
;
117 conf
.to_layer
= tm
->to_layer
;
118 conf
.pattern_len
= textsearch_get_pattern_len(tm
->config
);
121 if (nla_put_nohdr(skb
, sizeof(conf
), &conf
) < 0)
122 goto nla_put_failure
;
123 if (nla_append(skb
, conf
.pattern_len
,
124 textsearch_get_pattern(tm
->config
)) < 0)
125 goto nla_put_failure
;
132 static struct tcf_ematch_ops em_text_ops
= {
134 .change
= em_text_change
,
135 .match
= em_text_match
,
136 .destroy
= em_text_destroy
,
137 .dump
= em_text_dump
,
138 .owner
= THIS_MODULE
,
139 .link
= LIST_HEAD_INIT(em_text_ops
.link
)
142 static int __init
init_em_text(void)
144 return tcf_em_register(&em_text_ops
);
147 static void __exit
exit_em_text(void)
149 tcf_em_unregister(&em_text_ops
);
152 MODULE_LICENSE("GPL");
154 module_init(init_em_text
);
155 module_exit(exit_em_text
);
157 MODULE_ALIAS_TCF_EMATCH(TCF_EM_TEXT
);