aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/trace/events/rxrpc.h85
-rw-r--r--net/rxrpc/af_rxrpc.c2
-rw-r--r--net/rxrpc/ar-internal.h1
-rw-r--r--net/rxrpc/conn_event.c11
-rw-r--r--net/rxrpc/input.c2
-rw-r--r--net/rxrpc/local_event.c3
-rw-r--r--net/rxrpc/local_object.c57
-rw-r--r--net/rxrpc/output.c34
-rw-r--r--net/rxrpc/peer_event.c46
-rw-r--r--net/rxrpc/rxkad.c6
-rw-r--r--net/rxrpc/sendmsg.c10
11 files changed, 209 insertions, 48 deletions
diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
index 9e96c2fe2793..077e664ac9a2 100644
--- a/include/trace/events/rxrpc.h
+++ b/include/trace/events/rxrpc.h
@@ -15,6 +15,7 @@
15#define _TRACE_RXRPC_H 15#define _TRACE_RXRPC_H
16 16
17#include <linux/tracepoint.h> 17#include <linux/tracepoint.h>
18#include <linux/errqueue.h>
18 19
19/* 20/*
20 * Define enums for tracing information. 21 * Define enums for tracing information.
@@ -210,6 +211,20 @@ enum rxrpc_congest_change {
210 rxrpc_cong_saw_nack, 211 rxrpc_cong_saw_nack,
211}; 212};
212 213
214enum 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
213#endif /* end __RXRPC_DECLARE_TRACE_ENUMS_ONCE_ONLY */ 228#endif /* end __RXRPC_DECLARE_TRACE_ENUMS_ONCE_ONLY */
214 229
215/* 230/*
@@ -437,6 +452,19 @@ enum rxrpc_congest_change {
437 EM(RXRPC_CALL_LOCAL_ERROR, "LocalError") \ 452 EM(RXRPC_CALL_LOCAL_ERROR, "LocalError") \
438 E_(RXRPC_CALL_NETWORK_ERROR, "NetError") 453 E_(RXRPC_CALL_NETWORK_ERROR, "NetError")
439 454
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
440/* 468/*
441 * Export enum symbols via userspace. 469 * Export enum symbols via userspace.
442 */ 470 */
@@ -460,6 +488,7 @@ rxrpc_propose_ack_traces;
460rxrpc_propose_ack_outcomes; 488rxrpc_propose_ack_outcomes;
461rxrpc_congest_modes; 489rxrpc_congest_modes;
462rxrpc_congest_changes; 490rxrpc_congest_changes;
491rxrpc_tx_fail_traces;
463 492
464/* 493/*
465 * Now redefine the EM() and E_() macros to map the enums to the strings that 494 * Now redefine the EM() and E_() macros to map the enums to the strings that
@@ -1374,6 +1403,62 @@ TRACE_EVENT(rxrpc_resend,
1374 __entry->anno) 1403 __entry->anno)
1375 ); 1404 );
1376 1405
1406TRACE_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
1435TRACE_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
1377#endif /* _TRACE_RXRPC_H */ 1462#endif /* _TRACE_RXRPC_H */
1378 1463
1379/* This part must be outside protection */ 1464/* This part must be outside protection */
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 9a2c8e7c000e..2b463047dd7b 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -313,7 +313,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
313 memset(&cp, 0, sizeof(cp)); 313 memset(&cp, 0, sizeof(cp));
314 cp.local = rx->local; 314 cp.local = rx->local;
315 cp.key = key; 315 cp.key = key;
316 cp.security_level = 0; 316 cp.security_level = rx->min_sec_level;
317 cp.exclusive = false; 317 cp.exclusive = false;
318 cp.upgrade = upgrade; 318 cp.upgrade = upgrade;
319 cp.service_id = srx->srx_service; 319 cp.service_id = srx->srx_service;
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 90d7079e0aa9..19975d2ca9a2 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -476,6 +476,7 @@ enum rxrpc_call_flag {
476 RXRPC_CALL_SEND_PING, /* A ping will need to be sent */ 476 RXRPC_CALL_SEND_PING, /* A ping will need to be sent */
477 RXRPC_CALL_PINGING, /* Ping in process */ 477 RXRPC_CALL_PINGING, /* Ping in process */
478 RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */ 478 RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */
479 RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
479}; 480};
480 481
481/* 482/*
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c
index c717152070df..1350f1be8037 100644
--- a/net/rxrpc/conn_event.c
+++ b/net/rxrpc/conn_event.c
@@ -40,7 +40,7 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
40 } __attribute__((packed)) pkt; 40 } __attribute__((packed)) pkt;
41 struct rxrpc_ackinfo ack_info; 41 struct rxrpc_ackinfo ack_info;
42 size_t len; 42 size_t len;
43 int ioc; 43 int ret, ioc;
44 u32 serial, mtu, call_id, padding; 44 u32 serial, mtu, call_id, padding;
45 45
46 _enter("%d", conn->debug_id); 46 _enter("%d", conn->debug_id);
@@ -135,10 +135,13 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
135 break; 135 break;
136 } 136 }
137 137
138 kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len); 138 ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len);
139 conn->params.peer->last_tx_at = ktime_get_real(); 139 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
140 _leave(""); 144 _leave("");
141 return;
142} 145}
143 146
144/* 147/*
@@ -236,6 +239,8 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
236 239
237 ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len); 240 ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
238 if (ret < 0) { 241 if (ret < 0) {
242 trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
243 rxrpc_tx_fail_conn_abort);
239 _debug("sendmsg failed: %d", ret); 244 _debug("sendmsg failed: %d", ret);
240 return -EAGAIN; 245 return -EAGAIN;
241 } 246 }
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index 0410d2277ca2..b5fd6381313d 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -971,7 +971,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call,
971 if (timo) { 971 if (timo) {
972 unsigned long now = jiffies, expect_rx_by; 972 unsigned long now = jiffies, expect_rx_by;
973 973
974 expect_rx_by = jiffies + timo; 974 expect_rx_by = now + timo;
975 WRITE_ONCE(call->expect_rx_by, expect_rx_by); 975 WRITE_ONCE(call->expect_rx_by, expect_rx_by);
976 rxrpc_reduce_call_timer(call, expect_rx_by, now, 976 rxrpc_reduce_call_timer(call, expect_rx_by, now,
977 rxrpc_timer_set_for_normal); 977 rxrpc_timer_set_for_normal);
diff --git a/net/rxrpc/local_event.c b/net/rxrpc/local_event.c
index 93b5d910b4a1..8325f1b86840 100644
--- a/net/rxrpc/local_event.c
+++ b/net/rxrpc/local_event.c
@@ -71,7 +71,8 @@ static void rxrpc_send_version_request(struct rxrpc_local *local,
71 71
72 ret = kernel_sendmsg(local->socket, &msg, iov, 2, len); 72 ret = kernel_sendmsg(local->socket, &msg, iov, 2, len);
73 if (ret < 0) 73 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);
75 76
76 _leave(""); 77 _leave("");
77} 78}
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 8b54e9531d52..b493e6b62740 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -134,22 +134,49 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
134 } 134 }
135 } 135 }
136 136
137 /* we want to receive ICMP errors */ 137 switch (local->srx.transport.family) {
138 opt = 1; 138 case AF_INET:
139 ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR, 139 /* we want to receive ICMP errors */
140 (char *) &opt, sizeof(opt)); 140 opt = 1;
141 if (ret < 0) { 141 ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
142 _debug("setsockopt failed"); 142 (char *) &opt, sizeof(opt));
143 goto error; 143 if (ret < 0) {
144 } 144 _debug("setsockopt failed");
145 goto error;
146 }
145 147
146 /* we want to set the don't fragment bit */ 148 /* we want to set the don't fragment bit */
147 opt = IP_PMTUDISC_DO; 149 opt = IP_PMTUDISC_DO;
148 ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER, 150 ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
149 (char *) &opt, sizeof(opt)); 151 (char *) &opt, sizeof(opt));
150 if (ret < 0) { 152 if (ret < 0) {
151 _debug("setsockopt failed"); 153 _debug("setsockopt failed");
152 goto error; 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();
153 } 180 }
154 181
155 /* set the socket up */ 182 /* set the socket up */
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 7f1fc04775b3..f03de1c59ba3 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -210,6 +210,9 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
210 if (ping) 210 if (ping)
211 call->ping_time = now; 211 call->ping_time = now;
212 conn->params.peer->last_tx_at = ktime_get_real(); 212 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);
213 216
214 if (call->state < RXRPC_CALL_COMPLETE) { 217 if (call->state < RXRPC_CALL_COMPLETE) {
215 if (ret < 0) { 218 if (ret < 0) {
@@ -294,6 +297,10 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
294 ret = kernel_sendmsg(conn->params.local->socket, 297 ret = kernel_sendmsg(conn->params.local->socket,
295 &msg, iov, 1, sizeof(pkt)); 298 &msg, iov, 1, sizeof(pkt));
296 conn->params.peer->last_tx_at = ktime_get_real(); 299 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
297 304
298 rxrpc_put_connection(conn); 305 rxrpc_put_connection(conn);
299 return ret; 306 return ret;
@@ -387,6 +394,9 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
387 conn->params.peer->last_tx_at = ktime_get_real(); 394 conn->params.peer->last_tx_at = ktime_get_real();
388 395
389 up_read(&conn->params.local->defrag_sem); 396 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);
390 if (ret == -EMSGSIZE) 400 if (ret == -EMSGSIZE)
391 goto send_fragmentable; 401 goto send_fragmentable;
392 402
@@ -414,6 +424,17 @@ done:
414 rxrpc_timer_set_for_lost_ack); 424 rxrpc_timer_set_for_lost_ack);
415 } 425 }
416 } 426 }
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 }
417 } 438 }
418 439
419 rxrpc_set_keepalive(call); 440 rxrpc_set_keepalive(call);
@@ -465,6 +486,10 @@ send_fragmentable:
465#endif 486#endif
466 } 487 }
467 488
489 if (ret < 0)
490 trace_rxrpc_tx_fail(call->debug_id, serial, ret,
491 rxrpc_tx_fail_call_data_frag);
492
468 up_write(&conn->params.local->defrag_sem); 493 up_write(&conn->params.local->defrag_sem);
469 goto done; 494 goto done;
470} 495}
@@ -482,6 +507,7 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
482 struct kvec iov[2]; 507 struct kvec iov[2];
483 size_t size; 508 size_t size;
484 __be32 code; 509 __be32 code;
510 int ret;
485 511
486 _enter("%d", local->debug_id); 512 _enter("%d", local->debug_id);
487 513
@@ -516,7 +542,10 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
516 whdr.flags ^= RXRPC_CLIENT_INITIATED; 542 whdr.flags ^= RXRPC_CLIENT_INITIATED;
517 whdr.flags &= RXRPC_CLIENT_INITIATED; 543 whdr.flags &= RXRPC_CLIENT_INITIATED;
518 544
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);
520 } 549 }
521 550
522 rxrpc_free_skb(skb, rxrpc_skb_rx_freed); 551 rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
@@ -567,7 +596,8 @@ void rxrpc_send_keepalive(struct rxrpc_peer *peer)
567 596
568 ret = kernel_sendmsg(peer->local->socket, &msg, iov, 2, len); 597 ret = kernel_sendmsg(peer->local->socket, &msg, iov, 2, len);
569 if (ret < 0) 598 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);
571 601
572 peer->last_tx_at = ktime_get_real(); 602 peer->last_tx_at = ktime_get_real();
573 _leave(""); 603 _leave("");
diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c
index 78c2f95d1f22..0ed8b651cec2 100644
--- a/net/rxrpc/peer_event.c
+++ b/net/rxrpc/peer_event.c
@@ -28,39 +28,39 @@ static void rxrpc_store_error(struct rxrpc_peer *, struct sock_exterr_skb *);
28 * Find the peer associated with an ICMP packet. 28 * Find the peer associated with an ICMP packet.
29 */ 29 */
30static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, 30static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local,
31 const struct sk_buff *skb) 31 const struct sk_buff *skb,
32 struct sockaddr_rxrpc *srx)
32{ 33{
33 struct sock_exterr_skb *serr = SKB_EXT_ERR(skb); 34 struct sock_exterr_skb *serr = SKB_EXT_ERR(skb);
34 struct sockaddr_rxrpc srx;
35 35
36 _enter(""); 36 _enter("");
37 37
38 memset(&srx, 0, sizeof(srx)); 38 memset(srx, 0, sizeof(*srx));
39 srx.transport_type = local->srx.transport_type; 39 srx->transport_type = local->srx.transport_type;
40 srx.transport_len = local->srx.transport_len; 40 srx->transport_len = local->srx.transport_len;
41 srx.transport.family = local->srx.transport.family; 41 srx->transport.family = local->srx.transport.family;
42 42
43 /* Can we see an ICMP4 packet on an ICMP6 listening socket? and vice 43 /* Can we see an ICMP4 packet on an ICMP6 listening socket? and vice
44 * versa? 44 * versa?
45 */ 45 */
46 switch (srx.transport.family) { 46 switch (srx->transport.family) {
47 case AF_INET: 47 case AF_INET:
48 srx.transport.sin.sin_port = serr->port; 48 srx->transport.sin.sin_port = serr->port;
49 switch (serr->ee.ee_origin) { 49 switch (serr->ee.ee_origin) {
50 case SO_EE_ORIGIN_ICMP: 50 case SO_EE_ORIGIN_ICMP:
51 _net("Rx ICMP"); 51 _net("Rx ICMP");
52 memcpy(&srx.transport.sin.sin_addr, 52 memcpy(&srx->transport.sin.sin_addr,
53 skb_network_header(skb) + serr->addr_offset, 53 skb_network_header(skb) + serr->addr_offset,
54 sizeof(struct in_addr)); 54 sizeof(struct in_addr));
55 break; 55 break;
56 case SO_EE_ORIGIN_ICMP6: 56 case SO_EE_ORIGIN_ICMP6:
57 _net("Rx ICMP6 on v4 sock"); 57 _net("Rx ICMP6 on v4 sock");
58 memcpy(&srx.transport.sin.sin_addr, 58 memcpy(&srx->transport.sin.sin_addr,
59 skb_network_header(skb) + serr->addr_offset + 12, 59 skb_network_header(skb) + serr->addr_offset + 12,
60 sizeof(struct in_addr)); 60 sizeof(struct in_addr));
61 break; 61 break;
62 default: 62 default:
63 memcpy(&srx.transport.sin.sin_addr, &ip_hdr(skb)->saddr, 63 memcpy(&srx->transport.sin.sin_addr, &ip_hdr(skb)->saddr,
64 sizeof(struct in_addr)); 64 sizeof(struct in_addr));
65 break; 65 break;
66 } 66 }
@@ -68,25 +68,25 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local,
68 68
69#ifdef CONFIG_AF_RXRPC_IPV6 69#ifdef CONFIG_AF_RXRPC_IPV6
70 case AF_INET6: 70 case AF_INET6:
71 srx.transport.sin6.sin6_port = serr->port; 71 srx->transport.sin6.sin6_port = serr->port;
72 switch (serr->ee.ee_origin) { 72 switch (serr->ee.ee_origin) {
73 case SO_EE_ORIGIN_ICMP6: 73 case SO_EE_ORIGIN_ICMP6:
74 _net("Rx ICMP6"); 74 _net("Rx ICMP6");
75 memcpy(&srx.transport.sin6.sin6_addr, 75 memcpy(&srx->transport.sin6.sin6_addr,
76 skb_network_header(skb) + serr->addr_offset, 76 skb_network_header(skb) + serr->addr_offset,
77 sizeof(struct in6_addr)); 77 sizeof(struct in6_addr));
78 break; 78 break;
79 case SO_EE_ORIGIN_ICMP: 79 case SO_EE_ORIGIN_ICMP:
80 _net("Rx ICMP on v6 sock"); 80 _net("Rx ICMP on v6 sock");
81 srx.transport.sin6.sin6_addr.s6_addr32[0] = 0; 81 srx->transport.sin6.sin6_addr.s6_addr32[0] = 0;
82 srx.transport.sin6.sin6_addr.s6_addr32[1] = 0; 82 srx->transport.sin6.sin6_addr.s6_addr32[1] = 0;
83 srx.transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); 83 srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
84 memcpy(srx.transport.sin6.sin6_addr.s6_addr + 12, 84 memcpy(srx->transport.sin6.sin6_addr.s6_addr + 12,
85 skb_network_header(skb) + serr->addr_offset, 85 skb_network_header(skb) + serr->addr_offset,
86 sizeof(struct in_addr)); 86 sizeof(struct in_addr));
87 break; 87 break;
88 default: 88 default:
89 memcpy(&srx.transport.sin6.sin6_addr, 89 memcpy(&srx->transport.sin6.sin6_addr,
90 &ipv6_hdr(skb)->saddr, 90 &ipv6_hdr(skb)->saddr,
91 sizeof(struct in6_addr)); 91 sizeof(struct in6_addr));
92 break; 92 break;
@@ -98,7 +98,7 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local,
98 BUG(); 98 BUG();
99 } 99 }
100 100
101 return rxrpc_lookup_peer_rcu(local, &srx); 101 return rxrpc_lookup_peer_rcu(local, srx);
102} 102}
103 103
104/* 104/*
@@ -146,6 +146,7 @@ static void rxrpc_adjust_mtu(struct rxrpc_peer *peer, struct sock_exterr_skb *se
146void rxrpc_error_report(struct sock *sk) 146void rxrpc_error_report(struct sock *sk)
147{ 147{
148 struct sock_exterr_skb *serr; 148 struct sock_exterr_skb *serr;
149 struct sockaddr_rxrpc srx;
149 struct rxrpc_local *local = sk->sk_user_data; 150 struct rxrpc_local *local = sk->sk_user_data;
150 struct rxrpc_peer *peer; 151 struct rxrpc_peer *peer;
151 struct sk_buff *skb; 152 struct sk_buff *skb;
@@ -166,7 +167,7 @@ void rxrpc_error_report(struct sock *sk)
166 } 167 }
167 168
168 rcu_read_lock(); 169 rcu_read_lock();
169 peer = rxrpc_lookup_peer_icmp_rcu(local, skb); 170 peer = rxrpc_lookup_peer_icmp_rcu(local, skb, &srx);
170 if (peer && !rxrpc_get_peer_maybe(peer)) 171 if (peer && !rxrpc_get_peer_maybe(peer))
171 peer = NULL; 172 peer = NULL;
172 if (!peer) { 173 if (!peer) {
@@ -176,6 +177,8 @@ void rxrpc_error_report(struct sock *sk)
176 return; 177 return;
177 } 178 }
178 179
180 trace_rxrpc_rx_icmp(peer, &serr->ee, &srx);
181
179 if ((serr->ee.ee_origin == SO_EE_ORIGIN_ICMP && 182 if ((serr->ee.ee_origin == SO_EE_ORIGIN_ICMP &&
180 serr->ee.ee_type == ICMP_DEST_UNREACH && 183 serr->ee.ee_type == ICMP_DEST_UNREACH &&
181 serr->ee.ee_code == ICMP_FRAG_NEEDED)) { 184 serr->ee.ee_code == ICMP_FRAG_NEEDED)) {
@@ -209,9 +212,6 @@ static void rxrpc_store_error(struct rxrpc_peer *peer,
209 212
210 ee = &serr->ee; 213 ee = &serr->ee;
211 214
212 _net("Rx Error o=%d t=%d c=%d e=%d",
213 ee->ee_origin, ee->ee_type, ee->ee_code, ee->ee_errno);
214
215 err = ee->ee_errno; 215 err = ee->ee_errno;
216 216
217 switch (ee->ee_origin) { 217 switch (ee->ee_origin) {
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index 588fea0dd362..6c0ae27fff84 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -664,7 +664,8 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn)
664 664
665 ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len); 665 ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
666 if (ret < 0) { 666 if (ret < 0) {
667 _debug("sendmsg failed: %d", ret); 667 trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
668 rxrpc_tx_fail_conn_challenge);
668 return -EAGAIN; 669 return -EAGAIN;
669 } 670 }
670 671
@@ -719,7 +720,8 @@ static int rxkad_send_response(struct rxrpc_connection *conn,
719 720
720 ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 3, len); 721 ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 3, len);
721 if (ret < 0) { 722 if (ret < 0) {
722 _debug("sendmsg failed: %d", ret); 723 trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
724 rxrpc_tx_fail_conn_response);
723 return -EAGAIN; 725 return -EAGAIN;
724 } 726 }
725 727
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index 206e802ccbdc..be01f9c5d963 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -223,6 +223,15 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
223 223
224 ret = rxrpc_send_data_packet(call, skb, false); 224 ret = rxrpc_send_data_packet(call, skb, false);
225 if (ret < 0) { 225 if (ret < 0) {
226 switch (ret) {
227 case -ENETUNREACH:
228 case -EHOSTUNREACH:
229 case -ECONNREFUSED:
230 rxrpc_set_call_completion(call,
231 RXRPC_CALL_LOCAL_ERROR,
232 0, ret);
233 goto out;
234 }
226 _debug("need instant resend %d", ret); 235 _debug("need instant resend %d", ret);
227 rxrpc_instant_resend(call, ix); 236 rxrpc_instant_resend(call, ix);
228 } else { 237 } else {
@@ -241,6 +250,7 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
241 rxrpc_timer_set_for_send); 250 rxrpc_timer_set_for_send);
242 } 251 }
243 252
253out:
244 rxrpc_free_skb(skb, rxrpc_skb_tx_freed); 254 rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
245 _leave(""); 255 _leave("");
246} 256}