#include "internal.h"
 #include "afs_cm.h"
 #include "protocol_yfs.h"
+#define RXRPC_TRACE_ONLY_DEFINE_ENUMS
+#include <trace/events/rxrpc.h>
 
 static int afs_deliver_cb_init_call_back_state(struct afs_call *);
 static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
  * Abort a service call from within an action function.
  */
 static void afs_abort_service_call(struct afs_call *call, u32 abort_code, int error,
-                                  const char *why)
+                                  enum rxrpc_abort_reason why)
 {
        rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
                                abort_code, error, why);
        if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
                afs_send_empty_reply(call);
        else
-               afs_abort_service_call(call, 1, 1, "K-1");
+               afs_abort_service_call(call, 1, 1, afs_abort_probeuuid_negative);
 
        afs_put_call(call);
        _leave("");
 
 #include "internal.h"
 #include "afs_cm.h"
 #include "protocol_yfs.h"
+#define RXRPC_TRACE_ONLY_DEFINE_ENUMS
+#include <trace/events/rxrpc.h>
 
 struct workqueue_struct *afs_async_calls;
 
 error_do_abort:
        if (ret != -ECONNABORTED) {
                rxrpc_kernel_abort_call(call->net->socket, rxcall,
-                                       RX_USER_ABORT, ret, "KSD");
+                                       RX_USER_ABORT, ret,
+                                       afs_abort_send_data_error);
        } else {
                len = 0;
                iov_iter_kvec(&msg.msg_iter, ITER_DEST, NULL, 0, 0);
                case -ENOTSUPP:
                        abort_code = RXGEN_OPCODE;
                        rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
-                                               abort_code, ret, "KIV");
+                                               abort_code, ret,
+                                               afs_abort_op_not_supported);
                        goto local_abort;
                case -EIO:
                        pr_err("kAFS: Call %u in bad state %u\n",
                        if (state != AFS_CALL_CL_AWAIT_REPLY)
                                abort_code = RXGEN_SS_UNMARSHAL;
                        rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
-                                               abort_code, ret, "KUM");
+                                               abort_code, ret,
+                                               afs_abort_unmarshal_error);
                        goto local_abort;
                default:
                        abort_code = RX_CALL_DEAD;
                        rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
-                                               abort_code, ret, "KER");
+                                               abort_code, ret,
+                                               afs_abort_general_error);
                        goto local_abort;
                }
        }
                        /* Kill off the call if it's still live. */
                        _debug("call interrupted");
                        if (rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
-                                                   RX_USER_ABORT, -EINTR, "KWI"))
+                                                   RX_USER_ABORT, -EINTR,
+                                                   afs_abort_interrupted))
                                afs_set_call_complete(call, -EINTR, 0);
                }
        }
        case -ENOMEM:
                _debug("oom");
                rxrpc_kernel_abort_call(net->socket, call->rxcall,
-                                       RXGEN_SS_MARSHAL, -ENOMEM, "KOO");
+                                       RXGEN_SS_MARSHAL, -ENOMEM,
+                                       afs_abort_oom);
                fallthrough;
        default:
                _leave(" [error]");
        if (n == -ENOMEM) {
                _debug("oom");
                rxrpc_kernel_abort_call(net->socket, call->rxcall,
-                                       RXGEN_SS_MARSHAL, -ENOMEM, "KOO");
+                                       RXGEN_SS_MARSHAL, -ENOMEM,
+                                       afs_abort_oom);
        }
        _leave(" [error]");
 }
 
 struct sock;
 struct socket;
 struct rxrpc_call;
+enum rxrpc_abort_reason;
 
 enum rxrpc_interruptibility {
        RXRPC_INTERRUPTIBLE,    /* Call is interruptible */
 int rxrpc_kernel_recv_data(struct socket *, struct rxrpc_call *,
                           struct iov_iter *, size_t *, bool, u32 *, u16 *);
 bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
-                            u32, int, const char *);
+                            u32, int, enum rxrpc_abort_reason);
 void rxrpc_kernel_end_call(struct socket *, struct rxrpc_call *);
 void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *,
                           struct sockaddr_rxrpc *);
 
 /*
  * Declare tracing information enums and their string mappings for display.
  */
+#define rxrpc_abort_reasons \
+       /* AFS errors */                                                \
+       EM(afs_abort_general_error,             "afs-error")            \
+       EM(afs_abort_interrupted,               "afs-intr")             \
+       EM(afs_abort_oom,                       "afs-oom")              \
+       EM(afs_abort_op_not_supported,          "afs-op-notsupp")       \
+       EM(afs_abort_probeuuid_negative,        "afs-probeuuid-neg")    \
+       EM(afs_abort_send_data_error,           "afs-send-data")        \
+       EM(afs_abort_unmarshal_error,           "afs-unmarshal")        \
+       /* rxperf errors */                                             \
+       EM(rxperf_abort_general_error,          "rxperf-error")         \
+       EM(rxperf_abort_oom,                    "rxperf-oom")           \
+       EM(rxperf_abort_op_not_supported,       "rxperf-op-notsupp")    \
+       EM(rxperf_abort_unmarshal_error,        "rxperf-unmarshal")     \
+       /* RxKAD security errors */                                     \
+       EM(rxkad_abort_1_short_check,           "rxkad1-short-check")   \
+       EM(rxkad_abort_1_short_data,            "rxkad1-short-data")    \
+       EM(rxkad_abort_1_short_encdata,         "rxkad1-short-encdata") \
+       EM(rxkad_abort_1_short_header,          "rxkad1-short-hdr")     \
+       EM(rxkad_abort_2_short_check,           "rxkad2-short-check")   \
+       EM(rxkad_abort_2_short_data,            "rxkad2-short-data")    \
+       EM(rxkad_abort_2_short_header,          "rxkad2-short-hdr")     \
+       EM(rxkad_abort_2_short_len,             "rxkad2-short-len")     \
+       EM(rxkad_abort_bad_checksum,            "rxkad2-bad-cksum")     \
+       EM(rxkad_abort_chall_key_expired,       "rxkad-chall-key-exp")  \
+       EM(rxkad_abort_chall_level,             "rxkad-chall-level")    \
+       EM(rxkad_abort_chall_no_key,            "rxkad-chall-nokey")    \
+       EM(rxkad_abort_chall_short,             "rxkad-chall-short")    \
+       EM(rxkad_abort_chall_version,           "rxkad-chall-version")  \
+       EM(rxkad_abort_resp_bad_callid,         "rxkad-resp-bad-callid") \
+       EM(rxkad_abort_resp_bad_checksum,       "rxkad-resp-bad-cksum") \
+       EM(rxkad_abort_resp_bad_param,          "rxkad-resp-bad-param") \
+       EM(rxkad_abort_resp_call_ctr,           "rxkad-resp-call-ctr") \
+       EM(rxkad_abort_resp_call_state,         "rxkad-resp-call-state") \
+       EM(rxkad_abort_resp_key_expired,        "rxkad-resp-key-exp")   \
+       EM(rxkad_abort_resp_key_rejected,       "rxkad-resp-key-rej")   \
+       EM(rxkad_abort_resp_level,              "rxkad-resp-level")     \
+       EM(rxkad_abort_resp_nokey,              "rxkad-resp-nokey")     \
+       EM(rxkad_abort_resp_ooseq,              "rxkad-resp-ooseq")     \
+       EM(rxkad_abort_resp_short,              "rxkad-resp-short")     \
+       EM(rxkad_abort_resp_short_tkt,          "rxkad-resp-short-tkt") \
+       EM(rxkad_abort_resp_tkt_aname,          "rxkad-resp-tk-aname")  \
+       EM(rxkad_abort_resp_tkt_expired,        "rxkad-resp-tk-exp")    \
+       EM(rxkad_abort_resp_tkt_future,         "rxkad-resp-tk-future") \
+       EM(rxkad_abort_resp_tkt_inst,           "rxkad-resp-tk-inst")   \
+       EM(rxkad_abort_resp_tkt_len,            "rxkad-resp-tk-len")    \
+       EM(rxkad_abort_resp_tkt_realm,          "rxkad-resp-tk-realm")  \
+       EM(rxkad_abort_resp_tkt_short,          "rxkad-resp-tk-short")  \
+       EM(rxkad_abort_resp_tkt_sinst,          "rxkad-resp-tk-sinst")  \
+       EM(rxkad_abort_resp_tkt_sname,          "rxkad-resp-tk-sname")  \
+       EM(rxkad_abort_resp_unknown_tkt,        "rxkad-resp-unknown-tkt") \
+       EM(rxkad_abort_resp_version,            "rxkad-resp-version")   \
+       /* rxrpc errors */                                              \
+       EM(rxrpc_abort_call_improper_term,      "call-improper-term")   \
+       EM(rxrpc_abort_call_reset,              "call-reset")           \
+       EM(rxrpc_abort_call_sendmsg,            "call-sendmsg")         \
+       EM(rxrpc_abort_call_sock_release,       "call-sock-rel")        \
+       EM(rxrpc_abort_call_sock_release_tba,   "call-sock-rel-tba")    \
+       EM(rxrpc_abort_call_timeout,            "call-timeout")         \
+       EM(rxrpc_abort_no_service_key,          "no-serv-key")          \
+       EM(rxrpc_abort_nomem,                   "nomem")                \
+       EM(rxrpc_abort_service_not_offered,     "serv-not-offered")     \
+       EM(rxrpc_abort_shut_down,               "shut-down")            \
+       EM(rxrpc_abort_unsupported_security,    "unsup-sec")            \
+       EM(rxrpc_badmsg_bad_abort,              "bad-abort")            \
+       EM(rxrpc_badmsg_bad_jumbo,              "bad-jumbo")            \
+       EM(rxrpc_badmsg_short_ack,              "short-ack")            \
+       EM(rxrpc_badmsg_short_ack_info,         "short-ack-info")       \
+       EM(rxrpc_badmsg_short_hdr,              "short-hdr")            \
+       EM(rxrpc_badmsg_unsupported_packet,     "unsup-pkt")            \
+       EM(rxrpc_badmsg_zero_call,              "zero-call")            \
+       EM(rxrpc_badmsg_zero_seq,               "zero-seq")             \
+       EM(rxrpc_badmsg_zero_service,           "zero-service")         \
+       EM(rxrpc_eproto_ackr_outside_window,    "ackr-out-win")         \
+       EM(rxrpc_eproto_ackr_sack_overflow,     "ackr-sack-over")       \
+       EM(rxrpc_eproto_ackr_short_sack,        "ackr-short-sack")      \
+       EM(rxrpc_eproto_ackr_zero,              "ackr-zero")            \
+       EM(rxrpc_eproto_bad_upgrade,            "bad-upgrade")          \
+       EM(rxrpc_eproto_data_after_last,        "data-after-last")      \
+       EM(rxrpc_eproto_different_last,         "diff-last")            \
+       EM(rxrpc_eproto_early_reply,            "early-reply")          \
+       EM(rxrpc_eproto_improper_term,          "improper-term")        \
+       EM(rxrpc_eproto_no_client_call,         "no-cl-call")           \
+       EM(rxrpc_eproto_no_client_conn,         "no-cl-conn")           \
+       EM(rxrpc_eproto_no_service_call,        "no-sv-call")           \
+       EM(rxrpc_eproto_reupgrade,              "re-upgrade")           \
+       EM(rxrpc_eproto_rxnull_challenge,       "rxnull-chall")         \
+       EM(rxrpc_eproto_rxnull_response,        "rxnull-resp")          \
+       EM(rxrpc_eproto_tx_rot_last,            "tx-rot-last")          \
+       EM(rxrpc_eproto_unexpected_ack,         "unex-ack")             \
+       EM(rxrpc_eproto_unexpected_ackall,      "unex-ackall")          \
+       EM(rxrpc_eproto_unexpected_implicit_end, "unex-impl-end")       \
+       EM(rxrpc_eproto_unexpected_reply,       "unex-reply")           \
+       EM(rxrpc_eproto_wrong_security,         "wrong-sec")            \
+       EM(rxrpc_recvmsg_excess_data,           "recvmsg-excess")       \
+       EM(rxrpc_recvmsg_short_data,            "recvmsg-short")        \
+       E_(rxrpc_sendmsg_late_send,             "sendmsg-late")
+
 #define rxrpc_call_poke_traces \
        EM(rxrpc_call_poke_abort,               "Abort")        \
        EM(rxrpc_call_poke_complete,            "Compl")        \
 #define EM(a, b) a,
 #define E_(a, b) a
 
