Blame view

net/rxrpc/af_rxrpc.c 25.2 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
17926a793   David Howells   [AF_RXRPC]: Provi...
2
3
4
5
  /* AF_RXRPC implementation
   *
   * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   * Written by David Howells (dhowells@redhat.com)
17926a793   David Howells   [AF_RXRPC]: Provi...
6
   */
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
7
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17926a793   David Howells   [AF_RXRPC]: Provi...
8
  #include <linux/module.h>
ce6654cfc   YOSHIFUJI Hideaki / 吉藤英明   rxrpc: Use FIELD_...
9
  #include <linux/kernel.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
10
  #include <linux/net.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
11
  #include <linux/slab.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
12
  #include <linux/skbuff.h>
5f2d9c443   David Howells   rxrpc: Randomise ...
13
  #include <linux/random.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
14
15
  #include <linux/poll.h>
  #include <linux/proc_fs.h>
76181c134   David Howells   KEYS: Make reques...
16
  #include <linux/key-type.h>
457c4cbc5   Eric W. Biederman   [NET]: Make /proc...
17
  #include <net/net_namespace.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
18
19
  #include <net/sock.h>
  #include <net/af_rxrpc.h>
df844fd46   David Howells   rxrpc: Use a trac...
20
  #define CREATE_TRACE_POINTS
17926a793   David Howells   [AF_RXRPC]: Provi...
21
22
23
24
25
26
  #include "ar-internal.h"
  
  MODULE_DESCRIPTION("RxRPC network protocol");
  MODULE_AUTHOR("Red Hat, Inc.");
  MODULE_LICENSE("GPL");
  MODULE_ALIAS_NETPROTO(PF_RXRPC);
95c961747   Eric Dumazet   net: cleanup unsi...
27
  unsigned int rxrpc_debug; // = RXRPC_DEBUG_KPROTO;
d6444062f   Joe Perches   net: Use octal no...
28
  module_param_named(debug, rxrpc_debug, uint, 0644);
424b00e2c   Paul Bolle   AFS: Do not descr...
29
  MODULE_PARM_DESC(debug, "RxRPC debugging mask");
17926a793   David Howells   [AF_RXRPC]: Provi...
30

17926a793   David Howells   [AF_RXRPC]: Provi...
31
32
  static struct proto rxrpc_proto;
  static const struct proto_ops rxrpc_rpc_ops;
17926a793   David Howells   [AF_RXRPC]: Provi...
33
34
  /* current debugging ID */
  atomic_t rxrpc_debug_id;
a25e21f0b   David Howells   rxrpc, afs: Use d...
35
  EXPORT_SYMBOL(rxrpc_debug_id);
17926a793   David Howells   [AF_RXRPC]: Provi...
36
37
  
  /* count of skbs currently in use */
71f3ca408   David Howells   rxrpc: Improve sk...
38
  atomic_t rxrpc_n_tx_skbs, rxrpc_n_rx_skbs;
17926a793   David Howells   [AF_RXRPC]: Provi...
39

651350d10   David Howells   [AF_RXRPC]: Add a...
40
  struct workqueue_struct *rxrpc_workqueue;
