void rxrpc_process_connection(struct work_struct *work) { struct rxrpc_connection *conn = container_of(work, struct rxrpc_connection, processor); struct rxrpc_skb_priv *sp; struct sk_buff *skb; u32 abort_code = RX_PROTOCOL_ERROR; int ret; _enter("{%d}", conn->debug_id); atomic_inc(&conn->usage); if (test_and_clear_bit(RXRPC_CONN_CHALLENGE, &conn->events)) { rxrpc_secure_connection(conn); rxrpc_put_connection(conn); } /* go through the conn-level event packets, releasing the ref on this * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { sp = rxrpc_skb(skb); ret = rxrpc_process_event(conn, skb, &abort_code); switch (ret) { case -EPROTO: case -EKEYEXPIRED: case -EKEYREJECTED: goto protocol_error; case -EAGAIN: goto requeue_and_leave; case -ECONNABORTED: default: rxrpc_put_connection(conn); rxrpc_free_skb(skb); break; } } out: rxrpc_put_connection(conn); _leave(""); return; requeue_and_leave: skb_queue_head(&conn->rx_queue, skb); goto out; protocol_error: if (rxrpc_abort_connection(conn, -ret, abort_code) < 0) goto requeue_and_leave; rxrpc_put_connection(conn); rxrpc_free_skb(skb); _leave(" [EPROTO]"); goto out; }
/* * connection-level event processor */ void rxrpc_process_connection(struct work_struct *work) { struct rxrpc_connection *conn = container_of(work, struct rxrpc_connection, processor); struct sk_buff *skb; u32 abort_code = RX_PROTOCOL_ERROR; int ret; rxrpc_see_connection(conn); if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); /* Process delayed ACKs whose time has come. */ if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK) rxrpc_process_delayed_final_acks(conn); /* go through the conn-level event packets, releasing the ref on this * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_rx_seen); ret = rxrpc_process_event(conn, skb, &abort_code); switch (ret) { case -EPROTO: case -EKEYEXPIRED: case -EKEYREJECTED: goto protocol_error; case -ENOMEM: case -EAGAIN: goto requeue_and_leave; case -ECONNABORTED: default: rxrpc_free_skb(skb, rxrpc_skb_rx_freed); break; } } out: rxrpc_put_connection(conn); _leave(""); return; requeue_and_leave: skb_queue_head(&conn->rx_queue, skb); goto out; protocol_error: if (rxrpc_abort_connection(conn, ret, abort_code) < 0) goto requeue_and_leave; rxrpc_free_skb(skb, rxrpc_skb_rx_freed); goto out; }