Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / net / core / sock.c
index 93c8b20..654e38a 100644 (file)
@@ -466,7 +466,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
        skb_dst_force(skb);
 
        spin_lock_irqsave(&list->lock, flags);
-       skb->dropcount = atomic_read(&sk->sk_drops);
+       sock_skb_set_dropcount(sk, skb);
        __skb_queue_tail(list, skb);
        spin_unlock_irqrestore(&list->lock, flags);
 
@@ -653,6 +653,25 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
                sock_reset_flag(sk, bit);
 }
 
+bool sk_mc_loop(struct sock *sk)
+{
+       if (dev_recursion_level())
+               return false;
+       if (!sk)
+               return true;
+       switch (sk->sk_family) {
+       case AF_INET:
+               return inet_sk(sk)->mc_loop;
+#if IS_ENABLED(CONFIG_IPV6)
+       case AF_INET6:
+               return inet6_sk(sk)->mc_loop;
+#endif
+       }
+       WARN_ON(1);
+       return true;
+}
+EXPORT_SYMBOL(sk_mc_loop);
+
 /*
  *     This is meant for all protocols to use and covers goings on
  *     at the socket level. Everything here is generic.
@@ -928,8 +947,6 @@ set_rcvbuf:
                        sk->sk_mark = val;
                break;
 
-               /* We implement the SO_SNDLOWAT etc to
-                  not be settable (1003.1g 5.3) */
        case SO_RXQ_OVFL:
                sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
                break;
@@ -1234,6 +1251,9 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        default:
+               /* We implement the SO_SNDLOWAT etc to not be settable
+                * (1003.1g 7).
+                */
                return -ENOPROTOOPT;
        }
 
@@ -1454,9 +1474,8 @@ void sk_release_kernel(struct sock *sk)
                return;
 
        sock_hold(sk);
-       sock_release(sk->sk_socket);
-       release_net(sock_net(sk));
        sock_net_set(sk, get_net(&init_net));
+       sock_release(sk->sk_socket);
        sock_put(sk);
 }
 EXPORT_SYMBOL(sk_release_kernel);
@@ -1538,6 +1557,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
                newsk->sk_err      = 0;
                newsk->sk_priority = 0;
                newsk->sk_incoming_cpu = raw_smp_processor_id();
+               atomic64_set(&newsk->sk_cookie, 0);
                /*
                 * Before updating sk_refcnt, we must commit prior changes to memory
                 * (Documentation/RCU/rculist_nulls.txt for details)
@@ -1655,25 +1675,16 @@ void sock_rfree(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(sock_rfree);
 
+/*
+ * Buffer destructor for skbs that are not used directly in read or write
+ * path, e.g. for error handler skbs. Automatically called from kfree_skb.
+ */
 void sock_efree(struct sk_buff *skb)
 {
        sock_put(skb->sk);
 }
 EXPORT_SYMBOL(sock_efree);
 
-#ifdef CONFIG_INET
-void sock_edemux(struct sk_buff *skb)
-{
-       struct sock *sk = skb->sk;
-
-       if (sk->sk_state == TCP_TIME_WAIT)
-               inet_twsk_put(inet_twsk(sk));
-       else
-               sock_put(sk);
-}
-EXPORT_SYMBOL(sock_edemux);
-#endif
-
 kuid_t sock_i_uid(struct sock *sk)
 {
        kuid_t uid;
@@ -2163,15 +2174,14 @@ int sock_no_getsockopt(struct socket *sock, int level, int optname,
 }
 EXPORT_SYMBOL(sock_no_getsockopt);
 
-int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
-                   size_t len)
+int sock_no_sendmsg(struct socket *sock, struct msghdr *m, size_t len)
 {
        return -EOPNOTSUPP;
 }
 EXPORT_SYMBOL(sock_no_sendmsg);
 
-int sock_no_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
-                   size_t len, int flags)
+int sock_no_recvmsg(struct socket *sock, struct msghdr *m, size_t len,
+                   int flags)
 {
        return -EOPNOTSUPP;
 }
