@@ -798,17 +798,35 @@ static void unix_close(struct sock *sk, long timeout)
798798 */
799799}
800800
801- struct proto unix_proto = {
802- .name = "UNIX" ,
801+ static void unix_unhash (struct sock * sk )
802+ {
803+ /* Nothing to do here, unix socket does not need a ->unhash().
804+ * This is merely for sockmap.
805+ */
806+ }
807+
808+ struct proto unix_dgram_proto = {
809+ .name = "UNIX-DGRAM" ,
810+ .owner = THIS_MODULE ,
811+ .obj_size = sizeof (struct unix_sock ),
812+ .close = unix_close ,
813+ #ifdef CONFIG_BPF_SYSCALL
814+ .psock_update_sk_prot = unix_dgram_bpf_update_proto ,
815+ #endif
816+ };
817+
818+ struct proto unix_stream_proto = {
819+ .name = "UNIX-STREAM" ,
803820 .owner = THIS_MODULE ,
804821 .obj_size = sizeof (struct unix_sock ),
805822 .close = unix_close ,
823+ .unhash = unix_unhash ,
806824#ifdef CONFIG_BPF_SYSCALL
807- .psock_update_sk_prot = unix_bpf_update_proto ,
825+ .psock_update_sk_prot = unix_stream_bpf_update_proto ,
808826#endif
809827};
810828
811- static struct sock * unix_create1 (struct net * net , struct socket * sock , int kern )
829+ static struct sock * unix_create1 (struct net * net , struct socket * sock , int kern , int type )
812830{
813831 struct sock * sk = NULL ;
814832 struct unix_sock * u ;
@@ -817,7 +835,11 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
817835 if (atomic_long_read (& unix_nr_socks ) > 2 * get_max_files ())
818836 goto out ;
819837
820- sk = sk_alloc (net , PF_UNIX , GFP_KERNEL , & unix_proto , kern );
838+ if (type == SOCK_STREAM )
839+ sk = sk_alloc (net , PF_UNIX , GFP_KERNEL , & unix_stream_proto , kern );
840+ else /*dgram and seqpacket */
841+ sk = sk_alloc (net , PF_UNIX , GFP_KERNEL , & unix_dgram_proto , kern );
842+
821843 if (!sk )
822844 goto out ;
823845
@@ -879,7 +901,7 @@ static int unix_create(struct net *net, struct socket *sock, int protocol,
879901 return - ESOCKTNOSUPPORT ;
880902 }
881903
882- return unix_create1 (net , sock , kern ) ? 0 : - ENOMEM ;
904+ return unix_create1 (net , sock , kern , sock -> type ) ? 0 : - ENOMEM ;
883905}
884906
885907static int unix_release (struct socket * sock )
@@ -1293,7 +1315,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
12931315 err = - ENOMEM ;
12941316
12951317 /* create new sock for complete connection */
1296- newsk = unix_create1 (sock_net (sk ), NULL , 0 );
1318+ newsk = unix_create1 (sock_net (sk ), NULL , 0 , sock -> type );
12971319 if (newsk == NULL )
12981320 goto out ;
12991321
@@ -2323,8 +2345,10 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, size_t si
23232345 struct sock * sk = sock -> sk ;
23242346
23252347#ifdef CONFIG_BPF_SYSCALL
2326- if (sk -> sk_prot != & unix_proto )
2327- return sk -> sk_prot -> recvmsg (sk , msg , size , flags & MSG_DONTWAIT ,
2348+ const struct proto * prot = READ_ONCE (sk -> sk_prot );
2349+
2350+ if (prot != & unix_dgram_proto )
2351+ return prot -> recvmsg (sk , msg , size , flags & MSG_DONTWAIT ,
23282352 flags & ~MSG_DONTWAIT , NULL );
23292353#endif
23302354 return __unix_dgram_recvmsg (sk , msg , size , flags );
@@ -2728,6 +2752,20 @@ static int unix_stream_read_actor(struct sk_buff *skb,
27282752 return ret ?: chunk ;
27292753}
27302754
2755+ int __unix_stream_recvmsg (struct sock * sk , struct msghdr * msg ,
2756+ size_t size , int flags )
2757+ {
2758+ struct unix_stream_read_state state = {
2759+ .recv_actor = unix_stream_read_actor ,
2760+ .socket = sk -> sk_socket ,
2761+ .msg = msg ,
2762+ .size = size ,
2763+ .flags = flags
2764+ };
2765+
2766+ return unix_stream_read_generic (& state , true);
2767+ }
2768+
27312769static int unix_stream_recvmsg (struct socket * sock , struct msghdr * msg ,
27322770 size_t size , int flags )
27332771{
@@ -2739,6 +2777,14 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
27392777 .flags = flags
27402778 };
27412779
2780+ #ifdef CONFIG_BPF_SYSCALL
2781+ struct sock * sk = sock -> sk ;
2782+ const struct proto * prot = READ_ONCE (sk -> sk_prot );
2783+
2784+ if (prot != & unix_stream_proto )
2785+ return prot -> recvmsg (sk , msg , size , flags & MSG_DONTWAIT ,
2786+ flags & ~MSG_DONTWAIT , NULL );
2787+ #endif
27422788 return unix_stream_read_generic (& state , true);
27432789}
27442790
@@ -2799,7 +2845,9 @@ static int unix_shutdown(struct socket *sock, int mode)
27992845 (sk -> sk_type == SOCK_STREAM || sk -> sk_type == SOCK_SEQPACKET )) {
28002846
28012847 int peer_mode = 0 ;
2848+ const struct proto * prot = READ_ONCE (other -> sk_prot );
28022849
2850+ prot -> unhash (other );
28032851 if (mode & RCV_SHUTDOWN )
28042852 peer_mode |= SEND_SHUTDOWN ;
28052853 if (mode & SEND_SHUTDOWN )
@@ -2808,10 +2856,12 @@ static int unix_shutdown(struct socket *sock, int mode)
28082856 other -> sk_shutdown |= peer_mode ;
28092857 unix_state_unlock (other );
28102858 other -> sk_state_change (other );
2811- if (peer_mode == SHUTDOWN_MASK )
2859+ if (peer_mode == SHUTDOWN_MASK ) {
28122860 sk_wake_async (other , SOCK_WAKE_WAITD , POLL_HUP );
2813- else if (peer_mode & RCV_SHUTDOWN )
2861+ other -> sk_state = TCP_CLOSE ;
2862+ } else if (peer_mode & RCV_SHUTDOWN ) {
28142863 sk_wake_async (other , SOCK_WAKE_WAITD , POLL_IN );
2864+ }
28152865 }
28162866 if (other )
28172867 sock_put (other );
@@ -3289,7 +3339,13 @@ static int __init af_unix_init(void)
32893339
32903340 BUILD_BUG_ON (sizeof (struct unix_skb_parms ) > sizeof_field (struct sk_buff , cb ));
32913341
3292- rc = proto_register (& unix_proto , 1 );
3342+ rc = proto_register (& unix_dgram_proto , 1 );
3343+ if (rc != 0 ) {
3344+ pr_crit ("%s: Cannot create unix_sock SLAB cache!\n" , __func__ );
3345+ goto out ;
3346+ }
3347+
3348+ rc = proto_register (& unix_stream_proto , 1 );
32933349 if (rc != 0 ) {
32943350 pr_crit ("%s: Cannot create unix_sock SLAB cache!\n" , __func__ );
32953351 goto out ;
@@ -3310,7 +3366,8 @@ static int __init af_unix_init(void)
33103366static void __exit af_unix_exit (void )
33113367{
33123368 sock_unregister (PF_UNIX );
3313- proto_unregister (& unix_proto );
3369+ proto_unregister (& unix_dgram_proto );
3370+ proto_unregister (& unix_stream_proto );
33143371 unregister_pernet_subsys (& unix_net_ops );
33153372}
33163373
0 commit comments