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/slab.h>
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/skbuff.h>
18 #include <linux/textsearch.h>
19 #include <linux/tc_ematch/tc_em_text.h>
20 #include <net/pkt_cls.h>
28 struct ts_config
*config
;
31 #define EM_TEXT_PRIV(m) ((struct text_match *) (m)->data)
33 static int em_text_match(struct sk_buff
*skb
, struct tcf_ematch
*m
,
34 struct tcf_pkt_info
*info
)
36 struct text_match
*tm
= EM_TEXT_PRIV(m
);
38 struct ts_state state
;
40 from
= tcf_get_base_ptr(skb
, tm
->from_layer
) - skb
->data
;
41 from
+= tm
->from_offset
;
43 to
= tcf_get_base_ptr(skb
, tm
->to_layer
) - skb
->data
;
46 return skb_find_text(skb
, from
, to
, tm
->config
, &state
) != UINT_MAX
;
49 static int em_text_change(struct tcf_proto
*tp
, void *data
, int len
,
52 struct text_match
*tm
;
53 struct tcf_em_text
*conf
= data
;
54 struct ts_config
*ts_conf
;
57 if (len
< sizeof(*conf
) || len
< (sizeof(*conf
) + conf
->pattern_len
))
60 if (conf
->from_layer
> conf
->to_layer
)
63 if (conf
->from_layer
== conf
->to_layer
&&
64 conf
->from_offset
> conf
->to_offset
)
68 ts_conf
= textsearch_prepare(conf
->algo
, (u8
*) conf
+ sizeof(*conf
),
69 conf
->pattern_len
, GFP_KERNEL
, flags
);
71 if (flags
& TS_AUTOLOAD
)
74 if (IS_ERR(ts_conf
)) {
75 if (PTR_ERR(ts_conf
) == -ENOENT
&& !(flags
& TS_AUTOLOAD
)) {
80 return PTR_ERR(ts_conf
);
81 } else if (flags
& TS_AUTOLOAD
) {
82 textsearch_destroy(ts_conf
);
86 tm
= kmalloc(sizeof(*tm
), GFP_KERNEL
);
88 textsearch_destroy(ts_conf
);
92 tm
->from_offset
= conf
->from_offset
;
93 tm
->to_offset
= conf
->to_offset
;
94 tm
->from_layer
= conf
->from_layer
;
95 tm
->to_layer
= conf
->to_layer
;
98 m
->datalen
= sizeof(*tm
);
99 m
->data
= (unsigned long) tm
;
104 static void em_text_destroy(struct tcf_proto
*tp
, struct tcf_ematch
*m
)
106 textsearch_destroy(EM_TEXT_PRIV(m
)->config
);
109 static int em_text_dump(struct sk_buff
*skb
, struct tcf_ematch
*m
)
111 struct text_match
*tm
= EM_TEXT_PRIV(m
);
112 struct tcf_em_text conf
;
114 strncpy(conf
.algo
, tm
->config
->ops
->name
, sizeof(conf
.algo
) - 1);
115 conf
.from_offset
= tm
->from_offset
;
116 conf
.to_offset
= tm
->to_offset
;
117 conf
.from_layer
= tm
->from_layer
;
118 conf
.to_layer
= tm
->to_layer
;
119 conf
.pattern_len
= textsearch_get_pattern_len(tm
->config
);
122 if (nla_put_nohdr(skb
, sizeof(conf
), &conf
) < 0)
123 goto nla_put_failure
;
124 if (nla_append(skb
, conf
.pattern_len
,
125 textsearch_get_pattern(tm
->config
)) < 0)
126 goto nla_put_failure
;
133 static struct tcf_ematch_ops em_text_ops
= {
135 .change
= em_text_change
,
136 .match
= em_text_match
,
137 .destroy
= em_text_destroy
,
138 .dump
= em_text_dump
,
139 .owner
= THIS_MODULE
,
140 .link
= LIST_HEAD_INIT(em_text_ops
.link
)
143 static int __init
init_em_text(void)
145 return tcf_em_register(&em_text_ops
);
148 static void __exit
exit_em_text(void)
150 tcf_em_unregister(&em_text_ops
);
153 MODULE_LICENSE("GPL");
155 module_init(init_em_text
);
156 module_exit(exit_em_text
);
158 MODULE_ALIAS_TCF_EMATCH(TCF_EM_TEXT
);