[PATCH 2/2] iptables 32bit compat layer [message #1687] |
Mon, 20 February 2006 08:14 |
dim
Messages: 344 Registered: August 2005
|
Senior Member |
|
|
This patch introduces compatibility functions for some ip_tables matches and
targets, using interface provided in the first patch.
> Hello,
>
> This patch set 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.
>
--
Thanks,
Dmitry.
--- ./include/linux/netfilter/xt_conntrack.h.iptcompat2 2006-02-20 10:39:53.000000000 +0300
+++ ./include/linux/netfilter/xt_conntrack.h 2006-02-20 10:14:27.000000000 +0300
@@ -5,6 +5,7 @@
#ifndef _XT_CONNTRACK_H
#define _XT_CONNTRACK_H
+#include <linux/config.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <linux/in.h>
@@ -60,4 +61,21 @@ struct xt_conntrack_info
/* Inverse flags */
u_int8_t invflags;
};
+
+#ifdef CONFIG_COMPAT
+struct compat_xt_conntrack_info
+{
+ compat_uint_t statemask, statusmask;
+
+ struct ip_conntrack_tuple tuple[IP_CT_DIR_MAX];
+ struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
+
+ compat_ulong_t expires_min, expires_max;
+
+ /* Flags word */
+ u_int8_t flags;
+ /* Inverse flags */
+ u_int8_t invflags;
+};
+#endif
#endif /*_XT_CONNTRACK_H*/
--- ./include/linux/netfilter/xt_helper.h.iptcompat2 2006-02-20 10:39:06.000000000 +0300
+++ ./include/linux/netfilter/xt_helper.h 2006-02-20 10:42:24.000000000 +0300
@@ -1,8 +1,17 @@
#ifndef _XT_HELPER_H
#define _XT_HELPER_H
+#include <linux/config.h>
+
struct xt_helper_info {
int invert;
char name[30];
};
+
+#ifdef CONFIG_COMPAT
+struct compat_xt_helper_info {
+ compat_int_t invert;
+ char name[30];
+};
+#endif
#endif /* _XT_HELPER_H */
--- ./include/linux/netfilter/xt_limit.h.iptcompat2 2006-02-20 10:39:24.000000000 +0300
+++ ./include/linux/netfilter/xt_limit.h 2006-02-20 10:41:58.000000000 +0300
@@ -1,6 +1,8 @@
#ifndef _XT_RATE_H
#define _XT_RATE_H
+#include <linux/config.h>
+
/* timings are in milliseconds. */
#define XT_LIMIT_SCALE 10000
@@ -18,4 +20,19 @@ struct xt_rateinfo {
/* Ugly, ugly fucker. */
struct xt_rateinfo *master;
};
+
+#ifdef CONFIG_COMPAT
+struct compat_xt_rateinfo {
+ u_int32_t avg; /* Average secs between packets * scale */
+ u_int32_t burst; /* Period multiplier for upper limit. */
+
+ /* Used internally by the kernel */
+ compat_ulong_t prev;
+ u_int32_t credit;
+ u_int32_t credit_cap, cost;
+
+ /* Ugly, ugly fucker. */
+ compat_uptr_t master;
+};
+#endif
#endif /*_XT_RATE_H*/
--- ./include/linux/netfilter/xt_state.h.iptcompat2 2006-02-20 10:39:40.000000000 +0300
+++ ./include/linux/netfilter/xt_state.h 2006-02-20 10:42:13.000000000 +0300
@@ -1,6 +1,8 @@
#ifndef _XT_STATE_H
#define _XT_STATE_H
+#include <linux/config.h>
+
#define XT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define XT_STATE_INVALID (1 << 0)
@@ -10,4 +12,11 @@ struct xt_state_info
{
unsigned int statemask;
};
+
+#ifdef CONFIG_COMPAT
+struct compat_xt_state_info
+{
+ compat_uint_t statemask;
+};
+#endif
#endif /*_XT_STATE_H*/
--- ./include/linux/netfilter_ipv4/ip_nat.h.iptcompat2 2006-01-03 06:21:10.000000000 +0300
+++ ./include/linux/netfilter_ipv4/ip_nat.h 2006-02-20 10:56:20.000000000 +0300
@@ -1,5 +1,6 @@
#ifndef _IP_NAT_H
#define _IP_NAT_H
+#include <linux/config.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
@@ -76,6 +77,23 @@ extern int ip_nat_used_tuple(const struc
extern u_int16_t ip_nat_cheat_check(u_int32_t oldvalinv,
u_int32_t newval,
u_int16_t oldcheck);
+
+#ifdef CONFIG_COMPAT
+#include <net/compat.h>
+
+struct compat_ip_nat_range
+{
+ compat_uint_t flags;
+ u_int32_t min_ip, max_ip;
+ union ip_conntrack_manip_proto min, max;
+};
+
+struct compat_ip_nat_multi_range
+{
+ compat_uint_t rangesize;
+ struct compat_ip_nat_range range[1];
+};
+#endif
#else /* !__KERNEL__: iptables wants this to compile. */
#define ip_nat_multi_range ip_nat_multi_range_compat
#endif /*__KERNEL__*/
--- ./net/ipv4/netfilter/ip_nat_rule.c.iptcompat2 2006-02-15 16:06:42.000000000 +0300
+++ ./net/ipv4/netfilter/ip_nat_rule.c 2006-02-20 10:57:25.000000000 +0300
@@ -235,6 +235,93 @@ static int ipt_dnat_checkentry(const cha
return 1;
}
+#ifdef CONFIG_COMPAT
+static int compat_to_user(void *target, void **dstptr,
+ int *size, int off)
+{
+ struct ipt_entry_target *pt;
+ struct ip_nat_multi_range_compat *pinfo;
+ struct compat_ip_nat_multi_range info;
+ u_int16_t tsize;
+
+ pt = (struct ipt_entry_target *)target;
+ tsize = pt->u.user.target_size;
+ if (__copy_to_user(*dstptr, pt, sizeof(struct ipt_entry_target)))
+ return -EFAULT;
+ pinfo = (struct ip_nat_multi_range_compat *)pt->data;
+ memset(&info, 0, sizeof(struct compat_ip_nat_multi_range));
+ info.rangesize = pinfo->rangesize;
+ info.range[0].flags = pinfo->range[0].flags;
+ info.range[0].min_ip = pinfo->range[0].min_ip;
+ info.range[0].max_ip = pinfo->range[0].max_ip;
+ info.range[0].min = pinfo->range[0].min;
+ info.range[0].max = pinfo->range[0].max;
+ if (__copy_to_user(*dstptr + sizeof(struct ipt_entry_target),
+ &info, sizeof(struct compat_ip_nat_multi_range)))
+ return -EFAULT;
+ tsize -= off;
+ if (put_user(tsize, (u_int16_t *)*dstptr))
+ return -EFAULT;
+ *size -= off;
+ *dstptr += tsize;
+ return 0;
+}
+
+static int compat_from_user(void *target, void **dstptr,
+ int *size, int off)
+{
+ struct compat_ipt_entry_target *pt;
+ struct ipt_entry_target *dstpt;
+ struct compat_ip_nat_multi_range *pinfo;
+ struct ip_nat_multi_range_compat info;
+ u_int16_t tsize;
+
+ pt = (struct compat_ipt_entry_target *)target;
+ dstpt = (struct ipt_entry_target *)*dstptr;
+ tsize = pt->u.user.target_size;
+ memcpy(*dstptr, pt, sizeof(struct compat_ipt_entry_target));
+ pinfo = (struct compat_ip_nat_multi_range *)pt->data;
+ memset(&info, 0, sizeof(struct ip_nat_multi_range_compat));
+ info.rangesize = pinfo->rangesize;
+ info.range[0].flags = pinfo->range[0].flags;
+ info.range[0].min_ip = pinfo->range[0].min_ip;
+ info.range[0].max_ip = pinfo->range[0].max_ip;
+ info.range[0].min = pinfo->range[0].min;
+ info.range[0].max = pinfo->range[0].max;
+ memcpy(*dstptr + sizeof(struct compat_ipt_entry_target),
+ &info, sizeof(struct ip_nat_multi_range_compat));
+ tsize += off;
+ dstpt->u.user.target_size = tsize;
+ *size += off;
+ *dstptr += tsize;
+ return 0;
+}
+
+static int compat(void *target, void **dstptr, int *size, int convert)
+{
+ int ret, off;
+
+ off = IPT_ALIGN(sizeof(struct ip_nat_multi_range_compat)) -
+ COMPAT_IPT_ALIGN(sizeof(struct compat_ip_nat_multi_range));
+ switch (convert) {
+ case COMPAT_TO_USER:
+ ret = compat_to_user(target, dstptr, size, off);
+ break;
+ case COMPAT_FROM_USER:
+ ret = compat_from_user(target, dstptr, size, off);
+ break;
+ case COMPAT_CALC_SIZE:
+ *size += off;
+ ret = 0;
+ break;
+ default:
+ ret = -ENOPROTOOPT;
+ break;
+ }
+ return ret;
+}
+#endif
+
inline unsigned int
alloc_null_binding(struct ip_conntrack *conntrack,
struct ip_nat_info *info,
@@ -300,12 +387,18 @@ static struct ipt_target ipt_snat_reg =
.name = "SNAT",
.target = ipt_snat_target,
.checkentry = ipt_snat_checkentry,
+#ifdef CONFIG_COMPAT
+ .compat = &compat,
+#endif
};
static struct ipt_target ipt_dnat_reg = {
.name = "DNAT",
.target = ipt_dnat_target,
.checkentry = ipt_dnat_checkentry,
+#ifdef CONFIG_COMPAT
+ .compat = &compat,
+#endif
};
int __init ip_nat_rule_init(void)
--- ./net/ipv4/netfilter/ipt_LOG.c.iptcompat2 2006-02-15 16:06:42.000000000 +0300
+++ ./net/ipv4/netfilter/ipt_LOG.c 2006-02-20 10:05:08.000000000 +0300
@@ -458,10 +458,25 @@ static int ipt_log_checkentry(const char
return 1;
}
+#ifdef CONFIG_COMPAT
+static int ipt_log_compat(void *target,
+ void **dstptr, int *size, int convert)
+{
+ int off;
+
+ off = IPT_ALIGN(sizeof(struct ipt_log_info)) -
+ COMPAT_IPT_ALIGN(sizeof(struct ipt_log_info));
+ return ipt_target_align_compat(target, dstptr, size, off, convert);
+}
+#endif
+
static struct ipt_target ipt_log_reg = {
.name = "LOG",
.target = ipt_log_target,
.checkentry = ipt_log_checkentry,
+#ifdef CONFIG_COMPAT
+ .compat = ipt_log_compat,
+#endif
.me = THIS_MODULE,
};
--- ./net/ipv4/netfilter/ipt_REJECT.c.iptcompat2 2006-02-15 16:06:42.000000000 +0300
+++ ./net/ipv4/netfilter/ipt_REJECT.c 2006-02-20 10:05:08.000000000 +0300
@@ -322,10 +322,25 @@ static int check(const char *tablename,
return 1;
}
+#ifdef CONFIG_COMPAT
+static int compat(void *target,
+ void **dstptr, int *size, int convert)
+{
+ int off;
+
+ off = IPT_ALIGN(sizeof(struct ipt_reject_info)) -
+ COMPAT_IPT_ALIGN(sizeof(struct ipt_reject_info));
+ return ipt_target_align_compat(target, dstptr, size, off, convert);
+}
+#endif
+
static struct ipt_target ipt_reject_reg = {
.name = "REJECT",
.target = reject,
.checkentry = check,
+#ifdef CONFIG_COMPAT
+ .compat = compat,
+#endif
.me = THIS_MODULE,
};
--- ./net/ipv4/netfilter/ipt_TCPMSS.c.iptcompat2 2006-02-15 16:06:42.000000000 +0300
+++ ./net/ipv4/netfilter/ipt_TCPMSS.c 2006-02-20 10:05:08.000000000 +0300
@@ -242,10 +242,25 @@ ipt_tcpmss_checkentry(const char *tablen
return 0;
}
+#ifdef CONFIG_COMPAT
+static int ipt_tcpmss_compat(void *target,
+ void **dstptr, int *size, int convert)
+{
+ int off;
+
+ off = IPT_ALIGN(sizeof(struct ipt_tcpmss_info)) -
+ COMPAT_IPT_ALIGN(sizeof(struct ipt_tcpmss_info));
+ return ipt_target_align_compat(target, dstptr, size, off, convert);
+}
+#endif
+
static struct ipt_target ipt_tcpmss_reg = {
.name = "TCPMSS",
.target = ipt_tcpmss_target,
.checkentry = ipt_tcpmss_checkentry,
+#ifdef CONFIG_COMPAT
+ .compat = ipt_tcpmss_compat,
+#endif
.me = THIS_MODULE,
};
--- ./net/ipv4/netfilter/ipt_TOS.c.iptcompat2 2006-02-15 16:06:42.000000000 +0300
+++ ./net/ipv4/netfilter/ipt_TOS.c 20
...
|
|
|