@@ -138,15 +138,15 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
138138{
139139 struct sockaddr_in6 * usin = (struct sockaddr_in6 * ) uaddr ;
140140 struct inet_connection_sock * icsk = inet_csk (sk );
141- struct in6_addr * saddr = NULL , * final_p , final ;
142141 struct inet_timewait_death_row * tcp_death_row ;
143142 struct ipv6_pinfo * np = tcp_inet6_sk (sk );
143+ struct in6_addr * saddr = NULL , * final_p ;
144144 struct inet_sock * inet = inet_sk (sk );
145145 struct tcp_sock * tp = tcp_sk (sk );
146146 struct net * net = sock_net (sk );
147147 struct ipv6_txoptions * opt ;
148148 struct dst_entry * dst ;
149- struct flowi6 fl6 ;
149+ struct flowi6 * fl6 ;
150150 int addr_type ;
151151 int err ;
152152
@@ -156,14 +156,15 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
156156 if (usin -> sin6_family != AF_INET6 )
157157 return - EAFNOSUPPORT ;
158158
159- memset (& fl6 , 0 , sizeof (fl6 ));
159+ fl6 = & inet_sk (sk )-> cork .fl .u .ip6 ;
160+ memset (fl6 , 0 , sizeof (* fl6 ));
160161
161162 if (inet6_test_bit (SNDFLOW , sk )) {
162- fl6 . flowlabel = usin -> sin6_flowinfo & IPV6_FLOWINFO_MASK ;
163- IP6_ECN_flow_init (fl6 . flowlabel );
164- if (fl6 . flowlabel & IPV6_FLOWLABEL_MASK ) {
163+ fl6 -> flowlabel = usin -> sin6_flowinfo & IPV6_FLOWINFO_MASK ;
164+ IP6_ECN_flow_init (fl6 -> flowlabel );
165+ if (fl6 -> flowlabel & IPV6_FLOWLABEL_MASK ) {
165166 struct ip6_flowlabel * flowlabel ;
166- flowlabel = fl6_sock_lookup (sk , fl6 . flowlabel );
167+ flowlabel = fl6_sock_lookup (sk , fl6 -> flowlabel );
167168 if (IS_ERR (flowlabel ))
168169 return - EINVAL ;
169170 fl6_sock_release (flowlabel );
@@ -212,7 +213,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
212213 }
213214
214215 sk -> sk_v6_daddr = usin -> sin6_addr ;
215- np -> flow_label = fl6 . flowlabel ;
216+ np -> flow_label = fl6 -> flowlabel ;
216217
217218 /*
218219 * TCP over IPv4
@@ -260,24 +261,24 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
260261 if (!ipv6_addr_any (& sk -> sk_v6_rcv_saddr ))
261262 saddr = & sk -> sk_v6_rcv_saddr ;
262263
263- fl6 . flowi6_proto = IPPROTO_TCP ;
264- fl6 . daddr = sk -> sk_v6_daddr ;
265- fl6 . saddr = saddr ? * saddr : np -> saddr ;
266- fl6 . flowlabel = ip6_make_flowinfo (np -> tclass , np -> flow_label );
267- fl6 . flowi6_oif = sk -> sk_bound_dev_if ;
268- fl6 . flowi6_mark = sk -> sk_mark ;
269- fl6 . fl6_dport = usin -> sin6_port ;
270- fl6 . fl6_sport = inet -> inet_sport ;
271- if (IS_ENABLED (CONFIG_IP_ROUTE_MULTIPATH ) && !fl6 . fl6_sport )
272- fl6 . flowi6_flags = FLOWI_FLAG_ANY_SPORT ;
273- fl6 . flowi6_uid = sk_uid (sk );
264+ fl6 -> flowi6_proto = IPPROTO_TCP ;
265+ fl6 -> daddr = sk -> sk_v6_daddr ;
266+ fl6 -> saddr = saddr ? * saddr : np -> saddr ;
267+ fl6 -> flowlabel = ip6_make_flowinfo (np -> tclass , np -> flow_label );
268+ fl6 -> flowi6_oif = sk -> sk_bound_dev_if ;
269+ fl6 -> flowi6_mark = sk -> sk_mark ;
270+ fl6 -> fl6_dport = usin -> sin6_port ;
271+ fl6 -> fl6_sport = inet -> inet_sport ;
272+ if (IS_ENABLED (CONFIG_IP_ROUTE_MULTIPATH ) && !fl6 -> fl6_sport )
273+ fl6 -> flowi6_flags = FLOWI_FLAG_ANY_SPORT ;
274+ fl6 -> flowi6_uid = sk_uid (sk );
274275
275276 opt = rcu_dereference_protected (np -> opt , lockdep_sock_is_held (sk ));
276- final_p = fl6_update_dst (& fl6 , opt , & final );
277+ final_p = fl6_update_dst (fl6 , opt , & np -> final );
277278
278- security_sk_classify_flow (sk , flowi6_to_flowi_common (& fl6 ));
279+ security_sk_classify_flow (sk , flowi6_to_flowi_common (fl6 ));
279280
280- dst = ip6_dst_lookup_flow (net , sk , & fl6 , final_p );
281+ dst = ip6_dst_lookup_flow (net , sk , fl6 , final_p );
281282 if (IS_ERR (dst )) {
282283 err = PTR_ERR (dst );
283284 goto failure ;
@@ -287,7 +288,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
287288 tcp_death_row = & sock_net (sk )-> ipv4 .tcp_death_row ;
288289
289290 if (!saddr ) {
290- saddr = & fl6 . saddr ;
291+ saddr = & fl6 -> saddr ;
291292
292293 err = inet_bhash2_update_saddr (sk , saddr , AF_INET6 );
293294 if (err )
@@ -538,7 +539,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
538539 u8 tclass ;
539540
540541 /* First, grab a route. */
541- if (!dst && (dst = inet6_csk_route_req (sk , fl6 , req ,
542+ if (!dst && (dst = inet6_csk_route_req (sk , NULL , fl6 , req ,
542543 IPPROTO_TCP )) == NULL )
543544 goto done ;
544545
@@ -788,7 +789,7 @@ static struct dst_entry *tcp_v6_route_req(const struct sock *sk,
788789 if (security_inet_conn_request (sk , skb , req ))
789790 return NULL ;
790791
791- return inet6_csk_route_req (sk , & fl -> u .ip6 , req , IPPROTO_TCP );
792+ return inet6_csk_route_req (sk , NULL , & fl -> u .ip6 , req , IPPROTO_TCP );
792793}
793794
794795struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
@@ -1317,12 +1318,12 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
13171318 struct request_sock * req_unhash ,
13181319 bool * own_req )
13191320{
1320- struct inet_request_sock * ireq ;
1321- struct ipv6_pinfo * newnp ;
13221321 const struct ipv6_pinfo * np = tcp_inet6_sk (sk );
1322+ struct inet_request_sock * ireq ;
13231323 struct ipv6_txoptions * opt ;
13241324 struct inet_sock * newinet ;
13251325 bool found_dup_sk = false;
1326+ struct ipv6_pinfo * newnp ;
13261327 struct tcp_sock * newtp ;
13271328 struct sock * newsk ;
13281329#ifdef CONFIG_TCP_MD5SIG
@@ -1391,11 +1392,9 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
13911392 if (sk_acceptq_is_full (sk ))
13921393 goto exit_overflow ;
13931394
1394- if (!dst ) {
1395- dst = inet6_csk_route_req (sk , & fl6 , req , IPPROTO_TCP );
1396- if (!dst )
1397- goto exit ;
1398- }
1395+ dst = inet6_csk_route_req (sk , dst , & fl6 , req , IPPROTO_TCP );
1396+ if (!dst )
1397+ goto exit ;
13991398
14001399 newsk = tcp_create_openreq_child (sk , req , skb );
14011400 if (!newsk )
@@ -1411,6 +1410,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
14111410 inet6_sk_rx_dst_set (newsk , skb );
14121411
14131412 newinet = inet_sk (newsk );
1413+ newinet -> cork .fl .u .ip6 = fl6 ;
14141414 newinet -> pinet6 = tcp_inet6_sk (newsk );
14151415 newinet -> ipv6_fl_list = NULL ;
14161416 newinet -> inet_opt = NULL ;
0 commit comments