aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/Kconfig47
-rw-r--r--net/tipc/Makefile4
-rw-r--r--net/tipc/addr.c25
-rw-r--r--net/tipc/addr.h30
-rw-r--r--net/tipc/bcast.c97
-rw-r--r--net/tipc/bcast.h4
-rw-r--r--net/tipc/bearer.c136
-rw-r--r--net/tipc/bearer.h102
-rw-r--r--net/tipc/cluster.c557
-rw-r--r--net/tipc/cluster.h92
-rw-r--r--net/tipc/config.c149
-rw-r--r--net/tipc/config.h1
-rw-r--r--net/tipc/core.c110
-rw-r--r--net/tipc/core.h80
-rw-r--r--net/tipc/discover.c150
-rw-r--r--net/tipc/discover.h11
-rw-r--r--net/tipc/eth_media.c15
-rw-r--r--net/tipc/handler.c2
-rw-r--r--net/tipc/link.c507
-rw-r--r--net/tipc/link.h37
-rw-r--r--net/tipc/log.c (renamed from net/tipc/dbg.c)111
-rw-r--r--net/tipc/log.h (renamed from net/tipc/dbg.h)6
-rw-r--r--net/tipc/msg.c100
-rw-r--r--net/tipc/msg.h229
-rw-r--r--net/tipc/name_distr.c59
-rw-r--r--net/tipc/name_table.c60
-rw-r--r--net/tipc/name_table.h2
-rw-r--r--net/tipc/net.c76
-rw-r--r--net/tipc/net.h19
-rw-r--r--net/tipc/node.c362
-rw-r--r--net/tipc/node.h61
-rw-r--r--net/tipc/node_subscr.c23
-rw-r--r--net/tipc/node_subscr.h3
-rw-r--r--net/tipc/port.c470
-rw-r--r--net/tipc/port.h174
-rw-r--r--net/tipc/ref.c8
-rw-r--r--net/tipc/socket.c231
-rw-r--r--net/tipc/subscr.c51
-rw-r--r--net/tipc/user_reg.c264
-rw-r--r--net/tipc/user_reg.h48
-rw-r--r--net/tipc/zone.c162
-rw-r--r--net/tipc/zone.h70
42 files changed, 1326 insertions, 3419 deletions
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index b74f78d0c033..2c5954b85933 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -29,40 +29,6 @@ config TIPC_ADVANCED
29 Saying Y here will open some advanced configuration for TIPC. 29 Saying Y here will open some advanced configuration for TIPC.
30 Most users do not need to bother; if unsure, just say N. 30 Most users do not need to bother; if unsure, just say N.
31 31
32config TIPC_ZONES
33 int "Maximum number of zones in a network"
34 depends on TIPC_ADVANCED
35 range 1 255
36 default "3"
37 help
38 Specifies how many zones can be supported in a TIPC network.
39 Can range from 1 to 255 zones; default is 3.
40
41 Setting this to a smaller value saves some memory;
42 setting it to a higher value allows for more zones.
43
44config TIPC_CLUSTERS
45 int "Maximum number of clusters in a zone"
46 depends on TIPC_ADVANCED
47 range 1 1
48 default "1"
49 help
50 Specifies how many clusters can be supported in a TIPC zone.
51
52 *** Currently TIPC only supports a single cluster per zone. ***
53
54config TIPC_NODES
55 int "Maximum number of nodes in a cluster"
56 depends on TIPC_ADVANCED
57 range 8 2047
58 default "255"
59 help
60 Specifies how many nodes can be supported in a TIPC cluster.
61 Can range from 8 to 2047 nodes; default is 255.
62
63 Setting this to a smaller value saves some memory;
64 setting it to higher allows for more nodes.
65
66config TIPC_PORTS 32config TIPC_PORTS
67 int "Maximum number of ports in a node" 33 int "Maximum number of ports in a node"
68 depends on TIPC_ADVANCED 34 depends on TIPC_ADVANCED
@@ -72,7 +38,7 @@ config TIPC_PORTS
72 Specifies how many ports can be supported by a node. 38 Specifies how many ports can be supported by a node.
73 Can range from 127 to 65535 ports; default is 8191. 39 Can range from 127 to 65535 ports; default is 8191.
74 40
75 Setting this to a smaller value saves some memory, 41 Setting this to a smaller value saves some memory,
76 setting it to higher allows for more ports. 42 setting it to higher allows for more ports.
77 43
78config TIPC_LOG 44config TIPC_LOG
@@ -89,12 +55,15 @@ config TIPC_LOG
89 managed remotely via TIPC. 55 managed remotely via TIPC.
90 56
91config TIPC_DEBUG 57config TIPC_DEBUG
92 bool "Enable debug messages" 58 bool "Enable debugging support"
93 default n 59 default n
94 help 60 help
95 This enables debugging of TIPC. 61 Saying Y here enables TIPC debugging capabilities used by developers.
62 Most users do not need to bother; if unsure, just say N.
96 63
97 Only say Y here if you are having trouble with TIPC. It will 64 Enabling debugging support causes TIPC to display data about its
98 enable the display of detailed information about what is going on. 65 internal state when certain abnormal conditions occur. It also
66 makes it easy for developers to capture additional information of
67 interest using the dbg() or msg_dbg() macros.
99 68
100endif # TIPC 69endif # TIPC
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index dceb7027946c..521d24d04ab2 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -4,10 +4,10 @@
4 4
5obj-$(CONFIG_TIPC) := tipc.o 5obj-$(CONFIG_TIPC) := tipc.o
6 6
7tipc-y += addr.o bcast.o bearer.o config.o cluster.o \ 7tipc-y += addr.o bcast.o bearer.o config.o \
8 core.o handler.o link.o discover.o msg.o \ 8 core.o handler.o link.o discover.o msg.o \
9 name_distr.o subscr.o name_table.o net.o \ 9 name_distr.o subscr.o name_table.o net.o \
10 netlink.o node.o node_subscr.o port.o ref.o \ 10 netlink.o node.o node_subscr.o port.o ref.o \
11 socket.o user_reg.o zone.o dbg.o eth_media.o 11 socket.o log.o eth_media.o
12 12
13# End of file 13# End of file
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 8a2e89bffde5..a6fdab33877e 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -2,7 +2,7 @@
2 * net/tipc/addr.c: TIPC address utility routines 2 * net/tipc/addr.c: TIPC address utility routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-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
@@ -35,17 +35,13 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "addr.h" 38#include "addr.h"
40#include "zone.h"
41#include "cluster.h"
42#include "net.h"
43 39
44/** 40/**
45 * tipc_addr_domain_valid - validates a network domain address 41 * tipc_addr_domain_valid - validates a network domain address
46 * 42 *
47 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>, 43 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>,
48 * where Z, C, and N are non-zero and do not exceed the configured limits. 44 * where Z, C, and N are non-zero.
49 * 45 *
50 * Returns 1 if domain address is valid, otherwise 0 46 * Returns 1 if domain address is valid, otherwise 0
51 */ 47 */
@@ -55,16 +51,6 @@ int tipc_addr_domain_valid(u32 addr)
55 u32 n = tipc_node(addr); 51 u32 n = tipc_node(addr);
56 u32 c = tipc_cluster(addr); 52 u32 c = tipc_cluster(addr);
57 u32 z = tipc_zone(addr); 53 u32 z = tipc_zone(addr);
58 u32 max_nodes = tipc_max_nodes;
59
60 if (is_slave(addr))
61 max_nodes = LOWEST_SLAVE + tipc_max_slaves;
62 if (n > max_nodes)
63 return 0;
64 if (c > tipc_max_clusters)
65 return 0;
66 if (z > tipc_max_zones)
67 return 0;
68 54
69 if (n && (!z || !c)) 55 if (n && (!z || !c))
70 return 0; 56 return 0;
@@ -76,8 +62,7 @@ int tipc_addr_domain_valid(u32 addr)
76/** 62/**
77 * tipc_addr_node_valid - validates a proposed network address for this node 63 * tipc_addr_node_valid - validates a proposed network address for this node
78 * 64 *
79 * Accepts <Z.C.N>, where Z, C, and N are non-zero and do not exceed 65 * Accepts <Z.C.N>, where Z, C, and N are non-zero.
80 * the configured limits.
81 * 66 *
82 * Returns 1 if address can be used, otherwise 0 67 * Returns 1 if address can be used, otherwise 0
83 */ 68 */
@@ -91,9 +76,9 @@ int tipc_in_scope(u32 domain, u32 addr)
91{ 76{
92 if (!domain || (domain == addr)) 77 if (!domain || (domain == addr))
93 return 1; 78 return 1;
94 if (domain == (addr & 0xfffff000u)) /* domain <Z.C.0> */ 79 if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */
95 return 1; 80 return 1;
96 if (domain == (addr & 0xff000000u)) /* domain <Z.0.0> */ 81 if (domain == tipc_zone_mask(addr)) /* domain <Z.0.0> */
97 return 1; 82 return 1;
98 return 0; 83 return 0;
99} 84}
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index c1cc5724d8cc..8971aba99aea 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,19 +37,14 @@
37#ifndef _TIPC_ADDR_H 37#ifndef _TIPC_ADDR_H
38#define _TIPC_ADDR_H 38#define _TIPC_ADDR_H
39 39
40static inline u32 own_node(void) 40static inline u32 tipc_zone_mask(u32 addr)
41{ 41{
42 return tipc_node(tipc_own_addr); 42 return addr & 0xff000000u;
43} 43}
44 44
45static inline u32 own_cluster(void) 45static inline u32 tipc_cluster_mask(u32 addr)
46{ 46{
47 return tipc_cluster(tipc_own_addr); 47 return addr & 0xfffff000u;
48}
49
50static inline u32 own_zone(void)
51{
52 return tipc_zone(tipc_own_addr);
53} 48}
54 49
55static inline int in_own_cluster(u32 addr) 50static inline int in_own_cluster(u32 addr)
@@ -57,16 +52,6 @@ static inline int in_own_cluster(u32 addr)
57 return !((addr ^ tipc_own_addr) >> 12); 52 return !((addr ^ tipc_own_addr) >> 12);
58} 53}
59 54
60static inline int is_slave(u32 addr)
61{
62 return addr & 0x800;
63}
64
65static inline int may_route(u32 addr)
66{
67 return(addr ^ tipc_own_addr) >> 11;
68}
69
70/** 55/**
71 * addr_domain - convert 2-bit scope value to equivalent message lookup domain 56 * addr_domain - convert 2-bit scope value to equivalent message lookup domain
72 * 57 *
@@ -74,14 +59,13 @@ static inline int may_route(u32 addr)
74 * after a network hop. 59 * after a network hop.
75 */ 60 */
76 61
77static inline int addr_domain(int sc) 62static inline u32 addr_domain(u32 sc)
78{ 63{
79 if (likely(sc == TIPC_NODE_SCOPE)) 64 if (likely(sc == TIPC_NODE_SCOPE))
80 return tipc_own_addr; 65 return tipc_own_addr;
81 if (sc == TIPC_CLUSTER_SCOPE) 66 if (sc == TIPC_CLUSTER_SCOPE)
82 return tipc_addr(tipc_zone(tipc_own_addr), 67 return tipc_cluster_mask(tipc_own_addr);
83 tipc_cluster(tipc_own_addr), 0); 68 return tipc_zone_mask(tipc_own_addr);
84 return tipc_addr(tipc_zone(tipc_own_addr), 0, 0);
85} 69}
86 70
87int tipc_addr_domain_valid(u32); 71int tipc_addr_domain_valid(u32);
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 22a60fc98392..7dc1dc7151ea 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004-2006, Ericsson AB 4 * Copyright (c) 2004-2006, Ericsson AB
5 * Copyright (c) 2004, Intel Corporation. 5 * Copyright (c) 2004, Intel Corporation.
6 * Copyright (c) 2005, Wind River Systems 6 * Copyright (c) 2005, 2010-2011, Wind River Systems
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
@@ -36,25 +36,14 @@
36 */ 36 */
37 37
38#include "core.h" 38#include "core.h"
39#include "msg.h"
40#include "dbg.h"
41#include "link.h" 39#include "link.h"
42#include "net.h"
43#include "node.h"
44#include "port.h" 40#include "port.h"
45#include "addr.h"
46#include "node_subscr.h"
47#include "name_distr.h"
48#include "bearer.h"
49#include "name_table.h"
50#include "bcast.h" 41#include "bcast.h"
51 42
52#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ 43#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */
53 44
54#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ 45#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */
55 46
56#define BCLINK_LOG_BUF_SIZE 0
57
58/* 47/*
59 * Loss rate for incoming broadcast frames; used to test retransmission code. 48 * Loss rate for incoming broadcast frames; used to test retransmission code.
60 * Set to N to cause every N'th frame to be discarded; 0 => don't discard any. 49 * Set to N to cause every N'th frame to be discarded; 0 => don't discard any.
@@ -72,8 +61,8 @@
72 */ 61 */
73 62
74struct bcbearer_pair { 63struct bcbearer_pair {
75 struct bearer *primary; 64 struct tipc_bearer *primary;
76 struct bearer *secondary; 65 struct tipc_bearer *secondary;
77}; 66};
78 67
79/** 68/**
@@ -92,7 +81,7 @@ struct bcbearer_pair {
92 */ 81 */
93 82
94struct bcbearer { 83struct bcbearer {
95 struct bearer bearer; 84 struct tipc_bearer bearer;
96 struct media media; 85 struct media media;
97 struct bcbearer_pair bpairs[MAX_BEARERS]; 86 struct bcbearer_pair bpairs[MAX_BEARERS];
98 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; 87 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
@@ -104,6 +93,7 @@ struct bcbearer {
104 * struct bclink - link used for broadcast messages 93 * struct bclink - link used for broadcast messages
105 * @link: (non-standard) broadcast link structure 94 * @link: (non-standard) broadcast link structure
106 * @node: (non-standard) node structure representing b'cast link's peer node 95 * @node: (non-standard) node structure representing b'cast link's peer node
96 * @retransmit_to: node that most recently requested a retransmit
107 * 97 *
108 * Handles sequence numbering, fragmentation, bundling, etc. 98 * Handles sequence numbering, fragmentation, bundling, etc.
109 */ 99 */
@@ -111,14 +101,18 @@ struct bcbearer {
111struct bclink { 101struct bclink {
112 struct link link; 102 struct link link;
113 struct tipc_node node; 103 struct tipc_node node;
104 struct tipc_node *retransmit_to;
114}; 105};
115 106
116 107
117static struct bcbearer *bcbearer = NULL; 108static struct bcbearer *bcbearer;
118static struct bclink *bclink = NULL; 109static struct bclink *bclink;
119static struct link *bcl = NULL; 110static struct link *bcl;
120static DEFINE_SPINLOCK(bc_lock); 111static DEFINE_SPINLOCK(bc_lock);
121 112
113/* broadcast-capable node map */
114struct tipc_node_map tipc_bcast_nmap;
115
122const char tipc_bclink_name[] = "broadcast-link"; 116const char tipc_bclink_name[] = "broadcast-link";
123 117
124static void tipc_nmap_diff(struct tipc_node_map *nm_a, 118static void tipc_nmap_diff(struct tipc_node_map *nm_a,
@@ -192,6 +186,17 @@ static int bclink_ack_allowed(u32 n)
192 186
193 187
194/** 188/**
189 * tipc_bclink_retransmit_to - get most recent node to request retransmission
190 *
191 * Called with bc_lock locked
192 */
193
194struct tipc_node *tipc_bclink_retransmit_to(void)
195{
196 return bclink->retransmit_to;
197}
198
199/**
195 * bclink_retransmit_pkt - retransmit broadcast packets 200 * bclink_retransmit_pkt - retransmit broadcast packets
196 * @after: sequence number of last packet to *not* retransmit 201 * @after: sequence number of last packet to *not* retransmit
197 * @to: sequence number of last packet to retransmit 202 * @to: sequence number of last packet to retransmit
@@ -204,9 +209,8 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
204 struct sk_buff *buf; 209 struct sk_buff *buf;
205 210
206 buf = bcl->first_out; 211 buf = bcl->first_out;
207 while (buf && less_eq(buf_seqno(buf), after)) { 212 while (buf && less_eq(buf_seqno(buf), after))
208 buf = buf->next; 213 buf = buf->next;
209 }
210 tipc_link_retransmit(bcl, buf, mod(to - after)); 214 tipc_link_retransmit(bcl, buf, mod(to - after));
211} 215}
212 216
@@ -232,9 +236,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
232 /* Skip over packets that node has previously acknowledged */ 236 /* Skip over packets that node has previously acknowledged */
233 237
234 crs = bcl->first_out; 238 crs = bcl->first_out;
235 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) { 239 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
236 crs = crs->next; 240 crs = crs->next;
237 }
238 241
239 /* Update packets that node is now acknowledging */ 242 /* Update packets that node is now acknowledging */
240 243
@@ -295,6 +298,7 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
295 msg = buf_msg(buf); 298 msg = buf_msg(buf);
296 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 299 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
297 INT_H_SIZE, n_ptr->addr); 300 INT_H_SIZE, n_ptr->addr);
301 msg_set_non_seq(msg, 1);
298 msg_set_mc_netid(msg, tipc_net_id); 302 msg_set_mc_netid(msg, tipc_net_id);
299 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 303 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
300 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); 304 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after);
@@ -415,8 +419,6 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
415 else 419 else
416 bclink_set_last_sent(); 420 bclink_set_last_sent();
417 421
418 if (bcl->out_queue_size > bcl->stats.max_queue_sz)
419 bcl->stats.max_queue_sz = bcl->out_queue_size;
420 bcl->stats.queue_sz_counts++; 422 bcl->stats.queue_sz_counts++;
421 bcl->stats.accu_queue_sz += bcl->out_queue_size; 423 bcl->stats.accu_queue_sz += bcl->out_queue_size;
422 424
@@ -433,16 +435,14 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
433void tipc_bclink_recv_pkt(struct sk_buff *buf) 435void tipc_bclink_recv_pkt(struct sk_buff *buf)
434{ 436{
435#if (TIPC_BCAST_LOSS_RATE) 437#if (TIPC_BCAST_LOSS_RATE)
436 static int rx_count = 0; 438 static int rx_count;
437#endif 439#endif
438 struct tipc_msg *msg = buf_msg(buf); 440 struct tipc_msg *msg = buf_msg(buf);
439 struct tipc_node* node = tipc_node_find(msg_prevnode(msg)); 441 struct tipc_node *node = tipc_node_find(msg_prevnode(msg));
440 u32 next_in; 442 u32 next_in;
441 u32 seqno; 443 u32 seqno;
442 struct sk_buff *deferred; 444 struct sk_buff *deferred;
443 445
444 msg_dbg(msg, "<BC<<<");
445
446 if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported || 446 if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported ||
447 (msg_mc_netid(msg) != tipc_net_id))) { 447 (msg_mc_netid(msg) != tipc_net_id))) {
448 buf_discard(buf); 448 buf_discard(buf);
@@ -450,17 +450,15 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
450 } 450 }
451 451
452 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { 452 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
453 msg_dbg(msg, "<BCNACK<<<");
454 if (msg_destnode(msg) == tipc_own_addr) { 453 if (msg_destnode(msg) == tipc_own_addr) {
455 tipc_node_lock(node); 454 tipc_node_lock(node);
456 tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); 455 tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
457 tipc_node_unlock(node); 456 tipc_node_unlock(node);
458 spin_lock_bh(&bc_lock); 457 spin_lock_bh(&bc_lock);
459 bcl->stats.recv_nacks++; 458 bcl->stats.recv_nacks++;
460 bcl->owner->next = node; /* remember requestor */ 459 bclink->retransmit_to = node;
461 bclink_retransmit_pkt(msg_bcgap_after(msg), 460 bclink_retransmit_pkt(msg_bcgap_after(msg),
462 msg_bcgap_to(msg)); 461 msg_bcgap_to(msg));
463 bcl->owner->next = NULL;
464 spin_unlock_bh(&bc_lock); 462 spin_unlock_bh(&bc_lock);
465 } else { 463 } else {
466 tipc_bclink_peek_nack(msg_destnode(msg), 464 tipc_bclink_peek_nack(msg_destnode(msg),
@@ -574,8 +572,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
574 if (likely(!msg_non_seq(buf_msg(buf)))) { 572 if (likely(!msg_non_seq(buf_msg(buf)))) {
575 struct tipc_msg *msg; 573 struct tipc_msg *msg;
576 574
577 assert(tipc_cltr_bcast_nodes.count != 0); 575 assert(tipc_bcast_nmap.count != 0);
578 bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); 576 bcbuf_set_acks(buf, tipc_bcast_nmap.count);
579 msg = buf_msg(buf); 577 msg = buf_msg(buf);
580 msg_set_non_seq(msg, 1); 578 msg_set_non_seq(msg, 1);
581 msg_set_mc_netid(msg, tipc_net_id); 579 msg_set_mc_netid(msg, tipc_net_id);
@@ -584,11 +582,11 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
584 582
585 /* Send buffer over bearers until all targets reached */ 583 /* Send buffer over bearers until all targets reached */
586 584
587 bcbearer->remains = tipc_cltr_bcast_nodes; 585 bcbearer->remains = tipc_bcast_nmap;
588 586
589 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 587 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
590 struct bearer *p = bcbearer->bpairs[bp_index].primary; 588 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;
591 struct bearer *s = bcbearer->bpairs[bp_index].secondary; 589 struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary;
592 590
593 if (!p) 591 if (!p)
594 break; /* no more bearers to try */ 592 break; /* no more bearers to try */
@@ -597,11 +595,11 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
597 if (bcbearer->remains_new.count == bcbearer->remains.count) 595 if (bcbearer->remains_new.count == bcbearer->remains.count)
598 continue; /* bearer pair doesn't add anything */ 596 continue; /* bearer pair doesn't add anything */
599 597
600 if (p->publ.blocked || 598 if (p->blocked ||
601 p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { 599 p->media->send_msg(buf, p, &p->media->bcast_addr)) {
602 /* unable to send on primary bearer */ 600 /* unable to send on primary bearer */
603 if (!s || s->publ.blocked || 601 if (!s || s->blocked ||
604 s->media->send_msg(buf, &s->publ, 602 s->media->send_msg(buf, s,
605 &s->media->bcast_addr)) { 603 &s->media->bcast_addr)) {
606 /* unable to send on either bearer */ 604 /* unable to send on either bearer */
607 continue; 605 continue;
@@ -646,7 +644,7 @@ void tipc_bcbearer_sort(void)
646 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp)); 644 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));
647 645
648 for (b_index = 0; b_index < MAX_BEARERS; b_index++) { 646 for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
649 struct bearer *b = &tipc_bearers[b_index]; 647 struct tipc_bearer *b = &tipc_bearers[b_index];
650 648
651 if (!b->active || !b->nodes.count) 649 if (!b->active || !b->nodes.count)
652 continue; 650 continue;
@@ -695,12 +693,12 @@ void tipc_bcbearer_sort(void)
695 693
696void tipc_bcbearer_push(void) 694void tipc_bcbearer_push(void)
697{ 695{
698 struct bearer *b_ptr; 696 struct tipc_bearer *b_ptr;
699 697
700 spin_lock_bh(&bc_lock); 698 spin_lock_bh(&bc_lock);
701 b_ptr = &bcbearer->bearer; 699 b_ptr = &bcbearer->bearer;
702 if (b_ptr->publ.blocked) { 700 if (b_ptr->blocked) {
703 b_ptr->publ.blocked = 0; 701 b_ptr->blocked = 0;
704 tipc_bearer_lock_push(b_ptr); 702 tipc_bearer_lock_push(b_ptr);
705 } 703 }
706 spin_unlock_bh(&bc_lock); 704 spin_unlock_bh(&bc_lock);
@@ -782,7 +780,6 @@ int tipc_bclink_init(void)
782 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); 780 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
783 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); 781 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
784 if (!bcbearer || !bclink) { 782 if (!bcbearer || !bclink) {
785 nomem:
786 warn("Multicast link creation failed, no memory\n"); 783 warn("Multicast link creation failed, no memory\n");
787 kfree(bcbearer); 784 kfree(bcbearer);
788 bcbearer = NULL; 785 bcbearer = NULL;
@@ -807,14 +804,6 @@ int tipc_bclink_init(void)
807 bcl->state = WORKING_WORKING; 804 bcl->state = WORKING_WORKING;
808 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); 805 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
809 806
810 if (BCLINK_LOG_BUF_SIZE) {
811 char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC);
812
813 if (!pb)
814 goto nomem;
815 tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE);
816 }
817
818 return 0; 807 return 0;
819} 808}
820 809
@@ -823,8 +812,6 @@ void tipc_bclink_stop(void)
823 spin_lock_bh(&bc_lock); 812 spin_lock_bh(&bc_lock);
824 if (bcbearer) { 813 if (bcbearer) {
825 tipc_link_stop(bcl); 814 tipc_link_stop(bcl);
826 if (BCLINK_LOG_BUF_SIZE)
827 kfree(bcl->print_buf.buf);
828 bcl = NULL; 815 bcl = NULL;
829 kfree(bclink); 816 kfree(bclink);
830 bclink = NULL; 817 bclink = NULL;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 011c03f0a4ab..500c97f1c859 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -2,7 +2,7 @@
2 * net/tipc/bcast.h: Include file for TIPC broadcast code 2 * net/tipc/bcast.h: Include file for TIPC broadcast code
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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
@@ -51,6 +51,7 @@ struct tipc_node_map {
51 u32 map[MAX_NODES / WSIZE]; 51 u32 map[MAX_NODES / WSIZE];
52}; 52};
53 53
54extern struct tipc_node_map tipc_bcast_nmap;
54 55
55#define PLSIZE 32 56#define PLSIZE 32
56 57
@@ -89,6 +90,7 @@ void tipc_port_list_free(struct port_list *pl_ptr);
89 90
90int tipc_bclink_init(void); 91int tipc_bclink_init(void);
91void tipc_bclink_stop(void); 92void tipc_bclink_stop(void);
93struct tipc_node *tipc_bclink_retransmit_to(void);
92void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked); 94void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
93int tipc_bclink_send_msg(struct sk_buff *buf); 95int tipc_bclink_send_msg(struct sk_buff *buf);
94void tipc_bclink_recv_pkt(struct sk_buff *buf); 96void tipc_bclink_recv_pkt(struct sk_buff *buf);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 9927d1d56c4f..411719feb803 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -2,7 +2,7 @@
2 * net/tipc/bearer.c: TIPC bearer code 2 * net/tipc/bearer.c: TIPC bearer code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2004-2006, Wind River Systems 5 * Copyright (c) 2004-2006, 2010-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
@@ -36,19 +36,15 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "config.h"
39#include "dbg.h"
40#include "bearer.h" 39#include "bearer.h"
41#include "link.h"
42#include "port.h"
43#include "discover.h" 40#include "discover.h"
44#include "bcast.h"
45 41
46#define MAX_ADDR_STR 32 42#define MAX_ADDR_STR 32
47 43
48static struct media media_list[MAX_MEDIA]; 44static struct media media_list[MAX_MEDIA];
49static u32 media_count = 0; 45static u32 media_count;
50 46
51struct bearer tipc_bearers[MAX_BEARERS]; 47struct tipc_bearer tipc_bearers[MAX_BEARERS];
52 48
53/** 49/**
54 * media_name_valid - validate media name 50 * media_name_valid - validate media name
@@ -162,12 +158,10 @@ int tipc_register_media(u32 media_type,
162 m_ptr->disable_bearer = disable; 158 m_ptr->disable_bearer = disable;
163 m_ptr->addr2str = addr2str; 159 m_ptr->addr2str = addr2str;
164 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr)); 160 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr));
165 m_ptr->bcast = 1;
166 strcpy(m_ptr->name, name); 161 strcpy(m_ptr->name, name);
167 m_ptr->priority = bearer_priority; 162 m_ptr->priority = bearer_priority;
168 m_ptr->tolerance = link_tolerance; 163 m_ptr->tolerance = link_tolerance;
169 m_ptr->window = send_window_limit; 164 m_ptr->window = send_window_limit;
170 dbg("Media <%s> registered\n", name);
171 res = 0; 165 res = 0;
172exit: 166exit:
173 write_unlock_bh(&tipc_net_lock); 167 write_unlock_bh(&tipc_net_lock);
@@ -199,9 +193,8 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
199 unchar *addr = (unchar *)&a->dev_addr; 193 unchar *addr = (unchar *)&a->dev_addr;
200 194
201 tipc_printf(pb, "UNKNOWN(%u)", media_type); 195 tipc_printf(pb, "UNKNOWN(%u)", media_type);
202 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { 196 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++)
203 tipc_printf(pb, "-%02x", addr[i]); 197 tipc_printf(pb, "-%02x", addr[i]);
204 }
205 } 198 }
206} 199}
207 200
@@ -256,7 +249,8 @@ static int bearer_name_validate(const char *name,
256 /* ensure all component parts of bearer name are present */ 249 /* ensure all component parts of bearer name are present */
257 250
258 media_name = name_copy; 251 media_name = name_copy;
259 if ((if_name = strchr(media_name, ':')) == NULL) 252 if_name = strchr(media_name, ':');
253 if (if_name == NULL)
260 return 0; 254 return 0;
261 *(if_name++) = 0; 255 *(if_name++) = 0;
262 media_len = if_name - media_name; 256 media_len = if_name - media_name;
@@ -283,13 +277,13 @@ static int bearer_name_validate(const char *name,
283 * bearer_find - locates bearer object with matching bearer name 277 * bearer_find - locates bearer object with matching bearer name
284 */ 278 */
285 279
286static struct bearer *bearer_find(const char *name) 280static struct tipc_bearer *bearer_find(const char *name)
287{ 281{
288 struct bearer *b_ptr; 282 struct tipc_bearer *b_ptr;
289 u32 i; 283 u32 i;
290 284
291 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 285 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
292 if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) 286 if (b_ptr->active && (!strcmp(b_ptr->name, name)))
293 return b_ptr; 287 return b_ptr;
294 } 288 }
295 return NULL; 289 return NULL;
@@ -299,16 +293,16 @@ static struct bearer *bearer_find(const char *name)
299 * tipc_bearer_find_interface - locates bearer object with matching interface name 293 * tipc_bearer_find_interface - locates bearer object with matching interface name
300 */ 294 */
301 295
302struct bearer *tipc_bearer_find_interface(const char *if_name) 296struct tipc_bearer *tipc_bearer_find_interface(const char *if_name)
303{ 297{
304 struct bearer *b_ptr; 298 struct tipc_bearer *b_ptr;
305 char *b_if_name; 299 char *b_if_name;
306 u32 i; 300 u32 i;
307 301
308 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 302 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
309 if (!b_ptr->active) 303 if (!b_ptr->active)
310 continue; 304 continue;
311 b_if_name = strchr(b_ptr->publ.name, ':') + 1; 305 b_if_name = strchr(b_ptr->name, ':') + 1;
312 if (!strcmp(b_if_name, if_name)) 306 if (!strcmp(b_if_name, if_name))
313 return b_ptr; 307 return b_ptr;
314 } 308 }
@@ -323,7 +317,7 @@ struct sk_buff *tipc_bearer_get_names(void)
323{ 317{
324 struct sk_buff *buf; 318 struct sk_buff *buf;
325 struct media *m_ptr; 319 struct media *m_ptr;
326 struct bearer *b_ptr; 320 struct tipc_bearer *b_ptr;
327 int i, j; 321 int i, j;
328 322
329 buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME)); 323 buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME));
@@ -336,8 +330,8 @@ struct sk_buff *tipc_bearer_get_names(void)
336 b_ptr = &tipc_bearers[j]; 330 b_ptr = &tipc_bearers[j];
337 if (b_ptr->active && (b_ptr->media == m_ptr)) { 331 if (b_ptr->active && (b_ptr->media == m_ptr)) {
338 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 332 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME,
339 b_ptr->publ.name, 333 b_ptr->name,
340 strlen(b_ptr->publ.name) + 1); 334 strlen(b_ptr->name) + 1);
341 } 335 }
342 } 336 }
343 } 337 }
@@ -345,14 +339,14 @@ struct sk_buff *tipc_bearer_get_names(void)
345 return buf; 339 return buf;
346} 340}
347 341
348void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest) 342void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest)
349{ 343{
350 tipc_nmap_add(&b_ptr->nodes, dest); 344 tipc_nmap_add(&b_ptr->nodes, dest);
351 tipc_disc_update_link_req(b_ptr->link_req); 345 tipc_disc_update_link_req(b_ptr->link_req);
352 tipc_bcbearer_sort(); 346 tipc_bcbearer_sort();
353} 347}
354 348
355void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest) 349void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
356{ 350{
357 tipc_nmap_remove(&b_ptr->nodes, dest); 351 tipc_nmap_remove(&b_ptr->nodes, dest);
358 tipc_disc_update_link_req(b_ptr->link_req); 352 tipc_disc_update_link_req(b_ptr->link_req);
@@ -367,12 +361,12 @@ void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest)
367 * bearer.lock must be taken before calling 361 * bearer.lock must be taken before calling
368 * Returns binary true(1) ore false(0) 362 * Returns binary true(1) ore false(0)
369 */ 363 */
370static int bearer_push(struct bearer *b_ptr) 364static int bearer_push(struct tipc_bearer *b_ptr)
371{ 365{
372 u32 res = 0; 366 u32 res = 0;
373 struct link *ln, *tln; 367 struct link *ln, *tln;
374 368
375 if (b_ptr->publ.blocked) 369 if (b_ptr->blocked)
376 return 0; 370 return 0;
377 371
378 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) { 372 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) {
@@ -387,13 +381,13 @@ static int bearer_push(struct bearer *b_ptr)
387 return list_empty(&b_ptr->cong_links); 381 return list_empty(&b_ptr->cong_links);
388} 382}
389 383
390void tipc_bearer_lock_push(struct bearer *b_ptr) 384void tipc_bearer_lock_push(struct tipc_bearer *b_ptr)
391{ 385{
392 int res; 386 int res;
393 387
394 spin_lock_bh(&b_ptr->publ.lock); 388 spin_lock_bh(&b_ptr->lock);
395 res = bearer_push(b_ptr); 389 res = bearer_push(b_ptr);
396 spin_unlock_bh(&b_ptr->publ.lock); 390 spin_unlock_bh(&b_ptr->lock);
397 if (res) 391 if (res)
398 tipc_bcbearer_push(); 392 tipc_bcbearer_push();
399} 393}
@@ -403,16 +397,14 @@ void tipc_bearer_lock_push(struct bearer *b_ptr)
403 * Interrupt enabling new requests after bearer congestion or blocking: 397 * Interrupt enabling new requests after bearer congestion or blocking:
404 * See bearer_send(). 398 * See bearer_send().
405 */ 399 */
406void tipc_continue(struct tipc_bearer *tb_ptr) 400void tipc_continue(struct tipc_bearer *b_ptr)
407{ 401{
408 struct bearer *b_ptr = (struct bearer *)tb_ptr; 402 spin_lock_bh(&b_ptr->lock);
409
410 spin_lock_bh(&b_ptr->publ.lock);
411 b_ptr->continue_count++; 403 b_ptr->continue_count++;
412 if (!list_empty(&b_ptr->cong_links)) 404 if (!list_empty(&b_ptr->cong_links))
413 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr); 405 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr);
414 b_ptr->publ.blocked = 0; 406 b_ptr->blocked = 0;
415 spin_unlock_bh(&b_ptr->publ.lock); 407 spin_unlock_bh(&b_ptr->lock);
416} 408}
417 409
418/* 410/*
@@ -423,7 +415,7 @@ void tipc_continue(struct tipc_bearer *tb_ptr)
423 * bearer.lock is busy 415 * bearer.lock is busy
424 */ 416 */
425 417
426static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr) 418static void tipc_bearer_schedule_unlocked(struct tipc_bearer *b_ptr, struct link *l_ptr)
427{ 419{
428 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links); 420 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links);
429} 421}
@@ -436,11 +428,11 @@ static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_p
436 * bearer.lock is free 428 * bearer.lock is free
437 */ 429 */
438 430
439void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr) 431void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr)
440{ 432{
441 spin_lock_bh(&b_ptr->publ.lock); 433 spin_lock_bh(&b_ptr->lock);
442 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 434 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
443 spin_unlock_bh(&b_ptr->publ.lock); 435 spin_unlock_bh(&b_ptr->lock);
444} 436}
445 437
446 438
@@ -449,18 +441,18 @@ void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr)
449 * and if there is, try to resolve it before returning. 441 * and if there is, try to resolve it before returning.
450 * 'tipc_net_lock' is read_locked when this function is called 442 * 'tipc_net_lock' is read_locked when this function is called
451 */ 443 */
452int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr) 444int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr)
453{ 445{
454 int res = 1; 446 int res = 1;
455 447
456 if (list_empty(&b_ptr->cong_links)) 448 if (list_empty(&b_ptr->cong_links))
457 return 1; 449 return 1;
458 spin_lock_bh(&b_ptr->publ.lock); 450 spin_lock_bh(&b_ptr->lock);
459 if (!bearer_push(b_ptr)) { 451 if (!bearer_push(b_ptr)) {
460 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 452 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
461 res = 0; 453 res = 0;
462 } 454 }
463 spin_unlock_bh(&b_ptr->publ.lock); 455 spin_unlock_bh(&b_ptr->lock);
464 return res; 456 return res;
465} 457}
466 458
@@ -468,9 +460,9 @@ int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr)
468 * tipc_bearer_congested - determines if bearer is currently congested 460 * tipc_bearer_congested - determines if bearer is currently congested
469 */ 461 */
470 462
471int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr) 463int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr)
472{ 464{
473 if (unlikely(b_ptr->publ.blocked)) 465 if (unlikely(b_ptr->blocked))
474 return 1; 466 return 1;
475 if (likely(list_empty(&b_ptr->cong_links))) 467 if (likely(list_empty(&b_ptr->cong_links)))
476 return 0; 468 return 0;
@@ -481,9 +473,9 @@ int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr)
481 * tipc_enable_bearer - enable bearer with the given name 473 * tipc_enable_bearer - enable bearer with the given name
482 */ 474 */
483 475
484int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority) 476int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
485{ 477{
486 struct bearer *b_ptr; 478 struct tipc_bearer *b_ptr;
487 struct media *m_ptr; 479 struct media *m_ptr;
488 struct bearer_name b_name; 480 struct bearer_name b_name;
489 char addr_string[16]; 481 char addr_string[16];
@@ -501,9 +493,9 @@ int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority)
501 warn("Bearer <%s> rejected, illegal name\n", name); 493 warn("Bearer <%s> rejected, illegal name\n", name);
502 return -EINVAL; 494 return -EINVAL;
503 } 495 }
504 if (!tipc_addr_domain_valid(bcast_scope) || 496 if (!tipc_addr_domain_valid(disc_domain) ||
505 !tipc_in_scope(bcast_scope, tipc_own_addr)) { 497 !tipc_in_scope(disc_domain, tipc_own_addr)) {
506 warn("Bearer <%s> rejected, illegal broadcast scope\n", name); 498 warn("Bearer <%s> rejected, illegal discovery domain\n", name);
507 return -EINVAL; 499 return -EINVAL;
508 } 500 }
509 if ((priority < TIPC_MIN_LINK_PRI || 501 if ((priority < TIPC_MIN_LINK_PRI ||
@@ -533,7 +525,7 @@ restart:
533 bearer_id = i; 525 bearer_id = i;
534 continue; 526 continue;
535 } 527 }
536 if (!strcmp(name, tipc_bearers[i].publ.name)) { 528 if (!strcmp(name, tipc_bearers[i].name)) {
537 warn("Bearer <%s> rejected, already enabled\n", name); 529 warn("Bearer <%s> rejected, already enabled\n", name);
538 goto failed; 530 goto failed;
539 } 531 }
@@ -556,8 +548,8 @@ restart:
556 } 548 }
557 549
558 b_ptr = &tipc_bearers[bearer_id]; 550 b_ptr = &tipc_bearers[bearer_id];
559 strcpy(b_ptr->publ.name, name); 551 strcpy(b_ptr->name, name);
560 res = m_ptr->enable_bearer(&b_ptr->publ); 552 res = m_ptr->enable_bearer(b_ptr);
561 if (res) { 553 if (res) {
562 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); 554 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res);
563 goto failed; 555 goto failed;
@@ -567,18 +559,15 @@ restart:
567 b_ptr->media = m_ptr; 559 b_ptr->media = m_ptr;
568 b_ptr->net_plane = bearer_id + 'A'; 560 b_ptr->net_plane = bearer_id + 'A';
569 b_ptr->active = 1; 561 b_ptr->active = 1;
570 b_ptr->detect_scope = bcast_scope;
571 b_ptr->priority = priority; 562 b_ptr->priority = priority;
572 INIT_LIST_HEAD(&b_ptr->cong_links); 563 INIT_LIST_HEAD(&b_ptr->cong_links);
573 INIT_LIST_HEAD(&b_ptr->links); 564 INIT_LIST_HEAD(&b_ptr->links);
574 if (m_ptr->bcast) { 565 b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr,
575 b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, 566 disc_domain);
576 bcast_scope, 2); 567 spin_lock_init(&b_ptr->lock);
577 }
578 spin_lock_init(&b_ptr->publ.lock);
579 write_unlock_bh(&tipc_net_lock); 568 write_unlock_bh(&tipc_net_lock);
580 info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 569 info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
581 name, tipc_addr_string_fill(addr_string, bcast_scope), priority); 570 name, tipc_addr_string_fill(addr_string, disc_domain), priority);
582 return 0; 571 return 0;
583failed: 572failed:
584 write_unlock_bh(&tipc_net_lock); 573 write_unlock_bh(&tipc_net_lock);
@@ -592,7 +581,7 @@ failed:
592 581
593int tipc_block_bearer(const char *name) 582int tipc_block_bearer(const char *name)
594{ 583{
595 struct bearer *b_ptr = NULL; 584 struct tipc_bearer *b_ptr = NULL;
596 struct link *l_ptr; 585 struct link *l_ptr;
597 struct link *temp_l_ptr; 586 struct link *temp_l_ptr;
598 587
@@ -605,8 +594,8 @@ int tipc_block_bearer(const char *name)
605 } 594 }
606 595
607 info("Blocking bearer <%s>\n", name); 596 info("Blocking bearer <%s>\n", name);
608 spin_lock_bh(&b_ptr->publ.lock); 597 spin_lock_bh(&b_ptr->lock);
609 b_ptr->publ.blocked = 1; 598 b_ptr->blocked = 1;
610 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 599 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
611 struct tipc_node *n_ptr = l_ptr->owner; 600 struct tipc_node *n_ptr = l_ptr->owner;
612 601
@@ -614,7 +603,7 @@ int tipc_block_bearer(const char *name)
614 tipc_link_reset(l_ptr); 603 tipc_link_reset(l_ptr);
615 spin_unlock_bh(&n_ptr->lock); 604 spin_unlock_bh(&n_ptr->lock);
616 } 605 }
617 spin_unlock_bh(&b_ptr->publ.lock); 606 spin_unlock_bh(&b_ptr->lock);
618 read_unlock_bh(&tipc_net_lock); 607 read_unlock_bh(&tipc_net_lock);
619 return 0; 608 return 0;
620} 609}
@@ -625,28 +614,27 @@ int tipc_block_bearer(const char *name)
625 * Note: This routine assumes caller holds tipc_net_lock. 614 * Note: This routine assumes caller holds tipc_net_lock.
626 */ 615 */
627 616
628static int bearer_disable(struct bearer *b_ptr) 617static void bearer_disable(struct tipc_bearer *b_ptr)
629{ 618{
630 struct link *l_ptr; 619 struct link *l_ptr;
631 struct link *temp_l_ptr; 620 struct link *temp_l_ptr;
632 621
633 info("Disabling bearer <%s>\n", b_ptr->publ.name); 622 info("Disabling bearer <%s>\n", b_ptr->name);
634 tipc_disc_stop_link_req(b_ptr->link_req); 623 tipc_disc_stop_link_req(b_ptr->link_req);
635 spin_lock_bh(&b_ptr->publ.lock); 624 spin_lock_bh(&b_ptr->lock);
636 b_ptr->link_req = NULL; 625 b_ptr->link_req = NULL;
637 b_ptr->publ.blocked = 1; 626 b_ptr->blocked = 1;
638 b_ptr->media->disable_bearer(&b_ptr->publ); 627 b_ptr->media->disable_bearer(b_ptr);
639 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 628 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
640 tipc_link_delete(l_ptr); 629 tipc_link_delete(l_ptr);
641 } 630 }
642 spin_unlock_bh(&b_ptr->publ.lock); 631 spin_unlock_bh(&b_ptr->lock);
643 memset(b_ptr, 0, sizeof(struct bearer)); 632 memset(b_ptr, 0, sizeof(struct tipc_bearer));
644 return 0;
645} 633}
646 634
647int tipc_disable_bearer(const char *name) 635int tipc_disable_bearer(const char *name)
648{ 636{
649 struct bearer *b_ptr; 637 struct tipc_bearer *b_ptr;
650 int res; 638 int res;
651 639
652 write_lock_bh(&tipc_net_lock); 640 write_lock_bh(&tipc_net_lock);
@@ -654,8 +642,10 @@ int tipc_disable_bearer(const char *name)
654 if (b_ptr == NULL) { 642 if (b_ptr == NULL) {
655 warn("Attempt to disable unknown bearer <%s>\n", name); 643 warn("Attempt to disable unknown bearer <%s>\n", name);
656 res = -EINVAL; 644 res = -EINVAL;
657 } else 645 } else {
658 res = bearer_disable(b_ptr); 646 bearer_disable(b_ptr);
647 res = 0;
648 }
659 write_unlock_bh(&tipc_net_lock); 649 write_unlock_bh(&tipc_net_lock);
660 return res; 650 return res;
661} 651}
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index a850b389663e..31d6172b20fd 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -2,7 +2,7 @@
2 * net/tipc/bearer.h: Include file for TIPC bearer code 2 * net/tipc/bearer.h: Include file for TIPC bearer code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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,12 +37,31 @@
37#ifndef _TIPC_BEARER_H 37#ifndef _TIPC_BEARER_H
38#define _TIPC_BEARER_H 38#define _TIPC_BEARER_H
39 39
40#include "core.h"
41#include "bcast.h" 40#include "bcast.h"
42 41
43#define MAX_BEARERS 8 42#define MAX_BEARERS 8
44#define MAX_MEDIA 4 43#define MAX_MEDIA 4
45 44
45/*
46 * Identifiers of supported TIPC media types
47 */
48#define TIPC_MEDIA_TYPE_ETH 1
49
50/*
51 * Destination address structure used by TIPC bearers when sending messages
52 *
53 * IMPORTANT: The fields of this structure MUST be stored using the specified
54 * byte order indicated below, as the structure is exchanged between nodes
55 * as part of a link setup process.
56 */
57struct tipc_media_addr {
58 __be32 type; /* bearer type (network byte order) */
59 union {
60 __u8 eth_addr[6]; /* 48 bit Ethernet addr (byte array) */
61 } dev_addr;
62};
63
64struct tipc_bearer;
46 65
47/** 66/**
48 * struct media - TIPC media information available to internal users 67 * struct media - TIPC media information available to internal users
@@ -51,11 +70,10 @@
51 * @disable_bearer: routine which disables a bearer 70 * @disable_bearer: routine which disables a bearer
52 * @addr2str: routine which converts bearer's address to string form 71 * @addr2str: routine which converts bearer's address to string form
53 * @bcast_addr: media address used in broadcasting 72 * @bcast_addr: media address used in broadcasting
54 * @bcast: non-zero if media supports broadcasting [currently mandatory]
55 * @priority: default link (and bearer) priority 73 * @priority: default link (and bearer) priority
56 * @tolerance: default time (in ms) before declaring link failure 74 * @tolerance: default time (in ms) before declaring link failure
57 * @window: default window (in packets) before declaring link congestion 75 * @window: default window (in packets) before declaring link congestion
58 * @type_id: TIPC media identifier [defined in tipc_bearer.h] 76 * @type_id: TIPC media identifier
59 * @name: media name 77 * @name: media name
60 */ 78 */
61 79
@@ -68,7 +86,6 @@ struct media {
68 char *(*addr2str)(struct tipc_media_addr *a, 86 char *(*addr2str)(struct tipc_media_addr *a,
69 char *str_buf, int str_size); 87 char *str_buf, int str_size);
70 struct tipc_media_addr bcast_addr; 88 struct tipc_media_addr bcast_addr;
71 int bcast;
72 u32 priority; 89 u32 priority;
73 u32 tolerance; 90 u32 tolerance;
74 u32 window; 91 u32 window;
@@ -77,11 +94,15 @@ struct media {
77}; 94};
78 95
79/** 96/**
80 * struct bearer - TIPC bearer information available to internal users 97 * struct tipc_bearer - TIPC bearer structure
81 * @publ: bearer information available to privileged users 98 * @usr_handle: pointer to additional media-specific information about bearer
99 * @mtu: max packet size bearer can support
100 * @blocked: non-zero if bearer is blocked
101 * @lock: spinlock for controlling access to bearer
102 * @addr: media-specific address associated with bearer
103 * @name: bearer name (format = media:interface)
82 * @media: ptr to media structure associated with bearer 104 * @media: ptr to media structure associated with bearer
83 * @priority: default link priority for bearer 105 * @priority: default link priority for bearer
84 * @detect_scope: network address mask used during automatic link creation
85 * @identity: array index of this bearer within TIPC bearer array 106 * @identity: array index of this bearer within TIPC bearer array
86 * @link_req: ptr to (optional) structure making periodic link setup requests 107 * @link_req: ptr to (optional) structure making periodic link setup requests
87 * @links: list of non-congested links associated with bearer 108 * @links: list of non-congested links associated with bearer
@@ -90,13 +111,20 @@ struct media {
90 * @active: non-zero if bearer structure is represents a bearer 111 * @active: non-zero if bearer structure is represents a bearer
91 * @net_plane: network plane ('A' through 'H') currently associated with bearer 112 * @net_plane: network plane ('A' through 'H') currently associated with bearer
92 * @nodes: indicates which nodes in cluster can be reached through bearer 113 * @nodes: indicates which nodes in cluster can be reached through bearer
114 *
115 * Note: media-specific code is responsible for initialization of the fields
116 * indicated below when a bearer is enabled; TIPC's generic bearer code takes
117 * care of initializing all other fields.
93 */ 118 */
94 119struct tipc_bearer {
95struct bearer { 120 void *usr_handle; /* initalized by media */
96 struct tipc_bearer publ; 121 u32 mtu; /* initalized by media */
122 int blocked; /* initalized by media */
123 struct tipc_media_addr addr; /* initalized by media */
124 char name[TIPC_MAX_BEARER_NAME];
125 spinlock_t lock;
97 struct media *media; 126 struct media *media;
98 u32 priority; 127 u32 priority;
99 u32 detect_scope;
100 u32 identity; 128 u32 identity;
101 struct link_req *link_req; 129 struct link_req *link_req;
102 struct list_head links; 130 struct list_head links;
@@ -114,21 +142,48 @@ struct bearer_name {
114 142
115struct link; 143struct link;
116 144
117extern struct bearer tipc_bearers[]; 145extern struct tipc_bearer tipc_bearers[];
146
147/*
148 * TIPC routines available to supported media types
149 */
150int tipc_register_media(u32 media_type,
151 char *media_name, int (*enable)(struct tipc_bearer *),
152 void (*disable)(struct tipc_bearer *),
153 int (*send_msg)(struct sk_buff *,
154 struct tipc_bearer *, struct tipc_media_addr *),
155 char *(*addr2str)(struct tipc_media_addr *a,
156 char *str_buf, int str_size),
157 struct tipc_media_addr *bcast_addr, const u32 bearer_priority,
158 const u32 link_tolerance, /* [ms] */
159 const u32 send_window_limit);
160
161void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
162
163int tipc_block_bearer(const char *name);
164void tipc_continue(struct tipc_bearer *tb_ptr);
165
166int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
167int tipc_disable_bearer(const char *name);
168
169/*
170 * Routines made available to TIPC by supported media types
171 */
172int tipc_eth_media_start(void);
173void tipc_eth_media_stop(void);
118 174
119void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); 175void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
120struct sk_buff *tipc_media_get_names(void); 176struct sk_buff *tipc_media_get_names(void);
121 177
122struct sk_buff *tipc_bearer_get_names(void); 178struct sk_buff *tipc_bearer_get_names(void);
123void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest); 179void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest);
124void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest); 180void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest);
125void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr); 181void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr);
126struct bearer *tipc_bearer_find_interface(const char *if_name); 182struct tipc_bearer *tipc_bearer_find_interface(const char *if_name);
127int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr); 183int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr);
128int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr); 184int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr);
129int tipc_bearer_init(void);
130void tipc_bearer_stop(void); 185void tipc_bearer_stop(void);
131void tipc_bearer_lock_push(struct bearer *b_ptr); 186void tipc_bearer_lock_push(struct tipc_bearer *b_ptr);
132 187
133 188
134/** 189/**
@@ -149,10 +204,11 @@ void tipc_bearer_lock_push(struct bearer *b_ptr);
149 * and let TIPC's link code deal with the undelivered message. 204 * and let TIPC's link code deal with the undelivered message.
150 */ 205 */
151 206
152static inline int tipc_bearer_send(struct bearer *b_ptr, struct sk_buff *buf, 207static inline int tipc_bearer_send(struct tipc_bearer *b_ptr,
208 struct sk_buff *buf,
153 struct tipc_media_addr *dest) 209 struct tipc_media_addr *dest)
154{ 210{
155 return !b_ptr->media->send_msg(buf, &b_ptr->publ, dest); 211 return !b_ptr->media->send_msg(buf, b_ptr, dest);
156} 212}
157 213
158#endif /* _TIPC_BEARER_H */ 214#endif /* _TIPC_BEARER_H */
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
deleted file mode 100644
index 7fea14b98b97..000000000000
--- a/net/tipc/cluster.c
+++ /dev/null
@@ -1,557 +0,0 @@
1/*
2 * net/tipc/cluster.c: TIPC cluster management routines
3 *
4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "core.h"
38#include "cluster.h"
39#include "addr.h"
40#include "node_subscr.h"
41#include "link.h"
42#include "node.h"
43#include "net.h"
44#include "msg.h"
45#include "bearer.h"
46
47static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
48 u32 lower, u32 upper);
49static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest);
50
51struct tipc_node **tipc_local_nodes = NULL;
52struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}};
53u32 tipc_highest_allowed_slave = 0;
54
55struct cluster *tipc_cltr_create(u32 addr)
56{
57 struct _zone *z_ptr;
58 struct cluster *c_ptr;
59 int max_nodes;
60
61 c_ptr = kzalloc(sizeof(*c_ptr), GFP_ATOMIC);
62 if (c_ptr == NULL) {
63 warn("Cluster creation failure, no memory\n");
64 return NULL;
65 }
66
67 c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
68 if (in_own_cluster(addr))
69 max_nodes = LOWEST_SLAVE + tipc_max_slaves;
70 else
71 max_nodes = tipc_max_nodes + 1;
72
73 c_ptr->nodes = kcalloc(max_nodes + 1, sizeof(void*), GFP_ATOMIC);
74 if (c_ptr->nodes == NULL) {
75 warn("Cluster creation failure, no memory for node area\n");
76 kfree(c_ptr);
77 return NULL;
78 }
79
80 if (in_own_cluster(addr))
81 tipc_local_nodes = c_ptr->nodes;
82 c_ptr->highest_slave = LOWEST_SLAVE - 1;
83 c_ptr->highest_node = 0;
84
85 z_ptr = tipc_zone_find(tipc_zone(addr));
86 if (!z_ptr) {
87 z_ptr = tipc_zone_create(addr);
88 }
89 if (!z_ptr) {
90 kfree(c_ptr->nodes);
91 kfree(c_ptr);
92 return NULL;
93 }
94
95 tipc_zone_attach_cluster(z_ptr, c_ptr);
96 c_ptr->owner = z_ptr;
97 return c_ptr;
98}
99
100void tipc_cltr_delete(struct cluster *c_ptr)
101{
102 u32 n_num;
103
104 if (!c_ptr)
105 return;
106 for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) {
107 tipc_node_delete(c_ptr->nodes[n_num]);
108 }
109 for (n_num = LOWEST_SLAVE; n_num <= c_ptr->highest_slave; n_num++) {
110 tipc_node_delete(c_ptr->nodes[n_num]);
111 }
112 kfree(c_ptr->nodes);
113 kfree(c_ptr);
114}
115
116
117void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr)
118{
119 u32 n_num = tipc_node(n_ptr->addr);
120 u32 max_n_num = tipc_max_nodes;
121
122 if (in_own_cluster(n_ptr->addr))
123 max_n_num = tipc_highest_allowed_slave;
124 assert(n_num > 0);
125 assert(n_num <= max_n_num);
126 assert(c_ptr->nodes[n_num] == NULL);
127 c_ptr->nodes[n_num] = n_ptr;
128 if (n_num > c_ptr->highest_node)
129 c_ptr->highest_node = n_num;
130}
131
132/**
133 * tipc_cltr_select_router - select router to a cluster
134 *
135 * Uses deterministic and fair algorithm.
136 */
137
138u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref)
139{
140 u32 n_num;
141 u32 ulim = c_ptr->highest_node;
142 u32 mask;
143 u32 tstart;
144
145 assert(!in_own_cluster(c_ptr->addr));
146 if (!ulim)
147 return 0;
148
149 /* Start entry must be random */
150 mask = tipc_max_nodes;
151 while (mask > ulim)
152 mask >>= 1;
153 tstart = ref & mask;
154 n_num = tstart;
155
156 /* Lookup upwards with wrap-around */
157 do {
158 if (tipc_node_is_up(c_ptr->nodes[n_num]))
159 break;
160 } while (++n_num <= ulim);
161 if (n_num > ulim) {
162 n_num = 1;
163 do {
164 if (tipc_node_is_up(c_ptr->nodes[n_num]))
165 break;
166 } while (++n_num < tstart);
167 if (n_num == tstart)
168 return 0;
169 }
170 assert(n_num <= ulim);
171 return tipc_node_select_router(c_ptr->nodes[n_num], ref);
172}
173
174/**
175 * tipc_cltr_select_node - select destination node within a remote cluster
176 *
177 * Uses deterministic and fair algorithm.
178 */
179
180struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
181{
182 u32 n_num;
183 u32 mask = tipc_max_nodes;
184 u32 start_entry;
185
186 assert(!in_own_cluster(c_ptr->addr));
187 if (!c_ptr->highest_node)
188 return NULL;
189
190 /* Start entry must be random */
191 while (mask > c_ptr->highest_node) {
192 mask >>= 1;
193 }
194 start_entry = (selector & mask) ? selector & mask : 1u;
195 assert(start_entry <= c_ptr->highest_node);
196
197 /* Lookup upwards with wrap-around */
198 for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) {
199 if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
200 return c_ptr->nodes[n_num];
201 }
202 for (n_num = 1; n_num < start_entry; n_num++) {
203 if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
204 return c_ptr->nodes[n_num];
205 }
206 return NULL;
207}
208
209/*
210 * Routing table management: See description in node.c
211 */
212
213static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
214{
215 u32 size = INT_H_SIZE + data_size;
216 struct sk_buff *buf = tipc_buf_acquire(size);
217 struct tipc_msg *msg;
218
219 if (buf) {
220 msg = buf_msg(buf);
221 memset((char *)msg, 0, size);
222 tipc_msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest);
223 }
224 return buf;
225}
226
227void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest,
228 u32 lower, u32 upper)
229{
230 struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
231 struct tipc_msg *msg;
232
233 if (buf) {
234 msg = buf_msg(buf);
235 msg_set_remote_node(msg, dest);
236 msg_set_type(msg, ROUTE_ADDITION);
237 tipc_cltr_multicast(c_ptr, buf, lower, upper);
238 } else {
239 warn("Memory squeeze: broadcast of new route failed\n");
240 }
241}
242
243void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest,
244 u32 lower, u32 upper)
245{
246 struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
247 struct tipc_msg *msg;
248
249 if (buf) {
250 msg = buf_msg(buf);
251 msg_set_remote_node(msg, dest);
252 msg_set_type(msg, ROUTE_REMOVAL);
253 tipc_cltr_multicast(c_ptr, buf, lower, upper);
254 } else {
255 warn("Memory squeeze: broadcast of lost route failed\n");
256 }
257}
258
259void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest)
260{
261 struct sk_buff *buf;
262 struct tipc_msg *msg;
263 u32 highest = c_ptr->highest_slave;
264 u32 n_num;
265 int send = 0;
266
267 assert(!is_slave(dest));
268 assert(in_own_cluster(dest));
269 assert(in_own_cluster(c_ptr->addr));
270 if (highest <= LOWEST_SLAVE)
271 return;
272 buf = tipc_cltr_prepare_routing_msg(highest - LOWEST_SLAVE + 1,
273 c_ptr->addr);
274 if (buf) {
275 msg = buf_msg(buf);
276 msg_set_remote_node(msg, c_ptr->addr);
277 msg_set_type(msg, SLAVE_ROUTING_TABLE);
278 for (n_num = LOWEST_SLAVE; n_num <= highest; n_num++) {
279 if (c_ptr->nodes[n_num] &&
280 tipc_node_has_active_links(c_ptr->nodes[n_num])) {
281 send = 1;
282 msg_set_dataoctet(msg, n_num);
283 }
284 }
285 if (send)
286 tipc_link_send(buf, dest, dest);
287 else
288 buf_discard(buf);
289 } else {
290 warn("Memory squeeze: broadcast of lost route failed\n");
291 }
292}
293
294void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest)
295{
296 struct sk_buff *buf;
297 struct tipc_msg *msg;
298 u32 highest = c_ptr->highest_node;
299 u32 n_num;
300 int send = 0;
301
302 if (in_own_cluster(c_ptr->addr))
303 return;
304 assert(!is_slave(dest));
305 assert(in_own_cluster(dest));
306 highest = c_ptr->highest_node;
307 buf = tipc_cltr_prepare_routing_msg(highest + 1, c_ptr->addr);
308 if (buf) {
309 msg = buf_msg(buf);
310 msg_set_remote_node(msg, c_ptr->addr);
311 msg_set_type(msg, EXT_ROUTING_TABLE);
312 for (n_num = 1; n_num <= highest; n_num++) {
313 if (c_ptr->nodes[n_num] &&
314 tipc_node_has_active_links(c_ptr->nodes[n_num])) {
315 send = 1;
316 msg_set_dataoctet(msg, n_num);
317 }
318 }
319 if (send)
320 tipc_link_send(buf, dest, dest);
321 else
322 buf_discard(buf);
323 } else {
324 warn("Memory squeeze: broadcast of external route failed\n");
325 }
326}
327
328void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest)
329{
330 struct sk_buff *buf;
331 struct tipc_msg *msg;
332 u32 highest = c_ptr->highest_node;
333 u32 n_num;
334 int send = 0;
335
336 assert(is_slave(dest));
337 assert(in_own_cluster(c_ptr->addr));
338 buf = tipc_cltr_prepare_routing_msg(highest, c_ptr->addr);
339 if (buf) {
340 msg = buf_msg(buf);
341 msg_set_remote_node(msg, c_ptr->addr);
342 msg_set_type(msg, LOCAL_ROUTING_TABLE);
343 for (n_num = 1; n_num <= highest; n_num++) {
344 if (c_ptr->nodes[n_num] &&
345 tipc_node_has_active_links(c_ptr->nodes[n_num])) {
346 send = 1;
347 msg_set_dataoctet(msg, n_num);
348 }
349 }
350 if (send)
351 tipc_link_send(buf, dest, dest);
352 else
353 buf_discard(buf);
354 } else {
355 warn("Memory squeeze: broadcast of local route failed\n");
356 }
357}
358
359void tipc_cltr_recv_routing_table(struct sk_buff *buf)
360{
361 struct tipc_msg *msg = buf_msg(buf);
362 struct cluster *c_ptr;
363 struct tipc_node *n_ptr;
364 unchar *node_table;
365 u32 table_size;
366 u32 router;
367 u32 rem_node = msg_remote_node(msg);
368 u32 z_num;
369 u32 c_num;
370 u32 n_num;
371
372 c_ptr = tipc_cltr_find(rem_node);
373 if (!c_ptr) {
374 c_ptr = tipc_cltr_create(rem_node);
375 if (!c_ptr) {
376 buf_discard(buf);
377 return;
378 }
379 }
380
381 node_table = buf->data + msg_hdr_sz(msg);
382 table_size = msg_size(msg) - msg_hdr_sz(msg);
383 router = msg_prevnode(msg);
384 z_num = tipc_zone(rem_node);
385 c_num = tipc_cluster(rem_node);
386
387 switch (msg_type(msg)) {
388 case LOCAL_ROUTING_TABLE:
389 assert(is_slave(tipc_own_addr));
390 case EXT_ROUTING_TABLE:
391 for (n_num = 1; n_num < table_size; n_num++) {
392 if (node_table[n_num]) {
393 u32 addr = tipc_addr(z_num, c_num, n_num);
394 n_ptr = c_ptr->nodes[n_num];
395 if (!n_ptr) {
396 n_ptr = tipc_node_create(addr);
397 }
398 if (n_ptr)
399 tipc_node_add_router(n_ptr, router);
400 }
401 }
402 break;
403 case SLAVE_ROUTING_TABLE:
404 assert(!is_slave(tipc_own_addr));
405 assert(in_own_cluster(c_ptr->addr));
406 for (n_num = 1; n_num < table_size; n_num++) {
407 if (node_table[n_num]) {
408 u32 slave_num = n_num + LOWEST_SLAVE;
409 u32 addr = tipc_addr(z_num, c_num, slave_num);
410 n_ptr = c_ptr->nodes[slave_num];
411 if (!n_ptr) {
412 n_ptr = tipc_node_create(addr);
413 }
414 if (n_ptr)
415 tipc_node_add_router(n_ptr, router);
416 }
417 }
418 break;
419 case ROUTE_ADDITION:
420 if (!is_slave(tipc_own_addr)) {
421 assert(!in_own_cluster(c_ptr->addr) ||
422 is_slave(rem_node));
423 } else {
424 assert(in_own_cluster(c_ptr->addr) &&
425 !is_slave(rem_node));
426 }
427 n_ptr = c_ptr->nodes[tipc_node(rem_node)];
428 if (!n_ptr)
429 n_ptr = tipc_node_create(rem_node);
430 if (n_ptr)
431 tipc_node_add_router(n_ptr, router);
432 break;
433 case ROUTE_REMOVAL:
434 if (!is_slave(tipc_own_addr)) {
435 assert(!in_own_cluster(c_ptr->addr) ||
436 is_slave(rem_node));
437 } else {
438 assert(in_own_cluster(c_ptr->addr) &&
439 !is_slave(rem_node));
440 }
441 n_ptr = c_ptr->nodes[tipc_node(rem_node)];
442 if (n_ptr)
443 tipc_node_remove_router(n_ptr, router);
444 break;
445 default:
446 assert(!"Illegal routing manager message received\n");
447 }
448 buf_discard(buf);
449}
450
451void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router)
452{
453 u32 start_entry;
454 u32 tstop;
455 u32 n_num;
456
457 if (is_slave(router))
458 return; /* Slave nodes can not be routers */
459
460 if (in_own_cluster(c_ptr->addr)) {
461 start_entry = LOWEST_SLAVE;
462 tstop = c_ptr->highest_slave;
463 } else {
464 start_entry = 1;
465 tstop = c_ptr->highest_node;
466 }
467
468 for (n_num = start_entry; n_num <= tstop; n_num++) {
469 if (c_ptr->nodes[n_num]) {
470 tipc_node_remove_router(c_ptr->nodes[n_num], router);
471 }
472 }
473}
474
475/**
476 * tipc_cltr_multicast - multicast message to local nodes
477 */
478
479static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
480 u32 lower, u32 upper)
481{
482 struct sk_buff *buf_copy;
483 struct tipc_node *n_ptr;
484 u32 n_num;
485 u32 tstop;
486
487 assert(lower <= upper);
488 assert(((lower >= 1) && (lower <= tipc_max_nodes)) ||
489 ((lower >= LOWEST_SLAVE) && (lower <= tipc_highest_allowed_slave)));
490 assert(((upper >= 1) && (upper <= tipc_max_nodes)) ||
491 ((upper >= LOWEST_SLAVE) && (upper <= tipc_highest_allowed_slave)));
492 assert(in_own_cluster(c_ptr->addr));
493
494 tstop = is_slave(upper) ? c_ptr->highest_slave : c_ptr->highest_node;
495 if (tstop > upper)
496 tstop = upper;
497 for (n_num = lower; n_num <= tstop; n_num++) {
498 n_ptr = c_ptr->nodes[n_num];
499 if (n_ptr && tipc_node_has_active_links(n_ptr)) {
500 buf_copy = skb_copy(buf, GFP_ATOMIC);
501 if (buf_copy == NULL)
502 break;
503 msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
504 tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
505 }
506 }
507 buf_discard(buf);
508}
509
510/**
511 * tipc_cltr_broadcast - broadcast message to all nodes within cluster
512 */
513
514void tipc_cltr_broadcast(struct sk_buff *buf)
515{
516 struct sk_buff *buf_copy;
517 struct cluster *c_ptr;
518 struct tipc_node *n_ptr;
519 u32 n_num;
520 u32 tstart;
521 u32 tstop;
522 u32 node_type;
523
524 if (tipc_mode == TIPC_NET_MODE) {
525 c_ptr = tipc_cltr_find(tipc_own_addr);
526 assert(in_own_cluster(c_ptr->addr)); /* For now */
527
528 /* Send to standard nodes, then repeat loop sending to slaves */
529 tstart = 1;
530 tstop = c_ptr->highest_node;
531 for (node_type = 1; node_type <= 2; node_type++) {
532 for (n_num = tstart; n_num <= tstop; n_num++) {
533 n_ptr = c_ptr->nodes[n_num];
534 if (n_ptr && tipc_node_has_active_links(n_ptr)) {
535 buf_copy = skb_copy(buf, GFP_ATOMIC);
536 if (buf_copy == NULL)
537 goto exit;
538 msg_set_destnode(buf_msg(buf_copy),
539 n_ptr->addr);
540 tipc_link_send(buf_copy, n_ptr->addr,
541 n_ptr->addr);
542 }
543 }
544 tstart = LOWEST_SLAVE;
545 tstop = c_ptr->highest_slave;
546 }
547 }
548exit:
549 buf_discard(buf);
550}
551
552int tipc_cltr_init(void)
553{
554 tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves;
555 return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM;
556}
557
diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h
deleted file mode 100644
index 32636d98c9c6..000000000000
--- a/net/tipc/cluster.h
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2 * net/tipc/cluster.h: Include file for TIPC cluster management routines
3 *
4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _TIPC_CLUSTER_H
38#define _TIPC_CLUSTER_H
39
40#include "addr.h"
41#include "zone.h"
42
43#define LOWEST_SLAVE 2048u
44
45/**
46 * struct cluster - TIPC cluster structure
47 * @addr: network address of cluster
48 * @owner: pointer to zone that cluster belongs to
49 * @nodes: array of pointers to all nodes within cluster
50 * @highest_node: id of highest numbered node within cluster
51 * @highest_slave: (used for secondary node support)
52 */
53
54struct cluster {
55 u32 addr;
56 struct _zone *owner;
57 struct tipc_node **nodes;
58 u32 highest_node;
59 u32 highest_slave;
60};
61
62
63extern struct tipc_node **tipc_local_nodes;
64extern u32 tipc_highest_allowed_slave;
65extern struct tipc_node_map tipc_cltr_bcast_nodes;
66
67void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router);
68void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest);
69struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector);
70u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref);
71void tipc_cltr_recv_routing_table(struct sk_buff *buf);
72struct cluster *tipc_cltr_create(u32 addr);
73void tipc_cltr_delete(struct cluster *c_ptr);
74void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr);
75void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest);
76void tipc_cltr_broadcast(struct sk_buff *buf);
77int tipc_cltr_init(void);
78
79void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
80void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest);
81void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
82
83static inline struct cluster *tipc_cltr_find(u32 addr)
84{
85 struct _zone *z_ptr = tipc_zone_find(addr);
86
87 if (z_ptr)
88 return z_ptr->clusters[1];
89 return NULL;
90}
91
92#endif
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 50a6133a3668..b25a396b7e1e 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -2,7 +2,7 @@
2 * net/tipc/config.c: TIPC configuration management code 2 * net/tipc/config.c: TIPC configuration management code
3 * 3 *
4 * Copyright (c) 2002-2006, Ericsson AB 4 * Copyright (c) 2002-2006, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-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
@@ -35,30 +35,11 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "bearer.h"
40#include "port.h" 38#include "port.h"
41#include "link.h"
42#include "zone.h"
43#include "addr.h"
44#include "name_table.h" 39#include "name_table.h"
45#include "node.h"
46#include "config.h" 40#include "config.h"
47#include "discover.h"
48 41
49struct subscr_data { 42static u32 config_port_ref;
50 char usr_handle[8];
51 u32 domain;
52 u32 port_ref;
53 struct list_head subd_list;
54};
55
56struct manager {
57 u32 user_ref;
58 u32 port_ref;
59};
60
61static struct manager mng = { 0};
62 43
63static DEFINE_SPINLOCK(config_lock); 44static DEFINE_SPINLOCK(config_lock);
64 45
@@ -83,10 +64,8 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
83 struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf); 64 struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf);
84 int new_tlv_space = TLV_SPACE(tlv_data_size); 65 int new_tlv_space = TLV_SPACE(tlv_data_size);
85 66
86 if (skb_tailroom(buf) < new_tlv_space) { 67 if (skb_tailroom(buf) < new_tlv_space)
87 dbg("tipc_cfg_append_tlv unable to append TLV\n");
88 return 0; 68 return 0;
89 }
90 skb_put(buf, new_tlv_space); 69 skb_put(buf, new_tlv_space);
91 tlv->tlv_type = htons(tlv_type); 70 tlv->tlv_type = htons(tlv_type);
92 tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size)); 71 tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size));
@@ -169,7 +148,7 @@ static struct sk_buff *cfg_enable_bearer(void)
169 148
170 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area); 149 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area);
171 if (tipc_enable_bearer(args->name, 150 if (tipc_enable_bearer(args->name,
172 ntohl(args->detect_scope), 151 ntohl(args->disc_domain),
173 ntohl(args->priority))) 152 ntohl(args->priority)))
174 return tipc_cfg_reply_error_string("unable to enable bearer"); 153 return tipc_cfg_reply_error_string("unable to enable bearer");
175 154
@@ -281,70 +260,6 @@ static struct sk_buff *cfg_set_max_ports(void)
281 return tipc_cfg_reply_none(); 260 return tipc_cfg_reply_none();
282} 261}
283 262
284static struct sk_buff *cfg_set_max_zones(void)
285{
286 u32 value;
287
288 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
289 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
290 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
291 if (value == tipc_max_zones)
292 return tipc_cfg_reply_none();
293 if (value != delimit(value, 1, 255))
294 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
295 " (max zones must be 1-255)");
296 if (tipc_mode == TIPC_NET_MODE)
297 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
298 " (cannot change max zones once TIPC has joined a network)");
299 tipc_max_zones = value;
300 return tipc_cfg_reply_none();
301}
302
303static struct sk_buff *cfg_set_max_clusters(void)
304{
305 u32 value;
306
307 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
308 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
309 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
310 if (value != delimit(value, 1, 1))
311 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
312 " (max clusters fixed at 1)");
313 return tipc_cfg_reply_none();
314}
315
316static struct sk_buff *cfg_set_max_nodes(void)
317{
318 u32 value;
319
320 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
321 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
322 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
323 if (value == tipc_max_nodes)
324 return tipc_cfg_reply_none();
325 if (value != delimit(value, 8, 2047))
326 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
327 " (max nodes must be 8-2047)");
328 if (tipc_mode == TIPC_NET_MODE)
329 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
330 " (cannot change max nodes once TIPC has joined a network)");
331 tipc_max_nodes = value;
332 return tipc_cfg_reply_none();
333}
334
335static struct sk_buff *cfg_set_max_slaves(void)
336{
337 u32 value;
338
339 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
340 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
341 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
342 if (value != 0)
343 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
344 " (max secondary nodes fixed at 0)");
345 return tipc_cfg_reply_none();
346}
347
348static struct sk_buff *cfg_set_netid(void) 263static struct sk_buff *cfg_set_netid(void)
349{ 264{
350 u32 value; 265 u32 value;
@@ -388,8 +303,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
388 } else if (!tipc_remote_management) { 303 } else if (!tipc_remote_management) {
389 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE); 304 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
390 goto exit; 305 goto exit;
391 } 306 } else if (cmd >= 0x4000) {
392 else if (cmd >= 0x4000) {
393 u32 domain = 0; 307 u32 domain = 0;
394 308
395 if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) || 309 if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
@@ -464,18 +378,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
464 case TIPC_CMD_SET_MAX_SUBSCR: 378 case TIPC_CMD_SET_MAX_SUBSCR:
465 rep_tlv_buf = cfg_set_max_subscriptions(); 379 rep_tlv_buf = cfg_set_max_subscriptions();
466 break; 380 break;
467 case TIPC_CMD_SET_MAX_ZONES:
468 rep_tlv_buf = cfg_set_max_zones();
469 break;
470 case TIPC_CMD_SET_MAX_CLUSTERS:
471 rep_tlv_buf = cfg_set_max_clusters();
472 break;
473 case TIPC_CMD_SET_MAX_NODES:
474 rep_tlv_buf = cfg_set_max_nodes();
475 break;
476 case TIPC_CMD_SET_MAX_SLAVES:
477 rep_tlv_buf = cfg_set_max_slaves();
478 break;
479 case TIPC_CMD_SET_NETID: 381 case TIPC_CMD_SET_NETID:
480 rep_tlv_buf = cfg_set_netid(); 382 rep_tlv_buf = cfg_set_netid();
481 break; 383 break;
@@ -491,18 +393,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
491 case TIPC_CMD_GET_MAX_SUBSCR: 393 case TIPC_CMD_GET_MAX_SUBSCR:
492 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions); 394 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions);
493 break; 395 break;
494 case TIPC_CMD_GET_MAX_ZONES:
495 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_zones);
496 break;
497 case TIPC_CMD_GET_MAX_CLUSTERS:
498 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_clusters);
499 break;
500 case TIPC_CMD_GET_MAX_NODES:
501 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes);
502 break;
503 case TIPC_CMD_GET_MAX_SLAVES:
504 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_slaves);
505 break;
506 case TIPC_CMD_GET_NETID: 396 case TIPC_CMD_GET_NETID:
507 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 397 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
508 break; 398 break;
@@ -510,6 +400,17 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
510 rep_tlv_buf = 400 rep_tlv_buf =
511 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); 401 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
512 break; 402 break;
403 case TIPC_CMD_SET_MAX_ZONES:
404 case TIPC_CMD_GET_MAX_ZONES:
405 case TIPC_CMD_SET_MAX_SLAVES:
406 case TIPC_CMD_GET_MAX_SLAVES:
407 case TIPC_CMD_SET_MAX_CLUSTERS:
408 case TIPC_CMD_GET_MAX_CLUSTERS:
409 case TIPC_CMD_SET_MAX_NODES:
410 case TIPC_CMD_GET_MAX_NODES:
411 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
412 " (obsolete command)");
413 break;
513 default: 414 default:
514 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 415 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
515 " (unknown command)"); 416 " (unknown command)");
@@ -572,20 +473,16 @@ int tipc_cfg_init(void)
572 struct tipc_name_seq seq; 473 struct tipc_name_seq seq;
573 int res; 474 int res;
574 475
575 res = tipc_attach(&mng.user_ref, NULL, NULL); 476 res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
576 if (res)
577 goto failed;
578
579 res = tipc_createport(mng.user_ref, NULL, TIPC_CRITICAL_IMPORTANCE,
580 NULL, NULL, NULL, 477 NULL, NULL, NULL,
581 NULL, cfg_named_msg_event, NULL, 478 NULL, cfg_named_msg_event, NULL,
582 NULL, &mng.port_ref); 479 NULL, &config_port_ref);
583 if (res) 480 if (res)
584 goto failed; 481 goto failed;
585 482
586 seq.type = TIPC_CFG_SRV; 483 seq.type = TIPC_CFG_SRV;
587 seq.lower = seq.upper = tipc_own_addr; 484 seq.lower = seq.upper = tipc_own_addr;
588 res = tipc_nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq); 485 res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq);
589 if (res) 486 if (res)
590 goto failed; 487 goto failed;
591 488
@@ -593,15 +490,13 @@ int tipc_cfg_init(void)
593 490
594failed: 491failed:
595 err("Unable to create configuration service\n"); 492 err("Unable to create configuration service\n");
596 tipc_detach(mng.user_ref);
597 mng.user_ref = 0;
598 return res; 493 return res;
599} 494}
600 495
601void tipc_cfg_stop(void) 496void tipc_cfg_stop(void)
602{ 497{
603 if (mng.user_ref) { 498 if (config_port_ref) {
604 tipc_detach(mng.user_ref); 499 tipc_deleteport(config_port_ref);
605 mng.user_ref = 0; 500 config_port_ref = 0;
606 } 501 }
607} 502}
diff --git a/net/tipc/config.h b/net/tipc/config.h
index 481e12ece715..443159a166fd 100644
--- a/net/tipc/config.h
+++ b/net/tipc/config.h
@@ -39,7 +39,6 @@
39 39
40/* ---------------------------------------------------------------------- */ 40/* ---------------------------------------------------------------------- */
41 41
42#include "core.h"
43#include "link.h" 42#include "link.h"
44 43
45struct sk_buff *tipc_cfg_reply_alloc(int payload_size); 44struct sk_buff *tipc_cfg_reply_alloc(int payload_size);
diff --git a/net/tipc/core.c b/net/tipc/core.c
index e2a09eb8efd4..c9a73e7763f6 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -2,7 +2,7 @@
2 * net/tipc/core.c: TIPC module code 2 * net/tipc/core.c: TIPC module code
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-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
@@ -34,37 +34,13 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <linux/init.h>
38#include <linux/module.h>
39#include <linux/kernel.h>
40#include <linux/random.h>
41
42#include "core.h" 37#include "core.h"
43#include "dbg.h"
44#include "ref.h" 38#include "ref.h"
45#include "net.h"
46#include "user_reg.h"
47#include "name_table.h" 39#include "name_table.h"
48#include "subscr.h" 40#include "subscr.h"
49#include "config.h" 41#include "config.h"
50 42
51 43
52#ifndef CONFIG_TIPC_ZONES
53#define CONFIG_TIPC_ZONES 3
54#endif
55
56#ifndef CONFIG_TIPC_CLUSTERS
57#define CONFIG_TIPC_CLUSTERS 1
58#endif
59
60#ifndef CONFIG_TIPC_NODES
61#define CONFIG_TIPC_NODES 255
62#endif
63
64#ifndef CONFIG_TIPC_SLAVE_NODES
65#define CONFIG_TIPC_SLAVE_NODES 0
66#endif
67
68#ifndef CONFIG_TIPC_PORTS 44#ifndef CONFIG_TIPC_PORTS
69#define CONFIG_TIPC_PORTS 8191 45#define CONFIG_TIPC_PORTS 8191
70#endif 46#endif
@@ -77,7 +53,6 @@
77 53
78int tipc_mode = TIPC_NOT_RUNNING; 54int tipc_mode = TIPC_NOT_RUNNING;
79int tipc_random; 55int tipc_random;
80atomic_t tipc_user_count = ATOMIC_INIT(0);
81 56
82const char tipc_alphabet[] = 57const char tipc_alphabet[] =
83 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."; 58 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";
@@ -85,10 +60,6 @@ const char tipc_alphabet[] =
85/* configurable TIPC parameters */ 60/* configurable TIPC parameters */
86 61
87u32 tipc_own_addr; 62u32 tipc_own_addr;
88int tipc_max_zones;
89int tipc_max_clusters;
90int tipc_max_nodes;
91int tipc_max_slaves;
92int tipc_max_ports; 63int tipc_max_ports;
93int tipc_max_subscriptions; 64int tipc_max_subscriptions;
94int tipc_max_publications; 65int tipc_max_publications;
@@ -138,10 +109,11 @@ int tipc_core_start_net(unsigned long addr)
138{ 109{
139 int res; 110 int res;
140 111
141 if ((res = tipc_net_start(addr)) || 112 res = tipc_net_start(addr);
142 (res = tipc_eth_media_start())) { 113 if (!res)
114 res = tipc_eth_media_start();
115 if (res)
143 tipc_core_stop_net(); 116 tipc_core_stop_net();
144 }
145 return res; 117 return res;
146} 118}
147 119
@@ -160,7 +132,6 @@ static void tipc_core_stop(void)
160 tipc_handler_stop(); 132 tipc_handler_stop();
161 tipc_cfg_stop(); 133 tipc_cfg_stop();
162 tipc_subscr_stop(); 134 tipc_subscr_stop();
163 tipc_reg_stop();
164 tipc_nametbl_stop(); 135 tipc_nametbl_stop();
165 tipc_ref_table_stop(); 136 tipc_ref_table_stop();
166 tipc_socket_stop(); 137 tipc_socket_stop();
@@ -181,16 +152,22 @@ static int tipc_core_start(void)
181 get_random_bytes(&tipc_random, sizeof(tipc_random)); 152 get_random_bytes(&tipc_random, sizeof(tipc_random));
182 tipc_mode = TIPC_NODE_MODE; 153 tipc_mode = TIPC_NODE_MODE;
183 154
184 if ((res = tipc_handler_start()) || 155 res = tipc_handler_start();
185 (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) || 156 if (!res)
186 (res = tipc_reg_start()) || 157 res = tipc_ref_table_init(tipc_max_ports, tipc_random);
187 (res = tipc_nametbl_init()) || 158 if (!res)
188 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || 159 res = tipc_nametbl_init();
189 (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) || 160 if (!res)
190 (res = tipc_netlink_start()) || 161 res = tipc_k_signal((Handler)tipc_subscr_start, 0);
191 (res = tipc_socket_init())) { 162 if (!res)
163 res = tipc_k_signal((Handler)tipc_cfg_init, 0);
164 if (!res)
165 res = tipc_netlink_start();
166 if (!res)
167 res = tipc_socket_init();
168 if (res)
192 tipc_core_stop(); 169 tipc_core_stop();
193 } 170
194 return res; 171 return res;
195} 172}
196 173
@@ -210,13 +187,10 @@ static int __init tipc_init(void)
210 tipc_max_publications = 10000; 187 tipc_max_publications = 10000;
211 tipc_max_subscriptions = 2000; 188 tipc_max_subscriptions = 2000;
212 tipc_max_ports = CONFIG_TIPC_PORTS; 189 tipc_max_ports = CONFIG_TIPC_PORTS;
213 tipc_max_zones = CONFIG_TIPC_ZONES;
214 tipc_max_clusters = CONFIG_TIPC_CLUSTERS;
215 tipc_max_nodes = CONFIG_TIPC_NODES;
216 tipc_max_slaves = CONFIG_TIPC_SLAVE_NODES;
217 tipc_net_id = 4711; 190 tipc_net_id = 4711;
218 191
219 if ((res = tipc_core_start())) 192 res = tipc_core_start();
193 if (res)
220 err("Unable to start in single node mode\n"); 194 err("Unable to start in single node mode\n");
221 else 195 else
222 info("Started in single node mode\n"); 196 info("Started in single node mode\n");
@@ -236,43 +210,3 @@ module_exit(tipc_exit);
236MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication"); 210MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication");
237MODULE_LICENSE("Dual BSD/GPL"); 211MODULE_LICENSE("Dual BSD/GPL");
238MODULE_VERSION(TIPC_MOD_VER); 212MODULE_VERSION(TIPC_MOD_VER);
239
240/* Native TIPC API for kernel-space applications (see tipc.h) */
241
242EXPORT_SYMBOL(tipc_attach);
243EXPORT_SYMBOL(tipc_detach);
244EXPORT_SYMBOL(tipc_createport);
245EXPORT_SYMBOL(tipc_deleteport);
246EXPORT_SYMBOL(tipc_ownidentity);
247EXPORT_SYMBOL(tipc_portimportance);
248EXPORT_SYMBOL(tipc_set_portimportance);
249EXPORT_SYMBOL(tipc_portunreliable);
250EXPORT_SYMBOL(tipc_set_portunreliable);
251EXPORT_SYMBOL(tipc_portunreturnable);
252EXPORT_SYMBOL(tipc_set_portunreturnable);
253EXPORT_SYMBOL(tipc_publish);
254EXPORT_SYMBOL(tipc_withdraw);
255EXPORT_SYMBOL(tipc_connect2port);
256EXPORT_SYMBOL(tipc_disconnect);
257EXPORT_SYMBOL(tipc_shutdown);
258EXPORT_SYMBOL(tipc_send);
259EXPORT_SYMBOL(tipc_send2name);
260EXPORT_SYMBOL(tipc_send2port);
261EXPORT_SYMBOL(tipc_multicast);
262
263/* TIPC API for external bearers (see tipc_bearer.h) */
264
265EXPORT_SYMBOL(tipc_block_bearer);
266EXPORT_SYMBOL(tipc_continue);
267EXPORT_SYMBOL(tipc_disable_bearer);
268EXPORT_SYMBOL(tipc_enable_bearer);
269EXPORT_SYMBOL(tipc_recv_msg);
270EXPORT_SYMBOL(tipc_register_media);
271
272/* TIPC API for external APIs (see tipc_port.h) */
273
274EXPORT_SYMBOL(tipc_createport_raw);
275EXPORT_SYMBOL(tipc_reject_msg);
276EXPORT_SYMBOL(tipc_send_buf_fast);
277EXPORT_SYMBOL(tipc_acknowledge);
278
diff --git a/net/tipc/core.h b/net/tipc/core.h
index e19389e57227..436dda1159d2 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -2,7 +2,7 @@
2 * net/tipc/core.h: Include file for TIPC global declarations 2 * net/tipc/core.h: Include file for TIPC global declarations
3 * 3 *
4 * Copyright (c) 2005-2006, Ericsson AB 4 * Copyright (c) 2005-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-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
@@ -39,10 +39,6 @@
39 39
40#include <linux/tipc.h> 40#include <linux/tipc.h>
41#include <linux/tipc_config.h> 41#include <linux/tipc_config.h>
42#include <net/tipc/tipc_msg.h>
43#include <net/tipc/tipc_port.h>
44#include <net/tipc/tipc_bearer.h>
45#include <net/tipc/tipc.h>
46#include <linux/types.h> 42#include <linux/types.h>
47#include <linux/kernel.h> 43#include <linux/kernel.h>
48#include <linux/errno.h> 44#include <linux/errno.h>
@@ -62,6 +58,9 @@
62 58
63#define TIPC_MOD_VER "2.0.0" 59#define TIPC_MOD_VER "2.0.0"
64 60
61struct tipc_msg; /* msg.h */
62struct print_buf; /* log.h */
63
65/* 64/*
66 * TIPC sanity test macros 65 * TIPC sanity test macros
67 */ 66 */
@@ -84,6 +83,7 @@
84 * user-defined buffers can be configured to do the same thing. 83 * user-defined buffers can be configured to do the same thing.
85 */ 84 */
86extern struct print_buf *const TIPC_NULL; 85extern struct print_buf *const TIPC_NULL;
86extern struct print_buf *const TIPC_CONS;
87extern struct print_buf *const TIPC_LOG; 87extern struct print_buf *const TIPC_LOG;
88 88
89void tipc_printf(struct print_buf *, const char *fmt, ...); 89void tipc_printf(struct print_buf *, const char *fmt, ...);
@@ -96,73 +96,35 @@ void tipc_printf(struct print_buf *, const char *fmt, ...);
96#define TIPC_OUTPUT TIPC_LOG 96#define TIPC_OUTPUT TIPC_LOG
97#endif 97#endif
98 98
99/*
100 * TIPC can be configured to send system messages to TIPC_OUTPUT
101 * or to the system console only.
102 */
103
104#ifdef CONFIG_TIPC_DEBUG
105
106#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 99#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
107 KERN_ERR "TIPC: " fmt, ## arg) 100 KERN_ERR "TIPC: " fmt, ## arg)
108#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 101#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
109 KERN_WARNING "TIPC: " fmt, ## arg) 102 KERN_WARNING "TIPC: " fmt, ## arg)
110#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 103#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
111 KERN_NOTICE "TIPC: " fmt, ## arg) 104 KERN_NOTICE "TIPC: " fmt, ## arg)
112
113#else
114
115#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg)
116#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg)
117#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg)
118 105
119#endif 106#ifdef CONFIG_TIPC_DEBUG
120 107
121/* 108/*
122 * DBG_OUTPUT is the destination print buffer for debug messages. 109 * DBG_OUTPUT is the destination print buffer for debug messages.
123 * It defaults to the the null print buffer, but can be redefined
124 * (typically in the individual .c files being debugged) to allow
125 * selected debug messages to be generated where needed.
126 */ 110 */
127 111
128#ifndef DBG_OUTPUT 112#ifndef DBG_OUTPUT
129#define DBG_OUTPUT TIPC_NULL 113#define DBG_OUTPUT TIPC_LOG
130#endif 114#endif
131 115
132/* 116#define dbg(fmt, arg...) tipc_printf(DBG_OUTPUT, KERN_DEBUG fmt, ## arg);
133 * TIPC can be configured to send debug messages to the specified print buffer
134 * (typically DBG_OUTPUT) or to suppress them entirely.
135 */
136 117
137#ifdef CONFIG_TIPC_DEBUG 118#define msg_dbg(msg, txt) tipc_msg_dbg(DBG_OUTPUT, msg, txt);
138
139#define dbg(fmt, arg...) \
140 do { \
141 if (DBG_OUTPUT != TIPC_NULL) \
142 tipc_printf(DBG_OUTPUT, fmt, ## arg); \
143 } while (0)
144#define msg_dbg(msg, txt) \
145 do { \
146 if (DBG_OUTPUT != TIPC_NULL) \
147 tipc_msg_dbg(DBG_OUTPUT, msg, txt); \
148 } while (0)
149#define dump(fmt, arg...) \
150 do { \
151 if (DBG_OUTPUT != TIPC_NULL) \
152 tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \
153 } while (0)
154 119
155void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); 120void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
156void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
157 121
158#else 122#else
159 123
160#define dbg(fmt, arg...) do {} while (0) 124#define dbg(fmt, arg...) do {} while (0)
161#define msg_dbg(msg, txt) do {} while (0) 125#define msg_dbg(msg, txt) do {} while (0)
162#define dump(fmt, arg...) do {} while (0)
163 126
164#define tipc_msg_dbg(...) do {} while (0) 127#define tipc_msg_dbg(buf, msg, txt) do {} while (0)
165#define tipc_dump_dbg(...) do {} while (0)
166 128
167#endif 129#endif
168 130
@@ -174,14 +136,17 @@ void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
174#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */ 136#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
175 137
176/* 138/*
139 * TIPC operating mode routines
140 */
141#define TIPC_NOT_RUNNING 0
142#define TIPC_NODE_MODE 1
143#define TIPC_NET_MODE 2
144
145/*
177 * Global configuration variables 146 * Global configuration variables
178 */ 147 */
179 148
180extern u32 tipc_own_addr; 149extern u32 tipc_own_addr;
181extern int tipc_max_zones;
182extern int tipc_max_clusters;
183extern int tipc_max_nodes;
184extern int tipc_max_slaves;
185extern int tipc_max_ports; 150extern int tipc_max_ports;
186extern int tipc_max_subscriptions; 151extern int tipc_max_subscriptions;
187extern int tipc_max_publications; 152extern int tipc_max_publications;
@@ -195,7 +160,6 @@ extern int tipc_remote_management;
195extern int tipc_mode; 160extern int tipc_mode;
196extern int tipc_random; 161extern int tipc_random;
197extern const char tipc_alphabet[]; 162extern const char tipc_alphabet[];
198extern atomic_t tipc_user_count;
199 163
200 164
201/* 165/*
@@ -240,7 +204,6 @@ u32 tipc_k_signal(Handler routine, unsigned long argument);
240static inline void k_init_timer(struct timer_list *timer, Handler routine, 204static inline void k_init_timer(struct timer_list *timer, Handler routine,
241 unsigned long argument) 205 unsigned long argument)
242{ 206{
243 dbg("initializing timer %p\n", timer);
244 setup_timer(timer, routine, argument); 207 setup_timer(timer, routine, argument);
245} 208}
246 209
@@ -260,7 +223,6 @@ static inline void k_init_timer(struct timer_list *timer, Handler routine,
260 223
261static inline void k_start_timer(struct timer_list *timer, unsigned long msec) 224static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
262{ 225{
263 dbg("starting timer %p for %u\n", timer, msec);
264 mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1); 226 mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1);
265} 227}
266 228
@@ -277,7 +239,6 @@ static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
277 239
278static inline void k_cancel_timer(struct timer_list *timer) 240static inline void k_cancel_timer(struct timer_list *timer)
279{ 241{
280 dbg("cancelling timer %p\n", timer);
281 del_timer_sync(timer); 242 del_timer_sync(timer);
282} 243}
283 244
@@ -295,7 +256,6 @@ static inline void k_cancel_timer(struct timer_list *timer)
295 256
296static inline void k_term_timer(struct timer_list *timer) 257static inline void k_term_timer(struct timer_list *timer)
297{ 258{
298 dbg("terminating timer %p\n", timer);
299} 259}
300 260
301 261
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 4a7cd3719b78..491eff56b9da 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -2,7 +2,7 @@
2 * net/tipc/discover.c 2 * net/tipc/discover.c
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-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
@@ -35,12 +35,8 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "link.h" 38#include "link.h"
40#include "zone.h"
41#include "discover.h" 39#include "discover.h"
42#include "port.h"
43#include "name_table.h"
44 40
45#define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */ 41#define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */
46#define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */ 42#define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */
@@ -61,7 +57,7 @@
61 * @timer_intv: current interval between requests (in ms) 57 * @timer_intv: current interval between requests (in ms)
62 */ 58 */
63struct link_req { 59struct link_req {
64 struct bearer *bearer; 60 struct tipc_bearer *bearer;
65 struct tipc_media_addr dest; 61 struct tipc_media_addr dest;
66 struct sk_buff *buf; 62 struct sk_buff *buf;
67 struct timer_list timer; 63 struct timer_list timer;
@@ -71,27 +67,24 @@ struct link_req {
71/** 67/**
72 * tipc_disc_init_msg - initialize a link setup message 68 * tipc_disc_init_msg - initialize a link setup message
73 * @type: message type (request or response) 69 * @type: message type (request or response)
74 * @req_links: number of links associated with message
75 * @dest_domain: network domain of node(s) which should respond to message 70 * @dest_domain: network domain of node(s) which should respond to message
76 * @b_ptr: ptr to bearer issuing message 71 * @b_ptr: ptr to bearer issuing message
77 */ 72 */
78 73
79static struct sk_buff *tipc_disc_init_msg(u32 type, 74static struct sk_buff *tipc_disc_init_msg(u32 type,
80 u32 req_links,
81 u32 dest_domain, 75 u32 dest_domain,
82 struct bearer *b_ptr) 76 struct tipc_bearer *b_ptr)
83{ 77{
84 struct sk_buff *buf = tipc_buf_acquire(DSC_H_SIZE); 78 struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE);
85 struct tipc_msg *msg; 79 struct tipc_msg *msg;
86 80
87 if (buf) { 81 if (buf) {
88 msg = buf_msg(buf); 82 msg = buf_msg(buf);
89 tipc_msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain); 83 tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
90 msg_set_non_seq(msg, 1); 84 msg_set_non_seq(msg, 1);
91 msg_set_req_links(msg, req_links);
92 msg_set_dest_domain(msg, dest_domain); 85 msg_set_dest_domain(msg, dest_domain);
93 msg_set_bc_netid(msg, tipc_net_id); 86 msg_set_bc_netid(msg, tipc_net_id);
94 msg_set_media_addr(msg, &b_ptr->publ.addr); 87 msg_set_media_addr(msg, &b_ptr->addr);
95 } 88 }
96 return buf; 89 return buf;
97} 90}
@@ -103,7 +96,7 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
103 * @media_addr: media address advertised by duplicated node 96 * @media_addr: media address advertised by duplicated node
104 */ 97 */
105 98
106static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr, 99static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr,
107 struct tipc_media_addr *media_addr) 100 struct tipc_media_addr *media_addr)
108{ 101{
109 char node_addr_str[16]; 102 char node_addr_str[16];
@@ -115,7 +108,7 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
115 tipc_media_addr_printf(&pb, media_addr); 108 tipc_media_addr_printf(&pb, media_addr);
116 tipc_printbuf_validate(&pb); 109 tipc_printbuf_validate(&pb);
117 warn("Duplicate %s using %s seen on <%s>\n", 110 warn("Duplicate %s using %s seen on <%s>\n",
118 node_addr_str, media_addr_str, b_ptr->publ.name); 111 node_addr_str, media_addr_str, b_ptr->name);
119} 112}
120 113
121/** 114/**
@@ -124,20 +117,23 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
124 * @b_ptr: bearer that message arrived on 117 * @b_ptr: bearer that message arrived on
125 */ 118 */
126 119
127void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) 120void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
128{ 121{
122 struct tipc_node *n_ptr;
129 struct link *link; 123 struct link *link;
130 struct tipc_media_addr media_addr; 124 struct tipc_media_addr media_addr, *addr;
125 struct sk_buff *rbuf;
131 struct tipc_msg *msg = buf_msg(buf); 126 struct tipc_msg *msg = buf_msg(buf);
132 u32 dest = msg_dest_domain(msg); 127 u32 dest = msg_dest_domain(msg);
133 u32 orig = msg_prevnode(msg); 128 u32 orig = msg_prevnode(msg);
134 u32 net_id = msg_bc_netid(msg); 129 u32 net_id = msg_bc_netid(msg);
135 u32 type = msg_type(msg); 130 u32 type = msg_type(msg);
131 int link_fully_up;
136 132
137 msg_get_media_addr(msg,&media_addr); 133 msg_get_media_addr(msg, &media_addr);
138 msg_dbg(msg, "RECV:");
139 buf_discard(buf); 134 buf_discard(buf);
140 135
136 /* Validate discovery message from requesting node */
141 if (net_id != tipc_net_id) 137 if (net_id != tipc_net_id)
142 return; 138 return;
143 if (!tipc_addr_domain_valid(dest)) 139 if (!tipc_addr_domain_valid(dest))
@@ -145,70 +141,76 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
145 if (!tipc_addr_node_valid(orig)) 141 if (!tipc_addr_node_valid(orig))
146 return; 142 return;
147 if (orig == tipc_own_addr) { 143 if (orig == tipc_own_addr) {
148 if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr))) 144 if (memcmp(&media_addr, &b_ptr->addr, sizeof(media_addr)))
149 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr); 145 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr);
150 return; 146 return;
151 } 147 }
152 if (!tipc_in_scope(dest, tipc_own_addr)) 148 if (!tipc_in_scope(dest, tipc_own_addr))
153 return; 149 return;
154 if (is_slave(tipc_own_addr) && is_slave(orig)) 150 if (!in_own_cluster(orig))
155 return; 151 return;
156 if (is_slave(orig) && !in_own_cluster(orig)) 152
153 /* Locate structure corresponding to requesting node */
154 n_ptr = tipc_node_find(orig);
155 if (!n_ptr) {
156 n_ptr = tipc_node_create(orig);
157 if (!n_ptr)
158 return;
159 }
160 tipc_node_lock(n_ptr);
161
162 /* Don't talk to neighbor during cleanup after last session */
163 if (n_ptr->cleanup_required) {
164 tipc_node_unlock(n_ptr);
157 return; 165 return;
158 if (in_own_cluster(orig)) { 166 }
159 /* Always accept link here */
160 struct sk_buff *rbuf;
161 struct tipc_media_addr *addr;
162 struct tipc_node *n_ptr = tipc_node_find(orig);
163 int link_fully_up;
164
165 dbg(" in own cluster\n");
166 if (n_ptr == NULL) {
167 n_ptr = tipc_node_create(orig);
168 if (!n_ptr)
169 return;
170 }
171 spin_lock_bh(&n_ptr->lock);
172 167
173 /* Don't talk to neighbor during cleanup after last session */ 168 link = n_ptr->links[b_ptr->identity];
174 169
175 if (n_ptr->cleanup_required) { 170 /* Create a link endpoint for this bearer, if necessary */
176 spin_unlock_bh(&n_ptr->lock); 171 if (!link) {
172 link = tipc_link_create(n_ptr, b_ptr, &media_addr);
173 if (!link) {
174 tipc_node_unlock(n_ptr);
177 return; 175 return;
178 } 176 }
177 }
179 178
180 link = n_ptr->links[b_ptr->identity]; 179 /*
181 if (!link) { 180 * Ensure requesting node's media address is correct
182 dbg("creating link\n"); 181 *
183 link = tipc_link_create(b_ptr, orig, &media_addr); 182 * If media address doesn't match and the link is working, reject the
184 if (!link) { 183 * request (must be from a duplicate node).
185 spin_unlock_bh(&n_ptr->lock); 184 *
186 return; 185 * If media address doesn't match and the link is not working, accept
187 } 186 * the new media address and reset the link to ensure it starts up
188 } 187 * cleanly.
189 addr = &link->media_addr; 188 */
190 if (memcmp(addr, &media_addr, sizeof(*addr))) { 189 addr = &link->media_addr;
191 if (tipc_link_is_up(link) || (!link->started)) { 190 if (memcmp(addr, &media_addr, sizeof(*addr))) {
192 disc_dupl_alert(b_ptr, orig, &media_addr); 191 if (tipc_link_is_up(link) || (!link->started)) {
193 spin_unlock_bh(&n_ptr->lock); 192 disc_dupl_alert(b_ptr, orig, &media_addr);
194 return; 193 tipc_node_unlock(n_ptr);
195 }
196 warn("Resetting link <%s>, peer interface address changed\n",
197 link->name);
198 memcpy(addr, &media_addr, sizeof(*addr));
199 tipc_link_reset(link);
200 }
201 link_fully_up = link_working_working(link);
202 spin_unlock_bh(&n_ptr->lock);
203 if ((type == DSC_RESP_MSG) || link_fully_up)
204 return; 194 return;
205 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); 195 }
206 if (rbuf != NULL) { 196 warn("Resetting link <%s>, peer interface address changed\n",
207 msg_dbg(buf_msg(rbuf),"SEND:"); 197 link->name);
208 b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr); 198 memcpy(addr, &media_addr, sizeof(*addr));
199 tipc_link_reset(link);
200 }
201
202 /* Accept discovery message & send response, if necessary */
203 link_fully_up = link_working_working(link);
204
205 if ((type == DSC_REQ_MSG) && !link_fully_up && !b_ptr->blocked) {
206 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, orig, b_ptr);
207 if (rbuf) {
208 b_ptr->media->send_msg(rbuf, b_ptr, &media_addr);
209 buf_discard(rbuf); 209 buf_discard(rbuf);
210 } 210 }
211 } 211 }
212
213 tipc_node_unlock(n_ptr);
212} 214}
213 215
214/** 216/**
@@ -261,9 +263,9 @@ void tipc_disc_update_link_req(struct link_req *req)
261 263
262static void disc_timeout(struct link_req *req) 264static void disc_timeout(struct link_req *req)
263{ 265{
264 spin_lock_bh(&req->bearer->publ.lock); 266 spin_lock_bh(&req->bearer->lock);
265 267
266 req->bearer->media->send_msg(req->buf, &req->bearer->publ, &req->dest); 268 req->bearer->media->send_msg(req->buf, req->bearer, &req->dest);
267 269
268 if ((req->timer_intv == TIPC_LINK_REQ_SLOW) || 270 if ((req->timer_intv == TIPC_LINK_REQ_SLOW) ||
269 (req->timer_intv == TIPC_LINK_REQ_FAST)) { 271 (req->timer_intv == TIPC_LINK_REQ_FAST)) {
@@ -278,7 +280,7 @@ static void disc_timeout(struct link_req *req)
278 } 280 }
279 k_start_timer(&req->timer, req->timer_intv); 281 k_start_timer(&req->timer, req->timer_intv);
280 282
281 spin_unlock_bh(&req->bearer->publ.lock); 283 spin_unlock_bh(&req->bearer->lock);
282} 284}
283 285
284/** 286/**
@@ -286,15 +288,13 @@ static void disc_timeout(struct link_req *req)
286 * @b_ptr: ptr to bearer issuing requests 288 * @b_ptr: ptr to bearer issuing requests
287 * @dest: destination address for request messages 289 * @dest: destination address for request messages
288 * @dest_domain: network domain of node(s) which should respond to message 290 * @dest_domain: network domain of node(s) which should respond to message
289 * @req_links: max number of desired links
290 * 291 *
291 * Returns pointer to link request structure, or NULL if unable to create. 292 * Returns pointer to link request structure, or NULL if unable to create.
292 */ 293 */
293 294
294struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, 295struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
295 const struct tipc_media_addr *dest, 296 const struct tipc_media_addr *dest,
296 u32 dest_domain, 297 u32 dest_domain)
297 u32 req_links)
298{ 298{
299 struct link_req *req; 299 struct link_req *req;
300 300
@@ -302,7 +302,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr,
302 if (!req) 302 if (!req)
303 return NULL; 303 return NULL;
304 304
305 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr); 305 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr);
306 if (!req->buf) { 306 if (!req->buf) {
307 kfree(req); 307 kfree(req);
308 return NULL; 308 return NULL;
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index f8e750636123..e48a167e47b2 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -2,7 +2,7 @@
2 * net/tipc/discover.h 2 * net/tipc/discover.h
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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,17 +37,14 @@
37#ifndef _TIPC_DISCOVER_H 37#ifndef _TIPC_DISCOVER_H
38#define _TIPC_DISCOVER_H 38#define _TIPC_DISCOVER_H
39 39
40#include "core.h"
41
42struct link_req; 40struct link_req;
43 41
44struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, 42struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
45 const struct tipc_media_addr *dest, 43 const struct tipc_media_addr *dest,
46 u32 dest_domain, 44 u32 dest_domain);
47 u32 req_links);
48void tipc_disc_update_link_req(struct link_req *req); 45void tipc_disc_update_link_req(struct link_req *req);
49void tipc_disc_stop_link_req(struct link_req *req); 46void tipc_disc_stop_link_req(struct link_req *req);
50 47
51void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr); 48void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr);
52 49
53#endif 50#endif
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 6e988ba485fd..b69092eb95d8 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -34,12 +34,8 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <net/tipc/tipc.h> 37#include "core.h"
38#include <net/tipc/tipc_bearer.h> 38#include "bearer.h"
39#include <net/tipc/tipc_msg.h>
40#include <linux/netdevice.h>
41#include <linux/slab.h>
42#include <net/net_namespace.h>
43 39
44#define MAX_ETH_BEARERS 2 40#define MAX_ETH_BEARERS 2
45#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI 41#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI
@@ -60,7 +56,7 @@ struct eth_bearer {
60}; 56};
61 57
62static struct eth_bearer eth_bearers[MAX_ETH_BEARERS]; 58static struct eth_bearer eth_bearers[MAX_ETH_BEARERS];
63static int eth_started = 0; 59static int eth_started;
64static struct notifier_block notifier; 60static struct notifier_block notifier;
65 61
66/** 62/**
@@ -148,7 +144,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
148 144
149 /* Find device with specified name */ 145 /* Find device with specified name */
150 146
151 for_each_netdev(&init_net, pdev){ 147 for_each_netdev(&init_net, pdev) {
152 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) { 148 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
153 dev = pdev; 149 dev = pdev;
154 break; 150 break;
@@ -159,7 +155,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
159 155
160 /* Find Ethernet bearer for device (or create one) */ 156 /* Find Ethernet bearer for device (or create one) */
161 157
162 for (;(eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev); eb_ptr++); 158 while ((eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev))
159 eb_ptr++;
163 if (eb_ptr == stop) 160 if (eb_ptr == stop)
164 return -EDQUOT; 161 return -EDQUOT;
165 if (!eb_ptr->dev) { 162 if (!eb_ptr->dev) {
diff --git a/net/tipc/handler.c b/net/tipc/handler.c
index 0c70010a7dfe..274c98e164b7 100644
--- a/net/tipc/handler.c
+++ b/net/tipc/handler.c
@@ -45,7 +45,7 @@ struct queue_item {
45static struct kmem_cache *tipc_queue_item_cache; 45static struct kmem_cache *tipc_queue_item_cache;
46static struct list_head signal_queue_head; 46static struct list_head signal_queue_head;
47static DEFINE_SPINLOCK(qitem_lock); 47static DEFINE_SPINLOCK(qitem_lock);
48static int handler_enabled = 0; 48static int handler_enabled;
49 49
50static void process_signal_queue(unsigned long dummy); 50static void process_signal_queue(unsigned long dummy);
51 51
diff --git a/net/tipc/link.c b/net/tipc/link.c
index b31992ccd5d3..ebf338f7b14e 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2,7 +2,7 @@
2 * net/tipc/link.c: TIPC link code 2 * net/tipc/link.c: TIPC link code
3 * 3 *
4 * Copyright (c) 1996-2007, Ericsson AB 4 * Copyright (c) 1996-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-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
@@ -35,19 +35,11 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "link.h" 38#include "link.h"
40#include "net.h"
41#include "node.h"
42#include "port.h" 39#include "port.h"
43#include "addr.h"
44#include "node_subscr.h"
45#include "name_distr.h" 40#include "name_distr.h"
46#include "bearer.h"
47#include "name_table.h"
48#include "discover.h" 41#include "discover.h"
49#include "config.h" 42#include "config.h"
50#include "bcast.h"
51 43
52 44
53/* 45/*
@@ -57,12 +49,6 @@
57#define INVALID_SESSION 0x10000 49#define INVALID_SESSION 0x10000
58 50
59/* 51/*
60 * Limit for deferred reception queue:
61 */
62
63#define DEF_QUEUE_LIMIT 256u
64
65/*
66 * Link state events: 52 * Link state events:
67 */ 53 */
68 54
@@ -104,81 +90,16 @@ static void link_handle_out_of_seq_msg(struct link *l_ptr,
104static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf); 90static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf);
105static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf); 91static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf);
106static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); 92static void link_set_supervision_props(struct link *l_ptr, u32 tolerance);
107static int link_send_sections_long(struct port *sender, 93static int link_send_sections_long(struct tipc_port *sender,
108 struct iovec const *msg_sect, 94 struct iovec const *msg_sect,
109 u32 num_sect, u32 destnode); 95 u32 num_sect, u32 destnode);
110static void link_check_defragm_bufs(struct link *l_ptr); 96static void link_check_defragm_bufs(struct link *l_ptr);
111static void link_state_event(struct link *l_ptr, u32 event); 97static void link_state_event(struct link *l_ptr, u32 event);
112static void link_reset_statistics(struct link *l_ptr); 98static void link_reset_statistics(struct link *l_ptr);
113static void link_print(struct link *l_ptr, struct print_buf *buf, 99static void link_print(struct link *l_ptr, const char *str);
114 const char *str);
115static void link_start(struct link *l_ptr); 100static void link_start(struct link *l_ptr);
116static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf); 101static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
117 102
118
119/*
120 * Debugging code used by link routines only
121 *
122 * When debugging link problems on a system that has multiple links,
123 * the standard TIPC debugging routines may not be useful since they
124 * allow the output from multiple links to be intermixed. For this reason
125 * routines of the form "dbg_link_XXX()" have been created that will capture
126 * debug info into a link's personal print buffer, which can then be dumped
127 * into the TIPC system log (TIPC_LOG) upon request.
128 *
129 * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size
130 * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0,
131 * the dbg_link_XXX() routines simply send their output to the standard
132 * debug print buffer (DBG_OUTPUT), if it has been defined; this can be useful
133 * when there is only a single link in the system being debugged.
134 *
135 * Notes:
136 * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE
137 * - "l_ptr" must be valid when using dbg_link_XXX() macros
138 */
139
140#define LINK_LOG_BUF_SIZE 0
141
142#define dbg_link(fmt, arg...) \
143 do { \
144 if (LINK_LOG_BUF_SIZE) \
145 tipc_printf(&l_ptr->print_buf, fmt, ## arg); \
146 } while (0)
147#define dbg_link_msg(msg, txt) \
148 do { \
149 if (LINK_LOG_BUF_SIZE) \
150 tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \
151 } while (0)
152#define dbg_link_state(txt) \
153 do { \
154 if (LINK_LOG_BUF_SIZE) \
155 link_print(l_ptr, &l_ptr->print_buf, txt); \
156 } while (0)
157#define dbg_link_dump() do { \
158 if (LINK_LOG_BUF_SIZE) { \
159 tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \
160 tipc_printbuf_move(LOG, &l_ptr->print_buf); \
161 } \
162} while (0)
163
164static void dbg_print_link(struct link *l_ptr, const char *str)
165{
166 if (DBG_OUTPUT != TIPC_NULL)
167 link_print(l_ptr, DBG_OUTPUT, str);
168}
169
170static void dbg_print_buf_chain(struct sk_buff *root_buf)
171{
172 if (DBG_OUTPUT != TIPC_NULL) {
173 struct sk_buff *buf = root_buf;
174
175 while (buf) {
176 msg_dbg(buf_msg(buf), "In chain: ");
177 buf = buf->next;
178 }
179 }
180}
181
182/* 103/*
183 * Simple link routines 104 * Simple link routines
184 */ 105 */
@@ -192,7 +113,7 @@ static void link_init_max_pkt(struct link *l_ptr)
192{ 113{
193 u32 max_pkt; 114 u32 max_pkt;
194 115
195 max_pkt = (l_ptr->b_ptr->publ.mtu & ~3); 116 max_pkt = (l_ptr->b_ptr->mtu & ~3);
196 if (max_pkt > MAX_MSG_SIZE) 117 if (max_pkt > MAX_MSG_SIZE)
197 max_pkt = MAX_MSG_SIZE; 118 max_pkt = MAX_MSG_SIZE;
198 119
@@ -266,14 +187,17 @@ static int link_name_validate(const char *name, struct link_name *name_parts)
266 /* ensure all component parts of link name are present */ 187 /* ensure all component parts of link name are present */
267 188
268 addr_local = name_copy; 189 addr_local = name_copy;
269 if ((if_local = strchr(addr_local, ':')) == NULL) 190 if_local = strchr(addr_local, ':');
191 if (if_local == NULL)
270 return 0; 192 return 0;
271 *(if_local++) = 0; 193 *(if_local++) = 0;
272 if ((addr_peer = strchr(if_local, '-')) == NULL) 194 addr_peer = strchr(if_local, '-');
195 if (addr_peer == NULL)
273 return 0; 196 return 0;
274 *(addr_peer++) = 0; 197 *(addr_peer++) = 0;
275 if_local_len = addr_peer - if_local; 198 if_local_len = addr_peer - if_local;
276 if ((if_peer = strchr(addr_peer, ':')) == NULL) 199 if_peer = strchr(addr_peer, ':');
200 if (if_peer == NULL)
277 return 0; 201 return 0;
278 *(if_peer++) = 0; 202 *(if_peer++) = 0;
279 if_peer_len = strlen(if_peer) + 1; 203 if_peer_len = strlen(if_peer) + 1;
@@ -322,9 +246,6 @@ static void link_timeout(struct link *l_ptr)
322 l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size; 246 l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size;
323 l_ptr->stats.queue_sz_counts++; 247 l_ptr->stats.queue_sz_counts++;
324 248
325 if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz)
326 l_ptr->stats.max_queue_sz = l_ptr->out_queue_size;
327
328 if (l_ptr->first_out) { 249 if (l_ptr->first_out) {
329 struct tipc_msg *msg = buf_msg(l_ptr->first_out); 250 struct tipc_msg *msg = buf_msg(l_ptr->first_out);
330 u32 length = msg_size(msg); 251 u32 length = msg_size(msg);
@@ -372,39 +293,44 @@ static void link_set_timer(struct link *l_ptr, u32 time)
372 293
373/** 294/**
374 * tipc_link_create - create a new link 295 * tipc_link_create - create a new link
296 * @n_ptr: pointer to associated node
375 * @b_ptr: pointer to associated bearer 297 * @b_ptr: pointer to associated bearer
376 * @peer: network address of node at other end of link
377 * @media_addr: media address to use when sending messages over link 298 * @media_addr: media address to use when sending messages over link
378 * 299 *
379 * Returns pointer to link. 300 * Returns pointer to link.
380 */ 301 */
381 302
382struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, 303struct link *tipc_link_create(struct tipc_node *n_ptr,
304 struct tipc_bearer *b_ptr,
383 const struct tipc_media_addr *media_addr) 305 const struct tipc_media_addr *media_addr)
384{ 306{
385 struct link *l_ptr; 307 struct link *l_ptr;
386 struct tipc_msg *msg; 308 struct tipc_msg *msg;
387 char *if_name; 309 char *if_name;
310 char addr_string[16];
311 u32 peer = n_ptr->addr;
388 312
389 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); 313 if (n_ptr->link_cnt >= 2) {
390 if (!l_ptr) { 314 tipc_addr_string_fill(addr_string, n_ptr->addr);
391 warn("Link creation failed, no memory\n"); 315 err("Attempt to establish third link to %s\n", addr_string);
392 return NULL; 316 return NULL;
393 } 317 }
394 318
395 if (LINK_LOG_BUF_SIZE) { 319 if (n_ptr->links[b_ptr->identity]) {
396 char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); 320 tipc_addr_string_fill(addr_string, n_ptr->addr);
321 err("Attempt to establish second link on <%s> to %s\n",
322 b_ptr->name, addr_string);
323 return NULL;
324 }
397 325
398 if (!pb) { 326 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC);
399 kfree(l_ptr); 327 if (!l_ptr) {
400 warn("Link creation failed, no memory for print buffer\n"); 328 warn("Link creation failed, no memory\n");
401 return NULL; 329 return NULL;
402 }
403 tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
404 } 330 }
405 331
406 l_ptr->addr = peer; 332 l_ptr->addr = peer;
407 if_name = strchr(b_ptr->publ.name, ':') + 1; 333 if_name = strchr(b_ptr->name, ':') + 1;
408 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 334 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:",
409 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 335 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
410 tipc_node(tipc_own_addr), 336 tipc_node(tipc_own_addr),
@@ -412,6 +338,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
412 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 338 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
413 /* note: peer i/f is appended to link name by reset/activate */ 339 /* note: peer i/f is appended to link name by reset/activate */
414 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 340 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
341 l_ptr->owner = n_ptr;
415 l_ptr->checkpoint = 1; 342 l_ptr->checkpoint = 1;
416 l_ptr->b_ptr = b_ptr; 343 l_ptr->b_ptr = b_ptr;
417 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); 344 link_set_supervision_props(l_ptr, b_ptr->media->tolerance);
@@ -435,21 +362,12 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
435 362
436 link_reset_statistics(l_ptr); 363 link_reset_statistics(l_ptr);
437 364
438 l_ptr->owner = tipc_node_attach_link(l_ptr); 365 tipc_node_attach_link(n_ptr, l_ptr);
439 if (!l_ptr->owner) {
440 if (LINK_LOG_BUF_SIZE)
441 kfree(l_ptr->print_buf.buf);
442 kfree(l_ptr);
443 return NULL;
444 }
445 366
446 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); 367 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
447 list_add_tail(&l_ptr->link_list, &b_ptr->links); 368 list_add_tail(&l_ptr->link_list, &b_ptr->links);
448 tipc_k_signal((Handler)link_start, (unsigned long)l_ptr); 369 tipc_k_signal((Handler)link_start, (unsigned long)l_ptr);
449 370
450 dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",
451 l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit);
452
453 return l_ptr; 371 return l_ptr;
454} 372}
455 373
@@ -469,8 +387,6 @@ void tipc_link_delete(struct link *l_ptr)
469 return; 387 return;
470 } 388 }
471 389
472 dbg("tipc_link_delete()\n");
473
474 k_cancel_timer(&l_ptr->timer); 390 k_cancel_timer(&l_ptr->timer);
475 391
476 tipc_node_lock(l_ptr->owner); 392 tipc_node_lock(l_ptr->owner);
@@ -478,8 +394,6 @@ void tipc_link_delete(struct link *l_ptr)
478 tipc_node_detach_link(l_ptr->owner, l_ptr); 394 tipc_node_detach_link(l_ptr->owner, l_ptr);
479 tipc_link_stop(l_ptr); 395 tipc_link_stop(l_ptr);
480 list_del_init(&l_ptr->link_list); 396 list_del_init(&l_ptr->link_list);
481 if (LINK_LOG_BUF_SIZE)
482 kfree(l_ptr->print_buf.buf);
483 tipc_node_unlock(l_ptr->owner); 397 tipc_node_unlock(l_ptr->owner);
484 k_term_timer(&l_ptr->timer); 398 k_term_timer(&l_ptr->timer);
485 kfree(l_ptr); 399 kfree(l_ptr);
@@ -487,8 +401,9 @@ void tipc_link_delete(struct link *l_ptr)
487 401
488static void link_start(struct link *l_ptr) 402static void link_start(struct link *l_ptr)
489{ 403{
490 dbg("link_start %x\n", l_ptr); 404 tipc_node_lock(l_ptr->owner);
491 link_state_event(l_ptr, STARTING_EVT); 405 link_state_event(l_ptr, STARTING_EVT);
406 tipc_node_unlock(l_ptr->owner);
492} 407}
493 408
494/** 409/**
@@ -503,7 +418,7 @@ static void link_start(struct link *l_ptr)
503 418
504static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz) 419static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
505{ 420{
506 struct port *p_ptr; 421 struct tipc_port *p_ptr;
507 422
508 spin_lock_bh(&tipc_port_list_lock); 423 spin_lock_bh(&tipc_port_list_lock);
509 p_ptr = tipc_port_lock(origport); 424 p_ptr = tipc_port_lock(origport);
@@ -512,7 +427,7 @@ static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
512 goto exit; 427 goto exit;
513 if (!list_empty(&p_ptr->wait_list)) 428 if (!list_empty(&p_ptr->wait_list))
514 goto exit; 429 goto exit;
515 p_ptr->publ.congested = 1; 430 p_ptr->congested = 1;
516 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt); 431 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt);
517 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); 432 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports);
518 l_ptr->stats.link_congs++; 433 l_ptr->stats.link_congs++;
@@ -525,8 +440,8 @@ exit:
525 440
526void tipc_link_wakeup_ports(struct link *l_ptr, int all) 441void tipc_link_wakeup_ports(struct link *l_ptr, int all)
527{ 442{
528 struct port *p_ptr; 443 struct tipc_port *p_ptr;
529 struct port *temp_p_ptr; 444 struct tipc_port *temp_p_ptr;
530 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size; 445 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size;
531 446
532 if (all) 447 if (all)
@@ -542,11 +457,11 @@ void tipc_link_wakeup_ports(struct link *l_ptr, int all)
542 if (win <= 0) 457 if (win <= 0)
543 break; 458 break;
544 list_del_init(&p_ptr->wait_list); 459 list_del_init(&p_ptr->wait_list);
545 spin_lock_bh(p_ptr->publ.lock); 460 spin_lock_bh(p_ptr->lock);
546 p_ptr->publ.congested = 0; 461 p_ptr->congested = 0;
547 p_ptr->wakeup(&p_ptr->publ); 462 p_ptr->wakeup(p_ptr);
548 win -= p_ptr->waiting_pkts; 463 win -= p_ptr->waiting_pkts;
549 spin_unlock_bh(p_ptr->publ.lock); 464 spin_unlock_bh(p_ptr->lock);
550 } 465 }
551 466
552exit: 467exit:
@@ -639,7 +554,6 @@ void tipc_link_reset(struct link *l_ptr)
639 link_init_max_pkt(l_ptr); 554 link_init_max_pkt(l_ptr);
640 555
641 l_ptr->state = RESET_UNKNOWN; 556 l_ptr->state = RESET_UNKNOWN;
642 dbg_link_state("Resetting Link\n");
643 557
644 if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) 558 if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET))
645 return; 559 return;
@@ -647,7 +561,7 @@ void tipc_link_reset(struct link *l_ptr)
647 tipc_node_link_down(l_ptr->owner, l_ptr); 561 tipc_node_link_down(l_ptr->owner, l_ptr);
648 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); 562 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
649 563
650 if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && 564 if (was_active_link && tipc_node_active_links(l_ptr->owner) &&
651 l_ptr->owner->permit_changeover) { 565 l_ptr->owner->permit_changeover) {
652 l_ptr->reset_checkpoint = checkpoint; 566 l_ptr->reset_checkpoint = checkpoint;
653 l_ptr->exp_msg_count = START_CHANGEOVER; 567 l_ptr->exp_msg_count = START_CHANGEOVER;
@@ -713,25 +627,18 @@ static void link_state_event(struct link *l_ptr, unsigned event)
713 return; /* Not yet. */ 627 return; /* Not yet. */
714 628
715 if (link_blocked(l_ptr)) { 629 if (link_blocked(l_ptr)) {
716 if (event == TIMEOUT_EVT) { 630 if (event == TIMEOUT_EVT)
717 link_set_timer(l_ptr, cont_intv); 631 link_set_timer(l_ptr, cont_intv);
718 }
719 return; /* Changeover going on */ 632 return; /* Changeover going on */
720 } 633 }
721 dbg_link("STATE_EV: <%s> ", l_ptr->name);
722 634
723 switch (l_ptr->state) { 635 switch (l_ptr->state) {
724 case WORKING_WORKING: 636 case WORKING_WORKING:
725 dbg_link("WW/");
726 switch (event) { 637 switch (event) {
727 case TRAFFIC_MSG_EVT: 638 case TRAFFIC_MSG_EVT:
728 dbg_link("TRF-");
729 /* fall through */
730 case ACTIVATE_MSG: 639 case ACTIVATE_MSG:
731 dbg_link("ACT\n");
732 break; 640 break;
733 case TIMEOUT_EVT: 641 case TIMEOUT_EVT:
734 dbg_link("TIM ");
735 if (l_ptr->next_in_no != l_ptr->checkpoint) { 642 if (l_ptr->next_in_no != l_ptr->checkpoint) {
736 l_ptr->checkpoint = l_ptr->next_in_no; 643 l_ptr->checkpoint = l_ptr->next_in_no;
737 if (tipc_bclink_acks_missing(l_ptr->owner)) { 644 if (tipc_bclink_acks_missing(l_ptr->owner)) {
@@ -746,7 +653,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
746 link_set_timer(l_ptr, cont_intv); 653 link_set_timer(l_ptr, cont_intv);
747 break; 654 break;
748 } 655 }
749 dbg_link(" -> WU\n");
750 l_ptr->state = WORKING_UNKNOWN; 656 l_ptr->state = WORKING_UNKNOWN;
751 l_ptr->fsm_msg_cnt = 0; 657 l_ptr->fsm_msg_cnt = 0;
752 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); 658 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
@@ -754,7 +660,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
754 link_set_timer(l_ptr, cont_intv / 4); 660 link_set_timer(l_ptr, cont_intv / 4);
755 break; 661 break;
756 case RESET_MSG: 662 case RESET_MSG:
757 dbg_link("RES -> RR\n");
758 info("Resetting link <%s>, requested by peer\n", 663 info("Resetting link <%s>, requested by peer\n",
759 l_ptr->name); 664 l_ptr->name);
760 tipc_link_reset(l_ptr); 665 tipc_link_reset(l_ptr);
@@ -769,18 +674,14 @@ static void link_state_event(struct link *l_ptr, unsigned event)
769 } 674 }
770 break; 675 break;
771 case WORKING_UNKNOWN: 676 case WORKING_UNKNOWN:
772 dbg_link("WU/");
773 switch (event) { 677 switch (event) {
774 case TRAFFIC_MSG_EVT: 678 case TRAFFIC_MSG_EVT:
775 dbg_link("TRF-");
776 case ACTIVATE_MSG: 679 case ACTIVATE_MSG:
777 dbg_link("ACT -> WW\n");
778 l_ptr->state = WORKING_WORKING; 680 l_ptr->state = WORKING_WORKING;
779 l_ptr->fsm_msg_cnt = 0; 681 l_ptr->fsm_msg_cnt = 0;
780 link_set_timer(l_ptr, cont_intv); 682 link_set_timer(l_ptr, cont_intv);
781 break; 683 break;
782 case RESET_MSG: 684 case RESET_MSG:
783 dbg_link("RES -> RR\n");
784 info("Resetting link <%s>, requested by peer " 685 info("Resetting link <%s>, requested by peer "
785 "while probing\n", l_ptr->name); 686 "while probing\n", l_ptr->name);
786 tipc_link_reset(l_ptr); 687 tipc_link_reset(l_ptr);
@@ -791,9 +692,7 @@ static void link_state_event(struct link *l_ptr, unsigned event)
791 link_set_timer(l_ptr, cont_intv); 692 link_set_timer(l_ptr, cont_intv);
792 break; 693 break;
793 case TIMEOUT_EVT: 694 case TIMEOUT_EVT:
794 dbg_link("TIM ");
795 if (l_ptr->next_in_no != l_ptr->checkpoint) { 695 if (l_ptr->next_in_no != l_ptr->checkpoint) {
796 dbg_link("-> WW\n");
797 l_ptr->state = WORKING_WORKING; 696 l_ptr->state = WORKING_WORKING;
798 l_ptr->fsm_msg_cnt = 0; 697 l_ptr->fsm_msg_cnt = 0;
799 l_ptr->checkpoint = l_ptr->next_in_no; 698 l_ptr->checkpoint = l_ptr->next_in_no;
@@ -804,16 +703,11 @@ static void link_state_event(struct link *l_ptr, unsigned event)
804 } 703 }
805 link_set_timer(l_ptr, cont_intv); 704 link_set_timer(l_ptr, cont_intv);
806 } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) { 705 } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) {
807 dbg_link("Probing %u/%u,timer = %u ms)\n",
808 l_ptr->fsm_msg_cnt, l_ptr->abort_limit,
809 cont_intv / 4);
810 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 706 tipc_link_send_proto_msg(l_ptr, STATE_MSG,
811 1, 0, 0, 0, 0); 707 1, 0, 0, 0, 0);
812 l_ptr->fsm_msg_cnt++; 708 l_ptr->fsm_msg_cnt++;
813 link_set_timer(l_ptr, cont_intv / 4); 709 link_set_timer(l_ptr, cont_intv / 4);
814 } else { /* Link has failed */ 710 } else { /* Link has failed */
815 dbg_link("-> RU (%u probes unanswered)\n",
816 l_ptr->fsm_msg_cnt);
817 warn("Resetting link <%s>, peer not responding\n", 711 warn("Resetting link <%s>, peer not responding\n",
818 l_ptr->name); 712 l_ptr->name);
819 tipc_link_reset(l_ptr); 713 tipc_link_reset(l_ptr);
@@ -830,18 +724,13 @@ static void link_state_event(struct link *l_ptr, unsigned event)
830 } 724 }
831 break; 725 break;
832 case RESET_UNKNOWN: 726 case RESET_UNKNOWN:
833 dbg_link("RU/");
834 switch (event) { 727 switch (event) {
835 case TRAFFIC_MSG_EVT: 728 case TRAFFIC_MSG_EVT:
836 dbg_link("TRF-\n");
837 break; 729 break;
838 case ACTIVATE_MSG: 730 case ACTIVATE_MSG:
839 other = l_ptr->owner->active_links[0]; 731 other = l_ptr->owner->active_links[0];
840 if (other && link_working_unknown(other)) { 732 if (other && link_working_unknown(other))
841 dbg_link("ACT\n");
842 break; 733 break;
843 }
844 dbg_link("ACT -> WW\n");
845 l_ptr->state = WORKING_WORKING; 734 l_ptr->state = WORKING_WORKING;
846 l_ptr->fsm_msg_cnt = 0; 735 l_ptr->fsm_msg_cnt = 0;
847 link_activate(l_ptr); 736 link_activate(l_ptr);
@@ -850,8 +739,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
850 link_set_timer(l_ptr, cont_intv); 739 link_set_timer(l_ptr, cont_intv);
851 break; 740 break;
852 case RESET_MSG: 741 case RESET_MSG:
853 dbg_link("RES\n");
854 dbg_link(" -> RR\n");
855 l_ptr->state = RESET_RESET; 742 l_ptr->state = RESET_RESET;
856 l_ptr->fsm_msg_cnt = 0; 743 l_ptr->fsm_msg_cnt = 0;
857 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0); 744 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0);
@@ -859,11 +746,9 @@ static void link_state_event(struct link *l_ptr, unsigned event)
859 link_set_timer(l_ptr, cont_intv); 746 link_set_timer(l_ptr, cont_intv);
860 break; 747 break;
861 case STARTING_EVT: 748 case STARTING_EVT:
862 dbg_link("START-");
863 l_ptr->started = 1; 749 l_ptr->started = 1;
864 /* fall through */ 750 /* fall through */
865 case TIMEOUT_EVT: 751 case TIMEOUT_EVT:
866 dbg_link("TIM\n");
867 tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0); 752 tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
868 l_ptr->fsm_msg_cnt++; 753 l_ptr->fsm_msg_cnt++;
869 link_set_timer(l_ptr, cont_intv); 754 link_set_timer(l_ptr, cont_intv);
@@ -873,18 +758,12 @@ static void link_state_event(struct link *l_ptr, unsigned event)
873 } 758 }
874 break; 759 break;
875 case RESET_RESET: 760 case RESET_RESET:
876 dbg_link("RR/ ");
877 switch (event) { 761 switch (event) {
878 case TRAFFIC_MSG_EVT: 762 case TRAFFIC_MSG_EVT:
879 dbg_link("TRF-");
880 /* fall through */
881 case ACTIVATE_MSG: 763 case ACTIVATE_MSG:
882 other = l_ptr->owner->active_links[0]; 764 other = l_ptr->owner->active_links[0];
883 if (other && link_working_unknown(other)) { 765 if (other && link_working_unknown(other))
884 dbg_link("ACT\n");
885 break; 766 break;
886 }
887 dbg_link("ACT -> WW\n");
888 l_ptr->state = WORKING_WORKING; 767 l_ptr->state = WORKING_WORKING;
889 l_ptr->fsm_msg_cnt = 0; 768 l_ptr->fsm_msg_cnt = 0;
890 link_activate(l_ptr); 769 link_activate(l_ptr);
@@ -893,14 +772,11 @@ static void link_state_event(struct link *l_ptr, unsigned event)
893 link_set_timer(l_ptr, cont_intv); 772 link_set_timer(l_ptr, cont_intv);
894 break; 773 break;
895 case RESET_MSG: 774 case RESET_MSG:
896 dbg_link("RES\n");
897 break; 775 break;
898 case TIMEOUT_EVT: 776 case TIMEOUT_EVT:
899 dbg_link("TIM\n");
900 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); 777 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
901 l_ptr->fsm_msg_cnt++; 778 l_ptr->fsm_msg_cnt++;
902 link_set_timer(l_ptr, cont_intv); 779 link_set_timer(l_ptr, cont_intv);
903 dbg_link("fsm_msg_cnt %u\n", l_ptr->fsm_msg_cnt);
904 break; 780 break;
905 default: 781 default:
906 err("Unknown link event %u in RR state\n", event); 782 err("Unknown link event %u in RR state\n", event);
@@ -940,9 +816,6 @@ static int link_bundle_buf(struct link *l_ptr,
940 skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); 816 skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size);
941 msg_set_size(bundler_msg, to_pos + size); 817 msg_set_size(bundler_msg, to_pos + size);
942 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); 818 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1);
943 dbg("Packed msg # %u(%u octets) into pos %u in buf(#%u)\n",
944 msg_msgcnt(bundler_msg), size, to_pos, msg_seqno(bundler_msg));
945 msg_dbg(msg, "PACKD:");
946 buf_discard(buf); 819 buf_discard(buf);
947 l_ptr->stats.sent_bundled++; 820 l_ptr->stats.sent_bundled++;
948 return 1; 821 return 1;
@@ -963,7 +836,10 @@ static void link_add_to_outqueue(struct link *l_ptr,
963 l_ptr->last_out = buf; 836 l_ptr->last_out = buf;
964 } else 837 } else
965 l_ptr->first_out = l_ptr->last_out = buf; 838 l_ptr->first_out = l_ptr->last_out = buf;
839
966 l_ptr->out_queue_size++; 840 l_ptr->out_queue_size++;
841 if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz)
842 l_ptr->stats.max_queue_sz = l_ptr->out_queue_size;
967} 843}
968 844
969/* 845/*
@@ -991,7 +867,6 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
991 return link_schedule_port(l_ptr, msg_origport(msg), 867 return link_schedule_port(l_ptr, msg_origport(msg),
992 size); 868 size);
993 } 869 }
994 msg_dbg(msg, "TIPC: Congestion, throwing away\n");
995 buf_discard(buf); 870 buf_discard(buf);
996 if (imp > CONN_MANAGER) { 871 if (imp > CONN_MANAGER) {
997 warn("Resetting link <%s>, send queue full", l_ptr->name); 872 warn("Resetting link <%s>, send queue full", l_ptr->name);
@@ -1007,9 +882,6 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1007 882
1008 /* Packet can be queued or sent: */ 883 /* Packet can be queued or sent: */
1009 884
1010 if (queue_size > l_ptr->stats.max_queue_sz)
1011 l_ptr->stats.max_queue_sz = queue_size;
1012
1013 if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && 885 if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) &&
1014 !link_congested(l_ptr))) { 886 !link_congested(l_ptr))) {
1015 link_add_to_outqueue(l_ptr, buf, msg); 887 link_add_to_outqueue(l_ptr, buf, msg);
@@ -1075,22 +947,16 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
1075 int res = -ELINKCONG; 947 int res = -ELINKCONG;
1076 948
1077 read_lock_bh(&tipc_net_lock); 949 read_lock_bh(&tipc_net_lock);
1078 n_ptr = tipc_node_select(dest, selector); 950 n_ptr = tipc_node_find(dest);
1079 if (n_ptr) { 951 if (n_ptr) {
1080 tipc_node_lock(n_ptr); 952 tipc_node_lock(n_ptr);
1081 l_ptr = n_ptr->active_links[selector & 1]; 953 l_ptr = n_ptr->active_links[selector & 1];
1082 if (l_ptr) { 954 if (l_ptr)
1083 dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest);
1084 res = tipc_link_send_buf(l_ptr, buf); 955 res = tipc_link_send_buf(l_ptr, buf);
1085 } else { 956 else
1086 dbg("Attempt to send msg to unreachable node:\n");
1087 msg_dbg(buf_msg(buf),">>>");
1088 buf_discard(buf); 957 buf_discard(buf);
1089 }
1090 tipc_node_unlock(n_ptr); 958 tipc_node_unlock(n_ptr);
1091 } else { 959 } else {
1092 dbg("Attempt to send msg to unknown node:\n");
1093 msg_dbg(buf_msg(buf),">>>");
1094 buf_discard(buf); 960 buf_discard(buf);
1095 } 961 }
1096 read_unlock_bh(&tipc_net_lock); 962 read_unlock_bh(&tipc_net_lock);
@@ -1117,17 +983,14 @@ static int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf,
1117 if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, 983 if (likely(tipc_bearer_send(l_ptr->b_ptr, buf,
1118 &l_ptr->media_addr))) { 984 &l_ptr->media_addr))) {
1119 l_ptr->unacked_window = 0; 985 l_ptr->unacked_window = 0;
1120 msg_dbg(msg,"SENT_FAST:");
1121 return res; 986 return res;
1122 } 987 }
1123 dbg("failed sent fast...\n");
1124 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); 988 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
1125 l_ptr->stats.bearer_congs++; 989 l_ptr->stats.bearer_congs++;
1126 l_ptr->next_out = buf; 990 l_ptr->next_out = buf;
1127 return res; 991 return res;
1128 } 992 }
1129 } 993 } else
1130 else
1131 *used_max_pkt = l_ptr->max_pkt; 994 *used_max_pkt = l_ptr->max_pkt;
1132 } 995 }
1133 return tipc_link_send_buf(l_ptr, buf); /* All other cases */ 996 return tipc_link_send_buf(l_ptr, buf); /* All other cases */
@@ -1151,12 +1014,10 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1151 return tipc_port_recv_msg(buf); 1014 return tipc_port_recv_msg(buf);
1152 1015
1153 read_lock_bh(&tipc_net_lock); 1016 read_lock_bh(&tipc_net_lock);
1154 n_ptr = tipc_node_select(destnode, selector); 1017 n_ptr = tipc_node_find(destnode);
1155 if (likely(n_ptr)) { 1018 if (likely(n_ptr)) {
1156 tipc_node_lock(n_ptr); 1019 tipc_node_lock(n_ptr);
1157 l_ptr = n_ptr->active_links[selector]; 1020 l_ptr = n_ptr->active_links[selector];
1158 dbg("send_fast: buf %x selected %x, destnode = %x\n",
1159 buf, l_ptr, destnode);
1160 if (likely(l_ptr)) { 1021 if (likely(l_ptr)) {
1161 res = link_send_buf_fast(l_ptr, buf, &dummy); 1022 res = link_send_buf_fast(l_ptr, buf, &dummy);
1162 tipc_node_unlock(n_ptr); 1023 tipc_node_unlock(n_ptr);
@@ -1178,12 +1039,12 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1178 * except for total message length. 1039 * except for total message length.
1179 * Returns user data length or errno. 1040 * Returns user data length or errno.
1180 */ 1041 */
1181int tipc_link_send_sections_fast(struct port *sender, 1042int tipc_link_send_sections_fast(struct tipc_port *sender,
1182 struct iovec const *msg_sect, 1043 struct iovec const *msg_sect,
1183 const u32 num_sect, 1044 const u32 num_sect,
1184 u32 destaddr) 1045 u32 destaddr)
1185{ 1046{
1186 struct tipc_msg *hdr = &sender->publ.phdr; 1047 struct tipc_msg *hdr = &sender->phdr;
1187 struct link *l_ptr; 1048 struct link *l_ptr;
1188 struct sk_buff *buf; 1049 struct sk_buff *buf;
1189 struct tipc_node *node; 1050 struct tipc_node *node;
@@ -1196,18 +1057,18 @@ again:
1196 * (Must not hold any locks while building message.) 1057 * (Must not hold any locks while building message.)
1197 */ 1058 */
1198 1059
1199 res = tipc_msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt, 1060 res = tipc_msg_build(hdr, msg_sect, num_sect, sender->max_pkt,
1200 !sender->user_port, &buf); 1061 !sender->user_port, &buf);
1201 1062
1202 read_lock_bh(&tipc_net_lock); 1063 read_lock_bh(&tipc_net_lock);
1203 node = tipc_node_select(destaddr, selector); 1064 node = tipc_node_find(destaddr);
1204 if (likely(node)) { 1065 if (likely(node)) {
1205 tipc_node_lock(node); 1066 tipc_node_lock(node);
1206 l_ptr = node->active_links[selector]; 1067 l_ptr = node->active_links[selector];
1207 if (likely(l_ptr)) { 1068 if (likely(l_ptr)) {
1208 if (likely(buf)) { 1069 if (likely(buf)) {
1209 res = link_send_buf_fast(l_ptr, buf, 1070 res = link_send_buf_fast(l_ptr, buf,
1210 &sender->publ.max_pkt); 1071 &sender->max_pkt);
1211 if (unlikely(res < 0)) 1072 if (unlikely(res < 0))
1212 buf_discard(buf); 1073 buf_discard(buf);
1213exit: 1074exit:
@@ -1226,7 +1087,7 @@ exit:
1226 if (link_congested(l_ptr) || 1087 if (link_congested(l_ptr) ||
1227 !list_empty(&l_ptr->b_ptr->cong_links)) { 1088 !list_empty(&l_ptr->b_ptr->cong_links)) {
1228 res = link_schedule_port(l_ptr, 1089 res = link_schedule_port(l_ptr,
1229 sender->publ.ref, res); 1090 sender->ref, res);
1230 goto exit; 1091 goto exit;
1231 } 1092 }
1232 1093
@@ -1235,12 +1096,12 @@ exit:
1235 * then re-try fast path or fragment the message 1096 * then re-try fast path or fragment the message
1236 */ 1097 */
1237 1098
1238 sender->publ.max_pkt = l_ptr->max_pkt; 1099 sender->max_pkt = l_ptr->max_pkt;
1239 tipc_node_unlock(node); 1100 tipc_node_unlock(node);
1240 read_unlock_bh(&tipc_net_lock); 1101 read_unlock_bh(&tipc_net_lock);
1241 1102
1242 1103
1243 if ((msg_hdr_sz(hdr) + res) <= sender->publ.max_pkt) 1104 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
1244 goto again; 1105 goto again;
1245 1106
1246 return link_send_sections_long(sender, msg_sect, 1107 return link_send_sections_long(sender, msg_sect,
@@ -1274,26 +1135,26 @@ exit:
1274 * 1135 *
1275 * Returns user data length or errno. 1136 * Returns user data length or errno.
1276 */ 1137 */
1277static int link_send_sections_long(struct port *sender, 1138static int link_send_sections_long(struct tipc_port *sender,
1278 struct iovec const *msg_sect, 1139 struct iovec const *msg_sect,
1279 u32 num_sect, 1140 u32 num_sect,
1280 u32 destaddr) 1141 u32 destaddr)
1281{ 1142{
1282 struct link *l_ptr; 1143 struct link *l_ptr;
1283 struct tipc_node *node; 1144 struct tipc_node *node;
1284 struct tipc_msg *hdr = &sender->publ.phdr; 1145 struct tipc_msg *hdr = &sender->phdr;
1285 u32 dsz = msg_data_sz(hdr); 1146 u32 dsz = msg_data_sz(hdr);
1286 u32 max_pkt,fragm_sz,rest; 1147 u32 max_pkt, fragm_sz, rest;
1287 struct tipc_msg fragm_hdr; 1148 struct tipc_msg fragm_hdr;
1288 struct sk_buff *buf,*buf_chain,*prev; 1149 struct sk_buff *buf, *buf_chain, *prev;
1289 u32 fragm_crs,fragm_rest,hsz,sect_rest; 1150 u32 fragm_crs, fragm_rest, hsz, sect_rest;
1290 const unchar *sect_crs; 1151 const unchar *sect_crs;
1291 int curr_sect; 1152 int curr_sect;
1292 u32 fragm_no; 1153 u32 fragm_no;
1293 1154
1294again: 1155again:
1295 fragm_no = 1; 1156 fragm_no = 1;
1296 max_pkt = sender->publ.max_pkt - INT_H_SIZE; 1157 max_pkt = sender->max_pkt - INT_H_SIZE;
1297 /* leave room for tunnel header in case of link changeover */ 1158 /* leave room for tunnel header in case of link changeover */
1298 fragm_sz = max_pkt - INT_H_SIZE; 1159 fragm_sz = max_pkt - INT_H_SIZE;
1299 /* leave room for fragmentation header in each fragment */ 1160 /* leave room for fragmentation header in each fragment */
@@ -1306,10 +1167,9 @@ again:
1306 1167
1307 /* Prepare reusable fragment header: */ 1168 /* Prepare reusable fragment header: */
1308 1169
1309 msg_dbg(hdr, ">FRAGMENTING>");
1310 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 1170 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1311 INT_H_SIZE, msg_destnode(hdr)); 1171 INT_H_SIZE, msg_destnode(hdr));
1312 msg_set_link_selector(&fragm_hdr, sender->publ.ref); 1172 msg_set_link_selector(&fragm_hdr, sender->ref);
1313 msg_set_size(&fragm_hdr, max_pkt); 1173 msg_set_size(&fragm_hdr, max_pkt);
1314 msg_set_fragm_no(&fragm_hdr, 1); 1174 msg_set_fragm_no(&fragm_hdr, 1);
1315 1175
@@ -1322,7 +1182,6 @@ again:
1322 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); 1182 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
1323 hsz = msg_hdr_sz(hdr); 1183 hsz = msg_hdr_sz(hdr);
1324 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz); 1184 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz);
1325 msg_dbg(buf_msg(buf), ">BUILD>");
1326 1185
1327 /* Chop up message: */ 1186 /* Chop up message: */
1328 1187
@@ -1365,7 +1224,7 @@ error:
1365 /* Initiate new fragment: */ 1224 /* Initiate new fragment: */
1366 if (rest <= fragm_sz) { 1225 if (rest <= fragm_sz) {
1367 fragm_sz = rest; 1226 fragm_sz = rest;
1368 msg_set_type(&fragm_hdr,LAST_FRAGMENT); 1227 msg_set_type(&fragm_hdr, LAST_FRAGMENT);
1369 } else { 1228 } else {
1370 msg_set_type(&fragm_hdr, FRAGMENT); 1229 msg_set_type(&fragm_hdr, FRAGMENT);
1371 } 1230 }
@@ -1381,25 +1240,23 @@ error:
1381 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); 1240 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
1382 fragm_crs = INT_H_SIZE; 1241 fragm_crs = INT_H_SIZE;
1383 fragm_rest = fragm_sz; 1242 fragm_rest = fragm_sz;
1384 msg_dbg(buf_msg(buf)," >BUILD>");
1385 } 1243 }
1386 } 1244 } while (rest > 0);
1387 while (rest > 0);
1388 1245
1389 /* 1246 /*
1390 * Now we have a buffer chain. Select a link and check 1247 * Now we have a buffer chain. Select a link and check
1391 * that packet size is still OK 1248 * that packet size is still OK
1392 */ 1249 */
1393 node = tipc_node_select(destaddr, sender->publ.ref & 1); 1250 node = tipc_node_find(destaddr);
1394 if (likely(node)) { 1251 if (likely(node)) {
1395 tipc_node_lock(node); 1252 tipc_node_lock(node);
1396 l_ptr = node->active_links[sender->publ.ref & 1]; 1253 l_ptr = node->active_links[sender->ref & 1];
1397 if (!l_ptr) { 1254 if (!l_ptr) {
1398 tipc_node_unlock(node); 1255 tipc_node_unlock(node);
1399 goto reject; 1256 goto reject;
1400 } 1257 }
1401 if (l_ptr->max_pkt < max_pkt) { 1258 if (l_ptr->max_pkt < max_pkt) {
1402 sender->publ.max_pkt = l_ptr->max_pkt; 1259 sender->max_pkt = l_ptr->max_pkt;
1403 tipc_node_unlock(node); 1260 tipc_node_unlock(node);
1404 for (; buf_chain; buf_chain = buf) { 1261 for (; buf_chain; buf_chain = buf) {
1405 buf = buf_chain->next; 1262 buf = buf_chain->next;
@@ -1431,7 +1288,6 @@ reject:
1431 l_ptr->stats.sent_fragments++; 1288 l_ptr->stats.sent_fragments++;
1432 msg_set_long_msgno(msg, l_ptr->long_msg_seq_no); 1289 msg_set_long_msgno(msg, l_ptr->long_msg_seq_no);
1433 link_add_to_outqueue(l_ptr, buf, msg); 1290 link_add_to_outqueue(l_ptr, buf, msg);
1434 msg_dbg(msg, ">ADD>");
1435 buf = next; 1291 buf = next;
1436 } 1292 }
1437 1293
@@ -1473,14 +1329,12 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1473 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); 1329 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
1474 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); 1330 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
1475 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1331 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1476 msg_dbg(buf_msg(buf), ">DEF-RETR>");
1477 l_ptr->retransm_queue_head = mod(++r_q_head); 1332 l_ptr->retransm_queue_head = mod(++r_q_head);
1478 l_ptr->retransm_queue_size = --r_q_size; 1333 l_ptr->retransm_queue_size = --r_q_size;
1479 l_ptr->stats.retransmitted++; 1334 l_ptr->stats.retransmitted++;
1480 return 0; 1335 return 0;
1481 } else { 1336 } else {
1482 l_ptr->stats.bearer_congs++; 1337 l_ptr->stats.bearer_congs++;
1483 msg_dbg(buf_msg(buf), "|>DEF-RETR>");
1484 return PUSH_FAILED; 1338 return PUSH_FAILED;
1485 } 1339 }
1486 } 1340 }
@@ -1490,15 +1344,13 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1490 buf = l_ptr->proto_msg_queue; 1344 buf = l_ptr->proto_msg_queue;
1491 if (buf) { 1345 if (buf) {
1492 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); 1346 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
1493 msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in); 1347 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
1494 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1348 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1495 msg_dbg(buf_msg(buf), ">DEF-PROT>");
1496 l_ptr->unacked_window = 0; 1349 l_ptr->unacked_window = 0;
1497 buf_discard(buf); 1350 buf_discard(buf);
1498 l_ptr->proto_msg_queue = NULL; 1351 l_ptr->proto_msg_queue = NULL;
1499 return 0; 1352 return 0;
1500 } else { 1353 } else {
1501 msg_dbg(buf_msg(buf), "|>DEF-PROT>");
1502 l_ptr->stats.bearer_congs++; 1354 l_ptr->stats.bearer_congs++;
1503 return PUSH_FAILED; 1355 return PUSH_FAILED;
1504 } 1356 }
@@ -1518,11 +1370,9 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1518 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1370 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1519 if (msg_user(msg) == MSG_BUNDLER) 1371 if (msg_user(msg) == MSG_BUNDLER)
1520 msg_set_type(msg, CLOSED_MSG); 1372 msg_set_type(msg, CLOSED_MSG);
1521 msg_dbg(msg, ">PUSH-DATA>");
1522 l_ptr->next_out = buf->next; 1373 l_ptr->next_out = buf->next;
1523 return 0; 1374 return 0;
1524 } else { 1375 } else {
1525 msg_dbg(msg, "|PUSH-DATA|");
1526 l_ptr->stats.bearer_congs++; 1376 l_ptr->stats.bearer_congs++;
1527 return PUSH_FAILED; 1377 return PUSH_FAILED;
1528 } 1378 }
@@ -1570,8 +1420,7 @@ static void link_reset_all(unsigned long addr)
1570 1420
1571 for (i = 0; i < MAX_BEARERS; i++) { 1421 for (i = 0; i < MAX_BEARERS; i++) {
1572 if (n_ptr->links[i]) { 1422 if (n_ptr->links[i]) {
1573 link_print(n_ptr->links[i], TIPC_OUTPUT, 1423 link_print(n_ptr->links[i], "Resetting link\n");
1574 "Resetting link\n");
1575 tipc_link_reset(n_ptr->links[i]); 1424 tipc_link_reset(n_ptr->links[i]);
1576 } 1425 }
1577 } 1426 }
@@ -1585,13 +1434,12 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1585 struct tipc_msg *msg = buf_msg(buf); 1434 struct tipc_msg *msg = buf_msg(buf);
1586 1435
1587 warn("Retransmission failure on link <%s>\n", l_ptr->name); 1436 warn("Retransmission failure on link <%s>\n", l_ptr->name);
1588 tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>");
1589 1437
1590 if (l_ptr->addr) { 1438 if (l_ptr->addr) {
1591 1439
1592 /* Handle failure on standard link */ 1440 /* Handle failure on standard link */
1593 1441
1594 link_print(l_ptr, TIPC_OUTPUT, "Resetting link\n"); 1442 link_print(l_ptr, "Resetting link\n");
1595 tipc_link_reset(l_ptr); 1443 tipc_link_reset(l_ptr);
1596 1444
1597 } else { 1445 } else {
@@ -1601,21 +1449,21 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1601 struct tipc_node *n_ptr; 1449 struct tipc_node *n_ptr;
1602 char addr_string[16]; 1450 char addr_string[16];
1603 1451
1604 tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg)); 1452 info("Msg seq number: %u, ", msg_seqno(msg));
1605 tipc_printf(TIPC_OUTPUT, "Outstanding acks: %lu\n", 1453 info("Outstanding acks: %lu\n",
1606 (unsigned long) TIPC_SKB_CB(buf)->handle); 1454 (unsigned long) TIPC_SKB_CB(buf)->handle);
1607 1455
1608 n_ptr = l_ptr->owner->next; 1456 n_ptr = tipc_bclink_retransmit_to();
1609 tipc_node_lock(n_ptr); 1457 tipc_node_lock(n_ptr);
1610 1458
1611 tipc_addr_string_fill(addr_string, n_ptr->addr); 1459 tipc_addr_string_fill(addr_string, n_ptr->addr);
1612 tipc_printf(TIPC_OUTPUT, "Multicast link info for %s\n", addr_string); 1460 info("Multicast link info for %s\n", addr_string);
1613 tipc_printf(TIPC_OUTPUT, "Supported: %d, ", n_ptr->bclink.supported); 1461 info("Supported: %d, ", n_ptr->bclink.supported);
1614 tipc_printf(TIPC_OUTPUT, "Acked: %u\n", n_ptr->bclink.acked); 1462 info("Acked: %u\n", n_ptr->bclink.acked);
1615 tipc_printf(TIPC_OUTPUT, "Last in: %u, ", n_ptr->bclink.last_in); 1463 info("Last in: %u, ", n_ptr->bclink.last_in);
1616 tipc_printf(TIPC_OUTPUT, "Gap after: %u, ", n_ptr->bclink.gap_after); 1464 info("Gap after: %u, ", n_ptr->bclink.gap_after);
1617 tipc_printf(TIPC_OUTPUT, "Gap to: %u\n", n_ptr->bclink.gap_to); 1465 info("Gap to: %u\n", n_ptr->bclink.gap_to);
1618 tipc_printf(TIPC_OUTPUT, "Nack sync: %u\n\n", n_ptr->bclink.nack_sync); 1466 info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync);
1619 1467
1620 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); 1468 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
1621 1469
@@ -1635,12 +1483,8 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1635 1483
1636 msg = buf_msg(buf); 1484 msg = buf_msg(buf);
1637 1485
1638 dbg("Retransmitting %u in link %x\n", retransmits, l_ptr);
1639
1640 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { 1486 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
1641 if (l_ptr->retransm_queue_size == 0) { 1487 if (l_ptr->retransm_queue_size == 0) {
1642 msg_dbg(msg, ">NO_RETR->BCONG>");
1643 dbg_print_link(l_ptr, " ");
1644 l_ptr->retransm_queue_head = msg_seqno(msg); 1488 l_ptr->retransm_queue_head = msg_seqno(msg);
1645 l_ptr->retransm_queue_size = retransmits; 1489 l_ptr->retransm_queue_size = retransmits;
1646 } else { 1490 } else {
@@ -1667,7 +1511,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1667 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); 1511 msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
1668 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 1512 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
1669 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1513 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1670 msg_dbg(buf_msg(buf), ">RETR>");
1671 buf = buf->next; 1514 buf = buf->next;
1672 retransmits--; 1515 retransmits--;
1673 l_ptr->stats.retransmitted++; 1516 l_ptr->stats.retransmitted++;
@@ -1764,11 +1607,10 @@ static int link_recv_buf_validate(struct sk_buff *buf)
1764 * structure (i.e. cannot be NULL), but bearer can be inactive. 1607 * structure (i.e. cannot be NULL), but bearer can be inactive.
1765 */ 1608 */
1766 1609
1767void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) 1610void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1768{ 1611{
1769 read_lock_bh(&tipc_net_lock); 1612 read_lock_bh(&tipc_net_lock);
1770 while (head) { 1613 while (head) {
1771 struct bearer *b_ptr = (struct bearer *)tb_ptr;
1772 struct tipc_node *n_ptr; 1614 struct tipc_node *n_ptr;
1773 struct link *l_ptr; 1615 struct link *l_ptr;
1774 struct sk_buff *crs; 1616 struct sk_buff *crs;
@@ -1793,9 +1635,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1793 1635
1794 /* Ensure message data is a single contiguous unit */ 1636 /* Ensure message data is a single contiguous unit */
1795 1637
1796 if (unlikely(buf_linearize(buf))) { 1638 if (unlikely(buf_linearize(buf)))
1797 goto cont; 1639 goto cont;
1798 }
1799 1640
1800 /* Handle arrival of a non-unicast link message */ 1641 /* Handle arrival of a non-unicast link message */
1801 1642
@@ -1905,10 +1746,6 @@ deliver:
1905 tipc_node_unlock(n_ptr); 1746 tipc_node_unlock(n_ptr);
1906 tipc_link_recv_bundle(buf); 1747 tipc_link_recv_bundle(buf);
1907 continue; 1748 continue;
1908 case ROUTE_DISTRIBUTOR:
1909 tipc_node_unlock(n_ptr);
1910 tipc_cltr_recv_routing_table(buf);
1911 continue;
1912 case NAME_DISTRIBUTOR: 1749 case NAME_DISTRIBUTOR:
1913 tipc_node_unlock(n_ptr); 1750 tipc_node_unlock(n_ptr);
1914 tipc_named_recv(buf); 1751 tipc_named_recv(buf);
@@ -1935,6 +1772,10 @@ deliver:
1935 goto protocol_check; 1772 goto protocol_check;
1936 } 1773 }
1937 break; 1774 break;
1775 default:
1776 buf_discard(buf);
1777 buf = NULL;
1778 break;
1938 } 1779 }
1939 } 1780 }
1940 tipc_node_unlock(n_ptr); 1781 tipc_node_unlock(n_ptr);
@@ -1953,12 +1794,10 @@ deliver:
1953 tipc_node_unlock(n_ptr); 1794 tipc_node_unlock(n_ptr);
1954 continue; 1795 continue;
1955 } 1796 }
1956 msg_dbg(msg,"NSEQ<REC<");
1957 link_state_event(l_ptr, TRAFFIC_MSG_EVT); 1797 link_state_event(l_ptr, TRAFFIC_MSG_EVT);
1958 1798
1959 if (link_working_working(l_ptr)) { 1799 if (link_working_working(l_ptr)) {
1960 /* Re-insert in front of queue */ 1800 /* Re-insert in front of queue */
1961 msg_dbg(msg,"RECV-REINS:");
1962 buf->next = head; 1801 buf->next = head;
1963 head = buf; 1802 head = buf;
1964 tipc_node_unlock(n_ptr); 1803 tipc_node_unlock(n_ptr);
@@ -2012,13 +1851,11 @@ u32 tipc_link_defer_pkt(struct sk_buff **head,
2012 *head = buf; 1851 *head = buf;
2013 return 1; 1852 return 1;
2014 } 1853 }
2015 if (seq_no == msg_seqno(msg)) { 1854 if (seq_no == msg_seqno(msg))
2016 break; 1855 break;
2017 }
2018 prev = crs; 1856 prev = crs;
2019 crs = crs->next; 1857 crs = crs->next;
2020 } 1858 } while (crs);
2021 while (crs);
2022 1859
2023 /* Message is a duplicate of an existing message */ 1860 /* Message is a duplicate of an existing message */
2024 1861
@@ -2040,9 +1877,6 @@ static void link_handle_out_of_seq_msg(struct link *l_ptr,
2040 return; 1877 return;
2041 } 1878 }
2042 1879
2043 dbg("rx OOS msg: seq_no %u, expecting %u (%u)\n",
2044 seq_no, mod(l_ptr->next_in_no), l_ptr->next_in_no);
2045
2046 /* Record OOS packet arrival (force mismatch on next timeout) */ 1880 /* Record OOS packet arrival (force mismatch on next timeout) */
2047 1881
2048 l_ptr->checkpoint--; 1882 l_ptr->checkpoint--;
@@ -2077,6 +1911,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2077 struct sk_buff *buf = NULL; 1911 struct sk_buff *buf = NULL;
2078 struct tipc_msg *msg = l_ptr->pmsg; 1912 struct tipc_msg *msg = l_ptr->pmsg;
2079 u32 msg_size = sizeof(l_ptr->proto_msg); 1913 u32 msg_size = sizeof(l_ptr->proto_msg);
1914 int r_flag;
2080 1915
2081 if (link_blocked(l_ptr)) 1916 if (link_blocked(l_ptr))
2082 return; 1917 return;
@@ -2127,16 +1962,14 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2127 msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1)); 1962 msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1));
2128 msg_set_seq_gap(msg, 0); 1963 msg_set_seq_gap(msg, 0);
2129 msg_set_next_sent(msg, 1); 1964 msg_set_next_sent(msg, 1);
1965 msg_set_probe(msg, 0);
2130 msg_set_link_tolerance(msg, l_ptr->tolerance); 1966 msg_set_link_tolerance(msg, l_ptr->tolerance);
2131 msg_set_linkprio(msg, l_ptr->priority); 1967 msg_set_linkprio(msg, l_ptr->priority);
2132 msg_set_max_pkt(msg, l_ptr->max_pkt_target); 1968 msg_set_max_pkt(msg, l_ptr->max_pkt_target);
2133 } 1969 }
2134 1970
2135 if (tipc_node_has_redundant_links(l_ptr->owner)) { 1971 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr));
2136 msg_set_redundant_link(msg); 1972 msg_set_redundant_link(msg, r_flag);
2137 } else {
2138 msg_clear_redundant_link(msg);
2139 }
2140 msg_set_linkprio(msg, l_ptr->priority); 1973 msg_set_linkprio(msg, l_ptr->priority);
2141 1974
2142 /* Ensure sequence number will not fit : */ 1975 /* Ensure sequence number will not fit : */
@@ -2156,12 +1989,9 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2156 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); 1989 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
2157 return; 1990 return;
2158 } 1991 }
2159 msg_set_timestamp(msg, jiffies_to_msecs(jiffies));
2160 1992
2161 /* Message can be sent */ 1993 /* Message can be sent */
2162 1994
2163 msg_dbg(msg, ">>");
2164
2165 buf = tipc_buf_acquire(msg_size); 1995 buf = tipc_buf_acquire(msg_size);
2166 if (!buf) 1996 if (!buf)
2167 return; 1997 return;
@@ -2195,8 +2025,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2195 u32 msg_tol; 2025 u32 msg_tol;
2196 struct tipc_msg *msg = buf_msg(buf); 2026 struct tipc_msg *msg = buf_msg(buf);
2197 2027
2198 dbg("AT(%u):", jiffies_to_msecs(jiffies));
2199 msg_dbg(msg, "<<");
2200 if (link_blocked(l_ptr)) 2028 if (link_blocked(l_ptr))
2201 goto exit; 2029 goto exit;
2202 2030
@@ -2215,11 +2043,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2215 case RESET_MSG: 2043 case RESET_MSG:
2216 if (!link_working_unknown(l_ptr) && 2044 if (!link_working_unknown(l_ptr) &&
2217 (l_ptr->peer_session != INVALID_SESSION)) { 2045 (l_ptr->peer_session != INVALID_SESSION)) {
2218 if (msg_session(msg) == l_ptr->peer_session) { 2046 if (msg_session(msg) == l_ptr->peer_session)
2219 dbg("Duplicate RESET: %u<->%u\n",
2220 msg_session(msg), l_ptr->peer_session);
2221 break; /* duplicate: ignore */ 2047 break; /* duplicate: ignore */
2222 }
2223 } 2048 }
2224 /* fall thru' */ 2049 /* fall thru' */
2225 case ACTIVATE_MSG: 2050 case ACTIVATE_MSG:
@@ -2227,8 +2052,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2227 2052
2228 strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg)); 2053 strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg));
2229 2054
2230 if ((msg_tol = msg_link_tolerance(msg)) && 2055 msg_tol = msg_link_tolerance(msg);
2231 (msg_tol > l_ptr->tolerance)) 2056 if (msg_tol > l_ptr->tolerance)
2232 link_set_supervision_props(l_ptr, msg_tol); 2057 link_set_supervision_props(l_ptr, msg_tol);
2233 2058
2234 if (msg_linkprio(msg) > l_ptr->priority) 2059 if (msg_linkprio(msg) > l_ptr->priority)
@@ -2251,13 +2076,13 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2251 l_ptr->peer_bearer_id = msg_bearer_id(msg); 2076 l_ptr->peer_bearer_id = msg_bearer_id(msg);
2252 2077
2253 /* Synchronize broadcast sequence numbers */ 2078 /* Synchronize broadcast sequence numbers */
2254 if (!tipc_node_has_redundant_links(l_ptr->owner)) { 2079 if (!tipc_node_redundant_links(l_ptr->owner))
2255 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); 2080 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
2256 }
2257 break; 2081 break;
2258 case STATE_MSG: 2082 case STATE_MSG:
2259 2083
2260 if ((msg_tol = msg_link_tolerance(msg))) 2084 msg_tol = msg_link_tolerance(msg);
2085 if (msg_tol)
2261 link_set_supervision_props(l_ptr, msg_tol); 2086 link_set_supervision_props(l_ptr, msg_tol);
2262 2087
2263 if (msg_linkprio(msg) && 2088 if (msg_linkprio(msg) &&
@@ -2280,8 +2105,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2280 2105
2281 max_pkt_ack = msg_max_pkt(msg); 2106 max_pkt_ack = msg_max_pkt(msg);
2282 if (max_pkt_ack > l_ptr->max_pkt) { 2107 if (max_pkt_ack > l_ptr->max_pkt) {
2283 dbg("Link <%s> updated MTU %u -> %u\n",
2284 l_ptr->name, l_ptr->max_pkt, max_pkt_ack);
2285 l_ptr->max_pkt = max_pkt_ack; 2108 l_ptr->max_pkt = max_pkt_ack;
2286 l_ptr->max_pkt_probes = 0; 2109 l_ptr->max_pkt_probes = 0;
2287 } 2110 }
@@ -2289,9 +2112,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2289 max_pkt_ack = 0; 2112 max_pkt_ack = 0;
2290 if (msg_probe(msg)) { 2113 if (msg_probe(msg)) {
2291 l_ptr->stats.recv_probes++; 2114 l_ptr->stats.recv_probes++;
2292 if (msg_size(msg) > sizeof(l_ptr->proto_msg)) { 2115 if (msg_size(msg) > sizeof(l_ptr->proto_msg))
2293 max_pkt_ack = msg_size(msg); 2116 max_pkt_ack = msg_size(msg);
2294 }
2295 } 2117 }
2296 2118
2297 /* Protocol message before retransmits, reduce loss risk */ 2119 /* Protocol message before retransmits, reduce loss risk */
@@ -2303,14 +2125,11 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2303 0, rec_gap, 0, 0, max_pkt_ack); 2125 0, rec_gap, 0, 0, max_pkt_ack);
2304 } 2126 }
2305 if (msg_seq_gap(msg)) { 2127 if (msg_seq_gap(msg)) {
2306 msg_dbg(msg, "With Gap:");
2307 l_ptr->stats.recv_nacks++; 2128 l_ptr->stats.recv_nacks++;
2308 tipc_link_retransmit(l_ptr, l_ptr->first_out, 2129 tipc_link_retransmit(l_ptr, l_ptr->first_out,
2309 msg_seq_gap(msg)); 2130 msg_seq_gap(msg));
2310 } 2131 }
2311 break; 2132 break;
2312 default:
2313 msg_dbg(buf_msg(buf), "<DISCARDING UNKNOWN<");
2314 } 2133 }
2315exit: 2134exit:
2316 buf_discard(buf); 2135 buf_discard(buf);
@@ -2345,8 +2164,6 @@ static void tipc_link_tunnel(struct link *l_ptr,
2345 } 2164 }
2346 skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE); 2165 skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE);
2347 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length); 2166 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length);
2348 dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane);
2349 msg_dbg(buf_msg(buf), ">SEND>");
2350 tipc_link_send_buf(tunnel, buf); 2167 tipc_link_send_buf(tunnel, buf);
2351} 2168}
2352 2169
@@ -2378,7 +2195,6 @@ void tipc_link_changeover(struct link *l_ptr)
2378 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); 2195 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
2379 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2196 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2380 msg_set_msgcnt(&tunnel_hdr, msgcount); 2197 msg_set_msgcnt(&tunnel_hdr, msgcount);
2381 dbg("Link changeover requires %u tunnel messages\n", msgcount);
2382 2198
2383 if (!l_ptr->first_out) { 2199 if (!l_ptr->first_out) {
2384 struct sk_buff *buf; 2200 struct sk_buff *buf;
@@ -2387,9 +2203,6 @@ void tipc_link_changeover(struct link *l_ptr)
2387 if (buf) { 2203 if (buf) {
2388 skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); 2204 skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE);
2389 msg_set_size(&tunnel_hdr, INT_H_SIZE); 2205 msg_set_size(&tunnel_hdr, INT_H_SIZE);
2390 dbg("%c->%c:", l_ptr->b_ptr->net_plane,
2391 tunnel->b_ptr->net_plane);
2392 msg_dbg(&tunnel_hdr, "EMPTY>SEND>");
2393 tipc_link_send_buf(tunnel, buf); 2206 tipc_link_send_buf(tunnel, buf);
2394 } else { 2207 } else {
2395 warn("Link changeover error, " 2208 warn("Link changeover error, "
@@ -2406,11 +2219,11 @@ void tipc_link_changeover(struct link *l_ptr)
2406 2219
2407 if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) { 2220 if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) {
2408 struct tipc_msg *m = msg_get_wrapped(msg); 2221 struct tipc_msg *m = msg_get_wrapped(msg);
2409 unchar* pos = (unchar*)m; 2222 unchar *pos = (unchar *)m;
2410 2223
2411 msgcount = msg_msgcnt(msg); 2224 msgcount = msg_msgcnt(msg);
2412 while (msgcount--) { 2225 while (msgcount--) {
2413 msg_set_seqno(m,msg_seqno(msg)); 2226 msg_set_seqno(m, msg_seqno(msg));
2414 tipc_link_tunnel(l_ptr, &tunnel_hdr, m, 2227 tipc_link_tunnel(l_ptr, &tunnel_hdr, m,
2415 msg_link_selector(m)); 2228 msg_link_selector(m));
2416 pos += align(msg_size(m)); 2229 pos += align(msg_size(m));
@@ -2453,9 +2266,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2453 skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE); 2266 skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE);
2454 skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data, 2267 skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data,
2455 length); 2268 length);
2456 dbg("%c->%c:", l_ptr->b_ptr->net_plane,
2457 tunnel->b_ptr->net_plane);
2458 msg_dbg(buf_msg(outbuf), ">SEND>");
2459 tipc_link_send_buf(tunnel, outbuf); 2269 tipc_link_send_buf(tunnel, outbuf);
2460 if (!tipc_link_is_up(l_ptr)) 2270 if (!tipc_link_is_up(l_ptr))
2461 return; 2271 return;
@@ -2502,31 +2312,24 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2502 u32 msg_count = msg_msgcnt(tunnel_msg); 2312 u32 msg_count = msg_msgcnt(tunnel_msg);
2503 2313
2504 dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; 2314 dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)];
2505 if (!dest_link) { 2315 if (!dest_link)
2506 msg_dbg(tunnel_msg, "NOLINK/<REC<");
2507 goto exit; 2316 goto exit;
2508 }
2509 if (dest_link == *l_ptr) { 2317 if (dest_link == *l_ptr) {
2510 err("Unexpected changeover message on link <%s>\n", 2318 err("Unexpected changeover message on link <%s>\n",
2511 (*l_ptr)->name); 2319 (*l_ptr)->name);
2512 goto exit; 2320 goto exit;
2513 } 2321 }
2514 dbg("%c<-%c:", dest_link->b_ptr->net_plane,
2515 (*l_ptr)->b_ptr->net_plane);
2516 *l_ptr = dest_link; 2322 *l_ptr = dest_link;
2517 msg = msg_get_wrapped(tunnel_msg); 2323 msg = msg_get_wrapped(tunnel_msg);
2518 2324
2519 if (msg_typ == DUPLICATE_MSG) { 2325 if (msg_typ == DUPLICATE_MSG) {
2520 if (less(msg_seqno(msg), mod(dest_link->next_in_no))) { 2326 if (less(msg_seqno(msg), mod(dest_link->next_in_no)))
2521 msg_dbg(tunnel_msg, "DROP/<REC<");
2522 goto exit; 2327 goto exit;
2523 } 2328 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2524 *buf = buf_extract(tunnel_buf,INT_H_SIZE);
2525 if (*buf == NULL) { 2329 if (*buf == NULL) {
2526 warn("Link changeover error, duplicate msg dropped\n"); 2330 warn("Link changeover error, duplicate msg dropped\n");
2527 goto exit; 2331 goto exit;
2528 } 2332 }
2529 msg_dbg(tunnel_msg, "TNL<REC<");
2530 buf_discard(tunnel_buf); 2333 buf_discard(tunnel_buf);
2531 return 1; 2334 return 1;
2532 } 2335 }
@@ -2534,18 +2337,14 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2534 /* First original message ?: */ 2337 /* First original message ?: */
2535 2338
2536 if (tipc_link_is_up(dest_link)) { 2339 if (tipc_link_is_up(dest_link)) {
2537 msg_dbg(tunnel_msg, "UP/FIRST/<REC<");
2538 info("Resetting link <%s>, changeover initiated by peer\n", 2340 info("Resetting link <%s>, changeover initiated by peer\n",
2539 dest_link->name); 2341 dest_link->name);
2540 tipc_link_reset(dest_link); 2342 tipc_link_reset(dest_link);
2541 dest_link->exp_msg_count = msg_count; 2343 dest_link->exp_msg_count = msg_count;
2542 dbg("Expecting %u tunnelled messages\n", msg_count);
2543 if (!msg_count) 2344 if (!msg_count)
2544 goto exit; 2345 goto exit;
2545 } else if (dest_link->exp_msg_count == START_CHANGEOVER) { 2346 } else if (dest_link->exp_msg_count == START_CHANGEOVER) {
2546 msg_dbg(tunnel_msg, "BLK/FIRST/<REC<");
2547 dest_link->exp_msg_count = msg_count; 2347 dest_link->exp_msg_count = msg_count;
2548 dbg("Expecting %u tunnelled messages\n", msg_count);
2549 if (!msg_count) 2348 if (!msg_count)
2550 goto exit; 2349 goto exit;
2551 } 2350 }
@@ -2555,18 +2354,14 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2555 if (dest_link->exp_msg_count == 0) { 2354 if (dest_link->exp_msg_count == 0) {
2556 warn("Link switchover error, " 2355 warn("Link switchover error, "
2557 "got too many tunnelled messages\n"); 2356 "got too many tunnelled messages\n");
2558 msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<");
2559 dbg_print_link(dest_link, "LINK:");
2560 goto exit; 2357 goto exit;
2561 } 2358 }
2562 dest_link->exp_msg_count--; 2359 dest_link->exp_msg_count--;
2563 if (less(msg_seqno(msg), dest_link->reset_checkpoint)) { 2360 if (less(msg_seqno(msg), dest_link->reset_checkpoint)) {
2564 msg_dbg(tunnel_msg, "DROP/DUPL/<REC<");
2565 goto exit; 2361 goto exit;
2566 } else { 2362 } else {
2567 *buf = buf_extract(tunnel_buf, INT_H_SIZE); 2363 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2568 if (*buf != NULL) { 2364 if (*buf != NULL) {
2569 msg_dbg(tunnel_msg, "TNL<REC<");
2570 buf_discard(tunnel_buf); 2365 buf_discard(tunnel_buf);
2571 return 1; 2366 return 1;
2572 } else { 2367 } else {
@@ -2588,7 +2383,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2588 u32 pos = INT_H_SIZE; 2383 u32 pos = INT_H_SIZE;
2589 struct sk_buff *obuf; 2384 struct sk_buff *obuf;
2590 2385
2591 msg_dbg(buf_msg(buf), "<BNDL<: ");
2592 while (msgcount--) { 2386 while (msgcount--) {
2593 obuf = buf_extract(buf, pos); 2387 obuf = buf_extract(buf, pos);
2594 if (obuf == NULL) { 2388 if (obuf == NULL) {
@@ -2596,7 +2390,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2596 break; 2390 break;
2597 } 2391 }
2598 pos += align(msg_size(buf_msg(obuf))); 2392 pos += align(msg_size(buf_msg(obuf)));
2599 msg_dbg(buf_msg(obuf), " /");
2600 tipc_net_route_msg(obuf); 2393 tipc_net_route_msg(obuf);
2601 } 2394 }
2602 buf_discard(buf); 2395 buf_discard(buf);
@@ -2630,9 +2423,6 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2630 else 2423 else
2631 destaddr = msg_destnode(inmsg); 2424 destaddr = msg_destnode(inmsg);
2632 2425
2633 if (msg_routed(inmsg))
2634 msg_set_prevnode(inmsg, tipc_own_addr);
2635
2636 /* Prepare reusable fragment header: */ 2426 /* Prepare reusable fragment header: */
2637 2427
2638 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 2428 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
@@ -2681,7 +2471,7 @@ exit:
2681 * A pending message being re-assembled must store certain values 2471 * A pending message being re-assembled must store certain values
2682 * to handle subsequent fragments correctly. The following functions 2472 * to handle subsequent fragments correctly. The following functions
2683 * help storing these values in unused, available fields in the 2473 * help storing these values in unused, available fields in the
2684 * pending message. This makes dynamic memory allocation unecessary. 2474 * pending message. This makes dynamic memory allocation unnecessary.
2685 */ 2475 */
2686 2476
2687static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno) 2477static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno)
@@ -2733,7 +2523,6 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2733 u32 long_msg_seq_no = msg_long_msgno(fragm); 2523 u32 long_msg_seq_no = msg_long_msgno(fragm);
2734 2524
2735 *fb = NULL; 2525 *fb = NULL;
2736 msg_dbg(fragm,"FRG<REC<");
2737 2526
2738 /* Is there an incomplete message waiting for this fragment? */ 2527 /* Is there an incomplete message waiting for this fragment? */
2739 2528
@@ -2752,7 +2541,6 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2752 if (msg_type(imsg) == TIPC_MCAST_MSG) 2541 if (msg_type(imsg) == TIPC_MCAST_MSG)
2753 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; 2542 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
2754 if (msg_size(imsg) > max) { 2543 if (msg_size(imsg) > max) {
2755 msg_dbg(fragm,"<REC<Oversized: ");
2756 buf_discard(fbuf); 2544 buf_discard(fbuf);
2757 return 0; 2545 return 0;
2758 } 2546 }
@@ -2765,8 +2553,8 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2765 /* Prepare buffer for subsequent fragments. */ 2553 /* Prepare buffer for subsequent fragments. */
2766 2554
2767 set_long_msg_seqno(pbuf, long_msg_seq_no); 2555 set_long_msg_seqno(pbuf, long_msg_seq_no);
2768 set_fragm_size(pbuf,fragm_sz); 2556 set_fragm_size(pbuf, fragm_sz);
2769 set_expected_frags(pbuf,exp_fragm_cnt - 1); 2557 set_expected_frags(pbuf, exp_fragm_cnt - 1);
2770 } else { 2558 } else {
2771 warn("Link unable to reassemble fragmented message\n"); 2559 warn("Link unable to reassemble fragmented message\n");
2772 } 2560 }
@@ -2793,13 +2581,9 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2793 *m = buf_msg(pbuf); 2581 *m = buf_msg(pbuf);
2794 return 1; 2582 return 1;
2795 } 2583 }
2796 set_expected_frags(pbuf,exp_frags); 2584 set_expected_frags(pbuf, exp_frags);
2797 return 0; 2585 return 0;
2798 } 2586 }
2799 dbg(" Discarding orphan fragment %x\n",fbuf);
2800 msg_dbg(fragm,"ORPHAN:");
2801 dbg("Pending long buffers:\n");
2802 dbg_print_buf_chain(*pending);
2803 buf_discard(fbuf); 2587 buf_discard(fbuf);
2804 return 0; 2588 return 0;
2805} 2589}
@@ -2827,11 +2611,6 @@ static void link_check_defragm_bufs(struct link *l_ptr)
2827 incr_timer_cnt(buf); 2611 incr_timer_cnt(buf);
2828 prev = buf; 2612 prev = buf;
2829 } else { 2613 } else {
2830 dbg(" Discarding incomplete long buffer\n");
2831 msg_dbg(buf_msg(buf), "LONG:");
2832 dbg_print_link(l_ptr, "curr:");
2833 dbg("Pending long buffers:\n");
2834 dbg_print_buf_chain(l_ptr->defragm_buf);
2835 if (prev) 2614 if (prev)
2836 prev->next = buf->next; 2615 prev->next = buf->next;
2837 else 2616 else
@@ -2846,6 +2625,9 @@ static void link_check_defragm_bufs(struct link *l_ptr)
2846 2625
2847static void link_set_supervision_props(struct link *l_ptr, u32 tolerance) 2626static void link_set_supervision_props(struct link *l_ptr, u32 tolerance)
2848{ 2627{
2628 if ((tolerance < TIPC_MIN_LINK_TOL) || (tolerance > TIPC_MAX_LINK_TOL))
2629 return;
2630
2849 l_ptr->tolerance = tolerance; 2631 l_ptr->tolerance = tolerance;
2850 l_ptr->continuity_interval = 2632 l_ptr->continuity_interval =
2851 ((tolerance / 4) > 500) ? 500 : tolerance / 4; 2633 ((tolerance / 4) > 500) ? 500 : tolerance / 4;
@@ -2866,7 +2648,6 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
2866 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900; 2648 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900;
2867 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200; 2649 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200;
2868 l_ptr->queue_limit[CONN_MANAGER] = 1200; 2650 l_ptr->queue_limit[CONN_MANAGER] = 1200;
2869 l_ptr->queue_limit[ROUTE_DISTRIBUTOR] = 1200;
2870 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500; 2651 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500;
2871 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000; 2652 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000;
2872 /* FRAGMENT and LAST_FRAGMENT packets */ 2653 /* FRAGMENT and LAST_FRAGMENT packets */
@@ -2887,7 +2668,7 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
2887static struct link *link_find_link(const char *name, struct tipc_node **node) 2668static struct link *link_find_link(const char *name, struct tipc_node **node)
2888{ 2669{
2889 struct link_name link_name_parts; 2670 struct link_name link_name_parts;
2890 struct bearer *b_ptr; 2671 struct tipc_bearer *b_ptr;
2891 struct link *l_ptr; 2672 struct link *l_ptr;
2892 2673
2893 if (!link_name_validate(name, &link_name_parts)) 2674 if (!link_name_validate(name, &link_name_parts))
@@ -3168,7 +2949,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
3168 return MAX_MSG_SIZE; 2949 return MAX_MSG_SIZE;
3169 2950
3170 read_lock_bh(&tipc_net_lock); 2951 read_lock_bh(&tipc_net_lock);
3171 n_ptr = tipc_node_select(dest, selector); 2952 n_ptr = tipc_node_find(dest);
3172 if (n_ptr) { 2953 if (n_ptr) {
3173 tipc_node_lock(n_ptr); 2954 tipc_node_lock(n_ptr);
3174 l_ptr = n_ptr->active_links[selector & 1]; 2955 l_ptr = n_ptr->active_links[selector & 1];
@@ -3180,27 +2961,22 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
3180 return res; 2961 return res;
3181} 2962}
3182 2963
3183static void link_dump_send_queue(struct link *l_ptr) 2964static void link_print(struct link *l_ptr, const char *str)
3184{ 2965{
3185 if (l_ptr->next_out) { 2966 char print_area[256];
3186 info("\nContents of unsent queue:\n"); 2967 struct print_buf pb;
3187 dbg_print_buf_chain(l_ptr->next_out); 2968 struct print_buf *buf = &pb;
3188 } 2969
3189 info("\nContents of send queue:\n"); 2970 tipc_printbuf_init(buf, print_area, sizeof(print_area));
3190 if (l_ptr->first_out) {
3191 dbg_print_buf_chain(l_ptr->first_out);
3192 }
3193 info("Empty send queue\n");
3194}
3195 2971
3196static void link_print(struct link *l_ptr, struct print_buf *buf,
3197 const char *str)
3198{
3199 tipc_printf(buf, str); 2972 tipc_printf(buf, str);
3200 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
3201 return;
3202 tipc_printf(buf, "Link %x<%s>:", 2973 tipc_printf(buf, "Link %x<%s>:",
3203 l_ptr->addr, l_ptr->b_ptr->publ.name); 2974 l_ptr->addr, l_ptr->b_ptr->name);
2975
2976#ifdef CONFIG_TIPC_DEBUG
2977 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
2978 goto print_state;
2979
3204 tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no)); 2980 tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no));
3205 tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no)); 2981 tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no));
3206 tipc_printf(buf, "SQUE"); 2982 tipc_printf(buf, "SQUE");
@@ -3215,10 +2991,9 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
3215 != (l_ptr->out_queue_size - 1)) || 2991 != (l_ptr->out_queue_size - 1)) ||
3216 (l_ptr->last_out->next != NULL)) { 2992 (l_ptr->last_out->next != NULL)) {
3217 tipc_printf(buf, "\nSend queue inconsistency\n"); 2993 tipc_printf(buf, "\nSend queue inconsistency\n");
3218 tipc_printf(buf, "first_out= %x ", l_ptr->first_out); 2994 tipc_printf(buf, "first_out= %p ", l_ptr->first_out);
3219 tipc_printf(buf, "next_out= %x ", l_ptr->next_out); 2995 tipc_printf(buf, "next_out= %p ", l_ptr->next_out);
3220 tipc_printf(buf, "last_out= %x ", l_ptr->last_out); 2996 tipc_printf(buf, "last_out= %p ", l_ptr->last_out);
3221 link_dump_send_queue(l_ptr);
3222 } 2997 }
3223 } else 2998 } else
3224 tipc_printf(buf, "[]"); 2999 tipc_printf(buf, "[]");
@@ -3232,14 +3007,20 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
3232 l_ptr->deferred_inqueue_sz); 3007 l_ptr->deferred_inqueue_sz);
3233 } 3008 }
3234 } 3009 }
3010print_state:
3011#endif
3012
3235 if (link_working_unknown(l_ptr)) 3013 if (link_working_unknown(l_ptr))
3236 tipc_printf(buf, ":WU"); 3014 tipc_printf(buf, ":WU");
3237 if (link_reset_reset(l_ptr)) 3015 else if (link_reset_reset(l_ptr))
3238 tipc_printf(buf, ":RR"); 3016 tipc_printf(buf, ":RR");
3239 if (link_reset_unknown(l_ptr)) 3017 else if (link_reset_unknown(l_ptr))
3240 tipc_printf(buf, ":RU"); 3018 tipc_printf(buf, ":RU");
3241 if (link_working_working(l_ptr)) 3019 else if (link_working_working(l_ptr))
3242 tipc_printf(buf, ":WW"); 3020 tipc_printf(buf, ":WW");
3243 tipc_printf(buf, "\n"); 3021 tipc_printf(buf, "\n");
3022
3023 tipc_printbuf_validate(buf);
3024 info("%s", print_area);
3244} 3025}
3245 3026
diff --git a/net/tipc/link.h b/net/tipc/link.h
index f98bc613de67..e6a30dbe1aaa 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -2,7 +2,7 @@
2 * net/tipc/link.h: Include file for TIPC link code 2 * net/tipc/link.h: Include file for TIPC link code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-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,9 +37,8 @@
37#ifndef _TIPC_LINK_H 37#ifndef _TIPC_LINK_H
38#define _TIPC_LINK_H 38#define _TIPC_LINK_H
39 39
40#include "dbg.h" 40#include "log.h"
41#include "msg.h" 41#include "msg.h"
42#include "bearer.h"
43#include "node.h" 42#include "node.h"
44 43
45#define PUSH_FAILED 1 44#define PUSH_FAILED 1
@@ -108,7 +107,6 @@
108 * @long_msg_seq_no: next identifier to use for outbound fragmented messages 107 * @long_msg_seq_no: next identifier to use for outbound fragmented messages
109 * @defragm_buf: list of partially reassembled inbound message fragments 108 * @defragm_buf: list of partially reassembled inbound message fragments
110 * @stats: collects statistics regarding link activity 109 * @stats: collects statistics regarding link activity
111 * @print_buf: print buffer used to log link activity
112 */ 110 */
113 111
114struct link { 112struct link {
@@ -124,7 +122,7 @@ struct link {
124 u32 checkpoint; 122 u32 checkpoint;
125 u32 peer_session; 123 u32 peer_session;
126 u32 peer_bearer_id; 124 u32 peer_bearer_id;
127 struct bearer *b_ptr; 125 struct tipc_bearer *b_ptr;
128 u32 tolerance; 126 u32 tolerance;
129 u32 continuity_interval; 127 u32 continuity_interval;
130 u32 abort_limit; 128 u32 abort_limit;
@@ -198,26 +196,19 @@ struct link {
198 u32 bearer_congs; 196 u32 bearer_congs;
199 u32 deferred_recv; 197 u32 deferred_recv;
200 u32 duplicates; 198 u32 duplicates;
201 199 u32 max_queue_sz; /* send queue size high water mark */
202 /* for statistical profiling of send queue size */ 200 u32 accu_queue_sz; /* used for send queue size profiling */
203 201 u32 queue_sz_counts; /* used for send queue size profiling */
204 u32 max_queue_sz; 202 u32 msg_length_counts; /* used for message length profiling */
205 u32 accu_queue_sz; 203 u32 msg_lengths_total; /* used for message length profiling */
206 u32 queue_sz_counts; 204 u32 msg_length_profile[7]; /* used for msg. length profiling */
207
208 /* for statistical profiling of message lengths */
209
210 u32 msg_length_counts;
211 u32 msg_lengths_total;
212 u32 msg_length_profile[7];
213 } stats; 205 } stats;
214
215 struct print_buf print_buf;
216}; 206};
217 207
218struct port; 208struct tipc_port;
219 209
220struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, 210struct link *tipc_link_create(struct tipc_node *n_ptr,
211 struct tipc_bearer *b_ptr,
221 const struct tipc_media_addr *media_addr); 212 const struct tipc_media_addr *media_addr);
222void tipc_link_delete(struct link *l_ptr); 213void tipc_link_delete(struct link *l_ptr);
223void tipc_link_changeover(struct link *l_ptr); 214void tipc_link_changeover(struct link *l_ptr);
@@ -233,8 +224,8 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_
233void tipc_link_reset(struct link *l_ptr); 224void tipc_link_reset(struct link *l_ptr);
234int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector); 225int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
235int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf); 226int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf);
236u32 tipc_link_get_max_pkt(u32 dest,u32 selector); 227u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
237int tipc_link_send_sections_fast(struct port* sender, 228int tipc_link_send_sections_fast(struct tipc_port *sender,
238 struct iovec const *msg_sect, 229 struct iovec const *msg_sect,
239 const u32 num_sect, 230 const u32 num_sect,
240 u32 destnode); 231 u32 destnode);
diff --git a/net/tipc/dbg.c b/net/tipc/log.c
index 46f51d208e5e..952c39f643e6 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/log.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * net/tipc/dbg.c: TIPC print buffer routines for debugging 2 * net/tipc/log.c: TIPC print buffer routines for debugging
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
@@ -36,7 +36,7 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "config.h"
39#include "dbg.h" 39#include "log.h"
40 40
41/* 41/*
42 * TIPC pre-defines the following print buffers: 42 * TIPC pre-defines the following print buffers:
@@ -52,7 +52,7 @@ static struct print_buf null_buf = { NULL, 0, NULL, 0 };
52struct print_buf *const TIPC_NULL = &null_buf; 52struct print_buf *const TIPC_NULL = &null_buf;
53 53
54static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; 54static struct print_buf cons_buf = { NULL, 0, NULL, 1 };
55static struct print_buf *const TIPC_CONS = &cons_buf; 55struct print_buf *const TIPC_CONS = &cons_buf;
56 56
57static struct print_buf log_buf = { NULL, 0, NULL, 1 }; 57static struct print_buf log_buf = { NULL, 0, NULL, 1 };
58struct print_buf *const TIPC_LOG = &log_buf; 58struct print_buf *const TIPC_LOG = &log_buf;
@@ -64,9 +64,9 @@ struct print_buf *const TIPC_LOG = &log_buf;
64 * 'print_string' when writing to a print buffer. This also protects against 64 * 'print_string' when writing to a print buffer. This also protects against
65 * concurrent writes to the print buffer being written to. 65 * concurrent writes to the print buffer being written to.
66 * 66 *
67 * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned 67 * 2) tipc_log_XXX() leverages the aforementioned use of 'print_lock' to
68 * use of 'print_lock' to protect against all types of concurrent operations 68 * protect against all types of concurrent operations on their associated
69 * on their associated print buffer (not just write operations). 69 * print buffer (not just write operations).
70 * 70 *
71 * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely 71 * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely
72 * on the caller to prevent simultaneous use of the print buffer(s) being 72 * on the caller to prevent simultaneous use of the print buffer(s) being
@@ -76,18 +76,16 @@ struct print_buf *const TIPC_LOG = &log_buf;
76static char print_string[TIPC_PB_MAX_STR]; 76static char print_string[TIPC_PB_MAX_STR];
77static DEFINE_SPINLOCK(print_lock); 77static DEFINE_SPINLOCK(print_lock);
78 78
79static void tipc_printbuf_reset(struct print_buf *pb);
80static int tipc_printbuf_empty(struct print_buf *pb);
81static void tipc_printbuf_move(struct print_buf *pb_to, 79static void tipc_printbuf_move(struct print_buf *pb_to,
82 struct print_buf *pb_from); 80 struct print_buf *pb_from);
83 81
84#define FORMAT(PTR,LEN,FMT) \ 82#define FORMAT(PTR, LEN, FMT) \
85{\ 83{\
86 va_list args;\ 84 va_list args;\
87 va_start(args, FMT);\ 85 va_start(args, FMT);\
88 LEN = vsprintf(PTR, FMT, args);\ 86 LEN = vsprintf(PTR, FMT, args);\
89 va_end(args);\ 87 va_end(args);\
90 *(PTR + LEN) = '\0';\ 88 *(PTR + LEN) = '\0';\
91} 89}
92 90
93/** 91/**
@@ -268,81 +266,6 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
268 spin_unlock_bh(&print_lock); 266 spin_unlock_bh(&print_lock);
269} 267}
270 268
271#ifdef CONFIG_TIPC_DEBUG
272
273/**
274 * print_to_console - write string of bytes to console in multiple chunks
275 */
276
277static void print_to_console(char *crs, int len)
278{
279 int rest = len;
280
281 while (rest > 0) {
282 int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR;
283 char c = crs[sz];
284
285 crs[sz] = 0;
286 printk((const char *)crs);
287 crs[sz] = c;
288 rest -= sz;
289 crs += sz;
290 }
291}
292
293/**
294 * printbuf_dump - write print buffer contents to console
295 */
296
297static void printbuf_dump(struct print_buf *pb)
298{
299 int len;
300
301 if (!pb->buf) {
302 printk("*** PRINT BUFFER NOT ALLOCATED ***");
303 return;
304 }
305
306 /* Dump print buffer from char after cursor to end (if used) */
307
308 len = pb->buf + pb->size - pb->crs - 2;
309 if ((pb->buf[pb->size - 1] == 0) && (len > 0))
310 print_to_console(pb->crs + 1, len);
311
312 /* Dump print buffer from start to cursor (always) */
313
314 len = pb->crs - pb->buf;
315 print_to_console(pb->buf, len);
316}
317
318/**
319 * tipc_dump_dbg - dump (non-console) print buffer to console
320 * @pb: pointer to print buffer
321 */
322
323void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...)
324{
325 int len;
326
327 if (pb == TIPC_CONS)
328 return;
329
330 spin_lock_bh(&print_lock);
331
332 FORMAT(print_string, len, fmt);
333 printk(print_string);
334
335 printk("\n---- Start of %s log dump ----\n\n",
336 (pb == TIPC_LOG) ? "global" : "local");
337 printbuf_dump(pb);
338 tipc_printbuf_reset(pb);
339 printk("\n---- End of dump ----\n");
340
341 spin_unlock_bh(&print_lock);
342}
343
344#endif
345
346/** 269/**
347 * tipc_log_resize - change the size of the TIPC log buffer 270 * tipc_log_resize - change the size of the TIPC log buffer
348 * @log_size: print buffer size to use 271 * @log_size: print buffer size to use
@@ -353,10 +276,8 @@ int tipc_log_resize(int log_size)
353 int res = 0; 276 int res = 0;
354 277
355 spin_lock_bh(&print_lock); 278 spin_lock_bh(&print_lock);
356 if (TIPC_LOG->buf) { 279 kfree(TIPC_LOG->buf);
357 kfree(TIPC_LOG->buf); 280 TIPC_LOG->buf = NULL;
358 TIPC_LOG->buf = NULL;
359 }
360 if (log_size) { 281 if (log_size) {
361 if (log_size < TIPC_PB_MIN_SIZE) 282 if (log_size < TIPC_PB_MIN_SIZE)
362 log_size = TIPC_PB_MIN_SIZE; 283 log_size = TIPC_PB_MIN_SIZE;
@@ -407,8 +328,7 @@ struct sk_buff *tipc_log_dump(void)
407 } else if (tipc_printbuf_empty(TIPC_LOG)) { 328 } else if (tipc_printbuf_empty(TIPC_LOG)) {
408 spin_unlock_bh(&print_lock); 329 spin_unlock_bh(&print_lock);
409 reply = tipc_cfg_reply_ultra_string("log is empty\n"); 330 reply = tipc_cfg_reply_ultra_string("log is empty\n");
410 } 331 } else {
411 else {
412 struct tlv_desc *rep_tlv; 332 struct tlv_desc *rep_tlv;
413 struct print_buf pb; 333 struct print_buf pb;
414 int str_len; 334 int str_len;
@@ -429,4 +349,3 @@ struct sk_buff *tipc_log_dump(void)
429 } 349 }
430 return reply; 350 return reply;
431} 351}
432
diff --git a/net/tipc/dbg.h b/net/tipc/log.h
index 3ba6ba8b434a..2248d96238e6 100644
--- a/net/tipc/dbg.h
+++ b/net/tipc/log.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * net/tipc/dbg.h: Include file for TIPC print buffer routines 2 * net/tipc/log.h: Include file for TIPC print buffer routines
3 * 3 *
4 * Copyright (c) 1997-2006, Ericsson AB 4 * Copyright (c) 1997-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
@@ -34,8 +34,8 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#ifndef _TIPC_DBG_H 37#ifndef _TIPC_LOG_H
38#define _TIPC_DBG_H 38#define _TIPC_LOG_H
39 39
40/** 40/**
41 * struct print_buf - TIPC print buffer structure 41 * struct print_buf - TIPC print buffer structure
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index ecb532fb0351..6d92d17e7fb5 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -2,7 +2,7 @@
2 * net/tipc/msg.c: TIPC message header routines 2 * net/tipc/msg.c: TIPC message header routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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
@@ -35,10 +35,7 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "addr.h"
39#include "dbg.h"
40#include "msg.h" 38#include "msg.h"
41#include "bearer.h"
42 39
43u32 tipc_msg_tot_importance(struct tipc_msg *m) 40u32 tipc_msg_tot_importance(struct tipc_msg *m)
44{ 41{
@@ -94,7 +91,7 @@ int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
94 91
95int tipc_msg_build(struct tipc_msg *hdr, 92int tipc_msg_build(struct tipc_msg *hdr,
96 struct iovec const *msg_sect, u32 num_sect, 93 struct iovec const *msg_sect, u32 num_sect,
97 int max_size, int usrmem, struct sk_buff** buf) 94 int max_size, int usrmem, struct sk_buff **buf)
98{ 95{
99 int dsz, sz, hsz, pos, res, cnt; 96 int dsz, sz, hsz, pos, res, cnt;
100 97
@@ -140,6 +137,7 @@ int tipc_msg_build(struct tipc_msg *hdr,
140void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) 137void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
141{ 138{
142 u32 usr = msg_user(msg); 139 u32 usr = msg_user(msg);
140 tipc_printf(buf, KERN_DEBUG);
143 tipc_printf(buf, str); 141 tipc_printf(buf, str);
144 142
145 switch (usr) { 143 switch (usr) {
@@ -163,10 +161,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
163 tipc_printf(buf, "LAST:"); 161 tipc_printf(buf, "LAST:");
164 break; 162 break;
165 default: 163 default:
166 tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); 164 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
167 165
168 } 166 }
169 tipc_printf(buf, "NO(%u/%u):",msg_long_msgno(msg), 167 tipc_printf(buf, "NO(%u/%u):", msg_long_msgno(msg),
170 msg_fragm_no(msg)); 168 msg_fragm_no(msg));
171 break; 169 break;
172 case TIPC_LOW_IMPORTANCE: 170 case TIPC_LOW_IMPORTANCE:
@@ -192,10 +190,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
192 tipc_printf(buf, "DIR:"); 190 tipc_printf(buf, "DIR:");
193 break; 191 break;
194 default: 192 default:
195 tipc_printf(buf, "UNKNOWN TYPE %u",msg_type(msg)); 193 tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg));
196 } 194 }
197 if (msg_routed(msg) && !msg_non_seq(msg))
198 tipc_printf(buf, "ROUT:");
199 if (msg_reroute_cnt(msg)) 195 if (msg_reroute_cnt(msg))
200 tipc_printf(buf, "REROUTED(%u):", 196 tipc_printf(buf, "REROUTED(%u):",
201 msg_reroute_cnt(msg)); 197 msg_reroute_cnt(msg));
@@ -210,10 +206,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
210 tipc_printf(buf, "WDRW:"); 206 tipc_printf(buf, "WDRW:");
211 break; 207 break;
212 default: 208 default:
213 tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); 209 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
214 } 210 }
215 if (msg_routed(msg))
216 tipc_printf(buf, "ROUT:");
217 if (msg_reroute_cnt(msg)) 211 if (msg_reroute_cnt(msg))
218 tipc_printf(buf, "REROUTED(%u):", 212 tipc_printf(buf, "REROUTED(%u):",
219 msg_reroute_cnt(msg)); 213 msg_reroute_cnt(msg));
@@ -229,39 +223,36 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
229 break; 223 break;
230 case CONN_ACK: 224 case CONN_ACK:
231 tipc_printf(buf, "CONN_ACK:"); 225 tipc_printf(buf, "CONN_ACK:");
232 tipc_printf(buf, "ACK(%u):",msg_msgcnt(msg)); 226 tipc_printf(buf, "ACK(%u):", msg_msgcnt(msg));
233 break; 227 break;
234 default: 228 default:
235 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 229 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
236 } 230 }
237 if (msg_routed(msg))
238 tipc_printf(buf, "ROUT:");
239 if (msg_reroute_cnt(msg)) 231 if (msg_reroute_cnt(msg))
240 tipc_printf(buf, "REROUTED(%u):",msg_reroute_cnt(msg)); 232 tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg));
241 break; 233 break;
242 case LINK_PROTOCOL: 234 case LINK_PROTOCOL:
243 tipc_printf(buf, "PROT:TIM(%u):",msg_timestamp(msg));
244 switch (msg_type(msg)) { 235 switch (msg_type(msg)) {
245 case STATE_MSG: 236 case STATE_MSG:
246 tipc_printf(buf, "STATE:"); 237 tipc_printf(buf, "STATE:");
247 tipc_printf(buf, "%s:",msg_probe(msg) ? "PRB" :""); 238 tipc_printf(buf, "%s:", msg_probe(msg) ? "PRB" : "");
248 tipc_printf(buf, "NXS(%u):",msg_next_sent(msg)); 239 tipc_printf(buf, "NXS(%u):", msg_next_sent(msg));
249 tipc_printf(buf, "GAP(%u):",msg_seq_gap(msg)); 240 tipc_printf(buf, "GAP(%u):", msg_seq_gap(msg));
250 tipc_printf(buf, "LSTBC(%u):",msg_last_bcast(msg)); 241 tipc_printf(buf, "LSTBC(%u):", msg_last_bcast(msg));
251 break; 242 break;
252 case RESET_MSG: 243 case RESET_MSG:
253 tipc_printf(buf, "RESET:"); 244 tipc_printf(buf, "RESET:");
254 if (msg_size(msg) != msg_hdr_sz(msg)) 245 if (msg_size(msg) != msg_hdr_sz(msg))
255 tipc_printf(buf, "BEAR:%s:",msg_data(msg)); 246 tipc_printf(buf, "BEAR:%s:", msg_data(msg));
256 break; 247 break;
257 case ACTIVATE_MSG: 248 case ACTIVATE_MSG:
258 tipc_printf(buf, "ACTIVATE:"); 249 tipc_printf(buf, "ACTIVATE:");
259 break; 250 break;
260 default: 251 default:
261 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 252 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
262 } 253 }
263 tipc_printf(buf, "PLANE(%c):",msg_net_plane(msg)); 254 tipc_printf(buf, "PLANE(%c):", msg_net_plane(msg));
264 tipc_printf(buf, "SESS(%u):",msg_session(msg)); 255 tipc_printf(buf, "SESS(%u):", msg_session(msg));
265 break; 256 break;
266 case CHANGEOVER_PROTOCOL: 257 case CHANGEOVER_PROTOCOL:
267 tipc_printf(buf, "TUNL:"); 258 tipc_printf(buf, "TUNL:");
@@ -271,37 +262,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
271 break; 262 break;
272 case ORIGINAL_MSG: 263 case ORIGINAL_MSG:
273 tipc_printf(buf, "ORIG:"); 264 tipc_printf(buf, "ORIG:");
274 tipc_printf(buf, "EXP(%u)",msg_msgcnt(msg)); 265 tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg));
275 break; 266 break;
276 default: 267 default:
277 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 268 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
278 }
279 break;
280 case ROUTE_DISTRIBUTOR:
281 tipc_printf(buf, "ROUTING_MNG:");
282 switch (msg_type(msg)) {
283 case EXT_ROUTING_TABLE:
284 tipc_printf(buf, "EXT_TBL:");
285 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
286 break;
287 case LOCAL_ROUTING_TABLE:
288 tipc_printf(buf, "LOCAL_TBL:");
289 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
290 break;
291 case SLAVE_ROUTING_TABLE:
292 tipc_printf(buf, "DP_TBL:");
293 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
294 break;
295 case ROUTE_ADDITION:
296 tipc_printf(buf, "ADD:");
297 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
298 break;
299 case ROUTE_REMOVAL:
300 tipc_printf(buf, "REMOVE:");
301 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
302 break;
303 default:
304 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg));
305 } 269 }
306 break; 270 break;
307 case LINK_CONFIG: 271 case LINK_CONFIG:
@@ -314,7 +278,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
314 tipc_printf(buf, "DSC_RESP:"); 278 tipc_printf(buf, "DSC_RESP:");
315 break; 279 break;
316 default: 280 default:
317 tipc_printf(buf, "UNKNOWN TYPE:%x:",msg_type(msg)); 281 tipc_printf(buf, "UNKNOWN TYPE:%x:", msg_type(msg));
318 break; 282 break;
319 } 283 }
320 break; 284 break;
@@ -350,7 +314,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
350 tipc_printf(buf, "UNKNOWN ERROR(%x):", 314 tipc_printf(buf, "UNKNOWN ERROR(%x):",
351 msg_errcode(msg)); 315 msg_errcode(msg));
352 } 316 }
353 default:{} 317 default:
318 break;
354 } 319 }
355 320
356 tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg)); 321 tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg));
@@ -359,9 +324,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
359 324
360 if (msg_non_seq(msg)) 325 if (msg_non_seq(msg))
361 tipc_printf(buf, "NOSEQ:"); 326 tipc_printf(buf, "NOSEQ:");
362 else { 327 else
363 tipc_printf(buf, "ACK(%u):", msg_ack(msg)); 328 tipc_printf(buf, "ACK(%u):", msg_ack(msg));
364 }
365 tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg)); 329 tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg));
366 tipc_printf(buf, "PRND(%x)", msg_prevnode(msg)); 330 tipc_printf(buf, "PRND(%x)", msg_prevnode(msg));
367 331
@@ -383,21 +347,15 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
383 tipc_printf(buf, ":OPRT(%u):", msg_origport(msg)); 347 tipc_printf(buf, ":OPRT(%u):", msg_origport(msg));
384 tipc_printf(buf, ":DPRT(%u):", msg_destport(msg)); 348 tipc_printf(buf, ":DPRT(%u):", msg_destport(msg));
385 } 349 }
386 if (msg_routed(msg) && !msg_non_seq(msg))
387 tipc_printf(buf, ":TSEQN(%u)", msg_transp_seqno(msg));
388 } 350 }
389 if (msg_user(msg) == NAME_DISTRIBUTOR) { 351 if (msg_user(msg) == NAME_DISTRIBUTOR) {
390 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); 352 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg));
391 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); 353 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg));
392 if (msg_routed(msg)) {
393 tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg));
394 }
395 } 354 }
396 355
397 if (msg_user(msg) == LINK_CONFIG) { 356 if (msg_user(msg) == LINK_CONFIG) {
398 u32* raw = (u32*)msg; 357 u32 *raw = (u32 *)msg;
399 struct tipc_media_addr* orig = (struct tipc_media_addr*)&raw[5]; 358 struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5];
400 tipc_printf(buf, ":REQL(%u):", msg_req_links(msg));
401 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); 359 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg));
402 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); 360 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg));
403 tipc_media_addr_printf(buf, orig); 361 tipc_media_addr_printf(buf, orig);
@@ -407,12 +365,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
407 tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg)); 365 tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg));
408 } 366 }
409 tipc_printf(buf, "\n"); 367 tipc_printf(buf, "\n");
410 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { 368 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg)))
411 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); 369 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
412 } 370 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT))
413 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) {
414 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); 371 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
415 }
416} 372}
417 373
418#endif 374#endif
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 031aad18efce..de02339fc175 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -2,7 +2,7 @@
2 * net/tipc/msg.h: Include file for TIPC message header routines 2 * net/tipc/msg.h: Include file for TIPC message header routines
3 * 3 *
4 * Copyright (c) 2000-2007, Ericsson AB 4 * Copyright (c) 2000-2007, Ericsson AB
5 * Copyright (c) 2005-2008, Wind River Systems 5 * Copyright (c) 2005-2008, 2010-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,10 +37,51 @@
37#ifndef _TIPC_MSG_H 37#ifndef _TIPC_MSG_H
38#define _TIPC_MSG_H 38#define _TIPC_MSG_H
39 39
40#include "core.h" 40#include "bearer.h"
41 41
42#define TIPC_VERSION 2 42#define TIPC_VERSION 2
43 43
44/*
45 * TIPC user data message header format, version 2:
46 *
47 *
48 * 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 * w0:|vers | user |hdr sz |n|d|s|-| message size |
51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 * w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no |
53 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 * w2:| link level ack no | broadcast/link level seq no |
55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 * w3:| previous node |
57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 * w4:| originating port |
59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 * w5:| destination port |
61 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62 * w6:| originating node |
63 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 * w7:| destination node |
65 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 * w8:| name type / transport sequence number |
67 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68 * w9:| name instance/multicast lower bound |
69 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 * wA:| multicast upper bound |
71 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 * / /
73 * \ options \
74 * / /
75 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 *
77 */
78
79#define TIPC_CONN_MSG 0
80#define TIPC_MCAST_MSG 1
81#define TIPC_NAMED_MSG 2
82#define TIPC_DIRECT_MSG 3
83
84
44#define SHORT_H_SIZE 24 /* Connected, in-cluster messages */ 85#define SHORT_H_SIZE 24 /* Connected, in-cluster messages */
45#define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ 86#define DIR_MSG_H_SIZE 32 /* Directly addressed messages */
46#define LONG_H_SIZE 40 /* Named messages */ 87#define LONG_H_SIZE 40 /* Named messages */
@@ -52,20 +93,26 @@
52#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) 93#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE)
53 94
54 95
55/* 96struct tipc_msg {
56 TIPC user data message header format, version 2 97 __be32 hdr[15];
98};
57 99
58 - Fundamental definitions available to privileged TIPC users
59 are located in tipc_msg.h.
60 - Remaining definitions available to TIPC internal users appear below.
61*/
62 100
101static inline u32 msg_word(struct tipc_msg *m, u32 pos)
102{
103 return ntohl(m->hdr[pos]);
104}
63 105
64static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val) 106static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val)
65{ 107{
66 m->hdr[w] = htonl(val); 108 m->hdr[w] = htonl(val);
67} 109}
68 110
111static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask)
112{
113 return (msg_word(m, w) >> pos) & mask;
114}
115
69static inline void msg_set_bits(struct tipc_msg *m, u32 w, 116static inline void msg_set_bits(struct tipc_msg *m, u32 w,
70 u32 pos, u32 mask, u32 val) 117 u32 pos, u32 mask, u32 val)
71{ 118{
@@ -112,16 +159,36 @@ static inline void msg_set_user(struct tipc_msg *m, u32 n)
112 msg_set_bits(m, 0, 25, 0xf, n); 159 msg_set_bits(m, 0, 25, 0xf, n);
113} 160}
114 161
162static inline u32 msg_importance(struct tipc_msg *m)
163{
164 return msg_bits(m, 0, 25, 0xf);
165}
166
115static inline void msg_set_importance(struct tipc_msg *m, u32 i) 167static inline void msg_set_importance(struct tipc_msg *m, u32 i)
116{ 168{
117 msg_set_user(m, i); 169 msg_set_user(m, i);
118} 170}
119 171
120static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n) 172static inline u32 msg_hdr_sz(struct tipc_msg *m)
173{
174 return msg_bits(m, 0, 21, 0xf) << 2;
175}
176
177static inline void msg_set_hdr_sz(struct tipc_msg *m, u32 n)
121{ 178{
122 msg_set_bits(m, 0, 21, 0xf, n>>2); 179 msg_set_bits(m, 0, 21, 0xf, n>>2);
123} 180}
124 181
182static inline u32 msg_size(struct tipc_msg *m)
183{
184 return msg_bits(m, 0, 0, 0x1ffff);
185}
186
187static inline u32 msg_data_sz(struct tipc_msg *m)
188{
189 return msg_size(m) - msg_hdr_sz(m);
190}
191
125static inline int msg_non_seq(struct tipc_msg *m) 192static inline int msg_non_seq(struct tipc_msg *m)
126{ 193{
127 return msg_bits(m, 0, 20, 1); 194 return msg_bits(m, 0, 20, 1);
@@ -162,11 +229,36 @@ static inline void msg_set_size(struct tipc_msg *m, u32 sz)
162 * Word 1 229 * Word 1
163 */ 230 */
164 231
232static inline u32 msg_type(struct tipc_msg *m)
233{
234 return msg_bits(m, 1, 29, 0x7);
235}
236
165static inline void msg_set_type(struct tipc_msg *m, u32 n) 237static inline void msg_set_type(struct tipc_msg *m, u32 n)
166{ 238{
167 msg_set_bits(m, 1, 29, 0x7, n); 239 msg_set_bits(m, 1, 29, 0x7, n);
168} 240}
169 241
242static inline u32 msg_named(struct tipc_msg *m)
243{
244 return msg_type(m) == TIPC_NAMED_MSG;
245}
246
247static inline u32 msg_mcast(struct tipc_msg *m)
248{
249 return msg_type(m) == TIPC_MCAST_MSG;
250}
251
252static inline u32 msg_connected(struct tipc_msg *m)
253{
254 return msg_type(m) == TIPC_CONN_MSG;
255}
256
257static inline u32 msg_errcode(struct tipc_msg *m)
258{
259 return msg_bits(m, 1, 25, 0xf);
260}
261
170static inline void msg_set_errcode(struct tipc_msg *m, u32 err) 262static inline void msg_set_errcode(struct tipc_msg *m, u32 err)
171{ 263{
172 msg_set_bits(m, 1, 25, 0xf, err); 264 msg_set_bits(m, 1, 25, 0xf, err);
@@ -257,71 +349,96 @@ static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode)
257 */ 349 */
258 350
259 351
352static inline u32 msg_prevnode(struct tipc_msg *m)
353{
354 return msg_word(m, 3);
355}
356
260static inline void msg_set_prevnode(struct tipc_msg *m, u32 a) 357static inline void msg_set_prevnode(struct tipc_msg *m, u32 a)
261{ 358{
262 msg_set_word(m, 3, a); 359 msg_set_word(m, 3, a);
263} 360}
264 361
362static inline u32 msg_origport(struct tipc_msg *m)
363{
364 return msg_word(m, 4);
365}
366
265static inline void msg_set_origport(struct tipc_msg *m, u32 p) 367static inline void msg_set_origport(struct tipc_msg *m, u32 p)
266{ 368{
267 msg_set_word(m, 4, p); 369 msg_set_word(m, 4, p);
268} 370}
269 371
372static inline u32 msg_destport(struct tipc_msg *m)
373{
374 return msg_word(m, 5);
375}
376
270static inline void msg_set_destport(struct tipc_msg *m, u32 p) 377static inline void msg_set_destport(struct tipc_msg *m, u32 p)
271{ 378{
272 msg_set_word(m, 5, p); 379 msg_set_word(m, 5, p);
273} 380}
274 381
382static inline u32 msg_mc_netid(struct tipc_msg *m)
383{
384 return msg_word(m, 5);
385}
386
275static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p) 387static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p)
276{ 388{
277 msg_set_word(m, 5, p); 389 msg_set_word(m, 5, p);
278} 390}
279 391
280static inline void msg_set_orignode(struct tipc_msg *m, u32 a) 392static inline int msg_short(struct tipc_msg *m)
281{ 393{
282 msg_set_word(m, 6, a); 394 return msg_hdr_sz(m) == 24;
283} 395}
284 396
285static inline void msg_set_destnode(struct tipc_msg *m, u32 a) 397static inline u32 msg_orignode(struct tipc_msg *m)
286{ 398{
287 msg_set_word(m, 7, a); 399 if (likely(msg_short(m)))
400 return msg_prevnode(m);
401 return msg_word(m, 6);
288} 402}
289 403
290static inline int msg_is_dest(struct tipc_msg *m, u32 d) 404static inline void msg_set_orignode(struct tipc_msg *m, u32 a)
291{ 405{
292 return msg_short(m) || (msg_destnode(m) == d); 406 msg_set_word(m, 6, a);
293} 407}
294 408
295static inline u32 msg_routed(struct tipc_msg *m) 409static inline u32 msg_destnode(struct tipc_msg *m)
296{ 410{
297 if (likely(msg_short(m))) 411 return msg_word(m, 7);
298 return 0;
299 return(msg_destnode(m) ^ msg_orignode(m)) >> 11;
300} 412}
301 413
302static inline void msg_set_nametype(struct tipc_msg *m, u32 n) 414static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
303{ 415{
304 msg_set_word(m, 8, n); 416 msg_set_word(m, 7, a);
305} 417}
306 418
307static inline u32 msg_transp_seqno(struct tipc_msg *m) 419static inline int msg_is_dest(struct tipc_msg *m, u32 d)
420{
421 return msg_short(m) || (msg_destnode(m) == d);
422}
423
424static inline u32 msg_nametype(struct tipc_msg *m)
308{ 425{
309 return msg_word(m, 8); 426 return msg_word(m, 8);
310} 427}
311 428
312static inline void msg_set_timestamp(struct tipc_msg *m, u32 n) 429static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
313{ 430{
314 msg_set_word(m, 8, n); 431 msg_set_word(m, 8, n);
315} 432}
316 433
317static inline u32 msg_timestamp(struct tipc_msg *m) 434static inline u32 msg_nameinst(struct tipc_msg *m)
318{ 435{
319 return msg_word(m, 8); 436 return msg_word(m, 9);
320} 437}
321 438
322static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n) 439static inline u32 msg_namelower(struct tipc_msg *m)
323{ 440{
324 msg_set_word(m, 8, n); 441 return msg_nameinst(m);
325} 442}
326 443
327static inline void msg_set_namelower(struct tipc_msg *m, u32 n) 444static inline void msg_set_namelower(struct tipc_msg *m, u32 n)
@@ -334,11 +451,21 @@ static inline void msg_set_nameinst(struct tipc_msg *m, u32 n)
334 msg_set_namelower(m, n); 451 msg_set_namelower(m, n);
335} 452}
336 453
454static inline u32 msg_nameupper(struct tipc_msg *m)
455{
456 return msg_word(m, 10);
457}
458
337static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) 459static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
338{ 460{
339 msg_set_word(m, 10, n); 461 msg_set_word(m, 10, n);
340} 462}
341 463
464static inline unchar *msg_data(struct tipc_msg *m)
465{
466 return ((unchar *)m) + msg_hdr_sz(m);
467}
468
342static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) 469static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
343{ 470{
344 return (struct tipc_msg *)msg_data(m); 471 return (struct tipc_msg *)msg_data(m);
@@ -386,12 +513,11 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
386#define MSG_BUNDLER 6 513#define MSG_BUNDLER 6
387#define LINK_PROTOCOL 7 514#define LINK_PROTOCOL 7
388#define CONN_MANAGER 8 515#define CONN_MANAGER 8
389#define ROUTE_DISTRIBUTOR 9 516#define ROUTE_DISTRIBUTOR 9 /* obsoleted */
390#define CHANGEOVER_PROTOCOL 10 517#define CHANGEOVER_PROTOCOL 10
391#define NAME_DISTRIBUTOR 11 518#define NAME_DISTRIBUTOR 11
392#define MSG_FRAGMENTER 12 519#define MSG_FRAGMENTER 12
393#define LINK_CONFIG 13 520#define LINK_CONFIG 13
394#define DSC_H_SIZE 40
395 521
396/* 522/*
397 * Connection management protocol messages 523 * Connection management protocol messages
@@ -423,16 +549,6 @@ static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
423 msg_set_bits(m, 1, 16, 0x1fff, n); 549 msg_set_bits(m, 1, 16, 0x1fff, n);
424} 550}
425 551
426static inline u32 msg_req_links(struct tipc_msg *m)
427{
428 return msg_bits(m, 1, 16, 0xfff);
429}
430
431static inline void msg_set_req_links(struct tipc_msg *m, u32 n)
432{
433 msg_set_bits(m, 1, 16, 0xfff, n);
434}
435
436 552
437/* 553/*
438 * Word 2 554 * Word 2
@@ -595,14 +711,9 @@ static inline u32 msg_redundant_link(struct tipc_msg *m)
595 return msg_bits(m, 5, 12, 0x1); 711 return msg_bits(m, 5, 12, 0x1);
596} 712}
597 713
598static inline void msg_set_redundant_link(struct tipc_msg *m) 714static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r)
599{
600 msg_set_bits(m, 5, 12, 0x1, 1);
601}
602
603static inline void msg_clear_redundant_link(struct tipc_msg *m)
604{ 715{
605 msg_set_bits(m, 5, 12, 0x1, 0); 716 msg_set_bits(m, 5, 12, 0x1, r);
606} 717}
607 718
608 719
@@ -651,26 +762,6 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
651} 762}
652 763
653/* 764/*
654 * Routing table message data
655 */
656
657
658static inline u32 msg_remote_node(struct tipc_msg *m)
659{
660 return msg_word(m, msg_hdr_sz(m)/4);
661}
662
663static inline void msg_set_remote_node(struct tipc_msg *m, u32 a)
664{
665 msg_set_word(m, msg_hdr_sz(m)/4, a);
666}
667
668static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
669{
670 msg_data(m)[pos + 4] = 1;
671}
672
673/*
674 * Segmentation message types 765 * Segmentation message types
675 */ 766 */
676 767
@@ -696,7 +787,7 @@ static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
696 * Routing table message types 787 * Routing table message types
697 */ 788 */
698#define EXT_ROUTING_TABLE 0 789#define EXT_ROUTING_TABLE 0
699#define LOCAL_ROUTING_TABLE 1 790#define LOCAL_ROUTING_TABLE 1 /* obsoleted */
700#define SLAVE_ROUTING_TABLE 2 791#define SLAVE_ROUTING_TABLE 2
701#define ROUTE_ADDITION 3 792#define ROUTE_ADDITION 3
702#define ROUTE_REMOVAL 4 793#define ROUTE_REMOVAL 4
@@ -714,7 +805,7 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
714int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect); 805int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect);
715int tipc_msg_build(struct tipc_msg *hdr, 806int tipc_msg_build(struct tipc_msg *hdr,
716 struct iovec const *msg_sect, u32 num_sect, 807 struct iovec const *msg_sect, u32 num_sect,
717 int max_size, int usrmem, struct sk_buff** buf); 808 int max_size, int usrmem, struct sk_buff **buf);
718 809
719static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 810static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
720{ 811{
@@ -723,7 +814,7 @@ static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr
723 814
724static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 815static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
725{ 816{
726 memcpy(a, &((int*)m)[5], sizeof(*a)); 817 memcpy(a, &((int *)m)[5], sizeof(*a));
727} 818}
728 819
729#endif 820#endif
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 7b907171f879..80025a1b3bfd 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -2,7 +2,7 @@
2 * net/tipc/name_distr.c: TIPC name distribution code 2 * net/tipc/name_distr.c: TIPC name distribution code
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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
@@ -35,10 +35,7 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "cluster.h"
39#include "dbg.h"
40#include "link.h" 38#include "link.h"
41#include "msg.h"
42#include "name_distr.h" 39#include "name_distr.h"
43 40
44#define ITEM_SIZE sizeof(struct distr_item) 41#define ITEM_SIZE sizeof(struct distr_item)
@@ -76,7 +73,7 @@ struct distr_item {
76 */ 73 */
77 74
78static LIST_HEAD(publ_root); 75static LIST_HEAD(publ_root);
79static u32 publ_cnt = 0; 76static u32 publ_cnt;
80 77
81/** 78/**
82 * publ_to_item - add publication info to a publication message 79 * publ_to_item - add publication info to a publication message
@@ -89,7 +86,6 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
89 i->upper = htonl(p->upper); 86 i->upper = htonl(p->upper);
90 i->ref = htonl(p->ref); 87 i->ref = htonl(p->ref);
91 i->key = htonl(p->key); 88 i->key = htonl(p->key);
92 dbg("publ_to_item: %u, %u, %u\n", p->type, p->lower, p->upper);
93} 89}
94 90
95/** 91/**
@@ -109,6 +105,24 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
109 return buf; 105 return buf;
110} 106}
111 107
108static void named_cluster_distribute(struct sk_buff *buf)
109{
110 struct sk_buff *buf_copy;
111 struct tipc_node *n_ptr;
112
113 list_for_each_entry(n_ptr, &tipc_node_list, list) {
114 if (tipc_node_active_links(n_ptr)) {
115 buf_copy = skb_copy(buf, GFP_ATOMIC);
116 if (!buf_copy)
117 break;
118 msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
119 tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
120 }
121 }
122
123 buf_discard(buf);
124}
125
112/** 126/**
113 * tipc_named_publish - tell other nodes about a new publication by this node 127 * tipc_named_publish - tell other nodes about a new publication by this node
114 */ 128 */
@@ -129,8 +143,7 @@ void tipc_named_publish(struct publication *publ)
129 143
130 item = (struct distr_item *)msg_data(buf_msg(buf)); 144 item = (struct distr_item *)msg_data(buf_msg(buf));
131 publ_to_item(item, publ); 145 publ_to_item(item, publ);
132 dbg("tipc_named_withdraw: broadcasting publish msg\n"); 146 named_cluster_distribute(buf);
133 tipc_cltr_broadcast(buf);
134} 147}
135 148
136/** 149/**
@@ -147,14 +160,13 @@ void tipc_named_withdraw(struct publication *publ)
147 160
148 buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0); 161 buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0);
149 if (!buf) { 162 if (!buf) {
150 warn("Withdrawl distribution failure\n"); 163 warn("Withdrawal distribution failure\n");
151 return; 164 return;
152 } 165 }
153 166
154 item = (struct distr_item *)msg_data(buf_msg(buf)); 167 item = (struct distr_item *)msg_data(buf_msg(buf));
155 publ_to_item(item, publ); 168 publ_to_item(item, publ);
156 dbg("tipc_named_withdraw: broadcasting withdraw msg\n"); 169 named_cluster_distribute(buf);
157 tipc_cltr_broadcast(buf);
158} 170}
159 171
160/** 172/**
@@ -191,9 +203,6 @@ void tipc_named_node_up(unsigned long node)
191 left -= ITEM_SIZE; 203 left -= ITEM_SIZE;
192 if (!left) { 204 if (!left) {
193 msg_set_link_selector(buf_msg(buf), node); 205 msg_set_link_selector(buf_msg(buf), node);
194 dbg("tipc_named_node_up: sending publish msg to "
195 "<%u.%u.%u>\n", tipc_zone(node),
196 tipc_cluster(node), tipc_node(node));
197 tipc_link_send(buf, node, node); 206 tipc_link_send(buf, node, node);
198 buf = NULL; 207 buf = NULL;
199 } 208 }
@@ -203,26 +212,25 @@ exit:
203} 212}
204 213
205/** 214/**
206 * node_is_down - remove publication associated with a failed node 215 * named_purge_publ - remove publication associated with a failed node
207 * 216 *
208 * Invoked for each publication issued by a newly failed node. 217 * Invoked for each publication issued by a newly failed node.
209 * Removes publication structure from name table & deletes it. 218 * Removes publication structure from name table & deletes it.
210 * In rare cases the link may have come back up again when this 219 * In rare cases the link may have come back up again when this
211 * function is called, and we have two items representing the same 220 * function is called, and we have two items representing the same
212 * publication. Nudge this item's key to distinguish it from the other. 221 * publication. Nudge this item's key to distinguish it from the other.
213 * (Note: Publication's node subscription is already unsubscribed.)
214 */ 222 */
215 223
216static void node_is_down(struct publication *publ) 224static void named_purge_publ(struct publication *publ)
217{ 225{
218 struct publication *p; 226 struct publication *p;
219 227
220 write_lock_bh(&tipc_nametbl_lock); 228 write_lock_bh(&tipc_nametbl_lock);
221 dbg("node_is_down: withdrawing %u, %u, %u\n",
222 publ->type, publ->lower, publ->upper);
223 publ->key += 1222345; 229 publ->key += 1222345;
224 p = tipc_nametbl_remove_publ(publ->type, publ->lower, 230 p = tipc_nametbl_remove_publ(publ->type, publ->lower,
225 publ->node, publ->ref, publ->key); 231 publ->node, publ->ref, publ->key);
232 if (p)
233 tipc_nodesub_unsubscribe(&p->subscr);
226 write_unlock_bh(&tipc_nametbl_lock); 234 write_unlock_bh(&tipc_nametbl_lock);
227 235
228 if (p != publ) { 236 if (p != publ) {
@@ -231,9 +239,7 @@ static void node_is_down(struct publication *publ)
231 publ->type, publ->lower, publ->node, publ->ref, publ->key); 239 publ->type, publ->lower, publ->node, publ->ref, publ->key);
232 } 240 }
233 241
234 if (p) { 242 kfree(p);
235 kfree(p);
236 }
237} 243}
238 244
239/** 245/**
@@ -250,9 +256,6 @@ void tipc_named_recv(struct sk_buff *buf)
250 write_lock_bh(&tipc_nametbl_lock); 256 write_lock_bh(&tipc_nametbl_lock);
251 while (count--) { 257 while (count--) {
252 if (msg_type(msg) == PUBLICATION) { 258 if (msg_type(msg) == PUBLICATION) {
253 dbg("tipc_named_recv: got publication for %u, %u, %u\n",
254 ntohl(item->type), ntohl(item->lower),
255 ntohl(item->upper));
256 publ = tipc_nametbl_insert_publ(ntohl(item->type), 259 publ = tipc_nametbl_insert_publ(ntohl(item->type),
257 ntohl(item->lower), 260 ntohl(item->lower),
258 ntohl(item->upper), 261 ntohl(item->upper),
@@ -264,12 +267,10 @@ void tipc_named_recv(struct sk_buff *buf)
264 tipc_nodesub_subscribe(&publ->subscr, 267 tipc_nodesub_subscribe(&publ->subscr,
265 msg_orignode(msg), 268 msg_orignode(msg),
266 publ, 269 publ,
267 (net_ev_handler)node_is_down); 270 (net_ev_handler)
271 named_purge_publ);
268 } 272 }
269 } else if (msg_type(msg) == WITHDRAWAL) { 273 } else if (msg_type(msg) == WITHDRAWAL) {
270 dbg("tipc_named_recv: got withdrawl for %u, %u, %u\n",
271 ntohl(item->type), ntohl(item->lower),
272 ntohl(item->upper));
273 publ = tipc_nametbl_remove_publ(ntohl(item->type), 274 publ = tipc_nametbl_remove_publ(ntohl(item->type),
274 ntohl(item->lower), 275 ntohl(item->lower),
275 msg_orignode(msg), 276 msg_orignode(msg),
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 3a8de4334da1..205ed4a4e186 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -36,15 +36,10 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "config.h"
39#include "dbg.h"
40#include "name_table.h" 39#include "name_table.h"
41#include "name_distr.h" 40#include "name_distr.h"
42#include "addr.h"
43#include "node_subscr.h"
44#include "subscr.h" 41#include "subscr.h"
45#include "port.h" 42#include "port.h"
46#include "cluster.h"
47#include "bcast.h"
48 43
49static int tipc_nametbl_size = 1024; /* must be a power of 2 */ 44static int tipc_nametbl_size = 1024; /* must be a power of 2 */
50 45
@@ -109,7 +104,7 @@ struct name_table {
109 u32 local_publ_count; 104 u32 local_publ_count;
110}; 105};
111 106
112static struct name_table table = { NULL } ; 107static struct name_table table;
113static atomic_t rsv_publ_ok = ATOMIC_INIT(0); 108static atomic_t rsv_publ_ok = ATOMIC_INIT(0);
114DEFINE_RWLOCK(tipc_nametbl_lock); 109DEFINE_RWLOCK(tipc_nametbl_lock);
115 110
@@ -177,8 +172,6 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea
177 spin_lock_init(&nseq->lock); 172 spin_lock_init(&nseq->lock);
178 nseq->type = type; 173 nseq->type = type;
179 nseq->sseqs = sseq; 174 nseq->sseqs = sseq;
180 dbg("tipc_nameseq_create(): nseq = %p, type %u, ssseqs %p, ff: %u\n",
181 nseq, type, nseq->sseqs, nseq->first_free);
182 nseq->alloc = 1; 175 nseq->alloc = 1;
183 INIT_HLIST_NODE(&nseq->ns_list); 176 INIT_HLIST_NODE(&nseq->ns_list);
184 INIT_LIST_HEAD(&nseq->subscriptions); 177 INIT_LIST_HEAD(&nseq->subscriptions);
@@ -256,8 +249,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
256 int created_subseq = 0; 249 int created_subseq = 0;
257 250
258 sseq = nameseq_find_subseq(nseq, lower); 251 sseq = nameseq_find_subseq(nseq, lower);
259 dbg("nameseq_ins: for seq %p, {%u,%u}, found sseq %p\n",
260 nseq, type, lower, sseq);
261 if (sseq) { 252 if (sseq) {
262 253
263 /* Lower end overlaps existing entry => need an exact match */ 254 /* Lower end overlaps existing entry => need an exact match */
@@ -294,38 +285,30 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
294 type, lower, upper); 285 type, lower, upper);
295 return NULL; 286 return NULL;
296 } 287 }
297 dbg("Allocated %u more sseqs\n", nseq->alloc);
298 memcpy(sseqs, nseq->sseqs, 288 memcpy(sseqs, nseq->sseqs,
299 nseq->alloc * sizeof(struct sub_seq)); 289 nseq->alloc * sizeof(struct sub_seq));
300 kfree(nseq->sseqs); 290 kfree(nseq->sseqs);
301 nseq->sseqs = sseqs; 291 nseq->sseqs = sseqs;
302 nseq->alloc *= 2; 292 nseq->alloc *= 2;
303 } 293 }
304 dbg("Have %u sseqs for type %u\n", nseq->alloc, type);
305 294
306 /* Insert new sub-sequence */ 295 /* Insert new sub-sequence */
307 296
308 dbg("ins in pos %u, ff = %u\n", inspos, nseq->first_free);
309 sseq = &nseq->sseqs[inspos]; 297 sseq = &nseq->sseqs[inspos];
310 freesseq = &nseq->sseqs[nseq->first_free]; 298 freesseq = &nseq->sseqs[nseq->first_free];
311 memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof (*sseq)); 299 memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof(*sseq));
312 memset(sseq, 0, sizeof (*sseq)); 300 memset(sseq, 0, sizeof(*sseq));
313 nseq->first_free++; 301 nseq->first_free++;
314 sseq->lower = lower; 302 sseq->lower = lower;
315 sseq->upper = upper; 303 sseq->upper = upper;
316 created_subseq = 1; 304 created_subseq = 1;
317 } 305 }
318 dbg("inserting {%u,%u,%u} from <0x%x:%u> into sseq %p(%u,%u) of seq %p\n",
319 type, lower, upper, node, port, sseq,
320 sseq->lower, sseq->upper, nseq);
321 306
322 /* Insert a publication: */ 307 /* Insert a publication: */
323 308
324 publ = publ_create(type, lower, upper, scope, node, port, key); 309 publ = publ_create(type, lower, upper, scope, node, port, key);
325 if (!publ) 310 if (!publ)
326 return NULL; 311 return NULL;
327 dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n",
328 publ, node, publ->node, publ->subscr.node);
329 312
330 sseq->zone_list_size++; 313 sseq->zone_list_size++;
331 if (!sseq->zone_list) 314 if (!sseq->zone_list)
@@ -360,7 +343,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
360 * Any subscriptions waiting for notification? 343 * Any subscriptions waiting for notification?
361 */ 344 */
362 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { 345 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
363 dbg("calling report_overlap()\n");
364 tipc_subscr_report_overlap(s, 346 tipc_subscr_report_overlap(s,
365 publ->lower, 347 publ->lower,
366 publ->upper, 348 publ->upper,
@@ -398,9 +380,6 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
398 if (!sseq) 380 if (!sseq)
399 return NULL; 381 return NULL;
400 382
401 dbg("tipc_nameseq_remove_publ: seq: %p, sseq %p, {%u,%u}, key %u\n",
402 nseq, sseq, nseq->type, inst, key);
403
404 /* Remove publication from zone scope list */ 383 /* Remove publication from zone scope list */
405 384
406 prev = sseq->zone_list; 385 prev = sseq->zone_list;
@@ -492,7 +471,7 @@ end_node:
492 471
493 if (!sseq->zone_list) { 472 if (!sseq->zone_list) {
494 free = &nseq->sseqs[nseq->first_free--]; 473 free = &nseq->sseqs[nseq->first_free--];
495 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq)); 474 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
496 removed_subseq = 1; 475 removed_subseq = 1;
497 } 476 }
498 477
@@ -528,7 +507,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s
528 507
529 while (sseq != &nseq->sseqs[nseq->first_free]) { 508 while (sseq != &nseq->sseqs[nseq->first_free]) {
530 struct publication *zl = sseq->zone_list; 509 struct publication *zl = sseq->zone_list;
531 if (zl && tipc_subscr_overlap(s,sseq->lower,sseq->upper)) { 510 if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) {
532 struct publication *crs = zl; 511 struct publication *crs = zl;
533 int must_report = 1; 512 int must_report = 1;
534 513
@@ -554,15 +533,10 @@ static struct name_seq *nametbl_find_seq(u32 type)
554 struct hlist_node *seq_node; 533 struct hlist_node *seq_node;
555 struct name_seq *ns; 534 struct name_seq *ns;
556 535
557 dbg("find_seq %u,(%u,0x%x) table = %p, hash[type] = %u\n",
558 type, htonl(type), type, table.types, hash(type));
559
560 seq_head = &table.types[hash(type)]; 536 seq_head = &table.types[hash(type)];
561 hlist_for_each_entry(ns, seq_node, seq_head, ns_list) { 537 hlist_for_each_entry(ns, seq_node, seq_head, ns_list) {
562 if (ns->type == type) { 538 if (ns->type == type)
563 dbg("found %p\n", ns);
564 return ns; 539 return ns;
565 }
566 } 540 }
567 541
568 return NULL; 542 return NULL;
@@ -573,18 +547,14 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
573{ 547{
574 struct name_seq *seq = nametbl_find_seq(type); 548 struct name_seq *seq = nametbl_find_seq(type);
575 549
576 dbg("tipc_nametbl_insert_publ: {%u,%u,%u} found %p\n", type, lower, upper, seq);
577 if (lower > upper) { 550 if (lower > upper) {
578 warn("Failed to publish illegal {%u,%u,%u}\n", 551 warn("Failed to publish illegal {%u,%u,%u}\n",
579 type, lower, upper); 552 type, lower, upper);
580 return NULL; 553 return NULL;
581 } 554 }
582 555
583 dbg("Publishing {%u,%u,%u} from 0x%x\n", type, lower, upper, node); 556 if (!seq)
584 if (!seq) {
585 seq = tipc_nameseq_create(type, &table.types[hash(type)]); 557 seq = tipc_nameseq_create(type, &table.types[hash(type)]);
586 dbg("tipc_nametbl_insert_publ: created %p\n", seq);
587 }
588 if (!seq) 558 if (!seq)
589 return NULL; 559 return NULL;
590 560
@@ -601,7 +571,6 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
601 if (!seq) 571 if (!seq)
602 return NULL; 572 return NULL;
603 573
604 dbg("Withdrawing {%u,%u} from 0x%x\n", type, lower, node);
605 publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key); 574 publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key);
606 575
607 if (!seq->first_free && list_empty(&seq->subscriptions)) { 576 if (!seq->first_free && list_empty(&seq->subscriptions)) {
@@ -782,9 +751,8 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
782 table.local_publ_count++; 751 table.local_publ_count++;
783 publ = tipc_nametbl_insert_publ(type, lower, upper, scope, 752 publ = tipc_nametbl_insert_publ(type, lower, upper, scope,
784 tipc_own_addr, port_ref, key); 753 tipc_own_addr, port_ref, key);
785 if (publ && (scope != TIPC_NODE_SCOPE)) { 754 if (publ && (scope != TIPC_NODE_SCOPE))
786 tipc_named_publish(publ); 755 tipc_named_publish(publ);
787 }
788 write_unlock_bh(&tipc_nametbl_lock); 756 write_unlock_bh(&tipc_nametbl_lock);
789 return publ; 757 return publ;
790} 758}
@@ -797,7 +765,6 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
797{ 765{
798 struct publication *publ; 766 struct publication *publ;
799 767
800 dbg("tipc_nametbl_withdraw: {%u,%u}, key=%u\n", type, lower, key);
801 write_lock_bh(&tipc_nametbl_lock); 768 write_lock_bh(&tipc_nametbl_lock);
802 publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); 769 publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
803 if (likely(publ)) { 770 if (likely(publ)) {
@@ -827,13 +794,10 @@ void tipc_nametbl_subscribe(struct subscription *s)
827 794
828 write_lock_bh(&tipc_nametbl_lock); 795 write_lock_bh(&tipc_nametbl_lock);
829 seq = nametbl_find_seq(type); 796 seq = nametbl_find_seq(type);
830 if (!seq) { 797 if (!seq)
831 seq = tipc_nameseq_create(type, &table.types[hash(type)]); 798 seq = tipc_nameseq_create(type, &table.types[hash(type)]);
832 } 799 if (seq) {
833 if (seq){
834 spin_lock_bh(&seq->lock); 800 spin_lock_bh(&seq->lock);
835 dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n",
836 seq, type, s->seq.lower, s->seq.upper);
837 tipc_nameseq_subscribe(seq, s); 801 tipc_nameseq_subscribe(seq, s);
838 spin_unlock_bh(&seq->lock); 802 spin_unlock_bh(&seq->lock);
839 } else { 803 } else {
@@ -853,7 +817,7 @@ void tipc_nametbl_unsubscribe(struct subscription *s)
853 817
854 write_lock_bh(&tipc_nametbl_lock); 818 write_lock_bh(&tipc_nametbl_lock);
855 seq = nametbl_find_seq(s->seq.type); 819 seq = nametbl_find_seq(s->seq.type);
856 if (seq != NULL){ 820 if (seq != NULL) {
857 spin_lock_bh(&seq->lock); 821 spin_lock_bh(&seq->lock);
858 list_del_init(&s->nameseq_list); 822 list_del_init(&s->nameseq_list);
859 spin_unlock_bh(&seq->lock); 823 spin_unlock_bh(&seq->lock);
@@ -886,7 +850,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
886 } 850 }
887 851
888 do { 852 do {
889 sprintf (portIdStr, "<%u.%u.%u:%u>", 853 sprintf(portIdStr, "<%u.%u.%u:%u>",
890 tipc_zone(publ->node), tipc_cluster(publ->node), 854 tipc_zone(publ->node), tipc_cluster(publ->node),
891 tipc_node(publ->node), publ->ref); 855 tipc_node(publ->node), publ->ref);
892 tipc_printf(buf, "%-26s ", portIdStr); 856 tipc_printf(buf, "%-26s ", portIdStr);
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 139882d4ed00..d228bd682655 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -46,7 +46,7 @@ struct port_list;
46 * TIPC name types reserved for internal TIPC use (both current and planned) 46 * TIPC name types reserved for internal TIPC use (both current and planned)
47 */ 47 */
48 48
49#define TIPC_ZM_SRV 3 /* zone master service name type */ 49#define TIPC_ZM_SRV 3 /* zone master service name type */
50 50
51 51
52/** 52/**
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 1a621cfd6604..68b3dd637291 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -2,7 +2,7 @@
2 * net/tipc/net.c: TIPC network routing code 2 * net/tipc/net.c: TIPC network routing code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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
@@ -35,18 +35,11 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "bearer.h"
39#include "net.h" 38#include "net.h"
40#include "zone.h"
41#include "addr.h"
42#include "name_table.h"
43#include "name_distr.h" 39#include "name_distr.h"
44#include "subscr.h" 40#include "subscr.h"
45#include "link.h"
46#include "msg.h"
47#include "port.h" 41#include "port.h"
48#include "bcast.h" 42#include "node.h"
49#include "discover.h"
50#include "config.h" 43#include "config.h"
51 44
52/* 45/*
@@ -116,47 +109,6 @@
116*/ 109*/
117 110
118DEFINE_RWLOCK(tipc_net_lock); 111DEFINE_RWLOCK(tipc_net_lock);
119static struct _zone *tipc_zones[256] = { NULL, };
120struct network tipc_net = { tipc_zones };
121
122struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref)
123{
124 return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref);
125}
126
127u32 tipc_net_select_router(u32 addr, u32 ref)
128{
129 return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref);
130}
131
132void tipc_net_remove_as_router(u32 router)
133{
134 u32 z_num;
135
136 for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
137 if (!tipc_net.zones[z_num])
138 continue;
139 tipc_zone_remove_as_router(tipc_net.zones[z_num], router);
140 }
141}
142
143void tipc_net_send_external_routes(u32 dest)
144{
145 u32 z_num;
146
147 for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
148 if (tipc_net.zones[z_num])
149 tipc_zone_send_external_routes(tipc_net.zones[z_num], dest);
150 }
151}
152
153static void net_stop(void)
154{
155 u32 z_num;
156
157 for (z_num = 1; z_num <= tipc_max_zones; z_num++)
158 tipc_zone_delete(tipc_net.zones[z_num]);
159}
160 112
161static void net_route_named_msg(struct sk_buff *buf) 113static void net_route_named_msg(struct sk_buff *buf)
162{ 114{
@@ -165,22 +117,18 @@ static void net_route_named_msg(struct sk_buff *buf)
165 u32 dport; 117 u32 dport;
166 118
167 if (!msg_named(msg)) { 119 if (!msg_named(msg)) {
168 msg_dbg(msg, "tipc_net->drop_nam:");
169 buf_discard(buf); 120 buf_discard(buf);
170 return; 121 return;
171 } 122 }
172 123
173 dnode = addr_domain(msg_lookup_scope(msg)); 124 dnode = addr_domain(msg_lookup_scope(msg));
174 dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode); 125 dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode);
175 dbg("tipc_net->lookup<%u,%u>-><%u,%x>\n",
176 msg_nametype(msg), msg_nameinst(msg), dport, dnode);
177 if (dport) { 126 if (dport) {
178 msg_set_destnode(msg, dnode); 127 msg_set_destnode(msg, dnode);
179 msg_set_destport(msg, dport); 128 msg_set_destport(msg, dport);
180 tipc_net_route_msg(buf); 129 tipc_net_route_msg(buf);
181 return; 130 return;
182 } 131 }
183 msg_dbg(msg, "tipc_net->rej:NO NAME: ");
184 tipc_reject_msg(buf, TIPC_ERR_NO_NAME); 132 tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
185} 133}
186 134
@@ -196,18 +144,14 @@ void tipc_net_route_msg(struct sk_buff *buf)
196 msg_incr_reroute_cnt(msg); 144 msg_incr_reroute_cnt(msg);
197 if (msg_reroute_cnt(msg) > 6) { 145 if (msg_reroute_cnt(msg) > 6) {
198 if (msg_errcode(msg)) { 146 if (msg_errcode(msg)) {
199 msg_dbg(msg, "NET>DISC>:");
200 buf_discard(buf); 147 buf_discard(buf);
201 } else { 148 } else {
202 msg_dbg(msg, "NET>REJ>:");
203 tipc_reject_msg(buf, msg_destport(msg) ? 149 tipc_reject_msg(buf, msg_destport(msg) ?
204 TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME); 150 TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME);
205 } 151 }
206 return; 152 return;
207 } 153 }
208 154
209 msg_dbg(msg, "tipc_net->rout: ");
210
211 /* Handle message for this node */ 155 /* Handle message for this node */
212 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); 156 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg);
213 if (tipc_in_scope(dnode, tipc_own_addr)) { 157 if (tipc_in_scope(dnode, tipc_own_addr)) {
@@ -221,9 +165,6 @@ void tipc_net_route_msg(struct sk_buff *buf)
221 return; 165 return;
222 } 166 }
223 switch (msg_user(msg)) { 167 switch (msg_user(msg)) {
224 case ROUTE_DISTRIBUTOR:
225 tipc_cltr_recv_routing_table(buf);
226 break;
227 case NAME_DISTRIBUTOR: 168 case NAME_DISTRIBUTOR:
228 tipc_named_recv(buf); 169 tipc_named_recv(buf);
229 break; 170 break;
@@ -231,14 +172,12 @@ void tipc_net_route_msg(struct sk_buff *buf)
231 tipc_port_recv_proto_msg(buf); 172 tipc_port_recv_proto_msg(buf);
232 break; 173 break;
233 default: 174 default:
234 msg_dbg(msg,"DROP/NET/<REC<");
235 buf_discard(buf); 175 buf_discard(buf);
236 } 176 }
237 return; 177 return;
238 } 178 }
239 179
240 /* Handle message for another node */ 180 /* Handle message for another node */
241 msg_dbg(msg, "NET>SEND>: ");
242 skb_trim(buf, msg_size(msg)); 181 skb_trim(buf, msg_size(msg));
243 tipc_link_send(buf, dnode, msg_link_selector(msg)); 182 tipc_link_send(buf, dnode, msg_link_selector(msg));
244} 183}
@@ -259,10 +198,9 @@ int tipc_net_start(u32 addr)
259 tipc_named_reinit(); 198 tipc_named_reinit();
260 tipc_port_reinit(); 199 tipc_port_reinit();
261 200
262 if ((res = tipc_cltr_init()) || 201 res = tipc_bclink_init();
263 (res = tipc_bclink_init())) { 202 if (res)
264 return res; 203 return res;
265 }
266 204
267 tipc_k_signal((Handler)tipc_subscr_start, 0); 205 tipc_k_signal((Handler)tipc_subscr_start, 0);
268 tipc_k_signal((Handler)tipc_cfg_init, 0); 206 tipc_k_signal((Handler)tipc_cfg_init, 0);
@@ -275,14 +213,16 @@ int tipc_net_start(u32 addr)
275 213
276void tipc_net_stop(void) 214void tipc_net_stop(void)
277{ 215{
216 struct tipc_node *node, *t_node;
217
278 if (tipc_mode != TIPC_NET_MODE) 218 if (tipc_mode != TIPC_NET_MODE)
279 return; 219 return;
280 write_lock_bh(&tipc_net_lock); 220 write_lock_bh(&tipc_net_lock);
281 tipc_bearer_stop(); 221 tipc_bearer_stop();
282 tipc_mode = TIPC_NODE_MODE; 222 tipc_mode = TIPC_NODE_MODE;
283 tipc_bclink_stop(); 223 tipc_bclink_stop();
284 net_stop(); 224 list_for_each_entry_safe(node, t_node, &tipc_node_list, list)
225 tipc_node_delete(node);
285 write_unlock_bh(&tipc_net_lock); 226 write_unlock_bh(&tipc_net_lock);
286 info("Left network mode\n"); 227 info("Left network mode\n");
287} 228}
288
diff --git a/net/tipc/net.h b/net/tipc/net.h
index de2b9ad8f646..9eb4b9e220eb 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -2,7 +2,7 @@
2 * net/tipc/net.h: Include file for TIPC network routing code 2 * net/tipc/net.h: Include file for TIPC network routing code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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,26 +37,9 @@
37#ifndef _TIPC_NET_H 37#ifndef _TIPC_NET_H
38#define _TIPC_NET_H 38#define _TIPC_NET_H
39 39
40struct _zone;
41
42/**
43 * struct network - TIPC network structure
44 * @zones: array of pointers to all zones within network
45 */
46
47struct network {
48 struct _zone **zones;
49};
50
51
52extern struct network tipc_net;
53extern rwlock_t tipc_net_lock; 40extern rwlock_t tipc_net_lock;
54 41
55void tipc_net_remove_as_router(u32 router);
56void tipc_net_send_external_routes(u32 dest);
57void tipc_net_route_msg(struct sk_buff *buf); 42void tipc_net_route_msg(struct sk_buff *buf);
58struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref);
59u32 tipc_net_select_router(u32 addr, u32 ref);
60 43
61int tipc_net_start(u32 addr); 44int tipc_net_start(u32 addr);
62void tipc_net_stop(void); 45void tipc_net_stop(void);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b4d87eb2dc5d..2d106ef4fa4c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -2,7 +2,7 @@
2 * net/tipc/node.c: TIPC node management routines 2 * net/tipc/node.c: TIPC node management routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-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,25 +37,38 @@
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "config.h"
39#include "node.h" 39#include "node.h"
40#include "cluster.h"
41#include "net.h"
42#include "addr.h"
43#include "node_subscr.h"
44#include "link.h"
45#include "port.h"
46#include "bearer.h"
47#include "name_distr.h" 40#include "name_distr.h"
48 41
49void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str);
50static void node_lost_contact(struct tipc_node *n_ptr); 42static void node_lost_contact(struct tipc_node *n_ptr);
51static void node_established_contact(struct tipc_node *n_ptr); 43static void node_established_contact(struct tipc_node *n_ptr);
52 44
53/* sorted list of nodes within cluster */
54static struct tipc_node *tipc_nodes = NULL;
55
56static DEFINE_SPINLOCK(node_create_lock); 45static DEFINE_SPINLOCK(node_create_lock);
57 46
58u32 tipc_own_tag = 0; 47static struct hlist_head node_htable[NODE_HTABLE_SIZE];
48LIST_HEAD(tipc_node_list);
49static u32 tipc_num_nodes;
50
51static atomic_t tipc_num_links = ATOMIC_INIT(0);
52u32 tipc_own_tag;
53
54/**
55 * tipc_node_find - locate specified node object, if it exists
56 */
57
58struct tipc_node *tipc_node_find(u32 addr)
59{
60 struct tipc_node *node;
61 struct hlist_node *pos;
62
63 if (unlikely(!in_own_cluster(addr)))
64 return NULL;
65
66 hlist_for_each_entry(node, pos, &node_htable[tipc_hashfn(addr)], hash) {
67 if (node->addr == addr)
68 return node;
69 }
70 return NULL;
71}
59 72
60/** 73/**
61 * tipc_node_create - create neighboring node 74 * tipc_node_create - create neighboring node
@@ -69,65 +82,50 @@ u32 tipc_own_tag = 0;
69 82
70struct tipc_node *tipc_node_create(u32 addr) 83struct tipc_node *tipc_node_create(u32 addr)
71{ 84{
72 struct cluster *c_ptr; 85 struct tipc_node *n_ptr, *temp_node;
73 struct tipc_node *n_ptr;
74 struct tipc_node **curr_node;
75 86
76 spin_lock_bh(&node_create_lock); 87 spin_lock_bh(&node_create_lock);
77 88
78 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 89 n_ptr = tipc_node_find(addr);
79 if (addr < n_ptr->addr) 90 if (n_ptr) {
80 break; 91 spin_unlock_bh(&node_create_lock);
81 if (addr == n_ptr->addr) { 92 return n_ptr;
82 spin_unlock_bh(&node_create_lock);
83 return n_ptr;
84 }
85 } 93 }
86 94
87 n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); 95 n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC);
88 if (!n_ptr) { 96 if (!n_ptr) {
89 spin_unlock_bh(&node_create_lock); 97 spin_unlock_bh(&node_create_lock);
90 warn("Node creation failed, no memory\n"); 98 warn("Node creation failed, no memory\n");
91 return NULL; 99 return NULL;
92 } 100 }
93 101
94 c_ptr = tipc_cltr_find(addr);
95 if (!c_ptr) {
96 c_ptr = tipc_cltr_create(addr);
97 }
98 if (!c_ptr) {
99 spin_unlock_bh(&node_create_lock);
100 kfree(n_ptr);
101 return NULL;
102 }
103
104 n_ptr->addr = addr; 102 n_ptr->addr = addr;
105 spin_lock_init(&n_ptr->lock); 103 spin_lock_init(&n_ptr->lock);
104 INIT_HLIST_NODE(&n_ptr->hash);
105 INIT_LIST_HEAD(&n_ptr->list);
106 INIT_LIST_HEAD(&n_ptr->nsub); 106 INIT_LIST_HEAD(&n_ptr->nsub);
107 n_ptr->owner = c_ptr; 107
108 tipc_cltr_attach_node(c_ptr, n_ptr); 108 hlist_add_head(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
109 n_ptr->last_router = -1; 109
110 110 list_for_each_entry(temp_node, &tipc_node_list, list) {
111 /* Insert node into ordered list */ 111 if (n_ptr->addr < temp_node->addr)
112 for (curr_node = &tipc_nodes; *curr_node;
113 curr_node = &(*curr_node)->next) {
114 if (addr < (*curr_node)->addr) {
115 n_ptr->next = *curr_node;
116 break; 112 break;
117 }
118 } 113 }
119 (*curr_node) = n_ptr; 114 list_add_tail(&n_ptr->list, &temp_node->list);
115
116 tipc_num_nodes++;
117
120 spin_unlock_bh(&node_create_lock); 118 spin_unlock_bh(&node_create_lock);
121 return n_ptr; 119 return n_ptr;
122} 120}
123 121
124void tipc_node_delete(struct tipc_node *n_ptr) 122void tipc_node_delete(struct tipc_node *n_ptr)
125{ 123{
126 if (!n_ptr) 124 list_del(&n_ptr->list);
127 return; 125 hlist_del(&n_ptr->hash);
128
129 dbg("node %x deleted\n", n_ptr->addr);
130 kfree(n_ptr); 126 kfree(n_ptr);
127
128 tipc_num_nodes--;
131} 129}
132 130
133 131
@@ -147,7 +145,6 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr)
147 l_ptr->name, l_ptr->b_ptr->net_plane); 145 l_ptr->name, l_ptr->b_ptr->net_plane);
148 146
149 if (!active[0]) { 147 if (!active[0]) {
150 dbg(" link %x into %x/%x\n", l_ptr, &active[0], &active[1]);
151 active[0] = active[1] = l_ptr; 148 active[0] = active[1] = l_ptr;
152 node_established_contact(n_ptr); 149 node_established_contact(n_ptr);
153 return; 150 return;
@@ -226,59 +223,32 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr)
226 node_lost_contact(n_ptr); 223 node_lost_contact(n_ptr);
227} 224}
228 225
229int tipc_node_has_active_links(struct tipc_node *n_ptr) 226int tipc_node_active_links(struct tipc_node *n_ptr)
230{ 227{
231 return n_ptr->active_links[0] != NULL; 228 return n_ptr->active_links[0] != NULL;
232} 229}
233 230
234int tipc_node_has_redundant_links(struct tipc_node *n_ptr) 231int tipc_node_redundant_links(struct tipc_node *n_ptr)
235{ 232{
236 return n_ptr->working_links > 1; 233 return n_ptr->working_links > 1;
237} 234}
238 235
239static int tipc_node_has_active_routes(struct tipc_node *n_ptr)
240{
241 return n_ptr && (n_ptr->last_router >= 0);
242}
243
244int tipc_node_is_up(struct tipc_node *n_ptr) 236int tipc_node_is_up(struct tipc_node *n_ptr)
245{ 237{
246 return tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr); 238 return tipc_node_active_links(n_ptr);
247} 239}
248 240
249struct tipc_node *tipc_node_attach_link(struct link *l_ptr) 241void tipc_node_attach_link(struct tipc_node *n_ptr, struct link *l_ptr)
250{ 242{
251 struct tipc_node *n_ptr = tipc_node_find(l_ptr->addr); 243 n_ptr->links[l_ptr->b_ptr->identity] = l_ptr;
252 244 atomic_inc(&tipc_num_links);
253 if (!n_ptr) 245 n_ptr->link_cnt++;
254 n_ptr = tipc_node_create(l_ptr->addr);
255 if (n_ptr) {
256 u32 bearer_id = l_ptr->b_ptr->identity;
257 char addr_string[16];
258
259 if (n_ptr->link_cnt >= 2) {
260 err("Attempt to create third link to %s\n",
261 tipc_addr_string_fill(addr_string, n_ptr->addr));
262 return NULL;
263 }
264
265 if (!n_ptr->links[bearer_id]) {
266 n_ptr->links[bearer_id] = l_ptr;
267 tipc_net.zones[tipc_zone(l_ptr->addr)]->links++;
268 n_ptr->link_cnt++;
269 return n_ptr;
270 }
271 err("Attempt to establish second link on <%s> to %s\n",
272 l_ptr->b_ptr->publ.name,
273 tipc_addr_string_fill(addr_string, l_ptr->addr));
274 }
275 return NULL;
276} 246}
277 247
278void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr) 248void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
279{ 249{
280 n_ptr->links[l_ptr->b_ptr->identity] = NULL; 250 n_ptr->links[l_ptr->b_ptr->identity] = NULL;
281 tipc_net.zones[tipc_zone(l_ptr->addr)]->links--; 251 atomic_dec(&tipc_num_links);
282 n_ptr->link_cnt--; 252 n_ptr->link_cnt--;
283} 253}
284 254
@@ -330,48 +300,16 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
330 300
331static void node_established_contact(struct tipc_node *n_ptr) 301static void node_established_contact(struct tipc_node *n_ptr)
332{ 302{
333 struct cluster *c_ptr; 303 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
334
335 dbg("node_established_contact:-> %x\n", n_ptr->addr);
336 if (!tipc_node_has_active_routes(n_ptr) && in_own_cluster(n_ptr->addr)) {
337 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
338 }
339 304
340 /* Syncronize broadcast acks */ 305 /* Syncronize broadcast acks */
341 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 306 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
342 307
343 if (is_slave(tipc_own_addr))
344 return;
345 if (!in_own_cluster(n_ptr->addr)) {
346 /* Usage case 1 (see above) */
347 c_ptr = tipc_cltr_find(tipc_own_addr);
348 if (!c_ptr)
349 c_ptr = tipc_cltr_create(tipc_own_addr);
350 if (c_ptr)
351 tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1,
352 tipc_max_nodes);
353 return;
354 }
355
356 c_ptr = n_ptr->owner;
357 if (is_slave(n_ptr->addr)) {
358 /* Usage case 2 (see above) */
359 tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1, tipc_max_nodes);
360 tipc_cltr_send_local_routes(c_ptr, n_ptr->addr);
361 return;
362 }
363
364 if (n_ptr->bclink.supported) { 308 if (n_ptr->bclink.supported) {
365 tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr); 309 tipc_nmap_add(&tipc_bcast_nmap, n_ptr->addr);
366 if (n_ptr->addr < tipc_own_addr) 310 if (n_ptr->addr < tipc_own_addr)
367 tipc_own_tag++; 311 tipc_own_tag++;
368 } 312 }
369
370 /* Case 3 (see above) */
371 tipc_net_send_external_routes(n_ptr->addr);
372 tipc_cltr_send_slave_routes(c_ptr, n_ptr->addr);
373 tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, LOWEST_SLAVE,
374 tipc_highest_allowed_slave);
375} 313}
376 314
377static void node_cleanup_finished(unsigned long node_addr) 315static void node_cleanup_finished(unsigned long node_addr)
@@ -390,15 +328,13 @@ static void node_cleanup_finished(unsigned long node_addr)
390 328
391static void node_lost_contact(struct tipc_node *n_ptr) 329static void node_lost_contact(struct tipc_node *n_ptr)
392{ 330{
393 struct cluster *c_ptr;
394 struct tipc_node_subscr *ns, *tns;
395 char addr_string[16]; 331 char addr_string[16];
396 u32 i; 332 u32 i;
397 333
398 /* Clean up broadcast reception remains */ 334 /* Clean up broadcast reception remains */
399 n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0; 335 n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;
400 while (n_ptr->bclink.deferred_head) { 336 while (n_ptr->bclink.deferred_head) {
401 struct sk_buff* buf = n_ptr->bclink.deferred_head; 337 struct sk_buff *buf = n_ptr->bclink.deferred_head;
402 n_ptr->bclink.deferred_head = buf->next; 338 n_ptr->bclink.deferred_head = buf->next;
403 buf_discard(buf); 339 buf_discard(buf);
404 } 340 }
@@ -406,41 +342,14 @@ static void node_lost_contact(struct tipc_node *n_ptr)
406 buf_discard(n_ptr->bclink.defragm); 342 buf_discard(n_ptr->bclink.defragm);
407 n_ptr->bclink.defragm = NULL; 343 n_ptr->bclink.defragm = NULL;
408 } 344 }
409 if (in_own_cluster(n_ptr->addr) && n_ptr->bclink.supported) {
410 tipc_bclink_acknowledge(n_ptr, mod(n_ptr->bclink.acked + 10000));
411 }
412 345
413 /* Update routing tables */ 346 if (n_ptr->bclink.supported) {
414 if (is_slave(tipc_own_addr)) { 347 tipc_bclink_acknowledge(n_ptr,
415 tipc_net_remove_as_router(n_ptr->addr); 348 mod(n_ptr->bclink.acked + 10000));
416 } else { 349 tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);
417 if (!in_own_cluster(n_ptr->addr)) { 350 if (n_ptr->addr < tipc_own_addr)
418 /* Case 4 (see above) */ 351 tipc_own_tag--;
419 c_ptr = tipc_cltr_find(tipc_own_addr);
420 tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1,
421 tipc_max_nodes);
422 } else {
423 /* Case 5 (see above) */
424 c_ptr = tipc_cltr_find(n_ptr->addr);
425 if (is_slave(n_ptr->addr)) {
426 tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1,
427 tipc_max_nodes);
428 } else {
429 if (n_ptr->bclink.supported) {
430 tipc_nmap_remove(&tipc_cltr_bcast_nodes,
431 n_ptr->addr);
432 if (n_ptr->addr < tipc_own_addr)
433 tipc_own_tag--;
434 }
435 tipc_net_remove_as_router(n_ptr->addr);
436 tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr,
437 LOWEST_SLAVE,
438 tipc_highest_allowed_slave);
439 }
440 }
441 } 352 }
442 if (tipc_node_has_active_routes(n_ptr))
443 return;
444 353
445 info("Lost contact with %s\n", 354 info("Lost contact with %s\n",
446 tipc_addr_string_fill(addr_string, n_ptr->addr)); 355 tipc_addr_string_fill(addr_string, n_ptr->addr));
@@ -456,12 +365,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
456 } 365 }
457 366
458 /* Notify subscribers */ 367 /* Notify subscribers */
459 list_for_each_entry_safe(ns, tns, &n_ptr->nsub, nodesub_list) { 368 tipc_nodesub_notify(n_ptr);
460 ns->node = NULL;
461 list_del_init(&ns->nodesub_list);
462 tipc_k_signal((Handler)ns->handle_node_down,
463 (unsigned long)ns->usr_handle);
464 }
465 369
466 /* Prevent re-contact with node until all cleanup is done */ 370 /* Prevent re-contact with node until all cleanup is done */
467 371
@@ -469,125 +373,6 @@ static void node_lost_contact(struct tipc_node *n_ptr)
469 tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr); 373 tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);
470} 374}
471 375
472/**
473 * tipc_node_select_next_hop - find the next-hop node for a message
474 *
475 * Called by when cluster local lookup has failed.
476 */
477
478struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector)
479{
480 struct tipc_node *n_ptr;
481 u32 router_addr;
482
483 if (!tipc_addr_domain_valid(addr))
484 return NULL;
485
486 /* Look for direct link to destination processsor */
487 n_ptr = tipc_node_find(addr);
488 if (n_ptr && tipc_node_has_active_links(n_ptr))
489 return n_ptr;
490
491 /* Cluster local system nodes *must* have direct links */
492 if (!is_slave(addr) && in_own_cluster(addr))
493 return NULL;
494
495 /* Look for cluster local router with direct link to node */
496 router_addr = tipc_node_select_router(n_ptr, selector);
497 if (router_addr)
498 return tipc_node_select(router_addr, selector);
499
500 /* Slave nodes can only be accessed within own cluster via a
501 known router with direct link -- if no router was found,give up */
502 if (is_slave(addr))
503 return NULL;
504
505 /* Inter zone/cluster -- find any direct link to remote cluster */
506 addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
507 n_ptr = tipc_net_select_remote_node(addr, selector);
508 if (n_ptr && tipc_node_has_active_links(n_ptr))
509 return n_ptr;
510
511 /* Last resort -- look for any router to anywhere in remote zone */
512 router_addr = tipc_net_select_router(addr, selector);
513 if (router_addr)
514 return tipc_node_select(router_addr, selector);
515
516 return NULL;
517}
518
519/**
520 * tipc_node_select_router - select router to reach specified node
521 *
522 * Uses a deterministic and fair algorithm for selecting router node.
523 */
524
525u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref)
526{
527 u32 ulim;
528 u32 mask;
529 u32 start;
530 u32 r;
531
532 if (!n_ptr)
533 return 0;
534
535 if (n_ptr->last_router < 0)
536 return 0;
537 ulim = ((n_ptr->last_router + 1) * 32) - 1;
538
539 /* Start entry must be random */
540 mask = tipc_max_nodes;
541 while (mask > ulim)
542 mask >>= 1;
543 start = ref & mask;
544 r = start;
545
546 /* Lookup upwards with wrap-around */
547 do {
548 if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1)
549 break;
550 } while (++r <= ulim);
551 if (r > ulim) {
552 r = 1;
553 do {
554 if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1)
555 break;
556 } while (++r < start);
557 assert(r != start);
558 }
559 assert(r && (r <= ulim));
560 return tipc_addr(own_zone(), own_cluster(), r);
561}
562
563void tipc_node_add_router(struct tipc_node *n_ptr, u32 router)
564{
565 u32 r_num = tipc_node(router);
566
567 n_ptr->routers[r_num / 32] =
568 ((1 << (r_num % 32)) | n_ptr->routers[r_num / 32]);
569 n_ptr->last_router = tipc_max_nodes / 32;
570 while ((--n_ptr->last_router >= 0) &&
571 !n_ptr->routers[n_ptr->last_router]);
572}
573
574void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router)
575{
576 u32 r_num = tipc_node(router);
577
578 if (n_ptr->last_router < 0)
579 return; /* No routes */
580
581 n_ptr->routers[r_num / 32] =
582 ((~(1 << (r_num % 32))) & (n_ptr->routers[r_num / 32]));
583 n_ptr->last_router = tipc_max_nodes / 32;
584 while ((--n_ptr->last_router >= 0) &&
585 !n_ptr->routers[n_ptr->last_router]);
586
587 if (!tipc_node_is_up(n_ptr))
588 node_lost_contact(n_ptr);
589}
590
591struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) 376struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
592{ 377{
593 u32 domain; 378 u32 domain;
@@ -605,15 +390,14 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
605 " (network address)"); 390 " (network address)");
606 391
607 read_lock_bh(&tipc_net_lock); 392 read_lock_bh(&tipc_net_lock);
608 if (!tipc_nodes) { 393 if (!tipc_num_nodes) {
609 read_unlock_bh(&tipc_net_lock); 394 read_unlock_bh(&tipc_net_lock);
610 return tipc_cfg_reply_none(); 395 return tipc_cfg_reply_none();
611 } 396 }
612 397
613 /* For now, get space for all other nodes 398 /* For now, get space for all other nodes */
614 (will need to modify this when slave nodes are supported */
615 399
616 payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); 400 payload_size = TLV_SPACE(sizeof(node_info)) * tipc_num_nodes;
617 if (payload_size > 32768u) { 401 if (payload_size > 32768u) {
618 read_unlock_bh(&tipc_net_lock); 402 read_unlock_bh(&tipc_net_lock);
619 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 403 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -627,7 +411,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
627 411
628 /* Add TLVs for all nodes in scope */ 412 /* Add TLVs for all nodes in scope */
629 413
630 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 414 list_for_each_entry(n_ptr, &tipc_node_list, list) {
631 if (!tipc_in_scope(domain, n_ptr->addr)) 415 if (!tipc_in_scope(domain, n_ptr->addr))
632 continue; 416 continue;
633 node_info.addr = htonl(n_ptr->addr); 417 node_info.addr = htonl(n_ptr->addr);
@@ -664,7 +448,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
664 /* Get space for all unicast links + multicast link */ 448 /* Get space for all unicast links + multicast link */
665 449
666 payload_size = TLV_SPACE(sizeof(link_info)) * 450 payload_size = TLV_SPACE(sizeof(link_info)) *
667 (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); 451 (atomic_read(&tipc_num_links) + 1);
668 if (payload_size > 32768u) { 452 if (payload_size > 32768u) {
669 read_unlock_bh(&tipc_net_lock); 453 read_unlock_bh(&tipc_net_lock);
670 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 454 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -678,14 +462,14 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
678 462
679 /* Add TLV for broadcast link */ 463 /* Add TLV for broadcast link */
680 464
681 link_info.dest = htonl(tipc_own_addr & 0xfffff00); 465 link_info.dest = htonl(tipc_cluster_mask(tipc_own_addr));
682 link_info.up = htonl(1); 466 link_info.up = htonl(1);
683 strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME); 467 strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME);
684 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info)); 468 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info));
685 469
686 /* Add TLVs for any other links in scope */ 470 /* Add TLVs for any other links in scope */
687 471
688 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 472 list_for_each_entry(n_ptr, &tipc_node_list, list) {
689 u32 i; 473 u32 i;
690 474
691 if (!tipc_in_scope(domain, n_ptr->addr)) 475 if (!tipc_in_scope(domain, n_ptr->addr))
diff --git a/net/tipc/node.h b/net/tipc/node.h
index fff331b2d26c..5c61afc7a0b9 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -2,7 +2,7 @@
2 * net/tipc/node.h: Include file for TIPC node management routines 2 * net/tipc/node.h: Include file for TIPC node management routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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
@@ -39,15 +39,15 @@
39 39
40#include "node_subscr.h" 40#include "node_subscr.h"
41#include "addr.h" 41#include "addr.h"
42#include "cluster.h" 42#include "net.h"
43#include "bearer.h" 43#include "bearer.h"
44 44
45/** 45/**
46 * struct tipc_node - TIPC node structure 46 * struct tipc_node - TIPC node structure
47 * @addr: network address of node 47 * @addr: network address of node
48 * @lock: spinlock governing access to structure 48 * @lock: spinlock governing access to structure
49 * @owner: pointer to cluster that node belongs to 49 * @hash: links to adjacent nodes in unsorted hash chain
50 * @next: pointer to next node in sorted list of cluster's nodes 50 * @list: links to adjacent nodes in sorted list of cluster's nodes
51 * @nsub: list of "node down" subscriptions monitoring node 51 * @nsub: list of "node down" subscriptions monitoring node
52 * @active_links: pointers to active links to node 52 * @active_links: pointers to active links to node
53 * @links: pointers to all links to node 53 * @links: pointers to all links to node
@@ -55,8 +55,6 @@
55 * @cleanup_required: non-zero if cleaning up after a prior loss of contact 55 * @cleanup_required: non-zero if cleaning up after a prior loss of contact
56 * @link_cnt: number of links to node 56 * @link_cnt: number of links to node
57 * @permit_changeover: non-zero if node has redundant links to this system 57 * @permit_changeover: non-zero if node has redundant links to this system
58 * @routers: bitmap (used for multicluster communication)
59 * @last_router: (used for multicluster communication)
60 * @bclink: broadcast-related info 58 * @bclink: broadcast-related info
61 * @supported: non-zero if node supports TIPC b'cast capability 59 * @supported: non-zero if node supports TIPC b'cast capability
62 * @acked: sequence # of last outbound b'cast message acknowledged by node 60 * @acked: sequence # of last outbound b'cast message acknowledged by node
@@ -72,8 +70,8 @@
72struct tipc_node { 70struct tipc_node {
73 u32 addr; 71 u32 addr;
74 spinlock_t lock; 72 spinlock_t lock;
75 struct cluster *owner; 73 struct hlist_node hash;
76 struct tipc_node *next; 74 struct list_head list;
77 struct list_head nsub; 75 struct list_head nsub;
78 struct link *active_links[2]; 76 struct link *active_links[2];
79 struct link *links[MAX_BEARERS]; 77 struct link *links[MAX_BEARERS];
@@ -81,8 +79,6 @@ struct tipc_node {
81 int working_links; 79 int working_links;
82 int cleanup_required; 80 int cleanup_required;
83 int permit_changeover; 81 int permit_changeover;
84 u32 routers[512/32];
85 int last_router;
86 struct { 82 struct {
87 int supported; 83 int supported;
88 u32 acked; 84 u32 acked;
@@ -96,44 +92,35 @@ struct tipc_node {
96 } bclink; 92 } bclink;
97}; 93};
98 94
95#define NODE_HTABLE_SIZE 512
96extern struct list_head tipc_node_list;
97
98/*
99 * A trivial power-of-two bitmask technique is used for speed, since this
100 * operation is done for every incoming TIPC packet. The number of hash table
101 * entries has been chosen so that no hash chain exceeds 8 nodes and will
102 * usually be much smaller (typically only a single node).
103 */
104static inline unsigned int tipc_hashfn(u32 addr)
105{
106 return addr & (NODE_HTABLE_SIZE - 1);
107}
108
99extern u32 tipc_own_tag; 109extern u32 tipc_own_tag;
100 110
111struct tipc_node *tipc_node_find(u32 addr);
101struct tipc_node *tipc_node_create(u32 addr); 112struct tipc_node *tipc_node_create(u32 addr);
102void tipc_node_delete(struct tipc_node *n_ptr); 113void tipc_node_delete(struct tipc_node *n_ptr);
103struct tipc_node *tipc_node_attach_link(struct link *l_ptr); 114void tipc_node_attach_link(struct tipc_node *n_ptr, struct link *l_ptr);
104void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr); 115void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr);
105void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr); 116void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr);
106void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr); 117void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr);
107int tipc_node_has_active_links(struct tipc_node *n_ptr); 118int tipc_node_active_links(struct tipc_node *n_ptr);
108int tipc_node_has_redundant_links(struct tipc_node *n_ptr); 119int tipc_node_redundant_links(struct tipc_node *n_ptr);
109u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref);
110struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector);
111int tipc_node_is_up(struct tipc_node *n_ptr); 120int tipc_node_is_up(struct tipc_node *n_ptr);
112void tipc_node_add_router(struct tipc_node *n_ptr, u32 router);
113void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router);
114struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space); 121struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
115struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space); 122struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
116 123
117static inline struct tipc_node *tipc_node_find(u32 addr)
118{
119 if (likely(in_own_cluster(addr)))
120 return tipc_local_nodes[tipc_node(addr)];
121 else if (tipc_addr_domain_valid(addr)) {
122 struct cluster *c_ptr = tipc_cltr_find(addr);
123
124 if (c_ptr)
125 return c_ptr->nodes[tipc_node(addr)];
126 }
127 return NULL;
128}
129
130static inline struct tipc_node *tipc_node_select(u32 addr, u32 selector)
131{
132 if (likely(in_own_cluster(addr)))
133 return tipc_local_nodes[tipc_node(addr)];
134 return tipc_node_select_next_hop(addr, selector);
135}
136
137static inline void tipc_node_lock(struct tipc_node *n_ptr) 124static inline void tipc_node_lock(struct tipc_node *n_ptr)
138{ 125{
139 spin_lock_bh(&n_ptr->lock); 126 spin_lock_bh(&n_ptr->lock);
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 19194d476a9e..c3c2815ae630 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -2,7 +2,7 @@
2 * net/tipc/node_subscr.c: TIPC "node down" subscription handling 2 * net/tipc/node_subscr.c: TIPC "node down" subscription handling
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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
@@ -35,10 +35,8 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "node_subscr.h" 38#include "node_subscr.h"
40#include "node.h" 39#include "node.h"
41#include "addr.h"
42 40
43/** 41/**
44 * tipc_nodesub_subscribe - create "node down" subscription for specified node 42 * tipc_nodesub_subscribe - create "node down" subscription for specified node
@@ -78,3 +76,22 @@ void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub)
78 list_del_init(&node_sub->nodesub_list); 76 list_del_init(&node_sub->nodesub_list);
79 tipc_node_unlock(node_sub->node); 77 tipc_node_unlock(node_sub->node);
80} 78}
79
80/**
81 * tipc_nodesub_notify - notify subscribers that a node is unreachable
82 *
83 * Note: node is locked by caller
84 */
85
86void tipc_nodesub_notify(struct tipc_node *node)
87{
88 struct tipc_node_subscr *ns;
89
90 list_for_each_entry(ns, &node->nsub, nodesub_list) {
91 if (ns->handle_node_down) {
92 tipc_k_signal((Handler)ns->handle_node_down,
93 (unsigned long)ns->usr_handle);
94 ns->handle_node_down = NULL;
95 }
96 }
97}
diff --git a/net/tipc/node_subscr.h b/net/tipc/node_subscr.h
index 006ed739f515..4bc2ca0867a1 100644
--- a/net/tipc/node_subscr.h
+++ b/net/tipc/node_subscr.h
@@ -2,7 +2,7 @@
2 * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling 2 * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-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
@@ -59,5 +59,6 @@ struct tipc_node_subscr {
59void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr, 59void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
60 void *usr_handle, net_ev_handler handle_down); 60 void *usr_handle, net_ev_handler handle_down);
61void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub); 61void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub);
62void tipc_nodesub_notify(struct tipc_node *node);
62 63
63#endif 64#endif
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 82092eaa1536..6ff78f9c7d65 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -2,7 +2,7 @@
2 * net/tipc/port.c: TIPC port code 2 * net/tipc/port.c: TIPC port code
3 * 3 *
4 * Copyright (c) 1992-2007, Ericsson AB 4 * Copyright (c) 1992-2007, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-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
@@ -36,15 +36,8 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "config.h"
39#include "dbg.h"
40#include "port.h" 39#include "port.h"
41#include "addr.h"
42#include "link.h"
43#include "node.h"
44#include "name_table.h" 40#include "name_table.h"
45#include "user_reg.h"
46#include "msg.h"
47#include "bcast.h"
48 41
49/* Connection management: */ 42/* Connection management: */
50#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ 43#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */
@@ -53,55 +46,41 @@
53 46
54#define MAX_REJECT_SIZE 1024 47#define MAX_REJECT_SIZE 1024
55 48
56static struct sk_buff *msg_queue_head = NULL; 49static struct sk_buff *msg_queue_head;
57static struct sk_buff *msg_queue_tail = NULL; 50static struct sk_buff *msg_queue_tail;
58 51
59DEFINE_SPINLOCK(tipc_port_list_lock); 52DEFINE_SPINLOCK(tipc_port_list_lock);
60static DEFINE_SPINLOCK(queue_lock); 53static DEFINE_SPINLOCK(queue_lock);
61 54
62static LIST_HEAD(ports); 55static LIST_HEAD(ports);
63static void port_handle_node_down(unsigned long ref); 56static void port_handle_node_down(unsigned long ref);
64static struct sk_buff* port_build_self_abort_msg(struct port *,u32 err); 57static struct sk_buff *port_build_self_abort_msg(struct tipc_port *, u32 err);
65static struct sk_buff* port_build_peer_abort_msg(struct port *,u32 err); 58static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *, u32 err);
66static void port_timeout(unsigned long ref); 59static void port_timeout(unsigned long ref);
67 60
68 61
69static u32 port_peernode(struct port *p_ptr) 62static u32 port_peernode(struct tipc_port *p_ptr)
70{ 63{
71 return msg_destnode(&p_ptr->publ.phdr); 64 return msg_destnode(&p_ptr->phdr);
72} 65}
73 66
74static u32 port_peerport(struct port *p_ptr) 67static u32 port_peerport(struct tipc_port *p_ptr)
75{ 68{
76 return msg_destport(&p_ptr->publ.phdr); 69 return msg_destport(&p_ptr->phdr);
77}
78
79static u32 port_out_seqno(struct port *p_ptr)
80{
81 return msg_transp_seqno(&p_ptr->publ.phdr);
82}
83
84static void port_incr_out_seqno(struct port *p_ptr)
85{
86 struct tipc_msg *m = &p_ptr->publ.phdr;
87
88 if (likely(!msg_routed(m)))
89 return;
90 msg_set_transp_seqno(m, (msg_transp_seqno(m) + 1));
91} 70}
92 71
93/** 72/**
94 * tipc_multicast - send a multicast message to local and remote destinations 73 * tipc_multicast - send a multicast message to local and remote destinations
95 */ 74 */
96 75
97int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain, 76int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
98 u32 num_sect, struct iovec const *msg_sect) 77 u32 num_sect, struct iovec const *msg_sect)
99{ 78{
100 struct tipc_msg *hdr; 79 struct tipc_msg *hdr;
101 struct sk_buff *buf; 80 struct sk_buff *buf;
102 struct sk_buff *ibuf = NULL; 81 struct sk_buff *ibuf = NULL;
103 struct port_list dports = {0, NULL, }; 82 struct port_list dports = {0, NULL, };
104 struct port *oport = tipc_port_deref(ref); 83 struct tipc_port *oport = tipc_port_deref(ref);
105 int ext_targets; 84 int ext_targets;
106 int res; 85 int res;
107 86
@@ -110,7 +89,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
110 89
111 /* Create multicast message */ 90 /* Create multicast message */
112 91
113 hdr = &oport->publ.phdr; 92 hdr = &oport->phdr;
114 msg_set_type(hdr, TIPC_MCAST_MSG); 93 msg_set_type(hdr, TIPC_MCAST_MSG);
115 msg_set_nametype(hdr, seq->type); 94 msg_set_nametype(hdr, seq->type);
116 msg_set_namelower(hdr, seq->lower); 95 msg_set_namelower(hdr, seq->lower);
@@ -138,9 +117,8 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
138 } 117 }
139 } 118 }
140 res = tipc_bclink_send_msg(buf); 119 res = tipc_bclink_send_msg(buf);
141 if ((res < 0) && (dports.count != 0)) { 120 if ((res < 0) && (dports.count != 0))
142 buf_discard(ibuf); 121 buf_discard(ibuf);
143 }
144 } else { 122 } else {
145 ibuf = buf; 123 ibuf = buf;
146 } 124 }
@@ -162,7 +140,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
162 140
163void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) 141void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
164{ 142{
165 struct tipc_msg* msg; 143 struct tipc_msg *msg;
166 struct port_list dports = {0, NULL, }; 144 struct port_list dports = {0, NULL, };
167 struct port_list *item = dp; 145 struct port_list *item = dp;
168 int cnt = 0; 146 int cnt = 0;
@@ -195,13 +173,11 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
195 173
196 if (b == NULL) { 174 if (b == NULL) {
197 warn("Unable to deliver multicast message(s)\n"); 175 warn("Unable to deliver multicast message(s)\n");
198 msg_dbg(msg, "LOST:");
199 goto exit; 176 goto exit;
200 } 177 }
201 if ((index == 0) && (cnt != 0)) { 178 if ((index == 0) && (cnt != 0))
202 item = item->next; 179 item = item->next;
203 } 180 msg_set_destport(buf_msg(b), item->ports[index]);
204 msg_set_destport(buf_msg(b),item->ports[index]);
205 tipc_port_recv_msg(b); 181 tipc_port_recv_msg(b);
206 } 182 }
207 } 183 }
@@ -221,7 +197,7 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
221 void (*wakeup)(struct tipc_port *), 197 void (*wakeup)(struct tipc_port *),
222 const u32 importance) 198 const u32 importance)
223{ 199{
224 struct port *p_ptr; 200 struct tipc_port *p_ptr;
225 struct tipc_msg *msg; 201 struct tipc_msg *msg;
226 u32 ref; 202 u32 ref;
227 203
@@ -230,21 +206,19 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
230 warn("Port creation failed, no memory\n"); 206 warn("Port creation failed, no memory\n");
231 return NULL; 207 return NULL;
232 } 208 }
233 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); 209 ref = tipc_ref_acquire(p_ptr, &p_ptr->lock);
234 if (!ref) { 210 if (!ref) {
235 warn("Port creation failed, reference table exhausted\n"); 211 warn("Port creation failed, reference table exhausted\n");
236 kfree(p_ptr); 212 kfree(p_ptr);
237 return NULL; 213 return NULL;
238 } 214 }
239 215
240 p_ptr->publ.usr_handle = usr_handle; 216 p_ptr->usr_handle = usr_handle;
241 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 217 p_ptr->max_pkt = MAX_PKT_DEFAULT;
242 p_ptr->publ.ref = ref; 218 p_ptr->ref = ref;
243 msg = &p_ptr->publ.phdr; 219 msg = &p_ptr->phdr;
244 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); 220 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
245 msg_set_origport(msg, ref); 221 msg_set_origport(msg, ref);
246 p_ptr->last_in_seqno = 41;
247 p_ptr->sent = 1;
248 INIT_LIST_HEAD(&p_ptr->wait_list); 222 INIT_LIST_HEAD(&p_ptr->wait_list);
249 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 223 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
250 p_ptr->dispatcher = dispatcher; 224 p_ptr->dispatcher = dispatcher;
@@ -256,12 +230,12 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
256 INIT_LIST_HEAD(&p_ptr->port_list); 230 INIT_LIST_HEAD(&p_ptr->port_list);
257 list_add_tail(&p_ptr->port_list, &ports); 231 list_add_tail(&p_ptr->port_list, &ports);
258 spin_unlock_bh(&tipc_port_list_lock); 232 spin_unlock_bh(&tipc_port_list_lock);
259 return &(p_ptr->publ); 233 return p_ptr;
260} 234}
261 235
262int tipc_deleteport(u32 ref) 236int tipc_deleteport(u32 ref)
263{ 237{
264 struct port *p_ptr; 238 struct tipc_port *p_ptr;
265 struct sk_buff *buf = NULL; 239 struct sk_buff *buf = NULL;
266 240
267 tipc_withdraw(ref, 0, NULL); 241 tipc_withdraw(ref, 0, NULL);
@@ -273,14 +247,11 @@ int tipc_deleteport(u32 ref)
273 tipc_port_unlock(p_ptr); 247 tipc_port_unlock(p_ptr);
274 248
275 k_cancel_timer(&p_ptr->timer); 249 k_cancel_timer(&p_ptr->timer);
276 if (p_ptr->publ.connected) { 250 if (p_ptr->connected) {
277 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 251 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
278 tipc_nodesub_unsubscribe(&p_ptr->subscription); 252 tipc_nodesub_unsubscribe(&p_ptr->subscription);
279 } 253 }
280 if (p_ptr->user_port) { 254 kfree(p_ptr->user_port);
281 tipc_reg_remove_port(p_ptr->user_port);
282 kfree(p_ptr->user_port);
283 }
284 255
285 spin_lock_bh(&tipc_port_list_lock); 256 spin_lock_bh(&tipc_port_list_lock);
286 list_del(&p_ptr->port_list); 257 list_del(&p_ptr->port_list);
@@ -288,19 +259,18 @@ int tipc_deleteport(u32 ref)
288 spin_unlock_bh(&tipc_port_list_lock); 259 spin_unlock_bh(&tipc_port_list_lock);
289 k_term_timer(&p_ptr->timer); 260 k_term_timer(&p_ptr->timer);
290 kfree(p_ptr); 261 kfree(p_ptr);
291 dbg("Deleted port %u\n", ref);
292 tipc_net_route_msg(buf); 262 tipc_net_route_msg(buf);
293 return 0; 263 return 0;
294} 264}
295 265
296static int port_unreliable(struct port *p_ptr) 266static int port_unreliable(struct tipc_port *p_ptr)
297{ 267{
298 return msg_src_droppable(&p_ptr->publ.phdr); 268 return msg_src_droppable(&p_ptr->phdr);
299} 269}
300 270
301int tipc_portunreliable(u32 ref, unsigned int *isunreliable) 271int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
302{ 272{
303 struct port *p_ptr; 273 struct tipc_port *p_ptr;
304 274
305 p_ptr = tipc_port_lock(ref); 275 p_ptr = tipc_port_lock(ref);
306 if (!p_ptr) 276 if (!p_ptr)
@@ -312,24 +282,24 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
312 282
313int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) 283int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
314{ 284{
315 struct port *p_ptr; 285 struct tipc_port *p_ptr;
316 286
317 p_ptr = tipc_port_lock(ref); 287 p_ptr = tipc_port_lock(ref);
318 if (!p_ptr) 288 if (!p_ptr)
319 return -EINVAL; 289 return -EINVAL;
320 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); 290 msg_set_src_droppable(&p_ptr->phdr, (isunreliable != 0));
321 tipc_port_unlock(p_ptr); 291 tipc_port_unlock(p_ptr);
322 return 0; 292 return 0;
323} 293}
324 294
325static int port_unreturnable(struct port *p_ptr) 295static int port_unreturnable(struct tipc_port *p_ptr)
326{ 296{
327 return msg_dest_droppable(&p_ptr->publ.phdr); 297 return msg_dest_droppable(&p_ptr->phdr);
328} 298}
329 299
330int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) 300int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
331{ 301{
332 struct port *p_ptr; 302 struct tipc_port *p_ptr;
333 303
334 p_ptr = tipc_port_lock(ref); 304 p_ptr = tipc_port_lock(ref);
335 if (!p_ptr) 305 if (!p_ptr)
@@ -341,12 +311,12 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
341 311
342int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) 312int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
343{ 313{
344 struct port *p_ptr; 314 struct tipc_port *p_ptr;
345 315
346 p_ptr = tipc_port_lock(ref); 316 p_ptr = tipc_port_lock(ref);
347 if (!p_ptr) 317 if (!p_ptr)
348 return -EINVAL; 318 return -EINVAL;
349 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); 319 msg_set_dest_droppable(&p_ptr->phdr, (isunrejectable != 0));
350 tipc_port_unlock(p_ptr); 320 tipc_port_unlock(p_ptr);
351 return 0; 321 return 0;
352} 322}
@@ -359,7 +329,7 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
359static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, 329static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
360 u32 origport, u32 orignode, 330 u32 origport, u32 orignode,
361 u32 usr, u32 type, u32 err, 331 u32 usr, u32 type, u32 err,
362 u32 seqno, u32 ack) 332 u32 ack)
363{ 333{
364 struct sk_buff *buf; 334 struct sk_buff *buf;
365 struct tipc_msg *msg; 335 struct tipc_msg *msg;
@@ -372,9 +342,7 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
372 msg_set_destport(msg, destport); 342 msg_set_destport(msg, destport);
373 msg_set_origport(msg, origport); 343 msg_set_origport(msg, origport);
374 msg_set_orignode(msg, orignode); 344 msg_set_orignode(msg, orignode);
375 msg_set_transp_seqno(msg, seqno);
376 msg_set_msgcnt(msg, ack); 345 msg_set_msgcnt(msg, ack);
377 msg_dbg(msg, "PORT>SEND>:");
378 } 346 }
379 return buf; 347 return buf;
380} 348}
@@ -392,7 +360,6 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
392 data_sz = MAX_REJECT_SIZE; 360 data_sz = MAX_REJECT_SIZE;
393 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE)) 361 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE))
394 imp++; 362 imp++;
395 msg_dbg(msg, "port->rej: ");
396 363
397 /* discard rejected message if it shouldn't be returned to sender */ 364 /* discard rejected message if it shouldn't be returned to sender */
398 if (msg_errcode(msg) || msg_dest_droppable(msg)) { 365 if (msg_errcode(msg) || msg_dest_droppable(msg)) {
@@ -429,10 +396,10 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
429 /* send self-abort message when rejecting on a connected port */ 396 /* send self-abort message when rejecting on a connected port */
430 if (msg_connected(msg)) { 397 if (msg_connected(msg)) {
431 struct sk_buff *abuf = NULL; 398 struct sk_buff *abuf = NULL;
432 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 399 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
433 400
434 if (p_ptr) { 401 if (p_ptr) {
435 if (p_ptr->publ.connected) 402 if (p_ptr->connected)
436 abuf = port_build_self_abort_msg(p_ptr, err); 403 abuf = port_build_self_abort_msg(p_ptr, err);
437 tipc_port_unlock(p_ptr); 404 tipc_port_unlock(p_ptr);
438 } 405 }
@@ -445,7 +412,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
445 return data_sz; 412 return data_sz;
446} 413}
447 414
448int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 415int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
449 struct iovec const *msg_sect, u32 num_sect, 416 struct iovec const *msg_sect, u32 num_sect,
450 int err) 417 int err)
451{ 418{
@@ -462,13 +429,13 @@ int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
462 429
463static void port_timeout(unsigned long ref) 430static void port_timeout(unsigned long ref)
464{ 431{
465 struct port *p_ptr = tipc_port_lock(ref); 432 struct tipc_port *p_ptr = tipc_port_lock(ref);
466 struct sk_buff *buf = NULL; 433 struct sk_buff *buf = NULL;
467 434
468 if (!p_ptr) 435 if (!p_ptr)
469 return; 436 return;
470 437
471 if (!p_ptr->publ.connected) { 438 if (!p_ptr->connected) {
472 tipc_port_unlock(p_ptr); 439 tipc_port_unlock(p_ptr);
473 return; 440 return;
474 } 441 }
@@ -479,14 +446,12 @@ static void port_timeout(unsigned long ref)
479 } else { 446 } else {
480 buf = port_build_proto_msg(port_peerport(p_ptr), 447 buf = port_build_proto_msg(port_peerport(p_ptr),
481 port_peernode(p_ptr), 448 port_peernode(p_ptr),
482 p_ptr->publ.ref, 449 p_ptr->ref,
483 tipc_own_addr, 450 tipc_own_addr,
484 CONN_MANAGER, 451 CONN_MANAGER,
485 CONN_PROBE, 452 CONN_PROBE,
486 TIPC_OK, 453 TIPC_OK,
487 port_out_seqno(p_ptr),
488 0); 454 0);
489 port_incr_out_seqno(p_ptr);
490 p_ptr->probing_state = PROBING; 455 p_ptr->probing_state = PROBING;
491 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 456 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
492 } 457 }
@@ -497,8 +462,8 @@ static void port_timeout(unsigned long ref)
497 462
498static void port_handle_node_down(unsigned long ref) 463static void port_handle_node_down(unsigned long ref)
499{ 464{
500 struct port *p_ptr = tipc_port_lock(ref); 465 struct tipc_port *p_ptr = tipc_port_lock(ref);
501 struct sk_buff* buf = NULL; 466 struct sk_buff *buf = NULL;
502 467
503 if (!p_ptr) 468 if (!p_ptr)
504 return; 469 return;
@@ -508,75 +473,71 @@ static void port_handle_node_down(unsigned long ref)
508} 473}
509 474
510 475
511static struct sk_buff *port_build_self_abort_msg(struct port *p_ptr, u32 err) 476static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
512{ 477{
513 u32 imp = msg_importance(&p_ptr->publ.phdr); 478 u32 imp = msg_importance(&p_ptr->phdr);
514 479
515 if (!p_ptr->publ.connected) 480 if (!p_ptr->connected)
516 return NULL; 481 return NULL;
517 if (imp < TIPC_CRITICAL_IMPORTANCE) 482 if (imp < TIPC_CRITICAL_IMPORTANCE)
518 imp++; 483 imp++;
519 return port_build_proto_msg(p_ptr->publ.ref, 484 return port_build_proto_msg(p_ptr->ref,
520 tipc_own_addr, 485 tipc_own_addr,
521 port_peerport(p_ptr), 486 port_peerport(p_ptr),
522 port_peernode(p_ptr), 487 port_peernode(p_ptr),
523 imp, 488 imp,
524 TIPC_CONN_MSG, 489 TIPC_CONN_MSG,
525 err, 490 err,
526 p_ptr->last_in_seqno + 1,
527 0); 491 0);
528} 492}
529 493
530 494
531static struct sk_buff *port_build_peer_abort_msg(struct port *p_ptr, u32 err) 495static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
532{ 496{
533 u32 imp = msg_importance(&p_ptr->publ.phdr); 497 u32 imp = msg_importance(&p_ptr->phdr);
534 498
535 if (!p_ptr->publ.connected) 499 if (!p_ptr->connected)
536 return NULL; 500 return NULL;
537 if (imp < TIPC_CRITICAL_IMPORTANCE) 501 if (imp < TIPC_CRITICAL_IMPORTANCE)
538 imp++; 502 imp++;
539 return port_build_proto_msg(port_peerport(p_ptr), 503 return port_build_proto_msg(port_peerport(p_ptr),
540 port_peernode(p_ptr), 504 port_peernode(p_ptr),
541 p_ptr->publ.ref, 505 p_ptr->ref,
542 tipc_own_addr, 506 tipc_own_addr,
543 imp, 507 imp,
544 TIPC_CONN_MSG, 508 TIPC_CONN_MSG,
545 err, 509 err,
546 port_out_seqno(p_ptr),
547 0); 510 0);
548} 511}
549 512
550void tipc_port_recv_proto_msg(struct sk_buff *buf) 513void tipc_port_recv_proto_msg(struct sk_buff *buf)
551{ 514{
552 struct tipc_msg *msg = buf_msg(buf); 515 struct tipc_msg *msg = buf_msg(buf);
553 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 516 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
554 u32 err = TIPC_OK; 517 u32 err = TIPC_OK;
555 struct sk_buff *r_buf = NULL; 518 struct sk_buff *r_buf = NULL;
556 struct sk_buff *abort_buf = NULL; 519 struct sk_buff *abort_buf = NULL;
557 520
558 msg_dbg(msg, "PORT<RECV<:");
559
560 if (!p_ptr) { 521 if (!p_ptr) {
561 err = TIPC_ERR_NO_PORT; 522 err = TIPC_ERR_NO_PORT;
562 } else if (p_ptr->publ.connected) { 523 } else if (p_ptr->connected) {
563 if ((port_peernode(p_ptr) != msg_orignode(msg)) || 524 if ((port_peernode(p_ptr) != msg_orignode(msg)) ||
564 (port_peerport(p_ptr) != msg_origport(msg))) { 525 (port_peerport(p_ptr) != msg_origport(msg))) {
565 err = TIPC_ERR_NO_PORT; 526 err = TIPC_ERR_NO_PORT;
566 } else if (msg_type(msg) == CONN_ACK) { 527 } else if (msg_type(msg) == CONN_ACK) {
567 int wakeup = tipc_port_congested(p_ptr) && 528 int wakeup = tipc_port_congested(p_ptr) &&
568 p_ptr->publ.congested && 529 p_ptr->congested &&
569 p_ptr->wakeup; 530 p_ptr->wakeup;
570 p_ptr->acked += msg_msgcnt(msg); 531 p_ptr->acked += msg_msgcnt(msg);
571 if (tipc_port_congested(p_ptr)) 532 if (tipc_port_congested(p_ptr))
572 goto exit; 533 goto exit;
573 p_ptr->publ.congested = 0; 534 p_ptr->congested = 0;
574 if (!wakeup) 535 if (!wakeup)
575 goto exit; 536 goto exit;
576 p_ptr->wakeup(&p_ptr->publ); 537 p_ptr->wakeup(p_ptr);
577 goto exit; 538 goto exit;
578 } 539 }
579 } else if (p_ptr->publ.published) { 540 } else if (p_ptr->published) {
580 err = TIPC_ERR_NO_PORT; 541 err = TIPC_ERR_NO_PORT;
581 } 542 }
582 if (err) { 543 if (err) {
@@ -587,7 +548,6 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
587 TIPC_HIGH_IMPORTANCE, 548 TIPC_HIGH_IMPORTANCE,
588 TIPC_CONN_MSG, 549 TIPC_CONN_MSG,
589 err, 550 err,
590 0,
591 0); 551 0);
592 goto exit; 552 goto exit;
593 } 553 }
@@ -601,11 +561,9 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
601 CONN_MANAGER, 561 CONN_MANAGER,
602 CONN_PROBE_REPLY, 562 CONN_PROBE_REPLY,
603 TIPC_OK, 563 TIPC_OK,
604 port_out_seqno(p_ptr),
605 0); 564 0);
606 } 565 }
607 p_ptr->probing_state = CONFIRMED; 566 p_ptr->probing_state = CONFIRMED;
608 port_incr_out_seqno(p_ptr);
609exit: 567exit:
610 if (p_ptr) 568 if (p_ptr)
611 tipc_port_unlock(p_ptr); 569 tipc_port_unlock(p_ptr);
@@ -614,30 +572,29 @@ exit:
614 buf_discard(buf); 572 buf_discard(buf);
615} 573}
616 574
617static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id) 575static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id)
618{ 576{
619 struct publication *publ; 577 struct publication *publ;
620 578
621 if (full_id) 579 if (full_id)
622 tipc_printf(buf, "<%u.%u.%u:%u>:", 580 tipc_printf(buf, "<%u.%u.%u:%u>:",
623 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 581 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
624 tipc_node(tipc_own_addr), p_ptr->publ.ref); 582 tipc_node(tipc_own_addr), p_ptr->ref);
625 else 583 else
626 tipc_printf(buf, "%-10u:", p_ptr->publ.ref); 584 tipc_printf(buf, "%-10u:", p_ptr->ref);
627 585
628 if (p_ptr->publ.connected) { 586 if (p_ptr->connected) {
629 u32 dport = port_peerport(p_ptr); 587 u32 dport = port_peerport(p_ptr);
630 u32 destnode = port_peernode(p_ptr); 588 u32 destnode = port_peernode(p_ptr);
631 589
632 tipc_printf(buf, " connected to <%u.%u.%u:%u>", 590 tipc_printf(buf, " connected to <%u.%u.%u:%u>",
633 tipc_zone(destnode), tipc_cluster(destnode), 591 tipc_zone(destnode), tipc_cluster(destnode),
634 tipc_node(destnode), dport); 592 tipc_node(destnode), dport);
635 if (p_ptr->publ.conn_type != 0) 593 if (p_ptr->conn_type != 0)
636 tipc_printf(buf, " via {%u,%u}", 594 tipc_printf(buf, " via {%u,%u}",
637 p_ptr->publ.conn_type, 595 p_ptr->conn_type,
638 p_ptr->publ.conn_instance); 596 p_ptr->conn_instance);
639 } 597 } else if (p_ptr->published) {
640 else if (p_ptr->publ.published) {
641 tipc_printf(buf, " bound to"); 598 tipc_printf(buf, " bound to");
642 list_for_each_entry(publ, &p_ptr->publications, pport_list) { 599 list_for_each_entry(publ, &p_ptr->publications, pport_list) {
643 if (publ->lower == publ->upper) 600 if (publ->lower == publ->upper)
@@ -658,7 +615,7 @@ struct sk_buff *tipc_port_get_ports(void)
658 struct sk_buff *buf; 615 struct sk_buff *buf;
659 struct tlv_desc *rep_tlv; 616 struct tlv_desc *rep_tlv;
660 struct print_buf pb; 617 struct print_buf pb;
661 struct port *p_ptr; 618 struct tipc_port *p_ptr;
662 int str_len; 619 int str_len;
663 620
664 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY)); 621 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY));
@@ -669,9 +626,9 @@ struct sk_buff *tipc_port_get_ports(void)
669 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY); 626 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY);
670 spin_lock_bh(&tipc_port_list_lock); 627 spin_lock_bh(&tipc_port_list_lock);
671 list_for_each_entry(p_ptr, &ports, port_list) { 628 list_for_each_entry(p_ptr, &ports, port_list) {
672 spin_lock_bh(p_ptr->publ.lock); 629 spin_lock_bh(p_ptr->lock);
673 port_print(p_ptr, &pb, 0); 630 port_print(p_ptr, &pb, 0);
674 spin_unlock_bh(p_ptr->publ.lock); 631 spin_unlock_bh(p_ptr->lock);
675 } 632 }
676 spin_unlock_bh(&tipc_port_list_lock); 633 spin_unlock_bh(&tipc_port_list_lock);
677 str_len = tipc_printbuf_validate(&pb); 634 str_len = tipc_printbuf_validate(&pb);
@@ -684,12 +641,12 @@ struct sk_buff *tipc_port_get_ports(void)
684 641
685void tipc_port_reinit(void) 642void tipc_port_reinit(void)
686{ 643{
687 struct port *p_ptr; 644 struct tipc_port *p_ptr;
688 struct tipc_msg *msg; 645 struct tipc_msg *msg;
689 646
690 spin_lock_bh(&tipc_port_list_lock); 647 spin_lock_bh(&tipc_port_list_lock);
691 list_for_each_entry(p_ptr, &ports, port_list) { 648 list_for_each_entry(p_ptr, &ports, port_list) {
692 msg = &p_ptr->publ.phdr; 649 msg = &p_ptr->phdr;
693 if (msg_orignode(msg) == tipc_own_addr) 650 if (msg_orignode(msg) == tipc_own_addr)
694 break; 651 break;
695 msg_set_prevnode(msg, tipc_own_addr); 652 msg_set_prevnode(msg, tipc_own_addr);
@@ -714,7 +671,7 @@ static void port_dispatcher_sigh(void *dummy)
714 spin_unlock_bh(&queue_lock); 671 spin_unlock_bh(&queue_lock);
715 672
716 while (buf) { 673 while (buf) {
717 struct port *p_ptr; 674 struct tipc_port *p_ptr;
718 struct user_port *up_ptr; 675 struct user_port *up_ptr;
719 struct tipc_portid orig; 676 struct tipc_portid orig;
720 struct tipc_name_seq dseq; 677 struct tipc_name_seq dseq;
@@ -739,8 +696,8 @@ static void port_dispatcher_sigh(void *dummy)
739 orig.node = msg_orignode(msg); 696 orig.node = msg_orignode(msg);
740 up_ptr = p_ptr->user_port; 697 up_ptr = p_ptr->user_port;
741 usr_handle = up_ptr->usr_handle; 698 usr_handle = up_ptr->usr_handle;
742 connected = p_ptr->publ.connected; 699 connected = p_ptr->connected;
743 published = p_ptr->publ.published; 700 published = p_ptr->published;
744 701
745 if (unlikely(msg_errcode(msg))) 702 if (unlikely(msg_errcode(msg)))
746 goto err; 703 goto err;
@@ -751,6 +708,7 @@ static void port_dispatcher_sigh(void *dummy)
751 tipc_conn_msg_event cb = up_ptr->conn_msg_cb; 708 tipc_conn_msg_event cb = up_ptr->conn_msg_cb;
752 u32 peer_port = port_peerport(p_ptr); 709 u32 peer_port = port_peerport(p_ptr);
753 u32 peer_node = port_peernode(p_ptr); 710 u32 peer_node = port_peernode(p_ptr);
711 u32 dsz;
754 712
755 tipc_port_unlock(p_ptr); 713 tipc_port_unlock(p_ptr);
756 if (unlikely(!cb)) 714 if (unlikely(!cb))
@@ -761,13 +719,14 @@ static void port_dispatcher_sigh(void *dummy)
761 } else if ((msg_origport(msg) != peer_port) || 719 } else if ((msg_origport(msg) != peer_port) ||
762 (msg_orignode(msg) != peer_node)) 720 (msg_orignode(msg) != peer_node))
763 goto reject; 721 goto reject;
764 if (unlikely(++p_ptr->publ.conn_unacked >= 722 dsz = msg_data_sz(msg);
765 TIPC_FLOW_CONTROL_WIN)) 723 if (unlikely(dsz &&
724 (++p_ptr->conn_unacked >=
725 TIPC_FLOW_CONTROL_WIN)))
766 tipc_acknowledge(dref, 726 tipc_acknowledge(dref,
767 p_ptr->publ.conn_unacked); 727 p_ptr->conn_unacked);
768 skb_pull(buf, msg_hdr_sz(msg)); 728 skb_pull(buf, msg_hdr_sz(msg));
769 cb(usr_handle, dref, &buf, msg_data(msg), 729 cb(usr_handle, dref, &buf, msg_data(msg), dsz);
770 msg_data_sz(msg));
771 break; 730 break;
772 } 731 }
773 case TIPC_DIRECT_MSG:{ 732 case TIPC_DIRECT_MSG:{
@@ -891,7 +850,7 @@ static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf)
891 850
892static void port_wakeup_sh(unsigned long ref) 851static void port_wakeup_sh(unsigned long ref)
893{ 852{
894 struct port *p_ptr; 853 struct tipc_port *p_ptr;
895 struct user_port *up_ptr; 854 struct user_port *up_ptr;
896 tipc_continue_event cb = NULL; 855 tipc_continue_event cb = NULL;
897 void *uh = NULL; 856 void *uh = NULL;
@@ -917,14 +876,14 @@ static void port_wakeup(struct tipc_port *p_ptr)
917 876
918void tipc_acknowledge(u32 ref, u32 ack) 877void tipc_acknowledge(u32 ref, u32 ack)
919{ 878{
920 struct port *p_ptr; 879 struct tipc_port *p_ptr;
921 struct sk_buff *buf = NULL; 880 struct sk_buff *buf = NULL;
922 881
923 p_ptr = tipc_port_lock(ref); 882 p_ptr = tipc_port_lock(ref);
924 if (!p_ptr) 883 if (!p_ptr)
925 return; 884 return;
926 if (p_ptr->publ.connected) { 885 if (p_ptr->connected) {
927 p_ptr->publ.conn_unacked -= ack; 886 p_ptr->conn_unacked -= ack;
928 buf = port_build_proto_msg(port_peerport(p_ptr), 887 buf = port_build_proto_msg(port_peerport(p_ptr),
929 port_peernode(p_ptr), 888 port_peernode(p_ptr),
930 ref, 889 ref,
@@ -932,7 +891,6 @@ void tipc_acknowledge(u32 ref, u32 ack)
932 CONN_MANAGER, 891 CONN_MANAGER,
933 CONN_ACK, 892 CONN_ACK,
934 TIPC_OK, 893 TIPC_OK,
935 port_out_seqno(p_ptr),
936 ack); 894 ack);
937 } 895 }
938 tipc_port_unlock(p_ptr); 896 tipc_port_unlock(p_ptr);
@@ -940,12 +898,10 @@ void tipc_acknowledge(u32 ref, u32 ack)
940} 898}
941 899
942/* 900/*
943 * tipc_createport(): user level call. Will add port to 901 * tipc_createport(): user level call.
944 * registry if non-zero user_ref.
945 */ 902 */
946 903
947int tipc_createport(u32 user_ref, 904int tipc_createport(void *usr_handle,
948 void *usr_handle,
949 unsigned int importance, 905 unsigned int importance,
950 tipc_msg_err_event error_cb, 906 tipc_msg_err_event error_cb,
951 tipc_named_msg_err_event named_error_cb, 907 tipc_named_msg_err_event named_error_cb,
@@ -957,14 +913,14 @@ int tipc_createport(u32 user_ref,
957 u32 *portref) 913 u32 *portref)
958{ 914{
959 struct user_port *up_ptr; 915 struct user_port *up_ptr;
960 struct port *p_ptr; 916 struct tipc_port *p_ptr;
961 917
962 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); 918 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
963 if (!up_ptr) { 919 if (!up_ptr) {
964 warn("Port creation failed, no memory\n"); 920 warn("Port creation failed, no memory\n");
965 return -ENOMEM; 921 return -ENOMEM;
966 } 922 }
967 p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher, 923 p_ptr = (struct tipc_port *)tipc_createport_raw(NULL, port_dispatcher,
968 port_wakeup, importance); 924 port_wakeup, importance);
969 if (!p_ptr) { 925 if (!p_ptr) {
970 kfree(up_ptr); 926 kfree(up_ptr);
@@ -972,9 +928,8 @@ int tipc_createport(u32 user_ref,
972 } 928 }
973 929
974 p_ptr->user_port = up_ptr; 930 p_ptr->user_port = up_ptr;
975 up_ptr->user_ref = user_ref;
976 up_ptr->usr_handle = usr_handle; 931 up_ptr->usr_handle = usr_handle;
977 up_ptr->ref = p_ptr->publ.ref; 932 up_ptr->ref = p_ptr->ref;
978 up_ptr->err_cb = error_cb; 933 up_ptr->err_cb = error_cb;
979 up_ptr->named_err_cb = named_error_cb; 934 up_ptr->named_err_cb = named_error_cb;
980 up_ptr->conn_err_cb = conn_error_cb; 935 up_ptr->conn_err_cb = conn_error_cb;
@@ -982,35 +937,26 @@ int tipc_createport(u32 user_ref,
982 up_ptr->named_msg_cb = named_msg_cb; 937 up_ptr->named_msg_cb = named_msg_cb;
983 up_ptr->conn_msg_cb = conn_msg_cb; 938 up_ptr->conn_msg_cb = conn_msg_cb;
984 up_ptr->continue_event_cb = continue_event_cb; 939 up_ptr->continue_event_cb = continue_event_cb;
985 INIT_LIST_HEAD(&up_ptr->uport_list); 940 *portref = p_ptr->ref;
986 tipc_reg_add_port(up_ptr);
987 *portref = p_ptr->publ.ref;
988 tipc_port_unlock(p_ptr); 941 tipc_port_unlock(p_ptr);
989 return 0; 942 return 0;
990} 943}
991 944
992int tipc_ownidentity(u32 ref, struct tipc_portid *id)
993{
994 id->ref = ref;
995 id->node = tipc_own_addr;
996 return 0;
997}
998
999int tipc_portimportance(u32 ref, unsigned int *importance) 945int tipc_portimportance(u32 ref, unsigned int *importance)
1000{ 946{
1001 struct port *p_ptr; 947 struct tipc_port *p_ptr;
1002 948
1003 p_ptr = tipc_port_lock(ref); 949 p_ptr = tipc_port_lock(ref);
1004 if (!p_ptr) 950 if (!p_ptr)
1005 return -EINVAL; 951 return -EINVAL;
1006 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); 952 *importance = (unsigned int)msg_importance(&p_ptr->phdr);
1007 tipc_port_unlock(p_ptr); 953 tipc_port_unlock(p_ptr);
1008 return 0; 954 return 0;
1009} 955}
1010 956
1011int tipc_set_portimportance(u32 ref, unsigned int imp) 957int tipc_set_portimportance(u32 ref, unsigned int imp)
1012{ 958{
1013 struct port *p_ptr; 959 struct tipc_port *p_ptr;
1014 960
1015 if (imp > TIPC_CRITICAL_IMPORTANCE) 961 if (imp > TIPC_CRITICAL_IMPORTANCE)
1016 return -EINVAL; 962 return -EINVAL;
@@ -1018,7 +964,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
1018 p_ptr = tipc_port_lock(ref); 964 p_ptr = tipc_port_lock(ref);
1019 if (!p_ptr) 965 if (!p_ptr)
1020 return -EINVAL; 966 return -EINVAL;
1021 msg_set_importance(&p_ptr->publ.phdr, (u32)imp); 967 msg_set_importance(&p_ptr->phdr, (u32)imp);
1022 tipc_port_unlock(p_ptr); 968 tipc_port_unlock(p_ptr);
1023 return 0; 969 return 0;
1024} 970}
@@ -1026,7 +972,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
1026 972
1027int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 973int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1028{ 974{
1029 struct port *p_ptr; 975 struct tipc_port *p_ptr;
1030 struct publication *publ; 976 struct publication *publ;
1031 u32 key; 977 u32 key;
1032 int res = -EINVAL; 978 int res = -EINVAL;
@@ -1035,10 +981,7 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1035 if (!p_ptr) 981 if (!p_ptr)
1036 return -EINVAL; 982 return -EINVAL;
1037 983
1038 dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, " 984 if (p_ptr->connected)
1039 "lower = %u, upper = %u\n",
1040 ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);
1041 if (p_ptr->publ.connected)
1042 goto exit; 985 goto exit;
1043 if (seq->lower > seq->upper) 986 if (seq->lower > seq->upper)
1044 goto exit; 987 goto exit;
@@ -1050,11 +993,11 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1050 goto exit; 993 goto exit;
1051 } 994 }
1052 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, 995 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
1053 scope, p_ptr->publ.ref, key); 996 scope, p_ptr->ref, key);
1054 if (publ) { 997 if (publ) {
1055 list_add(&publ->pport_list, &p_ptr->publications); 998 list_add(&publ->pport_list, &p_ptr->publications);
1056 p_ptr->pub_count++; 999 p_ptr->pub_count++;
1057 p_ptr->publ.published = 1; 1000 p_ptr->published = 1;
1058 res = 0; 1001 res = 0;
1059 } 1002 }
1060exit: 1003exit:
@@ -1064,7 +1007,7 @@ exit:
1064 1007
1065int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 1008int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1066{ 1009{
1067 struct port *p_ptr; 1010 struct tipc_port *p_ptr;
1068 struct publication *publ; 1011 struct publication *publ;
1069 struct publication *tpubl; 1012 struct publication *tpubl;
1070 int res = -EINVAL; 1013 int res = -EINVAL;
@@ -1097,49 +1040,45 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1097 } 1040 }
1098 } 1041 }
1099 if (list_empty(&p_ptr->publications)) 1042 if (list_empty(&p_ptr->publications))
1100 p_ptr->publ.published = 0; 1043 p_ptr->published = 0;
1101 tipc_port_unlock(p_ptr); 1044 tipc_port_unlock(p_ptr);
1102 return res; 1045 return res;
1103} 1046}
1104 1047
1105int tipc_connect2port(u32 ref, struct tipc_portid const *peer) 1048int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1106{ 1049{
1107 struct port *p_ptr; 1050 struct tipc_port *p_ptr;
1108 struct tipc_msg *msg; 1051 struct tipc_msg *msg;
1109 int res = -EINVAL; 1052 int res = -EINVAL;
1110 1053
1111 p_ptr = tipc_port_lock(ref); 1054 p_ptr = tipc_port_lock(ref);
1112 if (!p_ptr) 1055 if (!p_ptr)
1113 return -EINVAL; 1056 return -EINVAL;
1114 if (p_ptr->publ.published || p_ptr->publ.connected) 1057 if (p_ptr->published || p_ptr->connected)
1115 goto exit; 1058 goto exit;
1116 if (!peer->ref) 1059 if (!peer->ref)
1117 goto exit; 1060 goto exit;
1118 1061
1119 msg = &p_ptr->publ.phdr; 1062 msg = &p_ptr->phdr;
1120 msg_set_destnode(msg, peer->node); 1063 msg_set_destnode(msg, peer->node);
1121 msg_set_destport(msg, peer->ref); 1064 msg_set_destport(msg, peer->ref);
1122 msg_set_orignode(msg, tipc_own_addr); 1065 msg_set_orignode(msg, tipc_own_addr);
1123 msg_set_origport(msg, p_ptr->publ.ref); 1066 msg_set_origport(msg, p_ptr->ref);
1124 msg_set_transp_seqno(msg, 42);
1125 msg_set_type(msg, TIPC_CONN_MSG); 1067 msg_set_type(msg, TIPC_CONN_MSG);
1126 if (!may_route(peer->node)) 1068 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1127 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1128 else
1129 msg_set_hdr_sz(msg, LONG_H_SIZE);
1130 1069
1131 p_ptr->probing_interval = PROBING_INTERVAL; 1070 p_ptr->probing_interval = PROBING_INTERVAL;
1132 p_ptr->probing_state = CONFIRMED; 1071 p_ptr->probing_state = CONFIRMED;
1133 p_ptr->publ.connected = 1; 1072 p_ptr->connected = 1;
1134 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 1073 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
1135 1074
1136 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, 1075 tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
1137 (void *)(unsigned long)ref, 1076 (void *)(unsigned long)ref,
1138 (net_ev_handler)port_handle_node_down); 1077 (net_ev_handler)port_handle_node_down);
1139 res = 0; 1078 res = 0;
1140exit: 1079exit:
1141 tipc_port_unlock(p_ptr); 1080 tipc_port_unlock(p_ptr);
1142 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); 1081 p_ptr->max_pkt = tipc_link_get_max_pkt(peer->node, ref);
1143 return res; 1082 return res;
1144} 1083}
1145 1084
@@ -1157,7 +1096,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1157 tp_ptr->connected = 0; 1096 tp_ptr->connected = 0;
1158 /* let timer expire on it's own to avoid deadlock! */ 1097 /* let timer expire on it's own to avoid deadlock! */
1159 tipc_nodesub_unsubscribe( 1098 tipc_nodesub_unsubscribe(
1160 &((struct port *)tp_ptr)->subscription); 1099 &((struct tipc_port *)tp_ptr)->subscription);
1161 res = 0; 1100 res = 0;
1162 } else { 1101 } else {
1163 res = -ENOTCONN; 1102 res = -ENOTCONN;
@@ -1172,7 +1111,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1172 1111
1173int tipc_disconnect(u32 ref) 1112int tipc_disconnect(u32 ref)
1174{ 1113{
1175 struct port *p_ptr; 1114 struct tipc_port *p_ptr;
1176 int res; 1115 int res;
1177 1116
1178 p_ptr = tipc_port_lock(ref); 1117 p_ptr = tipc_port_lock(ref);
@@ -1188,15 +1127,15 @@ int tipc_disconnect(u32 ref)
1188 */ 1127 */
1189int tipc_shutdown(u32 ref) 1128int tipc_shutdown(u32 ref)
1190{ 1129{
1191 struct port *p_ptr; 1130 struct tipc_port *p_ptr;
1192 struct sk_buff *buf = NULL; 1131 struct sk_buff *buf = NULL;
1193 1132
1194 p_ptr = tipc_port_lock(ref); 1133 p_ptr = tipc_port_lock(ref);
1195 if (!p_ptr) 1134 if (!p_ptr)
1196 return -EINVAL; 1135 return -EINVAL;
1197 1136
1198 if (p_ptr->publ.connected) { 1137 if (p_ptr->connected) {
1199 u32 imp = msg_importance(&p_ptr->publ.phdr); 1138 u32 imp = msg_importance(&p_ptr->phdr);
1200 if (imp < TIPC_CRITICAL_IMPORTANCE) 1139 if (imp < TIPC_CRITICAL_IMPORTANCE)
1201 imp++; 1140 imp++;
1202 buf = port_build_proto_msg(port_peerport(p_ptr), 1141 buf = port_build_proto_msg(port_peerport(p_ptr),
@@ -1206,7 +1145,6 @@ int tipc_shutdown(u32 ref)
1206 imp, 1145 imp,
1207 TIPC_CONN_MSG, 1146 TIPC_CONN_MSG,
1208 TIPC_CONN_SHUTDOWN, 1147 TIPC_CONN_SHUTDOWN,
1209 port_out_seqno(p_ptr),
1210 0); 1148 0);
1211 } 1149 }
1212 tipc_port_unlock(p_ptr); 1150 tipc_port_unlock(p_ptr);
@@ -1219,13 +1157,13 @@ int tipc_shutdown(u32 ref)
1219 * message for this node. 1157 * message for this node.
1220 */ 1158 */
1221 1159
1222static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, 1160static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect,
1223 struct iovec const *msg_sect) 1161 struct iovec const *msg_sect)
1224{ 1162{
1225 struct sk_buff *buf; 1163 struct sk_buff *buf;
1226 int res; 1164 int res;
1227 1165
1228 res = tipc_msg_build(&sender->publ.phdr, msg_sect, num_sect, 1166 res = tipc_msg_build(&sender->phdr, msg_sect, num_sect,
1229 MAX_MSG_SIZE, !sender->user_port, &buf); 1167 MAX_MSG_SIZE, !sender->user_port, &buf);
1230 if (likely(buf)) 1168 if (likely(buf))
1231 tipc_port_recv_msg(buf); 1169 tipc_port_recv_msg(buf);
@@ -1238,15 +1176,15 @@ static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
1238 1176
1239int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) 1177int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1240{ 1178{
1241 struct port *p_ptr; 1179 struct tipc_port *p_ptr;
1242 u32 destnode; 1180 u32 destnode;
1243 int res; 1181 int res;
1244 1182
1245 p_ptr = tipc_port_deref(ref); 1183 p_ptr = tipc_port_deref(ref);
1246 if (!p_ptr || !p_ptr->publ.connected) 1184 if (!p_ptr || !p_ptr->connected)
1247 return -EINVAL; 1185 return -EINVAL;
1248 1186
1249 p_ptr->publ.congested = 1; 1187 p_ptr->congested = 1;
1250 if (!tipc_port_congested(p_ptr)) { 1188 if (!tipc_port_congested(p_ptr)) {
1251 destnode = port_peernode(p_ptr); 1189 destnode = port_peernode(p_ptr);
1252 if (likely(destnode != tipc_own_addr)) 1190 if (likely(destnode != tipc_own_addr))
@@ -1256,14 +1194,14 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1256 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1194 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
1257 1195
1258 if (likely(res != -ELINKCONG)) { 1196 if (likely(res != -ELINKCONG)) {
1259 port_incr_out_seqno(p_ptr); 1197 p_ptr->congested = 0;
1260 p_ptr->publ.congested = 0; 1198 if (res > 0)
1261 p_ptr->sent++; 1199 p_ptr->sent++;
1262 return res; 1200 return res;
1263 } 1201 }
1264 } 1202 }
1265 if (port_unreliable(p_ptr)) { 1203 if (port_unreliable(p_ptr)) {
1266 p_ptr->publ.congested = 0; 1204 p_ptr->congested = 0;
1267 /* Just calculate msg length and return */ 1205 /* Just calculate msg length and return */
1268 return tipc_msg_calc_data_size(msg_sect, num_sect); 1206 return tipc_msg_calc_data_size(msg_sect, num_sect);
1269 } 1207 }
@@ -1271,49 +1209,46 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1271} 1209}
1272 1210
1273/** 1211/**
1274 * tipc_forward2name - forward message sections to port name 1212 * tipc_send2name - send message sections to port name
1275 */ 1213 */
1276 1214
1277static int tipc_forward2name(u32 ref, 1215int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1278 struct tipc_name const *name, 1216 unsigned int num_sect, struct iovec const *msg_sect)
1279 u32 domain,
1280 u32 num_sect,
1281 struct iovec const *msg_sect,
1282 struct tipc_portid const *orig,
1283 unsigned int importance)
1284{ 1217{
1285 struct port *p_ptr; 1218 struct tipc_port *p_ptr;
1286 struct tipc_msg *msg; 1219 struct tipc_msg *msg;
1287 u32 destnode = domain; 1220 u32 destnode = domain;
1288 u32 destport; 1221 u32 destport;
1289 int res; 1222 int res;
1290 1223
1291 p_ptr = tipc_port_deref(ref); 1224 p_ptr = tipc_port_deref(ref);
1292 if (!p_ptr || p_ptr->publ.connected) 1225 if (!p_ptr || p_ptr->connected)
1293 return -EINVAL; 1226 return -EINVAL;
1294 1227
1295 msg = &p_ptr->publ.phdr; 1228 msg = &p_ptr->phdr;
1296 msg_set_type(msg, TIPC_NAMED_MSG); 1229 msg_set_type(msg, TIPC_NAMED_MSG);
1297 msg_set_orignode(msg, orig->node); 1230 msg_set_orignode(msg, tipc_own_addr);
1298 msg_set_origport(msg, orig->ref); 1231 msg_set_origport(msg, ref);
1299 msg_set_hdr_sz(msg, LONG_H_SIZE); 1232 msg_set_hdr_sz(msg, LONG_H_SIZE);
1300 msg_set_nametype(msg, name->type); 1233 msg_set_nametype(msg, name->type);
1301 msg_set_nameinst(msg, name->instance); 1234 msg_set_nameinst(msg, name->instance);
1302 msg_set_lookup_scope(msg, tipc_addr_scope(domain)); 1235 msg_set_lookup_scope(msg, tipc_addr_scope(domain));
1303 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1304 msg_set_importance(msg,importance);
1305 destport = tipc_nametbl_translate(name->type, name->instance, &destnode); 1236 destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
1306 msg_set_destnode(msg, destnode); 1237 msg_set_destnode(msg, destnode);
1307 msg_set_destport(msg, destport); 1238 msg_set_destport(msg, destport);
1308 1239
1309 if (likely(destport)) { 1240 if (likely(destport)) {
1310 p_ptr->sent++;
1311 if (likely(destnode == tipc_own_addr)) 1241 if (likely(destnode == tipc_own_addr))
1312 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1242 res = tipc_port_recv_sections(p_ptr, num_sect,
1313 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1243 msg_sect);
1314 destnode); 1244 else
1315 if (likely(res != -ELINKCONG)) 1245 res = tipc_link_send_sections_fast(p_ptr, msg_sect,
1246 num_sect, destnode);
1247 if (likely(res != -ELINKCONG)) {
1248 if (res > 0)
1249 p_ptr->sent++;
1316 return res; 1250 return res;
1251 }
1317 if (port_unreliable(p_ptr)) { 1252 if (port_unreliable(p_ptr)) {
1318 /* Just calculate msg length and return */ 1253 /* Just calculate msg length and return */
1319 return tipc_msg_calc_data_size(msg_sect, num_sect); 1254 return tipc_msg_calc_data_size(msg_sect, num_sect);
@@ -1325,57 +1260,38 @@ static int tipc_forward2name(u32 ref,
1325} 1260}
1326 1261
1327/** 1262/**
1328 * tipc_send2name - send message sections to port name 1263 * tipc_send2port - send message sections to port identity
1329 */
1330
1331int tipc_send2name(u32 ref,
1332 struct tipc_name const *name,
1333 unsigned int domain,
1334 unsigned int num_sect,
1335 struct iovec const *msg_sect)
1336{
1337 struct tipc_portid orig;
1338
1339 orig.ref = ref;
1340 orig.node = tipc_own_addr;
1341 return tipc_forward2name(ref, name, domain, num_sect, msg_sect, &orig,
1342 TIPC_PORT_IMPORTANCE);
1343}
1344
1345/**
1346 * tipc_forward2port - forward message sections to port identity
1347 */ 1264 */
1348 1265
1349static int tipc_forward2port(u32 ref, 1266int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1350 struct tipc_portid const *dest, 1267 unsigned int num_sect, struct iovec const *msg_sect)
1351 unsigned int num_sect,
1352 struct iovec const *msg_sect,
1353 struct tipc_portid const *orig,
1354 unsigned int importance)
1355{ 1268{
1356 struct port *p_ptr; 1269 struct tipc_port *p_ptr;
1357 struct tipc_msg *msg; 1270 struct tipc_msg *msg;
1358 int res; 1271 int res;
1359 1272
1360 p_ptr = tipc_port_deref(ref); 1273 p_ptr = tipc_port_deref(ref);
1361 if (!p_ptr || p_ptr->publ.connected) 1274 if (!p_ptr || p_ptr->connected)
1362 return -EINVAL; 1275 return -EINVAL;
1363 1276
1364 msg = &p_ptr->publ.phdr; 1277 msg = &p_ptr->phdr;
1365 msg_set_type(msg, TIPC_DIRECT_MSG); 1278 msg_set_type(msg, TIPC_DIRECT_MSG);
1366 msg_set_orignode(msg, orig->node); 1279 msg_set_orignode(msg, tipc_own_addr);
1367 msg_set_origport(msg, orig->ref); 1280 msg_set_origport(msg, ref);
1368 msg_set_destnode(msg, dest->node); 1281 msg_set_destnode(msg, dest->node);
1369 msg_set_destport(msg, dest->ref); 1282 msg_set_destport(msg, dest->ref);
1370 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1283 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1371 if (importance <= TIPC_CRITICAL_IMPORTANCE) 1284
1372 msg_set_importance(msg, importance);
1373 p_ptr->sent++;
1374 if (dest->node == tipc_own_addr) 1285 if (dest->node == tipc_own_addr)
1375 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1286 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
1376 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node); 1287 else
1377 if (likely(res != -ELINKCONG)) 1288 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
1289 dest->node);
1290 if (likely(res != -ELINKCONG)) {
1291 if (res > 0)
1292 p_ptr->sent++;
1378 return res; 1293 return res;
1294 }
1379 if (port_unreliable(p_ptr)) { 1295 if (port_unreliable(p_ptr)) {
1380 /* Just calculate msg length and return */ 1296 /* Just calculate msg length and return */
1381 return tipc_msg_calc_data_size(msg_sect, num_sect); 1297 return tipc_msg_calc_data_size(msg_sect, num_sect);
@@ -1384,81 +1300,45 @@ static int tipc_forward2port(u32 ref,
1384} 1300}
1385 1301
1386/** 1302/**
1387 * tipc_send2port - send message sections to port identity 1303 * tipc_send_buf2port - send message buffer to port identity
1388 */ 1304 */
1389 1305
1390int tipc_send2port(u32 ref, 1306int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1391 struct tipc_portid const *dest, 1307 struct sk_buff *buf, unsigned int dsz)
1392 unsigned int num_sect,
1393 struct iovec const *msg_sect)
1394{ 1308{
1395 struct tipc_portid orig; 1309 struct tipc_port *p_ptr;
1396
1397 orig.ref = ref;
1398 orig.node = tipc_own_addr;
1399 return tipc_forward2port(ref, dest, num_sect, msg_sect, &orig,
1400 TIPC_PORT_IMPORTANCE);
1401}
1402
1403/**
1404 * tipc_forward_buf2port - forward message buffer to port identity
1405 */
1406static int tipc_forward_buf2port(u32 ref,
1407 struct tipc_portid const *dest,
1408 struct sk_buff *buf,
1409 unsigned int dsz,
1410 struct tipc_portid const *orig,
1411 unsigned int importance)
1412{
1413 struct port *p_ptr;
1414 struct tipc_msg *msg; 1310 struct tipc_msg *msg;
1415 int res; 1311 int res;
1416 1312
1417 p_ptr = (struct port *)tipc_ref_deref(ref); 1313 p_ptr = (struct tipc_port *)tipc_ref_deref(ref);
1418 if (!p_ptr || p_ptr->publ.connected) 1314 if (!p_ptr || p_ptr->connected)
1419 return -EINVAL; 1315 return -EINVAL;
1420 1316
1421 msg = &p_ptr->publ.phdr; 1317 msg = &p_ptr->phdr;
1422 msg_set_type(msg, TIPC_DIRECT_MSG); 1318 msg_set_type(msg, TIPC_DIRECT_MSG);
1423 msg_set_orignode(msg, orig->node); 1319 msg_set_orignode(msg, tipc_own_addr);
1424 msg_set_origport(msg, orig->ref); 1320 msg_set_origport(msg, ref);
1425 msg_set_destnode(msg, dest->node); 1321 msg_set_destnode(msg, dest->node);
1426 msg_set_destport(msg, dest->ref); 1322 msg_set_destport(msg, dest->ref);
1427 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1323 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1428 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1429 msg_set_importance(msg, importance);
1430 msg_set_size(msg, DIR_MSG_H_SIZE + dsz); 1324 msg_set_size(msg, DIR_MSG_H_SIZE + dsz);
1431 if (skb_cow(buf, DIR_MSG_H_SIZE)) 1325 if (skb_cow(buf, DIR_MSG_H_SIZE))
1432 return -ENOMEM; 1326 return -ENOMEM;
1433 1327
1434 skb_push(buf, DIR_MSG_H_SIZE); 1328 skb_push(buf, DIR_MSG_H_SIZE);
1435 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); 1329 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);
1436 msg_dbg(msg, "buf2port: "); 1330
1437 p_ptr->sent++;
1438 if (dest->node == tipc_own_addr) 1331 if (dest->node == tipc_own_addr)
1439 return tipc_port_recv_msg(buf); 1332 res = tipc_port_recv_msg(buf);
1440 res = tipc_send_buf_fast(buf, dest->node); 1333 else
1441 if (likely(res != -ELINKCONG)) 1334 res = tipc_send_buf_fast(buf, dest->node);
1335 if (likely(res != -ELINKCONG)) {
1336 if (res > 0)
1337 p_ptr->sent++;
1442 return res; 1338 return res;
1339 }
1443 if (port_unreliable(p_ptr)) 1340 if (port_unreliable(p_ptr))
1444 return dsz; 1341 return dsz;
1445 return -ELINKCONG; 1342 return -ELINKCONG;
1446} 1343}
1447 1344
1448/**
1449 * tipc_send_buf2port - send message buffer to port identity
1450 */
1451
1452int tipc_send_buf2port(u32 ref,
1453 struct tipc_portid const *dest,
1454 struct sk_buff *buf,
1455 unsigned int dsz)
1456{
1457 struct tipc_portid orig;
1458
1459 orig.ref = ref;
1460 orig.node = tipc_own_addr;
1461 return tipc_forward_buf2port(ref, dest, buf, dsz, &orig,
1462 TIPC_PORT_IMPORTANCE);
1463}
1464
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 73bbf442b346..87b9424ae0ec 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -2,7 +2,7 @@
2 * net/tipc/port.h: Include file for TIPC port code 2 * net/tipc/port.h: Include file for TIPC port code
3 * 3 *
4 * Copyright (c) 1994-2007, Ericsson AB 4 * Copyright (c) 1994-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-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,24 +37,52 @@
37#ifndef _TIPC_PORT_H 37#ifndef _TIPC_PORT_H
38#define _TIPC_PORT_H 38#define _TIPC_PORT_H
39 39
40#include "core.h"
41#include "ref.h" 40#include "ref.h"
42#include "net.h" 41#include "net.h"
43#include "msg.h" 42#include "msg.h"
44#include "dbg.h"
45#include "node_subscr.h" 43#include "node_subscr.h"
46 44
45#define TIPC_FLOW_CONTROL_WIN 512
46
47typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref,
48 struct sk_buff **buf, unsigned char const *data,
49 unsigned int size, int reason,
50 struct tipc_portid const *attmpt_destid);
51
52typedef void (*tipc_named_msg_err_event) (void *usr_handle, u32 portref,
53 struct sk_buff **buf, unsigned char const *data,
54 unsigned int size, int reason,
55 struct tipc_name_seq const *attmpt_dest);
56
57typedef void (*tipc_conn_shutdown_event) (void *usr_handle, u32 portref,
58 struct sk_buff **buf, unsigned char const *data,
59 unsigned int size, int reason);
60
61typedef void (*tipc_msg_event) (void *usr_handle, u32 portref,
62 struct sk_buff **buf, unsigned char const *data,
63 unsigned int size, unsigned int importance,
64 struct tipc_portid const *origin);
65
66typedef void (*tipc_named_msg_event) (void *usr_handle, u32 portref,
67 struct sk_buff **buf, unsigned char const *data,
68 unsigned int size, unsigned int importance,
69 struct tipc_portid const *orig,
70 struct tipc_name_seq const *dest);
71
72typedef void (*tipc_conn_msg_event) (void *usr_handle, u32 portref,
73 struct sk_buff **buf, unsigned char const *data,
74 unsigned int size);
75
76typedef void (*tipc_continue_event) (void *usr_handle, u32 portref);
77
47/** 78/**
48 * struct user_port - TIPC user port (used with native API) 79 * struct user_port - TIPC user port (used with native API)
49 * @user_ref: id of user who created user port
50 * @usr_handle: user-specified field 80 * @usr_handle: user-specified field
51 * @ref: object reference to associated TIPC port 81 * @ref: object reference to associated TIPC port
52 * <various callback routines> 82 * <various callback routines>
53 * @uport_list: adjacent user ports in list of ports held by user
54 */ 83 */
55 84
56struct user_port { 85struct user_port {
57 u32 user_ref;
58 void *usr_handle; 86 void *usr_handle;
59 u32 ref; 87 u32 ref;
60 tipc_msg_err_event err_cb; 88 tipc_msg_err_event err_cb;
@@ -64,31 +92,48 @@ struct user_port {
64 tipc_named_msg_event named_msg_cb; 92 tipc_named_msg_event named_msg_cb;
65 tipc_conn_msg_event conn_msg_cb; 93 tipc_conn_msg_event conn_msg_cb;
66 tipc_continue_event continue_event_cb; 94 tipc_continue_event continue_event_cb;
67 struct list_head uport_list;
68}; 95};
69 96
70/** 97/**
71 * struct port - TIPC port structure 98 * struct tipc_port - TIPC port structure
72 * @publ: TIPC port info available to privileged users 99 * @usr_handle: pointer to additional user-defined information about port
100 * @lock: pointer to spinlock for controlling access to port
101 * @connected: non-zero if port is currently connected to a peer port
102 * @conn_type: TIPC type used when connection was established
103 * @conn_instance: TIPC instance used when connection was established
104 * @conn_unacked: number of unacknowledged messages received from peer port
105 * @published: non-zero if port has one or more associated names
106 * @congested: non-zero if cannot send because of link or port congestion
107 * @max_pkt: maximum packet size "hint" used when building messages sent by port
108 * @ref: unique reference to port in TIPC object registry
109 * @phdr: preformatted message header used when sending messages
73 * @port_list: adjacent ports in TIPC's global list of ports 110 * @port_list: adjacent ports in TIPC's global list of ports
74 * @dispatcher: ptr to routine which handles received messages 111 * @dispatcher: ptr to routine which handles received messages
75 * @wakeup: ptr to routine to call when port is no longer congested 112 * @wakeup: ptr to routine to call when port is no longer congested
76 * @user_port: ptr to user port associated with port (if any) 113 * @user_port: ptr to user port associated with port (if any)
77 * @wait_list: adjacent ports in list of ports waiting on link congestion 114 * @wait_list: adjacent ports in list of ports waiting on link congestion
78 * @waiting_pkts: 115 * @waiting_pkts:
79 * @sent: 116 * @sent: # of non-empty messages sent by port
80 * @acked: 117 * @acked: # of non-empty message acknowledgements from connected port's peer
81 * @publications: list of publications for port 118 * @publications: list of publications for port
82 * @pub_count: total # of publications port has made during its lifetime 119 * @pub_count: total # of publications port has made during its lifetime
83 * @probing_state: 120 * @probing_state:
84 * @probing_interval: 121 * @probing_interval:
85 * @last_in_seqno:
86 * @timer_ref: 122 * @timer_ref:
87 * @subscription: "node down" subscription used to terminate failed connections 123 * @subscription: "node down" subscription used to terminate failed connections
88 */ 124 */
89 125struct tipc_port {
90struct port { 126 void *usr_handle;
91 struct tipc_port publ; 127 spinlock_t *lock;
128 int connected;
129 u32 conn_type;
130 u32 conn_instance;
131 u32 conn_unacked;
132 int published;
133 u32 congested;
134 u32 max_pkt;
135 u32 ref;
136 struct tipc_msg phdr;
92 struct list_head port_list; 137 struct list_head port_list;
93 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *); 138 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *);
94 void (*wakeup)(struct tipc_port *); 139 void (*wakeup)(struct tipc_port *);
@@ -101,7 +146,6 @@ struct port {
101 u32 pub_count; 146 u32 pub_count;
102 u32 probing_state; 147 u32 probing_state;
103 u32 probing_interval; 148 u32 probing_interval;
104 u32 last_in_seqno;
105 struct timer_list timer; 149 struct timer_list timer;
106 struct tipc_node_subscr subscription; 150 struct tipc_node_subscr subscription;
107}; 151};
@@ -109,11 +153,76 @@ struct port {
109extern spinlock_t tipc_port_list_lock; 153extern spinlock_t tipc_port_list_lock;
110struct port_list; 154struct port_list;
111 155
112int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 156/*
157 * TIPC port manipulation routines
158 */
159struct tipc_port *tipc_createport_raw(void *usr_handle,
160 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
161 void (*wakeup)(struct tipc_port *), const u32 importance);
162
163int tipc_reject_msg(struct sk_buff *buf, u32 err);
164
165int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode);
166
167void tipc_acknowledge(u32 port_ref, u32 ack);
168
169int tipc_createport(void *usr_handle,
170 unsigned int importance, tipc_msg_err_event error_cb,
171 tipc_named_msg_err_event named_error_cb,
172 tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb,
173 tipc_named_msg_event named_msg_cb,
174 tipc_conn_msg_event conn_msg_cb,
175 tipc_continue_event continue_event_cb, u32 *portref);
176
177int tipc_deleteport(u32 portref);
178
179int tipc_portimportance(u32 portref, unsigned int *importance);
180int tipc_set_portimportance(u32 portref, unsigned int importance);
181
182int tipc_portunreliable(u32 portref, unsigned int *isunreliable);
183int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
184
185int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
186int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
187
188int tipc_publish(u32 portref, unsigned int scope,
189 struct tipc_name_seq const *name_seq);
190int tipc_withdraw(u32 portref, unsigned int scope,
191 struct tipc_name_seq const *name_seq);
192
193int tipc_connect2port(u32 portref, struct tipc_portid const *port);
194
195int tipc_disconnect(u32 portref);
196
197int tipc_shutdown(u32 ref);
198
199
200/*
201 * The following routines require that the port be locked on entry
202 */
203int tipc_disconnect_port(struct tipc_port *tp_ptr);
204
205/*
206 * TIPC messaging routines
207 */
208int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect);
209
210int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
211 unsigned int num_sect, struct iovec const *msg_sect);
212
213int tipc_send2port(u32 portref, struct tipc_portid const *dest,
214 unsigned int num_sect, struct iovec const *msg_sect);
215
216int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
217 struct sk_buff *buf, unsigned int dsz);
218
219int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
220 unsigned int section_count, struct iovec const *msg);
221
222int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
113 struct iovec const *msg_sect, u32 num_sect, 223 struct iovec const *msg_sect, u32 num_sect,
114 int err); 224 int err);
115struct sk_buff *tipc_port_get_ports(void); 225struct sk_buff *tipc_port_get_ports(void);
116struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space);
117void tipc_port_recv_proto_msg(struct sk_buff *buf); 226void tipc_port_recv_proto_msg(struct sk_buff *buf);
118void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); 227void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
119void tipc_port_reinit(void); 228void tipc_port_reinit(void);
@@ -122,9 +231,9 @@ void tipc_port_reinit(void);
122 * tipc_port_lock - lock port instance referred to and return its pointer 231 * tipc_port_lock - lock port instance referred to and return its pointer
123 */ 232 */
124 233
125static inline struct port *tipc_port_lock(u32 ref) 234static inline struct tipc_port *tipc_port_lock(u32 ref)
126{ 235{
127 return (struct port *)tipc_ref_lock(ref); 236 return (struct tipc_port *)tipc_ref_lock(ref);
128} 237}
129 238
130/** 239/**
@@ -133,27 +242,27 @@ static inline struct port *tipc_port_lock(u32 ref)
133 * Can use pointer instead of tipc_ref_unlock() since port is already locked. 242 * Can use pointer instead of tipc_ref_unlock() since port is already locked.
134 */ 243 */
135 244
136static inline void tipc_port_unlock(struct port *p_ptr) 245static inline void tipc_port_unlock(struct tipc_port *p_ptr)
137{ 246{
138 spin_unlock_bh(p_ptr->publ.lock); 247 spin_unlock_bh(p_ptr->lock);
139} 248}
140 249
141static inline struct port* tipc_port_deref(u32 ref) 250static inline struct tipc_port *tipc_port_deref(u32 ref)
142{ 251{
143 return (struct port *)tipc_ref_deref(ref); 252 return (struct tipc_port *)tipc_ref_deref(ref);
144} 253}
145 254
146static inline u32 tipc_peer_port(struct port *p_ptr) 255static inline u32 tipc_peer_port(struct tipc_port *p_ptr)
147{ 256{
148 return msg_destport(&p_ptr->publ.phdr); 257 return msg_destport(&p_ptr->phdr);
149} 258}
150 259
151static inline u32 tipc_peer_node(struct port *p_ptr) 260static inline u32 tipc_peer_node(struct tipc_port *p_ptr)
152{ 261{
153 return msg_destnode(&p_ptr->publ.phdr); 262 return msg_destnode(&p_ptr->phdr);
154} 263}
155 264
156static inline int tipc_port_congested(struct port *p_ptr) 265static inline int tipc_port_congested(struct tipc_port *p_ptr)
157{ 266{
158 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); 267 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
159} 268}
@@ -164,7 +273,7 @@ static inline int tipc_port_congested(struct port *p_ptr)
164 273
165static inline int tipc_port_recv_msg(struct sk_buff *buf) 274static inline int tipc_port_recv_msg(struct sk_buff *buf)
166{ 275{
167 struct port *p_ptr; 276 struct tipc_port *p_ptr;
168 struct tipc_msg *msg = buf_msg(buf); 277 struct tipc_msg *msg = buf_msg(buf);
169 u32 destport = msg_destport(msg); 278 u32 destport = msg_destport(msg);
170 u32 dsz = msg_data_sz(msg); 279 u32 dsz = msg_data_sz(msg);
@@ -179,7 +288,7 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
179 /* validate destination & pass to port, otherwise reject message */ 288 /* validate destination & pass to port, otherwise reject message */
180 p_ptr = tipc_port_lock(destport); 289 p_ptr = tipc_port_lock(destport);
181 if (likely(p_ptr)) { 290 if (likely(p_ptr)) {
182 if (likely(p_ptr->publ.connected)) { 291 if (likely(p_ptr->connected)) {
183 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) || 292 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) ||
184 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) || 293 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) ||
185 (unlikely(!msg_connected(msg)))) { 294 (unlikely(!msg_connected(msg)))) {
@@ -188,7 +297,7 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
188 goto reject; 297 goto reject;
189 } 298 }
190 } 299 }
191 err = p_ptr->dispatcher(&p_ptr->publ, buf); 300 err = p_ptr->dispatcher(p_ptr, buf);
192 tipc_port_unlock(p_ptr); 301 tipc_port_unlock(p_ptr);
193 if (likely(!err)) 302 if (likely(!err))
194 return dsz; 303 return dsz;
@@ -196,7 +305,6 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
196 err = TIPC_ERR_NO_PORT; 305 err = TIPC_ERR_NO_PORT;
197 } 306 }
198reject: 307reject:
199 dbg("port->rejecting, err = %x..\n",err);
200 return tipc_reject_msg(buf, err); 308 return tipc_reject_msg(buf, err);
201} 309}
202 310
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index ab8ad32d8c20..83116892528b 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -89,7 +89,7 @@ struct ref_table {
89 * have a reference value of 0 (although this is unlikely). 89 * have a reference value of 0 (although this is unlikely).
90 */ 90 */
91 91
92static struct ref_table tipc_ref_table = { NULL }; 92static struct ref_table tipc_ref_table;
93 93
94static DEFINE_RWLOCK(ref_table_lock); 94static DEFINE_RWLOCK(ref_table_lock);
95 95
@@ -178,14 +178,12 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
178 next_plus_upper = entry->ref; 178 next_plus_upper = entry->ref;
179 tipc_ref_table.first_free = next_plus_upper & index_mask; 179 tipc_ref_table.first_free = next_plus_upper & index_mask;
180 ref = (next_plus_upper & ~index_mask) + index; 180 ref = (next_plus_upper & ~index_mask) + index;
181 } 181 } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
182 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
183 index = tipc_ref_table.init_point++; 182 index = tipc_ref_table.init_point++;
184 entry = &(tipc_ref_table.entries[index]); 183 entry = &(tipc_ref_table.entries[index]);
185 spin_lock_init(&entry->lock); 184 spin_lock_init(&entry->lock);
186 ref = tipc_ref_table.start_mask + index; 185 ref = tipc_ref_table.start_mask + index;
187 } 186 } else {
188 else {
189 ref = 0; 187 ref = 0;
190 } 188 }
191 write_unlock_bh(&ref_table_lock); 189 write_unlock_bh(&ref_table_lock);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e9f0d5004483..29d94d53198d 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2,7 +2,7 @@
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2007, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-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
@@ -34,25 +34,13 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <linux/module.h>
38#include <linux/types.h>
39#include <linux/net.h>
40#include <linux/socket.h>
41#include <linux/errno.h>
42#include <linux/mm.h>
43#include <linux/poll.h>
44#include <linux/fcntl.h>
45#include <linux/gfp.h>
46#include <asm/string.h>
47#include <asm/atomic.h>
48#include <net/sock.h> 37#include <net/sock.h>
49 38
50#include <linux/tipc.h> 39#include <linux/tipc.h>
51#include <linux/tipc_config.h> 40#include <linux/tipc_config.h>
52#include <net/tipc/tipc_msg.h>
53#include <net/tipc/tipc_port.h>
54 41
55#include "core.h" 42#include "core.h"
43#include "port.h"
56 44
57#define SS_LISTENING -1 /* socket is listening */ 45#define SS_LISTENING -1 /* socket is listening */
58#define SS_READY -2 /* socket is connectionless */ 46#define SS_READY -2 /* socket is connectionless */
@@ -70,6 +58,9 @@ struct tipc_sock {
70#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 58#define tipc_sk(sk) ((struct tipc_sock *)(sk))
71#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) 59#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p))
72 60
61#define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \
62 (sock->state == SS_DISCONNECTING))
63
73static int backlog_rcv(struct sock *sk, struct sk_buff *skb); 64static int backlog_rcv(struct sock *sk, struct sk_buff *skb);
74static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); 65static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
75static void wakeupdispatch(struct tipc_port *tport); 66static void wakeupdispatch(struct tipc_port *tport);
@@ -80,7 +71,7 @@ static const struct proto_ops msg_ops;
80 71
81static struct proto tipc_proto; 72static struct proto tipc_proto;
82 73
83static int sockets_enabled = 0; 74static int sockets_enabled;
84 75
85static atomic_t tipc_queue_size = ATOMIC_INIT(0); 76static atomic_t tipc_queue_size = ATOMIC_INIT(0);
86 77
@@ -253,7 +244,6 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
253 tipc_set_portunreliable(tp_ptr->ref, 1); 244 tipc_set_portunreliable(tp_ptr->ref, 1);
254 } 245 }
255 246
256 atomic_inc(&tipc_user_count);
257 return 0; 247 return 0;
258} 248}
259 249
@@ -302,7 +292,7 @@ static int release(struct socket *sock)
302 if (buf == NULL) 292 if (buf == NULL)
303 break; 293 break;
304 atomic_dec(&tipc_queue_size); 294 atomic_dec(&tipc_queue_size);
305 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) 295 if (TIPC_SKB_CB(buf)->handle != 0)
306 buf_discard(buf); 296 buf_discard(buf);
307 else { 297 else {
308 if ((sock->state == SS_CONNECTING) || 298 if ((sock->state == SS_CONNECTING) ||
@@ -333,7 +323,6 @@ static int release(struct socket *sock)
333 sock_put(sk); 323 sock_put(sk);
334 sock->sk = NULL; 324 sock->sk = NULL;
335 325
336 atomic_dec(&tipc_user_count);
337 return res; 326 return res;
338} 327}
339 328
@@ -387,7 +376,7 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
387 * 376 *
388 * NOTE: This routine doesn't need to take the socket lock since it only 377 * NOTE: This routine doesn't need to take the socket lock since it only
389 * accesses socket information that is unchanging (or which changes in 378 * accesses socket information that is unchanging (or which changes in
390 * a completely predictable manner). 379 * a completely predictable manner).
391 */ 380 */
392 381
393static int get_name(struct socket *sock, struct sockaddr *uaddr, 382static int get_name(struct socket *sock, struct sockaddr *uaddr,
@@ -404,7 +393,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
404 addr->addr.id.ref = tsock->peer_name.ref; 393 addr->addr.id.ref = tsock->peer_name.ref;
405 addr->addr.id.node = tsock->peer_name.node; 394 addr->addr.id.node = tsock->peer_name.node;
406 } else { 395 } else {
407 tipc_ownidentity(tsock->p->ref, &addr->addr.id); 396 addr->addr.id.ref = tsock->p->ref;
397 addr->addr.id.node = tipc_own_addr;
408 } 398 }
409 399
410 *uaddr_len = sizeof(*addr); 400 *uaddr_len = sizeof(*addr);
@@ -506,6 +496,8 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m)
506 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV)) 496 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV))
507 return -EACCES; 497 return -EACCES;
508 498
499 if (!m->msg_iovlen || (m->msg_iov[0].iov_len < sizeof(hdr)))
500 return -EMSGSIZE;
509 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr))) 501 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr)))
510 return -EFAULT; 502 return -EFAULT;
511 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN))) 503 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN)))
@@ -574,37 +566,35 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
574 566
575 do { 567 do {
576 if (dest->addrtype == TIPC_ADDR_NAME) { 568 if (dest->addrtype == TIPC_ADDR_NAME) {
577 if ((res = dest_name_check(dest, m))) 569 res = dest_name_check(dest, m);
570 if (res)
578 break; 571 break;
579 res = tipc_send2name(tport->ref, 572 res = tipc_send2name(tport->ref,
580 &dest->addr.name.name, 573 &dest->addr.name.name,
581 dest->addr.name.domain, 574 dest->addr.name.domain,
582 m->msg_iovlen, 575 m->msg_iovlen,
583 m->msg_iov); 576 m->msg_iov);
584 } 577 } else if (dest->addrtype == TIPC_ADDR_ID) {
585 else if (dest->addrtype == TIPC_ADDR_ID) {
586 res = tipc_send2port(tport->ref, 578 res = tipc_send2port(tport->ref,
587 &dest->addr.id, 579 &dest->addr.id,
588 m->msg_iovlen, 580 m->msg_iovlen,
589 m->msg_iov); 581 m->msg_iov);
590 } 582 } else if (dest->addrtype == TIPC_ADDR_MCAST) {
591 else if (dest->addrtype == TIPC_ADDR_MCAST) {
592 if (needs_conn) { 583 if (needs_conn) {
593 res = -EOPNOTSUPP; 584 res = -EOPNOTSUPP;
594 break; 585 break;
595 } 586 }
596 if ((res = dest_name_check(dest, m))) 587 res = dest_name_check(dest, m);
588 if (res)
597 break; 589 break;
598 res = tipc_multicast(tport->ref, 590 res = tipc_multicast(tport->ref,
599 &dest->addr.nameseq, 591 &dest->addr.nameseq,
600 0,
601 m->msg_iovlen, 592 m->msg_iovlen,
602 m->msg_iov); 593 m->msg_iov);
603 } 594 }
604 if (likely(res != -ELINKCONG)) { 595 if (likely(res != -ELINKCONG)) {
605 if (needs_conn && (res >= 0)) { 596 if (needs_conn && (res >= 0))
606 sock->state = SS_CONNECTING; 597 sock->state = SS_CONNECTING;
607 }
608 break; 598 break;
609 } 599 }
610 if (m->msg_flags & MSG_DONTWAIT) { 600 if (m->msg_flags & MSG_DONTWAIT) {
@@ -663,9 +653,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
663 } 653 }
664 654
665 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); 655 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov);
666 if (likely(res != -ELINKCONG)) { 656 if (likely(res != -ELINKCONG))
667 break; 657 break;
668 }
669 if (m->msg_flags & MSG_DONTWAIT) { 658 if (m->msg_flags & MSG_DONTWAIT) {
670 res = -EWOULDBLOCK; 659 res = -EWOULDBLOCK;
671 break; 660 break;
@@ -764,7 +753,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
764 bytes_to_send = curr_left; 753 bytes_to_send = curr_left;
765 my_iov.iov_base = curr_start; 754 my_iov.iov_base = curr_start;
766 my_iov.iov_len = bytes_to_send; 755 my_iov.iov_len = bytes_to_send;
767 if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) { 756 res = send_packet(NULL, sock, &my_msg, 0);
757 if (res < 0) {
768 if (bytes_sent) 758 if (bytes_sent)
769 res = bytes_sent; 759 res = bytes_sent;
770 goto exit; 760 goto exit;
@@ -824,8 +814,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
824 addr->addrtype = TIPC_ADDR_ID; 814 addr->addrtype = TIPC_ADDR_ID;
825 addr->addr.id.ref = msg_origport(msg); 815 addr->addr.id.ref = msg_origport(msg);
826 addr->addr.id.node = msg_orignode(msg); 816 addr->addr.id.node = msg_orignode(msg);
827 addr->addr.name.domain = 0; /* could leave uninitialized */ 817 addr->addr.name.domain = 0; /* could leave uninitialized */
828 addr->scope = 0; /* could leave uninitialized */ 818 addr->scope = 0; /* could leave uninitialized */
829 m->msg_namelen = sizeof(struct sockaddr_tipc); 819 m->msg_namelen = sizeof(struct sockaddr_tipc);
830 } 820 }
831} 821}
@@ -859,12 +849,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
859 if (unlikely(err)) { 849 if (unlikely(err)) {
860 anc_data[0] = err; 850 anc_data[0] = err;
861 anc_data[1] = msg_data_sz(msg); 851 anc_data[1] = msg_data_sz(msg);
862 if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data))) 852 res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data);
863 return res; 853 if (res)
864 if (anc_data[1] &&
865 (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
866 msg_data(msg))))
867 return res; 854 return res;
855 if (anc_data[1]) {
856 res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
857 msg_data(msg));
858 if (res)
859 return res;
860 }
868 } 861 }
869 862
870 /* Optionally capture message destination object */ 863 /* Optionally capture message destination object */
@@ -892,9 +885,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
892 default: 885 default:
893 has_name = 0; 886 has_name = 0;
894 } 887 }
895 if (has_name && 888 if (has_name) {
896 (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data))) 889 res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data);
897 return res; 890 if (res)
891 return res;
892 }
898 893
899 return 0; 894 return 0;
900} 895}
@@ -919,15 +914,13 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
919 struct tipc_port *tport = tipc_sk_port(sk); 914 struct tipc_port *tport = tipc_sk_port(sk);
920 struct sk_buff *buf; 915 struct sk_buff *buf;
921 struct tipc_msg *msg; 916 struct tipc_msg *msg;
917 long timeout;
922 unsigned int sz; 918 unsigned int sz;
923 u32 err; 919 u32 err;
924 int res; 920 int res;
925 921
926 /* Catch invalid receive requests */ 922 /* Catch invalid receive requests */
927 923
928 if (m->msg_iovlen != 1)
929 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
930
931 if (unlikely(!buf_len)) 924 if (unlikely(!buf_len))
932 return -EINVAL; 925 return -EINVAL;
933 926
@@ -938,6 +931,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
938 goto exit; 931 goto exit;
939 } 932 }
940 933
934 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
941restart: 935restart:
942 936
943 /* Look for a message in receive queue; wait if necessary */ 937 /* Look for a message in receive queue; wait if necessary */
@@ -947,17 +941,15 @@ restart:
947 res = -ENOTCONN; 941 res = -ENOTCONN;
948 goto exit; 942 goto exit;
949 } 943 }
950 if (flags & MSG_DONTWAIT) { 944 if (timeout <= 0L) {
951 res = -EWOULDBLOCK; 945 res = timeout ? timeout : -EWOULDBLOCK;
952 goto exit; 946 goto exit;
953 } 947 }
954 release_sock(sk); 948 release_sock(sk);
955 res = wait_event_interruptible(*sk_sleep(sk), 949 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
956 (!skb_queue_empty(&sk->sk_receive_queue) || 950 tipc_rx_ready(sock),
957 (sock->state == SS_DISCONNECTING))); 951 timeout);
958 lock_sock(sk); 952 lock_sock(sk);
959 if (res)
960 goto exit;
961 } 953 }
962 954
963 /* Look at first message in receive queue */ 955 /* Look at first message in receive queue */
@@ -999,11 +991,10 @@ restart:
999 sz = buf_len; 991 sz = buf_len;
1000 m->msg_flags |= MSG_TRUNC; 992 m->msg_flags |= MSG_TRUNC;
1001 } 993 }
1002 if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg), 994 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg),
1003 sz))) { 995 m->msg_iov, sz);
1004 res = -EFAULT; 996 if (res)
1005 goto exit; 997 goto exit;
1006 }
1007 res = sz; 998 res = sz;
1008 } else { 999 } else {
1009 if ((sock->state == SS_READY) || 1000 if ((sock->state == SS_READY) ||
@@ -1046,19 +1037,15 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1046 struct tipc_port *tport = tipc_sk_port(sk); 1037 struct tipc_port *tport = tipc_sk_port(sk);
1047 struct sk_buff *buf; 1038 struct sk_buff *buf;
1048 struct tipc_msg *msg; 1039 struct tipc_msg *msg;
1040 long timeout;
1049 unsigned int sz; 1041 unsigned int sz;
1050 int sz_to_copy, target, needed; 1042 int sz_to_copy, target, needed;
1051 int sz_copied = 0; 1043 int sz_copied = 0;
1052 char __user *crs = m->msg_iov->iov_base;
1053 unsigned char *buf_crs;
1054 u32 err; 1044 u32 err;
1055 int res = 0; 1045 int res = 0;
1056 1046
1057 /* Catch invalid receive attempts */ 1047 /* Catch invalid receive attempts */
1058 1048
1059 if (m->msg_iovlen != 1)
1060 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
1061
1062 if (unlikely(!buf_len)) 1049 if (unlikely(!buf_len))
1063 return -EINVAL; 1050 return -EINVAL;
1064 1051
@@ -1071,7 +1058,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1071 } 1058 }
1072 1059
1073 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1060 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1074 1061 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1075restart: 1062restart:
1076 1063
1077 /* Look for a message in receive queue; wait if necessary */ 1064 /* Look for a message in receive queue; wait if necessary */
@@ -1081,17 +1068,15 @@ restart:
1081 res = -ENOTCONN; 1068 res = -ENOTCONN;
1082 goto exit; 1069 goto exit;
1083 } 1070 }
1084 if (flags & MSG_DONTWAIT) { 1071 if (timeout <= 0L) {
1085 res = -EWOULDBLOCK; 1072 res = timeout ? timeout : -EWOULDBLOCK;
1086 goto exit; 1073 goto exit;
1087 } 1074 }
1088 release_sock(sk); 1075 release_sock(sk);
1089 res = wait_event_interruptible(*sk_sleep(sk), 1076 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
1090 (!skb_queue_empty(&sk->sk_receive_queue) || 1077 tipc_rx_ready(sock),
1091 (sock->state == SS_DISCONNECTING))); 1078 timeout);
1092 lock_sock(sk); 1079 lock_sock(sk);
1093 if (res)
1094 goto exit;
1095 } 1080 }
1096 1081
1097 /* Look at first message in receive queue */ 1082 /* Look at first message in receive queue */
@@ -1120,24 +1105,25 @@ restart:
1120 /* Capture message data (if valid) & compute return value (always) */ 1105 /* Capture message data (if valid) & compute return value (always) */
1121 1106
1122 if (!err) { 1107 if (!err) {
1123 buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle); 1108 u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle);
1124 sz = (unsigned char *)msg + msg_size(msg) - buf_crs;
1125 1109
1110 sz -= offset;
1126 needed = (buf_len - sz_copied); 1111 needed = (buf_len - sz_copied);
1127 sz_to_copy = (sz <= needed) ? sz : needed; 1112 sz_to_copy = (sz <= needed) ? sz : needed;
1128 if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) { 1113
1129 res = -EFAULT; 1114 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset,
1115 m->msg_iov, sz_to_copy);
1116 if (res)
1130 goto exit; 1117 goto exit;
1131 } 1118
1132 sz_copied += sz_to_copy; 1119 sz_copied += sz_to_copy;
1133 1120
1134 if (sz_to_copy < sz) { 1121 if (sz_to_copy < sz) {
1135 if (!(flags & MSG_PEEK)) 1122 if (!(flags & MSG_PEEK))
1136 TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy; 1123 TIPC_SKB_CB(buf)->handle =
1124 (void *)(unsigned long)(offset + sz_to_copy);
1137 goto exit; 1125 goto exit;
1138 } 1126 }
1139
1140 crs += sz_to_copy;
1141 } else { 1127 } else {
1142 if (sz_copied != 0) 1128 if (sz_copied != 0)
1143 goto exit; /* can't add error msg to valid data */ 1129 goto exit; /* can't add error msg to valid data */
@@ -1227,42 +1213,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1227 */ 1213 */
1228 1214
1229 if (sock->state == SS_READY) { 1215 if (sock->state == SS_READY) {
1230 if (msg_connected(msg)) { 1216 if (msg_connected(msg))
1231 msg_dbg(msg, "dispatch filter 1\n");
1232 return TIPC_ERR_NO_PORT; 1217 return TIPC_ERR_NO_PORT;
1233 }
1234 } else { 1218 } else {
1235 if (msg_mcast(msg)) { 1219 if (msg_mcast(msg))
1236 msg_dbg(msg, "dispatch filter 2\n");
1237 return TIPC_ERR_NO_PORT; 1220 return TIPC_ERR_NO_PORT;
1238 }
1239 if (sock->state == SS_CONNECTED) { 1221 if (sock->state == SS_CONNECTED) {
1240 if (!msg_connected(msg)) { 1222 if (!msg_connected(msg))
1241 msg_dbg(msg, "dispatch filter 3\n");
1242 return TIPC_ERR_NO_PORT; 1223 return TIPC_ERR_NO_PORT;
1243 } 1224 } else if (sock->state == SS_CONNECTING) {
1244 } 1225 if (!msg_connected(msg) && (msg_errcode(msg) == 0))
1245 else if (sock->state == SS_CONNECTING) {
1246 if (!msg_connected(msg) && (msg_errcode(msg) == 0)) {
1247 msg_dbg(msg, "dispatch filter 4\n");
1248 return TIPC_ERR_NO_PORT; 1226 return TIPC_ERR_NO_PORT;
1249 } 1227 } else if (sock->state == SS_LISTENING) {
1250 } 1228 if (msg_connected(msg) || msg_errcode(msg))
1251 else if (sock->state == SS_LISTENING) {
1252 if (msg_connected(msg) || msg_errcode(msg)) {
1253 msg_dbg(msg, "dispatch filter 5\n");
1254 return TIPC_ERR_NO_PORT; 1229 return TIPC_ERR_NO_PORT;
1255 } 1230 } else if (sock->state == SS_DISCONNECTING) {
1256 }
1257 else if (sock->state == SS_DISCONNECTING) {
1258 msg_dbg(msg, "dispatch filter 6\n");
1259 return TIPC_ERR_NO_PORT; 1231 return TIPC_ERR_NO_PORT;
1260 } 1232 } else /* (sock->state == SS_UNCONNECTED) */ {
1261 else /* (sock->state == SS_UNCONNECTED) */ { 1233 if (msg_connected(msg) || msg_errcode(msg))
1262 if (msg_connected(msg) || msg_errcode(msg)) {
1263 msg_dbg(msg, "dispatch filter 7\n");
1264 return TIPC_ERR_NO_PORT; 1234 return TIPC_ERR_NO_PORT;
1265 }
1266 } 1235 }
1267 } 1236 }
1268 1237
@@ -1281,8 +1250,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1281 1250
1282 /* Enqueue message (finally!) */ 1251 /* Enqueue message (finally!) */
1283 1252
1284 msg_dbg(msg, "<DISP<: "); 1253 TIPC_SKB_CB(buf)->handle = 0;
1285 TIPC_SKB_CB(buf)->handle = msg_data(msg);
1286 atomic_inc(&tipc_queue_size); 1254 atomic_inc(&tipc_queue_size);
1287 __skb_queue_tail(&sk->sk_receive_queue, buf); 1255 __skb_queue_tail(&sk->sk_receive_queue, buf);
1288 1256
@@ -1442,9 +1410,8 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1442 m.msg_name = dest; 1410 m.msg_name = dest;
1443 m.msg_namelen = destlen; 1411 m.msg_namelen = destlen;
1444 res = send_msg(NULL, sock, &m, 0); 1412 res = send_msg(NULL, sock, &m, 0);
1445 if (res < 0) { 1413 if (res < 0)
1446 goto exit; 1414 goto exit;
1447 }
1448 1415
1449 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ 1416 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
1450 1417
@@ -1466,11 +1433,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1466 advance_rx_queue(sk); 1433 advance_rx_queue(sk);
1467 } 1434 }
1468 } else { 1435 } else {
1469 if (sock->state == SS_CONNECTED) { 1436 if (sock->state == SS_CONNECTED)
1470 res = -EISCONN; 1437 res = -EISCONN;
1471 } else { 1438 else
1472 res = -ECONNREFUSED; 1439 res = -ECONNREFUSED;
1473 }
1474 } 1440 }
1475 } else { 1441 } else {
1476 if (res == 0) 1442 if (res == 0)
@@ -1589,7 +1555,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1589 * Respond to 'SYN+' by queuing it on new socket. 1555 * Respond to 'SYN+' by queuing it on new socket.
1590 */ 1556 */
1591 1557
1592 msg_dbg(msg,"<ACC<: ");
1593 if (!msg_data_sz(msg)) { 1558 if (!msg_data_sz(msg)) {
1594 struct msghdr m = {NULL,}; 1559 struct msghdr m = {NULL,};
1595 1560
@@ -1637,7 +1602,7 @@ restart:
1637 buf = __skb_dequeue(&sk->sk_receive_queue); 1602 buf = __skb_dequeue(&sk->sk_receive_queue);
1638 if (buf) { 1603 if (buf) {
1639 atomic_dec(&tipc_queue_size); 1604 atomic_dec(&tipc_queue_size);
1640 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) { 1605 if (TIPC_SKB_CB(buf)->handle != 0) {
1641 buf_discard(buf); 1606 buf_discard(buf);
1642 goto restart; 1607 goto restart;
1643 } 1608 }
@@ -1697,7 +1662,8 @@ static int setsockopt(struct socket *sock,
1697 return -ENOPROTOOPT; 1662 return -ENOPROTOOPT;
1698 if (ol < sizeof(value)) 1663 if (ol < sizeof(value))
1699 return -EINVAL; 1664 return -EINVAL;
1700 if ((res = get_user(value, (u32 __user *)ov))) 1665 res = get_user(value, (u32 __user *)ov);
1666 if (res)
1701 return res; 1667 return res;
1702 1668
1703 lock_sock(sk); 1669 lock_sock(sk);
@@ -1755,7 +1721,8 @@ static int getsockopt(struct socket *sock,
1755 return put_user(0, ol); 1721 return put_user(0, ol);
1756 if (lvl != SOL_TIPC) 1722 if (lvl != SOL_TIPC)
1757 return -ENOPROTOOPT; 1723 return -ENOPROTOOPT;
1758 if ((res = get_user(len, ol))) 1724 res = get_user(len, ol);
1725 if (res)
1759 return res; 1726 return res;
1760 1727
1761 lock_sock(sk); 1728 lock_sock(sk);
@@ -1774,10 +1741,10 @@ static int getsockopt(struct socket *sock,
1774 value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); 1741 value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout);
1775 /* no need to set "res", since already 0 at this point */ 1742 /* no need to set "res", since already 0 at this point */
1776 break; 1743 break;
1777 case TIPC_NODE_RECVQ_DEPTH: 1744 case TIPC_NODE_RECVQ_DEPTH:
1778 value = (u32)atomic_read(&tipc_queue_size); 1745 value = (u32)atomic_read(&tipc_queue_size);
1779 break; 1746 break;
1780 case TIPC_SOCK_RECVQ_DEPTH: 1747 case TIPC_SOCK_RECVQ_DEPTH:
1781 value = skb_queue_len(&sk->sk_receive_queue); 1748 value = skb_queue_len(&sk->sk_receive_queue);
1782 break; 1749 break;
1783 default: 1750 default:
@@ -1786,20 +1753,16 @@ static int getsockopt(struct socket *sock,
1786 1753
1787 release_sock(sk); 1754 release_sock(sk);
1788 1755
1789 if (res) { 1756 if (res)
1790 /* "get" failed */ 1757 return res; /* "get" failed */
1791 }
1792 else if (len < sizeof(value)) {
1793 res = -EINVAL;
1794 }
1795 else if (copy_to_user(ov, &value, sizeof(value))) {
1796 res = -EFAULT;
1797 }
1798 else {
1799 res = put_user(sizeof(value), ol);
1800 }
1801 1758
1802 return res; 1759 if (len < sizeof(value))
1760 return -EINVAL;
1761
1762 if (copy_to_user(ov, &value, sizeof(value)))
1763 return -EFAULT;
1764
1765 return put_user(sizeof(value), ol);
1803} 1766}
1804 1767
1805/** 1768/**
@@ -1807,7 +1770,7 @@ static int getsockopt(struct socket *sock,
1807 */ 1770 */
1808 1771
1809static const struct proto_ops msg_ops = { 1772static const struct proto_ops msg_ops = {
1810 .owner = THIS_MODULE, 1773 .owner = THIS_MODULE,
1811 .family = AF_TIPC, 1774 .family = AF_TIPC,
1812 .release = release, 1775 .release = release,
1813 .bind = bind, 1776 .bind = bind,
@@ -1828,7 +1791,7 @@ static const struct proto_ops msg_ops = {
1828}; 1791};
1829 1792
1830static const struct proto_ops packet_ops = { 1793static const struct proto_ops packet_ops = {
1831 .owner = THIS_MODULE, 1794 .owner = THIS_MODULE,
1832 .family = AF_TIPC, 1795 .family = AF_TIPC,
1833 .release = release, 1796 .release = release,
1834 .bind = bind, 1797 .bind = bind,
@@ -1849,7 +1812,7 @@ static const struct proto_ops packet_ops = {
1849}; 1812};
1850 1813
1851static const struct proto_ops stream_ops = { 1814static const struct proto_ops stream_ops = {
1852 .owner = THIS_MODULE, 1815 .owner = THIS_MODULE,
1853 .family = AF_TIPC, 1816 .family = AF_TIPC,
1854 .release = release, 1817 .release = release,
1855 .bind = bind, 1818 .bind = bind,
@@ -1870,7 +1833,7 @@ static const struct proto_ops stream_ops = {
1870}; 1833};
1871 1834
1872static const struct net_proto_family tipc_family_ops = { 1835static const struct net_proto_family tipc_family_ops = {
1873 .owner = THIS_MODULE, 1836 .owner = THIS_MODULE,
1874 .family = AF_TIPC, 1837 .family = AF_TIPC,
1875 .create = tipc_create 1838 .create = tipc_create
1876}; 1839};
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 33313961d010..aae9eae13404 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -2,7 +2,7 @@
2 * net/tipc/subscr.c: TIPC network topology service 2 * net/tipc/subscr.c: TIPC network topology service
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-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
@@ -35,10 +35,8 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "name_table.h" 38#include "name_table.h"
40#include "port.h" 39#include "port.h"
41#include "ref.h"
42#include "subscr.h" 40#include "subscr.h"
43 41
44/** 42/**
@@ -66,14 +64,13 @@ struct subscriber {
66 */ 64 */
67 65
68struct top_srv { 66struct top_srv {
69 u32 user_ref;
70 u32 setup_port; 67 u32 setup_port;
71 atomic_t subscription_count; 68 atomic_t subscription_count;
72 struct list_head subscriber_list; 69 struct list_head subscriber_list;
73 spinlock_t lock; 70 spinlock_t lock;
74}; 71};
75 72
76static struct top_srv topsrv = { 0 }; 73static struct top_srv topsrv;
77 74
78/** 75/**
79 * htohl - convert value to endianness used by destination 76 * htohl - convert value to endianness used by destination
@@ -163,7 +160,7 @@ void tipc_subscr_report_overlap(struct subscription *sub,
163 160
164static void subscr_timeout(struct subscription *sub) 161static void subscr_timeout(struct subscription *sub)
165{ 162{
166 struct port *server_port; 163 struct tipc_port *server_port;
167 164
168 /* Validate server port reference (in case subscriber is terminating) */ 165 /* Validate server port reference (in case subscriber is terminating) */
169 166
@@ -252,8 +249,6 @@ static void subscr_terminate(struct subscriber *subscriber)
252 k_cancel_timer(&sub->timer); 249 k_cancel_timer(&sub->timer);
253 k_term_timer(&sub->timer); 250 k_term_timer(&sub->timer);
254 } 251 }
255 dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n",
256 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
257 subscr_del(sub); 252 subscr_del(sub);
258 } 253 }
259 254
@@ -310,8 +305,6 @@ static void subscr_cancel(struct tipc_subscr *s,
310 k_term_timer(&sub->timer); 305 k_term_timer(&sub->timer);
311 spin_lock_bh(subscriber->lock); 306 spin_lock_bh(subscriber->lock);
312 } 307 }
313 dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n",
314 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
315 subscr_del(sub); 308 subscr_del(sub);
316} 309}
317 310
@@ -479,8 +472,6 @@ static void subscr_named_msg_event(void *usr_handle,
479 struct tipc_portid const *orig, 472 struct tipc_portid const *orig,
480 struct tipc_name_seq const *dest) 473 struct tipc_name_seq const *dest)
481{ 474{
482 static struct iovec msg_sect = {NULL, 0};
483
484 struct subscriber *subscriber; 475 struct subscriber *subscriber;
485 u32 server_port_ref; 476 u32 server_port_ref;
486 477
@@ -496,8 +487,7 @@ static void subscr_named_msg_event(void *usr_handle,
496 487
497 /* Create server port & establish connection to subscriber */ 488 /* Create server port & establish connection to subscriber */
498 489
499 tipc_createport(topsrv.user_ref, 490 tipc_createport(subscriber,
500 subscriber,
501 importance, 491 importance,
502 NULL, 492 NULL,
503 NULL, 493 NULL,
@@ -516,7 +506,7 @@ static void subscr_named_msg_event(void *usr_handle,
516 506
517 /* Lock server port (& save lock address for future use) */ 507 /* Lock server port (& save lock address for future use) */
518 508
519 subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock; 509 subscriber->lock = tipc_port_lock(subscriber->port_ref)->lock;
520 510
521 /* Add subscriber to topology server's subscriber list */ 511 /* Add subscriber to topology server's subscriber list */
522 512
@@ -531,7 +521,7 @@ static void subscr_named_msg_event(void *usr_handle,
531 521
532 /* Send an ACK- to complete connection handshaking */ 522 /* Send an ACK- to complete connection handshaking */
533 523
534 tipc_send(server_port_ref, 1, &msg_sect); 524 tipc_send(server_port_ref, 0, NULL);
535 525
536 /* Handle optional subscription request */ 526 /* Handle optional subscription request */
537 527
@@ -544,21 +534,13 @@ static void subscr_named_msg_event(void *usr_handle,
544int tipc_subscr_start(void) 534int tipc_subscr_start(void)
545{ 535{
546 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV}; 536 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV};
547 int res = -1; 537 int res;
548 538
549 memset(&topsrv, 0, sizeof (topsrv)); 539 memset(&topsrv, 0, sizeof(topsrv));
550 spin_lock_init(&topsrv.lock); 540 spin_lock_init(&topsrv.lock);
551 INIT_LIST_HEAD(&topsrv.subscriber_list); 541 INIT_LIST_HEAD(&topsrv.subscriber_list);
552 542
553 spin_lock_bh(&topsrv.lock); 543 res = tipc_createport(NULL,
554 res = tipc_attach(&topsrv.user_ref, NULL, NULL);
555 if (res) {
556 spin_unlock_bh(&topsrv.lock);
557 return res;
558 }
559
560 res = tipc_createport(topsrv.user_ref,
561 NULL,
562 TIPC_CRITICAL_IMPORTANCE, 544 TIPC_CRITICAL_IMPORTANCE,
563 NULL, 545 NULL,
564 NULL, 546 NULL,
@@ -572,17 +554,16 @@ int tipc_subscr_start(void)
572 goto failed; 554 goto failed;
573 555
574 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq); 556 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
575 if (res) 557 if (res) {
558 tipc_deleteport(topsrv.setup_port);
559 topsrv.setup_port = 0;
576 goto failed; 560 goto failed;
561 }
577 562
578 spin_unlock_bh(&topsrv.lock);
579 return 0; 563 return 0;
580 564
581failed: 565failed:
582 err("Failed to create subscription service\n"); 566 err("Failed to create subscription service\n");
583 tipc_detach(topsrv.user_ref);
584 topsrv.user_ref = 0;
585 spin_unlock_bh(&topsrv.lock);
586 return res; 567 return res;
587} 568}
588 569
@@ -592,8 +573,10 @@ void tipc_subscr_stop(void)
592 struct subscriber *subscriber_temp; 573 struct subscriber *subscriber_temp;
593 spinlock_t *subscriber_lock; 574 spinlock_t *subscriber_lock;
594 575
595 if (topsrv.user_ref) { 576 if (topsrv.setup_port) {
596 tipc_deleteport(topsrv.setup_port); 577 tipc_deleteport(topsrv.setup_port);
578 topsrv.setup_port = 0;
579
597 list_for_each_entry_safe(subscriber, subscriber_temp, 580 list_for_each_entry_safe(subscriber, subscriber_temp,
598 &topsrv.subscriber_list, 581 &topsrv.subscriber_list,
599 subscriber_list) { 582 subscriber_list) {
@@ -602,7 +585,5 @@ void tipc_subscr_stop(void)
602 subscr_terminate(subscriber); 585 subscr_terminate(subscriber);
603 spin_unlock_bh(subscriber_lock); 586 spin_unlock_bh(subscriber_lock);
604 } 587 }
605 tipc_detach(topsrv.user_ref);
606 topsrv.user_ref = 0;
607 } 588 }
608} 589}
diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c
deleted file mode 100644
index 506928803162..000000000000
--- a/net/tipc/user_reg.c
+++ /dev/null
@@ -1,264 +0,0 @@
1/*
2 * net/tipc/user_reg.c: TIPC user registry code
3 *
4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "core.h"
38#include "user_reg.h"
39
40/*
41 * TIPC user registry keeps track of users of the tipc_port interface.
42 *
43 * The registry utilizes an array of "TIPC user" entries;
44 * a user's ID is the index of their associated array entry.
45 * Array entry 0 is not used, so userid 0 is not valid;
46 * TIPC sometimes uses this value to denote an anonymous user.
47 * The list of free entries is initially chained from last entry to entry 1.
48 */
49
50/**
51 * struct tipc_user - registered TIPC user info
52 * @next: index of next free registry entry (or -1 for an allocated entry)
53 * @callback: ptr to routine to call when TIPC mode changes (NULL if none)
54 * @usr_handle: user-defined value passed to callback routine
55 * @ports: list of user ports owned by the user
56 */
57
58struct tipc_user {
59 int next;
60 tipc_mode_event callback;
61 void *usr_handle;
62 struct list_head ports;
63};
64
65#define MAX_USERID 64
66#define USER_LIST_SIZE ((MAX_USERID + 1) * sizeof(struct tipc_user))
67
68static struct tipc_user *users = NULL;
69static u32 next_free_user = MAX_USERID + 1;
70static DEFINE_SPINLOCK(reg_lock);
71
72/**
73 * reg_init - create TIPC user registry (but don't activate it)
74 *
75 * If registry has been pre-initialized it is left "as is".
76 * NOTE: This routine may be called when TIPC is inactive.
77 */
78
79static int reg_init(void)
80{
81 u32 i;
82
83 spin_lock_bh(&reg_lock);
84 if (!users) {
85 users = kzalloc(USER_LIST_SIZE, GFP_ATOMIC);
86 if (users) {
87 for (i = 1; i <= MAX_USERID; i++) {
88 users[i].next = i - 1;
89 }
90 next_free_user = MAX_USERID;
91 }
92 }
93 spin_unlock_bh(&reg_lock);
94 return users ? 0 : -ENOMEM;
95}
96
97/**
98 * reg_callback - inform TIPC user about current operating mode
99 */
100
101static void reg_callback(struct tipc_user *user_ptr)
102{
103 tipc_mode_event cb;
104 void *arg;
105
106 spin_lock_bh(&reg_lock);
107 cb = user_ptr->callback;
108 arg = user_ptr->usr_handle;
109 spin_unlock_bh(&reg_lock);
110
111 if (cb)
112 cb(arg, tipc_mode, tipc_own_addr);
113}
114
115/**
116 * tipc_reg_start - activate TIPC user registry
117 */
118
119int tipc_reg_start(void)
120{
121 u32 u;
122 int res;
123
124 if ((res = reg_init()))
125 return res;
126
127 for (u = 1; u <= MAX_USERID; u++) {
128 if (users[u].callback)
129 tipc_k_signal((Handler)reg_callback,
130 (unsigned long)&users[u]);
131 }
132 return 0;
133}
134
135/**
136 * tipc_reg_stop - shut down & delete TIPC user registry
137 */
138
139void tipc_reg_stop(void)
140{
141 int id;
142
143 if (!users)
144 return;
145
146 for (id = 1; id <= MAX_USERID; id++) {
147 if (users[id].callback)
148 reg_callback(&users[id]);
149 }
150 kfree(users);
151 users = NULL;
152}
153
154/**
155 * tipc_attach - register a TIPC user
156 *
157 * NOTE: This routine may be called when TIPC is inactive.
158 */
159
160int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle)
161{
162 struct tipc_user *user_ptr;
163
164 if ((tipc_mode == TIPC_NOT_RUNNING) && !cb)
165 return -ENOPROTOOPT;
166 if (!users)
167 reg_init();
168
169 spin_lock_bh(&reg_lock);
170 if (!next_free_user) {
171 spin_unlock_bh(&reg_lock);
172 return -EBUSY;
173 }
174 user_ptr = &users[next_free_user];
175 *userid = next_free_user;
176 next_free_user = user_ptr->next;
177 user_ptr->next = -1;
178 spin_unlock_bh(&reg_lock);
179
180 user_ptr->callback = cb;
181 user_ptr->usr_handle = usr_handle;
182 INIT_LIST_HEAD(&user_ptr->ports);
183 atomic_inc(&tipc_user_count);
184
185 if (cb && (tipc_mode != TIPC_NOT_RUNNING))
186 tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr);
187 return 0;
188}
189
190/**
191 * tipc_detach - deregister a TIPC user
192 */
193
194void tipc_detach(u32 userid)
195{
196 struct tipc_user *user_ptr;
197 struct list_head ports_temp;
198 struct user_port *up_ptr, *temp_up_ptr;
199
200 if ((userid == 0) || (userid > MAX_USERID))
201 return;
202
203 spin_lock_bh(&reg_lock);
204 if ((!users) || (users[userid].next >= 0)) {
205 spin_unlock_bh(&reg_lock);
206 return;
207 }
208
209 user_ptr = &users[userid];
210 user_ptr->callback = NULL;
211 INIT_LIST_HEAD(&ports_temp);
212 list_splice(&user_ptr->ports, &ports_temp);
213 user_ptr->next = next_free_user;
214 next_free_user = userid;
215 spin_unlock_bh(&reg_lock);
216
217 atomic_dec(&tipc_user_count);
218
219 list_for_each_entry_safe(up_ptr, temp_up_ptr, &ports_temp, uport_list) {
220 tipc_deleteport(up_ptr->ref);
221 }
222}
223
224/**
225 * tipc_reg_add_port - register a user's driver port
226 */
227
228int tipc_reg_add_port(struct user_port *up_ptr)
229{
230 struct tipc_user *user_ptr;
231
232 if (up_ptr->user_ref == 0)
233 return 0;
234 if (up_ptr->user_ref > MAX_USERID)
235 return -EINVAL;
236 if ((tipc_mode == TIPC_NOT_RUNNING) || !users )
237 return -ENOPROTOOPT;
238
239 spin_lock_bh(&reg_lock);
240 user_ptr = &users[up_ptr->user_ref];
241 list_add(&up_ptr->uport_list, &user_ptr->ports);
242 spin_unlock_bh(&reg_lock);
243 return 0;
244}
245
246/**
247 * tipc_reg_remove_port - deregister a user's driver port
248 */
249
250int tipc_reg_remove_port(struct user_port *up_ptr)
251{
252 if (up_ptr->user_ref == 0)
253 return 0;
254 if (up_ptr->user_ref > MAX_USERID)
255 return -EINVAL;
256 if (!users )
257 return -ENOPROTOOPT;
258
259 spin_lock_bh(&reg_lock);
260 list_del_init(&up_ptr->uport_list);
261 spin_unlock_bh(&reg_lock);
262 return 0;
263}
264
diff --git a/net/tipc/user_reg.h b/net/tipc/user_reg.h
deleted file mode 100644
index 81dc12e2882f..000000000000
--- a/net/tipc/user_reg.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * net/tipc/user_reg.h: Include file for TIPC user registry code
3 *
4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _TIPC_USER_REG_H
38#define _TIPC_USER_REG_H
39
40#include "port.h"
41
42int tipc_reg_start(void);
43void tipc_reg_stop(void);
44
45int tipc_reg_add_port(struct user_port *up_ptr);
46int tipc_reg_remove_port(struct user_port *up_ptr);
47
48#endif
diff --git a/net/tipc/zone.c b/net/tipc/zone.c
deleted file mode 100644
index 83f8b5e91fc8..000000000000
--- a/net/tipc/zone.c
+++ /dev/null
@@ -1,162 +0,0 @@
1/*
2 * net/tipc/zone.c: TIPC zone management routines
3 *
4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "core.h"
38#include "zone.h"
39#include "net.h"
40#include "addr.h"
41#include "node_subscr.h"
42#include "cluster.h"
43#include "node.h"
44
45struct _zone *tipc_zone_create(u32 addr)
46{
47 struct _zone *z_ptr;
48 u32 z_num;
49
50 if (!tipc_addr_domain_valid(addr)) {
51 err("Zone creation failed, invalid domain 0x%x\n", addr);
52 return NULL;
53 }
54
55 z_ptr = kzalloc(sizeof(*z_ptr), GFP_ATOMIC);
56 if (!z_ptr) {
57 warn("Zone creation failed, insufficient memory\n");
58 return NULL;
59 }
60
61 z_num = tipc_zone(addr);
62 z_ptr->addr = tipc_addr(z_num, 0, 0);
63 tipc_net.zones[z_num] = z_ptr;
64 return z_ptr;
65}
66
67void tipc_zone_delete(struct _zone *z_ptr)
68{
69 u32 c_num;
70
71 if (!z_ptr)
72 return;
73 for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
74 tipc_cltr_delete(z_ptr->clusters[c_num]);
75 }
76 kfree(z_ptr);
77}
78
79void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr)
80{
81 u32 c_num = tipc_cluster(c_ptr->addr);
82
83 assert(c_ptr->addr);
84 assert(c_num <= tipc_max_clusters);
85 assert(z_ptr->clusters[c_num] == NULL);
86 z_ptr->clusters[c_num] = c_ptr;
87}
88
89void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router)
90{
91 u32 c_num;
92
93 for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
94 if (z_ptr->clusters[c_num]) {
95 tipc_cltr_remove_as_router(z_ptr->clusters[c_num],
96 router);
97 }
98 }
99}
100
101void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest)
102{
103 u32 c_num;
104
105 for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
106 if (z_ptr->clusters[c_num]) {
107 if (in_own_cluster(z_ptr->addr))
108 continue;
109 tipc_cltr_send_ext_routes(z_ptr->clusters[c_num], dest);
110 }
111 }
112}
113
114struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref)
115{
116 struct cluster *c_ptr;
117 struct tipc_node *n_ptr;
118 u32 c_num;
119
120 if (!z_ptr)
121 return NULL;
122 c_ptr = z_ptr->clusters[tipc_cluster(addr)];
123 if (!c_ptr)
124 return NULL;
125 n_ptr = tipc_cltr_select_node(c_ptr, ref);
126 if (n_ptr)
127 return n_ptr;
128
129 /* Links to any other clusters within this zone ? */
130 for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
131 c_ptr = z_ptr->clusters[c_num];
132 if (!c_ptr)
133 return NULL;
134 n_ptr = tipc_cltr_select_node(c_ptr, ref);
135 if (n_ptr)
136 return n_ptr;
137 }
138 return NULL;
139}
140
141u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref)
142{
143 struct cluster *c_ptr;
144 u32 c_num;
145 u32 router;
146
147 if (!z_ptr)
148 return 0;
149 c_ptr = z_ptr->clusters[tipc_cluster(addr)];
150 router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0;
151 if (router)
152 return router;
153
154 /* Links to any other clusters within the zone? */
155 for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
156 c_ptr = z_ptr->clusters[c_num];
157 router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0;
158 if (router)
159 return router;
160 }
161 return 0;
162}
diff --git a/net/tipc/zone.h b/net/tipc/zone.h
deleted file mode 100644
index bd1c20ce9d06..000000000000
--- a/net/tipc/zone.h
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * net/tipc/zone.h: Include file for TIPC zone management routines
3 *
4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _TIPC_ZONE_H
38#define _TIPC_ZONE_H
39
40#include "node_subscr.h"
41#include "net.h"
42
43
44/**
45 * struct _zone - TIPC zone structure
46 * @addr: network address of zone
47 * @clusters: array of pointers to all clusters within zone
48 * @links: number of (unicast) links to zone
49 */
50
51struct _zone {
52 u32 addr;
53 struct cluster *clusters[2]; /* currently limited to just 1 cluster */
54 u32 links;
55};
56
57struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref);
58u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref);
59void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router);
60void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest);
61struct _zone *tipc_zone_create(u32 addr);
62void tipc_zone_delete(struct _zone *z_ptr);
63void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr);
64
65static inline struct _zone *tipc_zone_find(u32 addr)
66{
67 return tipc_net.zones[tipc_zone(addr)];
68}
69
70#endif