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