+enum rxrpc_abort_reason                { rxrpc_abort_reasons } __mode(byte);
 enum rxrpc_bundle_trace                { rxrpc_bundle_traces } __mode(byte);
 enum rxrpc_call_poke_trace     { rxrpc_call_poke_traces } __mode(byte);
 enum rxrpc_call_trace          { rxrpc_call_traces } __mode(byte);
  */
 #undef EM
 #undef E_
+
+#ifndef RXRPC_TRACE_ONLY_DEFINE_ENUMS
+
 #define EM(a, b) TRACE_DEFINE_ENUM(a);
 #define E_(a, b) TRACE_DEFINE_ENUM(a);
 
+rxrpc_abort_reasons;
 rxrpc_bundle_traces;
 rxrpc_call_poke_traces;
 rxrpc_call_traces;
            );
 
 TRACE_EVENT(rxrpc_abort,
-           TP_PROTO(unsigned int call_nr, const char *why, u32 cid, u32 call_id,
-                    rxrpc_seq_t seq, int abort_code, int error),
+           TP_PROTO(unsigned int call_nr, enum rxrpc_abort_reason why,
+                    u32 cid, u32 call_id, rxrpc_seq_t seq, int abort_code, int error),
 
            TP_ARGS(call_nr, why, cid, call_id, seq, abort_code, error),
 
            TP_STRUCT__entry(
                    __field(unsigned int,               call_nr         )
-                   __array(char,                       why, 4          )
+                   __field(enum rxrpc_abort_reason,    why             )
                    __field(u32,                        cid             )
                    __field(u32,                        call_id         )
                    __field(rxrpc_seq_t,                seq             )
                             ),
 
            TP_fast_assign(
-                   memcpy(__entry->why, why, 4);
                    __entry->call_nr = call_nr;
+                   __entry->why = why;
                    __entry->cid = cid;
                    __entry->call_id = call_id;
                    __entry->abort_code = abort_code;
            TP_printk("c=%08x %08x:%08x s=%u a=%d e=%d %s",
                      __entry->call_nr,
                      __entry->cid, __entry->call_id, __entry->seq,
-                     __entry->abort_code, __entry->error, __entry->why)
+                     __entry->abort_code, __entry->error,
+                     __print_symbolic(__entry->why, rxrpc_abort_reasons))
            );
 
 TRACE_EVENT(rxrpc_call_complete,
                      __entry->abort_code)
            );
 
-TRACE_EVENT(rxrpc_rx_eproto,
-           TP_PROTO(struct rxrpc_call *call, rxrpc_serial_t serial,
-                    const char *why),
-
-           TP_ARGS(call, serial, why),
-
-           TP_STRUCT__entry(
-                   __field(unsigned int,               call            )
-                   __field(rxrpc_serial_t,             serial          )
-                   __field(const char *,               why             )
-                            ),
-
-           TP_fast_assign(
-                   __entry->call = call ? call->debug_id : 0;
-                   __entry->serial = serial;
-                   __entry->why = why;
-                          ),
-
-           TP_printk("c=%08x EPROTO %08x %s",
-                     __entry->call,
-                     __entry->serial,
-                     __entry->why)
-           );
-
 TRACE_EVENT(rxrpc_connect_call,
            TP_PROTO(struct rxrpc_call *call),
 
 
 #undef EM
 #undef E_
+
+#endif /* RXRPC_TRACE_ONLY_DEFINE_ENUMS */
 #endif /* _TRACE_RXRPC_H */
 
 /* This part must be outside protection */
 
        unsigned long           events;
        spinlock_t              notify_lock;    /* Kernel notification lock */
        rwlock_t                state_lock;     /* lock for state transition */
-       const char              *send_abort_why; /* String indicating why the abort was sent */
+       unsigned int            send_abort_why; /* Why the abort [enum rxrpc_abort_reason] */
        s32                     send_abort;     /* Abort code to be sent */
        short                   send_abort_err; /* Error to be associated with the abort */
+       rxrpc_seq_t             send_abort_seq; /* DATA packet that incurred the abort (or 0) */
        s32                     abort_code;     /* Local/remote abort code */
        int                     error;          /* Local error incurred */
        enum rxrpc_call_state   state;          /* current state of call */
  */
 int rxrpc_service_prealloc(struct rxrpc_sock *, gfp_t);
 void rxrpc_discard_prealloc(struct rxrpc_sock *);
-int rxrpc_new_incoming_call(struct rxrpc_local *, struct rxrpc_peer *,
-                           struct rxrpc_connection *, struct sockaddr_rxrpc *,
-                           struct sk_buff *);
+bool rxrpc_new_incoming_call(struct rxrpc_local *local,
+                            struct rxrpc_peer *peer,
+                            struct rxrpc_connection *conn,
+                            struct sockaddr_rxrpc *peer_srx,
+                            struct sk_buff *skb);
 void rxrpc_accept_incoming_calls(struct rxrpc_local *);
 int rxrpc_user_charge_accept(struct rxrpc_sock *, unsigned long);
 
                             unsigned long now,
                             enum rxrpc_timer_trace why);
 
-void rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb);
+bool rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb);
 
 /*
  * call_object.c
 void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, struct sk_buff *skb,
                                unsigned int channel);
 int rxrpc_abort_conn(struct rxrpc_connection *conn, struct sk_buff *skb,
-                    s32 abort_code, int err, const char *why);
+                    s32 abort_code, int err, enum rxrpc_abort_reason why);
 void rxrpc_process_connection(struct work_struct *);
 void rxrpc_process_delayed_final_acks(struct rxrpc_connection *, bool);
-int rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb);
+bool rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb);
 void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb);
 
 static inline bool rxrpc_is_conn_aborted(const struct rxrpc_connection *conn)
  */
 int rxrpc_encap_rcv(struct sock *, struct sk_buff *);
 void rxrpc_error_report(struct sock *);
+bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
+                       s32 abort_code, int err);
 int rxrpc_io_thread(void *data);
 static inline void rxrpc_wake_up_io_thread(struct rxrpc_local *local)
 {
        wake_up_process(local->io_thread);
 }
 
