]> err.no Git - linux-2.6/blobdiff - net/ipv6/tcp_ipv6.c
nfsd: move cache proc (un)registration to separate function
[linux-2.6] / net / ipv6 / tcp_ipv6.c
index 4b9032880959421be4d8e08780f58efd38cdb726..59d0029e93a7b3f6123a0a7353eee918e1bd425b 100644 (file)
@@ -265,7 +265,7 @@ 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, 1)) < 0) {
+       if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
                if (err == -EREMOTE)
                        err = ip6_dst_blackhole(sk, &dst, &fl);
                if (err < 0)
@@ -330,8 +330,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        struct tcp_sock *tp;
        __u32 seq;
 
-       sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr,
-                         th->source, skb->dev->ifindex);
+       sk = inet6_lookup(skb->dev->nd_net, &tcp_hashinfo, &hdr->daddr,
+                       th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
 
        if (sk == NULL) {
                ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -581,7 +581,10 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
                        }
                        sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
                }
-               tcp_alloc_md5sig_pool();
+               if (tcp_alloc_md5sig_pool() == NULL) {
+                       kfree(newkey);
+                       return -ENOMEM;
+               }
                if (tp->md5sig_info->alloced6 == tp->md5sig_info->entries6) {
                        keys = kmalloc((sizeof (tp->md5sig_info->keys6[0]) *
                                       (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC);
@@ -634,10 +637,6 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
                                kfree(tp->md5sig_info->keys6);
                                tp->md5sig_info->keys6 = NULL;
                                tp->md5sig_info->alloced6 = 0;
-
-                               tcp_free_md5sig_pool();
-
-                               return 0;
                        } else {
                                /* shrink the database */
                                if (tp->md5sig_info->entries6 != i)
@@ -646,6 +645,8 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
                                                (tp->md5sig_info->entries6 - i)
                                                * sizeof (tp->md5sig_info->keys6[0]));
                        }
+                       tcp_free_md5sig_pool();
+                       return 0;
                }
        }
        return -ENOENT;
@@ -732,7 +733,7 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
                                   struct in6_addr *saddr,
                                   struct in6_addr *daddr,
                                   struct tcphdr *th, int protocol,
-                                  int tcplen)
+                                  unsigned int tcplen)
 {
        struct scatterlist sg[4];
        __u16 data_len;
@@ -781,7 +782,7 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
        sg_set_buf(&sg[block++], key->key, key->keylen);
        nbytes += key->keylen;
 
-       __sg_mark_end(&sg[block - 1]);
+       sg_mark_end(&sg[block - 1]);
 
        /* Now store the hash into the packet */
        err = crypto_hash_init(desc);
@@ -817,7 +818,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
                                struct dst_entry *dst,
                                struct request_sock *req,
                                struct tcphdr *th, int protocol,
-                               int tcplen)
+                               unsigned int tcplen)
 {
        struct in6_addr *saddr, *daddr;
 
@@ -984,7 +985,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
        struct tcphdr *th = tcp_hdr(skb), *t1;
        struct sk_buff *buff;
        struct flowi fl;
-       int tot_len = sizeof(*th);
+       unsigned int tot_len = sizeof(*th);
 #ifdef CONFIG_TCP_MD5SIG
        struct tcp_md5sig_key *key;
 #endif
@@ -1084,7 +1085,7 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
        struct tcphdr *th = tcp_hdr(skb), *t1;
        struct sk_buff *buff;
        struct flowi fl;
-       int tot_len = sizeof(struct tcphdr);
+       unsigned int tot_len = sizeof(struct tcphdr);
        __be32 *topt;
 #ifdef CONFIG_TCP_MD5SIG
        struct tcp_md5sig_key *key;
@@ -1207,9 +1208,9 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
        if (req)
                return tcp_check_req(sk, skb, req, prev);
 
-       nsk = __inet6_lookup_established(&tcp_hashinfo, &ipv6_hdr(skb)->saddr,
-                                        th->source, &ipv6_hdr(skb)->daddr,
-                                        ntohs(th->dest), inet6_iif(skb));
+       nsk = __inet6_lookup_established(sk->sk_net, &tcp_hashinfo,
+                       &ipv6_hdr(skb)->saddr, th->source,
+                       &ipv6_hdr(skb)->daddr, ntohs(th->dest), inet6_iif(skb));
 
        if (nsk) {
                if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1709,9 +1710,10 @@ static int tcp_v6_rcv(struct sk_buff *skb)
        TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
        TCP_SKB_CB(skb)->sacked = 0;
 
-       sk = __inet6_lookup(&tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source,
-                           &ipv6_hdr(skb)->daddr, ntohs(th->dest),
-                           inet6_iif(skb));
+       sk = __inet6_lookup(skb->dev->nd_net, &tcp_hashinfo,
+                       &ipv6_hdr(skb)->saddr, th->source,
+                       &ipv6_hdr(skb)->daddr, ntohs(th->dest),
+                       inet6_iif(skb));
 
        if (!sk)
                goto no_tcp_socket;
@@ -1791,7 +1793,7 @@ do_time_wait:
        {
                struct sock *sk2;
 
-               sk2 = inet6_lookup_listener(&tcp_hashinfo,
+               sk2 = inet6_lookup_listener(skb->dev->nd_net, &tcp_hashinfo,
                                            &ipv6_hdr(skb)->daddr,
                                            ntohs(th->dest), inet6_iif(skb));
                if (sk2 != NULL) {
@@ -2107,6 +2109,8 @@ void tcp6_proc_exit(void)
 }
 #endif
 
+DEFINE_PROTO_INUSE(tcpv6)
+
 struct proto tcpv6_prot = {
        .name                   = "TCPv6",
        .owner                  = THIS_MODULE,
@@ -2141,6 +2145,7 @@ struct proto tcpv6_prot = {
        .compat_setsockopt      = compat_tcp_setsockopt,
        .compat_getsockopt      = compat_tcp_getsockopt,
 #endif
+       REF_PROTO_INUSE(tcpv6)
 };
 
 static struct inet6_protocol tcpv6_protocol = {
@@ -2162,14 +2167,36 @@ static struct inet_protosw tcpv6_protosw = {
                                INET_PROTOSW_ICSK,
 };
 
-void __init tcpv6_init(void)
+int __init tcpv6_init(void)
 {
+       int ret;
+
+       ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP);
+       if (ret)
+               goto out;
+
        /* register inet6 protocol */
-       if (inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP) < 0)
-               printk(KERN_ERR "tcpv6_init: Could not register protocol\n");
-       inet6_register_protosw(&tcpv6_protosw);
+       ret = inet6_register_protosw(&tcpv6_protosw);
+       if (ret)
+               goto out_tcpv6_protocol;
+
+       ret = inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6,
+                                      SOCK_RAW, IPPROTO_TCP);
+       if (ret)
+               goto out_tcpv6_protosw;
+out:
+       return ret;
 
-       if (inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6, SOCK_RAW,
-                                    IPPROTO_TCP) < 0)
-               panic("Failed to create the TCPv6 control socket.\n");
+out_tcpv6_protocol:
+       inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
+out_tcpv6_protosw:
+       inet6_unregister_protosw(&tcpv6_protosw);
+       goto out;
+}
+
+void tcpv6_exit(void)
+{
+       sock_release(tcp6_socket);
+       inet6_unregister_protosw(&tcpv6_protosw);
+       inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
 }