aboutsummaryrefslogtreecommitdiffstats
path: root/net
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
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')
-rw-r--r--net/tipc/bcast.c24
-rw-r--r--net/tipc/bcast.h4
-rw-r--r--net/tipc/node.c4
3 files changed, 22 insertions, 10 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 738cb642d31b..5ca8fdda63ca 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;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 0b0444363b45..3c37fdb8a0a6 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -51,8 +51,6 @@ struct tipc_node_map {
51 u32 map[MAX_NODES / WSIZE]; 51 u32 map[MAX_NODES / WSIZE];
52}; 52};
53 53
54extern struct tipc_node_map tipc_bcast_nmap;
55
56#define PLSIZE 32 54#define PLSIZE 32
57 55
58/** 56/**
@@ -90,6 +88,8 @@ void tipc_port_list_free(struct port_list *pl_ptr);
90 88
91void tipc_bclink_init(void); 89void tipc_bclink_init(void);
92void tipc_bclink_stop(void); 90void tipc_bclink_stop(void);
91void tipc_bclink_add_node(u32 addr);
92void tipc_bclink_remove_node(u32 addr);
93struct tipc_node *tipc_bclink_retransmit_to(void); 93struct tipc_node *tipc_bclink_retransmit_to(void);
94void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked); 94void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
95int tipc_bclink_send_msg(struct sk_buff *buf); 95int tipc_bclink_send_msg(struct sk_buff *buf);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 27b4bb0cca6c..1861ae915f17 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -307,7 +307,7 @@ static void node_established_contact(struct tipc_node *n_ptr)
307 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 307 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
308 308
309 if (n_ptr->bclink.supported) { 309 if (n_ptr->bclink.supported) {
310 tipc_nmap_add(&tipc_bcast_nmap, n_ptr->addr); 310 tipc_bclink_add_node(n_ptr->addr);
311 if (n_ptr->addr < tipc_own_addr) 311 if (n_ptr->addr < tipc_own_addr)
312 tipc_own_tag++; 312 tipc_own_tag++;
313 } 313 }
@@ -350,7 +350,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
350 n_ptr->bclink.defragm = NULL; 350 n_ptr->bclink.defragm = NULL;
351 } 351 }
352 352
353 tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr); 353 tipc_bclink_remove_node(n_ptr->addr);
354 tipc_bclink_acknowledge(n_ptr, 354 tipc_bclink_acknowledge(n_ptr,
355 mod(n_ptr->bclink.acked + 10000)); 355 mod(n_ptr->bclink.acked + 10000));
356 if (n_ptr->addr < tipc_own_addr) 356 if (n_ptr->addr < tipc_own_addr)