net/ipv6: set expires in rt6_add_dflt_router().
authorKui-Feng Lee <thinker.li@gmail.com>
Thu, 8 Feb 2024 22:06:49 +0000 (14:06 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 12 Feb 2024 10:24:12 +0000 (10:24 +0000)
Pass the duration of a lifetime (in seconds) to the function
rt6_add_dflt_router() so that it can properly set the expiration time.

The function ndisc_router_discovery() is the only one that calls
rt6_add_dflt_router(), and it will later set the expiration time for the
route created by rt6_add_dflt_router(). However, there is a gap of time
between calling rt6_add_dflt_router() and setting the expiration time in
ndisc_router_discovery(). During this period, there is a possibility that a
new route may be removed from the routing table. By setting the correct
expiration time in rt6_add_dflt_router(), we can prevent this from
happening. The reason for setting RTF_EXPIRES in rt6_add_dflt_router() is
to start the Garbage Collection (GC) timer, as it only activates when a
route with RTF_EXPIRES is added to a table.

Suggested-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip6_route.h
net/ipv6/ndisc.c
net/ipv6/route.c

index 28b0657902615157c4cbd836cc70e0767cf49a4d..52a51c69aa9de2fe1e6d351997f5b3d94862521a 100644 (file)
@@ -170,7 +170,8 @@ struct fib6_info *rt6_get_dflt_router(struct net *net,
 struct fib6_info *rt6_add_dflt_router(struct net *net,
                                     const struct in6_addr *gwaddr,
                                     struct net_device *dev, unsigned int pref,
-                                    u32 defrtr_usr_metric);
+                                    u32 defrtr_usr_metric,
+                                    int lifetime);
 
 void rt6_purge_dflt_routers(struct net *net);
 
index a19999b30bc07d50a83c41d5a985a69cf565db08..a68462668158b4203e871e5057cde4fecf0d49ac 100644 (file)
@@ -1382,7 +1382,8 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
                        neigh_release(neigh);
 
                rt = rt6_add_dflt_router(net, &ipv6_hdr(skb)->saddr,
-                                        skb->dev, pref, defrtr_usr_metric);
+                                        skb->dev, pref, defrtr_usr_metric,
+                                        lifetime);
                if (!rt) {
                        ND_PRINTK(0, err,
                                  "RA: %s failed to add default route\n",
index 63b4c60565820c712a9f1b1f43c14785e932f803..98abba8f15cdc6400e86625de704e2bc9b6c1501 100644 (file)
@@ -4355,7 +4355,8 @@ struct fib6_info *rt6_add_dflt_router(struct net *net,
                                     const struct in6_addr *gwaddr,
                                     struct net_device *dev,
                                     unsigned int pref,
-                                    u32 defrtr_usr_metric)
+                                    u32 defrtr_usr_metric,
+                                    int lifetime)
 {
        struct fib6_config cfg = {
                .fc_table       = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT,
@@ -4368,6 +4369,7 @@ struct fib6_info *rt6_add_dflt_router(struct net *net,
                .fc_nlinfo.portid = 0,
                .fc_nlinfo.nlh = NULL,
                .fc_nlinfo.nl_net = net,
+               .fc_expires = jiffies_to_clock_t(lifetime * HZ),
        };
 
        cfg.fc_gateway = *gwaddr;