]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'rprpc-2nd-rewrite-part-1'
authorDavid S. Miller <davem@davemloft.net>
Mon, 11 Apr 2016 19:34:42 +0000 (15:34 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 11 Apr 2016 19:34:42 +0000 (15:34 -0400)
David Howells says:

====================
RxRPC: 2nd rewrite part 1

Okay, I'm in the process of rewriting the RxRPC rewrite.  The primary aim of
this second rewrite is to strictly control the number of active connections we
know about and to get rid of connections we don't need much more quickly.

On top of this, there are fixes to the protocol handling which will all occur
in later parts.

Here's the first set of patches from the second go, aimed at net-next.  These
are all fixes and cleanups preparatory to the main event.

Notable parts of this set include:

 (1) A fix for the AFS filesystem to wait for outstanding calls to complete
     before closing the RxRPC socket.

 (2) Differentiation of local and remote abort codes.  At a future point
     userspace will get to see this via control message data on recvmsg().

 (3) Absorb the rxkad module into the af_rxrpc module to prevent a dependency
     loop.

 (4) Create a null security module and unconditionalise calls into the
     security module that's in force (there will always be a security module
     applied to a connection, even if it's just the null one).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
20 files changed:
fs/afs/rxrpc.c
include/net/af_rxrpc.h
include/rxrpc/packet.h
net/rxrpc/Kconfig
net/rxrpc/Makefile
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-accept.c
net/rxrpc/ar-ack.c
net/rxrpc/ar-call.c
net/rxrpc/ar-connection.c
net/rxrpc/ar-connevent.c
net/rxrpc/ar-input.c
net/rxrpc/ar-internal.h
net/rxrpc/ar-output.c
net/rxrpc/ar-proc.c
net/rxrpc/ar-recvmsg.c
net/rxrpc/ar-security.c
net/rxrpc/insecure.c [new file with mode: 0644]
net/rxrpc/misc.c [new file with mode: 0644]
net/rxrpc/rxkad.c

index b50642870a43b9675a3b1fe97b1cfadcdbb1c54a..63cd9f939f19965b3b2f049b444b9bbba97528f9 100644 (file)
@@ -65,6 +65,12 @@ static void afs_async_workfn(struct work_struct *work)
        call->async_workfn(call);
 }
 
+static int afs_wait_atomic_t(atomic_t *p)
+{
+       schedule();
+       return 0;
+}
+
 /*
  * open an RxRPC socket and bind it to be a server for callback notifications
  * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT
@@ -126,13 +132,16 @@ void afs_close_socket(void)
 {
        _enter("");
 
+       wait_on_atomic_t(&afs_outstanding_calls, afs_wait_atomic_t,
+                        TASK_UNINTERRUPTIBLE);
+       _debug("no outstanding calls");
+
        sock_release(afs_socket);
 
        _debug("dework");
        destroy_workqueue(afs_async_calls);
 
        ASSERTCMP(atomic_read(&afs_outstanding_skbs), ==, 0);
-       ASSERTCMP(atomic_read(&afs_outstanding_calls), ==, 0);
        _leave("");
 }
 
@@ -178,8 +187,6 @@ static void afs_free_call(struct afs_call *call)
 {
        _debug("DONE %p{%s} [%d]",
               call, call->type->name, atomic_read(&afs_outstanding_calls));
-       if (atomic_dec_return(&afs_outstanding_calls) == -1)
-               BUG();
 
        ASSERTCMP(call->rxcall, ==, NULL);
        ASSERT(!work_pending(&call->async_work));
@@ -188,6 +195,9 @@ static void afs_free_call(struct afs_call *call)
 
        kfree(call->request);
        kfree(call);
+
+       if (atomic_dec_and_test(&afs_outstanding_calls))
+               wake_up_atomic_t(&afs_outstanding_calls);
 }
 
 /*
@@ -420,9 +430,11 @@ error_kill_call:
 }
 
 /*
- * handles intercepted messages that were arriving in the socket's Rx queue
- * - called with the socket receive queue lock held to ensure message ordering
- * - called with softirqs disabled
+ * Handles intercepted messages that were arriving in the socket's Rx queue.
+ *
+ * Called from the AF_RXRPC call processor in waitqueue process context.  For
+ * each call, it is guaranteed this will be called in order of packet to be
+ * delivered.
  */
 static void afs_rx_interceptor(struct sock *sk, unsigned long user_call_ID,
                               struct sk_buff *skb)
@@ -513,6 +525,12 @@ static void afs_deliver_to_call(struct afs_call *call)
                        call->state = AFS_CALL_ABORTED;
                        _debug("Rcv ABORT %u -> %d", abort_code, call->error);
                        break;
+               case RXRPC_SKB_MARK_LOCAL_ABORT:
+                       abort_code = rxrpc_kernel_get_abort_code(skb);
+                       call->error = call->type->abort_to_error(abort_code);
+                       call->state = AFS_CALL_ABORTED;
+                       _debug("Loc ABORT %u -> %d", abort_code, call->error);
+                       break;
                case RXRPC_SKB_MARK_NET_ERROR:
                        call->error = -rxrpc_kernel_get_error_number(skb);
                        call->state = AFS_CALL_ERROR;
index e797d45a5ae62697361e1ca827a7638542cc4f41..ac1bc3c49fbdf9832fdb4f895657c0336bb61926 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _NET_RXRPC_H
 #define _NET_RXRPC_H
 
+#include <linux/skbuff.h>
 #include <linux/rxrpc.h>
 
 struct rxrpc_call;
@@ -19,11 +20,12 @@ struct rxrpc_call;
 /*
  * the mark applied to socket buffers that may be intercepted
  */