17926a793   David Howells   [AF_RXRPC]: Provi...
41
42
43
44
45
46
47
  static void rxrpc_sock_destructor(struct sock *);
  
  /*
   * see if an RxRPC socket is currently writable
   */
  static inline int rxrpc_writable(struct sock *sk)
  {
14afee4b6   Reshetova, Elena   net: convert sock...
48
  	return refcount_read(&sk->sk_wmem_alloc) < (size_t) sk->sk_sndbuf;
17926a793   David Howells   [AF_RXRPC]: Provi...
49
50
51
52
53
54
55
56
  }
  
  /*
   * wait for write bufferage to become available
   */
  static void rxrpc_write_space(struct sock *sk)
  {
  	_enter("%p", sk);
438154823   Eric Dumazet   net: sock_def_rea...
57
  	rcu_read_lock();
17926a793   David Howells   [AF_RXRPC]: Provi...
58
  	if (rxrpc_writable(sk)) {
438154823   Eric Dumazet   net: sock_def_rea...
59
  		struct socket_wq *wq = rcu_dereference(sk->sk_wq);
1ce0bf50a   Herbert Xu   net: Generalise w...
60
  		if (skwq_has_sleeper(wq))
438154823   Eric Dumazet   net: sock_def_rea...
61
  			wake_up_interruptible(&wq->wait);
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
62
  		sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
17926a793   David Howells   [AF_RXRPC]: Provi...
63
  	}
438154823   Eric Dumazet   net: sock_def_rea...
64
  	rcu_read_unlock();
17926a793   David Howells   [AF_RXRPC]: Provi...
65
66
67
68
69
70
71
72
73
  }
  
  /*
   * validate an RxRPC address
   */
  static int rxrpc_validate_address(struct rxrpc_sock *rx,
  				  struct sockaddr_rxrpc *srx,
  				  int len)
  {
dad8aff75   David Howells   rxrpc: Replace al...
74
  	unsigned int tail;
ab802ee0a   David Howells   rxrpc: Clear the ...
75

17926a793   David Howells   [AF_RXRPC]: Provi...
76
77
78
79
80
81
82
83
84
85
86
87
88
  	if (len < sizeof(struct sockaddr_rxrpc))
  		return -EINVAL;
  
  	if (srx->srx_family != AF_RXRPC)
  		return -EAFNOSUPPORT;
  
  	if (srx->transport_type != SOCK_DGRAM)
  		return -ESOCKTNOSUPPORT;
  
  	len -= offsetof(struct sockaddr_rxrpc, transport);
  	if (srx->transport_len < sizeof(sa_family_t) ||
  	    srx->transport_len > len)
  		return -EINVAL;
46894a135   David Howells   rxrpc: Use IPv4 a...
89
90
  	if (srx->transport.family != rx->family &&
  	    srx->transport.family == AF_INET && rx->family != AF_INET6)
17926a793   David Howells   [AF_RXRPC]: Provi...
91
92
93
94
  		return -EAFNOSUPPORT;
  
  	switch (srx->transport.family) {
  	case AF_INET:
4f95dd78a   David Howells   rxrpc: Rework loc...
95
96
  		if (srx->transport_len < sizeof(struct sockaddr_in))
  			return -EINVAL;
ab802ee0a   David Howells   rxrpc: Clear the ...
97
  		tail = offsetof(struct sockaddr_rxrpc, transport.sin.__pad);
17926a793   David Howells   [AF_RXRPC]: Provi...
98
  		break;
d19127473   David Howells   rxrpc: Make IPv6 ...
99
  #ifdef CONFIG_AF_RXRPC_IPV6
17926a793   David Howells   [AF_RXRPC]: Provi...
100
  	case AF_INET6:
75b54cb57   David Howells   rxrpc: Add IPv6 s...
101
102
103
104
105
  		if (srx->transport_len < sizeof(struct sockaddr_in6))
  			return -EINVAL;
  		tail = offsetof(struct sockaddr_rxrpc, transport) +
  			sizeof(struct sockaddr_in6);
  		break;
d19127473   David Howells   rxrpc: Make IPv6 ...
106
  #endif
75b54cb57   David Howells   rxrpc: Add IPv6 s...
107

17926a793   David Howells   [AF_RXRPC]: Provi...
108
109
110
  	default:
  		return -EAFNOSUPPORT;
  	}
ab802ee0a   David Howells   rxrpc: Clear the ...
111
112
  	if (tail < len)
  		memset((void *)srx + tail, 0, len - tail);
75b54cb57   David Howells   rxrpc: Add IPv6 s...
113
  	_debug("INET: %pISp", &srx->transport);
17926a793   David Howells   [AF_RXRPC]: Provi...
114
115
116
117
118
119
120
121
  	return 0;
  }
  
  /*
   * bind a local address to an RxRPC socket
   */
  static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
  {
b4f1342f9   David Howells   rxrpc: Adjust som...
122
  	struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr;
17926a793   David Howells   [AF_RXRPC]: Provi...
123
  	struct rxrpc_local *local;
68d6d1ae5   David Howells   rxrpc: Separate t...
124
  	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
a9107a14a   Tetsuo Handa   rxrpc: Check addr...
125
  	u16 service_id;
17926a793   David Howells   [AF_RXRPC]: Provi...
126
127
128
129
130
131
132
  	int ret;
  
  	_enter("%p,%p,%d", rx, saddr, len);
  
  	ret = rxrpc_validate_address(rx, srx, len);
  	if (ret < 0)
  		goto error;
a9107a14a   Tetsuo Handa   rxrpc: Check addr...
133
  	service_id = srx->srx_service;
17926a793   David Howells   [AF_RXRPC]: Provi...
134
135
  
  	lock_sock(&rx->sk);
28036f448   David Howells   rxrpc: Permit mul...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  	switch (rx->sk.sk_state) {
  	case RXRPC_UNBOUND:
  		rx->srx = *srx;
  		local = rxrpc_lookup_local(sock_net(&rx->sk), &rx->srx);
  		if (IS_ERR(local)) {
  			ret = PTR_ERR(local);
  			goto error_unlock;
  		}
  
  		if (service_id) {
  			write_lock(&local->services_lock);
  			if (rcu_access_pointer(local->service))
  				goto service_in_use;
  			rx->local = local;
  			rcu_assign_pointer(local->service, rx);
  			write_unlock(&local->services_lock);
  
  			rx->sk.sk_state = RXRPC_SERVER_BOUND;
  		} else {
  			rx->local = local;
  			rx->sk.sk_state = RXRPC_CLIENT_BOUND;
  		}
  		break;
17926a793   David Howells   [AF_RXRPC]: Provi...
159

28036f448   David Howells   rxrpc: Permit mul...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  	case RXRPC_SERVER_BOUND:
  		ret = -EINVAL;
  		if (service_id == 0)
  			goto error_unlock;
  		ret = -EADDRINUSE;
  		if (service_id == rx->srx.srx_service)
  			goto error_unlock;
  		ret = -EINVAL;
  		srx->srx_service = rx->srx.srx_service;
  		if (memcmp(srx, &rx->srx, sizeof(*srx)) != 0)
  			goto error_unlock;
  		rx->second_service = service_id;
  		rx->sk.sk_state = RXRPC_SERVER_BOUND2;
  		break;
17926a793   David Howells   [AF_RXRPC]: Provi...
174

28036f448   David Howells   rxrpc: Permit mul...
175
176
  	default:
  		ret = -EINVAL;
17926a793   David Howells   [AF_RXRPC]: Provi...
177
178
  		goto error_unlock;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
179
180
181
182
183
  	release_sock(&rx->sk);
  	_leave(" = 0");
  	return 0;
  
  service_in_use:
248f219cb   David Howells   rxrpc: Rewrite th...
184
  	write_unlock(&local->services_lock);
730c5fd42   David Howells   rxrpc: Fix local ...
185
  	rxrpc_unuse_local(local);
04d36d748   David Howells   rxrpc: Fix missin...
186
  	rxrpc_put_local(local);
2341e0775   David Howells   rxrpc: Simplify c...
187
  	ret = -EADDRINUSE;
17926a793   David Howells   [AF_RXRPC]: Provi...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  error_unlock:
  	release_sock(&rx->sk);
  error:
  	_leave(" = %d", ret);
  	return ret;
  }
  
  /*
   * set the number of pending calls permitted on a listening socket
   */
  static int rxrpc_listen(struct socket *sock, int backlog)
  {
  	struct sock *sk = sock->sk;
  	struct rxrpc_sock *rx = rxrpc_sk(sk);
00e907127   David Howells   rxrpc: Preallocat...
202
  	unsigned int max, old;
17926a793   David Howells   [AF_RXRPC]: Provi...
203
204
205
206
207
208
209
  	int ret;
  
  	_enter("%p,%d", rx, backlog);
  
  	lock_sock(&rx->sk);
  
  	switch (rx->sk.sk_state) {
2341e0775   David Howells   rxrpc: Simplify c...
210
  	case RXRPC_UNBOUND:
17926a793   David Howells   [AF_RXRPC]: Provi...
211
212
  		ret = -EADDRNOTAVAIL;
  		break;
17926a793   David Howells   [AF_RXRPC]: Provi...
213
  	case RXRPC_SERVER_BOUND:
28036f448   David Howells   rxrpc: Permit mul...
214
  	case RXRPC_SERVER_BOUND2:
17926a793   David Howells   [AF_RXRPC]: Provi...
215
  		ASSERT(rx->local != NULL);
0e119b41b   David Howells   rxrpc: Limit the ...
216
217
218
219
220
221
  		max = READ_ONCE(rxrpc_max_backlog);
  		ret = -EINVAL;
  		if (backlog == INT_MAX)
  			backlog = max;
  		else if (backlog < 0 || backlog > max)
  			break;
00e907127   David Howells   rxrpc: Preallocat...
222
  		old = sk->sk_max_ack_backlog;
17926a793   David Howells   [AF_RXRPC]: Provi...
223
  		sk->sk_max_ack_backlog = backlog;
00e907127   David Howells   rxrpc: Preallocat...
224
225
226
227
228
  		ret = rxrpc_service_prealloc(rx, GFP_KERNEL);
  		if (ret == 0)
  			rx->sk.sk_state = RXRPC_SERVER_LISTENING;
  		else
  			sk->sk_max_ack_backlog = old;
17926a793   David Howells   [AF_RXRPC]: Provi...
229
  		break;
210f03531   David Howells   rxrpc: Allow list...
230
231
232
233
234
235
236
237
  	case RXRPC_SERVER_LISTENING:
  		if (backlog == 0) {
  			rx->sk.sk_state = RXRPC_SERVER_LISTEN_DISABLED;
  			sk->sk_max_ack_backlog = 0;
  			rxrpc_discard_prealloc(rx);
  			ret = 0;
  			break;
  		}
df561f668   Gustavo A. R. Silva   treewide: Use fal...
238
  		fallthrough;
0e119b41b   David Howells   rxrpc: Limit the ...
239
240
241
  	default:
  		ret = -EBUSY;
  		break;
17926a793   David Howells   [AF_RXRPC]: Provi...
242
243
244
245
246
247
  	}
  
  	release_sock(&rx->sk);
  	_leave(" = %d", ret);
  	return ret;
  }
651350d10   David Howells   [AF_RXRPC]: Add a...
248
249
250
  /**
   * rxrpc_kernel_begin_call - Allow a kernel service to begin a call
   * @sock: The socket on which to make the call
2341e0775   David Howells   rxrpc: Simplify c...
251
   * @srx: The address of the peer to contact
651350d10   David Howells   [AF_RXRPC]: Add a...
252
253
   * @key: The security context to use (defaults to socket setting)
   * @user_call_ID: The ID to use
e754eba68   David Howells   rxrpc: Provide a ...
254
   * @tx_total_len: Total length of data to transmit during the call (or -1)
d001648ec   David Howells   rxrpc: Don't expo...
255
256
   * @gfp: The allocation constraints
   * @notify_rx: Where to send notifications instead of socket queue
a68f4a27f   David Howells   rxrpc: Support se...
257
   * @upgrade: Request service upgrade for call
76f2fe73c   Andrew Lunn   net: rxrpc: kerne...
258
   * @interruptibility: The call is interruptible, or can be canceled.
a25e21f0b   David Howells   rxrpc, afs: Use d...
259
   * @debug_id: The debug ID for tracing to be assigned to the call
651350d10   David Howells   [AF_RXRPC]: Add a...
260
261
262
263
264
265
266
267
268
269
270
271
   *
   * Allow a kernel service to begin a call on the nominated socket.  This just
   * sets up all the internal tracking structures and allocates connection and
   * call IDs as appropriate.  The call to be used is returned.
   *
   * The default socket destination address and security may be overridden by
   * supplying @srx and @key.
   */
  struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
  					   struct sockaddr_rxrpc *srx,
  					   struct key *key,
  					   unsigned long user_call_ID,
e754eba68   David Howells   rxrpc: Provide a ...
272
  					   s64 tx_total_len,
d001648ec   David Howells   rxrpc: Don't expo...
273
  					   gfp_t gfp,
a68f4a27f   David Howells   rxrpc: Support se...
274
  					   rxrpc_notify_rx_t notify_rx,
a25e21f0b   David Howells   rxrpc, afs: Use d...
275
  					   bool upgrade,
e138aa7d3   David Howells   rxrpc: Fix call i...
276
  					   enum rxrpc_interruptibility interruptibility,
a25e21f0b   David Howells   rxrpc, afs: Use d...
277
  					   unsigned int debug_id)
