Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (c) 2006, 2019 Oracle and/or its affiliates. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This software is available to you under a choice of one of two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * licenses.  You may choose to be licensed under the terms of the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * General Public License (GPL) Version 2, available from the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * COPYING in the main directory of this source tree, or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * OpenIB.org BSD license below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *     Redistribution and use in source and binary forms, with or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *     without modification, are permitted provided that the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *     conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *      - Redistributions of source code must retain the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *        copyright notice, this list of conditions and the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *        disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *      - Redistributions in binary form must reproduce the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *        copyright notice, this list of conditions and the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *        disclaimer in the documentation and/or other materials
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *        provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include "rds.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static struct rhashtable bind_hash_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static const struct rhashtable_params ht_parms = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	.nelem_hint = 768,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	.key_len = RDS_BOUND_KEY_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	.key_offset = offsetof(struct rds_sock, rs_bound_key),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	.head_offset = offsetof(struct rds_sock, rs_bound_node),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	.max_size = 16384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	.min_size = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /* Create a key for the bind hash table manipulation.  Port is in network byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static inline void __rds_create_bind_key(u8 *key, const struct in6_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 					 __be16 port, __u32 scope_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	memcpy(key, addr, sizeof(*addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	key += sizeof(*addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	memcpy(key, &port, sizeof(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	key += sizeof(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	memcpy(key, &scope_id, sizeof(scope_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * Return the rds_sock bound at the given local address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * The rx path can race with rds_release.  We notice if rds_release() has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * marked this socket and don't return a rs ref to the rx path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) struct rds_sock *rds_find_bound(const struct in6_addr *addr, __be16 port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				__u32 scope_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	u8 key[RDS_BOUND_KEY_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	struct rds_sock *rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	__rds_create_bind_key(key, addr, port, scope_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	rs = rhashtable_lookup(&bind_hash_table, key, ht_parms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (rs && (sock_flag(rds_rs_to_sk(rs), SOCK_DEAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		   !refcount_inc_not_zero(&rds_rs_to_sk(rs)->sk_refcnt)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		rs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	rdsdebug("returning rs %p for %pI6c:%u\n", rs, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		 ntohs(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	return rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) /* returns -ve errno or +ve port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static int rds_add_bound(struct rds_sock *rs, const struct in6_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			 __be16 *port, __u32 scope_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	int ret = -EADDRINUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	u16 rover, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	u8 key[RDS_BOUND_KEY_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (*port != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		rover = be16_to_cpu(*port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		if (rover == RDS_FLAG_PROBE_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		last = rover;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		rover = max_t(u16, prandom_u32(), 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		last = rover - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		if (rover == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			rover++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		if (rover == RDS_FLAG_PROBE_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		__rds_create_bind_key(key, addr, cpu_to_be16(rover),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				      scope_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		if (rhashtable_lookup_fast(&bind_hash_table, key, ht_parms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		memcpy(rs->rs_bound_key, key, sizeof(rs->rs_bound_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		rs->rs_bound_addr = *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		net_get_random_once(&rs->rs_hash_initval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 				    sizeof(rs->rs_hash_initval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		rs->rs_bound_port = cpu_to_be16(rover);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		rs->rs_bound_node.next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		rds_sock_addref(rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		if (!rhashtable_insert_fast(&bind_hash_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 					    &rs->rs_bound_node, ht_parms)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			*port = rs->rs_bound_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			rs->rs_bound_scope_id = scope_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			rdsdebug("rs %p binding to %pI6c:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				 rs, addr, (int)ntohs(*port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			rs->rs_bound_addr = in6addr_any;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			rds_sock_put(rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	} while (rover++ != last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) void rds_remove_bound(struct rds_sock *rs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (ipv6_addr_any(&rs->rs_bound_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	rdsdebug("rs %p unbinding from %pI6c:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		 rs, &rs->rs_bound_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		 ntohs(rs->rs_bound_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	rhashtable_remove_fast(&bind_hash_table, &rs->rs_bound_node, ht_parms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	rds_sock_put(rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	rs->rs_bound_addr = in6addr_any;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	struct rds_sock *rs = rds_sk_to_rs(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	struct in6_addr v6addr, *binding_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct rds_transport *trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	__u32 scope_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	__be16 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	/* We allow an RDS socket to be bound to either IPv4 or IPv6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	 * address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	if (addr_len < offsetofend(struct sockaddr, sa_family))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if (uaddr->sa_family == AF_INET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		if (addr_len < sizeof(struct sockaddr_in) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		    sin->sin_addr.s_addr == htonl(INADDR_ANY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		    sin->sin_addr.s_addr == htonl(INADDR_BROADCAST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		    ipv4_is_multicast(sin->sin_addr.s_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &v6addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		binding_addr = &v6addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		port = sin->sin_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	} else if (uaddr->sa_family == AF_INET6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		int addr_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		if (addr_len < sizeof(struct sockaddr_in6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		addr_type = ipv6_addr_type(&sin6->sin6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		if (!(addr_type & IPV6_ADDR_UNICAST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			__be32 addr4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			if (!(addr_type & IPV6_ADDR_MAPPED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			/* It is a mapped address.  Need to do some sanity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			 * checks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			addr4 = sin6->sin6_addr.s6_addr32[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			if (addr4 == htonl(INADDR_ANY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			    addr4 == htonl(INADDR_BROADCAST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			    ipv4_is_multicast(addr4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		/* The scope ID must be specified for link local address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		if (addr_type & IPV6_ADDR_LINKLOCAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			if (sin6->sin6_scope_id == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			scope_id = sin6->sin6_scope_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		binding_addr = &sin6->sin6_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		port = sin6->sin6_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	/* RDS socket does not allow re-binding. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (!ipv6_addr_any(&rs->rs_bound_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	/* Socket is connected.  The binding address should have the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	 * scope ID as the connected address, except the case when one is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	 * non-link local address (scope_id is 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (!ipv6_addr_any(&rs->rs_conn_addr) && scope_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	    rs->rs_bound_scope_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	    scope_id != rs->rs_bound_scope_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	/* The transport can be set using SO_RDS_TRANSPORT option before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	 * socket is bound.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if (rs->rs_transport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		trans = rs->rs_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		if (!trans->laddr_check ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		    trans->laddr_check(sock_net(sock->sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				       binding_addr, scope_id) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			ret = -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		trans = rds_trans_get_preferred(sock_net(sock->sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 						binding_addr, scope_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		if (!trans) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			ret = -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			pr_info_ratelimited("RDS: %s could not find a transport for %pI6c, load rds_tcp or rds_rdma?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 					    __func__, binding_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		rs->rs_transport = trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	sock_set_flag(sk, SOCK_RCU_FREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	ret = rds_add_bound(rs, binding_addr, &port, scope_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		rs->rs_transport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) void rds_bind_lock_destroy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	rhashtable_destroy(&bind_hash_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int rds_bind_lock_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	return rhashtable_init(&bind_hash_table, &ht_parms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }