aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bcast.c
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2015-01-09 02:27:07 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-12 16:24:33 -0500
commit1da465683a93142488a54a9038155f23d6349441 (patch)
tree95ccbeb4302d4b18fe0e12bfbb2b6b819ad84614 /net/tipc/bcast.c
parent7f9f95d9d9bcdf253c4149a157b096958013eceb (diff)
tipc: make tipc broadcast link support net namespace
TIPC broadcast link is statically established and its relevant states are maintained with the global variables: "bcbearer", "bclink" and "bcl". Allowing different namespace to own different broadcast link instances, these variables must be moved to tipc_net structure and broadcast link instances would be allocated and initialized when namespace is created. Signed-off-by: Ying Xue <ying.xue@windriver.com> Tested-by: Tero Aho <Tero.Aho@coriant.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r--net/tipc/bcast.c297
1 files changed, 140 insertions, 157 deletions
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/**