aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/xt_conntrack.c61
1 files changed, 17 insertions, 44 deletions
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 6dc4652f2fe8..ae66305f0fe5 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -113,7 +113,8 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info,
113} 113}
114 114
115static bool 115static bool
116conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) 116conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par,
117 u16 state_mask, u16 status_mask)
117{ 118{
118 const struct xt_conntrack_mtinfo2 *info = par->matchinfo; 119 const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
119 enum ip_conntrack_info ctinfo; 120 enum ip_conntrack_info ctinfo;
@@ -136,7 +137,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
136 if (test_bit(IPS_DST_NAT_BIT, &ct->status)) 137 if (test_bit(IPS_DST_NAT_BIT, &ct->status))
137 statebit |= XT_CONNTRACK_STATE_DNAT; 138 statebit |= XT_CONNTRACK_STATE_DNAT;
138 } 139 }
139 if (!!(info->state_mask & statebit) ^ 140 if (!!(state_mask & statebit) ^
140 !(info->invert_flags & XT_CONNTRACK_STATE)) 141 !(info->invert_flags & XT_CONNTRACK_STATE))
141 return false; 142 return false;
142 } 143 }
@@ -172,7 +173,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
172 return false; 173 return false;
173 174
174 if ((info->match_flags & XT_CONNTRACK_STATUS) && 175 if ((info->match_flags & XT_CONNTRACK_STATUS) &&
175 (!!(info->status_mask & ct->status) ^ 176 (!!(status_mask & ct->status) ^
176 !(info->invert_flags & XT_CONNTRACK_STATUS))) 177 !(info->invert_flags & XT_CONNTRACK_STATUS)))
177 return false; 178 return false;
178 179
@@ -192,11 +193,17 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
192static bool 193static bool
193conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) 194conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
194{ 195{
195 const struct xt_conntrack_mtinfo2 *const *info = par->matchinfo; 196 const struct xt_conntrack_mtinfo1 *info = par->matchinfo;
196 struct xt_match_param newpar = *par;
197 197
198 newpar.matchinfo = *info; 198 return conntrack_mt(skb, par, info->state_mask, info->status_mask);
199 return conntrack_mt(skb, &newpar); 199}
200
201static bool
202conntrack_mt_v2(const struct sk_buff *skb, const struct xt_match_param *par)
203{
204 const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
205
206 return conntrack_mt(skb, par, info->state_mask, info->status_mask);
200} 207}
201 208
202static bool conntrack_mt_check(const struct xt_mtchk_param *par) 209static bool conntrack_mt_check(const struct xt_mtchk_param *par)
@@ -209,45 +216,11 @@ static bool conntrack_mt_check(const struct xt_mtchk_param *par)
209 return true; 216 return true;
210} 217}
211 218
212static bool conntrack_mt_check_v1(const struct xt_mtchk_param *par)
213{
214 struct xt_conntrack_mtinfo1 *info = par->matchinfo;
215 struct xt_conntrack_mtinfo2 *up;
216 int ret = conntrack_mt_check(par);
217
218 if (ret < 0)
219 return ret;
220
221 up = kmalloc(sizeof(*up), GFP_KERNEL);
222 if (up == NULL) {
223 nf_ct_l3proto_module_put(par->family);
224 return -ENOMEM;
225 }
226
227 /*
228 * The strategy here is to minimize the overhead of v1 matching,
229 * by prebuilding a v2 struct and putting the pointer into the
230 * v1 dataspace.
231 */
232 memcpy(up, info, offsetof(typeof(*info), state_mask));
233 up->state_mask = info->state_mask;
234 up->status_mask = info->status_mask;
235 *(void **)info = up;
236 return true;
237}
238
239static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) 219static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
240{ 220{
241 nf_ct_l3proto_module_put(par->family); 221 nf_ct_l3proto_module_put(par->family);
242} 222}
243 223
244static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par)
245{
246 struct xt_conntrack_mtinfo2 **info = par->matchinfo;
247 kfree(*info);
248 conntrack_mt_destroy(par);
249}
250
251static struct xt_match conntrack_mt_reg[] __read_mostly = { 224static struct xt_match conntrack_mt_reg[] __read_mostly = {
252 { 225 {
253 .name = "conntrack", 226 .name = "conntrack",
@@ -255,8 +228,8 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
255 .family = NFPROTO_UNSPEC, 228 .family = NFPROTO_UNSPEC,
256 .matchsize = sizeof(struct xt_conntrack_mtinfo1), 229 .matchsize = sizeof(struct xt_conntrack_mtinfo1),
257 .match = conntrack_mt_v1, 230 .match = conntrack_mt_v1,
258 .checkentry = conntrack_mt_check_v1, 231 .checkentry = conntrack_mt_check,
259 .destroy = conntrack_mt_destroy_v1, 232 .destroy = conntrack_mt_destroy,
260 .me = THIS_MODULE, 233 .me = THIS_MODULE,
261 }, 234 },
262 { 235 {
@@ -264,7 +237,7 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
264 .revision = 2, 237 .revision = 2,
265 .family = NFPROTO_UNSPEC, 238 .family = NFPROTO_UNSPEC,
266 .matchsize = sizeof(struct xt_conntrack_mtinfo2), 239 .matchsize = sizeof(struct xt_conntrack_mtinfo2),
267 .match = conntrack_mt, 240 .match = conntrack_mt_v2,
268 .checkentry = conntrack_mt_check, 241 .checkentry = conntrack_mt_check,
269 .destroy = conntrack_mt_destroy, 242 .destroy = conntrack_mt_destroy,
270 .me = THIS_MODULE, 243 .me = THIS_MODULE,