Skip to content

Commit d991b4a

Browse files
committed
rxrpc: Move peer lookup from call-accept to new-incoming-conn
Move the lookup of a peer from a call that's being accepted into the function that creates a new incoming connection. This will allow us to avoid incrementing the peer's usage count in some cases in future. Note that I haven't bother to integrate rxrpc_get_addr_from_skb() with rxrpc_extract_addr_from_skb() as I'm going to delete the former in the very near future. Signed-off-by: David Howells <[email protected]>
1 parent 7877a4a commit d991b4a

File tree

4 files changed

+51
-26
lines changed

4 files changed

+51
-26
lines changed

net/rxrpc/ar-internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ static inline void rxrpc_queue_conn(struct rxrpc_connection *conn)
607607
* conn_service.c
608608
*/
609609
struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *,
610-
struct rxrpc_peer *,
610+
struct sockaddr_rxrpc *,
611611
struct sk_buff *);
612612

613613
/*
@@ -773,6 +773,7 @@ static inline void rxrpc_sysctl_exit(void) {}
773773
*/
774774
void rxrpc_get_addr_from_skb(struct rxrpc_local *, const struct sk_buff *,
775775
struct sockaddr_rxrpc *);
776+
int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *);
776777

777778
/*
778779
* debug tracing

net/rxrpc/call_accept.c

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
7575
{
7676
struct rxrpc_connection *conn;
7777
struct rxrpc_skb_priv *sp, *nsp;
78-
struct rxrpc_peer *peer;
7978
struct rxrpc_call *call;
8079
struct sk_buff *notification;
8180
int ret;
@@ -94,15 +93,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
9493
rxrpc_new_skb(notification);
9594
notification->mark = RXRPC_SKB_MARK_NEW_CALL;
9695

97-
peer = rxrpc_lookup_peer(local, srx, GFP_NOIO);
98-
if (!peer) {
99-
_debug("no peer");
100-
ret = -EBUSY;
101-
goto error;
102-
}
103-
104-
conn = rxrpc_incoming_connection(local, peer, skb);
105-
rxrpc_put_peer(peer);
96+
conn = rxrpc_incoming_connection(local, srx, skb);
10697
if (IS_ERR(conn)) {
10798
_debug("no conn");
10899
ret = PTR_ERR(conn);
@@ -226,20 +217,8 @@ void rxrpc_accept_incoming_calls(struct rxrpc_local *local)
226217
whdr._rsvd = 0;
227218
whdr.serviceId = htons(sp->hdr.serviceId);
228219

229-
/* determine the remote address */
230-
memset(&srx, 0, sizeof(srx));
231-
srx.srx_family = AF_RXRPC;
232-
srx.transport.family = local->srx.transport.family;
233-
srx.transport_type = local->srx.transport_type;
234-
switch (srx.transport.family) {
235-
case AF_INET:
236-
srx.transport_len = sizeof(struct sockaddr_in);
237-
srx.transport.sin.sin_port = udp_hdr(skb)->source;
238-
srx.transport.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
239-
break;
240-
default:
241-
goto busy;
242-
}
220+
if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
221+
goto drop;
243222

244223
/* get the socket providing the service */
245224
read_lock_bh(&local->services_lock);
@@ -285,6 +264,10 @@ void rxrpc_accept_incoming_calls(struct rxrpc_local *local)
285264
rxrpc_free_skb(skb);
286265
return;
287266

267+
drop:
268+
rxrpc_free_skb(skb);
269+
return;
270+
288271
invalid_service:
289272
skb->priority = RX_INVALID_OPERATION;
290273
rxrpc_reject_packet(local, skb);

net/rxrpc/conn_service.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,24 @@
1616
* get a record of an incoming connection
1717
*/
1818
struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *local,
19-
struct rxrpc_peer *peer,
19+
struct sockaddr_rxrpc *srx,
2020
struct sk_buff *skb)
2121
{
2222
struct rxrpc_connection *conn, *candidate = NULL;
2323
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
24+
struct rxrpc_peer *peer;
2425
struct rb_node *p, **pp;
2526
const char *new = "old";
2627
u32 epoch, cid;
2728

2829
_enter("");
2930

31+
peer = rxrpc_lookup_peer(local, srx, GFP_NOIO);
32+
if (!peer) {
33+
_debug("no peer");
34+
return ERR_PTR(-EBUSY);
35+
}
36+
3037
ASSERT(sp->hdr.flags & RXRPC_CLIENT_INITIATED);
3138

3239
epoch = sp->hdr.epoch;
@@ -58,6 +65,7 @@ struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *local,
5865
* redo the search */
5966
candidate = rxrpc_alloc_connection(GFP_NOIO);
6067
if (!candidate) {
68+
rxrpc_put_peer(peer);
6169
_leave(" = -ENOMEM");
6270
return ERR_PTR(-ENOMEM);
6371
}
@@ -114,6 +122,7 @@ struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *local,
114122
success:
115123
_net("CONNECTION %s %d {%x}", new, conn->debug_id, conn->proto.cid);
116124

125+
rxrpc_put_peer(peer);
117126
_leave(" = %p {u=%d}", conn, atomic_read(&conn->usage));
118127
return conn;
119128

net/rxrpc/utils.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111

1212
#include <linux/ip.h>
13+
#include <linux/ipv6.h>
1314
#include <linux/udp.h>
1415
#include "ar-internal.h"
1516

@@ -39,3 +40,34 @@ void rxrpc_get_addr_from_skb(struct rxrpc_local *local,
3940
BUG();
4041
}
4142
}
43+
44+
/*
45+
* Fill out a peer address from a socket buffer containing a packet.
46+
*/
47+
int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *srx, struct sk_buff *skb)
48+
{
49+
memset(srx, 0, sizeof(*srx));
50+
51+
switch (ntohs(skb->protocol)) {
52+
case ETH_P_IP:
53+
srx->transport_type = SOCK_DGRAM;
54+
srx->transport_len = sizeof(srx->transport.sin);
55+
srx->transport.sin.sin_family = AF_INET;
56+
srx->transport.sin.sin_port = udp_hdr(skb)->source;
57+
srx->transport.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
58+
return 0;
59+
60+
case ETH_P_IPV6:
61+
srx->transport_type = SOCK_DGRAM;
62+
srx->transport_len = sizeof(srx->transport.sin6);
63+
srx->transport.sin6.sin6_family = AF_INET6;
64+
srx->transport.sin6.sin6_port = udp_hdr(skb)->source;
65+
srx->transport.sin6.sin6_addr = ipv6_hdr(skb)->saddr;
66+
return 0;
67+
68+
default:
69+
pr_warn_ratelimited("AF_RXRPC: Unknown eth protocol %u\n",
70+
ntohs(skb->protocol));
71+
return -EAFNOSUPPORT;
72+
}
73+
}

0 commit comments

Comments
 (0)