linux/net/rxrpc/ar-connevent.c
<<
>>
Prefs
   1/* connection-level event handling
   2 *
   3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/net.h>
  14#include <linux/skbuff.h>
  15#include <linux/errqueue.h>
  16#include <linux/udp.h>
  17#include <linux/in.h>
  18#include <linux/in6.h>
  19#include <linux/icmp.h>
  20#include <net/sock.h>
  21#include <net/af_rxrpc.h>
  22#include <net/ip.h>
  23#include "ar-internal.h"
  24
  25/*
  26 * pass a connection-level abort onto all calls on that connection
  27 */
  28static void rxrpc_abort_calls(struct rxrpc_connection *conn, int state,
  29                              u32 abort_code)
  30{
  31        struct rxrpc_call *call;
  32        struct rb_node *p;
  33
  34        _enter("{%d},%x", conn->debug_id, abort_code);
  35
  36        read_lock_bh(&conn->lock);
  37
  38        for (p = rb_first(&conn->calls); p; p = rb_next(p)) {
  39                call = rb_entry(p, struct rxrpc_call, conn_node);
  40                write_lock(&call->state_lock);
  41                if (call->state <= RXRPC_CALL_COMPLETE) {
  42                        call->state = state;
  43                        call->abort_code = abort_code;
  44                        if (state == RXRPC_CALL_LOCALLY_ABORTED)
  45                                set_bit(RXRPC_CALL_CONN_ABORT, &call->events);
  46                        else
  47                                set_bit(RXRPC_CALL_RCVD_ABORT, &call->events);
  48                        rxrpc_queue_call(call);
  49                }
  50                write_unlock(&call->state_lock);
  51        }
  52
  53        read_unlock_bh(&conn->lock);
  54        _leave("");
  55}
  56
  57/*
  58 * generate a connection-level abort
  59 */
  60static int rxrpc_abort_connection(struct rxrpc_connection *conn,
  61                                  u32 error, u32 abort_code)
  62{
  63        struct rxrpc_header hdr;
  64        struct msghdr msg;
  65        struct kvec iov[2];
  66        __be32 word;
  67        size_t len;
  68        int ret;
  69
  70        _enter("%d,,%u,%u", conn->debug_id, error, abort_code);
  71
  72        /* generate a connection-level abort */
  73        spin_lock_bh(&conn->state_lock);
  74        if (conn->state < RXRPC_CONN_REMOTELY_ABORTED) {
  75                conn->state = RXRPC_CONN_LOCALLY_ABORTED;
  76                conn->error = error;
  77                spin_unlock_bh(&conn->state_lock);
  78        } else {
  79                spin_unlock_bh(&conn->state_lock);
  80                _leave(" = 0 [already dead]");
  81                return 0;
  82        }
  83
  84        rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED, abort_code);
  85
  86        msg.msg_name    = &conn->trans->peer->srx.transport.sin;
  87        msg.msg_namelen = sizeof(conn->trans->peer->srx.transport.sin);
  88        msg.msg_control = NULL;
  89        msg.msg_controllen = 0;
  90        msg.msg_flags   = 0;
  91
  92        hdr.epoch       = conn->epoch;
  93        hdr.cid         = conn->cid;
  94        hdr.callNumber  = 0;
  95        hdr.seq         = 0;
  96        hdr.type        = RXRPC_PACKET_TYPE_ABORT;
  97        hdr.flags       = conn->out_clientflag;
  98        hdr.userStatus  = 0;
  99        hdr.securityIndex = conn->security_ix;
 100        hdr._rsvd       = 0;
 101        hdr.serviceId   = conn->service_id;
 102
 103        word = htonl(abort_code);
 104
 105        iov[0].iov_base = &hdr;
 106        iov[0].iov_len  = sizeof(hdr);
 107        iov[1].iov_base = &word;
 108        iov[1].iov_len  = sizeof(word);
 109
 110        len = iov[0].iov_len + iov[1].iov_len;
 111
 112        hdr.serial = htonl(atomic_inc_return(&conn->serial));
 113        _proto("Tx CONN ABORT %%%u { %d }", ntohl(hdr.serial), abort_code);
 114
 115        ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 2, len);
 116        if (ret < 0) {
 117                _debug("sendmsg failed: %d", ret);
 118                return -EAGAIN;
 119        }
 120
 121        _leave(" = 0");
 122        return 0;
 123}
 124
 125/*
 126 * mark a call as being on a now-secured channel
 127 * - must be called with softirqs disabled
 128 */
 129static void rxrpc_call_is_secure(struct rxrpc_call *call)
 130{
 131        _enter("%p", call);
 132        if (call) {
 133                read_lock(&call->state_lock);
 134                if (call->state < RXRPC_CALL_COMPLETE &&
 135                    !test_and_set_bit(RXRPC_CALL_SECURED, &call->events))
 136                        rxrpc_queue_call(call);
 137                read_unlock(&call->state_lock);
 138        }
 139}
 140
 141/*
 142 * connection-level Rx packet processor
 143 */
 144static int rxrpc_process_event(struct rxrpc_connection *conn,
 145                               struct sk_buff *skb,
 146                               u32 *_abort_code)
 147{
 148        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
 149        __be32 tmp;
 150        u32 serial;
 151        int loop, ret;
 152
 153        if (conn->state >= RXRPC_CONN_REMOTELY_ABORTED)
 154                return -ECONNABORTED;
 155
 156        serial = ntohl(sp->hdr.serial);
 157
 158        switch (sp->hdr.type) {
 159        case RXRPC_PACKET_TYPE_ABORT:
 160                if (skb_copy_bits(skb, 0, &tmp, sizeof(tmp)) < 0)
 161                        return -EPROTO;
 162                _proto("Rx ABORT %%%u { ac=%d }", serial, ntohl(tmp));
 163
 164                conn->state = RXRPC_CONN_REMOTELY_ABORTED;
 165                rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED,
 166                                  ntohl(tmp));
 167                return -ECONNABORTED;
 168
 169        case RXRPC_PACKET_TYPE_CHALLENGE:
 170                if (conn->security)
 171                        return conn->security->respond_to_challenge(
 172                                conn, skb, _abort_code);
 173                return -EPROTO;
 174
 175        case RXRPC_PACKET_TYPE_RESPONSE:
 176                if (!conn->security)
 177                        return -EPROTO;
 178
 179                ret = conn->security->verify_response(conn, skb, _abort_code);
 180                if (ret < 0)
 181                        return ret;
 182
 183                ret = conn->security->init_connection_security(conn);
 184                if (ret < 0)
 185                        return ret;
 186
 187                conn->security->prime_packet_security(conn);
 188                read_lock_bh(&conn->lock);
 189                spin_lock(&conn->state_lock);
 190
 191                if (conn->state == RXRPC_CONN_SERVER_CHALLENGING) {
 192                        conn->state = RXRPC_CONN_SERVER;
 193                        for (loop = 0; loop < RXRPC_MAXCALLS; loop++)
 194                                rxrpc_call_is_secure(conn->channels[loop]);
 195                }
 196
 197                spin_unlock(&conn->state_lock);
 198                read_unlock_bh(&conn->lock);
 199                return 0;
 200
 201        default:
 202                return -EPROTO;
 203        }
 204}
 205
 206/*
 207 * set up security and issue a challenge
 208 */
 209static void rxrpc_secure_connection(struct rxrpc_connection *conn)
 210{
 211        u32 abort_code;
 212        int ret;
 213
 214        _enter("{%d}", conn->debug_id);
 215
 216        ASSERT(conn->security_ix != 0);
 217
 218        if (!conn->key) {
 219                _debug("set up security");
 220                ret = rxrpc_init_server_conn_security(conn);
 221                switch (ret) {
 222                case 0:
 223                        break;
 224                case -ENOENT:
 225                        abort_code = RX_CALL_DEAD;
 226                        goto abort;
 227                default:
 228                        abort_code = RXKADNOAUTH;
 229                        goto abort;
 230                }
 231        }
 232
 233        ASSERT(conn->security != NULL);
 234
 235        if (conn->security->issue_challenge(conn) < 0) {
 236                abort_code = RX_CALL_DEAD;
 237                ret = -ENOMEM;
 238                goto abort;
 239        }
 240
 241        _leave("");
 242        return;
 243
 244abort:
 245        _debug("abort %d, %d", ret, abort_code);
 246        rxrpc_abort_connection(conn, -ret, abort_code);
 247        _leave(" [aborted]");
 248}
 249
 250/*
 251 * connection-level event processor
 252 */
 253void rxrpc_process_connection(struct work_struct *work)
 254{
 255        struct rxrpc_connection *conn =
 256                container_of(work, struct rxrpc_connection, processor);
 257        struct rxrpc_skb_priv *sp;
 258        struct sk_buff *skb;
 259        u32 abort_code = RX_PROTOCOL_ERROR;
 260        int ret;
 261
 262        _enter("{%d}", conn->debug_id);
 263
 264        atomic_inc(&conn->usage);
 265
 266        if (test_and_clear_bit(RXRPC_CONN_CHALLENGE, &conn->events)) {
 267                rxrpc_secure_connection(conn);
 268                rxrpc_put_connection(conn);
 269        }
 270
 271        /* go through the conn-level event packets, releasing the ref on this
 272         * connection that each one has when we've finished with it */
 273        while ((skb = skb_dequeue(&conn->rx_queue))) {
 274                sp = rxrpc_skb(skb);
 275
 276                ret = rxrpc_process_event(conn, skb, &abort_code);
 277                switch (ret) {
 278                case -EPROTO:
 279                case -EKEYEXPIRED:
 280                case -EKEYREJECTED:
 281                        goto protocol_error;
 282                case -EAGAIN:
 283                        goto requeue_and_leave;
 284                case -ECONNABORTED:
 285                default:
 286                        rxrpc_put_connection(conn);
 287                        rxrpc_free_skb(skb);
 288                        break;
 289                }
 290        }
 291
 292out:
 293        rxrpc_put_connection(conn);
 294        _leave("");
 295        return;
 296
 297requeue_and_leave:
 298        skb_queue_head(&conn->rx_queue, skb);
 299        goto out;
 300
 301protocol_error:
 302        if (rxrpc_abort_connection(conn, -ret, abort_code) < 0)
 303                goto requeue_and_leave;
 304        rxrpc_put_connection(conn);
 305        rxrpc_free_skb(skb);
 306        _leave(" [EPROTO]");
 307        goto out;
 308}
 309
 310/*
 311 * put a packet up for transport-level abort
 312 */
 313void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
 314{
 315        CHECK_SLAB_OKAY(&local->usage);
 316
 317        if (!atomic_inc_not_zero(&local->usage)) {
 318                printk("resurrected on reject\n");
 319                BUG();
 320        }
 321
 322        skb_queue_tail(&local->reject_queue, skb);
 323        rxrpc_queue_work(&local->rejecter);
 324}
 325
 326/*
 327 * reject packets through the local endpoint
 328 */
 329void rxrpc_reject_packets(struct work_struct *work)
 330{
 331        union {
 332                struct sockaddr sa;
 333                struct sockaddr_in sin;
 334        } sa;
 335        struct rxrpc_skb_priv *sp;
 336        struct rxrpc_header hdr;
 337        struct rxrpc_local *local;
 338        struct sk_buff *skb;
 339        struct msghdr msg;
 340        struct kvec iov[2];
 341        size_t size;
 342        __be32 code;
 343
 344        local = container_of(work, struct rxrpc_local, rejecter);
 345        rxrpc_get_local(local);
 346
 347        _enter("%d", local->debug_id);
 348
 349        iov[0].iov_base = &hdr;
 350        iov[0].iov_len = sizeof(hdr);
 351        iov[1].iov_base = &code;
 352        iov[1].iov_len = sizeof(code);
 353        size = sizeof(hdr) + sizeof(code);
 354
 355        msg.msg_name = &sa;
 356        msg.msg_control = NULL;
 357        msg.msg_controllen = 0;
 358        msg.msg_flags = 0;
 359
 360        memset(&sa, 0, sizeof(sa));
 361        sa.sa.sa_family = local->srx.transport.family;
 362        switch (sa.sa.sa_family) {
 363        case AF_INET:
 364                msg.msg_namelen = sizeof(sa.sin);
 365                break;
 366        default:
 367                msg.msg_namelen = 0;
 368                break;
 369        }
 370
 371        memset(&hdr, 0, sizeof(hdr));
 372        hdr.type = RXRPC_PACKET_TYPE_ABORT;
 373
 374        while ((skb = skb_dequeue(&local->reject_queue))) {
 375                sp = rxrpc_skb(skb);
 376                switch (sa.sa.sa_family) {
 377                case AF_INET:
 378                        sa.sin.sin_port = udp_hdr(skb)->source;
 379                        sa.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
 380                        code = htonl(skb->priority);
 381
 382                        hdr.epoch = sp->hdr.epoch;
 383                        hdr.cid = sp->hdr.cid;
 384                        hdr.callNumber = sp->hdr.callNumber;
 385                        hdr.serviceId = sp->hdr.serviceId;
 386                        hdr.flags = sp->hdr.flags;
 387                        hdr.flags ^= RXRPC_CLIENT_INITIATED;
 388                        hdr.flags &= RXRPC_CLIENT_INITIATED;
 389
 390                        kernel_sendmsg(local->socket, &msg, iov, 2, size);
 391                        break;
 392
 393                default:
 394                        break;
 395                }
 396
 397                rxrpc_free_skb(skb);
 398                rxrpc_put_local(local);
 399        }
 400
 401        rxrpc_put_local(local);
 402        _leave("");
 403}
 404