Skip to content

Commit 393a2a2

Browse files
committed
rxrpc: Extract the peer address from an incoming packet earlier
Extract the peer address from an incoming packet earlier, at the beginning of rxrpc_input_packet() and thence pass a pointer to it to various functions that use it as part of the lookup rather than doing it on several separate paths. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent cd21eff commit 393a2a2

File tree

4 files changed

+31
-27
lines changed

4 files changed

+31
-27
lines changed

net/rxrpc/ar-internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ int rxrpc_service_prealloc(struct rxrpc_sock *, gfp_t);
824824
void rxrpc_discard_prealloc(struct rxrpc_sock *);
825825
struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *,
826826
struct rxrpc_sock *,
827+
struct sockaddr_rxrpc *,
827828
struct sk_buff *);
828829
void rxrpc_accept_incoming_calls(struct rxrpc_local *);
829830
int rxrpc_user_charge_accept(struct rxrpc_sock *, unsigned long);
@@ -916,6 +917,7 @@ extern unsigned int rxrpc_closed_conn_expiry;
916917

917918
struct rxrpc_connection *rxrpc_alloc_connection(struct rxrpc_net *, gfp_t);
918919
struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *,
920+
struct sockaddr_rxrpc *,
919921
struct sk_buff *,
920922
struct rxrpc_peer **);
921923
void __rxrpc_disconnect_call(struct rxrpc_connection *, struct rxrpc_call *);

