diff options
| author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-06-18 03:36:46 -0400 |
|---|---|---|
| committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-06-18 03:36:46 -0400 |
| commit | 0107b3cf3225aed6ddde4fa8dbcd4ed643b34f4d (patch) | |
| tree | 9b9337ae627fc56a0eda43c60860765f25efaa0b /net/sctp/proc.c | |
| parent | 1c3f45ab2f7f879ea482501c83899505c31f7539 (diff) | |
| parent | 9ee1c939d1cb936b1f98e8d81aeffab57bae46ab (diff) | |
Merge with master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'net/sctp/proc.c')
| -rw-r--r-- | net/sctp/proc.c | 194 |
1 files changed, 151 insertions, 43 deletions
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index e42fd8c2916b..98d49ec9b74b 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
| @@ -132,14 +132,25 @@ void sctp_snmp_proc_exit(void) | |||
| 132 | static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb) | 132 | static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb) |
| 133 | { | 133 | { |
| 134 | struct list_head *pos; | 134 | struct list_head *pos; |
| 135 | struct sctp_association *asoc; | ||
| 135 | struct sctp_sockaddr_entry *laddr; | 136 | struct sctp_sockaddr_entry *laddr; |
| 136 | union sctp_addr *addr; | 137 | struct sctp_transport *peer; |
| 138 | union sctp_addr *addr, *primary = NULL; | ||
| 137 | struct sctp_af *af; | 139 | struct sctp_af *af; |
| 138 | 140 | ||
| 141 | if (epb->type == SCTP_EP_TYPE_ASSOCIATION) { | ||
| 142 | asoc = sctp_assoc(epb); | ||
| 143 | peer = asoc->peer.primary_path; | ||
| 144 | primary = &peer->saddr; | ||
| 145 | } | ||
| 146 | |||
| 139 | list_for_each(pos, &epb->bind_addr.address_list) { | 147 | list_for_each(pos, &epb->bind_addr.address_list) { |
| 140 | laddr = list_entry(pos, struct sctp_sockaddr_entry, list); | 148 | laddr = list_entry(pos, struct sctp_sockaddr_entry, list); |
| 141 | addr = (union sctp_addr *)&laddr->a; | 149 | addr = (union sctp_addr *)&laddr->a; |
| 142 | af = sctp_get_af_specific(addr->sa.sa_family); | 150 | af = sctp_get_af_specific(addr->sa.sa_family); |
| 151 | if (primary && af->cmp_addr(addr, primary)) { | ||
| 152 | seq_printf(seq, "*"); | ||
| 153 | } | ||
| 143 | af->seq_dump_addr(seq, addr); | 154 | af->seq_dump_addr(seq, addr); |
| 144 | } | 155 | } |
| 145 | } | 156 | } |
| @@ -149,17 +160,54 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa | |||
| 149 | { | 160 | { |
| 150 | struct list_head *pos; | 161 | struct list_head *pos; |
| 151 | struct sctp_transport *transport; | 162 | struct sctp_transport *transport; |
| 152 | union sctp_addr *addr; | 163 | union sctp_addr *addr, *primary; |
| 153 | struct sctp_af *af; | 164 | struct sctp_af *af; |
| 154 | 165 | ||
| 166 | primary = &(assoc->peer.primary_addr); | ||
| 155 | list_for_each(pos, &assoc->peer.transport_addr_list) { | 167 | list_for_each(pos, &assoc->peer.transport_addr_list) { |
| 156 | transport = list_entry(pos, struct sctp_transport, transports); | 168 | transport = list_entry(pos, struct sctp_transport, transports); |
| 157 | addr = (union sctp_addr *)&transport->ipaddr; | 169 | addr = (union sctp_addr *)&transport->ipaddr; |
| 158 | af = sctp_get_af_specific(addr->sa.sa_family); | 170 | af = sctp_get_af_specific(addr->sa.sa_family); |
| 171 | if (af->cmp_addr(addr, primary)) { | ||
| 172 | seq_printf(seq, "*"); | ||
| 173 | } | ||
| 159 | af->seq_dump_addr(seq, addr); | 174 | af->seq_dump_addr(seq, addr); |
| 160 | } | 175 | } |
| 161 | } | 176 | } |
| 162 | 177 | ||
| 178 | static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 179 | { | ||
| 180 | if (*pos > sctp_ep_hashsize) | ||
| 181 | return NULL; | ||
| 182 | |||
| 183 | if (*pos < 0) | ||
| 184 | *pos = 0; | ||
| 185 | |||
| 186 | if (*pos == 0) | ||
| 187 | seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n"); | ||
| 188 | |||
| 189 | ++*pos; | ||
| 190 | |||
| 191 | return (void *)pos; | ||
| 192 | } | ||
| 193 | |||
| 194 | static void sctp_eps_seq_stop(struct seq_file *seq, void *v) | ||
| 195 | { | ||
| 196 | return; | ||
| 197 | } | ||
| 198 | |||
| 199 | |||
| 200 | static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 201 | { | ||
| 202 | if (*pos > sctp_ep_hashsize) | ||
| 203 | return NULL; | ||
| 204 | |||
| 205 | ++*pos; | ||
| 206 | |||
| 207 | return pos; | ||
| 208 | } | ||
| 209 | |||
| 210 | |||
| 163 | /* Display sctp endpoints (/proc/net/sctp/eps). */ | 211 | /* Display sctp endpoints (/proc/net/sctp/eps). */ |
| 164 | static int sctp_eps_seq_show(struct seq_file *seq, void *v) | 212 | static int sctp_eps_seq_show(struct seq_file *seq, void *v) |
| 165 | { | 213 | { |
| @@ -167,38 +215,50 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) | |||
| 167 | struct sctp_ep_common *epb; | 215 | struct sctp_ep_common *epb; |
| 168 | struct sctp_endpoint *ep; | 216 | struct sctp_endpoint *ep; |
| 169 | struct sock *sk; | 217 | struct sock *sk; |
| 170 | int hash; | 218 | int hash = *(int *)v; |
| 171 | 219 | ||
| 172 | seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT LADDRS\n"); | 220 | if (hash > sctp_ep_hashsize) |
| 173 | for (hash = 0; hash < sctp_ep_hashsize; hash++) { | 221 | return -ENOMEM; |
| 174 | head = &sctp_ep_hashtable[hash]; | 222 | |
| 175 | read_lock(&head->lock); | 223 | head = &sctp_ep_hashtable[hash-1]; |
| 176 | for (epb = head->chain; epb; epb = epb->next) { | 224 | sctp_local_bh_disable(); |
| 177 | ep = sctp_ep(epb); | 225 | read_lock(&head->lock); |
| 178 | sk = epb->sk; | 226 | for (epb = head->chain; epb; epb = epb->next) { |
| 179 | seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d ", ep, sk, | 227 | ep = sctp_ep(epb); |
| 180 | sctp_sk(sk)->type, sk->sk_state, hash, | 228 | sk = epb->sk; |
| 181 | epb->bind_addr.port); | 229 | seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, |
| 182 | sctp_seq_dump_local_addrs(seq, epb); | 230 | sctp_sk(sk)->type, sk->sk_state, hash-1, |
| 183 | seq_printf(seq, "\n"); | 231 | epb->bind_addr.port, |
| 184 | } | 232 | sock_i_uid(sk), sock_i_ino(sk)); |
| 185 | read_unlock(&head->lock); | 233 | |
| 234 | sctp_seq_dump_local_addrs(seq, epb); | ||
| 235 | seq_printf(seq, "\n"); | ||
| 186 | } | 236 | } |
| 237 | read_unlock(&head->lock); | ||
| 238 | sctp_local_bh_enable(); | ||
| 187 | 239 | ||
| 188 | return 0; | 240 | return 0; |
| 189 | } | 241 | } |
| 190 | 242 | ||
| 243 | static struct seq_operations sctp_eps_ops = { | ||
| 244 | .start = sctp_eps_seq_start, | ||
| 245 | .next = sctp_eps_seq_next, | ||
| 246 | .stop = sctp_eps_seq_stop, | ||
| 247 | .show = sctp_eps_seq_show, | ||
| 248 | }; | ||
| 249 | |||
| 250 | |||
| 191 | /* Initialize the seq file operations for 'eps' object. */ | 251 | /* Initialize the seq file operations for 'eps' object. */ |
| 192 | static int sctp_eps_seq_open(struct inode *inode, struct file *file) | 252 | static int sctp_eps_seq_open(struct inode *inode, struct file *file) |
| 193 | { | 253 | { |
| 194 | return single_open(file, sctp_eps_seq_show, NULL); | 254 | return seq_open(file, &sctp_eps_ops); |
| 195 | } | 255 | } |
| 196 | 256 | ||
| 197 | static struct file_operations sctp_eps_seq_fops = { | 257 | static struct file_operations sctp_eps_seq_fops = { |
| 198 | .open = sctp_eps_seq_open, | 258 | .open = sctp_eps_seq_open, |
| 199 | .read = seq_read, | 259 | .read = seq_read, |
| 200 | .llseek = seq_lseek, | 260 | .llseek = seq_lseek, |
| 201 | .release = single_release, | 261 | .release = seq_release, |
| 202 | }; | 262 | }; |
| 203 | 263 | ||
| 204 | /* Set up the proc fs entry for 'eps' object. */ | 264 | /* Set up the proc fs entry for 'eps' object. */ |
| @@ -221,6 +281,40 @@ void sctp_eps_proc_exit(void) | |||
| 221 | remove_proc_entry("eps", proc_net_sctp); | 281 | remove_proc_entry("eps", proc_net_sctp); |
| 222 | } | 282 | } |
| 223 | 283 | ||
| 284 | |||
| 285 | static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 286 | { | ||
| 287 | if (*pos > sctp_assoc_hashsize) | ||
| 288 | return NULL; | ||
| 289 | |||
| 290 | if (*pos < 0) | ||
| 291 | *pos = 0; | ||
| 292 | |||
| 293 | if (*pos == 0) | ||
| 294 | seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT " | ||
| 295 | "RPORT LADDRS <-> RADDRS\n"); | ||
| 296 | |||
| 297 | ++*pos; | ||
| 298 | |||
| 299 | return (void *)pos; | ||
| 300 | } | ||
| 301 | |||
| 302 | static void sctp_assocs_seq_stop(struct seq_file *seq, void *v) | ||
| 303 | { | ||
| 304 | return; | ||
| 305 | } | ||
| 306 | |||
| 307 | |||
| 308 | static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 309 | { | ||
| 310 | if (*pos > sctp_assoc_hashsize) | ||
| 311 | return NULL; | ||
| 312 | |||
| 313 | ++*pos; | ||
| 314 | |||
| 315 | return pos; | ||
| 316 | } | ||
| 317 | |||
| 224 | /* Display sctp associations (/proc/net/sctp/assocs). */ | 318 | /* Display sctp associations (/proc/net/sctp/assocs). */ |
| 225 | static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | 319 | static int sctp_assocs_seq_show(struct seq_file *seq, void *v) |
| 226 | { | 320 | { |
| @@ -228,43 +322,57 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
| 228 | struct sctp_ep_common *epb; | 322 | struct sctp_ep_common *epb; |
| 229 | struct sctp_association *assoc; | 323 | struct sctp_association *assoc; |
| 230 | struct sock *sk; | 324 | struct sock *sk; |
| 231 | int hash; | 325 | int hash = *(int *)v; |
| 232 | 326 | ||
| 233 | seq_printf(seq, " ASSOC SOCK STY SST ST HBKT LPORT RPORT " | 327 | if (hash > sctp_assoc_hashsize) |
| 234 | "LADDRS <-> RADDRS\n"); | 328 | return -ENOMEM; |
| 235 | for (hash = 0; hash < sctp_assoc_hashsize; hash++) { | 329 | |
| 236 | head = &sctp_assoc_hashtable[hash]; | 330 | head = &sctp_assoc_hashtable[hash-1]; |
| 237 | read_lock(&head->lock); | 331 | sctp_local_bh_disable(); |
| 238 | for (epb = head->chain; epb; epb = epb->next) { | 332 | read_lock(&head->lock); |
| 239 | assoc = sctp_assoc(epb); | 333 | for (epb = head->chain; epb; epb = epb->next) { |
| 240 | sk = epb->sk; | 334 | assoc = sctp_assoc(epb); |
| 241 | seq_printf(seq, | 335 | sk = epb->sk; |
| 242 | "%8p %8p %-3d %-3d %-2d %-4d %-5d %-5d ", | 336 | seq_printf(seq, |
| 243 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, | 337 | "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", |
| 244 | assoc->state, hash, epb->bind_addr.port, | 338 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, |
| 245 | assoc->peer.port); | 339 | assoc->state, hash-1, assoc->assoc_id, |
| 246 | sctp_seq_dump_local_addrs(seq, epb); | 340 | (sk->sk_rcvbuf - assoc->rwnd), |
| 247 | seq_printf(seq, "<-> "); | 341 | assoc->sndbuf_used, |
| 248 | sctp_seq_dump_remote_addrs(seq, assoc); | 342 | sock_i_uid(sk), sock_i_ino(sk), |
| 249 | seq_printf(seq, "\n"); | 343 | epb->bind_addr.port, |
| 250 | } | 344 | assoc->peer.port); |
| 251 | read_unlock(&head->lock); | 345 | |
| 346 | seq_printf(seq, " "); | ||
| 347 | sctp_seq_dump_local_addrs(seq, epb); | ||
| 348 | seq_printf(seq, "<-> "); | ||
| 349 | sctp_seq_dump_remote_addrs(seq, assoc); | ||
| 350 | seq_printf(seq, "\n"); | ||
| 252 | } | 351 | } |
| 352 | read_unlock(&head->lock); | ||
| 353 | sctp_local_bh_enable(); | ||
| 253 | 354 | ||
| 254 | return 0; | 355 | return 0; |
| 255 | } | 356 | } |
| 256 | 357 | ||
| 358 | static struct seq_operations sctp_assoc_ops = { | ||
| 359 | .start = sctp_assocs_seq_start, | ||
| 360 | .next = sctp_assocs_seq_next, | ||
| 361 | .stop = sctp_assocs_seq_stop, | ||
| 362 | .show = sctp_assocs_seq_show, | ||
| 363 | }; | ||
| 364 | |||
| 257 | /* Initialize the seq file operations for 'assocs' object. */ | 365 | /* Initialize the seq file operations for 'assocs' object. */ |
| 258 | static int sctp_assocs_seq_open(struct inode *inode, struct file *file) | 366 | static int sctp_assocs_seq_open(struct inode *inode, struct file *file) |
| 259 | { | 367 | { |
| 260 | return single_open(file, sctp_assocs_seq_show, NULL); | 368 | return seq_open(file, &sctp_assoc_ops); |
| 261 | } | 369 | } |
| 262 | 370 | ||
| 263 | static struct file_operations sctp_assocs_seq_fops = { | 371 | static struct file_operations sctp_assocs_seq_fops = { |
| 264 | .open = sctp_assocs_seq_open, | 372 | .open = sctp_assocs_seq_open, |
| 265 | .read = seq_read, | 373 | .read = seq_read, |
| 266 | .llseek = seq_lseek, | 374 | .llseek = seq_lseek, |
| 267 | .release = single_release, | 375 | .release = seq_release, |
| 268 | }; | 376 | }; |
| 269 | 377 | ||
| 270 | /* Set up the proc fs entry for 'assocs' object. */ | 378 | /* Set up the proc fs entry for 'assocs' object. */ |
