4242 * TCP_ESTABLISHED connected pipe in enabled state
4343 *
4444 * pep_sock locking:
45- * - sk_state, ackq, hlist: sock lock needed
45+ * - sk_state, hlist: sock lock needed
4646 * - listener: read only
4747 * - pipe_handle: read only
4848 */
@@ -202,11 +202,12 @@ static int pep_accept_conn(struct sock *sk, struct sk_buff *skb)
202202 GFP_KERNEL );
203203}
204204
205- static int pep_reject_conn (struct sock * sk , struct sk_buff * skb , u8 code )
205+ static int pep_reject_conn (struct sock * sk , struct sk_buff * skb , u8 code ,
206+ gfp_t priority )
206207{
207208 static const u8 data [4 ] = { PAD , PAD , PAD , 0 /* sub-blocks */ };
208209 WARN_ON (code == PN_PIPE_NO_ERROR );
209- return pep_reply (sk , skb , code , data , sizeof (data ), GFP_ATOMIC );
210+ return pep_reply (sk , skb , code , data , sizeof (data ), priority );
210211}
211212
212213/* Control requests are not sent by the pipe service and have a specific
@@ -365,7 +366,7 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
365366
366367 switch (hdr -> message_id ) {
367368 case PNS_PEP_CONNECT_REQ :
368- pep_reject_conn (sk , skb , PN_PIPE_ERR_PEP_IN_USE );
369+ pep_reject_conn (sk , skb , PN_PIPE_ERR_PEP_IN_USE , GFP_ATOMIC );
369370 break ;
370371
371372 case PNS_PEP_DISCONNECT_REQ :
@@ -574,104 +575,13 @@ static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb)
574575
575576 sk -> sk_state = TCP_SYN_RECV ;
576577 sk -> sk_backlog_rcv = pipe_do_rcv ;
577- sk -> sk_destruct = pipe_destruct ;
578578 pn -> rx_credits = 0 ;
579579 sk -> sk_state_change (sk );
580580
581581 return pipe_handler_send_created_ind (sk );
582582}
583583#endif
584584
585- static int pep_connreq_rcv (struct sock * sk , struct sk_buff * skb )
586- {
587- struct sock * newsk ;
588- struct pep_sock * newpn , * pn = pep_sk (sk );
589- struct pnpipehdr * hdr ;
590- struct sockaddr_pn dst , src ;
591- u16 peer_type ;
592- u8 pipe_handle , enabled , n_sb ;
593- u8 aligned = 0 ;
594-
595- if (!pskb_pull (skb , sizeof (* hdr ) + 4 ))
596- return - EINVAL ;
597-
598- hdr = pnp_hdr (skb );
599- pipe_handle = hdr -> pipe_handle ;
600- switch (hdr -> state_after_connect ) {
601- case PN_PIPE_DISABLE :
602- enabled = 0 ;
603- break ;
604- case PN_PIPE_ENABLE :
605- enabled = 1 ;
606- break ;
607- default :
608- pep_reject_conn (sk , skb , PN_PIPE_ERR_INVALID_PARAM );
609- return - EINVAL ;
610- }
611- peer_type = hdr -> other_pep_type << 8 ;
612-
613- /* Parse sub-blocks (options) */
614- n_sb = hdr -> data [4 ];
615- while (n_sb > 0 ) {
616- u8 type , buf [1 ], len = sizeof (buf );
617- const u8 * data = pep_get_sb (skb , & type , & len , buf );
618-
619- if (data == NULL )
620- return - EINVAL ;
621- switch (type ) {
622- case PN_PIPE_SB_CONNECT_REQ_PEP_SUB_TYPE :
623- if (len < 1 )
624- return - EINVAL ;
625- peer_type = (peer_type & 0xff00 ) | data [0 ];
626- break ;
627- case PN_PIPE_SB_ALIGNED_DATA :
628- aligned = data [0 ] != 0 ;
629- break ;
630- }
631- n_sb -- ;
632- }
633-
634- skb = skb_clone (skb , GFP_ATOMIC );
635- if (!skb )
636- return - ENOMEM ;
637-
638- /* Create a new to-be-accepted sock */
639- newsk = sk_alloc (sock_net (sk ), PF_PHONET , GFP_ATOMIC , sk -> sk_prot );
640- if (!newsk ) {
641- kfree_skb (skb );
642- return - ENOMEM ;
643- }
644- sock_init_data (NULL , newsk );
645- newsk -> sk_state = TCP_SYN_RECV ;
646- newsk -> sk_backlog_rcv = pipe_do_rcv ;
647- newsk -> sk_protocol = sk -> sk_protocol ;
648- newsk -> sk_destruct = pipe_destruct ;
649-
650- newpn = pep_sk (newsk );
651- pn_skb_get_dst_sockaddr (skb , & dst );
652- pn_skb_get_src_sockaddr (skb , & src );
653- newpn -> pn_sk .sobject = pn_sockaddr_get_object (& dst );
654- newpn -> pn_sk .dobject = pn_sockaddr_get_object (& src );
655- newpn -> pn_sk .resource = pn_sockaddr_get_resource (& dst );
656- skb_queue_head_init (& newpn -> ctrlreq_queue );
657- newpn -> pipe_handle = pipe_handle ;
658- atomic_set (& newpn -> tx_credits , 0 );
659- newpn -> peer_type = peer_type ;
660- newpn -> rx_credits = 0 ;
661- newpn -> rx_fc = newpn -> tx_fc = PN_LEGACY_FLOW_CONTROL ;
662- newpn -> init_enable = enabled ;
663- newpn -> aligned = aligned ;
664-
665- BUG_ON (!skb_queue_empty (& newsk -> sk_receive_queue ));
666- skb_queue_head (& newsk -> sk_receive_queue , skb );
667- if (!sock_flag (sk , SOCK_DEAD ))
668- sk -> sk_data_ready (sk , 0 );
669-
670- sk_acceptq_added (sk );
671- sk_add_node (newsk , & pn -> ackq );
672- return 0 ;
673- }
674-
675585/* Listening sock must be locked */
676586static struct sock * pep_find_pipe (const struct hlist_head * hlist ,
677587 const struct sockaddr_pn * dst ,
@@ -726,22 +636,18 @@ static int pep_do_rcv(struct sock *sk, struct sk_buff *skb)
726636 if (sknode )
727637 return sk_receive_skb (sknode , skb , 1 );
728638
729- /* Look for a pipe handle pending accept */
730- sknode = pep_find_pipe (& pn -> ackq , & dst , pipe_handle );
731- if (sknode ) {
732- sock_put (sknode );
733- if (net_ratelimit ())
734- printk (KERN_WARNING "Phonet unconnected PEP ignored" );
735- goto drop ;
736- }
737-
738639 switch (hdr -> message_id ) {
739640 case PNS_PEP_CONNECT_REQ :
740- if (sk -> sk_state == TCP_LISTEN && !sk_acceptq_is_full (sk ))
741- pep_connreq_rcv (sk , skb );
742- else
743- pep_reject_conn (sk , skb , PN_PIPE_ERR_PEP_IN_USE );
744- break ;
641+ if (sk -> sk_state != TCP_LISTEN || sk_acceptq_is_full (sk )) {
642+ pep_reject_conn (sk , skb , PN_PIPE_ERR_PEP_IN_USE ,
643+ GFP_ATOMIC );
644+ break ;
645+ }
646+ skb_queue_head (& sk -> sk_receive_queue , skb );
647+ sk_acceptq_added (sk );
648+ if (!sock_flag (sk , SOCK_DEAD ))
649+ sk -> sk_data_ready (sk , 0 );
650+ return NET_RX_SUCCESS ;
745651
746652#ifdef CONFIG_PHONET_PIPECTRLR
747653 case PNS_PEP_CONNECT_RESP :
@@ -799,24 +705,16 @@ static void pep_sock_close(struct sock *sk, long timeout)
799705 sk_common_release (sk );
800706
801707 lock_sock (sk );
802- if (sk -> sk_state == TCP_LISTEN ) {
803- /* Destroy the listen queue */
804- struct sock * sknode ;
805- struct hlist_node * p , * n ;
806-
807- sk_for_each_safe (sknode , p , n , & pn -> ackq )
808- sk_del_node_init (sknode );
809- sk -> sk_state = TCP_CLOSE ;
810- } else if ((1 << sk -> sk_state ) & (TCPF_SYN_RECV |TCPF_ESTABLISHED )) {
708+ if ((1 << sk -> sk_state ) & (TCPF_SYN_RECV |TCPF_ESTABLISHED )) {
811709#ifndef CONFIG_PHONET_PIPECTRLR
812710 /* Forcefully remove dangling Phonet pipe */
813711 pipe_do_remove (sk );
814712#else
815713 /* send pep disconnect request */
816714 pipe_handler_request (sk , PNS_PEP_DISCONNECT_REQ , PAD , NULL , 0 );
817- sk -> sk_state = TCP_CLOSE ;
818715#endif
819716 }
717+ sk -> sk_state = TCP_CLOSE ;
820718
821719 ifindex = pn -> ifindex ;
822720 pn -> ifindex = 0 ;
@@ -827,69 +725,121 @@ static void pep_sock_close(struct sock *sk, long timeout)
827725 sock_put (sk );
828726}
829727
830- static int pep_wait_connreq (struct sock * sk , int noblock )
728+ static struct sock * pep_sock_accept (struct sock * sk , int flags , int * errp )
831729{
832- struct task_struct * tsk = current ;
833- struct pep_sock * pn = pep_sk (sk );
834- long timeo = sock_rcvtimeo (sk , noblock );
835-
836- for (;;) {
837- DEFINE_WAIT (wait );
730+ struct pep_sock * pn = pep_sk (sk ), * newpn ;
731+ struct sock * newsk = NULL ;
732+ struct sk_buff * skb ;
733+ struct pnpipehdr * hdr ;
734+ struct sockaddr_pn dst , src ;
735+ int err ;
736+ u16 peer_type ;
737+ u8 pipe_handle , enabled , n_sb ;
738+ u8 aligned = 0 ;
838739
839- if (sk -> sk_state != TCP_LISTEN )
840- return - EINVAL ;
841- if (!hlist_empty (& pn -> ackq ))
842- break ;
843- if (!timeo )
844- return - EWOULDBLOCK ;
845- if (signal_pending (tsk ))
846- return sock_intr_errno (timeo );
740+ skb = skb_recv_datagram (sk , 0 , flags & O_NONBLOCK , errp );
741+ if (!skb )
742+ return NULL ;
847743
848- prepare_to_wait_exclusive (sk_sleep (sk ), & wait ,
849- TASK_INTERRUPTIBLE );
850- release_sock (sk );
851- timeo = schedule_timeout (timeo );
852- lock_sock (sk );
853- finish_wait (sk_sleep (sk ), & wait );
744+ lock_sock (sk );
745+ if (sk -> sk_state != TCP_LISTEN ) {
746+ err = - EINVAL ;
747+ goto drop ;
854748 }
749+ sk_acceptq_removed (sk );
855750
856- return 0 ;
857- }
751+ err = - EPROTO ;
752+ if (!pskb_may_pull (skb , sizeof (* hdr ) + 4 ))
753+ goto drop ;
858754
859- static struct sock * pep_sock_accept (struct sock * sk , int flags , int * errp )
860- {
861- struct pep_sock * pn = pep_sk (sk );
862- struct sock * newsk = NULL ;
863- struct sk_buff * oskb ;
864- int err ;
755+ hdr = pnp_hdr (skb );
756+ pipe_handle = hdr -> pipe_handle ;
757+ switch (hdr -> state_after_connect ) {
758+ case PN_PIPE_DISABLE :
759+ enabled = 0 ;
760+ break ;
761+ case PN_PIPE_ENABLE :
762+ enabled = 1 ;
763+ break ;
764+ default :
765+ pep_reject_conn (sk , skb , PN_PIPE_ERR_INVALID_PARAM ,
766+ GFP_KERNEL );
767+ goto drop ;
768+ }
769+ peer_type = hdr -> other_pep_type << 8 ;
865770
866- lock_sock (sk );
867- err = pep_wait_connreq (sk , flags & O_NONBLOCK );
868- if (err )
869- goto out ;
771+ /* Parse sub-blocks (options) */
772+ n_sb = hdr -> data [4 ];
773+ while (n_sb > 0 ) {
774+ u8 type , buf [1 ], len = sizeof (buf );
775+ const u8 * data = pep_get_sb (skb , & type , & len , buf );
870776
871- newsk = __sk_head (& pn -> ackq );
777+ if (data == NULL )
778+ goto drop ;
779+ switch (type ) {
780+ case PN_PIPE_SB_CONNECT_REQ_PEP_SUB_TYPE :
781+ if (len < 1 )
782+ goto drop ;
783+ peer_type = (peer_type & 0xff00 ) | data [0 ];
784+ break ;
785+ case PN_PIPE_SB_ALIGNED_DATA :
786+ aligned = data [0 ] != 0 ;
787+ break ;
788+ }
789+ n_sb -- ;
790+ }
872791
873- oskb = skb_dequeue ( & newsk -> sk_receive_queue );
874- err = pep_accept_conn ( newsk , oskb );
875- if (err ) {
876- skb_queue_head ( & newsk -> sk_receive_queue , oskb );
792+ /* Check for duplicate pipe handle */
793+ newsk = pep_find_pipe ( & pn -> hlist , & dst , pipe_handle );
794+ if (unlikely ( newsk ) ) {
795+ __sock_put ( newsk );
877796 newsk = NULL ;
878- goto out ;
797+ pep_reject_conn (sk , skb , PN_PIPE_ERR_PEP_IN_USE , GFP_KERNEL );
798+ goto drop ;
799+ }
800+
801+ /* Create a new to-be-accepted sock */
802+ newsk = sk_alloc (sock_net (sk ), PF_PHONET , GFP_KERNEL , sk -> sk_prot );
803+ if (!newsk ) {
804+ pep_reject_conn (sk , skb , PN_PIPE_ERR_OVERLOAD , GFP_KERNEL );
805+ err = - ENOBUFS ;
806+ goto drop ;
879807 }
880- kfree_skb (oskb );
881808
809+ sock_init_data (NULL , newsk );
810+ newsk -> sk_state = TCP_SYN_RECV ;
811+ newsk -> sk_backlog_rcv = pipe_do_rcv ;
812+ newsk -> sk_protocol = sk -> sk_protocol ;
813+ newsk -> sk_destruct = pipe_destruct ;
814+
815+ newpn = pep_sk (newsk );
816+ pn_skb_get_dst_sockaddr (skb , & dst );
817+ pn_skb_get_src_sockaddr (skb , & src );
818+ newpn -> pn_sk .sobject = pn_sockaddr_get_object (& dst );
819+ newpn -> pn_sk .dobject = pn_sockaddr_get_object (& src );
820+ newpn -> pn_sk .resource = pn_sockaddr_get_resource (& dst );
882821 sock_hold (sk );
883- pep_sk (newsk )-> listener = sk ;
822+ newpn -> listener = sk ;
823+ skb_queue_head_init (& newpn -> ctrlreq_queue );
824+ newpn -> pipe_handle = pipe_handle ;
825+ atomic_set (& newpn -> tx_credits , 0 );
826+ newpn -> ifindex = 0 ;
827+ newpn -> peer_type = peer_type ;
828+ newpn -> rx_credits = 0 ;
829+ newpn -> rx_fc = newpn -> tx_fc = PN_LEGACY_FLOW_CONTROL ;
830+ newpn -> init_enable = enabled ;
831+ newpn -> aligned = aligned ;
884832
885- sock_hold (newsk );
886- sk_del_node_init (newsk );
887- sk_acceptq_removed (sk );
833+ err = pep_accept_conn (newsk , skb );
834+ if (err ) {
835+ sock_put (newsk );
836+ newsk = NULL ;
837+ goto drop ;
838+ }
888839 sk_add_node (newsk , & pn -> hlist );
889- __sock_put (newsk );
890-
891- out :
840+ drop :
892841 release_sock (sk );
842+ kfree_skb (skb );
893843 * errp = err ;
894844 return newsk ;
895845}
@@ -937,7 +887,7 @@ static int pep_init(struct sock *sk)
937887{
938888 struct pep_sock * pn = pep_sk (sk );
939889
940- INIT_HLIST_HEAD ( & pn -> ackq ) ;
890+ sk -> sk_destruct = pipe_destruct ;
941891 INIT_HLIST_HEAD (& pn -> hlist );
942892 skb_queue_head_init (& pn -> ctrlreq_queue );
943893 pn -> pipe_handle = PN_PIPE_INVALID_HANDLE ;
0 commit comments