651350d10   David Howells   [AF_RXRPC]: Add a...
278
  {
19ffa01c9   David Howells   rxrpc: Use struct...
279
  	struct rxrpc_conn_parameters cp;
481241789   David Howells   rxrpc: Split the ...
280
  	struct rxrpc_call_params p;
651350d10   David Howells   [AF_RXRPC]: Add a...
281
282
  	struct rxrpc_call *call;
  	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
f4552c2d2   David Howells   rxrpc: Validate t...
283
  	int ret;
651350d10   David Howells   [AF_RXRPC]: Add a...
284
285
  
  	_enter(",,%x,%lx", key_serial(key), user_call_ID);
f4552c2d2   David Howells   rxrpc: Validate t...
286
287
288
  	ret = rxrpc_validate_address(rx, srx, sizeof(*srx));
  	if (ret < 0)
  		return ERR_PTR(ret);
651350d10   David Howells   [AF_RXRPC]: Add a...
289
  	lock_sock(&rx->sk);
19ffa01c9   David Howells   rxrpc: Use struct...
290
291
292
293
  	if (!key)
  		key = rx->key;
  	if (key && !key->payload.data[0])
  		key = NULL; /* a no-security key */
481241789   David Howells   rxrpc: Split the ...
294
  	memset(&p, 0, sizeof(p));
b7a7d6740   David Howells   rxrpc: Impose a m...
295
296
297
298
  	p.user_call_ID		= user_call_ID;
  	p.tx_total_len		= tx_total_len;
  	p.interruptibility	= interruptibility;
  	p.kernel		= true;
481241789   David Howells   rxrpc: Split the ...
299

19ffa01c9   David Howells   rxrpc: Use struct...
300
301
302
  	memset(&cp, 0, sizeof(cp));
  	cp.local		= rx->local;
  	cp.key			= key;
93864fc3f   David Howells   rxrpc: Fix the mi...
303
  	cp.security_level	= rx->min_sec_level;
19ffa01c9   David Howells   rxrpc: Use struct...
304
  	cp.exclusive		= false;
a68f4a27f   David Howells   rxrpc: Support se...
305
  	cp.upgrade		= upgrade;
19ffa01c9   David Howells   rxrpc: Use struct...
306
  	cp.service_id		= srx->srx_service;
a25e21f0b   David Howells   rxrpc, afs: Use d...
307
  	call = rxrpc_new_client_call(rx, &cp, srx, &p, gfp, debug_id);
540b1c48c   David Howells   rxrpc: Fix deadlo...
308
  	/* The socket has been unlocked. */
6cb3ece96   David Howells   rxrpc: Don't rele...
309
  	if (!IS_ERR(call)) {
d001648ec   David Howells   rxrpc: Don't expo...
310
  		call->notify_rx = notify_rx;
6cb3ece96   David Howells   rxrpc: Don't rele...
311
312
  		mutex_unlock(&call->user_mutex);
  	}
19ffa01c9   David Howells   rxrpc: Use struct...
313

17226f124   David Howells   rxrpc: Fix leak o...
314
  	rxrpc_put_peer(cp.peer);
651350d10   David Howells   [AF_RXRPC]: Add a...
315
316
317
  	_leave(" = %p", call);
  	return call;
  }
651350d10   David Howells   [AF_RXRPC]: Add a...
318
  EXPORT_SYMBOL(rxrpc_kernel_begin_call);
20acbd9a7   David Howells   rxrpc: Lock aroun...
319
320
321
322
323
324
325
  /*
   * Dummy function used to stop the notifier talking to recvmsg().
   */
  static void rxrpc_dummy_notify_rx(struct sock *sk, struct rxrpc_call *rxcall,
  				  unsigned long call_user_ID)
  {
  }
651350d10   David Howells   [AF_RXRPC]: Add a...
326
327
  /**
   * rxrpc_kernel_end_call - Allow a kernel service to end a call it was using
4de48af66   David Howells   rxrpc: Pass struc...
328
   * @sock: The socket the call is on
651350d10   David Howells   [AF_RXRPC]: Add a...
329
330
331
332
333
   * @call: The call to end
   *
   * Allow a kernel service to end a call it was using.  The call must be
   * complete before this is called (the call should be aborted if necessary).
   */
4de48af66   David Howells   rxrpc: Pass struc...
334
  void rxrpc_kernel_end_call(struct socket *sock, struct rxrpc_call *call)
651350d10   David Howells   [AF_RXRPC]: Add a...
335
336
  {
  	_enter("%d{%d}", call->debug_id, atomic_read(&call->usage));
540b1c48c   David Howells   rxrpc: Fix deadlo...
337
338
  
  	mutex_lock(&call->user_mutex);
8d94aa381   David Howells   rxrpc: Calls shou...
339
  	rxrpc_release_call(rxrpc_sk(sock->sk), call);
20acbd9a7   David Howells   rxrpc: Lock aroun...
340
341
342
343
344
345
346
  
  	/* Make sure we're not going to call back into a kernel service */
  	if (call->notify_rx) {
  		spin_lock_bh(&call->notify_lock);
  		call->notify_rx = rxrpc_dummy_notify_rx;
  		spin_unlock_bh(&call->notify_lock);
  	}
540b1c48c   David Howells   rxrpc: Fix deadlo...
347
  	mutex_unlock(&call->user_mutex);
cbd00891d   David Howells   rxrpc: Adjust the...
348
  	rxrpc_put_call(call, rxrpc_call_put_kernel);
651350d10   David Howells   [AF_RXRPC]: Add a...
349
  }
651350d10   David Howells   [AF_RXRPC]: Add a...
350
351
352
  EXPORT_SYMBOL(rxrpc_kernel_end_call);
  
  /**
f4d15fb6f   David Howells   rxrpc: Provide fu...
353
354
355
356
   * rxrpc_kernel_check_life - Check to see whether a call is still alive
   * @sock: The socket the call is on
   * @call: The call to check
   *
7d7587db0   David Howells   afs: Fix client c...
357
358
   * Allow a kernel service to find out whether a call is still alive -
   * ie. whether it has completed.
f4d15fb6f   David Howells   rxrpc: Provide fu...
359
   */
4611da30d   Marc Dionne   rxrpc: Make rxrpc...
360
  bool rxrpc_kernel_check_life(const struct socket *sock,
7d7587db0   David Howells   afs: Fix client c...
361
  			     const struct rxrpc_call *call)
