This patch breaks up ip6_rt_copy() into ip6_rt_copy_init() and
ip6_rt_cache_alloc().

In the later patch, we need to create a percpu rt6_info copy. Hence,
refactor the common rt6_info init codes to ip6_rt_copy_init().

Signed-off-by: Martin KaFai Lau <[email protected]>
Reviewed-by: Hannes Frederic Sowa <[email protected]>
Cc: Steffen Klassert <[email protected]>
---
 net/ipv6/route.c | 80 ++++++++++++++++++++++++++++++++------------------------
 1 file changed, 46 insertions(+), 34 deletions(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 09ab0f4..cb3c585 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -72,8 +72,11 @@ enum rt6_nud_state {
        RT6_NUD_SUCCEED = 1
 };
 
-static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
-                                   const struct in6_addr *dest);
+static void ip6_rt_copy_init(struct rt6_info *rt,
+                            struct rt6_info *ort,
+                            const struct in6_addr *dest);
+static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort,
+                                          const struct in6_addr *dest);
 static struct dst_entry        *ip6_dst_check(struct dst_entry *dst, u32 
cookie);
 static unsigned int     ip6_default_advmss(const struct dst_entry *dst);
 static unsigned int     ip6_mtu(const struct dst_entry *dst);
@@ -848,11 +851,9 @@ static struct rt6_info *ip6_pmtu_rt_cache_alloc(struct 
rt6_info *ort,
         *      Clone the route.
         */
 
-       rt = ip6_rt_copy(ort, daddr);
+       rt = ip6_rt_cache_alloc(ort, daddr);
 
        if (rt) {
-               rt->rt6i_flags |= RTF_CACHE;
-
                if (!rt6_is_gw_or_nonexthop(ort)) {
                        if (ort->rt6i_dst.plen != 128 &&
                            ipv6_addr_equal(&ort->rt6i_dst.addr, daddr))
@@ -1865,7 +1866,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct 
sock *sk, struct sk_bu
                                     NEIGH_UPDATE_F_ISROUTER))
                     );
 
-       nrt = ip6_rt_copy(rt, &msg->dest);
+       nrt = ip6_rt_cache_alloc(rt, &msg->dest);
        if (!nrt)
                goto out;
 
@@ -1907,41 +1908,52 @@ static void rt6_set_from(struct rt6_info *rt, struct 
rt6_info *from)
        dst_init_metrics(&rt->dst, dst_metrics_ptr(&from->dst), true);
 }
 
-static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
-                                   const struct in6_addr *dest)
+static void ip6_rt_copy_init(struct rt6_info *rt,
+                            struct rt6_info *ort,
+                            const struct in6_addr *dest)
 {
-       struct net *net = dev_net(ort->dst.dev);
-       struct rt6_info *rt;
-
-       if (ort->rt6i_flags & RTF_CACHE)
-               ort = (struct rt6_info *)ort->dst.from;
-
-       rt = ip6_dst_alloc(net, ort->dst.dev, 0,
-                          ort->rt6i_table);
-
-       if (rt) {
-               rt->dst.input = ort->dst.input;
-               rt->dst.output = ort->dst.output;
+       if (dest) {
                rt->dst.flags |= DST_HOST;
-
                rt->rt6i_dst.addr = *dest;
                rt->rt6i_dst.plen = 128;
-               rt->dst.error = ort->dst.error;
-               rt->rt6i_idev = ort->rt6i_idev;
-               if (rt->rt6i_idev)
-                       in6_dev_hold(rt->rt6i_idev);
-               rt->dst.lastuse = jiffies;
-               rt->rt6i_gateway = ort->rt6i_gateway;
-               rt->rt6i_flags = ort->rt6i_flags;
-               rt6_set_from(rt, ort);
-               rt->rt6i_metric = 0;
+       } else {
+               rt->rt6i_dst = ort->rt6i_dst;
+       }
 
+       rt->dst.input = ort->dst.input;
+       rt->dst.output = ort->dst.output;
+       rt->dst.error = ort->dst.error;
+       rt->rt6i_idev = ort->rt6i_idev;
+       if (rt->rt6i_idev)
+               in6_dev_hold(rt->rt6i_idev);
+       rt->dst.lastuse = jiffies;
+       rt->rt6i_gateway = ort->rt6i_gateway;
+       rt->rt6i_flags = ort->rt6i_flags;
+       rt6_set_from(rt, ort);
+       rt->rt6i_metric = ort->rt6i_metric;
 #ifdef CONFIG_IPV6_SUBTREES
-               memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
+       rt->rt6i_src = ort->rt6i_src;
 #endif
-               memcpy(&rt->rt6i_prefsrc, &ort->rt6i_prefsrc, sizeof(struct 
rt6key));
-               rt->rt6i_table = ort->rt6i_table;
-       }
+       rt->rt6i_prefsrc = ort->rt6i_prefsrc;
+       rt->rt6i_table = ort->rt6i_table;
+}
+
+static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort,
+                                          const struct in6_addr *dest)
+{
+       struct rt6_info *rt;
+
+       if (ort->rt6i_flags & RTF_CACHE)
+               ort = (struct rt6_info *)ort->dst.from;
+
+       rt = ip6_dst_alloc(dev_net(ort->dst.dev), ort->dst.dev,
+                          0, ort->rt6i_table);
+
+       if (!rt)
+               return NULL;
+       ip6_rt_copy_init(rt, ort, dest);
+       rt->rt6i_flags |= RTF_CACHE;
+       rt->rt6i_metric = 0;
        return rt;
 }
 
-- 
1.8.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to