diff options
| author | David Howells <dhowells@redhat.com> | 2016-06-30 07:02:53 -0400 |
|---|---|---|
| committer | David Howells <dhowells@redhat.com> | 2016-07-06 05:51:14 -0400 |
| commit | 1291e9d1084506c5cba6313ce809d7516bb5868a (patch) | |
| tree | be33d884464e6072ee278801327de9fe76c9b089 /net | |
| parent | e8d70ce177eeb4fbd1c218c60118d2c19c2496a6 (diff) | |
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>
Diffstat (limited to 'net')
| -rw-r--r-- | net/rxrpc/ar-internal.h | 3 | ||||
| -rw-r--r-- | net/rxrpc/conn_object.c | 73 | ||||
| -rw-r--r-- | net/rxrpc/input.c | 30 | ||||
| -rw-r--r-- | net/rxrpc/utils.c | 27 |
4 files changed, 59 insertions, 74 deletions
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 6fdee761dd0b..0fe63baf1286 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h | |||
| @@ -564,7 +564,6 @@ void rxrpc_extract_conn_params(struct rxrpc_conn_proto *, | |||
| 564 | struct rxrpc_local *, struct sk_buff *); | 564 | struct rxrpc_local *, struct sk_buff *); |
| 565 | struct rxrpc_connection *rxrpc_alloc_connection(gfp_t); | 565 | struct rxrpc_connection *rxrpc_alloc_connection(gfp_t); |
| 566 | struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *, | 566 | struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *, |
| 567 | struct rxrpc_peer *, | ||
| 568 | struct sk_buff *); | 567 | struct sk_buff *); |
| 569 | void __rxrpc_disconnect_call(struct rxrpc_call *); | 568 | void __rxrpc_disconnect_call(struct rxrpc_call *); |
| 570 | void rxrpc_disconnect_call(struct rxrpc_call *); | 569 | void rxrpc_disconnect_call(struct rxrpc_call *); |
| @@ -768,8 +767,6 @@ static inline void rxrpc_sysctl_exit(void) {} | |||
| 768 | /* | 767 | /* |
| 769 | * utils.c | 768 | * utils.c |
| 770 | */ | 769 | */ |
| 771 | void rxrpc_get_addr_from_skb(struct rxrpc_local *, const struct sk_buff *, | ||
| 772 | struct sockaddr_rxrpc *); | ||
| 773 | int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *); | 770 | int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *); |
| 774 | 771 | ||
| 775 | /* | 772 | /* |
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index 89bc6480b4e2..130713869a16 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c | |||
| @@ -68,52 +68,91 @@ struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp) | |||
| 68 | * packet | 68 | * packet |
| 69 | */ | 69 | */ |
| 70 | struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *local, | 70 | struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *local, |
| 71 | struct rxrpc_peer *peer, | ||
| 72 | struct sk_buff *skb) | 71 | struct sk_buff *skb) |
| 73 | { | 72 | { |
| 74 | struct rxrpc_connection *conn; | 73 | struct rxrpc_connection *conn; |
| 74 | struct rxrpc_conn_proto k; | ||
| 75 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | 75 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 76 | struct sockaddr_rxrpc srx; | ||
| 77 | struct rxrpc_peer *peer; | ||
| 76 | struct rb_node *p; | 78 | struct rb_node *p; |
| 77 | u32 epoch, cid; | ||
| 78 | 79 | ||
| 79 | _enter(",{%x,%x}", sp->hdr.cid, sp->hdr.flags); | 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; | 85 | /* We may have to handle mixing IPv4 and IPv6 */ |
| 84 | epoch = sp->hdr.epoch; | 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 | if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) { | 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 | p = peer->service_conns.rb_node; | 107 | p = peer->service_conns.rb_node; |
| 88 | while (p) { | 108 | while (p) { |
| 89 | conn = rb_entry(p, struct rxrpc_connection, service_node); | 109 | conn = rb_entry(p, struct rxrpc_connection, service_node); |
| 90 | 110 | ||
| 91 | _debug("maybe %x", conn->proto.cid); | 111 | _debug("maybe %x", conn->proto.cid); |
| 92 | 112 | ||
| 93 | if (epoch < conn->proto.epoch) | 113 | if (k.epoch < conn->proto.epoch) |
| 94 | p = p->rb_left; | 114 | p = p->rb_left; |
| 95 | else if (epoch > conn->proto.epoch) | 115 | else if (k.epoch > conn->proto.epoch) |
| 96 | p = p->rb_right; | 116 | p = p->rb_right; |
| 97 | else if (cid < conn->proto.cid) | 117 | else if (k.cid < conn->proto.cid) |
| 98 | p = p->rb_left; | 118 | p = p->rb_left; |
| 99 | else if (cid > conn->proto.cid) | 119 | else if (k.cid > conn->proto.cid) |
| 100 | p = p->rb_right; | 120 | p = p->rb_right; |
| 101 | else | 121 | else |
| 102 | goto found; | 122 | goto found_service_conn; |
| 103 | } | 123 | } |
| 124 | read_unlock_bh(&peer->conn_lock); | ||
| 104 | } else { | 125 | } else { |
| 105 | conn = idr_find(&rxrpc_client_conn_ids, cid >> RXRPC_CIDSHIFT); | 126 | conn = idr_find(&rxrpc_client_conn_ids, |
| 106 | if (conn && | 127 | k.cid >> RXRPC_CIDSHIFT); |
| 107 | conn->proto.epoch == epoch && | 128 | if (!conn || |
| 108 | conn->params.peer == peer) | 129 | conn->proto.epoch != k.epoch || |
| 109 | goto found; | 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 | _leave(" = NULL"); | 152 | _leave(" = NULL"); |
| 114 | return NULL; | 153 | return NULL; |
| 115 | 154 | ||
| 116 | found: | 155 | found_service_conn: |
| 117 | conn = rxrpc_get_connection_maybe(conn); | 156 | conn = rxrpc_get_connection_maybe(conn); |
| 118 | read_unlock_bh(&peer->conn_lock); | 157 | read_unlock_bh(&peer->conn_lock); |
| 119 | _leave(" = %p", conn); | 158 | _leave(" = %p", conn); |
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index b993f2dc5a09..c2436476f793 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
| @@ -626,32 +626,6 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb) | |||
| 626 | return 0; | 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 | * handle data received on the local endpoint | 630 | * handle data received on the local endpoint |
| 657 | * - may be called in interrupt context | 631 | * - may be called in interrupt context |
| @@ -731,7 +705,9 @@ void rxrpc_data_ready(struct sock *sk) | |||
| 731 | * old-fashioned way doesn't really hurt */ | 705 | * old-fashioned way doesn't really hurt */ |
| 732 | struct rxrpc_connection *conn; | 706 | struct rxrpc_connection *conn; |
| 733 | 707 | ||
| 734 | conn = rxrpc_conn_from_local(local, skb); | 708 | rcu_read_lock(); |
| 709 | conn = rxrpc_find_connection(local, skb); | ||
| 710 | rcu_read_unlock(); | ||
| 735 | if (!conn) | 711 | if (!conn) |
| 736 | goto cant_route_call; | 712 | goto cant_route_call; |
| 737 | 713 | ||
diff --git a/net/rxrpc/utils.c b/net/rxrpc/utils.c index d3db02ecc37f..b88914d53ca5 100644 --- a/net/rxrpc/utils.c +++ b/net/rxrpc/utils.c | |||
| @@ -15,33 +15,6 @@ | |||
| 15 | #include "ar-internal.h" | 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 | * Fill out a peer address from a socket buffer containing a packet. | 18 | * Fill out a peer address from a socket buffer containing a packet. |
| 46 | */ | 19 | */ |
| 47 | int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *srx, struct sk_buff *skb) | 20 | int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *srx, struct sk_buff *skb) |
