diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 12750f2b05ab..1cbbb87dbad2 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -455,8 +455,7 @@ out: | |||
455 | } | 455 | } |
456 | 456 | ||
457 | 457 | ||
458 | static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | 458 | static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req) |
459 | struct dst_entry *dst) | ||
460 | { | 459 | { |
461 | struct inet6_request_sock *treq = inet6_rsk(req); | 460 | struct inet6_request_sock *treq = inet6_rsk(req); |
462 | struct ipv6_pinfo *np = inet6_sk(sk); | 461 | struct ipv6_pinfo *np = inet6_sk(sk); |
@@ -464,6 +463,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
464 | struct ipv6_txoptions *opt = NULL; | 463 | struct ipv6_txoptions *opt = NULL; |
465 | struct in6_addr * final_p = NULL, final; | 464 | struct in6_addr * final_p = NULL, final; |
466 | struct flowi fl; | 465 | struct flowi fl; |
466 | struct dst_entry *dst; | ||
467 | int err = -1; | 467 | int err = -1; |
468 | 468 | ||
469 | memset(&fl, 0, sizeof(fl)); | 469 | memset(&fl, 0, sizeof(fl)); |
@@ -476,24 +476,22 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
476 | fl.fl_ip_sport = inet_sk(sk)->sport; | 476 | fl.fl_ip_sport = inet_sk(sk)->sport; |
477 | security_req_classify_flow(req, &fl); | 477 | security_req_classify_flow(req, &fl); |
478 | 478 | ||
479 | if (dst == NULL) { | 479 | opt = np->opt; |
480 | opt = np->opt; | 480 | if (opt && opt->srcrt) { |
481 | if (opt && opt->srcrt) { | 481 | struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; |
482 | struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; | 482 | ipv6_addr_copy(&final, &fl.fl6_dst); |
483 | ipv6_addr_copy(&final, &fl.fl6_dst); | 483 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); |
484 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | 484 | final_p = &final; |
485 | final_p = &final; | ||
486 | } | ||
487 | |||
488 | err = ip6_dst_lookup(sk, &dst, &fl); | ||
489 | if (err) | ||
490 | goto done; | ||
491 | if (final_p) | ||
492 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
493 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | ||
494 | goto done; | ||
495 | } | 485 | } |
496 | 486 | ||
487 | err = ip6_dst_lookup(sk, &dst, &fl); | ||
488 | if (err) | ||
489 | goto done; | ||
490 | if (final_p) | ||
491 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
492 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | ||
493 | goto done; | ||
494 | |||
497 | skb = tcp_make_synack(sk, dst, req); | 495 | skb = tcp_make_synack(sk, dst, req); |
498 | if (skb) { | 496 | if (skb) { |
499 | struct tcphdr *th = tcp_hdr(skb); | 497 | struct tcphdr *th = tcp_hdr(skb); |
@@ -1294,7 +1292,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1294 | 1292 | ||
1295 | security_inet_conn_request(sk, skb, req); | 1293 | security_inet_conn_request(sk, skb, req); |
1296 | 1294 | ||
1297 | if (tcp_v6_send_synack(sk, req, NULL)) | 1295 | if (tcp_v6_send_synack(sk, req)) |
1298 | goto drop; | 1296 | goto drop; |
1299 | 1297 | ||
1300 | inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); | 1298 | inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); |