conn_object.c 11.6 KB
Newer Older
1
/* RxRPC virtual connection handler, common bits.
2
 *
3
 * Copyright (C) 2007, 2016 Red Hat, Inc. All Rights Reserved.
4 5 6 7 8 9 10 11
 * 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 License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

12 13
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

14
#include <linux/module.h>
15
#include <linux/slab.h>
16 17 18 19
#include <linux/net.h>
#include <linux/skbuff.h>
#include "ar-internal.h"

20 21 22
/*
 * Time till a connection expires after last use (in seconds).
 */
23
unsigned int rxrpc_connection_expiry = 10 * 60;
24

25 26 27
static void rxrpc_connection_reaper(struct work_struct *work);

LIST_HEAD(rxrpc_connections);
28
LIST_HEAD(rxrpc_connection_proc_list);
29 30 31
DEFINE_RWLOCK(rxrpc_connection_lock);
static DECLARE_DELAYED_WORK(rxrpc_connection_reap, rxrpc_connection_reaper);

32 33
static void rxrpc_destroy_connection(struct rcu_head *);

34 35 36
/*
 * allocate a new connection
 */
37
struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
38 39 40 41 42 43 44
{
	struct rxrpc_connection *conn;

	_enter("");

	conn = kzalloc(sizeof(struct rxrpc_connection), gfp);
	if (conn) {
45
		INIT_LIST_HEAD(&conn->cache_link);
46
		spin_lock_init(&conn->channel_lock);
47
		INIT_LIST_HEAD(&conn->waiting_calls);
48
		INIT_WORK(&conn->processor, &rxrpc_process_connection);
49
		INIT_LIST_HEAD(&conn->proc_link);
50
		INIT_LIST_HEAD(&conn->link);
51
		skb_queue_head_init(&conn->rx_queue);
52
		conn->security = &rxrpc_no_security;
53 54 55
		spin_lock_init(&conn->state_lock);
		conn->debug_id = atomic_inc_return(&rxrpc_debug_id);
		conn->size_align = 4;
56
		conn->idle_timestamp = jiffies;
57 58
	}

59
	_leave(" = %p{%d}", conn, conn ? conn->debug_id : 0);
60 61 62 63
	return conn;
}

/*
64 65 66 67 68 69
 * Look up a connection in the cache by protocol parameters.
 *
 * If successful, a pointer to the connection is returned, but no ref is taken.
 * NULL is returned if there is no match.
 *
 * The caller must be holding the RCU read lock.
70
 */
71 72
struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
						   struct sk_buff *skb)
73 74
{
	struct rxrpc_connection *conn;
75
	struct rxrpc_conn_proto k;
76
	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
77 78
	struct sockaddr_rxrpc srx;
	struct rxrpc_peer *peer;
79

80
	_enter(",%x", sp->hdr.cid & RXRPC_CIDMASK);
81

82 83
	if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
		goto not_found;
84

85 86 87
	k.epoch	= sp->hdr.epoch;
	k.cid	= sp->hdr.cid & RXRPC_CIDMASK;

88 89 90 91 92 93 94 95 96 97
	/* We may have to handle mixing IPv4 and IPv6 */
	if (srx.transport.family != local->srx.transport.family) {
		pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
				    srx.transport.family,
				    local->srx.transport.family);
		goto not_found;
	}

	k.epoch	= sp->hdr.epoch;
	k.cid	= sp->hdr.cid & RXRPC_CIDMASK;
98

