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