tcp: Optimise GRO port comparisons
[linux-2.6] / net / netfilter / xt_mark.c
1 /*
2  *      xt_mark - Netfilter module to match NFMARK value
3  *
4  *      (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
5  *      Copyright © CC Computer Consultants GmbH, 2007 - 2008
6  *      Jan Engelhardt <jengelh@computergmbh.de>
7  *
8  *      This program is free software; you can redistribute it and/or modify
9  *      it under the terms of the GNU General Public License version 2 as
10  *      published by the Free Software Foundation.
11  */
12
13 #include <linux/module.h>
14 #include <linux/skbuff.h>
15
16 #include <linux/netfilter/xt_mark.h>
17 #include <linux/netfilter/x_tables.h>
18
19 MODULE_LICENSE("GPL");
20 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
21 MODULE_DESCRIPTION("Xtables: packet mark match");
22 MODULE_ALIAS("ipt_mark");
23 MODULE_ALIAS("ip6t_mark");
24
25 static bool
26 mark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
27 {
28         const struct xt_mark_info *info = par->matchinfo;
29
30         return ((skb->mark & info->mask) == info->mark) ^ info->invert;
31 }
32
33 static bool
34 mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
35 {
36         const struct xt_mark_mtinfo1 *info = par->matchinfo;
37
38         return ((skb->mark & info->mask) == info->mark) ^ info->invert;
39 }
40
41 static bool mark_mt_check_v0(const struct xt_mtchk_param *par)
42 {
43         const struct xt_mark_info *minfo = par->matchinfo;
44
45         if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
46                 printk(KERN_WARNING "mark: only supports 32bit mark\n");
47                 return false;
48         }
49         return true;
50 }
51
52 #ifdef CONFIG_COMPAT
53 struct compat_xt_mark_info {
54         compat_ulong_t  mark, mask;
55         u_int8_t        invert;
56         u_int8_t        __pad1;
57         u_int16_t       __pad2;
58 };
59
60 static void mark_mt_compat_from_user_v0(void *dst, void *src)
61 {
62         const struct compat_xt_mark_info *cm = src;
63         struct xt_mark_info m = {
64                 .mark   = cm->mark,
65                 .mask   = cm->mask,
66                 .invert = cm->invert,
67         };
68         memcpy(dst, &m, sizeof(m));
69 }
70
71 static int mark_mt_compat_to_user_v0(void __user *dst, void *src)
72 {
73         const struct xt_mark_info *m = src;
74         struct compat_xt_mark_info cm = {
75                 .mark   = m->mark,
76                 .mask   = m->mask,
77                 .invert = m->invert,
78         };
79         return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
80 }
81 #endif /* CONFIG_COMPAT */
82
83 static struct xt_match mark_mt_reg[] __read_mostly = {
84         {
85                 .name           = "mark",
86                 .revision       = 0,
87                 .family         = NFPROTO_UNSPEC,
88                 .checkentry     = mark_mt_check_v0,
89                 .match          = mark_mt_v0,
90                 .matchsize      = sizeof(struct xt_mark_info),
91 #ifdef CONFIG_COMPAT
92                 .compatsize     = sizeof(struct compat_xt_mark_info),
93                 .compat_from_user = mark_mt_compat_from_user_v0,
94                 .compat_to_user = mark_mt_compat_to_user_v0,
95 #endif
96                 .me             = THIS_MODULE,
97         },
98         {
99                 .name           = "mark",
100                 .revision       = 1,
101                 .family         = NFPROTO_UNSPEC,
102                 .match          = mark_mt,
103                 .matchsize      = sizeof(struct xt_mark_mtinfo1),
104                 .me             = THIS_MODULE,
105         },
106 };
107
108 static int __init mark_mt_init(void)
109 {
110         return xt_register_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg));
111 }
112
113 static void __exit mark_mt_exit(void)
114 {
115         xt_unregister_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg));
116 }
117
118 module_init(mark_mt_init);
119 module_exit(mark_mt_exit);