xref: /linux/include/net/pkt_cls.h (revision 2b8232ce512105e28453f301d1510de8363bccd1)
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
365