99
	if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) {
100 101 102 103 104 105 106
		/* We need to look up service connections by the full protocol
		 * parameter set.  We look up the peer first as an intermediate
		 * step and then the connection from the peer's tree.
		 */
		peer = rxrpc_lookup_peer_rcu(local, &srx);
		if (!peer)
			goto not_found;
107 108 109 110 111
		conn = rxrpc_find_service_conn_rcu(peer, skb);
		if (!conn || atomic_read(&conn->usage) == 0)
			goto not_found;
		_leave(" = %p", conn);
		return conn;
112
	} else {
113 114 115
		/* Look up client connections by connection ID alone as their
		 * IDs are unique for this machine.
		 */
116
		conn = idr_find(&rxrpc_client_conn_ids,
117 118 119 120 121 122 123
				sp->hdr.cid >> RXRPC_CIDSHIFT);
		if (!conn || atomic_read(&conn->usage) == 0) {
			_debug("no conn");
			goto not_found;
		}

		if (conn->proto.epoch != k.epoch ||
124 125 126 127 128 129 130 131 132 133 134 135
		    conn->params.local != local)
			goto not_found;

		peer = conn->params.peer;
		switch (srx.transport.family) {
		case AF_INET:
			if (peer->srx.transport.sin.sin_port !=
			    srx.transport.sin.sin_port ||
			    peer->srx.transport.sin.sin_addr.s_addr !=
			    srx.transport.sin.sin_addr.s_addr)
				goto not_found;
			break;
136
#ifdef CONFIG_AF_RXRPC_IPV6
D
David Howells 已提交
137 138 139 140 141 142 143 144
		case AF_INET6:
			if (peer->srx.transport.sin6.sin6_port !=
			    srx.transport.sin6.sin6_port ||
			    memcmp(&peer->srx.transport.sin6.sin6_addr,
				   &srx.transport.sin6.sin6_addr,
				   sizeof(struct in6_addr)) != 0)
				goto not_found;
			break;
145
#endif
146 147 148 149 150 151
		default:
			BUG();
		}

		_leave(" = %p", conn);
		return conn;
152 153
	}

154
not_found:
155 156 157 158
	_leave(" = NULL");
	return NULL;
}

159 160
/*
 * Disconnect a call and clear any channel it occupies when that call
161 162
 * terminates.  The caller must hold the channel_lock and must release the
 * call's ref on the connection.
163
 */
164 165
void __rxrpc_disconnect_call(struct rxrpc_connection *conn,
			     struct rxrpc_call *call)
166
{
167 168
	struct rxrpc_channel *chan =
		&conn->channels[call->cid & RXRPC_CHANNELMASK];
169

170
	_enter("%d,%x", conn->debug_id, call->cid);
171

172 173 174 175
	if (rcu_access_pointer(chan->call) == call) {
		/* Save the result of the call so that we can repeat it if necessary
		 * through the channel, whilst disposing of the actual call record.
		 */
D
David Howells 已提交
176
		trace_rxrpc_disconnect_call(call);
177
		chan->last_service_id = call->service_id;
178 179
		if (call->abort_code) {
			chan->last_abort = call->abort_code;
180 181
			chan->last_type = RXRPC_PACKET_TYPE_ABORT;
		} else {
182
			chan->last_seq = call->rx_hard_ack;
183 184 185
			chan->last_type = RXRPC_PACKET_TYPE_ACK;
		}
		/* Sync with rxrpc_conn_retransmit(). */
186 187 188
		smp_wmb();
		chan->last_call = chan->call_id;
		chan->call_id = chan->call_counter;
189

190
		rcu_assign_pointer(chan->call, NULL);
191
	}
192

193 194 195 196 197 198 199 200 201 202 203
	_leave("");
}

/*
 * Disconnect a call and clear any channel it occupies when that call
 * terminates.
 */
void rxrpc_disconnect_call(struct rxrpc_call *call)
{
	struct rxrpc_connection *conn = call->conn;

204 205 206 207
	spin_lock_bh(&conn->params.peer->lock);
	hlist_del_init(&call->error_link);
	spin_unlock_bh(&conn->params.peer->lock);

208 209 210
	if (rxrpc_is_client_call(call))
		return rxrpc_disconnect_client_call(call);

211
	spin_lock(&conn->channel_lock);
212
	__rxrpc_disconnect_call(conn, call);
213 214 215
	spin_unlock(&conn->channel_lock);

	call->conn = NULL;
216
	conn->idle_timestamp = jiffies;
217
	rxrpc_put_connection(conn);
218 219
}

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
/*
 * Kill off a connection.
 */
