diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 36 |
1 files changed, 13 insertions, 23 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 794734f1d230..80643e6b346b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -632,10 +632,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
632 | if (final_p) | 632 | if (final_p) |
633 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 633 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
634 | 634 | ||
635 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 635 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
636 | dst_release(dst); | ||
637 | goto failure; | 636 | goto failure; |
638 | } | ||
639 | 637 | ||
640 | if (saddr == NULL) { | 638 | if (saddr == NULL) { |
641 | saddr = &fl.fl6_src; | 639 | saddr = &fl.fl6_src; |
@@ -849,7 +847,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
849 | if (dst == NULL) { | 847 | if (dst == NULL) { |
850 | opt = np->opt; | 848 | opt = np->opt; |
851 | if (opt == NULL && | 849 | if (opt == NULL && |
852 | np->rxopt.bits.srcrt == 2 && | 850 | np->rxopt.bits.osrcrt == 2 && |
853 | treq->pktopts) { | 851 | treq->pktopts) { |
854 | struct sk_buff *pktopts = treq->pktopts; | 852 | struct sk_buff *pktopts = treq->pktopts; |
855 | struct inet6_skb_parm *rxopt = IP6CB(pktopts); | 853 | struct inet6_skb_parm *rxopt = IP6CB(pktopts); |
@@ -888,7 +886,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
888 | } | 886 | } |
889 | 887 | ||
890 | done: | 888 | done: |
891 | dst_release(dst); | ||
892 | if (opt && opt != np->opt) | 889 | if (opt && opt != np->opt) |
893 | sock_kfree_s(sk, opt, opt->tot_len); | 890 | sock_kfree_s(sk, opt, opt->tot_len); |
894 | return err; | 891 | return err; |
@@ -915,11 +912,10 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb) | |||
915 | struct inet6_skb_parm *opt = IP6CB(skb); | 912 | struct inet6_skb_parm *opt = IP6CB(skb); |
916 | 913 | ||
917 | if (np->rxopt.all) { | 914 | if (np->rxopt.all) { |
918 | if ((opt->hop && np->rxopt.bits.hopopts) || | 915 | if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) || |
919 | ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) && | 916 | ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) || |
920 | np->rxopt.bits.rxflow) || | 917 | (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) || |
921 | (opt->srcrt && np->rxopt.bits.srcrt) || | 918 | ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts))) |
922 | ((opt->dst1 || opt->dst0) && np->rxopt.bits.dstopts)) | ||
923 | return 1; | 919 | return 1; |
924 | } | 920 | } |
925 | return 0; | 921 | return 0; |
@@ -1001,10 +997,8 @@ static void tcp_v6_send_reset(struct sk_buff *skb) | |||
1001 | /* sk = NULL, but it is safe for now. RST socket required. */ | 997 | /* sk = NULL, but it is safe for now. RST socket required. */ |
1002 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { | 998 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { |
1003 | 999 | ||
1004 | if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) { | 1000 | if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) |
1005 | dst_release(buff->dst); | ||
1006 | return; | 1001 | return; |
1007 | } | ||
1008 | 1002 | ||
1009 | ip6_xmit(NULL, buff, &fl, NULL, 0); | 1003 | ip6_xmit(NULL, buff, &fl, NULL, 0); |
1010 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); | 1004 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); |
@@ -1068,10 +1062,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1068 | fl.fl_ip_sport = t1->source; | 1062 | fl.fl_ip_sport = t1->source; |
1069 | 1063 | ||
1070 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { | 1064 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { |
1071 | if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) { | 1065 | if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) |
1072 | dst_release(buff->dst); | ||
1073 | return; | 1066 | return; |
1074 | } | ||
1075 | ip6_xmit(NULL, buff, &fl, NULL, 0); | 1067 | ip6_xmit(NULL, buff, &fl, NULL, 0); |
1076 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); | 1068 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); |
1077 | return; | 1069 | return; |
@@ -1190,8 +1182,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1190 | TCP_ECN_create_request(req, skb->h.th); | 1182 | TCP_ECN_create_request(req, skb->h.th); |
1191 | treq->pktopts = NULL; | 1183 | treq->pktopts = NULL; |
1192 | if (ipv6_opt_accepted(sk, skb) || | 1184 | if (ipv6_opt_accepted(sk, skb) || |
1193 | np->rxopt.bits.rxinfo || | 1185 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || |
1194 | np->rxopt.bits.rxhlim) { | 1186 | np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { |
1195 | atomic_inc(&skb->users); | 1187 | atomic_inc(&skb->users); |
1196 | treq->pktopts = skb; | 1188 | treq->pktopts = skb; |
1197 | } | 1189 | } |
@@ -1288,7 +1280,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1288 | if (sk_acceptq_is_full(sk)) | 1280 | if (sk_acceptq_is_full(sk)) |
1289 | goto out_overflow; | 1281 | goto out_overflow; |
1290 | 1282 | ||
1291 | if (np->rxopt.bits.srcrt == 2 && | 1283 | if (np->rxopt.bits.osrcrt == 2 && |
1292 | opt == NULL && treq->pktopts) { | 1284 | opt == NULL && treq->pktopts) { |
1293 | struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts); | 1285 | struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts); |
1294 | if (rxopt->srcrt) | 1286 | if (rxopt->srcrt) |
@@ -1544,9 +1536,9 @@ ipv6_pktoptions: | |||
1544 | tp = tcp_sk(sk); | 1536 | tp = tcp_sk(sk); |
1545 | if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && | 1537 | if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && |
1546 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { | 1538 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { |
1547 | if (np->rxopt.bits.rxinfo) | 1539 | if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo) |
1548 | np->mcast_oif = inet6_iif(opt_skb); | 1540 | np->mcast_oif = inet6_iif(opt_skb); |
1549 | if (np->rxopt.bits.rxhlim) | 1541 | if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) |
1550 | np->mcast_hops = opt_skb->nh.ipv6h->hop_limit; | 1542 | np->mcast_hops = opt_skb->nh.ipv6h->hop_limit; |
1551 | if (ipv6_opt_accepted(sk, opt_skb)) { | 1543 | if (ipv6_opt_accepted(sk, opt_skb)) { |
1552 | skb_set_owner_r(opt_skb, sk); | 1544 | skb_set_owner_r(opt_skb, sk); |
@@ -1734,7 +1726,6 @@ static int tcp_v6_rebuild_header(struct sock *sk) | |||
1734 | 1726 | ||
1735 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 1727 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { |
1736 | sk->sk_err_soft = -err; | 1728 | sk->sk_err_soft = -err; |
1737 | dst_release(dst); | ||
1738 | return err; | 1729 | return err; |
1739 | } | 1730 | } |
1740 | 1731 | ||
@@ -1787,7 +1778,6 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok) | |||
1787 | 1778 | ||
1788 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 1779 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { |
1789 | sk->sk_route_caps = 0; | 1780 | sk->sk_route_caps = 0; |
1790 | dst_release(dst); | ||
1791 | return err; | 1781 | return err; |
1792 | } | 1782 | } |
1793 | 1783 | ||