]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/ipv6/tcp_ipv6.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[mirror_ubuntu-artful-kernel.git] / net / ipv6 / tcp_ipv6.c
index bd100b47c7171ce1d85ea5a437c13081a60cd29c..db9f1c318afc3a5157c373f5b5d5fdac09f0049d 100644 (file)
@@ -856,7 +856,9 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
 
 #ifdef CONFIG_TCP_MD5SIG
        hash_location = tcp_parse_md5sig_option(th);
-       if (!sk && hash_location) {
+       if (sk && sk_fullsock(sk)) {
+               key = tcp_v6_md5_do_lookup(sk, &ipv6h->saddr);
+       } else if (hash_location) {
                /*
                 * active side is lost. Try to find listening socket through
                 * source port, and then find md5 key through listening socket.
@@ -879,8 +881,6 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
                genhash = tcp_v6_md5_hash_skb(newhash, key, NULL, skb);
                if (genhash || memcmp(hash_location, newhash, 16) != 0)
                        goto release_sk1;
-       } else {
-               key = sk ? tcp_v6_md5_do_lookup(sk, &ipv6h->saddr) : NULL;
        }
 #endif
 
@@ -1137,7 +1137,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
                 */
                tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newsk->sk_v6_daddr,
                               AF_INET6, key->key, key->keylen,
-                              sk_gfp_atomic(sk, GFP_ATOMIC));
+                              sk_gfp_mask(sk, GFP_ATOMIC));
        }
 #endif
 
@@ -1153,7 +1153,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
                /* Clone pktoptions received with SYN, if we own the req */
                if (ireq->pktopts) {
                        newnp->pktoptions = skb_clone(ireq->pktopts,
-                                                     sk_gfp_atomic(sk, GFP_ATOMIC));
+                                                     sk_gfp_mask(sk, GFP_ATOMIC));
                        consume_skb(ireq->pktopts);
                        ireq->pktopts = NULL;
                        if (newnp->pktoptions)
@@ -1219,7 +1219,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
                                               --ANK (980728)
         */
        if (np->rxopt.all)
-               opt_skb = skb_clone(skb, sk_gfp_atomic(sk, GFP_ATOMIC));
+               opt_skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC));
 
        if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
                struct dst_entry *dst = sk->sk_rx_dst;
@@ -1518,7 +1518,9 @@ do_time_wait:
                break;
        case TCP_TW_RST:
                tcp_v6_restore_cb(skb);
-               goto no_tcp_socket;
+               tcp_v6_send_reset(sk, skb);
+               inet_twsk_deschedule_put(inet_twsk(sk));
+               goto discard_it;
        case TCP_TW_SUCCESS:
                ;
        }
@@ -1891,6 +1893,7 @@ struct proto tcpv6_prot = {
        .proto_cgroup           = tcp_proto_cgroup,
 #endif
        .clear_sk               = tcp_v6_clear_sk,
+       .diag_destroy           = tcp_abort,
 };
 
 static const struct inet6_protocol tcpv6_protocol = {