Commit cebe84c6 authored by Xin Long's avatar Xin Long Committed by David S. Miller

route: also update fnhe_genid when updating a route cache

Now when ip route flush cache and it turn out all fnhe_genid != genid.
If a redirect/pmtu icmp packet comes and the old fnhe is found and all
it's members but fnhe_genid will be updated.

Then next time when it looks up route and tries to rebind this fnhe to
the new dst, the fnhe will be flushed due to fnhe_genid != genid. It
causes this redirect/pmtu icmp packet acutally not to be applied.

This patch is to also reset fnhe_genid when updating a route cache.

Fixes: 5aad1de5 ("ipv4: use separate genid for next hop exceptions")
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e39d5246
...@@ -651,9 +651,12 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, ...@@ -651,9 +651,12 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
struct fnhe_hash_bucket *hash; struct fnhe_hash_bucket *hash;
struct fib_nh_exception *fnhe; struct fib_nh_exception *fnhe;
struct rtable *rt; struct rtable *rt;
u32 genid, hval;
unsigned int i; unsigned int i;
int depth; int depth;
u32 hval = fnhe_hashfun(daddr);
genid = fnhe_genid(dev_net(nh->nh_dev));
hval = fnhe_hashfun(daddr);
spin_lock_bh(&fnhe_lock); spin_lock_bh(&fnhe_lock);
...@@ -676,6 +679,8 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, ...@@ -676,6 +679,8 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
} }
if (fnhe) { if (fnhe) {
if (fnhe->fnhe_genid != genid)
fnhe->fnhe_genid = genid;
if (gw) if (gw)
fnhe->fnhe_gw = gw; fnhe->fnhe_gw = gw;
if (pmtu) if (pmtu)
...@@ -699,7 +704,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, ...@@ -699,7 +704,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
fnhe->fnhe_next = hash->chain; fnhe->fnhe_next = hash->chain;
rcu_assign_pointer(hash->chain, fnhe); rcu_assign_pointer(hash->chain, fnhe);
} }
fnhe->fnhe_genid = fnhe_genid(dev_net(nh->nh_dev)); fnhe->fnhe_genid = genid;
fnhe->fnhe_daddr = daddr; fnhe->fnhe_daddr = daddr;
fnhe->fnhe_gw = gw; fnhe->fnhe_gw = gw;
fnhe->fnhe_pmtu = pmtu; fnhe->fnhe_pmtu = pmtu;
......
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