Merge master.kernel.org:/home/rmk/linux-2.6-mmc
[powerpc.git] / net / ipv6 / tcp_ipv6.c
index 794734f..80643e6 100644 (file)
@@ -632,10 +632,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-               dst_release(dst);
+       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
                goto failure;
-       }
 
        if (saddr == NULL) {
                saddr = &fl.fl6_src;
@@ -849,7 +847,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
        if (dst == NULL) {
                opt = np->opt;
                if (opt == NULL &&
-                   np->rxopt.bits.srcrt == 2 &&
+                   np->rxopt.bits.osrcrt == 2 &&
                    treq->pktopts) {
                        struct sk_buff *pktopts = treq->pktopts;
                        struct inet6_skb_parm *rxopt = IP6CB(pktopts);
@@ -888,7 +886,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
        }
 
 done:
-       dst_release(dst);
         if (opt && opt != np->opt)
                sock_kfree_s(sk, opt, opt->tot_len);
        return err;
@@ -915,11 +912,10 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
        struct inet6_skb_parm *opt = IP6CB(skb);
 
        if (np->rxopt.all) {
-               if ((opt->hop && np->rxopt.bits.hopopts) ||
-                   ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) &&
-                    np->rxopt.bits.rxflow) ||
-                   (opt->srcrt && np->rxopt.bits.srcrt) ||
-                   ((opt->dst1 || opt->dst0) && np->rxopt.bits.dstopts))
+               if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
+                   ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
+                   (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
+                   ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
                        return 1;
        }
        return 0;
@@ -1001,10 +997,8 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
        /* sk = NULL, but it is safe for now. RST socket required. */
        if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
 
-               if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
-                       dst_release(buff->dst);
+               if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
                        return;
-               }
 
                ip6_xmit(NULL, buff, &fl, NULL, 0);
                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
        fl.fl_ip_sport = t1->source;
 
        if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
-               if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
-                       dst_release(buff->dst);
+               if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
                        return;
-               }
                ip6_xmit(NULL, buff, &fl, NULL, 0);
                TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
                return;
@@ -1190,8 +1182,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        TCP_ECN_create_request(req, skb->h.th);
        treq->pktopts = NULL;
        if (ipv6_opt_accepted(sk, skb) ||
-           np->rxopt.bits.rxinfo ||
-           np->rxopt.bits.rxhlim) {
+           np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
+           np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
                atomic_inc(&skb->users);
                treq->pktopts = skb;
        }
@@ -1288,7 +1280,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        if (sk_acceptq_is_full(sk))
                goto out_overflow;
 
-       if (np->rxopt.bits.srcrt == 2 &&
+       if (np->rxopt.bits.osrcrt == 2 &&
            opt == NULL && treq->pktopts) {
                struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
                if (rxopt->srcrt)
@@ -1544,9 +1536,9 @@ ipv6_pktoptions:
        tp = tcp_sk(sk);
        if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
            !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
-               if (np->rxopt.bits.rxinfo)
+               if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
                        np->mcast_oif = inet6_iif(opt_skb);
-               if (np->rxopt.bits.rxhlim)
+               if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
                        np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
                if (ipv6_opt_accepted(sk, opt_skb)) {
                        skb_set_owner_r(opt_skb, sk);
@@ -1734,7 +1726,6 @@ static int tcp_v6_rebuild_header(struct sock *sk)
 
                if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
                        sk->sk_err_soft = -err;
-                       dst_release(dst);
                        return err;
                }
 
@@ -1787,7 +1778,6 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
 
                if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
                        sk->sk_route_caps = 0;
-                       dst_release(dst);
                        return err;
                }