void rxrpc_kill_connection(struct rxrpc_connection *conn)
{
	ASSERT(!rcu_access_pointer(conn->channels[0].call) &&
	       !rcu_access_pointer(conn->channels[1].call) &&
	       !rcu_access_pointer(conn->channels[2].call) &&
	       !rcu_access_pointer(conn->channels[3].call));
	ASSERT(list_empty(&conn->cache_link));

	write_lock(&rxrpc_connection_lock);
	list_del_init(&conn->proc_link);
	write_unlock(&rxrpc_connection_lock);

	/* Drain the Rx queue.  Note that even though we've unpublished, an
	 * incoming packet could still be being added to our Rx queue, so we
	 * will need to drain it again in the RCU cleanup handler.
	 */
	rxrpc_purge_queue(&conn->rx_queue);

	/* Leave final destruction to RCU.  The connection processor work item
	 * must carry a ref on the connection to prevent us getting here whilst
	 * it is queued or running.
	 */
	call_rcu(&conn->rcu, rxrpc_destroy_connection);
}

248
/*
249 250
 * Queue a connection's work processor, getting a ref to pass to the work
 * queue.
251
 */
252
bool rxrpc_queue_conn(struct rxrpc_connection *conn)
253
{
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
	const void *here = __builtin_return_address(0);
	int n = __atomic_add_unless(&conn->usage, 1, 0);
	if (n == 0)
		return false;
	if (rxrpc_queue_work(&conn->processor))
		trace_rxrpc_conn(conn, rxrpc_conn_queued, n + 1, here);
	else
		rxrpc_put_connection(conn);
	return true;
}

/*
 * Note the re-emergence of a connection.
 */
void rxrpc_see_connection(struct rxrpc_connection *conn)
{
	const void *here = __builtin_return_address(0);
	if (conn) {
		int n = atomic_read(&conn->usage);

		trace_rxrpc_conn(conn, rxrpc_conn_seen, n, here);
	}
}

/*
 * Get a ref on a connection.
 */
void rxrpc_get_connection(struct rxrpc_connection *conn)
{
	const void *here = __builtin_return_address(0);
	int n = atomic_inc_return(&conn->usage);

	trace_rxrpc_conn(conn, rxrpc_conn_got, n, here);
}

/*
 * Try to get a ref on a connection.
 */
struct rxrpc_connection *
rxrpc_get_connection_maybe(struct rxrpc_connection *conn)
{
	const void *here = __builtin_return_address(0);

	if (conn) {
		int n = __atomic_add_unless(&conn->usage, 1, 0);
		if (n > 0)
			trace_rxrpc_conn(conn, rxrpc_conn_got, n + 1, here);
		else
			conn = NULL;
	}
	return conn;
}

/*
 * Release a service connection
 */
void rxrpc_put_service_conn(struct rxrpc_connection *conn)
{
	const void *here = __builtin_return_address(0);
	int n;

	n = atomic_dec_return(&conn->usage);
	trace_rxrpc_conn(conn, rxrpc_conn_put_service, n, here);
	ASSERTCMP(n, >=, 0);
	if (n == 0)
		rxrpc_queue_delayed_work(&rxrpc_connection_reap, 0);
320 321 322 323 324
}

/*
 * destroy a virtual connection
 */
325
static void rxrpc_destroy_connection(struct rcu_head *rcu)
326
{
327 328 329 330
	struct rxrpc_connection *conn =
		container_of(rcu, struct rxrpc_connection, rcu);

	_enter("{%d,u=%d}", conn->debug_id, atomic_read(&conn->usage));
331 332 333 334 335 336 337

	ASSERTCMP(atomic_read(&conn->usage), ==, 0);

	_net("DESTROY CONN %d", conn->debug_id);

	rxrpc_purge_queue(&conn->rx_queue);

338
	conn->security->clear(conn);
339
	key_put(conn->params.key);
340
	key_put(conn->server_key);
341 342
	rxrpc_put_peer(conn->params.peer);
	rxrpc_put_local(conn->params.local);
343

344 345 346 347 348
	kfree(conn);
	_leave("");
}

