[NETFILTER]: x_tables: consistent and unique symbol names
[safe/jmp/linux-2.6] / net / netfilter / xt_connmark.c
1 /* This kernel module matches connection mark values set by the
2  * CONNMARK target
3  *
4  * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
5  * by Henrik Nordstrom <hno@marasystems.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <linux/module.h>
23 #include <linux/skbuff.h>
24 #include <net/netfilter/nf_conntrack.h>
25 #include <linux/netfilter/x_tables.h>
26 #include <linux/netfilter/xt_connmark.h>
27
28 MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
29 MODULE_DESCRIPTION("IP tables connmark match module");
30 MODULE_LICENSE("GPL");
31 MODULE_ALIAS("ipt_connmark");
32 MODULE_ALIAS("ip6t_connmark");
33
34 static bool
35 connmark_mt(const struct sk_buff *skb, const struct net_device *in,
36             const struct net_device *out, const struct xt_match *match,
37             const void *matchinfo, int offset, unsigned int protoff,
38             bool *hotdrop)
39 {
40         const struct xt_connmark_info *info = matchinfo;
41         const struct nf_conn *ct;
42         enum ip_conntrack_info ctinfo;
43
44         ct = nf_ct_get(skb, &ctinfo);
45         if (!ct)
46                 return false;
47
48         return ((ct->mark & info->mask) == info->mark) ^ info->invert;
49 }
50
51 static bool
52 connmark_mt_check(const char *tablename, const void *ip,
53                   const struct xt_match *match, void *matchinfo,
54                   unsigned int hook_mask)
55 {
56         const struct xt_connmark_info *cm = matchinfo;
57
58         if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
59                 printk(KERN_WARNING "connmark: only support 32bit mark\n");
60                 return false;
61         }
62         if (nf_ct_l3proto_try_module_get(match->family) < 0) {
63                 printk(KERN_WARNING "can't load conntrack support for "
64                                     "proto=%d\n", match->family);
65                 return false;
66         }
67         return true;
68 }
69
70 static void
71 connmark_mt_destroy(const struct xt_match *match, void *matchinfo)
72 {
73         nf_ct_l3proto_module_put(match->family);
74 }
75
76 #ifdef CONFIG_COMPAT
77 struct compat_xt_connmark_info {
78         compat_ulong_t  mark, mask;
79         u_int8_t        invert;
80         u_int8_t        __pad1;
81         u_int16_t       __pad2;
82 };
83
84 static void connmark_mt_compat_from_user(void *dst, void *src)
85 {
86         const struct compat_xt_connmark_info *cm = src;
87         struct xt_connmark_info m = {
88                 .mark   = cm->mark,
89                 .mask   = cm->mask,
90                 .invert = cm->invert,
91         };
92         memcpy(dst, &m, sizeof(m));
93 }
94
95 static int connmark_mt_compat_to_user(void __user *dst, void *src)
96 {
97         const struct xt_connmark_info *m = src;
98         struct compat_xt_connmark_info cm = {
99                 .mark   = m->mark,
100                 .mask   = m->mask,
101                 .invert = m->invert,
102         };
103         return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
104 }
105 #endif /* CONFIG_COMPAT */
106
107 static struct xt_match connmark_mt_reg[] __read_mostly = {
108         {
109                 .name           = "connmark",
110                 .family         = AF_INET,
111                 .checkentry     = connmark_mt_check,
112                 .match          = connmark_mt,
113                 .destroy        = connmark_mt_destroy,
114                 .matchsize      = sizeof(struct xt_connmark_info),
115 #ifdef CONFIG_COMPAT
116                 .compatsize     = sizeof(struct compat_xt_connmark_info),
117                 .compat_from_user = connmark_mt_compat_from_user,
118                 .compat_to_user = connmark_mt_compat_to_user,
119 #endif
120                 .me             = THIS_MODULE
121         },
122         {
123                 .name           = "connmark",
124                 .family         = AF_INET6,
125                 .checkentry     = connmark_mt_check,
126                 .match          = connmark_mt,
127                 .destroy        = connmark_mt_destroy,
128                 .matchsize      = sizeof(struct xt_connmark_info),
129                 .me             = THIS_MODULE
130         },
131 };
132
133 static int __init connmark_mt_init(void)
134 {
135         return xt_register_matches(connmark_mt_reg,
136                ARRAY_SIZE(connmark_mt_reg));
137 }
138
139 static void __exit connmark_mt_exit(void)
140 {
141         xt_unregister_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
142 }
143
144 module_init(connmark_mt_init);
145 module_exit(connmark_mt_exit);