[RAW]: Consolidate proto->unhash callback
[linux-2.6] / include / net / pkt_cls.h
1 #ifndef __NET_PKT_CLS_H
2 #define __NET_PKT_CLS_H
3
4 #include <linux/pkt_cls.h>
5 #include <net/net_namespace.h>
6 #include <net/sch_generic.h>
7 #include <net/act_api.h>
8
9 /* Basic packet classifier frontend definitions. */
10
11 struct tcf_walker
12 {
13         int     stop;
14         int     skip;
15         int     count;
16         int     (*fn)(struct tcf_proto *, unsigned long node, struct tcf_walker *);
17 };
18
19 extern int register_tcf_proto_ops(struct tcf_proto_ops *ops);
20 extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
21
22 static inline unsigned long
23 __cls_set_class(unsigned long *clp, unsigned long cl)
24 {
25         unsigned long old_cl;
26  
27         old_cl = *clp;
28         *clp = cl;
29         return old_cl;
30 }
31
32 static inline unsigned long
33 cls_set_class(struct tcf_proto *tp, unsigned long *clp, 
34         unsigned long cl)
35 {
36         unsigned long old_cl;
37         
38         tcf_tree_lock(tp);
39         old_cl = __cls_set_class(clp, cl);
40         tcf_tree_unlock(tp);
41  
42         return old_cl;
43 }
44
45 static inline void
46 tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
47 {
48         unsigned long cl;
49
50         cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, r->classid);
51         cl = cls_set_class(tp, &r->class, cl);
52         if (cl)
53                 tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
54 }
55
56 static inline void
57 tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
58 {
59         unsigned long cl;
60
61         if ((cl = __cls_set_class(&r->class, 0)) != 0)
62                 tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
63 }
64
65 struct tcf_exts
66 {
67 #ifdef CONFIG_NET_CLS_ACT
68         struct tc_action *action;
69 #endif
70 };
71
72 /* Map to export classifier specific extension TLV types to the
73  * generic extensions API. Unsupported extensions must be set to 0.
74  */
75 struct tcf_ext_map
76 {
77         int action;
78         int police;
79 };
80
81 /**
82  * tcf_exts_is_predicative - check if a predicative extension is present
83  * @exts: tc filter extensions handle
84  *
85  * Returns 1 if a predicative extension is present, i.e. an extension which
86  * might cause further actions and thus overrule the regular tcf_result.
87  */
88 static inline int
89 tcf_exts_is_predicative(struct tcf_exts *exts)
90 {
91 #ifdef CONFIG_NET_CLS_ACT
92         return !!exts->action;
93 #else
94         return 0;
95 #endif
96 }
97
98 /**
99  * tcf_exts_is_available - check if at least one extension is present
100  * @exts: tc filter extensions handle
101  *
102  * Returns 1 if at least one extension is present.
103  */
104 static inline int
105 tcf_exts_is_available(struct tcf_exts *exts)
106 {
107         /* All non-predicative extensions must be added here. */
108         return tcf_exts_is_predicative(exts);
109 }
110
111 /**
112  * tcf_exts_exec - execute tc filter extensions
113  * @skb: socket buffer
114  * @exts: tc filter extensions handle
115  * @res: desired result
116  *
117  * Executes all configured extensions. Returns 0 on a normal execution,
118  * a negative number if the filter must be considered unmatched or
119  * a positive action code (TC_ACT_*) which must be returned to the
120  * underlying layer.
121  */
122 static inline int
123 tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
124                struct tcf_result *res)
125 {
126 #ifdef CONFIG_NET_CLS_ACT
127         if (exts->action)
128                 return tcf_action_exec(skb, exts->action, res);
129 #endif
130         return 0;
131 }
132
133 extern int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
134                              struct rtattr *rate_tlv, struct tcf_exts *exts,
135                              struct tcf_ext_map *map);
136 extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
137 extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
138                              struct tcf_exts *src);
139 extern int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
140                          struct tcf_ext_map *map);
141 extern int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
142                                struct tcf_ext_map *map);
143
144 /**
145  * struct tcf_pkt_info - packet information
146  */
147 struct tcf_pkt_info
148 {
149         unsigned char *         ptr;
150         int                     nexthdr;
151 };
152
153 #ifdef CONFIG_NET_EMATCH
154
155 struct tcf_ematch_ops;
156
157 /**
158  * struct tcf_ematch - extended match (ematch)
159  * 
160  * @matchid: identifier to allow userspace to reidentify a match
161  * @flags: flags specifying attributes and the relation to other matches
162  * @ops: the operations lookup table of the corresponding ematch module
163  * @datalen: length of the ematch specific configuration data
164  * @data: ematch specific data
165  */
166 struct tcf_ematch
167 {
168         struct tcf_ematch_ops * ops;
169         unsigned long           data;
170         unsigned int            datalen;
171         u16                     matchid;
172         u16                     flags;
173 };
174
175 static inline int tcf_em_is_container(struct tcf_ematch *em)
176 {
177         return !em->ops;
178 }
179
180 static inline int tcf_em_is_simple(struct tcf_ematch *em)
181 {
182         return em->flags & TCF_EM_SIMPLE;
183 }
184
185 static inline int tcf_em_is_inverted(struct tcf_ematch *em)
186 {
187         return em->flags & TCF_EM_INVERT;
188 }
189
190 static inline int tcf_em_last_match(struct tcf_ematch *em)
191 {
192         return (em->flags & TCF_EM_REL_MASK) == TCF_EM_REL_END;
193 }
194
195 static inline int tcf_em_early_end(struct tcf_ematch *em, int result)
196 {
197         if (tcf_em_last_match(em))
198                 return 1;
199
200         if (result == 0 && em->flags & TCF_EM_REL_AND)
201                 return 1;
202
203         if (result != 0 && em->flags & TCF_EM_REL_OR)
204                 return 1;
205
206         return 0;
207 }
208         
209 /**
210  * struct tcf_ematch_tree - ematch tree handle
211  *
212  * @hdr: ematch tree header supplied by userspace
213  * @matches: array of ematches
214  */
215 struct tcf_ematch_tree
216 {
217         struct tcf_ematch_tree_hdr hdr;
218         struct tcf_ematch *     matches;
219         
220 };
221
222 /**
223  * struct tcf_ematch_ops - ematch module operations
224  * 
225  * @kind: identifier (kind) of this ematch module
226  * @datalen: length of expected configuration data (optional)
227  * @change: called during validation (optional)
228  * @match: called during ematch tree evaluation, must return 1/0
229  * @destroy: called during destroyage (optional)
230  * @dump: called during dumping process (optional)
231  * @owner: owner, must be set to THIS_MODULE
232  * @link: link to previous/next ematch module (internal use)
233  */
234 struct tcf_ematch_ops
235 {
236         int                     kind;
237         int                     datalen;
238         int                     (*change)(struct tcf_proto *, void *,
239                                           int, struct tcf_ematch *);
240         int                     (*match)(struct sk_buff *, struct tcf_ematch *,
241                                          struct tcf_pkt_info *);
242         void                    (*destroy)(struct tcf_proto *,
243                                            struct tcf_ematch *);
244         int                     (*dump)(struct sk_buff *, struct tcf_ematch *);
245         struct module           *owner;
246         struct list_head        link;
247 };
248
249 extern int tcf_em_register(struct tcf_ematch_ops *);
250 extern int tcf_em_unregister(struct tcf_ematch_ops *);
251 extern int tcf_em_tree_validate(struct tcf_proto *, struct rtattr *,
252                                 struct tcf_ematch_tree *);
253 extern void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *);
254 extern int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
255 extern int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
256                                struct tcf_pkt_info *);
257
258 /**
259  * tcf_em_tree_change - replace ematch tree of a running classifier
260  *
261  * @tp: classifier kind handle
262  * @dst: destination ematch tree variable
263  * @src: source ematch tree (temporary tree from tcf_em_tree_validate)
264  *
265  * This functions replaces the ematch tree in @dst with the ematch
266  * tree in @src. The classifier in charge of the ematch tree may be
267  * running.
268  */
269 static inline void tcf_em_tree_change(struct tcf_proto *tp,
270                                       struct tcf_ematch_tree *dst,
271                                       struct tcf_ematch_tree *src)
272 {
273         tcf_tree_lock(tp);
274         memcpy(dst, src, sizeof(*dst));
275         tcf_tree_unlock(tp);
276 }
277
278 /**
279  * tcf_em_tree_match - evaulate an ematch tree
280  *
281  * @skb: socket buffer of the packet in question
282  * @tree: ematch tree to be used for evaluation
283  * @info: packet information examined by classifier
284  *
285  * This function matches @skb against the ematch tree in @tree by going
286  * through all ematches respecting their logic relations returning
287  * as soon as the result is obvious.
288  *
289  * Returns 1 if the ematch tree as-one matches, no ematches are configured
290  * or ematch is not enabled in the kernel, otherwise 0 is returned.
291  */
292 static inline int tcf_em_tree_match(struct sk_buff *skb,
293                                     struct tcf_ematch_tree *tree,
294                                     struct tcf_pkt_info *info)
295 {
296         if (tree->hdr.nmatches)
297                 return __tcf_em_tree_match(skb, tree, info);
298         else
299                 return 1;
300 }
301
302 #define MODULE_ALIAS_TCF_EMATCH(kind)   MODULE_ALIAS("ematch-kind-" __stringify(kind))
303
304 #else /* CONFIG_NET_EMATCH */
305
306 struct tcf_ematch_tree
307 {
308 };
309
310 #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0)
311 #define tcf_em_tree_destroy(tp, t) do { (void)(t); } while(0)
312 #define tcf_em_tree_dump(skb, t, tlv) (0)
313 #define tcf_em_tree_change(tp, dst, src) do { } while(0)
314 #define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
315
316 #endif /* CONFIG_NET_EMATCH */
317
318 static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer)
319 {
320         switch (layer) {
321                 case TCF_LAYER_LINK:
322                         return skb->data;
323                 case TCF_LAYER_NETWORK:
324                         return skb_network_header(skb);
325                 case TCF_LAYER_TRANSPORT:
326                         return skb_transport_header(skb);
327         }
328
329         return NULL;
330 }
331
332 static inline int tcf_valid_offset(const struct sk_buff *skb,
333                                    const unsigned char *ptr, const int len)
334 {
335         return unlikely((ptr + len) < skb_tail_pointer(skb) && ptr > skb->head);
336 }
337
338 #ifdef CONFIG_NET_CLS_IND
339 static inline int
340 tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
341 {
342         if (rtattr_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
343                 return -EINVAL;
344         return 0;
345 }
346
347 static inline int
348 tcf_match_indev(struct sk_buff *skb, char *indev)
349 {
350         struct net_device *dev;
351
352         if (indev[0]) {
353                 if  (!skb->iif)
354                         return 0;
355                 dev = __dev_get_by_index(&init_net, skb->iif);
356                 if (!dev || strcmp(indev, dev->name))
357                         return 0;
358         }
359
360         return 1;
361 }
362 #endif /* CONFIG_NET_CLS_IND */
363
364 #endif