aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c111
-rw-r--r--net/tipc/bcast.h1
-rw-r--r--net/tipc/bearer.c8
-rw-r--r--net/tipc/bearer.h4
-rw-r--r--net/tipc/config.h1
-rw-r--r--net/tipc/discover.c6
-rw-r--r--net/tipc/eth_media.c32
-rw-r--r--net/tipc/link.c111
-rw-r--r--net/tipc/link.h1
-rw-r--r--net/tipc/name_distr.c35
-rw-r--r--net/tipc/net.c11
-rw-r--r--net/tipc/node.c45
-rw-r--r--net/tipc/node.h10
-rw-r--r--net/tipc/socket.c51
-rw-r--r--net/tipc/subscr.c3
-rw-r--r--net/tipc/subscr.h6
16 files changed, 239 insertions, 197 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 759b318b5ffb..28908f54459e 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -39,6 +39,7 @@
39#include "link.h" 39#include "link.h"
40#include "port.h" 40#include "port.h"
41#include "bcast.h" 41#include "bcast.h"
42#include "name_distr.h"
42 43
43#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ 44#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */
44 45
@@ -298,14 +299,9 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
298 msg_set_bcgap_to(msg, n_ptr->bclink.gap_to); 299 msg_set_bcgap_to(msg, n_ptr->bclink.gap_to);
299 msg_set_bcast_tag(msg, tipc_own_tag); 300 msg_set_bcast_tag(msg, tipc_own_tag);
300 301
301 if (tipc_bearer_send(&bcbearer->bearer, buf, NULL)) { 302 tipc_bearer_send(&bcbearer->bearer, buf, NULL);
302 bcl->stats.sent_nacks++; 303 bcl->stats.sent_nacks++;
303 buf_discard(buf); 304 buf_discard(buf);
304 } else {
305 tipc_bearer_schedule(bcl->b_ptr, bcl);
306 bcl->proto_msg_queue = buf;
307 bcl->stats.bearer_congs++;
308 }
309 305
310 /* 306 /*
311 * Ensure we doesn't send another NACK msg to the node 307 * Ensure we doesn't send another NACK msg to the node
@@ -426,20 +422,28 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
426void tipc_bclink_recv_pkt(struct sk_buff *buf) 422void tipc_bclink_recv_pkt(struct sk_buff *buf)
427{ 423{
428 struct tipc_msg *msg = buf_msg(buf); 424 struct tipc_msg *msg = buf_msg(buf);
429 struct tipc_node *node = tipc_node_find(msg_prevnode(msg)); 425 struct tipc_node *node;
430 u32 next_in; 426 u32 next_in;
431 u32 seqno; 427 u32 seqno;
432 struct sk_buff *deferred; 428 struct sk_buff *deferred;
433 429
434 if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported || 430 /* Screen out unwanted broadcast messages */
435 (msg_mc_netid(msg) != tipc_net_id))) { 431
436 buf_discard(buf); 432 if (msg_mc_netid(msg) != tipc_net_id)
437 return; 433 goto exit;
438 } 434
435 node = tipc_node_find(msg_prevnode(msg));
436 if (unlikely(!node))
437 goto exit;
438
439 tipc_node_lock(node);
440 if (unlikely(!node->bclink.supported))
441 goto unlock;
439 442
440 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { 443 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
444 if (msg_type(msg) != STATE_MSG)
445 goto unlock;
441 if (msg_destnode(msg) == tipc_own_addr) { 446 if (msg_destnode(msg) == tipc_own_addr) {
442 tipc_node_lock(node);
443 tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); 447 tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
444 tipc_node_unlock(node); 448 tipc_node_unlock(node);
445 spin_lock_bh(&bc_lock); 449 spin_lock_bh(&bc_lock);
@@ -449,18 +453,18 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
449 msg_bcgap_to(msg)); 453 msg_bcgap_to(msg));
450 spin_unlock_bh(&bc_lock); 454 spin_unlock_bh(&bc_lock);
451 } else { 455 } else {
456 tipc_node_unlock(node);
452 tipc_bclink_peek_nack(msg_destnode(msg), 457 tipc_bclink_peek_nack(msg_destnode(msg),
453 msg_bcast_tag(msg), 458 msg_bcast_tag(msg),
454 msg_bcgap_after(msg), 459 msg_bcgap_after(msg),
455 msg_bcgap_to(msg)); 460 msg_bcgap_to(msg));
456 } 461 }
457 buf_discard(buf); 462 goto exit;
458 return;
459 } 463 }
460 464
461 tipc_node_lock(node); 465 /* Handle in-sequence broadcast message */
466
462receive: 467receive:
463 deferred = node->bclink.deferred_head;
464 next_in = mod(node->bclink.last_in + 1); 468 next_in = mod(node->bclink.last_in + 1);
465 seqno = msg_seqno(msg); 469 seqno = msg_seqno(msg);
466 470
@@ -474,7 +478,10 @@ receive:
474 } 478 }
475 if (likely(msg_isdata(msg))) { 479 if (likely(msg_isdata(msg))) {
476 tipc_node_unlock(node); 480 tipc_node_unlock(node);
477 tipc_port_recv_mcast(buf, NULL); 481 if (likely(msg_mcast(msg)))
482 tipc_port_recv_mcast(buf, NULL);
483 else
484 buf_discard(buf);
478 } else if (msg_user(msg) == MSG_BUNDLER) { 485 } else if (msg_user(msg) == MSG_BUNDLER) {
479 bcl->stats.recv_bundles++; 486 bcl->stats.recv_bundles++;
480 bcl->stats.recv_bundled += msg_msgcnt(msg); 487 bcl->stats.recv_bundled += msg_msgcnt(msg);
@@ -487,18 +494,22 @@ receive:
487 bcl->stats.recv_fragmented++; 494 bcl->stats.recv_fragmented++;
488 tipc_node_unlock(node); 495 tipc_node_unlock(node);
489 tipc_net_route_msg(buf); 496 tipc_net_route_msg(buf);
497 } else if (msg_user(msg) == NAME_DISTRIBUTOR) {
498 tipc_node_unlock(node);
499 tipc_named_recv(buf);
490 } else { 500 } else {
491 tipc_node_unlock(node); 501 tipc_node_unlock(node);
492 tipc_net_route_msg(buf); 502 buf_discard(buf);
493 } 503 }
504 buf = NULL;
505 tipc_node_lock(node);
506 deferred = node->bclink.deferred_head;
494 if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) { 507 if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) {
495 tipc_node_lock(node);
496 buf = deferred; 508 buf = deferred;
497 msg = buf_msg(buf); 509 msg = buf_msg(buf);
498 node->bclink.deferred_head = deferred->next; 510 node->bclink.deferred_head = deferred->next;
499 goto receive; 511 goto receive;
500 } 512 }
501 return;
502 } else if (less(next_in, seqno)) { 513 } else if (less(next_in, seqno)) {
503 u32 gap_after = node->bclink.gap_after; 514 u32 gap_after = node->bclink.gap_after;
504 u32 gap_to = node->bclink.gap_to; 515 u32 gap_to = node->bclink.gap_to;
@@ -513,6 +524,7 @@ receive:
513 else if (less(gap_after, seqno) && less(seqno, gap_to)) 524 else if (less(gap_after, seqno) && less(seqno, gap_to))
514 node->bclink.gap_to = seqno; 525 node->bclink.gap_to = seqno;
515 } 526 }
527 buf = NULL;
516 if (bclink_ack_allowed(node->bclink.nack_sync)) { 528 if (bclink_ack_allowed(node->bclink.nack_sync)) {
517 if (gap_to != gap_after) 529 if (gap_to != gap_after)
518 bclink_send_nack(node); 530 bclink_send_nack(node);
@@ -520,9 +532,11 @@ receive:
520 } 532 }
521 } else { 533 } else {
522 bcl->stats.duplicates++; 534 bcl->stats.duplicates++;
523 buf_discard(buf);
524 } 535 }
536unlock:
525 tipc_node_unlock(node); 537 tipc_node_unlock(node);
538exit:
539 buf_discard(buf);
526} 540}
527 541
528u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) 542u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
@@ -535,10 +549,11 @@ u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
535/** 549/**
536 * tipc_bcbearer_send - send a packet through the broadcast pseudo-bearer 550 * tipc_bcbearer_send - send a packet through the broadcast pseudo-bearer
537 * 551 *
538 * Send through as many bearers as necessary to reach all nodes 552 * Send packet over as many bearers as necessary to reach all nodes
539 * that support TIPC multicasting. 553 * that have joined the broadcast link.
540 * 554 *
541 * Returns 0 if packet sent successfully, non-zero if not 555 * Returns 0 (packet sent successfully) under all circumstances,
556 * since the broadcast link's pseudo-bearer never blocks
542 */ 557 */
543 558
544static int tipc_bcbearer_send(struct sk_buff *buf, 559static int tipc_bcbearer_send(struct sk_buff *buf,
@@ -547,7 +562,12 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
547{ 562{
548 int bp_index; 563 int bp_index;
549 564
550 /* Prepare buffer for broadcasting (if first time trying to send it) */ 565 /*
566 * Prepare broadcast link message for reliable transmission,
567 * if first time trying to send it;
568 * preparation is skipped for broadcast link protocol messages
569 * since they are sent in an unreliable manner and don't need it
570 */
551 571
552 if (likely(!msg_non_seq(buf_msg(buf)))) { 572 if (likely(!msg_non_seq(buf_msg(buf)))) {
553 struct tipc_msg *msg; 573 struct tipc_msg *msg;
@@ -596,18 +616,12 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
596 } 616 }
597 617
598 if (bcbearer->remains_new.count == 0) 618 if (bcbearer->remains_new.count == 0)
599 return 0; 619 break; /* all targets reached */
600 620
601 bcbearer->remains = bcbearer->remains_new; 621 bcbearer->remains = bcbearer->remains_new;
602 } 622 }
603 623
604 /* 624 return 0;
605 * Unable to reach all targets (indicate success, since currently
606 * there isn't code in place to properly block & unblock the
607 * pseudo-bearer used by the broadcast link)
608 */
609
610 return TIPC_OK;
611} 625}
612 626
613/** 627/**
@@ -667,27 +681,6 @@ void tipc_bcbearer_sort(void)
667 spin_unlock_bh(&bc_lock); 681 spin_unlock_bh(&bc_lock);
668} 682}
669 683
670/**
671 * tipc_bcbearer_push - resolve bearer congestion
672 *
673 * Forces bclink to push out any unsent packets, until all packets are gone
674 * or congestion reoccurs.
675 * No locks set when function called
676 */
677
678void tipc_bcbearer_push(void)
679{
680 struct tipc_bearer *b_ptr;
681
682 spin_lock_bh(&bc_lock);
683 b_ptr = &bcbearer->bearer;
684 if (b_ptr->blocked) {
685 b_ptr->blocked = 0;
686 tipc_bearer_lock_push(b_ptr);
687 }
688 spin_unlock_bh(&bc_lock);
689}
690
691 684
692int tipc_bclink_stats(char *buf, const u32 buf_size) 685int tipc_bclink_stats(char *buf, const u32 buf_size)
693{ 686{
@@ -764,7 +757,7 @@ int tipc_bclink_init(void)
764 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); 757 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
765 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); 758 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
766 if (!bcbearer || !bclink) { 759 if (!bcbearer || !bclink) {
767 warn("Multicast link creation failed, no memory\n"); 760 warn("Broadcast link creation failed, no memory\n");
768 kfree(bcbearer); 761 kfree(bcbearer);
769 bcbearer = NULL; 762 bcbearer = NULL;
770 kfree(bclink); 763 kfree(bclink);
@@ -775,7 +768,7 @@ int tipc_bclink_init(void)
775 INIT_LIST_HEAD(&bcbearer->bearer.cong_links); 768 INIT_LIST_HEAD(&bcbearer->bearer.cong_links);
776 bcbearer->bearer.media = &bcbearer->media; 769 bcbearer->bearer.media = &bcbearer->media;
777 bcbearer->media.send_msg = tipc_bcbearer_send; 770 bcbearer->media.send_msg = tipc_bcbearer_send;
778 sprintf(bcbearer->media.name, "tipc-multicast"); 771 sprintf(bcbearer->media.name, "tipc-broadcast");
779 772
780 bcl = &bclink->link; 773 bcl = &bclink->link;
781 INIT_LIST_HEAD(&bcl->waiting_ports); 774 INIT_LIST_HEAD(&bcl->waiting_ports);
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 500c97f1c859..06740da5ae61 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -101,6 +101,5 @@ int 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);
103void tipc_bcbearer_sort(void); 103void tipc_bcbearer_sort(void);
104void tipc_bcbearer_push(void);
105 104
106#endif 105#endif
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 85eba9c08ee9..e2202de3d93e 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -385,13 +385,9 @@ static int bearer_push(struct tipc_bearer *b_ptr)
385 385
386void tipc_bearer_lock_push(struct tipc_bearer *b_ptr) 386void tipc_bearer_lock_push(struct tipc_bearer *b_ptr)
387{ 387{
388 int res;
389
390 spin_lock_bh(&b_ptr->lock); 388 spin_lock_bh(&b_ptr->lock);
391 res = bearer_push(b_ptr); 389 bearer_push(b_ptr);
392 spin_unlock_bh(&b_ptr->lock); 390 spin_unlock_bh(&b_ptr->lock);
393 if (res)
394 tipc_bcbearer_push();
395} 391}
396 392
397 393
@@ -608,6 +604,7 @@ int tipc_block_bearer(const char *name)
608 info("Blocking bearer <%s>\n", name); 604 info("Blocking bearer <%s>\n", name);
609 spin_lock_bh(&b_ptr->lock); 605 spin_lock_bh(&b_ptr->lock);
610 b_ptr->blocked = 1; 606 b_ptr->blocked = 1;
607 list_splice_init(&b_ptr->cong_links, &b_ptr->links);
611 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 608 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
612 struct tipc_node *n_ptr = l_ptr->owner; 609 struct tipc_node *n_ptr = l_ptr->owner;
613 610
@@ -635,6 +632,7 @@ static void bearer_disable(struct tipc_bearer *b_ptr)
635 spin_lock_bh(&b_ptr->lock); 632 spin_lock_bh(&b_ptr->lock);
636 b_ptr->blocked = 1; 633 b_ptr->blocked = 1;
637 b_ptr->media->disable_bearer(b_ptr); 634 b_ptr->media->disable_bearer(b_ptr);
635 list_splice_init(&b_ptr->cong_links, &b_ptr->links);
638 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 636 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
639 tipc_link_delete(l_ptr); 637 tipc_link_delete(l_ptr);
640 } 638 }
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 5ad70eff1ebf..d696f9e414e3 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -39,8 +39,8 @@
39 39
40#include "bcast.h" 40#include "bcast.h"
41 41
42#define MAX_BEARERS 8 42#define MAX_BEARERS 2
43#define MAX_MEDIA 4 43#define MAX_MEDIA 2
44 44
45/* 45/*
46 * Identifiers of supported TIPC media types 46 * Identifiers of supported TIPC media types
diff --git a/net/tipc/config.h b/net/tipc/config.h
index 443159a166fd..80da6ebc2785 100644
--- a/net/tipc/config.h
+++ b/net/tipc/config.h
@@ -65,7 +65,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd,
65 const void *req_tlv_area, int req_tlv_space, 65 const void *req_tlv_area, int req_tlv_space,
66 int headroom); 66 int headroom);
67 67
68void tipc_cfg_link_event(u32 addr, char *name, int up);
69int tipc_cfg_init(void); 68int tipc_cfg_init(void);
70void tipc_cfg_stop(void); 69void tipc_cfg_stop(void);
71 70
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 0987933155b9..f2fb96e86ee8 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -159,12 +159,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
159 } 159 }
160 tipc_node_lock(n_ptr); 160 tipc_node_lock(n_ptr);
161 161
162 /* Don't talk to neighbor during cleanup after last session */
163 if (n_ptr->cleanup_required) {
164 tipc_node_unlock(n_ptr);
165 return;
166 }
167
168 link = n_ptr->links[b_ptr->identity]; 162 link = n_ptr->links[b_ptr->identity];
169 163
170 /* Create a link endpoint for this bearer, if necessary */ 164 /* Create a link endpoint for this bearer, if necessary */
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index b69092eb95d8..e728d4ce2a1b 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -2,7 +2,7 @@
2 * net/tipc/eth_media.c: Ethernet bearer support for TIPC 2 * net/tipc/eth_media.c: Ethernet bearer support for TIPC
3 * 3 *
4 * Copyright (c) 2001-2007, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2008, 2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,7 @@
37#include "core.h" 37#include "core.h"
38#include "bearer.h" 38#include "bearer.h"
39 39
40#define MAX_ETH_BEARERS 2 40#define MAX_ETH_BEARERS MAX_BEARERS
41#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI 41#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI
42#define ETH_LINK_TOLERANCE TIPC_DEF_LINK_TOL 42#define ETH_LINK_TOLERANCE TIPC_DEF_LINK_TOL
43#define ETH_LINK_WINDOW TIPC_DEF_LINK_WIN 43#define ETH_LINK_WINDOW TIPC_DEF_LINK_WIN
@@ -144,31 +144,27 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
144 144
145 /* Find device with specified name */ 145 /* Find device with specified name */
146 146
147 read_lock(&dev_base_lock);
147 for_each_netdev(&init_net, pdev) { 148 for_each_netdev(&init_net, pdev) {
148 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) { 149 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
149 dev = pdev; 150 dev = pdev;
151 dev_hold(dev);
150 break; 152 break;
151 } 153 }
152 } 154 }
155 read_unlock(&dev_base_lock);
153 if (!dev) 156 if (!dev)
154 return -ENODEV; 157 return -ENODEV;
155 158
156 /* Find Ethernet bearer for device (or create one) */ 159 /* Create Ethernet bearer for device */
157 160
158 while ((eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev)) 161 eb_ptr->dev = dev;
159 eb_ptr++; 162 eb_ptr->tipc_packet_type.type = htons(ETH_P_TIPC);
160 if (eb_ptr == stop) 163 eb_ptr->tipc_packet_type.dev = dev;
161 return -EDQUOT; 164 eb_ptr->tipc_packet_type.func = recv_msg;
162 if (!eb_ptr->dev) { 165 eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
163 eb_ptr->dev = dev; 166 INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));
164 eb_ptr->tipc_packet_type.type = htons(ETH_P_TIPC); 167 dev_add_pack(&eb_ptr->tipc_packet_type);
165 eb_ptr->tipc_packet_type.dev = dev;
166 eb_ptr->tipc_packet_type.func = recv_msg;
167 eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
168 INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));
169 dev_hold(dev);
170 dev_add_pack(&eb_ptr->tipc_packet_type);
171 }
172 168
173 /* Associate TIPC bearer with Ethernet bearer */ 169 /* Associate TIPC bearer with Ethernet bearer */
174 170
diff --git a/net/tipc/link.c b/net/tipc/link.c
index f89570c54f54..ae98a72da11a 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -332,15 +332,16 @@ struct link *tipc_link_create(struct tipc_node *n_ptr,
332 332
333 l_ptr->addr = peer; 333 l_ptr->addr = peer;
334 if_name = strchr(b_ptr->name, ':') + 1; 334 if_name = strchr(b_ptr->name, ':') + 1;
335 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 335 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
336 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 336 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
337 tipc_node(tipc_own_addr), 337 tipc_node(tipc_own_addr),
338 if_name, 338 if_name,
339 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 339 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
340 /* note: peer i/f is appended to link name by reset/activate */ 340 /* note: peer i/f name is updated by reset/activate message */
341 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 341 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
342 l_ptr->owner = n_ptr; 342 l_ptr->owner = n_ptr;
343 l_ptr->checkpoint = 1; 343 l_ptr->checkpoint = 1;
344 l_ptr->peer_session = INVALID_SESSION;
344 l_ptr->b_ptr = b_ptr; 345 l_ptr->b_ptr = b_ptr;
345 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); 346 link_set_supervision_props(l_ptr, b_ptr->media->tolerance);
346 l_ptr->state = RESET_UNKNOWN; 347 l_ptr->state = RESET_UNKNOWN;
@@ -536,9 +537,6 @@ void tipc_link_stop(struct link *l_ptr)
536 l_ptr->proto_msg_queue = NULL; 537 l_ptr->proto_msg_queue = NULL;
537} 538}
538 539
539/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
540#define link_send_event(fcn, l_ptr, up) do { } while (0)
541
542void tipc_link_reset(struct link *l_ptr) 540void tipc_link_reset(struct link *l_ptr)
543{ 541{
544 struct sk_buff *buf; 542 struct sk_buff *buf;
@@ -596,10 +594,6 @@ void tipc_link_reset(struct link *l_ptr)
596 l_ptr->fsm_msg_cnt = 0; 594 l_ptr->fsm_msg_cnt = 0;
597 l_ptr->stale_count = 0; 595 l_ptr->stale_count = 0;
598 link_reset_statistics(l_ptr); 596 link_reset_statistics(l_ptr);
599
600 link_send_event(tipc_cfg_link_event, l_ptr, 0);
601 if (!in_own_cluster(l_ptr->addr))
602 link_send_event(tipc_disc_link_event, l_ptr, 0);
603} 597}
604 598
605 599
@@ -608,9 +602,6 @@ static void link_activate(struct link *l_ptr)
608 l_ptr->next_in_no = l_ptr->stats.recv_info = 1; 602 l_ptr->next_in_no = l_ptr->stats.recv_info = 1;
609 tipc_node_link_up(l_ptr->owner, l_ptr); 603 tipc_node_link_up(l_ptr->owner, l_ptr);
610 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr); 604 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
611 link_send_event(tipc_cfg_link_event, l_ptr, 1);
612 if (!in_own_cluster(l_ptr->addr))
613 link_send_event(tipc_disc_link_event, l_ptr, 1);
614} 605}
615 606
616/** 607/**
@@ -985,6 +976,51 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
985} 976}
986 977
987/* 978/*
979 * tipc_link_send_names - send name table entries to new neighbor
980 *
981 * Send routine for bulk delivery of name table messages when contact
982 * with a new neighbor occurs. No link congestion checking is performed
983 * because name table messages *must* be delivered. The messages must be
984 * small enough not to require fragmentation.
985 * Called without any locks held.
986 */
987
988void tipc_link_send_names(struct list_head *message_list, u32 dest)
989{
990 struct tipc_node *n_ptr;
991 struct link *l_ptr;
992 struct sk_buff *buf;
993 struct sk_buff *temp_buf;
994
995 if (list_empty(message_list))
996 return;
997
998 read_lock_bh(&tipc_net_lock);
999 n_ptr = tipc_node_find(dest);
1000 if (n_ptr) {
1001 tipc_node_lock(n_ptr);
1002 l_ptr = n_ptr->active_links[0];
1003 if (l_ptr) {
1004 /* convert circular list to linear list */
1005 ((struct sk_buff *)message_list->prev)->next = NULL;
1006 link_add_chain_to_outqueue(l_ptr,
1007 (struct sk_buff *)message_list->next, 0);
1008 tipc_link_push_queue(l_ptr);
1009 INIT_LIST_HEAD(message_list);
1010 }
1011 tipc_node_unlock(n_ptr);
1012 }
1013 read_unlock_bh(&tipc_net_lock);
1014
1015 /* discard the messages if they couldn't be sent */
1016
1017 list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) {
1018 list_del((struct list_head *)buf);
1019 buf_discard(buf);
1020 }
1021}
1022
1023/*
988 * link_send_buf_fast: Entry for data messages where the 1024 * link_send_buf_fast: Entry for data messages where the
989 * destination link is known and the header is complete, 1025 * destination link is known and the header is complete,
990 * inclusive total message length. Very time critical. 1026 * inclusive total message length. Very time critical.
@@ -1031,9 +1067,6 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1031 u32 selector = msg_origport(buf_msg(buf)) & 1; 1067 u32 selector = msg_origport(buf_msg(buf)) & 1;
1032 u32 dummy; 1068 u32 dummy;
1033 1069
1034 if (destnode == tipc_own_addr)
1035 return tipc_port_recv_msg(buf);
1036
1037 read_lock_bh(&tipc_net_lock); 1070 read_lock_bh(&tipc_net_lock);
1038 n_ptr = tipc_node_find(destnode); 1071 n_ptr = tipc_node_find(destnode);
1039 if (likely(n_ptr)) { 1072 if (likely(n_ptr)) {
@@ -1658,19 +1691,12 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1658 continue; 1691 continue;
1659 } 1692 }
1660 1693
1694 /* Discard unicast link messages destined for another node */
1695
1661 if (unlikely(!msg_short(msg) && 1696 if (unlikely(!msg_short(msg) &&
1662 (msg_destnode(msg) != tipc_own_addr))) 1697 (msg_destnode(msg) != tipc_own_addr)))
1663 goto cont; 1698 goto cont;
1664 1699
1665 /* Discard non-routeable messages destined for another node */
1666
1667 if (unlikely(!msg_isdata(msg) &&
1668 (msg_destnode(msg) != tipc_own_addr))) {
1669 if ((msg_user(msg) != CONN_MANAGER) &&
1670 (msg_user(msg) != MSG_FRAGMENTER))
1671 goto cont;
1672 }
1673
1674 /* Locate neighboring node that sent message */ 1700 /* Locate neighboring node that sent message */
1675 1701
1676 n_ptr = tipc_node_find(msg_prevnode(msg)); 1702 n_ptr = tipc_node_find(msg_prevnode(msg));
@@ -1678,17 +1704,24 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1678 goto cont; 1704 goto cont;
1679 tipc_node_lock(n_ptr); 1705 tipc_node_lock(n_ptr);
1680 1706
1681 /* Don't talk to neighbor during cleanup after last session */ 1707 /* Locate unicast link endpoint that should handle message */
1682 1708
1683 if (n_ptr->cleanup_required) { 1709 l_ptr = n_ptr->links[b_ptr->identity];
1710 if (unlikely(!l_ptr)) {
1684 tipc_node_unlock(n_ptr); 1711 tipc_node_unlock(n_ptr);
1685 goto cont; 1712 goto cont;
1686 } 1713 }
1687 1714
1688 /* Locate unicast link endpoint that should handle message */ 1715 /* Verify that communication with node is currently allowed */
1689 1716
1690 l_ptr = n_ptr->links[b_ptr->identity]; 1717 if ((n_ptr->block_setup & WAIT_PEER_DOWN) &&
1691 if (unlikely(!l_ptr)) { 1718 msg_user(msg) == LINK_PROTOCOL &&
1719 (msg_type(msg) == RESET_MSG ||
1720 msg_type(msg) == ACTIVATE_MSG) &&
1721 !msg_redundant_link(msg))
1722 n_ptr->block_setup &= ~WAIT_PEER_DOWN;
1723
1724 if (n_ptr->block_setup) {
1692 tipc_node_unlock(n_ptr); 1725 tipc_node_unlock(n_ptr);
1693 goto cont; 1726 goto cont;
1694 } 1727 }
@@ -1923,6 +1956,12 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
1923 1956
1924 if (link_blocked(l_ptr)) 1957 if (link_blocked(l_ptr))
1925 return; 1958 return;
1959
1960 /* Abort non-RESET send if communication with node is prohibited */
1961
1962 if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG))
1963 return;
1964
1926 msg_set_type(msg, msg_typ); 1965 msg_set_type(msg, msg_typ);
1927 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane); 1966 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);
1928 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in)); 1967 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in));
@@ -2051,9 +2090,19 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2051 case RESET_MSG: 2090 case RESET_MSG:
2052 if (!link_working_unknown(l_ptr) && 2091 if (!link_working_unknown(l_ptr) &&
2053 (l_ptr->peer_session != INVALID_SESSION)) { 2092 (l_ptr->peer_session != INVALID_SESSION)) {
2054 if (msg_session(msg) == l_ptr->peer_session) 2093 if (less_eq(msg_session(msg), l_ptr->peer_session))
2055 break; /* duplicate: ignore */ 2094 break; /* duplicate or old reset: ignore */
2095 }
2096
2097 if (!msg_redundant_link(msg) && (link_working_working(l_ptr) ||
2098 link_working_unknown(l_ptr))) {
2099 /*
2100 * peer has lost contact -- don't allow peer's links
2101 * to reactivate before we recognize loss & clean up
2102 */
2103 l_ptr->owner->block_setup = WAIT_NODE_DOWN;
2056 } 2104 }
2105
2057 /* fall thru' */ 2106 /* fall thru' */
2058 case ACTIVATE_MSG: 2107 case ACTIVATE_MSG:
2059 /* Update link settings according other endpoint's values */ 2108 /* Update link settings according other endpoint's values */
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 74fbecab1ea0..e56cb532913e 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -223,6 +223,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s
223struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space); 223struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space);
224void tipc_link_reset(struct link *l_ptr); 224void tipc_link_reset(struct link *l_ptr);
225int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector); 225int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
226void tipc_link_send_names(struct list_head *message_list, u32 dest);
226int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf); 227int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf);
227u32 tipc_link_get_max_pkt(u32 dest, u32 selector); 228u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
228int tipc_link_send_sections_fast(struct tipc_port *sender, 229int tipc_link_send_sections_fast(struct tipc_port *sender,
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index cd356e504332..b7ca1bd7b151 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -173,18 +173,40 @@ void tipc_named_withdraw(struct publication *publ)
173 * tipc_named_node_up - tell specified node about all publications by this node 173 * tipc_named_node_up - tell specified node about all publications by this node
174 */ 174 */
175 175
176void tipc_named_node_up(unsigned long node) 176void tipc_named_node_up(unsigned long nodearg)
177{ 177{
178 struct tipc_node *n_ptr;
179 struct link *l_ptr;
178 struct publication *publ; 180 struct publication *publ;
179 struct distr_item *item = NULL; 181 struct distr_item *item = NULL;
180 struct sk_buff *buf = NULL; 182 struct sk_buff *buf = NULL;
183 struct list_head message_list;
184 u32 node = (u32)nodearg;
181 u32 left = 0; 185 u32 left = 0;
182 u32 rest; 186 u32 rest;
183 u32 max_item_buf; 187 u32 max_item_buf = 0;
188
189 /* compute maximum amount of publication data to send per message */
190
191 read_lock_bh(&tipc_net_lock);
192 n_ptr = tipc_node_find(node);
193 if (n_ptr) {
194 tipc_node_lock(n_ptr);
195 l_ptr = n_ptr->active_links[0];
196 if (l_ptr)
197 max_item_buf = ((l_ptr->max_pkt - INT_H_SIZE) /
198 ITEM_SIZE) * ITEM_SIZE;
199 tipc_node_unlock(n_ptr);
200 }
201 read_unlock_bh(&tipc_net_lock);
202 if (!max_item_buf)
203 return;
204
205 /* create list of publication messages, then send them as a unit */
206
207 INIT_LIST_HEAD(&message_list);
184 208
185 read_lock_bh(&tipc_nametbl_lock); 209 read_lock_bh(&tipc_nametbl_lock);
186 max_item_buf = TIPC_MAX_USER_MSG_SIZE / ITEM_SIZE;
187 max_item_buf *= ITEM_SIZE;
188 rest = publ_cnt * ITEM_SIZE; 210 rest = publ_cnt * ITEM_SIZE;
189 211
190 list_for_each_entry(publ, &publ_root, local_list) { 212 list_for_each_entry(publ, &publ_root, local_list) {
@@ -202,13 +224,14 @@ void tipc_named_node_up(unsigned long node)
202 item++; 224 item++;
203 left -= ITEM_SIZE; 225 left -= ITEM_SIZE;
204 if (!left) { 226 if (!left) {
205 msg_set_link_selector(buf_msg(buf), node); 227 list_add_tail((struct list_head *)buf, &message_list);
206 tipc_link_send(buf, node, node);
207 buf = NULL; 228 buf = NULL;
208 } 229 }
209 } 230 }
210exit: 231exit:
211 read_unlock_bh(&tipc_nametbl_lock); 232 read_unlock_bh(&tipc_nametbl_lock);
233
234 tipc_link_send_names(&message_list, (u32)node);
212} 235}
213 236
214/** 237/**
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 68b3dd637291..fafef6c3c0f6 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -141,17 +141,6 @@ void tipc_net_route_msg(struct sk_buff *buf)
141 return; 141 return;
142 msg = buf_msg(buf); 142 msg = buf_msg(buf);
143 143
144 msg_incr_reroute_cnt(msg);
145 if (msg_reroute_cnt(msg) > 6) {
146 if (msg_errcode(msg)) {
147 buf_discard(buf);
148 } else {
149 tipc_reject_msg(buf, msg_destport(msg) ?
150 TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME);
151 }
152 return;
153 }
154
155 /* Handle message for this node */ 144 /* Handle message for this node */
156 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); 145 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg);
157 if (tipc_in_scope(dnode, tipc_own_addr)) { 146 if (tipc_in_scope(dnode, tipc_own_addr)) {
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 2d106ef4fa4c..27b4bb0cca6c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -112,6 +112,7 @@ struct tipc_node *tipc_node_create(u32 addr)
112 break; 112 break;
113 } 113 }
114 list_add_tail(&n_ptr->list, &temp_node->list); 114 list_add_tail(&n_ptr->list, &temp_node->list);
115 n_ptr->block_setup = WAIT_PEER_DOWN;
115 116
116 tipc_num_nodes++; 117 tipc_num_nodes++;
117 118
@@ -312,7 +313,7 @@ static void node_established_contact(struct tipc_node *n_ptr)
312 } 313 }
313} 314}
314 315
315static void node_cleanup_finished(unsigned long node_addr) 316static void node_name_purge_complete(unsigned long node_addr)
316{ 317{
317 struct tipc_node *n_ptr; 318 struct tipc_node *n_ptr;
318 319
@@ -320,7 +321,7 @@ static void node_cleanup_finished(unsigned long node_addr)
320 n_ptr = tipc_node_find(node_addr); 321 n_ptr = tipc_node_find(node_addr);
321 if (n_ptr) { 322 if (n_ptr) {
322 tipc_node_lock(n_ptr); 323 tipc_node_lock(n_ptr);
323 n_ptr->cleanup_required = 0; 324 n_ptr->block_setup &= ~WAIT_NAMES_GONE;
324 tipc_node_unlock(n_ptr); 325 tipc_node_unlock(n_ptr);
325 } 326 }
326 read_unlock_bh(&tipc_net_lock); 327 read_unlock_bh(&tipc_net_lock);
@@ -331,28 +332,32 @@ static void node_lost_contact(struct tipc_node *n_ptr)
331 char addr_string[16]; 332 char addr_string[16];
332 u32 i; 333 u32 i;
333 334
334 /* Clean up broadcast reception remains */ 335 info("Lost contact with %s\n",
335 n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0; 336 tipc_addr_string_fill(addr_string, n_ptr->addr));
336 while (n_ptr->bclink.deferred_head) { 337
337 struct sk_buff *buf = n_ptr->bclink.deferred_head; 338 /* Flush broadcast link info associated with lost node */
338 n_ptr->bclink.deferred_head = buf->next;
339 buf_discard(buf);
340 }
341 if (n_ptr->bclink.defragm) {
342 buf_discard(n_ptr->bclink.defragm);
343 n_ptr->bclink.defragm = NULL;
344 }
345 339
346 if (n_ptr->bclink.supported) { 340 if (n_ptr->bclink.supported) {
341 n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;
342 while (n_ptr->bclink.deferred_head) {
343 struct sk_buff *buf = n_ptr->bclink.deferred_head;
344 n_ptr->bclink.deferred_head = buf->next;
345 buf_discard(buf);
346 }
347
348 if (n_ptr->bclink.defragm) {
349 buf_discard(n_ptr->bclink.defragm);
350 n_ptr->bclink.defragm = NULL;
351 }
352
353 tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);
347 tipc_bclink_acknowledge(n_ptr, 354 tipc_bclink_acknowledge(n_ptr,
348 mod(n_ptr->bclink.acked + 10000)); 355 mod(n_ptr->bclink.acked + 10000));
349 tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);
350 if (n_ptr->addr < tipc_own_addr) 356 if (n_ptr->addr < tipc_own_addr)
351 tipc_own_tag--; 357 tipc_own_tag--;
352 }
353 358
354 info("Lost contact with %s\n", 359 n_ptr->bclink.supported = 0;
355 tipc_addr_string_fill(addr_string, n_ptr->addr)); 360 }
356 361
357 /* Abort link changeover */ 362 /* Abort link changeover */
358 for (i = 0; i < MAX_BEARERS; i++) { 363 for (i = 0; i < MAX_BEARERS; i++) {
@@ -367,10 +372,10 @@ static void node_lost_contact(struct tipc_node *n_ptr)
367 /* Notify subscribers */ 372 /* Notify subscribers */
368 tipc_nodesub_notify(n_ptr); 373 tipc_nodesub_notify(n_ptr);
369 374
370 /* Prevent re-contact with node until all cleanup is done */ 375 /* Prevent re-contact with node until cleanup is done */
371 376
372 n_ptr->cleanup_required = 1; 377 n_ptr->block_setup = WAIT_PEER_DOWN | WAIT_NAMES_GONE;
373 tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr); 378 tipc_k_signal((Handler)node_name_purge_complete, n_ptr->addr);
374} 379}
375 380
376struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) 381struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 5c61afc7a0b9..4f15cb40aaa4 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -42,6 +42,12 @@
42#include "net.h" 42#include "net.h"
43#include "bearer.h" 43#include "bearer.h"
44 44
45/* Flags used to block (re)establishment of contact with a neighboring node */
46
47#define WAIT_PEER_DOWN 0x0001 /* wait to see that peer's links are down */
48#define WAIT_NAMES_GONE 0x0002 /* wait for peer's publications to be purged */
49#define WAIT_NODE_DOWN 0x0004 /* wait until peer node is declared down */
50
45/** 51/**
46 * struct tipc_node - TIPC node structure 52 * struct tipc_node - TIPC node structure
47 * @addr: network address of node 53 * @addr: network address of node
@@ -52,7 +58,7 @@
52 * @active_links: pointers to active links to node 58 * @active_links: pointers to active links to node
53 * @links: pointers to all links to node 59 * @links: pointers to all links to node
54 * @working_links: number of working links to node (both active and standby) 60 * @working_links: number of working links to node (both active and standby)
55 * @cleanup_required: non-zero if cleaning up after a prior loss of contact 61 * @block_setup: bit mask of conditions preventing link establishment to node
56 * @link_cnt: number of links to node 62 * @link_cnt: number of links to node
57 * @permit_changeover: non-zero if node has redundant links to this system 63 * @permit_changeover: non-zero if node has redundant links to this system
58 * @bclink: broadcast-related info 64 * @bclink: broadcast-related info
@@ -77,7 +83,7 @@ struct tipc_node {
77 struct link *links[MAX_BEARERS]; 83 struct link *links[MAX_BEARERS];
78 int link_cnt; 84 int link_cnt;
79 int working_links; 85 int working_links;
80 int cleanup_required; 86 int block_setup;
81 int permit_changeover; 87 int permit_changeover;
82 struct { 88 struct {
83 int supported; 89 int supported;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index adb2eff4a102..9440a3d48ca0 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -49,7 +49,7 @@ struct tipc_sock {
49 struct sock sk; 49 struct sock sk;
50 struct tipc_port *p; 50 struct tipc_port *p;
51 struct tipc_portid peer_name; 51 struct tipc_portid peer_name;
52 long conn_timeout; 52 unsigned int conn_timeout;
53}; 53};
54 54
55#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 55#define tipc_sk(sk) ((struct tipc_sock *)(sk))
@@ -231,7 +231,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
231 sock_init_data(sock, sk); 231 sock_init_data(sock, sk);
232 sk->sk_backlog_rcv = backlog_rcv; 232 sk->sk_backlog_rcv = backlog_rcv;
233 tipc_sk(sk)->p = tp_ptr; 233 tipc_sk(sk)->p = tp_ptr;
234 tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); 234 tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT;
235 235
236 spin_unlock_bh(tp_ptr->lock); 236 spin_unlock_bh(tp_ptr->lock);
237 237
@@ -525,6 +525,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
525 struct tipc_port *tport = tipc_sk_port(sk); 525 struct tipc_port *tport = tipc_sk_port(sk);
526 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; 526 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;
527 int needs_conn; 527 int needs_conn;
528 long timeout_val;
528 int res = -EINVAL; 529 int res = -EINVAL;
529 530
530 if (unlikely(!dest)) 531 if (unlikely(!dest))
@@ -564,6 +565,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
564 reject_rx_queue(sk); 565 reject_rx_queue(sk);
565 } 566 }
566 567
568 timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
569
567 do { 570 do {
568 if (dest->addrtype == TIPC_ADDR_NAME) { 571 if (dest->addrtype == TIPC_ADDR_NAME) {
569 res = dest_name_check(dest, m); 572 res = dest_name_check(dest, m);
@@ -600,16 +603,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
600 sock->state = SS_CONNECTING; 603 sock->state = SS_CONNECTING;
601 break; 604 break;
602 } 605 }
603 if (m->msg_flags & MSG_DONTWAIT) { 606 if (timeout_val <= 0L) {
604 res = -EWOULDBLOCK; 607 res = timeout_val ? timeout_val : -EWOULDBLOCK;
605 break; 608 break;
606 } 609 }
607 release_sock(sk); 610 release_sock(sk);
608 res = wait_event_interruptible(*sk_sleep(sk), 611 timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk),
609 !tport->congested); 612 !tport->congested, timeout_val);
610 lock_sock(sk); 613 lock_sock(sk);
611 if (res)
612 break;
613 } while (1); 614 } while (1);
614 615
615exit: 616exit:
@@ -636,6 +637,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
636 struct sock *sk = sock->sk; 637 struct sock *sk = sock->sk;
637 struct tipc_port *tport = tipc_sk_port(sk); 638 struct tipc_port *tport = tipc_sk_port(sk);
638 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; 639 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;
640 long timeout_val;
639 int res; 641 int res;
640 642
641 /* Handle implied connection establishment */ 643 /* Handle implied connection establishment */
@@ -650,6 +652,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
650 if (iocb) 652 if (iocb)
651 lock_sock(sk); 653 lock_sock(sk);
652 654
655 timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
656
653 do { 657 do {
654 if (unlikely(sock->state != SS_CONNECTED)) { 658 if (unlikely(sock->state != SS_CONNECTED)) {
655 if (sock->state == SS_DISCONNECTING) 659 if (sock->state == SS_DISCONNECTING)
@@ -663,16 +667,14 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
663 total_len); 667 total_len);
664 if (likely(res != -ELINKCONG)) 668 if (likely(res != -ELINKCONG))
665 break; 669 break;
666 if (m->msg_flags & MSG_DONTWAIT) { 670 if (timeout_val <= 0L) {
667 res = -EWOULDBLOCK; 671 res = timeout_val ? timeout_val : -EWOULDBLOCK;
668 break; 672 break;
669 } 673 }
670 release_sock(sk); 674 release_sock(sk);
671 res = wait_event_interruptible(*sk_sleep(sk), 675 timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk),
672 (!tport->congested || !tport->connected)); 676 (!tport->congested || !tport->connected), timeout_val);
673 lock_sock(sk); 677 lock_sock(sk);
674 if (res)
675 break;
676 } while (1); 678 } while (1);
677 679
678 if (iocb) 680 if (iocb)
@@ -1369,7 +1371,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1369 struct msghdr m = {NULL,}; 1371 struct msghdr m = {NULL,};
1370 struct sk_buff *buf; 1372 struct sk_buff *buf;
1371 struct tipc_msg *msg; 1373 struct tipc_msg *msg;
1372 long timeout; 1374 unsigned int timeout;
1373 int res; 1375 int res;
1374 1376
1375 lock_sock(sk); 1377 lock_sock(sk);
@@ -1434,7 +1436,8 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1434 res = wait_event_interruptible_timeout(*sk_sleep(sk), 1436 res = wait_event_interruptible_timeout(*sk_sleep(sk),
1435 (!skb_queue_empty(&sk->sk_receive_queue) || 1437 (!skb_queue_empty(&sk->sk_receive_queue) ||
1436 (sock->state != SS_CONNECTING)), 1438 (sock->state != SS_CONNECTING)),
1437 timeout ? timeout : MAX_SCHEDULE_TIMEOUT); 1439 timeout ? (long)msecs_to_jiffies(timeout)
1440 : MAX_SCHEDULE_TIMEOUT);
1438 lock_sock(sk); 1441 lock_sock(sk);
1439 1442
1440 if (res > 0) { 1443 if (res > 0) {
@@ -1480,9 +1483,7 @@ static int listen(struct socket *sock, int len)
1480 1483
1481 lock_sock(sk); 1484 lock_sock(sk);
1482 1485
1483 if (sock->state == SS_READY) 1486 if (sock->state != SS_UNCONNECTED)
1484 res = -EOPNOTSUPP;
1485 else if (sock->state != SS_UNCONNECTED)
1486 res = -EINVAL; 1487 res = -EINVAL;
1487 else { 1488 else {
1488 sock->state = SS_LISTENING; 1489 sock->state = SS_LISTENING;
@@ -1510,10 +1511,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1510 1511
1511 lock_sock(sk); 1512 lock_sock(sk);
1512 1513
1513 if (sock->state == SS_READY) {
1514 res = -EOPNOTSUPP;
1515 goto exit;
1516 }
1517 if (sock->state != SS_LISTENING) { 1514 if (sock->state != SS_LISTENING) {
1518 res = -EINVAL; 1515 res = -EINVAL;
1519 goto exit; 1516 goto exit;
@@ -1696,7 +1693,7 @@ static int setsockopt(struct socket *sock,
1696 res = tipc_set_portunreturnable(tport->ref, value); 1693 res = tipc_set_portunreturnable(tport->ref, value);
1697 break; 1694 break;
1698 case TIPC_CONN_TIMEOUT: 1695 case TIPC_CONN_TIMEOUT:
1699 tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value); 1696 tipc_sk(sk)->conn_timeout = value;
1700 /* no need to set "res", since already 0 at this point */ 1697 /* no need to set "res", since already 0 at this point */
1701 break; 1698 break;
1702 default: 1699 default:
@@ -1752,7 +1749,7 @@ static int getsockopt(struct socket *sock,
1752 res = tipc_portunreturnable(tport->ref, &value); 1749 res = tipc_portunreturnable(tport->ref, &value);
1753 break; 1750 break;
1754 case TIPC_CONN_TIMEOUT: 1751 case TIPC_CONN_TIMEOUT:
1755 value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); 1752 value = tipc_sk(sk)->conn_timeout;
1756 /* no need to set "res", since already 0 at this point */ 1753 /* no need to set "res", since already 0 at this point */
1757 break; 1754 break;
1758 case TIPC_NODE_RECVQ_DEPTH: 1755 case TIPC_NODE_RECVQ_DEPTH:
@@ -1790,11 +1787,11 @@ static const struct proto_ops msg_ops = {
1790 .bind = bind, 1787 .bind = bind,
1791 .connect = connect, 1788 .connect = connect,
1792 .socketpair = sock_no_socketpair, 1789 .socketpair = sock_no_socketpair,
1793 .accept = accept, 1790 .accept = sock_no_accept,
1794 .getname = get_name, 1791 .getname = get_name,
1795 .poll = poll, 1792 .poll = poll,
1796 .ioctl = sock_no_ioctl, 1793 .ioctl = sock_no_ioctl,
1797 .listen = listen, 1794 .listen = sock_no_listen,
1798 .shutdown = shutdown, 1795 .shutdown = shutdown,
1799 .setsockopt = setsockopt, 1796 .setsockopt = setsockopt,
1800 .getsockopt = getsockopt, 1797 .getsockopt = getsockopt,
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 6cf726863485..198371723b41 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -151,7 +151,7 @@ void tipc_subscr_report_overlap(struct subscription *sub,
151 if (!must && !(sub->filter & TIPC_SUB_PORTS)) 151 if (!must && !(sub->filter & TIPC_SUB_PORTS))
152 return; 152 return;
153 153
154 sub->event_cb(sub, found_lower, found_upper, event, port_ref, node); 154 subscr_send_event(sub, found_lower, found_upper, event, port_ref, node);
155} 155}
156 156
157/** 157/**
@@ -365,7 +365,6 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
365 subscr_terminate(subscriber); 365 subscr_terminate(subscriber);
366 return NULL; 366 return NULL;
367 } 367 }
368 sub->event_cb = subscr_send_event;
369 INIT_LIST_HEAD(&sub->nameseq_list); 368 INIT_LIST_HEAD(&sub->nameseq_list);
370 list_add(&sub->subscription_list, &subscriber->subscription_list); 369 list_add(&sub->subscription_list, &subscriber->subscription_list);
371 sub->server_ref = subscriber->port_ref; 370 sub->server_ref = subscriber->port_ref;
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 45d89bf4d202..4b06ef6f8401 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -39,16 +39,11 @@
39 39
40struct subscription; 40struct subscription;
41 41
42typedef void (*tipc_subscr_event) (struct subscription *sub,
43 u32 found_lower, u32 found_upper,
44 u32 event, u32 port_ref, u32 node);
45
46/** 42/**
47 * struct subscription - TIPC network topology subscription object 43 * struct subscription - TIPC network topology subscription object
48 * @seq: name sequence associated with subscription 44 * @seq: name sequence associated with subscription
49 * @timeout: duration of subscription (in ms) 45 * @timeout: duration of subscription (in ms)
50 * @filter: event filtering to be done for subscription 46 * @filter: event filtering to be done for subscription
51 * @event_cb: routine invoked when a subscription event is detected
52 * @timer: timer governing subscription duration (optional) 47 * @timer: timer governing subscription duration (optional)
53 * @nameseq_list: adjacent subscriptions in name sequence's subscription list 48 * @nameseq_list: adjacent subscriptions in name sequence's subscription list
54 * @subscription_list: adjacent subscriptions in subscriber's subscription list 49 * @subscription_list: adjacent subscriptions in subscriber's subscription list
@@ -61,7 +56,6 @@ struct subscription {
61 struct tipc_name_seq seq; 56 struct tipc_name_seq seq;
62 u32 timeout; 57 u32 timeout;
63 u32 filter; 58 u32 filter;
64 tipc_subscr_event event_cb;
65 struct timer_list timer; 59 struct timer_list timer;
66 struct list_head nameseq_list; 60 struct list_head nameseq_list;
67 struct list_head subscription_list; 61 struct list_head subscription_list;