Blame view
net/rxrpc/proc.c
8.05 KB
2874c5fd2
|
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
17926a793
|
2 3 4 5 |
/* /proc/net/ support for AF_RXRPC * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) |
17926a793
|
6 7 8 9 10 11 |
*/ #include <linux/module.h> #include <net/sock.h> #include <net/af_rxrpc.h> #include "ar-internal.h" |
bba304db3
|
12 13 14 |
static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES] = { [RXRPC_CONN_UNUSED] = "Unused ", [RXRPC_CONN_CLIENT] = "Client ", |
00e907127
|
15 |
[RXRPC_CONN_SERVICE_PREALLOC] = "SvPrealc", |
bba304db3
|
16 17 18 19 20 |
[RXRPC_CONN_SERVICE_UNSECURED] = "SvUnsec ", [RXRPC_CONN_SERVICE_CHALLENGING] = "SvChall ", [RXRPC_CONN_SERVICE] = "SvSecure", [RXRPC_CONN_REMOTELY_ABORTED] = "RmtAbort", [RXRPC_CONN_LOCALLY_ABORTED] = "LocAbort", |
17926a793
|
21 |
}; |
17926a793
|
22 23 24 25 |
/* * generate a list of extant and dead calls in /proc/net/rxrpc_calls */ static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos) |
88f2a8257
|
26 27 |
__acquires(rcu) __acquires(rxnet->call_lock) |
17926a793
|
28 |
{ |
2baec2c3f
|
29 |
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); |
8d94aa381
|
30 |
rcu_read_lock(); |
2baec2c3f
|
31 32 |
read_lock(&rxnet->call_lock); return seq_list_start_head(&rxnet->calls, *_pos); |
17926a793
|
33 34 35 36 |
} static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos) { |
2baec2c3f
|
37 38 39 |
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); return seq_list_next(v, &rxnet->calls, pos); |
17926a793
|
40 41 42 |
} static void rxrpc_call_seq_stop(struct seq_file *seq, void *v) |
88f2a8257
|
43 44 |
__releases(rxnet->call_lock) __releases(rcu) |
17926a793
|
45 |
{ |
2baec2c3f
|
46 47 48 |
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); read_unlock(&rxnet->call_lock); |
8d94aa381
|
49 |
rcu_read_unlock(); |
17926a793
|
50 51 52 53 |
} static int rxrpc_call_seq_show(struct seq_file *seq, void *v) { |
df5d8bf70
|
54 55 56 |
struct rxrpc_local *local; struct rxrpc_sock *rx; struct rxrpc_peer *peer; |
17926a793
|
57 |
struct rxrpc_call *call; |
2baec2c3f
|
58 |
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); |
770b26de1
|
59 |
unsigned long timeout = 0; |
3e018daf0
|
60 |
rxrpc_seq_t tx_hard_ack, rx_hard_ack; |
75b54cb57
|
61 |
char lbuff[50], rbuff[50]; |
17926a793
|
62 |
|
2baec2c3f
|
63 |
if (v == &rxnet->calls) { |
17926a793
|
64 |
seq_puts(seq, |
75b54cb57
|
65 66 |
"Proto Local " " Remote " |
17926a793
|
67 |
" SvID ConnID CallID End Use State Abort " |
6b97bd7a2
|
68 69 |
" UserID TxSeq TW RxSeq RW RxSerial RxTimo "); |
17926a793
|
70 71 72 73 |
return 0; } call = list_entry(v, struct rxrpc_call, link); |
17926a793
|
74 |
|
8d94aa381
|
75 |
rx = rcu_dereference(call->socket); |
df5d8bf70
|
76 77 78 |
if (rx) { local = READ_ONCE(rx->local); if (local) |
75b54cb57
|
79 |
sprintf(lbuff, "%pISpc", &local->srx.transport); |
df5d8bf70
|
80 81 82 83 84 |
else strcpy(lbuff, "no_local"); } else { strcpy(lbuff, "no_socket"); } |
17926a793
|
85 |
|
df5d8bf70
|
86 87 |
peer = call->peer; if (peer) |
75b54cb57
|
88 |
sprintf(rbuff, "%pISpc", &peer->srx.transport); |
f4e7da8cd
|
89 90 |
else strcpy(rbuff, "no_connection"); |
17926a793
|
91 |
|
887763bbc
|
92 93 |
if (call->state != RXRPC_CALL_SERVER_PREALLOC) { timeout = READ_ONCE(call->expect_rx_by); |
887763bbc
|
94 95 |
timeout -= jiffies; } |
3e018daf0
|
96 97 |
tx_hard_ack = READ_ONCE(call->tx_hard_ack); rx_hard_ack = READ_ONCE(call->rx_hard_ack); |
17926a793
|
98 |
seq_printf(seq, |
75b54cb57
|
99 |
"UDP %-47.47s %-47.47s %4x %08x %08x %s %3u" |
6b97bd7a2
|
100 101 |
" %-8.8s %08x %lx %08x %02x %08x %02x %08x %06lx ", |
17926a793
|
102 103 |
lbuff, rbuff, |
f4e7da8cd
|
104 |
call->service_id, |
0d12f8a40
|
105 106 |
call->cid, call->call_id, |
dabe5a790
|
107 |
rxrpc_is_service_call(call) ? "Svc" : "Clt", |
17926a793
|
108 109 |
atomic_read(&call->usage), rxrpc_call_states[call->state], |
f5c17aaeb
|
110 |
call->abort_code, |
3e018daf0
|
111 112 |
call->user_call_ID, tx_hard_ack, READ_ONCE(call->tx_top) - tx_hard_ack, |
887763bbc
|
113 |
rx_hard_ack, READ_ONCE(call->rx_top) - rx_hard_ack, |
6b97bd7a2
|
114 |
call->rx_serial, |
887763bbc
|
115 |
timeout); |
17926a793
|
116 117 118 |
return 0; } |
c35063722
|
119 |
const struct seq_operations rxrpc_call_seq_ops = { |
17926a793
|
120 121 122 123 124 |
.start = rxrpc_call_seq_start, .next = rxrpc_call_seq_next, .stop = rxrpc_call_seq_stop, .show = rxrpc_call_seq_show, }; |
17926a793
|
125 126 127 128 |
/* * generate a list of extant virtual connections in /proc/net/rxrpc_conns */ static void *rxrpc_connection_seq_start(struct seq_file *seq, loff_t *_pos) |
88f2a8257
|
129 |
__acquires(rxnet->conn_lock) |
17926a793
|
130 |
{ |
2baec2c3f
|
131 132 133 134 |
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); read_lock(&rxnet->conn_lock); return seq_list_start_head(&rxnet->conn_proc_list, *_pos); |
17926a793
|
135 136 137 138 139 |
} static void *rxrpc_connection_seq_next(struct seq_file *seq, void *v, loff_t *pos) { |
2baec2c3f
|
140 141 142 |
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); return seq_list_next(v, &rxnet->conn_proc_list, pos); |
17926a793
|
143 144 145 |
} static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v) |
88f2a8257
|
146 |
__releases(rxnet->conn_lock) |
17926a793
|
147 |
{ |
2baec2c3f
|
148 149 150 |
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); read_unlock(&rxnet->conn_lock); |
17926a793
|
151 152 153 154 155 |
} static int rxrpc_connection_seq_show(struct seq_file *seq, void *v) { struct rxrpc_connection *conn; |
2baec2c3f
|
156 |
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); |
75b54cb57
|
157 |
char lbuff[50], rbuff[50]; |
17926a793
|
158 |
|
2baec2c3f
|
159 |
if (v == &rxnet->conn_proc_list) { |
17926a793
|
160 |
seq_puts(seq, |
75b54cb57
|
161 162 |
"Proto Local " " Remote " |
a1399f8bb
|
163 |
" SvID ConnID End Use State Key " |
17926a793
|
164 165 166 167 168 |
" Serial ISerial " ); return 0; } |
4d028b2c8
|
169 |
conn = list_entry(v, struct rxrpc_connection, proc_link); |
00e907127
|
170 171 172 173 174 |
if (conn->state == RXRPC_CONN_SERVICE_PREALLOC) { strcpy(lbuff, "no_local"); strcpy(rbuff, "no_connection"); goto print; } |
17926a793
|
175 |
|
75b54cb57
|
176 |
sprintf(lbuff, "%pISpc", &conn->params.local->srx.transport); |
17926a793
|
177 |
|
75b54cb57
|
178 |
sprintf(rbuff, "%pISpc", &conn->params.peer->srx.transport); |
00e907127
|
179 |
print: |
17926a793
|
180 |
seq_printf(seq, |
75b54cb57
|
181 |
"UDP %-47.47s %-47.47s %4x %08x %s %3u" |
6b97bd7a2
|
182 183 |
" %s %08x %08x %08x %08x %08x %08x %08x ", |
17926a793
|
184 185 |
lbuff, rbuff, |
68d6d1ae5
|
186 |
conn->service_id, |
19ffa01c9
|
187 |
conn->proto.cid, |
19ffa01c9
|
188 |
rxrpc_conn_is_service(conn) ? "Svc" : "Clt", |
17926a793
|
189 190 |
atomic_read(&conn->usage), rxrpc_conn_states[conn->state], |
19ffa01c9
|
191 |
key_serial(conn->params.key), |
17926a793
|
192 |
atomic_read(&conn->serial), |
6b97bd7a2
|
193 194 195 196 197 |
conn->hi_serial, conn->channels[0].call_id, conn->channels[1].call_id, conn->channels[2].call_id, conn->channels[3].call_id); |
17926a793
|
198 199 200 |
return 0; } |
c35063722
|
201 |
const struct seq_operations rxrpc_connection_seq_ops = { |
17926a793
|
202 203 204 205 206 |
.start = rxrpc_connection_seq_start, .next = rxrpc_connection_seq_next, .stop = rxrpc_connection_seq_stop, .show = rxrpc_connection_seq_show, }; |
bc0e7cf43
|
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
/* * generate a list of extant virtual peers in /proc/net/rxrpc/peers */ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v) { struct rxrpc_peer *peer; time64_t now; char lbuff[50], rbuff[50]; if (v == SEQ_START_TOKEN) { seq_puts(seq, "Proto Local " " Remote " " Use CW MTU LastUse RTT Rc " ); return 0; } peer = list_entry(v, struct rxrpc_peer, hash_link); sprintf(lbuff, "%pISpc", &peer->local->srx.transport); sprintf(rbuff, "%pISpc", &peer->srx.transport); now = ktime_get_seconds(); seq_printf(seq, "UDP %-47.47s %-47.47s %3u" " %3u %5u %6llus %12llu %2u ", lbuff, rbuff, atomic_read(&peer->usage), peer->cong_cwnd, peer->mtu, now - peer->last_tx_at, peer->rtt, peer->rtt_cursor); return 0; } static void *rxrpc_peer_seq_start(struct seq_file *seq, loff_t *_pos) __acquires(rcu) { struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); unsigned int bucket, n; unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash); void *p; rcu_read_lock(); if (*_pos >= UINT_MAX) return NULL; n = *_pos & ((1U << shift) - 1); bucket = *_pos >> shift; for (;;) { if (bucket >= HASH_SIZE(rxnet->peer_hash)) { *_pos = UINT_MAX; return NULL; } if (n == 0) { if (bucket == 0) return SEQ_START_TOKEN; *_pos += 1; n++; } p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1); if (p) return p; bucket++; n = 1; *_pos = (bucket << shift) | n; } } static void *rxrpc_peer_seq_next(struct seq_file *seq, void *v, loff_t *_pos) { struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); unsigned int bucket, n; unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash); void *p; if (*_pos >= UINT_MAX) return NULL; bucket = *_pos >> shift; p = seq_hlist_next_rcu(v, &rxnet->peer_hash[bucket], _pos); if (p) return p; for (;;) { bucket++; n = 1; *_pos = (bucket << shift) | n; if (bucket >= HASH_SIZE(rxnet->peer_hash)) { *_pos = UINT_MAX; return NULL; } if (n == 0) { *_pos += 1; n++; } p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1); if (p) return p; } } static void rxrpc_peer_seq_stop(struct seq_file *seq, void *v) __releases(rcu) { rcu_read_unlock(); } const struct seq_operations rxrpc_peer_seq_ops = { .start = rxrpc_peer_seq_start, .next = rxrpc_peer_seq_next, .stop = rxrpc_peer_seq_stop, .show = rxrpc_peer_seq_show, }; |