0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/kernel.h>
0034 #include <net/sock.h>
0035 #include <linux/in.h>
0036 #include <linux/ipv6.h>
0037 #include <linux/if_arp.h>
0038 #include <linux/jhash.h>
0039 #include <linux/ratelimit.h>
0040 #include "rds.h"
0041
0042 static struct rhashtable bind_hash_table;
0043
0044 static const struct rhashtable_params ht_parms = {
0045 .nelem_hint = 768,
0046 .key_len = RDS_BOUND_KEY_LEN,
0047 .key_offset = offsetof(struct rds_sock, rs_bound_key),
0048 .head_offset = offsetof(struct rds_sock, rs_bound_node),
0049 .max_size = 16384,
0050 .min_size = 1024,
0051 };
0052
0053
0054
0055
0056 static inline void __rds_create_bind_key(u8 *key, const struct in6_addr *addr,
0057 __be16 port, __u32 scope_id)
0058 {
0059 memcpy(key, addr, sizeof(*addr));
0060 key += sizeof(*addr);
0061 memcpy(key, &port, sizeof(port));
0062 key += sizeof(port);
0063 memcpy(key, &scope_id, sizeof(scope_id));
0064 }
0065
0066
0067
0068
0069
0070
0071
0072 struct rds_sock *rds_find_bound(const struct in6_addr *addr, __be16 port,
0073 __u32 scope_id)
0074 {
0075 u8 key[RDS_BOUND_KEY_LEN];
0076 struct rds_sock *rs;
0077
0078 __rds_create_bind_key(key, addr, port, scope_id);
0079 rcu_read_lock();
0080 rs = rhashtable_lookup(&bind_hash_table, key, ht_parms);
0081 if (rs && (sock_flag(rds_rs_to_sk(rs), SOCK_DEAD) ||
0082 !refcount_inc_not_zero(&rds_rs_to_sk(rs)->sk_refcnt)))
0083 rs = NULL;
0084
0085 rcu_read_unlock();
0086
0087 rdsdebug("returning rs %p for %pI6c:%u\n", rs, addr,
0088 ntohs(port));
0089
0090 return rs;
0091 }
0092
0093
0094 static int rds_add_bound(struct rds_sock *rs, const struct in6_addr *addr,
0095 __be16 *port, __u32 scope_id)
0096 {
0097 int ret = -EADDRINUSE;
0098 u16 rover, last;
0099 u8 key[RDS_BOUND_KEY_LEN];
0100
0101 if (*port != 0) {
0102 rover = be16_to_cpu(*port);
0103 if (rover == RDS_FLAG_PROBE_PORT)
0104 return -EINVAL;
0105 last = rover;
0106 } else {
0107 rover = max_t(u16, prandom_u32(), 2);
0108 last = rover - 1;
0109 }
0110
0111 do {
0112 if (rover == 0)
0113 rover++;
0114
0115 if (rover == RDS_FLAG_PROBE_PORT)
0116 continue;
0117 __rds_create_bind_key(key, addr, cpu_to_be16(rover),
0118 scope_id);
0119 if (rhashtable_lookup_fast(&bind_hash_table, key, ht_parms))
0120 continue;
0121
0122 memcpy(rs->rs_bound_key, key, sizeof(rs->rs_bound_key));
0123 rs->rs_bound_addr = *addr;
0124 net_get_random_once(&rs->rs_hash_initval,
0125 sizeof(rs->rs_hash_initval));
0126 rs->rs_bound_port = cpu_to_be16(rover);
0127 rs->rs_bound_node.next = NULL;
0128 rds_sock_addref(rs);
0129 if (!rhashtable_insert_fast(&bind_hash_table,
0130 &rs->rs_bound_node, ht_parms)) {
0131 *port = rs->rs_bound_port;
0132 rs->rs_bound_scope_id = scope_id;
0133 ret = 0;
0134 rdsdebug("rs %p binding to %pI6c:%d\n",
0135 rs, addr, (int)ntohs(*port));
0136 break;
0137 } else {
0138 rs->rs_bound_addr = in6addr_any;
0139 rds_sock_put(rs);
0140 ret = -ENOMEM;
0141 break;
0142 }
0143 } while (rover++ != last);
0144
0145 return ret;
0146 }
0147
0148 void rds_remove_bound(struct rds_sock *rs)
0149 {
0150
0151 if (ipv6_addr_any(&rs->rs_bound_addr))
0152 return;
0153
0154 rdsdebug("rs %p unbinding from %pI6c:%d\n",
0155 rs, &rs->rs_bound_addr,
0156 ntohs(rs->rs_bound_port));
0157
0158 rhashtable_remove_fast(&bind_hash_table, &rs->rs_bound_node, ht_parms);
0159 rds_sock_put(rs);
0160 rs->rs_bound_addr = in6addr_any;
0161 }
0162
0163 int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
0164 {
0165 struct sock *sk = sock->sk;
0166 struct rds_sock *rs = rds_sk_to_rs(sk);
0167 struct in6_addr v6addr, *binding_addr;
0168 struct rds_transport *trans;
0169 __u32 scope_id = 0;
0170 int ret = 0;
0171 __be16 port;
0172
0173
0174
0175
0176 if (addr_len < offsetofend(struct sockaddr, sa_family))
0177 return -EINVAL;
0178 if (uaddr->sa_family == AF_INET) {
0179 struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
0180
0181 if (addr_len < sizeof(struct sockaddr_in) ||
0182 sin->sin_addr.s_addr == htonl(INADDR_ANY) ||
0183 sin->sin_addr.s_addr == htonl(INADDR_BROADCAST) ||
0184 ipv4_is_multicast(sin->sin_addr.s_addr))
0185 return -EINVAL;
0186 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &v6addr);
0187 binding_addr = &v6addr;
0188 port = sin->sin_port;
0189 #if IS_ENABLED(CONFIG_IPV6)
0190 } else if (uaddr->sa_family == AF_INET6) {
0191 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)uaddr;
0192 int addr_type;
0193
0194 if (addr_len < sizeof(struct sockaddr_in6))
0195 return -EINVAL;
0196 addr_type = ipv6_addr_type(&sin6->sin6_addr);
0197 if (!(addr_type & IPV6_ADDR_UNICAST)) {
0198 __be32 addr4;
0199
0200 if (!(addr_type & IPV6_ADDR_MAPPED))
0201 return -EINVAL;
0202
0203
0204
0205
0206 addr4 = sin6->sin6_addr.s6_addr32[3];
0207 if (addr4 == htonl(INADDR_ANY) ||
0208 addr4 == htonl(INADDR_BROADCAST) ||
0209 ipv4_is_multicast(addr4))
0210 return -EINVAL;
0211 }
0212
0213 if (addr_type & IPV6_ADDR_LINKLOCAL) {
0214 if (sin6->sin6_scope_id == 0)
0215 return -EINVAL;
0216 scope_id = sin6->sin6_scope_id;
0217 }
0218 binding_addr = &sin6->sin6_addr;
0219 port = sin6->sin6_port;
0220 #endif
0221 } else {
0222 return -EINVAL;
0223 }
0224 lock_sock(sk);
0225
0226
0227 if (!ipv6_addr_any(&rs->rs_bound_addr)) {
0228 ret = -EINVAL;
0229 goto out;
0230 }
0231
0232
0233
0234
0235 if (!ipv6_addr_any(&rs->rs_conn_addr) && scope_id &&
0236 rs->rs_bound_scope_id &&
0237 scope_id != rs->rs_bound_scope_id) {
0238 ret = -EINVAL;
0239 goto out;
0240 }
0241
0242
0243
0244
0245 if (rs->rs_transport) {
0246 trans = rs->rs_transport;
0247 if (!trans->laddr_check ||
0248 trans->laddr_check(sock_net(sock->sk),
0249 binding_addr, scope_id) != 0) {
0250 ret = -ENOPROTOOPT;
0251 goto out;
0252 }
0253 } else {
0254 trans = rds_trans_get_preferred(sock_net(sock->sk),
0255 binding_addr, scope_id);
0256 if (!trans) {
0257 ret = -EADDRNOTAVAIL;
0258 pr_info_ratelimited("RDS: %s could not find a transport for %pI6c, load rds_tcp or rds_rdma?\n",
0259 __func__, binding_addr);
0260 goto out;
0261 }
0262 rs->rs_transport = trans;
0263 }
0264
0265 sock_set_flag(sk, SOCK_RCU_FREE);
0266 ret = rds_add_bound(rs, binding_addr, &port, scope_id);
0267 if (ret)
0268 rs->rs_transport = NULL;
0269
0270 out:
0271 release_sock(sk);
0272 return ret;
0273 }
0274
0275 void rds_bind_lock_destroy(void)
0276 {
0277 rhashtable_destroy(&bind_hash_table);
0278 }
0279
0280 int rds_bind_lock_init(void)
0281 {
0282 return rhashtable_init(&bind_hash_table, &ht_parms);
0283 }