Commit 8b699049 authored by Rusty Russell's avatar Rusty Russell Committed by Hideaki Yoshifuji

[NETFILTER]: MASQUERADE target for mostly-static IP addresses.

Herve Eychenne noted that many ADSL connections get the same
address when the interface comes back up, so some users use SNAT
instead of masquerade.  The answer is that MASQUERADE should only
drop connections when the interface comes up, and then only if the
interface address has actually changed.
parent 1c9bfd4a
......@@ -130,57 +130,35 @@ masquerade_target(struct sk_buff **pskb,
}
static inline int
device_cmp(const struct ip_conntrack *i, void *ifindex)
device_cmp(const struct ip_conntrack *i, void *_ina)
{
int ret;
int ret = 0;
struct in_ifaddr *ina = _ina;
READ_LOCK(&masq_lock);
ret = (i->nat.masq_index == (int)(long)ifindex);
/* If it's masquerading out this interface with a different address,
or we don't know the new address of this interface. */
if (i->nat.masq_index == ina->ifa_dev->dev->ifindex
&& i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address)
ret = 1;
READ_UNLOCK(&masq_lock);
return ret;
}
static int masq_device_event(struct notifier_block *this,
unsigned long event,
void *ptr)
{
struct net_device *dev = ptr;
if (event == NETDEV_DOWN) {
/* Device was downed. Search entire table for
conntracks which were associated with that device,
and forget them. */
IP_NF_ASSERT(dev->ifindex != 0);
ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
}
return NOTIFY_DONE;
}
static int masq_inet_event(struct notifier_block *this,
unsigned long event,
void *ptr)
{
struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
if (event == NETDEV_DOWN) {
/* IP address was deleted. Search entire table for
conntracks which were associated with that device,
and forget them. */
IP_NF_ASSERT(dev->ifindex != 0);
ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
}
/* For some configurations, interfaces often come back with
* the same address. If not, clean up old conntrack
* entries. */
if (event == NETDEV_UP)
ip_ct_selective_cleanup(device_cmp, ptr);
return NOTIFY_DONE;
}
static struct notifier_block masq_dev_notifier = {
.notifier_call = masq_device_event,
};
static struct notifier_block masq_inet_notifier = {
.notifier_call = masq_inet_event,
};
......@@ -198,12 +176,9 @@ static int __init init(void)
ret = ipt_register_target(&masquerade);
if (ret == 0) {
/* Register for device down reports */
register_netdevice_notifier(&masq_dev_notifier);
if (ret == 0)
/* Register IP address change reports */
register_inetaddr_notifier(&masq_inet_notifier);
}
return ret;
}
......@@ -211,7 +186,6 @@ static int __init init(void)
static void __exit fini(void)
{
ipt_unregister_target(&masquerade);
unregister_netdevice_notifier(&masq_dev_notifier);
unregister_inetaddr_notifier(&masq_inet_notifier);
}
......
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