Showing error 1677

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: net/rxrpc/ar-connection.c
Line in file: 351
Project: Linux Kernel
Project version: 2.6.28
Confirmation: Fixed by 0975ecba3b670df7c488a5e0e6fe9f1f370a8ad8
Tools: Smatch (1.59)
Entered: 2013-09-10 07:54:05 UTC


Source:

  1/* RxRPC virtual connection handler
  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/crypto.h>
 16#include <net/sock.h>
 17#include <net/af_rxrpc.h>
 18#include "ar-internal.h"
 19
 20static void rxrpc_connection_reaper(struct work_struct *work);
 21
 22LIST_HEAD(rxrpc_connections);
 23DEFINE_RWLOCK(rxrpc_connection_lock);
 24static unsigned long rxrpc_connection_timeout = 10 * 60;
 25static DECLARE_DELAYED_WORK(rxrpc_connection_reap, rxrpc_connection_reaper);
 26
 27/*
 28 * allocate a new client connection bundle
 29 */
 30static struct rxrpc_conn_bundle *rxrpc_alloc_bundle(gfp_t gfp)
 31{
 32        struct rxrpc_conn_bundle *bundle;
 33
 34        _enter("");
 35
 36        bundle = kzalloc(sizeof(struct rxrpc_conn_bundle), gfp);
 37        if (bundle) {
 38                INIT_LIST_HEAD(&bundle->unused_conns);
 39                INIT_LIST_HEAD(&bundle->avail_conns);
 40                INIT_LIST_HEAD(&bundle->busy_conns);
 41                init_waitqueue_head(&bundle->chanwait);
 42                atomic_set(&bundle->usage, 1);
 43        }
 44
 45        _leave(" = %p", bundle);
 46        return bundle;
 47}
 48
 49/*
 50 * compare bundle parameters with what we're looking for
 51 * - return -ve, 0 or +ve
 52 */
 53static inline
 54int rxrpc_cmp_bundle(const struct rxrpc_conn_bundle *bundle,
 55                     struct key *key, __be16 service_id)
 56{
 57        return (bundle->service_id - service_id) ?:
 58                ((unsigned long) bundle->key - (unsigned long) key);
 59}
 60
 61/*
 62 * get bundle of client connections that a client socket can make use of
 63 */
 64struct rxrpc_conn_bundle *rxrpc_get_bundle(struct rxrpc_sock *rx,
 65                                           struct rxrpc_transport *trans,
 66                                           struct key *key,
 67                                           __be16 service_id,
 68                                           gfp_t gfp)
 69{
 70        struct rxrpc_conn_bundle *bundle, *candidate;
 71        struct rb_node *p, *parent, **pp;
 72
 73        _enter("%p{%x},%x,%hx,",
 74               rx, key_serial(key), trans->debug_id, ntohs(service_id));
 75
 76        if (rx->trans == trans && rx->bundle) {
 77                atomic_inc(&rx->bundle->usage);
 78                return rx->bundle;
 79        }
 80
 81        /* search the extant bundles first for one that matches the specified
 82         * user ID */
 83        spin_lock(&trans->client_lock);
 84
 85        p = trans->bundles.rb_node;
 86        while (p) {
 87                bundle = rb_entry(p, struct rxrpc_conn_bundle, node);
 88
 89                if (rxrpc_cmp_bundle(bundle, key, service_id) < 0)
 90                        p = p->rb_left;
 91                else if (rxrpc_cmp_bundle(bundle, key, service_id) > 0)
 92                        p = p->rb_right;
 93                else
 94                        goto found_extant_bundle;
 95        }
 96
 97        spin_unlock(&trans->client_lock);
 98
 99        /* not yet present - create a candidate for a new record and then
100         * redo the search */
101        candidate = rxrpc_alloc_bundle(gfp);
102        if (!candidate) {
103                _leave(" = -ENOMEM");
104                return ERR_PTR(-ENOMEM);
105        }
106
107        candidate->key = key_get(key);
108        candidate->service_id = service_id;
109
110        spin_lock(&trans->client_lock);
111
112        pp = &trans->bundles.rb_node;
113        parent = NULL;
114        while (*pp) {
115                parent = *pp;
116                bundle = rb_entry(parent, struct rxrpc_conn_bundle, node);
117
118                if (rxrpc_cmp_bundle(bundle, key, service_id) < 0)
119                        pp = &(*pp)->rb_left;
120                else if (rxrpc_cmp_bundle(bundle, key, service_id) > 0)
121                        pp = &(*pp)->rb_right;
122                else
123                        goto found_extant_second;
124        }
125
126        /* second search also failed; add the new bundle */
127        bundle = candidate;
128        candidate = NULL;
129
130        rb_link_node(&bundle->node, parent, pp);
131        rb_insert_color(&bundle->node, &trans->bundles);
132        spin_unlock(&trans->client_lock);
133        _net("BUNDLE new on trans %d", trans->debug_id);
134        if (!rx->bundle && rx->sk.sk_state == RXRPC_CLIENT_CONNECTED) {
135                atomic_inc(&bundle->usage);
136                rx->bundle = bundle;
137        }
138        _leave(" = %p [new]", bundle);
139        return bundle;
140
141        /* we found the bundle in the list immediately */
142found_extant_bundle:
143        atomic_inc(&bundle->usage);
144        spin_unlock(&trans->client_lock);
145        _net("BUNDLE old on trans %d", trans->debug_id);
146        if (!rx->bundle && rx->sk.sk_state == RXRPC_CLIENT_CONNECTED) {
147                atomic_inc(&bundle->usage);
148                rx->bundle = bundle;
149        }
150        _leave(" = %p [extant %d]", bundle, atomic_read(&bundle->usage));
151        return bundle;
152
153        /* we found the bundle on the second time through the list */
154found_extant_second:
155        atomic_inc(&bundle->usage);
156        spin_unlock(&trans->client_lock);
157        kfree(candidate);
158        _net("BUNDLE old2 on trans %d", trans->debug_id);
159        if (!rx->bundle && rx->sk.sk_state == RXRPC_CLIENT_CONNECTED) {
160                atomic_inc(&bundle->usage);
161                rx->bundle = bundle;
162        }
163        _leave(" = %p [second %d]", bundle, atomic_read(&bundle->usage));
164        return bundle;
165}
166
167/*
168 * release a bundle
169 */
170void rxrpc_put_bundle(struct rxrpc_transport *trans,
171                      struct rxrpc_conn_bundle *bundle)
172{
173        _enter("%p,%p{%d}",trans, bundle, atomic_read(&bundle->usage));
174
175        if (atomic_dec_and_lock(&bundle->usage, &trans->client_lock)) {
176                _debug("Destroy bundle");
177                rb_erase(&bundle->node, &trans->bundles);
178                spin_unlock(&trans->client_lock);
179                ASSERT(list_empty(&bundle->unused_conns));
180                ASSERT(list_empty(&bundle->avail_conns));
181                ASSERT(list_empty(&bundle->busy_conns));
182                ASSERTCMP(bundle->num_conns, ==, 0);
183                key_put(bundle->key);
184                kfree(bundle);
185        }
186
187        _leave("");
188}
189
190/*
191 * allocate a new connection
192 */
193static struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
194{
195        struct rxrpc_connection *conn;
196
197        _enter("");
198
199        conn = kzalloc(sizeof(struct rxrpc_connection), gfp);
200        if (conn) {
201                INIT_WORK(&conn->processor, &rxrpc_process_connection);
202                INIT_LIST_HEAD(&conn->bundle_link);
203                conn->calls = RB_ROOT;
204                skb_queue_head_init(&conn->rx_queue);
205                rwlock_init(&conn->lock);
206                spin_lock_init(&conn->state_lock);
207                atomic_set(&conn->usage, 1);
208                conn->debug_id = atomic_inc_return(&rxrpc_debug_id);
209                conn->avail_calls = RXRPC_MAXCALLS;
210                conn->size_align = 4;
211                conn->header_size = sizeof(struct rxrpc_header);
212        }
213
214        _leave(" = %p{%d}", conn, conn ? conn->debug_id : 0);
215        return conn;
216}
217
218/*
219 * assign a connection ID to a connection and add it to the transport's
220 * connection lookup tree
221 * - called with transport client lock held
222 */
223static void rxrpc_assign_connection_id(struct rxrpc_connection *conn)
224{
225        struct rxrpc_connection *xconn;
226        struct rb_node *parent, **p;
227        __be32 epoch;
228        u32 real_conn_id;
229
230        _enter("");
231
232        epoch = conn->epoch;
233
234        write_lock_bh(&conn->trans->conn_lock);
235
236        conn->trans->conn_idcounter += RXRPC_CID_INC;
237        if (conn->trans->conn_idcounter < RXRPC_CID_INC)
238                conn->trans->conn_idcounter = RXRPC_CID_INC;
239        real_conn_id = conn->trans->conn_idcounter;
240
241attempt_insertion:
242        parent = NULL;
243        p = &conn->trans->client_conns.rb_node;
244
245        while (*p) {
246                parent = *p;
247                xconn = rb_entry(parent, struct rxrpc_connection, node);
248
249                if (epoch < xconn->epoch)
250                        p = &(*p)->rb_left;
251                else if (epoch > xconn->epoch)
252                        p = &(*p)->rb_right;
253                else if (real_conn_id < xconn->real_conn_id)
254                        p = &(*p)->rb_left;
255                else if (real_conn_id > xconn->real_conn_id)
256                        p = &(*p)->rb_right;
257                else
258                        goto id_exists;
259        }
260
261        /* we've found a suitable hole - arrange for this connection to occupy
262         * it */
263        rb_link_node(&conn->node, parent, p);
264        rb_insert_color(&conn->node, &conn->trans->client_conns);
265
266        conn->real_conn_id = real_conn_id;
267        conn->cid = htonl(real_conn_id);
268        write_unlock_bh(&conn->trans->conn_lock);
269        _leave(" [CONNID %x CID %x]", real_conn_id, ntohl(conn->cid));
270        return;
271
272        /* we found a connection with the proposed ID - walk the tree from that
273         * point looking for the next unused ID */
274id_exists:
275        for (;;) {
276                real_conn_id += RXRPC_CID_INC;
277                if (real_conn_id < RXRPC_CID_INC) {
278                        real_conn_id = RXRPC_CID_INC;
279                        conn->trans->conn_idcounter = real_conn_id;
280                        goto attempt_insertion;
281                }
282
283                parent = rb_next(parent);
284                if (!parent)
285                        goto attempt_insertion;
286
287                xconn = rb_entry(parent, struct rxrpc_connection, node);
288                if (epoch < xconn->epoch ||
289                    real_conn_id < xconn->real_conn_id)
290                        goto attempt_insertion;
291        }
292}
293
294/*
295 * add a call to a connection's call-by-ID tree
296 */
297static void rxrpc_add_call_ID_to_conn(struct rxrpc_connection *conn,
298                                      struct rxrpc_call *call)
299{
300        struct rxrpc_call *xcall;
301        struct rb_node *parent, **p;
302        __be32 call_id;
303
304        write_lock_bh(&conn->lock);
305
306        call_id = call->call_id;
307        p = &conn->calls.rb_node;
308        parent = NULL;
309        while (*p) {
310                parent = *p;
311                xcall = rb_entry(parent, struct rxrpc_call, conn_node);
312
313                if (call_id < xcall->call_id)
314                        p = &(*p)->rb_left;
315                else if (call_id > xcall->call_id)
316                        p = &(*p)->rb_right;
317                else
318                        BUG();
319        }
320
321        rb_link_node(&call->conn_node, parent, p);
322        rb_insert_color(&call->conn_node, &conn->calls);
323
324        write_unlock_bh(&conn->lock);
325}
326
327/*
328 * connect a call on an exclusive connection
329 */
330static int rxrpc_connect_exclusive(struct rxrpc_sock *rx,
331                                   struct rxrpc_transport *trans,
332                                   __be16 service_id,
333                                   struct rxrpc_call *call,
334                                   gfp_t gfp)
335{
336        struct rxrpc_connection *conn;
337        int chan, ret;
338
339        _enter("");
340
341        conn = rx->conn;
342        if (!conn) {
343                /* not yet present - create a candidate for a new connection
344                 * and then redo the check */
345                conn = rxrpc_alloc_connection(gfp);
346                if (IS_ERR(conn)) {
347                        _leave(" = %ld", PTR_ERR(conn));
348                        return PTR_ERR(conn);
349                }
350
351                conn->trans = trans;
352                conn->bundle = NULL;
353                conn->service_id = service_id;
354                conn->epoch = rxrpc_epoch;
355                conn->in_clientflag = 0;
356                conn->out_clientflag = RXRPC_CLIENT_INITIATED;
357                conn->cid = 0;
358                conn->state = RXRPC_CONN_CLIENT;
359                conn->avail_calls = RXRPC_MAXCALLS - 1;
360                conn->security_level = rx->min_sec_level;
361                conn->key = key_get(rx->key);
362
363                ret = rxrpc_init_client_conn_security(conn);
364                if (ret < 0) {
365                        key_put(conn->key);
366                        kfree(conn);
367                        _leave(" = %d [key]", ret);
368                        return ret;
369                }
370
371                write_lock_bh(&rxrpc_connection_lock);
372                list_add_tail(&conn->link, &rxrpc_connections);
373                write_unlock_bh(&rxrpc_connection_lock);
374
375                spin_lock(&trans->client_lock);
376                atomic_inc(&trans->usage);
377
378                _net("CONNECT EXCL new %d on TRANS %d",
379                     conn->debug_id, conn->trans->debug_id);
380
381                rxrpc_assign_connection_id(conn);
382                rx->conn = conn;
383        }
384
385        /* we've got a connection with a free channel and we can now attach the
386         * call to it
387         * - we're holding the transport's client lock
388         * - we're holding a reference on the connection
389         */
390        for (chan = 0; chan < RXRPC_MAXCALLS; chan++)
391                if (!conn->channels[chan])
392                        goto found_channel;
393        goto no_free_channels;
394
395found_channel:
396        atomic_inc(&conn->usage);
397        conn->channels[chan] = call;
398        call->conn = conn;
399        call->channel = chan;
400        call->cid = conn->cid | htonl(chan);
401        call->call_id = htonl(++conn->call_counter);
402
403        _net("CONNECT client on conn %d chan %d as call %x",
404             conn->debug_id, chan, ntohl(call->call_id));
405
406        spin_unlock(&trans->client_lock);
407
408        rxrpc_add_call_ID_to_conn(conn, call);
409        _leave(" = 0");
410        return 0;
411
412no_free_channels:
413        spin_unlock(&trans->client_lock);
414        _leave(" = -ENOSR");
415        return -ENOSR;
416}
417
418/*
419 * find a connection for a call
420 * - called in process context with IRQs enabled
421 */
422int rxrpc_connect_call(struct rxrpc_sock *rx,
423                       struct rxrpc_transport *trans,
424                       struct rxrpc_conn_bundle *bundle,
425                       struct rxrpc_call *call,
426                       gfp_t gfp)
427{
428        struct rxrpc_connection *conn, *candidate;
429        int chan, ret;
430
431        DECLARE_WAITQUEUE(myself, current);
432
433        _enter("%p,%lx,", rx, call->user_call_ID);
434
435        if (test_bit(RXRPC_SOCK_EXCLUSIVE_CONN, &rx->flags))
436                return rxrpc_connect_exclusive(rx, trans, bundle->service_id,
437                                               call, gfp);
438
439        spin_lock(&trans->client_lock);
440        for (;;) {
441                /* see if the bundle has a call slot available */
442                if (!list_empty(&bundle->avail_conns)) {
443                        _debug("avail");
444                        conn = list_entry(bundle->avail_conns.next,
445                                          struct rxrpc_connection,
446                                          bundle_link);
447                        if (--conn->avail_calls == 0)
448                                list_move(&conn->bundle_link,
449                                          &bundle->busy_conns);
450                        ASSERTCMP(conn->avail_calls, <, RXRPC_MAXCALLS);
451                        ASSERT(conn->channels[0] == NULL ||
452                               conn->channels[1] == NULL ||
453                               conn->channels[2] == NULL ||
454                               conn->channels[3] == NULL);
455                        atomic_inc(&conn->usage);
456                        break;
457                }
458
459                if (!list_empty(&bundle->unused_conns)) {
460                        _debug("unused");
461                        conn = list_entry(bundle->unused_conns.next,
462                                          struct rxrpc_connection,
463                                          bundle_link);
464                        ASSERTCMP(conn->avail_calls, ==, RXRPC_MAXCALLS);
465                        conn->avail_calls = RXRPC_MAXCALLS - 1;
466                        ASSERT(conn->channels[0] == NULL &&
467                               conn->channels[1] == NULL &&
468                               conn->channels[2] == NULL &&
469                               conn->channels[3] == NULL);
470                        atomic_inc(&conn->usage);
471                        list_move(&conn->bundle_link, &bundle->avail_conns);
472                        break;
473                }
474
475                /* need to allocate a new connection */
476                _debug("get new conn [%d]", bundle->num_conns);
477
478                spin_unlock(&trans->client_lock);
479
480                if (signal_pending(current))
481                        goto interrupted;
482
483                if (bundle->num_conns >= 20) {
484                        _debug("too many conns");
485
486                        if (!(gfp & __GFP_WAIT)) {
487                                _leave(" = -EAGAIN");
488                                return -EAGAIN;
489                        }
490
491                        add_wait_queue(&bundle->chanwait, &myself);
492                        for (;;) {
493                                set_current_state(TASK_INTERRUPTIBLE);
494                                if (bundle->num_conns < 20 ||
495                                    !list_empty(&bundle->unused_conns) ||
496                                    !list_empty(&bundle->avail_conns))
497                                        break;
498                                if (signal_pending(current))
499                                        goto interrupted_dequeue;
500                                schedule();
501                        }
502                        remove_wait_queue(&bundle->chanwait, &myself);
503                        __set_current_state(TASK_RUNNING);
504                        spin_lock(&trans->client_lock);
505                        continue;
506                }
507
508                /* not yet present - create a candidate for a new connection and then
509                 * redo the check */
510                candidate = rxrpc_alloc_connection(gfp);
511                if (IS_ERR(candidate)) {
512                        _leave(" = %ld", PTR_ERR(candidate));
513                        return PTR_ERR(candidate);
514                }
515
516                candidate->trans = trans;
517                candidate->bundle = bundle;
518                candidate->service_id = bundle->service_id;
519                candidate->epoch = rxrpc_epoch;
520                candidate->in_clientflag = 0;
521                candidate->out_clientflag = RXRPC_CLIENT_INITIATED;
522                candidate->cid = 0;
523                candidate->state = RXRPC_CONN_CLIENT;
524                candidate->avail_calls = RXRPC_MAXCALLS;
525                candidate->security_level = rx->min_sec_level;
526                candidate->key = key_get(bundle->key);
527
528                ret = rxrpc_init_client_conn_security(candidate);
529                if (ret < 0) {
530                        key_put(candidate->key);
531                        kfree(candidate);
532                        _leave(" = %d [key]", ret);
533                        return ret;
534                }
535
536                write_lock_bh(&rxrpc_connection_lock);
537                list_add_tail(&candidate->link, &rxrpc_connections);
538                write_unlock_bh(&rxrpc_connection_lock);
539
540                spin_lock(&trans->client_lock);
541
542                list_add(&candidate->bundle_link, &bundle->unused_conns);
543                bundle->num_conns++;
544                atomic_inc(&bundle->usage);
545                atomic_inc(&trans->usage);
546
547                _net("CONNECT new %d on TRANS %d",
548                     candidate->debug_id, candidate->trans->debug_id);
549
550                rxrpc_assign_connection_id(candidate);
551                if (candidate->security)
552                        candidate->security->prime_packet_security(candidate);
553
554                /* leave the candidate lurking in zombie mode attached to the
555                 * bundle until we're ready for it */
556                rxrpc_put_connection(candidate);
557                candidate = NULL;
558        }
559
560        /* we've got a connection with a free channel and we can now attach the
561         * call to it
562         * - we're holding the transport's client lock
563         * - we're holding a reference on the connection
564         * - we're holding a reference on the bundle
565         */
566        for (chan = 0; chan < RXRPC_MAXCALLS; chan++)
567                if (!conn->channels[chan])
568                        goto found_channel;
569        ASSERT(conn->channels[0] == NULL ||
570               conn->channels[1] == NULL ||
571               conn->channels[2] == NULL ||
572               conn->channels[3] == NULL);
573        BUG();
574
575found_channel:
576        conn->channels[chan] = call;
577        call->conn = conn;
578        call->channel = chan;
579        call->cid = conn->cid | htonl(chan);
580        call->call_id = htonl(++conn->call_counter);
581
582        _net("CONNECT client on conn %d chan %d as call %x",
583             conn->debug_id, chan, ntohl(call->call_id));
584
585        ASSERTCMP(conn->avail_calls, <, RXRPC_MAXCALLS);
586        spin_unlock(&trans->client_lock);
587
588        rxrpc_add_call_ID_to_conn(conn, call);
589
590        _leave(" = 0");
591        return 0;
592
593interrupted_dequeue:
594        remove_wait_queue(&bundle->chanwait, &myself);
595        __set_current_state(TASK_RUNNING);
596interrupted:
597        _leave(" = -ERESTARTSYS");
598        return -ERESTARTSYS;
599}
600
601/*
602 * get a record of an incoming connection
603 */
604struct rxrpc_connection *
605rxrpc_incoming_connection(struct rxrpc_transport *trans,
606                          struct rxrpc_header *hdr,
607                          gfp_t gfp)
608{
609        struct rxrpc_connection *conn, *candidate = NULL;
610        struct rb_node *p, **pp;
611        const char *new = "old";
612        __be32 epoch;
613        u32 conn_id;
614
615        _enter("");
616
617        ASSERT(hdr->flags & RXRPC_CLIENT_INITIATED);
618
619        epoch = hdr->epoch;
620        conn_id = ntohl(hdr->cid) & RXRPC_CIDMASK;
621
622        /* search the connection list first */
623        read_lock_bh(&trans->conn_lock);
624
625        p = trans->server_conns.rb_node;
626        while (p) {
627                conn = rb_entry(p, struct rxrpc_connection, node);
628
629                _debug("maybe %x", conn->real_conn_id);
630
631                if (epoch < conn->epoch)
632                        p = p->rb_left;
633                else if (epoch > conn->epoch)
634                        p = p->rb_right;
635                else if (conn_id < conn->real_conn_id)
636                        p = p->rb_left;
637                else if (conn_id > conn->real_conn_id)
638                        p = p->rb_right;
639                else
640                        goto found_extant_connection;
641        }
642        read_unlock_bh(&trans->conn_lock);
643
644        /* not yet present - create a candidate for a new record and then
645         * redo the search */
646        candidate = rxrpc_alloc_connection(gfp);
647        if (!candidate) {
648                _leave(" = -ENOMEM");
649                return ERR_PTR(-ENOMEM);
650        }
651
652        candidate->trans = trans;
653        candidate->epoch = hdr->epoch;
654        candidate->cid = hdr->cid & cpu_to_be32(RXRPC_CIDMASK);
655        candidate->service_id = hdr->serviceId;
656        candidate->security_ix = hdr->securityIndex;
657        candidate->in_clientflag = RXRPC_CLIENT_INITIATED;
658        candidate->out_clientflag = 0;
659        candidate->real_conn_id = conn_id;
660        candidate->state = RXRPC_CONN_SERVER;
661        if (candidate->service_id)
662                candidate->state = RXRPC_CONN_SERVER_UNSECURED;
663
664        write_lock_bh(&trans->conn_lock);
665
666        pp = &trans->server_conns.rb_node;
667        p = NULL;
668        while (*pp) {
669                p = *pp;
670                conn = rb_entry(p, struct rxrpc_connection, node);
671
672                if (epoch < conn->epoch)
673                        pp = &(*pp)->rb_left;
674                else if (epoch > conn->epoch)
675                        pp = &(*pp)->rb_right;
676                else if (conn_id < conn->real_conn_id)
677                        pp = &(*pp)->rb_left;
678                else if (conn_id > conn->real_conn_id)
679                        pp = &(*pp)->rb_right;
680                else
681                        goto found_extant_second;
682        }
683
684        /* we can now add the new candidate to the list */
685        conn = candidate;
686        candidate = NULL;
687        rb_link_node(&conn->node, p, pp);
688        rb_insert_color(&conn->node, &trans->server_conns);
689        atomic_inc(&conn->trans->usage);
690
691        write_unlock_bh(&trans->conn_lock);
692
693        write_lock_bh(&rxrpc_connection_lock);
694        list_add_tail(&conn->link, &rxrpc_connections);
695        write_unlock_bh(&rxrpc_connection_lock);
696
697        new = "new";
698
699success:
700        _net("CONNECTION %s %d {%x}", new, conn->debug_id, conn->real_conn_id);
701
702        _leave(" = %p {u=%d}", conn, atomic_read(&conn->usage));
703        return conn;
704
705        /* we found the connection in the list immediately */
706found_extant_connection:
707        if (hdr->securityIndex != conn->security_ix) {
708                read_unlock_bh(&trans->conn_lock);
709                goto security_mismatch;
710        }
711        atomic_inc(&conn->usage);
712        read_unlock_bh(&trans->conn_lock);
713        goto success;
714
715        /* we found the connection on the second time through the list */
716found_extant_second:
717        if (hdr->securityIndex != conn->security_ix) {
718                write_unlock_bh(&trans->conn_lock);
719                goto security_mismatch;
720        }
721        atomic_inc(&conn->usage);
722        write_unlock_bh(&trans->conn_lock);
723        kfree(candidate);
724        goto success;
725
726security_mismatch:
727        kfree(candidate);
728        _leave(" = -EKEYREJECTED");
729        return ERR_PTR(-EKEYREJECTED);
730}
731
732/*
733 * find a connection based on transport and RxRPC connection ID for an incoming
734 * packet
735 */
736struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *trans,
737                                               struct rxrpc_header *hdr)
738{
739        struct rxrpc_connection *conn;
740        struct rb_node *p;
741        __be32 epoch;
742        u32 conn_id;
743
744        _enter(",{%x,%x}", ntohl(hdr->cid), hdr->flags);
745
746        read_lock_bh(&trans->conn_lock);
747
748        conn_id = ntohl(hdr->cid) & RXRPC_CIDMASK;
749        epoch = hdr->epoch;
750
751        if (hdr->flags & RXRPC_CLIENT_INITIATED)
752                p = trans->server_conns.rb_node;
753        else
754                p = trans->client_conns.rb_node;
755
756        while (p) {
757                conn = rb_entry(p, struct rxrpc_connection, node);
758
759                _debug("maybe %x", conn->real_conn_id);
760
761                if (epoch < conn->epoch)
762                        p = p->rb_left;
763                else if (epoch > conn->epoch)
764                        p = p->rb_right;
765                else if (conn_id < conn->real_conn_id)
766                        p = p->rb_left;
767                else if (conn_id > conn->real_conn_id)
768                        p = p->rb_right;
769                else
770                        goto found;
771        }
772
773        read_unlock_bh(&trans->conn_lock);
774        _leave(" = NULL");
775        return NULL;
776
777found:
778        atomic_inc(&conn->usage);
779        read_unlock_bh(&trans->conn_lock);
780        _leave(" = %p", conn);
781        return conn;
782}
783
784/*
785 * release a virtual connection
786 */
787void rxrpc_put_connection(struct rxrpc_connection *conn)
788{
789        _enter("%p{u=%d,d=%d}",
790               conn, atomic_read(&conn->usage), conn->debug_id);
791
792        ASSERTCMP(atomic_read(&conn->usage), >, 0);
793
794        conn->put_time = get_seconds();
795        if (atomic_dec_and_test(&conn->usage)) {
796                _debug("zombie");
797                rxrpc_queue_delayed_work(&rxrpc_connection_reap, 0);
798        }
799
800        _leave("");
801}
802
803/*
804 * destroy a virtual connection
805 */
806static void rxrpc_destroy_connection(struct rxrpc_connection *conn)
807{
808        _enter("%p{%d}", conn, atomic_read(&conn->usage));
809
810        ASSERTCMP(atomic_read(&conn->usage), ==, 0);
811
812        _net("DESTROY CONN %d", conn->debug_id);
813
814        if (conn->bundle)
815                rxrpc_put_bundle(conn->trans, conn->bundle);
816
817        ASSERT(RB_EMPTY_ROOT(&conn->calls));
818        rxrpc_purge_queue(&conn->rx_queue);
819
820        rxrpc_clear_conn_security(conn);
821        rxrpc_put_transport(conn->trans);
822        kfree(conn);
823        _leave("");
824}
825
826/*
827 * reap dead connections
828 */
829void rxrpc_connection_reaper(struct work_struct *work)
830{
831        struct rxrpc_connection *conn, *_p;
832        unsigned long now, earliest, reap_time;
833
834        LIST_HEAD(graveyard);
835
836        _enter("");
837
838        now = get_seconds();
839        earliest = ULONG_MAX;
840
841        write_lock_bh(&rxrpc_connection_lock);
842        list_for_each_entry_safe(conn, _p, &rxrpc_connections, link) {
843                _debug("reap CONN %d { u=%d,t=%ld }",
844                       conn->debug_id, atomic_read(&conn->usage),
845                       (long) now - (long) conn->put_time);
846
847                if (likely(atomic_read(&conn->usage) > 0))
848                        continue;
849
850                spin_lock(&conn->trans->client_lock);
851                write_lock(&conn->trans->conn_lock);
852                reap_time = conn->put_time + rxrpc_connection_timeout;
853
854                if (atomic_read(&conn->usage) > 0) {
855                        ;
856                } else if (reap_time <= now) {
857                        list_move_tail(&conn->link, &graveyard);
858                        if (conn->out_clientflag)
859                                rb_erase(&conn->node,
860                                         &conn->trans->client_conns);
861                        else
862                                rb_erase(&conn->node,
863                                         &conn->trans->server_conns);
864                        if (conn->bundle) {
865                                list_del_init(&conn->bundle_link);
866                                conn->bundle->num_conns--;
867                        }
868
869                } else if (reap_time < earliest) {
870                        earliest = reap_time;
871                }
872
873                write_unlock(&conn->trans->conn_lock);
874                spin_unlock(&conn->trans->client_lock);
875        }
876        write_unlock_bh(&rxrpc_connection_lock);
877
878        if (earliest != ULONG_MAX) {
879                _debug("reschedule reaper %ld", (long) earliest - now);
880                ASSERTCMP(earliest, >, now);
881                rxrpc_queue_delayed_work(&rxrpc_connection_reap,
882                                         (earliest - now) * HZ);
883        }
884
885        /* then destroy all those pulled out */
886        while (!list_empty(&graveyard)) {
887                conn = list_entry(graveyard.next, struct rxrpc_connection,
888                                  link);
889                list_del_init(&conn->link);
890
891                ASSERTCMP(atomic_read(&conn->usage), ==, 0);
892                rxrpc_destroy_connection(conn);
893        }
894
895        _leave("");
896}
897
898/*
899 * preemptively destroy all the connection records rather than waiting for them
900 * to time out
901 */
902void __exit rxrpc_destroy_all_connections(void)
903{
904        _enter("");
905
906        rxrpc_connection_timeout = 0;
907        cancel_delayed_work(&rxrpc_connection_reap);
908        rxrpc_queue_delayed_work(&rxrpc_connection_reap, 0);
909
910        _leave("");
911}