f4d15fb6f   David Howells   rxrpc: Provide fu...
362
  {
4611da30d   Marc Dionne   rxrpc: Make rxrpc...
363
  	return call->state != RXRPC_CALL_COMPLETE;
f4d15fb6f   David Howells   rxrpc: Provide fu...
364
365
366
367
  }
  EXPORT_SYMBOL(rxrpc_kernel_check_life);
  
  /**
e908bcf4f   David Howells   rxrpc: Allow the ...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
   * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call.
   * @sock: The socket the call is on
   * @call: The call to query
   *
   * Allow a kernel service to retrieve the epoch value from a service call to
   * see if the client at the other end rebooted.
   */
  u32 rxrpc_kernel_get_epoch(struct socket *sock, struct rxrpc_call *call)
  {
  	return call->conn->proto.epoch;
  }
  EXPORT_SYMBOL(rxrpc_kernel_get_epoch);
  
  /**
d001648ec   David Howells   rxrpc: Don't expo...
382
   * rxrpc_kernel_new_call_notification - Get notifications of new calls
651350d10   David Howells   [AF_RXRPC]: Add a...
383
   * @sock: The socket to intercept received messages on
d001648ec   David Howells   rxrpc: Don't expo...
384
   * @notify_new_call: Function to be called when new calls appear
00e907127   David Howells   rxrpc: Preallocat...
385
   * @discard_new_call: Function to discard preallocated calls
651350d10   David Howells   [AF_RXRPC]: Add a...
386
   *
d001648ec   David Howells   rxrpc: Don't expo...
387
   * Allow a kernel service to be given notifications about new calls.
651350d10   David Howells   [AF_RXRPC]: Add a...
388
   */
d001648ec   David Howells   rxrpc: Don't expo...
389
390
  void rxrpc_kernel_new_call_notification(
  	struct socket *sock,
00e907127   David Howells   rxrpc: Preallocat...
391
392
  	rxrpc_notify_new_call_t notify_new_call,
  	rxrpc_discard_new_call_t discard_new_call)
651350d10   David Howells   [AF_RXRPC]: Add a...
393
394
  {
  	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
d001648ec   David Howells   rxrpc: Don't expo...
395
  	rx->notify_new_call = notify_new_call;
00e907127   David Howells   rxrpc: Preallocat...
396
  	rx->discard_new_call = discard_new_call;
651350d10   David Howells   [AF_RXRPC]: Add a...
397
  }
d001648ec   David Howells   rxrpc: Don't expo...
398
  EXPORT_SYMBOL(rxrpc_kernel_new_call_notification);
651350d10   David Howells   [AF_RXRPC]: Add a...
399

bbd172e31   David Howells   rxrpc: Provide ke...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  /**
   * rxrpc_kernel_set_max_life - Set maximum lifespan on a call
   * @sock: The socket the call is on
   * @call: The call to configure
   * @hard_timeout: The maximum lifespan of the call in jiffies
   *
   * Set the maximum lifespan of a call.  The call will end with ETIME or
   * ETIMEDOUT if it takes longer than this.
   */
  void rxrpc_kernel_set_max_life(struct socket *sock, struct rxrpc_call *call,
  			       unsigned long hard_timeout)
  {
  	unsigned long now;
  
  	mutex_lock(&call->user_mutex);
  
  	now = jiffies;
  	hard_timeout += now;
  	WRITE_ONCE(call->expect_term_by, hard_timeout);
  	rxrpc_reduce_call_timer(call, hard_timeout, now, rxrpc_timer_set_for_hard);
  
  	mutex_unlock(&call->user_mutex);
  }
  EXPORT_SYMBOL(rxrpc_kernel_set_max_life);
17926a793   David Howells   [AF_RXRPC]: Provi...
424
425
426
427
428
429
430
431
  /*
   * connect an RxRPC socket
   * - this just targets it at a specific destination; no actual connection
   *   negotiation takes place
   */
  static int rxrpc_connect(struct socket *sock, struct sockaddr *addr,
  			 int addr_len, int flags)
  {
2341e0775   David Howells   rxrpc: Simplify c...
432
433
  	struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)addr;
  	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
17926a793   David Howells   [AF_RXRPC]: Provi...
434
435
436
437
438
439
440
441
442
443
444
  	int ret;
  
  	_enter("%p,%p,%d,%d", rx, addr, addr_len, flags);
  
  	ret = rxrpc_validate_address(rx, srx, addr_len);
  	if (ret < 0) {
  		_leave(" = %d [bad addr]", ret);
  		return ret;
  	}
  
  	lock_sock(&rx->sk);
2341e0775   David Howells   rxrpc: Simplify c...
445
446
447
  	ret = -EISCONN;
  	if (test_bit(RXRPC_SOCK_CONNECTED, &rx->flags))
  		goto error;
17926a793   David Howells   [AF_RXRPC]: Provi...
448
  	switch (rx->sk.sk_state) {
2341e0775   David Howells   rxrpc: Simplify c...
449
450
451
  	case RXRPC_UNBOUND:
  		rx->sk.sk_state = RXRPC_CLIENT_UNBOUND;
  	case RXRPC_CLIENT_UNBOUND:
17926a793   David Howells   [AF_RXRPC]: Provi...
452
453
  	case RXRPC_CLIENT_BOUND:
  		break;
17926a793   David Howells   [AF_RXRPC]: Provi...
454
  	default:
2341e0775   David Howells   rxrpc: Simplify c...
455
456
  		ret = -EBUSY;
  		goto error;
17926a793   David Howells   [AF_RXRPC]: Provi...
457
  	}
2341e0775   David Howells   rxrpc: Simplify c...
458
459
460
  	rx->connect_srx = *srx;
  	set_bit(RXRPC_SOCK_CONNECTED, &rx->flags);
  	ret = 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
461

2341e0775   David Howells   rxrpc: Simplify c...
462
  error:
17926a793   David Howells   [AF_RXRPC]: Provi...
463
  	release_sock(&rx->sk);
2341e0775   David Howells   rxrpc: Simplify c...
464
  	return ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
465
466
467
468
469
470
471
472
473
474
475
  }
  
  /*
   * send a message through an RxRPC socket
   * - in a client this does a number of things:
   *   - finds/sets up a connection for the security specified (if any)
   *   - initiates a call (ID in control data)
   *   - ends the request phase of a call (if MSG_MORE is not set)
   *   - sends a call data packet
   *   - may send an abort (abort code in control data)
   */
1b7841404   Ying Xue   net: Remove iocb ...
476
  static int rxrpc_sendmsg(struct socket *sock, struct msghdr *m, size_t len)
