aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorDmitry Mishin <dim@openvz.org>2006-04-01 05:25:19 -0500
committerDavid S. Miller <davem@davemloft.net>2006-04-01 05:25:19 -0500
commit2722971cbe831117686039d5c334f2c0f560be13 (patch)
treeb810ea96778e4f5de2a7713685c0551aa34c8f97 /net/netfilter
parente64a70be5175ac2c209fa742123a6ce845852e0e (diff)
[NETFILTER]: iptables 32bit compat layer
This patch extends current iptables compatibility layer in order to get 32bit iptables to work on 64bit kernel. Current layer is insufficient due to alignment checks both in kernel and user space tools. Patch is for current net-2.6.17 with addition of move of ipt_entry_{match| target} definitions to xt_entry_{match|target}. Signed-off-by: Dmitry Mishin <dim@openvz.org> Acked-off-by: Kirill Korotaev <dev@openvz.org> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/x_tables.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index a657ab5394c3..feb8a9e066b0 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -38,6 +38,7 @@ struct xt_af {
38 struct list_head match; 38 struct list_head match;
39 struct list_head target; 39 struct list_head target;
40 struct list_head tables; 40 struct list_head tables;
41 struct mutex compat_mutex;
41}; 42};
42 43
43static struct xt_af *xt; 44static struct xt_af *xt;
@@ -272,6 +273,54 @@ int xt_check_match(const struct xt_match *match, unsigned short family,
272} 273}
273EXPORT_SYMBOL_GPL(xt_check_match); 274EXPORT_SYMBOL_GPL(xt_check_match);
274 275
276#ifdef CONFIG_COMPAT
277int xt_compat_match(void *match, void **dstptr, int *size, int convert)
278{
279 struct xt_match *m;
280 struct compat_xt_entry_match *pcompat_m;
281 struct xt_entry_match *pm;
282 u_int16_t msize;
283 int off, ret;
284
285 ret = 0;
286 m = ((struct xt_entry_match *)match)->u.kernel.match;
287 off = XT_ALIGN(m->matchsize) - COMPAT_XT_ALIGN(m->matchsize);
288 switch (convert) {
289 case COMPAT_TO_USER:
290 pm = (struct xt_entry_match *)match;
291 msize = pm->u.user.match_size;
292 if (__copy_to_user(*dstptr, pm, msize)) {
293 ret = -EFAULT;
294 break;
295 }
296 msize -= off;
297 if (put_user(msize, (u_int16_t *)*dstptr))
298 ret = -EFAULT;
299 *size -= off;
300 *dstptr += msize;
301 break;
302 case COMPAT_FROM_USER:
303 pcompat_m = (struct compat_xt_entry_match *)match;
304 pm = (struct xt_entry_match *)*dstptr;
305 msize = pcompat_m->u.user.match_size;
306 memcpy(pm, pcompat_m, msize);
307 msize += off;
308 pm->u.user.match_size = msize;
309 *size += off;
310 *dstptr += msize;
311 break;
312 case COMPAT_CALC_SIZE:
313 *size += off;
314 break;
315 default:
316 ret = -ENOPROTOOPT;
317 break;
318 }
319 return ret;
320}
321EXPORT_SYMBOL_GPL(xt_compat_match);
322#endif
323
275int xt_check_target(const struct xt_target *target, unsigned short family, 324int xt_check_target(const struct xt_target *target, unsigned short family,
276 unsigned int size, const char *table, unsigned int hook_mask, 325 unsigned int size, const char *table, unsigned int hook_mask,
277 unsigned short proto, int inv_proto) 326 unsigned short proto, int inv_proto)
@@ -301,6 +350,54 @@ int xt_check_target(const struct xt_target *target, unsigned short family,
301} 350}
302EXPORT_SYMBOL_GPL(xt_check_target); 351EXPORT_SYMBOL_GPL(xt_check_target);
303 352
353#ifdef CONFIG_COMPAT
354int xt_compat_target(void *target, void **dstptr, int *size, int convert)
355{
356 struct xt_target *t;
357 struct compat_xt_entry_target *pcompat;
358 struct xt_entry_target *pt;
359 u_int16_t tsize;
360 int off, ret;
361
362 ret = 0;
363 t = ((struct xt_entry_target *)target)->u.kernel.target;
364 off = XT_ALIGN(t->targetsize) - COMPAT_XT_ALIGN(t->targetsize);
365 switch (convert) {
366 case COMPAT_TO_USER:
367 pt = (struct xt_entry_target *)target;
368 tsize = pt->u.user.target_size;
369 if (__copy_to_user(*dstptr, pt, tsize)) {
370 ret = -EFAULT;
371 break;
372 }
373 tsize -= off;
374 if (put_user(tsize, (u_int16_t *)*dstptr))
375 ret = -EFAULT;
376 *size -= off;
377 *dstptr += tsize;
378 break;
379 case COMPAT_FROM_USER:
380 pcompat = (struct compat_xt_entry_target *)target;
381 pt = (struct xt_entry_target *)*dstptr;
382 tsize = pcompat->u.user.target_size;
383 memcpy(pt, pcompat, tsize);
384 tsize += off;
385 pt->u.user.target_size = tsize;
386 *size += off;
387 *dstptr += tsize;
388 break;
389 case COMPAT_CALC_SIZE:
390 *size += off;
391 break;
392 default:
393 ret = -ENOPROTOOPT;
394 break;
395 }
396 return ret;
397}
398EXPORT_SYMBOL_GPL(xt_compat_target);
399#endif
400
304struct xt_table_info *xt_alloc_table_info(unsigned int size) 401struct xt_table_info *xt_alloc_table_info(unsigned int size)
305{ 402{
306 struct xt_table_info *newinfo; 403 struct xt_table_info *newinfo;
@@ -371,6 +468,19 @@ void xt_table_unlock(struct xt_table *table)
371} 468}
372EXPORT_SYMBOL_GPL(xt_table_unlock); 469EXPORT_SYMBOL_GPL(xt_table_unlock);
373 470
471#ifdef CONFIG_COMPAT
472void xt_compat_lock(int af)
473{
474 mutex_lock(&xt[af].compat_mutex);
475}
476EXPORT_SYMBOL_GPL(xt_compat_lock);
477
478void xt_compat_unlock(int af)
479{
480 mutex_unlock(&xt[af].compat_mutex);
481}
482EXPORT_SYMBOL_GPL(xt_compat_unlock);
483#endif
374 484
375struct xt_table_info * 485struct xt_table_info *
376xt_replace_table(struct xt_table *table, 486xt_replace_table(struct xt_table *table,
@@ -671,6 +781,9 @@ static int __init xt_init(void)
671 781
672 for (i = 0; i < NPROTO; i++) { 782 for (i = 0; i < NPROTO; i++) {
673 mutex_init(&xt[i].mutex); 783 mutex_init(&xt[i].mutex);
784#ifdef CONFIG_COMPAT
785 mutex_init(&xt[i].compat_mutex);
786#endif
674 INIT_LIST_HEAD(&xt[i].target); 787 INIT_LIST_HEAD(&xt[i].target);
675 INIT_LIST_HEAD(&xt[i].match); 788 INIT_LIST_HEAD(&xt[i].match);
676 INIT_LIST_HEAD(&xt[i].tables); 789 INIT_LIST_HEAD(&xt[i].tables);