-enum {
+enum rxrpc_skb_mark {
        RXRPC_SKB_MARK_DATA,            /* data message */
        RXRPC_SKB_MARK_FINAL_ACK,       /* final ACK received message */
        RXRPC_SKB_MARK_BUSY,            /* server busy message */
        RXRPC_SKB_MARK_REMOTE_ABORT,    /* remote abort message */
+       RXRPC_SKB_MARK_LOCAL_ABORT,     /* local abort message */
        RXRPC_SKB_MARK_NET_ERROR,       /* network error message */
        RXRPC_SKB_MARK_LOCAL_ERROR,     /* local error message */
        RXRPC_SKB_MARK_NEW_CALL,        /* local error message */
index 9ebab3a8cf0aa2f566fda02a9b3e4e42561ca42c..b2017440b7654ab37045fabad95b076d539d95d0 100644 (file)
@@ -68,8 +68,6 @@ struct rxrpc_wire_header {
 
 } __packed;
 
-extern const char *rxrpc_pkts[];
-
 #define RXRPC_SUPPORTED_PACKET_TYPES (                 \
                (1 << RXRPC_PACKET_TYPE_DATA) |         \
                (1 << RXRPC_PACKET_TYPE_ACK) |          \
index 23dcef12b986dcd5774147b5ed215ff2fa62cb50..784c53163b7b045ac8c98c60da8e227886a40d85 100644 (file)
@@ -30,7 +30,7 @@ config AF_RXRPC_DEBUG
 
 
 config RXKAD
-       tristate "RxRPC Kerberos security"
+       bool "RxRPC Kerberos security"
        depends on AF_RXRPC
        select CRYPTO
        select CRYPTO_MANAGER
index ec126f91276b349c7fe8e181ad4ce7aec24f0c67..e05a06ef2254248519616b06dd9dac6c6bf2a2fb 100644 (file)
@@ -18,11 +18,12 @@ af-rxrpc-y := \
        ar-recvmsg.o \
        ar-security.o \
        ar-skbuff.o \
-       ar-transport.o
+       ar-transport.o \
+       insecure.o \
+       misc.o
 
 af-rxrpc-$(CONFIG_PROC_FS) += ar-proc.o
+af-rxrpc-$(CONFIG_RXKAD) += rxkad.o
 af-rxrpc-$(CONFIG_SYSCTL) += sysctl.o
 
 obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o
-
-obj-$(CONFIG_RXKAD) += rxkad.o
index 9d935fa5a2a98884beca08329433cf66dbafebdc..e45e94ca030f3b1e3a6881d3178b021b4ce670ad 100644 (file)
@@ -806,6 +806,12 @@ static int __init af_rxrpc_init(void)
                goto error_work_queue;
        }
 
+       ret = rxrpc_init_security();
+       if (ret < 0) {
+               printk(KERN_CRIT "RxRPC: Cannot initialise security\n");
+               goto error_security;
+       }
+
        ret = proto_register(&rxrpc_proto, 1);
        if (ret < 0) {
                printk(KERN_CRIT "RxRPC: Cannot register protocol\n");
@@ -853,6 +859,8 @@ error_sock:
        proto_unregister(&rxrpc_proto);
 error_proto:
        destroy_workqueue(rxrpc_workqueue);
+error_security:
+       rxrpc_exit_security();
 error_work_queue:
        kmem_cache_destroy(rxrpc_call_jar);
 error_call_jar:
@@ -883,6 +891,7 @@ static void __exit af_rxrpc_exit(void)
        remove_proc_entry("rxrpc_conns", init_net.proc_net);
        remove_proc_entry("rxrpc_calls", init_net.proc_net);
        destroy_workqueue(rxrpc_workqueue);
+       rxrpc_exit_security();
        kmem_cache_destroy(rxrpc_call_jar);
        _leave("");
 }
index 277731a5e67a523988673d5f7dccfc8de6ac47a8..e7a7f05f13e2b0b39d921cf312e9a6aeb6599571 100644 (file)
@@ -108,7 +108,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
                goto error;
        }
 
-       conn = rxrpc_incoming_connection(trans, &sp->hdr, GFP_NOIO);
+       conn = rxrpc_incoming_connection(trans, &sp->hdr);
        rxrpc_put_transport(trans);
        if (IS_ERR(conn)) {
                _debug("no conn");
@@ -116,7 +116,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
                goto error;
        }
 
-       call = rxrpc_incoming_call(rx, conn, &sp->hdr, GFP_NOIO);
+       call = rxrpc_incoming_call(rx, conn, &sp->hdr);
        rxrpc_put_connection(conn);
        if (IS_ERR(call)) {
                _debug("no call");
index 16d967075eaf8f1c4cc15ea0ac926cd97277d2d8..374478e006e7c806a82b9dd907907f39e1d4cd5c 100644 (file)
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
 
-/*
- * How long to wait before scheduling ACK generation after seeing a
- * packet with RXRPC_REQUEST_ACK set (in jiffies).
- */
-unsigned int rxrpc_requested_ack_delay = 1;
-
-/*
- * How long to wait before scheduling an ACK with subtype DELAY (in jiffies).
- *
- * We use this when we've received new data packets.  If those packets aren't
- * all consumed within this time we will send a DELAY ACK if an ACK was not
- * requested to let the sender know it doesn't need to resend.
- */
-unsigned int rxrpc_soft_ack_delay = 1 * HZ;
-
-/*
- * How long to wait before scheduling an ACK with subtype IDLE (in jiffies).
- *
- * We use this when we've consumed some previously soft-ACK'd packets when
- * further packets aren't immediately received to decide when to send an IDLE
- * ACK let the other end know that it can free up its Tx buffer space.
- */
-unsigned int rxrpc_idle_ack_delay = 0.5 * HZ;
-
-/*
- * Receive window size in packets.  This indicates the maximum number of
- * unconsumed received packets we're willing to retain in memory.  Once this
- * limit is hit, we should generate an EXCEEDS_WINDOW ACK and discard further
- * packets.
- */
-unsigned int rxrpc_rx_window_size = 32;
-
-/*
- * Maximum Rx MTU size.  This indicates to the sender the size of jumbo packet
- * made by gluing normal packets together that we're willing to handle.
- */
-unsigned int rxrpc_rx_mtu = 5692;
-
-/*
- * The maximum number of fragments in a received jumbo packet that we tell the
- * sender that we're willing to handle.
- */
-unsigned int rxrpc_rx_jumbo_max = 4;
-
-static const char *rxrpc_acks(u8 reason)
-{
-       static const char *const str[] = {
-               "---", "REQ", "DUP", "OOS", "WIN", "MEM", "PNG", "PNR", "DLY",
-               "IDL", "-?-"
-       };
-
-       if (reason >= ARRAY_SIZE(str))
-               reason = ARRAY_SIZE(str) - 1;
-       return str[reason];
-}
-
-static const s8 rxrpc_ack_priority[] = {
-       [0]                             = 0,
-       [RXRPC_ACK_DELAY]               = 1,
-       [RXRPC_ACK_REQUESTED]           = 2,
-       [RXRPC_ACK_IDLE]                = 3,
-       [RXRPC_ACK_PING_RESPONSE]       = 4,
-       [RXRPC_ACK_DUPLICATE]           = 5,
-       [RXRPC_ACK_OUT_OF_SEQUENCE]     = 6,
-       [RXRPC_ACK_EXCEEDS_WINDOW]      = 7,
-       [RXRPC_ACK_NOSPACE]             = 8,
-};
-
 /*
  * propose an ACK be sent
  */
@@ -426,7 +358,7 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, u32 hard)
        int tail = call->acks_tail, old_tail;
        int win = CIRC_CNT(call->acks_head, tail, call->acks_winsz);
 
