1/* 2 * Copyright (c) 2006 Oracle. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 * 32 */ 33#include <linux/kernel.h> 34#include <net/sock.h> 35#include <linux/in.h> 36#include <linux/if_arp.h> 37#include <linux/jhash.h> 38#include <linux/ratelimit.h> 39#include "rds.h" 40 41#define BIND_HASH_SIZE 1024 42static struct hlist_head bind_hash_table[BIND_HASH_SIZE]; 43static DEFINE_SPINLOCK(rds_bind_lock); 44 45static struct hlist_head *hash_to_bucket(__be32 addr, __be16 port) 46{ 47 return bind_hash_table + (jhash_2words((u32)addr, (u32)port, 0) & 48 (BIND_HASH_SIZE - 1)); 49} 50 51static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, 52 struct rds_sock *insert) 53{ 54 struct rds_sock *rs; 55 struct hlist_head *head = hash_to_bucket(addr, port); 56 u64 cmp; 57 u64 needle = ((u64)be32_to_cpu(addr) << 32) | be16_to_cpu(port); 58 59 rcu_read_lock(); 60 hlist_for_each_entry_rcu(rs, head, rs_bound_node) { 61 cmp = ((u64)be32_to_cpu(rs->rs_bound_addr) << 32) | 62 be16_to_cpu(rs->rs_bound_port); 63 64 if (cmp == needle) { 65 rcu_read_unlock(); 66 return rs; 67 } 68 } 69 rcu_read_unlock(); 70 71 if (insert) { 72 /* 73 * make sure our addr and port are set before 74 * we are added to the list, other people 75 * in rcu will find us as soon as the 76 * hlist_add_head_rcu is done 77 */ 78 insert->rs_bound_addr = addr; 79 insert->rs_bound_port = port; 80 rds_sock_addref(insert); 81 82 hlist_add_head_rcu(&insert->rs_bound_node, head); 83 } 84 return NULL; 85} 86 87/* 88 * Return the rds_sock bound at the given local address. 89 * 90 * The rx path can race with rds_release. We notice if rds_release() has 91 * marked this socket and don't return a rs ref to the rx path. 92 */ 93struct rds_sock *rds_find_bound(__be32 addr, __be16 port) 94{ 95 struct rds_sock *rs; 96 97 rs = rds_bind_lookup(addr, port, NULL); 98 99 if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD)) 100 rds_sock_addref(rs); 101 else 102 rs = NULL; 103 104 rdsdebug("returning rs %p for %pI4:%u\n", rs, &addr, 105 ntohs(port)); 106 return rs; 107} 108 109/* returns -ve errno or +ve port */ 110static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port) 111{ 112 unsigned long flags; 113 int ret = -EADDRINUSE; 114 u16 rover, last; 115 116 if (*port != 0) { 117 rover = be16_to_cpu(*port); 118 last = rover; 119 } else { 120 rover = max_t(u16, prandom_u32(), 2); 121 last = rover - 1; 122 } 123 124 spin_lock_irqsave(&rds_bind_lock, flags); 125 126 do { 127 if (rover == 0) 128 rover++; 129 if (!rds_bind_lookup(addr, cpu_to_be16(rover), rs)) { 130 *port = rs->rs_bound_port; 131 ret = 0; 132 rdsdebug("rs %p binding to %pI4:%d\n", 133 rs, &addr, (int)ntohs(*port)); 134 break; 135 } 136 } while (rover++ != last); 137 138 spin_unlock_irqrestore(&rds_bind_lock, flags); 139 140 return ret; 141} 142 143void rds_remove_bound(struct rds_sock *rs) 144{ 145 unsigned long flags; 146 147 spin_lock_irqsave(&rds_bind_lock, flags); 148 149 if (rs->rs_bound_addr) { 150 rdsdebug("rs %p unbinding from %pI4:%d\n", 151 rs, &rs->rs_bound_addr, 152 ntohs(rs->rs_bound_port)); 153 154 hlist_del_init_rcu(&rs->rs_bound_node); 155 rds_sock_put(rs); 156 rs->rs_bound_addr = 0; 157 } 158 159 spin_unlock_irqrestore(&rds_bind_lock, flags); 160} 161 162int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 163{ 164 struct sock *sk = sock->sk; 165 struct sockaddr_in *sin = (struct sockaddr_in *)uaddr; 166 struct rds_sock *rs = rds_sk_to_rs(sk); 167 struct rds_transport *trans; 168 int ret = 0; 169 170 lock_sock(sk); 171 172 if (addr_len != sizeof(struct sockaddr_in) || 173 sin->sin_family != AF_INET || 174 rs->rs_bound_addr || 175 sin->sin_addr.s_addr == htonl(INADDR_ANY)) { 176 ret = -EINVAL; 177 goto out; 178 } 179 180 ret = rds_add_bound(rs, sin->sin_addr.s_addr, &sin->sin_port); 181 if (ret) 182 goto out; 183 184 trans = rds_trans_get_preferred(sin->sin_addr.s_addr); 185 if (!trans) { 186 ret = -EADDRNOTAVAIL; 187 rds_remove_bound(rs); 188 printk_ratelimited(KERN_INFO "RDS: rds_bind() could not find a transport, " 189 "load rds_tcp or rds_rdma?\n"); 190 goto out; 191 } 192 193 rs->rs_transport = trans; 194 ret = 0; 195 196out: 197 release_sock(sk); 198 199 /* we might have called rds_remove_bound on error */ 200 if (ret) 201 synchronize_rcu(); 202 return ret; 203} 204