aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-24 20:42:21 -0400
committerDavid S. Miller <davem@davemloft.net>2011-03-24 20:42:21 -0400
commit436c3b66ec9824a633724ae42de1c416af4f2063 (patch)
tree8da6452386b6e900c4226c9b67694d1ea21e847e /net/ipv4/route.c
parentf7594d42944c0dfca90318f50978a4bdf8504086 (diff)
ipv4: Invalidate nexthop cache nh_saddr more correctly.
Any operation that: 1) Brings up an interface 2) Adds an IP address to an interface 3) Deletes an IP address from an interface can potentially invalidate the nh_saddr value, requiring it to be recomputed. Perform the recomputation lazily using a generation ID. Reported-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 34921b0d3f8e..4b0c81180804 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1718,7 +1718,7 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt)
1718 1718
1719 rcu_read_lock(); 1719 rcu_read_lock();
1720 if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0) 1720 if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0)
1721 src = FIB_RES_PREFSRC(res); 1721 src = FIB_RES_PREFSRC(dev_net(rt->dst.dev), res);
1722 else 1722 else
1723 src = inet_select_addr(rt->dst.dev, rt->rt_gateway, 1723 src = inet_select_addr(rt->dst.dev, rt->rt_gateway,
1724 RT_SCOPE_UNIVERSE); 1724 RT_SCOPE_UNIVERSE);
@@ -2615,7 +2615,7 @@ static struct rtable *ip_route_output_slow(struct net *net,
2615 fib_select_default(&res); 2615 fib_select_default(&res);
2616 2616
2617 if (!fl4.saddr) 2617 if (!fl4.saddr)
2618 fl4.saddr = FIB_RES_PREFSRC(res); 2618 fl4.saddr = FIB_RES_PREFSRC(net, res);
2619 2619
2620 dev_out = FIB_RES_DEV(res); 2620 dev_out = FIB_RES_DEV(res);
2621 fl4.flowi4_oif = dev_out->ifindex; 2621 fl4.flowi4_oif = dev_out->ifindex;
@@ -3219,6 +3219,8 @@ static __net_init int rt_genid_init(struct net *net)
3219{ 3219{
3220 get_random_bytes(&net->ipv4.rt_genid, 3220 get_random_bytes(&net->ipv4.rt_genid,
3221 sizeof(net->ipv4.rt_genid)); 3221 sizeof(net->ipv4.rt_genid));
3222 get_random_bytes(&net->ipv4.dev_addr_genid,
3223 sizeof(net->ipv4.dev_addr_genid));
3222 return 0; 3224 return 0;
3223} 3225}
3224 3226