-       kenter("{%u,%u},%u", call->acks_hard, win, hard);
+       _enter("{%u,%u},%u", call->acks_hard, win, hard);
 
        ASSERTCMP(hard - call->acks_hard, <=, win);
 
@@ -656,7 +588,8 @@ process_further:
                _proto("OOSQ DATA %%%u { #%u }", sp->hdr.serial, sp->hdr.seq);
 
                /* secured packets must be verified and possibly decrypted */
-               if (rxrpc_verify_packet(call, skb, _abort_code) < 0)
+               if (call->conn->security->verify_packet(call, skb,
+                                                       _abort_code) < 0)
                        goto protocol_error;
 
                rxrpc_insert_oos_packet(call, skb);
@@ -901,8 +834,8 @@ void rxrpc_process_call(struct work_struct *work)
 
        /* there's a good chance we're going to have to send a message, so set
         * one up in advance */
-       msg.msg_name    = &call->conn->trans->peer->srx.transport.sin;
-       msg.msg_namelen = sizeof(call->conn->trans->peer->srx.transport.sin);
+       msg.msg_name    = &call->conn->trans->peer->srx.transport;
+       msg.msg_namelen = call->conn->trans->peer->srx.transport_len;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
        msg.msg_flags   = 0;
@@ -973,7 +906,7 @@ void rxrpc_process_call(struct work_struct *work)
                                       ECONNABORTED, true) < 0)
                        goto no_mem;
                whdr.type = RXRPC_PACKET_TYPE_ABORT;
-               data = htonl(call->abort_code);
+               data = htonl(call->local_abort);
                iov[1].iov_base = &data;
                iov[1].iov_len = sizeof(data);
                genbit = RXRPC_CALL_EV_ABORT;
@@ -1036,7 +969,7 @@ void rxrpc_process_call(struct work_struct *work)
                write_lock_bh(&call->state_lock);
                if (call->state <= RXRPC_CALL_COMPLETE) {
                        call->state = RXRPC_CALL_LOCALLY_ABORTED;
-                       call->abort_code = RX_CALL_TIMEOUT;
+                       call->local_abort = RX_CALL_TIMEOUT;
                        set_bit(RXRPC_CALL_EV_ABORT, &call->events);
                }
                write_unlock_bh(&call->state_lock);
index 7c8d300ade9bb32079b716b4fced72dce51f585b..571a41fd5a324705a30e78304833b39c8c501380 100644 (file)
@@ -411,18 +411,17 @@ found_extant_second:
  */
 struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
                                       struct rxrpc_connection *conn,
-                                      struct rxrpc_host_header *hdr,
-                                      gfp_t gfp)
+                                      struct rxrpc_host_header *hdr)
 {
        struct rxrpc_call *call, *candidate;
        struct rb_node **p, *parent;
        u32 call_id;
 
-       _enter(",%d,,%x", conn->debug_id, gfp);
+       _enter(",%d", conn->debug_id);
 
        ASSERT(rx != NULL);
 
-       candidate = rxrpc_alloc_call(gfp);
+       candidate = rxrpc_alloc_call(GFP_NOIO);
        if (!candidate)
                return ERR_PTR(-EBUSY);
 
@@ -682,7 +681,7 @@ void rxrpc_release_call(struct rxrpc_call *call)
            call->state != RXRPC_CALL_CLIENT_FINAL_ACK) {
                _debug("+++ ABORTING STATE %d +++\n", call->state);
                call->state = RXRPC_CALL_LOCALLY_ABORTED;
-               call->abort_code = RX_CALL_DEAD;
+               call->local_abort = RX_CALL_DEAD;
                set_bit(RXRPC_CALL_EV_ABORT, &call->events);
                rxrpc_queue_call(call);
        }
@@ -758,7 +757,7 @@ static void rxrpc_mark_call_released(struct rxrpc_call *call)
                if (call->state < RXRPC_CALL_COMPLETE) {
                        _debug("abort call %p", call);
                        call->state = RXRPC_CALL_LOCALLY_ABORTED;
-                       call->abort_code = RX_CALL_DEAD;
+                       call->local_abort = RX_CALL_DEAD;
                        if (!test_and_set_bit(RXRPC_CALL_EV_ABORT, &call->events))
                                sched = true;
                }
index 9942da1edbf6c00a4f5acee07de7c0c92069f121..97f4fae74bcab5c2305801d85dca51a3295e3663 100644 (file)
@@ -207,6 +207,7 @@ static struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
                INIT_LIST_HEAD(&conn->bundle_link);
                conn->calls = RB_ROOT;
                skb_queue_head_init(&conn->rx_queue);
+               conn->security = &rxrpc_no_security;
                rwlock_init(&conn->lock);
                spin_lock_init(&conn->state_lock);
                atomic_set(&conn->usage, 1);
@@ -564,8 +565,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
                     candidate->debug_id, candidate->trans->debug_id);
 
                rxrpc_assign_connection_id(candidate);
-               if (candidate->security)
-                       candidate->security->prime_packet_security(candidate);
+               candidate->security->prime_packet_security(candidate);
 
                /* leave the candidate lurking in zombie mode attached to the
                 * bundle until we're ready for it */