17926a793   David Howells   [AF_RXRPC]: Provi...
477
  {
2341e0775   David Howells   rxrpc: Simplify c...
478
  	struct rxrpc_local *local;
17926a793   David Howells   [AF_RXRPC]: Provi...
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
  	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
  	int ret;
  
  	_enter(",{%d},,%zu", rx->sk.sk_state, len);
  
  	if (m->msg_flags & MSG_OOB)
  		return -EOPNOTSUPP;
  
  	if (m->msg_name) {
  		ret = rxrpc_validate_address(rx, m->msg_name, m->msg_namelen);
  		if (ret < 0) {
  			_leave(" = %d [bad addr]", ret);
  			return ret;
  		}
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
494
  	lock_sock(&rx->sk);
17926a793   David Howells   [AF_RXRPC]: Provi...
495
  	switch (rx->sk.sk_state) {
2341e0775   David Howells   rxrpc: Simplify c...
496
  	case RXRPC_UNBOUND:
e835ada07   David Howells   rxrpc: Fix send o...
497
  	case RXRPC_CLIENT_UNBOUND:
cd5892c75   David Howells   rxrpc: Create an ...
498
499
500
501
502
503
504
505
  		rx->srx.srx_family = AF_RXRPC;
  		rx->srx.srx_service = 0;
  		rx->srx.transport_type = SOCK_DGRAM;
  		rx->srx.transport.family = rx->family;
  		switch (rx->family) {
  		case AF_INET:
  			rx->srx.transport_len = sizeof(struct sockaddr_in);
  			break;
d19127473   David Howells   rxrpc: Make IPv6 ...
506
  #ifdef CONFIG_AF_RXRPC_IPV6
75b54cb57   David Howells   rxrpc: Add IPv6 s...
507
508
509
  		case AF_INET6:
  			rx->srx.transport_len = sizeof(struct sockaddr_in6);
  			break;
d19127473   David Howells   rxrpc: Make IPv6 ...
510
  #endif
cd5892c75   David Howells   rxrpc: Create an ...
511
512
513
514
  		default:
  			ret = -EAFNOSUPPORT;
  			goto error_unlock;
  		}
2baec2c3f   David Howells   rxrpc: Support ne...
515
  		local = rxrpc_lookup_local(sock_net(sock->sk), &rx->srx);
2341e0775   David Howells   rxrpc: Simplify c...
516
517
518
  		if (IS_ERR(local)) {
  			ret = PTR_ERR(local);
  			goto error_unlock;
17926a793   David Howells   [AF_RXRPC]: Provi...
519
  		}
2341e0775   David Howells   rxrpc: Simplify c...
520
521
  
  		rx->local = local;
e835ada07   David Howells   rxrpc: Fix send o...
522
  		rx->sk.sk_state = RXRPC_CLIENT_BOUND;
df561f668   Gustavo A. R. Silva   treewide: Use fal...
523
  		fallthrough;
2341e0775   David Howells   rxrpc: Simplify c...
524

17926a793   David Howells   [AF_RXRPC]: Provi...
525
  	case RXRPC_CLIENT_BOUND:
2341e0775   David Howells   rxrpc: Simplify c...
526
527
528
529
  		if (!m->msg_name &&
  		    test_bit(RXRPC_SOCK_CONNECTED, &rx->flags)) {
  			m->msg_name = &rx->connect_srx;
  			m->msg_namelen = sizeof(rx->connect_srx);
17926a793   David Howells   [AF_RXRPC]: Provi...
530
  		}
df561f668   Gustavo A. R. Silva   treewide: Use fal...
531
  		fallthrough;
2341e0775   David Howells   rxrpc: Simplify c...
532
533
534
  	case RXRPC_SERVER_BOUND:
  	case RXRPC_SERVER_LISTENING:
  		ret = rxrpc_do_sendmsg(rx, m, len);
540b1c48c   David Howells   rxrpc: Fix deadlo...
535
536
  		/* The socket has been unlocked */
  		goto out;
17926a793   David Howells   [AF_RXRPC]: Provi...
537
  	default:
2341e0775   David Howells   rxrpc: Simplify c...
538
  		ret = -EINVAL;
540b1c48c   David Howells   rxrpc: Fix deadlo...
539
  		goto error_unlock;
17926a793   David Howells   [AF_RXRPC]: Provi...
540
  	}
2341e0775   David Howells   rxrpc: Simplify c...
541
  error_unlock:
17926a793   David Howells   [AF_RXRPC]: Provi...
542
  	release_sock(&rx->sk);
540b1c48c   David Howells   rxrpc: Fix deadlo...
543
  out:
17926a793   David Howells   [AF_RXRPC]: Provi...
544
545
546
  	_leave(" = %d", ret);
  	return ret;
  }
298cd88a6   Christoph Hellwig   rxrpc: add rxrpc_...
547
548
549
550
551
552
553
554
555
556
557
558
  int rxrpc_sock_set_min_security_level(struct sock *sk, unsigned int val)
  {
  	if (sk->sk_state != RXRPC_UNBOUND)
  		return -EISCONN;
  	if (val > RXRPC_SECURITY_MAX)
  		return -EINVAL;
  	lock_sock(sk);
  	rxrpc_sk(sk)->min_sec_level = val;
  	release_sock(sk);
  	return 0;
  }
  EXPORT_SYMBOL(rxrpc_sock_set_min_security_level);
17926a793   David Howells   [AF_RXRPC]: Provi...
559
560
561
562
  /*
   * set RxRPC socket options
   */
  static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
563
  			    sockptr_t optval, unsigned int optlen)