+static inline bool rxrpc_protocol_error(struct sk_buff *skb, enum rxrpc_abort_reason why)
+{
+       return rxrpc_direct_abort(skb, why, RX_PROTOCOL_ERROR, -EPROTO);
+}
+
 /*
  * insecure.c
  */
 bool rxrpc_set_call_completion(struct rxrpc_call *, enum rxrpc_call_completion, u32, int);
 bool __rxrpc_call_completed(struct rxrpc_call *);
 bool rxrpc_call_completed(struct rxrpc_call *);
-bool __rxrpc_abort_call(const char *, struct rxrpc_call *, rxrpc_seq_t, u32, int);
-bool rxrpc_abort_call(const char *, struct rxrpc_call *, rxrpc_seq_t, u32, int);
+bool __rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq,
+                       u32 abort_code, int error, enum rxrpc_abort_reason why);
+bool rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq,
+                     u32 abort_code, int error, enum rxrpc_abort_reason why);
 int rxrpc_recvmsg(struct socket *, struct msghdr *, size_t, int);
 
 /*
  * Abort a call due to a protocol error.
  */
-static inline bool __rxrpc_abort_eproto(struct rxrpc_call *call,
-                                       struct sk_buff *skb,
-                                       const char *eproto_why,
-                                       const char *why,
-                                       u32 abort_code)
+static inline int rxrpc_abort_eproto(struct rxrpc_call *call,
+                                    struct sk_buff *skb,
+                                    s32 abort_code,
+                                    enum rxrpc_abort_reason why)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
 
-       trace_rxrpc_rx_eproto(call, sp->hdr.serial, eproto_why);
-       return rxrpc_abort_call(why, call, sp->hdr.seq, abort_code, -EPROTO);
+       rxrpc_abort_call(call, sp->hdr.seq, abort_code, -EPROTO, why);
+       return -EPROTO;
 }
 
-#define rxrpc_abort_eproto(call, skb, eproto_why, abort_why, abort_code) \
-       __rxrpc_abort_eproto((call), (skb), tracepoint_string(eproto_why), \
-                            (abort_why), (abort_code))
-
 /*
  * rtt.c
  */
 /*
  * sendmsg.c
  */
-bool rxrpc_propose_abort(struct rxrpc_call *call,
-                        u32 abort_code, int error, const char *why);
+bool rxrpc_propose_abort(struct rxrpc_call *call, s32 abort_code, int error,
+                        enum rxrpc_abort_reason why);
 int rxrpc_do_sendmsg(struct rxrpc_sock *, struct msghdr *, size_t);
 
 /*
 
  * If we want to report an error, we mark the skb with the packet type and
  * abort code and return false.
  */
-int rxrpc_new_incoming_call(struct rxrpc_local *local,
-                           struct rxrpc_peer *peer,
-                           struct rxrpc_connection *conn,
-                           struct sockaddr_rxrpc *peer_srx,
-                           struct sk_buff *skb)
+bool rxrpc_new_incoming_call(struct rxrpc_local *local,
+                            struct rxrpc_peer *peer,
+                            struct rxrpc_connection *conn,
+                            struct sockaddr_rxrpc *peer_srx,
+                            struct sk_buff *skb)
 {
        const struct rxrpc_security *sec = NULL;
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
 
        _enter("");
 
-       /* Don't set up a call for anything other than the first DATA packet. */
-       if (sp->hdr.seq != 1 ||
-           sp->hdr.type != RXRPC_PACKET_TYPE_DATA)
-               return 0; /* Just discard */
+       /* Don't set up a call for anything other than a DATA packet. */
+       if (sp->hdr.type != RXRPC_PACKET_TYPE_DATA)
+               return rxrpc_protocol_error(skb, rxrpc_eproto_no_service_call);
 
        rcu_read_lock();
 
        if (!conn) {
                sec = rxrpc_get_incoming_security(rx, skb);
                if (!sec)
-                       goto reject;
+                       goto unsupported_security;
        }
 
        spin_lock(&rx->incoming_lock);
        if (rx->sk.sk_state == RXRPC_SERVER_LISTEN_DISABLED ||
            rx->sk.sk_state == RXRPC_CLOSE) {
-               trace_rxrpc_abort(0, "CLS", sp->hdr.cid, sp->hdr.callNumber,
-                                 sp->hdr.seq, RX_INVALID_OPERATION, ESHUTDOWN);
-               skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
-               skb->priority = RX_INVALID_OPERATION;
+               rxrpc_direct_abort(skb, rxrpc_abort_shut_down,
+                                  RX_INVALID_OPERATION, -ESHUTDOWN);
                goto no_call;
        }
 
        _leave(" = %p{%d}", call, call->debug_id);
        rxrpc_input_call_event(call, skb);
        rxrpc_put_call(call, rxrpc_call_put_input);
-       return 0;
+       return true;
 
 unsupported_service:
-       trace_rxrpc_abort(0, "INV", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
-                         RX_INVALID_OPERATION, EOPNOTSUPP);
-       skb->priority = RX_INVALID_OPERATION;
-       goto reject;
+       rcu_read_unlock();
+       return rxrpc_direct_abort(skb, rxrpc_abort_service_not_offered,
+                                 RX_INVALID_OPERATION, -EOPNOTSUPP);
+unsupported_security:
+       rcu_read_unlock();
+       return rxrpc_direct_abort(skb, rxrpc_abort_service_not_offered,
+                                 RX_INVALID_OPERATION, -EKEYREJECTED);
 no_call:
        spin_unlock(&rx->incoming_lock);
-reject:
        rcu_read_unlock();
        _leave(" = f [%u]", skb->mark);
-       return -EPROTO;
+       return false;
 discard:
        rcu_read_unlock();
-       return 0;
+       return true;
 }
 
 /*
 
 /*
  * Handle retransmission and deferred ACK/abort generation.
  */
-void rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
+bool rxrpc_input_call_event(struct rxrpc_call *call, struct sk_buff *skb)
 {
        unsigned long now, next, t;
        rxrpc_serial_t ackr_serial;
        /* Handle abort request locklessly, vs rxrpc_propose_abort(). */
        abort_code = smp_load_acquire(&call->send_abort);
        if (abort_code) {
-               rxrpc_abort_call(call->send_abort_why, call, 0, call->send_abort,
-                                call->send_abort_err);
+               rxrpc_abort_call(call, 0, call->send_abort, call->send_abort_err,
+                                call->send_abort_why);
                goto out;
        }
 
                if (test_bit(RXRPC_CALL_RX_HEARD, &call->flags) &&
                    (int)call->conn->hi_serial - (int)call->rx_serial > 0) {
                        trace_rxrpc_call_reset(call);
-                       rxrpc_abort_call("EXP", call, 0, RX_CALL_DEAD, -ECONNRESET);
+                       rxrpc_abort_call(call, 0, RX_CALL_DEAD, -ECONNRESET,
+                                        rxrpc_abort_call_reset);
                } else {
-                       rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, -ETIME);
+                       rxrpc_abort_call(call, 0, RX_CALL_TIMEOUT, -ETIME,
+                                        rxrpc_abort_call_timeout);
                }
                goto out;
        }
        if (call->acks_hard_ack != call->tx_bottom)
                rxrpc_shrink_call_tx_buffer(call);
        _leave("");
+       return true;
 }
 
                call = list_entry(rx->to_be_accepted.next,
                                  struct rxrpc_call, accept_link);
                list_del(&call->accept_link);
-               rxrpc_propose_abort(call, RX_CALL_DEAD, -ECONNRESET, "SKR");
+               rxrpc_propose_abort(call, RX_CALL_DEAD, -ECONNRESET,
+                                   rxrpc_abort_call_sock_release_tba);
                rxrpc_put_call(call, rxrpc_call_put_release_sock_tba);
        }
 
                call = list_entry(rx->sock_calls.next,
                                  struct rxrpc_call, sock_link);
                rxrpc_get_call(call, rxrpc_call_get_release_sock);
-               rxrpc_propose_abort(call, RX_CALL_DEAD, -ECONNRESET, "SKT");
+               rxrpc_propose_abort(call, RX_CALL_DEAD, -ECONNRESET,
+                                   rxrpc_abort_call_sock_release);
                rxrpc_release_call(rx, call);
                rxrpc_put_call(call, rxrpc_call_put_release_sock);
        }
 
  * Mark a socket buffer to indicate that the connection it's on should be aborted.
  */
 int rxrpc_abort_conn(struct rxrpc_connection *conn, struct sk_buff *skb,
-                    s32 abort_code, int err, const char *why)
+                    s32 abort_code, int err, enum rxrpc_abort_reason why)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
 
                return 0;
 
        default:
-               trace_rxrpc_rx_eproto(NULL, sp->hdr.serial,
-                                     tracepoint_string("bad_conn_pkt"));
+               WARN_ON_ONCE(1);
                return -EPROTO;
        }
 }
 static void rxrpc_secure_connection(struct rxrpc_connection *conn)
 {
        if (conn->security->issue_challenge(conn) < 0)
-               rxrpc_abort_conn(conn, NULL, RX_CALL_DEAD, -ENOMEM, "OOM");
+               rxrpc_abort_conn(conn, NULL, RX_CALL_DEAD, -ENOMEM,
+                                rxrpc_abort_nomem);
 }
 
 /*
 /*
  * Input a connection-level packet.
  */
-int rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb)
+bool rxrpc_input_conn_packet(struct rxrpc_connection *conn, struct sk_buff *skb)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
 
        switch (sp->hdr.type) {
        case RXRPC_PACKET_TYPE_BUSY:
                /* Just ignore BUSY packets for now. */
-               return 0;
+               return true;
 
        case RXRPC_PACKET_TYPE_ABORT:
                if (rxrpc_is_conn_aborted(conn))
                        return true;
                }
                rxrpc_post_packet_to_conn(conn, skb);