@@ -619,8 +619,7 @@ interrupted:
  */
 struct rxrpc_connection *
 rxrpc_incoming_connection(struct rxrpc_transport *trans,
-                         struct rxrpc_host_header *hdr,
-                         gfp_t gfp)
+                         struct rxrpc_host_header *hdr)
 {
        struct rxrpc_connection *conn, *candidate = NULL;
        struct rb_node *p, **pp;
@@ -659,7 +658,7 @@ rxrpc_incoming_connection(struct rxrpc_transport *trans,
 
        /* not yet present - create a candidate for a new record and then
         * redo the search */
-       candidate = rxrpc_alloc_connection(gfp);
+       candidate = rxrpc_alloc_connection(GFP_NOIO);
        if (!candidate) {
                _leave(" = -ENOMEM");
                return ERR_PTR(-ENOMEM);
@@ -831,7 +830,10 @@ static void rxrpc_destroy_connection(struct rxrpc_connection *conn)
        ASSERT(RB_EMPTY_ROOT(&conn->calls));
        rxrpc_purge_queue(&conn->rx_queue);
 
-       rxrpc_clear_conn_security(conn);
+       conn->security->clear(conn);
+       key_put(conn->key);
+       key_put(conn->server_key);
+
        rxrpc_put_transport(conn->trans);
        kfree(conn);
        _leave("");
index 1bdaaed8cdc456c419a9da5ce95412d1853ef06c..5f9563968a5b498e837bef9baf2921867a8073da 100644 (file)
@@ -40,11 +40,13 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn, int state,
                write_lock(&call->state_lock);
                if (call->state <= RXRPC_CALL_COMPLETE) {
                        call->state = state;
-                       call->abort_code = abort_code;
-                       if (state == RXRPC_CALL_LOCALLY_ABORTED)
+                       if (state == RXRPC_CALL_LOCALLY_ABORTED) {
+                               call->local_abort = conn->local_abort;
                                set_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events);
-                       else
+                       } else {
+                               call->remote_abort = conn->remote_abort;
                                set_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events);
+                       }
                        rxrpc_queue_call(call);
                }
                write_unlock(&call->state_lock);
@@ -84,8 +86,8 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
 
        rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED, abort_code);
 
-       msg.msg_name    = &conn->trans->peer->srx.transport.sin;
-       msg.msg_namelen = sizeof(conn->trans->peer->srx.transport.sin);
+       msg.msg_name    = &conn->trans->peer->srx.transport;
+       msg.msg_namelen = conn->trans->peer->srx.transport_len;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
        msg.msg_flags   = 0;
@@ -101,7 +103,7 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
        whdr._rsvd      = 0;
        whdr.serviceId  = htons(conn->service_id);
 
-       word = htonl(abort_code);
+       word            = htonl(conn->local_abort);
 
        iov[0].iov_base = &whdr;
        iov[0].iov_len  = sizeof(whdr);
@@ -112,7 +114,7 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
 
        serial = atomic_inc_return(&conn->serial);
        whdr.serial = htonl(serial);
-       _proto("Tx CONN ABORT %%%u { %d }", serial, abort_code);
+       _proto("Tx CONN ABORT %%%u { %d }", serial, conn->local_abort);
 
        ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 2, len);
        if (ret < 0) {
@@ -172,15 +174,10 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
                return -ECONNABORTED;
 
        case RXRPC_PACKET_TYPE_CHALLENGE:
-               if (conn->security)
-                       return conn->security->respond_to_challenge(
-                               conn, skb, _abort_code);
-               return -EPROTO;
+               return conn->security->respond_to_challenge(conn, skb,
+                                                           _abort_code);
 
        case RXRPC_PACKET_TYPE_RESPONSE:
-               if (!conn->security)
-                       return -EPROTO;
-
                ret = conn->security->verify_response(conn, skb, _abort_code);
                if (ret < 0)
                        return ret;
@@ -236,8 +233,6 @@ static void rxrpc_secure_connection(struct rxrpc_connection *conn)
                }
        }
 
-       ASSERT(conn->security != NULL);
-
        if (conn->security->issue_challenge(conn) < 0) {
                abort_code = RX_CALL_DEAD;
                ret = -ENOMEM;
index 4824a827d10d68e0c73a27b8b3a202eb7be8fcd8..01e038146b7ca863e9eacf714067eee365425844 100644 (file)
 #include <net/net_namespace.h>
 #include "ar-internal.h"
 
-const char *rxrpc_pkts[] = {
-       "?00",
-       "DATA", "ACK", "BUSY", "ABORT", "ACKALL", "CHALL", "RESP", "DEBUG",
-       "?09", "?10", "?11", "?12", "VERSION", "?14", "?15"
-};
-
 /*
  * queue a packet for recvmsg to pass to userspace
  * - the caller must hold a lock on call->lock
@@ -199,7 +193,7 @@ static int rxrpc_fast_process_data(struct rxrpc_call *call,
 
        /* if the packet need security things doing to it, then it goes down
         * the slow path */
-       if (call->conn->security)
+       if (call->conn->security_ix)
                goto enqueue_packet;
 
        sp->call = call;
@@ -355,7 +349,7 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
                write_lock_bh(&call->state_lock);
                if (call->state < RXRPC_CALL_COMPLETE) {
                        call->state = RXRPC_CALL_REMOTELY_ABORTED;
-                       call->abort_code = abort_code;
+                       call->remote_abort = abort_code;
                        set_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events);
                        rxrpc_queue_call(call);
                }
@@ -428,7 +422,7 @@ protocol_error:
 protocol_error_locked:
        if (call->state <= RXRPC_CALL_COMPLETE) {
                call->state = RXRPC_CALL_LOCALLY_ABORTED;
-               call->abort_code = RX_PROTOCOL_ERROR;
+               call->local_abort = RX_PROTOCOL_ERROR;
                set_bit(RXRPC_CALL_EV_ABORT, &call->events);
                rxrpc_queue_call(call);
        }
@@ -500,7 +494,7 @@ protocol_error:
        write_lock_bh(&call->state_lock);
        if (call->state <= RXRPC_CALL_COMPLETE) {
                call->state = RXRPC_CALL_LOCALLY_ABORTED;
-               call->abort_code = RX_PROTOCOL_ERROR;
+               call->local_abort = RX_PROTOCOL_ERROR;
                set_bit(RXRPC_CALL_EV_ABORT, &call->events);
                rxrpc_queue_call(call);
        }
index cd6cdbe87125a827186b85cbd8286dea9d8aab3e..f0b807a163fa3d7d10cc4ddb7fd66c0129a7ca44 100644 (file)
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <net/sock.h>
 #include <rxrpc/packet.h>
 
 #if 0