17926a793   David Howells   [AF_RXRPC]: Provi...
564
565
  {
  	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
95c961747   Eric Dumazet   net: cleanup unsi...
566
  	unsigned int min_sec_level;
4722974d9   David Howells   rxrpc: Implement ...
567
  	u16 service_upgrade[2];
17926a793   David Howells   [AF_RXRPC]: Provi...
568
569
570
571
572
573
574
575
576
577
578
579
580
581
  	int ret;
  
  	_enter(",%d,%d,,%d", level, optname, optlen);
  
  	lock_sock(&rx->sk);
  	ret = -EOPNOTSUPP;
  
  	if (level == SOL_RXRPC) {
  		switch (optname) {
  		case RXRPC_EXCLUSIVE_CONNECTION:
  			ret = -EINVAL;
  			if (optlen != 0)
  				goto error;
  			ret = -EISCONN;
2341e0775   David Howells   rxrpc: Simplify c...
582
  			if (rx->sk.sk_state != RXRPC_UNBOUND)
17926a793   David Howells   [AF_RXRPC]: Provi...
583
  				goto error;
cc8feb8ed   David Howells   rxrpc: Fix exclus...
584
  			rx->exclusive = true;
17926a793   David Howells   [AF_RXRPC]: Provi...
585
586
587
588
589
590
591
  			goto success;
  
  		case RXRPC_SECURITY_KEY:
  			ret = -EINVAL;
  			if (rx->key)
  				goto error;
  			ret = -EISCONN;
2341e0775   David Howells   rxrpc: Simplify c...
592
  			if (rx->sk.sk_state != RXRPC_UNBOUND)
17926a793   David Howells   [AF_RXRPC]: Provi...
593
594
595
596
597
598
599
600
601
  				goto error;
  			ret = rxrpc_request_key(rx, optval, optlen);
  			goto error;
  
  		case RXRPC_SECURITY_KEYRING:
  			ret = -EINVAL;
  			if (rx->key)
  				goto error;
  			ret = -EISCONN;
2341e0775   David Howells   rxrpc: Simplify c...
602
  			if (rx->sk.sk_state != RXRPC_UNBOUND)
17926a793   David Howells   [AF_RXRPC]: Provi...
603
604
605
606
607
608
  				goto error;
  			ret = rxrpc_server_keyring(rx, optval, optlen);
  			goto error;
  
  		case RXRPC_MIN_SECURITY_LEVEL:
  			ret = -EINVAL;
95c961747   Eric Dumazet   net: cleanup unsi...
609
  			if (optlen != sizeof(unsigned int))
17926a793   David Howells   [AF_RXRPC]: Provi...
610
611
  				goto error;
  			ret = -EISCONN;
2341e0775   David Howells   rxrpc: Simplify c...
612
  			if (rx->sk.sk_state != RXRPC_UNBOUND)
17926a793   David Howells   [AF_RXRPC]: Provi...
613
  				goto error;
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
614
615
  			ret = copy_from_sockptr(&min_sec_level, optval,
  				       sizeof(unsigned int));
17926a793   David Howells   [AF_RXRPC]: Provi...
616
617
618
619
620
621
622
  			if (ret < 0)
  				goto error;
  			ret = -EINVAL;
  			if (min_sec_level > RXRPC_SECURITY_MAX)
  				goto error;
  			rx->min_sec_level = min_sec_level;
  			goto success;
4722974d9   David Howells   rxrpc: Implement ...
623
624
625
626
627
628
629
630
631
  		case RXRPC_UPGRADEABLE_SERVICE:
  			ret = -EINVAL;
  			if (optlen != sizeof(service_upgrade) ||
  			    rx->service_upgrade.from != 0)
  				goto error;
  			ret = -EISCONN;
  			if (rx->sk.sk_state != RXRPC_SERVER_BOUND2)
  				goto error;
  			ret = -EFAULT;
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
632
  			if (copy_from_sockptr(service_upgrade, optval,
4722974d9   David Howells   rxrpc: Implement ...
633
634
635
636
637
638
639
640
641
642
643
  					   sizeof(service_upgrade)) != 0)
  				goto error;
  			ret = -EINVAL;
  			if ((service_upgrade[0] != rx->srx.srx_service ||
  			     service_upgrade[1] != rx->second_service) &&
  			    (service_upgrade[0] != rx->second_service ||
  			     service_upgrade[1] != rx->srx.srx_service))
  				goto error;
  			rx->service_upgrade.from = service_upgrade[0];
  			rx->service_upgrade.to = service_upgrade[1];
  			goto success;
17926a793   David Howells   [AF_RXRPC]: Provi...
644
645
646
647
648
649
650
651
652
653
654
655
656
  		default:
  			break;
  		}
  	}
  
  success:
  	ret = 0;
  error:
  	release_sock(&rx->sk);
  	return ret;
  }
  
  /*
515559ca2   David Howells   rxrpc: Provide a ...
657
658
659
660
661
662
   * Get socket options.
   */
  static int rxrpc_getsockopt(struct socket *sock, int level, int optname,
  			    char __user *optval, int __user *_optlen)
  {
  	int optlen;
3ec0efde5   David Howells   rxrpc: Remove som...
663

515559ca2   David Howells   rxrpc: Provide a ...
664
665
666
667
668
  	if (level != SOL_RXRPC)
  		return -EOPNOTSUPP;
  
  	if (get_user(optlen, _optlen))
  		return -EFAULT;
3ec0efde5   David Howells   rxrpc: Remove som...
669

515559ca2   David Howells   rxrpc: Provide a ...
670
671
672
673
674
675
676
677
  	switch (optname) {
  	case RXRPC_SUPPORTED_CMSG:
  		if (optlen < sizeof(int))
  			return -ETOOSMALL;
  		if (put_user(RXRPC__SUPPORTED - 1, (int __user *)optval) ||
  		    put_user(sizeof(int), _optlen))
  			return -EFAULT;
  		return 0;
3ec0efde5   David Howells   rxrpc: Remove som...
678

515559ca2   David Howells   rxrpc: Provide a ...
679
680
681
682
683
684
  	default:
  		return -EOPNOTSUPP;
  	}
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
685
686
   * permit an RxRPC socket to be polled
   */
a11e1d432   Linus Torvalds   Revert changes to...
687
688
  static __poll_t rxrpc_poll(struct file *file, struct socket *sock,
  			       poll_table *wait)
17926a793   David Howells   [AF_RXRPC]: Provi...
689
  {
17926a793   David Howells   [AF_RXRPC]: Provi...
690
  	struct sock *sk = sock->sk;
248f219cb   David Howells   rxrpc: Rewrite th...
691
  	struct rxrpc_sock *rx = rxrpc_sk(sk);
a11e1d432   Linus Torvalds   Revert changes to...
692
  	__poll_t mask;
89ab066d4   Karsten Graul   Revert "net: simp...
693
  	sock_poll_wait(file, sock, wait);
a11e1d432   Linus Torvalds   Revert changes to...
694
  	mask = 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
695
696
697
  
  	/* the socket is readable if there are any messages waiting on the Rx
  	 * queue */
248f219cb   David Howells   rxrpc: Rewrite th...
698
  	if (!list_empty(&rx->recvmsg_q))
a9a08845e   Linus Torvalds   vfs: do bulk POLL...
699
  		mask |= EPOLLIN | EPOLLRDNORM;
17926a793   David Howells   [AF_RXRPC]: Provi...
700
701
702
703
704
  
  	/* the socket is writable if there is space to add new data to the
  	 * socket; there is no guarantee that any particular call in progress
  	 * on the socket may have space in the Tx ACK window */
  	if (rxrpc_writable(sk))
a9a08845e   Linus Torvalds   vfs: do bulk POLL...
705
  		mask |= EPOLLOUT | EPOLLWRNORM;
17926a793   David Howells   [AF_RXRPC]: Provi...
706
707
708
709
710
711
712
  
  	return mask;
  }
  
  /*
   * create an RxRPC socket
   */
3f378b684   Eric Paris   net: pass kern to...
713
714
  static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
  			int kern)
