diff options
| author | Xin Long <lucien.xin@gmail.com> | 2017-11-17 14:27:18 +0800 |
|---|---|---|
| committer | Ben Hutchings <ben@decadent.org.uk> | 2018-02-13 18:42:26 +0000 |
| commit | a5cdb35c21b19bcc22b43c5140604c182ae533a4 (patch) | |
| tree | 788490918e6ad8e0babd460d14a971dfd12e0cb3 | |
| parent | 8741483f17570f513c5c46abb5e5fd777cd3aa50 (diff) | |
| download | linux-a5cdb35c21b19bcc22b43c5140604c182ae533a4.tar.gz linux-a5cdb35c21b19bcc22b43c5140604c182ae533a4.tar.bz2 linux-a5cdb35c21b19bcc22b43c5140604c182ae533a4.zip | |
route: also update fnhe_genid when updating a route cache
commit cebe84c6190d741045a322f5343f717139993c08 upstream.
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: 5aad1de5ea2c ("ipv4: use separate genid for next hop exceptions")
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
| -rw-r--r-- | net/ipv4/route.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index aab5eb56ec61..a7c1d6f798ea 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -623,9 +623,12 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, struct fnhe_hash_bucket *hash; struct fib_nh_exception *fnhe; struct rtable *rt; + u32 genid, hval; unsigned int i; int depth; - u32 hval = fnhe_hashfun(daddr); + + genid = fnhe_genid(dev_net(nh->nh_dev)); + hval = fnhe_hashfun(daddr); spin_lock_bh(&fnhe_lock); @@ -648,6 +651,8 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, } if (fnhe) { + if (fnhe->fnhe_genid != genid) + fnhe->fnhe_genid = genid; if (gw) fnhe->fnhe_gw = gw; if (pmtu) @@ -671,7 +676,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, fnhe->fnhe_next = hash->chain; 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_gw = gw; fnhe->fnhe_pmtu = pmtu; |
