diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 57 |
1 files changed, 21 insertions, 36 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 1d0ab5570904..e59a31c48baf 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -255,18 +255,10 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
255 | 255 | ||
256 | security_sk_classify_flow(sk, &fl); | 256 | security_sk_classify_flow(sk, &fl); |
257 | 257 | ||
258 | err = ip6_dst_lookup(sk, &dst, &fl); | 258 | dst = ip6_dst_lookup_flow(sk, &fl, final_p, true); |
259 | if (err) | 259 | if (IS_ERR(dst)) { |
260 | err = PTR_ERR(dst); | ||
260 | goto failure; | 261 | goto failure; |
261 | if (final_p) | ||
262 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
263 | |||
264 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); | ||
265 | if (err < 0) { | ||
266 | if (err == -EREMOTE) | ||
267 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
268 | if (err < 0) | ||
269 | goto failure; | ||
270 | } | 262 | } |
271 | 263 | ||
272 | if (saddr == NULL) { | 264 | if (saddr == NULL) { |
@@ -385,7 +377,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
385 | np = inet6_sk(sk); | 377 | np = inet6_sk(sk); |
386 | 378 | ||
387 | if (type == ICMPV6_PKT_TOOBIG) { | 379 | if (type == ICMPV6_PKT_TOOBIG) { |
388 | struct dst_entry *dst = NULL; | 380 | struct dst_entry *dst; |
389 | 381 | ||
390 | if (sock_owned_by_user(sk)) | 382 | if (sock_owned_by_user(sk)) |
391 | goto out; | 383 | goto out; |
@@ -413,13 +405,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
413 | fl.fl_ip_sport = inet->inet_sport; | 405 | fl.fl_ip_sport = inet->inet_sport; |
414 | security_skb_classify_flow(skb, &fl); | 406 | security_skb_classify_flow(skb, &fl); |
415 | 407 | ||
416 | if ((err = ip6_dst_lookup(sk, &dst, &fl))) { | 408 | dst = ip6_dst_lookup_flow(sk, &fl, NULL, false); |
417 | sk->sk_err_soft = -err; | 409 | if (IS_ERR(dst)) { |
418 | goto out; | 410 | sk->sk_err_soft = -PTR_ERR(dst); |
419 | } | ||
420 | |||
421 | if ((err = xfrm_lookup(net, &dst, &fl, sk, 0)) < 0) { | ||
422 | sk->sk_err_soft = -err; | ||
423 | goto out; | 411 | goto out; |
424 | } | 412 | } |
425 | 413 | ||
@@ -496,7 +484,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
496 | struct in6_addr * final_p, final; | 484 | struct in6_addr * final_p, final; |
497 | struct flowi fl; | 485 | struct flowi fl; |
498 | struct dst_entry *dst; | 486 | struct dst_entry *dst; |
499 | int err = -1; | 487 | int err; |
500 | 488 | ||
501 | memset(&fl, 0, sizeof(fl)); | 489 | memset(&fl, 0, sizeof(fl)); |
502 | fl.proto = IPPROTO_TCP; | 490 | fl.proto = IPPROTO_TCP; |
@@ -512,15 +500,13 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
512 | opt = np->opt; | 500 | opt = np->opt; |
513 | final_p = fl6_update_dst(&fl, opt, &final); | 501 | final_p = fl6_update_dst(&fl, opt, &final); |
514 | 502 | ||
515 | err = ip6_dst_lookup(sk, &dst, &fl); | 503 | dst = ip6_dst_lookup_flow(sk, &fl, final_p, false); |
516 | if (err) | 504 | if (IS_ERR(dst)) { |
505 | err = PTR_ERR(dst); | ||
517 | goto done; | 506 | goto done; |
518 | if (final_p) | 507 | } |
519 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
520 | if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) | ||
521 | goto done; | ||
522 | |||
523 | skb = tcp_make_synack(sk, dst, req, rvp); | 508 | skb = tcp_make_synack(sk, dst, req, rvp); |
509 | err = -ENOMEM; | ||
524 | if (skb) { | 510 | if (skb) { |
525 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); | 511 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); |
526 | 512 | ||
@@ -1079,15 +1065,14 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1079 | * Underlying function will use this to retrieve the network | 1065 | * Underlying function will use this to retrieve the network |
1080 | * namespace | 1066 | * namespace |
1081 | */ | 1067 | */ |
1082 | if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { | 1068 | dst = ip6_dst_lookup_flow(ctl_sk, &fl, NULL, false); |
1083 | if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { | 1069 | if (!IS_ERR(dst)) { |
1084 | skb_dst_set(buff, dst); | 1070 | skb_dst_set(buff, dst); |
1085 | ip6_xmit(ctl_sk, buff, &fl, NULL); | 1071 | ip6_xmit(ctl_sk, buff, &fl, NULL); |
1086 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); | 1072 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
1087 | if (rst) | 1073 | if (rst) |
1088 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); | 1074 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); |
1089 | return; | 1075 | return; |
1090 | } | ||
1091 | } | 1076 | } |
1092 | 1077 | ||
1093 | kfree_skb(buff); | 1078 | kfree_skb(buff); |