-               return 0;
+               return true;
 
        default:
-               trace_rxrpc_rx_eproto(NULL, sp->hdr.serial,
-                                     tracepoint_string("bad_conn_pkt"));
-               return -EPROTO;
+               WARN_ON_ONCE(1);
+               return true;
        }
 }
 
 
 
 #include "ar-internal.h"
 
-static void rxrpc_proto_abort(const char *why,
-                             struct rxrpc_call *call, rxrpc_seq_t seq)
+static void rxrpc_proto_abort(struct rxrpc_call *call, rxrpc_seq_t seq,
+                             enum rxrpc_abort_reason why)
 {
-       rxrpc_abort_call(why, call, seq, RX_PROTOCOL_ERROR, -EBADMSG);
+       rxrpc_abort_call(call, seq, RX_PROTOCOL_ERROR, -EBADMSG, why);
 }
 
 /*
  * This occurs when we get an ACKALL packet, the first DATA packet of a reply,
  * or a final ACK packet.
  */
-static bool rxrpc_end_tx_phase(struct rxrpc_call *call, bool reply_begun,
-                              const char *abort_why)
+static void rxrpc_end_tx_phase(struct rxrpc_call *call, bool reply_begun,
+                              enum rxrpc_abort_reason abort_why)
 {
        unsigned int state;
 
        else
                trace_rxrpc_txqueue(call, rxrpc_txqueue_end);
        _leave(" = ok");
-       return true;
+       return;
 
 bad_state:
        write_unlock(&call->state_lock);
        kdebug("end_tx %s", rxrpc_call_states[call->state]);
-       rxrpc_proto_abort(abort_why, call, call->tx_top);
-       return false;
+       rxrpc_proto_abort(call, call->tx_top, abort_why);
 }
 
 /*
 
        if (!test_bit(RXRPC_CALL_TX_LAST, &call->flags)) {
                if (!rxrpc_rotate_tx_window(call, top, &summary)) {
-                       rxrpc_proto_abort("TXL", call, top);
+                       rxrpc_proto_abort(call, top, rxrpc_eproto_early_reply);
                        return false;
                }
        }
-       return rxrpc_end_tx_phase(call, true, "ETD");
+
+       rxrpc_end_tx_phase(call, true, rxrpc_eproto_unexpected_reply);
+       return true;
 }
 
 static void rxrpc_input_update_ack_window(struct rxrpc_call *call,
 
        if (last) {
                if (test_and_set_bit(RXRPC_CALL_RX_LAST, &call->flags) &&
-                   seq + 1 != wtop) {
-                       rxrpc_proto_abort("LSN", call, seq);
-                       return;
-               }
+                   seq + 1 != wtop)
+                       return rxrpc_proto_abort(call, seq, rxrpc_eproto_different_last);
        } else {
                if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) &&
                    after_eq(seq, wtop)) {
                        pr_warn("Packet beyond last: c=%x q=%x window=%x-%x wlimit=%x\n",
                                call->debug_id, seq, window, wtop, wlimit);
-                       rxrpc_proto_abort("LSA", call, seq);
-                       return;
+                       return rxrpc_proto_abort(call, seq, rxrpc_eproto_data_after_last);
                }
        }
 
                goto out_notify;
 
        if (!rxrpc_input_split_jumbo(call, skb)) {
-               rxrpc_proto_abort("VLD", call, sp->hdr.seq);
+               rxrpc_proto_abort(call, sp->hdr.seq, rxrpc_badmsg_bad_jumbo);
                goto out_notify;
        }
        skb = NULL;
 
        offset = sizeof(struct rxrpc_wire_header);
        if (skb_copy_bits(skb, offset, &ack, sizeof(ack)) < 0)
-               return rxrpc_proto_abort("XAK", call, 0);
+               return rxrpc_proto_abort(call, 0, rxrpc_badmsg_short_ack);
        offset += sizeof(ack);
 
        ack_serial = sp->hdr.serial;
        ioffset = offset + nr_acks + 3;
        if (skb->len >= ioffset + sizeof(info) &&
            skb_copy_bits(skb, ioffset, &info, sizeof(info)) < 0)
-               return rxrpc_proto_abort("XAI", call, 0);
+               return rxrpc_proto_abort(call, 0, rxrpc_badmsg_short_ack_info);
 
        if (nr_acks > 0)
                skb_condense(skb);
                rxrpc_input_ackinfo(call, skb, &info);
 
        if (first_soft_ack == 0)
-               return rxrpc_proto_abort("AK0", call, 0);
+               return rxrpc_proto_abort(call, 0, rxrpc_eproto_ackr_zero);
 
        /* Ignore ACKs unless we are or have just been transmitting. */
        switch (READ_ONCE(call->state)) {
 
        if (before(hard_ack, call->acks_hard_ack) ||
            after(hard_ack, call->tx_top))
-               return rxrpc_proto_abort("AKW", call, 0);
+               return rxrpc_proto_abort(call, 0, rxrpc_eproto_ackr_outside_window);
        if (nr_acks > call->tx_top - hard_ack)
-               return rxrpc_proto_abort("AKN", call, 0);
+               return rxrpc_proto_abort(call, 0, rxrpc_eproto_ackr_sack_overflow);
 
        if (after(hard_ack, call->acks_hard_ack)) {
                if (rxrpc_rotate_tx_window(call, hard_ack, &summary)) {
-                       rxrpc_end_tx_phase(call, false, "ETA");
+                       rxrpc_end_tx_phase(call, false, rxrpc_eproto_unexpected_ack);
                        return;
                }
        }
 
        if (nr_acks > 0) {
                if (offset > (int)skb->len - nr_acks)
-                       return rxrpc_proto_abort("XSA", call, 0);
+                       return rxrpc_proto_abort(call, 0, rxrpc_eproto_ackr_short_sack);
                rxrpc_input_soft_acks(call, skb->data + offset, first_soft_ack,
                                      nr_acks, &summary);
        }
        struct rxrpc_ack_summary summary = { 0 };
 
        if (rxrpc_rotate_tx_window(call, call->tx_top, &summary))
-               rxrpc_end_tx_phase(call, false, "ETL");
+               rxrpc_end_tx_phase(call, false, rxrpc_eproto_unexpected_ackall);
 }
 
 /*
 
        switch (sp->hdr.type) {
        case RXRPC_PACKET_TYPE_DATA:
-               rxrpc_input_data(call, skb);
-               break;
+               return rxrpc_input_data(call, skb);
 
        case RXRPC_PACKET_TYPE_ACK:
-               rxrpc_input_ack(call, skb);
-               break;
+               return rxrpc_input_ack(call, skb);
 
        case RXRPC_PACKET_TYPE_BUSY:
                /* Just ignore BUSY packets from the server; the retry and
                 * lifespan timers will take care of business.  BUSY packets
                 * from the client don't make sense.
                 */
-               break;
+               return;
 
        case RXRPC_PACKET_TYPE_ABORT:
-               rxrpc_input_abort(call, skb);
-               break;
+               return rxrpc_input_abort(call, skb);
 
        case RXRPC_PACKET_TYPE_ACKALL:
-               rxrpc_input_ackall(call, skb);
-               break;
+               return rxrpc_input_ackall(call, skb);
 
        default:
                break;
        case RXRPC_CALL_COMPLETE:
                break;
        default:
-               rxrpc_abort_call("IMP", call, 0, RX_CALL_DEAD, -ESHUTDOWN);
+               rxrpc_abort_call(call, 0, RX_CALL_DEAD, -ESHUTDOWN,
+                                rxrpc_eproto_improper_term);
                trace_rxrpc_improper_term(call);
                break;
        }
 
 static int none_respond_to_challenge(struct rxrpc_connection *conn,
                                     struct sk_buff *skb)
 {
-       return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO, "RXN");
+       return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO,
+                               rxrpc_eproto_rxnull_challenge);
 }
 
 static int none_verify_response(struct rxrpc_connection *conn,
                                struct sk_buff *skb)
 {
-       return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO, "RXN");
+       return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO,
+                               rxrpc_eproto_rxnull_response);
 }
 
 static void none_clear(struct rxrpc_connection *conn)
 
        rcu_read_unlock();
 }
 
+/*
+ * Directly produce an abort from a packet.
+ */
+bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
+                       s32 abort_code, int err)
+{
+       struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+
+       trace_rxrpc_abort(0, why, sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
+                         abort_code, err);
+       skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
+       skb->priority = abort_code;
+       return false;
+}
+
+static bool rxrpc_bad_message(struct sk_buff *skb, enum rxrpc_abort_reason why)
+{
+       return rxrpc_direct_abort(skb, why, RX_PROTOCOL_ERROR, -EBADMSG);
+}
+
+#define just_discard true
+
 /*
  * Process event packets targeted at a local endpoint.
  */
-static void rxrpc_input_version(struct rxrpc_local *local, struct sk_buff *skb)
+static bool rxrpc_input_version(struct rxrpc_local *local, struct sk_buff *skb)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        char v;
                if (v == 0)
                        rxrpc_send_version_request(local, &sp->hdr, skb);
        }
+
+       return true;
 }
 
 /*
  * Extract the wire header from a packet and translate the byte order.
  */