@@ -2543,14 +2553,14 @@ int compat_sock_common_getsockopt(struct socket *sock, int level, int optname,
 EXPORT_SYMBOL(compat_sock_common_getsockopt);
 #endif
 
-int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
-                       struct msghdr *msg, size_t size, int flags)
+int sock_common_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
+                       int flags)
 {
        struct sock *sk = sock->sk;
        int addr_len = 0;
        int err;
 
-       err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,
+       err = sk->sk_prot->recvmsg(sk, msg, size, flags & MSG_DONTWAIT,
                                   flags & ~MSG_DONTWAIT, &addr_len);
        if (err >= 0)
                msg->msg_namelen = addr_len;
@@ -2727,6 +2737,42 @@ static inline void release_proto_idx(struct proto *prot)
 }
 #endif
 
+static void req_prot_cleanup(struct request_sock_ops *rsk_prot)
+{
+       if (!rsk_prot)
+               return;
+       kfree(rsk_prot->slab_name);
+       rsk_prot->slab_name = NULL;
+       if (rsk_prot->slab) {
+               kmem_cache_destroy(rsk_prot->slab);
+               rsk_prot->slab = NULL;
+       }
+}
+
+static int req_prot_init(const struct proto *prot)
+{
+       struct request_sock_ops *rsk_prot = prot->rsk_prot;
+
+       if (!rsk_prot)
+               return 0;
+
+       rsk_prot->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s",
+                                       prot->name);
+       if (!rsk_prot->slab_name)
+               return -ENOMEM;
+
+       rsk_prot->slab = kmem_cache_create(rsk_prot->slab_name,
+                                          rsk_prot->obj_size, 0,
+                                          0, NULL);
+
+       if (!rsk_prot->slab) {
+               pr_crit("%s: Can't create request sock SLAB cache!\n",
+                       prot->name);
+               return -ENOMEM;
+       }
+       return 0;
+}
+
 int proto_register(struct proto *prot, int alloc_slab)
 {
        if (alloc_slab) {
@@ -2740,21 +2786,8 @@ int proto_register(struct proto *prot, int alloc_slab)
                        goto out;
                }
 
-               if (prot->rsk_prot != NULL) {
-                       prot->rsk_prot->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", prot->name);
-                       if (prot->rsk_prot->slab_name == NULL)
-                               goto out_free_sock_slab;
-
-                       prot->rsk_prot->slab = kmem_cache_create(prot->rsk_prot->slab_name,
-                                                                prot->rsk_prot->obj_size, 0,
-                                                                SLAB_HWCACHE_ALIGN, NULL);
-
-                       if (prot->rsk_prot->slab == NULL) {
-                               pr_crit("%s: Can't create request sock SLAB cache!\n",
-                                       prot->name);
-                               goto out_free_request_sock_slab_name;
-                       }
-               }
+               if (req_prot_init(prot))
+                       goto out_free_request_sock_slab;
 
                if (prot->twsk_prot != NULL) {
                        prot->twsk_prot->twsk_slab_name = kasprintf(GFP_KERNEL, "tw_sock_%s", prot->name);
@@ -2783,14 +2816,8 @@ int proto_register(struct proto *prot, int alloc_slab)
 out_free_timewait_sock_slab_name:
        kfree(prot->twsk_prot->twsk_slab_name);
 out_free_request_sock_slab:
-       if (prot->rsk_prot && prot->rsk_prot->slab) {
-               kmem_cache_destroy(prot->rsk_prot->slab);
-               prot->rsk_prot->slab = NULL;
-       }
-out_free_request_sock_slab_name:
-       if (prot->rsk_prot)
-               kfree(prot->rsk_prot->slab_name);
-out_free_sock_slab:
+       req_prot_cleanup(prot->rsk_prot);
+
        kmem_cache_destroy(prot->slab);
        prot->slab = NULL;
 out:
@@ -2810,11 +2837,7 @@ void proto_unregister(struct proto *prot)
                prot->slab = NULL;
        }
 
-       if (prot->rsk_prot != NULL && prot->rsk_prot->slab != NULL) {
-               kmem_cache_destroy(prot->rsk_prot->slab);
-               kfree(prot->rsk_prot->slab_name);
-               prot->rsk_prot->slab = NULL;
-       }
+       req_prot_cleanup(prot->rsk_prot);
 
        if (prot->twsk_prot != NULL && prot->twsk_prot->twsk_slab != NULL) {
                kmem_cache_destroy(prot->twsk_prot->twsk_slab);