diff options
Diffstat (limited to 'net/sctp/proc.c')
-rw-r--r-- | net/sctp/proc.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index c3bea269faf4..8c19e97262ca 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = { | |||
102 | .open = sctp_snmp_seq_open, | 102 | .open = sctp_snmp_seq_open, |
103 | .read = seq_read, | 103 | .read = seq_read, |
104 | .llseek = seq_lseek, | 104 | .llseek = seq_lseek, |
105 | .release = single_release, | 105 | .release = single_release_net, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | /* Set up the proc fs entry for 'snmp' object. */ | 108 | /* Set up the proc fs entry for 'snmp' object. */ |
@@ -139,7 +139,11 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_commo | |||
139 | primary = &peer->saddr; | 139 | primary = &peer->saddr; |
140 | } | 140 | } |
141 | 141 | ||
142 | list_for_each_entry(laddr, &epb->bind_addr.address_list, list) { | 142 | rcu_read_lock(); |
143 | list_for_each_entry_rcu(laddr, &epb->bind_addr.address_list, list) { | ||
144 | if (!laddr->valid) | ||
145 | continue; | ||
146 | |||
143 | addr = &laddr->a; | 147 | addr = &laddr->a; |
144 | af = sctp_get_af_specific(addr->sa.sa_family); | 148 | af = sctp_get_af_specific(addr->sa.sa_family); |
145 | if (primary && af->cmp_addr(addr, primary)) { | 149 | if (primary && af->cmp_addr(addr, primary)) { |
@@ -147,6 +151,7 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_commo | |||
147 | } | 151 | } |
148 | af->seq_dump_addr(seq, addr); | 152 | af->seq_dump_addr(seq, addr); |
149 | } | 153 | } |
154 | rcu_read_unlock(); | ||
150 | } | 155 | } |
151 | 156 | ||
152 | /* Dump remote addresses of an association. */ | 157 | /* Dump remote addresses of an association. */ |
@@ -157,15 +162,20 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa | |||
157 | struct sctp_af *af; | 162 | struct sctp_af *af; |
158 | 163 | ||
159 | primary = &assoc->peer.primary_addr; | 164 | primary = &assoc->peer.primary_addr; |
160 | list_for_each_entry(transport, &assoc->peer.transport_addr_list, | 165 | rcu_read_lock(); |
166 | list_for_each_entry_rcu(transport, &assoc->peer.transport_addr_list, | ||
161 | transports) { | 167 | transports) { |
162 | addr = &transport->ipaddr; | 168 | addr = &transport->ipaddr; |
169 | if (transport->dead) | ||
170 | continue; | ||
171 | |||
163 | af = sctp_get_af_specific(addr->sa.sa_family); | 172 | af = sctp_get_af_specific(addr->sa.sa_family); |
164 | if (af->cmp_addr(addr, primary)) { | 173 | if (af->cmp_addr(addr, primary)) { |
165 | seq_printf(seq, "*"); | 174 | seq_printf(seq, "*"); |
166 | } | 175 | } |
167 | af->seq_dump_addr(seq, addr); | 176 | af->seq_dump_addr(seq, addr); |
168 | } | 177 | } |
178 | rcu_read_unlock(); | ||
169 | } | 179 | } |
170 | 180 | ||
171 | static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) | 181 | static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) |
@@ -251,7 +261,7 @@ static const struct file_operations sctp_eps_seq_fops = { | |||
251 | .open = sctp_eps_seq_open, | 261 | .open = sctp_eps_seq_open, |
252 | .read = seq_read, | 262 | .read = seq_read, |
253 | .llseek = seq_lseek, | 263 | .llseek = seq_lseek, |
254 | .release = seq_release, | 264 | .release = seq_release_net, |
255 | }; | 265 | }; |
256 | 266 | ||
257 | /* Set up the proc fs entry for 'eps' object. */ | 267 | /* Set up the proc fs entry for 'eps' object. */ |
@@ -372,7 +382,7 @@ static const struct file_operations sctp_assocs_seq_fops = { | |||
372 | .open = sctp_assocs_seq_open, | 382 | .open = sctp_assocs_seq_open, |
373 | .read = seq_read, | 383 | .read = seq_read, |
374 | .llseek = seq_lseek, | 384 | .llseek = seq_lseek, |
375 | .release = seq_release, | 385 | .release = seq_release_net, |
376 | }; | 386 | }; |
377 | 387 | ||
378 | /* Set up the proc fs entry for 'assocs' object. */ | 388 | /* Set up the proc fs entry for 'assocs' object. */ |
@@ -436,12 +446,16 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v) | |||
436 | head = &sctp_assoc_hashtable[hash]; | 446 | head = &sctp_assoc_hashtable[hash]; |
437 | sctp_local_bh_disable(); | 447 | sctp_local_bh_disable(); |
438 | read_lock(&head->lock); | 448 | read_lock(&head->lock); |
449 | rcu_read_lock(); | ||
439 | sctp_for_each_hentry(epb, node, &head->chain) { | 450 | sctp_for_each_hentry(epb, node, &head->chain) { |
440 | if (!net_eq(sock_net(epb->sk), seq_file_net(seq))) | 451 | if (!net_eq(sock_net(epb->sk), seq_file_net(seq))) |
441 | continue; | 452 | continue; |
442 | assoc = sctp_assoc(epb); | 453 | assoc = sctp_assoc(epb); |
443 | list_for_each_entry(tsp, &assoc->peer.transport_addr_list, | 454 | list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list, |
444 | transports) { | 455 | transports) { |
456 | if (tsp->dead) | ||
457 | continue; | ||
458 | |||
445 | /* | 459 | /* |
446 | * The remote address (ADDR) | 460 | * The remote address (ADDR) |
447 | */ | 461 | */ |
@@ -487,6 +501,7 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v) | |||
487 | } | 501 | } |
488 | } | 502 | } |
489 | 503 | ||
504 | rcu_read_unlock(); | ||
490 | read_unlock(&head->lock); | 505 | read_unlock(&head->lock); |
491 | sctp_local_bh_enable(); | 506 | sctp_local_bh_enable(); |
492 | 507 | ||
@@ -517,7 +532,7 @@ static const struct file_operations sctp_remaddr_seq_fops = { | |||
517 | .open = sctp_remaddr_seq_open, | 532 | .open = sctp_remaddr_seq_open, |
518 | .read = seq_read, | 533 | .read = seq_read, |
519 | .llseek = seq_lseek, | 534 | .llseek = seq_lseek, |
520 | .release = seq_release, | 535 | .release = seq_release_net, |
521 | }; | 536 | }; |
522 | 537 | ||
523 | int __net_init sctp_remaddr_proc_init(struct net *net) | 538 | int __net_init sctp_remaddr_proc_init(struct net *net) |