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, |
