12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 28c3e34a4SDavid Howells /* connection-level event handling 38c3e34a4SDavid Howells * 48c3e34a4SDavid Howells * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 58c3e34a4SDavid Howells * Written by David Howells (dhowells@redhat.com) 68c3e34a4SDavid Howells */ 78c3e34a4SDavid Howells 88c3e34a4SDavid Howells #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 98c3e34a4SDavid Howells 108c3e34a4SDavid Howells #include <linux/module.h> 118c3e34a4SDavid Howells #include <linux/net.h> 128c3e34a4SDavid Howells #include <linux/skbuff.h> 138c3e34a4SDavid Howells #include <linux/errqueue.h> 148c3e34a4SDavid Howells #include <net/sock.h> 158c3e34a4SDavid Howells #include <net/af_rxrpc.h> 168c3e34a4SDavid Howells #include <net/ip.h> 178c3e34a4SDavid Howells #include "ar-internal.h" 188c3e34a4SDavid Howells 198c3e34a4SDavid Howells /* 20a00ce28bSDavid Howells * Set the completion state on an aborted connection. 21a00ce28bSDavid Howells */ 22a00ce28bSDavid Howells static bool rxrpc_set_conn_aborted(struct rxrpc_connection *conn, struct sk_buff *skb, 23a00ce28bSDavid Howells s32 abort_code, int err, 24a00ce28bSDavid Howells enum rxrpc_call_completion compl) 25a00ce28bSDavid Howells { 26a00ce28bSDavid Howells bool aborted = false; 27a00ce28bSDavid Howells 28a00ce28bSDavid Howells if (conn->state != RXRPC_CONN_ABORTED) { 29a00ce28bSDavid Howells spin_lock(&conn->state_lock); 30a00ce28bSDavid Howells if (conn->state != RXRPC_CONN_ABORTED) { 31a00ce28bSDavid Howells conn->abort_code = abort_code; 32a00ce28bSDavid Howells conn->error = err; 33a00ce28bSDavid Howells conn->completion = compl; 34a00ce28bSDavid Howells /* Order the abort info before the state change. */ 35a00ce28bSDavid Howells smp_store_release(&conn->state, RXRPC_CONN_ABORTED); 36a00ce28bSDavid Howells set_bit(RXRPC_CONN_DONT_REUSE, &conn->flags); 37a00ce28bSDavid Howells set_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events); 38a00ce28bSDavid Howells aborted = true; 39a00ce28bSDavid Howells } 40a00ce28bSDavid Howells spin_unlock(&conn->state_lock); 41a00ce28bSDavid Howells } 42a00ce28bSDavid Howells 43a00ce28bSDavid Howells return aborted; 44a00ce28bSDavid Howells } 45a00ce28bSDavid Howells 46a00ce28bSDavid Howells /* 47a00ce28bSDavid Howells * Mark a socket buffer to indicate that the connection it's on should be aborted. 48a00ce28bSDavid Howells */ 49a00ce28bSDavid Howells int rxrpc_abort_conn(struct rxrpc_connection *conn, struct sk_buff *skb, 5057af281eSDavid Howells s32 abort_code, int err, enum rxrpc_abort_reason why) 51a00ce28bSDavid Howells { 52a00ce28bSDavid Howells struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 53a00ce28bSDavid Howells 54a00ce28bSDavid Howells if (rxrpc_set_conn_aborted(conn, skb, abort_code, err, 55a00ce28bSDavid Howells RXRPC_CALL_LOCALLY_ABORTED)) { 56a00ce28bSDavid Howells trace_rxrpc_abort(0, why, sp->hdr.cid, sp->hdr.callNumber, 57a00ce28bSDavid Howells sp->hdr.seq, abort_code, err); 58a00ce28bSDavid Howells rxrpc_poke_conn(conn, rxrpc_conn_get_poke_abort); 59a00ce28bSDavid Howells } 60a00ce28bSDavid Howells return -EPROTO; 61a00ce28bSDavid Howells } 62a00ce28bSDavid Howells 63a00ce28bSDavid Howells /* 64a00ce28bSDavid Howells * Mark a connection as being remotely aborted. 65a00ce28bSDavid Howells */ 66a00ce28bSDavid Howells static bool rxrpc_input_conn_abort(struct rxrpc_connection *conn, 67a00ce28bSDavid Howells struct sk_buff *skb) 68a00ce28bSDavid Howells { 69a00ce28bSDavid Howells return rxrpc_set_conn_aborted(conn, skb, skb->priority, -ECONNABORTED, 70a00ce28bSDavid Howells RXRPC_CALL_REMOTELY_ABORTED); 71a00ce28bSDavid Howells } 72a00ce28bSDavid Howells 73a00ce28bSDavid Howells /* 7418bfeba5SDavid Howells * Retransmit terminal ACK or ABORT of the previous call. 7518bfeba5SDavid Howells */ 7630df927bSDavid Howells void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, 773136ef49SDavid Howells struct sk_buff *skb, 783136ef49SDavid Howells unsigned int channel) 7918bfeba5SDavid Howells { 803136ef49SDavid Howells struct rxrpc_skb_priv *sp = skb ? rxrpc_skb(skb) : NULL; 8118bfeba5SDavid Howells struct rxrpc_channel *chan; 8218bfeba5SDavid Howells struct msghdr msg; 835fc62f6aSDavid Howells struct kvec iov[3]; 8418bfeba5SDavid Howells struct { 8518bfeba5SDavid Howells struct rxrpc_wire_header whdr; 8618bfeba5SDavid Howells union { 875fc62f6aSDavid Howells __be32 abort_code; 8818bfeba5SDavid Howells struct rxrpc_ackpacket ack; 8918bfeba5SDavid Howells }; 9018bfeba5SDavid Howells } __attribute__((packed)) pkt; 915fc62f6aSDavid Howells struct rxrpc_ackinfo ack_info; 9218bfeba5SDavid Howells size_t len; 936b47fe1dSDavid Howells int ret, ioc; 945fc62f6aSDavid Howells u32 serial, mtu, call_id, padding; 9518bfeba5SDavid Howells 9618bfeba5SDavid Howells _enter("%d", conn->debug_id); 9718bfeba5SDavid Howells 983136ef49SDavid Howells chan = &conn->channels[channel]; 9918bfeba5SDavid Howells 10018bfeba5SDavid Howells /* If the last call got moved on whilst we were waiting to run, just 10118bfeba5SDavid Howells * ignore this packet. 10218bfeba5SDavid Howells */ 1039d35d880SDavid Howells call_id = chan->last_call; 1043136ef49SDavid Howells if (skb && call_id != sp->hdr.callNumber) 10518bfeba5SDavid Howells return; 10618bfeba5SDavid Howells 1072cc80086SDavid Howells msg.msg_name = &conn->peer->srx.transport; 1082cc80086SDavid Howells msg.msg_namelen = conn->peer->srx.transport_len; 10918bfeba5SDavid Howells msg.msg_control = NULL; 11018bfeba5SDavid Howells msg.msg_controllen = 0; 11118bfeba5SDavid Howells msg.msg_flags = 0; 11218bfeba5SDavid Howells 1135fc62f6aSDavid Howells iov[0].iov_base = &pkt; 1145fc62f6aSDavid Howells iov[0].iov_len = sizeof(pkt.whdr); 1155fc62f6aSDavid Howells iov[1].iov_base = &padding; 1165fc62f6aSDavid Howells iov[1].iov_len = 3; 1175fc62f6aSDavid Howells iov[2].iov_base = &ack_info; 1185fc62f6aSDavid Howells iov[2].iov_len = sizeof(ack_info); 1195fc62f6aSDavid Howells 1209d35d880SDavid Howells serial = atomic_inc_return(&conn->serial); 1219d35d880SDavid Howells 1223136ef49SDavid Howells pkt.whdr.epoch = htonl(conn->proto.epoch); 123fb1967a6SDavid Howells pkt.whdr.cid = htonl(conn->proto.cid | channel); 1243136ef49SDavid Howells pkt.whdr.callNumber = htonl(call_id); 1259d35d880SDavid Howells pkt.whdr.serial = htonl(serial); 12618bfeba5SDavid Howells pkt.whdr.seq = 0; 12718bfeba5SDavid Howells pkt.whdr.type = chan->last_type; 12818bfeba5SDavid Howells pkt.whdr.flags = conn->out_clientflag; 12918bfeba5SDavid Howells pkt.whdr.userStatus = 0; 13018bfeba5SDavid Howells pkt.whdr.securityIndex = conn->security_ix; 13118bfeba5SDavid Howells pkt.whdr._rsvd = 0; 13268d6d1aeSDavid Howells pkt.whdr.serviceId = htons(conn->service_id); 13318bfeba5SDavid Howells 13418bfeba5SDavid Howells len = sizeof(pkt.whdr); 13518bfeba5SDavid Howells switch (chan->last_type) { 13618bfeba5SDavid Howells case RXRPC_PACKET_TYPE_ABORT: 1375fc62f6aSDavid Howells pkt.abort_code = htonl(chan->last_abort); 1385fc62f6aSDavid Howells iov[0].iov_len += sizeof(pkt.abort_code); 1395fc62f6aSDavid Howells len += sizeof(pkt.abort_code); 1405fc62f6aSDavid Howells ioc = 1; 14118bfeba5SDavid Howells break; 14218bfeba5SDavid Howells 14318bfeba5SDavid Howells case RXRPC_PACKET_TYPE_ACK: 1442cc80086SDavid Howells mtu = conn->peer->if_mtu; 1452cc80086SDavid Howells mtu -= conn->peer->hdrsize; 14618bfeba5SDavid Howells pkt.ack.bufferSpace = 0; 1473136ef49SDavid Howells pkt.ack.maxSkew = htons(skb ? skb->priority : 0); 1483136ef49SDavid Howells pkt.ack.firstPacket = htonl(chan->last_seq + 1); 1493136ef49SDavid Howells pkt.ack.previousPacket = htonl(chan->last_seq); 1503136ef49SDavid Howells pkt.ack.serial = htonl(skb ? sp->hdr.serial : 0); 1513136ef49SDavid Howells pkt.ack.reason = skb ? RXRPC_ACK_DUPLICATE : RXRPC_ACK_IDLE; 15218bfeba5SDavid Howells pkt.ack.nAcks = 0; 1535fc62f6aSDavid Howells ack_info.rxMTU = htonl(rxrpc_rx_mtu); 1545fc62f6aSDavid Howells ack_info.maxMTU = htonl(mtu); 1555fc62f6aSDavid Howells ack_info.rwind = htonl(rxrpc_rx_window_size); 1565fc62f6aSDavid Howells ack_info.jumbo_max = htonl(rxrpc_rx_jumbo_max); 15757494343SDavid Howells pkt.whdr.flags |= RXRPC_SLOW_START_OK; 1585fc62f6aSDavid Howells padding = 0; 1595fc62f6aSDavid Howells iov[0].iov_len += sizeof(pkt.ack); 1605fc62f6aSDavid Howells len += sizeof(pkt.ack) + 3 + sizeof(ack_info); 1615fc62f6aSDavid Howells ioc = 3; 1625fc62f6aSDavid Howells 1634764c0daSDavid Howells trace_rxrpc_tx_ack(chan->call_debug_id, serial, 164f3f8337cSDavid Howells ntohl(pkt.ack.firstPacket), 165f3f8337cSDavid Howells ntohl(pkt.ack.serial), 166*f789bff2SDavid Howells pkt.ack.reason, 0, rxrpc_rx_window_size); 16718bfeba5SDavid Howells break; 1689d35d880SDavid Howells 1699d35d880SDavid Howells default: 1709d35d880SDavid Howells return; 17118bfeba5SDavid Howells } 17218bfeba5SDavid Howells 1732cc80086SDavid Howells ret = kernel_sendmsg(conn->local->socket, &msg, iov, ioc, len); 1742cc80086SDavid Howells conn->peer->last_tx_at = ktime_get_seconds(); 1756b47fe1dSDavid Howells if (ret < 0) 1764764c0daSDavid Howells trace_rxrpc_tx_fail(chan->call_debug_id, serial, ret, 1774764c0daSDavid Howells rxrpc_tx_point_call_final_resend); 1784764c0daSDavid Howells else 1794764c0daSDavid Howells trace_rxrpc_tx_packet(chan->call_debug_id, &pkt.whdr, 1804764c0daSDavid Howells rxrpc_tx_point_call_final_resend); 1816b47fe1dSDavid Howells 18218bfeba5SDavid Howells _leave(""); 18318bfeba5SDavid Howells } 18418bfeba5SDavid Howells 18518bfeba5SDavid Howells /* 1868c3e34a4SDavid Howells * pass a connection-level abort onto all calls on that connection 1878c3e34a4SDavid Howells */ 188a00ce28bSDavid Howells static void rxrpc_abort_calls(struct rxrpc_connection *conn) 1898c3e34a4SDavid Howells { 1908c3e34a4SDavid Howells struct rxrpc_call *call; 191248f219cSDavid Howells int i; 1928c3e34a4SDavid Howells 19364753092SDavid Howells _enter("{%d},%x", conn->debug_id, conn->abort_code); 1948c3e34a4SDavid Howells 195a1399f8bSDavid Howells for (i = 0; i < RXRPC_MAXCALLS; i++) { 1969d35d880SDavid Howells call = conn->channels[i].call; 197a00ce28bSDavid Howells if (call) 198a00ce28bSDavid Howells rxrpc_set_call_completion(call, 199a00ce28bSDavid Howells conn->completion, 20064753092SDavid Howells conn->abort_code, 20164753092SDavid Howells conn->error); 202ccbd3dbeSDavid Howells } 2038c3e34a4SDavid Howells 2048c3e34a4SDavid Howells _leave(""); 2058c3e34a4SDavid Howells } 2068c3e34a4SDavid Howells 2078c3e34a4SDavid Howells /* 2088c3e34a4SDavid Howells * mark a call as being on a now-secured channel 209248f219cSDavid Howells * - must be called with BH's disabled. 2108c3e34a4SDavid Howells */ 2118c3e34a4SDavid Howells static void rxrpc_call_is_secure(struct rxrpc_call *call) 2128c3e34a4SDavid Howells { 21396b4059fSDavid Howells if (call && __rxrpc_call_state(call) == RXRPC_CALL_SERVER_SECURING) { 21496b4059fSDavid Howells rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST); 215248f219cSDavid Howells rxrpc_notify_socket(call); 216248f219cSDavid Howells } 2178c3e34a4SDavid Howells } 2188c3e34a4SDavid Howells 2198c3e34a4SDavid Howells /* 2208c3e34a4SDavid Howells * connection-level Rx packet processor 2218c3e34a4SDavid Howells */ 2228c3e34a4SDavid Howells static int rxrpc_process_event(struct rxrpc_connection *conn, 223a00ce28bSDavid Howells struct sk_buff *skb) 2248c3e34a4SDavid Howells { 2258c3e34a4SDavid Howells struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 2262953d3b8SDavid Howells int ret; 2278c3e34a4SDavid Howells 228a00ce28bSDavid Howells if (conn->state == RXRPC_CONN_ABORTED) 2298c3e34a4SDavid Howells return -ECONNABORTED; 2308c3e34a4SDavid Howells 2318c3e34a4SDavid Howells _enter("{%d},{%u,%%%u},", conn->debug_id, sp->hdr.type, sp->hdr.serial); 2328c3e34a4SDavid Howells 2338c3e34a4SDavid Howells switch (sp->hdr.type) { 2348c3e34a4SDavid Howells case RXRPC_PACKET_TYPE_CHALLENGE: 235a00ce28bSDavid Howells return conn->security->respond_to_challenge(conn, skb); 2368c3e34a4SDavid Howells 2378c3e34a4SDavid Howells case RXRPC_PACKET_TYPE_RESPONSE: 238a00ce28bSDavid Howells ret = conn->security->verify_response(conn, skb); 2398c3e34a4SDavid Howells if (ret < 0) 2408c3e34a4SDavid Howells return ret; 2418c3e34a4SDavid Howells 24241057ebdSDavid Howells ret = conn->security->init_connection_security( 2432cc80086SDavid Howells conn, conn->key->payload.data[0]); 2448c3e34a4SDavid Howells if (ret < 0) 2458c3e34a4SDavid Howells return ret; 2468c3e34a4SDavid Howells 2473dd9c8b5SDavid Howells spin_lock(&conn->state_lock); 2482953d3b8SDavid Howells if (conn->state == RXRPC_CONN_SERVICE_CHALLENGING) 249bba304dbSDavid Howells conn->state = RXRPC_CONN_SERVICE; 2503dd9c8b5SDavid Howells spin_unlock(&conn->state_lock); 2518c3e34a4SDavid Howells 2522953d3b8SDavid Howells if (conn->state == RXRPC_CONN_SERVICE) { 2532953d3b8SDavid Howells /* Offload call state flipping to the I/O thread. As 2542953d3b8SDavid Howells * we've already received the packet, put it on the 2552953d3b8SDavid Howells * front of the queue. 2562953d3b8SDavid Howells */ 2572953d3b8SDavid Howells skb->mark = RXRPC_SKB_MARK_SERVICE_CONN_SECURED; 2582953d3b8SDavid Howells rxrpc_get_skb(skb, rxrpc_skb_get_conn_secured); 2592953d3b8SDavid Howells skb_queue_head(&conn->local->rx_queue, skb); 2602953d3b8SDavid Howells rxrpc_wake_up_io_thread(conn->local); 2612953d3b8SDavid Howells } 2628c3e34a4SDavid Howells return 0; 2638c3e34a4SDavid Howells 2648c3e34a4SDavid Howells default: 26557af281eSDavid Howells WARN_ON_ONCE(1); 2668c3e34a4SDavid Howells return -EPROTO; 2678c3e34a4SDavid Howells } 2688c3e34a4SDavid Howells } 2698c3e34a4SDavid Howells 2708c3e34a4SDavid Howells /* 2718c3e34a4SDavid Howells * set up security and issue a challenge 2728c3e34a4SDavid Howells */ 2738c3e34a4SDavid Howells static void rxrpc_secure_connection(struct rxrpc_connection *conn) 2748c3e34a4SDavid Howells { 275a00ce28bSDavid Howells if (conn->security->issue_challenge(conn) < 0) 27657af281eSDavid Howells rxrpc_abort_conn(conn, NULL, RX_CALL_DEAD, -ENOMEM, 27757af281eSDavid Howells rxrpc_abort_nomem); 2788c3e34a4SDavid Howells } 2798c3e34a4SDavid Howells 2808c3e34a4SDavid Howells /* 2813136ef49SDavid Howells * Process delayed final ACKs that we haven't subsumed into a subsequent call. 2823136ef49SDavid Howells */ 283ddc7834aSDavid Howells void rxrpc_process_delayed_final_acks(struct rxrpc_connection *conn, bool force) 2843136ef49SDavid Howells { 2853136ef49SDavid Howells unsigned long j = jiffies, next_j; 2863136ef49SDavid Howells unsigned int channel; 2873136ef49SDavid Howells bool set; 2883136ef49SDavid Howells 2893136ef49SDavid Howells again: 2903136ef49SDavid Howells next_j = j + LONG_MAX; 2913136ef49SDavid Howells set = false; 2923136ef49SDavid Howells for (channel = 0; channel < RXRPC_MAXCALLS; channel++) { 2933136ef49SDavid Howells struct rxrpc_channel *chan = &conn->channels[channel]; 2943136ef49SDavid Howells unsigned long ack_at; 2953136ef49SDavid Howells 2963136ef49SDavid Howells if (!test_bit(RXRPC_CONN_FINAL_ACK_0 + channel, &conn->flags)) 2973136ef49SDavid Howells continue; 2983136ef49SDavid Howells 2999d35d880SDavid Howells ack_at = chan->final_ack_at; 300ddc7834aSDavid Howells if (time_before(j, ack_at) && !force) { 3013136ef49SDavid Howells if (time_before(ack_at, next_j)) { 3023136ef49SDavid Howells next_j = ack_at; 3033136ef49SDavid Howells set = true; 3043136ef49SDavid Howells } 3053136ef49SDavid Howells continue; 3063136ef49SDavid Howells } 3073136ef49SDavid Howells 3083136ef49SDavid Howells if (test_and_clear_bit(RXRPC_CONN_FINAL_ACK_0 + channel, 3093136ef49SDavid Howells &conn->flags)) 3103136ef49SDavid Howells rxrpc_conn_retransmit_call(conn, NULL, channel); 3113136ef49SDavid Howells } 3123136ef49SDavid Howells 3133136ef49SDavid Howells j = jiffies; 3143136ef49SDavid Howells if (time_before_eq(next_j, j)) 3153136ef49SDavid Howells goto again; 3163136ef49SDavid Howells if (set) 3173136ef49SDavid Howells rxrpc_reduce_conn_timer(conn, next_j); 3183136ef49SDavid Howells } 3193136ef49SDavid Howells 3203136ef49SDavid Howells /* 3218c3e34a4SDavid Howells * connection-level event processor 3228c3e34a4SDavid Howells */ 32304d36d74SDavid Howells static void rxrpc_do_process_connection(struct rxrpc_connection *conn) 3248c3e34a4SDavid Howells { 3258c3e34a4SDavid Howells struct sk_buff *skb; 3268c3e34a4SDavid Howells int ret; 3278c3e34a4SDavid Howells 3282c4579e4SDavid Howells if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) 3298c3e34a4SDavid Howells rxrpc_secure_connection(conn); 3308c3e34a4SDavid Howells 3318c3e34a4SDavid Howells /* go through the conn-level event packets, releasing the ref on this 3328c3e34a4SDavid Howells * connection that each one has when we've finished with it */ 3338c3e34a4SDavid Howells while ((skb = skb_dequeue(&conn->rx_queue))) { 3349a36a6bcSDavid Howells rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); 335a00ce28bSDavid Howells ret = rxrpc_process_event(conn, skb); 3368c3e34a4SDavid Howells switch (ret) { 3378c2f826dSDavid Howells case -ENOMEM: 3388c3e34a4SDavid Howells case -EAGAIN: 339a00ce28bSDavid Howells skb_queue_head(&conn->rx_queue, skb); 340a00ce28bSDavid Howells rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); 341a00ce28bSDavid Howells break; 3428c3e34a4SDavid Howells default: 3439a36a6bcSDavid Howells rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); 3448c3e34a4SDavid Howells break; 3458c3e34a4SDavid Howells } 3468c3e34a4SDavid Howells } 34704d36d74SDavid Howells } 34804d36d74SDavid Howells 34904d36d74SDavid Howells void rxrpc_process_connection(struct work_struct *work) 35004d36d74SDavid Howells { 35104d36d74SDavid Howells struct rxrpc_connection *conn = 35204d36d74SDavid Howells container_of(work, struct rxrpc_connection, processor); 35304d36d74SDavid Howells 3547fa25105SDavid Howells rxrpc_see_connection(conn, rxrpc_conn_see_work); 35504d36d74SDavid Howells 3560fde882fSDavid Howells if (__rxrpc_use_local(conn->local, rxrpc_local_use_conn_work)) { 35704d36d74SDavid Howells rxrpc_do_process_connection(conn); 3580fde882fSDavid Howells rxrpc_unuse_local(conn->local, rxrpc_local_unuse_conn_work); 35904d36d74SDavid Howells } 3608c3e34a4SDavid Howells } 3615e6ef4f1SDavid Howells 3625e6ef4f1SDavid Howells /* 3635e6ef4f1SDavid Howells * post connection-level events to the connection 3645e6ef4f1SDavid Howells * - this includes challenges, responses, some aborts and call terminal packet 3655e6ef4f1SDavid Howells * retransmission. 3665e6ef4f1SDavid Howells */ 3675e6ef4f1SDavid Howells static void rxrpc_post_packet_to_conn(struct rxrpc_connection *conn, 3685e6ef4f1SDavid Howells struct sk_buff *skb) 3695e6ef4f1SDavid Howells { 3705e6ef4f1SDavid Howells _enter("%p,%p", conn, skb); 3715e6ef4f1SDavid Howells 3725e6ef4f1SDavid Howells rxrpc_get_skb(skb, rxrpc_skb_get_conn_work); 3735e6ef4f1SDavid Howells skb_queue_tail(&conn->rx_queue, skb); 3745e6ef4f1SDavid Howells rxrpc_queue_conn(conn, rxrpc_conn_queue_rx_work); 3755e6ef4f1SDavid Howells } 3765e6ef4f1SDavid Howells 3775e6ef4f1SDavid Howells /* 3785e6ef4f1SDavid Howells * Input a connection-level packet. 3795e6ef4f1SDavid Howells */ 38057af281eSDavid Howells bool rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb) 3815e6ef4f1SDavid Howells { 3825e6ef4f1SDavid Howells struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 3835e6ef4f1SDavid Howells 3845e6ef4f1SDavid Howells switch (sp->hdr.type) { 3855e6ef4f1SDavid Howells case RXRPC_PACKET_TYPE_BUSY: 3865e6ef4f1SDavid Howells /* Just ignore BUSY packets for now. */ 38757af281eSDavid Howells return true; 3885e6ef4f1SDavid Howells 3895e6ef4f1SDavid Howells case RXRPC_PACKET_TYPE_ABORT: 390a00ce28bSDavid Howells if (rxrpc_is_conn_aborted(conn)) 391a00ce28bSDavid Howells return true; 392a00ce28bSDavid Howells rxrpc_input_conn_abort(conn, skb); 393a00ce28bSDavid Howells rxrpc_abort_calls(conn); 394a00ce28bSDavid Howells return true; 3955e6ef4f1SDavid Howells 3965e6ef4f1SDavid Howells case RXRPC_PACKET_TYPE_CHALLENGE: 3975e6ef4f1SDavid Howells case RXRPC_PACKET_TYPE_RESPONSE: 398a00ce28bSDavid Howells if (rxrpc_is_conn_aborted(conn)) { 399a00ce28bSDavid Howells if (conn->completion == RXRPC_CALL_LOCALLY_ABORTED) 400a00ce28bSDavid Howells rxrpc_send_conn_abort(conn); 401a00ce28bSDavid Howells return true; 402a00ce28bSDavid Howells } 4035e6ef4f1SDavid Howells rxrpc_post_packet_to_conn(conn, skb); 40457af281eSDavid Howells return true; 4055e6ef4f1SDavid Howells 4065e6ef4f1SDavid Howells default: 40757af281eSDavid Howells WARN_ON_ONCE(1); 40857af281eSDavid Howells return true; 4095e6ef4f1SDavid Howells } 4105e6ef4f1SDavid Howells } 411f2cce89aSDavid Howells 412f2cce89aSDavid Howells /* 413f2cce89aSDavid Howells * Input a connection event. 414f2cce89aSDavid Howells */ 415f2cce89aSDavid Howells void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb) 416f2cce89aSDavid Howells { 4172953d3b8SDavid Howells unsigned int loop; 4182953d3b8SDavid Howells 419a00ce28bSDavid Howells if (test_and_clear_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events)) 420a00ce28bSDavid Howells rxrpc_abort_calls(conn); 421a00ce28bSDavid Howells 4222953d3b8SDavid Howells switch (skb->mark) { 4232953d3b8SDavid Howells case RXRPC_SKB_MARK_SERVICE_CONN_SECURED: 4242953d3b8SDavid Howells if (conn->state != RXRPC_CONN_SERVICE) 4252953d3b8SDavid Howells break; 4262953d3b8SDavid Howells 4272953d3b8SDavid Howells for (loop = 0; loop < RXRPC_MAXCALLS; loop++) 4289d35d880SDavid Howells rxrpc_call_is_secure(conn->channels[loop].call); 4292953d3b8SDavid Howells break; 4302953d3b8SDavid Howells } 4312953d3b8SDavid Howells 432f2cce89aSDavid Howells /* Process delayed ACKs whose time has come. */ 433f2cce89aSDavid Howells if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK) 434f2cce89aSDavid Howells rxrpc_process_delayed_final_acks(conn, false); 435f2cce89aSDavid Howells } 436