-static noinline
-int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
+static bool rxrpc_extract_header(struct rxrpc_skb_priv *sp,
+                                struct sk_buff *skb)
 {
        struct rxrpc_wire_header whdr;
 
        /* dig out the RxRPC connection details */
-       if (skb_copy_bits(skb, 0, &whdr, sizeof(whdr)) < 0) {
-               trace_rxrpc_rx_eproto(NULL, sp->hdr.serial,
-                                     tracepoint_string("bad_hdr"));
-               return -EBADMSG;
-       }
+       if (skb_copy_bits(skb, 0, &whdr, sizeof(whdr)) < 0)
+               return rxrpc_bad_message(skb, rxrpc_badmsg_short_hdr);
 
        memset(sp, 0, sizeof(*sp));
        sp->hdr.epoch           = ntohl(whdr.epoch);
        sp->hdr.securityIndex   = whdr.securityIndex;
        sp->hdr._rsvd           = ntohs(whdr._rsvd);
        sp->hdr.serviceId       = ntohs(whdr.serviceId);
-       return 0;
+       return true;
 }
 
 /*
 /*
  * Process packets received on the local endpoint
  */
-static int rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff **_skb)
+static bool rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff **_skb)
 {
        struct rxrpc_connection *conn;
        struct sockaddr_rxrpc peer_srx;
        struct rxrpc_skb_priv *sp;
        struct rxrpc_peer *peer = NULL;
        struct sk_buff *skb = *_skb;
-       int ret = 0;
+       bool ret = false;
 
        skb_pull(skb, sizeof(struct udphdr));
 
        sp = rxrpc_skb(skb);
 
        /* dig out the RxRPC connection details */
-       if (rxrpc_extract_header(sp, skb) < 0)
-               goto bad_message;
+       if (!rxrpc_extract_header(sp, skb))
+               return just_discard;
 
        if (IS_ENABLED(CONFIG_AF_RXRPC_INJECT_LOSS)) {
                static int lose;
                if ((lose++ & 7) == 7) {
                        trace_rxrpc_rx_lose(sp);
-                       return 0;
+                       return just_discard;
                }
        }
 
        switch (sp->hdr.type) {
        case RXRPC_PACKET_TYPE_VERSION:
                if (rxrpc_to_client(sp))
-                       return 0;
-               rxrpc_input_version(local, skb);
-               return 0;
+                       return just_discard;
+               return rxrpc_input_version(local, skb);
 
        case RXRPC_PACKET_TYPE_BUSY:
                if (rxrpc_to_server(sp))
-                       return 0;
+                       return just_discard;
                fallthrough;
        case RXRPC_PACKET_TYPE_ACK:
        case RXRPC_PACKET_TYPE_ACKALL:
                if (sp->hdr.callNumber == 0)
-                       goto bad_message;
+                       return rxrpc_bad_message(skb, rxrpc_badmsg_zero_call);
                break;
        case RXRPC_PACKET_TYPE_ABORT:
                if (!rxrpc_extract_abort(skb))
-                       return 0; /* Just discard if malformed */
+                       return just_discard; /* Just discard if malformed */
                break;
 
        case RXRPC_PACKET_TYPE_DATA:
-               if (sp->hdr.callNumber == 0 ||
-                   sp->hdr.seq == 0)
-                       goto bad_message;
+               if (sp->hdr.callNumber == 0)
+                       return rxrpc_bad_message(skb, rxrpc_badmsg_zero_call);
+               if (sp->hdr.seq == 0)
+                       return rxrpc_bad_message(skb, rxrpc_badmsg_zero_seq);
 
                /* Unshare the packet so that it can be modified for in-place
                 * decryption.
                        if (!skb) {
                                rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare_nomem);
                                *_skb = NULL;
-                               return 0;
+                               return just_discard;
                        }
 
                        if (skb != *_skb) {
 
        case RXRPC_PACKET_TYPE_CHALLENGE:
                if (rxrpc_to_server(sp))
-                       return 0;
+                       return just_discard;
                break;
        case RXRPC_PACKET_TYPE_RESPONSE:
                if (rxrpc_to_client(sp))
-                       return 0;
+                       return just_discard;
                break;
 
                /* Packet types 9-11 should just be ignored. */
        case RXRPC_PACKET_TYPE_PARAMS:
        case RXRPC_PACKET_TYPE_10:
        case RXRPC_PACKET_TYPE_11:
-               return 0;
+               return just_discard;
 
        default:
-               goto bad_message;
+               return rxrpc_bad_message(skb, rxrpc_badmsg_unsupported_packet);
        }
 
        if (sp->hdr.serviceId == 0)
-               goto bad_message;
+               return rxrpc_bad_message(skb, rxrpc_badmsg_zero_service);
 
        if (WARN_ON_ONCE(rxrpc_extract_addr_from_skb(&peer_srx, skb) < 0))
-               return true; /* Unsupported address type - discard. */
+               return just_discard; /* Unsupported address type. */
 
        if (peer_srx.transport.family != local->srx.transport.family &&
            (peer_srx.transport.family == AF_INET &&
                pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
                                    peer_srx.transport.family,
                                    local->srx.transport.family);
-               return true; /* Wrong address type - discard. */
+               return just_discard; /* Wrong address type. */
        }
 
        if (rxrpc_to_client(sp)) {
                conn = rxrpc_find_client_connection_rcu(local, &peer_srx, skb);
                conn = rxrpc_get_connection_maybe(conn, rxrpc_conn_get_call_input);
                rcu_read_unlock();
-               if (!conn) {
-                       trace_rxrpc_abort(0, "NCC", sp->hdr.cid,
-                                         sp->hdr.callNumber, sp->hdr.seq,
-                                         RXKADINCONSISTENCY, EBADMSG);
-                       goto protocol_error;
-               }
+               if (!conn)
+                       return rxrpc_protocol_error(skb, rxrpc_eproto_no_client_conn);
 
                ret = rxrpc_input_packet_on_conn(conn, &peer_srx, skb);
                rxrpc_put_connection(conn, rxrpc_conn_put_call_input);
 
        ret = rxrpc_new_incoming_call(local, peer, NULL, &peer_srx, skb);
        rxrpc_put_peer(peer, rxrpc_peer_put_input);
-       if (ret < 0)
-               goto reject_packet;
-       return 0;
-
-bad_message:
-       trace_rxrpc_abort(0, "BAD", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
-                         RX_PROTOCOL_ERROR, EBADMSG);
-protocol_error:
-       skb->priority = RX_PROTOCOL_ERROR;
-       skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
-reject_packet:
-       rxrpc_reject_packet(local, skb);
-       return 0;
+       return ret;
 }
 
 /*
        struct rxrpc_channel *chan;
        struct rxrpc_call *call = NULL;
        unsigned int channel;
+       bool ret;
 
        if (sp->hdr.securityIndex != conn->security_ix)
-               goto wrong_security;
+               return rxrpc_direct_abort(skb, rxrpc_eproto_wrong_security,
+                                         RXKADINCONSISTENCY, -EBADMSG);
 
        if (sp->hdr.serviceId != conn->service_id) {
                int old_id;
 
                if (!test_bit(RXRPC_CONN_PROBING_FOR_UPGRADE, &conn->flags))
-                       goto reupgrade;
+                       return rxrpc_protocol_error(skb, rxrpc_eproto_reupgrade);
+
                old_id = cmpxchg(&conn->service_id, conn->orig_service_id,
                                 sp->hdr.serviceId);
-
                if (old_id != conn->orig_service_id &&
                    old_id != sp->hdr.serviceId)
-                       goto reupgrade;
+                       return rxrpc_protocol_error(skb, rxrpc_eproto_bad_upgrade);
        }
 
        if (after(sp->hdr.serial, conn->hi_serial))
 
        /* Ignore really old calls */
        if (sp->hdr.callNumber < chan->last_call)
-               return 0;
+               return just_discard;
 
        if (sp->hdr.callNumber == chan->last_call) {
                if (chan->call ||
                    sp->hdr.type == RXRPC_PACKET_TYPE_ABORT)
-                       return 0;
+                       return just_discard;
 
                /* For the previous service call, if completed successfully, we
                 * discard all further packets.
                 */
                if (rxrpc_conn_is_service(conn) &&
                    chan->last_type == RXRPC_PACKET_TYPE_ACK)
-                       return 0;
+                       return just_discard;
 
                /* But otherwise we need to retransmit the final packet from
                 * data cached in the connection record.
                                            sp->hdr.serial,
                                            sp->hdr.flags);
                rxrpc_conn_retransmit_call(conn, skb, channel);
-               return 0;
+               return just_discard;
        }
 
        rcu_read_lock();
        if (sp->hdr.callNumber > chan->call_id) {
                if (rxrpc_to_client(sp)) {
                        rxrpc_put_call(call, rxrpc_call_put_input);
-                       goto reject_packet;
+                       return rxrpc_protocol_error(skb,
+                                                   rxrpc_eproto_unexpected_implicit_end);
                }
 
                if (call) {
 
        if (!call) {
                if (rxrpc_to_client(sp))
-                       goto bad_message;
-               if (rxrpc_new_incoming_call(conn->local, conn->peer, conn,
-                                           peer_srx, skb) == 0)
-                       return 0;
-               goto reject_packet;
+                       return rxrpc_protocol_error(skb, rxrpc_eproto_no_client_call);
+               return rxrpc_new_incoming_call(conn->local, conn->peer, conn,
+                                              peer_srx, skb);
        }
 
-       rxrpc_input_call_event(call, skb);
+       ret = rxrpc_input_call_event(call, skb);
        rxrpc_put_call(call, rxrpc_call_put_input);
-       return 0;
-
-wrong_security:
-       trace_rxrpc_abort(0, "SEC", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
-                         RXKADINCONSISTENCY, EBADMSG);
-       skb->priority = RXKADINCONSISTENCY;
-       goto post_abort;
-
-reupgrade:
-       trace_rxrpc_abort(0, "UPG", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
-                         RX_PROTOCOL_ERROR, EBADMSG);
-       goto protocol_error;
-
-bad_message:
-       trace_rxrpc_abort(0, "BAD", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
-                         RX_PROTOCOL_ERROR, EBADMSG);
-protocol_error:
-       skb->priority = RX_PROTOCOL_ERROR;
-post_abort:
-       skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
-reject_packet:
-       rxrpc_reject_packet(conn->local, skb);
-       return 0;
+       return ret;
 }
 
 /*
                        switch (skb->mark) {
                        case RXRPC_SKB_MARK_PACKET:
                                skb->priority = 0;
-                               rxrpc_input_packet(local, &skb);
+                               if (!rxrpc_input_packet(local, &skb))
+                                       rxrpc_reject_packet(local, skb);
                                trace_rxrpc_rx_done(skb->mark, skb->priority);
                                rxrpc_free_skb(skb, rxrpc_skb_put_input);
                                break;
 
 /*
  * Record that a call is locally aborted.
  */
-bool __rxrpc_abort_call(const char *why, struct rxrpc_call *call,
-                       rxrpc_seq_t seq, u32 abort_code, int error)
+bool __rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq,
+                       u32 abort_code, int error, enum rxrpc_abort_reason why)
 {
        trace_rxrpc_abort(call->debug_id, why, call->cid, call->call_id, seq,
                          abort_code, error);
                                           abort_code, error);
 }
 
