1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* /proc/net/ support for AF_RXRPC 3 * 4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/module.h> 9 #include <net/sock.h> 10 #include <net/af_rxrpc.h> 11 #include "ar-internal.h" 12 13 static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES] = { 14 [RXRPC_CONN_UNUSED] = "Unused ", 15 [RXRPC_CONN_CLIENT] = "Client ", 16 [RXRPC_CONN_SERVICE_PREALLOC] = "SvPrealc", 17 [RXRPC_CONN_SERVICE_UNSECURED] = "SvUnsec ", 18 [RXRPC_CONN_SERVICE_CHALLENGING] = "SvChall ", 19 [RXRPC_CONN_SERVICE] = "SvSecure", 20 [RXRPC_CONN_ABORTED] = "Aborted ", 21 }; 22 23 /* 24 * generate a list of extant and dead calls in /proc/net/rxrpc_calls 25 */ 26 static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos) 27 __acquires(rcu) 28 { 29 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 30 31 rcu_read_lock(); 32 return seq_list_start_head_rcu(&rxnet->calls, *_pos); 33 } 34 35 static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos) 36 { 37 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 38 39 return seq_list_next_rcu(v, &rxnet->calls, pos); 40 } 41 42 static void rxrpc_call_seq_stop(struct seq_file *seq, void *v) 43 __releases(rcu) 44 { 45 rcu_read_unlock(); 46 } 47 48 static int rxrpc_call_seq_show(struct seq_file *seq, void *v) 49 { 50 struct rxrpc_local *local; 51 struct rxrpc_call *call; 52 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 53 enum rxrpc_call_state state; 54 unsigned long timeout = 0; 55 rxrpc_seq_t acks_hard_ack; 56 char lbuff[50], rbuff[50]; 57 u64 wtmp; 58 59 if (v == &rxnet->calls) { 60 seq_puts(seq, 61 "Proto Local " 62 " Remote " 63 " SvID ConnID CallID End Use State Abort " 64 " DebugId TxSeq TW RxSeq RW RxSerial CW RxTimo\n"); 65 return 0; 66 } 67 68 call = list_entry(v, struct rxrpc_call, link); 69 70 local = call->local; 71 if (local) 72 sprintf(lbuff, "%pISpc", &local->srx.transport); 73 else 74 strcpy(lbuff, "no_local"); 75 76 sprintf(rbuff, "%pISpc", &call->dest_srx.transport); 77 78 state = rxrpc_call_state(call); 79 if (state != RXRPC_CALL_SERVER_PREALLOC) { 80 timeout = READ_ONCE(call->expect_rx_by); 81 timeout -= jiffies; 82 } 83 84 acks_hard_ack = READ_ONCE(call->acks_hard_ack); 85 wtmp = atomic64_read_acquire(&call->ackr_window); 86 seq_printf(seq, 87 "UDP %-47.47s %-47.47s %4x %08x %08x %s %3u" 88 " %-8.8s %08x %08x %08x %02x %08x %02x %08x %02x %06lx\n", 89 lbuff, 90 rbuff, 91 call->dest_srx.srx_service, 92 call->cid, 93 call->call_id, 94 rxrpc_is_service_call(call) ? "Svc" : "Clt", 95 refcount_read(&call->ref), 96 rxrpc_call_states[state], 97 call->abort_code, 98 call->debug_id, 99 acks_hard_ack, READ_ONCE(call->tx_top) - acks_hard_ack, 100 lower_32_bits(wtmp), upper_32_bits(wtmp) - lower_32_bits(wtmp), 101 call->rx_serial, 102 call->cong_cwnd, 103 timeout); 104 105 return 0; 106 } 107 108 const struct seq_operations rxrpc_call_seq_ops = { 109 .start = rxrpc_call_seq_start, 110 .next = rxrpc_call_seq_next, 111 .stop = rxrpc_call_seq_stop, 112 .show = rxrpc_call_seq_show, 113 }; 114 115 /* 116 * generate a list of extant virtual connections in /proc/net/rxrpc_conns 117 */ 118 static void *rxrpc_connection_seq_start(struct seq_file *seq, loff_t *_pos) 119 __acquires(rxnet->conn_lock) 120 { 121 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 122 123 read_lock(&rxnet->conn_lock); 124 return seq_list_start_head(&rxnet->conn_proc_list, *_pos); 125 } 126 127 static void *rxrpc_connection_seq_next(struct seq_file *seq, void *v, 128 loff_t *pos) 129 { 130 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 131 132 return seq_list_next(v, &rxnet->conn_proc_list, pos); 133 } 134 135 static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v) 136 __releases(rxnet->conn_lock) 137 { 138 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 139 140 read_unlock(&rxnet->conn_lock); 141 } 142 143 static int rxrpc_connection_seq_show(struct seq_file *seq, void *v) 144 { 145 struct rxrpc_connection *conn; 146 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 147 const char *state; 148 char lbuff[50], rbuff[50]; 149 150 if (v == &rxnet->conn_proc_list) { 151 seq_puts(seq, 152 "Proto Local " 153 " Remote " 154 " SvID ConnID End Ref Act State Key " 155 " Serial ISerial CallId0 CallId1 CallId2 CallId3\n" 156 ); 157 return 0; 158 } 159 160 conn = list_entry(v, struct rxrpc_connection, proc_link); 161 if (conn->state == RXRPC_CONN_SERVICE_PREALLOC) { 162 strcpy(lbuff, "no_local"); 163 strcpy(rbuff, "no_connection"); 164 goto print; 165 } 166 167 sprintf(lbuff, "%pISpc", &conn->local->srx.transport); 168 sprintf(rbuff, "%pISpc", &conn->peer->srx.transport); 169 print: 170 state = rxrpc_is_conn_aborted(conn) ? 171 rxrpc_call_completions[conn->completion] : 172 rxrpc_conn_states[conn->state]; 173 seq_printf(seq, 174 "UDP %-47.47s %-47.47s %4x %08x %s %3u %3d" 175 " %s %08x %08x %08x %08x %08x %08x %08x\n", 176 lbuff, 177 rbuff, 178 conn->service_id, 179 conn->proto.cid, 180 rxrpc_conn_is_service(conn) ? "Svc" : "Clt", 181 refcount_read(&conn->ref), 182 atomic_read(&conn->active), 183 state, 184 key_serial(conn->key), 185 atomic_read(&conn->serial), 186 conn->hi_serial, 187 conn->channels[0].call_id, 188 conn->channels[1].call_id, 189 conn->channels[2].call_id, 190 conn->channels[3].call_id); 191 192 return 0; 193 } 194 195 const struct seq_operations rxrpc_connection_seq_ops = { 196 .start = rxrpc_connection_seq_start, 197 .next = rxrpc_connection_seq_next, 198 .stop = rxrpc_connection_seq_stop, 199 .show = rxrpc_connection_seq_show, 200 }; 201 202 /* 203 * generate a list of extant virtual peers in /proc/net/rxrpc/peers 204 */ 205 static int rxrpc_peer_seq_show(struct seq_file *seq, void *v) 206 { 207 struct rxrpc_peer *peer; 208 time64_t now; 209 char lbuff[50], rbuff[50]; 210 211 if (v == SEQ_START_TOKEN) { 212 seq_puts(seq, 213 "Proto Local " 214 " Remote " 215 " Use SST MTU LastUse RTT RTO\n" 216 ); 217 return 0; 218 } 219 220 peer = list_entry(v, struct rxrpc_peer, hash_link); 221 222 sprintf(lbuff, "%pISpc", &peer->local->srx.transport); 223 224 sprintf(rbuff, "%pISpc", &peer->srx.transport); 225 226 now = ktime_get_seconds(); 227 seq_printf(seq, 228 "UDP %-47.47s %-47.47s %3u" 229 " %3u %5u %6llus %8u %8u\n", 230 lbuff, 231 rbuff, 232 refcount_read(&peer->ref), 233 peer->cong_ssthresh, 234 peer->mtu, 235 now - peer->last_tx_at, 236 peer->srtt_us >> 3, 237 jiffies_to_usecs(peer->rto_j)); 238 239 return 0; 240 } 241 242 static void *rxrpc_peer_seq_start(struct seq_file *seq, loff_t *_pos) 243 __acquires(rcu) 244 { 245 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 246 unsigned int bucket, n; 247 unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash); 248 void *p; 249 250 rcu_read_lock(); 251 252 if (*_pos >= UINT_MAX) 253 return NULL; 254 255 n = *_pos & ((1U << shift) - 1); 256 bucket = *_pos >> shift; 257 for (;;) { 258 if (bucket >= HASH_SIZE(rxnet->peer_hash)) { 259 *_pos = UINT_MAX; 260 return NULL; 261 } 262 if (n == 0) { 263 if (bucket == 0) 264 return SEQ_START_TOKEN; 265 *_pos += 1; 266 n++; 267 } 268 269 p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1); 270 if (p) 271 return p; 272 bucket++; 273 n = 1; 274 *_pos = (bucket << shift) | n; 275 } 276 } 277 278 static void *rxrpc_peer_seq_next(struct seq_file *seq, void *v, loff_t *_pos) 279 { 280 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 281 unsigned int bucket, n; 282 unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash); 283 void *p; 284 285 if (*_pos >= UINT_MAX) 286 return NULL; 287 288 bucket = *_pos >> shift; 289 290 p = seq_hlist_next_rcu(v, &rxnet->peer_hash[bucket], _pos); 291 if (p) 292 return p; 293 294 for (;;) { 295 bucket++; 296 n = 1; 297 *_pos = (bucket << shift) | n; 298 299 if (bucket >= HASH_SIZE(rxnet->peer_hash)) { 300 *_pos = UINT_MAX; 301 return NULL; 302 } 303 if (n == 0) { 304 *_pos += 1; 305 n++; 306 } 307 308 p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1); 309 if (p) 310 return p; 311 } 312 } 313 314 static void rxrpc_peer_seq_stop(struct seq_file *seq, void *v) 315 __releases(rcu) 316 { 317 rcu_read_unlock(); 318 } 319 320 321 const struct seq_operations rxrpc_peer_seq_ops = { 322 .start = rxrpc_peer_seq_start, 323 .next = rxrpc_peer_seq_next, 324 .stop = rxrpc_peer_seq_stop, 325 .show = rxrpc_peer_seq_show, 326 }; 327 328 /* 329 * Generate a list of extant virtual local endpoints in /proc/net/rxrpc/locals 330 */ 331 static int rxrpc_local_seq_show(struct seq_file *seq, void *v) 332 { 333 struct rxrpc_local *local; 334 char lbuff[50]; 335 336 if (v == SEQ_START_TOKEN) { 337 seq_puts(seq, 338 "Proto Local " 339 " Use Act RxQ\n"); 340 return 0; 341 } 342 343 local = hlist_entry(v, struct rxrpc_local, link); 344 345 sprintf(lbuff, "%pISpc", &local->srx.transport); 346 347 seq_printf(seq, 348 "UDP %-47.47s %3u %3u %3u\n", 349 lbuff, 350 refcount_read(&local->ref), 351 atomic_read(&local->active_users), 352 local->rx_queue.qlen); 353 354 return 0; 355 } 356 357 static void *rxrpc_local_seq_start(struct seq_file *seq, loff_t *_pos) 358 __acquires(rcu) 359 { 360 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 361 unsigned int n; 362 363 rcu_read_lock(); 364 365 if (*_pos >= UINT_MAX) 366 return NULL; 367 368 n = *_pos; 369 if (n == 0) 370 return SEQ_START_TOKEN; 371 372 return seq_hlist_start_rcu(&rxnet->local_endpoints, n - 1); 373 } 374 375 static void *rxrpc_local_seq_next(struct seq_file *seq, void *v, loff_t *_pos) 376 { 377 struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); 378 379 if (*_pos >= UINT_MAX) 380 return NULL; 381 382 return seq_hlist_next_rcu(v, &rxnet->local_endpoints, _pos); 383 } 384 385 static void rxrpc_local_seq_stop(struct seq_file *seq, void *v) 386 __releases(rcu) 387 { 388 rcu_read_unlock(); 389 } 390 391 const struct seq_operations rxrpc_local_seq_ops = { 392 .start = rxrpc_local_seq_start, 393 .next = rxrpc_local_seq_next, 394 .stop = rxrpc_local_seq_stop, 395 .show = rxrpc_local_seq_show, 396 }; 397 398 /* 399 * Display stats in /proc/net/rxrpc/stats 400 */ 401 int rxrpc_stats_show(struct seq_file *seq, void *v) 402 { 403 struct rxrpc_net *rxnet = rxrpc_net(seq_file_single_net(seq)); 404 405 seq_printf(seq, 406 "Data : send=%u sendf=%u fail=%u\n", 407 atomic_read(&rxnet->stat_tx_data_send), 408 atomic_read(&rxnet->stat_tx_data_send_frag), 409 atomic_read(&rxnet->stat_tx_data_send_fail)); 410 seq_printf(seq, 411 "Data-Tx : nr=%u retrans=%u uf=%u cwr=%u\n", 412 atomic_read(&rxnet->stat_tx_data), 413 atomic_read(&rxnet->stat_tx_data_retrans), 414 atomic_read(&rxnet->stat_tx_data_underflow), 415 atomic_read(&rxnet->stat_tx_data_cwnd_reset)); 416 seq_printf(seq, 417 "Data-Rx : nr=%u reqack=%u jumbo=%u\n", 418 atomic_read(&rxnet->stat_rx_data), 419 atomic_read(&rxnet->stat_rx_data_reqack), 420 atomic_read(&rxnet->stat_rx_data_jumbo)); 421 seq_printf(seq, 422 "Ack : fill=%u send=%u skip=%u\n", 423 atomic_read(&rxnet->stat_tx_ack_fill), 424 atomic_read(&rxnet->stat_tx_ack_send), 425 atomic_read(&rxnet->stat_tx_ack_skip)); 426 seq_printf(seq, 427 "Ack-Tx : req=%u dup=%u oos=%u exw=%u nos=%u png=%u prs=%u dly=%u idl=%u\n", 428 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_REQUESTED]), 429 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_DUPLICATE]), 430 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_OUT_OF_SEQUENCE]), 431 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_EXCEEDS_WINDOW]), 432 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_NOSPACE]), 433 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_PING]), 434 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_PING_RESPONSE]), 435 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_DELAY]), 436 atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_IDLE])); 437 seq_printf(seq, 438 "Ack-Rx : req=%u dup=%u oos=%u exw=%u nos=%u png=%u prs=%u dly=%u idl=%u\n", 439 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_REQUESTED]), 440 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_DUPLICATE]), 441 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_OUT_OF_SEQUENCE]), 442 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_EXCEEDS_WINDOW]), 443 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_NOSPACE]), 444 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_PING]), 445 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_PING_RESPONSE]), 446 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_DELAY]), 447 atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_IDLE])); 448 seq_printf(seq, 449 "Why-Req-A: acklost=%u already=%u mrtt=%u ortt=%u\n", 450 atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_ack_lost]), 451 atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_already_on]), 452 atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_more_rtt]), 453 atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_old_rtt])); 454 seq_printf(seq, 455 "Why-Req-A: nolast=%u retx=%u slows=%u smtxw=%u\n", 456 atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_no_srv_last]), 457 atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_retrans]), 458 atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_slow_start]), 459 atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_small_txwin])); 460 seq_printf(seq, 461 "Buffers : txb=%u rxb=%u\n", 462 atomic_read(&rxrpc_nr_txbuf), 463 atomic_read(&rxrpc_n_rx_skbs)); 464 seq_printf(seq, 465 "IO-thread: loops=%u\n", 466 atomic_read(&rxnet->stat_io_loop)); 467 return 0; 468 } 469 470 /* 471 * Clear stats if /proc/net/rxrpc/stats is written to. 472 */ 473 int rxrpc_stats_clear(struct file *file, char *buf, size_t size) 474 { 475 struct seq_file *m = file->private_data; 476 struct rxrpc_net *rxnet = rxrpc_net(seq_file_single_net(m)); 477 478 if (size > 1 || (size == 1 && buf[0] != '\n')) 479 return -EINVAL; 480 481 atomic_set(&rxnet->stat_tx_data, 0); 482 atomic_set(&rxnet->stat_tx_data_retrans, 0); 483 atomic_set(&rxnet->stat_tx_data_underflow, 0); 484 atomic_set(&rxnet->stat_tx_data_cwnd_reset, 0); 485 atomic_set(&rxnet->stat_tx_data_send, 0); 486 atomic_set(&rxnet->stat_tx_data_send_frag, 0); 487 atomic_set(&rxnet->stat_tx_data_send_fail, 0); 488 atomic_set(&rxnet->stat_rx_data, 0); 489 atomic_set(&rxnet->stat_rx_data_reqack, 0); 490 atomic_set(&rxnet->stat_rx_data_jumbo, 0); 491 492 atomic_set(&rxnet->stat_tx_ack_fill, 0); 493 atomic_set(&rxnet->stat_tx_ack_send, 0); 494 atomic_set(&rxnet->stat_tx_ack_skip, 0); 495 memset(&rxnet->stat_tx_acks, 0, sizeof(rxnet->stat_tx_acks)); 496 memset(&rxnet->stat_rx_acks, 0, sizeof(rxnet->stat_rx_acks)); 497 498 memset(&rxnet->stat_why_req_ack, 0, sizeof(rxnet->stat_why_req_ack)); 499 500 atomic_set(&rxnet->stat_io_loop, 0); 501 return size; 502 } 503