Commit d9c7f710 authored by Rusty Russell's avatar Rusty Russell Committed by Linus Torvalds

[PATCH] Remove NAT to multiple ranges

The NAT code has the concept of multiple ranges: you can say "map this
connection onto IP 192.168.1.2 - 192.168.1.4, 192.168.1.7 ports
1024-65535, and 192.168.1.10".  I implemented this because we could.

But it's not actually *used* by many (any?) people, and you can
approximate this by a random match (from patch-o-matic) if you really
want to.  It adds complexity to the code.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a18d7224
......@@ -41,10 +41,10 @@ struct ip_nat_range
union ip_conntrack_manip_proto min, max;
};
/* A range consists of an array of 1 or more ip_nat_range */
struct ip_nat_multi_range
/* For backwards compat: don't use in modern code. */
struct ip_nat_multi_range_compat
{
unsigned int rangesize;
unsigned int rangesize; /* Must be 1. */
/* hangs off end. */
struct ip_nat_range range[1];
......@@ -96,7 +96,7 @@ struct ip_nat_info
/* Set up the info structure to map into this range. */
extern unsigned int ip_nat_setup_info(struct ip_conntrack *conntrack,
const struct ip_nat_multi_range *mr,
const struct ip_nat_range *range,
unsigned int hooknum);
/* Is this tuple already taken? (not by us)*/
......@@ -107,5 +107,7 @@ extern int ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple,
extern u_int16_t ip_nat_cheat_check(u_int32_t oldvalinv,
u_int32_t newval,
u_int16_t oldcheck);
#else /* !__KERNEL__: iptables wants this to compile. */
#define ip_nat_multi_range ip_nat_multi_range_compat
#endif /*__KERNEL__*/
#endif
......@@ -39,7 +39,7 @@ amanda_nat_expected(struct sk_buff **pskb,
{
struct ip_conntrack *master = master_ct(ct);
struct ip_ct_amanda_expect *exp_amanda_info;
struct ip_nat_multi_range mr;
struct ip_nat_range range;
u_int32_t newip;
IP_NF_ASSERT(info);
......@@ -51,20 +51,19 @@ amanda_nat_expected(struct sk_buff **pskb,
else
newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
mr.rangesize = 1;
/* We don't want to manip the per-protocol, just the IPs. */
mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
mr.range[0].min_ip = mr.range[0].max_ip = newip;
range.flags = IP_NAT_RANGE_MAP_IPS;
range.min_ip = range.max_ip = newip;
if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
exp_amanda_info = &ct->master->help.exp_amanda_info;
mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
mr.range[0].min = mr.range[0].max
range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
range.min = range.max
= ((union ip_conntrack_manip_proto)
{ .udp = { htons(exp_amanda_info->port) } });
}
return ip_nat_setup_info(ct, &mr, hooknum);
return ip_nat_setup_info(ct, &range, hooknum);
}
static int amanda_data_fixup(struct ip_conntrack *ct,
......
This diff is collapsed.
......@@ -44,7 +44,7 @@ ftp_nat_expected(struct sk_buff **pskb,
struct ip_conntrack *ct,
struct ip_nat_info *info)
{
struct ip_nat_multi_range mr;
struct ip_nat_range range;
u_int32_t newdstip, newsrcip, newip;
struct ip_ct_ftp_expect *exp_ftp_info;
......@@ -80,20 +80,19 @@ ftp_nat_expected(struct sk_buff **pskb,
DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
mr.rangesize = 1;
/* We don't want to manip the per-protocol, just the IPs... */
mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
mr.range[0].min_ip = mr.range[0].max_ip = newip;
range.flags = IP_NAT_RANGE_MAP_IPS;
range.min_ip = range.max_ip = newip;
/* ... unless we're doing a MANIP_DST, in which case, make
sure we map to the correct port */
if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
mr.range[0].min = mr.range[0].max
range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
range.min = range.max
= ((union ip_conntrack_manip_proto)
{ .tcp = { htons(exp_ftp_info->port) } });
}
return ip_nat_setup_info(ct, &mr, hooknum);
return ip_nat_setup_info(ct, &range, hooknum);
}
static int
......
......@@ -53,7 +53,7 @@ irc_nat_expected(struct sk_buff **pskb,
struct ip_conntrack *ct,
struct ip_nat_info *info)
{
struct ip_nat_multi_range mr;
struct ip_nat_range range;
u_int32_t newdstip, newsrcip, newip;
struct ip_conntrack *master = master_ct(ct);
......@@ -77,12 +77,11 @@ irc_nat_expected(struct sk_buff **pskb,
DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
mr.rangesize = 1;
/* We don't want to manip the per-protocol, just the IPs. */
mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
mr.range[0].min_ip = mr.range[0].max_ip = newip;
range.flags = IP_NAT_RANGE_MAP_IPS;
range.min_ip = range.max_ip = newip;
return ip_nat_setup_info(ct, &mr, hooknum);
return ip_nat_setup_info(ct, &range, hooknum);
}
static int irc_data_fixup(const struct ip_ct_irc_expect *exp_irc_info,
......
......@@ -126,6 +126,7 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
const struct ip_nat_multi_range_compat *mr = targinfo;
IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
......@@ -136,7 +137,7 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
|| ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
IP_NF_ASSERT(out);
return ip_nat_setup_info(ct, targinfo, hooknum);
return ip_nat_setup_info(ct, &mr->range[0], hooknum);
}
static unsigned int ipt_dnat_target(struct sk_buff **pskb,
......@@ -148,6 +149,7 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb,
{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
const struct ip_nat_multi_range_compat *mr = targinfo;
IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
|| hooknum == NF_IP_LOCAL_OUT);
......@@ -157,7 +159,7 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb,
/* Connection must be valid and new. */
IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
return ip_nat_setup_info(ct, targinfo, hooknum);
return ip_nat_setup_info(ct, &mr->range[0], hooknum);
}
static int ipt_snat_checkentry(const char *tablename,
......@@ -166,17 +168,15 @@ static int ipt_snat_checkentry(const char *tablename,
unsigned int targinfosize,
unsigned int hook_mask)
{
struct ip_nat_multi_range *mr = targinfo;
struct ip_nat_multi_range_compat *mr = targinfo;
/* Must be a valid range */
if (targinfosize < sizeof(struct ip_nat_multi_range)) {
DEBUGP("SNAT: Target size %u too small\n", targinfosize);
if (mr->rangesize != 1) {
printk("SNAT: multiple ranges no longer supported\n");
return 0;
}
if (targinfosize != IPT_ALIGN((sizeof(struct ip_nat_multi_range)
+ (sizeof(struct ip_nat_range)
* (mr->rangesize - 1))))) {
if (targinfosize != sizeof(struct ip_nat_multi_range_compat)) {
DEBUGP("SNAT: Target size %u wrong for %u ranges\n",
targinfosize, mr->rangesize);
return 0;
......@@ -201,17 +201,15 @@ static int ipt_dnat_checkentry(const char *tablename,
unsigned int targinfosize,
unsigned int hook_mask)
{
struct ip_nat_multi_range *mr = targinfo;
struct ip_nat_multi_range_compat *mr = targinfo;
/* Must be a valid range */
if (targinfosize < sizeof(struct ip_nat_multi_range)) {
DEBUGP("DNAT: Target size %u too small\n", targinfosize);
if (mr->rangesize != 1) {
printk("DNAT: multiple ranges no longer supported\n");
return 0;
}
if (targinfosize != IPT_ALIGN((sizeof(struct ip_nat_multi_range)
+ (sizeof(struct ip_nat_range)
* (mr->rangesize - 1))))) {
if (targinfosize != sizeof(struct ip_nat_multi_range_compat)) {
DEBUGP("DNAT: Target size %u wrong for %u ranges\n",
targinfosize, mr->rangesize);
return 0;
......@@ -244,12 +242,12 @@ alloc_null_binding(struct ip_conntrack *conntrack,
= (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
: conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
struct ip_nat_multi_range mr
= { 1, { { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } } } };
struct ip_nat_range range
= { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } };
DEBUGP("Allocating NULL binding for %p (%u.%u.%u.%u)\n", conntrack,
NIPQUAD(ip));
return ip_nat_setup_info(conntrack, &mr, hooknum);
return ip_nat_setup_info(conntrack, &range, hooknum);
}
int ip_nat_rule_find(struct sk_buff **pskb,
......
......@@ -107,7 +107,7 @@ tftp_nat_expected(struct sk_buff **pskb,
const struct ip_conntrack *master = ct->master->expectant;
const struct ip_conntrack_tuple *orig =
&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
struct ip_nat_multi_range mr;
struct ip_nat_range range;
#if 0
const struct ip_conntrack_tuple *repl =
&master->tuplehash[IP_CT_DIR_REPLY].tuple;
......@@ -124,21 +124,19 @@ tftp_nat_expected(struct sk_buff **pskb,
IP_NF_ASSERT(master);
IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
mr.rangesize = 1;
mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
range.flags = IP_NAT_RANGE_MAP_IPS;
if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) {
mr.range[0].min_ip = mr.range[0].max_ip = orig->dst.ip;
range.min_ip = range.max_ip = orig->dst.ip;
DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
"newsrc: %u.%u.%u.%u\n",
NIPQUAD((*pskb)->nh.iph->saddr), ntohs(uh->source),
NIPQUAD((*pskb)->nh.iph->daddr), ntohs(uh->dest),
NIPQUAD(orig->dst.ip));
} else {
mr.range[0].min_ip = mr.range[0].max_ip = orig->src.ip;
mr.range[0].min.udp.port = mr.range[0].max.udp.port =
orig->src.u.udp.port;
mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
range.min_ip = range.max_ip = orig->src.ip;
range.min.udp.port = range.max.udp.port = orig->src.u.udp.port;
range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
"newdst: %u.%u.%u.%u:%u\n",
......@@ -147,7 +145,7 @@ tftp_nat_expected(struct sk_buff **pskb,
NIPQUAD(orig->src.ip), ntohs(orig->src.u.udp.port));
}
return ip_nat_setup_info(ct,&mr,hooknum);
return ip_nat_setup_info(ct, &range, hooknum);
}
static struct ip_nat_helper tftp[MAX_PORTS];
......
......@@ -43,7 +43,7 @@ masquerade_check(const char *tablename,
unsigned int targinfosize,
unsigned int hook_mask)
{
const struct ip_nat_multi_range *mr = targinfo;
const struct ip_nat_multi_range_compat *mr = targinfo;
if (strcmp(tablename, "nat") != 0) {
DEBUGP("masquerade_check: bad table `%s'.\n", tablename);
......@@ -79,8 +79,8 @@ masquerade_target(struct sk_buff **pskb,
{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
const struct ip_nat_multi_range *mr;
struct ip_nat_multi_range newrange;
const struct ip_nat_multi_range_compat *mr;
struct ip_nat_range newrange;
struct rtable *rt;
u_int32_t newsrc;
......@@ -108,10 +108,10 @@ masquerade_target(struct sk_buff **pskb,
WRITE_UNLOCK(&masq_lock);
/* Transfer from original range. */
newrange = ((struct ip_nat_multi_range)
{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
newsrc, newsrc,
mr->range[0].min, mr->range[0].max } } });
newrange = ((struct ip_nat_range)
{ mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
newsrc, newsrc,
mr->range[0].min, mr->range[0].max });
/* Hand modified range to generic setup. */
return ip_nat_setup_info(ct, &newrange, hooknum);
......
......@@ -36,7 +36,7 @@ check(const char *tablename,
unsigned int targinfosize,
unsigned int hook_mask)
{
const struct ip_nat_multi_range *mr = targinfo;
const struct ip_nat_multi_range_compat *mr = targinfo;
if (strcmp(tablename, "nat") != 0) {
DEBUGP(MODULENAME":check: bad table `%s'.\n", tablename);
......@@ -72,8 +72,8 @@ target(struct sk_buff **pskb,
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
u_int32_t new_ip, netmask;
const struct ip_nat_multi_range *mr = targinfo;
struct ip_nat_multi_range newrange;
const struct ip_nat_multi_range_compat *mr = targinfo;
struct ip_nat_range newrange;
IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
|| hooknum == NF_IP_POST_ROUTING);
......@@ -87,10 +87,10 @@ target(struct sk_buff **pskb,
new_ip = (*pskb)->nh.iph->saddr & ~netmask;
new_ip |= mr->range[0].min_ip & netmask;
newrange = ((struct ip_nat_multi_range)
{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
new_ip, new_ip,
mr->range[0].min, mr->range[0].max } } });
newrange = ((struct ip_nat_range)
{ mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
new_ip, new_ip,
mr->range[0].min, mr->range[0].max });
/* Hand modified range to generic setup. */
return ip_nat_setup_info(ct, &newrange, hooknum);
......
......@@ -38,7 +38,7 @@ redirect_check(const char *tablename,
unsigned int targinfosize,
unsigned int hook_mask)
{
const struct ip_nat_multi_range *mr = targinfo;
const struct ip_nat_multi_range_compat *mr = targinfo;
if (strcmp(tablename, "nat") != 0) {
DEBUGP("redirect_check: bad table `%s'.\n", table);
......@@ -74,8 +74,8 @@ redirect_target(struct sk_buff **pskb,
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
u_int32_t newdst;
const struct ip_nat_multi_range *mr = targinfo;
struct ip_nat_multi_range newrange;
const struct ip_nat_multi_range_compat *mr = targinfo;
struct ip_nat_range newrange;
IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
|| hooknum == NF_IP_LOCAL_OUT);
......@@ -99,10 +99,10 @@ redirect_target(struct sk_buff **pskb,
}
/* Transfer from original range. */
newrange = ((struct ip_nat_multi_range)
{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
newdst, newdst,
mr->range[0].min, mr->range[0].max } } });
newrange = ((struct ip_nat_range)
{ mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
newdst, newdst,
mr->range[0].min, mr->range[0].max });
/* Hand modified range to generic setup. */
return ip_nat_setup_info(ct, &newrange, hooknum);
......
......@@ -149,8 +149,8 @@ same_target(struct sk_buff **pskb,
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
u_int32_t tmpip, aindex, new_ip;
const struct ipt_same_info *mr = targinfo;
struct ip_nat_multi_range newrange;
const struct ipt_same_info *same = targinfo;
struct ip_nat_range newrange;
const struct ip_conntrack_tuple *t;
IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
......@@ -161,17 +161,17 @@ same_target(struct sk_buff **pskb,
/* Base new source on real src ip and optionally dst ip,
giving some hope for consistency across reboots.
Here we calculate the index in mr->iparray which
Here we calculate the index in same->iparray which
holds the ipaddress we should use */
tmpip = ntohl(t->src.ip);
if (!(mr->info & IPT_SAME_NODST))
if (!(same->info & IPT_SAME_NODST))
tmpip += ntohl(t->dst.ip);
aindex = tmpip % mr->ipnum;
new_ip = htonl(mr->iparray[aindex]);
aindex = tmpip % same->ipnum;
new_ip = htonl(same->iparray[aindex]);
DEBUGP("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
"new src=%u.%u.%u.%u\n",
......@@ -179,10 +179,10 @@ same_target(struct sk_buff **pskb,
NIPQUAD(new_ip));
/* Transfer from original range. */
newrange = ((struct ip_nat_multi_range)
{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
new_ip, new_ip,
mr->range[0].min, mr->range[0].max } } });
newrange = ((struct ip_nat_range)
{ same->range[0].flags, new_ip, new_ip,
/* FIXME: Use ports from correct range! */
same->range[0].min, same->range[0].max });
/* Hand modified range to generic setup. */
return ip_nat_setup_info(ct, &newrange, hooknum);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment