Skip to content

Commit f010089

Browse files
committed
Merge tag 'rxrpc-fixes-20180510' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
David Howells says: ==================== rxrpc: Fixes Here are three fixes for AF_RXRPC and two tracepoints that were useful for finding them: (1) Fix missing start of expect-Rx-by timeout on initial packet transmission so that calls will time out if the peer doesn't respond. (2) Fix error reception on AF_INET6 sockets by using the correct family of sockopts on the UDP transport socket. (3) Fix setting the minimum security level on kernel calls so that they can be encrypted. (4) Add a tracepoint to log ICMP/ICMP6 and other error reports from the transport socket. (5) Add a tracepoint to log UDP sendmsg failure so that we can find out if transmission failure occurred on the UDP socket. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents af5d018 + 6b47fe1 commit f010089

File tree

11 files changed

+209
-48
lines changed

11 files changed

+209
-48
lines changed

include/trace/events/rxrpc.h

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define _TRACE_RXRPC_H
1616

1717
#include <linux/tracepoint.h>
18+
#include <linux/errqueue.h>
1819

1920
/*
2021
* Define enums for tracing information.
@@ -210,6 +211,20 @@ enum rxrpc_congest_change {
210211
rxrpc_cong_saw_nack,
211212
};
212213

214+
enum rxrpc_tx_fail_trace {
215+
rxrpc_tx_fail_call_abort,
216+
rxrpc_tx_fail_call_ack,
217+
rxrpc_tx_fail_call_data_frag,
218+
rxrpc_tx_fail_call_data_nofrag,
219+
rxrpc_tx_fail_call_final_resend,
220+
rxrpc_tx_fail_conn_abort,
221+
rxrpc_tx_fail_conn_challenge,
222+
rxrpc_tx_fail_conn_response,
223+
rxrpc_tx_fail_reject,
224+
rxrpc_tx_fail_version_keepalive,
225+
rxrpc_tx_fail_version_reply,
226+
};
227+
213228
#endif /* end __RXRPC_DECLARE_TRACE_ENUMS_ONCE_ONLY */
214229

215230
/*
@@ -437,6 +452,19 @@ enum rxrpc_congest_change {
437452
EM(RXRPC_CALL_LOCAL_ERROR, "LocalError") \
438453
E_(RXRPC_CALL_NETWORK_ERROR, "NetError")
439454

455+
#define rxrpc_tx_fail_traces \
456+
EM(rxrpc_tx_fail_call_abort, "CallAbort") \
457+
EM(rxrpc_tx_fail_call_ack, "CallAck") \
458+
EM(rxrpc_tx_fail_call_data_frag, "CallDataFrag") \
459+
EM(rxrpc_tx_fail_call_data_nofrag, "CallDataNofrag") \
460+
EM(rxrpc_tx_fail_call_final_resend, "CallFinalResend") \
461+
EM(rxrpc_tx_fail_conn_abort, "ConnAbort") \
462+
EM(rxrpc_tx_fail_conn_challenge, "ConnChall") \
463+
EM(rxrpc_tx_fail_conn_response, "ConnResp") \
464+
EM(rxrpc_tx_fail_reject, "Reject") \
465+
EM(rxrpc_tx_fail_version_keepalive, "VerKeepalive") \
466+
E_(rxrpc_tx_fail_version_reply, "VerReply")
467+
440468
/*
441469
* Export enum symbols via userspace.
442470
*/
@@ -460,6 +488,7 @@ rxrpc_propose_ack_traces;
460488
rxrpc_propose_ack_outcomes;
461489
rxrpc_congest_modes;
462490
rxrpc_congest_changes;
491+
rxrpc_tx_fail_traces;
463492

464493
/*
465494
* Now redefine the EM() and E_() macros to map the enums to the strings that
@@ -1374,6 +1403,62 @@ TRACE_EVENT(rxrpc_resend,
13741403
__entry->anno)
13751404
);
13761405

1406+
TRACE_EVENT(rxrpc_rx_icmp,
1407+
TP_PROTO(struct rxrpc_peer *peer, struct sock_extended_err *ee,
1408+
struct sockaddr_rxrpc *srx),
1409+
1410+
TP_ARGS(peer, ee, srx),
1411+
1412+
TP_STRUCT__entry(
1413+
__field(unsigned int, peer )
1414+
__field_struct(struct sock_extended_err, ee )
1415+
__field_struct(struct sockaddr_rxrpc, srx )
1416+
),
1417+
1418+
TP_fast_assign(
1419+
__entry->peer = peer->debug_id;
1420+
memcpy(&__entry->ee, ee, sizeof(__entry->ee));
1421+
memcpy(&__entry->srx, srx, sizeof(__entry->srx));
1422+
),
1423+
1424+
TP_printk("P=%08x o=%u t=%u c=%u i=%u d=%u e=%d %pISp",
1425+
__entry->peer,
1426+
__entry->ee.ee_origin,
1427+
__entry->ee.ee_type,
1428+
__entry->ee.ee_code,
1429+
__entry->ee.ee_info,
1430+
__entry->ee.ee_data,
1431+
__entry->ee.ee_errno,
1432+
&__entry->srx.transport)
1433+
);
1434+
1435+
TRACE_EVENT(rxrpc_tx_fail,
1436+
TP_PROTO(unsigned int debug_id, rxrpc_serial_t serial, int ret,
1437+
enum rxrpc_tx_fail_trace what),
1438+
1439+
TP_ARGS(debug_id, serial, ret, what),
1440+
1441+
TP_STRUCT__entry(
1442+
__field(unsigned int, debug_id )
1443+
__field(rxrpc_serial_t, serial )
1444+
__field(int, ret )
1445+
__field(enum rxrpc_tx_fail_trace, what )
1446+
),
1447+
1448+
TP_fast_assign(
1449+
__entry->debug_id = debug_id;
1450+
__entry->serial = serial;
1451+
__entry->ret = ret;
1452+
__entry->what = what;
1453+
),
1454+
1455+
TP_printk("c=%08x r=%x ret=%d %s",
1456+
__entry->debug_id,
1457+
__entry->serial,
1458+
__entry->ret,
1459+
__print_symbolic(__entry->what, rxrpc_tx_fail_traces))
1460+
);
1461+
13771462
#endif /* _TRACE_RXRPC_H */
13781463

13791464
/* This part must be outside protection */

net/rxrpc/af_rxrpc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
313313
memset(&cp, 0, sizeof(cp));
314314
cp.local = rx->local;
315315
cp.key = key;
316-
cp.security_level = 0;
316+
cp.security_level = rx->min_sec_level;
317317
cp.exclusive = false;
318318
cp.upgrade = upgrade;
319319
cp.service_id = srx->srx_service;

net/rxrpc/ar-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ enum rxrpc_call_flag {
476476
RXRPC_CALL_SEND_PING, /* A ping will need to be sent */
477477
RXRPC_CALL_PINGING, /* Ping in process */
478478
RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */
479+
RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
479480
};
480481

481482
/*

net/rxrpc/conn_event.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
4040
} __attribute__((packed)) pkt;
4141
struct rxrpc_ackinfo ack_info;
4242
size_t len;
43-
int ioc;
43+
int ret, ioc;
4444
u32 serial, mtu, call_id, padding;
4545

4646
_enter("%d", conn->debug_id);
@@ -135,10 +135,13 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
135135
break;
136136
}
137137

138-
kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len);
138+
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len);
139139
conn->params.peer->last_tx_at = ktime_get_real();
140+
if (ret < 0)
141+
trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
142+
rxrpc_tx_fail_call_final_resend);
143+
140144
_leave("");
141-
return;
142145
}
143146

144147
/*
@@ -236,6 +239,8 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
236239

237240
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
238241
if (ret < 0) {
242+
trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
243+
rxrpc_tx_fail_conn_abort);
239244
_debug("sendmsg failed: %d", ret);
240245
return -EAGAIN;
241246
}

net/rxrpc/input.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call,
971971
if (timo) {
972972
unsigned long now = jiffies, expect_rx_by;
973973

974-
expect_rx_by = jiffies + timo;
974+
expect_rx_by = now + timo;
975975
WRITE_ONCE(call->expect_rx_by, expect_rx_by);
976976
rxrpc_reduce_call_timer(call, expect_rx_by, now,
977977
rxrpc_timer_set_for_normal);

net/rxrpc/local_event.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ static void rxrpc_send_version_request(struct rxrpc_local *local,
7171

7272
ret = kernel_sendmsg(local->socket, &msg, iov, 2, len);
7373
if (ret < 0)
74-
_debug("sendmsg failed: %d", ret);
74+
trace_rxrpc_tx_fail(local->debug_id, 0, ret,
75+
rxrpc_tx_fail_version_reply);
7576

7677
_leave("");
7778
}

net/rxrpc/local_object.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,49 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
134134
}
135135
}
136136

137-
/* we want to receive ICMP errors */
138-
opt = 1;
139-
ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
140-
(char *) &opt, sizeof(opt));
141-
if (ret < 0) {
142-
_debug("setsockopt failed");
143-
goto error;
144-
}
137+
switch (local->srx.transport.family) {
138+
case AF_INET:
139+
/* we want to receive ICMP errors */
140+
opt = 1;
141+
ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
142+
(char *) &opt, sizeof(opt));
143+
if (ret < 0) {
144+
_debug("setsockopt failed");
145+
goto error;
146+
}
145147