net/rxrpc/call_accept.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx,
258258
struct rxrpc_peer *peer,
259259
struct rxrpc_connection *conn,
260260
const struct rxrpc_security *sec,
261+
struct sockaddr_rxrpc *peer_srx,
261262
struct sk_buff *skb)
262263
{
263264
struct rxrpc_backlog *b = rx->backlog;
@@ -287,8 +288,7 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx,
287288
peer = NULL;
288289
if (!peer) {
289290
peer = b->peer_backlog[peer_tail];
290-
if (rxrpc_extract_addr_from_skb(&peer->srx, skb) < 0)
291-
return NULL;
291+
peer->srx = *peer_srx;
292292
b->peer_backlog[peer_tail] = NULL;
293293
smp_store_release(&b->peer_backlog_tail,
294294
(peer_tail + 1) &
@@ -346,6 +346,7 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx,
346346
*/
347347
struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local,
348348
struct rxrpc_sock *rx,
349+
struct sockaddr_rxrpc *peer_srx,
349350
struct sk_buff *skb)
350351
{
351352
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
@@ -371,15 +372,16 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local,
371372
* we have to recheck the routing. However, we're now holding
372373
* rx->incoming_lock, so the values should remain stable.
373374
*/
374-
conn = rxrpc_find_connection_rcu(local, skb, &peer);
375+
conn = rxrpc_find_connection_rcu(local, peer_srx, skb, &peer);
375376

376377
if (!conn) {
377378
sec = rxrpc_get_incoming_security(rx, skb);
378379
if (!sec)
379380
goto no_call;
380381
}
381382

382-
call = rxrpc_alloc_incoming_call(rx, local, peer, conn, sec, skb);
383+
call = rxrpc_alloc_incoming_call(rx, local, peer, conn, sec, peer_srx,
384+
skb);
383385
if (!call) {
384386
skb->mark = RXRPC_SKB_MARK_REJECT_BUSY;
385387
goto no_call;

net/rxrpc/conn_object.c

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,29 +73,17 @@ struct rxrpc_connection *rxrpc_alloc_connection(struct rxrpc_net *rxnet,
7373
* The caller must be holding the RCU read lock.
7474
*/
7575
struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
76+
struct sockaddr_rxrpc *srx,
7677
struct sk_buff *skb,
7778
struct rxrpc_peer **_peer)
7879
{
7980
struct rxrpc_connection *conn;
8081
struct rxrpc_conn_proto k;
8182
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
82-
struct sockaddr_rxrpc srx;
8383
struct rxrpc_peer *peer;
8484

8585
_enter(",%x", sp->hdr.cid & RXRPC_CIDMASK);
8686

87-
if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
88-
goto not_found;
89-
90-
if (srx.transport.family != local->srx.transport.family &&
91-
(srx.transport.family == AF_INET &&
92-
local->srx.transport.family != AF_INET6)) {
93-
pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
94-
srx.transport.family,
95-
local->srx.transport.family);
96-
goto not_found;
97-
}
98-
9987
k.epoch = sp->hdr.epoch;
10088
k.cid = sp->hdr.cid & RXRPC_CIDMASK;
10189

@@ -104,7 +92,7 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
10492
* parameter set. We look up the peer first as an intermediate
10593
* step and then the connection from the peer's tree.
10694
*/
107-
peer = rxrpc_lookup_peer_rcu(local, &srx);
95+
peer = rxrpc_lookup_peer_rcu(local, srx);
10896
if (!peer)
10997
goto not_found;
11098
*_peer = peer;
@@ -117,8 +105,7 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
117105
/* Look up client connections by connection ID alone as their
118106
* IDs are unique for this machine.
119107
*/
120-
conn = idr_find(&rxrpc_client_conn_ids,
121-
sp->hdr.cid >> RXRPC_CIDSHIFT);
108+
conn = idr_find(&rxrpc_client_conn_ids, sp->hdr.cid >> RXRPC_CIDSHIFT);
122109
if (!conn || refcount_read(&conn->ref) == 0) {
123110
_debug("no conn");
124111
goto not_found;
@@ -129,20 +116,20 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
129116
goto not_found;
130117

131118
peer = conn->peer;
132-
switch (srx.transport.family) {
119+
switch (srx->transport.family) {
133120
case AF_INET:
134121
if (peer->srx.transport.sin.sin_port !=
135-
srx.transport.sin.sin_port ||
122+
srx->transport.sin.sin_port ||
136123
peer->srx.transport.sin.sin_addr.s_addr !=
137-
srx.transport.sin.sin_addr.s_addr)
124+
srx->transport.sin.sin_addr.s_addr)
138125
goto not_found;
139126
break;
140127
#ifdef CONFIG_AF_RXRPC_IPV6
141128
case AF_INET6:
142129
if (peer->srx.transport.sin6.sin6_port !=
143-
srx.transport.sin6.sin6_port ||
130+
srx->transport.sin6.sin6_port ||
144131
memcmp(&peer->srx.transport.sin6.sin6_addr,
145-
&srx.transport.sin6.sin6_addr,
132+
&srx->transport.sin6.sin6_addr,
146133
sizeof(struct in6_addr)) != 0)
147134
goto not_found;
148135
break;

net/rxrpc/io_thread.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ static bool rxrpc_extract_abort(struct sk_buff *skb)
155155
static int rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff **_skb)
156156
{
157157
struct rxrpc_connection *conn;
158+
struct sockaddr_rxrpc peer_srx;
158159
struct rxrpc_channel *chan;
159160
struct rxrpc_call *call = NULL;
160161
struct rxrpc_skb_priv *sp;
@@ -257,6 +258,18 @@ static int rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff **_skb)
257258
if (sp->hdr.serviceId == 0)
258259
goto bad_message;
259260

261+
if (WARN_ON_ONCE(rxrpc_extract_addr_from_skb(&peer_srx, skb) < 0))
262+
return 0; /* Unsupported address type - discard. */
263+
264+
if (peer_srx.transport.family != local->srx.transport.family &&
265+
(peer_srx.transport.family == AF_INET &&
266+
local->srx.transport.family != AF_INET6)) {
267+
pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
268+
peer_srx.transport.family,
269+
local->srx.transport.family);
270+
return 0; /* Wrong address type - discard. */
271+
}
272+
260273
rcu_read_lock();
261274

262275
if (rxrpc_to_server(sp)) {
@@ -276,7 +289,7 @@ static int rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff **_skb)
276289
}
277290
}
278291

279-
conn = rxrpc_find_connection_rcu(local, skb, &peer);
292+
conn = rxrpc_find_connection_rcu(local, &peer_srx, skb, &peer);
280293
if (conn) {
281294
if (sp->hdr.securityIndex != conn->security_ix)
282295
goto wrong_security;
@@ -389,7 +402,7 @@ static int rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff **_skb)
389402
rcu_read_unlock();
390403
return 0;
391404
}
392-
call = rxrpc_new_incoming_call(local, rx, skb);
405+
call = rxrpc_new_incoming_call(local, rx, &peer_srx, skb);
393406
if (!call) {
394407
rcu_read_unlock();
395408
goto reject_packet;

0 commit comments

Comments
 (0)