local_object.c 11.3 KB
Newer Older
1
/* Local endpoint object management
2
 *
3
 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
4 5 6
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public Licence
8
 * as published by the Free Software Foundation; either version
9
 * 2 of the Licence, or (at your option) any later version.
10 11
 */

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

14 15 16
#include <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
17
#include <linux/slab.h>
18 19
#include <linux/udp.h>
#include <linux/ip.h>
20
#include <linux/hashtable.h>
21 22 23 24
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include "ar-internal.h"

25 26
static void rxrpc_local_processor(struct work_struct *);
static void rxrpc_local_rcu(struct rcu_head *);
27 28

/*
29 30 31 32 33 34 35
 * Compare a local to an address.  Return -ve, 0 or +ve to indicate less than,
 * same or greater than.
 *
 * We explicitly don't compare the RxRPC service ID as we want to reject
 * conflicting uses by differing services.  Further, we don't want to share
 * addresses with different options (IPv6), so we don't compare those bits
 * either.
36
 */
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
static long rxrpc_local_cmp_key(const struct rxrpc_local *local,
				const struct sockaddr_rxrpc *srx)
{
	long diff;

	diff = ((local->srx.transport_type - srx->transport_type) ?:
		(local->srx.transport_len - srx->transport_len) ?:
		(local->srx.transport.family - srx->transport.family));
	if (diff != 0)
		return diff;

	switch (srx->transport.family) {
	case AF_INET:
		/* If the choice of UDP port is left up to the transport, then
		 * the endpoint record doesn't match.
		 */
		return ((u16 __force)local->srx.transport.sin.sin_port -
			(u16 __force)srx->transport.sin.sin_port) ?:
			memcmp(&local->srx.transport.sin.sin_addr,
			       &srx->transport.sin.sin_addr,
			       sizeof(struct in_addr));
58
#ifdef CONFIG_AF_RXRPC_IPV6
D
David Howells 已提交
59 60 61 62 63 64 65 66 67
	case AF_INET6:
		/* If the choice of UDP6 port is left up to the transport, then
		 * the endpoint record doesn't match.
		 */
		return ((u16 __force)local->srx.transport.sin6.sin6_port -
			(u16 __force)srx->transport.sin6.sin6_port) ?:
			memcmp(&local->srx.transport.sin6.sin6_addr,
			       &srx->transport.sin6.sin6_addr,
			       sizeof(struct in6_addr));
68
#endif
69 70 71 72 73 74 75 76
	default:
		BUG();
	}
}

/*
 * Allocate a new local endpoint.
 */
77 78
static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet,
					     const struct sockaddr_rxrpc *srx)
79 80 81 82 83
{
	struct rxrpc_local *local;

	local = kzalloc(sizeof(struct rxrpc_local), GFP_KERNEL);
	if (local) {
84
		atomic_set(&local->usage, 1);
85
		local->rxnet = rxnet;
86
		INIT_LIST_HEAD(&local->link);
87
		INIT_WORK(&local->processor, rxrpc_local_processor);
88 89
		init_rwsem(&local->defrag_sem);
		skb_queue_head_init(&local->reject_queue);
90
		skb_queue_head_init(&local->event_queue);
91 92
		local->client_conns = RB_ROOT;
		spin_lock_init(&local->client_conns_lock);
93 94 95 96
		spin_lock_init(&local->lock);
		rwlock_init(&local->services_lock);
		local->debug_id = atomic_inc_return(&rxrpc_debug_id);
		memcpy(&local->srx, srx, sizeof(*srx));
97
		local->srx.srx_service = 0;
98
		trace_rxrpc_local(local, rxrpc_local_new, 1, NULL);
99 100 101 102 103 104 105 106
	}

	_leave(" = %p", local);
	return local;
}

/*
 * create the local socket
107
 * - must be called with rxrpc_local_mutex locked
108
 */
109
static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
110 111 112 113
{
	struct sock *sock;
	int ret, opt;

D
David Howells 已提交
114 115
	_enter("%p{%d,%d}",
	       local, local->srx.transport_type, local->srx.transport.family);
116 117

	/* create a socket to represent the local endpoint */
118
	ret = sock_create_kern(net, local->srx.transport.family,
119
			       local->srx.transport_type, 0, &local->socket);
120 121 122 123 124 125 126 127 128
	if (ret < 0) {
		_leave(" = %d [socket]", ret);
		return ret;
	}

	/* if a local address was supplied then bind it */
	if (local->srx.transport_len > sizeof(sa_family_t)) {
		_debug("bind");
		ret = kernel_bind(local->socket,
129
				  (struct sockaddr *)&local->srx.transport,
130 131
				  local->srx.transport_len);
		if (ret < 0) {
132
			_debug("bind failed %d", ret);
133 134 135 136
			goto error;
		}
	}

137 138 139 140 141 142 143 144 145 146
	switch (local->srx.transport.family) {
	case AF_INET:
		/* we want to receive ICMP errors */
		opt = 1;
		ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
					(char *) &opt, sizeof(opt));
		if (ret < 0) {
			_debug("setsockopt failed");
			goto error;
		}
147

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
		/* we want to set the don't fragment bit */
		opt = IP_PMTUDISC_DO;
		ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
					(char *) &opt, sizeof(opt));
		if (ret < 0) {
			_debug("setsockopt failed");
			goto error;
		}
		break;

	case AF_INET6:
		/* we want to receive ICMP errors */
		opt = 1;
		ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
					(char *) &opt, sizeof(opt));
		if (ret < 0) {
			_debug("setsockopt failed");
			goto error;
		}

		/* we want to set the don't fragment bit */
		opt = IPV6_PMTUDISC_DO;
		ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
					(char *) &opt, sizeof(opt));
		if (ret < 0) {
			_debug("setsockopt failed");
			goto error;
		}
		break;

	default:
		BUG();