@@ -124,11 +125,15 @@ enum rxrpc_command {
  * RxRPC security module interface
  */
 struct rxrpc_security {
-       struct module           *owner;         /* providing module */
-       struct list_head        link;           /* link in master list */
        const char              *name;          /* name of this service */
        u8                      security_index; /* security type provided */
 
+       /* Initialise a security service */
+       int (*init)(void);
+
+       /* Clean up a security service */
+       void (*exit)(void);
+
        /* initialise a connection's security */
        int (*init_connection_security)(struct rxrpc_connection *);
 
@@ -268,7 +273,7 @@ struct rxrpc_connection {
        struct rb_root          calls;          /* calls on this connection */
        struct sk_buff_head     rx_queue;       /* received conn-level packets */
        struct rxrpc_call       *channels[RXRPC_MAXCALLS]; /* channels (active calls) */
-       struct rxrpc_security   *security;      /* applied security module */
+       const struct rxrpc_security *security;  /* applied security module */
        struct key              *key;           /* security for this connection (client) */
        struct key              *server_key;    /* security for this service */
        struct crypto_skcipher  *cipher;        /* encryption handle */
@@ -289,7 +294,9 @@ struct rxrpc_connection {
                RXRPC_CONN_LOCALLY_ABORTED,     /* - conn aborted locally */
                RXRPC_CONN_NETWORK_ERROR,       /* - conn terminated by network error */
        } state;
-       int                     error;          /* error code for local abort */
+       u32                     local_abort;    /* local abort code */
+       u32                     remote_abort;   /* remote abort code */
+       int                     error;          /* local error incurred */
        int                     debug_id;       /* debug ID for printks */
        unsigned int            call_counter;   /* call ID counter */
        atomic_t                serial;         /* packet serial number counter */
@@ -399,7 +406,9 @@ struct rxrpc_call {
        rwlock_t                state_lock;     /* lock for state transition */
        atomic_t                usage;
        atomic_t                sequence;       /* Tx data packet sequence counter */
-       u32                     abort_code;     /* local/remote abort code */
+       u32                     local_abort;    /* local abort code */
+       u32                     remote_abort;   /* remote abort code */
+       int                     error;          /* local error incurred */
        enum rxrpc_call_state   state : 8;      /* current state of call */
        int                     debug_id;       /* debug ID for printks */
        u8                      channel;        /* connection channel occupied by this call */
@@ -453,7 +462,7 @@ static inline void rxrpc_abort_call(struct rxrpc_call *call, u32 abort_code)
 {
        write_lock_bh(&call->state_lock);
        if (call->state < RXRPC_CALL_COMPLETE) {
-               call->abort_code = abort_code;
+               call->local_abort = abort_code;
                call->state = RXRPC_CALL_LOCALLY_ABORTED;
                set_bit(RXRPC_CALL_EV_ABORT, &call->events);
        }
@@ -478,13 +487,6 @@ int rxrpc_reject_call(struct rxrpc_sock *);
 /*
  * ar-ack.c
  */
-extern unsigned int rxrpc_requested_ack_delay;
-extern unsigned int rxrpc_soft_ack_delay;
-extern unsigned int rxrpc_idle_ack_delay;
-extern unsigned int rxrpc_rx_window_size;
-extern unsigned int rxrpc_rx_mtu;
-extern unsigned int rxrpc_rx_jumbo_max;
-
 void __rxrpc_propose_ACK(struct rxrpc_call *, u8, u32, bool);
 void rxrpc_propose_ACK(struct rxrpc_call *, u8, u32, bool);
 void rxrpc_process_call(struct work_struct *);
@@ -506,7 +508,7 @@ struct rxrpc_call *rxrpc_get_client_call(struct rxrpc_sock *,
                                         unsigned long, int, gfp_t);
 struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *,
                                       struct rxrpc_connection *,
-                                      struct rxrpc_host_header *, gfp_t);
+                                      struct rxrpc_host_header *);
 struct rxrpc_call *rxrpc_find_server_call(struct rxrpc_sock *, unsigned long);
 void rxrpc_release_call(struct rxrpc_call *);
 void rxrpc_release_calls_on_socket(struct rxrpc_sock *);
@@ -531,8 +533,7 @@ void __exit rxrpc_destroy_all_connections(void);
 struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *,
                                               struct rxrpc_host_header *);
 extern struct rxrpc_connection *
-rxrpc_incoming_connection(struct rxrpc_transport *, struct rxrpc_host_header *,
-                         gfp_t);
+rxrpc_incoming_connection(struct rxrpc_transport *, struct rxrpc_host_header *);
 
 /*
  * ar-connevent.c
@@ -550,8 +551,6 @@ void rxrpc_UDP_error_handler(struct work_struct *);
 /*
  * ar-input.c
  */
-extern const char *rxrpc_pkts[];
-
 void rxrpc_data_ready(struct sock *);
 int rxrpc_queue_rcv_skb(struct rxrpc_call *, struct sk_buff *, bool, bool);
 void rxrpc_fast_process_packet(struct rxrpc_call *, struct sk_buff *);
@@ -610,14 +609,10 @@ int rxrpc_recvmsg(struct socket *, struct msghdr *, size_t, int);
 /*
  * ar-security.c
  */
-int rxrpc_register_security(struct rxrpc_security *);
-void rxrpc_unregister_security(struct rxrpc_security *);
+int __init rxrpc_init_security(void);
+void rxrpc_exit_security(void);
 int rxrpc_init_client_conn_security(struct rxrpc_connection *);
 int rxrpc_init_server_conn_security(struct rxrpc_connection *);
-int rxrpc_secure_packet(const struct rxrpc_call *, struct sk_buff *, size_t,
-                       void *);
-int rxrpc_verify_packet(const struct rxrpc_call *, struct sk_buff *, u32 *);
-void rxrpc_clear_conn_security(struct rxrpc_connection *);
 
 /*
  * ar-skbuff.c
@@ -636,6 +631,33 @@ void __exit rxrpc_destroy_all_transports(void);
 struct rxrpc_transport *rxrpc_find_transport(struct rxrpc_local *,
                                             struct rxrpc_peer *);
 
+/*
+ * insecure.c
+ */
+extern const struct rxrpc_security rxrpc_no_security;
+
+/*
+ * misc.c
+ */
+extern unsigned int rxrpc_requested_ack_delay;
+extern unsigned int rxrpc_soft_ack_delay;
+extern unsigned int rxrpc_idle_ack_delay;
+extern unsigned int rxrpc_rx_window_size;
+extern unsigned int rxrpc_rx_mtu;
+extern unsigned int rxrpc_rx_jumbo_max;
+
+extern const char *const rxrpc_pkts[];
+extern const s8 rxrpc_ack_priority[];
+
+extern const char *rxrpc_acks(u8 reason);
+
+/*
+ * rxkad.c
+ */
+#ifdef CONFIG_RXKAD
+extern const struct rxrpc_security rxkad;
+#endif
+
 /*
  * sysctl.c
  */
index d36fb6e1a29ca64a7db3ecb1686738150bd8b50c..51cb10062a8dd2ad877e57a5ba49cc8ea1da0159 100644 (file)
@@ -110,7 +110,7 @@ static void rxrpc_send_abort(struct rxrpc_call *call, u32 abort_code)
 
        if (call->state <= RXRPC_CALL_COMPLETE) {
                call->state = RXRPC_CALL_LOCALLY_ABORTED;
-               call->abort_code = abort_code;
+               call->local_abort = abort_code;
                set_bit(RXRPC_CALL_EV_ABORT, &call->events);
                del_timer_sync(&call->resend_timer);
                del_timer_sync(&call->ack_timer);
@@ -663,7 +663,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
                        size_t pad;
 
                        /* pad out if we're using security */
-                       if (conn->security) {
+                       if (conn->security_ix) {
                                pad = conn->security_size + skb->mark;
                                pad = conn->size_align - pad;
                                pad &= conn->size_align - 1;
@@ -695,7 +695,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
                        if (more && seq & 1)
                                sp->hdr.flags |= RXRPC_REQUEST_ACK;
 
-                       ret = rxrpc_secure_packet(
+                       ret = conn->security->secure_packet(
                                call, skb, skb->mark,
                                skb->head + sizeof(struct rxrpc_wire_header));
                        if (ret < 0)
index 525b2ba5a8f4095105d27833dbb948cd26c75b7b..225163bc658d518d7fc8ca0276e84fc9ddd8b3d9 100644 (file)
@@ -80,7 +80,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
                   call->conn->in_clientflag ? "Svc" : "Clt",
                   atomic_read(&call->usage),
                   rxrpc_call_states[call->state],
-                  call->abort_code,
+                  call->remote_abort ?: call->local_abort,
                   call->user_call_ID);
 
        return 0;
index 64facba24a4507b97f7612497a2f18aa6ff19466..160f0927aa3e8921ec030a0b2733cab71c2961be 100644 (file)
@@ -288,7 +288,11 @@ receive_non_data_message:
                ret = put_cmsg(msg, SOL_RXRPC, RXRPC_BUSY, 0, &abort_code);
                break;
        case RXRPC_SKB_MARK_REMOTE_ABORT:
-               abort_code = call->abort_code;
+               abort_code = call->remote_abort;
+               ret = put_cmsg(msg, SOL_RXRPC, RXRPC_ABORT, 4, &abort_code);
+               break;
+       case RXRPC_SKB_MARK_LOCAL_ABORT:
+               abort_code = call->local_abort;
                ret = put_cmsg(msg, SOL_RXRPC, RXRPC_ABORT, 4, &abort_code);
                break;
        case RXRPC_SKB_MARK_NET_ERROR:
@@ -303,6 +307,7 @@ receive_non_data_message:
                               &abort_code);
                break;
        default:
+               pr_err("RxRPC: Unknown packet mark %u\n", skb->mark);
                BUG();
                break;
        }
@@ -401,9 +406,14 @@ u32 rxrpc_kernel_get_abort_code(struct sk_buff *skb)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
 
-       ASSERTCMP(skb->mark, ==, RXRPC_SKB_MARK_REMOTE_ABORT);
-
-       return sp->call->abort_code;
+       switch (skb->mark) {
+       case RXRPC_SKB_MARK_REMOTE_ABORT:
+               return sp->call->remote_abort;
+       case RXRPC_SKB_MARK_LOCAL_ABORT:
+               return sp->call->local_abort;
+       default:
+               BUG();
+       }
 }
 
 EXPORT_SYMBOL(rxrpc_kernel_get_abort_code);
index ceff6394a65f62e118f56aa599ccafb82dfa6cad..d223253b22fa05f5aa61e4b375b608e7bb6af3e4 100644 (file)
 static LIST_HEAD(rxrpc_security_methods);
 static DECLARE_RWSEM(rxrpc_security_sem);
 
-/*
- * get an RxRPC security module
- */
-static struct rxrpc_security *rxrpc_security_get(struct rxrpc_security *sec)
-{
-       return try_module_get(sec->owner) ? sec : NULL;
-}
-
-/*
- * release an RxRPC security module
- */
-static void rxrpc_security_put(struct rxrpc_security *sec)
+static const struct rxrpc_security *rxrpc_security_types[] = {
+       [RXRPC_SECURITY_NONE]   = &rxrpc_no_security,
+#ifdef CONFIG_RXKAD
+       [RXRPC_SECURITY_RXKAD]  = &rxkad,
+#endif
+};
+
+int __init rxrpc_init_security(void)
 {
-       module_put(sec->owner);
-}
-
-/*
- * look up an rxrpc security module
- */
-static struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
-{
-       struct rxrpc_security *sec = NULL;
-
-       _enter("");
+       int i, ret;
 
-       down_read(&rxrpc_security_sem);
-
-       list_for_each_entry(sec, &rxrpc_security_methods, link) {
-               if (sec->security_index == security_index) {
-                       if (unlikely(!rxrpc_security_get(sec)))
-                               break;
-                       goto out;
+       for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) {
+               if (rxrpc_security_types[i]) {
+                       ret = rxrpc_security_types[i]->init();
+                       if (ret < 0)
+                               goto failed;
                }
        }
 
-       sec = NULL;
-out:
-       up_read(&rxrpc_security_sem);
-       _leave(" = %p [%s]", sec, sec ? sec->name : "");
-       return sec;
+       return 0;
+
+failed:
+       for (i--; i >= 0; i--)
+               if (rxrpc_security_types[i])
+                       rxrpc_security_types[i]->exit();
+       return ret;
 }
 
-/**
- * rxrpc_register_security - register an RxRPC security handler
- * @sec: security module
- *
- * register an RxRPC security handler for use by RxRPC
- */
-int rxrpc_register_security(struct rxrpc_security *sec)
+void rxrpc_exit_security(void)
 {
-       struct rxrpc_security *psec;
-       int ret;
+       int i;
 
-       _enter("");
-       down_write(&rxrpc_security_sem);
-
-       ret = -EEXIST;
-       list_for_each_entry(psec, &rxrpc_security_methods, link) {
-               if (psec->security_index == sec->security_index)
-                       goto out;
-       }
-
-       list_add(&sec->link, &rxrpc_security_methods);
-
-       printk(KERN_NOTICE "RxRPC: Registered security type %d '%s'\n",
-              sec->security_index, sec->name);
-       ret = 0;
-
-out:
-       up_write(&rxrpc_security_sem);
-       _leave(" = %d", ret);
-       return ret;
+       for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++)
+               if (rxrpc_security_types[i])
+                       rxrpc_security_types[i]->exit();
 }
 
-EXPORT_SYMBOL_GPL(rxrpc_register_security);
-
-/**
- * rxrpc_unregister_security - unregister an RxRPC security handler
- * @sec: security module
- *
- * unregister an RxRPC security handler
+/*
+ * look up an rxrpc security module
  */
-void rxrpc_unregister_security(struct rxrpc_security *sec)
+static const struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
 {
-
-       _enter("");
-       down_write(&rxrpc_security_sem);
-       list_del_init(&sec->link);
-       up_write(&rxrpc_security_sem);
-
-       printk(KERN_NOTICE "RxRPC: Unregistered security type %d '%s'\n",
-              sec->security_index, sec->name);
+       if (security_index >= ARRAY_SIZE(rxrpc_security_types))
+               return NULL;
+       return rxrpc_security_types[security_index];
 }
 
-EXPORT_SYMBOL_GPL(rxrpc_unregister_security);
-
 /*
  * initialise the security on a client connection
  */
 int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
 {
+       const struct rxrpc_security *sec;
        struct rxrpc_key_token *token;
-       struct rxrpc_security *sec;
        struct key *key = conn->key;
        int ret;
 
@@ -148,8 +99,7 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
 
        ret = conn->security->init_connection_security(conn);
        if (ret < 0) {
-               rxrpc_security_put(conn->security);
-               conn->security = NULL;
+               conn->security = &rxrpc_no_security;
                return ret;
        }
 
@@ -162,7 +112,7 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
  */
 int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
 {
-       struct rxrpc_security *sec;
+       const struct rxrpc_security *sec;
        struct rxrpc_local *local = conn->trans->local;
        struct rxrpc_sock *rx;
        struct key *key;
@@ -188,14 +138,12 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
 
        /* the service appears to have died */
        read_unlock_bh(&local->services_lock);
-       rxrpc_security_put(sec);
        _leave(" = -ENOENT");
        return -ENOENT;
 
 found_service:
        if (!rx->securities) {
                read_unlock_bh(&local->services_lock);
-               rxrpc_security_put(sec);
                _leave(" = -ENOKEY");
                return -ENOKEY;
        }
@@ -205,7 +153,6 @@ found_service:
                              &key_type_rxrpc_s, kdesc);
        if (IS_ERR(kref)) {
                read_unlock_bh(&local->services_lock);
-               rxrpc_security_put(sec);
                _leave(" = %ld [search]", PTR_ERR(kref));
                return PTR_ERR(kref);
        }
@@ -219,46 +166,3 @@ found_service:
        _leave(" = 0");
        return 0;
 }
-
-/*
- * secure a packet prior to transmission
- */
-int rxrpc_secure_packet(const struct rxrpc_call *call,
-                       struct sk_buff *skb,
-                       size_t data_size,
-                       void *sechdr)
-{
-       if (call->conn->security)
-               return call->conn->security->secure_packet(
-                       call, skb, data_size, sechdr);
-       return 0;
-}
-
-/*
- * secure a packet prior to transmission
- */
-int rxrpc_verify_packet(const struct rxrpc_call *call, struct sk_buff *skb,
-                       u32 *_abort_code)
-{
-       if (call->conn->security)
-               return call->conn->security->verify_packet(
-                       call, skb, _abort_code);
-       return 0;
-}
-
-/*
- * clear connection security
- */
-void rxrpc_clear_conn_security(struct rxrpc_connection *conn)
-{
-       _enter("{%d}", conn->debug_id);
-
-       if (conn->security) {
-               conn->security->clear(conn);
-               rxrpc_security_put(conn->security);
-               conn->security = NULL;
-       }
-
-       key_put(conn->key);
-       key_put(conn->server_key);
-}
diff --git a/net/rxrpc/insecure.c b/net/rxrpc/insecure.c
new file mode 100644 (file)
index 0000000..e571403
--- /dev/null
@@ -0,0 +1,83 @@
+/* Null security operations.
+ *
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <net/af_rxrpc.h>
+#include "ar-internal.h"
+
+static int none_init_connection_security(struct rxrpc_connection *conn)
+{
+       return 0;
+}
+
+static void none_prime_packet_security(struct rxrpc_connection *conn)
+{
+}
+
+static int none_secure_packet(const struct rxrpc_call *call,
+                              struct sk_buff *skb,
+                              size_t data_size,
+                              void *sechdr)
+{
+       return 0;
+}
+
+static int none_verify_packet(const struct rxrpc_call *call,
+                              struct sk_buff *skb,
+                              u32 *_abort_code)
+{
+       return 0;
+}
+
+static int none_respond_to_challenge(struct rxrpc_connection *conn,
+                                     struct sk_buff *skb,
+                                     u32 *_abort_code)
+{
+       *_abort_code = RX_PROTOCOL_ERROR;
+       return -EPROTO;
+}
+
+static int none_verify_response(struct rxrpc_connection *conn,
+                                struct sk_buff *skb,
+                                u32 *_abort_code)
+{
+       *_abort_code = RX_PROTOCOL_ERROR;
+       return -EPROTO;
+}
+
+static void none_clear(struct rxrpc_connection *conn)
+{
+}
+
+static int none_init(void)
+{
+       return 0;
+}
+
+static void none_exit(void)
+{
+}
+
+/*
+ * RxRPC Kerberos-based security
+ */
+const struct rxrpc_security rxrpc_no_security = {
+       .name                           = "none",
+       .security_index                 = RXRPC_SECURITY_NONE,
+       .init                           = none_init,
+       .exit                           = none_exit,
+       .init_connection_security       = none_init_connection_security,
+       .prime_packet_security          = none_prime_packet_security,
+       .secure_packet                  = none_secure_packet,
+       .verify_packet                  = none_verify_packet,
+       .respond_to_challenge           = none_respond_to_challenge,
+       .verify_response                = none_verify_response,
+       .clear                          = none_clear,
+};
diff --git a/net/rxrpc/misc.c b/net/rxrpc/misc.c
new file mode 100644 (file)
index 0000000..1afe987
--- /dev/null
@@ -0,0 +1,89 @@
+/* Miscellaneous bits
+ *
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <net/sock.h>
+#include <net/af_rxrpc.h>
+#include "ar-internal.h"
+
+/*
+ * How long to wait before scheduling ACK generation after seeing a
+ * packet with RXRPC_REQUEST_ACK set (in jiffies).
+ */
+unsigned int rxrpc_requested_ack_delay = 1;
+
+/*
+ * How long to wait before scheduling an ACK with subtype DELAY (in jiffies).
+ *
+ * We use this when we've received new data packets.  If those packets aren't
+ * all consumed within this time we will send a DELAY ACK if an ACK was not
+ * requested to let the sender know it doesn't need to resend.
+ */
+unsigned int rxrpc_soft_ack_delay = 1 * HZ;
+
+/*
+ * How long to wait before scheduling an ACK with subtype IDLE (in jiffies).
+ *
+ * We use this when we've consumed some previously soft-ACK'd packets when
+ * further packets aren't immediately received to decide when to send an IDLE
+ * ACK let the other end know that it can free up its Tx buffer space.
+ */
+unsigned int rxrpc_idle_ack_delay = 0.5 * HZ;
+
+/*
+ * Receive window size in packets.  This indicates the maximum number of
+ * unconsumed received packets we're willing to retain in memory.  Once this
+ * limit is hit, we should generate an EXCEEDS_WINDOW ACK and discard further
+ * packets.
+ */
+unsigned int rxrpc_rx_window_size = 32;
+
+/*
+ * Maximum Rx MTU size.  This indicates to the sender the size of jumbo packet
+ * made by gluing normal packets together that we're willing to handle.
+ */
+unsigned int rxrpc_rx_mtu = 5692;
+
+/*
+ * The maximum number of fragments in a received jumbo packet that we tell the
+ * sender that we're willing to handle.
+ */
+unsigned int rxrpc_rx_jumbo_max = 4;
+
+const char *const rxrpc_pkts[] = {
+       "?00",
+       "DATA", "ACK", "BUSY", "ABORT", "ACKALL", "CHALL", "RESP", "DEBUG",
+       "?09", "?10", "?11", "?12", "VERSION", "?14", "?15"
+};
+
+const s8 rxrpc_ack_priority[] = {
+       [0]                             = 0,
+       [RXRPC_ACK_DELAY]               = 1,
+       [RXRPC_ACK_REQUESTED]           = 2,
+       [RXRPC_ACK_IDLE]                = 3,
+       [RXRPC_ACK_PING_RESPONSE]       = 4,
+       [RXRPC_ACK_DUPLICATE]           = 5,
+       [RXRPC_ACK_OUT_OF_SEQUENCE]     = 6,
+       [RXRPC_ACK_EXCEEDS_WINDOW]      = 7,
+       [RXRPC_ACK_NOSPACE]             = 8,
+};
+
+const char *rxrpc_acks(u8 reason)
+{
+       static const char *const str[] = {
+               "---", "REQ", "DUP", "OOS", "WIN", "MEM", "PNG", "PNR", "DLY",
+               "IDL", "-?-"
+       };
+
+       if (reason >= ARRAY_SIZE(str))
+               reason = ARRAY_SIZE(str) - 1;
+       return str[reason];
+}
index f0aeb8163688e6f4167874d9a6ac0f3bd270891d..6b726a046a7d47995ecc281f67979073fe02c102 100644 (file)
@@ -20,7 +20,6 @@
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <keys/rxrpc-type.h>
-#define rxrpc_debug rxkad_debug
 #include "ar-internal.h"
 
 #define RXKAD_VERSION                  2
 #define REALM_SZ                       40      /* size of principal's auth domain */
 #define SNAME_SZ                       40      /* size of service name */
 
-unsigned int rxrpc_debug;
-module_param_named(debug, rxrpc_debug, uint, S_IWUSR | S_IRUGO);
-MODULE_PARM_DESC(debug, "rxkad debugging mask");
-
 struct rxkad_level1_hdr {
        __be32  data_size;      /* true data size (excluding padding) */
 };
@@ -44,10 +39,6 @@ struct rxkad_level2_hdr {
        __be32  checksum;       /* decrypted data checksum */
 };
 
-MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos 4)");
-MODULE_AUTHOR("Red Hat, Inc.");
-MODULE_LICENSE("GPL");
-
 /*
  * this holds a pinned cipher so that keventd doesn't get called by the cipher
  * alloc routine, but since we have it to hand, we use it to decrypt RESPONSE
@@ -1163,13 +1154,36 @@ static void rxkad_clear(struct rxrpc_connection *conn)
                crypto_free_skcipher(conn->cipher);
 }
 
+/*
+ * Initialise the rxkad security service.
+ */
+static int rxkad_init(void)
+{
+       /* pin the cipher we need so that the crypto layer doesn't invoke
+        * keventd to go get it */
+       rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(rxkad_ci))
+               return PTR_ERR(rxkad_ci);
+       return 0;
+}
+
+/*
+ * Clean up the rxkad security service.
+ */
+static void rxkad_exit(void)
+{
+       if (rxkad_ci)
+               crypto_free_skcipher(rxkad_ci);
+}
+
 /*
  * RxRPC Kerberos-based security
  */
