aboutsummaryrefslogtreecommitdiffstats
path: root/net/phonet/pep.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/phonet/pep.c')
-rw-r--r--net/phonet/pep.c65
1 files changed, 41 insertions, 24 deletions
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 5f32d217535b..e2a95762abd3 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/slab.h>
26#include <linux/socket.h> 27#include <linux/socket.h>
27#include <net/sock.h> 28#include <net/sock.h>
28#include <net/tcp_states.h> 29#include <net/tcp_states.h>
@@ -354,14 +355,15 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
354 queue = &pn->ctrlreq_queue; 355 queue = &pn->ctrlreq_queue;
355 goto queue; 356 goto queue;
356 357
358 case PNS_PIPE_ALIGNED_DATA:
359 __skb_pull(skb, 1);
360 /* fall through */
357 case PNS_PIPE_DATA: 361 case PNS_PIPE_DATA:
358 __skb_pull(skb, 3); /* Pipe data header */ 362 __skb_pull(skb, 3); /* Pipe data header */
359 if (!pn_flow_safe(pn->rx_fc)) { 363 if (!pn_flow_safe(pn->rx_fc)) {
360 err = sock_queue_rcv_skb(sk, skb); 364 err = sock_queue_rcv_skb(sk, skb);
361 if (!err) 365 if (!err)
362 return 0; 366 return 0;
363 if (err == -ENOMEM)
364 atomic_inc(&sk->sk_drops);
365 break; 367 break;
366 } 368 }
367 369
@@ -443,6 +445,7 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
443 struct sockaddr_pn dst; 445 struct sockaddr_pn dst;
444 u16 peer_type; 446 u16 peer_type;
445 u8 pipe_handle, enabled, n_sb; 447 u8 pipe_handle, enabled, n_sb;
448 u8 aligned = 0;
446 449
447 if (!pskb_pull(skb, sizeof(*hdr) + 4)) 450 if (!pskb_pull(skb, sizeof(*hdr) + 4))
448 return -EINVAL; 451 return -EINVAL;
@@ -481,6 +484,9 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
481 return -EINVAL; 484 return -EINVAL;
482 peer_type = (peer_type & 0xff00) | data[0]; 485 peer_type = (peer_type & 0xff00) | data[0];
483 break; 486 break;
487 case PN_PIPE_SB_ALIGNED_DATA:
488 aligned = data[0] != 0;
489 break;
484 } 490 }
485 n_sb--; 491 n_sb--;
486 } 492 }
@@ -512,6 +518,7 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
512 newpn->rx_credits = 0; 518 newpn->rx_credits = 0;
513 newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL; 519 newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL;
514 newpn->init_enable = enabled; 520 newpn->init_enable = enabled;
521 newpn->aligned = aligned;
515 522
516 BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue)); 523 BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue));
517 skb_queue_head(&newsk->sk_receive_queue, skb); 524 skb_queue_head(&newsk->sk_receive_queue, skb);
@@ -716,8 +723,8 @@ static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
716 return -EINVAL; 723 return -EINVAL;
717 724
718 lock_sock(sk); 725 lock_sock(sk);
719 if (sock_flag(sk, SOCK_URGINLINE) 726 if (sock_flag(sk, SOCK_URGINLINE) &&
720 && !skb_queue_empty(&pn->ctrlreq_queue)) 727 !skb_queue_empty(&pn->ctrlreq_queue))
721 answ = skb_peek(&pn->ctrlreq_queue)->len; 728 answ = skb_peek(&pn->ctrlreq_queue)->len;
722 else if (!skb_queue_empty(&sk->sk_receive_queue)) 729 else if (!skb_queue_empty(&sk->sk_receive_queue))
723 answ = skb_peek(&sk->sk_receive_queue)->len; 730 answ = skb_peek(&sk->sk_receive_queue)->len;
@@ -831,11 +838,15 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb)
831 return -ENOBUFS; 838 return -ENOBUFS;
832 } 839 }
833 840
834 skb_push(skb, 3); 841 skb_push(skb, 3 + pn->aligned);
835 skb_reset_transport_header(skb); 842 skb_reset_transport_header(skb);
836 ph = pnp_hdr(skb); 843 ph = pnp_hdr(skb);
837 ph->utid = 0; 844 ph->utid = 0;
838 ph->message_id = PNS_PIPE_DATA; 845 if (pn->aligned) {
846 ph->message_id = PNS_PIPE_ALIGNED_DATA;
847 ph->data[0] = 0; /* padding */
848 } else
849 ph->message_id = PNS_PIPE_DATA;
839 ph->pipe_handle = pn->pipe_handle; 850 ph->pipe_handle = pn->pipe_handle;
840 851
841 return pn_skb_send(sk, skb, &pipe_srv); 852 return pn_skb_send(sk, skb, &pipe_srv);
@@ -845,14 +856,26 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
845 struct msghdr *msg, size_t len) 856 struct msghdr *msg, size_t len)
846{ 857{
847 struct pep_sock *pn = pep_sk(sk); 858 struct pep_sock *pn = pep_sk(sk);
848 struct sk_buff *skb = NULL; 859 struct sk_buff *skb;
849 long timeo; 860 long timeo;
850 int flags = msg->msg_flags; 861 int flags = msg->msg_flags;
851 int err, done; 862 int err, done;
852 863
853 if (msg->msg_flags & MSG_OOB || !(msg->msg_flags & MSG_EOR)) 864 if ((msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|
865 MSG_CMSG_COMPAT)) ||
866 !(msg->msg_flags & MSG_EOR))
854 return -EOPNOTSUPP; 867 return -EOPNOTSUPP;
855 868
869 skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len,
870 flags & MSG_DONTWAIT, &err);
871 if (!skb)
872 return -ENOBUFS;
873
874 skb_reserve(skb, MAX_PHONET_HEADER + 3);
875 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
876 if (err < 0)
877 goto outfree;
878
856 lock_sock(sk); 879 lock_sock(sk);
857 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); 880 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
858 if ((1 << sk->sk_state) & (TCPF_LISTEN|TCPF_CLOSE)) { 881 if ((1 << sk->sk_state) & (TCPF_LISTEN|TCPF_CLOSE)) {
@@ -896,28 +919,13 @@ disabled:
896 goto disabled; 919 goto disabled;
897 } 920 }
898 921
899 if (!skb) {
900 skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len,
901 flags & MSG_DONTWAIT, &err);
902 if (skb == NULL)
903 goto out;
904 skb_reserve(skb, MAX_PHONET_HEADER + 3);
905
906 if (sk->sk_state != TCP_ESTABLISHED ||
907 !atomic_read(&pn->tx_credits))
908 goto disabled; /* sock_alloc_send_skb might sleep */
909 }
910
911 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
912 if (err < 0)
913 goto out;
914
915 err = pipe_skb_send(sk, skb); 922 err = pipe_skb_send(sk, skb);
916 if (err >= 0) 923 if (err >= 0)
917 err = len; /* success! */ 924 err = len; /* success! */
918 skb = NULL; 925 skb = NULL;
919out: 926out:
920 release_sock(sk); 927 release_sock(sk);
928outfree:
921 kfree_skb(skb); 929 kfree_skb(skb);
922 return err; 930 return err;
923} 931}
@@ -934,6 +942,9 @@ int pep_write(struct sock *sk, struct sk_buff *skb)
934 struct sk_buff *rskb, *fs; 942 struct sk_buff *rskb, *fs;
935 int flen = 0; 943 int flen = 0;
936 944
945 if (pep_sk(sk)->aligned)
946 return pipe_skb_send(sk, skb);
947
937 rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); 948 rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC);
938 if (!rskb) { 949 if (!rskb) {
939 kfree_skb(skb); 950 kfree_skb(skb);
@@ -973,6 +984,10 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,
973 struct sk_buff *skb; 984 struct sk_buff *skb;
974 int err; 985 int err;
975 986
987 if (flags & ~(MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_DONTWAIT|MSG_WAITALL|
988 MSG_NOSIGNAL|MSG_CMSG_COMPAT))
989 return -EOPNOTSUPP;
990
976 if (unlikely(1 << sk->sk_state & (TCPF_LISTEN | TCPF_CLOSE))) 991 if (unlikely(1 << sk->sk_state & (TCPF_LISTEN | TCPF_CLOSE)))
977 return -ENOTCONN; 992 return -ENOTCONN;
978 993
@@ -980,6 +995,8 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,
980 /* Dequeue and acknowledge control request */ 995 /* Dequeue and acknowledge control request */
981 struct pep_sock *pn = pep_sk(sk); 996 struct pep_sock *pn = pep_sk(sk);
982 997
998 if (flags & MSG_PEEK)
999 return -EOPNOTSUPP;
983 skb = skb_dequeue(&pn->ctrlreq_queue); 1000 skb = skb_dequeue(&pn->ctrlreq_queue);
984 if (skb) { 1001 if (skb) {
985 pep_ctrlreq_error(sk, skb, PN_PIPE_NO_ERROR, 1002 pep_ctrlreq_error(sk, skb, PN_PIPE_NO_ERROR,