180 181 182 183 184 185
	}

	/* set the socket up */
	sock = local->socket->sk;
	sock->sk_user_data	= local;
	sock->sk_data_ready	= rxrpc_data_ready;
186
	sock->sk_error_report	= rxrpc_error_report;
187 188 189 190
	_leave(" = 0");
	return 0;

error:
191
	kernel_sock_shutdown(local->socket, SHUT_RDWR);
192 193 194 195 196 197 198 199 200
	local->socket->sk->sk_user_data = NULL;
	sock_release(local->socket);
	local->socket = NULL;

	_leave(" = %d", ret);
	return ret;
}

/*
201
 * Look up or create a new local endpoint using the specified local address.
202
 */
203 204
struct rxrpc_local *rxrpc_lookup_local(struct net *net,
				       const struct sockaddr_rxrpc *srx)
205 206
{
	struct rxrpc_local *local;
207
	struct rxrpc_net *rxnet = rxrpc_net(net);
208 209 210
	struct list_head *cursor;
	const char *age;
	long diff;
211 212
	int ret;

D
David Howells 已提交
213 214
	_enter("{%d,%d,%pISp}",
	       srx->transport_type, srx->transport.family, &srx->transport);
215

216
	mutex_lock(&rxnet->local_mutex);
217

218 219
	for (cursor = rxnet->local_endpoints.next;
	     cursor != &rxnet->local_endpoints;
220 221
	     cursor = cursor->next) {
		local = list_entry(cursor, struct rxrpc_local, link);
222

223 224
		diff = rxrpc_local_cmp_key(local, srx);
		if (diff < 0)
225
			continue;
226 227 228 229 230 231 232 233 234 235 236 237
		if (diff > 0)
			break;

		/* Services aren't allowed to share transport sockets, so
		 * reject that here.  It is possible that the object is dying -
		 * but it may also still have the local transport address that
		 * we want bound.
		 */
		if (srx->srx_service) {
			local = NULL;
			goto addr_in_use;
		}
238

239 240 241 242
		/* Found a match.  We replace a dying object.  Attempting to
		 * bind the transport socket may still fail if we're attempting
		 * to use a local address that the dying object is still using.
		 */
243
		if (!rxrpc_get_local_maybe(local)) {
244 245 246
			cursor = cursor->next;
			list_del_init(&local->link);
			break;
247 248
		}

249 250 251
		age = "old";
		goto found;
	}
252

253
	local = rxrpc_alloc_local(rxnet, srx);
254 255
	if (!local)
		goto nomem;
256

257
	ret = rxrpc_open_socket(local, net);
258 259 260 261 262
	if (ret < 0)
		goto sock_error;

	list_add_tail(&local->link, cursor);
	age = "new";
263

264
found:
265
	mutex_unlock(&rxnet->local_mutex);
266

D
David Howells 已提交
267 268
	_net("LOCAL %s %d {%pISp}",
	     age, local->debug_id, &local->srx.transport);
269

270
	_leave(" = %p", local);
271 272
	return local;

273 274 275
nomem:
	ret = -ENOMEM;
sock_error:
276
	mutex_unlock(&rxnet->local_mutex);
277 278 279
	kfree(local);
	_leave(" = %d", ret);
	return ERR_PTR(ret);
280

281
addr_in_use:
282
	mutex_unlock(&rxnet->local_mutex);
283 284 285
	_leave(" = -EADDRINUSE");
	return ERR_PTR(-EADDRINUSE);
}
286

287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
/*
 * Get a ref on a local endpoint.
 */
struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *local)
{
	const void *here = __builtin_return_address(0);
	int n;

	n = atomic_inc_return(&local->usage);
	trace_rxrpc_local(local, rxrpc_local_got, n, here);
	return local;
}

/*
 * Get a ref on a local endpoint unless its usage has already reached 0.
 */
struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local)
{
	const void *here = __builtin_return_address(0);

	if (local) {
308
		int n = atomic_fetch_add_unless(&local->usage, 1, 0);
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
		if (n > 0)
			trace_rxrpc_local(local, rxrpc_local_got, n + 1, here);
		else
			local = NULL;
	}
	return local;
}

/*
 * Queue a local endpoint.
 */
void rxrpc_queue_local(struct rxrpc_local *local)
{
	const void *here = __builtin_return_address(0);

	if (rxrpc_queue_work(&local->processor))
		trace_rxrpc_local(local, rxrpc_local_queued,
				  atomic_read(&local->usage), here);
}

329 330 331
/*
 * A local endpoint reached its end of life.
 */
332
static void __rxrpc_put_local(struct rxrpc_local *local)
333 334 335
{
	_enter("%d", local->debug_id);
	rxrpc_queue_work(&local->processor);
336 337
}

338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
/*
 * Drop a ref on a local endpoint.
 */
void rxrpc_put_local(struct rxrpc_local *local)
{
	const void *here = __builtin_return_address(0);
	int n;

	if (local) {
		n = atomic_dec_return(&local->usage);
		trace_rxrpc_local(local, rxrpc_local_put, n, here);

		if (n == 0)
			__rxrpc_put_local(local);
	}
}

355
/*
356 357 358 359 360
 * Destroy a local endpoint's socket and then hand the record to RCU to dispose
 * of.
 *
 * Closing the socket cannot be done from bottom half context or RCU callback
 * context because it might sleep.
361
 */
362
static void rxrpc_local_destroyer(struct rxrpc_local *local)
363
{
364
	struct socket *socket = local->socket;
365
	struct rxrpc_net *rxnet = local->rxnet;
366

367
	_enter("%d", local->debug_id);
368

369 370 371 372 373 374 375
	/* We can get a race between an incoming call packet queueing the
	 * processor again and the work processor starting the destruction
	 * process which will shut down the UDP socket.
	 */
	if (local->dead) {
		_leave(" [already dead]");
		return;
376
	}
377 378
	local->dead = true;

379
	mutex_lock(&rxnet->local_mutex);
380
	list_del_init(&local->link);
381
	mutex_unlock(&rxnet->local_mutex);
382

383
	ASSERT(RB_EMPTY_ROOT(&local->client_conns));
384
	ASSERT(!local->service);
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400

	if (socket) {
		local->socket = NULL;
		kernel_sock_shutdown(socket, SHUT_RDWR);
		socket->sk->sk_user_data = NULL;
		sock_release(socket);
	}

	/* At this point, there should be no more packets coming in to the
	 * local endpoint.
	 */
	rxrpc_purge_queue(&local->reject_queue);
	rxrpc_purge_queue(&local->event_queue);

	_debug("rcu local %d", local->debug_id);
	call_rcu(&local->rcu, rxrpc_local_rcu);
401 402 403
}

/*
404
 * Process events on an endpoint
405
 */
406
static void rxrpc_local_processor(struct work_struct *work)
407 408
{
	struct rxrpc_local *local =
409 410
		container_of(work, struct rxrpc_local, processor);
	bool again;
411

412 413
	trace_rxrpc_local(local, rxrpc_local_processing,
			  atomic_read(&local->usage), NULL);
414

415 416 417 418
	do {
		again = false;
		if (atomic_read(&local->usage) == 0)
			return rxrpc_local_destroyer(local);
419

420 421 422 423
		if (!skb_queue_empty(&local->reject_queue)) {
			rxrpc_reject_packets(local);
			again = true;
		}
424

425 426 427 428 429 430
		if (!skb_queue_empty(&local->event_queue)) {
			rxrpc_process_local_events(local);
			again = true;
		}
	} while (again);
}
431

432 433 434 435 436 437
/*
 * Destroy a local endpoint after the RCU grace period expires.
 */
static void rxrpc_local_rcu(struct rcu_head *rcu)
{
	struct rxrpc_local *local = container_of(rcu, struct rxrpc_local, rcu);
438

439
	_enter("%d", local->debug_id);
440

441
	ASSERT(!work_pending(&local->processor));
442 443 444 445 446 447 448

	_net("DESTROY LOCAL %d", local->debug_id);
	kfree(local);
	_leave("");
}

/*
449
 * Verify the local endpoint list is empty by this point.
450
 */
451
void rxrpc_destroy_all_locals(struct rxrpc_net *rxnet)
452
{
453
	struct rxrpc_local *local;
454 455 456

	_enter("");

457
	flush_workqueue(rxrpc_workqueue);
458

459 460 461
	if (!list_empty(&rxnet->local_endpoints)) {
		mutex_lock(&rxnet->local_mutex);
		list_for_each_entry(local, &rxnet->local_endpoints, link) {
462 463 464
			pr_err("AF_RXRPC: Leaked local %p {%d}\n",
			       local, atomic_read(&local->usage));
		}
465
		mutex_unlock(&rxnet->local_mutex);
466
		BUG();
467 468
	}
}