aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/xt_CONNMARK.h5
-rw-r--r--net/netfilter/xt_CONNMARK.c117
2 files changed, 102 insertions, 20 deletions
diff --git a/include/linux/netfilter/xt_CONNMARK.h b/include/linux/netfilter/xt_CONNMARK.h
index 9f744689fffc..4e58ba43c289 100644
--- a/include/linux/netfilter/xt_CONNMARK.h
+++ b/include/linux/netfilter/xt_CONNMARK.h
@@ -22,4 +22,9 @@ struct xt_connmark_target_info {
22 u_int8_t mode; 22 u_int8_t mode;
23}; 23};
24 24
25struct xt_connmark_tginfo1 {
26 u_int32_t ctmark, ctmask, nfmask;
27 u_int8_t mode;
28};
29
25#endif /*_XT_CONNMARK_H_target*/ 30#endif /*_XT_CONNMARK_H_target*/
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index ec2eb341d2e6..b9bd77233460 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -1,8 +1,10 @@
1/* This kernel module is used to modify the connection mark values, or 1/*
2 * to optionally restore the skb nfmark from the connection mark 2 * xt_CONNMARK - Netfilter module to modify the connection mark values
3 * 3 *
4 * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 4 * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
5 * by Henrik Nordstrom <hno@marasystems.com> 5 * by Henrik Nordstrom <hno@marasystems.com>
6 * Copyright © CC Computer Consultants GmbH, 2007 - 2008
7 * Jan Engelhardt <jengelh@computergmbh.de>
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify 9 * 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 10 * it under the terms of the GNU General Public License as published by
@@ -34,9 +36,9 @@ MODULE_ALIAS("ip6t_CONNMARK");
34#include <net/netfilter/nf_conntrack_ecache.h> 36#include <net/netfilter/nf_conntrack_ecache.h>
35 37
36static unsigned int 38static unsigned int
37connmark_tg(struct sk_buff *skb, const struct net_device *in, 39connmark_tg_v0(struct sk_buff *skb, const struct net_device *in,
38 const struct net_device *out, unsigned int hooknum, 40 const struct net_device *out, unsigned int hooknum,
39 const struct xt_target *target, const void *targinfo) 41 const struct xt_target *target, const void *targinfo)
40{ 42{
41 const struct xt_connmark_target_info *markinfo = targinfo; 43 const struct xt_connmark_target_info *markinfo = targinfo;
42 struct nf_conn *ct; 44 struct nf_conn *ct;
@@ -74,10 +76,50 @@ connmark_tg(struct sk_buff *skb, const struct net_device *in,
74 return XT_CONTINUE; 76 return XT_CONTINUE;
75} 77}
76 78
79static unsigned int
80connmark_tg(struct sk_buff *skb, const struct net_device *in,
81 const struct net_device *out, unsigned int hooknum,
82 const struct xt_target *target, const void *targinfo)
83{
84 const struct xt_connmark_tginfo1 *info = targinfo;
85 enum ip_conntrack_info ctinfo;
86 struct nf_conn *ct;
87 u_int32_t newmark;
88
89 ct = nf_ct_get(skb, &ctinfo);
90 if (ct == NULL)
91 return XT_CONTINUE;
92
93 switch (info->mode) {
94 case XT_CONNMARK_SET:
95 newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
96 if (ct->mark != newmark) {
97 ct->mark = newmark;
98 nf_conntrack_event_cache(IPCT_MARK, skb);
99 }
100 break;
101 case XT_CONNMARK_SAVE:
102 newmark = (ct->mark & ~info->ctmask) ^
103 (skb->mark & info->nfmask);
104 if (ct->mark != newmark) {
105 ct->mark = newmark;
106 nf_conntrack_event_cache(IPCT_MARK, skb);
107 }
108 break;
109 case XT_CONNMARK_RESTORE:
110 newmark = (skb->mark & ~info->nfmask) ^
111 (ct->mark & info->ctmask);
112 skb->mark = newmark;
113 break;
114 }
115
116 return XT_CONTINUE;
117}
118
77static bool 119static bool
78connmark_tg_check(const char *tablename, const void *entry, 120connmark_tg_check_v0(const char *tablename, const void *entry,
79 const struct xt_target *target, void *targinfo, 121 const struct xt_target *target, void *targinfo,
80 unsigned int hook_mask) 122 unsigned int hook_mask)
81{ 123{
82 const struct xt_connmark_target_info *matchinfo = targinfo; 124 const struct xt_connmark_target_info *matchinfo = targinfo;
83 125
@@ -101,6 +143,19 @@ connmark_tg_check(const char *tablename, const void *entry,
101 return true; 143 return true;
102} 144}
103 145
146static bool
147connmark_tg_check(const char *tablename, const void *entry,
148 const struct xt_target *target, void *targinfo,
149 unsigned int hook_mask)
150{
151 if (nf_ct_l3proto_try_module_get(target->family) < 0) {
152 printk(KERN_WARNING "cannot load conntrack support for "
153 "proto=%u\n", target->family);
154 return false;
155 }
156 return true;
157}
158
104static void 159static void
105connmark_tg_destroy(const struct xt_target *target, void *targinfo) 160connmark_tg_destroy(const struct xt_target *target, void *targinfo)
106{ 161{
@@ -115,7 +170,7 @@ struct compat_xt_connmark_target_info {
115 u_int16_t __pad2; 170 u_int16_t __pad2;
116}; 171};
117 172
118static void connmark_tg_compat_from_user(void *dst, void *src) 173static void connmark_tg_compat_from_user_v0(void *dst, void *src)
119{ 174{
120 const struct compat_xt_connmark_target_info *cm = src; 175 const struct compat_xt_connmark_target_info *cm = src;
121 struct xt_connmark_target_info m = { 176 struct xt_connmark_target_info m = {
@@ -126,7 +181,7 @@ static void connmark_tg_compat_from_user(void *dst, void *src)
126 memcpy(dst, &m, sizeof(m)); 181 memcpy(dst, &m, sizeof(m));
127} 182}
128 183
129static int connmark_tg_compat_to_user(void __user *dst, void *src) 184static int connmark_tg_compat_to_user_v0(void __user *dst, void *src)
130{ 185{
131 const struct xt_connmark_target_info *m = src; 186 const struct xt_connmark_target_info *m = src;
132 struct compat_xt_connmark_target_info cm = { 187 struct compat_xt_connmark_target_info cm = {
@@ -141,32 +196,54 @@ static int connmark_tg_compat_to_user(void __user *dst, void *src)
141static struct xt_target connmark_tg_reg[] __read_mostly = { 196static struct xt_target connmark_tg_reg[] __read_mostly = {
142 { 197 {
143 .name = "CONNMARK", 198 .name = "CONNMARK",
199 .revision = 0,
144 .family = AF_INET, 200 .family = AF_INET,
145 .checkentry = connmark_tg_check, 201 .checkentry = connmark_tg_check_v0,
146 .destroy = connmark_tg_destroy, 202 .destroy = connmark_tg_destroy,
147 .target = connmark_tg, 203 .target = connmark_tg_v0,
148 .targetsize = sizeof(struct xt_connmark_target_info), 204 .targetsize = sizeof(struct xt_connmark_target_info),
149#ifdef CONFIG_COMPAT 205#ifdef CONFIG_COMPAT
150 .compatsize = sizeof(struct compat_xt_connmark_target_info), 206 .compatsize = sizeof(struct compat_xt_connmark_target_info),
151 .compat_from_user = connmark_tg_compat_from_user, 207 .compat_from_user = connmark_tg_compat_from_user_v0,
152 .compat_to_user = connmark_tg_compat_to_user, 208 .compat_to_user = connmark_tg_compat_to_user_v0,
153#endif 209#endif
154 .me = THIS_MODULE 210 .me = THIS_MODULE
155 }, 211 },
156 { 212 {
157 .name = "CONNMARK", 213 .name = "CONNMARK",
214 .revision = 0,
158 .family = AF_INET6, 215 .family = AF_INET6,
159 .checkentry = connmark_tg_check, 216 .checkentry = connmark_tg_check_v0,
160 .destroy = connmark_tg_destroy, 217 .destroy = connmark_tg_destroy,
161 .target = connmark_tg, 218 .target = connmark_tg_v0,
162 .targetsize = sizeof(struct xt_connmark_target_info), 219 .targetsize = sizeof(struct xt_connmark_target_info),
163#ifdef CONFIG_COMPAT 220#ifdef CONFIG_COMPAT
164 .compatsize = sizeof(struct compat_xt_connmark_target_info), 221 .compatsize = sizeof(struct compat_xt_connmark_target_info),
165 .compat_from_user = connmark_tg_compat_from_user, 222 .compat_from_user = connmark_tg_compat_from_user_v0,
166 .compat_to_user = connmark_tg_compat_to_user, 223 .compat_to_user = connmark_tg_compat_to_user_v0,
167#endif 224#endif
168 .me = THIS_MODULE 225 .me = THIS_MODULE
169 }, 226 },
227 {
228 .name = "CONNMARK",
229 .revision = 1,
230 .family = AF_INET,
231 .checkentry = connmark_tg_check,
232 .target = connmark_tg,
233 .targetsize = sizeof(struct xt_connmark_tginfo1),
234 .destroy = connmark_tg_destroy,
235 .me = THIS_MODULE,
236 },
237 {
238 .name = "CONNMARK",
239 .revision = 1,
240 .family = AF_INET6,
241 .checkentry = connmark_tg_check,
242 .target = connmark_tg,
243 .targetsize = sizeof(struct xt_connmark_tginfo1),
244 .destroy = connmark_tg_destroy,
245 .me = THIS_MODULE,
246 },
170}; 247};
171 248
172static int __init connmark_tg_init(void) 249static int __init connmark_tg_init(void)