/*
349
 * reap dead service connections
350
 */
R
Roel Kluin 已提交
351
static void rxrpc_connection_reaper(struct work_struct *work)
352 353
{
	struct rxrpc_connection *conn, *_p;
354
	unsigned long reap_older_than, earliest, idle_timestamp, now;
355 356 357 358 359

	LIST_HEAD(graveyard);

	_enter("");

360 361
	now = jiffies;
	reap_older_than = now - rxrpc_connection_expiry * HZ;
362 363
	earliest = ULONG_MAX;

364
	write_lock(&rxrpc_connection_lock);
365
	list_for_each_entry_safe(conn, _p, &rxrpc_connections, link) {
366 367
		ASSERTCMP(atomic_read(&conn->usage), >, 0);
		if (likely(atomic_read(&conn->usage) > 1))
368
			continue;
369 370
		if (conn->state == RXRPC_CONN_SERVICE_PREALLOC)
			continue;
371

372 373 374 375 376 377 378 379
		idle_timestamp = READ_ONCE(conn->idle_timestamp);
		_debug("reap CONN %d { u=%d,t=%ld }",
		       conn->debug_id, atomic_read(&conn->usage),
		       (long)reap_older_than - (long)idle_timestamp);

		if (time_after(idle_timestamp, reap_older_than)) {
			if (time_before(idle_timestamp, earliest))
				earliest = idle_timestamp;
380
			continue;
381
		}
382 383 384 385 386 387 388 389

		/* The usage count sits at 1 whilst the object is unused on the
		 * list; we reduce that to 0 to make the object unavailable.
		 */
		if (atomic_cmpxchg(&conn->usage, 1, 0) != 1)
			continue;

		if (rxrpc_conn_is_client(conn))
390
			BUG();
391 392 393 394
		else
			rxrpc_unpublish_service_conn(conn);

		list_move_tail(&conn->link, &graveyard);
395
	}
396
	write_unlock(&rxrpc_connection_lock);
397 398 399

	if (earliest != ULONG_MAX) {
		_debug("reschedule reaper %ld", (long) earliest - now);
400
		ASSERT(time_after(earliest, now));
401
		rxrpc_queue_delayed_work(&rxrpc_connection_reap,
402
					 earliest - now);
403 404 405 406 407 408 409 410
	}

	while (!list_empty(&graveyard)) {
		conn = list_entry(graveyard.next, struct rxrpc_connection,
				  link);
		list_del_init(&conn->link);

		ASSERTCMP(atomic_read(&conn->usage), ==, 0);
411
		rxrpc_kill_connection(conn);
412 413 414 415 416 417
	}

	_leave("");
}

/*
418 419
 * preemptively destroy all the service connection records rather than
 * waiting for them to time out
420 421 422
 */
void __exit rxrpc_destroy_all_connections(void)
{
423 424 425
	struct rxrpc_connection *conn, *_p;
	bool leak = false;

426 427
	_enter("");

428 429
	rxrpc_destroy_all_client_connections();

430
	rxrpc_connection_expiry = 0;
431
	cancel_delayed_work(&rxrpc_connection_reap);
432
	rxrpc_queue_delayed_work(&rxrpc_connection_reap, 0);
433 434 435 436 437 438 439 440 441 442 443
	flush_workqueue(rxrpc_workqueue);

	write_lock(&rxrpc_connection_lock);
	list_for_each_entry_safe(conn, _p, &rxrpc_connections, link) {
		pr_err("AF_RXRPC: Leaked conn %p {%d}\n",
		       conn, atomic_read(&conn->usage));
		leak = true;
	}
	write_unlock(&rxrpc_connection_lock);
	BUG_ON(leak);

444 445
	ASSERT(list_empty(&rxrpc_connection_proc_list));

446 447 448 449 450
	/* Make sure the local and peer records pinned by any dying connections
	 * are released.
	 */
	rcu_barrier();
	rxrpc_destroy_client_conn_ids();
451 452 453

	_leave("");
}