Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rxrpc: Move data_ready peer lookup into rxrpc_find_connection()

Move the peer lookup done in input.c by data_ready into
rxrpc_find_connection().

Signed-off-by: David Howells <dhowells@redhat.com>

+59 -74
-3
net/rxrpc/ar-internal.h
··· 564 564 struct rxrpc_local *, struct sk_buff *); 565 565 struct rxrpc_connection *rxrpc_alloc_connection(gfp_t); 566 566 struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *, 567 - struct rxrpc_peer *, 568 567 struct sk_buff *); 569 568 void __rxrpc_disconnect_call(struct rxrpc_call *); 570 569 void rxrpc_disconnect_call(struct rxrpc_call *); ··· 767 768 /* 768 769 * utils.c 769 770 */ 770 - void rxrpc_get_addr_from_skb(struct rxrpc_local *, const struct sk_buff *, 771 - struct sockaddr_rxrpc *); 772 771 int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *); 773 772 774 773 /*
+56 -17
net/rxrpc/conn_object.c
··· 68 68 * packet 69 69 */ 70 70 struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *local, 71 - struct rxrpc_peer *peer, 72 71 struct sk_buff *skb) 73 72 { 74 73 struct rxrpc_connection *conn; 74 + struct rxrpc_conn_proto k; 75 75 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 76 + struct sockaddr_rxrpc srx; 77 + struct rxrpc_peer *peer; 76 78 struct rb_node *p; 77 - u32 epoch, cid; 78 79 79 80 _enter(",{%x,%x}", sp->hdr.cid, sp->hdr.flags); 80 81 81 - read_lock_bh(&peer->conn_lock); 82 + if (rxrpc_extract_addr_from_skb(&srx, skb) < 0) 83 + goto not_found; 82 84 83 - cid = sp->hdr.cid & RXRPC_CIDMASK; 84 - epoch = sp->hdr.epoch; 85 + /* We may have to handle mixing IPv4 and IPv6 */ 86 + if (srx.transport.family != local->srx.transport.family) { 87 + pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n", 88 + srx.transport.family, 89 + local->srx.transport.family); 90 + goto not_found; 91 + } 92 + 93 + k.epoch = sp->hdr.epoch; 94 + k.cid = sp->hdr.cid & RXRPC_CIDMASK; 85 95 86 96 if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) { 97 + /* We need to look up service connections by the full protocol 98 + * parameter set. We look up the peer first as an intermediate 99 + * step and then the connection from the peer's tree. 100 + */ 101 + peer = rxrpc_lookup_peer_rcu(local, &srx); 102 + if (!peer) 103 + goto not_found; 104 + 105 + read_lock_bh(&peer->conn_lock); 106 + 87 107 p = peer->service_conns.rb_node; 88 108 while (p) { 89 109 conn = rb_entry(p, struct rxrpc_connection, service_node); 90 110 91 111 _debug("maybe %x", conn->proto.cid); 92 112 93 - if (epoch < conn->proto.epoch) 113 + if (k.epoch < conn->proto.epoch) 94 114 p = p->rb_left; 95 - else if (epoch > conn->proto.epoch) 115 + else if (k.epoch > conn->proto.epoch) 96 116 p = p->rb_right; 97 - else if (cid < conn->proto.cid) 117 + else if (k.cid < conn->proto.cid) 98 118 p = p->rb_left; 99 - else if (cid > conn->proto.cid) 119 + else if (k.cid > conn->proto.cid) 100 120 p = p->rb_right; 101 121 else 102 - goto found; 122 + goto found_service_conn; 103 123 } 124 + read_unlock_bh(&peer->conn_lock); 104 125 } else { 105 - conn = idr_find(&rxrpc_client_conn_ids, cid >> RXRPC_CIDSHIFT); 106 - if (conn && 107 - conn->proto.epoch == epoch && 108 - conn->params.peer == peer) 109 - goto found; 126 + conn = idr_find(&rxrpc_client_conn_ids, 127 + k.cid >> RXRPC_CIDSHIFT); 128 + if (!conn || 129 + conn->proto.epoch != k.epoch || 130 + conn->params.local != local) 131 + goto not_found; 132 + 133 + peer = conn->params.peer; 134 + switch (srx.transport.family) { 135 + case AF_INET: 136 + if (peer->srx.transport.sin.sin_port != 137 + srx.transport.sin.sin_port || 138 + peer->srx.transport.sin.sin_addr.s_addr != 139 + srx.transport.sin.sin_addr.s_addr) 140 + goto not_found; 141 + break; 142 + default: 143 + BUG(); 144 + } 145 + 146 + conn = rxrpc_get_connection_maybe(conn); 147 + _leave(" = %p", conn); 148 + return conn; 110 149 } 111 150 112 - read_unlock_bh(&peer->conn_lock); 151 + not_found: 113 152 _leave(" = NULL"); 114 153 return NULL; 115 154 116 - found: 155 + found_service_conn: 117 156 conn = rxrpc_get_connection_maybe(conn); 118 157 read_unlock_bh(&peer->conn_lock); 119 158 _leave(" = %p", conn);
+3 -27
net/rxrpc/input.c
··· 626 626 return 0; 627 627 } 628 628 629 - static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local, 630 - struct sk_buff *skb) 631 - { 632 - struct rxrpc_peer *peer; 633 - struct rxrpc_connection *conn; 634 - struct sockaddr_rxrpc srx; 635 - 636 - rxrpc_get_addr_from_skb(local, skb, &srx); 637 - rcu_read_lock(); 638 - peer = rxrpc_lookup_peer_rcu(local, &srx); 639 - if (!peer) 640 - goto cant_find_peer; 641 - 642 - conn = rxrpc_find_connection(local, peer, skb); 643 - rcu_read_unlock(); 644 - if (!conn) 645 - goto cant_find_conn; 646 - 647 - return conn; 648 - 649 - cant_find_peer: 650 - rcu_read_unlock(); 651 - cant_find_conn: 652 - return NULL; 653 - } 654 - 655 629 /* 656 630 * handle data received on the local endpoint 657 631 * - may be called in interrupt context ··· 705 731 * old-fashioned way doesn't really hurt */ 706 732 struct rxrpc_connection *conn; 707 733 708 - conn = rxrpc_conn_from_local(local, skb); 734 + rcu_read_lock(); 735 + conn = rxrpc_find_connection(local, skb); 736 + rcu_read_unlock(); 709 737 if (!conn) 710 738 goto cant_route_call; 711 739
-27
net/rxrpc/utils.c
··· 15 15 #include "ar-internal.h" 16 16 17 17 /* 18 - * Set up an RxRPC address from a socket buffer. 19 - */ 20 - void rxrpc_get_addr_from_skb(struct rxrpc_local *local, 21 - const struct sk_buff *skb, 22 - struct sockaddr_rxrpc *srx) 23 - { 24 - memset(srx, 0, sizeof(*srx)); 25 - srx->transport_type = local->srx.transport_type; 26 - srx->transport.family = local->srx.transport.family; 27 - 28 - /* Can we see an ipv4 UDP packet on an ipv6 UDP socket? and vice 29 - * versa? 30 - */ 31 - switch (srx->transport.family) { 32 - case AF_INET: 33 - srx->transport.sin.sin_port = udp_hdr(skb)->source; 34 - srx->transport_len = sizeof(struct sockaddr_in); 35 - memcpy(&srx->transport.sin.sin_addr, &ip_hdr(skb)->saddr, 36 - sizeof(struct in_addr)); 37 - break; 38 - 39 - default: 40 - BUG(); 41 - } 42 - } 43 - 44 - /* 45 18 * Fill out a peer address from a socket buffer containing a packet. 46 19 */ 47 20 int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *srx, struct sk_buff *skb)