-static struct rxrpc_security rxkad = {
-       .owner                          = THIS_MODULE,
+const struct rxrpc_security rxkad = {
        .name                           = "rxkad",
        .security_index                 = RXRPC_SECURITY_RXKAD,
+       .init                           = rxkad_init,
+       .exit                           = rxkad_exit,
        .init_connection_security       = rxkad_init_connection_security,
        .prime_packet_security          = rxkad_prime_packet_security,
        .secure_packet                  = rxkad_secure_packet,
@@ -1179,28 +1193,3 @@ static struct rxrpc_security rxkad = {
        .verify_response                = rxkad_verify_response,
        .clear                          = rxkad_clear,
 };
-
-static __init int rxkad_init(void)
-{
-       _enter("");
-
-       /* pin the cipher we need so that the crypto layer doesn't invoke
-        * keventd to go get it */
-       rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
-       if (IS_ERR(rxkad_ci))
-               return PTR_ERR(rxkad_ci);
-
-       return rxrpc_register_security(&rxkad);
-}
-
-module_init(rxkad_init);
-
-static __exit void rxkad_exit(void)
-{
-       _enter("");
-
-       rxrpc_unregister_security(&rxkad);
-       crypto_free_skcipher(rxkad_ci);
-}
-
-module_exit(rxkad_exit);