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
87 * struct bclink - link used for broadcast messages87 * struct bclink - link used for broadcast messages
88 * @link: (non-standard) broadcast link structure88 * @link: (non-standard) broadcast link structure
89 * @node: (non-standard) node structure representing b'cast link's peer node89 * @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 retransmit91 * @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 { · 2 unmodified lines
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; · 6 unmodified lines
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) · 20 unmodified lines
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, · 433 unmodified lines
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, · 1 unmodified line
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;
net/tipc/bcast.h+2−2
@@ -51,8 +51,6 @@ struct tipc_node_map { · 50 unmodified lines
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 3254#define PLSIZE 32
57 55
58/**56/**
@@ -90,6 +88,8 @@ void tipc_port_list_free(struct port_list *pl_ptr); · 31 unmodified lines
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);
net/tipc/node.c+2−2
@@ -307,7 +307,7 @@ static void node_established_contact(struct tipc_node *n_ptr) · 306 unmodified lines
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) · 36 unmodified lines
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)