Commit 9e3466b3 authored by Rusty Russell's avatar Rusty Russell Committed by Patrick McHardy

[NETFILTER]: Change MASQUERADE to Use Device Address Directly

Instead of doing a dubious route lookup, just use the first IP address
of the (dynamic) interface.  Also, reset assured bit so after masq
connections can be cleaned up if memory pressure.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 6d441174
......@@ -82,7 +82,6 @@ masquerade_target(struct sk_buff **pskb,
const struct ip_nat_multi_range *mr;
struct ip_nat_multi_range newrange;
u_int32_t newsrc;
struct rtable *rt;
IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
......@@ -96,36 +95,12 @@ masquerade_target(struct sk_buff **pskb,
|| ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
mr = targinfo;
{
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = (*pskb)->nh.iph->daddr,
.tos = (RT_TOS((*pskb)->nh.iph->tos) |
RTO_CONN),
#ifdef CONFIG_IP_ROUTE_FWMARK
.fwmark = (*pskb)->nfmark
#endif
} } };
if (ip_route_output_key(&rt, &fl) != 0) {
/* Funky routing can do this. */
if (net_ratelimit())
printk("MASQUERADE:"
" No route: Rusty's brain broke!\n");
return NF_DROP;
}
if (rt->u.dst.dev != out) {
if (net_ratelimit())
printk("MASQUERADE:"
" Route sent us somewhere else.\n");
ip_rt_put(rt);
return NF_DROP;
}
newsrc = inet_select_addr(out, 0, RT_SCOPE_UNIVERSE);
if (!newsrc) {
printk("MASQUERADE: %s ate my IP address\n", out->name);
return NF_DROP;
}
newsrc = rt->rt_src;
DEBUGP("newsrc = %u.%u.%u.%u\n", NIPQUAD(newsrc));
ip_rt_put(rt);
WRITE_LOCK(&masq_lock);
ct->nat.masq_index = out->ifindex;
WRITE_UNLOCK(&masq_lock);
......@@ -157,6 +132,18 @@ device_cmp(const struct ip_conntrack *i, void *_ina)
return ret;
}
static inline int
connect_unassure(const struct ip_conntrack *i, void *_ina)
{
struct in_ifaddr *ina = _ina;
/* We reset the ASSURED bit on all connections, so they will
* get reaped under memory pressure. */
if (i->nat.masq_index == ina->ifa_dev->dev->ifindex)
clear_bit(IPS_ASSURED_BIT, (unsigned long *)&i->status);
return 0;
}
static int masq_inet_event(struct notifier_block *this,
unsigned long event,
void *ptr)
......@@ -166,6 +153,8 @@ static int masq_inet_event(struct notifier_block *this,
* entries. */
if (event == NETDEV_UP)
ip_ct_selective_cleanup(device_cmp, ptr);
else if (event == NETDEV_DOWN)
ip_ct_selective_cleanup(connect_unassure, ptr);
return NOTIFY_DONE;
}
......
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