18c3e34a4SDavid Howells /* RxRPC recvmsg() implementation 28c3e34a4SDavid Howells * 38c3e34a4SDavid Howells * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 48c3e34a4SDavid Howells * Written by David Howells (dhowells@redhat.com) 58c3e34a4SDavid Howells * 68c3e34a4SDavid Howells * This program is free software; you can redistribute it and/or 78c3e34a4SDavid Howells * modify it under the terms of the GNU General Public License 88c3e34a4SDavid Howells * as published by the Free Software Foundation; either version 98c3e34a4SDavid Howells * 2 of the License, or (at your option) any later version. 108c3e34a4SDavid Howells */ 118c3e34a4SDavid Howells 128c3e34a4SDavid Howells #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 138c3e34a4SDavid Howells 148c3e34a4SDavid Howells #include <linux/net.h> 158c3e34a4SDavid Howells #include <linux/skbuff.h> 168c3e34a4SDavid Howells #include <linux/export.h> 17174cd4b1SIngo Molnar #include <linux/sched/signal.h> 18174cd4b1SIngo Molnar 198c3e34a4SDavid Howells #include <net/sock.h> 208c3e34a4SDavid Howells #include <net/af_rxrpc.h> 218c3e34a4SDavid Howells #include "ar-internal.h" 228c3e34a4SDavid Howells 238c3e34a4SDavid Howells /* 24248f219cSDavid Howells * Post a call for attention by the socket or kernel service. Further 25248f219cSDavid Howells * notifications are suppressed by putting recvmsg_link on a dummy queue. 26248f219cSDavid Howells */ 27248f219cSDavid Howells void rxrpc_notify_socket(struct rxrpc_call *call) 28248f219cSDavid Howells { 29248f219cSDavid Howells struct rxrpc_sock *rx; 30248f219cSDavid Howells struct sock *sk; 31248f219cSDavid Howells 32248f219cSDavid Howells _enter("%d", call->debug_id); 33248f219cSDavid Howells 34248f219cSDavid Howells if (!list_empty(&call->recvmsg_link)) 35248f219cSDavid Howells return; 36248f219cSDavid Howells 37248f219cSDavid Howells rcu_read_lock(); 38248f219cSDavid Howells 39248f219cSDavid Howells rx = rcu_dereference(call->socket); 40248f219cSDavid Howells sk = &rx->sk; 41248f219cSDavid Howells if (rx && sk->sk_state < RXRPC_CLOSE) { 42248f219cSDavid Howells if (call->notify_rx) { 4320acbd9aSDavid Howells spin_lock_bh(&call->notify_lock); 44248f219cSDavid Howells call->notify_rx(sk, call, call->user_call_ID); 4520acbd9aSDavid Howells spin_unlock_bh(&call->notify_lock); 46248f219cSDavid Howells } else { 47248f219cSDavid Howells write_lock_bh(&rx->recvmsg_lock); 48248f219cSDavid Howells if (list_empty(&call->recvmsg_link)) { 49248f219cSDavid Howells rxrpc_get_call(call, rxrpc_call_got); 50248f219cSDavid Howells list_add_tail(&call->recvmsg_link, &rx->recvmsg_q); 51248f219cSDavid Howells } 52248f219cSDavid Howells write_unlock_bh(&rx->recvmsg_lock); 53248f219cSDavid Howells 54248f219cSDavid Howells if (!sock_flag(sk, SOCK_DEAD)) { 55248f219cSDavid Howells _debug("call %ps", sk->sk_data_ready); 56248f219cSDavid Howells sk->sk_data_ready(sk); 57248f219cSDavid Howells } 58248f219cSDavid Howells } 59248f219cSDavid Howells } 60248f219cSDavid Howells 61248f219cSDavid Howells rcu_read_unlock(); 62248f219cSDavid Howells _leave(""); 63248f219cSDavid Howells } 64248f219cSDavid Howells 65248f219cSDavid Howells /* 66248f219cSDavid Howells * Pass a call terminating message to userspace. 67248f219cSDavid Howells */ 68248f219cSDavid Howells static int rxrpc_recvmsg_term(struct rxrpc_call *call, struct msghdr *msg) 69248f219cSDavid Howells { 70248f219cSDavid Howells u32 tmp = 0; 71248f219cSDavid Howells int ret; 72248f219cSDavid Howells 73248f219cSDavid Howells switch (call->completion) { 74248f219cSDavid Howells case RXRPC_CALL_SUCCEEDED: 75248f219cSDavid Howells ret = 0; 76248f219cSDavid Howells if (rxrpc_is_service_call(call)) 77248f219cSDavid Howells ret = put_cmsg(msg, SOL_RXRPC, RXRPC_ACK, 0, &tmp); 78248f219cSDavid Howells break; 79248f219cSDavid Howells case RXRPC_CALL_REMOTELY_ABORTED: 80248f219cSDavid Howells tmp = call->abort_code; 81248f219cSDavid Howells ret = put_cmsg(msg, SOL_RXRPC, RXRPC_ABORT, 4, &tmp); 82248f219cSDavid Howells break; 83248f219cSDavid Howells case RXRPC_CALL_LOCALLY_ABORTED: 84248f219cSDavid Howells tmp = call->abort_code; 85248f219cSDavid Howells ret = put_cmsg(msg, SOL_RXRPC, RXRPC_ABORT, 4, &tmp); 86248f219cSDavid Howells break; 87248f219cSDavid Howells case RXRPC_CALL_NETWORK_ERROR: 883a92789aSDavid Howells tmp = -call->error; 89248f219cSDavid Howells ret = put_cmsg(msg, SOL_RXRPC, RXRPC_NET_ERROR, 4, &tmp); 90248f219cSDavid Howells break; 91248f219cSDavid Howells case RXRPC_CALL_LOCAL_ERROR: 923a92789aSDavid Howells tmp = -call->error; 93248f219cSDavid Howells ret = put_cmsg(msg, SOL_RXRPC, RXRPC_LOCAL_ERROR, 4, &tmp); 94248f219cSDavid Howells break; 95248f219cSDavid Howells default: 96248f219cSDavid Howells pr_err("Invalid terminal call state %u\n", call->state); 97248f219cSDavid Howells BUG(); 98248f219cSDavid Howells break; 99248f219cSDavid Howells } 100248f219cSDavid Howells 10184997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_terminal, call->rx_hard_ack, 10284997905SDavid Howells call->rx_pkt_offset, call->rx_pkt_len, ret); 103248f219cSDavid Howells return ret; 104248f219cSDavid Howells } 105248f219cSDavid Howells 106248f219cSDavid Howells /* 107248f219cSDavid Howells * Pass back notification of a new call. The call is added to the 108248f219cSDavid Howells * to-be-accepted list. This means that the next call to be accepted might not 109248f219cSDavid Howells * be the last call seen awaiting acceptance, but unless we leave this on the 110248f219cSDavid Howells * front of the queue and block all other messages until someone gives us a 111248f219cSDavid Howells * user_ID for it, there's not a lot we can do. 112248f219cSDavid Howells */ 113248f219cSDavid Howells static int rxrpc_recvmsg_new_call(struct rxrpc_sock *rx, 114248f219cSDavid Howells struct rxrpc_call *call, 115248f219cSDavid Howells struct msghdr *msg, int flags) 116248f219cSDavid Howells { 117248f219cSDavid Howells int tmp = 0, ret; 118248f219cSDavid Howells 119248f219cSDavid Howells ret = put_cmsg(msg, SOL_RXRPC, RXRPC_NEW_CALL, 0, &tmp); 120248f219cSDavid Howells 121248f219cSDavid Howells if (ret == 0 && !(flags & MSG_PEEK)) { 122248f219cSDavid Howells _debug("to be accepted"); 123248f219cSDavid Howells write_lock_bh(&rx->recvmsg_lock); 124248f219cSDavid Howells list_del_init(&call->recvmsg_link); 125248f219cSDavid Howells write_unlock_bh(&rx->recvmsg_lock); 126248f219cSDavid Howells 1273432a757SDavid Howells rxrpc_get_call(call, rxrpc_call_got); 128248f219cSDavid Howells write_lock(&rx->call_lock); 129248f219cSDavid Howells list_add_tail(&call->accept_link, &rx->to_be_accepted); 130248f219cSDavid Howells write_unlock(&rx->call_lock); 131248f219cSDavid Howells } 132248f219cSDavid Howells 13384997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_to_be_accepted, 1, 0, 0, ret); 134248f219cSDavid Howells return ret; 135248f219cSDavid Howells } 136248f219cSDavid Howells 137248f219cSDavid Howells /* 138248f219cSDavid Howells * End the packet reception phase. 139248f219cSDavid Howells */ 140b69d94d7SDavid Howells static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial) 141248f219cSDavid Howells { 142248f219cSDavid Howells _enter("%d,%s", call->debug_id, rxrpc_call_states[call->state]); 143248f219cSDavid Howells 14458dc63c9SDavid Howells trace_rxrpc_receive(call, rxrpc_receive_end, 0, call->rx_top); 145816c9fceSDavid Howells ASSERTCMP(call->rx_hard_ack, ==, call->rx_top); 146816c9fceSDavid Howells 147248f219cSDavid Howells if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) { 148a71a2651SDavid Howells rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, serial, false, true, 1499c7ad434SDavid Howells rxrpc_propose_ack_terminal_ack); 150a71a2651SDavid Howells //rxrpc_send_ack_packet(call, false, NULL); 151248f219cSDavid Howells } 152248f219cSDavid Howells 153248f219cSDavid Howells write_lock_bh(&call->state_lock); 154248f219cSDavid Howells 155248f219cSDavid Howells switch (call->state) { 156248f219cSDavid Howells case RXRPC_CALL_CLIENT_RECV_REPLY: 157248f219cSDavid Howells __rxrpc_call_completed(call); 1589749fd2bSDavid Howells write_unlock_bh(&call->state_lock); 159248f219cSDavid Howells break; 160248f219cSDavid Howells 161248f219cSDavid Howells case RXRPC_CALL_SERVER_RECV_REQUEST: 16271f3ca40SDavid Howells call->tx_phase = true; 163248f219cSDavid Howells call->state = RXRPC_CALL_SERVER_ACK_REQUEST; 164a158bdd3SDavid Howells call->expect_req_by = jiffies + MAX_JIFFY_OFFSET; 1659749fd2bSDavid Howells write_unlock_bh(&call->state_lock); 1669749fd2bSDavid Howells rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, 0, serial, false, true, 1679749fd2bSDavid Howells rxrpc_propose_ack_processing_op); 168248f219cSDavid Howells break; 169248f219cSDavid Howells default: 1709749fd2bSDavid Howells write_unlock_bh(&call->state_lock); 171248f219cSDavid Howells break; 172248f219cSDavid Howells } 173248f219cSDavid Howells } 174248f219cSDavid Howells 175248f219cSDavid Howells /* 176248f219cSDavid Howells * Discard a packet we've used up and advance the Rx window by one. 177248f219cSDavid Howells */ 178248f219cSDavid Howells static void rxrpc_rotate_rx_window(struct rxrpc_call *call) 179248f219cSDavid Howells { 180816c9fceSDavid Howells struct rxrpc_skb_priv *sp; 181248f219cSDavid Howells struct sk_buff *skb; 18258dc63c9SDavid Howells rxrpc_serial_t serial; 183248f219cSDavid Howells rxrpc_seq_t hard_ack, top; 184816c9fceSDavid Howells u8 flags; 185248f219cSDavid Howells int ix; 186248f219cSDavid Howells 187248f219cSDavid Howells _enter("%d", call->debug_id); 188248f219cSDavid Howells 189248f219cSDavid Howells hard_ack = call->rx_hard_ack; 190248f219cSDavid Howells top = smp_load_acquire(&call->rx_top); 191248f219cSDavid Howells ASSERT(before(hard_ack, top)); 192248f219cSDavid Howells 193248f219cSDavid Howells hard_ack++; 194248f219cSDavid Howells ix = hard_ack & RXRPC_RXTX_BUFF_MASK; 195248f219cSDavid Howells skb = call->rxtx_buffer[ix]; 19671f3ca40SDavid Howells rxrpc_see_skb(skb, rxrpc_skb_rx_rotated); 197816c9fceSDavid Howells sp = rxrpc_skb(skb); 198816c9fceSDavid Howells flags = sp->hdr.flags; 19958dc63c9SDavid Howells serial = sp->hdr.serial; 20058dc63c9SDavid Howells if (call->rxtx_annotations[ix] & RXRPC_RX_ANNO_JUMBO) 20158dc63c9SDavid Howells serial += (call->rxtx_annotations[ix] & RXRPC_RX_ANNO_JUMBO) - 1; 20258dc63c9SDavid Howells 203248f219cSDavid Howells call->rxtx_buffer[ix] = NULL; 204248f219cSDavid Howells call->rxtx_annotations[ix] = 0; 205248f219cSDavid Howells /* Barrier against rxrpc_input_data(). */ 206248f219cSDavid Howells smp_store_release(&call->rx_hard_ack, hard_ack); 207248f219cSDavid Howells 20871f3ca40SDavid Howells rxrpc_free_skb(skb, rxrpc_skb_rx_freed); 209248f219cSDavid Howells 210816c9fceSDavid Howells _debug("%u,%u,%02x", hard_ack, top, flags); 21158dc63c9SDavid Howells trace_rxrpc_receive(call, rxrpc_receive_rotate, serial, hard_ack); 212805b21b9SDavid Howells if (flags & RXRPC_LAST_PACKET) { 213b69d94d7SDavid Howells rxrpc_end_rx_phase(call, serial); 214805b21b9SDavid Howells } else { 215805b21b9SDavid Howells /* Check to see if there's an ACK that needs sending. */ 216805b21b9SDavid Howells if (after_eq(hard_ack, call->ackr_consumed + 2) || 217805b21b9SDavid Howells after_eq(top, call->ackr_seen + 2) || 218805b21b9SDavid Howells (hard_ack == top && after(hard_ack, call->ackr_consumed))) 219805b21b9SDavid Howells rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, 0, serial, 2208637abaaSDavid Howells true, true, 221805b21b9SDavid Howells rxrpc_propose_ack_rotate_rx); 2228637abaaSDavid Howells if (call->ackr_reason && call->ackr_reason != RXRPC_ACK_DELAY) 223bd1fdf8cSDavid Howells rxrpc_send_ack_packet(call, false, NULL); 224805b21b9SDavid Howells } 225248f219cSDavid Howells } 226248f219cSDavid Howells 227248f219cSDavid Howells /* 228248f219cSDavid Howells * Decrypt and verify a (sub)packet. The packet's length may be changed due to 229248f219cSDavid Howells * padding, but if this is the case, the packet length will be resident in the 230248f219cSDavid Howells * socket buffer. Note that we can't modify the master skb info as the skb may 231248f219cSDavid Howells * be the home to multiple subpackets. 232248f219cSDavid Howells */ 233248f219cSDavid Howells static int rxrpc_verify_packet(struct rxrpc_call *call, struct sk_buff *skb, 234248f219cSDavid Howells u8 annotation, 235248f219cSDavid Howells unsigned int offset, unsigned int len) 236248f219cSDavid Howells { 237248f219cSDavid Howells struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 238248f219cSDavid Howells rxrpc_seq_t seq = sp->hdr.seq; 239248f219cSDavid Howells u16 cksum = sp->hdr.cksum; 240248f219cSDavid Howells 241248f219cSDavid Howells _enter(""); 242248f219cSDavid Howells 243248f219cSDavid Howells /* For all but the head jumbo subpacket, the security checksum is in a 244248f219cSDavid Howells * jumbo header immediately prior to the data. 245248f219cSDavid Howells */ 246248f219cSDavid Howells if ((annotation & RXRPC_RX_ANNO_JUMBO) > 1) { 247248f219cSDavid Howells __be16 tmp; 248248f219cSDavid Howells if (skb_copy_bits(skb, offset - 2, &tmp, 2) < 0) 249248f219cSDavid Howells BUG(); 250248f219cSDavid Howells cksum = ntohs(tmp); 251248f219cSDavid Howells seq += (annotation & RXRPC_RX_ANNO_JUMBO) - 1; 252248f219cSDavid Howells } 253248f219cSDavid Howells 254248f219cSDavid Howells return call->conn->security->verify_packet(call, skb, offset, len, 255248f219cSDavid Howells seq, cksum); 256248f219cSDavid Howells } 257248f219cSDavid Howells 258248f219cSDavid Howells /* 259248f219cSDavid Howells * Locate the data within a packet. This is complicated by: 260248f219cSDavid Howells * 261248f219cSDavid Howells * (1) An skb may contain a jumbo packet - so we have to find the appropriate 262248f219cSDavid Howells * subpacket. 263248f219cSDavid Howells * 264248f219cSDavid Howells * (2) The (sub)packets may be encrypted and, if so, the encrypted portion 265248f219cSDavid Howells * contains an extra header which includes the true length of the data, 266248f219cSDavid Howells * excluding any encrypted padding. 267248f219cSDavid Howells */ 268248f219cSDavid Howells static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, 269248f219cSDavid Howells u8 *_annotation, 270248f219cSDavid Howells unsigned int *_offset, unsigned int *_len) 271248f219cSDavid Howells { 272775e5b71SDavid Howells unsigned int offset = sizeof(struct rxrpc_wire_header); 273650b4ecaSColin Ian King unsigned int len; 274248f219cSDavid Howells int ret; 275248f219cSDavid Howells u8 annotation = *_annotation; 276248f219cSDavid Howells 277248f219cSDavid Howells /* Locate the subpacket */ 278775e5b71SDavid Howells len = skb->len - offset; 279248f219cSDavid Howells if ((annotation & RXRPC_RX_ANNO_JUMBO) > 0) { 280248f219cSDavid Howells offset += (((annotation & RXRPC_RX_ANNO_JUMBO) - 1) * 281248f219cSDavid Howells RXRPC_JUMBO_SUBPKTLEN); 282248f219cSDavid Howells len = (annotation & RXRPC_RX_ANNO_JLAST) ? 283248f219cSDavid Howells skb->len - offset : RXRPC_JUMBO_SUBPKTLEN; 284248f219cSDavid Howells } 285248f219cSDavid Howells 286248f219cSDavid Howells if (!(annotation & RXRPC_RX_ANNO_VERIFIED)) { 287248f219cSDavid Howells ret = rxrpc_verify_packet(call, skb, annotation, offset, len); 288248f219cSDavid Howells if (ret < 0) 289248f219cSDavid Howells return ret; 290248f219cSDavid Howells *_annotation |= RXRPC_RX_ANNO_VERIFIED; 291248f219cSDavid Howells } 292248f219cSDavid Howells 293248f219cSDavid Howells *_offset = offset; 294248f219cSDavid Howells *_len = len; 295248f219cSDavid Howells call->conn->security->locate_data(call, skb, _offset, _len); 296248f219cSDavid Howells return 0; 297248f219cSDavid Howells } 298248f219cSDavid Howells 299248f219cSDavid Howells /* 300248f219cSDavid Howells * Deliver messages to a call. This keeps processing packets until the buffer 301248f219cSDavid Howells * is filled and we find either more DATA (returns 0) or the end of the DATA 302248f219cSDavid Howells * (returns 1). If more packets are required, it returns -EAGAIN. 303248f219cSDavid Howells */ 304248f219cSDavid Howells static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, 305248f219cSDavid Howells struct msghdr *msg, struct iov_iter *iter, 306248f219cSDavid Howells size_t len, int flags, size_t *_offset) 307248f219cSDavid Howells { 308248f219cSDavid Howells struct rxrpc_skb_priv *sp; 309248f219cSDavid Howells struct sk_buff *skb; 310248f219cSDavid Howells rxrpc_seq_t hard_ack, top, seq; 311248f219cSDavid Howells size_t remain; 312248f219cSDavid Howells bool last; 313248f219cSDavid Howells unsigned int rx_pkt_offset, rx_pkt_len; 314816c9fceSDavid Howells int ix, copy, ret = -EAGAIN, ret2; 315248f219cSDavid Howells 316248f219cSDavid Howells rx_pkt_offset = call->rx_pkt_offset; 317248f219cSDavid Howells rx_pkt_len = call->rx_pkt_len; 318248f219cSDavid Howells 319816c9fceSDavid Howells if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) { 320816c9fceSDavid Howells seq = call->rx_hard_ack; 321816c9fceSDavid Howells ret = 1; 322816c9fceSDavid Howells goto done; 323816c9fceSDavid Howells } 324816c9fceSDavid Howells 325248f219cSDavid Howells /* Barriers against rxrpc_input_data(). */ 326248f219cSDavid Howells hard_ack = call->rx_hard_ack; 327d7e15835SDavid Howells seq = hard_ack + 1; 328d7e15835SDavid Howells while (top = smp_load_acquire(&call->rx_top), 329d7e15835SDavid Howells before_eq(seq, top) 330d7e15835SDavid Howells ) { 331248f219cSDavid Howells ix = seq & RXRPC_RXTX_BUFF_MASK; 332248f219cSDavid Howells skb = call->rxtx_buffer[ix]; 33384997905SDavid Howells if (!skb) { 33484997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_hole, seq, 33584997905SDavid Howells rx_pkt_offset, rx_pkt_len, 0); 336248f219cSDavid Howells break; 33784997905SDavid Howells } 338248f219cSDavid Howells smp_rmb(); 33971f3ca40SDavid Howells rxrpc_see_skb(skb, rxrpc_skb_rx_seen); 340248f219cSDavid Howells sp = rxrpc_skb(skb); 341248f219cSDavid Howells 34258dc63c9SDavid Howells if (!(flags & MSG_PEEK)) 34358dc63c9SDavid Howells trace_rxrpc_receive(call, rxrpc_receive_front, 34458dc63c9SDavid Howells sp->hdr.serial, seq); 34558dc63c9SDavid Howells 346248f219cSDavid Howells if (msg) 347248f219cSDavid Howells sock_recv_timestamp(msg, sock->sk, skb); 348248f219cSDavid Howells 3492e2ea51dSDavid Howells if (rx_pkt_offset == 0) { 350816c9fceSDavid Howells ret2 = rxrpc_locate_data(call, skb, 3514b22457cSDavid Howells &call->rxtx_annotations[ix], 352248f219cSDavid Howells &rx_pkt_offset, &rx_pkt_len); 35384997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_next, seq, 35484997905SDavid Howells rx_pkt_offset, rx_pkt_len, ret2); 355816c9fceSDavid Howells if (ret2 < 0) { 356816c9fceSDavid Howells ret = ret2; 3572e2ea51dSDavid Howells goto out; 3582e2ea51dSDavid Howells } 35984997905SDavid Howells } else { 36084997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_cont, seq, 36184997905SDavid Howells rx_pkt_offset, rx_pkt_len, 0); 362816c9fceSDavid Howells } 363248f219cSDavid Howells 364248f219cSDavid Howells /* We have to handle short, empty and used-up DATA packets. */ 365248f219cSDavid Howells remain = len - *_offset; 366248f219cSDavid Howells copy = rx_pkt_len; 367248f219cSDavid Howells if (copy > remain) 368248f219cSDavid Howells copy = remain; 369248f219cSDavid Howells if (copy > 0) { 370816c9fceSDavid Howells ret2 = skb_copy_datagram_iter(skb, rx_pkt_offset, iter, 371248f219cSDavid Howells copy); 372816c9fceSDavid Howells if (ret2 < 0) { 373816c9fceSDavid Howells ret = ret2; 374248f219cSDavid Howells goto out; 375816c9fceSDavid Howells } 376248f219cSDavid Howells 377248f219cSDavid Howells /* handle piecemeal consumption of data packets */ 378248f219cSDavid Howells rx_pkt_offset += copy; 379248f219cSDavid Howells rx_pkt_len -= copy; 380248f219cSDavid Howells *_offset += copy; 381248f219cSDavid Howells } 382248f219cSDavid Howells 383248f219cSDavid Howells if (rx_pkt_len > 0) { 38484997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_full, seq, 38584997905SDavid Howells rx_pkt_offset, rx_pkt_len, 0); 386248f219cSDavid Howells ASSERTCMP(*_offset, ==, len); 387816c9fceSDavid Howells ret = 0; 388248f219cSDavid Howells break; 389248f219cSDavid Howells } 390248f219cSDavid Howells 391248f219cSDavid Howells /* The whole packet has been transferred. */ 392248f219cSDavid Howells last = sp->hdr.flags & RXRPC_LAST_PACKET; 393248f219cSDavid Howells if (!(flags & MSG_PEEK)) 394248f219cSDavid Howells rxrpc_rotate_rx_window(call); 395248f219cSDavid Howells rx_pkt_offset = 0; 396248f219cSDavid Howells rx_pkt_len = 0; 397248f219cSDavid Howells 398816c9fceSDavid Howells if (last) { 399816c9fceSDavid Howells ASSERTCMP(seq, ==, READ_ONCE(call->rx_top)); 400816c9fceSDavid Howells ret = 1; 401816c9fceSDavid Howells goto out; 402816c9fceSDavid Howells } 403d7e15835SDavid Howells 404d7e15835SDavid Howells seq++; 405248f219cSDavid Howells } 406248f219cSDavid Howells 407248f219cSDavid Howells out: 408248f219cSDavid Howells if (!(flags & MSG_PEEK)) { 409248f219cSDavid Howells call->rx_pkt_offset = rx_pkt_offset; 410248f219cSDavid Howells call->rx_pkt_len = rx_pkt_len; 411248f219cSDavid Howells } 412816c9fceSDavid Howells done: 41384997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_data_return, seq, 41484997905SDavid Howells rx_pkt_offset, rx_pkt_len, ret); 415248f219cSDavid Howells return ret; 416248f219cSDavid Howells } 417248f219cSDavid Howells 418248f219cSDavid Howells /* 419248f219cSDavid Howells * Receive a message from an RxRPC socket 4208c3e34a4SDavid Howells * - we need to be careful about two or more threads calling recvmsg 4218c3e34a4SDavid Howells * simultaneously 4228c3e34a4SDavid Howells */ 4238c3e34a4SDavid Howells int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, 4248c3e34a4SDavid Howells int flags) 4258c3e34a4SDavid Howells { 426248f219cSDavid Howells struct rxrpc_call *call; 4278c3e34a4SDavid Howells struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 428248f219cSDavid Howells struct list_head *l; 429248f219cSDavid Howells size_t copied = 0; 4308c3e34a4SDavid Howells long timeo; 431248f219cSDavid Howells int ret; 4328c3e34a4SDavid Howells 4338c3e34a4SDavid Howells DEFINE_WAIT(wait); 4348c3e34a4SDavid Howells 43584997905SDavid Howells trace_rxrpc_recvmsg(NULL, rxrpc_recvmsg_enter, 0, 0, 0, 0); 4368c3e34a4SDavid Howells 4378c3e34a4SDavid Howells if (flags & (MSG_OOB | MSG_TRUNC)) 4388c3e34a4SDavid Howells return -EOPNOTSUPP; 4398c3e34a4SDavid Howells 4408c3e34a4SDavid Howells timeo = sock_rcvtimeo(&rx->sk, flags & MSG_DONTWAIT); 4418c3e34a4SDavid Howells 442248f219cSDavid Howells try_again: 4438c3e34a4SDavid Howells lock_sock(&rx->sk); 4448c3e34a4SDavid Howells 445248f219cSDavid Howells /* Return immediately if a client socket has no outstanding calls */ 446248f219cSDavid Howells if (RB_EMPTY_ROOT(&rx->calls) && 447248f219cSDavid Howells list_empty(&rx->recvmsg_q) && 448248f219cSDavid Howells rx->sk.sk_state != RXRPC_SERVER_LISTENING) { 4498c3e34a4SDavid Howells release_sock(&rx->sk); 4508c3e34a4SDavid Howells return -ENODATA; 4518c3e34a4SDavid Howells } 4528c3e34a4SDavid Howells 453248f219cSDavid Howells if (list_empty(&rx->recvmsg_q)) { 454248f219cSDavid Howells ret = -EWOULDBLOCK; 45584997905SDavid Howells if (timeo == 0) { 45684997905SDavid Howells call = NULL; 457248f219cSDavid Howells goto error_no_call; 45884997905SDavid Howells } 4598c3e34a4SDavid Howells 4608c3e34a4SDavid Howells release_sock(&rx->sk); 461248f219cSDavid Howells 462248f219cSDavid Howells /* Wait for something to happen */ 4638c3e34a4SDavid Howells prepare_to_wait_exclusive(sk_sleep(&rx->sk), &wait, 4648c3e34a4SDavid Howells TASK_INTERRUPTIBLE); 4658c3e34a4SDavid Howells ret = sock_error(&rx->sk); 4668c3e34a4SDavid Howells if (ret) 4678c3e34a4SDavid Howells goto wait_error; 4688c3e34a4SDavid Howells 469248f219cSDavid Howells if (list_empty(&rx->recvmsg_q)) { 4708c3e34a4SDavid Howells if (signal_pending(current)) 4718c3e34a4SDavid Howells goto wait_interrupted; 47284997905SDavid Howells trace_rxrpc_recvmsg(NULL, rxrpc_recvmsg_wait, 47384997905SDavid Howells 0, 0, 0, 0); 4748c3e34a4SDavid Howells timeo = schedule_timeout(timeo); 4758c3e34a4SDavid Howells } 4768c3e34a4SDavid Howells finish_wait(sk_sleep(&rx->sk), &wait); 477248f219cSDavid Howells goto try_again; 4788c3e34a4SDavid Howells } 4798c3e34a4SDavid Howells 480248f219cSDavid Howells /* Find the next call and dequeue it if we're not just peeking. If we 481248f219cSDavid Howells * do dequeue it, that comes with a ref that we will need to release. 482248f219cSDavid Howells */ 483248f219cSDavid Howells write_lock_bh(&rx->recvmsg_lock); 484248f219cSDavid Howells l = rx->recvmsg_q.next; 485248f219cSDavid Howells call = list_entry(l, struct rxrpc_call, recvmsg_link); 486248f219cSDavid Howells if (!(flags & MSG_PEEK)) 487248f219cSDavid Howells list_del_init(&call->recvmsg_link); 488248f219cSDavid Howells else 489fff72429SDavid Howells rxrpc_get_call(call, rxrpc_call_got); 490248f219cSDavid Howells write_unlock_bh(&rx->recvmsg_lock); 4918c3e34a4SDavid Howells 49284997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_dequeue, 0, 0, 0, 0); 493248f219cSDavid Howells 494540b1c48SDavid Howells /* We're going to drop the socket lock, so we need to lock the call 495540b1c48SDavid Howells * against interference by sendmsg. 496540b1c48SDavid Howells */ 497540b1c48SDavid Howells if (!mutex_trylock(&call->user_mutex)) { 498540b1c48SDavid Howells ret = -EWOULDBLOCK; 499540b1c48SDavid Howells if (flags & MSG_DONTWAIT) 500540b1c48SDavid Howells goto error_requeue_call; 501540b1c48SDavid Howells ret = -ERESTARTSYS; 502540b1c48SDavid Howells if (mutex_lock_interruptible(&call->user_mutex) < 0) 503540b1c48SDavid Howells goto error_requeue_call; 504540b1c48SDavid Howells } 505540b1c48SDavid Howells 506540b1c48SDavid Howells release_sock(&rx->sk); 507540b1c48SDavid Howells 508248f219cSDavid Howells if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) 509248f219cSDavid Howells BUG(); 510248f219cSDavid Howells 511248f219cSDavid Howells if (test_bit(RXRPC_CALL_HAS_USERID, &call->flags)) { 512248f219cSDavid Howells if (flags & MSG_CMSG_COMPAT) { 513248f219cSDavid Howells unsigned int id32 = call->user_call_ID; 514248f219cSDavid Howells 515248f219cSDavid Howells ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, 516248f219cSDavid Howells sizeof(unsigned int), &id32); 517248f219cSDavid Howells } else { 518a16b8d0cSDavid Howells unsigned long idl = call->user_call_ID; 519a16b8d0cSDavid Howells 520248f219cSDavid Howells ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, 521a16b8d0cSDavid Howells sizeof(unsigned long), &idl); 522248f219cSDavid Howells } 523248f219cSDavid Howells if (ret < 0) 524540b1c48SDavid Howells goto error_unlock_call; 525248f219cSDavid Howells } 526248f219cSDavid Howells 5278c3e34a4SDavid Howells if (msg->msg_name) { 52868d6d1aeSDavid Howells struct sockaddr_rxrpc *srx = msg->msg_name; 52968d6d1aeSDavid Howells size_t len = sizeof(call->peer->srx); 53068d6d1aeSDavid Howells 53168d6d1aeSDavid Howells memcpy(msg->msg_name, &call->peer->srx, len); 53268d6d1aeSDavid Howells srx->srx_service = call->service_id; 5338c3e34a4SDavid Howells msg->msg_namelen = len; 5348c3e34a4SDavid Howells } 5358c3e34a4SDavid Howells 536146d8fefSDavid Howells switch (READ_ONCE(call->state)) { 537248f219cSDavid Howells case RXRPC_CALL_SERVER_ACCEPTING: 538248f219cSDavid Howells ret = rxrpc_recvmsg_new_call(rx, call, msg, flags); 5398c3e34a4SDavid Howells break; 540248f219cSDavid Howells case RXRPC_CALL_CLIENT_RECV_REPLY: 541248f219cSDavid Howells case RXRPC_CALL_SERVER_RECV_REQUEST: 542248f219cSDavid Howells case RXRPC_CALL_SERVER_ACK_REQUEST: 543248f219cSDavid Howells ret = rxrpc_recvmsg_data(sock, call, msg, &msg->msg_iter, len, 544248f219cSDavid Howells flags, &copied); 545248f219cSDavid Howells if (ret == -EAGAIN) 546248f219cSDavid Howells ret = 0; 54733b603fdSDavid Howells 54833b603fdSDavid Howells if (after(call->rx_top, call->rx_hard_ack) && 54933b603fdSDavid Howells call->rxtx_buffer[(call->rx_hard_ack + 1) & RXRPC_RXTX_BUFF_MASK]) 55033b603fdSDavid Howells rxrpc_notify_socket(call); 5518c3e34a4SDavid Howells break; 5528c3e34a4SDavid Howells default: 553248f219cSDavid Howells ret = 0; 5548c3e34a4SDavid Howells break; 5558c3e34a4SDavid Howells } 5568c3e34a4SDavid Howells 5578c3e34a4SDavid Howells if (ret < 0) 558540b1c48SDavid Howells goto error_unlock_call; 5598c3e34a4SDavid Howells 560248f219cSDavid Howells if (call->state == RXRPC_CALL_COMPLETE) { 561248f219cSDavid Howells ret = rxrpc_recvmsg_term(call, msg); 562248f219cSDavid Howells if (ret < 0) 563540b1c48SDavid Howells goto error_unlock_call; 564248f219cSDavid Howells if (!(flags & MSG_PEEK)) 5658d94aa38SDavid Howells rxrpc_release_call(rx, call); 566248f219cSDavid Howells msg->msg_flags |= MSG_EOR; 567248f219cSDavid Howells ret = 1; 5688c3e34a4SDavid Howells } 5698c3e34a4SDavid Howells 570248f219cSDavid Howells if (ret == 0) 571248f219cSDavid Howells msg->msg_flags |= MSG_MORE; 572248f219cSDavid Howells else 573248f219cSDavid Howells msg->msg_flags &= ~MSG_MORE; 574248f219cSDavid Howells ret = copied; 5758c3e34a4SDavid Howells 576540b1c48SDavid Howells error_unlock_call: 577540b1c48SDavid Howells mutex_unlock(&call->user_mutex); 578fff72429SDavid Howells rxrpc_put_call(call, rxrpc_call_put); 579540b1c48SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_return, 0, 0, 0, ret); 580540b1c48SDavid Howells return ret; 581540b1c48SDavid Howells 582540b1c48SDavid Howells error_requeue_call: 583540b1c48SDavid Howells if (!(flags & MSG_PEEK)) { 584540b1c48SDavid Howells write_lock_bh(&rx->recvmsg_lock); 585540b1c48SDavid Howells list_add(&call->recvmsg_link, &rx->recvmsg_q); 586540b1c48SDavid Howells write_unlock_bh(&rx->recvmsg_lock); 587540b1c48SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_requeue, 0, 0, 0, 0); 588540b1c48SDavid Howells } else { 589540b1c48SDavid Howells rxrpc_put_call(call, rxrpc_call_put); 590540b1c48SDavid Howells } 591248f219cSDavid Howells error_no_call: 592248f219cSDavid Howells release_sock(&rx->sk); 59384997905SDavid Howells trace_rxrpc_recvmsg(call, rxrpc_recvmsg_return, 0, 0, 0, ret); 5948c3e34a4SDavid Howells return ret; 5958c3e34a4SDavid Howells 5968c3e34a4SDavid Howells wait_interrupted: 5978c3e34a4SDavid Howells ret = sock_intr_errno(timeo); 5988c3e34a4SDavid Howells wait_error: 5998c3e34a4SDavid Howells finish_wait(sk_sleep(&rx->sk), &wait); 60084997905SDavid Howells call = NULL; 60184997905SDavid Howells goto error_no_call; 602d001648eSDavid Howells } 6038c3e34a4SDavid Howells 6048c3e34a4SDavid Howells /** 605d001648eSDavid Howells * rxrpc_kernel_recv_data - Allow a kernel service to receive data/info 606d001648eSDavid Howells * @sock: The socket that the call exists on 607d001648eSDavid Howells * @call: The call to send data through 608d001648eSDavid Howells * @buf: The buffer to receive into 609d001648eSDavid Howells * @size: The size of the buffer, including data already read 610d001648eSDavid Howells * @_offset: The running offset into the buffer. 611d001648eSDavid Howells * @want_more: True if more data is expected to be read 612d001648eSDavid Howells * @_abort: Where the abort code is stored if -ECONNABORTED is returned 613a68f4a27SDavid Howells * @_service: Where to store the actual service ID (may be upgraded) 6148c3e34a4SDavid Howells * 615d001648eSDavid Howells * Allow a kernel service to receive data and pick up information about the 616d001648eSDavid Howells * state of a call. Returns 0 if got what was asked for and there's more 617d001648eSDavid Howells * available, 1 if we got what was asked for and we're at the end of the data 618d001648eSDavid Howells * and -EAGAIN if we need more data. 619d001648eSDavid Howells * 620d001648eSDavid Howells * Note that we may return -EAGAIN to drain empty packets at the end of the 621d001648eSDavid Howells * data, even if we've already copied over the requested data. 622d001648eSDavid Howells * 623d001648eSDavid Howells * This function adds the amount it transfers to *_offset, so this should be 624d001648eSDavid Howells * precleared as appropriate. Note that the amount remaining in the buffer is 625d001648eSDavid Howells * taken to be size - *_offset. 626d001648eSDavid Howells * 627d001648eSDavid Howells * *_abort should also be initialised to 0. 6288c3e34a4SDavid Howells */ 629d001648eSDavid Howells int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call, 630d001648eSDavid Howells void *buf, size_t size, size_t *_offset, 631a68f4a27SDavid Howells bool want_more, u32 *_abort, u16 *_service) 6328c3e34a4SDavid Howells { 633d001648eSDavid Howells struct iov_iter iter; 634d001648eSDavid Howells struct kvec iov; 635d001648eSDavid Howells int ret; 6368c3e34a4SDavid Howells 637248f219cSDavid Howells _enter("{%d,%s},%zu/%zu,%d", 638248f219cSDavid Howells call->debug_id, rxrpc_call_states[call->state], 639248f219cSDavid Howells *_offset, size, want_more); 640d001648eSDavid Howells 641d001648eSDavid Howells ASSERTCMP(*_offset, <=, size); 642d001648eSDavid Howells ASSERTCMP(call->state, !=, RXRPC_CALL_SERVER_ACCEPTING); 643d001648eSDavid Howells 644d001648eSDavid Howells iov.iov_base = buf + *_offset; 645d001648eSDavid Howells iov.iov_len = size - *_offset; 646d001648eSDavid Howells iov_iter_kvec(&iter, ITER_KVEC | READ, &iov, 1, size - *_offset); 647d001648eSDavid Howells 648540b1c48SDavid Howells mutex_lock(&call->user_mutex); 649d001648eSDavid Howells 650146d8fefSDavid Howells switch (READ_ONCE(call->state)) { 651d001648eSDavid Howells case RXRPC_CALL_CLIENT_RECV_REPLY: 652d001648eSDavid Howells case RXRPC_CALL_SERVER_RECV_REQUEST: 653d001648eSDavid Howells case RXRPC_CALL_SERVER_ACK_REQUEST: 654248f219cSDavid Howells ret = rxrpc_recvmsg_data(sock, call, NULL, &iter, size, 0, 655248f219cSDavid Howells _offset); 656d001648eSDavid Howells if (ret < 0) 657d001648eSDavid Howells goto out; 658d001648eSDavid Howells 659d001648eSDavid Howells /* We can only reach here with a partially full buffer if we 660d001648eSDavid Howells * have reached the end of the data. We must otherwise have a 661d001648eSDavid Howells * full buffer or have been given -EAGAIN. 662d001648eSDavid Howells */ 663d001648eSDavid Howells if (ret == 1) { 664d001648eSDavid Howells if (*_offset < size) 665d001648eSDavid Howells goto short_data; 666d001648eSDavid Howells if (!want_more) 667d001648eSDavid Howells goto read_phase_complete; 668d001648eSDavid Howells ret = 0; 669d001648eSDavid Howells goto out; 6708c3e34a4SDavid Howells } 6718c3e34a4SDavid Howells 672d001648eSDavid Howells if (!want_more) 673d001648eSDavid Howells goto excess_data; 674d001648eSDavid Howells goto out; 675d001648eSDavid Howells 676d001648eSDavid Howells case RXRPC_CALL_COMPLETE: 677d001648eSDavid Howells goto call_complete; 678d001648eSDavid Howells 679d001648eSDavid Howells default: 680d001648eSDavid Howells ret = -EINPROGRESS; 681d001648eSDavid Howells goto out; 682d001648eSDavid Howells } 683d001648eSDavid Howells 684d001648eSDavid Howells read_phase_complete: 685d001648eSDavid Howells ret = 1; 686d001648eSDavid Howells out: 687a68f4a27SDavid Howells if (_service) 688a68f4a27SDavid Howells *_service = call->service_id; 689540b1c48SDavid Howells mutex_unlock(&call->user_mutex); 690d001648eSDavid Howells _leave(" = %d [%zu,%d]", ret, *_offset, *_abort); 691d001648eSDavid Howells return ret; 692d001648eSDavid Howells 693d001648eSDavid Howells short_data: 694fb46f6eeSDavid Howells trace_rxrpc_rx_eproto(call, 0, tracepoint_string("short_data")); 695d001648eSDavid Howells ret = -EBADMSG; 696d001648eSDavid Howells goto out; 697d001648eSDavid Howells excess_data: 698fb46f6eeSDavid Howells trace_rxrpc_rx_eproto(call, 0, tracepoint_string("excess_data")); 699d001648eSDavid Howells ret = -EMSGSIZE; 700d001648eSDavid Howells goto out; 701d001648eSDavid Howells call_complete: 702d001648eSDavid Howells *_abort = call->abort_code; 7033a92789aSDavid Howells ret = call->error; 704d001648eSDavid Howells if (call->completion == RXRPC_CALL_SUCCEEDED) { 705d001648eSDavid Howells ret = 1; 706d001648eSDavid Howells if (size > 0) 707d001648eSDavid Howells ret = -ECONNRESET; 708d001648eSDavid Howells } 709d001648eSDavid Howells goto out; 710d001648eSDavid Howells } 711d001648eSDavid Howells EXPORT_SYMBOL(rxrpc_kernel_recv_data); 712