Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* RxRPC remote transport endpoint record management
0003  *
0004  * Copyright (C) 2007, 2016 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  */
0007 
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 
0010 #include <linux/module.h>
0011 #include <linux/net.h>
0012 #include <linux/skbuff.h>
0013 #include <linux/udp.h>
0014 #include <linux/in.h>
0015 #include <linux/in6.h>
0016 #include <linux/slab.h>
0017 #include <linux/hashtable.h>
0018 #include <net/sock.h>
0019 #include <net/af_rxrpc.h>
0020 #include <net/ip.h>
0021 #include <net/route.h>
0022 #include <net/ip6_route.h>
0023 #include "ar-internal.h"
0024 
0025 /*
0026  * Hash a peer key.
0027  */
0028 static unsigned long rxrpc_peer_hash_key(struct rxrpc_local *local,
0029                      const struct sockaddr_rxrpc *srx)
0030 {
0031     const u16 *p;
0032     unsigned int i, size;
0033     unsigned long hash_key;
0034 
0035     _enter("");
0036 
0037     hash_key = (unsigned long)local / __alignof__(*local);
0038     hash_key += srx->transport_type;
0039     hash_key += srx->transport_len;
0040     hash_key += srx->transport.family;
0041 
0042     switch (srx->transport.family) {
0043     case AF_INET:
0044         hash_key += (u16 __force)srx->transport.sin.sin_port;
0045         size = sizeof(srx->transport.sin.sin_addr);
0046         p = (u16 *)&srx->transport.sin.sin_addr;
0047         break;
0048 #ifdef CONFIG_AF_RXRPC_IPV6
0049     case AF_INET6:
0050         hash_key += (u16 __force)srx->transport.sin.sin_port;
0051         size = sizeof(srx->transport.sin6.sin6_addr);
0052         p = (u16 *)&srx->transport.sin6.sin6_addr;
0053         break;
0054 #endif
0055     default:
0056         WARN(1, "AF_RXRPC: Unsupported transport address family\n");
0057         return 0;
0058     }
0059 
0060     /* Step through the peer address in 16-bit portions for speed */
0061     for (i = 0; i < size; i += sizeof(*p), p++)
0062         hash_key += *p;
0063 
0064     _leave(" 0x%lx", hash_key);
0065     return hash_key;
0066 }
0067 
0068 /*
0069  * Compare a peer to a key.  Return -ve, 0 or +ve to indicate less than, same
0070  * or greater than.
0071  *
0072  * Unfortunately, the primitives in linux/hashtable.h don't allow for sorted
0073  * buckets and mid-bucket insertion, so we don't make full use of this
0074  * information at this point.
0075  */
0076 static long rxrpc_peer_cmp_key(const struct rxrpc_peer *peer,
0077                    struct rxrpc_local *local,
0078                    const struct sockaddr_rxrpc *srx,
0079                    unsigned long hash_key)
0080 {
0081     long diff;
0082 
0083     diff = ((peer->hash_key - hash_key) ?:
0084         ((unsigned long)peer->local - (unsigned long)local) ?:
0085         (peer->srx.transport_type - srx->transport_type) ?:
0086         (peer->srx.transport_len - srx->transport_len) ?:
0087         (peer->srx.transport.family - srx->transport.family));
0088     if (diff != 0)
0089         return diff;
0090 
0091     switch (srx->transport.family) {
0092     case AF_INET:
0093         return ((u16 __force)peer->srx.transport.sin.sin_port -
0094             (u16 __force)srx->transport.sin.sin_port) ?:
0095             memcmp(&peer->srx.transport.sin.sin_addr,
0096                    &srx->transport.sin.sin_addr,
0097                    sizeof(struct in_addr));
0098 #ifdef CONFIG_AF_RXRPC_IPV6
0099     case AF_INET6:
0100         return ((u16 __force)peer->srx.transport.sin6.sin6_port -
0101             (u16 __force)srx->transport.sin6.sin6_port) ?:
0102             memcmp(&peer->srx.transport.sin6.sin6_addr,
0103                    &srx->transport.sin6.sin6_addr,
0104                    sizeof(struct in6_addr));
0105 #endif
0106     default:
0107         BUG();
0108     }
0109 }
0110 
0111 /*
0112  * Look up a remote transport endpoint for the specified address using RCU.
0113  */
0114 static struct rxrpc_peer *__rxrpc_lookup_peer_rcu(
0115     struct rxrpc_local *local,
0116     const struct sockaddr_rxrpc *srx,
0117     unsigned long hash_key)
0118 {
0119     struct rxrpc_peer *peer;
0120     struct rxrpc_net *rxnet = local->rxnet;
0121 
0122     hash_for_each_possible_rcu(rxnet->peer_hash, peer, hash_link, hash_key) {
0123         if (rxrpc_peer_cmp_key(peer, local, srx, hash_key) == 0 &&
0124             refcount_read(&peer->ref) > 0)
0125             return peer;
0126     }
0127 
0128     return NULL;
0129 }
0130 
0131 /*
0132  * Look up a remote transport endpoint for the specified address using RCU.
0133  */
0134 struct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *local,
0135                      const struct sockaddr_rxrpc *srx)
0136 {
0137     struct rxrpc_peer *peer;
0138     unsigned long hash_key = rxrpc_peer_hash_key(local, srx);
0139 
0140     peer = __rxrpc_lookup_peer_rcu(local, srx, hash_key);
0141     if (peer) {
0142         _net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
0143         _leave(" = %p {u=%d}", peer, refcount_read(&peer->ref));
0144     }
0145     return peer;
0146 }
0147 
0148 /*
0149  * assess the MTU size for the network interface through which this peer is
0150  * reached
0151  */
0152 static void rxrpc_assess_MTU_size(struct rxrpc_sock *rx,
0153                   struct rxrpc_peer *peer)
0154 {
0155     struct net *net = sock_net(&rx->sk);
0156     struct dst_entry *dst;
0157     struct rtable *rt;
0158     struct flowi fl;
0159     struct flowi4 *fl4 = &fl.u.ip4;
0160 #ifdef CONFIG_AF_RXRPC_IPV6
0161     struct flowi6 *fl6 = &fl.u.ip6;
0162 #endif
0163 
0164     peer->if_mtu = 1500;
0165 
0166     memset(&fl, 0, sizeof(fl));
0167     switch (peer->srx.transport.family) {
0168     case AF_INET:
0169         rt = ip_route_output_ports(
0170             net, fl4, NULL,
0171             peer->srx.transport.sin.sin_addr.s_addr, 0,
0172             htons(7000), htons(7001), IPPROTO_UDP, 0, 0);
0173         if (IS_ERR(rt)) {
0174             _leave(" [route err %ld]", PTR_ERR(rt));
0175             return;
0176         }
0177         dst = &rt->dst;
0178         break;
0179 
0180 #ifdef CONFIG_AF_RXRPC_IPV6
0181     case AF_INET6:
0182         fl6->flowi6_iif = LOOPBACK_IFINDEX;
0183         fl6->flowi6_scope = RT_SCOPE_UNIVERSE;
0184         fl6->flowi6_proto = IPPROTO_UDP;
0185         memcpy(&fl6->daddr, &peer->srx.transport.sin6.sin6_addr,
0186                sizeof(struct in6_addr));
0187         fl6->fl6_dport = htons(7001);
0188         fl6->fl6_sport = htons(7000);
0189         dst = ip6_route_output(net, NULL, fl6);
0190         if (dst->error) {
0191             _leave(" [route err %d]", dst->error);
0192             return;
0193         }
0194         break;
0195 #endif
0196 
0197     default:
0198         BUG();
0199     }
0200 
0201     peer->if_mtu = dst_mtu(dst);
0202     dst_release(dst);
0203 
0204     _leave(" [if_mtu %u]", peer->if_mtu);
0205 }
0206 
0207 /*
0208  * Allocate a peer.
0209  */
0210 struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp)
0211 {
0212     const void *here = __builtin_return_address(0);
0213     struct rxrpc_peer *peer;
0214 
0215     _enter("");
0216 
0217     peer = kzalloc(sizeof(struct rxrpc_peer), gfp);
0218     if (peer) {
0219         refcount_set(&peer->ref, 1);
0220         peer->local = rxrpc_get_local(local);
0221         INIT_HLIST_HEAD(&peer->error_targets);
0222         peer->service_conns = RB_ROOT;
0223         seqlock_init(&peer->service_conn_lock);
0224         spin_lock_init(&peer->lock);
0225         spin_lock_init(&peer->rtt_input_lock);
0226         peer->debug_id = atomic_inc_return(&rxrpc_debug_id);
0227 
0228         rxrpc_peer_init_rtt(peer);
0229 
0230         if (RXRPC_TX_SMSS > 2190)
0231             peer->cong_cwnd = 2;
0232         else if (RXRPC_TX_SMSS > 1095)
0233             peer->cong_cwnd = 3;
0234         else
0235             peer->cong_cwnd = 4;
0236         trace_rxrpc_peer(peer->debug_id, rxrpc_peer_new, 1, here);
0237     }
0238 
0239     _leave(" = %p", peer);
0240     return peer;
0241 }
0242 
0243 /*
0244  * Initialise peer record.
0245  */
0246 static void rxrpc_init_peer(struct rxrpc_sock *rx, struct rxrpc_peer *peer,
0247                 unsigned long hash_key)
0248 {
0249     peer->hash_key = hash_key;
0250     rxrpc_assess_MTU_size(rx, peer);
0251     peer->mtu = peer->if_mtu;
0252     peer->rtt_last_req = ktime_get_real();
0253 
0254     switch (peer->srx.transport.family) {
0255     case AF_INET:
0256         peer->hdrsize = sizeof(struct iphdr);
0257         break;
0258 #ifdef CONFIG_AF_RXRPC_IPV6
0259     case AF_INET6:
0260         peer->hdrsize = sizeof(struct ipv6hdr);
0261         break;
0262 #endif
0263     default:
0264         BUG();
0265     }
0266 
0267     switch (peer->srx.transport_type) {
0268     case SOCK_DGRAM:
0269         peer->hdrsize += sizeof(struct udphdr);
0270         break;
0271     default:
0272         BUG();
0273     }
0274 
0275     peer->hdrsize += sizeof(struct rxrpc_wire_header);
0276     peer->maxdata = peer->mtu - peer->hdrsize;
0277 }
0278 
0279 /*
0280  * Set up a new peer.
0281  */
0282 static struct rxrpc_peer *rxrpc_create_peer(struct rxrpc_sock *rx,
0283                         struct rxrpc_local *local,
0284                         struct sockaddr_rxrpc *srx,
0285                         unsigned long hash_key,
0286                         gfp_t gfp)
0287 {
0288     struct rxrpc_peer *peer;
0289 
0290     _enter("");
0291 
0292     peer = rxrpc_alloc_peer(local, gfp);
0293     if (peer) {
0294         memcpy(&peer->srx, srx, sizeof(*srx));
0295         rxrpc_init_peer(rx, peer, hash_key);
0296     }
0297 
0298     _leave(" = %p", peer);
0299     return peer;
0300 }
0301 
0302 static void rxrpc_free_peer(struct rxrpc_peer *peer)
0303 {
0304     rxrpc_put_local(peer->local);
0305     kfree_rcu(peer, rcu);
0306 }
0307 
0308 /*
0309  * Set up a new incoming peer.  There shouldn't be any other matching peers
0310  * since we've already done a search in the list from the non-reentrant context
0311  * (the data_ready handler) that is the only place we can add new peers.
0312  */
0313 void rxrpc_new_incoming_peer(struct rxrpc_sock *rx, struct rxrpc_local *local,
0314                  struct rxrpc_peer *peer)
0315 {
0316     struct rxrpc_net *rxnet = local->rxnet;
0317     unsigned long hash_key;
0318 
0319     hash_key = rxrpc_peer_hash_key(local, &peer->srx);
0320     rxrpc_init_peer(rx, peer, hash_key);
0321 
0322     spin_lock(&rxnet->peer_hash_lock);
0323     hash_add_rcu(rxnet->peer_hash, &peer->hash_link, hash_key);
0324     list_add_tail(&peer->keepalive_link, &rxnet->peer_keepalive_new);
0325     spin_unlock(&rxnet->peer_hash_lock);
0326 }
0327 
0328 /*
0329  * obtain a remote transport endpoint for the specified address
0330  */
0331 struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_sock *rx,
0332                      struct rxrpc_local *local,
0333                      struct sockaddr_rxrpc *srx, gfp_t gfp)
0334 {
0335     struct rxrpc_peer *peer, *candidate;
0336     struct rxrpc_net *rxnet = local->rxnet;
0337     unsigned long hash_key = rxrpc_peer_hash_key(local, srx);
0338 
0339     _enter("{%pISp}", &srx->transport);
0340 
0341     /* search the peer list first */
0342     rcu_read_lock();
0343     peer = __rxrpc_lookup_peer_rcu(local, srx, hash_key);
0344     if (peer && !rxrpc_get_peer_maybe(peer))
0345         peer = NULL;
0346     rcu_read_unlock();
0347 
0348     if (!peer) {
0349         /* The peer is not yet present in hash - create a candidate
0350          * for a new record and then redo the search.
0351          */
0352         candidate = rxrpc_create_peer(rx, local, srx, hash_key, gfp);
0353         if (!candidate) {
0354             _leave(" = NULL [nomem]");
0355             return NULL;
0356         }
0357 
0358         spin_lock_bh(&rxnet->peer_hash_lock);
0359 
0360         /* Need to check that we aren't racing with someone else */
0361         peer = __rxrpc_lookup_peer_rcu(local, srx, hash_key);
0362         if (peer && !rxrpc_get_peer_maybe(peer))
0363             peer = NULL;
0364         if (!peer) {
0365             hash_add_rcu(rxnet->peer_hash,
0366                      &candidate->hash_link, hash_key);
0367             list_add_tail(&candidate->keepalive_link,
0368                       &rxnet->peer_keepalive_new);
0369         }
0370 
0371         spin_unlock_bh(&rxnet->peer_hash_lock);
0372 
0373         if (peer)
0374             rxrpc_free_peer(candidate);
0375         else
0376             peer = candidate;
0377     }
0378 
0379     _net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
0380 
0381     _leave(" = %p {u=%d}", peer, refcount_read(&peer->ref));
0382     return peer;
0383 }
0384 
0385 /*
0386  * Get a ref on a peer record.
0387  */
0388 struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *peer)
0389 {
0390     const void *here = __builtin_return_address(0);
0391     int r;
0392 
0393     __refcount_inc(&peer->ref, &r);
0394     trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, r + 1, here);
0395     return peer;
0396 }
0397 
0398 /*
0399  * Get a ref on a peer record unless its usage has already reached 0.
0400  */
0401 struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *peer)
0402 {
0403     const void *here = __builtin_return_address(0);
0404     int r;
0405 
0406     if (peer) {
0407         if (__refcount_inc_not_zero(&peer->ref, &r))
0408             trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, r + 1, here);
0409         else
0410             peer = NULL;
0411     }
0412     return peer;
0413 }
0414 
0415 /*
0416  * Discard a peer record.
0417  */
0418 static void __rxrpc_put_peer(struct rxrpc_peer *peer)
0419 {
0420     struct rxrpc_net *rxnet = peer->local->rxnet;
0421 
0422     ASSERT(hlist_empty(&peer->error_targets));
0423 
0424     spin_lock_bh(&rxnet->peer_hash_lock);
0425     hash_del_rcu(&peer->hash_link);
0426     list_del_init(&peer->keepalive_link);
0427     spin_unlock_bh(&rxnet->peer_hash_lock);
0428 
0429     rxrpc_free_peer(peer);
0430 }
0431 
0432 /*
0433  * Drop a ref on a peer record.
0434  */
0435 void rxrpc_put_peer(struct rxrpc_peer *peer)
0436 {
0437     const void *here = __builtin_return_address(0);
0438     unsigned int debug_id;
0439     bool dead;
0440     int r;
0441 
0442     if (peer) {
0443         debug_id = peer->debug_id;
0444         dead = __refcount_dec_and_test(&peer->ref, &r);
0445         trace_rxrpc_peer(debug_id, rxrpc_peer_put, r - 1, here);
0446         if (dead)
0447             __rxrpc_put_peer(peer);
0448     }
0449 }
0450 
0451 /*
0452  * Drop a ref on a peer record where the caller already holds the
0453  * peer_hash_lock.
0454  */
0455 void rxrpc_put_peer_locked(struct rxrpc_peer *peer)
0456 {
0457     const void *here = __builtin_return_address(0);
0458     unsigned int debug_id = peer->debug_id;
0459     bool dead;
0460     int r;
0461 
0462     dead = __refcount_dec_and_test(&peer->ref, &r);
0463     trace_rxrpc_peer(debug_id, rxrpc_peer_put, r - 1, here);
0464     if (dead) {
0465         hash_del_rcu(&peer->hash_link);
0466         list_del_init(&peer->keepalive_link);
0467         rxrpc_free_peer(peer);
0468     }
0469 }
0470 
0471 /*
0472  * Make sure all peer records have been discarded.
0473  */
0474 void rxrpc_destroy_all_peers(struct rxrpc_net *rxnet)
0475 {
0476     struct rxrpc_peer *peer;
0477     int i;
0478 
0479     for (i = 0; i < HASH_SIZE(rxnet->peer_hash); i++) {
0480         if (hlist_empty(&rxnet->peer_hash[i]))
0481             continue;
0482 
0483         hlist_for_each_entry(peer, &rxnet->peer_hash[i], hash_link) {
0484             pr_err("Leaked peer %u {%u} %pISp\n",
0485                    peer->debug_id,
0486                    refcount_read(&peer->ref),
0487                    &peer->srx.transport);
0488         }
0489     }
0490 }
0491 
0492 /**
0493  * rxrpc_kernel_get_peer - Get the peer address of a call
0494  * @sock: The socket on which the call is in progress.
0495  * @call: The call to query
0496  * @_srx: Where to place the result
0497  *
0498  * Get the address of the remote peer in a call.
0499  */
0500 void rxrpc_kernel_get_peer(struct socket *sock, struct rxrpc_call *call,
0501                struct sockaddr_rxrpc *_srx)
0502 {
0503     *_srx = call->peer->srx;
0504 }
0505 EXPORT_SYMBOL(rxrpc_kernel_get_peer);
0506 
0507 /**
0508  * rxrpc_kernel_get_srtt - Get a call's peer smoothed RTT
0509  * @sock: The socket on which the call is in progress.
0510  * @call: The call to query
0511  * @_srtt: Where to store the SRTT value.
0512  *
0513  * Get the call's peer smoothed RTT in uS.
0514  */
0515 bool rxrpc_kernel_get_srtt(struct socket *sock, struct rxrpc_call *call,
0516                u32 *_srtt)
0517 {
0518     struct rxrpc_peer *peer = call->peer;
0519 
0520     if (peer->rtt_count == 0) {
0521         *_srtt = 1000000; /* 1S */
0522         return false;
0523     }
0524 
0525     *_srtt = call->peer->srtt_us >> 3;
0526     return true;
0527 }
0528 EXPORT_SYMBOL(rxrpc_kernel_get_srtt);