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 <han...@stressinduktion.org>
Signed-off-by: Xin Long <lucien....@gmail.com>
---
 net/ipv4/route.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 11cf2fe..43b69af 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -651,9 +651,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);
 
@@ -676,6 +679,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)
@@ -699,7 +704,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;
-- 
2.1.0

Reply via email to