diff options
Diffstat (limited to 'net/phonet/pep.c')
-rw-r--r-- | net/phonet/pep.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index b6356f3832f6..360cf377693e 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -354,6 +354,9 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
354 | queue = &pn->ctrlreq_queue; | 354 | queue = &pn->ctrlreq_queue; |
355 | goto queue; | 355 | goto queue; |
356 | 356 | ||
357 | case PNS_PIPE_ALIGNED_DATA: | ||
358 | __skb_pull(skb, 1); | ||
359 | /* fall through */ | ||
357 | case PNS_PIPE_DATA: | 360 | case PNS_PIPE_DATA: |
358 | __skb_pull(skb, 3); /* Pipe data header */ | 361 | __skb_pull(skb, 3); /* Pipe data header */ |
359 | if (!pn_flow_safe(pn->rx_fc)) { | 362 | if (!pn_flow_safe(pn->rx_fc)) { |
@@ -441,6 +444,7 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) | |||
441 | struct sockaddr_pn dst; | 444 | struct sockaddr_pn dst; |
442 | u16 peer_type; | 445 | u16 peer_type; |
443 | u8 pipe_handle, enabled, n_sb; | 446 | u8 pipe_handle, enabled, n_sb; |
447 | u8 aligned = 0; | ||
444 | 448 | ||
445 | if (!pskb_pull(skb, sizeof(*hdr) + 4)) | 449 | if (!pskb_pull(skb, sizeof(*hdr) + 4)) |
446 | return -EINVAL; | 450 | return -EINVAL; |
@@ -479,6 +483,9 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) | |||
479 | return -EINVAL; | 483 | return -EINVAL; |
480 | peer_type = (peer_type & 0xff00) | data[0]; | 484 | peer_type = (peer_type & 0xff00) | data[0]; |
481 | break; | 485 | break; |
486 | case PN_PIPE_SB_ALIGNED_DATA: | ||
487 | aligned = data[0] != 0; | ||
488 | break; | ||
482 | } | 489 | } |
483 | n_sb--; | 490 | n_sb--; |
484 | } | 491 | } |
@@ -510,6 +517,7 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) | |||
510 | newpn->rx_credits = 0; | 517 | newpn->rx_credits = 0; |
511 | newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL; | 518 | newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL; |
512 | newpn->init_enable = enabled; | 519 | newpn->init_enable = enabled; |
520 | newpn->aligned = aligned; | ||
513 | 521 | ||
514 | BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue)); | 522 | BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue)); |
515 | skb_queue_head(&newsk->sk_receive_queue, skb); | 523 | skb_queue_head(&newsk->sk_receive_queue, skb); |
@@ -829,11 +837,15 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) | |||
829 | return -ENOBUFS; | 837 | return -ENOBUFS; |
830 | } | 838 | } |
831 | 839 | ||
832 | skb_push(skb, 3); | 840 | skb_push(skb, 3 + pn->aligned); |
833 | skb_reset_transport_header(skb); | 841 | skb_reset_transport_header(skb); |
834 | ph = pnp_hdr(skb); | 842 | ph = pnp_hdr(skb); |
835 | ph->utid = 0; | 843 | ph->utid = 0; |
836 | ph->message_id = PNS_PIPE_DATA; | 844 | if (pn->aligned) { |
845 | ph->message_id = PNS_PIPE_ALIGNED_DATA; | ||
846 | ph->data[0] = 0; /* padding */ | ||
847 | } else | ||
848 | ph->message_id = PNS_PIPE_DATA; | ||
837 | ph->pipe_handle = pn->pipe_handle; | 849 | ph->pipe_handle = pn->pipe_handle; |
838 | 850 | ||
839 | return pn_skb_send(sk, skb, &pipe_srv); | 851 | return pn_skb_send(sk, skb, &pipe_srv); |
@@ -848,7 +860,9 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
848 | int flags = msg->msg_flags; | 860 | int flags = msg->msg_flags; |
849 | int err, done; | 861 | int err, done; |
850 | 862 | ||
851 | if (msg->msg_flags & MSG_OOB || !(msg->msg_flags & MSG_EOR)) | 863 | if ((msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL| |
864 | MSG_CMSG_COMPAT)) || | ||
865 | !(msg->msg_flags & MSG_EOR)) | ||
852 | return -EOPNOTSUPP; | 866 | return -EOPNOTSUPP; |
853 | 867 | ||
854 | skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len, | 868 | skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len, |
@@ -927,6 +941,9 @@ int pep_write(struct sock *sk, struct sk_buff *skb) | |||
927 | struct sk_buff *rskb, *fs; | 941 | struct sk_buff *rskb, *fs; |
928 | int flen = 0; | 942 | int flen = 0; |
929 | 943 | ||
944 | if (pep_sk(sk)->aligned) | ||
945 | return pipe_skb_send(sk, skb); | ||
946 | |||
930 | rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); | 947 | rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); |
931 | if (!rskb) { | 948 | if (!rskb) { |
932 | kfree_skb(skb); | 949 | kfree_skb(skb); |
@@ -966,6 +983,10 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
966 | struct sk_buff *skb; | 983 | struct sk_buff *skb; |
967 | int err; | 984 | int err; |
968 | 985 | ||
986 | if (flags & ~(MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_DONTWAIT|MSG_WAITALL| | ||
987 | MSG_NOSIGNAL|MSG_CMSG_COMPAT)) | ||
988 | return -EOPNOTSUPP; | ||
989 | |||
969 | if (unlikely(1 << sk->sk_state & (TCPF_LISTEN | TCPF_CLOSE))) | 990 | if (unlikely(1 << sk->sk_state & (TCPF_LISTEN | TCPF_CLOSE))) |
970 | return -ENOTCONN; | 991 | return -ENOTCONN; |
971 | 992 | ||
@@ -973,6 +994,8 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
973 | /* Dequeue and acknowledge control request */ | 994 | /* Dequeue and acknowledge control request */ |
974 | struct pep_sock *pn = pep_sk(sk); | 995 | struct pep_sock *pn = pep_sk(sk); |
975 | 996 | ||
997 | if (flags & MSG_PEEK) | ||
998 | return -EOPNOTSUPP; | ||
976 | skb = skb_dequeue(&pn->ctrlreq_queue); | 999 | skb = skb_dequeue(&pn->ctrlreq_queue); |
977 | if (skb) { | 1000 | if (skb) { |
978 | pep_ctrlreq_error(sk, skb, PN_PIPE_NO_ERROR, | 1001 | pep_ctrlreq_error(sk, skb, PN_PIPE_NO_ERROR, |