@@ -72,8 +72,7 @@ enum rt6_nud_state {
7272 RT6_NUD_SUCCEED = 1
7373};
7474
75- static struct rt6_info * ip6_rt_copy (struct rt6_info * ort ,
76- const struct in6_addr * dest );
75+ static void ip6_rt_copy_init (struct rt6_info * rt , struct rt6_info * ort );
7776static struct dst_entry * ip6_dst_check (struct dst_entry * dst , u32 cookie );
7877static unsigned int ip6_default_advmss (const struct dst_entry * dst );
7978static unsigned int ip6_mtu (const struct dst_entry * dst );
@@ -913,22 +912,32 @@ static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort,
913912 * Clone the route.
914913 */
915914
916- rt = ip6_rt_copy (ort , daddr );
915+ if (ort -> rt6i_flags & RTF_CACHE )
916+ ort = (struct rt6_info * )ort -> dst .from ;
917917
918- if (rt ) {
919- rt -> rt6i_flags |= RTF_CACHE ;
918+ rt = ip6_dst_alloc (dev_net (ort -> dst .dev ), ort -> dst .dev ,
919+ 0 , ort -> rt6i_table );
920+
921+ if (!rt )
922+ return NULL ;
923+
924+ ip6_rt_copy_init (rt , ort );
925+ rt -> rt6i_flags |= RTF_CACHE ;
926+ rt -> rt6i_metric = 0 ;
927+ rt -> dst .flags |= DST_HOST ;
928+ rt -> rt6i_dst .addr = * daddr ;
929+ rt -> rt6i_dst .plen = 128 ;
920930
921- if (!rt6_is_gw_or_nonexthop (ort )) {
922- if (ort -> rt6i_dst .plen != 128 &&
923- ipv6_addr_equal (& ort -> rt6i_dst .addr , daddr ))
924- rt -> rt6i_flags |= RTF_ANYCAST ;
931+ if (!rt6_is_gw_or_nonexthop (ort )) {
932+ if (ort -> rt6i_dst .plen != 128 &&
933+ ipv6_addr_equal (& ort -> rt6i_dst .addr , daddr ))
934+ rt -> rt6i_flags |= RTF_ANYCAST ;
925935#ifdef CONFIG_IPV6_SUBTREES
926- if (rt -> rt6i_src .plen && saddr ) {
927- rt -> rt6i_src .addr = * saddr ;
928- rt -> rt6i_src .plen = 128 ;
929- }
930- #endif
936+ if (rt -> rt6i_src .plen && saddr ) {
937+ rt -> rt6i_src .addr = * saddr ;
938+ rt -> rt6i_src .plen = 128 ;
931939 }
940+ #endif
932941 }
933942
934943 return rt ;
@@ -1980,7 +1989,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
19801989 NEIGH_UPDATE_F_ISROUTER ))
19811990 );
19821991
1983- nrt = ip6_rt_copy (rt , & msg -> dest );
1992+ nrt = ip6_rt_cache_alloc (rt , & msg -> dest , NULL );
19841993 if (!nrt )
19851994 goto out ;
19861995
@@ -2022,42 +2031,25 @@ static void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
20222031 dst_init_metrics (& rt -> dst , dst_metrics_ptr (& from -> dst ), true);
20232032}
20242033
2025- static struct rt6_info * ip6_rt_copy (struct rt6_info * ort ,
2026- const struct in6_addr * dest )
2027- {
2028- struct net * net = dev_net (ort -> dst .dev );
2029- struct rt6_info * rt ;
2030-
2031- if (ort -> rt6i_flags & RTF_CACHE )
2032- ort = (struct rt6_info * )ort -> dst .from ;
2033-
2034- rt = ip6_dst_alloc (net , ort -> dst .dev , 0 ,
2035- ort -> rt6i_table );
2036-
2037- if (rt ) {
2038- rt -> dst .input = ort -> dst .input ;
2039- rt -> dst .output = ort -> dst .output ;
2040- rt -> dst .flags |= DST_HOST ;
2041-
2042- rt -> rt6i_dst .addr = * dest ;
2043- rt -> rt6i_dst .plen = 128 ;
2044- rt -> dst .error = ort -> dst .error ;
2045- rt -> rt6i_idev = ort -> rt6i_idev ;
2046- if (rt -> rt6i_idev )
2047- in6_dev_hold (rt -> rt6i_idev );
2048- rt -> dst .lastuse = jiffies ;
2049- rt -> rt6i_gateway = ort -> rt6i_gateway ;
2050- rt -> rt6i_flags = ort -> rt6i_flags ;
2051- rt6_set_from (rt , ort );
2052- rt -> rt6i_metric = 0 ;
2053-
2034+ static void ip6_rt_copy_init (struct rt6_info * rt , struct rt6_info * ort )
2035+ {
2036+ rt -> dst .input = ort -> dst .input ;
2037+ rt -> dst .output = ort -> dst .output ;
2038+ rt -> rt6i_dst = ort -> rt6i_dst ;
2039+ rt -> dst .error = ort -> dst .error ;
2040+ rt -> rt6i_idev = ort -> rt6i_idev ;
2041+ if (rt -> rt6i_idev )
2042+ in6_dev_hold (rt -> rt6i_idev );
2043+ rt -> dst .lastuse = jiffies ;
2044+ rt -> rt6i_gateway = ort -> rt6i_gateway ;
2045+ rt -> rt6i_flags = ort -> rt6i_flags ;
2046+ rt6_set_from (rt , ort );
2047+ rt -> rt6i_metric = ort -> rt6i_metric ;
20542048#ifdef CONFIG_IPV6_SUBTREES
2055- memcpy ( & rt -> rt6i_src , & ort -> rt6i_src , sizeof ( struct rt6key )) ;
2049+ rt -> rt6i_src = ort -> rt6i_src ;
20562050#endif
2057- memcpy (& rt -> rt6i_prefsrc , & ort -> rt6i_prefsrc , sizeof (struct rt6key ));
2058- rt -> rt6i_table = ort -> rt6i_table ;
2059- }
2060- return rt ;
2051+ rt -> rt6i_prefsrc = ort -> rt6i_prefsrc ;
2052+ rt -> rt6i_table = ort -> rt6i_table ;
20612053}
20622054
20632055#ifdef CONFIG_IPV6_ROUTE_INFO
0 commit comments