17926a793   David Howells   [AF_RXRPC]: Provi...
715
  {
ace45bec6   David Howells   rxrpc: Fix firewa...
716
  	struct rxrpc_net *rxnet;
17926a793   David Howells   [AF_RXRPC]: Provi...
717
718
719
720
  	struct rxrpc_sock *rx;
  	struct sock *sk;
  
  	_enter("%p,%d", sock, protocol);
b4f1342f9   David Howells   rxrpc: Adjust som...
721
  	/* we support transport protocol UDP/UDP6 only */
d19127473   David Howells   rxrpc: Make IPv6 ...
722
723
  	if (protocol != PF_INET &&
  	    IS_ENABLED(CONFIG_AF_RXRPC_IPV6) && protocol != PF_INET6)
17926a793   David Howells   [AF_RXRPC]: Provi...
724
725
726
727
728
729
730
  		return -EPROTONOSUPPORT;
  
  	if (sock->type != SOCK_DGRAM)
  		return -ESOCKTNOSUPPORT;
  
  	sock->ops = &rxrpc_rpc_ops;
  	sock->state = SS_UNCONNECTED;
11aa9c28b   Eric W. Biederman   net: Pass kern fr...
731
  	sk = sk_alloc(net, PF_RXRPC, GFP_KERNEL, &rxrpc_proto, kern);
17926a793   David Howells   [AF_RXRPC]: Provi...
732
733
734
735
  	if (!sk)
  		return -ENOMEM;
  
  	sock_init_data(sock, sk);
8d94aa381   David Howells   rxrpc: Calls shou...
736
  	sock_set_flag(sk, SOCK_RCU_FREE);
2341e0775   David Howells   rxrpc: Simplify c...
737
  	sk->sk_state		= RXRPC_UNBOUND;
17926a793   David Howells   [AF_RXRPC]: Provi...
738
  	sk->sk_write_space	= rxrpc_write_space;
0e119b41b   David Howells   rxrpc: Limit the ...
739
  	sk->sk_max_ack_backlog	= 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
740
741
742
  	sk->sk_destruct		= rxrpc_sock_destructor;
  
  	rx = rxrpc_sk(sk);
19ffa01c9   David Howells   rxrpc: Use struct...
743
  	rx->family = protocol;
17926a793   David Howells   [AF_RXRPC]: Provi...
744
  	rx->calls = RB_ROOT;
248f219cb   David Howells   rxrpc: Rewrite th...
745
746
747
748
749
  	spin_lock_init(&rx->incoming_lock);
  	INIT_LIST_HEAD(&rx->sock_calls);
  	INIT_LIST_HEAD(&rx->to_be_accepted);
  	INIT_LIST_HEAD(&rx->recvmsg_q);
  	rwlock_init(&rx->recvmsg_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
750
751
  	rwlock_init(&rx->call_lock);
  	memset(&rx->srx, 0, sizeof(rx->srx));
ace45bec6   David Howells   rxrpc: Fix firewa...
752
753
  	rxnet = rxrpc_net(sock_net(&rx->sk));
  	timer_reduce(&rxnet->peer_keepalive_timer, jiffies + 1);
17926a793   David Howells   [AF_RXRPC]: Provi...
754
755
756
757
758
  	_leave(" = 0 [%p]", rx);
  	return 0;
  }
  
  /*
248f219cb   David Howells   rxrpc: Rewrite th...
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
   * Kill all the calls on a socket and shut it down.
   */
  static int rxrpc_shutdown(struct socket *sock, int flags)
  {
  	struct sock *sk = sock->sk;
  	struct rxrpc_sock *rx = rxrpc_sk(sk);
  	int ret = 0;
  
  	_enter("%p,%d", sk, flags);
  
  	if (flags != SHUT_RDWR)
  		return -EOPNOTSUPP;
  	if (sk->sk_state == RXRPC_CLOSE)
  		return -ESHUTDOWN;
  
  	lock_sock(sk);
  
  	spin_lock_bh(&sk->sk_receive_queue.lock);
  	if (sk->sk_state < RXRPC_CLOSE) {
  		sk->sk_state = RXRPC_CLOSE;
  		sk->sk_shutdown = SHUTDOWN_MASK;
  	} else {
  		ret = -ESHUTDOWN;
  	}
  	spin_unlock_bh(&sk->sk_receive_queue.lock);
  
  	rxrpc_discard_prealloc(rx);
  
  	release_sock(sk);
  	return ret;
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
792
793
794
795
796
797
798
   * RxRPC socket destructor
   */
  static void rxrpc_sock_destructor(struct sock *sk)
  {
  	_enter("%p", sk);
  
  	rxrpc_purge_queue(&sk->sk_receive_queue);
14afee4b6   Reshetova, Elena   net: convert sock...
799
  	WARN_ON(refcount_read(&sk->sk_wmem_alloc));
547b792ca   Ilpo Järvinen   net: convert BUG_...
800
801
  	WARN_ON(!sk_unhashed(sk));
  	WARN_ON(sk->sk_socket);
17926a793   David Howells   [AF_RXRPC]: Provi...
802
803
804
805
806
807
808
809
810
811
812
813
814
815
  
  	if (!sock_flag(sk, SOCK_DEAD)) {
  		printk("Attempt to release alive rxrpc socket: %p
  ", sk);
  		return;
  	}
  }
  
  /*
   * release an RxRPC socket
   */
  static int rxrpc_release_sock(struct sock *sk)
  {
  	struct rxrpc_sock *rx = rxrpc_sk(sk);
41c6d650f   Reshetova, Elena   net: convert sock...
816
  	_enter("%p{%d,%d}", sk, sk->sk_state, refcount_read(&sk->sk_refcnt));
17926a793   David Howells   [AF_RXRPC]: Provi...
817
818
819
820
  
  	/* declare the socket closed for business */
  	sock_orphan(sk);
  	sk->sk_shutdown = SHUTDOWN_MASK;
f859ab618   David Howells   rxrpc: Fix servic...
821
822
823
824
825
826
827
828
829
830
831
832
  	/* We want to kill off all connections from a service socket
  	 * as fast as possible because we can't share these; client
  	 * sockets, on the other hand, can share an endpoint.
  	 */
  	switch (sk->sk_state) {
  	case RXRPC_SERVER_BOUND:
  	case RXRPC_SERVER_BOUND2:
  	case RXRPC_SERVER_LISTENING:
  	case RXRPC_SERVER_LISTEN_DISABLED:
  		rx->local->service_closed = true;
  		break;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
833
834
835
  	spin_lock_bh(&sk->sk_receive_queue.lock);
  	sk->sk_state = RXRPC_CLOSE;
  	spin_unlock_bh(&sk->sk_receive_queue.lock);
b63452c11   David Howells   rxrpc: Accesses o...
836
  	if (rx->local && rcu_access_pointer(rx->local->service) == rx) {
248f219cb   David Howells   rxrpc: Rewrite th...
837
  		write_lock(&rx->local->services_lock);
b63452c11   David Howells   rxrpc: Accesses o...
838
  		rcu_assign_pointer(rx->local->service, NULL);
248f219cb   David Howells   rxrpc: Rewrite th...
839
  		write_unlock(&rx->local->services_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
840
841
842
  	}
  
  	/* try to flush out this socket */
00e907127   David Howells   rxrpc: Preallocat...
843
  	rxrpc_discard_prealloc(rx);
17926a793   David Howells   [AF_RXRPC]: Provi...
844
  	rxrpc_release_calls_on_socket(rx);
651350d10   David Howells   [AF_RXRPC]: Add a...
845
  	flush_workqueue(rxrpc_workqueue);
17926a793   David Howells   [AF_RXRPC]: Provi...
846
  	rxrpc_purge_queue(&sk->sk_receive_queue);
730c5fd42   David Howells   rxrpc: Fix local ...
847
  	rxrpc_unuse_local(rx->local);
04d36d748   David Howells   rxrpc: Fix missin...
848
  	rxrpc_put_local(rx->local);
5627cc8b9   David Howells   rxrpc: Provide mo...
849
  	rx->local = NULL;
17926a793   David Howells   [AF_RXRPC]: Provi...
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
  	key_put(rx->key);
  	rx->key = NULL;
  	key_put(rx->securities);
  	rx->securities = NULL;
  	sock_put(sk);
  
  	_leave(" = 0");
  	return 0;
  }
  
  /*
   * release an RxRPC BSD socket on close() or equivalent
   */
  static int rxrpc_release(struct socket *sock)
  {
  	struct sock *sk = sock->sk;
  
  	_enter("%p{%p}", sock, sk);
  
  	if (!sk)
  		return 0;
  
  	sock->sk = NULL;
  
  	return rxrpc_release_sock(sk);
  }
  
  /*
   * RxRPC network protocol
   */
  static const struct proto_ops rxrpc_rpc_ops = {
e33b3d97b   David Howells   rxrpc: The protoc...
881
  	.family		= PF_RXRPC,
17926a793   David Howells   [AF_RXRPC]: Provi...
882
883
884
885
886
887
888
  	.owner		= THIS_MODULE,
  	.release	= rxrpc_release,
  	.bind		= rxrpc_bind,
  	.connect	= rxrpc_connect,
  	.socketpair	= sock_no_socketpair,
  	.accept		= sock_no_accept,
  	.getname	= sock_no_getname,
a11e1d432   Linus Torvalds   Revert changes to...
889
  	.poll		= rxrpc_poll,
17926a793   David Howells   [AF_RXRPC]: Provi...
890
891
  	.ioctl		= sock_no_ioctl,
  	.listen		= rxrpc_listen,
248f219cb   David Howells   rxrpc: Rewrite th...
892
  	.shutdown	= rxrpc_shutdown,
17926a793   David Howells   [AF_RXRPC]: Provi...
893
  	.setsockopt	= rxrpc_setsockopt,
515559ca2   David Howells   rxrpc: Provide a ...
894
  	.getsockopt	= rxrpc_getsockopt,
17926a793   David Howells   [AF_RXRPC]: Provi...
895
896
897
898
899
900
901
902
903
904
  	.sendmsg	= rxrpc_sendmsg,
  	.recvmsg	= rxrpc_recvmsg,
  	.mmap		= sock_no_mmap,
  	.sendpage	= sock_no_sendpage,
  };
  
  static struct proto rxrpc_proto = {
  	.name		= "RXRPC",
  	.owner		= THIS_MODULE,
  	.obj_size	= sizeof(struct rxrpc_sock),
0d12f8a40   David Howells   rxrpc: Keep the s...
905
  	.max_header	= sizeof(struct rxrpc_wire_header),
17926a793   David Howells   [AF_RXRPC]: Provi...
906
  };
ec1b4cf74   Stephen Hemminger   net: mark net_pro...
907
  static const struct net_proto_family rxrpc_family_ops = {
17926a793   David Howells   [AF_RXRPC]: Provi...
908
909
910
911
912
913
914
915
916
917
  	.family	= PF_RXRPC,
  	.create = rxrpc_create,
  	.owner	= THIS_MODULE,
  };
  
  /*
   * initialise and register the RxRPC protocol
   */
  static int __init af_rxrpc_init(void)
  {
17926a793   David Howells   [AF_RXRPC]: Provi...
918
  	int ret = -1;
444306129   Matthew Wilcox   rxrpc: abstract a...
919
  	unsigned int tmp;
17926a793   David Howells   [AF_RXRPC]: Provi...
920

c593642c8   Pankaj Bharadiya   treewide: Use siz...
921
  	BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > sizeof_field(struct sk_buff, cb));
17926a793   David Howells   [AF_RXRPC]: Provi...
922

444306129   Matthew Wilcox   rxrpc: abstract a...
923
924
925
926
927
  	get_random_bytes(&tmp, sizeof(tmp));
  	tmp &= 0x3fffffff;
  	if (tmp == 0)
  		tmp = 1;
  	idr_set_cursor(&rxrpc_client_conn_ids, tmp);
17926a793   David Howells   [AF_RXRPC]: Provi...
928

651350d10   David Howells   [AF_RXRPC]: Add a...
929
  	ret = -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
930
931
  	rxrpc_call_jar = kmem_cache_create(
  		"rxrpc_call_jar", sizeof(struct rxrpc_call), 0,
20c2df83d   Paul Mundt   mm: Remove slab d...
932
  		SLAB_HWCACHE_ALIGN, NULL);
17926a793   David Howells   [AF_RXRPC]: Provi...
933
  	if (!rxrpc_call_jar) {
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
934
935
  		pr_notice("Failed to allocate call jar
  ");
17926a793   David Howells   [AF_RXRPC]: Provi...
936
937
  		goto error_call_jar;
  	}
e1fcc7e2a   Tejun Heo   rxrpc: rxrpc_work...
938
  	rxrpc_workqueue = alloc_workqueue("krxrpcd", 0, 1);
651350d10   David Howells   [AF_RXRPC]: Add a...
939
  	if (!rxrpc_workqueue) {
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
940
941
  		pr_notice("Failed to allocate work queue
  ");
651350d10   David Howells   [AF_RXRPC]: Add a...
942
943
  		goto error_work_queue;
  	}
648af7fca   David Howells   rxrpc: Absorb the...
944
945
  	ret = rxrpc_init_security();
  	if (ret < 0) {
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
946
947
  		pr_crit("Cannot initialise security
  ");
648af7fca   David Howells   rxrpc: Absorb the...
948
949
  		goto error_security;
  	}
2baec2c3f   David Howells   rxrpc: Support ne...
950
951
952
  	ret = register_pernet_subsys(&rxrpc_net_ops);
  	if (ret)
  		goto error_pernet;
17926a793   David Howells   [AF_RXRPC]: Provi...
953
  	ret = proto_register(&rxrpc_proto, 1);
1c899641a   YOSHIFUJI Hideaki   [NET] RXRPC: Fix ...
954
  	if (ret < 0) {
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
955
956
  		pr_crit("Cannot register protocol
  ");
17926a793   David Howells   [AF_RXRPC]: Provi...
957
958
959
960
961
  		goto error_proto;
  	}
  
  	ret = sock_register(&rxrpc_family_ops);
  	if (ret < 0) {
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
962
963
  		pr_crit("Cannot register socket family
  ");
17926a793   David Howells   [AF_RXRPC]: Provi...
964
965
966
967
968
  		goto error_sock;
  	}
  
  	ret = register_key_type(&key_type_rxrpc);
  	if (ret < 0) {
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
969
970
  		pr_crit("Cannot register client key type
  ");
17926a793   David Howells   [AF_RXRPC]: Provi...
971
972
973
974
975
  		goto error_key_type;
  	}
  
  	ret = register_key_type(&key_type_rxrpc_s);
  	if (ret < 0) {
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
976
977
  		pr_crit("Cannot register server key type
  ");
17926a793   David Howells   [AF_RXRPC]: Provi...
978
979
  		goto error_key_type_s;
  	}
5873c0834   David Howells   af_rxrpc: Add sys...
980
981
  	ret = rxrpc_sysctl_init();
  	if (ret < 0) {
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
982
983
  		pr_crit("Cannot register sysctls
  ");
5873c0834   David Howells   af_rxrpc: Add sys...
984
985
  		goto error_sysctls;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
986
  	return 0;
5873c0834   David Howells   af_rxrpc: Add sys...
987
988
  error_sysctls:
  	unregister_key_type(&key_type_rxrpc_s);
17926a793   David Howells   [AF_RXRPC]: Provi...
989
990
991
992
993
994
995
  error_key_type_s:
  	unregister_key_type(&key_type_rxrpc);
  error_key_type:
  	sock_unregister(PF_RXRPC);
  error_sock:
  	proto_unregister(&rxrpc_proto);
  error_proto:
2baec2c3f   David Howells   rxrpc: Support ne...
996
997
  	unregister_pernet_subsys(&rxrpc_net_ops);
  error_pernet:
648af7fca   David Howells   rxrpc: Absorb the...
998
  	rxrpc_exit_security();
8addc0440   Wei Yongjun   rxrpc: Fix error ...
999
1000
  error_security:
  	destroy_workqueue(rxrpc_workqueue);
651350d10   David Howells   [AF_RXRPC]: Add a...
1001
  error_work_queue:
17926a793   David Howells   [AF_RXRPC]: Provi...
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
  	kmem_cache_destroy(rxrpc_call_jar);
  error_call_jar:
  	return ret;
  }
  
  /*
   * unregister the RxRPC protocol
   */
  static void __exit af_rxrpc_exit(void)
  {
  	_enter("");
5873c0834   David Howells   af_rxrpc: Add sys...
1013
  	rxrpc_sysctl_exit();
17926a793   David Howells   [AF_RXRPC]: Provi...
1014
1015
1016
1017
  	unregister_key_type(&key_type_rxrpc_s);
  	unregister_key_type(&key_type_rxrpc);
  	sock_unregister(PF_RXRPC);
  	proto_unregister(&rxrpc_proto);
2baec2c3f   David Howells   rxrpc: Support ne...
1018
  	unregister_pernet_subsys(&rxrpc_net_ops);
71f3ca408   David Howells   rxrpc: Improve sk...
1019
1020
  	ASSERTCMP(atomic_read(&rxrpc_n_tx_skbs), ==, 0);
  	ASSERTCMP(atomic_read(&rxrpc_n_rx_skbs), ==, 0);
4f95dd78a   David Howells   rxrpc: Rework loc...
1021

2baec2c3f   David Howells   rxrpc: Support ne...
1022
1023
1024
1025
1026
  	/* Make sure the local and peer records pinned by any dying connections
  	 * are released.
  	 */
  	rcu_barrier();
  	rxrpc_destroy_client_conn_ids();
651350d10   David Howells   [AF_RXRPC]: Add a...
1027
  	destroy_workqueue(rxrpc_workqueue);
648af7fca   David Howells   rxrpc: Absorb the...
1028
  	rxrpc_exit_security();
17926a793   David Howells   [AF_RXRPC]: Provi...
1029
1030
1031
1032
1033
1034
  	kmem_cache_destroy(rxrpc_call_jar);
  	_leave("");
  }
  
  module_init(af_rxrpc_init);
  module_exit(af_rxrpc_exit);