Skip to content

Commit

Permalink
rxrpc: Move data_ready peer lookup into rxrpc_find_connection()
Browse files Browse the repository at this point in the history
Move the peer lookup done in input.c by data_ready into
rxrpc_find_connection().

Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed Jul 6, 2016
1 parent e8d70ce commit 1291e9d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 74 deletions.
3 changes: 0 additions & 3 deletions net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,6 @@ void rxrpc_extract_conn_params(struct rxrpc_conn_proto *,
struct rxrpc_local *, struct sk_buff *);
struct rxrpc_connection *rxrpc_alloc_connection(gfp_t);
struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *,
struct rxrpc_peer *,
struct sk_buff *);
void __rxrpc_disconnect_call(struct rxrpc_call *);
void rxrpc_disconnect_call(struct rxrpc_call *);
Expand Down Expand Up @@ -768,8 +767,6 @@ static inline void rxrpc_sysctl_exit(void) {}
/*
* utils.c
*/
void rxrpc_get_addr_from_skb(struct rxrpc_local *, const struct sk_buff *,
struct sockaddr_rxrpc *);
int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *);

/*
Expand Down
73 changes: 56 additions & 17 deletions net/rxrpc/conn_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,52 +68,91 @@ struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
* packet
*/
struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *local,
struct rxrpc_peer *peer,
struct sk_buff *skb)
{
struct rxrpc_connection *conn;
struct rxrpc_conn_proto k;
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
struct sockaddr_rxrpc srx;
struct rxrpc_peer *peer;
struct rb_node *p;
u32 epoch, cid;

_enter(",{%x,%x}", sp->hdr.cid, sp->hdr.flags);

read_lock_bh(&peer->conn_lock);
if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
goto not_found;

cid = sp->hdr.cid & RXRPC_CIDMASK;
epoch = sp->hdr.epoch;
/* We may have to handle mixing IPv4 and IPv6 */
if (srx.transport.family != local->srx.transport.family) {
pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
srx.transport.family,
local->srx.transport.family);
goto not_found;
}

k.epoch = sp->hdr.epoch;
k.cid = sp->hdr.cid & RXRPC_CIDMASK;

if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) {
/* We need to look up service connections by the full protocol
* parameter set. We look up the peer first as an intermediate
* step and then the connection from the peer's tree.
*/
peer = rxrpc_lookup_peer_rcu(local, &srx);
if (!peer)
goto not_found;

read_lock_bh(&peer->conn_lock);

p = peer->service_conns.rb_node;
while (p) {
conn = rb_entry(p, struct rxrpc_connection, service_node);

_debug("maybe %x", conn->proto.cid);

if (epoch < conn->proto.epoch)
if (k.epoch < conn->proto.epoch)
p = p->rb_left;
else if (epoch > conn->proto.epoch)
else if (k.epoch > conn->proto.epoch)
p = p->rb_right;
else if (cid < conn->proto.cid)
else if (k.cid < conn->proto.cid)
p = p->rb_left;
else if (cid > conn->proto.cid)
else if (k.cid > conn->proto.cid)
p = p->rb_right;
else
goto found;
goto found_service_conn;
}
read_unlock_bh(&peer->conn_lock);
} else {
conn = idr_find(&rxrpc_client_conn_ids, cid >> RXRPC_CIDSHIFT);
if (conn &&
conn->proto.epoch == epoch &&
conn->params.peer == peer)
goto found;
conn = idr_find(&rxrpc_client_conn_ids,
k.cid >> RXRPC_CIDSHIFT);
if (!conn ||
conn->proto.epoch != k.epoch ||
conn->params.local != local)
goto not_found;

peer = conn->params.peer;
switch (srx.transport.family) {
case AF_INET:
if (peer->srx.transport.sin.sin_port !=
srx.transport.sin.sin_port ||
peer->srx.transport.sin.sin_addr.s_addr !=
srx.transport.sin.sin_addr.s_addr)
goto not_found;
break;
default:
BUG();
}

conn = rxrpc_get_connection_maybe(conn);
_leave(" = %p", conn);
return conn;
}

read_unlock_bh(&peer->conn_lock);
not_found:
_leave(" = NULL");
return NULL;

found:
found_service_conn:
conn = rxrpc_get_connection_maybe(conn);
read_unlock_bh(&peer->conn_lock);
_leave(" = %p", conn);
Expand Down
30 changes: 3 additions & 27 deletions net/rxrpc/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,32 +626,6 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
return 0;
}

static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local,
struct sk_buff *skb)
{
struct rxrpc_peer *peer;
struct rxrpc_connection *conn;
struct sockaddr_rxrpc srx;

rxrpc_get_addr_from_skb(local, skb, &srx);
rcu_read_lock();
peer = rxrpc_lookup_peer_rcu(local, &srx);
if (!peer)
goto cant_find_peer;

conn = rxrpc_find_connection(local, peer, skb);
rcu_read_unlock();
if (!conn)
goto cant_find_conn;

return conn;

cant_find_peer:
rcu_read_unlock();
cant_find_conn:
return NULL;
}

/*
* handle data received on the local endpoint
* - may be called in interrupt context
Expand Down Expand Up @@ -731,7 +705,9 @@ void rxrpc_data_ready(struct sock *sk)
* old-fashioned way doesn't really hurt */
struct rxrpc_connection *conn;

conn = rxrpc_conn_from_local(local, skb);
rcu_read_lock();
conn = rxrpc_find_connection(local, skb);
rcu_read_unlock();
if (!conn)
goto cant_route_call;

Expand Down
27 changes: 0 additions & 27 deletions net/rxrpc/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,6 @@
#include <linux/udp.h>
#include "ar-internal.h"

/*
* Set up an RxRPC address from a socket buffer.
*/
void rxrpc_get_addr_from_skb(struct rxrpc_local *local,
const struct sk_buff *skb,
struct sockaddr_rxrpc *srx)
{
memset(srx, 0, sizeof(*srx));
srx->transport_type = local->srx.transport_type;
srx->transport.family = local->srx.transport.family;

/* Can we see an ipv4 UDP packet on an ipv6 UDP socket? and vice
* versa?
*/
switch (srx->transport.family) {
case AF_INET:
srx->transport.sin.sin_port = udp_hdr(skb)->source;
srx->transport_len = sizeof(struct sockaddr_in);
memcpy(&srx->transport.sin.sin_addr, &ip_hdr(skb)->saddr,
sizeof(struct in_addr));
break;

default:
BUG();
}
}

/*
* Fill out a peer address from a socket buffer containing a packet.
*/
Expand Down

0 comments on commit 1291e9d

Please sign in to comment.