-bool rxrpc_abort_call(const char *why, struct rxrpc_call *call,
-                     rxrpc_seq_t seq, u32 abort_code, int error)
+bool rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq,
+                     u32 abort_code, int error, enum rxrpc_abort_reason why)
 {
        bool ret;
 
        write_lock(&call->state_lock);
-       ret = __rxrpc_abort_call(why, call, seq, abort_code, error);
+       ret = __rxrpc_abort_call(call, seq, abort_code, error, why);
        write_unlock(&call->state_lock);
        if (ret && test_bit(RXRPC_CALL_EXPOSED, &call->flags))
                rxrpc_send_abort_packet(call);
        return ret;
 
 short_data:
-       trace_rxrpc_rx_eproto(call, 0, tracepoint_string("short_data"));
+       trace_rxrpc_abort(call->debug_id, rxrpc_recvmsg_short_data,
+                         call->cid, call->call_id, call->rx_consumed,
+                         0, -EBADMSG);
        ret = -EBADMSG;
        goto out;
 excess_data:
-       trace_rxrpc_rx_eproto(call, 0, tracepoint_string("excess_data"));
+       trace_rxrpc_abort(call->debug_id, rxrpc_recvmsg_excess_data,
+                         call->cid, call->call_id, call->rx_consumed,
+                         0, -EMSGSIZE);
        ret = -EMSGSIZE;
        goto out;
 call_complete:
 
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        struct rxrpc_crypt iv;
        struct scatterlist sg[16];
-       bool aborted;
        u32 data_size, buf;
        u16 check;
        int ret;
 
        _enter("");
 
-       if (sp->len < 8) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_hdr", "V1H",
-                                            RXKADSEALEDINCON);
-               goto protocol_error;
-       }
+       if (sp->len < 8)
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_1_short_header);
 
        /* Decrypt the skbuff in-place.  TODO: We really want to decrypt
         * directly into the target buffer.
        skcipher_request_zero(req);
 
        /* Extract the decrypted packet length */
-       if (skb_copy_bits(skb, sp->offset, &sechdr, sizeof(sechdr)) < 0) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_len", "XV1",
-                                            RXKADDATALEN);
-               goto protocol_error;
-       }
+       if (skb_copy_bits(skb, sp->offset, &sechdr, sizeof(sechdr)) < 0)
+               return rxrpc_abort_eproto(call, skb, RXKADDATALEN,
+                                         rxkad_abort_1_short_encdata);
        sp->offset += sizeof(sechdr);
        sp->len    -= sizeof(sechdr);
 
        check = buf >> 16;
        check ^= seq ^ call->call_id;
        check &= 0xffff;
-       if (check != 0) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_check", "V1C",
-                                            RXKADSEALEDINCON);
-               goto protocol_error;
-       }
-
-       if (data_size > sp->len) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_datalen", "V1L",
-                                            RXKADDATALEN);
-               goto protocol_error;
-       }
+       if (check != 0)
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_1_short_check);
+       if (data_size > sp->len)
+               return rxrpc_abort_eproto(call, skb, RXKADDATALEN,
+                                         rxkad_abort_1_short_data);
        sp->len = data_size;
 
        _leave(" = 0 [dlen=%x]", data_size);
        return 0;
-
-protocol_error:
-       if (aborted)
-               rxrpc_send_abort_packet(call);
-       return -EPROTO;
 }
 
 /*
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        struct rxrpc_crypt iv;
        struct scatterlist _sg[4], *sg;
-       bool aborted;
        u32 data_size, buf;
        u16 check;
        int nsg, ret;
 
        _enter(",{%d}", sp->len);
 
-       if (sp->len < 8) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_hdr", "V2H",
-                                            RXKADSEALEDINCON);
-               goto protocol_error;
-       }
+       if (sp->len < 8)
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_2_short_header);
 
        /* Decrypt the skbuff in-place.  TODO: We really want to decrypt
         * directly into the target buffer.
        } else {
                sg = kmalloc_array(nsg, sizeof(*sg), GFP_NOIO);
                if (!sg)
-                       goto nomem;
+                       return -ENOMEM;
        }
 
        sg_init_table(sg, nsg);
                kfree(sg);
 
        /* Extract the decrypted packet length */
-       if (skb_copy_bits(skb, sp->offset, &sechdr, sizeof(sechdr)) < 0) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_len", "XV2",
-                                            RXKADDATALEN);
-               goto protocol_error;
-       }
+       if (skb_copy_bits(skb, sp->offset, &sechdr, sizeof(sechdr)) < 0)
+               return rxrpc_abort_eproto(call, skb, RXKADDATALEN,
+                                         rxkad_abort_2_short_len);
        sp->offset += sizeof(sechdr);
        sp->len    -= sizeof(sechdr);
 
        check = buf >> 16;
        check ^= seq ^ call->call_id;
        check &= 0xffff;
-       if (check != 0) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_check", "V2C",
-                                            RXKADSEALEDINCON);
-               goto protocol_error;
-       }
+       if (check != 0)
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_2_short_check);
 
-       if (data_size > sp->len) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_datalen", "V2L",
-                                            RXKADDATALEN);
-               goto protocol_error;
-       }
+       if (data_size > sp->len)
+               return rxrpc_abort_eproto(call, skb, RXKADDATALEN,
+                                         rxkad_abort_2_short_data);
 
        sp->len = data_size;
        _leave(" = 0 [dlen=%x]", data_size);
        return 0;
-
-protocol_error:
-       if (aborted)
-               rxrpc_send_abort_packet(call);
-       return -EPROTO;
-
-nomem:
-       _leave(" = -ENOMEM");
-       return -ENOMEM;
 }
 
 /*
                __be32 buf[2];
        } crypto __aligned(8);
        rxrpc_seq_t seq = sp->hdr.seq;
-       bool aborted;
        int ret;
        u16 cksum;
        u32 x, y;
                cksum = 1; /* zero checksums are not permitted */
 
        if (cksum != sp->hdr.cksum) {
-               aborted = rxrpc_abort_eproto(call, skb, "rxkad_csum", "VCK",
-                                            RXKADSEALEDINCON);
-               goto protocol_error;
+               ret = rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                        rxkad_abort_bad_checksum);
+               goto out;
        }
 
        switch (call->conn->security_level) {
                break;
        }
 
+out:
        skcipher_request_free(req);
        return ret;
