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/config.h>
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <linux/sched.h>
17 #include <linux/string.h>
18 #include <linux/skbuff.h>
19 #include <linux/textsearch.h>
20 #include <linux/tc_ematch/tc_em_text.h>
21 #include <net/pkt_cls.h>
29 struct ts_config
*config
;
32 #define EM_TEXT_PRIV(m) ((struct text_match *) (m)->data)
34 static int em_text_match(struct sk_buff
*skb
, struct tcf_ematch
*m
,
35 struct tcf_pkt_info
*info
)
37 struct text_match
*tm
= EM_TEXT_PRIV(m
);
39 struct ts_state state
;
41 from
= tcf_get_base_ptr(skb
, tm
->from_layer
) - skb
->data
;
42 from
+= tm
->from_offset
;
44 to
= tcf_get_base_ptr(skb
, tm
->to_layer
) - skb
->data
;
47 return skb_find_text(skb
, from
, to
, tm
->config
, &state
) != UINT_MAX
;
50 static int em_text_change(struct tcf_proto
*tp
, void *data
, int len
,
53 struct text_match
*tm
;
54 struct tcf_em_text
*conf
= data
;
55 struct ts_config
*ts_conf
;
58 if (len
< sizeof(*conf
) || len
< (sizeof(*conf
) + conf
->pattern_len
))
61 if (conf
->from_layer
> conf
->to_layer
)
64 if (conf
->from_layer
== conf
->to_layer
&&
65 conf
->from_offset
> conf
->to_offset
)
69 ts_conf
= textsearch_prepare(conf
->algo
, (u8
*) conf
+ sizeof(*conf
),
70 conf
->pattern_len
, GFP_KERNEL
, flags
);
72 if (flags
& TS_AUTOLOAD
)
75 if (IS_ERR(ts_conf
)) {
76 if (PTR_ERR(ts_conf
) == -ENOENT
&& !(flags
& TS_AUTOLOAD
)) {
81 return PTR_ERR(ts_conf
);
82 } else if (flags
& TS_AUTOLOAD
) {
83 textsearch_destroy(ts_conf
);
87 tm
= kmalloc(sizeof(*tm
), GFP_KERNEL
);
89 textsearch_destroy(ts_conf
);
93 tm
->from_offset
= conf
->from_offset
;
94 tm
->to_offset
= conf
->to_offset
;
95 tm
->from_layer
= conf
->from_layer
;
96 tm
->to_layer
= conf
->to_layer
;
99 m
->datalen
= sizeof(*tm
);
100 m
->data
= (unsigned long) tm
;
105 static void em_text_destroy(struct tcf_proto
*tp
, struct tcf_ematch
*m
)
107 textsearch_destroy(EM_TEXT_PRIV(m
)->config
);
110 static int em_text_dump(struct sk_buff
*skb
, struct tcf_ematch
*m
)
112 struct text_match
*tm
= EM_TEXT_PRIV(m
);
113 struct tcf_em_text conf
;
115 strncpy(conf
.algo
, tm
->config
->ops
->name
, sizeof(conf
.algo
) - 1);
116 conf
.from_offset
= tm
->from_offset
;
117 conf
.to_offset
= tm
->to_offset
;
118 conf
.from_layer
= tm
->from_layer
;
119 conf
.to_layer
= tm
->to_layer
;
120 conf
.pattern_len
= textsearch_get_pattern_len(tm
->config
);
123 RTA_PUT_NOHDR(skb
, sizeof(conf
), &conf
);
124 RTA_APPEND(skb
, conf
.pattern_len
, textsearch_get_pattern(tm
->config
));
131 static struct tcf_ematch_ops em_text_ops
= {
133 .change
= em_text_change
,
134 .match
= em_text_match
,
135 .destroy
= em_text_destroy
,
136 .dump
= em_text_dump
,
137 .owner
= THIS_MODULE
,
138 .link
= LIST_HEAD_INIT(em_text_ops
.link
)
141 static int __init
init_em_text(void)
143 return tcf_em_register(&em_text_ops
);
146 static void __exit
exit_em_text(void)
148 tcf_em_unregister(&em_text_ops
);
151 MODULE_LICENSE("GPL");
153 module_init(init_em_text
);
154 module_exit(exit_em_text
);