1 /* RxRPC virtual connection handler
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/net.h>
17 #include <linux/skbuff.h>
19 #include <net/af_rxrpc.h>
20 #include "ar-internal.h"
23 * Time till a connection expires after last use (in seconds).
25 unsigned int rxrpc_connection_expiry
= 10 * 60;
27 static void rxrpc_connection_reaper(struct work_struct
*work
);
29 LIST_HEAD(rxrpc_connections
);
30 DEFINE_RWLOCK(rxrpc_connection_lock
);
31 static DECLARE_DELAYED_WORK(rxrpc_connection_reap
, rxrpc_connection_reaper
);
34 * allocate a new connection
36 struct rxrpc_connection
*rxrpc_alloc_connection(gfp_t gfp
)
38 struct rxrpc_connection
*conn
;
42 conn
= kzalloc(sizeof(struct rxrpc_connection
), gfp
);
44 spin_lock_init(&conn
->channel_lock
);
45 init_waitqueue_head(&conn
->channel_wq
);
46 INIT_WORK(&conn
->processor
, &rxrpc_process_connection
);
47 INIT_LIST_HEAD(&conn
->link
);
48 skb_queue_head_init(&conn
->rx_queue
);
49 conn
->security
= &rxrpc_no_security
;
50 spin_lock_init(&conn
->state_lock
);
51 /* We maintain an extra ref on the connection whilst it is
52 * on the rxrpc_connections list.
54 atomic_set(&conn
->usage
, 2);
55 conn
->debug_id
= atomic_inc_return(&rxrpc_debug_id
);
56 atomic_set(&conn
->avail_chans
, RXRPC_MAXCALLS
);
58 conn
->header_size
= sizeof(struct rxrpc_wire_header
);
61 _leave(" = %p{%d}", conn
, conn
? conn
->debug_id
: 0);
66 * Look up a connection in the cache by protocol parameters.
68 * If successful, a pointer to the connection is returned, but no ref is taken.
69 * NULL is returned if there is no match.
71 * The caller must be holding the RCU read lock.
73 struct rxrpc_connection
*rxrpc_find_connection_rcu(struct rxrpc_local
*local
,
76 struct rxrpc_connection
*conn
;
77 struct rxrpc_conn_proto k
;
78 struct rxrpc_skb_priv
*sp
= rxrpc_skb(skb
);
79 struct sockaddr_rxrpc srx
;
80 struct rxrpc_peer
*peer
;
82 _enter(",%x", sp
->hdr
.cid
& RXRPC_CIDMASK
);
84 if (rxrpc_extract_addr_from_skb(&srx
, skb
) < 0)
87 k
.epoch
= sp
->hdr
.epoch
;
88 k
.cid
= sp
->hdr
.cid
& RXRPC_CIDMASK
;
90 /* We may have to handle mixing IPv4 and IPv6 */
91 if (srx
.transport
.family
!= local
->srx
.transport
.family
) {
92 pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
94 local
->srx
.transport
.family
);
98 k
.epoch
= sp
->hdr
.epoch
;
99 k
.cid
= sp
->hdr
.cid
& RXRPC_CIDMASK
;
101 if (sp
->hdr
.flags
& RXRPC_CLIENT_INITIATED
) {
102 /* We need to look up service connections by the full protocol
103 * parameter set. We look up the peer first as an intermediate
104 * step and then the connection from the peer's tree.
106 peer
= rxrpc_lookup_peer_rcu(local
, &srx
);
109 conn
= rxrpc_find_service_conn_rcu(peer
, skb
);
110 if (!conn
|| atomic_read(&conn
->usage
) == 0)
112 _leave(" = %p", conn
);
115 /* Look up client connections by connection ID alone as their
116 * IDs are unique for this machine.
118 conn
= idr_find(&rxrpc_client_conn_ids
,
119 sp
->hdr
.cid
>> RXRPC_CIDSHIFT
);
120 if (!conn
|| atomic_read(&conn
->usage
) == 0) {
125 if (conn
->proto
.epoch
!= k
.epoch
||
126 conn
->params
.local
!= local
)
129 peer
= conn
->params
.peer
;
130 switch (srx
.transport
.family
) {
132 if (peer
->srx
.transport
.sin
.sin_port
!=
133 srx
.transport
.sin
.sin_port
||
134 peer
->srx
.transport
.sin
.sin_addr
.s_addr
!=
135 srx
.transport
.sin
.sin_addr
.s_addr
)
142 _leave(" = %p", conn
);
152 * Disconnect a call and clear any channel it occupies when that call
153 * terminates. The caller must hold the channel_lock and must release the
154 * call's ref on the connection.
156 void __rxrpc_disconnect_call(struct rxrpc_call
*call
)
158 struct rxrpc_connection
*conn
= call
->conn
;
159 struct rxrpc_channel
*chan
= &conn
->channels
[call
->channel
];
161 _enter("%d,%d", conn
->debug_id
, call
->channel
);
163 if (rcu_access_pointer(chan
->call
) == call
) {
164 /* Save the result of the call so that we can repeat it if necessary
165 * through the channel, whilst disposing of the actual call record.
167 chan
->last_result
= call
->local_abort
;
169 chan
->last_call
= chan
->call_id
;
170 chan
->call_id
= chan
->call_counter
;
172 rcu_assign_pointer(chan
->call
, NULL
);
173 atomic_inc(&conn
->avail_chans
);
174 wake_up(&conn
->channel_wq
);
181 * Disconnect a call and clear any channel it occupies when that call
184 void rxrpc_disconnect_call(struct rxrpc_call
*call
)
186 struct rxrpc_connection
*conn
= call
->conn
;
188 spin_lock(&conn
->channel_lock
);
189 __rxrpc_disconnect_call(call
);
190 spin_unlock(&conn
->channel_lock
);
193 rxrpc_put_connection(conn
);
197 * release a virtual connection
199 void rxrpc_put_connection(struct rxrpc_connection
*conn
)
204 _enter("%p{u=%d,d=%d}",
205 conn
, atomic_read(&conn
->usage
), conn
->debug_id
);
207 ASSERTCMP(atomic_read(&conn
->usage
), >, 1);
209 conn
->put_time
= ktime_get_seconds();
210 if (atomic_dec_return(&conn
->usage
) == 1) {
212 rxrpc_queue_delayed_work(&rxrpc_connection_reap
, 0);
219 * destroy a virtual connection
221 static void rxrpc_destroy_connection(struct rcu_head
*rcu
)
223 struct rxrpc_connection
*conn
=
224 container_of(rcu
, struct rxrpc_connection
, rcu
);
226 _enter("{%d,u=%d}", conn
->debug_id
, atomic_read(&conn
->usage
));
228 ASSERTCMP(atomic_read(&conn
->usage
), ==, 0);
230 _net("DESTROY CONN %d", conn
->debug_id
);
232 rxrpc_purge_queue(&conn
->rx_queue
);
234 conn
->security
->clear(conn
);
235 key_put(conn
->params
.key
);
236 key_put(conn
->server_key
);
237 rxrpc_put_peer(conn
->params
.peer
);
238 rxrpc_put_local(conn
->params
.local
);
245 * reap dead connections
247 static void rxrpc_connection_reaper(struct work_struct
*work
)
249 struct rxrpc_connection
*conn
, *_p
;
250 unsigned long reap_older_than
, earliest
, put_time
, now
;
252 LIST_HEAD(graveyard
);
256 now
= ktime_get_seconds();
257 reap_older_than
= now
- rxrpc_connection_expiry
;
258 earliest
= ULONG_MAX
;
260 write_lock(&rxrpc_connection_lock
);
261 list_for_each_entry_safe(conn
, _p
, &rxrpc_connections
, link
) {
262 ASSERTCMP(atomic_read(&conn
->usage
), >, 0);
263 if (likely(atomic_read(&conn
->usage
) > 1))
266 put_time
= READ_ONCE(conn
->put_time
);
267 if (time_after(put_time
, reap_older_than
)) {
268 if (time_before(put_time
, earliest
))
273 /* The usage count sits at 1 whilst the object is unused on the
274 * list; we reduce that to 0 to make the object unavailable.
276 if (atomic_cmpxchg(&conn
->usage
, 1, 0) != 1)
279 if (rxrpc_conn_is_client(conn
))
280 rxrpc_unpublish_client_conn(conn
);
282 rxrpc_unpublish_service_conn(conn
);
284 list_move_tail(&conn
->link
, &graveyard
);
286 write_unlock(&rxrpc_connection_lock
);
288 if (earliest
!= ULONG_MAX
) {
289 _debug("reschedule reaper %ld", (long) earliest
- now
);
290 ASSERTCMP(earliest
, >, now
);
291 rxrpc_queue_delayed_work(&rxrpc_connection_reap
,
292 (earliest
- now
) * HZ
);
295 while (!list_empty(&graveyard
)) {
296 conn
= list_entry(graveyard
.next
, struct rxrpc_connection
,
298 list_del_init(&conn
->link
);
300 ASSERTCMP(atomic_read(&conn
->usage
), ==, 0);
301 skb_queue_purge(&conn
->rx_queue
);
302 call_rcu(&conn
->rcu
, rxrpc_destroy_connection
);
309 * preemptively destroy all the connection records rather than waiting for them
312 void __exit
rxrpc_destroy_all_connections(void)
314 struct rxrpc_connection
*conn
, *_p
;
319 rxrpc_connection_expiry
= 0;
320 cancel_delayed_work(&rxrpc_connection_reap
);
321 rxrpc_queue_delayed_work(&rxrpc_connection_reap
, 0);
322 flush_workqueue(rxrpc_workqueue
);
324 write_lock(&rxrpc_connection_lock
);
325 list_for_each_entry_safe(conn
, _p
, &rxrpc_connections
, link
) {
326 pr_err("AF_RXRPC: Leaked conn %p {%d}\n",
327 conn
, atomic_read(&conn
->usage
));
330 write_unlock(&rxrpc_connection_lock
);
333 /* Make sure the local and peer records pinned by any dying connections
337 rxrpc_destroy_client_conn_ids();