History

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.

Allan Stephens committed 15 years ago

Commit cd3decd1 parent c47e9b93 files · +22 −10Browse files

Unified · Split

3 files
  1. net/tipc/bcast.c +18 −6
  2. net/tipc/bcast.h +2 −2
  3. net/tipc/node.c +2 −2
net/tipc/bcast.c+18−6
@@ -87,6 +87,7 @@ struct bcbearer { · 86 unmodified lines
8787 * struct bclink - link used for broadcast messages
8888 * @link: (non-standard) broadcast link structure
8989 * @node: (non-standard) node structure representing b'cast link's peer node
90+ * @bcast_nodes: map of broadcast-capable nodes
9091 * @retransmit_to: node that most recently requested a retransmit
9192 *
9293 * Handles sequence numbering, fragmentation, bundling, etc.
@@ -95,6 +96,7 @@ struct bcbearer { · 2 unmodified lines
9596 struct bclink {
9697 struct link link;
9798 struct tipc_node node;
99+ struct tipc_node_map bcast_nodes;
98100 struct tipc_node *retransmit_to;
99101 };
100102
@@ -107,9 +109,6 @@ static struct link *bcl = &bcast_link.link; · 6 unmodified lines
107109
108110 static DEFINE_SPINLOCK(bc_lock);
109111
110−/* broadcast-capable node map */
111−struct tipc_node_map tipc_bcast_nmap;
112−
113112 const char tipc_bclink_name[] = "broadcast-link";
114113
115114 static void tipc_nmap_diff(struct tipc_node_map *nm_a,
@@ -136,6 +135,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf) · 20 unmodified lines
136135 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1);
137136 }
138137
138+void 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+
145+void 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+}
139151
140152 static void bclink_set_last_sent(void)
141153 {
@@ -575,13 +587,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf, · 433 unmodified lines
575587 if (likely(!msg_non_seq(buf_msg(buf)))) {
576588 struct tipc_msg *msg;
577589
578− bcbuf_set_acks(buf, tipc_bcast_nmap.count);
590+ bcbuf_set_acks(buf, bclink->bcast_nodes.count);
579591 msg = buf_msg(buf);
580592 msg_set_non_seq(msg, 1);
581593 msg_set_mc_netid(msg, tipc_net_id);
582594 bcl->stats.sent_info++;
583595
584− if (WARN_ON(!tipc_bcast_nmap.count)) {
596+ if (WARN_ON(!bclink->bcast_nodes.count)) {
585597 dump_stack();
586598 return 0;
587599 }
@@ -589,7 +601,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, · 1 unmodified line
589601
590602 /* Send buffer over bearers until all targets reached */
591603
592− bcbearer->remains = tipc_bcast_nmap;
604+ bcbearer->remains = bclink->bcast_nodes;
593605
594606 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
595607 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;
net/tipc/bcast.h+2−2
@@ -51,8 +51,6 @@ struct tipc_node_map { · 50 unmodified lines
5151 u32 map[MAX_NODES / WSIZE];
5252 };
5353
54−extern struct tipc_node_map tipc_bcast_nmap;
55−
5654 #define PLSIZE 32
5755
5856 /**
@@ -90,6 +88,8 @@ void tipc_port_list_free(struct port_list *pl_ptr); · 31 unmodified lines
9088
9189 void tipc_bclink_init(void);
9290 void tipc_bclink_stop(void);
91+void tipc_bclink_add_node(u32 addr);
92+void tipc_bclink_remove_node(u32 addr);
9393 struct tipc_node *tipc_bclink_retransmit_to(void);
9494 void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
9595 int tipc_bclink_send_msg(struct sk_buff *buf);
net/tipc/node.c+2−2
@@ -307,7 +307,7 @@ static void node_established_contact(struct tipc_node *n_ptr) · 306 unmodified lines
307307 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
308308
309309 if (n_ptr->bclink.supported) {
310− tipc_nmap_add(&tipc_bcast_nmap, n_ptr->addr);
310+ tipc_bclink_add_node(n_ptr->addr);
311311 if (n_ptr->addr < tipc_own_addr)
312312 tipc_own_tag++;
313313 }
@@ -350,7 +350,7 @@ static void node_lost_contact(struct tipc_node *n_ptr) · 36 unmodified lines
350350 n_ptr->bclink.defragm = NULL;
351351 }
352352
353− tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);
353+ tipc_bclink_remove_node(n_ptr->addr);
354354 tipc_bclink_acknowledge(n_ptr,
355355 mod(n_ptr->bclink.acked + 10000));
356356 if (n_ptr->addr < tipc_own_addr)