146-
/* we want to set the don't fragment bit */
147-
opt = IP_PMTUDISC_DO;
148-
ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
149-
(char *) &opt, sizeof(opt));
150-
if (ret < 0) {
151-
_debug("setsockopt failed");
152-
goto error;
148+
/* we want to set the don't fragment bit */
149+
opt = IP_PMTUDISC_DO;
150+
ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
151+
(char *) &opt, sizeof(opt));
152+
if (ret < 0) {
153+
_debug("setsockopt failed");
154+
goto error;
155+
}
156+
break;
157+
158+
case AF_INET6:
159+
/* we want to receive ICMP errors */
160+
opt = 1;
161+
ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
162+
(char *) &opt, sizeof(opt));
163+
if (ret < 0) {
164+
_debug("setsockopt failed");
165+
goto error;
166+
}
167+
168+
/* we want to set the don't fragment bit */
169+
opt = IPV6_PMTUDISC_DO;
170+
ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
171+
(char *) &opt, sizeof(opt));
172+
if (ret < 0) {
173+
_debug("setsockopt failed");
174+
goto error;
175+
}
176+
break;
177+
178+
default:
179+
BUG();
153180
}
154181

155182
/* set the socket up */

net/rxrpc/output.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
210210
if (ping)
211211
call->ping_time = now;
212212
conn->params.peer->last_tx_at = ktime_get_real();
213+
if (ret < 0)
214+
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
215+
rxrpc_tx_fail_call_ack);
213216

214217
if (call->state < RXRPC_CALL_COMPLETE) {
215218
if (ret < 0) {
@@ -294,6 +297,10 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
294297
ret = kernel_sendmsg(conn->params.local->socket,
295298
&msg, iov, 1, sizeof(pkt));
296299
conn->params.peer->last_tx_at = ktime_get_real();
300+
if (ret < 0)
301+
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
302+
rxrpc_tx_fail_call_abort);
303+
297304

298305
rxrpc_put_connection(conn);
299306
return ret;
@@ -387,6 +394,9 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
387394
conn->params.peer->last_tx_at = ktime_get_real();
388395

389396
up_read(&conn->params.local->defrag_sem);
397+
if (ret < 0)
398+
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
399+
rxrpc_tx_fail_call_data_nofrag);
390400
if (ret == -EMSGSIZE)
391401
goto send_fragmentable;
392402

@@ -414,6 +424,17 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
414424
rxrpc_timer_set_for_lost_ack);
415425
}
416426
}
427+
428+
if (sp->hdr.seq == 1 &&
429+
!test_and_set_bit(RXRPC_CALL_BEGAN_RX_TIMER,
430+
&call->flags)) {
431+
unsigned long nowj = jiffies, expect_rx_by;
432+
433+
expect_rx_by = nowj + call->next_rx_timo;
434+
WRITE_ONCE(call->expect_rx_by, expect_rx_by);
435+
rxrpc_reduce_call_timer(call, expect_rx_by, nowj,
436+
rxrpc_timer_set_for_normal);
437+
}
417438
}
418439

419440
rxrpc_set_keepalive(call);
@@ -465,6 +486,10 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
465486
#endif
466487
}
467488

489+
if (ret < 0)
490+
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
491+
rxrpc_tx_fail_call_data_frag);
492+
468493
up_write(&conn->params.local->defrag_sem);
469494
goto done;
470495
}
@@ -482,6 +507,7 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
482507
struct kvec iov[2];
483508
size_t size;
484509
__be32 code;
510+
int ret;
485511

486512
_enter("%d", local->debug_id);
487513

@@ -516,7 +542,10 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
516542
whdr.flags ^= RXRPC_CLIENT_INITIATED;
517543
whdr.flags &= RXRPC_CLIENT_INITIATED;
518544

519-
kernel_sendmsg(local->socket, &msg, iov, 2, size);
545+
ret = kernel_sendmsg(local->socket, &msg, iov, 2, size);
546+
if (ret < 0)
547+
trace_rxrpc_tx_fail(local->debug_id, 0, ret,
548+
rxrpc_tx_fail_reject);
520549
}
521550

522551
rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
@@ -567,7 +596,8 @@ void rxrpc_send_keepalive(struct rxrpc_peer *peer)
567596

568597
ret = kernel_sendmsg(peer->local->socket, &msg, iov, 2, len);
569598
if (ret < 0)
570-
_debug("sendmsg failed: %d", ret);
599+
trace_rxrpc_tx_fail(peer->debug_id, 0, ret,
600+
rxrpc_tx_fail_version_keepalive);
571601

572602
peer->last_tx_at = ktime_get_real();
573603
_leave("");

0 commit comments

Comments
 (0)