1/* AF_RXRPC local endpoint management 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 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. 10 */ 11 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> 17#include <linux/ip.h> 18#include <net/sock.h> 19#include <net/af_rxrpc.h> 20#include <generated/utsrelease.h> 21#include "ar-internal.h" 22 23static const char rxrpc_version_string[65] = "linux-" UTS_RELEASE " AF_RXRPC"; 24 25static LIST_HEAD(rxrpc_locals); 26DEFINE_RWLOCK(rxrpc_local_lock); 27static DECLARE_RWSEM(rxrpc_local_sem); 28static DECLARE_WAIT_QUEUE_HEAD(rxrpc_local_wq); 29 30static void rxrpc_destroy_local(struct work_struct *work); 31static void rxrpc_process_local_events(struct work_struct *work); 32 33/* 34 * allocate a new local 35 */ 36static 37struct rxrpc_local *rxrpc_alloc_local(struct sockaddr_rxrpc *srx) 38{ 39 struct rxrpc_local *local; 40 41 local = kzalloc(sizeof(struct rxrpc_local), GFP_KERNEL); 42 if (local) { 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)); 58 } 59 60 _leave(" = %p", local); 61 return local; 62} 63 64/* 65 * create the local socket 66 * - must be called with rxrpc_local_sem writelocked 67 */ 68static int rxrpc_create_local(struct rxrpc_local *local) 69{ 70 struct sock *sock; 71 int ret, opt; 72 73 _enter("%p{%d}", local, local->srx.transport_type); 74 75 /* create a socket to represent the local endpoint */ 76 ret = sock_create_kern(PF_INET, local->srx.transport_type, IPPROTO_UDP, 77 &local->socket); 78 if (ret < 0) { 79 _leave(" = %d [socket]", ret); 80 return ret; 81 } 82 83 /* if a local address was supplied then bind it */ 84 if (local->srx.transport_len > sizeof(sa_family_t)) { 85 _debug("bind"); 86 ret = kernel_bind(local->socket, 87 (struct sockaddr *) &local->srx.transport, 88 local->srx.transport_len); 89 if (ret < 0) { 90 _debug("bind failed"); 91 goto error; 92 } 93 } 94 95 /* we want to receive ICMP errors */ 96 opt = 1; 97 ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR, 98 (char *) &opt, sizeof(opt)); 99 if (ret < 0) { 100 _debug("setsockopt failed"); 101 goto error; 102 } 103 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)); 108 if (ret < 0) { 109 _debug("setsockopt failed"); 110 goto error; 111 } 112 113 write_lock_bh(&rxrpc_local_lock); 114 list_add(&local->link, &rxrpc_locals); 115 write_unlock_bh(&rxrpc_local_lock); 116 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; 122 _leave(" = 0"); 123 return 0; 124 125error: 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; 130 131 _leave(" = %d", ret); 132 return ret; 133} 134 135/* 136 * create a new local endpoint using the specified UDP address 137 */ 138struct rxrpc_local *rxrpc_lookup_local(struct sockaddr_rxrpc *srx) 139{ 140 struct rxrpc_local *local; 141 int ret; 142 143 _enter("{%d,%u,%pI4+%hu}", 144 srx->transport_type, 145 srx->transport.family, 146 &srx->transport.sin.sin_addr, 147 ntohs(srx->transport.sin.sin_port)); 148 149 down_write(&rxrpc_local_sem); 150 151 /* see if we have a suitable local local endpoint already */ 152 read_lock_bh(&rxrpc_local_lock); 153 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)); 160 161 if (local->srx.transport_type != srx->transport_type || 162 local->srx.transport.family != srx->transport.family) 163 continue; 164 165 switch (srx->transport.family) { 166 case AF_INET: 167 if (local->srx.transport.sin.sin_port != 168 srx->transport.sin.sin_port) 169 continue; 170 if (memcmp(&local->srx.transport.sin.sin_addr, 171 &srx->transport.sin.sin_addr, 172 sizeof(struct in_addr)) != 0) 173 continue; 174 goto found_local; 175 176 default: 177 BUG(); 178 } 179 } 180 181 read_unlock_bh(&rxrpc_local_lock); 182 183 /* we didn't find one, so we need to create one */ 184 local = rxrpc_alloc_local(srx); 185 if (!local) { 186 up_write(&rxrpc_local_sem); 187 return ERR_PTR(-ENOMEM); 188 } 189 190 ret = rxrpc_create_local(local); 191 if (ret < 0) { 192 up_write(&rxrpc_local_sem); 193 kfree(local); 194 _leave(" = %d", ret); 195 return ERR_PTR(ret); 196 } 197 198 up_write(&rxrpc_local_sem); 199 200 _net("LOCAL new %d {%d,%u,%pI4+%hu}", 201 local->debug_id, 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)); 206 207 _leave(" = %p [new]", local); 208 return local; 209 210found_local: 211 rxrpc_get_local(local); 212 read_unlock_bh(&rxrpc_local_lock); 213 up_write(&rxrpc_local_sem); 214 215 _net("LOCAL old %d {%d,%u,%pI4+%hu}", 216 local->debug_id, 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)); 221 222 _leave(" = %p [reuse]", local); 223 return local; 224} 225 226/* 227 * release a local endpoint 228 */ 229void rxrpc_put_local(struct rxrpc_local *local) 230{ 231 _enter("%p{u=%d}", local, atomic_read(&local->usage)); 232 233 ASSERTCMP(atomic_read(&local->usage), >, 0); 234 235 /* to prevent a race, the decrement and the dequeue must be effectively 236 * atomic */ 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); 241 } 242 write_unlock_bh(&rxrpc_local_lock); 243 _leave(""); 244} 245 246/* 247 * destroy a local endpoint 248 */ 249static void rxrpc_destroy_local(struct work_struct *work) 250{ 251 struct rxrpc_local *local = 252 container_of(work, struct rxrpc_local, destroyer); 253 254 _enter("%p{%d}", local, atomic_read(&local->usage)); 255 256 down_write(&rxrpc_local_sem); 257 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]"); 263 return; 264 } 265 266 list_del(&local->link); 267 local->socket->sk->sk_user_data = NULL; 268 write_unlock_bh(&rxrpc_local_lock); 269 270 downgrade_write(&rxrpc_local_sem); 271 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)); 276 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); 283 284 up_read(&rxrpc_local_sem); 285 286 _net("DESTROY LOCAL %d", local->debug_id); 287 kfree(local); 288 289 if (list_empty(&rxrpc_locals)) 290 wake_up_all(&rxrpc_local_wq); 291 292 _leave(""); 293} 294 295/* 296 * preemptively destroy all local local endpoint rather than waiting for 297 * them to be destroyed 298 */ 299void __exit rxrpc_destroy_all_locals(void) 300{ 301 DECLARE_WAITQUEUE(myself,current); 302 303 _enter(""); 304 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); 309 310 while (!list_empty(&rxrpc_locals)) { 311 schedule(); 312 set_current_state(TASK_UNINTERRUPTIBLE); 313 } 314 315 remove_wait_queue(&rxrpc_local_wq, &myself); 316 set_current_state(TASK_RUNNING); 317 } 318 319 _leave(""); 320} 321 322/* 323 * Reply to a version request 324 */ 325static void rxrpc_send_version_request(struct rxrpc_local *local, 326 struct rxrpc_header *hdr, 327 struct sk_buff *skb) 328{ 329 struct sockaddr_in sin; 330 struct msghdr msg; 331 struct kvec iov[2]; 332 size_t len; 333 int ret; 334 335 _enter(""); 336 337 sin.sin_family = AF_INET; 338 sin.sin_port = udp_hdr(skb)->source; 339 sin.sin_addr.s_addr = ip_hdr(skb)->saddr; 340 341 msg.msg_name = &sin; 342 msg.msg_namelen = sizeof(sin); 343 msg.msg_control = NULL; 344 msg.msg_controllen = 0; 345 msg.msg_flags = 0; 346 347 hdr->seq = 0; 348 hdr->serial = 0; 349 hdr->type = RXRPC_PACKET_TYPE_VERSION; 350 hdr->flags = RXRPC_LAST_PACKET | (~hdr->flags & RXRPC_CLIENT_INITIATED); 351 hdr->userStatus = 0; 352 hdr->_rsvd = 0; 353 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); 358 359 len = iov[0].iov_len + iov[1].iov_len; 360 361 _proto("Tx VERSION (reply)"); 362 363 ret = kernel_sendmsg(local->socket, &msg, iov, 2, len); 364 if (ret < 0) 365 _debug("sendmsg failed: %d", ret); 366 367 _leave(""); 368} 369 370/* 371 * Process event packets targetted at a local endpoint. 372 */ 373static void rxrpc_process_local_events(struct work_struct *work) 374{ 375 struct rxrpc_local *local = container_of(work, struct rxrpc_local, event_processor); 376 struct sk_buff *skb; 377 char v; 378 379 _enter(""); 380 381 atomic_inc(&local->usage); 382 383 while ((skb = skb_dequeue(&local->event_queue))) { 384 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 385 386 kdebug("{%d},{%u}", local->debug_id, sp->hdr.type); 387 388 switch (sp->hdr.type) { 389 case RXRPC_PACKET_TYPE_VERSION: 390 if (skb_copy_bits(skb, 0, &v, 1) < 0) 391 return; 392 _proto("Rx VERSION { %02x }", v); 393 if (v == 0) 394 rxrpc_send_version_request(local, &sp->hdr, skb); 395 break; 396 397 default: 398 /* Just ignore anything we don't understand */ 399 break; 400 } 401 402 rxrpc_put_local(local); 403 rxrpc_free_skb(skb); 404 } 405 406 rxrpc_put_local(local); 407 _leave(""); 408} 409