aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-05-11 15:55:57 -0400
committerDavid S. Miller <davem@davemloft.net>2018-05-11 15:55:57 -0400
commitf01008916f1a4b7e238bf124d13d5c509e8cc362 (patch)
tree700ce63f72a5d47b0b0c784bf83301db26b11db6 /net
parentaf5d01842fe1fbfb9f5e1c1d957ba02ab6f4569a (diff)
parent6b47fe1d1ca3aec3a1a8623439c22fbf51016cd8 (diff)
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 <davem@davemloft.net>
Diffstat (limited to 'net')
-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
10 files changed, 124 insertions, 48 deletions
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}