aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/addr.c2
-rw-r--r--net/tipc/addr.h3
-rw-r--r--net/tipc/bcast.c297
-rw-r--r--net/tipc/bcast.h97
-rw-r--r--net/tipc/bearer.c7
-rw-r--r--net/tipc/bearer.h21
-rw-r--r--net/tipc/core.h10
-rw-r--r--net/tipc/link.c17
-rw-r--r--net/tipc/msg.h2
-rw-r--r--net/tipc/name_table.c1
-rw-r--r--net/tipc/net.c1
-rw-r--r--net/tipc/node.c6
12 files changed, 259 insertions, 205 deletions
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 357b74b26f9e..9e6eeb450fe1 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -34,7 +34,7 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include "core.h" 37#include <linux/kernel.h>
38#include "addr.h" 38#include "addr.h"
39 39
40/** 40/**
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 3e1f18e29f1e..4e364c4f1359 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,6 +37,9 @@
37#ifndef _TIPC_ADDR_H 37#ifndef _TIPC_ADDR_H
38#define _TIPC_ADDR_H 38#define _TIPC_ADDR_H
39 39
40#include <linux/types.h>
41#include <linux/tipc.h>
42
40#define TIPC_ZONE_MASK 0xff000000u 43#define TIPC_ZONE_MASK 0xff000000u
41#define TIPC_CLUSTER_MASK 0xfffff000u 44#define TIPC_CLUSTER_MASK 0xfffff000u
42 45
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index e7c538304595..bc58097ebad2 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -35,77 +35,14 @@
35 * POSSIBILITY OF SUCH DAMAGE. 35 * POSSIBILITY OF SUCH DAMAGE.
36 */ 36 */
37 37
38#include "core.h"
39#include "link.h"
40#include "socket.h" 38#include "socket.h"
41#include "msg.h" 39#include "msg.h"
42#include "bcast.h" 40#include "bcast.h"
43#include "name_distr.h" 41#include "name_distr.h"
42#include "core.h"
44 43
45#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ 44#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */
46#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ 45#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */
47#define BCBEARER MAX_BEARERS
48
49/**
50 * struct tipc_bcbearer_pair - a pair of bearers used by broadcast link
51 * @primary: pointer to primary bearer
52 * @secondary: pointer to secondary bearer
53 *
54 * Bearers must have same priority and same set of reachable destinations
55 * to be paired.
56 */
57
58struct tipc_bcbearer_pair {
59 struct tipc_bearer *primary;
60 struct tipc_bearer *secondary;
61};
62
63/**
64 * struct tipc_bcbearer - bearer used by broadcast link
65 * @bearer: (non-standard) broadcast bearer structure
66 * @media: (non-standard) broadcast media structure
67 * @bpairs: array of bearer pairs
68 * @bpairs_temp: temporary array of bearer pairs used by tipc_bcbearer_sort()
69 * @remains: temporary node map used by tipc_bcbearer_send()
70 * @remains_new: temporary node map used tipc_bcbearer_send()
71 *
72 * Note: The fields labelled "temporary" are incorporated into the bearer
73 * to avoid consuming potentially limited stack space through the use of
74 * large local variables within multicast routines. Concurrent access is
75 * prevented through use of the spinlock "bclink_lock".
76 */
77struct tipc_bcbearer {
78 struct tipc_bearer bearer;
79 struct tipc_media media;
80 struct tipc_bcbearer_pair bpairs[MAX_BEARERS];
81 struct tipc_bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
82 struct tipc_node_map remains;
83 struct tipc_node_map remains_new;
84};
85
86/**
87 * struct tipc_bclink - link used for broadcast messages
88 * @lock: spinlock governing access to structure
89 * @link: (non-standard) broadcast link structure
90 * @node: (non-standard) node structure representing b'cast link's peer node
91 * @flags: represent bclink states
92 * @bcast_nodes: map of broadcast-capable nodes
93 * @retransmit_to: node that most recently requested a retransmit
94 *
95 * Handles sequence numbering, fragmentation, bundling, etc.
96 */
97struct tipc_bclink {
98 spinlock_t lock;
99 struct tipc_link link;
100 struct tipc_node node;
101 unsigned int flags;
102 struct tipc_node_map bcast_nodes;
103 struct tipc_node *retransmit_to;
104};
105
106static struct tipc_bcbearer *bcbearer;
107static struct tipc_bclink *bclink;
108static struct tipc_link *bcl;
109 46
110const char tipc_bclink_name[] = "broadcast-link"; 47const char tipc_bclink_name[] = "broadcast-link";
111 48
@@ -115,25 +52,28 @@ static void tipc_nmap_diff(struct tipc_node_map *nm_a,
115static void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node); 52static void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node);
116static void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node); 53static void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node);
117 54
118static void tipc_bclink_lock(void) 55static void tipc_bclink_lock(struct net *net)
119{ 56{
120 spin_lock_bh(&bclink->lock); 57 struct tipc_net *tn = net_generic(net, tipc_net_id);
58
59 spin_lock_bh(&tn->bclink->lock);
121} 60}
122 61
123static void tipc_bclink_unlock(void) 62static void tipc_bclink_unlock(struct net *net)
124{ 63{
64 struct tipc_net *tn = net_generic(net, tipc_net_id);
125 struct tipc_node *node = NULL; 65 struct tipc_node *node = NULL;
126 66
127 if (likely(!bclink->flags)) { 67 if (likely(!tn->bclink->flags)) {
128 spin_unlock_bh(&bclink->lock); 68 spin_unlock_bh(&tn->bclink->lock);
129 return; 69 return;
130 } 70 }
131 71
132 if (bclink->flags & TIPC_BCLINK_RESET) { 72 if (tn->bclink->flags & TIPC_BCLINK_RESET) {
133 bclink->flags &= ~TIPC_BCLINK_RESET; 73 tn->bclink->flags &= ~TIPC_BCLINK_RESET;
134 node = tipc_bclink_retransmit_to(); 74 node = tipc_bclink_retransmit_to(net);
135 } 75 }
136 spin_unlock_bh(&bclink->lock); 76 spin_unlock_bh(&tn->bclink->lock);
137 77
138 if (node) 78 if (node)
139 tipc_link_reset_all(node); 79 tipc_link_reset_all(node);
@@ -144,9 +84,11 @@ uint tipc_bclink_get_mtu(void)
144 return MAX_PKT_DEFAULT_MCAST; 84 return MAX_PKT_DEFAULT_MCAST;
145} 85}
146 86
147void tipc_bclink_set_flags(unsigned int flags) 87void tipc_bclink_set_flags(struct net *net, unsigned int flags)
148{ 88{
149 bclink->flags |= flags; 89 struct tipc_net *tn = net_generic(net, tipc_net_id);
90
91 tn->bclink->flags |= flags;
150} 92}
151 93
152static u32 bcbuf_acks(struct sk_buff *buf) 94static u32 bcbuf_acks(struct sk_buff *buf)
@@ -164,31 +106,40 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
164 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1); 106 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1);
165} 107}
166 108
167void tipc_bclink_add_node(u32 addr) 109void tipc_bclink_add_node(struct net *net, u32 addr)
168{ 110{
169 tipc_bclink_lock(); 111 struct tipc_net *tn = net_generic(net, tipc_net_id);
170 tipc_nmap_add(&bclink->bcast_nodes, addr); 112
171 tipc_bclink_unlock(); 113 tipc_bclink_lock(net);
114 tipc_nmap_add(&tn->bclink->bcast_nodes, addr);
115 tipc_bclink_unlock(net);
172} 116}
173 117
174void tipc_bclink_remove_node(u32 addr) 118void tipc_bclink_remove_node(struct net *net, u32 addr)
175{ 119{
176 tipc_bclink_lock(); 120 struct tipc_net *tn = net_generic(net, tipc_net_id);
177 tipc_nmap_remove(&bclink->bcast_nodes, addr); 121
178 tipc_bclink_unlock(); 122 tipc_bclink_lock(net);
123 tipc_nmap_remove(&tn->bclink->bcast_nodes, addr);
124 tipc_bclink_unlock(net);
179} 125}
180 126
181static void bclink_set_last_sent(void) 127static void bclink_set_last_sent(struct net *net)
182{ 128{
129 struct tipc_net *tn = net_generic(net, tipc_net_id);
130 struct tipc_link *bcl = tn->bcl;
131
183 if (bcl->next_out) 132 if (bcl->next_out)
184 bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1); 133 bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1);
185 else 134 else
186 bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1); 135 bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1);
187} 136}
188 137
189u32 tipc_bclink_get_last_sent(void) 138u32 tipc_bclink_get_last_sent(struct net *net)
190{ 139{
191 return bcl->fsm_msg_cnt; 140 struct tipc_net *tn = net_generic(net, tipc_net_id);
141
142 return tn->bcl->fsm_msg_cnt;
192} 143}
193 144
194static void bclink_update_last_sent(struct tipc_node *node, u32 seqno) 145static void bclink_update_last_sent(struct tipc_node *node, u32 seqno)
@@ -203,9 +154,11 @@ static void bclink_update_last_sent(struct tipc_node *node, u32 seqno)
203 * 154 *
204 * Called with bclink_lock locked 155 * Called with bclink_lock locked
205 */ 156 */
206struct tipc_node *tipc_bclink_retransmit_to(void) 157struct tipc_node *tipc_bclink_retransmit_to(struct net *net)
207{ 158{
208 return bclink->retransmit_to; 159 struct tipc_net *tn = net_generic(net, tipc_net_id);
160
161 return tn->bclink->retransmit_to;
209} 162}
210 163
211/** 164/**
@@ -215,9 +168,10 @@ struct tipc_node *tipc_bclink_retransmit_to(void)
215 * 168 *
216 * Called with bclink_lock locked 169 * Called with bclink_lock locked
217 */ 170 */
218static void bclink_retransmit_pkt(u32 after, u32 to) 171static void bclink_retransmit_pkt(struct tipc_net *tn, u32 after, u32 to)
219{ 172{
220 struct sk_buff *skb; 173 struct sk_buff *skb;
174 struct tipc_link *bcl = tn->bcl;
221 175
222 skb_queue_walk(&bcl->outqueue, skb) { 176 skb_queue_walk(&bcl->outqueue, skb) {
223 if (more(buf_seqno(skb), after)) { 177 if (more(buf_seqno(skb), after)) {
@@ -234,9 +188,10 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
234 */ 188 */
235void tipc_bclink_wakeup_users(struct net *net) 189void tipc_bclink_wakeup_users(struct net *net)
236{ 190{
191 struct tipc_net *tn = net_generic(net, tipc_net_id);
237 struct sk_buff *skb; 192 struct sk_buff *skb;
238 193
239 while ((skb = skb_dequeue(&bclink->link.waiting_sks))) 194 while ((skb = skb_dequeue(&tn->bclink->link.waiting_sks)))
240 tipc_sk_rcv(net, skb); 195 tipc_sk_rcv(net, skb);
241} 196}
242 197
@@ -252,10 +207,12 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
252 struct sk_buff *skb, *tmp; 207 struct sk_buff *skb, *tmp;
253 struct sk_buff *next; 208 struct sk_buff *next;
254 unsigned int released = 0; 209 unsigned int released = 0;
210 struct net *net = n_ptr->net;
211 struct tipc_net *tn = net_generic(net, tipc_net_id);
255 212
256 tipc_bclink_lock(); 213 tipc_bclink_lock(net);
257 /* Bail out if tx queue is empty (no clean up is required) */ 214 /* Bail out if tx queue is empty (no clean up is required) */
258 skb = skb_peek(&bcl->outqueue); 215 skb = skb_peek(&tn->bcl->outqueue);
259 if (!skb) 216 if (!skb)
260 goto exit; 217 goto exit;
261 218
@@ -266,43 +223,43 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
266 * acknowledge sent messages only (if other nodes still exist) 223 * acknowledge sent messages only (if other nodes still exist)
267 * or both sent and unsent messages (otherwise) 224 * or both sent and unsent messages (otherwise)
268 */ 225 */
269 if (bclink->bcast_nodes.count) 226 if (tn->bclink->bcast_nodes.count)
270 acked = bcl->fsm_msg_cnt; 227 acked = tn->bcl->fsm_msg_cnt;
271 else 228 else
272 acked = bcl->next_out_no; 229 acked = tn->bcl->next_out_no;
273 } else { 230 } else {
274 /* 231 /*
275 * Bail out if specified sequence number does not correspond 232 * Bail out if specified sequence number does not correspond
276 * to a message that has been sent and not yet acknowledged 233 * to a message that has been sent and not yet acknowledged
277 */ 234 */
278 if (less(acked, buf_seqno(skb)) || 235 if (less(acked, buf_seqno(skb)) ||
279 less(bcl->fsm_msg_cnt, acked) || 236 less(tn->bcl->fsm_msg_cnt, acked) ||
280 less_eq(acked, n_ptr->bclink.acked)) 237 less_eq(acked, n_ptr->bclink.acked))
281 goto exit; 238 goto exit;
282 } 239 }
283 240
284 /* Skip over packets that node has previously acknowledged */ 241 /* Skip over packets that node has previously acknowledged */
285 skb_queue_walk(&bcl->outqueue, skb) { 242 skb_queue_walk(&tn->bcl->outqueue, skb) {
286 if (more(buf_seqno(skb), n_ptr->bclink.acked)) 243 if (more(buf_seqno(skb), n_ptr->bclink.acked))
287 break; 244 break;
288 } 245 }
289 246
290 /* Update packets that node is now acknowledging */ 247 /* Update packets that node is now acknowledging */
291 skb_queue_walk_from_safe(&bcl->outqueue, skb, tmp) { 248 skb_queue_walk_from_safe(&tn->bcl->outqueue, skb, tmp) {
292 if (more(buf_seqno(skb), acked)) 249 if (more(buf_seqno(skb), acked))
293 break; 250 break;
294 251
295 next = tipc_skb_queue_next(&bcl->outqueue, skb); 252 next = tipc_skb_queue_next(&tn->bcl->outqueue, skb);
296 if (skb != bcl->next_out) { 253 if (skb != tn->bcl->next_out) {
297 bcbuf_decr_acks(skb); 254 bcbuf_decr_acks(skb);
298 } else { 255 } else {
299 bcbuf_set_acks(skb, 0); 256 bcbuf_set_acks(skb, 0);
300 bcl->next_out = next; 257 tn->bcl->next_out = next;
301 bclink_set_last_sent(); 258 bclink_set_last_sent(net);
302 } 259 }
303 260
304 if (bcbuf_acks(skb) == 0) { 261 if (bcbuf_acks(skb) == 0) {
305 __skb_unlink(skb, &bcl->outqueue); 262 __skb_unlink(skb, &tn->bcl->outqueue);
306 kfree_skb(skb); 263 kfree_skb(skb);
307 released = 1; 264 released = 1;
308 } 265 }
@@ -310,15 +267,15 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
310 n_ptr->bclink.acked = acked; 267 n_ptr->bclink.acked = acked;
311 268
312 /* Try resolving broadcast link congestion, if necessary */ 269 /* Try resolving broadcast link congestion, if necessary */
313 if (unlikely(bcl->next_out)) { 270 if (unlikely(tn->bcl->next_out)) {
314 tipc_link_push_packets(bcl); 271 tipc_link_push_packets(tn->bcl);
315 bclink_set_last_sent(); 272 bclink_set_last_sent(net);
316 } 273 }
317 if (unlikely(released && !skb_queue_empty(&bcl->waiting_sks))) 274 if (unlikely(released && !skb_queue_empty(&tn->bcl->waiting_sks)))
318 n_ptr->action_flags |= TIPC_WAKEUP_BCAST_USERS; 275 n_ptr->action_flags |= TIPC_WAKEUP_BCAST_USERS;
319 276
320exit: 277exit:
321 tipc_bclink_unlock(); 278 tipc_bclink_unlock(net);
322} 279}
323 280
324/** 281/**
@@ -368,10 +325,10 @@ void tipc_bclink_update_link_state(struct net *net, struct tipc_node *n_ptr,
368 msg_set_bcgap_after(msg, n_ptr->bclink.last_in); 325 msg_set_bcgap_after(msg, n_ptr->bclink.last_in);
369 msg_set_bcgap_to(msg, to); 326 msg_set_bcgap_to(msg, to);
370 327
371 tipc_bclink_lock(); 328 tipc_bclink_lock(net);
372 tipc_bearer_send(net, MAX_BEARERS, buf, NULL); 329 tipc_bearer_send(net, MAX_BEARERS, buf, NULL);
373 bcl->stats.sent_nacks++; 330 tn->bcl->stats.sent_nacks++;
374 tipc_bclink_unlock(); 331 tipc_bclink_unlock(net);
375 kfree_skb(buf); 332 kfree_skb(buf);
376 333
377 n_ptr->bclink.oos_state++; 334 n_ptr->bclink.oos_state++;
@@ -410,6 +367,9 @@ static void bclink_peek_nack(struct net *net, struct tipc_msg *msg)
410 */ 367 */
411int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list) 368int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list)
412{ 369{
370 struct tipc_net *tn = net_generic(net, tipc_net_id);
371 struct tipc_link *bcl = tn->bcl;
372 struct tipc_bclink *bclink = tn->bclink;
413 int rc = 0; 373 int rc = 0;
414 int bc = 0; 374 int bc = 0;
415 struct sk_buff *skb; 375 struct sk_buff *skb;
@@ -423,19 +383,19 @@ int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list)
423 383
424 /* Broadcast to all other nodes */ 384 /* Broadcast to all other nodes */
425 if (likely(bclink)) { 385 if (likely(bclink)) {
426 tipc_bclink_lock(); 386 tipc_bclink_lock(net);
427 if (likely(bclink->bcast_nodes.count)) { 387 if (likely(bclink->bcast_nodes.count)) {
428 rc = __tipc_link_xmit(net, bcl, list); 388 rc = __tipc_link_xmit(net, bcl, list);
429 if (likely(!rc)) { 389 if (likely(!rc)) {
430 u32 len = skb_queue_len(&bcl->outqueue); 390 u32 len = skb_queue_len(&bcl->outqueue);
431 391
432 bclink_set_last_sent(); 392 bclink_set_last_sent(net);
433 bcl->stats.queue_sz_counts++; 393 bcl->stats.queue_sz_counts++;
434 bcl->stats.accu_queue_sz += len; 394 bcl->stats.accu_queue_sz += len;
435 } 395 }
436 bc = 1; 396 bc = 1;
437 } 397 }
438 tipc_bclink_unlock(); 398 tipc_bclink_unlock(net);
439 } 399 }
440 400
441 if (unlikely(!bc)) 401 if (unlikely(!bc))
@@ -457,10 +417,12 @@ int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list)
457 */ 417 */
458static void bclink_accept_pkt(struct tipc_node *node, u32 seqno) 418static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
459{ 419{
420 struct tipc_net *tn = net_generic(node->net, tipc_net_id);
421
460 bclink_update_last_sent(node, seqno); 422 bclink_update_last_sent(node, seqno);
461 node->bclink.last_in = seqno; 423 node->bclink.last_in = seqno;
462 node->bclink.oos_state = 0; 424 node->bclink.oos_state = 0;
463 bcl->stats.recv_info++; 425 tn->bcl->stats.recv_info++;
464 426
465 /* 427 /*
466 * Unicast an ACK periodically, ensuring that 428 * Unicast an ACK periodically, ensuring that
@@ -469,7 +431,7 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
469 if (((seqno - tipc_own_addr) % TIPC_MIN_LINK_WIN) == 0) { 431 if (((seqno - tipc_own_addr) % TIPC_MIN_LINK_WIN) == 0) {
470 tipc_link_proto_xmit(node->active_links[node->addr & 1], 432 tipc_link_proto_xmit(node->active_links[node->addr & 1],
471 STATE_MSG, 0, 0, 0, 0, 0); 433 STATE_MSG, 0, 0, 0, 0, 0);
472 bcl->stats.sent_acks++; 434 tn->bcl->stats.sent_acks++;
473 } 435 }
474} 436}
475 437
@@ -481,6 +443,7 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
481void tipc_bclink_rcv(struct net *net, struct sk_buff *buf) 443void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
482{ 444{
483 struct tipc_net *tn = net_generic(net, tipc_net_id); 445 struct tipc_net *tn = net_generic(net, tipc_net_id);
446 struct tipc_link *bcl = tn->bcl;
484 struct tipc_msg *msg = buf_msg(buf); 447 struct tipc_msg *msg = buf_msg(buf);
485 struct tipc_node *node; 448 struct tipc_node *node;
486 u32 next_in; 449 u32 next_in;
@@ -506,12 +469,12 @@ void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
506 if (msg_destnode(msg) == tipc_own_addr) { 469 if (msg_destnode(msg) == tipc_own_addr) {
507 tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); 470 tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
508 tipc_node_unlock(node); 471 tipc_node_unlock(node);
509 tipc_bclink_lock(); 472 tipc_bclink_lock(net);
510 bcl->stats.recv_nacks++; 473 bcl->stats.recv_nacks++;
511 bclink->retransmit_to = node; 474 tn->bclink->retransmit_to = node;
512 bclink_retransmit_pkt(msg_bcgap_after(msg), 475 bclink_retransmit_pkt(tn, msg_bcgap_after(msg),
513 msg_bcgap_to(msg)); 476 msg_bcgap_to(msg));
514 tipc_bclink_unlock(); 477 tipc_bclink_unlock(net);
515 } else { 478 } else {
516 tipc_node_unlock(node); 479 tipc_node_unlock(node);
517 bclink_peek_nack(net, msg); 480 bclink_peek_nack(net, msg);
@@ -527,47 +490,47 @@ void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
527receive: 490receive:
528 /* Deliver message to destination */ 491 /* Deliver message to destination */
529 if (likely(msg_isdata(msg))) { 492 if (likely(msg_isdata(msg))) {
530 tipc_bclink_lock(); 493 tipc_bclink_lock(net);
531 bclink_accept_pkt(node, seqno); 494 bclink_accept_pkt(node, seqno);
532 tipc_bclink_unlock(); 495 tipc_bclink_unlock(net);
533 tipc_node_unlock(node); 496 tipc_node_unlock(node);
534 if (likely(msg_mcast(msg))) 497 if (likely(msg_mcast(msg)))
535 tipc_sk_mcast_rcv(net, buf); 498 tipc_sk_mcast_rcv(net, buf);
536 else 499 else
537 kfree_skb(buf); 500 kfree_skb(buf);
538 } else if (msg_user(msg) == MSG_BUNDLER) { 501 } else if (msg_user(msg) == MSG_BUNDLER) {
539 tipc_bclink_lock(); 502 tipc_bclink_lock(net);
540 bclink_accept_pkt(node, seqno); 503 bclink_accept_pkt(node, seqno);
541 bcl->stats.recv_bundles++; 504 bcl->stats.recv_bundles++;
542 bcl->stats.recv_bundled += msg_msgcnt(msg); 505 bcl->stats.recv_bundled += msg_msgcnt(msg);
543 tipc_bclink_unlock(); 506 tipc_bclink_unlock(net);
544 tipc_node_unlock(node); 507 tipc_node_unlock(node);
545 tipc_link_bundle_rcv(net, buf); 508 tipc_link_bundle_rcv(net, buf);
546 } else if (msg_user(msg) == MSG_FRAGMENTER) { 509 } else if (msg_user(msg) == MSG_FRAGMENTER) {
547 tipc_buf_append(&node->bclink.reasm_buf, &buf); 510 tipc_buf_append(&node->bclink.reasm_buf, &buf);
548 if (unlikely(!buf && !node->bclink.reasm_buf)) 511 if (unlikely(!buf && !node->bclink.reasm_buf))
549 goto unlock; 512 goto unlock;
550 tipc_bclink_lock(); 513 tipc_bclink_lock(net);
551 bclink_accept_pkt(node, seqno); 514 bclink_accept_pkt(node, seqno);
552 bcl->stats.recv_fragments++; 515 bcl->stats.recv_fragments++;
553 if (buf) { 516 if (buf) {
554 bcl->stats.recv_fragmented++; 517 bcl->stats.recv_fragmented++;
555 msg = buf_msg(buf); 518 msg = buf_msg(buf);
556 tipc_bclink_unlock(); 519 tipc_bclink_unlock(net);
557 goto receive; 520 goto receive;
558 } 521 }
559 tipc_bclink_unlock(); 522 tipc_bclink_unlock(net);
560 tipc_node_unlock(node); 523 tipc_node_unlock(node);
561 } else if (msg_user(msg) == NAME_DISTRIBUTOR) { 524 } else if (msg_user(msg) == NAME_DISTRIBUTOR) {
562 tipc_bclink_lock(); 525 tipc_bclink_lock(net);
563 bclink_accept_pkt(node, seqno); 526 bclink_accept_pkt(node, seqno);
564 tipc_bclink_unlock(); 527 tipc_bclink_unlock(net);
565 tipc_node_unlock(node); 528 tipc_node_unlock(node);
566 tipc_named_rcv(net, buf); 529 tipc_named_rcv(net, buf);
567 } else { 530 } else {
568 tipc_bclink_lock(); 531 tipc_bclink_lock(net);
569 bclink_accept_pkt(node, seqno); 532 bclink_accept_pkt(node, seqno);
570 tipc_bclink_unlock(); 533 tipc_bclink_unlock(net);
571 tipc_node_unlock(node); 534 tipc_node_unlock(node);
572 kfree_skb(buf); 535 kfree_skb(buf);
573 } 536 }
@@ -605,14 +568,14 @@ receive:
605 buf = NULL; 568 buf = NULL;
606 } 569 }
607 570
608 tipc_bclink_lock(); 571 tipc_bclink_lock(net);
609 572
610 if (deferred) 573 if (deferred)
611 bcl->stats.deferred_recv++; 574 bcl->stats.deferred_recv++;
612 else 575 else
613 bcl->stats.duplicates++; 576 bcl->stats.duplicates++;
614 577
615 tipc_bclink_unlock(); 578 tipc_bclink_unlock(net);
616 579
617unlock: 580unlock:
618 tipc_node_unlock(node); 581 tipc_node_unlock(node);
@@ -623,7 +586,7 @@ exit:
623u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) 586u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
624{ 587{
625 return (n_ptr->bclink.recv_permitted && 588 return (n_ptr->bclink.recv_permitted &&
626 (tipc_bclink_get_last_sent() != n_ptr->bclink.acked)); 589 (tipc_bclink_get_last_sent(n_ptr->net) != n_ptr->bclink.acked));
627} 590}
628 591
629 592
@@ -636,13 +599,15 @@ u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
636 * Returns 0 (packet sent successfully) under all circumstances, 599 * Returns 0 (packet sent successfully) under all circumstances,
637 * since the broadcast link's pseudo-bearer never blocks 600 * since the broadcast link's pseudo-bearer never blocks
638 */ 601 */
639static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1, 602static int tipc_bcbearer_send(struct net *net, struct sk_buff *buf,
603 struct tipc_bearer *unused1,
640 struct tipc_media_addr *unused2) 604 struct tipc_media_addr *unused2)
641{ 605{
642 int bp_index; 606 int bp_index;
643 struct tipc_msg *msg = buf_msg(buf); 607 struct tipc_msg *msg = buf_msg(buf);
644 struct net *net = sock_net(buf->sk);
645 struct tipc_net *tn = net_generic(net, tipc_net_id); 608 struct tipc_net *tn = net_generic(net, tipc_net_id);
609 struct tipc_bcbearer *bcbearer = tn->bcbearer;
610 struct tipc_bclink *bclink = tn->bclink;
646 611
647 /* Prepare broadcast link message for reliable transmission, 612 /* Prepare broadcast link message for reliable transmission,
648 * if first time trying to send it; 613 * if first time trying to send it;
@@ -653,7 +618,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
653 bcbuf_set_acks(buf, bclink->bcast_nodes.count); 618 bcbuf_set_acks(buf, bclink->bcast_nodes.count);
654 msg_set_non_seq(msg, 1); 619 msg_set_non_seq(msg, 1);
655 msg_set_mc_netid(msg, tn->net_id); 620 msg_set_mc_netid(msg, tn->net_id);
656 bcl->stats.sent_info++; 621 tn->bcl->stats.sent_info++;
657 622
658 if (WARN_ON(!bclink->bcast_nodes.count)) { 623 if (WARN_ON(!bclink->bcast_nodes.count)) {
659 dump_stack(); 624 dump_stack();
@@ -708,13 +673,14 @@ void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr,
708 u32 node, bool action) 673 u32 node, bool action)
709{ 674{
710 struct tipc_net *tn = net_generic(net, tipc_net_id); 675 struct tipc_net *tn = net_generic(net, tipc_net_id);
676 struct tipc_bcbearer *bcbearer = tn->bcbearer;
711 struct tipc_bcbearer_pair *bp_temp = bcbearer->bpairs_temp; 677 struct tipc_bcbearer_pair *bp_temp = bcbearer->bpairs_temp;
712 struct tipc_bcbearer_pair *bp_curr; 678 struct tipc_bcbearer_pair *bp_curr;
713 struct tipc_bearer *b; 679 struct tipc_bearer *b;
714 int b_index; 680 int b_index;
715 int pri; 681 int pri;
716 682
717 tipc_bclink_lock(); 683 tipc_bclink_lock(net);
718 684
719 if (action) 685 if (action)
720 tipc_nmap_add(nm_ptr, node); 686 tipc_nmap_add(nm_ptr, node);
@@ -761,7 +727,7 @@ void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr,
761 bp_curr++; 727 bp_curr++;
762 } 728 }
763 729
764 tipc_bclink_unlock(); 730 tipc_bclink_unlock(net);
765} 731}
766 732
767static int __tipc_nl_add_bc_link_stat(struct sk_buff *skb, 733static int __tipc_nl_add_bc_link_stat(struct sk_buff *skb,
@@ -815,17 +781,19 @@ msg_full:
815 return -EMSGSIZE; 781 return -EMSGSIZE;
816} 782}
817 783
818int tipc_nl_add_bc_link(struct tipc_nl_msg *msg) 784int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg)
819{ 785{
820 int err; 786 int err;
821 void *hdr; 787 void *hdr;
822 struct nlattr *attrs; 788 struct nlattr *attrs;
823 struct nlattr *prop; 789 struct nlattr *prop;
790 struct tipc_net *tn = net_generic(net, tipc_net_id);
791 struct tipc_link *bcl = tn->bcl;
824 792
825 if (!bcl) 793 if (!bcl)
826 return 0; 794 return 0;
827 795
828 tipc_bclink_lock(); 796 tipc_bclink_lock(net);
829 797
830 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, 798 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family,
831 NLM_F_MULTI, TIPC_NL_LINK_GET); 799 NLM_F_MULTI, TIPC_NL_LINK_GET);
@@ -860,7 +828,7 @@ int tipc_nl_add_bc_link(struct tipc_nl_msg *msg)
860 if (err) 828 if (err)
861 goto attr_msg_full; 829 goto attr_msg_full;
862 830
863 tipc_bclink_unlock(); 831 tipc_bclink_unlock(net);
864 nla_nest_end(msg->skb, attrs); 832 nla_nest_end(msg->skb, attrs);
865 genlmsg_end(msg->skb, hdr); 833 genlmsg_end(msg->skb, hdr);
866 834
@@ -871,21 +839,23 @@ prop_msg_full:
871attr_msg_full: 839attr_msg_full:
872 nla_nest_cancel(msg->skb, attrs); 840 nla_nest_cancel(msg->skb, attrs);
873msg_full: 841msg_full:
874 tipc_bclink_unlock(); 842 tipc_bclink_unlock(net);
875 genlmsg_cancel(msg->skb, hdr); 843 genlmsg_cancel(msg->skb, hdr);
876 844
877 return -EMSGSIZE; 845 return -EMSGSIZE;
878} 846}
879 847
880int tipc_bclink_stats(char *buf, const u32 buf_size) 848int tipc_bclink_stats(struct net *net, char *buf, const u32 buf_size)
881{ 849{
882 int ret; 850 int ret;
883 struct tipc_stats *s; 851 struct tipc_stats *s;
852 struct tipc_net *tn = net_generic(net, tipc_net_id);
853 struct tipc_link *bcl = tn->bcl;
884 854
885 if (!bcl) 855 if (!bcl)
886 return 0; 856 return 0;
887 857
888 tipc_bclink_lock(); 858 tipc_bclink_lock(net);
889 859
890 s = &bcl->stats; 860 s = &bcl->stats;
891 861
@@ -914,37 +884,46 @@ int tipc_bclink_stats(char *buf, const u32 buf_size)
914 s->queue_sz_counts ? 884 s->queue_sz_counts ?
915 (s->accu_queue_sz / s->queue_sz_counts) : 0); 885 (s->accu_queue_sz / s->queue_sz_counts) : 0);
916 886
917 tipc_bclink_unlock(); 887 tipc_bclink_unlock(net);
918 return ret; 888 return ret;
919} 889}
920 890
921int tipc_bclink_reset_stats(void) 891int tipc_bclink_reset_stats(struct net *net)
922{ 892{
893 struct tipc_net *tn = net_generic(net, tipc_net_id);
894 struct tipc_link *bcl = tn->bcl;
895
923 if (!bcl) 896 if (!bcl)
924 return -ENOPROTOOPT; 897 return -ENOPROTOOPT;
925 898
926 tipc_bclink_lock(); 899 tipc_bclink_lock(net);
927 memset(&bcl->stats, 0, sizeof(bcl->stats)); 900 memset(&bcl->stats, 0, sizeof(bcl->stats));
928 tipc_bclink_unlock(); 901 tipc_bclink_unlock(net);
929 return 0; 902 return 0;
930} 903}
931 904
932int tipc_bclink_set_queue_limits(u32 limit) 905int tipc_bclink_set_queue_limits(struct net *net, u32 limit)
933{ 906{
907 struct tipc_net *tn = net_generic(net, tipc_net_id);
908 struct tipc_link *bcl = tn->bcl;
909
934 if (!bcl) 910 if (!bcl)
935 return -ENOPROTOOPT; 911 return -ENOPROTOOPT;
936 if ((limit < TIPC_MIN_LINK_WIN) || (limit > TIPC_MAX_LINK_WIN)) 912 if ((limit < TIPC_MIN_LINK_WIN) || (limit > TIPC_MAX_LINK_WIN))
937 return -EINVAL; 913 return -EINVAL;
938 914
939 tipc_bclink_lock(); 915 tipc_bclink_lock(net);
940 tipc_link_set_queue_limits(bcl, limit); 916 tipc_link_set_queue_limits(bcl, limit);
941 tipc_bclink_unlock(); 917 tipc_bclink_unlock(net);
942 return 0; 918 return 0;
943} 919}
944 920
945int tipc_bclink_init(struct net *net) 921int tipc_bclink_init(struct net *net)
946{ 922{
947 struct tipc_net *tn = net_generic(net, tipc_net_id); 923 struct tipc_net *tn = net_generic(net, tipc_net_id);
924 struct tipc_bcbearer *bcbearer;
925 struct tipc_bclink *bclink;
926 struct tipc_link *bcl;
948 927
949 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); 928 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
950 if (!bcbearer) 929 if (!bcbearer)
@@ -969,12 +948,16 @@ int tipc_bclink_init(struct net *net)
969 spin_lock_init(&bclink->node.lock); 948 spin_lock_init(&bclink->node.lock);
970 __skb_queue_head_init(&bclink->node.waiting_sks); 949 __skb_queue_head_init(&bclink->node.waiting_sks);
971 bcl->owner = &bclink->node; 950 bcl->owner = &bclink->node;
951 bcl->owner->net = net;
972 bcl->max_pkt = MAX_PKT_DEFAULT_MCAST; 952 bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
973 tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); 953 tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
974 bcl->bearer_id = MAX_BEARERS; 954 bcl->bearer_id = MAX_BEARERS;
975 rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer); 955 rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer);
976 bcl->state = WORKING_WORKING; 956 bcl->state = WORKING_WORKING;
977 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); 957 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
958 tn->bcbearer = bcbearer;
959 tn->bclink = bclink;
960 tn->bcl = bcl;
978 return 0; 961 return 0;
979} 962}
980 963
@@ -982,14 +965,14 @@ void tipc_bclink_stop(struct net *net)
982{ 965{
983 struct tipc_net *tn = net_generic(net, tipc_net_id); 966 struct tipc_net *tn = net_generic(net, tipc_net_id);
984 967
985 tipc_bclink_lock(); 968 tipc_bclink_lock(net);
986 tipc_link_purge_queues(bcl); 969 tipc_link_purge_queues(tn->bcl);
987 tipc_bclink_unlock(); 970 tipc_bclink_unlock(net);
988 971
989 RCU_INIT_POINTER(tn->bearer_list[BCBEARER], NULL); 972 RCU_INIT_POINTER(tn->bearer_list[BCBEARER], NULL);
990 synchronize_net(); 973 synchronize_net();
991 kfree(bcbearer); 974 kfree(tn->bcbearer);
992 kfree(bclink); 975 kfree(tn->bclink);
993} 976}
994 977
995/** 978/**
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 692efb662253..a4583a109486 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -37,23 +37,13 @@
37#ifndef _TIPC_BCAST_H 37#ifndef _TIPC_BCAST_H
38#define _TIPC_BCAST_H 38#define _TIPC_BCAST_H
39 39
40#include "netlink.h" 40#include <linux/tipc_config.h>
41#include "link.h"
42#include "node.h"
41 43
42#define MAX_NODES 4096 44#define TIPC_BCLINK_RESET 1
43#define WSIZE 32 45#define PLSIZE 32
44#define TIPC_BCLINK_RESET 1 46#define BCBEARER MAX_BEARERS
45
46/**
47 * struct tipc_node_map - set of node identifiers
48 * @count: # of nodes in set
49 * @map: bitmap of node identifiers that are in the set
50 */
51struct tipc_node_map {
52 u32 count;
53 u32 map[MAX_NODES / WSIZE];
54};
55
56#define PLSIZE 32
57 47
58/** 48/**
59 * struct tipc_port_list - set of node local destination ports 49 * struct tipc_port_list - set of node local destination ports
@@ -67,9 +57,64 @@ struct tipc_port_list {
67 u32 ports[PLSIZE]; 57 u32 ports[PLSIZE];
68}; 58};
69 59
60/**
61 * struct tipc_bcbearer_pair - a pair of bearers used by broadcast link
62 * @primary: pointer to primary bearer
63 * @secondary: pointer to secondary bearer
64 *
65 * Bearers must have same priority and same set of reachable destinations
66 * to be paired.
67 */
70 68
71struct tipc_node; 69struct tipc_bcbearer_pair {
70 struct tipc_bearer *primary;
71 struct tipc_bearer *secondary;
72};
72 73
74/**
75 * struct tipc_bcbearer - bearer used by broadcast link
76 * @bearer: (non-standard) broadcast bearer structure
77 * @media: (non-standard) broadcast media structure
78 * @bpairs: array of bearer pairs
79 * @bpairs_temp: temporary array of bearer pairs used by tipc_bcbearer_sort()
80 * @remains: temporary node map used by tipc_bcbearer_send()
81 * @remains_new: temporary node map used tipc_bcbearer_send()
82 *
83 * Note: The fields labelled "temporary" are incorporated into the bearer
84 * to avoid consuming potentially limited stack space through the use of
85 * large local variables within multicast routines. Concurrent access is
86 * prevented through use of the spinlock "bclink_lock".
87 */
88struct tipc_bcbearer {
89 struct tipc_bearer bearer;
90 struct tipc_media media;
91 struct tipc_bcbearer_pair bpairs[MAX_BEARERS];
92 struct tipc_bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
93 struct tipc_node_map remains;
94 struct tipc_node_map remains_new;
95};
96
97/**
98 * struct tipc_bclink - link used for broadcast messages
99 * @lock: spinlock governing access to structure
100 * @link: (non-standard) broadcast link structure
101 * @node: (non-standard) node structure representing b'cast link's peer node
102 * @flags: represent bclink states
103 * @bcast_nodes: map of broadcast-capable nodes
104 * @retransmit_to: node that most recently requested a retransmit
105 *
106 * Handles sequence numbering, fragmentation, bundling, etc.
107 */
108struct tipc_bclink {
109 spinlock_t lock;
110 struct tipc_link link;
111 struct tipc_node node;
112 unsigned int flags;
113 struct tipc_node_map bcast_nodes;
114 struct tipc_node *retransmit_to;
115};
116
117struct tipc_node;
73extern const char tipc_bclink_name[]; 118extern const char tipc_bclink_name[];
74 119
75/** 120/**
@@ -86,24 +131,24 @@ void tipc_port_list_free(struct tipc_port_list *pl_ptr);
86 131
87int tipc_bclink_init(struct net *net); 132int tipc_bclink_init(struct net *net);
88void tipc_bclink_stop(struct net *net); 133void tipc_bclink_stop(struct net *net);
89void tipc_bclink_set_flags(unsigned int flags); 134void tipc_bclink_set_flags(struct net *tn, unsigned int flags);
90void tipc_bclink_add_node(u32 addr); 135void tipc_bclink_add_node(struct net *net, u32 addr);
91void tipc_bclink_remove_node(u32 addr); 136void tipc_bclink_remove_node(struct net *net, u32 addr);
92struct tipc_node *tipc_bclink_retransmit_to(void); 137struct tipc_node *tipc_bclink_retransmit_to(struct net *tn);
93void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked); 138void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
94void tipc_bclink_rcv(struct net *net, struct sk_buff *buf); 139void tipc_bclink_rcv(struct net *net, struct sk_buff *buf);
95u32 tipc_bclink_get_last_sent(void); 140u32 tipc_bclink_get_last_sent(struct net *net);
96u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr); 141u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr);
97void tipc_bclink_update_link_state(struct net *net, struct tipc_node *n_ptr, 142void tipc_bclink_update_link_state(struct net *net, struct tipc_node *n_ptr,
98 u32 last_sent); 143 u32 last_sent);
99int tipc_bclink_stats(char *stats_buf, const u32 buf_size); 144int tipc_bclink_stats(struct net *net, char *stats_buf, const u32 buf_size);
100int tipc_bclink_reset_stats(void); 145int tipc_bclink_reset_stats(struct net *net);
101int tipc_bclink_set_queue_limits(u32 limit); 146int tipc_bclink_set_queue_limits(struct net *net, u32 limit);
102void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr, 147void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr,
103 u32 node, bool action); 148 u32 node, bool action);
104uint tipc_bclink_get_mtu(void); 149uint tipc_bclink_get_mtu(void);
105int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list); 150int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list);
106void tipc_bclink_wakeup_users(struct net *net); 151void tipc_bclink_wakeup_users(struct net *net);
107int tipc_nl_add_bc_link(struct tipc_nl_msg *msg); 152int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg);
108 153
109#endif 154#endif
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 2fe9dcb418d4..9a0d6ed5c96c 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -40,6 +40,7 @@
40#include "bearer.h" 40#include "bearer.h"
41#include "link.h" 41#include "link.h"
42#include "discover.h" 42#include "discover.h"
43#include "bcast.h"
43 44
44#define MAX_ADDR_STR 60 45#define MAX_ADDR_STR 60
45 46
@@ -482,8 +483,8 @@ void tipc_disable_l2_media(struct tipc_bearer *b)
482 * @b_ptr: the bearer through which the packet is to be sent 483 * @b_ptr: the bearer through which the packet is to be sent
483 * @dest: peer destination address 484 * @dest: peer destination address
484 */ 485 */
485int tipc_l2_send_msg(struct sk_buff *buf, struct tipc_bearer *b, 486int tipc_l2_send_msg(struct net *net, struct sk_buff *buf,
486 struct tipc_media_addr *dest) 487 struct tipc_bearer *b, struct tipc_media_addr *dest)
487{ 488{
488 struct sk_buff *clone; 489 struct sk_buff *clone;
489 struct net_device *dev; 490 struct net_device *dev;
@@ -528,7 +529,7 @@ void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf,
528 rcu_read_lock(); 529 rcu_read_lock();
529 b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]); 530 b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
530 if (likely(b_ptr)) 531 if (likely(b_ptr))
531 b_ptr->media->send_msg(buf, b_ptr, dest); 532 b_ptr->media->send_msg(net, buf, b_ptr, dest);
532 rcu_read_unlock(); 533 rcu_read_unlock();
533} 534}
534 535
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 01722d6b2058..c035e3e24764 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -37,12 +37,13 @@
37#ifndef _TIPC_BEARER_H 37#ifndef _TIPC_BEARER_H
38#define _TIPC_BEARER_H 38#define _TIPC_BEARER_H
39 39
40#include "bcast.h"
41#include "netlink.h" 40#include "netlink.h"
42#include <net/genetlink.h> 41#include <net/genetlink.h>
43 42
44#define MAX_BEARERS 2 43#define MAX_BEARERS 2
45#define MAX_MEDIA 2 44#define MAX_MEDIA 2
45#define MAX_NODES 4096
46#define WSIZE 32
46 47
47/* Identifiers associated with TIPC message header media address info 48/* Identifiers associated with TIPC message header media address info
48 * - address info field is 32 bytes long 49 * - address info field is 32 bytes long
@@ -59,6 +60,16 @@
59#define TIPC_MEDIA_TYPE_IB 2 60#define TIPC_MEDIA_TYPE_IB 2
60 61
61/** 62/**
63 * struct tipc_node_map - set of node identifiers
64 * @count: # of nodes in set
65 * @map: bitmap of node identifiers that are in the set
66 */
67struct tipc_node_map {
68 u32 count;
69 u32 map[MAX_NODES / WSIZE];
70};
71
72/**
62 * struct tipc_media_addr - destination address used by TIPC bearers 73 * struct tipc_media_addr - destination address used by TIPC bearers
63 * @value: address info (format defined by media) 74 * @value: address info (format defined by media)
64 * @media_id: TIPC media type identifier 75 * @media_id: TIPC media type identifier
@@ -89,7 +100,7 @@ struct tipc_bearer;
89 * @name: media name 100 * @name: media name
90 */ 101 */
91struct tipc_media { 102struct tipc_media {
92 int (*send_msg)(struct sk_buff *buf, 103 int (*send_msg)(struct net *net, struct sk_buff *buf,
93 struct tipc_bearer *b_ptr, 104 struct tipc_bearer *b_ptr,
94 struct tipc_media_addr *dest); 105 struct tipc_media_addr *dest);
95 int (*enable_media)(struct net *net, struct tipc_bearer *b_ptr); 106 int (*enable_media)(struct net *net, struct tipc_bearer *b_ptr);
@@ -157,8 +168,6 @@ struct tipc_bearer_names {
157 char if_name[TIPC_MAX_IF_NAME]; 168 char if_name[TIPC_MAX_IF_NAME];
158}; 169};
159 170
160struct tipc_link;
161
162/* 171/*
163 * TIPC routines available to supported media types 172 * TIPC routines available to supported media types
164 */ 173 */
@@ -193,8 +202,8 @@ void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
193struct sk_buff *tipc_media_get_names(void); 202struct sk_buff *tipc_media_get_names(void);
194int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b); 203int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b);
195void tipc_disable_l2_media(struct tipc_bearer *b); 204void tipc_disable_l2_media(struct tipc_bearer *b);
196int tipc_l2_send_msg(struct sk_buff *buf, struct tipc_bearer *b, 205int tipc_l2_send_msg(struct net *net, struct sk_buff *buf,
197 struct tipc_media_addr *dest); 206 struct tipc_bearer *b, struct tipc_media_addr *dest);
198 207
199struct sk_buff *tipc_bearer_get_names(struct net *net); 208struct sk_buff *tipc_bearer_get_names(struct net *net);
200void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest); 209void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 75a332b1968e..3f6f9e07da99 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -61,6 +61,11 @@
61 61
62#include "node.h" 62#include "node.h"
63#include "bearer.h" 63#include "bearer.h"
64#include "bcast.h"
65#include "netlink.h"
66#include "link.h"
67#include "node.h"
68#include "msg.h"
64 69
65#define TIPC_MOD_VER "2.0.0" 70#define TIPC_MOD_VER "2.0.0"
66 71
@@ -91,6 +96,11 @@ struct tipc_net {
91 96
92 /* Bearer list */ 97 /* Bearer list */
93 struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1]; 98 struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
99
100 /* Broadcast link */
101 struct tipc_bcbearer *bcbearer;
102 struct tipc_bclink *bclink;
103 struct tipc_link *bcl;
94}; 104};
95 105
96#ifdef CONFIG_SYSCTL 106#ifdef CONFIG_SYSCTL
diff --git a/net/tipc/link.c b/net/tipc/link.c
index be21e6ac73fe..a84d5c67997e 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -941,6 +941,7 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
941 struct sk_buff *buf) 941 struct sk_buff *buf)
942{ 942{
943 struct tipc_msg *msg = buf_msg(buf); 943 struct tipc_msg *msg = buf_msg(buf);
944 struct net *net = l_ptr->owner->net;
944 945
945 pr_warn("Retransmission failure on link <%s>\n", l_ptr->name); 946 pr_warn("Retransmission failure on link <%s>\n", l_ptr->name);
946 947
@@ -958,7 +959,7 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
958 pr_cont("Outstanding acks: %lu\n", 959 pr_cont("Outstanding acks: %lu\n",
959 (unsigned long) TIPC_SKB_CB(buf)->handle); 960 (unsigned long) TIPC_SKB_CB(buf)->handle);
960 961
961 n_ptr = tipc_bclink_retransmit_to(); 962 n_ptr = tipc_bclink_retransmit_to(net);
962 tipc_node_lock(n_ptr); 963 tipc_node_lock(n_ptr);
963 964
964 tipc_addr_string_fill(addr_string, n_ptr->addr); 965 tipc_addr_string_fill(addr_string, n_ptr->addr);
@@ -973,7 +974,7 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
973 974
974 tipc_node_unlock(n_ptr); 975 tipc_node_unlock(n_ptr);
975 976
976 tipc_bclink_set_flags(TIPC_BCLINK_RESET); 977 tipc_bclink_set_flags(net, TIPC_BCLINK_RESET);
977 l_ptr->stale_count = 0; 978 l_ptr->stale_count = 0;
978 } 979 }
979} 980}
@@ -1404,7 +1405,7 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
1404 msg_set_type(msg, msg_typ); 1405 msg_set_type(msg, msg_typ);
1405 msg_set_net_plane(msg, l_ptr->net_plane); 1406 msg_set_net_plane(msg, l_ptr->net_plane);
1406 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 1407 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
1407 msg_set_last_bcast(msg, tipc_bclink_get_last_sent()); 1408 msg_set_last_bcast(msg, tipc_bclink_get_last_sent(l_ptr->owner->net));
1408 1409
1409 if (msg_typ == STATE_MSG) { 1410 if (msg_typ == STATE_MSG) {
1410 u32 next_sent = mod(l_ptr->next_out_no); 1411 u32 next_sent = mod(l_ptr->next_out_no);
@@ -2105,7 +2106,7 @@ struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area,
2105 2106
2106 if (!strcmp(args->name, tipc_bclink_name)) { 2107 if (!strcmp(args->name, tipc_bclink_name)) {
2107 if ((cmd == TIPC_CMD_SET_LINK_WINDOW) && 2108 if ((cmd == TIPC_CMD_SET_LINK_WINDOW) &&
2108 (tipc_bclink_set_queue_limits(new_value) == 0)) 2109 (tipc_bclink_set_queue_limits(net, new_value) == 0))
2109 return tipc_cfg_reply_none(); 2110 return tipc_cfg_reply_none();
2110 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 2111 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
2111 " (cannot change setting on broadcast link)"); 2112 " (cannot change setting on broadcast link)");
@@ -2143,7 +2144,7 @@ struct sk_buff *tipc_link_cmd_reset_stats(struct net *net,
2143 2144
2144 link_name = (char *)TLV_DATA(req_tlv_area); 2145 link_name = (char *)TLV_DATA(req_tlv_area);
2145 if (!strcmp(link_name, tipc_bclink_name)) { 2146 if (!strcmp(link_name, tipc_bclink_name)) {
2146 if (tipc_bclink_reset_stats()) 2147 if (tipc_bclink_reset_stats(net))
2147 return tipc_cfg_reply_error_string("link not found"); 2148 return tipc_cfg_reply_error_string("link not found");
2148 return tipc_cfg_reply_none(); 2149 return tipc_cfg_reply_none();
2149 } 2150 }
@@ -2191,7 +2192,7 @@ static int tipc_link_stats(struct net *net, const char *name, char *buf,
2191 int ret; 2192 int ret;
2192 2193
2193 if (!strcmp(name, tipc_bclink_name)) 2194 if (!strcmp(name, tipc_bclink_name))
2194 return tipc_bclink_stats(buf, buf_size); 2195 return tipc_bclink_stats(net, buf, buf_size);
2195 2196
2196 node = tipc_link_find_owner(net, name, &bearer_id); 2197 node = tipc_link_find_owner(net, name, &bearer_id);
2197 if (!node) 2198 if (!node)
@@ -2640,7 +2641,7 @@ int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb)
2640 prev_node = node->addr; 2641 prev_node = node->addr;
2641 } 2642 }
2642 } else { 2643 } else {
2643 err = tipc_nl_add_bc_link(&msg); 2644 err = tipc_nl_add_bc_link(net, &msg);
2644 if (err) 2645 if (err)
2645 goto out; 2646 goto out;
2646 2647
@@ -2739,7 +2740,7 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info)
2739 link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]); 2740 link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
2740 2741
2741 if (strcmp(link_name, tipc_bclink_name) == 0) { 2742 if (strcmp(link_name, tipc_bclink_name) == 0) {
2742 err = tipc_bclink_reset_stats(); 2743 err = tipc_bclink_reset_stats(net);
2743 if (err) 2744 if (err)
2744 return err; 2745 return err;
2745 return 0; 2746 return 0;
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 0065a2e8ad9b..75f324287244 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -37,7 +37,7 @@
37#ifndef _TIPC_MSG_H 37#ifndef _TIPC_MSG_H
38#define _TIPC_MSG_H 38#define _TIPC_MSG_H
39 39
40#include "bearer.h" 40#include <linux/tipc.h>
41 41
42/* 42/*
43 * Constants and routines used to read and write TIPC payload message headers 43 * Constants and routines used to read and write TIPC payload message headers
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index cf177907bb53..beed5fdda004 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -39,6 +39,7 @@
39#include "name_table.h" 39#include "name_table.h"
40#include "name_distr.h" 40#include "name_distr.h"
41#include "subscr.h" 41#include "subscr.h"
42#include "bcast.h"
42 43
43#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ 44#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
44 45
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 38633e5f8a7d..7548ba80d289 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -41,6 +41,7 @@
41#include "socket.h" 41#include "socket.h"
42#include "node.h" 42#include "node.h"
43#include "config.h" 43#include "config.h"
44#include "bcast.h"
44 45
45static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { 46static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
46 [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, 47 [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC },
diff --git a/net/tipc/node.c b/net/tipc/node.c
index a0ca1ac53119..3db501260de1 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -368,8 +368,8 @@ static void node_established_contact(struct tipc_node *n_ptr)
368{ 368{
369 n_ptr->action_flags |= TIPC_NOTIFY_NODE_UP; 369 n_ptr->action_flags |= TIPC_NOTIFY_NODE_UP;
370 n_ptr->bclink.oos_state = 0; 370 n_ptr->bclink.oos_state = 0;
371 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 371 n_ptr->bclink.acked = tipc_bclink_get_last_sent(n_ptr->net);
372 tipc_bclink_add_node(n_ptr->addr); 372 tipc_bclink_add_node(n_ptr->net, n_ptr->addr);
373} 373}
374 374
375static void node_lost_contact(struct tipc_node *n_ptr) 375static void node_lost_contact(struct tipc_node *n_ptr)
@@ -389,7 +389,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
389 n_ptr->bclink.reasm_buf = NULL; 389 n_ptr->bclink.reasm_buf = NULL;
390 } 390 }
391 391
392 tipc_bclink_remove_node(n_ptr->addr); 392 tipc_bclink_remove_node(n_ptr->net, n_ptr->addr);
393 tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ); 393 tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ);
394 394
395 n_ptr->bclink.recv_permitted = false; 395 n_ptr->bclink.recv_permitted = false;