-
-protocol_error:
-       if (aborted)
-               rxrpc_send_abort_packet(call);
-       return -EPROTO;
 }
 
 /*
        struct rxkad_challenge challenge;
        struct rxkad_response *resp;
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
-       const char *eproto;
-       u32 version, nonce, min_level, abort_code;
-       int ret;
+       u32 version, nonce, min_level;
+       int ret = -EPROTO;
 
        _enter("{%d,%x}", conn->debug_id, key_serial(conn->key));
 
-       eproto = tracepoint_string("chall_no_key");
-       abort_code = RX_PROTOCOL_ERROR;
        if (!conn->key)
-               goto protocol_error;
+               return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO,
+                                       rxkad_abort_chall_no_key);
 
-       abort_code = RXKADEXPIRED;
        ret = key_validate(conn->key);
        if (ret < 0)
-               goto other_error;
+               return rxrpc_abort_conn(conn, skb, RXKADEXPIRED, ret,
+                                       rxkad_abort_chall_key_expired);
 
-       eproto = tracepoint_string("chall_short");
-       abort_code = RXKADPACKETSHORT;
        if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
                          &challenge, sizeof(challenge)) < 0)
-               goto protocol_error;
+               return rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+                                       rxkad_abort_chall_short);
 
        version = ntohl(challenge.version);
        nonce = ntohl(challenge.nonce);
 
        trace_rxrpc_rx_challenge(conn, sp->hdr.serial, version, nonce, min_level);
 
-       eproto = tracepoint_string("chall_ver");
-       abort_code = RXKADINCONSISTENCY;
        if (version != RXKAD_VERSION)
-               goto protocol_error;
+               return rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, -EPROTO,
+                                       rxkad_abort_chall_version);
 
-       abort_code = RXKADLEVELFAIL;
-       ret = -EACCES;
        if (conn->security_level < min_level)
-               goto other_error;
+               return rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, -EACCES,
+                                       rxkad_abort_chall_level);
 
        token = conn->key->payload.data[0];
 
                ret = rxkad_send_response(conn, &sp->hdr, resp, token->kad);
        kfree(resp);
        return ret;
-
-protocol_error:
-       trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
-       ret = -EPROTO;
-other_error:
-       rxrpc_abort_conn(conn, skb, abort_code, ret, "RXK");
-       return ret;
 }
 
 /*
                                time64_t *_expiry)
 {
        struct skcipher_request *req;
-       struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        struct rxrpc_crypt iv, key;
        struct scatterlist sg[1];
        struct in_addr addr;
        unsigned int life;
-       const char *eproto;
        time64_t issue, now;
        bool little_endian;
-       int ret;
-       u32 abort_code;
        u8 *p, *q, *name, *end;
 
        _enter("{%d},{%x}", conn->debug_id, key_serial(server_key));
 
        memcpy(&iv, &server_key->payload.data[2], sizeof(iv));
 
-       ret = -ENOMEM;
        req = skcipher_request_alloc(server_key->payload.data[0], GFP_NOFS);
        if (!req)
-               goto temporary_error;
+               return -ENOMEM;
 
        sg_init_one(&sg[0], ticket, ticket_len);
        skcipher_request_set_callback(req, 0, NULL, NULL);
        p = ticket;
        end = p + ticket_len;
 
-#define Z(field)                                       \
-       ({                                              \
-               u8 *__str = p;                          \
-               eproto = tracepoint_string("rxkad_bad_"#field); \
-               q = memchr(p, 0, end - p);              \
-               if (!q || q - p > (field##_SZ))         \
-                       goto bad_ticket;                \
-               for (; p < q; p++)                      \
-                       if (!isprint(*p))               \
-                               goto bad_ticket;        \
-               p++;                                    \
-               __str;                                  \
+#define Z(field, fieldl)                                               \
+       ({                                                              \
+               u8 *__str = p;                                          \
+               q = memchr(p, 0, end - p);                              \
+               if (!q || q - p > field##_SZ)                           \
+                       return rxrpc_abort_conn(                        \
+                               conn, skb, RXKADBADTICKET, -EPROTO,     \
+                               rxkad_abort_resp_tkt_##fieldl);         \
+               for (; p < q; p++)                                      \
+                       if (!isprint(*p))                               \
+                               return rxrpc_abort_conn(                \
+                                       conn, skb, RXKADBADTICKET, -EPROTO, \
+                                       rxkad_abort_resp_tkt_##fieldl); \
+               p++;                                                    \
+               __str;                                                  \
        })
 
        /* extract the ticket flags */
        p++;
 
        /* extract the authentication name */
-       name = Z(ANAME);
+       name = Z(ANAME, aname);
        _debug("KIV ANAME: %s", name);
 
        /* extract the principal's instance */
-       name = Z(INST);
+       name = Z(INST, inst);
        _debug("KIV INST : %s", name);
 
        /* extract the principal's authentication domain */
-       name = Z(REALM);
+       name = Z(REALM, realm);
        _debug("KIV REALM: %s", name);
 
-       eproto = tracepoint_string("rxkad_bad_len");
        if (end - p < 4 + 8 + 4 + 2)
-               goto bad_ticket;
+               return rxrpc_abort_conn(conn, skb, RXKADBADTICKET, -EPROTO,
+                                       rxkad_abort_resp_tkt_short);
 
        /* get the IPv4 address of the entity that requested the ticket */
        memcpy(&addr, p, sizeof(addr));
        _debug("KIV ISSUE: %llx [%llx]", issue, now);
 
        /* check the ticket is in date */
-       if (issue > now) {
-               abort_code = RXKADNOAUTH;
-               ret = -EKEYREJECTED;
-               goto other_error;
-       }
-
-       if (issue < now - life) {
-               abort_code = RXKADEXPIRED;
-               ret = -EKEYEXPIRED;
-               goto other_error;
-       }
+       if (issue > now)
+               return rxrpc_abort_conn(conn, skb, RXKADNOAUTH, -EKEYREJECTED,
+                                       rxkad_abort_resp_tkt_future);
+       if (issue < now - life)
+               return rxrpc_abort_conn(conn, skb, RXKADEXPIRED, -EKEYEXPIRED,
+                                       rxkad_abort_resp_tkt_expired);
 
        *_expiry = issue + life;
 
        /* get the service name */
-       name = Z(SNAME);
+       name = Z(SNAME, sname);
        _debug("KIV SNAME: %s", name);
 
        /* get the service instance name */
-       name = Z(INST);
+       name = Z(INST, sinst);
        _debug("KIV SINST: %s", name);
        return 0;
-
-bad_ticket:
-       trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
-       abort_code = RXKADBADTICKET;
-       ret = -EPROTO;
-other_error:
-       return rxrpc_abort_conn(conn, skb, abort_code, ret, "RXK");
-temporary_error:
-       return ret;
 }
 
 /*
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        struct rxrpc_crypt session_key;
        struct key *server_key;
-       const char *eproto;
        time64_t expiry;
        void *ticket;
-       u32 abort_code, version, kvno, ticket_len, level;
+       u32 version, kvno, ticket_len, level;
        __be32 csum;
        int ret, i;
 
 
        server_key = rxrpc_look_up_server_security(conn, skb, 0, 0);
        if (IS_ERR(server_key)) {
-               switch (PTR_ERR(server_key)) {
+               ret = PTR_ERR(server_key);
+               switch (ret) {
                case -ENOKEY:
-                       abort_code = RXKADUNKNOWNKEY;
-                       break;
+                       return rxrpc_abort_conn(conn, skb, RXKADUNKNOWNKEY, ret,
+                                               rxkad_abort_resp_nokey);
                case -EKEYEXPIRED:
-                       abort_code = RXKADEXPIRED;
-                       break;
+                       return rxrpc_abort_conn(conn, skb, RXKADEXPIRED, ret,
+                                               rxkad_abort_resp_key_expired);
                default:
-                       abort_code = RXKADNOAUTH;
-                       break;
+                       return rxrpc_abort_conn(conn, skb, RXKADNOAUTH, ret,
+                                               rxkad_abort_resp_key_rejected);
                }
-               return rxrpc_abort_conn(conn, skb, abort_code,
-                                       PTR_ERR(server_key), "RXK");
        }
 
        ret = -ENOMEM;
        if (!response)
                goto temporary_error;
 
-       eproto = tracepoint_string("rxkad_rsp_short");
-       abort_code = RXKADPACKETSHORT;
        if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
-                         response, sizeof(*response)) < 0)
+                         response, sizeof(*response)) < 0) {
+               rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+                                rxkad_abort_resp_short);
                goto protocol_error;
+       }
 
        version = ntohl(response->version);
        ticket_len = ntohl(response->ticket_len);
 
        trace_rxrpc_rx_response(conn, sp->hdr.serial, version, kvno, ticket_len);
 
-       eproto = tracepoint_string("rxkad_rsp_ver");
-       abort_code = RXKADINCONSISTENCY;
-       if (version != RXKAD_VERSION)
+       if (version != RXKAD_VERSION) {
+               rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, -EPROTO,
+                                rxkad_abort_resp_version);
                goto protocol_error;
+       }
 
-       eproto = tracepoint_string("rxkad_rsp_tktlen");
-       abort_code = RXKADTICKETLEN;
-       if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN)
+       if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN) {
+               rxrpc_abort_conn(conn, skb, RXKADTICKETLEN, -EPROTO,
+                                rxkad_abort_resp_tkt_len);
                goto protocol_error;
+       }
 
-       eproto = tracepoint_string("rxkad_rsp_unkkey");
-       abort_code = RXKADUNKNOWNKEY;
-       if (kvno >= RXKAD_TKT_TYPE_KERBEROS_V5)
+       if (kvno >= RXKAD_TKT_TYPE_KERBEROS_V5) {
+               rxrpc_abort_conn(conn, skb, RXKADUNKNOWNKEY, -EPROTO,
+                                rxkad_abort_resp_unknown_tkt);
                goto protocol_error;
+       }
 
        /* extract the kerberos ticket and decrypt and decode it */
        ret = -ENOMEM;
        if (!ticket)
                goto temporary_error_free_resp;
 
-       eproto = tracepoint_string("rxkad_tkt_short");
-       abort_code = RXKADPACKETSHORT;
-       ret = skb_copy_bits(skb, sizeof(struct rxrpc_wire_header) + sizeof(*response),
-                           ticket, ticket_len);
-       if (ret < 0)
-               goto temporary_error_free_ticket;
+       if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header) + sizeof(*response),
+                         ticket, ticket_len) < 0) {
+               rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+                                rxkad_abort_resp_short_tkt);
+               goto protocol_error;
+       }
 
        ret = rxkad_decrypt_ticket(conn, server_key, skb, ticket, ticket_len,
                                   &session_key, &expiry);
         * response */
        rxkad_decrypt_response(conn, response, &session_key);
 
