aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2012-04-06 21:48:59 -0400
committerLen Brown <len.brown@intel.com>2012-04-06 21:48:59 -0400
commiteeaab2d8af2cf1d36d7086f22e9de42d6dd2995c (patch)
tree369b9c91a6d808944f07d2290fec6f9fe2731904 /net/tipc
parentee01e663373343c63e0e3d364d09f6155378dbcc (diff)
parentaaef292acf3a78d9c0bb6fb72226077d286b45d7 (diff)
Merge branches 'idle-fix' and 'misc' into release
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c336
-rw-r--r--net/tipc/bcast.h2
-rw-r--r--net/tipc/bearer.c5
-rw-r--r--net/tipc/config.c21
-rw-r--r--net/tipc/core.c10
-rw-r--r--net/tipc/core.h42
-rw-r--r--net/tipc/discover.c79
-rw-r--r--net/tipc/link.c299
-rw-r--r--net/tipc/log.c2
-rw-r--r--net/tipc/msg.c2
-rw-r--r--net/tipc/msg.h15
-rw-r--r--net/tipc/name_distr.c8
-rw-r--r--net/tipc/name_table.c48
-rw-r--r--net/tipc/name_table.h2
-rw-r--r--net/tipc/net.c11
-rw-r--r--net/tipc/node.c84
-rw-r--r--net/tipc/node.h37
-rw-r--r--net/tipc/port.c72
-rw-r--r--net/tipc/port.h42
-rw-r--r--net/tipc/socket.c11
-rw-r--r--net/tipc/subscr.c2
21 files changed, 532 insertions, 598 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 8eb87b11d100..e00441a2092f 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -157,39 +157,14 @@ u32 tipc_bclink_get_last_sent(void)
157 return bcl->fsm_msg_cnt; 157 return bcl->fsm_msg_cnt;
158} 158}
159 159
160/** 160static void bclink_update_last_sent(struct tipc_node *node, u32 seqno)
161 * bclink_set_gap - set gap according to contents of current deferred pkt queue
162 *
163 * Called with 'node' locked, bc_lock unlocked
164 */
165
166static void bclink_set_gap(struct tipc_node *n_ptr)
167{
168 struct sk_buff *buf = n_ptr->bclink.deferred_head;
169
170 n_ptr->bclink.gap_after = n_ptr->bclink.gap_to =
171 mod(n_ptr->bclink.last_in);
172 if (unlikely(buf != NULL))
173 n_ptr->bclink.gap_to = mod(buf_seqno(buf) - 1);
174}
175
176/**
177 * bclink_ack_allowed - test if ACK or NACK message can be sent at this moment
178 *
179 * This mechanism endeavours to prevent all nodes in network from trying
180 * to ACK or NACK at the same time.
181 *
182 * Note: TIPC uses a different trigger to distribute ACKs than it does to
183 * distribute NACKs, but tries to use the same spacing (divide by 16).
184 */
185
186static int bclink_ack_allowed(u32 n)
187{ 161{
188 return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag; 162 node->bclink.last_sent = less_eq(node->bclink.last_sent, seqno) ?
163 seqno : node->bclink.last_sent;
189} 164}
190 165
191 166
192/** 167/*
193 * tipc_bclink_retransmit_to - get most recent node to request retransmission 168 * tipc_bclink_retransmit_to - get most recent node to request retransmission
194 * 169 *
195 * Called with bc_lock locked 170 * Called with bc_lock locked
@@ -281,7 +256,7 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
281 if (bcbuf_acks(crs) == 0) { 256 if (bcbuf_acks(crs) == 0) {
282 bcl->first_out = next; 257 bcl->first_out = next;
283 bcl->out_queue_size--; 258 bcl->out_queue_size--;
284 buf_discard(crs); 259 kfree_skb(crs);
285 released = 1; 260 released = 1;
286 } 261 }
287 crs = next; 262 crs = next;
@@ -300,140 +275,94 @@ exit:
300 spin_unlock_bh(&bc_lock); 275 spin_unlock_bh(&bc_lock);
301} 276}
302 277
303/** 278/*
304 * bclink_send_ack - unicast an ACK msg 279 * tipc_bclink_update_link_state - update broadcast link state
305 * 280 *
306 * tipc_net_lock and node lock set 281 * tipc_net_lock and node lock set
307 */ 282 */
308 283
309static void bclink_send_ack(struct tipc_node *n_ptr) 284void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
310{ 285{
311 struct tipc_link *l_ptr = n_ptr->active_links[n_ptr->addr & 1]; 286 struct sk_buff *buf;
312 287
313 if (l_ptr != NULL) 288 /* Ignore "stale" link state info */
314 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
315}
316 289
317/** 290 if (less_eq(last_sent, n_ptr->bclink.last_in))
318 * bclink_send_nack- broadcast a NACK msg 291 return;
319 *
320 * tipc_net_lock and node lock set
321 */
322 292
323static void bclink_send_nack(struct tipc_node *n_ptr) 293 /* Update link synchronization state; quit if in sync */
324{ 294
325 struct sk_buff *buf; 295 bclink_update_last_sent(n_ptr, last_sent);
326 struct tipc_msg *msg; 296
297 if (n_ptr->bclink.last_sent == n_ptr->bclink.last_in)
298 return;
299
300 /* Update out-of-sync state; quit if loss is still unconfirmed */
301
302 if ((++n_ptr->bclink.oos_state) == 1) {
303 if (n_ptr->bclink.deferred_size < (TIPC_MIN_LINK_WIN / 2))
304 return;
305 n_ptr->bclink.oos_state++;
306 }
327 307
328 if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to)) 308 /* Don't NACK if one has been recently sent (or seen) */
309
310 if (n_ptr->bclink.oos_state & 0x1)
329 return; 311 return;
330 312
313 /* Send NACK */
314
331 buf = tipc_buf_acquire(INT_H_SIZE); 315 buf = tipc_buf_acquire(INT_H_SIZE);
332 if (buf) { 316 if (buf) {
333 msg = buf_msg(buf); 317 struct tipc_msg *msg = buf_msg(buf);
318
334 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 319 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
335 INT_H_SIZE, n_ptr->addr); 320 INT_H_SIZE, n_ptr->addr);
336 msg_set_non_seq(msg, 1); 321 msg_set_non_seq(msg, 1);
337 msg_set_mc_netid(msg, tipc_net_id); 322 msg_set_mc_netid(msg, tipc_net_id);
338 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 323 msg_set_bcast_ack(msg, n_ptr->bclink.last_in);
339 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); 324 msg_set_bcgap_after(msg, n_ptr->bclink.last_in);
340 msg_set_bcgap_to(msg, n_ptr->bclink.gap_to); 325 msg_set_bcgap_to(msg, n_ptr->bclink.deferred_head
341 msg_set_bcast_tag(msg, tipc_own_tag); 326 ? buf_seqno(n_ptr->bclink.deferred_head) - 1
327 : n_ptr->bclink.last_sent);
342 328
329 spin_lock_bh(&bc_lock);
343 tipc_bearer_send(&bcbearer->bearer, buf, NULL); 330 tipc_bearer_send(&bcbearer->bearer, buf, NULL);
344 bcl->stats.sent_nacks++; 331 bcl->stats.sent_nacks++;
345 buf_discard(buf); 332 spin_unlock_bh(&bc_lock);
346 333 kfree_skb(buf);
347 /*
348 * Ensure we doesn't send another NACK msg to the node
349 * until 16 more deferred messages arrive from it
350 * (i.e. helps prevent all nodes from NACK'ing at same time)
351 */
352 334
353 n_ptr->bclink.nack_sync = tipc_own_tag; 335 n_ptr->bclink.oos_state++;
354 } 336 }
355} 337}
356 338
357/** 339/*
358 * tipc_bclink_check_gap - send a NACK if a sequence gap exists 340 * bclink_peek_nack - monitor retransmission requests sent by other nodes
359 * 341 *
360 * tipc_net_lock and node lock set 342 * Delay any upcoming NACK by this node if another node has already
361 */ 343 * requested the first message this node is going to ask for.
362
363void tipc_bclink_check_gap(struct tipc_node *n_ptr, u32 last_sent)
364{
365 if (!n_ptr->bclink.supported ||
366 less_eq(last_sent, mod(n_ptr->bclink.last_in)))
367 return;
368
369 bclink_set_gap(n_ptr);
370 if (n_ptr->bclink.gap_after == n_ptr->bclink.gap_to)
371 n_ptr->bclink.gap_to = last_sent;
372 bclink_send_nack(n_ptr);
373}
374
375/**
376 * tipc_bclink_peek_nack - process a NACK msg meant for another node
377 * 344 *
378 * Only tipc_net_lock set. 345 * Only tipc_net_lock set.
379 */ 346 */
380 347
381static void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to) 348static void bclink_peek_nack(struct tipc_msg *msg)
382{ 349{
383 struct tipc_node *n_ptr = tipc_node_find(dest); 350 struct tipc_node *n_ptr = tipc_node_find(msg_destnode(msg));
384 u32 my_after, my_to;
385 351
386 if (unlikely(!n_ptr || !tipc_node_is_up(n_ptr))) 352 if (unlikely(!n_ptr))
387 return; 353 return;
354
388 tipc_node_lock(n_ptr); 355 tipc_node_lock(n_ptr);
389 /*
390 * Modify gap to suppress unnecessary NACKs from this node
391 */
392 my_after = n_ptr->bclink.gap_after;
393 my_to = n_ptr->bclink.gap_to;
394
395 if (less_eq(gap_after, my_after)) {
396 if (less(my_after, gap_to) && less(gap_to, my_to))
397 n_ptr->bclink.gap_after = gap_to;
398 else if (less_eq(my_to, gap_to))
399 n_ptr->bclink.gap_to = n_ptr->bclink.gap_after;
400 } else if (less_eq(gap_after, my_to)) {
401 if (less_eq(my_to, gap_to))
402 n_ptr->bclink.gap_to = gap_after;
403 } else {
404 /*
405 * Expand gap if missing bufs not in deferred queue:
406 */
407 struct sk_buff *buf = n_ptr->bclink.deferred_head;
408 u32 prev = n_ptr->bclink.gap_to;
409 356
410 for (; buf; buf = buf->next) { 357 if (n_ptr->bclink.supported &&
411 u32 seqno = buf_seqno(buf); 358 (n_ptr->bclink.last_in != n_ptr->bclink.last_sent) &&
359 (n_ptr->bclink.last_in == msg_bcgap_after(msg)))
360 n_ptr->bclink.oos_state = 2;
412 361
413 if (mod(seqno - prev) != 1) {
414 buf = NULL;
415 break;
416 }
417 if (seqno == gap_after)
418 break;
419 prev = seqno;
420 }
421 if (buf == NULL)
422 n_ptr->bclink.gap_to = gap_after;
423 }
424 /*
425 * Some nodes may send a complementary NACK now:
426 */
427 if (bclink_ack_allowed(sender_tag + 1)) {
428 if (n_ptr->bclink.gap_to != n_ptr->bclink.gap_after) {
429 bclink_send_nack(n_ptr);
430 bclink_set_gap(n_ptr);
431 }
432 }
433 tipc_node_unlock(n_ptr); 362 tipc_node_unlock(n_ptr);
434} 363}
435 364
436/** 365/*
437 * tipc_bclink_send_msg - broadcast a packet to all nodes in cluster 366 * tipc_bclink_send_msg - broadcast a packet to all nodes in cluster
438 */ 367 */
439 368
@@ -445,7 +374,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
445 374
446 if (!bclink->bcast_nodes.count) { 375 if (!bclink->bcast_nodes.count) {
447 res = msg_data_sz(buf_msg(buf)); 376 res = msg_data_sz(buf_msg(buf));
448 buf_discard(buf); 377 kfree_skb(buf);
449 goto exit; 378 goto exit;
450 } 379 }
451 380
@@ -460,7 +389,33 @@ exit:
460 return res; 389 return res;
461} 390}
462 391
463/** 392/*
393 * bclink_accept_pkt - accept an incoming, in-sequence broadcast packet
394 *
395 * Called with both sending node's lock and bc_lock taken.
396 */
397
398static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
399{
400 bclink_update_last_sent(node, seqno);
401 node->bclink.last_in = seqno;
402 node->bclink.oos_state = 0;
403 bcl->stats.recv_info++;
404
405 /*
406 * Unicast an ACK periodically, ensuring that
407 * all nodes in the cluster don't ACK at the same time
408 */
409
410 if (((seqno - tipc_own_addr) % TIPC_MIN_LINK_WIN) == 0) {
411 tipc_link_send_proto_msg(
412 node->active_links[node->addr & 1],
413 STATE_MSG, 0, 0, 0, 0, 0);
414 bcl->stats.sent_acks++;
415 }
416}
417
418/*
464 * tipc_bclink_recv_pkt - receive a broadcast packet, and deliver upwards 419 * tipc_bclink_recv_pkt - receive a broadcast packet, and deliver upwards
465 * 420 *
466 * tipc_net_lock is read_locked, no other locks set 421 * tipc_net_lock is read_locked, no other locks set
@@ -472,7 +427,7 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
472 struct tipc_node *node; 427 struct tipc_node *node;
473 u32 next_in; 428 u32 next_in;
474 u32 seqno; 429 u32 seqno;
475 struct sk_buff *deferred; 430 int deferred;
476 431
477 /* Screen out unwanted broadcast messages */ 432 /* Screen out unwanted broadcast messages */
478 433
@@ -487,6 +442,8 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
487 if (unlikely(!node->bclink.supported)) 442 if (unlikely(!node->bclink.supported))
488 goto unlock; 443 goto unlock;
489 444
445 /* Handle broadcast protocol message */
446
490 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { 447 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
491 if (msg_type(msg) != STATE_MSG) 448 if (msg_type(msg) != STATE_MSG)
492 goto unlock; 449 goto unlock;
@@ -501,89 +458,118 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
501 spin_unlock_bh(&bc_lock); 458 spin_unlock_bh(&bc_lock);
502 } else { 459 } else {
503 tipc_node_unlock(node); 460 tipc_node_unlock(node);
504 tipc_bclink_peek_nack(msg_destnode(msg), 461 bclink_peek_nack(msg);
505 msg_bcast_tag(msg),
506 msg_bcgap_after(msg),
507 msg_bcgap_to(msg));
508 } 462 }
509 goto exit; 463 goto exit;
510 } 464 }
511 465
512 /* Handle in-sequence broadcast message */ 466 /* Handle in-sequence broadcast message */
513 467
514receive:
515 next_in = mod(node->bclink.last_in + 1);
516 seqno = msg_seqno(msg); 468 seqno = msg_seqno(msg);
469 next_in = mod(node->bclink.last_in + 1);
517 470
518 if (likely(seqno == next_in)) { 471 if (likely(seqno == next_in)) {
519 bcl->stats.recv_info++; 472receive:
520 node->bclink.last_in++; 473 /* Deliver message to destination */
521 bclink_set_gap(node); 474
522 if (unlikely(bclink_ack_allowed(seqno))) {
523 bclink_send_ack(node);
524 bcl->stats.sent_acks++;
525 }
526 if (likely(msg_isdata(msg))) { 475 if (likely(msg_isdata(msg))) {
476 spin_lock_bh(&bc_lock);
477 bclink_accept_pkt(node, seqno);
478 spin_unlock_bh(&bc_lock);
527 tipc_node_unlock(node); 479 tipc_node_unlock(node);
528 if (likely(msg_mcast(msg))) 480 if (likely(msg_mcast(msg)))
529 tipc_port_recv_mcast(buf, NULL); 481 tipc_port_recv_mcast(buf, NULL);
530 else 482 else
531 buf_discard(buf); 483 kfree_skb(buf);
532 } else if (msg_user(msg) == MSG_BUNDLER) { 484 } else if (msg_user(msg) == MSG_BUNDLER) {
485 spin_lock_bh(&bc_lock);
486 bclink_accept_pkt(node, seqno);
533 bcl->stats.recv_bundles++; 487 bcl->stats.recv_bundles++;
534 bcl->stats.recv_bundled += msg_msgcnt(msg); 488 bcl->stats.recv_bundled += msg_msgcnt(msg);
489 spin_unlock_bh(&bc_lock);
535 tipc_node_unlock(node); 490 tipc_node_unlock(node);
536 tipc_link_recv_bundle(buf); 491 tipc_link_recv_bundle(buf);
537 } else if (msg_user(msg) == MSG_FRAGMENTER) { 492 } else if (msg_user(msg) == MSG_FRAGMENTER) {
493 int ret = tipc_link_recv_fragment(&node->bclink.defragm,
494 &buf, &msg);
495 if (ret < 0)
496 goto unlock;
497 spin_lock_bh(&bc_lock);
498 bclink_accept_pkt(node, seqno);
538 bcl->stats.recv_fragments++; 499 bcl->stats.recv_fragments++;
539 if (tipc_link_recv_fragment(&node->bclink.defragm, 500 if (ret > 0)
540 &buf, &msg))
541 bcl->stats.recv_fragmented++; 501 bcl->stats.recv_fragmented++;
502 spin_unlock_bh(&bc_lock);
542 tipc_node_unlock(node); 503 tipc_node_unlock(node);
543 tipc_net_route_msg(buf); 504 tipc_net_route_msg(buf);
544 } else if (msg_user(msg) == NAME_DISTRIBUTOR) { 505 } else if (msg_user(msg) == NAME_DISTRIBUTOR) {
506 spin_lock_bh(&bc_lock);
507 bclink_accept_pkt(node, seqno);
508 spin_unlock_bh(&bc_lock);
545 tipc_node_unlock(node); 509 tipc_node_unlock(node);
546 tipc_named_recv(buf); 510 tipc_named_recv(buf);
547 } else { 511 } else {
512 spin_lock_bh(&bc_lock);
513 bclink_accept_pkt(node, seqno);
514 spin_unlock_bh(&bc_lock);
548 tipc_node_unlock(node); 515 tipc_node_unlock(node);
549 buf_discard(buf); 516 kfree_skb(buf);
550 } 517 }
551 buf = NULL; 518 buf = NULL;
519
520 /* Determine new synchronization state */
521
552 tipc_node_lock(node); 522 tipc_node_lock(node);
553 deferred = node->bclink.deferred_head; 523 if (unlikely(!tipc_node_is_up(node)))
554 if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) { 524 goto unlock;
555 buf = deferred; 525
556 msg = buf_msg(buf); 526 if (node->bclink.last_in == node->bclink.last_sent)
557 node->bclink.deferred_head = deferred->next; 527 goto unlock;
558 goto receive; 528
559 } 529 if (!node->bclink.deferred_head) {
560 } else if (less(next_in, seqno)) { 530 node->bclink.oos_state = 1;
561 u32 gap_after = node->bclink.gap_after; 531 goto unlock;
562 u32 gap_to = node->bclink.gap_to;
563
564 if (tipc_link_defer_pkt(&node->bclink.deferred_head,
565 &node->bclink.deferred_tail,
566 buf)) {
567 node->bclink.nack_sync++;
568 bcl->stats.deferred_recv++;
569 if (seqno == mod(gap_after + 1))
570 node->bclink.gap_after = seqno;
571 else if (less(gap_after, seqno) && less(seqno, gap_to))
572 node->bclink.gap_to = seqno;
573 } 532 }
533
534 msg = buf_msg(node->bclink.deferred_head);
535 seqno = msg_seqno(msg);
536 next_in = mod(next_in + 1);
537 if (seqno != next_in)
538 goto unlock;
539
540 /* Take in-sequence message from deferred queue & deliver it */
541
542 buf = node->bclink.deferred_head;
543 node->bclink.deferred_head = buf->next;
544 node->bclink.deferred_size--;
545 goto receive;
546 }
547
548 /* Handle out-of-sequence broadcast message */
549
550 if (less(next_in, seqno)) {
551 deferred = tipc_link_defer_pkt(&node->bclink.deferred_head,
552 &node->bclink.deferred_tail,
553 buf);
554 node->bclink.deferred_size += deferred;
555 bclink_update_last_sent(node, seqno);
574 buf = NULL; 556 buf = NULL;
575 if (bclink_ack_allowed(node->bclink.nack_sync)) { 557 } else
576 if (gap_to != gap_after) 558 deferred = 0;
577 bclink_send_nack(node); 559
578 bclink_set_gap(node); 560 spin_lock_bh(&bc_lock);
579 } 561
580 } else { 562 if (deferred)
563 bcl->stats.deferred_recv++;
564 else
581 bcl->stats.duplicates++; 565 bcl->stats.duplicates++;
582 } 566
567 spin_unlock_bh(&bc_lock);
568
583unlock: 569unlock:
584 tipc_node_unlock(node); 570 tipc_node_unlock(node);
585exit: 571exit:
586 buf_discard(buf); 572 kfree_skb(buf);
587} 573}
588 574
589u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) 575u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index b009666c60b0..5571394098f9 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -96,7 +96,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf);
96void tipc_bclink_recv_pkt(struct sk_buff *buf); 96void tipc_bclink_recv_pkt(struct sk_buff *buf);
97u32 tipc_bclink_get_last_sent(void); 97u32 tipc_bclink_get_last_sent(void);
98u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr); 98u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr);
99void tipc_bclink_check_gap(struct tipc_node *n_ptr, u32 seqno); 99void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent);
100int tipc_bclink_stats(char *stats_buf, const u32 buf_size); 100int tipc_bclink_stats(char *stats_buf, const u32 buf_size);
101int tipc_bclink_reset_stats(void); 101int tipc_bclink_reset_stats(void);
102int tipc_bclink_set_queue_limits(u32 limit); 102int tipc_bclink_set_queue_limits(u32 limit);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 329fb659fae4..5dfd89c40429 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -435,7 +435,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
435 u32 i; 435 u32 i;
436 int res = -EINVAL; 436 int res = -EINVAL;
437 437
438 if (tipc_mode != TIPC_NET_MODE) { 438 if (!tipc_own_addr) {
439 warn("Bearer <%s> rejected, not supported in standalone mode\n", 439 warn("Bearer <%s> rejected, not supported in standalone mode\n",
440 name); 440 name);
441 return -ENOPROTOOPT; 441 return -ENOPROTOOPT;
@@ -456,8 +456,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
456 warn("Bearer <%s> rejected, illegal discovery domain\n", name); 456 warn("Bearer <%s> rejected, illegal discovery domain\n", name);
457 return -EINVAL; 457 return -EINVAL;
458 } 458 }
459 if ((priority < TIPC_MIN_LINK_PRI || 459 if ((priority > TIPC_MAX_LINK_PRI) &&
460 priority > TIPC_MAX_LINK_PRI) &&
461 (priority != TIPC_MEDIA_LINK_PRI)) { 460 (priority != TIPC_MEDIA_LINK_PRI)) {
462 warn("Bearer <%s> rejected, illegal priority\n", name); 461 warn("Bearer <%s> rejected, illegal priority\n", name);
463 return -EINVAL; 462 return -EINVAL;
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 4785bf26cdf4..f76d3b15e4e2 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -179,7 +179,7 @@ static struct sk_buff *cfg_set_own_addr(void)
179 if (!tipc_addr_node_valid(addr)) 179 if (!tipc_addr_node_valid(addr))
180 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 180 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
181 " (node address)"); 181 " (node address)");
182 if (tipc_mode == TIPC_NET_MODE) 182 if (tipc_own_addr)
183 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 183 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
184 " (cannot change node address once assigned)"); 184 " (cannot change node address once assigned)");
185 185
@@ -218,7 +218,7 @@ static struct sk_buff *cfg_set_max_publications(void)
218 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 218 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
219 219
220 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 220 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
221 if (value != delimit(value, 1, 65535)) 221 if (value < 1 || value > 65535)
222 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 222 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
223 " (max publications must be 1-65535)"); 223 " (max publications must be 1-65535)");
224 tipc_max_publications = value; 224 tipc_max_publications = value;
@@ -233,7 +233,7 @@ static struct sk_buff *cfg_set_max_subscriptions(void)
233 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 233 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
234 234
235 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 235 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
236 if (value != delimit(value, 1, 65535)) 236 if (value < 1 || value > 65535)
237 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 237 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
238 " (max subscriptions must be 1-65535"); 238 " (max subscriptions must be 1-65535");
239 tipc_max_subscriptions = value; 239 tipc_max_subscriptions = value;
@@ -249,14 +249,11 @@ static struct sk_buff *cfg_set_max_ports(void)
249 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 249 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
250 if (value == tipc_max_ports) 250 if (value == tipc_max_ports)
251 return tipc_cfg_reply_none(); 251 return tipc_cfg_reply_none();
252 if (value != delimit(value, 127, 65535)) 252 if (value < 127 || value > 65535)
253 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 253 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
254 " (max ports must be 127-65535)"); 254 " (max ports must be 127-65535)");
255 if (tipc_mode != TIPC_NOT_RUNNING) 255 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
256 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 256 " (cannot change max ports while TIPC is active)");
257 " (cannot change max ports while TIPC is active)");
258 tipc_max_ports = value;
259 return tipc_cfg_reply_none();
260} 257}
261 258
262static struct sk_buff *cfg_set_netid(void) 259static struct sk_buff *cfg_set_netid(void)
@@ -268,10 +265,10 @@ static struct sk_buff *cfg_set_netid(void)
268 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 265 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
269 if (value == tipc_net_id) 266 if (value == tipc_net_id)
270 return tipc_cfg_reply_none(); 267 return tipc_cfg_reply_none();
271 if (value != delimit(value, 1, 9999)) 268 if (value < 1 || value > 9999)
272 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 269 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
273 " (network id must be 1-9999)"); 270 " (network id must be 1-9999)");
274 if (tipc_mode == TIPC_NET_MODE) 271 if (tipc_own_addr)
275 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 272 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
276 " (cannot change network id once TIPC has joined a network)"); 273 " (cannot change network id once TIPC has joined a network)");
277 tipc_net_id = value; 274 tipc_net_id = value;
@@ -481,7 +478,7 @@ int tipc_cfg_init(void)
481 478
482 seq.type = TIPC_CFG_SRV; 479 seq.type = TIPC_CFG_SRV;
483 seq.lower = seq.upper = tipc_own_addr; 480 seq.lower = seq.upper = tipc_own_addr;
484 res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq); 481 res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq);
485 if (res) 482 if (res)
486 goto failed; 483 goto failed;
487 484
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 2691cd57b8a8..68eba03e7955 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -53,7 +53,6 @@
53 53
54/* global variables used by multiple sub-systems within TIPC */ 54/* global variables used by multiple sub-systems within TIPC */
55 55
56int tipc_mode = TIPC_NOT_RUNNING;
57int tipc_random; 56int tipc_random;
58 57
59const char tipc_alphabet[] = 58const char tipc_alphabet[] =
@@ -125,11 +124,6 @@ int tipc_core_start_net(unsigned long addr)
125 124
126static void tipc_core_stop(void) 125static void tipc_core_stop(void)
127{ 126{
128 if (tipc_mode != TIPC_NODE_MODE)
129 return;
130
131 tipc_mode = TIPC_NOT_RUNNING;
132
133 tipc_netlink_stop(); 127 tipc_netlink_stop();
134 tipc_handler_stop(); 128 tipc_handler_stop();
135 tipc_cfg_stop(); 129 tipc_cfg_stop();
@@ -148,11 +142,7 @@ static int tipc_core_start(void)
148{ 142{
149 int res; 143 int res;
150 144
151 if (tipc_mode != TIPC_NOT_RUNNING)
152 return -ENOPROTOOPT;
153
154 get_random_bytes(&tipc_random, sizeof(tipc_random)); 145 get_random_bytes(&tipc_random, sizeof(tipc_random));
155 tipc_mode = TIPC_NODE_MODE;
156 146
157 res = tipc_handler_start(); 147 res = tipc_handler_start();
158 if (!res) 148 if (!res)
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 2761af36d141..13837e0e56b1 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -130,13 +130,6 @@ void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
130#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */ 130#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
131 131
132/* 132/*
133 * TIPC operating mode routines
134 */
135#define TIPC_NOT_RUNNING 0
136#define TIPC_NODE_MODE 1
137#define TIPC_NET_MODE 2
138
139/*
140 * Global configuration variables 133 * Global configuration variables
141 */ 134 */
142 135
@@ -151,7 +144,6 @@ extern int tipc_remote_management;
151 * Other global variables 144 * Other global variables
152 */ 145 */
153 146
154extern int tipc_mode;
155extern int tipc_random; 147extern int tipc_random;
156extern const char tipc_alphabet[]; 148extern const char tipc_alphabet[];
157 149
@@ -168,16 +160,6 @@ extern void tipc_netlink_stop(void);
168extern int tipc_socket_init(void); 160extern int tipc_socket_init(void);
169extern void tipc_socket_stop(void); 161extern void tipc_socket_stop(void);
170 162
171static inline int delimit(int val, int min, int max)
172{
173 if (val > max)
174 return max;
175 if (val < min)
176 return min;
177 return val;
178}
179
180
181/* 163/*
182 * TIPC timer and signal code 164 * TIPC timer and signal code
183 */ 165 */
@@ -279,28 +261,4 @@ static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
279 261
280extern struct sk_buff *tipc_buf_acquire(u32 size); 262extern struct sk_buff *tipc_buf_acquire(u32 size);
281 263
282/**
283 * buf_discard - frees a TIPC message buffer
284 * @skb: message buffer
285 *
286 * Frees a message buffer. If passed NULL, just returns.
287 */
288
289static inline void buf_discard(struct sk_buff *skb)
290{
291 kfree_skb(skb);
292}
293
294/**
295 * buf_linearize - convert a TIPC message buffer into a single contiguous piece
296 * @skb: message buffer
297 *
298 * Returns 0 on success.
299 */
300
301static inline int buf_linearize(struct sk_buff *skb)
302{
303 return skb_linearize(skb);
304}
305
306#endif 264#endif
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index a00e5f811569..c630a21b2bed 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -82,6 +82,7 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
82 msg = buf_msg(buf); 82 msg = buf_msg(buf);
83 tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain); 83 tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
84 msg_set_non_seq(msg, 1); 84 msg_set_non_seq(msg, 1);
85 msg_set_node_sig(msg, tipc_random);
85 msg_set_dest_domain(msg, dest_domain); 86 msg_set_dest_domain(msg, dest_domain);
86 msg_set_bc_netid(msg, tipc_net_id); 87 msg_set_bc_netid(msg, tipc_net_id);
87 b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg)); 88 b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg));
@@ -121,20 +122,22 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
121{ 122{
122 struct tipc_node *n_ptr; 123 struct tipc_node *n_ptr;
123 struct tipc_link *link; 124 struct tipc_link *link;
124 struct tipc_media_addr media_addr, *addr; 125 struct tipc_media_addr media_addr;
125 struct sk_buff *rbuf; 126 struct sk_buff *rbuf;
126 struct tipc_msg *msg = buf_msg(buf); 127 struct tipc_msg *msg = buf_msg(buf);
127 u32 dest = msg_dest_domain(msg); 128 u32 dest = msg_dest_domain(msg);
128 u32 orig = msg_prevnode(msg); 129 u32 orig = msg_prevnode(msg);
129 u32 net_id = msg_bc_netid(msg); 130 u32 net_id = msg_bc_netid(msg);
130 u32 type = msg_type(msg); 131 u32 type = msg_type(msg);
132 u32 signature = msg_node_sig(msg);
133 int addr_mismatch;
131 int link_fully_up; 134 int link_fully_up;
132 135
133 media_addr.broadcast = 1; 136 media_addr.broadcast = 1;
134 b_ptr->media->msg2addr(&media_addr, msg_media_addr(msg)); 137 b_ptr->media->msg2addr(&media_addr, msg_media_addr(msg));
135 buf_discard(buf); 138 kfree_skb(buf);
136 139
137 /* Validate discovery message from requesting node */ 140 /* Ensure message from node is valid and communication is permitted */
138 if (net_id != tipc_net_id) 141 if (net_id != tipc_net_id)
139 return; 142 return;
140 if (media_addr.broadcast) 143 if (media_addr.broadcast)
@@ -162,15 +165,50 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
162 } 165 }
163 tipc_node_lock(n_ptr); 166 tipc_node_lock(n_ptr);
164 167
168 /* Prepare to validate requesting node's signature and media address */
165 link = n_ptr->links[b_ptr->identity]; 169 link = n_ptr->links[b_ptr->identity];
170 addr_mismatch = (link != NULL) &&
171 memcmp(&link->media_addr, &media_addr, sizeof(media_addr));
166 172
167 /* Create a link endpoint for this bearer, if necessary */ 173 /*
168 if (!link) { 174 * Ensure discovery message's signature is correct
169 link = tipc_link_create(n_ptr, b_ptr, &media_addr); 175 *
170 if (!link) { 176 * If signature is incorrect and there is no working link to the node,
177 * accept the new signature but invalidate all existing links to the
178 * node so they won't re-activate without a new discovery message.
179 *
180 * If signature is incorrect and the requested link to the node is
181 * working, accept the new signature. (This is an instance of delayed
182 * rediscovery, where a link endpoint was able to re-establish contact
183 * with its peer endpoint on a node that rebooted before receiving a
184 * discovery message from that node.)
185 *
186 * If signature is incorrect and there is a working link to the node
187 * that is not the requested link, reject the request (must be from
188 * a duplicate node).
189 */
190 if (signature != n_ptr->signature) {
191 if (n_ptr->working_links == 0) {
192 struct tipc_link *curr_link;
193 int i;
194
195 for (i = 0; i < MAX_BEARERS; i++) {
196 curr_link = n_ptr->links[i];
197 if (curr_link) {
198 memset(&curr_link->media_addr, 0,
199 sizeof(media_addr));
200 tipc_link_reset(curr_link);
201 }
202 }
203 addr_mismatch = (link != NULL);
204 } else if (tipc_link_is_up(link) && !addr_mismatch) {
205 /* delayed rediscovery */
206 } else {
207 disc_dupl_alert(b_ptr, orig, &media_addr);
171 tipc_node_unlock(n_ptr); 208 tipc_node_unlock(n_ptr);
172 return; 209 return;
173 } 210 }
211 n_ptr->signature = signature;
174 } 212 }
175 213
176 /* 214 /*
@@ -183,17 +221,26 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
183 * the new media address and reset the link to ensure it starts up 221 * the new media address and reset the link to ensure it starts up
184 * cleanly. 222 * cleanly.
185 */ 223 */
186 addr = &link->media_addr; 224
187 if (memcmp(addr, &media_addr, sizeof(*addr))) { 225 if (addr_mismatch) {
188 if (tipc_link_is_up(link) || (!link->started)) { 226 if (tipc_link_is_up(link)) {
189 disc_dupl_alert(b_ptr, orig, &media_addr); 227 disc_dupl_alert(b_ptr, orig, &media_addr);
190 tipc_node_unlock(n_ptr); 228 tipc_node_unlock(n_ptr);
191 return; 229 return;
230 } else {
231 memcpy(&link->media_addr, &media_addr,
232 sizeof(media_addr));
233 tipc_link_reset(link);
234 }
235 }
236
237 /* Create a link endpoint for this bearer, if necessary */
238 if (!link) {
239 link = tipc_link_create(n_ptr, b_ptr, &media_addr);
240 if (!link) {
241 tipc_node_unlock(n_ptr);
242 return;
192 } 243 }
193 warn("Resetting link <%s>, peer interface address changed\n",
194 link->name);
195 memcpy(addr, &media_addr, sizeof(*addr));
196 tipc_link_reset(link);
197 } 244 }
198 245
199 /* Accept discovery message & send response, if necessary */ 246 /* Accept discovery message & send response, if necessary */
@@ -203,7 +250,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
203 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, orig, b_ptr); 250 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, orig, b_ptr);
204 if (rbuf) { 251 if (rbuf) {
205 b_ptr->media->send_msg(rbuf, b_ptr, &media_addr); 252 b_ptr->media->send_msg(rbuf, b_ptr, &media_addr);
206 buf_discard(rbuf); 253 kfree_skb(rbuf);
207 } 254 }
208 } 255 }
209 256
@@ -349,7 +396,7 @@ void tipc_disc_delete(struct tipc_link_req *req)
349{ 396{
350 k_cancel_timer(&req->timer); 397 k_cancel_timer(&req->timer);
351 k_term_timer(&req->timer); 398 k_term_timer(&req->timer);
352 buf_discard(req->buf); 399 kfree_skb(req->buf);
353 kfree(req); 400 kfree(req);
354} 401}
355 402
diff --git a/net/tipc/link.c b/net/tipc/link.c
index ac1832a66f8a..b4b9b30167a3 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -484,7 +484,7 @@ static void link_release_outqueue(struct tipc_link *l_ptr)
484 484
485 while (buf) { 485 while (buf) {
486 next = buf->next; 486 next = buf->next;
487 buf_discard(buf); 487 kfree_skb(buf);
488 buf = next; 488 buf = next;
489 } 489 }
490 l_ptr->first_out = NULL; 490 l_ptr->first_out = NULL;
@@ -503,7 +503,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr)
503 503
504 while (buf) { 504 while (buf) {
505 next = buf->next; 505 next = buf->next;
506 buf_discard(buf); 506 kfree_skb(buf);
507 buf = next; 507 buf = next;
508 } 508 }
509 l_ptr->defragm_buf = NULL; 509 l_ptr->defragm_buf = NULL;
@@ -522,20 +522,20 @@ void tipc_link_stop(struct tipc_link *l_ptr)
522 buf = l_ptr->oldest_deferred_in; 522 buf = l_ptr->oldest_deferred_in;
523 while (buf) { 523 while (buf) {
524 next = buf->next; 524 next = buf->next;
525 buf_discard(buf); 525 kfree_skb(buf);
526 buf = next; 526 buf = next;
527 } 527 }
528 528
529 buf = l_ptr->first_out; 529 buf = l_ptr->first_out;
530 while (buf) { 530 while (buf) {
531 next = buf->next; 531 next = buf->next;
532 buf_discard(buf); 532 kfree_skb(buf);
533 buf = next; 533 buf = next;
534 } 534 }
535 535
536 tipc_link_reset_fragments(l_ptr); 536 tipc_link_reset_fragments(l_ptr);
537 537
538 buf_discard(l_ptr->proto_msg_queue); 538 kfree_skb(l_ptr->proto_msg_queue);
539 l_ptr->proto_msg_queue = NULL; 539 l_ptr->proto_msg_queue = NULL;
540} 540}
541 541
@@ -571,12 +571,12 @@ void tipc_link_reset(struct tipc_link *l_ptr)
571 /* Clean up all queues: */ 571 /* Clean up all queues: */
572 572
573 link_release_outqueue(l_ptr); 573 link_release_outqueue(l_ptr);
574 buf_discard(l_ptr->proto_msg_queue); 574 kfree_skb(l_ptr->proto_msg_queue);
575 l_ptr->proto_msg_queue = NULL; 575 l_ptr->proto_msg_queue = NULL;
576 buf = l_ptr->oldest_deferred_in; 576 buf = l_ptr->oldest_deferred_in;
577 while (buf) { 577 while (buf) {
578 struct sk_buff *next = buf->next; 578 struct sk_buff *next = buf->next;
579 buf_discard(buf); 579 kfree_skb(buf);
580 buf = next; 580 buf = next;
581 } 581 }
582 if (!list_empty(&l_ptr->waiting_ports)) 582 if (!list_empty(&l_ptr->waiting_ports))
@@ -810,7 +810,7 @@ static int link_bundle_buf(struct tipc_link *l_ptr,
810 skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); 810 skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size);
811 msg_set_size(bundler_msg, to_pos + size); 811 msg_set_size(bundler_msg, to_pos + size);
812 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); 812 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1);
813 buf_discard(buf); 813 kfree_skb(buf);
814 l_ptr->stats.sent_bundled++; 814 l_ptr->stats.sent_bundled++;
815 return 1; 815 return 1;
816} 816}
@@ -871,17 +871,15 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
871 u32 queue_limit = l_ptr->queue_limit[imp]; 871 u32 queue_limit = l_ptr->queue_limit[imp];
872 u32 max_packet = l_ptr->max_pkt; 872 u32 max_packet = l_ptr->max_pkt;
873 873
874 msg_set_prevnode(msg, tipc_own_addr); /* If routed message */
875
876 /* Match msg importance against queue limits: */ 874 /* Match msg importance against queue limits: */
877 875
878 if (unlikely(queue_size >= queue_limit)) { 876 if (unlikely(queue_size >= queue_limit)) {
879 if (imp <= TIPC_CRITICAL_IMPORTANCE) { 877 if (imp <= TIPC_CRITICAL_IMPORTANCE) {
880 link_schedule_port(l_ptr, msg_origport(msg), size); 878 link_schedule_port(l_ptr, msg_origport(msg), size);
881 buf_discard(buf); 879 kfree_skb(buf);
882 return -ELINKCONG; 880 return -ELINKCONG;
883 } 881 }
884 buf_discard(buf); 882 kfree_skb(buf);
885 if (imp > CONN_MANAGER) { 883 if (imp > CONN_MANAGER) {
886 warn("Resetting link <%s>, send queue full", l_ptr->name); 884 warn("Resetting link <%s>, send queue full", l_ptr->name);
887 tipc_link_reset(l_ptr); 885 tipc_link_reset(l_ptr);
@@ -968,10 +966,10 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
968 if (l_ptr) 966 if (l_ptr)
969 res = tipc_link_send_buf(l_ptr, buf); 967 res = tipc_link_send_buf(l_ptr, buf);
970 else 968 else
971 buf_discard(buf); 969 kfree_skb(buf);
972 tipc_node_unlock(n_ptr); 970 tipc_node_unlock(n_ptr);
973 } else { 971 } else {
974 buf_discard(buf); 972 kfree_skb(buf);
975 } 973 }
976 read_unlock_bh(&tipc_net_lock); 974 read_unlock_bh(&tipc_net_lock);
977 return res; 975 return res;
@@ -1018,7 +1016,7 @@ void tipc_link_send_names(struct list_head *message_list, u32 dest)
1018 1016
1019 list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) { 1017 list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) {
1020 list_del((struct list_head *)buf); 1018 list_del((struct list_head *)buf);
1021 buf_discard(buf); 1019 kfree_skb(buf);
1022 } 1020 }
1023} 1021}
1024 1022
@@ -1262,7 +1260,7 @@ again:
1262error: 1260error:
1263 for (; buf_chain; buf_chain = buf) { 1261 for (; buf_chain; buf_chain = buf) {
1264 buf = buf_chain->next; 1262 buf = buf_chain->next;
1265 buf_discard(buf_chain); 1263 kfree_skb(buf_chain);
1266 } 1264 }
1267 return -EFAULT; 1265 return -EFAULT;
1268 } 1266 }
@@ -1316,7 +1314,7 @@ error:
1316 tipc_node_unlock(node); 1314 tipc_node_unlock(node);
1317 for (; buf_chain; buf_chain = buf) { 1315 for (; buf_chain; buf_chain = buf) {
1318 buf = buf_chain->next; 1316 buf = buf_chain->next;
1319 buf_discard(buf_chain); 1317 kfree_skb(buf_chain);
1320 } 1318 }
1321 goto again; 1319 goto again;
1322 } 1320 }
@@ -1324,7 +1322,7 @@ error:
1324reject: 1322reject:
1325 for (; buf_chain; buf_chain = buf) { 1323 for (; buf_chain; buf_chain = buf) {
1326 buf = buf_chain->next; 1324 buf = buf_chain->next;
1327 buf_discard(buf_chain); 1325 kfree_skb(buf_chain);
1328 } 1326 }
1329 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1327 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
1330 total_len, TIPC_ERR_NO_NODE); 1328 total_len, TIPC_ERR_NO_NODE);
@@ -1390,7 +1388,7 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr)
1390 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); 1388 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
1391 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1389 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1392 l_ptr->unacked_window = 0; 1390 l_ptr->unacked_window = 0;
1393 buf_discard(buf); 1391 kfree_skb(buf);
1394 l_ptr->proto_msg_queue = NULL; 1392 l_ptr->proto_msg_queue = NULL;
1395 return 0; 1393 return 0;
1396 } else { 1394 } else {
@@ -1501,13 +1499,13 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
1501 tipc_node_lock(n_ptr); 1499 tipc_node_lock(n_ptr);
1502 1500
1503 tipc_addr_string_fill(addr_string, n_ptr->addr); 1501 tipc_addr_string_fill(addr_string, n_ptr->addr);
1504 info("Multicast link info for %s\n", addr_string); 1502 info("Broadcast link info for %s\n", addr_string);
1503 info("Supportable: %d, ", n_ptr->bclink.supportable);
1505 info("Supported: %d, ", n_ptr->bclink.supported); 1504 info("Supported: %d, ", n_ptr->bclink.supported);
1506 info("Acked: %u\n", n_ptr->bclink.acked); 1505 info("Acked: %u\n", n_ptr->bclink.acked);
1507 info("Last in: %u, ", n_ptr->bclink.last_in); 1506 info("Last in: %u, ", n_ptr->bclink.last_in);
1508 info("Gap after: %u, ", n_ptr->bclink.gap_after); 1507 info("Oos state: %u, ", n_ptr->bclink.oos_state);
1509 info("Gap to: %u\n", n_ptr->bclink.gap_to); 1508 info("Last sent: %u\n", n_ptr->bclink.last_sent);
1510 info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync);
1511 1509
1512 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); 1510 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
1513 1511
@@ -1679,7 +1677,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1679 1677
1680 /* Ensure message data is a single contiguous unit */ 1678 /* Ensure message data is a single contiguous unit */
1681 1679
1682 if (unlikely(buf_linearize(buf))) 1680 if (unlikely(skb_linearize(buf)))
1683 goto cont; 1681 goto cont;
1684 1682
1685 /* Handle arrival of a non-unicast link message */ 1683 /* Handle arrival of a non-unicast link message */
@@ -1736,7 +1734,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1736 1734
1737 /* Release acked messages */ 1735 /* Release acked messages */
1738 1736
1739 if (tipc_node_is_up(n_ptr) && n_ptr->bclink.supported) 1737 if (n_ptr->bclink.supported)
1740 tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); 1738 tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
1741 1739
1742 crs = l_ptr->first_out; 1740 crs = l_ptr->first_out;
@@ -1744,7 +1742,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1744 less_eq(buf_seqno(crs), ackd)) { 1742 less_eq(buf_seqno(crs), ackd)) {
1745 struct sk_buff *next = crs->next; 1743 struct sk_buff *next = crs->next;
1746 1744
1747 buf_discard(crs); 1745 kfree_skb(crs);
1748 crs = next; 1746 crs = next;
1749 released++; 1747 released++;
1750 } 1748 }
@@ -1773,52 +1771,56 @@ protocol_check:
1773 if (unlikely(l_ptr->oldest_deferred_in)) 1771 if (unlikely(l_ptr->oldest_deferred_in))
1774 head = link_insert_deferred_queue(l_ptr, 1772 head = link_insert_deferred_queue(l_ptr,
1775 head); 1773 head);
1776 if (likely(msg_is_dest(msg, tipc_own_addr))) {
1777deliver: 1774deliver:
1778 if (likely(msg_isdata(msg))) { 1775 if (likely(msg_isdata(msg))) {
1779 tipc_node_unlock(n_ptr); 1776 tipc_node_unlock(n_ptr);
1780 tipc_port_recv_msg(buf); 1777 tipc_port_recv_msg(buf);
1781 continue; 1778 continue;
1779 }
1780 switch (msg_user(msg)) {
1781 int ret;
1782 case MSG_BUNDLER:
1783 l_ptr->stats.recv_bundles++;
1784 l_ptr->stats.recv_bundled +=
1785 msg_msgcnt(msg);
1786 tipc_node_unlock(n_ptr);
1787 tipc_link_recv_bundle(buf);
1788 continue;
1789 case NAME_DISTRIBUTOR:
1790 tipc_node_unlock(n_ptr);
1791 tipc_named_recv(buf);
1792 continue;
1793 case CONN_MANAGER:
1794 tipc_node_unlock(n_ptr);
1795 tipc_port_recv_proto_msg(buf);
1796 continue;
1797 case MSG_FRAGMENTER:
1798 l_ptr->stats.recv_fragments++;
1799 ret = tipc_link_recv_fragment(
1800 &l_ptr->defragm_buf,
1801 &buf, &msg);
1802 if (ret == 1) {
1803 l_ptr->stats.recv_fragmented++;
1804 goto deliver;
1782 } 1805 }
1783 switch (msg_user(msg)) { 1806 if (ret == -1)
1784 case MSG_BUNDLER: 1807 l_ptr->next_in_no--;
1785 l_ptr->stats.recv_bundles++; 1808 break;
1786 l_ptr->stats.recv_bundled += 1809 case CHANGEOVER_PROTOCOL:
1787 msg_msgcnt(msg); 1810 type = msg_type(msg);
1788 tipc_node_unlock(n_ptr); 1811 if (link_recv_changeover_msg(&l_ptr,
1789 tipc_link_recv_bundle(buf); 1812 &buf)) {
1790 continue; 1813 msg = buf_msg(buf);
1791 case NAME_DISTRIBUTOR: 1814 seq_no = msg_seqno(msg);
1792 tipc_node_unlock(n_ptr); 1815 if (type == ORIGINAL_MSG)
1793 tipc_named_recv(buf);
1794 continue;
1795 case CONN_MANAGER:
1796 tipc_node_unlock(n_ptr);
1797 tipc_port_recv_proto_msg(buf);
1798 continue;
1799 case MSG_FRAGMENTER:
1800 l_ptr->stats.recv_fragments++;
1801 if (tipc_link_recv_fragment(&l_ptr->defragm_buf,
1802 &buf, &msg)) {
1803 l_ptr->stats.recv_fragmented++;
1804 goto deliver; 1816 goto deliver;
1805 } 1817 goto protocol_check;
1806 break;
1807 case CHANGEOVER_PROTOCOL:
1808 type = msg_type(msg);
1809 if (link_recv_changeover_msg(&l_ptr, &buf)) {
1810 msg = buf_msg(buf);
1811 seq_no = msg_seqno(msg);
1812 if (type == ORIGINAL_MSG)
1813 goto deliver;
1814 goto protocol_check;
1815 }
1816 break;
1817 default:
1818 buf_discard(buf);
1819 buf = NULL;
1820 break;
1821 } 1818 }
1819 break;
1820 default:
1821 kfree_skb(buf);
1822 buf = NULL;
1823 break;
1822 } 1824 }
1823 tipc_node_unlock(n_ptr); 1825 tipc_node_unlock(n_ptr);
1824 tipc_net_route_msg(buf); 1826 tipc_net_route_msg(buf);
@@ -1847,23 +1849,22 @@ deliver:
1847 } 1849 }
1848 tipc_node_unlock(n_ptr); 1850 tipc_node_unlock(n_ptr);
1849cont: 1851cont:
1850 buf_discard(buf); 1852 kfree_skb(buf);
1851 } 1853 }
1852 read_unlock_bh(&tipc_net_lock); 1854 read_unlock_bh(&tipc_net_lock);
1853} 1855}
1854 1856
1855/* 1857/*
1856 * link_defer_buf(): Sort a received out-of-sequence packet 1858 * tipc_link_defer_pkt - Add out-of-sequence message to deferred reception queue
1857 * into the deferred reception queue. 1859 *
1858 * Returns the increase of the queue length,i.e. 0 or 1 1860 * Returns increase in queue length (i.e. 0 or 1)
1859 */ 1861 */
1860 1862
1861u32 tipc_link_defer_pkt(struct sk_buff **head, 1863u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
1862 struct sk_buff **tail,
1863 struct sk_buff *buf) 1864 struct sk_buff *buf)
1864{ 1865{
1865 struct sk_buff *prev = NULL; 1866 struct sk_buff *queue_buf;
1866 struct sk_buff *crs = *head; 1867 struct sk_buff **prev;
1867 u32 seq_no = buf_seqno(buf); 1868 u32 seq_no = buf_seqno(buf);
1868 1869
1869 buf->next = NULL; 1870 buf->next = NULL;
@@ -1881,31 +1882,30 @@ u32 tipc_link_defer_pkt(struct sk_buff **head,
1881 return 1; 1882 return 1;
1882 } 1883 }
1883 1884
1884 /* Scan through queue and sort it in */ 1885 /* Locate insertion point in queue, then insert; discard if duplicate */
1885 do { 1886 prev = head;
1886 struct tipc_msg *msg = buf_msg(crs); 1887 queue_buf = *head;
1888 for (;;) {
1889 u32 curr_seqno = buf_seqno(queue_buf);
1887 1890
1888 if (less(seq_no, msg_seqno(msg))) { 1891 if (seq_no == curr_seqno) {
1889 buf->next = crs; 1892 kfree_skb(buf);
1890 if (prev) 1893 return 0;
1891 prev->next = buf;
1892 else
1893 *head = buf;
1894 return 1;
1895 } 1894 }
1896 if (seq_no == msg_seqno(msg)) 1895
1896 if (less(seq_no, curr_seqno))
1897 break; 1897 break;
1898 prev = crs;
1899 crs = crs->next;
1900 } while (crs);
1901 1898
1902 /* Message is a duplicate of an existing message */ 1899 prev = &queue_buf->next;
1900 queue_buf = queue_buf->next;
1901 }
1903 1902
1904 buf_discard(buf); 1903 buf->next = queue_buf;
1905 return 0; 1904 *prev = buf;
1905 return 1;
1906} 1906}
1907 1907
1908/** 1908/*
1909 * link_handle_out_of_seq_msg - handle arrival of out-of-sequence packet 1909 * link_handle_out_of_seq_msg - handle arrival of out-of-sequence packet
1910 */ 1910 */
1911 1911
@@ -1930,7 +1930,7 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
1930 1930
1931 if (less(seq_no, mod(l_ptr->next_in_no))) { 1931 if (less(seq_no, mod(l_ptr->next_in_no))) {
1932 l_ptr->stats.duplicates++; 1932 l_ptr->stats.duplicates++;
1933 buf_discard(buf); 1933 kfree_skb(buf);
1934 return; 1934 return;
1935 } 1935 }
1936 1936
@@ -1956,6 +1956,13 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
1956 u32 msg_size = sizeof(l_ptr->proto_msg); 1956 u32 msg_size = sizeof(l_ptr->proto_msg);
1957 int r_flag; 1957 int r_flag;
1958 1958
1959 /* Discard any previous message that was deferred due to congestion */
1960
1961 if (l_ptr->proto_msg_queue) {
1962 kfree_skb(l_ptr->proto_msg_queue);
1963 l_ptr->proto_msg_queue = NULL;
1964 }
1965
1959 if (link_blocked(l_ptr)) 1966 if (link_blocked(l_ptr))
1960 return; 1967 return;
1961 1968
@@ -1964,9 +1971,11 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
1964 if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG)) 1971 if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG))
1965 return; 1972 return;
1966 1973
1974 /* Create protocol message with "out-of-sequence" sequence number */
1975
1967 msg_set_type(msg, msg_typ); 1976 msg_set_type(msg, msg_typ);
1968 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane); 1977 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);
1969 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in)); 1978 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
1970 msg_set_last_bcast(msg, tipc_bclink_get_last_sent()); 1979 msg_set_last_bcast(msg, tipc_bclink_get_last_sent());
1971 1980
1972 if (msg_typ == STATE_MSG) { 1981 if (msg_typ == STATE_MSG) {
@@ -2020,44 +2029,36 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
2020 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr)); 2029 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr));
2021 msg_set_redundant_link(msg, r_flag); 2030 msg_set_redundant_link(msg, r_flag);
2022 msg_set_linkprio(msg, l_ptr->priority); 2031 msg_set_linkprio(msg, l_ptr->priority);
2023 2032 msg_set_size(msg, msg_size);
2024 /* Ensure sequence number will not fit : */
2025 2033
2026 msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2))); 2034 msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2)));
2027 2035
2028 /* Congestion? */
2029
2030 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
2031 if (!l_ptr->proto_msg_queue) {
2032 l_ptr->proto_msg_queue =
2033 tipc_buf_acquire(sizeof(l_ptr->proto_msg));
2034 }
2035 buf = l_ptr->proto_msg_queue;
2036 if (!buf)
2037 return;
2038 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
2039 return;
2040 }
2041
2042 /* Message can be sent */
2043
2044 buf = tipc_buf_acquire(msg_size); 2036 buf = tipc_buf_acquire(msg_size);
2045 if (!buf) 2037 if (!buf)
2046 return; 2038 return;
2047 2039
2048 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); 2040 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
2049 msg_set_size(buf_msg(buf), msg_size);
2050 2041
2051 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 2042 /* Defer message if bearer is already congested */
2052 l_ptr->unacked_window = 0; 2043
2053 buf_discard(buf); 2044 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
2045 l_ptr->proto_msg_queue = buf;
2054 return; 2046 return;
2055 } 2047 }
2056 2048
2057 /* New congestion */ 2049 /* Defer message if attempting to send results in bearer congestion */
2058 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); 2050
2059 l_ptr->proto_msg_queue = buf; 2051 if (!tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
2060 l_ptr->stats.bearer_congs++; 2052 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
2053 l_ptr->proto_msg_queue = buf;
2054 l_ptr->stats.bearer_congs++;
2055 return;
2056 }
2057
2058 /* Discard message if it was sent successfully */
2059
2060 l_ptr->unacked_window = 0;
2061 kfree_skb(buf);
2061} 2062}
2062 2063
2063/* 2064/*
@@ -2105,6 +2106,8 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
2105 l_ptr->owner->block_setup = WAIT_NODE_DOWN; 2106 l_ptr->owner->block_setup = WAIT_NODE_DOWN;
2106 } 2107 }
2107 2108
2109 link_state_event(l_ptr, RESET_MSG);
2110
2108 /* fall thru' */ 2111 /* fall thru' */
2109 case ACTIVATE_MSG: 2112 case ACTIVATE_MSG:
2110 /* Update link settings according other endpoint's values */ 2113 /* Update link settings according other endpoint's values */
@@ -2127,16 +2130,22 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
2127 } else { 2130 } else {
2128 l_ptr->max_pkt = l_ptr->max_pkt_target; 2131 l_ptr->max_pkt = l_ptr->max_pkt_target;
2129 } 2132 }
2130 l_ptr->owner->bclink.supported = (max_pkt_info != 0); 2133 l_ptr->owner->bclink.supportable = (max_pkt_info != 0);
2131 2134
2132 link_state_event(l_ptr, msg_type(msg)); 2135 /* Synchronize broadcast link info, if not done previously */
2136
2137 if (!tipc_node_is_up(l_ptr->owner)) {
2138 l_ptr->owner->bclink.last_sent =
2139 l_ptr->owner->bclink.last_in =
2140 msg_last_bcast(msg);
2141 l_ptr->owner->bclink.oos_state = 0;
2142 }
2133 2143
2134 l_ptr->peer_session = msg_session(msg); 2144 l_ptr->peer_session = msg_session(msg);
2135 l_ptr->peer_bearer_id = msg_bearer_id(msg); 2145 l_ptr->peer_bearer_id = msg_bearer_id(msg);
2136 2146
2137 /* Synchronize broadcast sequence numbers */ 2147 if (msg_type(msg) == ACTIVATE_MSG)
2138 if (!tipc_node_redundant_links(l_ptr->owner)) 2148 link_state_event(l_ptr, ACTIVATE_MSG);
2139 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
2140 break; 2149 break;
2141 case STATE_MSG: 2150 case STATE_MSG:
2142 2151
@@ -2177,7 +2186,9 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
2177 2186
2178 /* Protocol message before retransmits, reduce loss risk */ 2187 /* Protocol message before retransmits, reduce loss risk */
2179 2188
2180 tipc_bclink_check_gap(l_ptr->owner, msg_last_bcast(msg)); 2189 if (l_ptr->owner->bclink.supported)
2190 tipc_bclink_update_link_state(l_ptr->owner,
2191 msg_last_bcast(msg));
2181 2192
2182 if (rec_gap || (msg_probe(msg))) { 2193 if (rec_gap || (msg_probe(msg))) {
2183 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 2194 tipc_link_send_proto_msg(l_ptr, STATE_MSG,
@@ -2191,7 +2202,7 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
2191 break; 2202 break;
2192 } 2203 }
2193exit: 2204exit:
2194 buf_discard(buf); 2205 kfree_skb(buf);
2195} 2206}
2196 2207
2197 2208
@@ -2389,7 +2400,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
2389 warn("Link changeover error, duplicate msg dropped\n"); 2400 warn("Link changeover error, duplicate msg dropped\n");
2390 goto exit; 2401 goto exit;
2391 } 2402 }
2392 buf_discard(tunnel_buf); 2403 kfree_skb(tunnel_buf);
2393 return 1; 2404 return 1;
2394 } 2405 }
2395 2406
@@ -2421,7 +2432,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
2421 } else { 2432 } else {
2422 *buf = buf_extract(tunnel_buf, INT_H_SIZE); 2433 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2423 if (*buf != NULL) { 2434 if (*buf != NULL) {
2424 buf_discard(tunnel_buf); 2435 kfree_skb(tunnel_buf);
2425 return 1; 2436 return 1;
2426 } else { 2437 } else {
2427 warn("Link changeover error, original msg dropped\n"); 2438 warn("Link changeover error, original msg dropped\n");
@@ -2429,7 +2440,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
2429 } 2440 }
2430exit: 2441exit:
2431 *buf = NULL; 2442 *buf = NULL;
2432 buf_discard(tunnel_buf); 2443 kfree_skb(tunnel_buf);
2433 return 0; 2444 return 0;
2434} 2445}
2435 2446
@@ -2451,7 +2462,7 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2451 pos += align(msg_size(buf_msg(obuf))); 2462 pos += align(msg_size(buf_msg(obuf)));
2452 tipc_net_route_msg(obuf); 2463 tipc_net_route_msg(obuf);
2453 } 2464 }
2454 buf_discard(buf); 2465 kfree_skb(buf);
2455} 2466}
2456 2467
2457/* 2468/*
@@ -2500,11 +2511,11 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
2500 } 2511 }
2501 fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); 2512 fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
2502 if (fragm == NULL) { 2513 if (fragm == NULL) {
2503 buf_discard(buf); 2514 kfree_skb(buf);
2504 while (buf_chain) { 2515 while (buf_chain) {
2505 buf = buf_chain; 2516 buf = buf_chain;
2506 buf_chain = buf_chain->next; 2517 buf_chain = buf_chain->next;
2507 buf_discard(buf); 2518 kfree_skb(buf);
2508 } 2519 }
2509 return -ENOMEM; 2520 return -ENOMEM;
2510 } 2521 }
@@ -2521,7 +2532,7 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
2521 crs += fragm_sz; 2532 crs += fragm_sz;
2522 msg_set_type(&fragm_hdr, FRAGMENT); 2533 msg_set_type(&fragm_hdr, FRAGMENT);
2523 } 2534 }
2524 buf_discard(buf); 2535 kfree_skb(buf);
2525 2536
2526 /* Append chain of fragments to send queue & send them */ 2537 /* Append chain of fragments to send queue & send them */
2527 2538
@@ -2608,7 +2619,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2608 if (msg_type(imsg) == TIPC_MCAST_MSG) 2619 if (msg_type(imsg) == TIPC_MCAST_MSG)
2609 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; 2620 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
2610 if (msg_size(imsg) > max) { 2621 if (msg_size(imsg) > max) {
2611 buf_discard(fbuf); 2622 kfree_skb(fbuf);
2612 return 0; 2623 return 0;
2613 } 2624 }
2614 pbuf = tipc_buf_acquire(msg_size(imsg)); 2625 pbuf = tipc_buf_acquire(msg_size(imsg));
@@ -2623,9 +2634,11 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2623 set_fragm_size(pbuf, fragm_sz); 2634 set_fragm_size(pbuf, fragm_sz);
2624 set_expected_frags(pbuf, exp_fragm_cnt - 1); 2635 set_expected_frags(pbuf, exp_fragm_cnt - 1);
2625 } else { 2636 } else {
2626 warn("Link unable to reassemble fragmented message\n"); 2637 dbg("Link unable to reassemble fragmented message\n");
2638 kfree_skb(fbuf);
2639 return -1;
2627 } 2640 }
2628 buf_discard(fbuf); 2641 kfree_skb(fbuf);
2629 return 0; 2642 return 0;
2630 } else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) { 2643 } else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) {
2631 u32 dsz = msg_data_sz(fragm); 2644 u32 dsz = msg_data_sz(fragm);
@@ -2634,7 +2647,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2634 u32 exp_frags = get_expected_frags(pbuf) - 1; 2647 u32 exp_frags = get_expected_frags(pbuf) - 1;
2635 skb_copy_to_linear_data_offset(pbuf, crs, 2648 skb_copy_to_linear_data_offset(pbuf, crs,
2636 msg_data(fragm), dsz); 2649 msg_data(fragm), dsz);
2637 buf_discard(fbuf); 2650 kfree_skb(fbuf);
2638 2651
2639 /* Is message complete? */ 2652 /* Is message complete? */
2640 2653
@@ -2651,7 +2664,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2651 set_expected_frags(pbuf, exp_frags); 2664 set_expected_frags(pbuf, exp_frags);
2652 return 0; 2665 return 0;
2653 } 2666 }
2654 buf_discard(fbuf); 2667 kfree_skb(fbuf);
2655 return 0; 2668 return 0;
2656} 2669}
2657 2670
@@ -2682,7 +2695,7 @@ static void link_check_defragm_bufs(struct tipc_link *l_ptr)
2682 prev->next = buf->next; 2695 prev->next = buf->next;
2683 else 2696 else
2684 l_ptr->defragm_buf = buf->next; 2697 l_ptr->defragm_buf = buf->next;
2685 buf_discard(buf); 2698 kfree_skb(buf);
2686 } 2699 }
2687 buf = next; 2700 buf = next;
2688 } 2701 }
@@ -3057,7 +3070,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s
3057 str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area), 3070 str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area),
3058 (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO); 3071 (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO);
3059 if (!str_len) { 3072 if (!str_len) {
3060 buf_discard(buf); 3073 kfree_skb(buf);
3061 return tipc_cfg_reply_error_string("link not found"); 3074 return tipc_cfg_reply_error_string("link not found");
3062 } 3075 }
3063 3076
diff --git a/net/tipc/log.c b/net/tipc/log.c
index 952c39f643e6..895c6e530b0b 100644
--- a/net/tipc/log.c
+++ b/net/tipc/log.c
@@ -304,7 +304,7 @@ struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space)
304 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 304 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
305 305
306 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 306 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
307 if (value != delimit(value, 0, 32768)) 307 if (value > 32768)
308 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 308 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
309 " (log size must be 0-32768)"); 309 " (log size must be 0-32768)");
310 if (tipc_log_resize(value)) 310 if (tipc_log_resize(value))
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 3e4d3e29be61..e3afe162c0ac 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -106,7 +106,7 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
106 if (likely(res)) 106 if (likely(res))
107 return dsz; 107 return dsz;
108 108
109 buf_discard(*buf); 109 kfree_skb(*buf);
110 *buf = NULL; 110 *buf = NULL;
111 return -EFAULT; 111 return -EFAULT;
112} 112}
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 7b0cda167107..eba524e34a6b 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -384,11 +384,6 @@ static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
384 msg_set_word(m, 7, a); 384 msg_set_word(m, 7, a);
385} 385}
386 386
387static inline int msg_is_dest(struct tipc_msg *m, u32 d)
388{
389 return msg_short(m) || (msg_destnode(m) == d);
390}
391
392static inline u32 msg_nametype(struct tipc_msg *m) 387static inline u32 msg_nametype(struct tipc_msg *m)
393{ 388{
394 return msg_word(m, 8); 389 return msg_word(m, 8);
@@ -517,6 +512,16 @@ static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
517 msg_set_bits(m, 1, 16, 0x1fff, n); 512 msg_set_bits(m, 1, 16, 0x1fff, n);
518} 513}
519 514
515static inline u32 msg_node_sig(struct tipc_msg *m)
516{
517 return msg_bits(m, 1, 0, 0xffff);
518}
519
520static inline void msg_set_node_sig(struct tipc_msg *m, u32 n)
521{
522 msg_set_bits(m, 1, 0, 0xffff, n);
523}
524
520 525
521/* 526/*
522 * Word 2 527 * Word 2
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 98ebb37f1808..d57da6159616 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -120,7 +120,7 @@ static void named_cluster_distribute(struct sk_buff *buf)
120 } 120 }
121 } 121 }
122 122
123 buf_discard(buf); 123 kfree_skb(buf);
124} 124}
125 125
126/** 126/**
@@ -239,9 +239,6 @@ exit:
239 * 239 *
240 * Invoked for each publication issued by a newly failed node. 240 * Invoked for each publication issued by a newly failed node.
241 * Removes publication structure from name table & deletes it. 241 * Removes publication structure from name table & deletes it.
242 * In rare cases the link may have come back up again when this
243 * function is called, and we have two items representing the same
244 * publication. Nudge this item's key to distinguish it from the other.
245 */ 242 */
246 243
247static void named_purge_publ(struct publication *publ) 244static void named_purge_publ(struct publication *publ)
@@ -249,7 +246,6 @@ static void named_purge_publ(struct publication *publ)
249 struct publication *p; 246 struct publication *p;
250 247
251 write_lock_bh(&tipc_nametbl_lock); 248 write_lock_bh(&tipc_nametbl_lock);
252 publ->key += 1222345;
253 p = tipc_nametbl_remove_publ(publ->type, publ->lower, 249 p = tipc_nametbl_remove_publ(publ->type, publ->lower,
254 publ->node, publ->ref, publ->key); 250 publ->node, publ->ref, publ->key);
255 if (p) 251 if (p)
@@ -316,7 +312,7 @@ void tipc_named_recv(struct sk_buff *buf)
316 item++; 312 item++;
317 } 313 }
318 write_unlock_bh(&tipc_nametbl_lock); 314 write_unlock_bh(&tipc_nametbl_lock);
319 buf_discard(buf); 315 kfree_skb(buf);
320} 316}
321 317
322/** 318/**
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 89eb5621ebba..c6a1ae36952e 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -114,10 +114,8 @@ struct name_table {
114}; 114};
115 115
116static struct name_table table; 116static struct name_table table;
117static atomic_t rsv_publ_ok = ATOMIC_INIT(0);
118DEFINE_RWLOCK(tipc_nametbl_lock); 117DEFINE_RWLOCK(tipc_nametbl_lock);
119 118
120
121static int hash(int x) 119static int hash(int x)
122{ 120{
123 return x & (tipc_nametbl_size - 1); 121 return x & (tipc_nametbl_size - 1);
@@ -270,6 +268,13 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
270 } 268 }
271 269
272 info = sseq->info; 270 info = sseq->info;
271
272 /* Check if an identical publication already exists */
273 list_for_each_entry(publ, &info->zone_list, zone_list) {
274 if ((publ->ref == port) && (publ->key == key) &&
275 (!publ->node || (publ->node == node)))
276 return NULL;
277 }
273 } else { 278 } else {
274 u32 inspos; 279 u32 inspos;
275 struct sub_seq *freesseq; 280 struct sub_seq *freesseq;
@@ -534,10 +539,17 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
534} 539}
535 540
536/* 541/*
537 * tipc_nametbl_translate - translate name to port id 542 * tipc_nametbl_translate - perform name translation
543 *
544 * On entry, 'destnode' is the search domain used during translation.
538 * 545 *
539 * Note: on entry 'destnode' is the search domain used during translation; 546 * On exit:
540 * on exit it passes back the node address of the matching port (if any) 547 * - if name translation is deferred to another node/cluster/zone,
548 * leaves 'destnode' unchanged (will be non-zero) and returns 0
549 * - if name translation is attempted and succeeds, sets 'destnode'
550 * to publishing node and returns port reference (will be non-zero)
551 * - if name translation is attempted and fails, sets 'destnode' to 0
552 * and returns 0
541 */ 553 */
542 554
543u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) 555u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
@@ -547,6 +559,7 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
547 struct publication *publ; 559 struct publication *publ;
548 struct name_seq *seq; 560 struct name_seq *seq;
549 u32 ref = 0; 561 u32 ref = 0;
562 u32 node = 0;
550 563
551 if (!tipc_in_scope(*destnode, tipc_own_addr)) 564 if (!tipc_in_scope(*destnode, tipc_own_addr))
552 return 0; 565 return 0;
@@ -604,11 +617,12 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
604 } 617 }
605 618
606 ref = publ->ref; 619 ref = publ->ref;
607 *destnode = publ->node; 620 node = publ->node;
608no_match: 621no_match:
609 spin_unlock_bh(&seq->lock); 622 spin_unlock_bh(&seq->lock);
610not_found: 623not_found:
611 read_unlock_bh(&tipc_nametbl_lock); 624 read_unlock_bh(&tipc_nametbl_lock);
625 *destnode = node;
612 return ref; 626 return ref;
613} 627}
614 628
@@ -665,22 +679,7 @@ exit:
665 return res; 679 return res;
666} 680}
667 681
668/** 682/*
669 * tipc_nametbl_publish_rsv - publish port name using a reserved name type
670 */
671
672int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope,
673 struct tipc_name_seq const *seq)
674{
675 int res;
676
677 atomic_inc(&rsv_publ_ok);
678 res = tipc_publish(ref, scope, seq);
679 atomic_dec(&rsv_publ_ok);
680 return res;
681}
682
683/**
684 * tipc_nametbl_publish - add name publication to network name tables 683 * tipc_nametbl_publish - add name publication to network name tables
685 */ 684 */
686 685
@@ -694,11 +693,6 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
694 tipc_max_publications); 693 tipc_max_publications);
695 return NULL; 694 return NULL;
696 } 695 }
697 if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) {
698 warn("Publication failed, reserved name {%u,%u,%u}\n",
699 type, lower, upper);
700 return NULL;
701 }
702 696
703 write_lock_bh(&tipc_nametbl_lock); 697 write_lock_bh(&tipc_nametbl_lock);
704 table.local_publ_count++; 698 table.local_publ_count++;
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 8086b42f92ad..207d59ebf849 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -91,8 +91,6 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space);
91u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node); 91u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node);
92int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, 92int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
93 struct tipc_port_list *dports); 93 struct tipc_port_list *dports);
94int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope,
95 struct tipc_name_seq const *seq);
96struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, 94struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
97 u32 scope, u32 port_ref, u32 key); 95 u32 scope, u32 port_ref, u32 key);
98int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key); 96int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key);
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 61afee7e8291..d4531b07076c 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -117,7 +117,7 @@ static void net_route_named_msg(struct sk_buff *buf)
117 u32 dport; 117 u32 dport;
118 118
119 if (!msg_named(msg)) { 119 if (!msg_named(msg)) {
120 buf_discard(buf); 120 kfree_skb(buf);
121 return; 121 return;
122 } 122 }
123 123
@@ -161,7 +161,7 @@ void tipc_net_route_msg(struct sk_buff *buf)
161 tipc_port_recv_proto_msg(buf); 161 tipc_port_recv_proto_msg(buf);
162 break; 162 break;
163 default: 163 default:
164 buf_discard(buf); 164 kfree_skb(buf);
165 } 165 }
166 return; 166 return;
167 } 167 }
@@ -175,14 +175,10 @@ int tipc_net_start(u32 addr)
175{ 175{
176 char addr_string[16]; 176 char addr_string[16];
177 177
178 if (tipc_mode != TIPC_NODE_MODE)
179 return -ENOPROTOOPT;
180
181 tipc_subscr_stop(); 178 tipc_subscr_stop();
182 tipc_cfg_stop(); 179 tipc_cfg_stop();
183 180
184 tipc_own_addr = addr; 181 tipc_own_addr = addr;
185 tipc_mode = TIPC_NET_MODE;
186 tipc_named_reinit(); 182 tipc_named_reinit();
187 tipc_port_reinit(); 183 tipc_port_reinit();
188 184
@@ -201,10 +197,9 @@ void tipc_net_stop(void)
201{ 197{
202 struct tipc_node *node, *t_node; 198 struct tipc_node *node, *t_node;
203 199
204 if (tipc_mode != TIPC_NET_MODE) 200 if (!tipc_own_addr)
205 return; 201 return;
206 write_lock_bh(&tipc_net_lock); 202 write_lock_bh(&tipc_net_lock);
207 tipc_mode = TIPC_NODE_MODE;
208 tipc_bearer_stop(); 203 tipc_bearer_stop();
209 tipc_bclink_stop(); 204 tipc_bclink_stop();
210 list_for_each_entry_safe(node, t_node, &tipc_node_list, list) 205 list_for_each_entry_safe(node, t_node, &tipc_node_list, list)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 6b226faad89f..a34cabc2c43a 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -39,6 +39,8 @@
39#include "node.h" 39#include "node.h"
40#include "name_distr.h" 40#include "name_distr.h"
41 41
42#define NODE_HTABLE_SIZE 512
43
42static void node_lost_contact(struct tipc_node *n_ptr); 44static void node_lost_contact(struct tipc_node *n_ptr);
43static void node_established_contact(struct tipc_node *n_ptr); 45static void node_established_contact(struct tipc_node *n_ptr);
44 46
@@ -49,9 +51,19 @@ LIST_HEAD(tipc_node_list);
49static u32 tipc_num_nodes; 51static u32 tipc_num_nodes;
50 52
51static atomic_t tipc_num_links = ATOMIC_INIT(0); 53static atomic_t tipc_num_links = ATOMIC_INIT(0);
52u32 tipc_own_tag;
53 54
54/** 55/*
56 * A trivial power-of-two bitmask technique is used for speed, since this
57 * operation is done for every incoming TIPC packet. The number of hash table
58 * entries has been chosen so that no hash chain exceeds 8 nodes and will
59 * usually be much smaller (typically only a single node).
60 */
61static inline unsigned int tipc_hashfn(u32 addr)
62{
63 return addr & (NODE_HTABLE_SIZE - 1);
64}
65
66/*
55 * tipc_node_find - locate specified node object, if it exists 67 * tipc_node_find - locate specified node object, if it exists
56 */ 68 */
57 69
@@ -113,6 +125,7 @@ struct tipc_node *tipc_node_create(u32 addr)
113 } 125 }
114 list_add_tail(&n_ptr->list, &temp_node->list); 126 list_add_tail(&n_ptr->list, &temp_node->list);
115 n_ptr->block_setup = WAIT_PEER_DOWN; 127 n_ptr->block_setup = WAIT_PEER_DOWN;
128 n_ptr->signature = INVALID_NODE_SIG;
116 129
117 tipc_num_nodes++; 130 tipc_num_nodes++;
118 131
@@ -253,63 +266,14 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
253 n_ptr->link_cnt--; 266 n_ptr->link_cnt--;
254} 267}
255 268
256/*
257 * Routing table management - five cases to handle:
258 *
259 * 1: A link towards a zone/cluster external node comes up.
260 * => Send a multicast message updating routing tables of all
261 * system nodes within own cluster that the new destination
262 * can be reached via this node.
263 * (node.establishedContact()=>cluster.multicastNewRoute())
264 *
265 * 2: A link towards a slave node comes up.
266 * => Send a multicast message updating routing tables of all
267 * system nodes within own cluster that the new destination
268 * can be reached via this node.
269 * (node.establishedContact()=>cluster.multicastNewRoute())
270 * => Send a message to the slave node about existence
271 * of all system nodes within cluster:
272 * (node.establishedContact()=>cluster.sendLocalRoutes())
273 *
274 * 3: A new cluster local system node becomes available.
275 * => Send message(s) to this particular node containing
276 * information about all cluster external and slave
277 * nodes which can be reached via this node.
278 * (node.establishedContact()==>network.sendExternalRoutes())
279 * (node.establishedContact()==>network.sendSlaveRoutes())
280 * => Send messages to all directly connected slave nodes
281 * containing information about the existence of the new node
282 * (node.establishedContact()=>cluster.multicastNewRoute())
283 *
284 * 4: The link towards a zone/cluster external node or slave
285 * node goes down.
286 * => Send a multcast message updating routing tables of all
287 * nodes within cluster that the new destination can not any
288 * longer be reached via this node.
289 * (node.lostAllLinks()=>cluster.bcastLostRoute())
290 *
291 * 5: A cluster local system node becomes unavailable.
292 * => Remove all references to this node from the local
293 * routing tables. Note: This is a completely node
294 * local operation.
295 * (node.lostAllLinks()=>network.removeAsRouter())
296 * => Send messages to all directly connected slave nodes
297 * containing information about loss of the node
298 * (node.establishedContact()=>cluster.multicastLostRoute())
299 *
300 */
301
302static void node_established_contact(struct tipc_node *n_ptr) 269static void node_established_contact(struct tipc_node *n_ptr)
303{ 270{
304 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); 271 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
305 272
306 /* Syncronize broadcast acks */ 273 if (n_ptr->bclink.supportable) {
307 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 274 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
308
309 if (n_ptr->bclink.supported) {
310 tipc_bclink_add_node(n_ptr->addr); 275 tipc_bclink_add_node(n_ptr->addr);
311 if (n_ptr->addr < tipc_own_addr) 276 n_ptr->bclink.supported = 1;
312 tipc_own_tag++;
313 } 277 }
314} 278}
315 279
@@ -338,22 +302,20 @@ static void node_lost_contact(struct tipc_node *n_ptr)
338 /* Flush broadcast link info associated with lost node */ 302 /* Flush broadcast link info associated with lost node */
339 303
340 if (n_ptr->bclink.supported) { 304 if (n_ptr->bclink.supported) {
341 n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;
342 while (n_ptr->bclink.deferred_head) { 305 while (n_ptr->bclink.deferred_head) {
343 struct sk_buff *buf = n_ptr->bclink.deferred_head; 306 struct sk_buff *buf = n_ptr->bclink.deferred_head;
344 n_ptr->bclink.deferred_head = buf->next; 307 n_ptr->bclink.deferred_head = buf->next;
345 buf_discard(buf); 308 kfree_skb(buf);
346 } 309 }
310 n_ptr->bclink.deferred_size = 0;
347 311
348 if (n_ptr->bclink.defragm) { 312 if (n_ptr->bclink.defragm) {
349 buf_discard(n_ptr->bclink.defragm); 313 kfree_skb(n_ptr->bclink.defragm);
350 n_ptr->bclink.defragm = NULL; 314 n_ptr->bclink.defragm = NULL;
351 } 315 }
352 316
353 tipc_bclink_remove_node(n_ptr->addr); 317 tipc_bclink_remove_node(n_ptr->addr);
354 tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ); 318 tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ);
355 if (n_ptr->addr < tipc_own_addr)
356 tipc_own_tag--;
357 319
358 n_ptr->bclink.supported = 0; 320 n_ptr->bclink.supported = 0;
359 } 321 }
@@ -444,12 +406,12 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
444 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 406 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
445 " (network address)"); 407 " (network address)");
446 408
447 if (tipc_mode != TIPC_NET_MODE) 409 if (!tipc_own_addr)
448 return tipc_cfg_reply_none(); 410 return tipc_cfg_reply_none();
449 411
450 read_lock_bh(&tipc_net_lock); 412 read_lock_bh(&tipc_net_lock);
451 413
452 /* Get space for all unicast links + multicast link */ 414 /* Get space for all unicast links + broadcast link */
453 415
454 payload_size = TLV_SPACE(sizeof(link_info)) * 416 payload_size = TLV_SPACE(sizeof(link_info)) *
455 (atomic_read(&tipc_num_links) + 1); 417 (atomic_read(&tipc_num_links) + 1);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 0b1c5f8b6996..72561c971d67 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -42,6 +42,11 @@
42#include "net.h" 42#include "net.h"
43#include "bearer.h" 43#include "bearer.h"
44 44
45/*
46 * Out-of-range value for node signature
47 */
48#define INVALID_NODE_SIG 0x10000
49
45/* Flags used to block (re)establishment of contact with a neighboring node */ 50/* Flags used to block (re)establishment of contact with a neighboring node */
46 51
47#define WAIT_PEER_DOWN 0x0001 /* wait to see that peer's links are down */ 52#define WAIT_PEER_DOWN 0x0001 /* wait to see that peer's links are down */
@@ -61,13 +66,15 @@
61 * @block_setup: bit mask of conditions preventing link establishment to node 66 * @block_setup: bit mask of conditions preventing link establishment to node
62 * @link_cnt: number of links to node 67 * @link_cnt: number of links to node
63 * @permit_changeover: non-zero if node has redundant links to this system 68 * @permit_changeover: non-zero if node has redundant links to this system
69 * @signature: node instance identifier
64 * @bclink: broadcast-related info 70 * @bclink: broadcast-related info
71 * @supportable: non-zero if node supports TIPC b'cast link capability
65 * @supported: non-zero if node supports TIPC b'cast capability 72 * @supported: non-zero if node supports TIPC b'cast capability
66 * @acked: sequence # of last outbound b'cast message acknowledged by node 73 * @acked: sequence # of last outbound b'cast message acknowledged by node
67 * @last_in: sequence # of last in-sequence b'cast message received from node 74 * @last_in: sequence # of last in-sequence b'cast message received from node
68 * @gap_after: sequence # of last message not requiring a NAK request 75 * @last_sent: sequence # of last b'cast message sent by node
69 * @gap_to: sequence # of last message requiring a NAK request 76 * @oos_state: state tracker for handling OOS b'cast messages
70 * @nack_sync: counter that determines when NAK requests should be sent 77 * @deferred_size: number of OOS b'cast messages in deferred queue
71 * @deferred_head: oldest OOS b'cast message received from node 78 * @deferred_head: oldest OOS b'cast message received from node
72 * @deferred_tail: newest OOS b'cast message received from node 79 * @deferred_tail: newest OOS b'cast message received from node
73 * @defragm: list of partially reassembled b'cast message fragments from node 80 * @defragm: list of partially reassembled b'cast message fragments from node
@@ -85,35 +92,23 @@ struct tipc_node {
85 int working_links; 92 int working_links;
86 int block_setup; 93 int block_setup;
87 int permit_changeover; 94 int permit_changeover;
95 u32 signature;
88 struct { 96 struct {
89 int supported; 97 u8 supportable;
98 u8 supported;
90 u32 acked; 99 u32 acked;
91 u32 last_in; 100 u32 last_in;
92 u32 gap_after; 101 u32 last_sent;
93 u32 gap_to; 102 u32 oos_state;
94 u32 nack_sync; 103 u32 deferred_size;
95 struct sk_buff *deferred_head; 104 struct sk_buff *deferred_head;
96 struct sk_buff *deferred_tail; 105 struct sk_buff *deferred_tail;
97 struct sk_buff *defragm; 106 struct sk_buff *defragm;
98 } bclink; 107 } bclink;
99}; 108};
100 109
101#define NODE_HTABLE_SIZE 512
102extern struct list_head tipc_node_list; 110extern struct list_head tipc_node_list;
103 111
104/*
105 * A trivial power-of-two bitmask technique is used for speed, since this
106 * operation is done for every incoming TIPC packet. The number of hash table
107 * entries has been chosen so that no hash chain exceeds 8 nodes and will
108 * usually be much smaller (typically only a single node).
109 */
110static inline unsigned int tipc_hashfn(u32 addr)
111{
112 return addr & (NODE_HTABLE_SIZE - 1);
113}
114
115extern u32 tipc_own_tag;
116
117struct tipc_node *tipc_node_find(u32 addr); 112struct tipc_node *tipc_node_find(u32 addr);
118struct tipc_node *tipc_node_create(u32 addr); 113struct tipc_node *tipc_node_create(u32 addr);
119void tipc_node_delete(struct tipc_node *n_ptr); 114void tipc_node_delete(struct tipc_node *n_ptr);
diff --git a/net/tipc/port.c b/net/tipc/port.c
index d91efc69e6f9..94d2904cce66 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -116,13 +116,13 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
116 ibuf = skb_copy(buf, GFP_ATOMIC); 116 ibuf = skb_copy(buf, GFP_ATOMIC);
117 if (ibuf == NULL) { 117 if (ibuf == NULL) {
118 tipc_port_list_free(&dports); 118 tipc_port_list_free(&dports);
119 buf_discard(buf); 119 kfree_skb(buf);
120 return -ENOMEM; 120 return -ENOMEM;
121 } 121 }
122 } 122 }
123 res = tipc_bclink_send_msg(buf); 123 res = tipc_bclink_send_msg(buf);
124 if ((res < 0) && (dports.count != 0)) 124 if ((res < 0) && (dports.count != 0))
125 buf_discard(ibuf); 125 kfree_skb(ibuf);
126 } else { 126 } else {
127 ibuf = buf; 127 ibuf = buf;
128 } 128 }
@@ -187,7 +187,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct tipc_port_list *dp)
187 } 187 }
188 } 188 }
189exit: 189exit:
190 buf_discard(buf); 190 kfree_skb(buf);
191 tipc_port_list_free(dp); 191 tipc_port_list_free(dp);
192} 192}
193 193
@@ -400,15 +400,16 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
400 400
401 /* send self-abort message when rejecting on a connected port */ 401 /* send self-abort message when rejecting on a connected port */
402 if (msg_connected(msg)) { 402 if (msg_connected(msg)) {
403 struct sk_buff *abuf = NULL;
404 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg)); 403 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
405 404
406 if (p_ptr) { 405 if (p_ptr) {
406 struct sk_buff *abuf = NULL;
407
407 if (p_ptr->connected) 408 if (p_ptr->connected)
408 abuf = port_build_self_abort_msg(p_ptr, err); 409 abuf = port_build_self_abort_msg(p_ptr, err);
409 tipc_port_unlock(p_ptr); 410 tipc_port_unlock(p_ptr);
411 tipc_net_route_msg(abuf);
410 } 412 }
411 tipc_net_route_msg(abuf);
412 } 413 }
413 414
414 /* send returned message & dispose of rejected message */ 415 /* send returned message & dispose of rejected message */
@@ -419,7 +420,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
419 else 420 else
420 tipc_link_send(rbuf, src_node, msg_link_selector(rmsg)); 421 tipc_link_send(rbuf, src_node, msg_link_selector(rmsg));
421exit: 422exit:
422 buf_discard(buf); 423 kfree_skb(buf);
423 return data_sz; 424 return data_sz;
424} 425}
425 426
@@ -567,7 +568,7 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
567 tipc_port_unlock(p_ptr); 568 tipc_port_unlock(p_ptr);
568exit: 569exit:
569 tipc_net_route_msg(r_buf); 570 tipc_net_route_msg(r_buf);
570 buf_discard(buf); 571 kfree_skb(buf);
571} 572}
572 573
573static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id) 574static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id)
@@ -758,7 +759,7 @@ static void port_dispatcher_sigh(void *dummy)
758 } 759 }
759 } 760 }
760 if (buf) 761 if (buf)
761 buf_discard(buf); 762 kfree_skb(buf);
762 buf = next; 763 buf = next;
763 continue; 764 continue;
764err: 765err:
@@ -812,7 +813,7 @@ err:
812 } 813 }
813 } 814 }
814 if (buf) 815 if (buf)
815 buf_discard(buf); 816 kfree_skb(buf);
816 buf = next; 817 buf = next;
817 continue; 818 continue;
818reject: 819reject:
@@ -1053,8 +1054,6 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1053 msg = &p_ptr->phdr; 1054 msg = &p_ptr->phdr;
1054 msg_set_destnode(msg, peer->node); 1055 msg_set_destnode(msg, peer->node);
1055 msg_set_destport(msg, peer->ref); 1056 msg_set_destport(msg, peer->ref);
1056 msg_set_orignode(msg, tipc_own_addr);
1057 msg_set_origport(msg, p_ptr->ref);
1058 msg_set_type(msg, TIPC_CONN_MSG); 1057 msg_set_type(msg, TIPC_CONN_MSG);
1059 msg_set_lookup_scope(msg, 0); 1058 msg_set_lookup_scope(msg, 0);
1060 msg_set_hdr_sz(msg, SHORT_H_SIZE); 1059 msg_set_hdr_sz(msg, SHORT_H_SIZE);
@@ -1132,6 +1131,49 @@ int tipc_shutdown(u32 ref)
1132 return tipc_disconnect(ref); 1131 return tipc_disconnect(ref);
1133} 1132}
1134 1133
1134/**
1135 * tipc_port_recv_msg - receive message from lower layer and deliver to port user
1136 */
1137
1138int tipc_port_recv_msg(struct sk_buff *buf)
1139{
1140 struct tipc_port *p_ptr;
1141 struct tipc_msg *msg = buf_msg(buf);
1142 u32 destport = msg_destport(msg);
1143 u32 dsz = msg_data_sz(msg);
1144 u32 err;
1145
1146 /* forward unresolved named message */
1147 if (unlikely(!destport)) {
1148 tipc_net_route_msg(buf);
1149 return dsz;
1150 }
1151
1152 /* validate destination & pass to port, otherwise reject message */
1153 p_ptr = tipc_port_lock(destport);
1154 if (likely(p_ptr)) {
1155 if (likely(p_ptr->connected)) {
1156 if ((unlikely(msg_origport(msg) !=
1157 tipc_peer_port(p_ptr))) ||
1158 (unlikely(msg_orignode(msg) !=
1159 tipc_peer_node(p_ptr))) ||
1160 (unlikely(!msg_connected(msg)))) {
1161 err = TIPC_ERR_NO_PORT;
1162 tipc_port_unlock(p_ptr);
1163 goto reject;
1164 }
1165 }
1166 err = p_ptr->dispatcher(p_ptr, buf);
1167 tipc_port_unlock(p_ptr);
1168 if (likely(!err))
1169 return dsz;
1170 } else {
1171 err = TIPC_ERR_NO_PORT;
1172 }
1173reject:
1174 return tipc_reject_msg(buf, err);
1175}
1176
1135/* 1177/*
1136 * tipc_port_recv_sections(): Concatenate and deliver sectioned 1178 * tipc_port_recv_sections(): Concatenate and deliver sectioned
1137 * message for this node. 1179 * message for this node.
@@ -1210,8 +1252,6 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1210 1252
1211 msg = &p_ptr->phdr; 1253 msg = &p_ptr->phdr;
1212 msg_set_type(msg, TIPC_NAMED_MSG); 1254 msg_set_type(msg, TIPC_NAMED_MSG);
1213 msg_set_orignode(msg, tipc_own_addr);
1214 msg_set_origport(msg, ref);
1215 msg_set_hdr_sz(msg, NAMED_H_SIZE); 1255 msg_set_hdr_sz(msg, NAMED_H_SIZE);
1216 msg_set_nametype(msg, name->type); 1256 msg_set_nametype(msg, name->type);
1217 msg_set_nameinst(msg, name->instance); 1257 msg_set_nameinst(msg, name->instance);
@@ -1220,7 +1260,7 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1220 msg_set_destnode(msg, destnode); 1260 msg_set_destnode(msg, destnode);
1221 msg_set_destport(msg, destport); 1261 msg_set_destport(msg, destport);
1222 1262
1223 if (likely(destport)) { 1263 if (likely(destport || destnode)) {
1224 if (likely(destnode == tipc_own_addr)) 1264 if (likely(destnode == tipc_own_addr))
1225 res = tipc_port_recv_sections(p_ptr, num_sect, 1265 res = tipc_port_recv_sections(p_ptr, num_sect,
1226 msg_sect, total_len); 1266 msg_sect, total_len);
@@ -1261,8 +1301,6 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1261 msg = &p_ptr->phdr; 1301 msg = &p_ptr->phdr;
1262 msg_set_type(msg, TIPC_DIRECT_MSG); 1302 msg_set_type(msg, TIPC_DIRECT_MSG);
1263 msg_set_lookup_scope(msg, 0); 1303 msg_set_lookup_scope(msg, 0);
1264 msg_set_orignode(msg, tipc_own_addr);
1265 msg_set_origport(msg, ref);
1266 msg_set_destnode(msg, dest->node); 1304 msg_set_destnode(msg, dest->node);
1267 msg_set_destport(msg, dest->ref); 1305 msg_set_destport(msg, dest->ref);
1268 msg_set_hdr_sz(msg, BASIC_H_SIZE); 1306 msg_set_hdr_sz(msg, BASIC_H_SIZE);
@@ -1301,8 +1339,6 @@ int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1301 1339
1302 msg = &p_ptr->phdr; 1340 msg = &p_ptr->phdr;
1303 msg_set_type(msg, TIPC_DIRECT_MSG); 1341 msg_set_type(msg, TIPC_DIRECT_MSG);
1304 msg_set_orignode(msg, tipc_own_addr);
1305 msg_set_origport(msg, ref);
1306 msg_set_destnode(msg, dest->node); 1342 msg_set_destnode(msg, dest->node);
1307 msg_set_destport(msg, dest->ref); 1343 msg_set_destport(msg, dest->ref);
1308 msg_set_hdr_sz(msg, BASIC_H_SIZE); 1344 msg_set_hdr_sz(msg, BASIC_H_SIZE);
diff --git a/net/tipc/port.h b/net/tipc/port.h
index f751807e2a91..9b88531e5a61 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -205,6 +205,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr);
205/* 205/*
206 * TIPC messaging routines 206 * TIPC messaging routines
207 */ 207 */
208int tipc_port_recv_msg(struct sk_buff *buf);
208int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect, 209int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect,
209 unsigned int total_len); 210 unsigned int total_len);
210 211
@@ -271,45 +272,4 @@ static inline int tipc_port_congested(struct tipc_port *p_ptr)
271 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); 272 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
272} 273}
273 274
274/**
275 * tipc_port_recv_msg - receive message from lower layer and deliver to port user
276 */
277
278static inline int tipc_port_recv_msg(struct sk_buff *buf)
279{
280 struct tipc_port *p_ptr;
281 struct tipc_msg *msg = buf_msg(buf);
282 u32 destport = msg_destport(msg);
283 u32 dsz = msg_data_sz(msg);
284 u32 err;
285
286 /* forward unresolved named message */
287 if (unlikely(!destport)) {
288 tipc_net_route_msg(buf);
289 return dsz;
290 }
291
292 /* validate destination & pass to port, otherwise reject message */
293 p_ptr = tipc_port_lock(destport);
294 if (likely(p_ptr)) {
295 if (likely(p_ptr->connected)) {
296 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) ||
297 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) ||
298 (unlikely(!msg_connected(msg)))) {
299 err = TIPC_ERR_NO_PORT;
300 tipc_port_unlock(p_ptr);
301 goto reject;
302 }
303 }
304 err = p_ptr->dispatcher(p_ptr, buf);
305 tipc_port_unlock(p_ptr);
306 if (likely(!err))
307 return dsz;
308 } else {
309 err = TIPC_ERR_NO_PORT;
310 }
311reject:
312 return tipc_reject_msg(buf, err);
313}
314
315#endif 275#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e2f7c5d370ba..29e957f64458 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -126,7 +126,7 @@ static atomic_t tipc_queue_size = ATOMIC_INIT(0);
126 126
127static void advance_rx_queue(struct sock *sk) 127static void advance_rx_queue(struct sock *sk)
128{ 128{
129 buf_discard(__skb_dequeue(&sk->sk_receive_queue)); 129 kfree_skb(__skb_dequeue(&sk->sk_receive_queue));
130 atomic_dec(&tipc_queue_size); 130 atomic_dec(&tipc_queue_size);
131} 131}
132 132
@@ -142,7 +142,7 @@ static void discard_rx_queue(struct sock *sk)
142 142
143 while ((buf = __skb_dequeue(&sk->sk_receive_queue))) { 143 while ((buf = __skb_dequeue(&sk->sk_receive_queue))) {
144 atomic_dec(&tipc_queue_size); 144 atomic_dec(&tipc_queue_size);
145 buf_discard(buf); 145 kfree_skb(buf);
146 } 146 }
147} 147}
148 148
@@ -288,7 +288,7 @@ static int release(struct socket *sock)
288 break; 288 break;
289 atomic_dec(&tipc_queue_size); 289 atomic_dec(&tipc_queue_size);
290 if (TIPC_SKB_CB(buf)->handle != 0) 290 if (TIPC_SKB_CB(buf)->handle != 0)
291 buf_discard(buf); 291 kfree_skb(buf);
292 else { 292 else {
293 if ((sock->state == SS_CONNECTING) || 293 if ((sock->state == SS_CONNECTING) ||
294 (sock->state == SS_CONNECTED)) { 294 (sock->state == SS_CONNECTED)) {
@@ -355,6 +355,9 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
355 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) 355 else if (addr->addrtype != TIPC_ADDR_NAMESEQ)
356 return -EAFNOSUPPORT; 356 return -EAFNOSUPPORT;
357 357
358 if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES)
359 return -EACCES;
360
358 return (addr->scope > 0) ? 361 return (addr->scope > 0) ?
359 tipc_publish(portref, addr->scope, &addr->addr.nameseq) : 362 tipc_publish(portref, addr->scope, &addr->addr.nameseq) :
360 tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq); 363 tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq);
@@ -1612,7 +1615,7 @@ restart:
1612 if (buf) { 1615 if (buf) {
1613 atomic_dec(&tipc_queue_size); 1616 atomic_dec(&tipc_queue_size);
1614 if (TIPC_SKB_CB(buf)->handle != 0) { 1617 if (TIPC_SKB_CB(buf)->handle != 0) {
1615 buf_discard(buf); 1618 kfree_skb(buf);
1616 goto restart; 1619 goto restart;
1617 } 1620 }
1618 tipc_disconnect(tport->ref); 1621 tipc_disconnect(tport->ref);
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 8c49566da8f3..b2964e9895d3 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -552,7 +552,7 @@ int tipc_subscr_start(void)
552 if (res) 552 if (res)
553 goto failed; 553 goto failed;
554 554
555 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq); 555 res = tipc_publish(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
556 if (res) { 556 if (res) {
557 tipc_deleteport(topsrv.setup_port); 557 tipc_deleteport(topsrv.setup_port);
558 topsrv.setup_port = 0; 558 topsrv.setup_port = 0;