1 /* /proc/net/ support for AF_RXRPC
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
12 #include <linux/module.h>
14 #include <net/af_rxrpc.h>
15 #include "ar-internal.h"
17 static const char *const rxrpc_conn_states
[RXRPC_CONN__NR_STATES
] = {
18 [RXRPC_CONN_UNUSED
] = "Unused ",
19 [RXRPC_CONN_CLIENT
] = "Client ",
20 [RXRPC_CONN_SERVICE_PREALLOC
] = "SvPrealc",
21 [RXRPC_CONN_SERVICE_UNSECURED
] = "SvUnsec ",
22 [RXRPC_CONN_SERVICE_CHALLENGING
] = "SvChall ",
23 [RXRPC_CONN_SERVICE
] = "SvSecure",
24 [RXRPC_CONN_REMOTELY_ABORTED
] = "RmtAbort",
25 [RXRPC_CONN_LOCALLY_ABORTED
] = "LocAbort",
29 * generate a list of extant and dead calls in /proc/net/rxrpc_calls
31 static void *rxrpc_call_seq_start(struct seq_file
*seq
, loff_t
*_pos
)
33 __acquires(rxnet
->call_lock
)
35 struct rxrpc_net
*rxnet
= rxrpc_net(seq_file_net(seq
));
38 read_lock(&rxnet
->call_lock
);
39 return seq_list_start_head(&rxnet
->calls
, *_pos
);
42 static void *rxrpc_call_seq_next(struct seq_file
*seq
, void *v
, loff_t
*pos
)
44 struct rxrpc_net
*rxnet
= rxrpc_net(seq_file_net(seq
));
46 return seq_list_next(v
, &rxnet
->calls
, pos
);
49 static void rxrpc_call_seq_stop(struct seq_file
*seq
, void *v
)
50 __releases(rxnet
->call_lock
)
53 struct rxrpc_net
*rxnet
= rxrpc_net(seq_file_net(seq
));
55 read_unlock(&rxnet
->call_lock
);
59 static int rxrpc_call_seq_show(struct seq_file
*seq
, void *v
)
61 struct rxrpc_local
*local
;
62 struct rxrpc_sock
*rx
;
63 struct rxrpc_peer
*peer
;
64 struct rxrpc_call
*call
;
65 struct rxrpc_net
*rxnet
= rxrpc_net(seq_file_net(seq
));
66 rxrpc_seq_t tx_hard_ack
, rx_hard_ack
;
67 char lbuff
[50], rbuff
[50];
69 if (v
== &rxnet
->calls
) {
73 " SvID ConnID CallID End Use State Abort "
78 call
= list_entry(v
, struct rxrpc_call
, link
);
80 rx
= rcu_dereference(call
->socket
);
82 local
= READ_ONCE(rx
->local
);
84 sprintf(lbuff
, "%pISpc", &local
->srx
.transport
);
86 strcpy(lbuff
, "no_local");
88 strcpy(lbuff
, "no_socket");
93 sprintf(rbuff
, "%pISpc", &peer
->srx
.transport
);
95 strcpy(rbuff
, "no_connection");
97 tx_hard_ack
= READ_ONCE(call
->tx_hard_ack
);
98 rx_hard_ack
= READ_ONCE(call
->rx_hard_ack
);
100 "UDP %-47.47s %-47.47s %4x %08x %08x %s %3u"
101 " %-8.8s %08x %lx %08x %02x %08x %02x\n",
107 rxrpc_is_service_call(call
) ? "Svc" : "Clt",
108 atomic_read(&call
->usage
),
109 rxrpc_call_states
[call
->state
],
112 tx_hard_ack
, READ_ONCE(call
->tx_top
) - tx_hard_ack
,
113 rx_hard_ack
, READ_ONCE(call
->rx_top
) - rx_hard_ack
);
118 const struct seq_operations rxrpc_call_seq_ops
= {
119 .start
= rxrpc_call_seq_start
,
120 .next
= rxrpc_call_seq_next
,
121 .stop
= rxrpc_call_seq_stop
,
122 .show
= rxrpc_call_seq_show
,
126 * generate a list of extant virtual connections in /proc/net/rxrpc_conns
128 static void *rxrpc_connection_seq_start(struct seq_file
*seq
, loff_t
*_pos
)
129 __acquires(rxnet
->conn_lock
)
131 struct rxrpc_net
*rxnet
= rxrpc_net(seq_file_net(seq
));
133 read_lock(&rxnet
->conn_lock
);
134 return seq_list_start_head(&rxnet
->conn_proc_list
, *_pos
);
137 static void *rxrpc_connection_seq_next(struct seq_file
*seq
, void *v
,
140 struct rxrpc_net
*rxnet
= rxrpc_net(seq_file_net(seq
));
142 return seq_list_next(v
, &rxnet
->conn_proc_list
, pos
);
145 static void rxrpc_connection_seq_stop(struct seq_file
*seq
, void *v
)
146 __releases(rxnet
->conn_lock
)
148 struct rxrpc_net
*rxnet
= rxrpc_net(seq_file_net(seq
));
150 read_unlock(&rxnet
->conn_lock
);
153 static int rxrpc_connection_seq_show(struct seq_file
*seq
, void *v
)
155 struct rxrpc_connection
*conn
;
156 struct rxrpc_net
*rxnet
= rxrpc_net(seq_file_net(seq
));
157 char lbuff
[50], rbuff
[50];
159 if (v
== &rxnet
->conn_proc_list
) {
163 " SvID ConnID End Use State Key "
169 conn
= list_entry(v
, struct rxrpc_connection
, proc_link
);
170 if (conn
->state
== RXRPC_CONN_SERVICE_PREALLOC
) {
171 strcpy(lbuff
, "no_local");
172 strcpy(rbuff
, "no_connection");
176 sprintf(lbuff
, "%pISpc", &conn
->params
.local
->srx
.transport
);
178 sprintf(rbuff
, "%pISpc", &conn
->params
.peer
->srx
.transport
);
181 "UDP %-47.47s %-47.47s %4x %08x %s %3u"
182 " %s %08x %08x %08x\n",
187 rxrpc_conn_is_service(conn
) ? "Svc" : "Clt",
188 atomic_read(&conn
->usage
),
189 rxrpc_conn_states
[conn
->state
],
190 key_serial(conn
->params
.key
),
191 atomic_read(&conn
->serial
),
197 const struct seq_operations rxrpc_connection_seq_ops
= {
198 .start
= rxrpc_connection_seq_start
,
199 .next
= rxrpc_connection_seq_next
,
200 .stop
= rxrpc_connection_seq_stop
,
201 .show
= rxrpc_connection_seq_show
,