Blame view

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