aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bcast.c
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2011-10-24 11:18:12 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2011-12-27 11:33:48 -0500
commitcd3decdfd1dbab8a585eafe2e5b9866f193de99e (patch)
tree6683d9e56ca9554aa8c446b311521449c2f4ded5 /net/tipc/bcast.c
parentc47e9b918844ab7bb139eada7b085c576ddf0afb (diff)
tipc: Ensure broadcast link spinlock is held when updating node map
Fixes oversight that allowed broadcast link node map to be updated without first taking the broadcast link spinlock that protects the map. As part of this fix the node map has been incorporated into the broadcast link structure to make the need for such protection more evident. Signed-off-by: Allan Stephens <allan.stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r--net/tipc/bcast.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 738cb642d31..5ca8fdda63c 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -87,6 +87,7 @@ struct bcbearer {
87 * struct bclink - link used for broadcast messages 87 * struct bclink - link used for broadcast messages
88 * @link: (non-standard) broadcast link structure 88 * @link: (non-standard) broadcast link structure
89 * @node: (non-standard) node structure representing b'cast link's peer node 89 * @node: (non-standard) node structure representing b'cast link's peer node
90 * @bcast_nodes: map of broadcast-capable nodes
90 * @retransmit_to: node that most recently requested a retransmit 91 * @retransmit_to: node that most recently requested a retransmit
91 * 92 *
92 * Handles sequence numbering, fragmentation, bundling, etc. 93 * Handles sequence numbering, fragmentation, bundling, etc.
@@ -95,6 +96,7 @@ struct bcbearer {
95struct bclink { 96struct bclink {
96 struct link link; 97 struct link link;
97 struct tipc_node node; 98 struct tipc_node node;
99 struct tipc_node_map bcast_nodes;
98 struct tipc_node *retransmit_to; 100 struct tipc_node *retransmit_to;
99}; 101};
100 102
@@ -107,9 +109,6 @@ static struct link *bcl = &bcast_link.link;
107 109
108static DEFINE_SPINLOCK(bc_lock); 110static DEFINE_SPINLOCK(bc_lock);
109 111
110/* broadcast-capable node map */
111struct tipc_node_map tipc_bcast_nmap;
112
113const char tipc_bclink_name[] = "broadcast-link"; 112const char tipc_bclink_name[] = "broadcast-link";
114 113
115static void tipc_nmap_diff(struct tipc_node_map *nm_a, 114static void tipc_nmap_diff(struct tipc_node_map *nm_a,
@@ -136,6 +135,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
136 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1); 135 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1);
137} 136}
138 137
138void tipc_bclink_add_node(u32 addr)
139{
140 spin_lock_bh(&bc_lock);
141 tipc_nmap_add(&bclink->bcast_nodes, addr);
142 spin_unlock_bh(&bc_lock);
143}
144
145void tipc_bclink_remove_node(u32 addr)
146{
147 spin_lock_bh(&bc_lock);
148 tipc_nmap_remove(&bclink->bcast_nodes, addr);
149 spin_unlock_bh(&bc_lock);
150}
139 151
140static void bclink_set_last_sent(void) 152static void bclink_set_last_sent(void)
141{ 153{
@@ -575,13 +587,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
575 if (likely(!msg_non_seq(buf_msg(buf)))) { 587 if (likely(!msg_non_seq(buf_msg(buf)))) {
576 struct tipc_msg *msg; 588 struct tipc_msg *msg;
577 589
578 bcbuf_set_acks(buf, tipc_bcast_nmap.count); 590 bcbuf_set_acks(buf, bclink->bcast_nodes.count);
579 msg = buf_msg(buf); 591 msg = buf_msg(buf);
580 msg_set_non_seq(msg, 1); 592 msg_set_non_seq(msg, 1);
581 msg_set_mc_netid(msg, tipc_net_id); 593 msg_set_mc_netid(msg, tipc_net_id);
582 bcl->stats.sent_info++; 594 bcl->stats.sent_info++;
583 595
584 if (WARN_ON(!tipc_bcast_nmap.count)) { 596 if (WARN_ON(!bclink->bcast_nodes.count)) {
585 dump_stack(); 597 dump_stack();
586 return 0; 598 return 0;
587 } 599 }
@@ -589,7 +601,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
589 601
590 /* Send buffer over bearers until all targets reached */ 602 /* Send buffer over bearers until all targets reached */
591 603
592 bcbearer->remains = tipc_bcast_nmap; 604 bcbearer->remains = bclink->bcast_nodes;
593 605
594 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 606 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
595 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary; 607 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;