-       eproto = tracepoint_string("rxkad_rsp_param");
-       abort_code = RXKADSEALEDINCON;
-       if (ntohl(response->encrypted.epoch) != conn->proto.epoch)
-               goto protocol_error_free;
-       if (ntohl(response->encrypted.cid) != conn->proto.cid)
-               goto protocol_error_free;
-       if (ntohl(response->encrypted.securityIndex) != conn->security_ix)
+       if (ntohl(response->encrypted.epoch) != conn->proto.epoch ||
+           ntohl(response->encrypted.cid) != conn->proto.cid ||
+           ntohl(response->encrypted.securityIndex) != conn->security_ix) {
+               rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+                                rxkad_abort_resp_bad_param);
                goto protocol_error_free;
+       }
+
        csum = response->encrypted.checksum;
        response->encrypted.checksum = 0;
        rxkad_calc_response_checksum(response);
-       eproto = tracepoint_string("rxkad_rsp_csum");
-       if (response->encrypted.checksum != csum)
+       if (response->encrypted.checksum != csum) {
+               rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+                                rxkad_abort_resp_bad_checksum);
                goto protocol_error_free;
+       }
 
        spin_lock(&conn->bundle->channel_lock);
        for (i = 0; i < RXRPC_MAXCALLS; i++) {
                struct rxrpc_call *call;
                u32 call_id = ntohl(response->encrypted.call_id[i]);
 
-               eproto = tracepoint_string("rxkad_rsp_callid");
-               if (call_id > INT_MAX)
+               if (call_id > INT_MAX) {
+                       rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+                                        rxkad_abort_resp_bad_callid);
                        goto protocol_error_unlock;
+               }
 
-               eproto = tracepoint_string("rxkad_rsp_callctr");
-               if (call_id < conn->channels[i].call_counter)
+               if (call_id < conn->channels[i].call_counter) {
+                       rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+                                        rxkad_abort_resp_call_ctr);
                        goto protocol_error_unlock;
+               }
 
-               eproto = tracepoint_string("rxkad_rsp_callst");
                if (call_id > conn->channels[i].call_counter) {
                        call = rcu_dereference_protected(
                                conn->channels[i].call,
                                lockdep_is_held(&conn->bundle->channel_lock));
-                       if (call && call->state < RXRPC_CALL_COMPLETE)
+                       if (call && call->state < RXRPC_CALL_COMPLETE) {
+                               rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+                                                rxkad_abort_resp_call_state);
                                goto protocol_error_unlock;
+                       }
                        conn->channels[i].call_counter = call_id;
                }
        }
        spin_unlock(&conn->bundle->channel_lock);
 
-       eproto = tracepoint_string("rxkad_rsp_seq");
-       abort_code = RXKADOUTOFSEQUENCE;
-       if (ntohl(response->encrypted.inc_nonce) != conn->rxkad.nonce + 1)
+       if (ntohl(response->encrypted.inc_nonce) != conn->rxkad.nonce + 1) {
+               rxrpc_abort_conn(conn, skb, RXKADOUTOFSEQUENCE, -EPROTO,
+                                rxkad_abort_resp_ooseq);
                goto protocol_error_free;
+       }
 
-       eproto = tracepoint_string("rxkad_rsp_level");
-       abort_code = RXKADLEVELFAIL;
        level = ntohl(response->encrypted.level);
-       if (level > RXRPC_SECURITY_ENCRYPT)
+       if (level > RXRPC_SECURITY_ENCRYPT) {
+               rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, -EPROTO,
+                                rxkad_abort_resp_level);
                goto protocol_error_free;
+       }
        conn->security_level = level;
 
        /* create a key to hold the security data and expiration time - after
 protocol_error:
        kfree(response);
        key_put(server_key);
-       trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
-       return rxrpc_abort_conn(conn, skb, abort_code, -EPROTO, "RXK");
+       return -EPROTO;
 
 temporary_error_free_ticket:
        kfree(ticket);
 
 #include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
+#define RXRPC_TRACE_ONLY_DEFINE_ENUMS
+#include <trace/events/rxrpc.h>
 
 MODULE_DESCRIPTION("rxperf test server (afs)");
 MODULE_AUTHOR("Red Hat, Inc.");
                case -EOPNOTSUPP:
                        abort_code = RXGEN_OPCODE;
                        rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
-                                               abort_code, ret, "GOP");
+                                               abort_code, ret,
+                                               rxperf_abort_op_not_supported);
                        goto call_complete;
                case -ENOTSUPP:
                        abort_code = RX_USER_ABORT;
                        rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
-                                               abort_code, ret, "GUA");
+                                               abort_code, ret,
+                                               rxperf_abort_op_not_supported);
                        goto call_complete;
                case -EIO:
                        pr_err("Call %u in bad state %u\n",
                case -ENOMEM:
                case -EFAULT:
                        rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
-                                               RXGEN_SS_UNMARSHAL, ret, "GUM");
+                                               RXGEN_SS_UNMARSHAL, ret,
+                                               rxperf_abort_unmarshal_error);
                        goto call_complete;
                default:
                        rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
-                                               RX_CALL_DEAD, ret, "GER");
+                                               RX_CALL_DEAD, ret,
+                                               rxperf_abort_general_error);
                        goto call_complete;
                }
        }
 
        if (n == -ENOMEM)
                rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
-                                       RXGEN_SS_MARSHAL, -ENOMEM, "GOM");
+                                       RXGEN_SS_MARSHAL, -ENOMEM,
+                                       rxperf_abort_oom);
        return n;
 }
 
 
 
        sec = rxrpc_security_lookup(sp->hdr.securityIndex);
        if (!sec) {
-               trace_rxrpc_abort(0, "SVS",
-                                 sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
-                                 RX_INVALID_OPERATION, EKEYREJECTED);
-               skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
-               skb->priority = RX_INVALID_OPERATION;
+               rxrpc_direct_abort(skb, rxrpc_abort_unsupported_security,
+                                  RX_INVALID_OPERATION, -EKEYREJECTED);
                return NULL;
        }
 
        if (sp->hdr.securityIndex != RXRPC_SECURITY_NONE &&
            !rx->securities) {
-               trace_rxrpc_abort(0, "SVR",
-                                 sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
-                                 RX_INVALID_OPERATION, EKEYREJECTED);
-               skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
-               skb->priority = sec->no_key_abort;
+               rxrpc_direct_abort(skb, rxrpc_abort_no_service_key,
+                                  sec->no_key_abort, -EKEYREJECTED);
                return NULL;
        }
 
 
 /*
  * Propose an abort to be made in the I/O thread.
  */
-bool rxrpc_propose_abort(struct rxrpc_call *call,
-                        u32 abort_code, int error, const char *why)
+bool rxrpc_propose_abort(struct rxrpc_call *call, s32 abort_code, int error,
+                        enum rxrpc_abort_reason why)
 {
-       _enter("{%d},%d,%d,%s", call->debug_id, abort_code, error, why);
+       _enter("{%d},%d,%d,%u", call->debug_id, abort_code, error, why);
 
        if (!call->send_abort && call->state < RXRPC_CALL_COMPLETE) {
                call->send_abort_why = why;
                call->send_abort_err = error;
+               call->send_abort_seq = 0;
                /* Request abort locklessly vs rxrpc_input_call_event(). */
                smp_store_release(&call->send_abort, abort_code);
                rxrpc_poke_call(call, rxrpc_call_poke_abort);
                /* it's too late for this call */
                ret = -ESHUTDOWN;
        } else if (p.command == RXRPC_CMD_SEND_ABORT) {
-               rxrpc_propose_abort(call, p.abort_code, -ECONNABORTED, "CMD");
+               rxrpc_propose_abort(call, p.abort_code, -ECONNABORTED,
+                                   rxrpc_abort_call_sendmsg);
                ret = 0;
        } else if (p.command != RXRPC_CMD_SEND_DATA) {
                ret = -EINVAL;
                break;
        default:
                /* Request phase complete for this client call */
-               trace_rxrpc_rx_eproto(call, 0, tracepoint_string("late_send"));
+               trace_rxrpc_abort(call->debug_id, rxrpc_sendmsg_late_send,
+                                 call->cid, call->call_id, call->rx_consumed,
+                                 0, -EPROTO);
                ret = -EPROTO;
                break;
        }
  * @call: The call to be aborted
  * @abort_code: The abort code to stick into the ABORT packet
  * @error: Local error value
- * @why: 3-char string indicating why.
+ * @why: Indication as to why.
  *
  * Allow a kernel service to abort a call, if it's still in an abortable state
  * and return true if the call was aborted, false if it was already complete.
  */
 bool rxrpc_kernel_abort_call(struct socket *sock, struct rxrpc_call *call,
-                            u32 abort_code, int error, const char *why)
+                            u32 abort_code, int error, enum rxrpc_abort_reason why)
 {
        bool aborted;
 
-       _enter("{%d},%d,%d,%s", call->debug_id, abort_code, error, why);
+       _enter("{%d},%d,%d,%u", call->debug_id, abort_code, error, why);
 
        mutex_lock(&call->user_mutex);
        aborted = rxrpc_propose_abort(call, abort_code, error, why);