1 /* AF_RXRPC local endpoint management
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 #include <linux/module.h>
13 #include <linux/net.h>
14 #include <linux/skbuff.h>
15 #include <linux/slab.h>
16 #include <linux/udp.h>
19 #include <net/af_rxrpc.h>
20 #include <generated/utsrelease.h>
21 #include "ar-internal.h"
23 static const char rxrpc_version_string
[65] = "linux-" UTS_RELEASE
" AF_RXRPC";
25 static LIST_HEAD(rxrpc_locals
);
26 DEFINE_RWLOCK(rxrpc_local_lock
);
27 static DECLARE_RWSEM(rxrpc_local_sem
);
28 static DECLARE_WAIT_QUEUE_HEAD(rxrpc_local_wq
);
30 static void rxrpc_destroy_local(struct work_struct
*work
);
31 static void rxrpc_process_local_events(struct work_struct
*work
);
34 * allocate a new local
37 struct rxrpc_local
*rxrpc_alloc_local(struct sockaddr_rxrpc
*srx
)
39 struct rxrpc_local
*local
;
41 local
= kzalloc(sizeof(struct rxrpc_local
), GFP_KERNEL
);
43 INIT_WORK(&local
->destroyer
, &rxrpc_destroy_local
);
44 INIT_WORK(&local
->acceptor
, &rxrpc_accept_incoming_calls
);
45 INIT_WORK(&local
->rejecter
, &rxrpc_reject_packets
);
46 INIT_WORK(&local
->event_processor
, &rxrpc_process_local_events
);
47 INIT_LIST_HEAD(&local
->services
);
48 INIT_LIST_HEAD(&local
->link
);
49 init_rwsem(&local
->defrag_sem
);
50 skb_queue_head_init(&local
->accept_queue
);
51 skb_queue_head_init(&local
->reject_queue
);
52 skb_queue_head_init(&local
->event_queue
);
53 spin_lock_init(&local
->lock
);
54 rwlock_init(&local
->services_lock
);
55 atomic_set(&local
->usage
, 1);
56 local
->debug_id
= atomic_inc_return(&rxrpc_debug_id
);
57 memcpy(&local
->srx
, srx
, sizeof(*srx
));
60 _leave(" = %p", local
);
65 * create the local socket
66 * - must be called with rxrpc_local_sem writelocked
68 static int rxrpc_create_local(struct rxrpc_local
*local
)
73 _enter("%p{%d}", local
, local
->srx
.transport_type
);
75 /* create a socket to represent the local endpoint */
76 ret
= sock_create_kern(PF_INET
, local
->srx
.transport_type
, IPPROTO_UDP
,
79 _leave(" = %d [socket]", ret
);
83 /* if a local address was supplied then bind it */
84 if (local
->srx
.transport_len
> sizeof(sa_family_t
)) {
86 ret
= kernel_bind(local
->socket
,
87 (struct sockaddr
*) &local
->srx
.transport
,
88 local
->srx
.transport_len
);
90 _debug("bind failed");
95 /* we want to receive ICMP errors */
97 ret
= kernel_setsockopt(local
->socket
, SOL_IP
, IP_RECVERR
,
98 (char *) &opt
, sizeof(opt
));
100 _debug("setsockopt failed");
104 /* we want to set the don't fragment bit */
105 opt
= IP_PMTUDISC_DO
;
106 ret
= kernel_setsockopt(local
->socket
, SOL_IP
, IP_MTU_DISCOVER
,
107 (char *) &opt
, sizeof(opt
));
109 _debug("setsockopt failed");
113 write_lock_bh(&rxrpc_local_lock
);
114 list_add(&local
->link
, &rxrpc_locals
);
115 write_unlock_bh(&rxrpc_local_lock
);
117 /* set the socket up */
118 sock
= local
->socket
->sk
;
119 sock
->sk_user_data
= local
;
120 sock
->sk_data_ready
= rxrpc_data_ready
;
121 sock
->sk_error_report
= rxrpc_UDP_error_report
;
126 kernel_sock_shutdown(local
->socket
, SHUT_RDWR
);
127 local
->socket
->sk
->sk_user_data
= NULL
;
128 sock_release(local
->socket
);
129 local
->socket
= NULL
;
131 _leave(" = %d", ret
);
136 * create a new local endpoint using the specified UDP address
138 struct rxrpc_local
*rxrpc_lookup_local(struct sockaddr_rxrpc
*srx
)
140 struct rxrpc_local
*local
;
143 _enter("{%d,%u,%pI4+%hu}",
145 srx
->transport
.family
,
146 &srx
->transport
.sin
.sin_addr
,
147 ntohs(srx
->transport
.sin
.sin_port
));
149 down_write(&rxrpc_local_sem
);
151 /* see if we have a suitable local local endpoint already */
152 read_lock_bh(&rxrpc_local_lock
);
154 list_for_each_entry(local
, &rxrpc_locals
, link
) {
155 _debug("CMP {%d,%u,%pI4+%hu}",
156 local
->srx
.transport_type
,
157 local
->srx
.transport
.family
,
158 &local
->srx
.transport
.sin
.sin_addr
,
159 ntohs(local
->srx
.transport
.sin
.sin_port
));
161 if (local
->srx
.transport_type
!= srx
->transport_type
||
162 local
->srx
.transport
.family
!= srx
->transport
.family
)
165 switch (srx
->transport
.family
) {
167 if (local
->srx
.transport
.sin
.sin_port
!=
168 srx
->transport
.sin
.sin_port
)
170 if (memcmp(&local
->srx
.transport
.sin
.sin_addr
,
171 &srx
->transport
.sin
.sin_addr
,
172 sizeof(struct in_addr
)) != 0)
181 read_unlock_bh(&rxrpc_local_lock
);
183 /* we didn't find one, so we need to create one */
184 local
= rxrpc_alloc_local(srx
);
186 up_write(&rxrpc_local_sem
);
187 return ERR_PTR(-ENOMEM
);
190 ret
= rxrpc_create_local(local
);
192 up_write(&rxrpc_local_sem
);
194 _leave(" = %d", ret
);
198 up_write(&rxrpc_local_sem
);
200 _net("LOCAL new %d {%d,%u,%pI4+%hu}",
202 local
->srx
.transport_type
,
203 local
->srx
.transport
.family
,
204 &local
->srx
.transport
.sin
.sin_addr
,
205 ntohs(local
->srx
.transport
.sin
.sin_port
));
207 _leave(" = %p [new]", local
);
211 rxrpc_get_local(local
);
212 read_unlock_bh(&rxrpc_local_lock
);
213 up_write(&rxrpc_local_sem
);
215 _net("LOCAL old %d {%d,%u,%pI4+%hu}",
217 local
->srx
.transport_type
,
218 local
->srx
.transport
.family
,
219 &local
->srx
.transport
.sin
.sin_addr
,
220 ntohs(local
->srx
.transport
.sin
.sin_port
));
222 _leave(" = %p [reuse]", local
);
227 * release a local endpoint
229 void rxrpc_put_local(struct rxrpc_local
*local
)
231 _enter("%p{u=%d}", local
, atomic_read(&local
->usage
));
233 ASSERTCMP(atomic_read(&local
->usage
), >, 0);
235 /* to prevent a race, the decrement and the dequeue must be effectively
237 write_lock_bh(&rxrpc_local_lock
);
238 if (unlikely(atomic_dec_and_test(&local
->usage
))) {
239 _debug("destroy local");
240 rxrpc_queue_work(&local
->destroyer
);
242 write_unlock_bh(&rxrpc_local_lock
);
247 * destroy a local endpoint
249 static void rxrpc_destroy_local(struct work_struct
*work
)
251 struct rxrpc_local
*local
=
252 container_of(work
, struct rxrpc_local
, destroyer
);
254 _enter("%p{%d}", local
, atomic_read(&local
->usage
));
256 down_write(&rxrpc_local_sem
);
258 write_lock_bh(&rxrpc_local_lock
);
259 if (atomic_read(&local
->usage
) > 0) {
260 write_unlock_bh(&rxrpc_local_lock
);
261 up_read(&rxrpc_local_sem
);
262 _leave(" [resurrected]");
266 list_del(&local
->link
);
267 local
->socket
->sk
->sk_user_data
= NULL
;
268 write_unlock_bh(&rxrpc_local_lock
);
270 downgrade_write(&rxrpc_local_sem
);
272 ASSERT(list_empty(&local
->services
));
273 ASSERT(!work_pending(&local
->acceptor
));
274 ASSERT(!work_pending(&local
->rejecter
));
275 ASSERT(!work_pending(&local
->event_processor
));
277 /* finish cleaning up the local descriptor */
278 rxrpc_purge_queue(&local
->accept_queue
);
279 rxrpc_purge_queue(&local
->reject_queue
);
280 rxrpc_purge_queue(&local
->event_queue
);
281 kernel_sock_shutdown(local
->socket
, SHUT_RDWR
);
282 sock_release(local
->socket
);
284 up_read(&rxrpc_local_sem
);
286 _net("DESTROY LOCAL %d", local
->debug_id
);
289 if (list_empty(&rxrpc_locals
))
290 wake_up_all(&rxrpc_local_wq
);
296 * preemptively destroy all local local endpoint rather than waiting for
297 * them to be destroyed
299 void __exit
rxrpc_destroy_all_locals(void)
301 DECLARE_WAITQUEUE(myself
,current
);
305 /* we simply have to wait for them to go away */
306 if (!list_empty(&rxrpc_locals
)) {
307 set_current_state(TASK_UNINTERRUPTIBLE
);
308 add_wait_queue(&rxrpc_local_wq
, &myself
);
310 while (!list_empty(&rxrpc_locals
)) {
312 set_current_state(TASK_UNINTERRUPTIBLE
);
315 remove_wait_queue(&rxrpc_local_wq
, &myself
);
316 set_current_state(TASK_RUNNING
);
323 * Reply to a version request
325 static void rxrpc_send_version_request(struct rxrpc_local
*local
,
326 struct rxrpc_header
*hdr
,
329 struct sockaddr_in sin
;
337 sin
.sin_family
= AF_INET
;
338 sin
.sin_port
= udp_hdr(skb
)->source
;
339 sin
.sin_addr
.s_addr
= ip_hdr(skb
)->saddr
;
342 msg
.msg_namelen
= sizeof(sin
);
343 msg
.msg_control
= NULL
;
344 msg
.msg_controllen
= 0;
349 hdr
->type
= RXRPC_PACKET_TYPE_VERSION
;
350 hdr
->flags
= RXRPC_LAST_PACKET
| (~hdr
->flags
& RXRPC_CLIENT_INITIATED
);
354 iov
[0].iov_base
= hdr
;
355 iov
[0].iov_len
= sizeof(*hdr
);
356 iov
[1].iov_base
= (char *)rxrpc_version_string
;
357 iov
[1].iov_len
= sizeof(rxrpc_version_string
);
359 len
= iov
[0].iov_len
+ iov
[1].iov_len
;
361 _proto("Tx VERSION (reply)");
363 ret
= kernel_sendmsg(local
->socket
, &msg
, iov
, 2, len
);
365 _debug("sendmsg failed: %d", ret
);
371 * Process event packets targetted at a local endpoint.
373 static void rxrpc_process_local_events(struct work_struct
*work
)
375 struct rxrpc_local
*local
= container_of(work
, struct rxrpc_local
, event_processor
);
381 atomic_inc(&local
->usage
);
383 while ((skb
= skb_dequeue(&local
->event_queue
))) {
384 struct rxrpc_skb_priv
*sp
= rxrpc_skb(skb
);
386 kdebug("{%d},{%u}", local
->debug_id
, sp
->hdr
.type
);
388 switch (sp
->hdr
.type
) {
389 case RXRPC_PACKET_TYPE_VERSION
:
390 if (skb_copy_bits(skb
, 0, &v
, 1) < 0)
392 _proto("Rx VERSION { %02x }", v
);
394 rxrpc_send_version_request(local
, &sp
->hdr
, skb
);
398 /* Just ignore anything we don't understand */
402 rxrpc_put_local(local
);
406 rxrpc_put_local(local
);