aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-13 01:06:28 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-13 01:06:28 -0500
commitf43dc23d5ea91fca257be02138a255f02d98e806 (patch)
treeb29722f6e965316e90ac97abf79923ced250dc21 /net/tipc
parentf8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff)
parent4162cf64973df51fc885825bc9ca4d055891c49f (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts: arch/sh/kernel/cpu/sh2/setup-sh7619.c arch/sh/kernel/cpu/sh2a/setup-mxg.c arch/sh/kernel/cpu/sh2a/setup-sh7201.c arch/sh/kernel/cpu/sh2a/setup-sh7203.c arch/sh/kernel/cpu/sh2a/setup-sh7206.c arch/sh/kernel/cpu/sh3/setup-sh7705.c arch/sh/kernel/cpu/sh3/setup-sh770x.c arch/sh/kernel/cpu/sh3/setup-sh7710.c arch/sh/kernel/cpu/sh3/setup-sh7720.c arch/sh/kernel/cpu/sh4/setup-sh4-202.c arch/sh/kernel/cpu/sh4/setup-sh7750.c arch/sh/kernel/cpu/sh4/setup-sh7760.c arch/sh/kernel/cpu/sh4a/setup-sh7343.c arch/sh/kernel/cpu/sh4a/setup-sh7366.c arch/sh/kernel/cpu/sh4a/setup-sh7722.c arch/sh/kernel/cpu/sh4a/setup-sh7723.c arch/sh/kernel/cpu/sh4a/setup-sh7724.c arch/sh/kernel/cpu/sh4a/setup-sh7763.c arch/sh/kernel/cpu/sh4a/setup-sh7770.c arch/sh/kernel/cpu/sh4a/setup-sh7780.c arch/sh/kernel/cpu/sh4a/setup-sh7785.c arch/sh/kernel/cpu/sh4a/setup-sh7786.c arch/sh/kernel/cpu/sh4a/setup-shx3.c arch/sh/kernel/cpu/sh5/setup-sh5.c drivers/serial/sh-sci.c drivers/serial/sh-sci.h include/linux/serial_sci.h
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/Kconfig86
-rw-r--r--net/tipc/Makefile4
-rw-r--r--net/tipc/addr.c49
-rw-r--r--net/tipc/addr.h62
-rw-r--r--net/tipc/bcast.c246
-rw-r--r--net/tipc/bcast.h117
-rw-r--r--net/tipc/bearer.c113
-rw-r--r--net/tipc/bearer.h89
-rw-r--r--net/tipc/cluster.c576
-rw-r--r--net/tipc/cluster.h92
-rw-r--r--net/tipc/config.c282
-rw-r--r--net/tipc/config.h7
-rw-r--r--net/tipc/core.c159
-rw-r--r--net/tipc/core.h109
-rw-r--r--net/tipc/discover.c66
-rw-r--r--net/tipc/discover.h7
-rw-r--r--net/tipc/eth_media.c62
-rw-r--r--net/tipc/handler.c2
-rw-r--r--net/tipc/link.c680
-rw-r--r--net/tipc/link.h57
-rw-r--r--net/tipc/log.c (renamed from net/tipc/dbg.c)120
-rw-r--r--net/tipc/log.h (renamed from net/tipc/dbg.h)9
-rw-r--r--net/tipc/msg.c167
-rw-r--r--net/tipc/msg.h288
-rw-r--r--net/tipc/name_distr.c51
-rw-r--r--net/tipc/name_table.c129
-rw-r--r--net/tipc/name_table.h2
-rw-r--r--net/tipc/net.c105
-rw-r--r--net/tipc/net.h14
-rw-r--r--net/tipc/netlink.c2
-rw-r--r--net/tipc/node.c368
-rw-r--r--net/tipc/node.h30
-rw-r--r--net/tipc/node_subscr.c2
-rw-r--r--net/tipc/port.c450
-rw-r--r--net/tipc/port.h143
-rw-r--r--net/tipc/ref.c49
-rw-r--r--net/tipc/ref.h1
-rw-r--r--net/tipc/socket.c293
-rw-r--r--net/tipc/subscr.c53
-rw-r--r--net/tipc/user_reg.c264
-rw-r--r--net/tipc/user_reg.h48
-rw-r--r--net/tipc/zone.c173
-rw-r--r--net/tipc/zone.h71
43 files changed, 1581 insertions, 4116 deletions
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index 3b30d1130b61..0436927369f3 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -10,7 +10,7 @@ menuconfig TIPC
10 specially designed for intra cluster communication. This protocol 10 specially designed for intra cluster communication. This protocol
11 originates from Ericsson where it has been used in carrier grade 11 originates from Ericsson where it has been used in carrier grade
12 cluster applications for many years. 12 cluster applications for many years.
13 13
14 For more information about TIPC, see http://tipc.sourceforge.net. 14 For more information about TIPC, see http://tipc.sourceforge.net.
15 15
16 This protocol support is also available as a module ( = code which 16 This protocol support is also available as a module ( = code which
@@ -23,82 +23,45 @@ menuconfig TIPC
23if TIPC 23if TIPC
24 24
25config TIPC_ADVANCED 25config TIPC_ADVANCED
26 bool "TIPC: Advanced configuration" 26 bool "Advanced TIPC configuration"
27 default n 27 default n
28 help 28 help
29 Saying Y here will open some advanced configuration 29 Saying Y here will open some advanced configuration for TIPC.
30 for TIPC. Most users do not need to bother, so if 30 Most users do not need to bother; if unsure, just say N.
31 unsure, just say N.
32
33config TIPC_ZONES
34 int "Maximum number of zones in network"
35 depends on TIPC_ADVANCED
36 default "3"
37 help
38 Max number of zones inside TIPC network. Max supported value
39 is 255 zones, minimum is 1
40
41 Default is 3 zones in a network; setting this to higher
42 allows more zones but might use more memory.
43
44config TIPC_CLUSTERS
45 int "Maximum number of clusters in a zone"
46 depends on TIPC_ADVANCED
47 default "1"
48 help
49 ***Only 1 (one cluster in a zone) is supported by current code.
50 Any value set here will be overridden.***
51
52 (Max number of clusters inside TIPC zone. Max supported
53 value is 4095 clusters, minimum is 1.
54
55 Default is 1; setting this to smaller value might save
56 some memory, setting it to higher
57 allows more clusters and might consume more memory.)
58 31
59config TIPC_NODES 32config TIPC_NODES
60 int "Maximum number of nodes in cluster" 33 int "Maximum number of nodes in a cluster"
61 depends on TIPC_ADVANCED 34 depends on TIPC_ADVANCED
35 range 8 2047
62 default "255" 36 default "255"
63 help 37 help
64 Maximum number of nodes inside a TIPC cluster. Maximum 38 Specifies how many nodes can be supported in a TIPC cluster.
65 supported value is 2047 nodes, minimum is 8. 39 Can range from 8 to 2047 nodes; default is 255.
66
67 Setting this to a smaller value saves some memory,
68 setting it to higher allows more nodes.
69
70config TIPC_SLAVE_NODES
71 int "Maximum number of slave nodes in cluster"
72 depends on TIPC_ADVANCED
73 default "0"
74 help
75 ***This capability is not supported by current code.***
76
77 Maximum number of slave nodes inside a TIPC cluster. Maximum
78 supported value is 2047 nodes, minimum is 0.
79 40
80 Setting this to a smaller value saves some memory, 41 Setting this to a smaller value saves some memory;
81 setting it to higher allows more nodes. 42 setting it to higher allows for more nodes.
82 43
83config TIPC_PORTS 44config TIPC_PORTS
84 int "Maximum number of ports in a node" 45 int "Maximum number of ports in a node"
85 depends on TIPC_ADVANCED 46 depends on TIPC_ADVANCED
47 range 127 65535
86 default "8191" 48 default "8191"
87 help 49 help
88 Maximum number of ports within a node. Maximum 50 Specifies how many ports can be supported by a node.
89 supported value is 64535 nodes, minimum is 127. 51 Can range from 127 to 65535 ports; default is 8191.
90 52
91 Setting this to a smaller value saves some memory, 53 Setting this to a smaller value saves some memory,
92 setting it to higher allows more ports. 54 setting it to higher allows for more ports.
93 55
94config TIPC_LOG 56config TIPC_LOG
95 int "Size of log buffer" 57 int "Size of log buffer"
96 depends on TIPC_ADVANCED 58 depends on TIPC_ADVANCED
97 default 0 59 range 0 32768
60 default "0"
98 help 61 help
99 Size (in bytes) of TIPC's internal log buffer, which records the 62 Size (in bytes) of TIPC's internal log buffer, which records the
100 occurrence of significant events. Maximum supported value 63 occurrence of significant events. Can range from 0 to 32768 bytes;
101 is 32768 bytes, minimum is 0. 64 default is 0.
102 65
103 There is no need to enable the log buffer unless the node will be 66 There is no need to enable the log buffer unless the node will be
104 managed remotely via TIPC. 67 managed remotely via TIPC.
@@ -107,9 +70,12 @@ config TIPC_DEBUG
107 bool "Enable debugging support" 70 bool "Enable debugging support"
108 default n 71 default n
109 help 72 help
110 This will enable debugging of TIPC. 73 Saying Y here enables TIPC debugging capabilities used by developers.
74 Most users do not need to bother; if unsure, just say N.
111 75
112 Only say Y here if you are having trouble with TIPC. It will 76 Enabling debugging support causes TIPC to display data about its
113 enable the display of detailed information about what is going on. 77 internal state when certain abnormal conditions occur. It also
78 makes it easy for developers to capture additional information of
79 interest using the dbg() or msg_dbg() macros.
114 80
115endif # TIPC 81endif # 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 e5207a11edf6..88463d9a6f12 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -35,16 +35,7 @@
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
44u32 tipc_get_addr(void)
45{
46 return tipc_own_addr;
47}
48 39
49/** 40/**
50 * tipc_addr_domain_valid - validates a network domain address 41 * tipc_addr_domain_valid - validates a network domain address
@@ -62,14 +53,8 @@ int tipc_addr_domain_valid(u32 addr)
62 u32 z = tipc_zone(addr); 53 u32 z = tipc_zone(addr);
63 u32 max_nodes = tipc_max_nodes; 54 u32 max_nodes = tipc_max_nodes;
64 55
65 if (is_slave(addr))
66 max_nodes = LOWEST_SLAVE + tipc_max_slaves;
67 if (n > max_nodes) 56 if (n > max_nodes)
68 return 0; 57 return 0;
69 if (c > tipc_max_clusters)
70 return 0;
71 if (z > tipc_max_zones)
72 return 0;
73 58
74 if (n && (!z || !c)) 59 if (n && (!z || !c))
75 return 0; 60 return 0;
@@ -89,6 +74,38 @@ int tipc_addr_domain_valid(u32 addr)
89 74
90int tipc_addr_node_valid(u32 addr) 75int tipc_addr_node_valid(u32 addr)
91{ 76{
92 return (tipc_addr_domain_valid(addr) && tipc_node(addr)); 77 return tipc_addr_domain_valid(addr) && tipc_node(addr);
78}
79
80int tipc_in_scope(u32 domain, u32 addr)
81{
82 if (!domain || (domain == addr))
83 return 1;
84 if (domain == (addr & 0xfffff000u)) /* domain <Z.C.0> */
85 return 1;
86 if (domain == (addr & 0xff000000u)) /* domain <Z.0.0> */
87 return 1;
88 return 0;
93} 89}
94 90
91/**
92 * tipc_addr_scope - convert message lookup domain to a 2-bit scope value
93 */
94
95int tipc_addr_scope(u32 domain)
96{
97 if (likely(!domain))
98 return TIPC_ZONE_SCOPE;
99 if (tipc_node(domain))
100 return TIPC_NODE_SCOPE;
101 if (tipc_cluster(domain))
102 return TIPC_CLUSTER_SCOPE;
103 return TIPC_ZONE_SCOPE;
104}
105
106char *tipc_addr_string_fill(char *string, u32 addr)
107{
108 snprintf(string, 16, "<%u.%u.%u>",
109 tipc_zone(addr), tipc_cluster(addr), tipc_node(addr));
110 return string;
111}
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 3ba67e6ce03e..2490fadd0caf 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,62 +37,11 @@
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)
41{
42 return tipc_node(tipc_own_addr);
43}
44
45static inline u32 own_cluster(void)
46{
47 return tipc_cluster(tipc_own_addr);
48}
49
50static inline u32 own_zone(void)
51{
52 return tipc_zone(tipc_own_addr);
53}
54
55static inline int in_own_cluster(u32 addr) 40static inline int in_own_cluster(u32 addr)
56{ 41{
57 return !((addr ^ tipc_own_addr) >> 12); 42 return !((addr ^ tipc_own_addr) >> 12);
58} 43}
59 44
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
70static inline int in_scope(u32 domain, u32 addr)
71{
72 if (!domain || (domain == addr))
73 return 1;
74 if (domain == (addr & 0xfffff000u)) /* domain <Z.C.0> */
75 return 1;
76 if (domain == (addr & 0xff000000u)) /* domain <Z.0.0> */
77 return 1;
78 return 0;
79}
80
81/**
82 * addr_scope - convert message lookup domain to equivalent 2-bit scope value
83 */
84
85static inline int addr_scope(u32 domain)
86{
87 if (likely(!domain))
88 return TIPC_ZONE_SCOPE;
89 if (tipc_node(domain))
90 return TIPC_NODE_SCOPE;
91 if (tipc_cluster(domain))
92 return TIPC_CLUSTER_SCOPE;
93 return TIPC_ZONE_SCOPE;
94}
95
96/** 45/**
97 * addr_domain - convert 2-bit scope value to equivalent message lookup domain 46 * addr_domain - convert 2-bit scope value to equivalent message lookup domain
98 * 47 *
@@ -110,14 +59,9 @@ static inline int addr_domain(int sc)
110 return tipc_addr(tipc_zone(tipc_own_addr), 0, 0); 59 return tipc_addr(tipc_zone(tipc_own_addr), 0, 0);
111} 60}
112 61
113static inline char *addr_string_fill(char *string, u32 addr)
114{
115 snprintf(string, 16, "<%u.%u.%u>",
116 tipc_zone(addr), tipc_cluster(addr), tipc_node(addr));
117 return string;
118}
119
120int tipc_addr_domain_valid(u32); 62int tipc_addr_domain_valid(u32);
121int tipc_addr_node_valid(u32 addr); 63int tipc_addr_node_valid(u32 addr);
122 64int tipc_in_scope(u32 domain, u32 addr);
65int tipc_addr_scope(u32 domain);
66char *tipc_addr_string_fill(char *string, u32 addr);
123#endif 67#endif
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index a3bfd4064912..70ab5ef48766 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -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.
@@ -114,13 +103,19 @@ struct bclink {
114}; 103};
115 104
116 105
117static struct bcbearer *bcbearer = NULL; 106static struct bcbearer *bcbearer;
118static struct bclink *bclink = NULL; 107static struct bclink *bclink;
119static struct link *bcl = NULL; 108static struct link *bcl;
120static DEFINE_SPINLOCK(bc_lock); 109static DEFINE_SPINLOCK(bc_lock);
121 110
122const char tipc_bclink_name[] = "multicast-link"; 111/* broadcast-capable node map */
112struct tipc_node_map tipc_bcast_nmap;
113
114const char tipc_bclink_name[] = "broadcast-link";
123 115
116static void tipc_nmap_diff(struct tipc_node_map *nm_a,
117 struct tipc_node_map *nm_b,
118 struct tipc_node_map *nm_diff);
124 119
125static u32 buf_seqno(struct sk_buff *buf) 120static u32 buf_seqno(struct sk_buff *buf)
126{ 121{
@@ -143,6 +138,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
143} 138}
144 139
145 140
141static void bclink_set_last_sent(void)
142{
143 if (bcl->next_out)
144 bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1);
145 else
146 bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1);
147}
148
149u32 tipc_bclink_get_last_sent(void)
150{
151 return bcl->fsm_msg_cnt;
152}
153
146/** 154/**
147 * bclink_set_gap - set gap according to contents of current deferred pkt queue 155 * bclink_set_gap - set gap according to contents of current deferred pkt queue
148 * 156 *
@@ -171,7 +179,7 @@ static void bclink_set_gap(struct tipc_node *n_ptr)
171 179
172static int bclink_ack_allowed(u32 n) 180static int bclink_ack_allowed(u32 n)
173{ 181{
174 return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag); 182 return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag;
175} 183}
176 184
177 185
@@ -188,9 +196,8 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
188 struct sk_buff *buf; 196 struct sk_buff *buf;
189 197
190 buf = bcl->first_out; 198 buf = bcl->first_out;
191 while (buf && less_eq(buf_seqno(buf), after)) { 199 while (buf && less_eq(buf_seqno(buf), after))
192 buf = buf->next; 200 buf = buf->next;
193 }
194 tipc_link_retransmit(bcl, buf, mod(to - after)); 201 tipc_link_retransmit(bcl, buf, mod(to - after));
195} 202}
196 203
@@ -216,9 +223,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
216 /* Skip over packets that node has previously acknowledged */ 223 /* Skip over packets that node has previously acknowledged */
217 224
218 crs = bcl->first_out; 225 crs = bcl->first_out;
219 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) { 226 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
220 crs = crs->next; 227 crs = crs->next;
221 }
222 228
223 /* Update packets that node is now acknowledging */ 229 /* Update packets that node is now acknowledging */
224 230
@@ -237,8 +243,10 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
237 243
238 /* Try resolving broadcast link congestion, if necessary */ 244 /* Try resolving broadcast link congestion, if necessary */
239 245
240 if (unlikely(bcl->next_out)) 246 if (unlikely(bcl->next_out)) {
241 tipc_link_push_queue(bcl); 247 tipc_link_push_queue(bcl);
248 bclink_set_last_sent();
249 }
242 if (unlikely(released && !list_empty(&bcl->waiting_ports))) 250 if (unlikely(released && !list_empty(&bcl->waiting_ports)))
243 tipc_link_wakeup_ports(bcl, 0); 251 tipc_link_wakeup_ports(bcl, 0);
244 spin_unlock_bh(&bc_lock); 252 spin_unlock_bh(&bc_lock);
@@ -272,10 +280,10 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
272 if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to)) 280 if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to))
273 return; 281 return;
274 282
275 buf = buf_acquire(INT_H_SIZE); 283 buf = tipc_buf_acquire(INT_H_SIZE);
276 if (buf) { 284 if (buf) {
277 msg = buf_msg(buf); 285 msg = buf_msg(buf);
278 msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 286 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
279 INT_H_SIZE, n_ptr->addr); 287 INT_H_SIZE, n_ptr->addr);
280 msg_set_mc_netid(msg, tipc_net_id); 288 msg_set_mc_netid(msg, tipc_net_id);
281 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 289 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
@@ -395,7 +403,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
395 if (unlikely(res == -ELINKCONG)) 403 if (unlikely(res == -ELINKCONG))
396 buf_discard(buf); 404 buf_discard(buf);
397 else 405 else
398 bcl->stats.sent_info++; 406 bclink_set_last_sent();
399 407
400 if (bcl->out_queue_size > bcl->stats.max_queue_sz) 408 if (bcl->out_queue_size > bcl->stats.max_queue_sz)
401 bcl->stats.max_queue_sz = bcl->out_queue_size; 409 bcl->stats.max_queue_sz = bcl->out_queue_size;
@@ -415,16 +423,14 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
415void tipc_bclink_recv_pkt(struct sk_buff *buf) 423void tipc_bclink_recv_pkt(struct sk_buff *buf)
416{ 424{
417#if (TIPC_BCAST_LOSS_RATE) 425#if (TIPC_BCAST_LOSS_RATE)
418 static int rx_count = 0; 426 static int rx_count;
419#endif 427#endif
420 struct tipc_msg *msg = buf_msg(buf); 428 struct tipc_msg *msg = buf_msg(buf);
421 struct tipc_node* node = tipc_node_find(msg_prevnode(msg)); 429 struct tipc_node *node = tipc_node_find(msg_prevnode(msg));
422 u32 next_in; 430 u32 next_in;
423 u32 seqno; 431 u32 seqno;
424 struct sk_buff *deferred; 432 struct sk_buff *deferred;
425 433
426 msg_dbg(msg, "<BC<<<");
427
428 if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported || 434 if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported ||
429 (msg_mc_netid(msg) != tipc_net_id))) { 435 (msg_mc_netid(msg) != tipc_net_id))) {
430 buf_discard(buf); 436 buf_discard(buf);
@@ -432,7 +438,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
432 } 438 }
433 439
434 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { 440 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
435 msg_dbg(msg, "<BCNACK<<<");
436 if (msg_destnode(msg) == tipc_own_addr) { 441 if (msg_destnode(msg) == tipc_own_addr) {
437 tipc_node_lock(node); 442 tipc_node_lock(node);
438 tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); 443 tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
@@ -529,15 +534,6 @@ receive:
529 tipc_node_unlock(node); 534 tipc_node_unlock(node);
530} 535}
531 536
532u32 tipc_bclink_get_last_sent(void)
533{
534 u32 last_sent = mod(bcl->next_out_no - 1);
535
536 if (bcl->next_out)
537 last_sent = mod(buf_seqno(bcl->next_out) - 1);
538 return last_sent;
539}
540
541u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) 537u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
542{ 538{
543 return (n_ptr->bclink.supported && 539 return (n_ptr->bclink.supported &&
@@ -558,31 +554,24 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
558 struct tipc_bearer *unused1, 554 struct tipc_bearer *unused1,
559 struct tipc_media_addr *unused2) 555 struct tipc_media_addr *unused2)
560{ 556{
561 static int send_count = 0;
562
563 int bp_index; 557 int bp_index;
564 int swap_time;
565 558
566 /* Prepare buffer for broadcasting (if first time trying to send it) */ 559 /* Prepare buffer for broadcasting (if first time trying to send it) */
567 560
568 if (likely(!msg_non_seq(buf_msg(buf)))) { 561 if (likely(!msg_non_seq(buf_msg(buf)))) {
569 struct tipc_msg *msg; 562 struct tipc_msg *msg;
570 563
571 assert(tipc_cltr_bcast_nodes.count != 0); 564 assert(tipc_bcast_nmap.count != 0);
572 bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); 565 bcbuf_set_acks(buf, tipc_bcast_nmap.count);
573 msg = buf_msg(buf); 566 msg = buf_msg(buf);
574 msg_set_non_seq(msg, 1); 567 msg_set_non_seq(msg, 1);
575 msg_set_mc_netid(msg, tipc_net_id); 568 msg_set_mc_netid(msg, tipc_net_id);
569 bcl->stats.sent_info++;
576 } 570 }
577 571
578 /* Determine if bearer pairs should be swapped following this attempt */
579
580 if ((swap_time = (++send_count >= 10)))
581 send_count = 0;
582
583 /* Send buffer over bearers until all targets reached */ 572 /* Send buffer over bearers until all targets reached */
584 573
585 bcbearer->remains = tipc_cltr_bcast_nodes; 574 bcbearer->remains = tipc_bcast_nmap;
586 575
587 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 576 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
588 struct bearer *p = bcbearer->bpairs[bp_index].primary; 577 struct bearer *p = bcbearer->bpairs[bp_index].primary;
@@ -595,32 +584,35 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
595 if (bcbearer->remains_new.count == bcbearer->remains.count) 584 if (bcbearer->remains_new.count == bcbearer->remains.count)
596 continue; /* bearer pair doesn't add anything */ 585 continue; /* bearer pair doesn't add anything */
597 586
598 if (!p->publ.blocked && 587 if (p->publ.blocked ||
599 !p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { 588 p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) {
600 if (swap_time && s && !s->publ.blocked) 589 /* unable to send on primary bearer */
601 goto swap; 590 if (!s || s->publ.blocked ||
602 else 591 s->media->send_msg(buf, &s->publ,
603 goto update; 592 &s->media->bcast_addr)) {
593 /* unable to send on either bearer */
594 continue;
595 }
596 }
597
598 if (s) {
599 bcbearer->bpairs[bp_index].primary = s;
600 bcbearer->bpairs[bp_index].secondary = p;
604 } 601 }
605 602
606 if (!s || s->publ.blocked ||
607 s->media->send_msg(buf, &s->publ, &s->media->bcast_addr))
608 continue; /* unable to send using bearer pair */
609swap:
610 bcbearer->bpairs[bp_index].primary = s;
611 bcbearer->bpairs[bp_index].secondary = p;
612update:
613 if (bcbearer->remains_new.count == 0) 603 if (bcbearer->remains_new.count == 0)
614 return 0; 604 return 0;
615 605
616 bcbearer->remains = bcbearer->remains_new; 606 bcbearer->remains = bcbearer->remains_new;
617 } 607 }
618 608
619 /* Unable to reach all targets */ 609 /*
610 * Unable to reach all targets (indicate success, since currently
611 * there isn't code in place to properly block & unblock the
612 * pseudo-bearer used by the broadcast link)
613 */
620 614
621 bcbearer->bearer.publ.blocked = 1; 615 return TIPC_OK;
622 bcl->stats.bearer_congs++;
623 return 1;
624} 616}
625 617
626/** 618/**
@@ -777,7 +769,6 @@ int tipc_bclink_init(void)
777 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); 769 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
778 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); 770 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
779 if (!bcbearer || !bclink) { 771 if (!bcbearer || !bclink) {
780 nomem:
781 warn("Multicast link creation failed, no memory\n"); 772 warn("Multicast link creation failed, no memory\n");
782 kfree(bcbearer); 773 kfree(bcbearer);
783 bcbearer = NULL; 774 bcbearer = NULL;
@@ -802,14 +793,6 @@ int tipc_bclink_init(void)
802 bcl->state = WORKING_WORKING; 793 bcl->state = WORKING_WORKING;
803 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); 794 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
804 795
805 if (BCLINK_LOG_BUF_SIZE) {
806 char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC);
807
808 if (!pb)
809 goto nomem;
810 tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE);
811 }
812
813 return 0; 796 return 0;
814} 797}
815 798
@@ -818,8 +801,6 @@ void tipc_bclink_stop(void)
818 spin_lock_bh(&bc_lock); 801 spin_lock_bh(&bc_lock);
819 if (bcbearer) { 802 if (bcbearer) {
820 tipc_link_stop(bcl); 803 tipc_link_stop(bcl);
821 if (BCLINK_LOG_BUF_SIZE)
822 kfree(bcl->print_buf.buf);
823 bcl = NULL; 804 bcl = NULL;
824 kfree(bclink); 805 kfree(bclink);
825 bclink = NULL; 806 bclink = NULL;
@@ -829,3 +810,114 @@ void tipc_bclink_stop(void)
829 spin_unlock_bh(&bc_lock); 810 spin_unlock_bh(&bc_lock);
830} 811}
831 812
813
814/**
815 * tipc_nmap_add - add a node to a node map
816 */
817
818void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
819{
820 int n = tipc_node(node);
821 int w = n / WSIZE;
822 u32 mask = (1 << (n % WSIZE));
823
824 if ((nm_ptr->map[w] & mask) == 0) {
825 nm_ptr->count++;
826 nm_ptr->map[w] |= mask;
827 }
828}
829
830/**
831 * tipc_nmap_remove - remove a node from a node map
832 */
833
834void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
835{
836 int n = tipc_node(node);
837 int w = n / WSIZE;
838 u32 mask = (1 << (n % WSIZE));
839
840 if ((nm_ptr->map[w] & mask) != 0) {
841 nm_ptr->map[w] &= ~mask;
842 nm_ptr->count--;
843 }
844}
845
846/**
847 * tipc_nmap_diff - find differences between node maps
848 * @nm_a: input node map A
849 * @nm_b: input node map B
850 * @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
851 */
852
853static void tipc_nmap_diff(struct tipc_node_map *nm_a,
854 struct tipc_node_map *nm_b,
855 struct tipc_node_map *nm_diff)
856{
857 int stop = ARRAY_SIZE(nm_a->map);
858 int w;
859 int b;
860 u32 map;
861
862 memset(nm_diff, 0, sizeof(*nm_diff));
863 for (w = 0; w < stop; w++) {
864 map = nm_a->map[w] ^ (nm_a->map[w] & nm_b->map[w]);
865 nm_diff->map[w] = map;
866 if (map != 0) {
867 for (b = 0 ; b < WSIZE; b++) {
868 if (map & (1 << b))
869 nm_diff->count++;
870 }
871 }
872 }
873}
874
875/**
876 * tipc_port_list_add - add a port to a port list, ensuring no duplicates
877 */
878
879void tipc_port_list_add(struct port_list *pl_ptr, u32 port)
880{
881 struct port_list *item = pl_ptr;
882 int i;
883 int item_sz = PLSIZE;
884 int cnt = pl_ptr->count;
885
886 for (; ; cnt -= item_sz, item = item->next) {
887 if (cnt < PLSIZE)
888 item_sz = cnt;
889 for (i = 0; i < item_sz; i++)
890 if (item->ports[i] == port)
891 return;
892 if (i < PLSIZE) {
893 item->ports[i] = port;
894 pl_ptr->count++;
895 return;
896 }
897 if (!item->next) {
898 item->next = kmalloc(sizeof(*item), GFP_ATOMIC);
899 if (!item->next) {
900 warn("Incomplete multicast delivery, no memory\n");
901 return;
902 }
903 item->next->next = NULL;
904 }
905 }
906}
907
908/**
909 * tipc_port_list_free - free dynamically created entries in port_list chain
910 *
911 */
912
913void tipc_port_list_free(struct port_list *pl_ptr)
914{
915 struct port_list *item;
916 struct port_list *next;
917
918 for (item = pl_ptr->next; item; item = next) {
919 next = item->next;
920 kfree(item);
921 }
922}
923
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 4c1771e95c99..51f8c5326ce6 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -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
@@ -72,41 +73,11 @@ struct tipc_node;
72 73
73extern const char tipc_bclink_name[]; 74extern const char tipc_bclink_name[];
74 75
76void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node);
77void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node);
75 78
76/** 79/**
77 * nmap_add - add a node to a node map 80 * tipc_nmap_equal - test for equality of node maps
78 */
79
80static inline void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
81{
82 int n = tipc_node(node);
83 int w = n / WSIZE;
84 u32 mask = (1 << (n % WSIZE));
85
86 if ((nm_ptr->map[w] & mask) == 0) {
87 nm_ptr->count++;
88 nm_ptr->map[w] |= mask;
89 }
90}
91
92/**
93 * nmap_remove - remove a node from a node map
94 */
95
96static inline void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
97{
98 int n = tipc_node(node);
99 int w = n / WSIZE;
100 u32 mask = (1 << (n % WSIZE));
101
102 if ((nm_ptr->map[w] & mask) != 0) {
103 nm_ptr->map[w] &= ~mask;
104 nm_ptr->count--;
105 }
106}
107
108/**
109 * nmap_equal - test for equality of node maps
110 */ 81 */
111 82
112static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b) 83static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b)
@@ -114,84 +85,8 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_m
114 return !memcmp(nm_a, nm_b, sizeof(*nm_a)); 85 return !memcmp(nm_a, nm_b, sizeof(*nm_a));
115} 86}
116 87
117/** 88void tipc_port_list_add(struct port_list *pl_ptr, u32 port);
118 * nmap_diff - find differences between node maps 89void tipc_port_list_free(struct port_list *pl_ptr);
119 * @nm_a: input node map A
120 * @nm_b: input node map B
121 * @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
122 */
123
124static inline void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b,
125 struct tipc_node_map *nm_diff)
126{
127 int stop = ARRAY_SIZE(nm_a->map);
128 int w;
129 int b;
130 u32 map;
131
132 memset(nm_diff, 0, sizeof(*nm_diff));
133 for (w = 0; w < stop; w++) {
134 map = nm_a->map[w] ^ (nm_a->map[w] & nm_b->map[w]);
135 nm_diff->map[w] = map;
136 if (map != 0) {
137 for (b = 0 ; b < WSIZE; b++) {
138 if (map & (1 << b))
139 nm_diff->count++;
140 }
141 }
142 }
143}
144
145/**
146 * port_list_add - add a port to a port list, ensuring no duplicates
147 */
148
149static inline void tipc_port_list_add(struct port_list *pl_ptr, u32 port)
150{
151 struct port_list *item = pl_ptr;
152 int i;
153 int item_sz = PLSIZE;
154 int cnt = pl_ptr->count;
155
156 for (; ; cnt -= item_sz, item = item->next) {
157 if (cnt < PLSIZE)
158 item_sz = cnt;
159 for (i = 0; i < item_sz; i++)
160 if (item->ports[i] == port)
161 return;
162 if (i < PLSIZE) {
163 item->ports[i] = port;
164 pl_ptr->count++;
165 return;
166 }
167 if (!item->next) {
168 item->next = kmalloc(sizeof(*item), GFP_ATOMIC);
169 if (!item->next) {
170 warn("Incomplete multicast delivery, no memory\n");
171 return;
172 }
173 item->next->next = NULL;
174 }
175 }
176}
177
178/**
179 * port_list_free - free dynamically created entries in port_list chain
180 *
181 * Note: First item is on stack, so it doesn't need to be released
182 */
183
184static inline void tipc_port_list_free(struct port_list *pl_ptr)
185{
186 struct port_list *item;
187 struct port_list *next;
188
189 for (item = pl_ptr->next; item; item = next) {
190 next = item->next;
191 kfree(item);
192 }
193}
194
195 90
196int tipc_bclink_init(void); 91int tipc_bclink_init(void);
197void tipc_bclink_stop(void); 92void tipc_bclink_stop(void);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index a7a36779b9b3..837b7a467885 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -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 = NULL; 44static struct media media_list[MAX_MEDIA];
49static u32 media_count = 0; 45static u32 media_count;
50 46
51struct bearer *tipc_bearers = NULL; 47struct bearer tipc_bearers[MAX_BEARERS];
52 48
53/** 49/**
54 * media_name_valid - validate media name 50 * media_name_valid - validate media name
@@ -63,7 +59,7 @@ static int media_name_valid(const char *name)
63 len = strlen(name); 59 len = strlen(name);
64 if ((len + 1) > TIPC_MAX_MEDIA_NAME) 60 if ((len + 1) > TIPC_MAX_MEDIA_NAME)
65 return 0; 61 return 0;
66 return (strspn(name, tipc_alphabet) == len); 62 return strspn(name, tipc_alphabet) == len;
67} 63}
68 64
69/** 65/**
@@ -108,9 +104,11 @@ int tipc_register_media(u32 media_type,
108 int res = -EINVAL; 104 int res = -EINVAL;
109 105
110 write_lock_bh(&tipc_net_lock); 106 write_lock_bh(&tipc_net_lock);
111 if (!media_list)
112 goto exit;
113 107
108 if (tipc_mode != TIPC_NET_MODE) {
109 warn("Media <%s> rejected, not in networked mode yet\n", name);
110 goto exit;
111 }
114 if (!media_name_valid(name)) { 112 if (!media_name_valid(name)) {
115 warn("Media <%s> rejected, illegal name\n", name); 113 warn("Media <%s> rejected, illegal name\n", name);
116 goto exit; 114 goto exit;
@@ -119,7 +117,7 @@ int tipc_register_media(u32 media_type,
119 warn("Media <%s> rejected, no broadcast address\n", name); 117 warn("Media <%s> rejected, no broadcast address\n", name);
120 goto exit; 118 goto exit;
121 } 119 }
122 if ((bearer_priority < TIPC_MIN_LINK_PRI) && 120 if ((bearer_priority < TIPC_MIN_LINK_PRI) ||
123 (bearer_priority > TIPC_MAX_LINK_PRI)) { 121 (bearer_priority > TIPC_MAX_LINK_PRI)) {
124 warn("Media <%s> rejected, illegal priority (%u)\n", name, 122 warn("Media <%s> rejected, illegal priority (%u)\n", name,
125 bearer_priority); 123 bearer_priority);
@@ -165,7 +163,6 @@ int tipc_register_media(u32 media_type,
165 m_ptr->priority = bearer_priority; 163 m_ptr->priority = bearer_priority;
166 m_ptr->tolerance = link_tolerance; 164 m_ptr->tolerance = link_tolerance;
167 m_ptr->window = send_window_limit; 165 m_ptr->window = send_window_limit;
168 dbg("Media <%s> registered\n", name);
169 res = 0; 166 res = 0;
170exit: 167exit:
171 write_unlock_bh(&tipc_net_lock); 168 write_unlock_bh(&tipc_net_lock);
@@ -197,9 +194,8 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
197 unchar *addr = (unchar *)&a->dev_addr; 194 unchar *addr = (unchar *)&a->dev_addr;
198 195
199 tipc_printf(pb, "UNKNOWN(%u)", media_type); 196 tipc_printf(pb, "UNKNOWN(%u)", media_type);
200 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { 197 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++)
201 tipc_printf(pb, "-%02x", addr[i]); 198 tipc_printf(pb, "-%02x", addr[i]);
202 }
203 } 199 }
204} 200}
205 201
@@ -254,7 +250,8 @@ static int bearer_name_validate(const char *name,
254 /* ensure all component parts of bearer name are present */ 250 /* ensure all component parts of bearer name are present */
255 251
256 media_name = name_copy; 252 media_name = name_copy;
257 if ((if_name = strchr(media_name, ':')) == NULL) 253 if_name = strchr(media_name, ':');
254 if (if_name == NULL)
258 return 0; 255 return 0;
259 *(if_name++) = 0; 256 *(if_name++) = 0;
260 media_len = if_name - media_name; 257 media_len = if_name - media_name;
@@ -286,9 +283,6 @@ static struct bearer *bearer_find(const char *name)
286 struct bearer *b_ptr; 283 struct bearer *b_ptr;
287 u32 i; 284 u32 i;
288 285
289 if (tipc_mode != TIPC_NET_MODE)
290 return NULL;
291
292 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 286 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
293 if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) 287 if (b_ptr->active && (!strcmp(b_ptr->publ.name, name)))
294 return b_ptr; 288 return b_ptr;
@@ -465,6 +459,18 @@ int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr)
465 return res; 459 return res;
466} 460}
467 461
462/**
463 * tipc_bearer_congested - determines if bearer is currently congested
464 */
465
466int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr)
467{
468 if (unlikely(b_ptr->publ.blocked))
469 return 1;
470 if (likely(list_empty(&b_ptr->cong_links)))
471 return 0;
472 return !tipc_bearer_resolve_congestion(b_ptr, l_ptr);
473}
468 474
469/** 475/**
470 * tipc_enable_bearer - enable bearer with the given name 476 * tipc_enable_bearer - enable bearer with the given name
@@ -491,7 +497,7 @@ int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority)
491 return -EINVAL; 497 return -EINVAL;
492 } 498 }
493 if (!tipc_addr_domain_valid(bcast_scope) || 499 if (!tipc_addr_domain_valid(bcast_scope) ||
494 !in_scope(bcast_scope, tipc_own_addr)) { 500 !tipc_in_scope(bcast_scope, tipc_own_addr)) {
495 warn("Bearer <%s> rejected, illegal broadcast scope\n", name); 501 warn("Bearer <%s> rejected, illegal broadcast scope\n", name);
496 return -EINVAL; 502 return -EINVAL;
497 } 503 }
@@ -545,8 +551,6 @@ restart:
545 } 551 }
546 552
547 b_ptr = &tipc_bearers[bearer_id]; 553 b_ptr = &tipc_bearers[bearer_id];
548 memset(b_ptr, 0, sizeof(struct bearer));
549
550 strcpy(b_ptr->publ.name, name); 554 strcpy(b_ptr->publ.name, name);
551 res = m_ptr->enable_bearer(&b_ptr->publ); 555 res = m_ptr->enable_bearer(&b_ptr->publ);
552 if (res) { 556 if (res) {
@@ -569,7 +573,7 @@ restart:
569 spin_lock_init(&b_ptr->publ.lock); 573 spin_lock_init(&b_ptr->publ.lock);
570 write_unlock_bh(&tipc_net_lock); 574 write_unlock_bh(&tipc_net_lock);
571 info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 575 info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
572 name, addr_string_fill(addr_string, bcast_scope), priority); 576 name, tipc_addr_string_fill(addr_string, bcast_scope), priority);
573 return 0; 577 return 0;
574failed: 578failed:
575 write_unlock_bh(&tipc_net_lock); 579 write_unlock_bh(&tipc_net_lock);
@@ -616,90 +620,51 @@ int tipc_block_bearer(const char *name)
616 * Note: This routine assumes caller holds tipc_net_lock. 620 * Note: This routine assumes caller holds tipc_net_lock.
617 */ 621 */
618 622
619static int bearer_disable(const char *name) 623static void bearer_disable(struct bearer *b_ptr)
620{ 624{
621 struct bearer *b_ptr;
622 struct link *l_ptr; 625 struct link *l_ptr;
623 struct link *temp_l_ptr; 626 struct link *temp_l_ptr;
624 627
625 b_ptr = bearer_find(name); 628 info("Disabling bearer <%s>\n", b_ptr->publ.name);
626 if (!b_ptr) {
627 warn("Attempt to disable unknown bearer <%s>\n", name);
628 return -EINVAL;
629 }
630
631 info("Disabling bearer <%s>\n", name);
632 tipc_disc_stop_link_req(b_ptr->link_req); 629 tipc_disc_stop_link_req(b_ptr->link_req);
633 spin_lock_bh(&b_ptr->publ.lock); 630 spin_lock_bh(&b_ptr->publ.lock);
634 b_ptr->link_req = NULL; 631 b_ptr->link_req = NULL;
635 b_ptr->publ.blocked = 1; 632 b_ptr->publ.blocked = 1;
636 if (b_ptr->media->disable_bearer) { 633 b_ptr->media->disable_bearer(&b_ptr->publ);
637 spin_unlock_bh(&b_ptr->publ.lock);
638 write_unlock_bh(&tipc_net_lock);
639 b_ptr->media->disable_bearer(&b_ptr->publ);
640 write_lock_bh(&tipc_net_lock);
641 spin_lock_bh(&b_ptr->publ.lock);
642 }
643 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 634 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
644 tipc_link_delete(l_ptr); 635 tipc_link_delete(l_ptr);
645 } 636 }
646 spin_unlock_bh(&b_ptr->publ.lock); 637 spin_unlock_bh(&b_ptr->publ.lock);
647 memset(b_ptr, 0, sizeof(struct bearer)); 638 memset(b_ptr, 0, sizeof(struct bearer));
648 return 0;
649} 639}
650 640
651int tipc_disable_bearer(const char *name) 641int tipc_disable_bearer(const char *name)
652{ 642{
643 struct bearer *b_ptr;
653 int res; 644 int res;
654 645
655 write_lock_bh(&tipc_net_lock); 646 write_lock_bh(&tipc_net_lock);
656 res = bearer_disable(name); 647 b_ptr = bearer_find(name);
657 write_unlock_bh(&tipc_net_lock); 648 if (b_ptr == NULL) {
658 return res; 649 warn("Attempt to disable unknown bearer <%s>\n", name);
659} 650 res = -EINVAL;
660
661
662
663int tipc_bearer_init(void)
664{
665 int res;
666
667 write_lock_bh(&tipc_net_lock);
668 tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC);
669 media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC);
670 if (tipc_bearers && media_list) {
671 res = 0;
672 } else { 651 } else {
673 kfree(tipc_bearers); 652 bearer_disable(b_ptr);
674 kfree(media_list); 653 res = 0;
675 tipc_bearers = NULL;
676 media_list = NULL;
677 res = -ENOMEM;
678 } 654 }
679 write_unlock_bh(&tipc_net_lock); 655 write_unlock_bh(&tipc_net_lock);
680 return res; 656 return res;
681} 657}
682 658
659
660
683void tipc_bearer_stop(void) 661void tipc_bearer_stop(void)
684{ 662{
685 u32 i; 663 u32 i;
686 664
687 if (!tipc_bearers)
688 return;
689
690 for (i = 0; i < MAX_BEARERS; i++) {
691 if (tipc_bearers[i].active)
692 tipc_bearers[i].publ.blocked = 1;
693 }
694 for (i = 0; i < MAX_BEARERS; i++) { 665 for (i = 0; i < MAX_BEARERS; i++) {
695 if (tipc_bearers[i].active) 666 if (tipc_bearers[i].active)
696 bearer_disable(tipc_bearers[i].publ.name); 667 bearer_disable(&tipc_bearers[i]);
697 } 668 }
698 kfree(tipc_bearers);
699 kfree(media_list);
700 tipc_bearers = NULL;
701 media_list = NULL;
702 media_count = 0; 669 media_count = 0;
703} 670}
704
705
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index ca5734892713..85f451d5aacf 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -37,12 +37,50 @@
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
64/**
65 * struct tipc_bearer - TIPC bearer info available to media code
66 * @usr_handle: pointer to additional media-specific information about bearer
67 * @mtu: max packet size bearer can support
68 * @blocked: non-zero if bearer is blocked
69 * @lock: spinlock for controlling access to bearer
70 * @addr: media-specific address associated with bearer
71 * @name: bearer name (format = media:interface)
72 *
73 * Note: TIPC initializes "name" and "lock" fields; media code is responsible
74 * for initialization all other fields when a bearer is enabled.
75 */
76struct tipc_bearer {
77 void *usr_handle;
78 u32 mtu;
79 int blocked;
80 spinlock_t lock;
81 struct tipc_media_addr addr;
82 char name[TIPC_MAX_BEARER_NAME];
83};
46 84
47/** 85/**
48 * struct media - TIPC media information available to internal users 86 * struct media - TIPC media information available to internal users
@@ -55,7 +93,7 @@
55 * @priority: default link (and bearer) priority 93 * @priority: default link (and bearer) priority
56 * @tolerance: default time (in ms) before declaring link failure 94 * @tolerance: default time (in ms) before declaring link failure
57 * @window: default window (in packets) before declaring link congestion 95 * @window: default window (in packets) before declaring link congestion
58 * @type_id: TIPC media identifier [defined in tipc_bearer.h] 96 * @type_id: TIPC media identifier
59 * @name: media name 97 * @name: media name
60 */ 98 */
61 99
@@ -114,7 +152,35 @@ struct bearer_name {
114 152
115struct link; 153struct link;
116 154
117extern struct bearer *tipc_bearers; 155extern struct bearer tipc_bearers[];
156
157/*
158 * TIPC routines available to supported media types
159 */
160int tipc_register_media(u32 media_type,
161 char *media_name, int (*enable)(struct tipc_bearer *),
162 void (*disable)(struct tipc_bearer *),
163 int (*send_msg)(struct sk_buff *,
164 struct tipc_bearer *, struct tipc_media_addr *),
165 char *(*addr2str)(struct tipc_media_addr *a,
166 char *str_buf, int str_size),
167 struct tipc_media_addr *bcast_addr, const u32 bearer_priority,
168 const u32 link_tolerance, /* [ms] */
169 const u32 send_window_limit);
170
171void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
172
173int tipc_block_bearer(const char *name);
174void tipc_continue(struct tipc_bearer *tb_ptr);
175
176int tipc_enable_bearer(const char *bearer_name, u32 bcast_scope, u32 priority);
177int tipc_disable_bearer(const char *name);
178
179/*
180 * Routines made available to TIPC by supported media types
181 */
182int tipc_eth_media_start(void);
183void tipc_eth_media_stop(void);
118 184
119void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); 185void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
120struct sk_buff *tipc_media_get_names(void); 186struct sk_buff *tipc_media_get_names(void);
@@ -125,7 +191,7 @@ void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest);
125void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr); 191void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr);
126struct bearer *tipc_bearer_find_interface(const char *if_name); 192struct bearer *tipc_bearer_find_interface(const char *if_name);
127int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr); 193int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr);
128int tipc_bearer_init(void); 194int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr);
129void tipc_bearer_stop(void); 195void tipc_bearer_stop(void);
130void tipc_bearer_lock_push(struct bearer *b_ptr); 196void tipc_bearer_lock_push(struct bearer *b_ptr);
131 197
@@ -154,17 +220,4 @@ static inline int tipc_bearer_send(struct bearer *b_ptr, struct sk_buff *buf,
154 return !b_ptr->media->send_msg(buf, &b_ptr->publ, dest); 220 return !b_ptr->media->send_msg(buf, &b_ptr->publ, dest);
155} 221}
156 222
157/** 223#endif /* _TIPC_BEARER_H */
158 * tipc_bearer_congested - determines if bearer is currently congested
159 */
160
161static inline int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr)
162{
163 if (unlikely(b_ptr->publ.blocked))
164 return 1;
165 if (likely(list_empty(&b_ptr->cong_links)))
166 return 0;
167 return !tipc_bearer_resolve_congestion(b_ptr, l_ptr);
168}
169
170#endif
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
deleted file mode 100644
index 689fdefe9d04..000000000000
--- a/net/tipc/cluster.c
+++ /dev/null
@@ -1,576 +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
116u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr)
117{
118 struct tipc_node *n_ptr;
119 u32 n_num = tipc_node(addr) + 1;
120
121 if (!c_ptr)
122 return addr;
123 for (; n_num <= c_ptr->highest_node; n_num++) {
124 n_ptr = c_ptr->nodes[n_num];
125 if (n_ptr && tipc_node_has_active_links(n_ptr))
126 return n_ptr->addr;
127 }
128 for (n_num = 1; n_num < tipc_node(addr); n_num++) {
129 n_ptr = c_ptr->nodes[n_num];
130 if (n_ptr && tipc_node_has_active_links(n_ptr))
131 return n_ptr->addr;
132 }
133 return 0;
134}
135
136void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr)
137{
138 u32 n_num = tipc_node(n_ptr->addr);
139 u32 max_n_num = tipc_max_nodes;
140
141 if (in_own_cluster(n_ptr->addr))
142 max_n_num = tipc_highest_allowed_slave;
143 assert(n_num > 0);
144 assert(n_num <= max_n_num);
145 assert(c_ptr->nodes[n_num] == NULL);
146 c_ptr->nodes[n_num] = n_ptr;
147 if (n_num > c_ptr->highest_node)
148 c_ptr->highest_node = n_num;
149}
150
151/**
152 * tipc_cltr_select_router - select router to a cluster
153 *
154 * Uses deterministic and fair algorithm.
155 */
156
157u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref)
158{
159 u32 n_num;
160 u32 ulim = c_ptr->highest_node;
161 u32 mask;
162 u32 tstart;
163
164 assert(!in_own_cluster(c_ptr->addr));
165 if (!ulim)
166 return 0;
167
168 /* Start entry must be random */
169 mask = tipc_max_nodes;
170 while (mask > ulim)
171 mask >>= 1;
172 tstart = ref & mask;
173 n_num = tstart;
174
175 /* Lookup upwards with wrap-around */
176 do {
177 if (tipc_node_is_up(c_ptr->nodes[n_num]))
178 break;
179 } while (++n_num <= ulim);
180 if (n_num > ulim) {
181 n_num = 1;
182 do {
183 if (tipc_node_is_up(c_ptr->nodes[n_num]))
184 break;
185 } while (++n_num < tstart);
186 if (n_num == tstart)
187 return 0;
188 }
189 assert(n_num <= ulim);
190 return tipc_node_select_router(c_ptr->nodes[n_num], ref);
191}
192
193/**
194 * tipc_cltr_select_node - select destination node within a remote cluster
195 *
196 * Uses deterministic and fair algorithm.
197 */
198
199struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
200{
201 u32 n_num;
202 u32 mask = tipc_max_nodes;
203 u32 start_entry;
204
205 assert(!in_own_cluster(c_ptr->addr));
206 if (!c_ptr->highest_node)
207 return NULL;
208
209 /* Start entry must be random */
210 while (mask > c_ptr->highest_node) {
211 mask >>= 1;
212 }
213 start_entry = (selector & mask) ? selector & mask : 1u;
214 assert(start_entry <= c_ptr->highest_node);
215
216 /* Lookup upwards with wrap-around */
217 for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) {
218 if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
219 return c_ptr->nodes[n_num];
220 }
221 for (n_num = 1; n_num < start_entry; n_num++) {
222 if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
223 return c_ptr->nodes[n_num];
224 }
225 return NULL;
226}
227
228/*
229 * Routing table management: See description in node.c
230 */
231
232static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
233{
234 u32 size = INT_H_SIZE + data_size;
235 struct sk_buff *buf = buf_acquire(size);
236 struct tipc_msg *msg;
237
238 if (buf) {
239 msg = buf_msg(buf);
240 memset((char *)msg, 0, size);
241 msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest);
242 }
243 return buf;
244}
245
246void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest,
247 u32 lower, u32 upper)
248{
249 struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
250 struct tipc_msg *msg;
251
252 if (buf) {
253 msg = buf_msg(buf);
254 msg_set_remote_node(msg, dest);
255 msg_set_type(msg, ROUTE_ADDITION);
256 tipc_cltr_multicast(c_ptr, buf, lower, upper);
257 } else {
258 warn("Memory squeeze: broadcast of new route failed\n");
259 }
260}
261
262void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest,
263 u32 lower, u32 upper)
264{
265 struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
266 struct tipc_msg *msg;
267
268 if (buf) {
269 msg = buf_msg(buf);
270 msg_set_remote_node(msg, dest);
271 msg_set_type(msg, ROUTE_REMOVAL);
272 tipc_cltr_multicast(c_ptr, buf, lower, upper);
273 } else {
274 warn("Memory squeeze: broadcast of lost route failed\n");
275 }
276}
277
278void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest)
279{
280 struct sk_buff *buf;
281 struct tipc_msg *msg;
282 u32 highest = c_ptr->highest_slave;
283 u32 n_num;
284 int send = 0;
285
286 assert(!is_slave(dest));
287 assert(in_own_cluster(dest));
288 assert(in_own_cluster(c_ptr->addr));
289 if (highest <= LOWEST_SLAVE)
290 return;
291 buf = tipc_cltr_prepare_routing_msg(highest - LOWEST_SLAVE + 1,
292 c_ptr->addr);
293 if (buf) {
294 msg = buf_msg(buf);
295 msg_set_remote_node(msg, c_ptr->addr);
296 msg_set_type(msg, SLAVE_ROUTING_TABLE);
297 for (n_num = LOWEST_SLAVE; n_num <= highest; n_num++) {
298 if (c_ptr->nodes[n_num] &&
299 tipc_node_has_active_links(c_ptr->nodes[n_num])) {
300 send = 1;
301 msg_set_dataoctet(msg, n_num);
302 }
303 }
304 if (send)
305 tipc_link_send(buf, dest, dest);
306 else
307 buf_discard(buf);
308 } else {
309 warn("Memory squeeze: broadcast of lost route failed\n");
310 }
311}
312
313void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest)
314{
315 struct sk_buff *buf;
316 struct tipc_msg *msg;
317 u32 highest = c_ptr->highest_node;
318 u32 n_num;
319 int send = 0;
320
321 if (in_own_cluster(c_ptr->addr))
322 return;
323 assert(!is_slave(dest));
324 assert(in_own_cluster(dest));
325 highest = c_ptr->highest_node;
326 buf = tipc_cltr_prepare_routing_msg(highest + 1, c_ptr->addr);
327 if (buf) {
328 msg = buf_msg(buf);
329 msg_set_remote_node(msg, c_ptr->addr);
330 msg_set_type(msg, EXT_ROUTING_TABLE);
331 for (n_num = 1; n_num <= highest; n_num++) {
332 if (c_ptr->nodes[n_num] &&
333 tipc_node_has_active_links(c_ptr->nodes[n_num])) {
334 send = 1;
335 msg_set_dataoctet(msg, n_num);
336 }
337 }
338 if (send)
339 tipc_link_send(buf, dest, dest);
340 else
341 buf_discard(buf);
342 } else {
343 warn("Memory squeeze: broadcast of external route failed\n");
344 }
345}
346
347void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest)
348{
349 struct sk_buff *buf;
350 struct tipc_msg *msg;
351 u32 highest = c_ptr->highest_node;
352 u32 n_num;
353 int send = 0;
354
355 assert(is_slave(dest));
356 assert(in_own_cluster(c_ptr->addr));
357 buf = tipc_cltr_prepare_routing_msg(highest, c_ptr->addr);
358 if (buf) {
359 msg = buf_msg(buf);
360 msg_set_remote_node(msg, c_ptr->addr);
361 msg_set_type(msg, LOCAL_ROUTING_TABLE);
362 for (n_num = 1; n_num <= highest; n_num++) {
363 if (c_ptr->nodes[n_num] &&
364 tipc_node_has_active_links(c_ptr->nodes[n_num])) {
365 send = 1;
366 msg_set_dataoctet(msg, n_num);
367 }
368 }
369 if (send)
370 tipc_link_send(buf, dest, dest);
371 else
372 buf_discard(buf);
373 } else {
374 warn("Memory squeeze: broadcast of local route failed\n");
375 }
376}
377
378void tipc_cltr_recv_routing_table(struct sk_buff *buf)
379{
380 struct tipc_msg *msg = buf_msg(buf);
381 struct cluster *c_ptr;
382 struct tipc_node *n_ptr;
383 unchar *node_table;
384 u32 table_size;
385 u32 router;
386 u32 rem_node = msg_remote_node(msg);
387 u32 z_num;
388 u32 c_num;
389 u32 n_num;
390
391 c_ptr = tipc_cltr_find(rem_node);
392 if (!c_ptr) {
393 c_ptr = tipc_cltr_create(rem_node);
394 if (!c_ptr) {
395 buf_discard(buf);
396 return;
397 }
398 }
399
400 node_table = buf->data + msg_hdr_sz(msg);
401 table_size = msg_size(msg) - msg_hdr_sz(msg);
402 router = msg_prevnode(msg);
403 z_num = tipc_zone(rem_node);
404 c_num = tipc_cluster(rem_node);
405
406 switch (msg_type(msg)) {
407 case LOCAL_ROUTING_TABLE:
408 assert(is_slave(tipc_own_addr));
409 case EXT_ROUTING_TABLE:
410 for (n_num = 1; n_num < table_size; n_num++) {
411 if (node_table[n_num]) {
412 u32 addr = tipc_addr(z_num, c_num, n_num);
413 n_ptr = c_ptr->nodes[n_num];
414 if (!n_ptr) {
415 n_ptr = tipc_node_create(addr);
416 }
417 if (n_ptr)
418 tipc_node_add_router(n_ptr, router);
419 }
420 }
421 break;
422 case SLAVE_ROUTING_TABLE:
423 assert(!is_slave(tipc_own_addr));
424 assert(in_own_cluster(c_ptr->addr));
425 for (n_num = 1; n_num < table_size; n_num++) {
426 if (node_table[n_num]) {
427 u32 slave_num = n_num + LOWEST_SLAVE;
428 u32 addr = tipc_addr(z_num, c_num, slave_num);
429 n_ptr = c_ptr->nodes[slave_num];
430 if (!n_ptr) {
431 n_ptr = tipc_node_create(addr);
432 }
433 if (n_ptr)
434 tipc_node_add_router(n_ptr, router);
435 }
436 }
437 break;
438 case ROUTE_ADDITION:
439 if (!is_slave(tipc_own_addr)) {
440 assert(!in_own_cluster(c_ptr->addr)
441 || is_slave(rem_node));
442 } else {
443 assert(in_own_cluster(c_ptr->addr)
444 && !is_slave(rem_node));
445 }
446 n_ptr = c_ptr->nodes[tipc_node(rem_node)];
447 if (!n_ptr)
448 n_ptr = tipc_node_create(rem_node);
449 if (n_ptr)
450 tipc_node_add_router(n_ptr, router);
451 break;
452 case ROUTE_REMOVAL:
453 if (!is_slave(tipc_own_addr)) {
454 assert(!in_own_cluster(c_ptr->addr)
455 || is_slave(rem_node));
456 } else {
457 assert(in_own_cluster(c_ptr->addr)
458 && !is_slave(rem_node));
459 }
460 n_ptr = c_ptr->nodes[tipc_node(rem_node)];
461 if (n_ptr)
462 tipc_node_remove_router(n_ptr, router);
463 break;
464 default:
465 assert(!"Illegal routing manager message received\n");
466 }
467 buf_discard(buf);
468}
469
470void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router)
471{
472 u32 start_entry;
473 u32 tstop;
474 u32 n_num;
475
476 if (is_slave(router))
477 return; /* Slave nodes can not be routers */
478
479 if (in_own_cluster(c_ptr->addr)) {
480 start_entry = LOWEST_SLAVE;
481 tstop = c_ptr->highest_slave;
482 } else {
483 start_entry = 1;
484 tstop = c_ptr->highest_node;
485 }
486
487 for (n_num = start_entry; n_num <= tstop; n_num++) {
488 if (c_ptr->nodes[n_num]) {
489 tipc_node_remove_router(c_ptr->nodes[n_num], router);
490 }
491 }
492}
493
494/**
495 * tipc_cltr_multicast - multicast message to local nodes
496 */
497
498static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
499 u32 lower, u32 upper)
500{
501 struct sk_buff *buf_copy;
502 struct tipc_node *n_ptr;
503 u32 n_num;
504 u32 tstop;
505
506 assert(lower <= upper);
507 assert(((lower >= 1) && (lower <= tipc_max_nodes)) ||
508 ((lower >= LOWEST_SLAVE) && (lower <= tipc_highest_allowed_slave)));
509 assert(((upper >= 1) && (upper <= tipc_max_nodes)) ||
510 ((upper >= LOWEST_SLAVE) && (upper <= tipc_highest_allowed_slave)));
511 assert(in_own_cluster(c_ptr->addr));
512
513 tstop = is_slave(upper) ? c_ptr->highest_slave : c_ptr->highest_node;
514 if (tstop > upper)
515 tstop = upper;
516 for (n_num = lower; n_num <= tstop; n_num++) {
517 n_ptr = c_ptr->nodes[n_num];
518 if (n_ptr && tipc_node_has_active_links(n_ptr)) {
519 buf_copy = skb_copy(buf, GFP_ATOMIC);
520 if (buf_copy == NULL)
521 break;
522 msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
523 tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
524 }
525 }
526 buf_discard(buf);
527}
528
529/**
530 * tipc_cltr_broadcast - broadcast message to all nodes within cluster
531 */
532
533void tipc_cltr_broadcast(struct sk_buff *buf)
534{
535 struct sk_buff *buf_copy;
536 struct cluster *c_ptr;
537 struct tipc_node *n_ptr;
538 u32 n_num;
539 u32 tstart;
540 u32 tstop;
541 u32 node_type;
542
543 if (tipc_mode == TIPC_NET_MODE) {
544 c_ptr = tipc_cltr_find(tipc_own_addr);
545 assert(in_own_cluster(c_ptr->addr)); /* For now */
546
547 /* Send to standard nodes, then repeat loop sending to slaves */
548 tstart = 1;
549 tstop = c_ptr->highest_node;
550 for (node_type = 1; node_type <= 2; node_type++) {
551 for (n_num = tstart; n_num <= tstop; n_num++) {
552 n_ptr = c_ptr->nodes[n_num];
553 if (n_ptr && tipc_node_has_active_links(n_ptr)) {
554 buf_copy = skb_copy(buf, GFP_ATOMIC);
555 if (buf_copy == NULL)
556 goto exit;
557 msg_set_destnode(buf_msg(buf_copy),
558 n_ptr->addr);
559 tipc_link_send(buf_copy, n_ptr->addr,
560 n_ptr->addr);
561 }
562 }
563 tstart = LOWEST_SLAVE;
564 tstop = c_ptr->highest_slave;
565 }
566 }
567exit:
568 buf_discard(buf);
569}
570
571int tipc_cltr_init(void)
572{
573 tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves;
574 return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM;
575}
576
diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h
deleted file mode 100644
index 333efb0b9c44..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);
78u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr);
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 ca3544d030c7..e16750dcf3c1 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -35,33 +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 u32 subscr_ref;
60 u32 link_subscriptions;
61 struct list_head link_subscribers;
62};
63
64static struct manager mng = { 0};
65 43
66static DEFINE_SPINLOCK(config_lock); 44static DEFINE_SPINLOCK(config_lock);
67 45
@@ -70,12 +48,6 @@ static int req_tlv_space; /* request message TLV area size */
70static int rep_headroom; /* reply message headroom to use */ 48static int rep_headroom; /* reply message headroom to use */
71 49
72 50
73void tipc_cfg_link_event(u32 addr, char *name, int up)
74{
75 /* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */
76}
77
78
79struct sk_buff *tipc_cfg_reply_alloc(int payload_size) 51struct sk_buff *tipc_cfg_reply_alloc(int payload_size)
80{ 52{
81 struct sk_buff *buf; 53 struct sk_buff *buf;
@@ -92,10 +64,8 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
92 struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf); 64 struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf);
93 int new_tlv_space = TLV_SPACE(tlv_data_size); 65 int new_tlv_space = TLV_SPACE(tlv_data_size);
94 66
95 if (skb_tailroom(buf) < new_tlv_space) { 67 if (skb_tailroom(buf) < new_tlv_space)
96 dbg("tipc_cfg_append_tlv unable to append TLV\n");
97 return 0; 68 return 0;
98 }
99 skb_put(buf, new_tlv_space); 69 skb_put(buf, new_tlv_space);
100 tlv->tlv_type = htons(tlv_type); 70 tlv->tlv_type = htons(tlv_type);
101 tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size)); 71 tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size));
@@ -104,7 +74,7 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
104 return 1; 74 return 1;
105} 75}
106 76
107struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) 77static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
108{ 78{
109 struct sk_buff *buf; 79 struct sk_buff *buf;
110 __be32 value_net; 80 __be32 value_net;
@@ -118,6 +88,11 @@ struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
118 return buf; 88 return buf;
119} 89}
120 90
91static struct sk_buff *tipc_cfg_reply_unsigned(u32 value)
92{
93 return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value);
94}
95
121struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) 96struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
122{ 97{
123 struct sk_buff *buf; 98 struct sk_buff *buf;
@@ -129,126 +104,40 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
129 return buf; 104 return buf;
130} 105}
131 106
107#define MAX_STATS_INFO 2000
132 108
109static struct sk_buff *tipc_show_stats(void)
110{
111 struct sk_buff *buf;
112 struct tlv_desc *rep_tlv;
113 struct print_buf pb;
114 int str_len;
115 u32 value;
133 116
117 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
118 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
134 119
135#if 0 120 value = ntohl(*(u32 *)TLV_DATA(req_tlv_area));
121 if (value != 0)
122 return tipc_cfg_reply_error_string("unsupported argument");
136 123
137/* Now obsolete code for handling commands not yet implemented the new way */ 124 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO));
125 if (buf == NULL)
126 return NULL;
138 127
139int tipc_cfg_cmd(const struct tipc_cmd_msg * msg, 128 rep_tlv = (struct tlv_desc *)buf->data;
140 char *data, 129 tipc_printbuf_init(&pb, (char *)TLV_DATA(rep_tlv), MAX_STATS_INFO);
141 u32 sz,
142 u32 *ret_size,
143 struct tipc_portid *orig)
144{
145 int rv = -EINVAL;
146 u32 cmd = msg->cmd;
147 130
148 *ret_size = 0; 131 tipc_printf(&pb, "TIPC version " TIPC_MOD_VER "\n");
149 switch (cmd) {
150 case TIPC_REMOVE_LINK:
151 case TIPC_CMD_BLOCK_LINK:
152 case TIPC_CMD_UNBLOCK_LINK:
153 if (!cfg_check_connection(orig))
154 rv = link_control(msg->argv.link_name, msg->cmd, 0);
155 break;
156 case TIPC_ESTABLISH:
157 {
158 int connected;
159
160 tipc_isconnected(mng.conn_port_ref, &connected);
161 if (connected || !orig) {
162 rv = TIPC_FAILURE;
163 break;
164 }
165 rv = tipc_connect2port(mng.conn_port_ref, orig);
166 if (rv == TIPC_OK)
167 orig = 0;
168 break;
169 }
170 case TIPC_GET_PEER_ADDRESS:
171 *ret_size = link_peer_addr(msg->argv.link_name, data, sz);
172 break;
173 case TIPC_GET_ROUTES:
174 rv = TIPC_OK;
175 break;
176 default: {}
177 }
178 if (*ret_size)
179 rv = TIPC_OK;
180 return rv;
181}
182 132
183static void cfg_cmd_event(struct tipc_cmd_msg *msg, 133 /* Use additional tipc_printf()'s to return more info ... */
184 char *data,
185 u32 sz,
186 struct tipc_portid const *orig)
187{
188 int rv = -EINVAL;
189 struct tipc_cmd_result_msg rmsg;
190 struct iovec msg_sect[2];
191 int *arg;
192
193 msg->cmd = ntohl(msg->cmd);
194 134
195 cfg_prepare_res_msg(msg->cmd, msg->usr_handle, rv, &rmsg, msg_sect, 135 str_len = tipc_printbuf_validate(&pb);
196 data, 0); 136 skb_put(buf, TLV_SPACE(str_len));
197 if (ntohl(msg->magic) != TIPC_MAGIC) 137 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
198 goto exit;
199 138
200 switch (msg->cmd) { 139 return buf;
201 case TIPC_CREATE_LINK:
202 if (!cfg_check_connection(orig))
203 rv = disc_create_link(&msg->argv.create_link);
204 break;
205 case TIPC_LINK_SUBSCRIBE:
206 {
207 struct subscr_data *sub;
208
209 if (mng.link_subscriptions > 64)
210 break;
211 sub = kmalloc(sizeof(*sub),
212 GFP_ATOMIC);
213 if (sub == NULL) {
214 warn("Memory squeeze; dropped remote link subscription\n");
215 break;
216 }
217 INIT_LIST_HEAD(&sub->subd_list);
218 tipc_createport(mng.user_ref,
219 (void *)sub,
220 TIPC_HIGH_IMPORTANCE,
221 0,
222 0,
223 (tipc_conn_shutdown_event)cfg_linksubscr_cancel,
224 0,
225 0,
226 (tipc_conn_msg_event)cfg_linksubscr_cancel,
227 0,
228 &sub->port_ref);
229 if (!sub->port_ref) {
230 kfree(sub);
231 break;
232 }
233 memcpy(sub->usr_handle,msg->usr_handle,
234 sizeof(sub->usr_handle));
235 sub->domain = msg->argv.domain;
236 list_add_tail(&sub->subd_list, &mng.link_subscribers);
237 tipc_connect2port(sub->port_ref, orig);
238 rmsg.retval = TIPC_OK;
239 tipc_send(sub->port_ref, 2u, msg_sect);
240 mng.link_subscriptions++;
241 return;
242 }
243 default:
244 rv = tipc_cfg_cmd(msg, data, sz, (u32 *)&msg_sect[1].iov_len, orig);
245 }
246 exit:
247 rmsg.result_len = htonl(msg_sect[1].iov_len);
248 rmsg.retval = htonl(rv);
249 tipc_cfg_respond(msg_sect, 2u, orig);
250} 140}
251#endif
252 141
253static struct sk_buff *cfg_enable_bearer(void) 142static struct sk_buff *cfg_enable_bearer(void)
254{ 143{
@@ -371,38 +260,6 @@ static struct sk_buff *cfg_set_max_ports(void)
371 return tipc_cfg_reply_none(); 260 return tipc_cfg_reply_none();
372} 261}
373 262
374static struct sk_buff *cfg_set_max_zones(void)
375{
376 u32 value;
377
378 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
379 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
380 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
381 if (value == tipc_max_zones)
382 return tipc_cfg_reply_none();
383 if (value != delimit(value, 1, 255))
384 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
385 " (max zones must be 1-255)");
386 if (tipc_mode == TIPC_NET_MODE)
387 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
388 " (cannot change max zones once TIPC has joined a network)");
389 tipc_max_zones = value;
390 return tipc_cfg_reply_none();
391}
392
393static struct sk_buff *cfg_set_max_clusters(void)
394{
395 u32 value;
396
397 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
398 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
399 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
400 if (value != delimit(value, 1, 1))
401 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
402 " (max clusters fixed at 1)");
403 return tipc_cfg_reply_none();
404}
405
406static struct sk_buff *cfg_set_max_nodes(void) 263static struct sk_buff *cfg_set_max_nodes(void)
407{ 264{
408 u32 value; 265 u32 value;
@@ -422,19 +279,6 @@ static struct sk_buff *cfg_set_max_nodes(void)
422 return tipc_cfg_reply_none(); 279 return tipc_cfg_reply_none();
423} 280}
424 281
425static struct sk_buff *cfg_set_max_slaves(void)
426{
427 u32 value;
428
429 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
430 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
431 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
432 if (value != 0)
433 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
434 " (max secondary nodes fixed at 0)");
435 return tipc_cfg_reply_none();
436}
437
438static struct sk_buff *cfg_set_netid(void) 282static struct sk_buff *cfg_set_netid(void)
439{ 283{
440 u32 value; 284 u32 value;
@@ -478,8 +322,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
478 } else if (!tipc_remote_management) { 322 } else if (!tipc_remote_management) {
479 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE); 323 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
480 goto exit; 324 goto exit;
481 } 325 } else if (cmd >= 0x4000) {
482 else if (cmd >= 0x4000) {
483 u32 domain = 0; 326 u32 domain = 0;
484 327
485 if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) || 328 if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
@@ -519,20 +362,15 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
519 case TIPC_CMD_SHOW_PORTS: 362 case TIPC_CMD_SHOW_PORTS:
520 rep_tlv_buf = tipc_port_get_ports(); 363 rep_tlv_buf = tipc_port_get_ports();
521 break; 364 break;
522#if 0
523 case TIPC_CMD_SHOW_PORT_STATS:
524 rep_tlv_buf = port_show_stats(req_tlv_area, req_tlv_space);
525 break;
526 case TIPC_CMD_RESET_PORT_STATS:
527 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED);
528 break;
529#endif
530 case TIPC_CMD_SET_LOG_SIZE: 365 case TIPC_CMD_SET_LOG_SIZE:
531 rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space); 366 rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space);
532 break; 367 break;
533 case TIPC_CMD_DUMP_LOG: 368 case TIPC_CMD_DUMP_LOG:
534 rep_tlv_buf = tipc_log_dump(); 369 rep_tlv_buf = tipc_log_dump();
535 break; 370 break;
371 case TIPC_CMD_SHOW_STATS:
372 rep_tlv_buf = tipc_show_stats();
373 break;
536 case TIPC_CMD_SET_LINK_TOL: 374 case TIPC_CMD_SET_LINK_TOL:
537 case TIPC_CMD_SET_LINK_PRI: 375 case TIPC_CMD_SET_LINK_PRI:
538 case TIPC_CMD_SET_LINK_WINDOW: 376 case TIPC_CMD_SET_LINK_WINDOW:
@@ -559,18 +397,9 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
559 case TIPC_CMD_SET_MAX_SUBSCR: 397 case TIPC_CMD_SET_MAX_SUBSCR:
560 rep_tlv_buf = cfg_set_max_subscriptions(); 398 rep_tlv_buf = cfg_set_max_subscriptions();
561 break; 399 break;
562 case TIPC_CMD_SET_MAX_ZONES:
563 rep_tlv_buf = cfg_set_max_zones();
564 break;
565 case TIPC_CMD_SET_MAX_CLUSTERS:
566 rep_tlv_buf = cfg_set_max_clusters();
567 break;
568 case TIPC_CMD_SET_MAX_NODES: 400 case TIPC_CMD_SET_MAX_NODES:
569 rep_tlv_buf = cfg_set_max_nodes(); 401 rep_tlv_buf = cfg_set_max_nodes();
570 break; 402 break;
571 case TIPC_CMD_SET_MAX_SLAVES:
572 rep_tlv_buf = cfg_set_max_slaves();
573 break;
574 case TIPC_CMD_SET_NETID: 403 case TIPC_CMD_SET_NETID:
575 rep_tlv_buf = cfg_set_netid(); 404 rep_tlv_buf = cfg_set_netid();
576 break; 405 break;
@@ -586,18 +415,9 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
586 case TIPC_CMD_GET_MAX_SUBSCR: 415 case TIPC_CMD_GET_MAX_SUBSCR:
587 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions); 416 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions);
588 break; 417 break;
589 case TIPC_CMD_GET_MAX_ZONES:
590 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_zones);
591 break;
592 case TIPC_CMD_GET_MAX_CLUSTERS:
593 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_clusters);
594 break;
595 case TIPC_CMD_GET_MAX_NODES: 418 case TIPC_CMD_GET_MAX_NODES:
596 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes); 419 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes);
597 break; 420 break;
598 case TIPC_CMD_GET_MAX_SLAVES:
599 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_slaves);
600 break;
601 case TIPC_CMD_GET_NETID: 421 case TIPC_CMD_GET_NETID:
602 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 422 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
603 break; 423 break;
@@ -605,6 +425,15 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
605 rep_tlv_buf = 425 rep_tlv_buf =
606 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); 426 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
607 break; 427 break;
428 case TIPC_CMD_SET_MAX_ZONES:
429 case TIPC_CMD_GET_MAX_ZONES:
430 case TIPC_CMD_SET_MAX_SLAVES:
431 case TIPC_CMD_GET_MAX_SLAVES:
432 case TIPC_CMD_SET_MAX_CLUSTERS:
433 case TIPC_CMD_GET_MAX_CLUSTERS:
434 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
435 " (obsolete command)");
436 break;
608 default: 437 default:
609 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 438 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
610 " (unknown command)"); 439 " (unknown command)");
@@ -667,23 +496,16 @@ int tipc_cfg_init(void)
667 struct tipc_name_seq seq; 496 struct tipc_name_seq seq;
668 int res; 497 int res;
669 498
670 memset(&mng, 0, sizeof(mng)); 499 res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
671 INIT_LIST_HEAD(&mng.link_subscribers);
672
673 res = tipc_attach(&mng.user_ref, NULL, NULL);
674 if (res)
675 goto failed;
676
677 res = tipc_createport(mng.user_ref, NULL, TIPC_CRITICAL_IMPORTANCE,
678 NULL, NULL, NULL, 500 NULL, NULL, NULL,
679 NULL, cfg_named_msg_event, NULL, 501 NULL, cfg_named_msg_event, NULL,
680 NULL, &mng.port_ref); 502 NULL, &config_port_ref);
681 if (res) 503 if (res)
682 goto failed; 504 goto failed;
683 505
684 seq.type = TIPC_CFG_SRV; 506 seq.type = TIPC_CFG_SRV;
685 seq.lower = seq.upper = tipc_own_addr; 507 seq.lower = seq.upper = tipc_own_addr;
686 res = tipc_nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq); 508 res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq);
687 if (res) 509 if (res)
688 goto failed; 510 goto failed;
689 511
@@ -691,15 +513,13 @@ int tipc_cfg_init(void)
691 513
692failed: 514failed:
693 err("Unable to create configuration service\n"); 515 err("Unable to create configuration service\n");
694 tipc_detach(mng.user_ref);
695 mng.user_ref = 0;
696 return res; 516 return res;
697} 517}
698 518
699void tipc_cfg_stop(void) 519void tipc_cfg_stop(void)
700{ 520{
701 if (mng.user_ref) { 521 if (config_port_ref) {
702 tipc_detach(mng.user_ref); 522 tipc_deleteport(config_port_ref);
703 mng.user_ref = 0; 523 config_port_ref = 0;
704 } 524 }
705} 525}
diff --git a/net/tipc/config.h b/net/tipc/config.h
index 5cd7cc56c54d..443159a166fd 100644
--- a/net/tipc/config.h
+++ b/net/tipc/config.h
@@ -39,13 +39,11 @@
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);
46int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, 45int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
47 void *tlv_data, int tlv_data_size); 46 void *tlv_data, int tlv_data_size);
48struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value);
49struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string); 47struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string);
50 48
51static inline struct sk_buff *tipc_cfg_reply_none(void) 49static inline struct sk_buff *tipc_cfg_reply_none(void)
@@ -53,11 +51,6 @@ static inline struct sk_buff *tipc_cfg_reply_none(void)
53 return tipc_cfg_reply_alloc(0); 51 return tipc_cfg_reply_alloc(0);
54} 52}
55 53
56static inline struct sk_buff *tipc_cfg_reply_unsigned(u32 value)
57{
58 return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value);
59}
60
61static inline struct sk_buff *tipc_cfg_reply_error_string(char *string) 54static inline struct sk_buff *tipc_cfg_reply_error_string(char *string)
62{ 55{
63 return tipc_cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string); 56 return tipc_cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string);
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 3256bd7d398f..e071579e0850 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -34,39 +34,17 @@
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#define TIPC_MOD_VER "1.6.4"
53
54#ifndef CONFIG_TIPC_ZONES
55#define CONFIG_TIPC_ZONES 3
56#endif
57
58#ifndef CONFIG_TIPC_CLUSTERS
59#define CONFIG_TIPC_CLUSTERS 1
60#endif
61
62#ifndef CONFIG_TIPC_NODES 44#ifndef CONFIG_TIPC_NODES
63#define CONFIG_TIPC_NODES 255 45#define CONFIG_TIPC_NODES 255
64#endif 46#endif
65 47
66#ifndef CONFIG_TIPC_SLAVE_NODES
67#define CONFIG_TIPC_SLAVE_NODES 0
68#endif
69
70#ifndef CONFIG_TIPC_PORTS 48#ifndef CONFIG_TIPC_PORTS
71#define CONFIG_TIPC_PORTS 8191 49#define CONFIG_TIPC_PORTS 8191
72#endif 50#endif
@@ -87,10 +65,7 @@ const char tipc_alphabet[] =
87/* configurable TIPC parameters */ 65/* configurable TIPC parameters */
88 66
89u32 tipc_own_addr; 67u32 tipc_own_addr;
90int tipc_max_zones;
91int tipc_max_clusters;
92int tipc_max_nodes; 68int tipc_max_nodes;
93int tipc_max_slaves;
94int tipc_max_ports; 69int tipc_max_ports;
95int tipc_max_subscriptions; 70int tipc_max_subscriptions;
96int tipc_max_publications; 71int tipc_max_publications;
@@ -98,16 +73,35 @@ int tipc_net_id;
98int tipc_remote_management; 73int tipc_remote_management;
99 74
100 75
101int tipc_get_mode(void) 76/**
77 * tipc_buf_acquire - creates a TIPC message buffer
78 * @size: message size (including TIPC header)
79 *
80 * Returns a new buffer with data pointers set to the specified size.
81 *
82 * NOTE: Headroom is reserved to allow prepending of a data link header.
83 * There may also be unrequested tailroom present at the buffer's end.
84 */
85
86struct sk_buff *tipc_buf_acquire(u32 size)
102{ 87{
103 return tipc_mode; 88 struct sk_buff *skb;
89 unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
90
91 skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
92 if (skb) {
93 skb_reserve(skb, BUF_HEADROOM);
94 skb_put(skb, size);
95 skb->next = NULL;
96 }
97 return skb;
104} 98}
105 99
106/** 100/**
107 * tipc_core_stop_net - shut down TIPC networking sub-systems 101 * tipc_core_stop_net - shut down TIPC networking sub-systems
108 */ 102 */
109 103
110void tipc_core_stop_net(void) 104static void tipc_core_stop_net(void)
111{ 105{
112 tipc_eth_media_stop(); 106 tipc_eth_media_stop();
113 tipc_net_stop(); 107 tipc_net_stop();
@@ -121,10 +115,11 @@ int tipc_core_start_net(unsigned long addr)
121{ 115{
122 int res; 116 int res;
123 117
124 if ((res = tipc_net_start(addr)) || 118 res = tipc_net_start(addr);
125 (res = tipc_eth_media_start())) { 119 if (!res)
120 res = tipc_eth_media_start();
121 if (res)
126 tipc_core_stop_net(); 122 tipc_core_stop_net();
127 }
128 return res; 123 return res;
129} 124}
130 125
@@ -132,7 +127,7 @@ int tipc_core_start_net(unsigned long addr)
132 * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode 127 * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode
133 */ 128 */
134 129
135void tipc_core_stop(void) 130static void tipc_core_stop(void)
136{ 131{
137 if (tipc_mode != TIPC_NODE_MODE) 132 if (tipc_mode != TIPC_NODE_MODE)
138 return; 133 return;
@@ -143,17 +138,17 @@ void tipc_core_stop(void)
143 tipc_handler_stop(); 138 tipc_handler_stop();
144 tipc_cfg_stop(); 139 tipc_cfg_stop();
145 tipc_subscr_stop(); 140 tipc_subscr_stop();
146 tipc_reg_stop();
147 tipc_nametbl_stop(); 141 tipc_nametbl_stop();
148 tipc_ref_table_stop(); 142 tipc_ref_table_stop();
149 tipc_socket_stop(); 143 tipc_socket_stop();
144 tipc_log_resize(0);
150} 145}
151 146
152/** 147/**
153 * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode 148 * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode
154 */ 149 */
155 150
156int tipc_core_start(void) 151static int tipc_core_start(void)
157{ 152{
158 int res; 153 int res;
159 154
@@ -163,16 +158,22 @@ int tipc_core_start(void)
163 get_random_bytes(&tipc_random, sizeof(tipc_random)); 158 get_random_bytes(&tipc_random, sizeof(tipc_random));
164 tipc_mode = TIPC_NODE_MODE; 159 tipc_mode = TIPC_NODE_MODE;
165 160
166 if ((res = tipc_handler_start()) || 161 res = tipc_handler_start();
167 (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) || 162 if (!res)
168 (res = tipc_reg_start()) || 163 res = tipc_ref_table_init(tipc_max_ports, tipc_random);
169 (res = tipc_nametbl_init()) || 164 if (!res)
170 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || 165 res = tipc_nametbl_init();
171 (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) || 166 if (!res)
172 (res = tipc_netlink_start()) || 167 res = tipc_k_signal((Handler)tipc_subscr_start, 0);
173 (res = tipc_socket_init())) { 168 if (!res)
169 res = tipc_k_signal((Handler)tipc_cfg_init, 0);
170 if (!res)
171 res = tipc_netlink_start();
172 if (!res)
173 res = tipc_socket_init();
174 if (res)
174 tipc_core_stop(); 175 tipc_core_stop();
175 } 176
176 return res; 177 return res;
177} 178}
178 179
@@ -181,7 +182,9 @@ static int __init tipc_init(void)
181{ 182{
182 int res; 183 int res;
183 184
184 tipc_log_resize(CONFIG_TIPC_LOG); 185 if (tipc_log_resize(CONFIG_TIPC_LOG) != 0)
186 warn("Unable to create log buffer\n");
187
185 info("Activated (version " TIPC_MOD_VER 188 info("Activated (version " TIPC_MOD_VER
186 " compiled " __DATE__ " " __TIME__ ")\n"); 189 " compiled " __DATE__ " " __TIME__ ")\n");
187 190
@@ -189,14 +192,12 @@ static int __init tipc_init(void)
189 tipc_remote_management = 1; 192 tipc_remote_management = 1;
190 tipc_max_publications = 10000; 193 tipc_max_publications = 10000;
191 tipc_max_subscriptions = 2000; 194 tipc_max_subscriptions = 2000;
192 tipc_max_ports = delimit(CONFIG_TIPC_PORTS, 127, 65536); 195 tipc_max_ports = CONFIG_TIPC_PORTS;
193 tipc_max_zones = delimit(CONFIG_TIPC_ZONES, 1, 255); 196 tipc_max_nodes = CONFIG_TIPC_NODES;
194 tipc_max_clusters = delimit(CONFIG_TIPC_CLUSTERS, 1, 1);
195 tipc_max_nodes = delimit(CONFIG_TIPC_NODES, 8, 2047);
196 tipc_max_slaves = delimit(CONFIG_TIPC_SLAVE_NODES, 0, 2047);
197 tipc_net_id = 4711; 197 tipc_net_id = 4711;
198 198
199 if ((res = tipc_core_start())) 199 res = tipc_core_start();
200 if (res)
200 err("Unable to start in single node mode\n"); 201 err("Unable to start in single node mode\n");
201 else 202 else
202 info("Started in single node mode\n"); 203 info("Started in single node mode\n");
@@ -208,7 +209,6 @@ static void __exit tipc_exit(void)
208 tipc_core_stop_net(); 209 tipc_core_stop_net();
209 tipc_core_stop(); 210 tipc_core_stop();
210 info("Deactivated\n"); 211 info("Deactivated\n");
211 tipc_log_resize(0);
212} 212}
213 213
214module_init(tipc_init); 214module_init(tipc_init);
@@ -217,60 +217,3 @@ module_exit(tipc_exit);
217MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication"); 217MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication");
218MODULE_LICENSE("Dual BSD/GPL"); 218MODULE_LICENSE("Dual BSD/GPL");
219MODULE_VERSION(TIPC_MOD_VER); 219MODULE_VERSION(TIPC_MOD_VER);
220
221/* Native TIPC API for kernel-space applications (see tipc.h) */
222
223EXPORT_SYMBOL(tipc_attach);
224EXPORT_SYMBOL(tipc_detach);
225EXPORT_SYMBOL(tipc_get_addr);
226EXPORT_SYMBOL(tipc_get_mode);
227EXPORT_SYMBOL(tipc_createport);
228EXPORT_SYMBOL(tipc_deleteport);
229EXPORT_SYMBOL(tipc_ownidentity);
230EXPORT_SYMBOL(tipc_portimportance);
231EXPORT_SYMBOL(tipc_set_portimportance);
232EXPORT_SYMBOL(tipc_portunreliable);
233EXPORT_SYMBOL(tipc_set_portunreliable);
234EXPORT_SYMBOL(tipc_portunreturnable);
235EXPORT_SYMBOL(tipc_set_portunreturnable);
236EXPORT_SYMBOL(tipc_publish);
237EXPORT_SYMBOL(tipc_withdraw);
238EXPORT_SYMBOL(tipc_connect2port);
239EXPORT_SYMBOL(tipc_disconnect);
240EXPORT_SYMBOL(tipc_shutdown);
241EXPORT_SYMBOL(tipc_isconnected);
242EXPORT_SYMBOL(tipc_peer);
243EXPORT_SYMBOL(tipc_ref_valid);
244EXPORT_SYMBOL(tipc_send);
245EXPORT_SYMBOL(tipc_send_buf);
246EXPORT_SYMBOL(tipc_send2name);
247EXPORT_SYMBOL(tipc_forward2name);
248EXPORT_SYMBOL(tipc_send_buf2name);
249EXPORT_SYMBOL(tipc_forward_buf2name);
250EXPORT_SYMBOL(tipc_send2port);
251EXPORT_SYMBOL(tipc_forward2port);
252EXPORT_SYMBOL(tipc_send_buf2port);
253EXPORT_SYMBOL(tipc_forward_buf2port);
254EXPORT_SYMBOL(tipc_multicast);
255/* EXPORT_SYMBOL(tipc_multicast_buf); not available yet */
256EXPORT_SYMBOL(tipc_ispublished);
257EXPORT_SYMBOL(tipc_available_nodes);
258
259/* TIPC API for external bearers (see tipc_bearer.h) */
260
261EXPORT_SYMBOL(tipc_block_bearer);
262EXPORT_SYMBOL(tipc_continue);
263EXPORT_SYMBOL(tipc_disable_bearer);
264EXPORT_SYMBOL(tipc_enable_bearer);
265EXPORT_SYMBOL(tipc_recv_msg);
266EXPORT_SYMBOL(tipc_register_media);
267
268/* TIPC API for external APIs (see tipc_port.h) */
269
270EXPORT_SYMBOL(tipc_createport_raw);
271EXPORT_SYMBOL(tipc_reject_msg);
272EXPORT_SYMBOL(tipc_send_buf_fast);
273EXPORT_SYMBOL(tipc_acknowledge);
274EXPORT_SYMBOL(tipc_get_port);
275EXPORT_SYMBOL(tipc_get_handle);
276
diff --git a/net/tipc/core.h b/net/tipc/core.h
index a881f92a8537..997158546e25 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -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>
@@ -56,8 +52,15 @@
56#include <linux/netdevice.h> 52#include <linux/netdevice.h>
57#include <linux/in.h> 53#include <linux/in.h>
58#include <linux/list.h> 54#include <linux/list.h>
55#include <linux/slab.h>
59#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
60 57
58
59#define TIPC_MOD_VER "2.0.0"
60
61struct tipc_msg; /* msg.h */
62struct print_buf; /* log.h */
63
61/* 64/*
62 * TIPC sanity test macros 65 * TIPC sanity test macros
63 */ 66 */
@@ -79,7 +82,6 @@
79 * Note: TIPC_LOG is configured to echo its output to the system console; 82 * Note: TIPC_LOG is configured to echo its output to the system console;
80 * user-defined buffers can be configured to do the same thing. 83 * user-defined buffers can be configured to do the same thing.
81 */ 84 */
82
83extern struct print_buf *const TIPC_NULL; 85extern struct print_buf *const TIPC_NULL;
84extern struct print_buf *const TIPC_CONS; 86extern struct print_buf *const TIPC_CONS;
85extern struct print_buf *const TIPC_LOG; 87extern struct print_buf *const TIPC_LOG;
@@ -94,73 +96,35 @@ void tipc_printf(struct print_buf *, const char *fmt, ...);
94#define TIPC_OUTPUT TIPC_LOG 96#define TIPC_OUTPUT TIPC_LOG
95#endif 97#endif
96 98
97/*
98 * TIPC can be configured to send system messages to TIPC_OUTPUT
99 * or to the system console only.
100 */
101
102#ifdef CONFIG_TIPC_DEBUG
103
104#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 99#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
105 KERN_ERR "TIPC: " fmt, ## arg) 100 KERN_ERR "TIPC: " fmt, ## arg)
106#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 101#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
107 KERN_WARNING "TIPC: " fmt, ## arg) 102 KERN_WARNING "TIPC: " fmt, ## arg)
108#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 103#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
109 KERN_NOTICE "TIPC: " fmt, ## arg) 104 KERN_NOTICE "TIPC: " fmt, ## arg)
110
111#else
112 105
113#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) 106#ifdef CONFIG_TIPC_DEBUG
114#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg)
115#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg)
116
117#endif
118 107
119/* 108/*
120 * DBG_OUTPUT is the destination print buffer for debug messages. 109 * DBG_OUTPUT is the destination print buffer for debug messages.
121 * It defaults to the the null print buffer, but can be redefined
122 * (typically in the individual .c files being debugged) to allow
123 * selected debug messages to be generated where needed.
124 */ 110 */
125 111
126#ifndef DBG_OUTPUT 112#ifndef DBG_OUTPUT
127#define DBG_OUTPUT TIPC_NULL 113#define DBG_OUTPUT TIPC_LOG
128#endif 114#endif
129 115
130/* 116#define dbg(fmt, arg...) tipc_printf(DBG_OUTPUT, KERN_DEBUG fmt, ## arg);
131 * TIPC can be configured to send debug messages to the specified print buffer
132 * (typically DBG_OUTPUT) or to suppress them entirely.
133 */
134
135#ifdef CONFIG_TIPC_DEBUG
136 117
137#define dbg(fmt, arg...) \ 118#define msg_dbg(msg, txt) tipc_msg_dbg(DBG_OUTPUT, msg, txt);
138 do { \
139 if (DBG_OUTPUT != TIPC_NULL) \
140 tipc_printf(DBG_OUTPUT, fmt, ## arg); \
141 } while (0)
142#define msg_dbg(msg, txt) \
143 do { \
144 if (DBG_OUTPUT != TIPC_NULL) \
145 tipc_msg_dbg(DBG_OUTPUT, msg, txt); \
146 } while (0)
147#define dump(fmt, arg...) \
148 do { \
149 if (DBG_OUTPUT != TIPC_NULL) \
150 tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \
151 } while (0)
152 119
153void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); 120void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
154void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
155 121
156#else 122#else
157 123
158#define dbg(fmt, arg...) do {} while (0) 124#define dbg(fmt, arg...) do {} while (0)
159#define msg_dbg(msg, txt) do {} while (0) 125#define msg_dbg(msg, txt) do {} while (0)
160#define dump(fmt, arg...) do {} while (0)
161 126
162#define tipc_msg_dbg(...) do {} while (0) 127#define tipc_msg_dbg(buf, msg, txt) do {} while (0)
163#define tipc_dump_dbg(...) do {} while (0)
164 128
165#endif 129#endif
166 130
@@ -172,14 +136,18 @@ void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
172#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */ 136#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
173 137
174/* 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/*
175 * Global configuration variables 146 * Global configuration variables
176 */ 147 */
177 148
178extern u32 tipc_own_addr; 149extern u32 tipc_own_addr;
179extern int tipc_max_zones;
180extern int tipc_max_clusters;
181extern int tipc_max_nodes; 150extern int tipc_max_nodes;
182extern int tipc_max_slaves;
183extern int tipc_max_ports; 151extern int tipc_max_ports;
184extern int tipc_max_subscriptions; 152extern int tipc_max_subscriptions;
185extern int tipc_max_publications; 153extern int tipc_max_publications;
@@ -200,10 +168,7 @@ extern atomic_t tipc_user_count;
200 * Routines available to privileged subsystems 168 * Routines available to privileged subsystems
201 */ 169 */
202 170
203extern int tipc_core_start(void); 171extern int tipc_core_start_net(unsigned long);
204extern void tipc_core_stop(void);
205extern int tipc_core_start_net(unsigned long addr);
206extern void tipc_core_stop_net(void);
207extern int tipc_handler_start(void); 172extern int tipc_handler_start(void);
208extern void tipc_handler_stop(void); 173extern void tipc_handler_stop(void);
209extern int tipc_netlink_start(void); 174extern int tipc_netlink_start(void);
@@ -241,7 +206,6 @@ u32 tipc_k_signal(Handler routine, unsigned long argument);
241static inline void k_init_timer(struct timer_list *timer, Handler routine, 206static inline void k_init_timer(struct timer_list *timer, Handler routine,
242 unsigned long argument) 207 unsigned long argument)
243{ 208{
244 dbg("initializing timer %p\n", timer);
245 setup_timer(timer, routine, argument); 209 setup_timer(timer, routine, argument);
246} 210}
247 211
@@ -261,7 +225,6 @@ static inline void k_init_timer(struct timer_list *timer, Handler routine,
261 225
262static inline void k_start_timer(struct timer_list *timer, unsigned long msec) 226static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
263{ 227{
264 dbg("starting timer %p for %u\n", timer, msec);
265 mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1); 228 mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1);
266} 229}
267 230
@@ -278,7 +241,6 @@ static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
278 241
279static inline void k_cancel_timer(struct timer_list *timer) 242static inline void k_cancel_timer(struct timer_list *timer)
280{ 243{
281 dbg("cancelling timer %p\n", timer);
282 del_timer_sync(timer); 244 del_timer_sync(timer);
283} 245}
284 246
@@ -296,7 +258,6 @@ static inline void k_cancel_timer(struct timer_list *timer)
296 258
297static inline void k_term_timer(struct timer_list *timer) 259static inline void k_term_timer(struct timer_list *timer)
298{ 260{
299 dbg("terminating timer %p\n", timer);
300} 261}
301 262
302 263
@@ -324,29 +285,7 @@ static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
324 return (struct tipc_msg *)skb->data; 285 return (struct tipc_msg *)skb->data;
325} 286}
326 287
327/** 288extern struct sk_buff *tipc_buf_acquire(u32 size);
328 * buf_acquire - creates a TIPC message buffer
329 * @size: message size (including TIPC header)
330 *
331 * Returns a new buffer with data pointers set to the specified size.
332 *
333 * NOTE: Headroom is reserved to allow prepending of a data link header.
334 * There may also be unrequested tailroom present at the buffer's end.
335 */
336
337static inline struct sk_buff *buf_acquire(u32 size)
338{
339 struct sk_buff *skb;
340 unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
341
342 skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
343 if (skb) {
344 skb_reserve(skb, BUF_HEADROOM);
345 skb_put(skb, size);
346 skb->next = NULL;
347 }
348 return skb;
349}
350 289
351/** 290/**
352 * buf_discard - frees a TIPC message buffer 291 * buf_discard - frees a TIPC message buffer
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 74b7d1e28aec..fa026bd91a68 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -35,27 +35,13 @@
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 */
47#define TIPC_LINK_REQ_SLOW 600000 /* normal delay if bearer has links */ 43#define TIPC_LINK_REQ_SLOW 600000 /* normal delay if bearer has links */
48 44
49#if 0
50#define GET_NODE_INFO 300
51#define GET_NODE_INFO_RESULT 301
52#define FORWARD_LINK_PROBE 302
53#define LINK_REQUEST_REJECTED 303
54#define LINK_REQUEST_ACCEPTED 304
55#define DROP_LINK_REQUEST 305
56#define CHECK_LINK_COUNT 306
57#endif
58
59/* 45/*
60 * TODO: Most of the inter-cluster setup stuff should be 46 * TODO: Most of the inter-cluster setup stuff should be
61 * rewritten, and be made conformant with specification. 47 * rewritten, and be made conformant with specification.
@@ -78,30 +64,6 @@ struct link_req {
78 unsigned int timer_intv; 64 unsigned int timer_intv;
79}; 65};
80 66
81
82#if 0
83int disc_create_link(const struct tipc_link_create *argv)
84{
85 /*
86 * Code for inter cluster link setup here
87 */
88 return TIPC_OK;
89}
90#endif
91
92/*
93 * disc_lost_link(): A link has lost contact
94 */
95
96void tipc_disc_link_event(u32 addr, char *name, int up)
97{
98 if (in_own_cluster(addr))
99 return;
100 /*
101 * Code for inter cluster link setup here
102 */
103}
104
105/** 67/**
106 * tipc_disc_init_msg - initialize a link setup message 68 * tipc_disc_init_msg - initialize a link setup message
107 * @type: message type (request or response) 69 * @type: message type (request or response)
@@ -115,12 +77,12 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
115 u32 dest_domain, 77 u32 dest_domain,
116 struct bearer *b_ptr) 78 struct bearer *b_ptr)
117{ 79{
118 struct sk_buff *buf = buf_acquire(DSC_H_SIZE); 80 struct sk_buff *buf = tipc_buf_acquire(DSC_H_SIZE);
119 struct tipc_msg *msg; 81 struct tipc_msg *msg;
120 82
121 if (buf) { 83 if (buf) {
122 msg = buf_msg(buf); 84 msg = buf_msg(buf);
123 msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain); 85 tipc_msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain);
124 msg_set_non_seq(msg, 1); 86 msg_set_non_seq(msg, 1);
125 msg_set_req_links(msg, req_links); 87 msg_set_req_links(msg, req_links);
126 msg_set_dest_domain(msg, dest_domain); 88 msg_set_dest_domain(msg, dest_domain);
@@ -144,7 +106,7 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
144 char media_addr_str[64]; 106 char media_addr_str[64];
145 struct print_buf pb; 107 struct print_buf pb;
146 108
147 addr_string_fill(node_addr_str, node_addr); 109 tipc_addr_string_fill(node_addr_str, node_addr);
148 tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str)); 110 tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str));
149 tipc_media_addr_printf(&pb, media_addr); 111 tipc_media_addr_printf(&pb, media_addr);
150 tipc_printbuf_validate(&pb); 112 tipc_printbuf_validate(&pb);
@@ -168,8 +130,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
168 u32 net_id = msg_bc_netid(msg); 130 u32 net_id = msg_bc_netid(msg);
169 u32 type = msg_type(msg); 131 u32 type = msg_type(msg);
170 132
171 msg_get_media_addr(msg,&media_addr); 133 msg_get_media_addr(msg, &media_addr);
172 msg_dbg(msg, "RECV:");
173 buf_discard(buf); 134 buf_discard(buf);
174 135
175 if (net_id != tipc_net_id) 136 if (net_id != tipc_net_id)
@@ -183,11 +144,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
183 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr); 144 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr);
184 return; 145 return;
185 } 146 }
186 if (!in_scope(dest, tipc_own_addr)) 147 if (!tipc_in_scope(dest, tipc_own_addr))
187 return;
188 if (is_slave(tipc_own_addr) && is_slave(orig))
189 return;
190 if (is_slave(orig) && !in_own_cluster(orig))
191 return; 148 return;
192 if (in_own_cluster(orig)) { 149 if (in_own_cluster(orig)) {
193 /* Always accept link here */ 150 /* Always accept link here */
@@ -196,16 +153,22 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
196 struct tipc_node *n_ptr = tipc_node_find(orig); 153 struct tipc_node *n_ptr = tipc_node_find(orig);
197 int link_fully_up; 154 int link_fully_up;
198 155
199 dbg(" in own cluster\n");
200 if (n_ptr == NULL) { 156 if (n_ptr == NULL) {
201 n_ptr = tipc_node_create(orig); 157 n_ptr = tipc_node_create(orig);
202 if (!n_ptr) 158 if (!n_ptr)
203 return; 159 return;
204 } 160 }
205 spin_lock_bh(&n_ptr->lock); 161 spin_lock_bh(&n_ptr->lock);
162
163 /* Don't talk to neighbor during cleanup after last session */
164
165 if (n_ptr->cleanup_required) {
166 spin_unlock_bh(&n_ptr->lock);
167 return;
168 }
169
206 link = n_ptr->links[b_ptr->identity]; 170 link = n_ptr->links[b_ptr->identity];
207 if (!link) { 171 if (!link) {
208 dbg("creating link\n");
209 link = tipc_link_create(b_ptr, orig, &media_addr); 172 link = tipc_link_create(b_ptr, orig, &media_addr);
210 if (!link) { 173 if (!link) {
211 spin_unlock_bh(&n_ptr->lock); 174 spin_unlock_bh(&n_ptr->lock);
@@ -224,13 +187,12 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
224 memcpy(addr, &media_addr, sizeof(*addr)); 187 memcpy(addr, &media_addr, sizeof(*addr));
225 tipc_link_reset(link); 188 tipc_link_reset(link);
226 } 189 }
227 link_fully_up = (link->state == WORKING_WORKING); 190 link_fully_up = link_working_working(link);
228 spin_unlock_bh(&n_ptr->lock); 191 spin_unlock_bh(&n_ptr->lock);
229 if ((type == DSC_RESP_MSG) || link_fully_up) 192 if ((type == DSC_RESP_MSG) || link_fully_up)
230 return; 193 return;
231 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); 194 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
232 if (rbuf != NULL) { 195 if (rbuf != NULL) {
233 msg_dbg(buf_msg(rbuf),"SEND:");
234 b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr); 196 b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr);
235 buf_discard(rbuf); 197 buf_discard(rbuf);
236 } 198 }
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index c36eaeb7d5d0..d2c3cffb79fc 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -37,8 +37,6 @@
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 bearer *b_ptr,
@@ -50,9 +48,4 @@ void tipc_disc_stop_link_req(struct link_req *req);
50 48
51void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr); 49void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr);
52 50
53void tipc_disc_link_event(u32 addr, char *name, int up);
54#if 0
55int disc_create_link(const struct tipc_link_create *argv);
56#endif
57
58#endif 51#endif
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 524ba5696d4d..b69092eb95d8 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -34,11 +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 <net/net_namespace.h>
42 39
43#define MAX_ETH_BEARERS 2 40#define MAX_ETH_BEARERS 2
44#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI 41#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI
@@ -59,7 +56,7 @@ struct eth_bearer {
59}; 56};
60 57
61static struct eth_bearer eth_bearers[MAX_ETH_BEARERS]; 58static struct eth_bearer eth_bearers[MAX_ETH_BEARERS];
62static int eth_started = 0; 59static int eth_started;
63static struct notifier_block notifier; 60static struct notifier_block notifier;
64 61
65/** 62/**
@@ -71,17 +68,26 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
71{ 68{
72 struct sk_buff *clone; 69 struct sk_buff *clone;
73 struct net_device *dev; 70 struct net_device *dev;
71 int delta;
74 72
75 clone = skb_clone(buf, GFP_ATOMIC); 73 clone = skb_clone(buf, GFP_ATOMIC);
76 if (clone) { 74 if (!clone)
77 skb_reset_network_header(clone); 75 return 0;
78 dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; 76
79 clone->dev = dev; 77 dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev;
80 dev_hard_header(clone, dev, ETH_P_TIPC, 78 delta = dev->hard_header_len - skb_headroom(buf);
81 &dest->dev_addr.eth_addr, 79
82 dev->dev_addr, clone->len); 80 if ((delta > 0) &&
83 dev_queue_xmit(clone); 81 pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
82 kfree_skb(clone);
83 return 0;
84 } 84 }
85
86 skb_reset_network_header(clone);
87 clone->dev = dev;
88 dev_hard_header(clone, dev, ETH_P_TIPC, &dest->dev_addr.eth_addr,
89 dev->dev_addr, clone->len);
90 dev_queue_xmit(clone);
85 return 0; 91 return 0;
86} 92}
87 93
@@ -91,15 +97,12 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
91 * Accept only packets explicitly sent to this node, or broadcast packets; 97 * Accept only packets explicitly sent to this node, or broadcast packets;
92 * ignores packets sent using Ethernet multicast, and traffic sent to other 98 * ignores packets sent using Ethernet multicast, and traffic sent to other
93 * nodes (which can happen if interface is running in promiscuous mode). 99 * nodes (which can happen if interface is running in promiscuous mode).
94 * Routine truncates any Ethernet padding/CRC appended to the message,
95 * and ensures message size matches actual length
96 */ 100 */
97 101
98static int recv_msg(struct sk_buff *buf, struct net_device *dev, 102static int recv_msg(struct sk_buff *buf, struct net_device *dev,
99 struct packet_type *pt, struct net_device *orig_dev) 103 struct packet_type *pt, struct net_device *orig_dev)
100{ 104{
101 struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; 105 struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv;
102 u32 size;
103 106
104 if (!net_eq(dev_net(dev), &init_net)) { 107 if (!net_eq(dev_net(dev), &init_net)) {
105 kfree_skb(buf); 108 kfree_skb(buf);
@@ -108,13 +111,9 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
108 111
109 if (likely(eb_ptr->bearer)) { 112 if (likely(eb_ptr->bearer)) {
110 if (likely(buf->pkt_type <= PACKET_BROADCAST)) { 113 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
111 size = msg_size((struct tipc_msg *)buf->data); 114 buf->next = NULL;
112 skb_trim(buf, size); 115 tipc_recv_msg(buf, eb_ptr->bearer);
113 if (likely(buf->len == size)) { 116 return 0;
114 buf->next = NULL;
115 tipc_recv_msg(buf, eb_ptr->bearer);
116 return 0;
117 }
118 } 117 }
119 } 118 }
120 kfree_skb(buf); 119 kfree_skb(buf);
@@ -132,10 +131,20 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
132 struct eth_bearer *eb_ptr = &eth_bearers[0]; 131 struct eth_bearer *eb_ptr = &eth_bearers[0];
133 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS]; 132 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
134 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; 133 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
134 int pending_dev = 0;
135
136 /* Find unused Ethernet bearer structure */
137
138 while (eb_ptr->dev) {
139 if (!eb_ptr->bearer)
140 pending_dev++;
141 if (++eb_ptr == stop)
142 return pending_dev ? -EAGAIN : -EDQUOT;
143 }
135 144
136 /* Find device with specified name */ 145 /* Find device with specified name */
137 146
138 for_each_netdev(&init_net, pdev){ 147 for_each_netdev(&init_net, pdev) {
139 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) { 148 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
140 dev = pdev; 149 dev = pdev;
141 break; 150 break;
@@ -146,7 +155,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
146 155
147 /* Find Ethernet bearer for device (or create one) */ 156 /* Find Ethernet bearer for device (or create one) */
148 157
149 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++;
150 if (eb_ptr == stop) 160 if (eb_ptr == stop)
151 return -EDQUOT; 161 return -EDQUOT;
152 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 dd4c18b9a35b..18702f58d111 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -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
@@ -99,23 +85,6 @@ struct link_name {
99 char if_peer[TIPC_MAX_IF_NAME]; 85 char if_peer[TIPC_MAX_IF_NAME];
100}; 86};
101 87
102#if 0
103
104/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
105
106/**
107 * struct link_event - link up/down event notification
108 */
109
110struct link_event {
111 u32 addr;
112 int up;
113 void (*fcn)(u32, char *, int);
114 char name[TIPC_MAX_LINK_NAME];
115};
116
117#endif
118
119static void link_handle_out_of_seq_msg(struct link *l_ptr, 88static void link_handle_out_of_seq_msg(struct link *l_ptr,
120 struct sk_buff *buf); 89 struct sk_buff *buf);
121static 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);
@@ -127,71 +96,9 @@ static int link_send_sections_long(struct port *sender,
127static void link_check_defragm_bufs(struct link *l_ptr); 96static void link_check_defragm_bufs(struct link *l_ptr);
128static void link_state_event(struct link *l_ptr, u32 event); 97static void link_state_event(struct link *l_ptr, u32 event);
129static void link_reset_statistics(struct link *l_ptr); 98static void link_reset_statistics(struct link *l_ptr);
130static void link_print(struct link *l_ptr, struct print_buf *buf, 99static void link_print(struct link *l_ptr, const char *str);
131 const char *str); 100static void link_start(struct link *l_ptr);
132 101static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
133/*
134 * Debugging code used by link routines only
135 *
136 * When debugging link problems on a system that has multiple links,
137 * the standard TIPC debugging routines may not be useful since they
138 * allow the output from multiple links to be intermixed. For this reason
139 * routines of the form "dbg_link_XXX()" have been created that will capture
140 * debug info into a link's personal print buffer, which can then be dumped
141 * into the TIPC system log (TIPC_LOG) upon request.
142 *
143 * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size
144 * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0,
145 * the dbg_link_XXX() routines simply send their output to the standard
146 * debug print buffer (DBG_OUTPUT), if it has been defined; this can be useful
147 * when there is only a single link in the system being debugged.
148 *
149 * Notes:
150 * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE
151 * - "l_ptr" must be valid when using dbg_link_XXX() macros
152 */
153
154#define LINK_LOG_BUF_SIZE 0
155
156#define dbg_link(fmt, arg...) \
157 do { \
158 if (LINK_LOG_BUF_SIZE) \
159 tipc_printf(&l_ptr->print_buf, fmt, ## arg); \
160 } while (0)
161#define dbg_link_msg(msg, txt) \
162 do { \
163 if (LINK_LOG_BUF_SIZE) \
164 tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \
165 } while (0)
166#define dbg_link_state(txt) \
167 do { \
168 if (LINK_LOG_BUF_SIZE) \
169 link_print(l_ptr, &l_ptr->print_buf, txt); \
170 } while (0)
171#define dbg_link_dump() do { \
172 if (LINK_LOG_BUF_SIZE) { \
173 tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \
174 tipc_printbuf_move(LOG, &l_ptr->print_buf); \
175 } \
176} while (0)
177
178static void dbg_print_link(struct link *l_ptr, const char *str)
179{
180 if (DBG_OUTPUT != TIPC_NULL)
181 link_print(l_ptr, DBG_OUTPUT, str);
182}
183
184static void dbg_print_buf_chain(struct sk_buff *root_buf)
185{
186 if (DBG_OUTPUT != TIPC_NULL) {
187 struct sk_buff *buf = root_buf;
188
189 while (buf) {
190 msg_dbg(buf_msg(buf), "In chain: ");
191 buf = buf->next;
192 }
193 }
194}
195 102
196/* 103/*
197 * Simple link routines 104 * Simple link routines
@@ -202,41 +109,6 @@ static unsigned int align(unsigned int i)
202 return (i + 3) & ~3u; 109 return (i + 3) & ~3u;
203} 110}
204 111
205static int link_working_working(struct link *l_ptr)
206{
207 return (l_ptr->state == WORKING_WORKING);
208}
209
210static int link_working_unknown(struct link *l_ptr)
211{
212 return (l_ptr->state == WORKING_UNKNOWN);
213}
214
215static int link_reset_unknown(struct link *l_ptr)
216{
217 return (l_ptr->state == RESET_UNKNOWN);
218}
219
220static int link_reset_reset(struct link *l_ptr)
221{
222 return (l_ptr->state == RESET_RESET);
223}
224
225static int link_blocked(struct link *l_ptr)
226{
227 return (l_ptr->exp_msg_count || l_ptr->blocked);
228}
229
230static int link_congested(struct link *l_ptr)
231{
232 return (l_ptr->out_queue_size >= l_ptr->queue_limit[0]);
233}
234
235static u32 link_max_pkt(struct link *l_ptr)
236{
237 return l_ptr->max_pkt;
238}
239
240static void link_init_max_pkt(struct link *l_ptr) 112static void link_init_max_pkt(struct link *l_ptr)
241{ 113{
242 u32 max_pkt; 114 u32 max_pkt;
@@ -274,13 +146,13 @@ int tipc_link_is_up(struct link *l_ptr)
274{ 146{
275 if (!l_ptr) 147 if (!l_ptr)
276 return 0; 148 return 0;
277 return (link_working_working(l_ptr) || link_working_unknown(l_ptr)); 149 return link_working_working(l_ptr) || link_working_unknown(l_ptr);
278} 150}
279 151
280int tipc_link_is_active(struct link *l_ptr) 152int tipc_link_is_active(struct link *l_ptr)
281{ 153{
282 return ((l_ptr->owner->active_links[0] == l_ptr) || 154 return (l_ptr->owner->active_links[0] == l_ptr) ||
283 (l_ptr->owner->active_links[1] == l_ptr)); 155 (l_ptr->owner->active_links[1] == l_ptr);
284} 156}
285 157
286/** 158/**
@@ -315,14 +187,17 @@ static int link_name_validate(const char *name, struct link_name *name_parts)
315 /* ensure all component parts of link name are present */ 187 /* ensure all component parts of link name are present */
316 188
317 addr_local = name_copy; 189 addr_local = name_copy;
318 if ((if_local = strchr(addr_local, ':')) == NULL) 190 if_local = strchr(addr_local, ':');
191 if (if_local == NULL)
319 return 0; 192 return 0;
320 *(if_local++) = 0; 193 *(if_local++) = 0;
321 if ((addr_peer = strchr(if_local, '-')) == NULL) 194 addr_peer = strchr(if_local, '-');
195 if (addr_peer == NULL)
322 return 0; 196 return 0;
323 *(addr_peer++) = 0; 197 *(addr_peer++) = 0;
324 if_local_len = addr_peer - if_local; 198 if_local_len = addr_peer - if_local;
325 if ((if_peer = strchr(addr_peer, ':')) == NULL) 199 if_peer = strchr(addr_peer, ':');
200 if (if_peer == NULL)
326 return 0; 201 return 0;
327 *(if_peer++) = 0; 202 *(if_peer++) = 0;
328 if_peer_len = strlen(if_peer) + 1; 203 if_peer_len = strlen(if_peer) + 1;
@@ -378,8 +253,8 @@ static void link_timeout(struct link *l_ptr)
378 struct tipc_msg *msg = buf_msg(l_ptr->first_out); 253 struct tipc_msg *msg = buf_msg(l_ptr->first_out);
379 u32 length = msg_size(msg); 254 u32 length = msg_size(msg);
380 255
381 if ((msg_user(msg) == MSG_FRAGMENTER) 256 if ((msg_user(msg) == MSG_FRAGMENTER) &&
382 && (msg_type(msg) == FIRST_FRAGMENT)) { 257 (msg_type(msg) == FIRST_FRAGMENT)) {
383 length = msg_size(msg_get_wrapped(msg)); 258 length = msg_size(msg_get_wrapped(msg));
384 } 259 }
385 if (length) { 260 if (length) {
@@ -441,17 +316,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
441 return NULL; 316 return NULL;
442 } 317 }
443 318
444 if (LINK_LOG_BUF_SIZE) {
445 char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC);
446
447 if (!pb) {
448 kfree(l_ptr);
449 warn("Link creation failed, no memory for print buffer\n");
450 return NULL;
451 }
452 tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
453 }
454
455 l_ptr->addr = peer; 319 l_ptr->addr = peer;
456 if_name = strchr(b_ptr->publ.name, ':') + 1; 320 if_name = strchr(b_ptr->publ.name, ':') + 1;
457 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 321 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:",
@@ -468,7 +332,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
468 332
469 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; 333 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg;
470 msg = l_ptr->pmsg; 334 msg = l_ptr->pmsg;
471 msg_init(msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, l_ptr->addr); 335 tipc_msg_init(msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, l_ptr->addr);
472 msg_set_size(msg, sizeof(l_ptr->proto_msg)); 336 msg_set_size(msg, sizeof(l_ptr->proto_msg));
473 msg_set_session(msg, (tipc_random & 0xffff)); 337 msg_set_session(msg, (tipc_random & 0xffff));
474 msg_set_bearer_id(msg, b_ptr->identity); 338 msg_set_bearer_id(msg, b_ptr->identity);
@@ -486,18 +350,13 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
486 350
487 l_ptr->owner = tipc_node_attach_link(l_ptr); 351 l_ptr->owner = tipc_node_attach_link(l_ptr);
488 if (!l_ptr->owner) { 352 if (!l_ptr->owner) {
489 if (LINK_LOG_BUF_SIZE)
490 kfree(l_ptr->print_buf.buf);
491 kfree(l_ptr); 353 kfree(l_ptr);
492 return NULL; 354 return NULL;
493 } 355 }
494 356
495 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); 357 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
496 list_add_tail(&l_ptr->link_list, &b_ptr->links); 358 list_add_tail(&l_ptr->link_list, &b_ptr->links);
497 tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr); 359 tipc_k_signal((Handler)link_start, (unsigned long)l_ptr);
498
499 dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",
500 l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit);
501 360
502 return l_ptr; 361 return l_ptr;
503} 362}
@@ -518,8 +377,6 @@ void tipc_link_delete(struct link *l_ptr)
518 return; 377 return;
519 } 378 }
520 379
521 dbg("tipc_link_delete()\n");
522
523 k_cancel_timer(&l_ptr->timer); 380 k_cancel_timer(&l_ptr->timer);
524 381
525 tipc_node_lock(l_ptr->owner); 382 tipc_node_lock(l_ptr->owner);
@@ -527,16 +384,13 @@ void tipc_link_delete(struct link *l_ptr)
527 tipc_node_detach_link(l_ptr->owner, l_ptr); 384 tipc_node_detach_link(l_ptr->owner, l_ptr);
528 tipc_link_stop(l_ptr); 385 tipc_link_stop(l_ptr);
529 list_del_init(&l_ptr->link_list); 386 list_del_init(&l_ptr->link_list);
530 if (LINK_LOG_BUF_SIZE)
531 kfree(l_ptr->print_buf.buf);
532 tipc_node_unlock(l_ptr->owner); 387 tipc_node_unlock(l_ptr->owner);
533 k_term_timer(&l_ptr->timer); 388 k_term_timer(&l_ptr->timer);
534 kfree(l_ptr); 389 kfree(l_ptr);
535} 390}
536 391
537void tipc_link_start(struct link *l_ptr) 392static void link_start(struct link *l_ptr)
538{ 393{
539 dbg("tipc_link_start %x\n", l_ptr);
540 link_state_event(l_ptr, STARTING_EVT); 394 link_state_event(l_ptr, STARTING_EVT);
541} 395}
542 396
@@ -561,9 +415,8 @@ static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
561 goto exit; 415 goto exit;
562 if (!list_empty(&p_ptr->wait_list)) 416 if (!list_empty(&p_ptr->wait_list))
563 goto exit; 417 goto exit;
564 p_ptr->congested_link = l_ptr;
565 p_ptr->publ.congested = 1; 418 p_ptr->publ.congested = 1;
566 p_ptr->waiting_pkts = 1 + ((sz - 1) / link_max_pkt(l_ptr)); 419 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt);
567 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); 420 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports);
568 l_ptr->stats.link_congs++; 421 l_ptr->stats.link_congs++;
569exit: 422exit:
@@ -592,7 +445,6 @@ void tipc_link_wakeup_ports(struct link *l_ptr, int all)
592 if (win <= 0) 445 if (win <= 0)
593 break; 446 break;
594 list_del_init(&p_ptr->wait_list); 447 list_del_init(&p_ptr->wait_list);
595 p_ptr->congested_link = NULL;
596 spin_lock_bh(p_ptr->publ.lock); 448 spin_lock_bh(p_ptr->publ.lock);
597 p_ptr->publ.congested = 0; 449 p_ptr->publ.congested = 0;
598 p_ptr->wakeup(&p_ptr->publ); 450 p_ptr->wakeup(&p_ptr->publ);
@@ -671,39 +523,9 @@ void tipc_link_stop(struct link *l_ptr)
671 l_ptr->proto_msg_queue = NULL; 523 l_ptr->proto_msg_queue = NULL;
672} 524}
673 525
674#if 0
675
676/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ 526/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
677
678static void link_recv_event(struct link_event *ev)
679{
680 ev->fcn(ev->addr, ev->name, ev->up);
681 kfree(ev);
682}
683
684static void link_send_event(void (*fcn)(u32 a, char *n, int up),
685 struct link *l_ptr, int up)
686{
687 struct link_event *ev;
688
689 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
690 if (!ev) {
691 warn("Link event allocation failure\n");
692 return;
693 }
694 ev->addr = l_ptr->addr;
695 ev->up = up;
696 ev->fcn = fcn;
697 memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME);
698 tipc_k_signal((Handler)link_recv_event, (unsigned long)ev);
699}
700
701#else
702
703#define link_send_event(fcn, l_ptr, up) do { } while (0) 527#define link_send_event(fcn, l_ptr, up) do { } while (0)
704 528
705#endif
706
707void tipc_link_reset(struct link *l_ptr) 529void tipc_link_reset(struct link *l_ptr)
708{ 530{
709 struct sk_buff *buf; 531 struct sk_buff *buf;
@@ -720,17 +542,13 @@ void tipc_link_reset(struct link *l_ptr)
720 link_init_max_pkt(l_ptr); 542 link_init_max_pkt(l_ptr);
721 543
722 l_ptr->state = RESET_UNKNOWN; 544 l_ptr->state = RESET_UNKNOWN;
723 dbg_link_state("Resetting Link\n");
724 545
725 if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) 546 if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET))
726 return; 547 return;
727 548
728 tipc_node_link_down(l_ptr->owner, l_ptr); 549 tipc_node_link_down(l_ptr->owner, l_ptr);
729 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); 550 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
730#if 0 551
731 tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name);
732 dbg_link_dump();
733#endif
734 if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && 552 if (was_active_link && tipc_node_has_active_links(l_ptr->owner) &&
735 l_ptr->owner->permit_changeover) { 553 l_ptr->owner->permit_changeover) {
736 l_ptr->reset_checkpoint = checkpoint; 554 l_ptr->reset_checkpoint = checkpoint;
@@ -797,25 +615,18 @@ static void link_state_event(struct link *l_ptr, unsigned event)
797 return; /* Not yet. */ 615 return; /* Not yet. */
798 616
799 if (link_blocked(l_ptr)) { 617 if (link_blocked(l_ptr)) {
800 if (event == TIMEOUT_EVT) { 618 if (event == TIMEOUT_EVT)
801 link_set_timer(l_ptr, cont_intv); 619 link_set_timer(l_ptr, cont_intv);
802 }
803 return; /* Changeover going on */ 620 return; /* Changeover going on */
804 } 621 }
805 dbg_link("STATE_EV: <%s> ", l_ptr->name);
806 622
807 switch (l_ptr->state) { 623 switch (l_ptr->state) {
808 case WORKING_WORKING: 624 case WORKING_WORKING:
809 dbg_link("WW/");
810 switch (event) { 625 switch (event) {
811 case TRAFFIC_MSG_EVT: 626 case TRAFFIC_MSG_EVT:
812 dbg_link("TRF-");
813 /* fall through */
814 case ACTIVATE_MSG: 627 case ACTIVATE_MSG:
815 dbg_link("ACT\n");
816 break; 628 break;
817 case TIMEOUT_EVT: 629 case TIMEOUT_EVT:
818 dbg_link("TIM ");
819 if (l_ptr->next_in_no != l_ptr->checkpoint) { 630 if (l_ptr->next_in_no != l_ptr->checkpoint) {
820 l_ptr->checkpoint = l_ptr->next_in_no; 631 l_ptr->checkpoint = l_ptr->next_in_no;
821 if (tipc_bclink_acks_missing(l_ptr->owner)) { 632 if (tipc_bclink_acks_missing(l_ptr->owner)) {
@@ -830,7 +641,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
830 link_set_timer(l_ptr, cont_intv); 641 link_set_timer(l_ptr, cont_intv);
831 break; 642 break;
832 } 643 }
833 dbg_link(" -> WU\n");
834 l_ptr->state = WORKING_UNKNOWN; 644 l_ptr->state = WORKING_UNKNOWN;
835 l_ptr->fsm_msg_cnt = 0; 645 l_ptr->fsm_msg_cnt = 0;
836 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); 646 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
@@ -838,7 +648,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
838 link_set_timer(l_ptr, cont_intv / 4); 648 link_set_timer(l_ptr, cont_intv / 4);
839 break; 649 break;
840 case RESET_MSG: 650 case RESET_MSG:
841 dbg_link("RES -> RR\n");
842 info("Resetting link <%s>, requested by peer\n", 651 info("Resetting link <%s>, requested by peer\n",
843 l_ptr->name); 652 l_ptr->name);
844 tipc_link_reset(l_ptr); 653 tipc_link_reset(l_ptr);
@@ -853,18 +662,14 @@ static void link_state_event(struct link *l_ptr, unsigned event)
853 } 662 }
854 break; 663 break;
855 case WORKING_UNKNOWN: 664 case WORKING_UNKNOWN:
856 dbg_link("WU/");
857 switch (event) { 665 switch (event) {
858 case TRAFFIC_MSG_EVT: 666 case TRAFFIC_MSG_EVT:
859 dbg_link("TRF-");
860 case ACTIVATE_MSG: 667 case ACTIVATE_MSG:
861 dbg_link("ACT -> WW\n");
862 l_ptr->state = WORKING_WORKING; 668 l_ptr->state = WORKING_WORKING;
863 l_ptr->fsm_msg_cnt = 0; 669 l_ptr->fsm_msg_cnt = 0;
864 link_set_timer(l_ptr, cont_intv); 670 link_set_timer(l_ptr, cont_intv);
865 break; 671 break;
866 case RESET_MSG: 672 case RESET_MSG:
867 dbg_link("RES -> RR\n");
868 info("Resetting link <%s>, requested by peer " 673 info("Resetting link <%s>, requested by peer "
869 "while probing\n", l_ptr->name); 674 "while probing\n", l_ptr->name);
870 tipc_link_reset(l_ptr); 675 tipc_link_reset(l_ptr);
@@ -875,9 +680,7 @@ static void link_state_event(struct link *l_ptr, unsigned event)
875 link_set_timer(l_ptr, cont_intv); 680 link_set_timer(l_ptr, cont_intv);
876 break; 681 break;
877 case TIMEOUT_EVT: 682 case TIMEOUT_EVT:
878 dbg_link("TIM ");
879 if (l_ptr->next_in_no != l_ptr->checkpoint) { 683 if (l_ptr->next_in_no != l_ptr->checkpoint) {
880 dbg_link("-> WW \n");
881 l_ptr->state = WORKING_WORKING; 684 l_ptr->state = WORKING_WORKING;
882 l_ptr->fsm_msg_cnt = 0; 685 l_ptr->fsm_msg_cnt = 0;
883 l_ptr->checkpoint = l_ptr->next_in_no; 686 l_ptr->checkpoint = l_ptr->next_in_no;
@@ -888,16 +691,11 @@ static void link_state_event(struct link *l_ptr, unsigned event)
888 } 691 }
889 link_set_timer(l_ptr, cont_intv); 692 link_set_timer(l_ptr, cont_intv);
890 } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) { 693 } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) {
891 dbg_link("Probing %u/%u,timer = %u ms)\n",
892 l_ptr->fsm_msg_cnt, l_ptr->abort_limit,
893 cont_intv / 4);
894 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 694 tipc_link_send_proto_msg(l_ptr, STATE_MSG,
895 1, 0, 0, 0, 0); 695 1, 0, 0, 0, 0);
896 l_ptr->fsm_msg_cnt++; 696 l_ptr->fsm_msg_cnt++;
897 link_set_timer(l_ptr, cont_intv / 4); 697 link_set_timer(l_ptr, cont_intv / 4);
898 } else { /* Link has failed */ 698 } else { /* Link has failed */
899 dbg_link("-> RU (%u probes unanswered)\n",
900 l_ptr->fsm_msg_cnt);
901 warn("Resetting link <%s>, peer not responding\n", 699 warn("Resetting link <%s>, peer not responding\n",
902 l_ptr->name); 700 l_ptr->name);
903 tipc_link_reset(l_ptr); 701 tipc_link_reset(l_ptr);
@@ -914,18 +712,13 @@ static void link_state_event(struct link *l_ptr, unsigned event)
914 } 712 }
915 break; 713 break;
916 case RESET_UNKNOWN: 714 case RESET_UNKNOWN:
917 dbg_link("RU/");
918 switch (event) { 715 switch (event) {
919 case TRAFFIC_MSG_EVT: 716 case TRAFFIC_MSG_EVT:
920 dbg_link("TRF-\n");
921 break; 717 break;
922 case ACTIVATE_MSG: 718 case ACTIVATE_MSG:
923 other = l_ptr->owner->active_links[0]; 719 other = l_ptr->owner->active_links[0];
924 if (other && link_working_unknown(other)) { 720 if (other && link_working_unknown(other))
925 dbg_link("ACT\n");
926 break; 721 break;
927 }
928 dbg_link("ACT -> WW\n");
929 l_ptr->state = WORKING_WORKING; 722 l_ptr->state = WORKING_WORKING;
930 l_ptr->fsm_msg_cnt = 0; 723 l_ptr->fsm_msg_cnt = 0;
931 link_activate(l_ptr); 724 link_activate(l_ptr);
@@ -934,8 +727,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
934 link_set_timer(l_ptr, cont_intv); 727 link_set_timer(l_ptr, cont_intv);
935 break; 728 break;
936 case RESET_MSG: 729 case RESET_MSG:
937 dbg_link("RES \n");
938 dbg_link(" -> RR\n");
939 l_ptr->state = RESET_RESET; 730 l_ptr->state = RESET_RESET;
940 l_ptr->fsm_msg_cnt = 0; 731 l_ptr->fsm_msg_cnt = 0;
941 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0); 732 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0);
@@ -943,11 +734,9 @@ static void link_state_event(struct link *l_ptr, unsigned event)
943 link_set_timer(l_ptr, cont_intv); 734 link_set_timer(l_ptr, cont_intv);
944 break; 735 break;
945 case STARTING_EVT: 736 case STARTING_EVT:
946 dbg_link("START-");
947 l_ptr->started = 1; 737 l_ptr->started = 1;
948 /* fall through */ 738 /* fall through */
949 case TIMEOUT_EVT: 739 case TIMEOUT_EVT:
950 dbg_link("TIM \n");
951 tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0); 740 tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
952 l_ptr->fsm_msg_cnt++; 741 l_ptr->fsm_msg_cnt++;
953 link_set_timer(l_ptr, cont_intv); 742 link_set_timer(l_ptr, cont_intv);
@@ -957,18 +746,12 @@ static void link_state_event(struct link *l_ptr, unsigned event)
957 } 746 }
958 break; 747 break;
959 case RESET_RESET: 748 case RESET_RESET:
960 dbg_link("RR/ ");
961 switch (event) { 749 switch (event) {
962 case TRAFFIC_MSG_EVT: 750 case TRAFFIC_MSG_EVT:
963 dbg_link("TRF-");
964 /* fall through */
965 case ACTIVATE_MSG: 751 case ACTIVATE_MSG:
966 other = l_ptr->owner->active_links[0]; 752 other = l_ptr->owner->active_links[0];
967 if (other && link_working_unknown(other)) { 753 if (other && link_working_unknown(other))
968 dbg_link("ACT\n");
969 break; 754 break;
970 }
971 dbg_link("ACT -> WW\n");
972 l_ptr->state = WORKING_WORKING; 755 l_ptr->state = WORKING_WORKING;
973 l_ptr->fsm_msg_cnt = 0; 756 l_ptr->fsm_msg_cnt = 0;
974 link_activate(l_ptr); 757 link_activate(l_ptr);
@@ -977,14 +760,11 @@ static void link_state_event(struct link *l_ptr, unsigned event)
977 link_set_timer(l_ptr, cont_intv); 760 link_set_timer(l_ptr, cont_intv);
978 break; 761 break;
979 case RESET_MSG: 762 case RESET_MSG:
980 dbg_link("RES\n");
981 break; 763 break;
982 case TIMEOUT_EVT: 764 case TIMEOUT_EVT:
983 dbg_link("TIM\n");
984 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); 765 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
985 l_ptr->fsm_msg_cnt++; 766 l_ptr->fsm_msg_cnt++;
986 link_set_timer(l_ptr, cont_intv); 767 link_set_timer(l_ptr, cont_intv);
987 dbg_link("fsm_msg_cnt %u\n", l_ptr->fsm_msg_cnt);
988 break; 768 break;
989 default: 769 default:
990 err("Unknown link event %u in RR state\n", event); 770 err("Unknown link event %u in RR state\n", event);
@@ -1017,16 +797,13 @@ static int link_bundle_buf(struct link *l_ptr,
1017 return 0; 797 return 0;
1018 if (skb_tailroom(bundler) < (pad + size)) 798 if (skb_tailroom(bundler) < (pad + size))
1019 return 0; 799 return 0;
1020 if (link_max_pkt(l_ptr) < (to_pos + size)) 800 if (l_ptr->max_pkt < (to_pos + size))
1021 return 0; 801 return 0;
1022 802
1023 skb_put(bundler, pad + size); 803 skb_put(bundler, pad + size);
1024 skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); 804 skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size);
1025 msg_set_size(bundler_msg, to_pos + size); 805 msg_set_size(bundler_msg, to_pos + size);
1026 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); 806 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1);
1027 dbg("Packed msg # %u(%u octets) into pos %u in buf(#%u)\n",
1028 msg_msgcnt(bundler_msg), size, to_pos, msg_seqno(bundler_msg));
1029 msg_dbg(msg, "PACKD:");
1030 buf_discard(buf); 807 buf_discard(buf);
1031 l_ptr->stats.sent_bundled++; 808 l_ptr->stats.sent_bundled++;
1032 return 1; 809 return 1;
@@ -1062,9 +839,9 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1062 u32 size = msg_size(msg); 839 u32 size = msg_size(msg);
1063 u32 dsz = msg_data_sz(msg); 840 u32 dsz = msg_data_sz(msg);
1064 u32 queue_size = l_ptr->out_queue_size; 841 u32 queue_size = l_ptr->out_queue_size;
1065 u32 imp = msg_tot_importance(msg); 842 u32 imp = tipc_msg_tot_importance(msg);
1066 u32 queue_limit = l_ptr->queue_limit[imp]; 843 u32 queue_limit = l_ptr->queue_limit[imp];
1067 u32 max_packet = link_max_pkt(l_ptr); 844 u32 max_packet = l_ptr->max_pkt;
1068 845
1069 msg_set_prevnode(msg, tipc_own_addr); /* If routed message */ 846 msg_set_prevnode(msg, tipc_own_addr); /* If routed message */
1070 847
@@ -1075,7 +852,6 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1075 return link_schedule_port(l_ptr, msg_origport(msg), 852 return link_schedule_port(l_ptr, msg_origport(msg),
1076 size); 853 size);
1077 } 854 }
1078 msg_dbg(msg, "TIPC: Congestion, throwing away\n");
1079 buf_discard(buf); 855 buf_discard(buf);
1080 if (imp > CONN_MANAGER) { 856 if (imp > CONN_MANAGER) {
1081 warn("Resetting link <%s>, send queue full", l_ptr->name); 857 warn("Resetting link <%s>, send queue full", l_ptr->name);
@@ -1087,7 +863,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1087 /* Fragmentation needed ? */ 863 /* Fragmentation needed ? */
1088 864
1089 if (size > max_packet) 865 if (size > max_packet)
1090 return tipc_link_send_long_buf(l_ptr, buf); 866 return link_send_long_buf(l_ptr, buf);
1091 867
1092 /* Packet can be queued or sent: */ 868 /* Packet can be queued or sent: */
1093 869
@@ -1123,11 +899,11 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1123 /* Try creating a new bundle */ 899 /* Try creating a new bundle */
1124 900
1125 if (size <= max_packet * 2 / 3) { 901 if (size <= max_packet * 2 / 3) {
1126 struct sk_buff *bundler = buf_acquire(max_packet); 902 struct sk_buff *bundler = tipc_buf_acquire(max_packet);
1127 struct tipc_msg bundler_hdr; 903 struct tipc_msg bundler_hdr;
1128 904
1129 if (bundler) { 905 if (bundler) {
1130 msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG, 906 tipc_msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG,
1131 INT_H_SIZE, l_ptr->addr); 907 INT_H_SIZE, l_ptr->addr);
1132 skb_copy_to_linear_data(bundler, &bundler_hdr, 908 skb_copy_to_linear_data(bundler, &bundler_hdr,
1133 INT_H_SIZE); 909 INT_H_SIZE);
@@ -1159,22 +935,16 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
1159 int res = -ELINKCONG; 935 int res = -ELINKCONG;
1160 936
1161 read_lock_bh(&tipc_net_lock); 937 read_lock_bh(&tipc_net_lock);
1162 n_ptr = tipc_node_select(dest, selector); 938 n_ptr = tipc_node_find(dest);
1163 if (n_ptr) { 939 if (n_ptr) {
1164 tipc_node_lock(n_ptr); 940 tipc_node_lock(n_ptr);
1165 l_ptr = n_ptr->active_links[selector & 1]; 941 l_ptr = n_ptr->active_links[selector & 1];
1166 if (l_ptr) { 942 if (l_ptr)
1167 dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest);
1168 res = tipc_link_send_buf(l_ptr, buf); 943 res = tipc_link_send_buf(l_ptr, buf);
1169 } else { 944 else
1170 dbg("Attempt to send msg to unreachable node:\n");
1171 msg_dbg(buf_msg(buf),">>>");
1172 buf_discard(buf); 945 buf_discard(buf);
1173 }
1174 tipc_node_unlock(n_ptr); 946 tipc_node_unlock(n_ptr);
1175 } else { 947 } else {
1176 dbg("Attempt to send msg to unknown node:\n");
1177 msg_dbg(buf_msg(buf),">>>");
1178 buf_discard(buf); 948 buf_discard(buf);
1179 } 949 }
1180 read_unlock_bh(&tipc_net_lock); 950 read_unlock_bh(&tipc_net_lock);
@@ -1195,24 +965,21 @@ static int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf,
1195 int res = msg_data_sz(msg); 965 int res = msg_data_sz(msg);
1196 966
1197 if (likely(!link_congested(l_ptr))) { 967 if (likely(!link_congested(l_ptr))) {
1198 if (likely(msg_size(msg) <= link_max_pkt(l_ptr))) { 968 if (likely(msg_size(msg) <= l_ptr->max_pkt)) {
1199 if (likely(list_empty(&l_ptr->b_ptr->cong_links))) { 969 if (likely(list_empty(&l_ptr->b_ptr->cong_links))) {
1200 link_add_to_outqueue(l_ptr, buf, msg); 970 link_add_to_outqueue(l_ptr, buf, msg);
1201 if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, 971 if (likely(tipc_bearer_send(l_ptr->b_ptr, buf,
1202 &l_ptr->media_addr))) { 972 &l_ptr->media_addr))) {
1203 l_ptr->unacked_window = 0; 973 l_ptr->unacked_window = 0;
1204 msg_dbg(msg,"SENT_FAST:");
1205 return res; 974 return res;
1206 } 975 }
1207 dbg("failed sent fast...\n");
1208 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); 976 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
1209 l_ptr->stats.bearer_congs++; 977 l_ptr->stats.bearer_congs++;
1210 l_ptr->next_out = buf; 978 l_ptr->next_out = buf;
1211 return res; 979 return res;
1212 } 980 }
1213 } 981 } else
1214 else 982 *used_max_pkt = l_ptr->max_pkt;
1215 *used_max_pkt = link_max_pkt(l_ptr);
1216 } 983 }
1217 return tipc_link_send_buf(l_ptr, buf); /* All other cases */ 984 return tipc_link_send_buf(l_ptr, buf); /* All other cases */
1218} 985}
@@ -1235,12 +1002,10 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1235 return tipc_port_recv_msg(buf); 1002 return tipc_port_recv_msg(buf);
1236 1003
1237 read_lock_bh(&tipc_net_lock); 1004 read_lock_bh(&tipc_net_lock);
1238 n_ptr = tipc_node_select(destnode, selector); 1005 n_ptr = tipc_node_find(destnode);
1239 if (likely(n_ptr)) { 1006 if (likely(n_ptr)) {
1240 tipc_node_lock(n_ptr); 1007 tipc_node_lock(n_ptr);
1241 l_ptr = n_ptr->active_links[selector]; 1008 l_ptr = n_ptr->active_links[selector];
1242 dbg("send_fast: buf %x selected %x, destnode = %x\n",
1243 buf, l_ptr, destnode);
1244 if (likely(l_ptr)) { 1009 if (likely(l_ptr)) {
1245 res = link_send_buf_fast(l_ptr, buf, &dummy); 1010 res = link_send_buf_fast(l_ptr, buf, &dummy);
1246 tipc_node_unlock(n_ptr); 1011 tipc_node_unlock(n_ptr);
@@ -1280,11 +1045,11 @@ again:
1280 * (Must not hold any locks while building message.) 1045 * (Must not hold any locks while building message.)
1281 */ 1046 */
1282 1047
1283 res = msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt, 1048 res = tipc_msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt,
1284 !sender->user_port, &buf); 1049 !sender->user_port, &buf);
1285 1050
1286 read_lock_bh(&tipc_net_lock); 1051 read_lock_bh(&tipc_net_lock);
1287 node = tipc_node_select(destaddr, selector); 1052 node = tipc_node_find(destaddr);
1288 if (likely(node)) { 1053 if (likely(node)) {
1289 tipc_node_lock(node); 1054 tipc_node_lock(node);
1290 l_ptr = node->active_links[selector]; 1055 l_ptr = node->active_links[selector];
@@ -1319,7 +1084,7 @@ exit:
1319 * then re-try fast path or fragment the message 1084 * then re-try fast path or fragment the message
1320 */ 1085 */
1321 1086
1322 sender->publ.max_pkt = link_max_pkt(l_ptr); 1087 sender->publ.max_pkt = l_ptr->max_pkt;
1323 tipc_node_unlock(node); 1088 tipc_node_unlock(node);
1324 read_unlock_bh(&tipc_net_lock); 1089 read_unlock_bh(&tipc_net_lock);
1325 1090
@@ -1367,10 +1132,10 @@ static int link_send_sections_long(struct port *sender,
1367 struct tipc_node *node; 1132 struct tipc_node *node;
1368 struct tipc_msg *hdr = &sender->publ.phdr; 1133 struct tipc_msg *hdr = &sender->publ.phdr;
1369 u32 dsz = msg_data_sz(hdr); 1134 u32 dsz = msg_data_sz(hdr);
1370 u32 max_pkt,fragm_sz,rest; 1135 u32 max_pkt, fragm_sz, rest;
1371 struct tipc_msg fragm_hdr; 1136 struct tipc_msg fragm_hdr;
1372 struct sk_buff *buf,*buf_chain,*prev; 1137 struct sk_buff *buf, *buf_chain, *prev;
1373 u32 fragm_crs,fragm_rest,hsz,sect_rest; 1138 u32 fragm_crs, fragm_rest, hsz, sect_rest;
1374 const unchar *sect_crs; 1139 const unchar *sect_crs;
1375 int curr_sect; 1140 int curr_sect;
1376 u32 fragm_no; 1141 u32 fragm_no;
@@ -1390,8 +1155,7 @@ again:
1390 1155
1391 /* Prepare reusable fragment header: */ 1156 /* Prepare reusable fragment header: */
1392 1157
1393 msg_dbg(hdr, ">FRAGMENTING>"); 1158 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1394 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1395 INT_H_SIZE, msg_destnode(hdr)); 1159 INT_H_SIZE, msg_destnode(hdr));
1396 msg_set_link_selector(&fragm_hdr, sender->publ.ref); 1160 msg_set_link_selector(&fragm_hdr, sender->publ.ref);
1397 msg_set_size(&fragm_hdr, max_pkt); 1161 msg_set_size(&fragm_hdr, max_pkt);
@@ -1399,14 +1163,13 @@ again:
1399 1163
1400 /* Prepare header of first fragment: */ 1164 /* Prepare header of first fragment: */
1401 1165
1402 buf_chain = buf = buf_acquire(max_pkt); 1166 buf_chain = buf = tipc_buf_acquire(max_pkt);
1403 if (!buf) 1167 if (!buf)
1404 return -ENOMEM; 1168 return -ENOMEM;
1405 buf->next = NULL; 1169 buf->next = NULL;
1406 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); 1170 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
1407 hsz = msg_hdr_sz(hdr); 1171 hsz = msg_hdr_sz(hdr);
1408 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz); 1172 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz);
1409 msg_dbg(buf_msg(buf), ">BUILD>");
1410 1173
1411 /* Chop up message: */ 1174 /* Chop up message: */
1412 1175
@@ -1449,14 +1212,14 @@ error:
1449 /* Initiate new fragment: */ 1212 /* Initiate new fragment: */
1450 if (rest <= fragm_sz) { 1213 if (rest <= fragm_sz) {
1451 fragm_sz = rest; 1214 fragm_sz = rest;
1452 msg_set_type(&fragm_hdr,LAST_FRAGMENT); 1215 msg_set_type(&fragm_hdr, LAST_FRAGMENT);
1453 } else { 1216 } else {
1454 msg_set_type(&fragm_hdr, FRAGMENT); 1217 msg_set_type(&fragm_hdr, FRAGMENT);
1455 } 1218 }
1456 msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); 1219 msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE);
1457 msg_set_fragm_no(&fragm_hdr, ++fragm_no); 1220 msg_set_fragm_no(&fragm_hdr, ++fragm_no);
1458 prev = buf; 1221 prev = buf;
1459 buf = buf_acquire(fragm_sz + INT_H_SIZE); 1222 buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
1460 if (!buf) 1223 if (!buf)
1461 goto error; 1224 goto error;
1462 1225
@@ -1465,16 +1228,14 @@ error:
1465 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); 1228 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
1466 fragm_crs = INT_H_SIZE; 1229 fragm_crs = INT_H_SIZE;
1467 fragm_rest = fragm_sz; 1230 fragm_rest = fragm_sz;
1468 msg_dbg(buf_msg(buf)," >BUILD>");
1469 } 1231 }
1470 } 1232 } while (rest > 0);
1471 while (rest > 0);
1472 1233
1473 /* 1234 /*
1474 * Now we have a buffer chain. Select a link and check 1235 * Now we have a buffer chain. Select a link and check
1475 * that packet size is still OK 1236 * that packet size is still OK
1476 */ 1237 */
1477 node = tipc_node_select(destaddr, sender->publ.ref & 1); 1238 node = tipc_node_find(destaddr);
1478 if (likely(node)) { 1239 if (likely(node)) {
1479 tipc_node_lock(node); 1240 tipc_node_lock(node);
1480 l_ptr = node->active_links[sender->publ.ref & 1]; 1241 l_ptr = node->active_links[sender->publ.ref & 1];
@@ -1482,8 +1243,8 @@ error:
1482 tipc_node_unlock(node); 1243 tipc_node_unlock(node);
1483 goto reject; 1244 goto reject;
1484 } 1245 }
1485 if (link_max_pkt(l_ptr) < max_pkt) { 1246 if (l_ptr->max_pkt < max_pkt) {
1486 sender->publ.max_pkt = link_max_pkt(l_ptr); 1247 sender->publ.max_pkt = l_ptr->max_pkt;
1487 tipc_node_unlock(node); 1248 tipc_node_unlock(node);
1488 for (; buf_chain; buf_chain = buf) { 1249 for (; buf_chain; buf_chain = buf) {
1489 buf = buf_chain->next; 1250 buf = buf_chain->next;
@@ -1515,7 +1276,6 @@ reject:
1515 l_ptr->stats.sent_fragments++; 1276 l_ptr->stats.sent_fragments++;
1516 msg_set_long_msgno(msg, l_ptr->long_msg_seq_no); 1277 msg_set_long_msgno(msg, l_ptr->long_msg_seq_no);
1517 link_add_to_outqueue(l_ptr, buf, msg); 1278 link_add_to_outqueue(l_ptr, buf, msg);
1518 msg_dbg(msg, ">ADD>");
1519 buf = next; 1279 buf = next;
1520 } 1280 }
1521 1281
@@ -1553,18 +1313,16 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1553 1313
1554 /* Continue retransmission now, if there is anything: */ 1314 /* Continue retransmission now, if there is anything: */
1555 1315
1556 if (r_q_size && buf && !skb_cloned(buf)) { 1316 if (r_q_size && buf) {
1557 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); 1317 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
1558 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); 1318 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
1559 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1319 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1560 msg_dbg(buf_msg(buf), ">DEF-RETR>");
1561 l_ptr->retransm_queue_head = mod(++r_q_head); 1320 l_ptr->retransm_queue_head = mod(++r_q_head);
1562 l_ptr->retransm_queue_size = --r_q_size; 1321 l_ptr->retransm_queue_size = --r_q_size;
1563 l_ptr->stats.retransmitted++; 1322 l_ptr->stats.retransmitted++;
1564 return 0; 1323 return 0;
1565 } else { 1324 } else {
1566 l_ptr->stats.bearer_congs++; 1325 l_ptr->stats.bearer_congs++;
1567 msg_dbg(buf_msg(buf), "|>DEF-RETR>");
1568 return PUSH_FAILED; 1326 return PUSH_FAILED;
1569 } 1327 }
1570 } 1328 }
@@ -1574,15 +1332,13 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1574 buf = l_ptr->proto_msg_queue; 1332 buf = l_ptr->proto_msg_queue;
1575 if (buf) { 1333 if (buf) {
1576 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); 1334 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
1577 msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in); 1335 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
1578 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1336 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1579 msg_dbg(buf_msg(buf), ">DEF-PROT>");
1580 l_ptr->unacked_window = 0; 1337 l_ptr->unacked_window = 0;
1581 buf_discard(buf); 1338 buf_discard(buf);
1582 l_ptr->proto_msg_queue = NULL; 1339 l_ptr->proto_msg_queue = NULL;
1583 return 0; 1340 return 0;
1584 } else { 1341 } else {
1585 msg_dbg(buf_msg(buf), "|>DEF-PROT>");
1586 l_ptr->stats.bearer_congs++; 1342 l_ptr->stats.bearer_congs++;
1587 return PUSH_FAILED; 1343 return PUSH_FAILED;
1588 } 1344 }
@@ -1602,11 +1358,9 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1602 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1358 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1603 if (msg_user(msg) == MSG_BUNDLER) 1359 if (msg_user(msg) == MSG_BUNDLER)
1604 msg_set_type(msg, CLOSED_MSG); 1360 msg_set_type(msg, CLOSED_MSG);
1605 msg_dbg(msg, ">PUSH-DATA>");
1606 l_ptr->next_out = buf->next; 1361 l_ptr->next_out = buf->next;
1607 return 0; 1362 return 0;
1608 } else { 1363 } else {
1609 msg_dbg(msg, "|PUSH-DATA|");
1610 l_ptr->stats.bearer_congs++; 1364 l_ptr->stats.bearer_congs++;
1611 return PUSH_FAILED; 1365 return PUSH_FAILED;
1612 } 1366 }
@@ -1650,12 +1404,11 @@ static void link_reset_all(unsigned long addr)
1650 tipc_node_lock(n_ptr); 1404 tipc_node_lock(n_ptr);
1651 1405
1652 warn("Resetting all links to %s\n", 1406 warn("Resetting all links to %s\n",
1653 addr_string_fill(addr_string, n_ptr->addr)); 1407 tipc_addr_string_fill(addr_string, n_ptr->addr));
1654 1408
1655 for (i = 0; i < MAX_BEARERS; i++) { 1409 for (i = 0; i < MAX_BEARERS; i++) {
1656 if (n_ptr->links[i]) { 1410 if (n_ptr->links[i]) {
1657 link_print(n_ptr->links[i], TIPC_OUTPUT, 1411 link_print(n_ptr->links[i], "Resetting link\n");
1658 "Resetting link\n");
1659 tipc_link_reset(n_ptr->links[i]); 1412 tipc_link_reset(n_ptr->links[i]);
1660 } 1413 }
1661 } 1414 }
@@ -1669,13 +1422,12 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1669 struct tipc_msg *msg = buf_msg(buf); 1422 struct tipc_msg *msg = buf_msg(buf);
1670 1423
1671 warn("Retransmission failure on link <%s>\n", l_ptr->name); 1424 warn("Retransmission failure on link <%s>\n", l_ptr->name);
1672 tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>");
1673 1425
1674 if (l_ptr->addr) { 1426 if (l_ptr->addr) {
1675 1427
1676 /* Handle failure on standard link */ 1428 /* Handle failure on standard link */
1677 1429
1678 link_print(l_ptr, TIPC_OUTPUT, "Resetting link\n"); 1430 link_print(l_ptr, "Resetting link\n");
1679 tipc_link_reset(l_ptr); 1431 tipc_link_reset(l_ptr);
1680 1432
1681 } else { 1433 } else {
@@ -1685,21 +1437,21 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1685 struct tipc_node *n_ptr; 1437 struct tipc_node *n_ptr;
1686 char addr_string[16]; 1438 char addr_string[16];
1687 1439
1688 tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg)); 1440 info("Msg seq number: %u, ", msg_seqno(msg));
1689 tipc_printf(TIPC_OUTPUT, "Outstanding acks: %lu\n", 1441 info("Outstanding acks: %lu\n",
1690 (unsigned long) TIPC_SKB_CB(buf)->handle); 1442 (unsigned long) TIPC_SKB_CB(buf)->handle);
1691 1443
1692 n_ptr = l_ptr->owner->next; 1444 n_ptr = l_ptr->owner->next;
1693 tipc_node_lock(n_ptr); 1445 tipc_node_lock(n_ptr);
1694 1446
1695 addr_string_fill(addr_string, n_ptr->addr); 1447 tipc_addr_string_fill(addr_string, n_ptr->addr);
1696 tipc_printf(TIPC_OUTPUT, "Multicast link info for %s\n", addr_string); 1448 info("Multicast link info for %s\n", addr_string);
1697 tipc_printf(TIPC_OUTPUT, "Supported: %d, ", n_ptr->bclink.supported); 1449 info("Supported: %d, ", n_ptr->bclink.supported);
1698 tipc_printf(TIPC_OUTPUT, "Acked: %u\n", n_ptr->bclink.acked); 1450 info("Acked: %u\n", n_ptr->bclink.acked);
1699 tipc_printf(TIPC_OUTPUT, "Last in: %u, ", n_ptr->bclink.last_in); 1451 info("Last in: %u, ", n_ptr->bclink.last_in);
1700 tipc_printf(TIPC_OUTPUT, "Gap after: %u, ", n_ptr->bclink.gap_after); 1452 info("Gap after: %u, ", n_ptr->bclink.gap_after);
1701 tipc_printf(TIPC_OUTPUT, "Gap to: %u\n", n_ptr->bclink.gap_to); 1453 info("Gap to: %u\n", n_ptr->bclink.gap_to);
1702 tipc_printf(TIPC_OUTPUT, "Nack sync: %u\n\n", n_ptr->bclink.nack_sync); 1454 info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync);
1703 1455
1704 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); 1456 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
1705 1457
@@ -1719,18 +1471,15 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1719 1471
1720 msg = buf_msg(buf); 1472 msg = buf_msg(buf);
1721 1473
1722 dbg("Retransmitting %u in link %x\n", retransmits, l_ptr);
1723
1724 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { 1474 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
1725 if (!skb_cloned(buf)) { 1475 if (l_ptr->retransm_queue_size == 0) {
1726 msg_dbg(msg, ">NO_RETR->BCONG>");
1727 dbg_print_link(l_ptr, " ");
1728 l_ptr->retransm_queue_head = msg_seqno(msg); 1476 l_ptr->retransm_queue_head = msg_seqno(msg);
1729 l_ptr->retransm_queue_size = retransmits; 1477 l_ptr->retransm_queue_size = retransmits;
1730 return;
1731 } else { 1478 } else {
1732 /* Don't retransmit if driver already has the buffer */ 1479 err("Unexpected retransmit on link %s (qsize=%d)\n",
1480 l_ptr->name, l_ptr->retransm_queue_size);
1733 } 1481 }
1482 return;
1734 } else { 1483 } else {
1735 /* Detect repeated retransmit failures on uncongested bearer */ 1484 /* Detect repeated retransmit failures on uncongested bearer */
1736 1485
@@ -1745,12 +1494,11 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1745 } 1494 }
1746 } 1495 }
1747 1496
1748 while (retransmits && (buf != l_ptr->next_out) && buf && !skb_cloned(buf)) { 1497 while (retransmits && (buf != l_ptr->next_out) && buf) {
1749 msg = buf_msg(buf); 1498 msg = buf_msg(buf);
1750 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); 1499 msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
1751 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 1500 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
1752 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1501 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1753 msg_dbg(buf_msg(buf), ">RETR>");
1754 buf = buf->next; 1502 buf = buf->next;
1755 retransmits--; 1503 retransmits--;
1756 l_ptr->stats.retransmitted++; 1504 l_ptr->stats.retransmitted++;
@@ -1838,6 +1586,15 @@ static int link_recv_buf_validate(struct sk_buff *buf)
1838 return pskb_may_pull(buf, hdr_size); 1586 return pskb_may_pull(buf, hdr_size);
1839} 1587}
1840 1588
1589/**
1590 * tipc_recv_msg - process TIPC messages arriving from off-node
1591 * @head: pointer to message buffer chain
1592 * @tb_ptr: pointer to bearer message arrived on
1593 *
1594 * Invoked with no locks held. Bearer pointer must point to a valid bearer
1595 * structure (i.e. cannot be NULL), but bearer can be inactive.
1596 */
1597
1841void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) 1598void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1842{ 1599{
1843 read_lock_bh(&tipc_net_lock); 1600 read_lock_bh(&tipc_net_lock);
@@ -1855,6 +1612,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1855 1612
1856 head = head->next; 1613 head = head->next;
1857 1614
1615 /* Ensure bearer is still enabled */
1616
1617 if (unlikely(!b_ptr->active))
1618 goto cont;
1619
1858 /* Ensure message is well-formed */ 1620 /* Ensure message is well-formed */
1859 1621
1860 if (unlikely(!link_recv_buf_validate(buf))) 1622 if (unlikely(!link_recv_buf_validate(buf)))
@@ -1862,9 +1624,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1862 1624
1863 /* Ensure message data is a single contiguous unit */ 1625 /* Ensure message data is a single contiguous unit */
1864 1626
1865 if (unlikely(buf_linearize(buf))) { 1627 if (unlikely(buf_linearize(buf)))
1866 goto cont; 1628 goto cont;
1867 }
1868 1629
1869 /* Handle arrival of a non-unicast link message */ 1630 /* Handle arrival of a non-unicast link message */
1870 1631
@@ -1882,13 +1643,31 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1882 (msg_destnode(msg) != tipc_own_addr))) 1643 (msg_destnode(msg) != tipc_own_addr)))
1883 goto cont; 1644 goto cont;
1884 1645
1885 /* Locate unicast link endpoint that should handle message */ 1646 /* Discard non-routeable messages destined for another node */
1647
1648 if (unlikely(!msg_isdata(msg) &&
1649 (msg_destnode(msg) != tipc_own_addr))) {
1650 if ((msg_user(msg) != CONN_MANAGER) &&
1651 (msg_user(msg) != MSG_FRAGMENTER))
1652 goto cont;
1653 }
1654
1655 /* Locate neighboring node that sent message */
1886 1656
1887 n_ptr = tipc_node_find(msg_prevnode(msg)); 1657 n_ptr = tipc_node_find(msg_prevnode(msg));
1888 if (unlikely(!n_ptr)) 1658 if (unlikely(!n_ptr))
1889 goto cont; 1659 goto cont;
1890 tipc_node_lock(n_ptr); 1660 tipc_node_lock(n_ptr);
1891 1661
1662 /* Don't talk to neighbor during cleanup after last session */
1663
1664 if (n_ptr->cleanup_required) {
1665 tipc_node_unlock(n_ptr);
1666 goto cont;
1667 }
1668
1669 /* Locate unicast link endpoint that should handle message */
1670
1892 l_ptr = n_ptr->links[b_ptr->identity]; 1671 l_ptr = n_ptr->links[b_ptr->identity];
1893 if (unlikely(!l_ptr)) { 1672 if (unlikely(!l_ptr)) {
1894 tipc_node_unlock(n_ptr); 1673 tipc_node_unlock(n_ptr);
@@ -1958,7 +1737,7 @@ deliver:
1958 continue; 1737 continue;
1959 case ROUTE_DISTRIBUTOR: 1738 case ROUTE_DISTRIBUTOR:
1960 tipc_node_unlock(n_ptr); 1739 tipc_node_unlock(n_ptr);
1961 tipc_cltr_recv_routing_table(buf); 1740 buf_discard(buf);
1962 continue; 1741 continue;
1963 case NAME_DISTRIBUTOR: 1742 case NAME_DISTRIBUTOR:
1964 tipc_node_unlock(n_ptr); 1743 tipc_node_unlock(n_ptr);
@@ -2004,12 +1783,10 @@ deliver:
2004 tipc_node_unlock(n_ptr); 1783 tipc_node_unlock(n_ptr);
2005 continue; 1784 continue;
2006 } 1785 }
2007 msg_dbg(msg,"NSEQ<REC<");
2008 link_state_event(l_ptr, TRAFFIC_MSG_EVT); 1786 link_state_event(l_ptr, TRAFFIC_MSG_EVT);
2009 1787
2010 if (link_working_working(l_ptr)) { 1788 if (link_working_working(l_ptr)) {
2011 /* Re-insert in front of queue */ 1789 /* Re-insert in front of queue */
2012 msg_dbg(msg,"RECV-REINS:");
2013 buf->next = head; 1790 buf->next = head;
2014 head = buf; 1791 head = buf;
2015 tipc_node_unlock(n_ptr); 1792 tipc_node_unlock(n_ptr);
@@ -2063,13 +1840,11 @@ u32 tipc_link_defer_pkt(struct sk_buff **head,
2063 *head = buf; 1840 *head = buf;
2064 return 1; 1841 return 1;
2065 } 1842 }
2066 if (seq_no == msg_seqno(msg)) { 1843 if (seq_no == msg_seqno(msg))
2067 break; 1844 break;
2068 }
2069 prev = crs; 1845 prev = crs;
2070 crs = crs->next; 1846 crs = crs->next;
2071 } 1847 } while (crs);
2072 while (crs);
2073 1848
2074 /* Message is a duplicate of an existing message */ 1849 /* Message is a duplicate of an existing message */
2075 1850
@@ -2091,9 +1866,6 @@ static void link_handle_out_of_seq_msg(struct link *l_ptr,
2091 return; 1866 return;
2092 } 1867 }
2093 1868
2094 dbg("rx OOS msg: seq_no %u, expecting %u (%u)\n",
2095 seq_no, mod(l_ptr->next_in_no), l_ptr->next_in_no);
2096
2097 /* Record OOS packet arrival (force mismatch on next timeout) */ 1869 /* Record OOS packet arrival (force mismatch on next timeout) */
2098 1870
2099 l_ptr->checkpoint--; 1871 l_ptr->checkpoint--;
@@ -2183,11 +1955,10 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2183 msg_set_max_pkt(msg, l_ptr->max_pkt_target); 1955 msg_set_max_pkt(msg, l_ptr->max_pkt_target);
2184 } 1956 }
2185 1957
2186 if (tipc_node_has_redundant_links(l_ptr->owner)) { 1958 if (tipc_node_has_redundant_links(l_ptr->owner))
2187 msg_set_redundant_link(msg); 1959 msg_set_redundant_link(msg);
2188 } else { 1960 else
2189 msg_clear_redundant_link(msg); 1961 msg_clear_redundant_link(msg);
2190 }
2191 msg_set_linkprio(msg, l_ptr->priority); 1962 msg_set_linkprio(msg, l_ptr->priority);
2192 1963
2193 /* Ensure sequence number will not fit : */ 1964 /* Ensure sequence number will not fit : */
@@ -2199,7 +1970,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2199 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { 1970 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
2200 if (!l_ptr->proto_msg_queue) { 1971 if (!l_ptr->proto_msg_queue) {
2201 l_ptr->proto_msg_queue = 1972 l_ptr->proto_msg_queue =
2202 buf_acquire(sizeof(l_ptr->proto_msg)); 1973 tipc_buf_acquire(sizeof(l_ptr->proto_msg));
2203 } 1974 }
2204 buf = l_ptr->proto_msg_queue; 1975 buf = l_ptr->proto_msg_queue;
2205 if (!buf) 1976 if (!buf)
@@ -2211,9 +1982,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2211 1982
2212 /* Message can be sent */ 1983 /* Message can be sent */
2213 1984
2214 msg_dbg(msg, ">>"); 1985 buf = tipc_buf_acquire(msg_size);
2215
2216 buf = buf_acquire(msg_size);
2217 if (!buf) 1986 if (!buf)
2218 return; 1987 return;
2219 1988
@@ -2246,8 +2015,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2246 u32 msg_tol; 2015 u32 msg_tol;
2247 struct tipc_msg *msg = buf_msg(buf); 2016 struct tipc_msg *msg = buf_msg(buf);
2248 2017
2249 dbg("AT(%u):", jiffies_to_msecs(jiffies));
2250 msg_dbg(msg, "<<");
2251 if (link_blocked(l_ptr)) 2018 if (link_blocked(l_ptr))
2252 goto exit; 2019 goto exit;
2253 2020
@@ -2266,11 +2033,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2266 case RESET_MSG: 2033 case RESET_MSG:
2267 if (!link_working_unknown(l_ptr) && 2034 if (!link_working_unknown(l_ptr) &&
2268 (l_ptr->peer_session != INVALID_SESSION)) { 2035 (l_ptr->peer_session != INVALID_SESSION)) {
2269 if (msg_session(msg) == l_ptr->peer_session) { 2036 if (msg_session(msg) == l_ptr->peer_session)
2270 dbg("Duplicate RESET: %u<->%u\n",
2271 msg_session(msg), l_ptr->peer_session);
2272 break; /* duplicate: ignore */ 2037 break; /* duplicate: ignore */
2273 }
2274 } 2038 }
2275 /* fall thru' */ 2039 /* fall thru' */
2276 case ACTIVATE_MSG: 2040 case ACTIVATE_MSG:
@@ -2278,8 +2042,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2278 2042
2279 strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg)); 2043 strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg));
2280 2044
2281 if ((msg_tol = msg_link_tolerance(msg)) && 2045 msg_tol = msg_link_tolerance(msg);
2282 (msg_tol > l_ptr->tolerance)) 2046 if (msg_tol > l_ptr->tolerance)
2283 link_set_supervision_props(l_ptr, msg_tol); 2047 link_set_supervision_props(l_ptr, msg_tol);
2284 2048
2285 if (msg_linkprio(msg) > l_ptr->priority) 2049 if (msg_linkprio(msg) > l_ptr->priority)
@@ -2302,13 +2066,13 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2302 l_ptr->peer_bearer_id = msg_bearer_id(msg); 2066 l_ptr->peer_bearer_id = msg_bearer_id(msg);
2303 2067
2304 /* Synchronize broadcast sequence numbers */ 2068 /* Synchronize broadcast sequence numbers */
2305 if (!tipc_node_has_redundant_links(l_ptr->owner)) { 2069 if (!tipc_node_has_redundant_links(l_ptr->owner))
2306 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); 2070 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
2307 }
2308 break; 2071 break;
2309 case STATE_MSG: 2072 case STATE_MSG:
2310 2073
2311 if ((msg_tol = msg_link_tolerance(msg))) 2074 msg_tol = msg_link_tolerance(msg);
2075 if (msg_tol)
2312 link_set_supervision_props(l_ptr, msg_tol); 2076 link_set_supervision_props(l_ptr, msg_tol);
2313 2077
2314 if (msg_linkprio(msg) && 2078 if (msg_linkprio(msg) &&
@@ -2331,8 +2095,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2331 2095
2332 max_pkt_ack = msg_max_pkt(msg); 2096 max_pkt_ack = msg_max_pkt(msg);
2333 if (max_pkt_ack > l_ptr->max_pkt) { 2097 if (max_pkt_ack > l_ptr->max_pkt) {
2334 dbg("Link <%s> updated MTU %u -> %u\n",
2335 l_ptr->name, l_ptr->max_pkt, max_pkt_ack);
2336 l_ptr->max_pkt = max_pkt_ack; 2098 l_ptr->max_pkt = max_pkt_ack;
2337 l_ptr->max_pkt_probes = 0; 2099 l_ptr->max_pkt_probes = 0;
2338 } 2100 }
@@ -2340,9 +2102,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2340 max_pkt_ack = 0; 2102 max_pkt_ack = 0;
2341 if (msg_probe(msg)) { 2103 if (msg_probe(msg)) {
2342 l_ptr->stats.recv_probes++; 2104 l_ptr->stats.recv_probes++;
2343 if (msg_size(msg) > sizeof(l_ptr->proto_msg)) { 2105 if (msg_size(msg) > sizeof(l_ptr->proto_msg))
2344 max_pkt_ack = msg_size(msg); 2106 max_pkt_ack = msg_size(msg);
2345 }
2346 } 2107 }
2347 2108
2348 /* Protocol message before retransmits, reduce loss risk */ 2109 /* Protocol message before retransmits, reduce loss risk */
@@ -2354,14 +2115,11 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2354 0, rec_gap, 0, 0, max_pkt_ack); 2115 0, rec_gap, 0, 0, max_pkt_ack);
2355 } 2116 }
2356 if (msg_seq_gap(msg)) { 2117 if (msg_seq_gap(msg)) {
2357 msg_dbg(msg, "With Gap:");
2358 l_ptr->stats.recv_nacks++; 2118 l_ptr->stats.recv_nacks++;
2359 tipc_link_retransmit(l_ptr, l_ptr->first_out, 2119 tipc_link_retransmit(l_ptr, l_ptr->first_out,
2360 msg_seq_gap(msg)); 2120 msg_seq_gap(msg));
2361 } 2121 }
2362 break; 2122 break;
2363 default:
2364 msg_dbg(buf_msg(buf), "<DISCARDING UNKNOWN<");
2365 } 2123 }
2366exit: 2124exit:
2367 buf_discard(buf); 2125 buf_discard(buf);
@@ -2372,10 +2130,10 @@ exit:
2372 * tipc_link_tunnel(): Send one message via a link belonging to 2130 * tipc_link_tunnel(): Send one message via a link belonging to
2373 * another bearer. Owner node is locked. 2131 * another bearer. Owner node is locked.
2374 */ 2132 */
2375void tipc_link_tunnel(struct link *l_ptr, 2133static void tipc_link_tunnel(struct link *l_ptr,
2376 struct tipc_msg *tunnel_hdr, 2134 struct tipc_msg *tunnel_hdr,
2377 struct tipc_msg *msg, 2135 struct tipc_msg *msg,
2378 u32 selector) 2136 u32 selector)
2379{ 2137{
2380 struct link *tunnel; 2138 struct link *tunnel;
2381 struct sk_buff *buf; 2139 struct sk_buff *buf;
@@ -2388,7 +2146,7 @@ void tipc_link_tunnel(struct link *l_ptr,
2388 return; 2146 return;
2389 } 2147 }
2390 msg_set_size(tunnel_hdr, length + INT_H_SIZE); 2148 msg_set_size(tunnel_hdr, length + INT_H_SIZE);
2391 buf = buf_acquire(length + INT_H_SIZE); 2149 buf = tipc_buf_acquire(length + INT_H_SIZE);
2392 if (!buf) { 2150 if (!buf) {
2393 warn("Link changeover error, " 2151 warn("Link changeover error, "
2394 "unable to send tunnel msg\n"); 2152 "unable to send tunnel msg\n");
@@ -2396,8 +2154,6 @@ void tipc_link_tunnel(struct link *l_ptr,
2396 } 2154 }
2397 skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE); 2155 skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE);
2398 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length); 2156 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length);
2399 dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane);
2400 msg_dbg(buf_msg(buf), ">SEND>");
2401 tipc_link_send_buf(tunnel, buf); 2157 tipc_link_send_buf(tunnel, buf);
2402} 2158}
2403 2159
@@ -2425,22 +2181,18 @@ void tipc_link_changeover(struct link *l_ptr)
2425 return; 2181 return;
2426 } 2182 }
2427 2183
2428 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, 2184 tipc_msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
2429 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); 2185 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
2430 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2186 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2431 msg_set_msgcnt(&tunnel_hdr, msgcount); 2187 msg_set_msgcnt(&tunnel_hdr, msgcount);
2432 dbg("Link changeover requires %u tunnel messages\n", msgcount);
2433 2188
2434 if (!l_ptr->first_out) { 2189 if (!l_ptr->first_out) {
2435 struct sk_buff *buf; 2190 struct sk_buff *buf;
2436 2191
2437 buf = buf_acquire(INT_H_SIZE); 2192 buf = tipc_buf_acquire(INT_H_SIZE);
2438 if (buf) { 2193 if (buf) {
2439 skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); 2194 skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE);
2440 msg_set_size(&tunnel_hdr, INT_H_SIZE); 2195 msg_set_size(&tunnel_hdr, INT_H_SIZE);
2441 dbg("%c->%c:", l_ptr->b_ptr->net_plane,
2442 tunnel->b_ptr->net_plane);
2443 msg_dbg(&tunnel_hdr, "EMPTY>SEND>");
2444 tipc_link_send_buf(tunnel, buf); 2196 tipc_link_send_buf(tunnel, buf);
2445 } else { 2197 } else {
2446 warn("Link changeover error, " 2198 warn("Link changeover error, "
@@ -2457,11 +2209,11 @@ void tipc_link_changeover(struct link *l_ptr)
2457 2209
2458 if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) { 2210 if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) {
2459 struct tipc_msg *m = msg_get_wrapped(msg); 2211 struct tipc_msg *m = msg_get_wrapped(msg);
2460 unchar* pos = (unchar*)m; 2212 unchar *pos = (unchar *)m;
2461 2213
2462 msgcount = msg_msgcnt(msg); 2214 msgcount = msg_msgcnt(msg);
2463 while (msgcount--) { 2215 while (msgcount--) {
2464 msg_set_seqno(m,msg_seqno(msg)); 2216 msg_set_seqno(m, msg_seqno(msg));
2465 tipc_link_tunnel(l_ptr, &tunnel_hdr, m, 2217 tipc_link_tunnel(l_ptr, &tunnel_hdr, m,
2466 msg_link_selector(m)); 2218 msg_link_selector(m));
2467 pos += align(msg_size(m)); 2219 pos += align(msg_size(m));
@@ -2480,7 +2232,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2480 struct sk_buff *iter; 2232 struct sk_buff *iter;
2481 struct tipc_msg tunnel_hdr; 2233 struct tipc_msg tunnel_hdr;
2482 2234
2483 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, 2235 tipc_msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
2484 DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr); 2236 DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr);
2485 msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); 2237 msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size);
2486 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2238 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
@@ -2495,7 +2247,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2495 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */ 2247 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */
2496 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 2248 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
2497 msg_set_size(&tunnel_hdr, length + INT_H_SIZE); 2249 msg_set_size(&tunnel_hdr, length + INT_H_SIZE);
2498 outbuf = buf_acquire(length + INT_H_SIZE); 2250 outbuf = tipc_buf_acquire(length + INT_H_SIZE);
2499 if (outbuf == NULL) { 2251 if (outbuf == NULL) {
2500 warn("Link changeover error, " 2252 warn("Link changeover error, "
2501 "unable to send duplicate msg\n"); 2253 "unable to send duplicate msg\n");
@@ -2504,9 +2256,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2504 skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE); 2256 skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE);
2505 skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data, 2257 skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data,
2506 length); 2258 length);
2507 dbg("%c->%c:", l_ptr->b_ptr->net_plane,
2508 tunnel->b_ptr->net_plane);
2509 msg_dbg(buf_msg(outbuf), ">SEND>");
2510 tipc_link_send_buf(tunnel, outbuf); 2259 tipc_link_send_buf(tunnel, outbuf);
2511 if (!tipc_link_is_up(l_ptr)) 2260 if (!tipc_link_is_up(l_ptr))
2512 return; 2261 return;
@@ -2531,7 +2280,7 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
2531 u32 size = msg_size(msg); 2280 u32 size = msg_size(msg);
2532 struct sk_buff *eb; 2281 struct sk_buff *eb;
2533 2282
2534 eb = buf_acquire(size); 2283 eb = tipc_buf_acquire(size);
2535 if (eb) 2284 if (eb)
2536 skb_copy_to_linear_data(eb, msg, size); 2285 skb_copy_to_linear_data(eb, msg, size);
2537 return eb; 2286 return eb;
@@ -2553,31 +2302,24 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2553 u32 msg_count = msg_msgcnt(tunnel_msg); 2302 u32 msg_count = msg_msgcnt(tunnel_msg);
2554 2303
2555 dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; 2304 dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)];
2556 if (!dest_link) { 2305 if (!dest_link)
2557 msg_dbg(tunnel_msg, "NOLINK/<REC<");
2558 goto exit; 2306 goto exit;
2559 }
2560 if (dest_link == *l_ptr) { 2307 if (dest_link == *l_ptr) {
2561 err("Unexpected changeover message on link <%s>\n", 2308 err("Unexpected changeover message on link <%s>\n",
2562 (*l_ptr)->name); 2309 (*l_ptr)->name);
2563 goto exit; 2310 goto exit;
2564 } 2311 }
2565 dbg("%c<-%c:", dest_link->b_ptr->net_plane,
2566 (*l_ptr)->b_ptr->net_plane);
2567 *l_ptr = dest_link; 2312 *l_ptr = dest_link;
2568 msg = msg_get_wrapped(tunnel_msg); 2313 msg = msg_get_wrapped(tunnel_msg);
2569 2314
2570 if (msg_typ == DUPLICATE_MSG) { 2315 if (msg_typ == DUPLICATE_MSG) {
2571 if (less(msg_seqno(msg), mod(dest_link->next_in_no))) { 2316 if (less(msg_seqno(msg), mod(dest_link->next_in_no)))
2572 msg_dbg(tunnel_msg, "DROP/<REC<");
2573 goto exit; 2317 goto exit;
2574 } 2318 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2575 *buf = buf_extract(tunnel_buf,INT_H_SIZE);
2576 if (*buf == NULL) { 2319 if (*buf == NULL) {
2577 warn("Link changeover error, duplicate msg dropped\n"); 2320 warn("Link changeover error, duplicate msg dropped\n");
2578 goto exit; 2321 goto exit;
2579 } 2322 }
2580 msg_dbg(tunnel_msg, "TNL<REC<");
2581 buf_discard(tunnel_buf); 2323 buf_discard(tunnel_buf);
2582 return 1; 2324 return 1;
2583 } 2325 }
@@ -2585,18 +2327,14 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2585 /* First original message ?: */ 2327 /* First original message ?: */
2586 2328
2587 if (tipc_link_is_up(dest_link)) { 2329 if (tipc_link_is_up(dest_link)) {
2588 msg_dbg(tunnel_msg, "UP/FIRST/<REC<");
2589 info("Resetting link <%s>, changeover initiated by peer\n", 2330 info("Resetting link <%s>, changeover initiated by peer\n",
2590 dest_link->name); 2331 dest_link->name);
2591 tipc_link_reset(dest_link); 2332 tipc_link_reset(dest_link);
2592 dest_link->exp_msg_count = msg_count; 2333 dest_link->exp_msg_count = msg_count;
2593 dbg("Expecting %u tunnelled messages\n", msg_count);
2594 if (!msg_count) 2334 if (!msg_count)
2595 goto exit; 2335 goto exit;
2596 } else if (dest_link->exp_msg_count == START_CHANGEOVER) { 2336 } else if (dest_link->exp_msg_count == START_CHANGEOVER) {
2597 msg_dbg(tunnel_msg, "BLK/FIRST/<REC<");
2598 dest_link->exp_msg_count = msg_count; 2337 dest_link->exp_msg_count = msg_count;
2599 dbg("Expecting %u tunnelled messages\n", msg_count);
2600 if (!msg_count) 2338 if (!msg_count)
2601 goto exit; 2339 goto exit;
2602 } 2340 }
@@ -2606,18 +2344,14 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2606 if (dest_link->exp_msg_count == 0) { 2344 if (dest_link->exp_msg_count == 0) {
2607 warn("Link switchover error, " 2345 warn("Link switchover error, "
2608 "got too many tunnelled messages\n"); 2346 "got too many tunnelled messages\n");
2609 msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<");
2610 dbg_print_link(dest_link, "LINK:");
2611 goto exit; 2347 goto exit;
2612 } 2348 }
2613 dest_link->exp_msg_count--; 2349 dest_link->exp_msg_count--;
2614 if (less(msg_seqno(msg), dest_link->reset_checkpoint)) { 2350 if (less(msg_seqno(msg), dest_link->reset_checkpoint)) {
2615 msg_dbg(tunnel_msg, "DROP/DUPL/<REC<");
2616 goto exit; 2351 goto exit;
2617 } else { 2352 } else {
2618 *buf = buf_extract(tunnel_buf, INT_H_SIZE); 2353 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2619 if (*buf != NULL) { 2354 if (*buf != NULL) {
2620 msg_dbg(tunnel_msg, "TNL<REC<");
2621 buf_discard(tunnel_buf); 2355 buf_discard(tunnel_buf);
2622 return 1; 2356 return 1;
2623 } else { 2357 } else {
@@ -2639,7 +2373,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2639 u32 pos = INT_H_SIZE; 2373 u32 pos = INT_H_SIZE;
2640 struct sk_buff *obuf; 2374 struct sk_buff *obuf;
2641 2375
2642 msg_dbg(buf_msg(buf), "<BNDL<: ");
2643 while (msgcount--) { 2376 while (msgcount--) {
2644 obuf = buf_extract(buf, pos); 2377 obuf = buf_extract(buf, pos);
2645 if (obuf == NULL) { 2378 if (obuf == NULL) {
@@ -2647,7 +2380,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2647 break; 2380 break;
2648 } 2381 }
2649 pos += align(msg_size(buf_msg(obuf))); 2382 pos += align(msg_size(buf_msg(obuf)));
2650 msg_dbg(buf_msg(obuf), " /");
2651 tipc_net_route_msg(obuf); 2383 tipc_net_route_msg(obuf);
2652 } 2384 }
2653 buf_discard(buf); 2385 buf_discard(buf);
@@ -2659,11 +2391,11 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2659 2391
2660 2392
2661/* 2393/*
2662 * tipc_link_send_long_buf: Entry for buffers needing fragmentation. 2394 * link_send_long_buf: Entry for buffers needing fragmentation.
2663 * The buffer is complete, inclusive total message length. 2395 * The buffer is complete, inclusive total message length.
2664 * Returns user data length. 2396 * Returns user data length.
2665 */ 2397 */
2666int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) 2398static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2667{ 2399{
2668 struct tipc_msg *inmsg = buf_msg(buf); 2400 struct tipc_msg *inmsg = buf_msg(buf);
2669 struct tipc_msg fragm_hdr; 2401 struct tipc_msg fragm_hdr;
@@ -2671,7 +2403,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2671 u32 dsz = msg_data_sz(inmsg); 2403 u32 dsz = msg_data_sz(inmsg);
2672 unchar *crs = buf->data; 2404 unchar *crs = buf->data;
2673 u32 rest = insize; 2405 u32 rest = insize;
2674 u32 pack_sz = link_max_pkt(l_ptr); 2406 u32 pack_sz = l_ptr->max_pkt;
2675 u32 fragm_sz = pack_sz - INT_H_SIZE; 2407 u32 fragm_sz = pack_sz - INT_H_SIZE;
2676 u32 fragm_no = 1; 2408 u32 fragm_no = 1;
2677 u32 destaddr; 2409 u32 destaddr;
@@ -2686,7 +2418,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2686 2418
2687 /* Prepare reusable fragment header: */ 2419 /* Prepare reusable fragment header: */
2688 2420
2689 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 2421 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
2690 INT_H_SIZE, destaddr); 2422 INT_H_SIZE, destaddr);
2691 msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); 2423 msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg));
2692 msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); 2424 msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++));
@@ -2702,7 +2434,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2702 fragm_sz = rest; 2434 fragm_sz = rest;
2703 msg_set_type(&fragm_hdr, LAST_FRAGMENT); 2435 msg_set_type(&fragm_hdr, LAST_FRAGMENT);
2704 } 2436 }
2705 fragm = buf_acquire(fragm_sz + INT_H_SIZE); 2437 fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
2706 if (fragm == NULL) { 2438 if (fragm == NULL) {
2707 warn("Link unable to fragment message\n"); 2439 warn("Link unable to fragment message\n");
2708 dsz = -ENOMEM; 2440 dsz = -ENOMEM;
@@ -2784,12 +2516,11 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2784 u32 long_msg_seq_no = msg_long_msgno(fragm); 2516 u32 long_msg_seq_no = msg_long_msgno(fragm);
2785 2517
2786 *fb = NULL; 2518 *fb = NULL;
2787 msg_dbg(fragm,"FRG<REC<");
2788 2519
2789 /* Is there an incomplete message waiting for this fragment? */ 2520 /* Is there an incomplete message waiting for this fragment? */
2790 2521
2791 while (pbuf && ((msg_seqno(buf_msg(pbuf)) != long_msg_seq_no) 2522 while (pbuf && ((msg_seqno(buf_msg(pbuf)) != long_msg_seq_no) ||
2792 || (msg_orignode(fragm) != msg_orignode(buf_msg(pbuf))))) { 2523 (msg_orignode(fragm) != msg_orignode(buf_msg(pbuf))))) {
2793 prev = pbuf; 2524 prev = pbuf;
2794 pbuf = pbuf->next; 2525 pbuf = pbuf->next;
2795 } 2526 }
@@ -2803,11 +2534,10 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2803 if (msg_type(imsg) == TIPC_MCAST_MSG) 2534 if (msg_type(imsg) == TIPC_MCAST_MSG)
2804 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; 2535 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
2805 if (msg_size(imsg) > max) { 2536 if (msg_size(imsg) > max) {
2806 msg_dbg(fragm,"<REC<Oversized: ");
2807 buf_discard(fbuf); 2537 buf_discard(fbuf);
2808 return 0; 2538 return 0;
2809 } 2539 }
2810 pbuf = buf_acquire(msg_size(imsg)); 2540 pbuf = tipc_buf_acquire(msg_size(imsg));
2811 if (pbuf != NULL) { 2541 if (pbuf != NULL) {
2812 pbuf->next = *pending; 2542 pbuf->next = *pending;
2813 *pending = pbuf; 2543 *pending = pbuf;
@@ -2816,8 +2546,8 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2816 /* Prepare buffer for subsequent fragments. */ 2546 /* Prepare buffer for subsequent fragments. */
2817 2547
2818 set_long_msg_seqno(pbuf, long_msg_seq_no); 2548 set_long_msg_seqno(pbuf, long_msg_seq_no);
2819 set_fragm_size(pbuf,fragm_sz); 2549 set_fragm_size(pbuf, fragm_sz);
2820 set_expected_frags(pbuf,exp_fragm_cnt - 1); 2550 set_expected_frags(pbuf, exp_fragm_cnt - 1);
2821 } else { 2551 } else {
2822 warn("Link unable to reassemble fragmented message\n"); 2552 warn("Link unable to reassemble fragmented message\n");
2823 } 2553 }
@@ -2844,13 +2574,9 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2844 *m = buf_msg(pbuf); 2574 *m = buf_msg(pbuf);
2845 return 1; 2575 return 1;
2846 } 2576 }
2847 set_expected_frags(pbuf,exp_frags); 2577 set_expected_frags(pbuf, exp_frags);
2848 return 0; 2578 return 0;
2849 } 2579 }
2850 dbg(" Discarding orphan fragment %x\n",fbuf);
2851 msg_dbg(fragm,"ORPHAN:");
2852 dbg("Pending long buffers:\n");
2853 dbg_print_buf_chain(*pending);
2854 buf_discard(fbuf); 2580 buf_discard(fbuf);
2855 return 0; 2581 return 0;
2856} 2582}
@@ -2878,11 +2604,6 @@ static void link_check_defragm_bufs(struct link *l_ptr)
2878 incr_timer_cnt(buf); 2604 incr_timer_cnt(buf);
2879 prev = buf; 2605 prev = buf;
2880 } else { 2606 } else {
2881 dbg(" Discarding incomplete long buffer\n");
2882 msg_dbg(buf_msg(buf), "LONG:");
2883 dbg_print_link(l_ptr, "curr:");
2884 dbg("Pending long buffers:\n");
2885 dbg_print_buf_chain(l_ptr->defragm_buf);
2886 if (prev) 2607 if (prev)
2887 prev->next = buf->next; 2608 prev->next = buf->next;
2888 else 2609 else
@@ -2917,7 +2638,6 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
2917 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900; 2638 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900;
2918 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200; 2639 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200;
2919 l_ptr->queue_limit[CONN_MANAGER] = 1200; 2640 l_ptr->queue_limit[CONN_MANAGER] = 1200;
2920 l_ptr->queue_limit[ROUTE_DISTRIBUTOR] = 1200;
2921 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500; 2641 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500;
2922 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000; 2642 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000;
2923 /* FRAGMENT and LAST_FRAGMENT packets */ 2643 /* FRAGMENT and LAST_FRAGMENT packets */
@@ -3117,7 +2837,7 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
3117 tipc_printf(&pb, "Link <%s>\n" 2837 tipc_printf(&pb, "Link <%s>\n"
3118 " %s MTU:%u Priority:%u Tolerance:%u ms" 2838 " %s MTU:%u Priority:%u Tolerance:%u ms"
3119 " Window:%u packets\n", 2839 " Window:%u packets\n",
3120 l_ptr->name, status, link_max_pkt(l_ptr), 2840 l_ptr->name, status, l_ptr->max_pkt,
3121 l_ptr->priority, l_ptr->tolerance, l_ptr->queue_limit[0]); 2841 l_ptr->priority, l_ptr->tolerance, l_ptr->queue_limit[0]);
3122 tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", 2842 tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n",
3123 l_ptr->next_in_no - l_ptr->stats.recv_info, 2843 l_ptr->next_in_no - l_ptr->stats.recv_info,
@@ -3201,44 +2921,6 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s
3201 return buf; 2921 return buf;
3202} 2922}
3203 2923
3204#if 0
3205int link_control(const char *name, u32 op, u32 val)
3206{
3207 int res = -EINVAL;
3208 struct link *l_ptr;
3209 u32 bearer_id;
3210 struct tipc_node * node;
3211 u32 a;
3212
3213 a = link_name2addr(name, &bearer_id);
3214 read_lock_bh(&tipc_net_lock);
3215 node = tipc_node_find(a);
3216 if (node) {
3217 tipc_node_lock(node);
3218 l_ptr = node->links[bearer_id];
3219 if (l_ptr) {
3220 if (op == TIPC_REMOVE_LINK) {
3221 struct bearer *b_ptr = l_ptr->b_ptr;
3222 spin_lock_bh(&b_ptr->publ.lock);
3223 tipc_link_delete(l_ptr);
3224 spin_unlock_bh(&b_ptr->publ.lock);
3225 }
3226 if (op == TIPC_CMD_BLOCK_LINK) {
3227 tipc_link_reset(l_ptr);
3228 l_ptr->blocked = 1;
3229 }
3230 if (op == TIPC_CMD_UNBLOCK_LINK) {
3231 l_ptr->blocked = 0;
3232 }
3233 res = 0;
3234 }
3235 tipc_node_unlock(node);
3236 }
3237 read_unlock_bh(&tipc_net_lock);
3238 return res;
3239}
3240#endif
3241
3242/** 2924/**
3243 * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination 2925 * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination
3244 * @dest: network address of destination node 2926 * @dest: network address of destination node
@@ -3257,61 +2939,34 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
3257 return MAX_MSG_SIZE; 2939 return MAX_MSG_SIZE;
3258 2940
3259 read_lock_bh(&tipc_net_lock); 2941 read_lock_bh(&tipc_net_lock);
3260 n_ptr = tipc_node_select(dest, selector); 2942 n_ptr = tipc_node_find(dest);
3261 if (n_ptr) { 2943 if (n_ptr) {
3262 tipc_node_lock(n_ptr); 2944 tipc_node_lock(n_ptr);
3263 l_ptr = n_ptr->active_links[selector & 1]; 2945 l_ptr = n_ptr->active_links[selector & 1];
3264 if (l_ptr) 2946 if (l_ptr)
3265 res = link_max_pkt(l_ptr); 2947 res = l_ptr->max_pkt;
3266 tipc_node_unlock(n_ptr); 2948 tipc_node_unlock(n_ptr);
3267 } 2949 }
3268 read_unlock_bh(&tipc_net_lock); 2950 read_unlock_bh(&tipc_net_lock);
3269 return res; 2951 return res;
3270} 2952}
3271 2953
3272#if 0 2954static void link_print(struct link *l_ptr, const char *str)
3273static void link_dump_rec_queue(struct link *l_ptr)
3274{ 2955{
3275 struct sk_buff *crs; 2956 char print_area[256];
3276 2957 struct print_buf pb;
3277 if (!l_ptr->oldest_deferred_in) { 2958 struct print_buf *buf = &pb;
3278 info("Reception queue empty\n");
3279 return;
3280 }
3281 info("Contents of Reception queue:\n");
3282 crs = l_ptr->oldest_deferred_in;
3283 while (crs) {
3284 if (crs->data == (void *)0x0000a3a3) {
3285 info("buffer %x invalid\n", crs);
3286 return;
3287 }
3288 msg_dbg(buf_msg(crs), "In rec queue: \n");
3289 crs = crs->next;
3290 }
3291}
3292#endif
3293 2959
3294static void link_dump_send_queue(struct link *l_ptr) 2960 tipc_printbuf_init(buf, print_area, sizeof(print_area));
3295{
3296 if (l_ptr->next_out) {
3297 info("\nContents of unsent queue:\n");
3298 dbg_print_buf_chain(l_ptr->next_out);
3299 }
3300 info("\nContents of send queue:\n");
3301 if (l_ptr->first_out) {
3302 dbg_print_buf_chain(l_ptr->first_out);
3303 }
3304 info("Empty send queue\n");
3305}
3306 2961
3307static void link_print(struct link *l_ptr, struct print_buf *buf,
3308 const char *str)
3309{
3310 tipc_printf(buf, str); 2962 tipc_printf(buf, str);
3311 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
3312 return;
3313 tipc_printf(buf, "Link %x<%s>:", 2963 tipc_printf(buf, "Link %x<%s>:",
3314 l_ptr->addr, l_ptr->b_ptr->publ.name); 2964 l_ptr->addr, l_ptr->b_ptr->publ.name);
2965
2966#ifdef CONFIG_TIPC_DEBUG
2967 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
2968 goto print_state;
2969
3315 tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no)); 2970 tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no));
3316 tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no)); 2971 tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no));
3317 tipc_printf(buf, "SQUE"); 2972 tipc_printf(buf, "SQUE");
@@ -3320,18 +2975,15 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
3320 if (l_ptr->next_out) 2975 if (l_ptr->next_out)
3321 tipc_printf(buf, "%u..", 2976 tipc_printf(buf, "%u..",
3322 msg_seqno(buf_msg(l_ptr->next_out))); 2977 msg_seqno(buf_msg(l_ptr->next_out)));
3323 tipc_printf(buf, "%u]", 2978 tipc_printf(buf, "%u]", msg_seqno(buf_msg(l_ptr->last_out)));
3324 msg_seqno(buf_msg
3325 (l_ptr->last_out)), l_ptr->out_queue_size);
3326 if ((mod(msg_seqno(buf_msg(l_ptr->last_out)) - 2979 if ((mod(msg_seqno(buf_msg(l_ptr->last_out)) -
3327 msg_seqno(buf_msg(l_ptr->first_out))) 2980 msg_seqno(buf_msg(l_ptr->first_out)))
3328 != (l_ptr->out_queue_size - 1)) 2981 != (l_ptr->out_queue_size - 1)) ||
3329 || (l_ptr->last_out->next != NULL)) { 2982 (l_ptr->last_out->next != NULL)) {
3330 tipc_printf(buf, "\nSend queue inconsistency\n"); 2983 tipc_printf(buf, "\nSend queue inconsistency\n");
3331 tipc_printf(buf, "first_out= %x ", l_ptr->first_out); 2984 tipc_printf(buf, "first_out= %x ", l_ptr->first_out);
3332 tipc_printf(buf, "next_out= %x ", l_ptr->next_out); 2985 tipc_printf(buf, "next_out= %x ", l_ptr->next_out);
3333 tipc_printf(buf, "last_out= %x ", l_ptr->last_out); 2986 tipc_printf(buf, "last_out= %x ", l_ptr->last_out);
3334 link_dump_send_queue(l_ptr);
3335 } 2987 }
3336 } else 2988 } else
3337 tipc_printf(buf, "[]"); 2989 tipc_printf(buf, "[]");
@@ -3345,14 +2997,20 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
3345 l_ptr->deferred_inqueue_sz); 2997 l_ptr->deferred_inqueue_sz);
3346 } 2998 }
3347 } 2999 }
3000print_state:
3001#endif
3002
3348 if (link_working_unknown(l_ptr)) 3003 if (link_working_unknown(l_ptr))
3349 tipc_printf(buf, ":WU"); 3004 tipc_printf(buf, ":WU");
3350 if (link_reset_reset(l_ptr)) 3005 else if (link_reset_reset(l_ptr))
3351 tipc_printf(buf, ":RR"); 3006 tipc_printf(buf, ":RR");
3352 if (link_reset_unknown(l_ptr)) 3007 else if (link_reset_unknown(l_ptr))
3353 tipc_printf(buf, ":RU"); 3008 tipc_printf(buf, ":RU");
3354 if (link_working_working(l_ptr)) 3009 else if (link_working_working(l_ptr))
3355 tipc_printf(buf, ":WW"); 3010 tipc_printf(buf, ":WW");
3356 tipc_printf(buf, "\n"); 3011 tipc_printf(buf, "\n");
3012
3013 tipc_printbuf_validate(buf);
3014 info("%s", print_area);
3357} 3015}
3358 3016
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 6a51e38ad25c..70967e637027 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -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 {
@@ -210,13 +208,7 @@ struct link {
210 u32 msg_length_counts; 208 u32 msg_length_counts;
211 u32 msg_lengths_total; 209 u32 msg_lengths_total;
212 u32 msg_length_profile[7]; 210 u32 msg_length_profile[7];
213#if 0
214 u32 sent_tunneled;
215 u32 recv_tunneled;
216#endif
217 } stats; 211 } stats;
218
219 struct print_buf print_buf;
220}; 212};
221 213
222struct port; 214struct port;
@@ -229,7 +221,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *dest);
229void tipc_link_reset_fragments(struct link *l_ptr); 221void tipc_link_reset_fragments(struct link *l_ptr);
230int tipc_link_is_up(struct link *l_ptr); 222int tipc_link_is_up(struct link *l_ptr);
231int tipc_link_is_active(struct link *l_ptr); 223int tipc_link_is_active(struct link *l_ptr);
232void tipc_link_start(struct link *l_ptr);
233u32 tipc_link_push_packet(struct link *l_ptr); 224u32 tipc_link_push_packet(struct link *l_ptr);
234void tipc_link_stop(struct link *l_ptr); 225void tipc_link_stop(struct link *l_ptr);
235struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd); 226struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd);
@@ -238,14 +229,11 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_
238void tipc_link_reset(struct link *l_ptr); 229void tipc_link_reset(struct link *l_ptr);
239int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector); 230int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
240int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf); 231int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf);
241u32 tipc_link_get_max_pkt(u32 dest,u32 selector); 232u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
242int tipc_link_send_sections_fast(struct port* sender, 233int tipc_link_send_sections_fast(struct port *sender,
243 struct iovec const *msg_sect, 234 struct iovec const *msg_sect,
244 const u32 num_sect, 235 const u32 num_sect,
245 u32 destnode); 236 u32 destnode);
246int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
247void tipc_link_tunnel(struct link *l_ptr, struct tipc_msg *tnl_hdr,
248 struct tipc_msg *msg, u32 selector);
249void tipc_link_recv_bundle(struct sk_buff *buf); 237void tipc_link_recv_bundle(struct sk_buff *buf);
250int tipc_link_recv_fragment(struct sk_buff **pending, 238int tipc_link_recv_fragment(struct sk_buff **pending,
251 struct sk_buff **fb, 239 struct sk_buff **fb,
@@ -279,12 +267,12 @@ static inline int between(u32 lower, u32 upper, u32 n)
279 267
280static inline int less_eq(u32 left, u32 right) 268static inline int less_eq(u32 left, u32 right)
281{ 269{
282 return (mod(right - left) < 32768u); 270 return mod(right - left) < 32768u;
283} 271}
284 272
285static inline int less(u32 left, u32 right) 273static inline int less(u32 left, u32 right)
286{ 274{
287 return (less_eq(left, right) && (mod(right) != mod(left))); 275 return less_eq(left, right) && (mod(right) != mod(left));
288} 276}
289 277
290static inline u32 lesser(u32 left, u32 right) 278static inline u32 lesser(u32 left, u32 right)
@@ -292,4 +280,39 @@ static inline u32 lesser(u32 left, u32 right)
292 return less_eq(left, right) ? left : right; 280 return less_eq(left, right) ? left : right;
293} 281}
294 282
283
284/*
285 * Link status checking routines
286 */
287
288static inline int link_working_working(struct link *l_ptr)
289{
290 return l_ptr->state == WORKING_WORKING;
291}
292
293static inline int link_working_unknown(struct link *l_ptr)
294{
295 return l_ptr->state == WORKING_UNKNOWN;
296}
297
298static inline int link_reset_unknown(struct link *l_ptr)
299{
300 return l_ptr->state == RESET_UNKNOWN;
301}
302
303static inline int link_reset_reset(struct link *l_ptr)
304{
305 return l_ptr->state == RESET_RESET;
306}
307
308static inline int link_blocked(struct link *l_ptr)
309{
310 return l_ptr->exp_msg_count || l_ptr->blocked;
311}
312
313static inline int link_congested(struct link *l_ptr)
314{
315 return l_ptr->out_queue_size >= l_ptr->queue_limit[0];
316}
317
295#endif 318#endif
diff --git a/net/tipc/dbg.c b/net/tipc/log.c
index 1885a7edb0c8..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:
@@ -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,14 +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_move(struct print_buf *pb_to,
80 struct print_buf *pb_from);
79 81
80#define FORMAT(PTR,LEN,FMT) \ 82#define FORMAT(PTR, LEN, FMT) \
81{\ 83{\
82 va_list args;\ 84 va_list args;\
83 va_start(args, FMT);\ 85 va_start(args, FMT);\
84 LEN = vsprintf(PTR, FMT, args);\ 86 LEN = vsprintf(PTR, FMT, args);\
85 va_end(args);\ 87 va_end(args);\
86 *(PTR + LEN) = '\0';\ 88 *(PTR + LEN) = '\0';\
87} 89}
88 90
89/** 91/**
@@ -116,7 +118,7 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
116 * @pb: pointer to print buffer structure 118 * @pb: pointer to print buffer structure
117 */ 119 */
118 120
119void tipc_printbuf_reset(struct print_buf *pb) 121static void tipc_printbuf_reset(struct print_buf *pb)
120{ 122{
121 if (pb->buf) { 123 if (pb->buf) {
122 pb->crs = pb->buf; 124 pb->crs = pb->buf;
@@ -132,9 +134,9 @@ void tipc_printbuf_reset(struct print_buf *pb)
132 * Returns non-zero if print buffer is empty. 134 * Returns non-zero if print buffer is empty.
133 */ 135 */
134 136
135int tipc_printbuf_empty(struct print_buf *pb) 137static int tipc_printbuf_empty(struct print_buf *pb)
136{ 138{
137 return (!pb->buf || (pb->crs == pb->buf)); 139 return !pb->buf || (pb->crs == pb->buf);
138} 140}
139 141
140/** 142/**
@@ -169,7 +171,7 @@ int tipc_printbuf_validate(struct print_buf *pb)
169 tipc_printf(pb, err); 171 tipc_printf(pb, err);
170 } 172 }
171 } 173 }
172 return (pb->crs - pb->buf + 1); 174 return pb->crs - pb->buf + 1;
173} 175}
174 176
175/** 177/**
@@ -181,7 +183,8 @@ int tipc_printbuf_validate(struct print_buf *pb)
181 * Source print buffer becomes empty if a successful move occurs. 183 * Source print buffer becomes empty if a successful move occurs.
182 */ 184 */
183 185
184void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) 186static void tipc_printbuf_move(struct print_buf *pb_to,
187 struct print_buf *pb_from)
185{ 188{
186 int len; 189 int len;
187 190
@@ -263,81 +266,6 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
263 spin_unlock_bh(&print_lock); 266 spin_unlock_bh(&print_lock);
264} 267}
265 268
266#ifdef CONFIG_TIPC_DEBUG
267
268/**
269 * print_to_console - write string of bytes to console in multiple chunks
270 */
271
272static void print_to_console(char *crs, int len)
273{
274 int rest = len;
275
276 while (rest > 0) {
277 int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR;
278 char c = crs[sz];
279
280 crs[sz] = 0;
281 printk((const char *)crs);
282 crs[sz] = c;
283 rest -= sz;
284 crs += sz;
285 }
286}
287
288/**
289 * printbuf_dump - write print buffer contents to console
290 */
291
292static void printbuf_dump(struct print_buf *pb)
293{
294 int len;
295
296 if (!pb->buf) {
297 printk("*** PRINT BUFFER NOT ALLOCATED ***");
298 return;
299 }
300
301 /* Dump print buffer from char after cursor to end (if used) */
302
303 len = pb->buf + pb->size - pb->crs - 2;
304 if ((pb->buf[pb->size - 1] == 0) && (len > 0))
305 print_to_console(pb->crs + 1, len);
306
307 /* Dump print buffer from start to cursor (always) */
308
309 len = pb->crs - pb->buf;
310 print_to_console(pb->buf, len);
311}
312
313/**
314 * tipc_dump_dbg - dump (non-console) print buffer to console
315 * @pb: pointer to print buffer
316 */
317
318void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...)
319{
320 int len;
321
322 if (pb == TIPC_CONS)
323 return;
324
325 spin_lock_bh(&print_lock);
326
327 FORMAT(print_string, len, fmt);
328 printk(print_string);
329
330 printk("\n---- Start of %s log dump ----\n\n",
331 (pb == TIPC_LOG) ? "global" : "local");
332 printbuf_dump(pb);
333 tipc_printbuf_reset(pb);
334 printk("\n---- End of dump ----\n");
335
336 spin_unlock_bh(&print_lock);
337}
338
339#endif
340
341/** 269/**
342 * tipc_log_resize - change the size of the TIPC log buffer 270 * tipc_log_resize - change the size of the TIPC log buffer
343 * @log_size: print buffer size to use 271 * @log_size: print buffer size to use
@@ -348,10 +276,8 @@ int tipc_log_resize(int log_size)
348 int res = 0; 276 int res = 0;
349 277
350 spin_lock_bh(&print_lock); 278 spin_lock_bh(&print_lock);
351 if (TIPC_LOG->buf) { 279 kfree(TIPC_LOG->buf);
352 kfree(TIPC_LOG->buf); 280 TIPC_LOG->buf = NULL;
353 TIPC_LOG->buf = NULL;
354 }
355 if (log_size) { 281 if (log_size) {
356 if (log_size < TIPC_PB_MIN_SIZE) 282 if (log_size < TIPC_PB_MIN_SIZE)
357 log_size = TIPC_PB_MIN_SIZE; 283 log_size = TIPC_PB_MIN_SIZE;
@@ -402,8 +328,7 @@ struct sk_buff *tipc_log_dump(void)
402 } else if (tipc_printbuf_empty(TIPC_LOG)) { 328 } else if (tipc_printbuf_empty(TIPC_LOG)) {
403 spin_unlock_bh(&print_lock); 329 spin_unlock_bh(&print_lock);
404 reply = tipc_cfg_reply_ultra_string("log is empty\n"); 330 reply = tipc_cfg_reply_ultra_string("log is empty\n");
405 } 331 } else {
406 else {
407 struct tlv_desc *rep_tlv; 332 struct tlv_desc *rep_tlv;
408 struct print_buf pb; 333 struct print_buf pb;
409 int str_len; 334 int str_len;
@@ -424,4 +349,3 @@ struct sk_buff *tipc_log_dump(void)
424 } 349 }
425 return reply; 350 return reply;
426} 351}
427
diff --git a/net/tipc/dbg.h b/net/tipc/log.h
index 5ef1bc8f64ef..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
@@ -56,10 +56,7 @@ struct print_buf {
56#define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */ 56#define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */
57 57
58void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); 58void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size);
59void tipc_printbuf_reset(struct print_buf *pb);
60int tipc_printbuf_empty(struct print_buf *pb);
61int tipc_printbuf_validate(struct print_buf *pb); 59int tipc_printbuf_validate(struct print_buf *pb);
62void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from);
63 60
64int tipc_log_resize(int log_size); 61int tipc_log_resize(int log_size);
65 62
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 73dcd00d674e..bb6180c4fcbb 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -35,17 +35,109 @@
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
40u32 tipc_msg_tot_importance(struct tipc_msg *m)
41{
42 if (likely(msg_isdata(m))) {
43 if (likely(msg_orignode(m) == tipc_own_addr))
44 return msg_importance(m);
45 return msg_importance(m) + 4;
46 }
47 if ((msg_user(m) == MSG_FRAGMENTER) &&
48 (msg_type(m) == FIRST_FRAGMENT))
49 return msg_importance(msg_get_wrapped(m));
50 return msg_importance(m);
51}
52
53
54void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
55 u32 hsize, u32 destnode)
56{
57 memset(m, 0, hsize);
58 msg_set_version(m);
59 msg_set_user(m, user);
60 msg_set_hdr_sz(m, hsize);
61 msg_set_size(m, hsize);
62 msg_set_prevnode(m, tipc_own_addr);
63 msg_set_type(m, type);
64 if (!msg_short(m)) {
65 msg_set_orignode(m, tipc_own_addr);
66 msg_set_destnode(m, destnode);
67 }
68}
69
70/**
71 * tipc_msg_calc_data_size - determine total data size for message
72 */
73
74int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
75{
76 int dsz = 0;
77 int i;
78
79 for (i = 0; i < num_sect; i++)
80 dsz += msg_sect[i].iov_len;
81 return dsz;
82}
83
84/**
85 * tipc_msg_build - create message using specified header and data
86 *
87 * Note: Caller must not hold any locks in case copy_from_user() is interrupted!
88 *
89 * Returns message data size or errno
90 */
91
92int tipc_msg_build(struct tipc_msg *hdr,
93 struct iovec const *msg_sect, u32 num_sect,
94 int max_size, int usrmem, struct sk_buff **buf)
95{
96 int dsz, sz, hsz, pos, res, cnt;
97
98 dsz = tipc_msg_calc_data_size(msg_sect, num_sect);
99 if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) {
100 *buf = NULL;
101 return -EINVAL;
102 }
103
104 pos = hsz = msg_hdr_sz(hdr);
105 sz = hsz + dsz;
106 msg_set_size(hdr, sz);
107 if (unlikely(sz > max_size)) {
108 *buf = NULL;
109 return dsz;
110 }
111
112 *buf = tipc_buf_acquire(sz);
113 if (!(*buf))
114 return -ENOMEM;
115 skb_copy_to_linear_data(*buf, hdr, hsz);
116 for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) {
117 if (likely(usrmem))
118 res = !copy_from_user((*buf)->data + pos,
119 msg_sect[cnt].iov_base,
120 msg_sect[cnt].iov_len);
121 else
122 skb_copy_to_linear_data_offset(*buf, pos,
123 msg_sect[cnt].iov_base,
124 msg_sect[cnt].iov_len);
125 pos += msg_sect[cnt].iov_len;
126 }
127 if (likely(res))
128 return dsz;
129
130 buf_discard(*buf);
131 *buf = NULL;
132 return -EFAULT;
133}
43 134
44#ifdef CONFIG_TIPC_DEBUG 135#ifdef CONFIG_TIPC_DEBUG
45 136
46void 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)
47{ 138{
48 u32 usr = msg_user(msg); 139 u32 usr = msg_user(msg);
140 tipc_printf(buf, KERN_DEBUG);
49 tipc_printf(buf, str); 141 tipc_printf(buf, str);
50 142
51 switch (usr) { 143 switch (usr) {
@@ -69,10 +161,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
69 tipc_printf(buf, "LAST:"); 161 tipc_printf(buf, "LAST:");
70 break; 162 break;
71 default: 163 default:
72 tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); 164 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
73 165
74 } 166 }
75 tipc_printf(buf, "NO(%u/%u):",msg_long_msgno(msg), 167 tipc_printf(buf, "NO(%u/%u):", msg_long_msgno(msg),
76 msg_fragm_no(msg)); 168 msg_fragm_no(msg));
77 break; 169 break;
78 case TIPC_LOW_IMPORTANCE: 170 case TIPC_LOW_IMPORTANCE:
@@ -98,7 +190,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
98 tipc_printf(buf, "DIR:"); 190 tipc_printf(buf, "DIR:");
99 break; 191 break;
100 default: 192 default:
101 tipc_printf(buf, "UNKNOWN TYPE %u",msg_type(msg)); 193 tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg));
102 } 194 }
103 if (msg_routed(msg) && !msg_non_seq(msg)) 195 if (msg_routed(msg) && !msg_non_seq(msg))
104 tipc_printf(buf, "ROUT:"); 196 tipc_printf(buf, "ROUT:");
@@ -116,7 +208,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
116 tipc_printf(buf, "WDRW:"); 208 tipc_printf(buf, "WDRW:");
117 break; 209 break;
118 default: 210 default:
119 tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); 211 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
120 } 212 }
121 if (msg_routed(msg)) 213 if (msg_routed(msg))
122 tipc_printf(buf, "ROUT:"); 214 tipc_printf(buf, "ROUT:");
@@ -135,39 +227,39 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
135 break; 227 break;
136 case CONN_ACK: 228 case CONN_ACK:
137 tipc_printf(buf, "CONN_ACK:"); 229 tipc_printf(buf, "CONN_ACK:");
138 tipc_printf(buf, "ACK(%u):",msg_msgcnt(msg)); 230 tipc_printf(buf, "ACK(%u):", msg_msgcnt(msg));
139 break; 231 break;
140 default: 232 default:
141 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 233 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
142 } 234 }
143 if (msg_routed(msg)) 235 if (msg_routed(msg))
144 tipc_printf(buf, "ROUT:"); 236 tipc_printf(buf, "ROUT:");
145 if (msg_reroute_cnt(msg)) 237 if (msg_reroute_cnt(msg))
146 tipc_printf(buf, "REROUTED(%u):",msg_reroute_cnt(msg)); 238 tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg));
147 break; 239 break;
148 case LINK_PROTOCOL: 240 case LINK_PROTOCOL:
149 tipc_printf(buf, "PROT:TIM(%u):",msg_timestamp(msg)); 241 tipc_printf(buf, "PROT:TIM(%u):", msg_timestamp(msg));
150 switch (msg_type(msg)) { 242 switch (msg_type(msg)) {
151 case STATE_MSG: 243 case STATE_MSG:
152 tipc_printf(buf, "STATE:"); 244 tipc_printf(buf, "STATE:");
153 tipc_printf(buf, "%s:",msg_probe(msg) ? "PRB" :""); 245 tipc_printf(buf, "%s:", msg_probe(msg) ? "PRB" : "");
154 tipc_printf(buf, "NXS(%u):",msg_next_sent(msg)); 246 tipc_printf(buf, "NXS(%u):", msg_next_sent(msg));
155 tipc_printf(buf, "GAP(%u):",msg_seq_gap(msg)); 247 tipc_printf(buf, "GAP(%u):", msg_seq_gap(msg));
156 tipc_printf(buf, "LSTBC(%u):",msg_last_bcast(msg)); 248 tipc_printf(buf, "LSTBC(%u):", msg_last_bcast(msg));
157 break; 249 break;
158 case RESET_MSG: 250 case RESET_MSG:
159 tipc_printf(buf, "RESET:"); 251 tipc_printf(buf, "RESET:");
160 if (msg_size(msg) != msg_hdr_sz(msg)) 252 if (msg_size(msg) != msg_hdr_sz(msg))
161 tipc_printf(buf, "BEAR:%s:",msg_data(msg)); 253 tipc_printf(buf, "BEAR:%s:", msg_data(msg));
162 break; 254 break;
163 case ACTIVATE_MSG: 255 case ACTIVATE_MSG:
164 tipc_printf(buf, "ACTIVATE:"); 256 tipc_printf(buf, "ACTIVATE:");
165 break; 257 break;
166 default: 258 default:
167 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 259 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
168 } 260 }
169 tipc_printf(buf, "PLANE(%c):",msg_net_plane(msg)); 261 tipc_printf(buf, "PLANE(%c):", msg_net_plane(msg));
170 tipc_printf(buf, "SESS(%u):",msg_session(msg)); 262 tipc_printf(buf, "SESS(%u):", msg_session(msg));
171 break; 263 break;
172 case CHANGEOVER_PROTOCOL: 264 case CHANGEOVER_PROTOCOL:
173 tipc_printf(buf, "TUNL:"); 265 tipc_printf(buf, "TUNL:");
@@ -177,10 +269,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
177 break; 269 break;
178 case ORIGINAL_MSG: 270 case ORIGINAL_MSG:
179 tipc_printf(buf, "ORIG:"); 271 tipc_printf(buf, "ORIG:");
180 tipc_printf(buf, "EXP(%u)",msg_msgcnt(msg)); 272 tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg));
181 break; 273 break;
182 default: 274 default:
183 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 275 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
184 } 276 }
185 break; 277 break;
186 case ROUTE_DISTRIBUTOR: 278 case ROUTE_DISTRIBUTOR:
@@ -188,26 +280,26 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
188 switch (msg_type(msg)) { 280 switch (msg_type(msg)) {
189 case EXT_ROUTING_TABLE: 281 case EXT_ROUTING_TABLE:
190 tipc_printf(buf, "EXT_TBL:"); 282 tipc_printf(buf, "EXT_TBL:");
191 tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); 283 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
192 break; 284 break;
193 case LOCAL_ROUTING_TABLE: 285 case LOCAL_ROUTING_TABLE:
194 tipc_printf(buf, "LOCAL_TBL:"); 286 tipc_printf(buf, "LOCAL_TBL:");
195 tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); 287 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
196 break; 288 break;
197 case SLAVE_ROUTING_TABLE: 289 case SLAVE_ROUTING_TABLE:
198 tipc_printf(buf, "DP_TBL:"); 290 tipc_printf(buf, "DP_TBL:");
199 tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); 291 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
200 break; 292 break;
201 case ROUTE_ADDITION: 293 case ROUTE_ADDITION:
202 tipc_printf(buf, "ADD:"); 294 tipc_printf(buf, "ADD:");
203 tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); 295 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
204 break; 296 break;
205 case ROUTE_REMOVAL: 297 case ROUTE_REMOVAL:
206 tipc_printf(buf, "REMOVE:"); 298 tipc_printf(buf, "REMOVE:");
207 tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); 299 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
208 break; 300 break;
209 default: 301 default:
210 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 302 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
211 } 303 }
212 break; 304 break;
213 case LINK_CONFIG: 305 case LINK_CONFIG:
@@ -220,7 +312,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
220 tipc_printf(buf, "DSC_RESP:"); 312 tipc_printf(buf, "DSC_RESP:");
221 break; 313 break;
222 default: 314 default:
223 tipc_printf(buf, "UNKNOWN TYPE:%x:",msg_type(msg)); 315 tipc_printf(buf, "UNKNOWN TYPE:%x:", msg_type(msg));
224 break; 316 break;
225 } 317 }
226 break; 318 break;
@@ -256,7 +348,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
256 tipc_printf(buf, "UNKNOWN ERROR(%x):", 348 tipc_printf(buf, "UNKNOWN ERROR(%x):",
257 msg_errcode(msg)); 349 msg_errcode(msg));
258 } 350 }
259 default:{} 351 default:
352 break;
260 } 353 }
261 354
262 tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg)); 355 tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg));
@@ -265,9 +358,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
265 358
266 if (msg_non_seq(msg)) 359 if (msg_non_seq(msg))
267 tipc_printf(buf, "NOSEQ:"); 360 tipc_printf(buf, "NOSEQ:");
268 else { 361 else
269 tipc_printf(buf, "ACK(%u):", msg_ack(msg)); 362 tipc_printf(buf, "ACK(%u):", msg_ack(msg));
270 }
271 tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg)); 363 tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg));
272 tipc_printf(buf, "PRND(%x)", msg_prevnode(msg)); 364 tipc_printf(buf, "PRND(%x)", msg_prevnode(msg));
273 365
@@ -295,14 +387,13 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
295 if (msg_user(msg) == NAME_DISTRIBUTOR) { 387 if (msg_user(msg) == NAME_DISTRIBUTOR) {
296 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); 388 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg));
297 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); 389 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg));
298 if (msg_routed(msg)) { 390 if (msg_routed(msg))
299 tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg)); 391 tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg));
300 }
301 } 392 }
302 393
303 if (msg_user(msg) == LINK_CONFIG) { 394 if (msg_user(msg) == LINK_CONFIG) {
304 u32* raw = (u32*)msg; 395 u32 *raw = (u32 *)msg;
305 struct tipc_media_addr* orig = (struct tipc_media_addr*)&raw[5]; 396 struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5];
306 tipc_printf(buf, ":REQL(%u):", msg_req_links(msg)); 397 tipc_printf(buf, ":REQL(%u):", msg_req_links(msg));
307 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); 398 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg));
308 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); 399 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg));
@@ -313,12 +404,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
313 tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg)); 404 tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg));
314 } 405 }
315 tipc_printf(buf, "\n"); 406 tipc_printf(buf, "\n");
316 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { 407 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg)))
317 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); 408 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
318 } 409 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT))
319 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) {
320 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); 410 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
321 }
322} 411}
323 412
324#endif 413#endif
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 7ee6ae238147..92c4c4fd7b3f 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -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{
@@ -104,7 +151,7 @@ static inline u32 msg_user(struct tipc_msg *m)
104 151
105static inline u32 msg_isdata(struct tipc_msg *m) 152static inline u32 msg_isdata(struct tipc_msg *m)
106{ 153{
107 return (msg_user(m) <= TIPC_CRITICAL_IMPORTANCE); 154 return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE;
108} 155}
109 156
110static inline void msg_set_user(struct tipc_msg *m, u32 n) 157static inline void msg_set_user(struct tipc_msg *m, u32 n)
@@ -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,31 +349,68 @@ 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
392static inline int msg_short(struct tipc_msg *m)
393{
394 return msg_hdr_sz(m) == 24;
395}
396
397static inline u32 msg_orignode(struct tipc_msg *m)
398{
399 if (likely(msg_short(m)))
400 return msg_prevnode(m);
401 return msg_word(m, 6);
402}
403
280static inline void msg_set_orignode(struct tipc_msg *m, u32 a) 404static inline void msg_set_orignode(struct tipc_msg *m, u32 a)
281{ 405{
282 msg_set_word(m, 6, a); 406 msg_set_word(m, 6, a);
283} 407}
284 408
409static inline u32 msg_destnode(struct tipc_msg *m)
410{
411 return msg_word(m, 7);
412}
413
285static inline void msg_set_destnode(struct tipc_msg *m, u32 a) 414static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
286{ 415{
287 msg_set_word(m, 7, a); 416 msg_set_word(m, 7, a);
@@ -289,14 +418,19 @@ static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
289 418
290static inline int msg_is_dest(struct tipc_msg *m, u32 d) 419static inline int msg_is_dest(struct tipc_msg *m, u32 d)
291{ 420{
292 return(msg_short(m) || (msg_destnode(m) == d)); 421 return msg_short(m) || (msg_destnode(m) == d);
293} 422}
294 423
295static inline u32 msg_routed(struct tipc_msg *m) 424static inline u32 msg_routed(struct tipc_msg *m)
296{ 425{
297 if (likely(msg_short(m))) 426 if (likely(msg_short(m)))
298 return 0; 427 return 0;
299 return(msg_destnode(m) ^ msg_orignode(m)) >> 11; 428 return (msg_destnode(m) ^ msg_orignode(m)) >> 11;
429}
430
431static inline u32 msg_nametype(struct tipc_msg *m)
432{
433 return msg_word(m, 8);
300} 434}
301 435
302static inline void msg_set_nametype(struct tipc_msg *m, u32 n) 436static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
@@ -324,6 +458,16 @@ static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n)
324 msg_set_word(m, 8, n); 458 msg_set_word(m, 8, n);
325} 459}
326 460
461static inline u32 msg_nameinst(struct tipc_msg *m)
462{
463 return msg_word(m, 9);
464}
465
466static inline u32 msg_namelower(struct tipc_msg *m)
467{
468 return msg_nameinst(m);
469}
470
327static inline void msg_set_namelower(struct tipc_msg *m, u32 n) 471static inline void msg_set_namelower(struct tipc_msg *m, u32 n)
328{ 472{
329 msg_set_word(m, 9, n); 473 msg_set_word(m, 9, n);
@@ -334,11 +478,21 @@ static inline void msg_set_nameinst(struct tipc_msg *m, u32 n)
334 msg_set_namelower(m, n); 478 msg_set_namelower(m, n);
335} 479}
336 480
481static inline u32 msg_nameupper(struct tipc_msg *m)
482{
483 return msg_word(m, 10);
484}
485
337static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) 486static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
338{ 487{
339 msg_set_word(m, 10, n); 488 msg_set_word(m, 10, n);
340} 489}
341 490
491static inline unchar *msg_data(struct tipc_msg *m)
492{
493 return ((unchar *)m) + msg_hdr_sz(m);
494}
495
342static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) 496static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
343{ 497{
344 return (struct tipc_msg *)msg_data(m); 498 return (struct tipc_msg *)msg_data(m);
@@ -386,7 +540,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
386#define MSG_BUNDLER 6 540#define MSG_BUNDLER 6
387#define LINK_PROTOCOL 7 541#define LINK_PROTOCOL 7
388#define CONN_MANAGER 8 542#define CONN_MANAGER 8
389#define ROUTE_DISTRIBUTOR 9 543#define ROUTE_DISTRIBUTOR 9 /* obsoleted */
390#define CHANGEOVER_PROTOCOL 10 544#define CHANGEOVER_PROTOCOL 10
391#define NAME_DISTRIBUTOR 11 545#define NAME_DISTRIBUTOR 11
392#define MSG_FRAGMENTER 12 546#define MSG_FRAGMENTER 12
@@ -632,7 +786,7 @@ static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n)
632 786
633static inline u32 msg_max_pkt(struct tipc_msg *m) 787static inline u32 msg_max_pkt(struct tipc_msg *m)
634{ 788{
635 return (msg_bits(m, 9, 16, 0xffff) * 4); 789 return msg_bits(m, 9, 16, 0xffff) * 4;
636} 790}
637 791
638static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) 792static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n)
@@ -665,11 +819,6 @@ static inline void msg_set_remote_node(struct tipc_msg *m, u32 a)
665 msg_set_word(m, msg_hdr_sz(m)/4, a); 819 msg_set_word(m, msg_hdr_sz(m)/4, a);
666} 820}
667 821
668static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
669{
670 msg_data(m)[pos + 4] = 1;
671}
672
673/* 822/*
674 * Segmentation message types 823 * Segmentation message types
675 */ 824 */
@@ -696,7 +845,7 @@ static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
696 * Routing table message types 845 * Routing table message types
697 */ 846 */
698#define EXT_ROUTING_TABLE 0 847#define EXT_ROUTING_TABLE 0
699#define LOCAL_ROUTING_TABLE 1 848#define LOCAL_ROUTING_TABLE 1 /* obsoleted */
700#define SLAVE_ROUTING_TABLE 2 849#define SLAVE_ROUTING_TABLE 2
701#define ROUTE_ADDITION 3 850#define ROUTE_ADDITION 3
702#define ROUTE_REMOVAL 4 851#define ROUTE_REMOVAL 4
@@ -708,100 +857,13 @@ static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
708#define DSC_REQ_MSG 0 857#define DSC_REQ_MSG 0
709#define DSC_RESP_MSG 1 858#define DSC_RESP_MSG 1
710 859
711static inline u32 msg_tot_importance(struct tipc_msg *m) 860u32 tipc_msg_tot_importance(struct tipc_msg *m);
712{ 861void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
713 if (likely(msg_isdata(m))) { 862 u32 hsize, u32 destnode);
714 if (likely(msg_orignode(m) == tipc_own_addr)) 863int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect);
715 return msg_importance(m); 864int tipc_msg_build(struct tipc_msg *hdr,
716 return msg_importance(m) + 4;
717 }
718 if ((msg_user(m) == MSG_FRAGMENTER) &&
719 (msg_type(m) == FIRST_FRAGMENT))
720 return msg_importance(msg_get_wrapped(m));
721 return msg_importance(m);
722}
723
724
725static inline void msg_init(struct tipc_msg *m, u32 user, u32 type,
726 u32 hsize, u32 destnode)
727{
728 memset(m, 0, hsize);
729 msg_set_version(m);
730 msg_set_user(m, user);
731 msg_set_hdr_sz(m, hsize);
732 msg_set_size(m, hsize);
733 msg_set_prevnode(m, tipc_own_addr);
734 msg_set_type(m, type);
735 if (!msg_short(m)) {
736 msg_set_orignode(m, tipc_own_addr);
737 msg_set_destnode(m, destnode);
738 }
739}
740
741/**
742 * msg_calc_data_size - determine total data size for message
743 */
744
745static inline int msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
746{
747 int dsz = 0;
748 int i;
749
750 for (i = 0; i < num_sect; i++)
751 dsz += msg_sect[i].iov_len;
752 return dsz;
753}
754
755/**
756 * msg_build - create message using specified header and data
757 *
758 * Note: Caller must not hold any locks in case copy_from_user() is interrupted!
759 *
760 * Returns message data size or errno
761 */
762
763static inline int msg_build(struct tipc_msg *hdr,
764 struct iovec const *msg_sect, u32 num_sect, 865 struct iovec const *msg_sect, u32 num_sect,
765 int max_size, int usrmem, struct sk_buff** buf) 866 int max_size, int usrmem, struct sk_buff **buf);
766{
767 int dsz, sz, hsz, pos, res, cnt;
768
769 dsz = msg_calc_data_size(msg_sect, num_sect);
770 if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) {
771 *buf = NULL;
772 return -EINVAL;
773 }
774
775 pos = hsz = msg_hdr_sz(hdr);
776 sz = hsz + dsz;
777 msg_set_size(hdr, sz);
778 if (unlikely(sz > max_size)) {
779 *buf = NULL;
780 return dsz;
781 }
782
783 *buf = buf_acquire(sz);
784 if (!(*buf))
785 return -ENOMEM;
786 skb_copy_to_linear_data(*buf, hdr, hsz);
787 for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) {
788 if (likely(usrmem))
789 res = !copy_from_user((*buf)->data + pos,
790 msg_sect[cnt].iov_base,
791 msg_sect[cnt].iov_len);
792 else
793 skb_copy_to_linear_data_offset(*buf, pos,
794 msg_sect[cnt].iov_base,
795 msg_sect[cnt].iov_len);
796 pos += msg_sect[cnt].iov_len;
797 }
798 if (likely(res))
799 return dsz;
800
801 buf_discard(*buf);
802 *buf = NULL;
803 return -EFAULT;
804}
805 867
806static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 868static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
807{ 869{
@@ -810,7 +872,7 @@ static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr
810 872
811static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 873static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
812{ 874{
813 memcpy(a, &((int*)m)[5], sizeof(*a)); 875 memcpy(a, &((int *)m)[5], sizeof(*a));
814} 876}
815 877
816#endif 878#endif
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 10a69894e2fd..483c226c9581 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -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/**
@@ -98,17 +94,37 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
98 94
99static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) 95static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
100{ 96{
101 struct sk_buff *buf = buf_acquire(LONG_H_SIZE + size); 97 struct sk_buff *buf = tipc_buf_acquire(LONG_H_SIZE + size);
102 struct tipc_msg *msg; 98 struct tipc_msg *msg;
103 99
104 if (buf != NULL) { 100 if (buf != NULL) {
105 msg = buf_msg(buf); 101 msg = buf_msg(buf);
106 msg_init(msg, NAME_DISTRIBUTOR, type, LONG_H_SIZE, dest); 102 tipc_msg_init(msg, NAME_DISTRIBUTOR, type, LONG_H_SIZE, dest);
107 msg_set_size(msg, LONG_H_SIZE + size); 103 msg_set_size(msg, LONG_H_SIZE + size);
108 } 104 }
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 u32 n_num;
113
114 for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) {
115 n_ptr = tipc_net.nodes[n_num];
116 if (n_ptr && tipc_node_has_active_links(n_ptr)) {
117 buf_copy = skb_copy(buf, GFP_ATOMIC);
118 if (!buf_copy)
119 break;
120 msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
121 tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
122 }
123 }
124
125 buf_discard(buf);
126}
127
112/** 128/**
113 * tipc_named_publish - tell other nodes about a new publication by this node 129 * tipc_named_publish - tell other nodes about a new publication by this node
114 */ 130 */
@@ -129,8 +145,7 @@ void tipc_named_publish(struct publication *publ)
129 145
130 item = (struct distr_item *)msg_data(buf_msg(buf)); 146 item = (struct distr_item *)msg_data(buf_msg(buf));
131 publ_to_item(item, publ); 147 publ_to_item(item, publ);
132 dbg("tipc_named_withdraw: broadcasting publish msg\n"); 148 named_cluster_distribute(buf);
133 tipc_cltr_broadcast(buf);
134} 149}
135 150
136/** 151/**
@@ -153,8 +168,7 @@ void tipc_named_withdraw(struct publication *publ)
153 168
154 item = (struct distr_item *)msg_data(buf_msg(buf)); 169 item = (struct distr_item *)msg_data(buf_msg(buf));
155 publ_to_item(item, publ); 170 publ_to_item(item, publ);
156 dbg("tipc_named_withdraw: broadcasting withdraw msg\n"); 171 named_cluster_distribute(buf);
157 tipc_cltr_broadcast(buf);
158} 172}
159 173
160/** 174/**
@@ -191,9 +205,6 @@ void tipc_named_node_up(unsigned long node)
191 left -= ITEM_SIZE; 205 left -= ITEM_SIZE;
192 if (!left) { 206 if (!left) {
193 msg_set_link_selector(buf_msg(buf), node); 207 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); 208 tipc_link_send(buf, node, node);
198 buf = NULL; 209 buf = NULL;
199 } 210 }
@@ -218,8 +229,6 @@ static void node_is_down(struct publication *publ)
218 struct publication *p; 229 struct publication *p;
219 230
220 write_lock_bh(&tipc_nametbl_lock); 231 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; 232 publ->key += 1222345;
224 p = tipc_nametbl_remove_publ(publ->type, publ->lower, 233 p = tipc_nametbl_remove_publ(publ->type, publ->lower,
225 publ->node, publ->ref, publ->key); 234 publ->node, publ->ref, publ->key);
@@ -231,9 +240,7 @@ static void node_is_down(struct publication *publ)
231 publ->type, publ->lower, publ->node, publ->ref, publ->key); 240 publ->type, publ->lower, publ->node, publ->ref, publ->key);
232 } 241 }
233 242
234 if (p) { 243 kfree(p);
235 kfree(p);
236 }
237} 244}
238 245
239/** 246/**
@@ -250,9 +257,6 @@ void tipc_named_recv(struct sk_buff *buf)
250 write_lock_bh(&tipc_nametbl_lock); 257 write_lock_bh(&tipc_nametbl_lock);
251 while (count--) { 258 while (count--) {
252 if (msg_type(msg) == PUBLICATION) { 259 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), 260 publ = tipc_nametbl_insert_publ(ntohl(item->type),
257 ntohl(item->lower), 261 ntohl(item->lower),
258 ntohl(item->upper), 262 ntohl(item->upper),
@@ -267,9 +271,6 @@ void tipc_named_recv(struct sk_buff *buf)
267 (net_ev_handler)node_is_down); 271 (net_ev_handler)node_is_down);
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 acab41a48d67..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,14 +104,14 @@ 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
116 111
117static int hash(int x) 112static int hash(int x)
118{ 113{
119 return(x & (tipc_nametbl_size - 1)); 114 return x & (tipc_nametbl_size - 1);
120} 115}
121 116
122/** 117/**
@@ -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)) {
@@ -613,8 +582,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
613} 582}
614 583
615/* 584/*
616 * tipc_nametbl_translate(): Translate tipc_name -> tipc_portid. 585 * tipc_nametbl_translate - translate name to port id
617 * Very time-critical.
618 * 586 *
619 * Note: on entry 'destnode' is the search domain used during translation; 587 * Note: on entry 'destnode' is the search domain used during translation;
620 * on exit it passes back the node address of the matching port (if any) 588 * on exit it passes back the node address of the matching port (if any)
@@ -627,7 +595,7 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
627 struct name_seq *seq; 595 struct name_seq *seq;
628 u32 ref; 596 u32 ref;
629 597
630 if (!in_scope(*destnode, tipc_own_addr)) 598 if (!tipc_in_scope(*destnode, tipc_own_addr))
631 return 0; 599 return 0;
632 600
633 read_lock_bh(&tipc_nametbl_lock); 601 read_lock_bh(&tipc_nametbl_lock);
@@ -685,7 +653,6 @@ found:
685 } 653 }
686 spin_unlock_bh(&seq->lock); 654 spin_unlock_bh(&seq->lock);
687not_found: 655not_found:
688 *destnode = 0;
689 read_unlock_bh(&tipc_nametbl_lock); 656 read_unlock_bh(&tipc_nametbl_lock);
690 return 0; 657 return 0;
691} 658}
@@ -784,9 +751,8 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
784 table.local_publ_count++; 751 table.local_publ_count++;
785 publ = tipc_nametbl_insert_publ(type, lower, upper, scope, 752 publ = tipc_nametbl_insert_publ(type, lower, upper, scope,
786 tipc_own_addr, port_ref, key); 753 tipc_own_addr, port_ref, key);
787 if (publ && (scope != TIPC_NODE_SCOPE)) { 754 if (publ && (scope != TIPC_NODE_SCOPE))
788 tipc_named_publish(publ); 755 tipc_named_publish(publ);
789 }
790 write_unlock_bh(&tipc_nametbl_lock); 756 write_unlock_bh(&tipc_nametbl_lock);
791 return publ; 757 return publ;
792} 758}
@@ -799,7 +765,6 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
799{ 765{
800 struct publication *publ; 766 struct publication *publ;
801 767
802 dbg("tipc_nametbl_withdraw: {%u,%u}, key=%u\n", type, lower, key);
803 write_lock_bh(&tipc_nametbl_lock); 768 write_lock_bh(&tipc_nametbl_lock);
804 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);
805 if (likely(publ)) { 770 if (likely(publ)) {
@@ -829,13 +794,10 @@ void tipc_nametbl_subscribe(struct subscription *s)
829 794
830 write_lock_bh(&tipc_nametbl_lock); 795 write_lock_bh(&tipc_nametbl_lock);
831 seq = nametbl_find_seq(type); 796 seq = nametbl_find_seq(type);
832 if (!seq) { 797 if (!seq)
833 seq = tipc_nameseq_create(type, &table.types[hash(type)]); 798 seq = tipc_nameseq_create(type, &table.types[hash(type)]);
834 } 799 if (seq) {
835 if (seq){
836 spin_lock_bh(&seq->lock); 800 spin_lock_bh(&seq->lock);
837 dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n",
838 seq, type, s->seq.lower, s->seq.upper);
839 tipc_nameseq_subscribe(seq, s); 801 tipc_nameseq_subscribe(seq, s);
840 spin_unlock_bh(&seq->lock); 802 spin_unlock_bh(&seq->lock);
841 } else { 803 } else {
@@ -855,7 +817,7 @@ void tipc_nametbl_unsubscribe(struct subscription *s)
855 817
856 write_lock_bh(&tipc_nametbl_lock); 818 write_lock_bh(&tipc_nametbl_lock);
857 seq = nametbl_find_seq(s->seq.type); 819 seq = nametbl_find_seq(s->seq.type);
858 if (seq != NULL){ 820 if (seq != NULL) {
859 spin_lock_bh(&seq->lock); 821 spin_lock_bh(&seq->lock);
860 list_del_init(&s->nameseq_list); 822 list_del_init(&s->nameseq_list);
861 spin_unlock_bh(&seq->lock); 823 spin_unlock_bh(&seq->lock);
@@ -877,7 +839,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
877 u32 index) 839 u32 index)
878{ 840{
879 char portIdStr[27]; 841 char portIdStr[27];
880 char *scopeStr; 842 const char *scope_str[] = {"", " zone", " cluster", " node"};
881 struct publication *publ = sseq->zone_list; 843 struct publication *publ = sseq->zone_list;
882 844
883 tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); 845 tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper);
@@ -888,20 +850,13 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
888 } 850 }
889 851
890 do { 852 do {
891 sprintf (portIdStr, "<%u.%u.%u:%u>", 853 sprintf(portIdStr, "<%u.%u.%u:%u>",
892 tipc_zone(publ->node), tipc_cluster(publ->node), 854 tipc_zone(publ->node), tipc_cluster(publ->node),
893 tipc_node(publ->node), publ->ref); 855 tipc_node(publ->node), publ->ref);
894 tipc_printf(buf, "%-26s ", portIdStr); 856 tipc_printf(buf, "%-26s ", portIdStr);
895 if (depth > 3) { 857 if (depth > 3) {
896 if (publ->node != tipc_own_addr) 858 tipc_printf(buf, "%-10u %s", publ->key,
897 scopeStr = ""; 859 scope_str[publ->scope]);
898 else if (publ->scope == TIPC_NODE_SCOPE)
899 scopeStr = "node";
900 else if (publ->scope == TIPC_CLUSTER_SCOPE)
901 scopeStr = "cluster";
902 else
903 scopeStr = "zone";
904 tipc_printf(buf, "%-10u %s", publ->key, scopeStr);
905 } 860 }
906 861
907 publ = publ->zone_list_next; 862 publ = publ->zone_list_next;
@@ -951,24 +906,19 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
951 906
952static void nametbl_header(struct print_buf *buf, u32 depth) 907static void nametbl_header(struct print_buf *buf, u32 depth)
953{ 908{
954 tipc_printf(buf, "Type "); 909 const char *header[] = {
955 910 "Type ",
956 if (depth > 1) 911 "Lower Upper ",
957 tipc_printf(buf, "Lower Upper "); 912 "Port Identity ",
958 if (depth > 2) 913 "Publication Scope"
959 tipc_printf(buf, "Port Identity "); 914 };
960 if (depth > 3) 915
961 tipc_printf(buf, "Publication"); 916 int i;
962 917
963 tipc_printf(buf, "\n-----------"); 918 if (depth > 4)
964 919 depth = 4;
965 if (depth > 1) 920 for (i = 0; i < depth; i++)
966 tipc_printf(buf, "--------------------- "); 921 tipc_printf(buf, header[i]);
967 if (depth > 2)
968 tipc_printf(buf, "-------------------------- ");
969 if (depth > 3)
970 tipc_printf(buf, "------------------");
971
972 tipc_printf(buf, "\n"); 922 tipc_printf(buf, "\n");
973} 923}
974 924
@@ -1023,16 +973,6 @@ static void nametbl_list(struct print_buf *buf, u32 depth_info,
1023 } 973 }
1024} 974}
1025 975
1026#if 0
1027void tipc_nametbl_print(struct print_buf *buf, const char *str)
1028{
1029 tipc_printf(buf, str);
1030 read_lock_bh(&tipc_nametbl_lock);
1031 nametbl_list(buf, 0, 0, 0, 0);
1032 read_unlock_bh(&tipc_nametbl_lock);
1033}
1034#endif
1035
1036#define MAX_NAME_TBL_QUERY 32768 976#define MAX_NAME_TBL_QUERY 32768
1037 977
1038struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) 978struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space)
@@ -1065,13 +1005,6 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space)
1065 return buf; 1005 return buf;
1066} 1006}
1067 1007
1068#if 0
1069void tipc_nametbl_dump(void)
1070{
1071 nametbl_list(TIPC_CONS, 0, 0, 0, 0);
1072}
1073#endif
1074
1075int tipc_nametbl_init(void) 1008int tipc_nametbl_init(void)
1076{ 1009{
1077 table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head), 1010 table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head),
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 7906608bf510..9bacfd00b91e 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -35,18 +35,10 @@
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"
49#include "discover.h"
50#include "config.h" 42#include "config.h"
51 43
52/* 44/*
@@ -116,70 +108,25 @@
116*/ 108*/
117 109
118DEFINE_RWLOCK(tipc_net_lock); 110DEFINE_RWLOCK(tipc_net_lock);
119struct network tipc_net = { NULL }; 111struct network tipc_net;
120 112
121struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref) 113static int net_start(void)
122{ 114{
123 return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref); 115 tipc_net.nodes = kcalloc(tipc_max_nodes + 1,
124} 116 sizeof(*tipc_net.nodes), GFP_ATOMIC);
125 117 tipc_net.highest_node = 0;
126u32 tipc_net_select_router(u32 addr, u32 ref)
127{
128 return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref);
129}
130
131#if 0
132u32 tipc_net_next_node(u32 a)
133{
134 if (tipc_net.zones[tipc_zone(a)])
135 return tipc_zone_next_node(a);
136 return 0;
137}
138#endif
139
140void tipc_net_remove_as_router(u32 router)
141{
142 u32 z_num;
143
144 for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
145 if (!tipc_net.zones[z_num])
146 continue;
147 tipc_zone_remove_as_router(tipc_net.zones[z_num], router);
148 }
149}
150
151void tipc_net_send_external_routes(u32 dest)
152{
153 u32 z_num;
154
155 for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
156 if (tipc_net.zones[z_num])
157 tipc_zone_send_external_routes(tipc_net.zones[z_num], dest);
158 }
159}
160 118
161static int net_init(void) 119 return tipc_net.nodes ? 0 : -ENOMEM;
162{
163 memset(&tipc_net, 0, sizeof(tipc_net));
164 tipc_net.zones = kcalloc(tipc_max_zones + 1, sizeof(struct _zone *), GFP_ATOMIC);
165 if (!tipc_net.zones) {
166 return -ENOMEM;
167 }
168 return 0;
169} 120}
170 121
171static void net_stop(void) 122static void net_stop(void)
172{ 123{
173 u32 z_num; 124 u32 n_num;
174 125
175 if (!tipc_net.zones) 126 for (n_num = 1; n_num <= tipc_net.highest_node; n_num++)
176 return; 127 tipc_node_delete(tipc_net.nodes[n_num]);
177 128 kfree(tipc_net.nodes);
178 for (z_num = 1; z_num <= tipc_max_zones; z_num++) { 129 tipc_net.nodes = NULL;
179 tipc_zone_delete(tipc_net.zones[z_num]);
180 }
181 kfree(tipc_net.zones);
182 tipc_net.zones = NULL;
183} 130}
184 131
185static void net_route_named_msg(struct sk_buff *buf) 132static void net_route_named_msg(struct sk_buff *buf)
@@ -189,22 +136,18 @@ static void net_route_named_msg(struct sk_buff *buf)
189 u32 dport; 136 u32 dport;
190 137
191 if (!msg_named(msg)) { 138 if (!msg_named(msg)) {
192 msg_dbg(msg, "tipc_net->drop_nam:");
193 buf_discard(buf); 139 buf_discard(buf);
194 return; 140 return;
195 } 141 }
196 142
197 dnode = addr_domain(msg_lookup_scope(msg)); 143 dnode = addr_domain(msg_lookup_scope(msg));
198 dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode); 144 dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode);
199 dbg("tipc_net->lookup<%u,%u>-><%u,%x>\n",
200 msg_nametype(msg), msg_nameinst(msg), dport, dnode);
201 if (dport) { 145 if (dport) {
202 msg_set_destnode(msg, dnode); 146 msg_set_destnode(msg, dnode);
203 msg_set_destport(msg, dport); 147 msg_set_destport(msg, dport);
204 tipc_net_route_msg(buf); 148 tipc_net_route_msg(buf);
205 return; 149 return;
206 } 150 }
207 msg_dbg(msg, "tipc_net->rej:NO NAME: ");
208 tipc_reject_msg(buf, TIPC_ERR_NO_NAME); 151 tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
209} 152}
210 153
@@ -220,21 +163,17 @@ void tipc_net_route_msg(struct sk_buff *buf)
220 msg_incr_reroute_cnt(msg); 163 msg_incr_reroute_cnt(msg);
221 if (msg_reroute_cnt(msg) > 6) { 164 if (msg_reroute_cnt(msg) > 6) {
222 if (msg_errcode(msg)) { 165 if (msg_errcode(msg)) {
223 msg_dbg(msg, "NET>DISC>:");
224 buf_discard(buf); 166 buf_discard(buf);
225 } else { 167 } else {
226 msg_dbg(msg, "NET>REJ>:");
227 tipc_reject_msg(buf, msg_destport(msg) ? 168 tipc_reject_msg(buf, msg_destport(msg) ?
228 TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME); 169 TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME);
229 } 170 }
230 return; 171 return;
231 } 172 }
232 173
233 msg_dbg(msg, "tipc_net->rout: ");
234
235 /* Handle message for this node */ 174 /* Handle message for this node */
236 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); 175 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg);
237 if (in_scope(dnode, tipc_own_addr)) { 176 if (tipc_in_scope(dnode, tipc_own_addr)) {
238 if (msg_isdata(msg)) { 177 if (msg_isdata(msg)) {
239 if (msg_mcast(msg)) 178 if (msg_mcast(msg))
240 tipc_port_recv_mcast(buf, NULL); 179 tipc_port_recv_mcast(buf, NULL);
@@ -245,9 +184,6 @@ void tipc_net_route_msg(struct sk_buff *buf)
245 return; 184 return;
246 } 185 }
247 switch (msg_user(msg)) { 186 switch (msg_user(msg)) {
248 case ROUTE_DISTRIBUTOR:
249 tipc_cltr_recv_routing_table(buf);
250 break;
251 case NAME_DISTRIBUTOR: 187 case NAME_DISTRIBUTOR:
252 tipc_named_recv(buf); 188 tipc_named_recv(buf);
253 break; 189 break;
@@ -255,14 +191,13 @@ void tipc_net_route_msg(struct sk_buff *buf)
255 tipc_port_recv_proto_msg(buf); 191 tipc_port_recv_proto_msg(buf);
256 break; 192 break;
257 default: 193 default:
258 msg_dbg(msg,"DROP/NET/<REC<");
259 buf_discard(buf); 194 buf_discard(buf);
260 } 195 }
261 return; 196 return;
262 } 197 }
263 198
264 /* Handle message for another node */ 199 /* Handle message for another node */
265 msg_dbg(msg, "NET>SEND>: "); 200 skb_trim(buf, msg_size(msg));
266 tipc_link_send(buf, dnode, msg_link_selector(msg)); 201 tipc_link_send(buf, dnode, msg_link_selector(msg));
267} 202}
268 203
@@ -282,19 +217,19 @@ int tipc_net_start(u32 addr)
282 tipc_named_reinit(); 217 tipc_named_reinit();
283 tipc_port_reinit(); 218 tipc_port_reinit();
284 219
285 if ((res = tipc_bearer_init()) || 220 res = net_start();
286 (res = net_init()) || 221 if (res)
287 (res = tipc_cltr_init()) || 222 return res;
288 (res = tipc_bclink_init())) { 223 res = tipc_bclink_init();
224 if (res)
289 return res; 225 return res;
290 }
291 226
292 tipc_k_signal((Handler)tipc_subscr_start, 0); 227 tipc_k_signal((Handler)tipc_subscr_start, 0);
293 tipc_k_signal((Handler)tipc_cfg_init, 0); 228 tipc_k_signal((Handler)tipc_cfg_init, 0);
294 229
295 info("Started in network mode\n"); 230 info("Started in network mode\n");
296 info("Own node address %s, network identity %u\n", 231 info("Own node address %s, network identity %u\n",
297 addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); 232 tipc_addr_string_fill(addr_string, tipc_own_addr), tipc_net_id);
298 return 0; 233 return 0;
299} 234}
300 235
@@ -308,6 +243,6 @@ void tipc_net_stop(void)
308 tipc_bclink_stop(); 243 tipc_bclink_stop();
309 net_stop(); 244 net_stop();
310 write_unlock_bh(&tipc_net_lock); 245 write_unlock_bh(&tipc_net_lock);
311 info("Left network mode \n"); 246 info("Left network mode\n");
312} 247}
313 248
diff --git a/net/tipc/net.h b/net/tipc/net.h
index de2b9ad8f646..4ae59ad04893 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -37,26 +37,26 @@
37#ifndef _TIPC_NET_H 37#ifndef _TIPC_NET_H
38#define _TIPC_NET_H 38#define _TIPC_NET_H
39 39
40struct _zone; 40struct tipc_node;
41 41
42/** 42/**
43 * struct network - TIPC network structure 43 * struct network - TIPC network structure
44 * @zones: array of pointers to all zones within network 44 * @nodes: array of pointers to all nodes within cluster
45 * @highest_node: id of highest numbered node within cluster
46 * @links: number of (unicast) links to cluster
45 */ 47 */
46 48
47struct network { 49struct network {
48 struct _zone **zones; 50 struct tipc_node **nodes;
51 u32 highest_node;
52 u32 links;
49}; 53};
50 54
51 55
52extern struct network tipc_net; 56extern struct network tipc_net;
53extern rwlock_t tipc_net_lock; 57extern rwlock_t tipc_net_lock;
54 58
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); 59void 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 60
61int tipc_net_start(u32 addr); 61int tipc_net_start(u32 addr);
62void tipc_net_stop(void); 62void tipc_net_stop(void);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 3c57005e44d1..7bda8e3d1398 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -62,7 +62,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
62 rep_nlh = nlmsg_hdr(rep_buf); 62 rep_nlh = nlmsg_hdr(rep_buf);
63 memcpy(rep_nlh, req_nlh, hdr_space); 63 memcpy(rep_nlh, req_nlh, hdr_space);
64 rep_nlh->nlmsg_len = rep_buf->len; 64 rep_nlh->nlmsg_len = rep_buf->len;
65 genlmsg_unicast(rep_buf, NETLINK_CB(skb).pid); 65 genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).pid);
66 } 66 }
67 67
68 return 0; 68 return 0;
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 2c24e7d6d950..3af53e327f49 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -37,24 +37,14 @@
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
53struct tipc_node *tipc_nodes = NULL; /* sorted list of nodes within cluster */
54
55static DEFINE_SPINLOCK(node_create_lock); 45static DEFINE_SPINLOCK(node_create_lock);
56 46
57u32 tipc_own_tag = 0; 47u32 tipc_own_tag;
58 48
59/** 49/**
60 * tipc_node_create - create neighboring node 50 * tipc_node_create - create neighboring node
@@ -68,75 +58,51 @@ u32 tipc_own_tag = 0;
68 58
69struct tipc_node *tipc_node_create(u32 addr) 59struct tipc_node *tipc_node_create(u32 addr)
70{ 60{
71 struct cluster *c_ptr;
72 struct tipc_node *n_ptr; 61 struct tipc_node *n_ptr;
73 struct tipc_node **curr_node; 62 u32 n_num;
74 63
75 spin_lock_bh(&node_create_lock); 64 spin_lock_bh(&node_create_lock);
76 65
77 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 66 n_ptr = tipc_node_find(addr);
78 if (addr < n_ptr->addr) 67 if (n_ptr) {
79 break; 68 spin_unlock_bh(&node_create_lock);
80 if (addr == n_ptr->addr) { 69 return n_ptr;
81 spin_unlock_bh(&node_create_lock);
82 return n_ptr;
83 }
84 } 70 }
85 71
86 n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); 72 n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC);
87 if (!n_ptr) { 73 if (!n_ptr) {
88 spin_unlock_bh(&node_create_lock); 74 spin_unlock_bh(&node_create_lock);
89 warn("Node creation failed, no memory\n"); 75 warn("Node creation failed, no memory\n");
90 return NULL; 76 return NULL;
91 } 77 }
92 78
93 c_ptr = tipc_cltr_find(addr);
94 if (!c_ptr) {
95 c_ptr = tipc_cltr_create(addr);
96 }
97 if (!c_ptr) {
98 spin_unlock_bh(&node_create_lock);
99 kfree(n_ptr);
100 return NULL;
101 }
102
103 n_ptr->addr = addr; 79 n_ptr->addr = addr;
104 spin_lock_init(&n_ptr->lock); 80 spin_lock_init(&n_ptr->lock);
105 INIT_LIST_HEAD(&n_ptr->nsub); 81 INIT_LIST_HEAD(&n_ptr->nsub);
106 n_ptr->owner = c_ptr; 82
107 tipc_cltr_attach_node(c_ptr, n_ptr); 83 n_num = tipc_node(addr);
108 n_ptr->last_router = -1; 84 tipc_net.nodes[n_num] = n_ptr;
109 85 if (n_num > tipc_net.highest_node)
110 /* Insert node into ordered list */ 86 tipc_net.highest_node = n_num;
111 for (curr_node = &tipc_nodes; *curr_node; 87
112 curr_node = &(*curr_node)->next) {
113 if (addr < (*curr_node)->addr) {
114 n_ptr->next = *curr_node;
115 break;
116 }
117 }
118 (*curr_node) = n_ptr;
119 spin_unlock_bh(&node_create_lock); 88 spin_unlock_bh(&node_create_lock);
120 return n_ptr; 89 return n_ptr;
121} 90}
122 91
123void tipc_node_delete(struct tipc_node *n_ptr) 92void tipc_node_delete(struct tipc_node *n_ptr)
124{ 93{
94 u32 n_num;
95
125 if (!n_ptr) 96 if (!n_ptr)
126 return; 97 return;
127 98
128#if 0 99 n_num = tipc_node(n_ptr->addr);
129 /* Not needed because links are already deleted via tipc_bearer_stop() */ 100 tipc_net.nodes[n_num] = NULL;
130
131 u32 l_num;
132
133 for (l_num = 0; l_num < MAX_BEARERS; l_num++) {
134 link_delete(n_ptr->links[l_num]);
135 }
136#endif
137
138 dbg("node %x deleted\n", n_ptr->addr);
139 kfree(n_ptr); 101 kfree(n_ptr);
102
103 while (!tipc_net.nodes[tipc_net.highest_node])
104 if (--tipc_net.highest_node == 0)
105 break;
140} 106}
141 107
142 108
@@ -156,7 +122,6 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr)
156 l_ptr->name, l_ptr->b_ptr->net_plane); 122 l_ptr->name, l_ptr->b_ptr->net_plane);
157 123
158 if (!active[0]) { 124 if (!active[0]) {
159 dbg(" link %x into %x/%x\n", l_ptr, &active[0], &active[1]);
160 active[0] = active[1] = l_ptr; 125 active[0] = active[1] = l_ptr;
161 node_established_contact(n_ptr); 126 node_established_contact(n_ptr);
162 return; 127 return;
@@ -237,23 +202,17 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr)
237 202
238int tipc_node_has_active_links(struct tipc_node *n_ptr) 203int tipc_node_has_active_links(struct tipc_node *n_ptr)
239{ 204{
240 return (n_ptr && 205 return n_ptr->active_links[0] != NULL;
241 ((n_ptr->active_links[0]) || (n_ptr->active_links[1])));
242} 206}
243 207
244int tipc_node_has_redundant_links(struct tipc_node *n_ptr) 208int tipc_node_has_redundant_links(struct tipc_node *n_ptr)
245{ 209{
246 return (n_ptr->working_links > 1); 210 return n_ptr->working_links > 1;
247}
248
249static int tipc_node_has_active_routes(struct tipc_node *n_ptr)
250{
251 return (n_ptr && (n_ptr->last_router >= 0));
252} 211}
253 212
254int tipc_node_is_up(struct tipc_node *n_ptr) 213int tipc_node_is_up(struct tipc_node *n_ptr)
255{ 214{
256 return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr)); 215 return tipc_node_has_active_links(n_ptr);
257} 216}
258 217
259struct tipc_node *tipc_node_attach_link(struct link *l_ptr) 218struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
@@ -268,19 +227,19 @@ struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
268 227
269 if (n_ptr->link_cnt >= 2) { 228 if (n_ptr->link_cnt >= 2) {
270 err("Attempt to create third link to %s\n", 229 err("Attempt to create third link to %s\n",
271 addr_string_fill(addr_string, n_ptr->addr)); 230 tipc_addr_string_fill(addr_string, n_ptr->addr));
272 return NULL; 231 return NULL;
273 } 232 }
274 233
275 if (!n_ptr->links[bearer_id]) { 234 if (!n_ptr->links[bearer_id]) {
276 n_ptr->links[bearer_id] = l_ptr; 235 n_ptr->links[bearer_id] = l_ptr;
277 tipc_net.zones[tipc_zone(l_ptr->addr)]->links++; 236 tipc_net.links++;
278 n_ptr->link_cnt++; 237 n_ptr->link_cnt++;
279 return n_ptr; 238 return n_ptr;
280 } 239 }
281 err("Attempt to establish second link on <%s> to %s \n", 240 err("Attempt to establish second link on <%s> to %s\n",
282 l_ptr->b_ptr->publ.name, 241 l_ptr->b_ptr->publ.name,
283 addr_string_fill(addr_string, l_ptr->addr)); 242 tipc_addr_string_fill(addr_string, l_ptr->addr));
284 } 243 }
285 return NULL; 244 return NULL;
286} 245}
@@ -288,7 +247,7 @@ struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
288void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr) 247void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
289{ 248{
290 n_ptr->links[l_ptr->b_ptr->identity] = NULL; 249 n_ptr->links[l_ptr->b_ptr->identity] = NULL;
291 tipc_net.zones[tipc_zone(l_ptr->addr)]->links--; 250 tipc_net.links--;
292 n_ptr->link_cnt--; 251 n_ptr->link_cnt--;
293} 252}
294 253
@@ -340,53 +299,34 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
340 299
341static void node_established_contact(struct tipc_node *n_ptr) 300static void node_established_contact(struct tipc_node *n_ptr)
342{ 301{
343 struct cluster *c_ptr; 302 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
344
345 dbg("node_established_contact:-> %x\n", n_ptr->addr);
346 if (!tipc_node_has_active_routes(n_ptr) && in_own_cluster(n_ptr->addr)) {
347 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
348 }
349 303
350 /* Syncronize broadcast acks */ 304 /* Syncronize broadcast acks */
351 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 305 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
352 306
353 if (is_slave(tipc_own_addr))
354 return;
355 if (!in_own_cluster(n_ptr->addr)) {
356 /* Usage case 1 (see above) */
357 c_ptr = tipc_cltr_find(tipc_own_addr);
358 if (!c_ptr)
359 c_ptr = tipc_cltr_create(tipc_own_addr);
360 if (c_ptr)
361 tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1,
362 tipc_max_nodes);
363 return;
364 }
365
366 c_ptr = n_ptr->owner;
367 if (is_slave(n_ptr->addr)) {
368 /* Usage case 2 (see above) */
369 tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1, tipc_max_nodes);
370 tipc_cltr_send_local_routes(c_ptr, n_ptr->addr);
371 return;
372 }
373
374 if (n_ptr->bclink.supported) { 307 if (n_ptr->bclink.supported) {
375 tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr); 308 tipc_nmap_add(&tipc_bcast_nmap, n_ptr->addr);
376 if (n_ptr->addr < tipc_own_addr) 309 if (n_ptr->addr < tipc_own_addr)
377 tipc_own_tag++; 310 tipc_own_tag++;
378 } 311 }
312}
379 313
380 /* Case 3 (see above) */ 314static void node_cleanup_finished(unsigned long node_addr)
381 tipc_net_send_external_routes(n_ptr->addr); 315{
382 tipc_cltr_send_slave_routes(c_ptr, n_ptr->addr); 316 struct tipc_node *n_ptr;
383 tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, LOWEST_SLAVE, 317
384 tipc_highest_allowed_slave); 318 read_lock_bh(&tipc_net_lock);
319 n_ptr = tipc_node_find(node_addr);
320 if (n_ptr) {
321 tipc_node_lock(n_ptr);
322 n_ptr->cleanup_required = 0;
323 tipc_node_unlock(n_ptr);
324 }
325 read_unlock_bh(&tipc_net_lock);
385} 326}
386 327
387static void node_lost_contact(struct tipc_node *n_ptr) 328static void node_lost_contact(struct tipc_node *n_ptr)
388{ 329{
389 struct cluster *c_ptr;
390 struct tipc_node_subscr *ns, *tns; 330 struct tipc_node_subscr *ns, *tns;
391 char addr_string[16]; 331 char addr_string[16];
392 u32 i; 332 u32 i;
@@ -394,7 +334,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
394 /* Clean up broadcast reception remains */ 334 /* Clean up broadcast reception remains */
395 n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0; 335 n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;
396 while (n_ptr->bclink.deferred_head) { 336 while (n_ptr->bclink.deferred_head) {
397 struct sk_buff* buf = n_ptr->bclink.deferred_head; 337 struct sk_buff *buf = n_ptr->bclink.deferred_head;
398 n_ptr->bclink.deferred_head = buf->next; 338 n_ptr->bclink.deferred_head = buf->next;
399 buf_discard(buf); 339 buf_discard(buf);
400 } 340 }
@@ -402,44 +342,17 @@ static void node_lost_contact(struct tipc_node *n_ptr)
402 buf_discard(n_ptr->bclink.defragm); 342 buf_discard(n_ptr->bclink.defragm);
403 n_ptr->bclink.defragm = NULL; 343 n_ptr->bclink.defragm = NULL;
404 } 344 }
405 if (in_own_cluster(n_ptr->addr) && n_ptr->bclink.supported) {
406 tipc_bclink_acknowledge(n_ptr, mod(n_ptr->bclink.acked + 10000));
407 }
408 345
409 /* Update routing tables */ 346 if (n_ptr->bclink.supported) {
410 if (is_slave(tipc_own_addr)) { 347 tipc_bclink_acknowledge(n_ptr,
411 tipc_net_remove_as_router(n_ptr->addr); 348 mod(n_ptr->bclink.acked + 10000));
412 } else { 349 tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);
413 if (!in_own_cluster(n_ptr->addr)) { 350 if (n_ptr->addr < tipc_own_addr)
414 /* Case 4 (see above) */ 351 tipc_own_tag--;
415 c_ptr = tipc_cltr_find(tipc_own_addr);
416 tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1,
417 tipc_max_nodes);
418 } else {
419 /* Case 5 (see above) */
420 c_ptr = tipc_cltr_find(n_ptr->addr);
421 if (is_slave(n_ptr->addr)) {
422 tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1,
423 tipc_max_nodes);
424 } else {
425 if (n_ptr->bclink.supported) {
426 tipc_nmap_remove(&tipc_cltr_bcast_nodes,
427 n_ptr->addr);
428 if (n_ptr->addr < tipc_own_addr)
429 tipc_own_tag--;
430 }
431 tipc_net_remove_as_router(n_ptr->addr);
432 tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr,
433 LOWEST_SLAVE,
434 tipc_highest_allowed_slave);
435 }
436 }
437 } 352 }
438 if (tipc_node_has_active_routes(n_ptr))
439 return;
440 353
441 info("Lost contact with %s\n", 354 info("Lost contact with %s\n",
442 addr_string_fill(addr_string, n_ptr->addr)); 355 tipc_addr_string_fill(addr_string, n_ptr->addr));
443 356
444 /* Abort link changeover */ 357 /* Abort link changeover */
445 for (i = 0; i < MAX_BEARERS; i++) { 358 for (i = 0; i < MAX_BEARERS; i++) {
@@ -458,157 +371,11 @@ static void node_lost_contact(struct tipc_node *n_ptr)
458 tipc_k_signal((Handler)ns->handle_node_down, 371 tipc_k_signal((Handler)ns->handle_node_down,
459 (unsigned long)ns->usr_handle); 372 (unsigned long)ns->usr_handle);
460 } 373 }
461}
462 374
463/** 375 /* Prevent re-contact with node until all cleanup is done */
464 * tipc_node_select_next_hop - find the next-hop node for a message
465 *
466 * Called by when cluster local lookup has failed.
467 */
468 376
469struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector) 377 n_ptr->cleanup_required = 1;
470{ 378 tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);
471 struct tipc_node *n_ptr;
472 u32 router_addr;
473
474 if (!tipc_addr_domain_valid(addr))
475 return NULL;
476
477 /* Look for direct link to destination processsor */
478 n_ptr = tipc_node_find(addr);
479 if (n_ptr && tipc_node_has_active_links(n_ptr))
480 return n_ptr;
481
482 /* Cluster local system nodes *must* have direct links */
483 if (!is_slave(addr) && in_own_cluster(addr))
484 return NULL;
485
486 /* Look for cluster local router with direct link to node */
487 router_addr = tipc_node_select_router(n_ptr, selector);
488 if (router_addr)
489 return tipc_node_select(router_addr, selector);
490
491 /* Slave nodes can only be accessed within own cluster via a
492 known router with direct link -- if no router was found,give up */
493 if (is_slave(addr))
494 return NULL;
495
496 /* Inter zone/cluster -- find any direct link to remote cluster */
497 addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
498 n_ptr = tipc_net_select_remote_node(addr, selector);
499 if (n_ptr && tipc_node_has_active_links(n_ptr))
500 return n_ptr;
501
502 /* Last resort -- look for any router to anywhere in remote zone */
503 router_addr = tipc_net_select_router(addr, selector);
504 if (router_addr)
505 return tipc_node_select(router_addr, selector);
506
507 return NULL;
508}
509
510/**
511 * tipc_node_select_router - select router to reach specified node
512 *
513 * Uses a deterministic and fair algorithm for selecting router node.
514 */
515
516u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref)
517{
518 u32 ulim;
519 u32 mask;
520 u32 start;
521 u32 r;
522
523 if (!n_ptr)
524 return 0;
525
526 if (n_ptr->last_router < 0)
527 return 0;
528 ulim = ((n_ptr->last_router + 1) * 32) - 1;
529
530 /* Start entry must be random */
531 mask = tipc_max_nodes;
532 while (mask > ulim)
533 mask >>= 1;
534 start = ref & mask;
535 r = start;
536
537 /* Lookup upwards with wrap-around */
538 do {
539 if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1)
540 break;
541 } while (++r <= ulim);
542 if (r > ulim) {
543 r = 1;
544 do {
545 if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1)
546 break;
547 } while (++r < start);
548 assert(r != start);
549 }
550 assert(r && (r <= ulim));
551 return tipc_addr(own_zone(), own_cluster(), r);
552}
553
554void tipc_node_add_router(struct tipc_node *n_ptr, u32 router)
555{
556 u32 r_num = tipc_node(router);
557
558 n_ptr->routers[r_num / 32] =
559 ((1 << (r_num % 32)) | n_ptr->routers[r_num / 32]);
560 n_ptr->last_router = tipc_max_nodes / 32;
561 while ((--n_ptr->last_router >= 0) &&
562 !n_ptr->routers[n_ptr->last_router]);
563}
564
565void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router)
566{
567 u32 r_num = tipc_node(router);
568
569 if (n_ptr->last_router < 0)
570 return; /* No routes */
571
572 n_ptr->routers[r_num / 32] =
573 ((~(1 << (r_num % 32))) & (n_ptr->routers[r_num / 32]));
574 n_ptr->last_router = tipc_max_nodes / 32;
575 while ((--n_ptr->last_router >= 0) &&
576 !n_ptr->routers[n_ptr->last_router]);
577
578 if (!tipc_node_is_up(n_ptr))
579 node_lost_contact(n_ptr);
580}
581
582#if 0
583void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str)
584{
585 u32 i;
586
587 tipc_printf(buf, "\n\n%s", str);
588 for (i = 0; i < MAX_BEARERS; i++) {
589 if (!n_ptr->links[i])
590 continue;
591 tipc_printf(buf, "Links[%u]: %x, ", i, n_ptr->links[i]);
592 }
593 tipc_printf(buf, "Active links: [%x,%x]\n",
594 n_ptr->active_links[0], n_ptr->active_links[1]);
595}
596#endif
597
598u32 tipc_available_nodes(const u32 domain)
599{
600 struct tipc_node *n_ptr;
601 u32 cnt = 0;
602
603 read_lock_bh(&tipc_net_lock);
604 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
605 if (!in_scope(domain, n_ptr->addr))
606 continue;
607 if (tipc_node_is_up(n_ptr))
608 cnt++;
609 }
610 read_unlock_bh(&tipc_net_lock);
611 return cnt;
612} 379}
613 380
614struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) 381struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
@@ -618,6 +385,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
618 struct tipc_node *n_ptr; 385 struct tipc_node *n_ptr;
619 struct tipc_node_info node_info; 386 struct tipc_node_info node_info;
620 u32 payload_size; 387 u32 payload_size;
388 u32 n_num;
621 389
622 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 390 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
623 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 391 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -628,15 +396,15 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
628 " (network address)"); 396 " (network address)");
629 397
630 read_lock_bh(&tipc_net_lock); 398 read_lock_bh(&tipc_net_lock);
631 if (!tipc_nodes) { 399 if (!tipc_net.nodes) {
632 read_unlock_bh(&tipc_net_lock); 400 read_unlock_bh(&tipc_net_lock);
633 return tipc_cfg_reply_none(); 401 return tipc_cfg_reply_none();
634 } 402 }
635 403
636 /* For now, get space for all other nodes 404 /* For now, get space for all other nodes */
637 (will need to modify this when slave nodes are supported */
638 405
639 payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); 406 payload_size = TLV_SPACE(sizeof(node_info)) *
407 (tipc_net.highest_node - 1);
640 if (payload_size > 32768u) { 408 if (payload_size > 32768u) {
641 read_unlock_bh(&tipc_net_lock); 409 read_unlock_bh(&tipc_net_lock);
642 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 410 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -650,8 +418,9 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
650 418
651 /* Add TLVs for all nodes in scope */ 419 /* Add TLVs for all nodes in scope */
652 420
653 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 421 for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) {
654 if (!in_scope(domain, n_ptr->addr)) 422 n_ptr = tipc_net.nodes[n_num];
423 if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr))
655 continue; 424 continue;
656 node_info.addr = htonl(n_ptr->addr); 425 node_info.addr = htonl(n_ptr->addr);
657 node_info.up = htonl(tipc_node_is_up(n_ptr)); 426 node_info.up = htonl(tipc_node_is_up(n_ptr));
@@ -670,6 +439,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
670 struct tipc_node *n_ptr; 439 struct tipc_node *n_ptr;
671 struct tipc_link_info link_info; 440 struct tipc_link_info link_info;
672 u32 payload_size; 441 u32 payload_size;
442 u32 n_num;
673 443
674 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 444 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
675 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 445 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -686,8 +456,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
686 456
687 /* Get space for all unicast links + multicast link */ 457 /* Get space for all unicast links + multicast link */
688 458
689 payload_size = TLV_SPACE(sizeof(link_info)) * 459 payload_size = TLV_SPACE(sizeof(link_info)) * (tipc_net.links + 1);
690 (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1);
691 if (payload_size > 32768u) { 460 if (payload_size > 32768u) {
692 read_unlock_bh(&tipc_net_lock); 461 read_unlock_bh(&tipc_net_lock);
693 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 462 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -708,10 +477,11 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
708 477
709 /* Add TLVs for any other links in scope */ 478 /* Add TLVs for any other links in scope */
710 479
711 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 480 for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) {
712 u32 i; 481 u32 i;
713 482
714 if (!in_scope(domain, n_ptr->addr)) 483 n_ptr = tipc_net.nodes[n_num];
484 if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr))
715 continue; 485 continue;
716 tipc_node_lock(n_ptr); 486 tipc_node_lock(n_ptr);
717 for (i = 0; i < MAX_BEARERS; i++) { 487 for (i = 0; i < MAX_BEARERS; i++) {
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 6f990da5d143..206a8efa410e 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -39,23 +39,21 @@
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
50 * @next: pointer to next node in sorted list of cluster's nodes 49 * @next: pointer to next node in sorted list of cluster's nodes
51 * @nsub: list of "node down" subscriptions monitoring node 50 * @nsub: list of "node down" subscriptions monitoring node
52 * @active_links: pointers to active links to node 51 * @active_links: pointers to active links to node
53 * @links: pointers to all links to node 52 * @links: pointers to all links to node
54 * @working_links: number of working links to node (both active and standby) 53 * @working_links: number of working links to node (both active and standby)
54 * @cleanup_required: non-zero if cleaning up after a prior loss of contact
55 * @link_cnt: number of links to node 55 * @link_cnt: number of links to node
56 * @permit_changeover: non-zero if node has redundant links to this system 56 * @permit_changeover: non-zero if node has redundant links to this system
57 * @routers: bitmap (used for multicluster communication)
58 * @last_router: (used for multicluster communication)
59 * @bclink: broadcast-related info 57 * @bclink: broadcast-related info
60 * @supported: non-zero if node supports TIPC b'cast capability 58 * @supported: non-zero if node supports TIPC b'cast capability
61 * @acked: sequence # of last outbound b'cast message acknowledged by node 59 * @acked: sequence # of last outbound b'cast message acknowledged by node
@@ -71,16 +69,14 @@
71struct tipc_node { 69struct tipc_node {
72 u32 addr; 70 u32 addr;
73 spinlock_t lock; 71 spinlock_t lock;
74 struct cluster *owner;
75 struct tipc_node *next; 72 struct tipc_node *next;
76 struct list_head nsub; 73 struct list_head nsub;
77 struct link *active_links[2]; 74 struct link *active_links[2];
78 struct link *links[MAX_BEARERS]; 75 struct link *links[MAX_BEARERS];
79 int link_cnt; 76 int link_cnt;
80 int working_links; 77 int working_links;
78 int cleanup_required;
81 int permit_changeover; 79 int permit_changeover;
82 u32 routers[512/32];
83 int last_router;
84 struct { 80 struct {
85 int supported; 81 int supported;
86 u32 acked; 82 u32 acked;
@@ -94,7 +90,6 @@ struct tipc_node {
94 } bclink; 90 } bclink;
95}; 91};
96 92
97extern struct tipc_node *tipc_nodes;
98extern u32 tipc_own_tag; 93extern u32 tipc_own_tag;
99 94
100struct tipc_node *tipc_node_create(u32 addr); 95struct tipc_node *tipc_node_create(u32 addr);
@@ -105,34 +100,17 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr);
105void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr); 100void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr);
106int tipc_node_has_active_links(struct tipc_node *n_ptr); 101int tipc_node_has_active_links(struct tipc_node *n_ptr);
107int tipc_node_has_redundant_links(struct tipc_node *n_ptr); 102int tipc_node_has_redundant_links(struct tipc_node *n_ptr);
108u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref);
109struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector);
110int tipc_node_is_up(struct tipc_node *n_ptr); 103int tipc_node_is_up(struct tipc_node *n_ptr);
111void tipc_node_add_router(struct tipc_node *n_ptr, u32 router);
112void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router);
113struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space); 104struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
114struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space); 105struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
115 106
116static inline struct tipc_node *tipc_node_find(u32 addr) 107static inline struct tipc_node *tipc_node_find(u32 addr)
117{ 108{
118 if (likely(in_own_cluster(addr))) 109 if (likely(in_own_cluster(addr)))
119 return tipc_local_nodes[tipc_node(addr)]; 110 return tipc_net.nodes[tipc_node(addr)];
120 else if (tipc_addr_domain_valid(addr)) {
121 struct cluster *c_ptr = tipc_cltr_find(addr);
122
123 if (c_ptr)
124 return c_ptr->nodes[tipc_node(addr)];
125 }
126 return NULL; 111 return NULL;
127} 112}
128 113
129static inline struct tipc_node *tipc_node_select(u32 addr, u32 selector)
130{
131 if (likely(in_own_cluster(addr)))
132 return tipc_local_nodes[tipc_node(addr)];
133 return tipc_node_select_next_hop(addr, selector);
134}
135
136static inline void tipc_node_lock(struct tipc_node *n_ptr) 114static inline void tipc_node_lock(struct tipc_node *n_ptr)
137{ 115{
138 spin_lock_bh(&n_ptr->lock); 116 spin_lock_bh(&n_ptr->lock);
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 19194d476a9e..018a55332d91 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -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
diff --git a/net/tipc/port.c b/net/tipc/port.c
index e70d27ea6578..067bab2a0b98 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -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,16 +46,16 @@
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 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 port *, u32 err);
66static void port_timeout(unsigned long ref); 59static void port_timeout(unsigned long ref);
67 60
68 61
@@ -94,7 +87,7 @@ static void port_incr_out_seqno(struct port *p_ptr)
94 * tipc_multicast - send a multicast message to local and remote destinations 87 * tipc_multicast - send a multicast message to local and remote destinations
95 */ 88 */
96 89
97int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain, 90int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
98 u32 num_sect, struct iovec const *msg_sect) 91 u32 num_sect, struct iovec const *msg_sect)
99{ 92{
100 struct tipc_msg *hdr; 93 struct tipc_msg *hdr;
@@ -116,7 +109,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
116 msg_set_namelower(hdr, seq->lower); 109 msg_set_namelower(hdr, seq->lower);
117 msg_set_nameupper(hdr, seq->upper); 110 msg_set_nameupper(hdr, seq->upper);
118 msg_set_hdr_sz(hdr, MCAST_H_SIZE); 111 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
119 res = msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, 112 res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
120 !oport->user_port, &buf); 113 !oport->user_port, &buf);
121 if (unlikely(!buf)) 114 if (unlikely(!buf))
122 return res; 115 return res;
@@ -138,9 +131,8 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
138 } 131 }
139 } 132 }
140 res = tipc_bclink_send_msg(buf); 133 res = tipc_bclink_send_msg(buf);
141 if ((res < 0) && (dports.count != 0)) { 134 if ((res < 0) && (dports.count != 0))
142 buf_discard(ibuf); 135 buf_discard(ibuf);
143 }
144 } else { 136 } else {
145 ibuf = buf; 137 ibuf = buf;
146 } 138 }
@@ -162,7 +154,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
162 154
163void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) 155void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
164{ 156{
165 struct tipc_msg* msg; 157 struct tipc_msg *msg;
166 struct port_list dports = {0, NULL, }; 158 struct port_list dports = {0, NULL, };
167 struct port_list *item = dp; 159 struct port_list *item = dp;
168 int cnt = 0; 160 int cnt = 0;
@@ -195,13 +187,11 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
195 187
196 if (b == NULL) { 188 if (b == NULL) {
197 warn("Unable to deliver multicast message(s)\n"); 189 warn("Unable to deliver multicast message(s)\n");
198 msg_dbg(msg, "LOST:");
199 goto exit; 190 goto exit;
200 } 191 }
201 if ((index == 0) && (cnt != 0)) { 192 if ((index == 0) && (cnt != 0))
202 item = item->next; 193 item = item->next;
203 } 194 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); 195 tipc_port_recv_msg(b);
206 } 196 }
207 } 197 }
@@ -241,13 +231,12 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
241 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 231 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT;
242 p_ptr->publ.ref = ref; 232 p_ptr->publ.ref = ref;
243 msg = &p_ptr->publ.phdr; 233 msg = &p_ptr->publ.phdr;
244 msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); 234 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
245 msg_set_origport(msg, ref); 235 msg_set_origport(msg, ref);
246 p_ptr->last_in_seqno = 41; 236 p_ptr->last_in_seqno = 41;
247 p_ptr->sent = 1; 237 p_ptr->sent = 1;
248 INIT_LIST_HEAD(&p_ptr->wait_list); 238 INIT_LIST_HEAD(&p_ptr->wait_list);
249 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 239 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
250 p_ptr->congested_link = NULL;
251 p_ptr->dispatcher = dispatcher; 240 p_ptr->dispatcher = dispatcher;
252 p_ptr->wakeup = wakeup; 241 p_ptr->wakeup = wakeup;
253 p_ptr->user_port = NULL; 242 p_ptr->user_port = NULL;
@@ -278,10 +267,7 @@ int tipc_deleteport(u32 ref)
278 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 267 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
279 tipc_nodesub_unsubscribe(&p_ptr->subscription); 268 tipc_nodesub_unsubscribe(&p_ptr->subscription);
280 } 269 }
281 if (p_ptr->user_port) { 270 kfree(p_ptr->user_port);
282 tipc_reg_remove_port(p_ptr->user_port);
283 kfree(p_ptr->user_port);
284 }
285 271
286 spin_lock_bh(&tipc_port_list_lock); 272 spin_lock_bh(&tipc_port_list_lock);
287 list_del(&p_ptr->port_list); 273 list_del(&p_ptr->port_list);
@@ -289,39 +275,10 @@ int tipc_deleteport(u32 ref)
289 spin_unlock_bh(&tipc_port_list_lock); 275 spin_unlock_bh(&tipc_port_list_lock);
290 k_term_timer(&p_ptr->timer); 276 k_term_timer(&p_ptr->timer);
291 kfree(p_ptr); 277 kfree(p_ptr);
292 dbg("Deleted port %u\n", ref);
293 tipc_net_route_msg(buf); 278 tipc_net_route_msg(buf);
294 return 0; 279 return 0;
295} 280}
296 281
297/**
298 * tipc_get_port() - return port associated with 'ref'
299 *
300 * Note: Port is not locked.
301 */
302
303struct tipc_port *tipc_get_port(const u32 ref)
304{
305 return (struct tipc_port *)tipc_ref_deref(ref);
306}
307
308/**
309 * tipc_get_handle - return user handle associated to port 'ref'
310 */
311
312void *tipc_get_handle(const u32 ref)
313{
314 struct port *p_ptr;
315 void * handle;
316
317 p_ptr = tipc_port_lock(ref);
318 if (!p_ptr)
319 return NULL;
320 handle = p_ptr->publ.usr_handle;
321 tipc_port_unlock(p_ptr);
322 return handle;
323}
324
325static int port_unreliable(struct port *p_ptr) 282static int port_unreliable(struct port *p_ptr)
326{ 283{
327 return msg_src_droppable(&p_ptr->publ.phdr); 284 return msg_src_droppable(&p_ptr->publ.phdr);
@@ -393,17 +350,16 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
393 struct sk_buff *buf; 350 struct sk_buff *buf;
394 struct tipc_msg *msg; 351 struct tipc_msg *msg;
395 352
396 buf = buf_acquire(LONG_H_SIZE); 353 buf = tipc_buf_acquire(LONG_H_SIZE);
397 if (buf) { 354 if (buf) {
398 msg = buf_msg(buf); 355 msg = buf_msg(buf);
399 msg_init(msg, usr, type, LONG_H_SIZE, destnode); 356 tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode);
400 msg_set_errcode(msg, err); 357 msg_set_errcode(msg, err);
401 msg_set_destport(msg, destport); 358 msg_set_destport(msg, destport);
402 msg_set_origport(msg, origport); 359 msg_set_origport(msg, origport);
403 msg_set_orignode(msg, orignode); 360 msg_set_orignode(msg, orignode);
404 msg_set_transp_seqno(msg, seqno); 361 msg_set_transp_seqno(msg, seqno);
405 msg_set_msgcnt(msg, ack); 362 msg_set_msgcnt(msg, ack);
406 msg_dbg(msg, "PORT>SEND>:");
407 } 363 }
408 return buf; 364 return buf;
409} 365}
@@ -421,7 +377,6 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
421 data_sz = MAX_REJECT_SIZE; 377 data_sz = MAX_REJECT_SIZE;
422 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE)) 378 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE))
423 imp++; 379 imp++;
424 msg_dbg(msg, "port->rej: ");
425 380
426 /* discard rejected message if it shouldn't be returned to sender */ 381 /* discard rejected message if it shouldn't be returned to sender */
427 if (msg_errcode(msg) || msg_dest_droppable(msg)) { 382 if (msg_errcode(msg) || msg_dest_droppable(msg)) {
@@ -434,13 +389,13 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
434 hdr_sz = MCAST_H_SIZE; 389 hdr_sz = MCAST_H_SIZE;
435 else 390 else
436 hdr_sz = LONG_H_SIZE; 391 hdr_sz = LONG_H_SIZE;
437 rbuf = buf_acquire(data_sz + hdr_sz); 392 rbuf = tipc_buf_acquire(data_sz + hdr_sz);
438 if (rbuf == NULL) { 393 if (rbuf == NULL) {
439 buf_discard(buf); 394 buf_discard(buf);
440 return data_sz; 395 return data_sz;
441 } 396 }
442 rmsg = buf_msg(rbuf); 397 rmsg = buf_msg(rbuf);
443 msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg)); 398 tipc_msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg));
444 msg_set_errcode(rmsg, err); 399 msg_set_errcode(rmsg, err);
445 msg_set_destport(rmsg, msg_origport(msg)); 400 msg_set_destport(rmsg, msg_origport(msg));
446 msg_set_origport(rmsg, msg_destport(msg)); 401 msg_set_origport(rmsg, msg_destport(msg));
@@ -481,7 +436,7 @@ int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
481 struct sk_buff *buf; 436 struct sk_buff *buf;
482 int res; 437 int res;
483 438
484 res = msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, 439 res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
485 !p_ptr->user_port, &buf); 440 !p_ptr->user_port, &buf);
486 if (!buf) 441 if (!buf)
487 return res; 442 return res;
@@ -527,7 +482,7 @@ static void port_timeout(unsigned long ref)
527static void port_handle_node_down(unsigned long ref) 482static void port_handle_node_down(unsigned long ref)
528{ 483{
529 struct port *p_ptr = tipc_port_lock(ref); 484 struct port *p_ptr = tipc_port_lock(ref);
530 struct sk_buff* buf = NULL; 485 struct sk_buff *buf = NULL;
531 486
532 if (!p_ptr) 487 if (!p_ptr)
533 return; 488 return;
@@ -584,24 +539,13 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
584 struct sk_buff *r_buf = NULL; 539 struct sk_buff *r_buf = NULL;
585 struct sk_buff *abort_buf = NULL; 540 struct sk_buff *abort_buf = NULL;
586 541
587 msg_dbg(msg, "PORT<RECV<:");
588
589 if (!p_ptr) { 542 if (!p_ptr) {
590 err = TIPC_ERR_NO_PORT; 543 err = TIPC_ERR_NO_PORT;
591 } else if (p_ptr->publ.connected) { 544 } else if (p_ptr->publ.connected) {
592 if (port_peernode(p_ptr) != msg_orignode(msg)) 545 if ((port_peernode(p_ptr) != msg_orignode(msg)) ||
546 (port_peerport(p_ptr) != msg_origport(msg))) {
593 err = TIPC_ERR_NO_PORT; 547 err = TIPC_ERR_NO_PORT;
594 if (port_peerport(p_ptr) != msg_origport(msg)) 548 } else if (msg_type(msg) == CONN_ACK) {
595 err = TIPC_ERR_NO_PORT;
596 if (!err && msg_routed(msg)) {
597 u32 seqno = msg_transp_seqno(msg);
598 u32 myno = ++p_ptr->last_in_seqno;
599 if (seqno != myno) {
600 err = TIPC_ERR_NO_PORT;
601 abort_buf = port_build_self_abort_msg(p_ptr, err);
602 }
603 }
604 if (msg_type(msg) == CONN_ACK) {
605 int wakeup = tipc_port_congested(p_ptr) && 549 int wakeup = tipc_port_congested(p_ptr) &&
606 p_ptr->publ.congested && 550 p_ptr->publ.congested &&
607 p_ptr->wakeup; 551 p_ptr->wakeup;
@@ -674,8 +618,7 @@ static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id)
674 tipc_printf(buf, " via {%u,%u}", 618 tipc_printf(buf, " via {%u,%u}",
675 p_ptr->publ.conn_type, 619 p_ptr->publ.conn_type,
676 p_ptr->publ.conn_instance); 620 p_ptr->publ.conn_instance);
677 } 621 } else if (p_ptr->publ.published) {
678 else if (p_ptr->publ.published) {
679 tipc_printf(buf, " bound to"); 622 tipc_printf(buf, " bound to");
680 list_for_each_entry(publ, &p_ptr->publications, pport_list) { 623 list_for_each_entry(publ, &p_ptr->publications, pport_list) {
681 if (publ->lower == publ->upper) 624 if (publ->lower == publ->upper)
@@ -720,50 +663,6 @@ struct sk_buff *tipc_port_get_ports(void)
720 return buf; 663 return buf;
721} 664}
722 665
723#if 0
724
725#define MAX_PORT_STATS 2000
726
727struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space)
728{
729 u32 ref;
730 struct port *p_ptr;
731 struct sk_buff *buf;
732 struct tlv_desc *rep_tlv;
733 struct print_buf pb;
734 int str_len;
735
736 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_PORT_REF))
737 return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
738
739 ref = *(u32 *)TLV_DATA(req_tlv_area);
740 ref = ntohl(ref);
741
742 p_ptr = tipc_port_lock(ref);
743 if (!p_ptr)
744 return cfg_reply_error_string("port not found");
745
746 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS));
747 if (!buf) {
748 tipc_port_unlock(p_ptr);
749 return NULL;
750 }
751 rep_tlv = (struct tlv_desc *)buf->data;
752
753 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS);
754 port_print(p_ptr, &pb, 1);
755 /* NEED TO FILL IN ADDITIONAL PORT STATISTICS HERE */
756 tipc_port_unlock(p_ptr);
757 str_len = tipc_printbuf_validate(&pb);
758
759 skb_put(buf, TLV_SPACE(str_len));
760 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
761
762 return buf;
763}
764
765#endif
766
767void tipc_port_reinit(void) 666void tipc_port_reinit(void)
768{ 667{
769 struct port *p_ptr; 668 struct port *p_ptr;
@@ -1022,12 +921,10 @@ void tipc_acknowledge(u32 ref, u32 ack)
1022} 921}
1023 922
1024/* 923/*
1025 * tipc_createport(): user level call. Will add port to 924 * tipc_createport(): user level call.
1026 * registry if non-zero user_ref.
1027 */ 925 */
1028 926
1029int tipc_createport(u32 user_ref, 927int tipc_createport(void *usr_handle,
1030 void *usr_handle,
1031 unsigned int importance, 928 unsigned int importance,
1032 tipc_msg_err_event error_cb, 929 tipc_msg_err_event error_cb,
1033 tipc_named_msg_err_event named_error_cb, 930 tipc_named_msg_err_event named_error_cb,
@@ -1054,7 +951,6 @@ int tipc_createport(u32 user_ref,
1054 } 951 }
1055 952
1056 p_ptr->user_port = up_ptr; 953 p_ptr->user_port = up_ptr;
1057 up_ptr->user_ref = user_ref;
1058 up_ptr->usr_handle = usr_handle; 954 up_ptr->usr_handle = usr_handle;
1059 up_ptr->ref = p_ptr->publ.ref; 955 up_ptr->ref = p_ptr->publ.ref;
1060 up_ptr->err_cb = error_cb; 956 up_ptr->err_cb = error_cb;
@@ -1064,20 +960,11 @@ int tipc_createport(u32 user_ref,
1064 up_ptr->named_msg_cb = named_msg_cb; 960 up_ptr->named_msg_cb = named_msg_cb;
1065 up_ptr->conn_msg_cb = conn_msg_cb; 961 up_ptr->conn_msg_cb = conn_msg_cb;
1066 up_ptr->continue_event_cb = continue_event_cb; 962 up_ptr->continue_event_cb = continue_event_cb;
1067 INIT_LIST_HEAD(&up_ptr->uport_list);
1068 tipc_reg_add_port(up_ptr);
1069 *portref = p_ptr->publ.ref; 963 *portref = p_ptr->publ.ref;
1070 tipc_port_unlock(p_ptr); 964 tipc_port_unlock(p_ptr);
1071 return 0; 965 return 0;
1072} 966}
1073 967
1074int tipc_ownidentity(u32 ref, struct tipc_portid *id)
1075{
1076 id->ref = ref;
1077 id->node = tipc_own_addr;
1078 return 0;
1079}
1080
1081int tipc_portimportance(u32 ref, unsigned int *importance) 968int tipc_portimportance(u32 ref, unsigned int *importance)
1082{ 969{
1083 struct port *p_ptr; 970 struct port *p_ptr;
@@ -1117,9 +1004,6 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1117 if (!p_ptr) 1004 if (!p_ptr)
1118 return -EINVAL; 1005 return -EINVAL;
1119 1006
1120 dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, "
1121 "lower = %u, upper = %u\n",
1122 ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);
1123 if (p_ptr->publ.connected) 1007 if (p_ptr->publ.connected)
1124 goto exit; 1008 goto exit;
1125 if (seq->lower > seq->upper) 1009 if (seq->lower > seq->upper)
@@ -1205,17 +1089,14 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1205 msg_set_origport(msg, p_ptr->publ.ref); 1089 msg_set_origport(msg, p_ptr->publ.ref);
1206 msg_set_transp_seqno(msg, 42); 1090 msg_set_transp_seqno(msg, 42);
1207 msg_set_type(msg, TIPC_CONN_MSG); 1091 msg_set_type(msg, TIPC_CONN_MSG);
1208 if (!may_route(peer->node)) 1092 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1209 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1210 else
1211 msg_set_hdr_sz(msg, LONG_H_SIZE);
1212 1093
1213 p_ptr->probing_interval = PROBING_INTERVAL; 1094 p_ptr->probing_interval = PROBING_INTERVAL;
1214 p_ptr->probing_state = CONFIRMED; 1095 p_ptr->probing_state = CONFIRMED;
1215 p_ptr->publ.connected = 1; 1096 p_ptr->publ.connected = 1;
1216 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 1097 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
1217 1098
1218 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, 1099 tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
1219 (void *)(unsigned long)ref, 1100 (void *)(unsigned long)ref,
1220 (net_ev_handler)port_handle_node_down); 1101 (net_ev_handler)port_handle_node_down);
1221 res = 0; 1102 res = 0;
@@ -1296,55 +1177,18 @@ int tipc_shutdown(u32 ref)
1296 return tipc_disconnect(ref); 1177 return tipc_disconnect(ref);
1297} 1178}
1298 1179
1299int tipc_isconnected(u32 ref, int *isconnected)
1300{
1301 struct port *p_ptr;
1302
1303 p_ptr = tipc_port_lock(ref);
1304 if (!p_ptr)
1305 return -EINVAL;
1306 *isconnected = p_ptr->publ.connected;
1307 tipc_port_unlock(p_ptr);
1308 return 0;
1309}
1310
1311int tipc_peer(u32 ref, struct tipc_portid *peer)
1312{
1313 struct port *p_ptr;
1314 int res;
1315
1316 p_ptr = tipc_port_lock(ref);
1317 if (!p_ptr)
1318 return -EINVAL;
1319 if (p_ptr->publ.connected) {
1320 peer->ref = port_peerport(p_ptr);
1321 peer->node = port_peernode(p_ptr);
1322 res = 0;
1323 } else
1324 res = -ENOTCONN;
1325 tipc_port_unlock(p_ptr);
1326 return res;
1327}
1328
1329int tipc_ref_valid(u32 ref)
1330{
1331 /* Works irrespective of type */
1332 return !!tipc_ref_deref(ref);
1333}
1334
1335
1336/* 1180/*
1337 * tipc_port_recv_sections(): Concatenate and deliver sectioned 1181 * tipc_port_recv_sections(): Concatenate and deliver sectioned
1338 * message for this node. 1182 * message for this node.
1339 */ 1183 */
1340 1184
1341int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, 1185static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
1342 struct iovec const *msg_sect) 1186 struct iovec const *msg_sect)
1343{ 1187{
1344 struct sk_buff *buf; 1188 struct sk_buff *buf;
1345 int res; 1189 int res;
1346 1190
1347 res = msg_build(&sender->publ.phdr, msg_sect, num_sect, 1191 res = tipc_msg_build(&sender->publ.phdr, msg_sect, num_sect,
1348 MAX_MSG_SIZE, !sender->user_port, &buf); 1192 MAX_MSG_SIZE, !sender->user_port, &buf);
1349 if (likely(buf)) 1193 if (likely(buf))
1350 tipc_port_recv_msg(buf); 1194 tipc_port_recv_msg(buf);
@@ -1384,76 +1228,22 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1384 if (port_unreliable(p_ptr)) { 1228 if (port_unreliable(p_ptr)) {
1385 p_ptr->publ.congested = 0; 1229 p_ptr->publ.congested = 0;
1386 /* Just calculate msg length and return */ 1230 /* Just calculate msg length and return */
1387 return msg_calc_data_size(msg_sect, num_sect); 1231 return tipc_msg_calc_data_size(msg_sect, num_sect);
1388 } 1232 }
1389 return -ELINKCONG; 1233 return -ELINKCONG;
1390} 1234}
1391 1235
1392/** 1236/**
1393 * tipc_send_buf - send message buffer on connection 1237 * tipc_send2name - send message sections to port name
1394 */
1395
1396int tipc_send_buf(u32 ref, struct sk_buff *buf, unsigned int dsz)
1397{
1398 struct port *p_ptr;
1399 struct tipc_msg *msg;
1400 u32 destnode;
1401 u32 hsz;
1402 u32 sz;
1403 u32 res;
1404
1405 p_ptr = tipc_port_deref(ref);
1406 if (!p_ptr || !p_ptr->publ.connected)
1407 return -EINVAL;
1408
1409 msg = &p_ptr->publ.phdr;
1410 hsz = msg_hdr_sz(msg);
1411 sz = hsz + dsz;
1412 msg_set_size(msg, sz);
1413 if (skb_cow(buf, hsz))
1414 return -ENOMEM;
1415
1416 skb_push(buf, hsz);
1417 skb_copy_to_linear_data(buf, msg, hsz);
1418 destnode = msg_destnode(msg);
1419 p_ptr->publ.congested = 1;
1420 if (!tipc_port_congested(p_ptr)) {
1421 if (likely(destnode != tipc_own_addr))
1422 res = tipc_send_buf_fast(buf, destnode);
1423 else {
1424 tipc_port_recv_msg(buf);
1425 res = sz;
1426 }
1427 if (likely(res != -ELINKCONG)) {
1428 port_incr_out_seqno(p_ptr);
1429 p_ptr->sent++;
1430 p_ptr->publ.congested = 0;
1431 return res;
1432 }
1433 }
1434 if (port_unreliable(p_ptr)) {
1435 p_ptr->publ.congested = 0;
1436 return dsz;
1437 }
1438 return -ELINKCONG;
1439}
1440
1441/**
1442 * tipc_forward2name - forward message sections to port name
1443 */ 1238 */
1444 1239
1445int tipc_forward2name(u32 ref, 1240int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1446 struct tipc_name const *name, 1241 unsigned int num_sect, struct iovec const *msg_sect)
1447 u32 domain,
1448 u32 num_sect,
1449 struct iovec const *msg_sect,
1450 struct tipc_portid const *orig,
1451 unsigned int importance)
1452{ 1242{
1453 struct port *p_ptr; 1243 struct port *p_ptr;
1454 struct tipc_msg *msg; 1244 struct tipc_msg *msg;
1455 u32 destnode = domain; 1245 u32 destnode = domain;
1456 u32 destport = 0; 1246 u32 destport;
1457 int res; 1247 int res;
1458 1248
1459 p_ptr = tipc_port_deref(ref); 1249 p_ptr = tipc_port_deref(ref);
@@ -1462,19 +1252,17 @@ int tipc_forward2name(u32 ref,
1462 1252
1463 msg = &p_ptr->publ.phdr; 1253 msg = &p_ptr->publ.phdr;
1464 msg_set_type(msg, TIPC_NAMED_MSG); 1254 msg_set_type(msg, TIPC_NAMED_MSG);
1465 msg_set_orignode(msg, orig->node); 1255 msg_set_orignode(msg, tipc_own_addr);
1466 msg_set_origport(msg, orig->ref); 1256 msg_set_origport(msg, ref);
1467 msg_set_hdr_sz(msg, LONG_H_SIZE); 1257 msg_set_hdr_sz(msg, LONG_H_SIZE);
1468 msg_set_nametype(msg, name->type); 1258 msg_set_nametype(msg, name->type);
1469 msg_set_nameinst(msg, name->instance); 1259 msg_set_nameinst(msg, name->instance);
1470 msg_set_lookup_scope(msg, addr_scope(domain)); 1260 msg_set_lookup_scope(msg, tipc_addr_scope(domain));
1471 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1472 msg_set_importance(msg,importance);
1473 destport = tipc_nametbl_translate(name->type, name->instance, &destnode); 1261 destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
1474 msg_set_destnode(msg, destnode); 1262 msg_set_destnode(msg, destnode);
1475 msg_set_destport(msg, destport); 1263 msg_set_destport(msg, destport);
1476 1264
1477 if (likely(destport || destnode)) { 1265 if (likely(destport)) {
1478 p_ptr->sent++; 1266 p_ptr->sent++;
1479 if (likely(destnode == tipc_own_addr)) 1267 if (likely(destnode == tipc_own_addr))
1480 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1268 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
@@ -1484,7 +1272,7 @@ int tipc_forward2name(u32 ref,
1484 return res; 1272 return res;
1485 if (port_unreliable(p_ptr)) { 1273 if (port_unreliable(p_ptr)) {
1486 /* Just calculate msg length and return */ 1274 /* Just calculate msg length and return */
1487 return msg_calc_data_size(msg_sect, num_sect); 1275 return tipc_msg_calc_data_size(msg_sect, num_sect);
1488 } 1276 }
1489 return -ELINKCONG; 1277 return -ELINKCONG;
1490 } 1278 }
@@ -1493,107 +1281,11 @@ int tipc_forward2name(u32 ref,
1493} 1281}
1494 1282
1495/** 1283/**
1496 * tipc_send2name - send message sections to port name 1284 * tipc_send2port - send message sections to port identity
1497 */
1498
1499int tipc_send2name(u32 ref,
1500 struct tipc_name const *name,
1501 unsigned int domain,
1502 unsigned int num_sect,
1503 struct iovec const *msg_sect)
1504{
1505 struct tipc_portid orig;
1506
1507 orig.ref = ref;
1508 orig.node = tipc_own_addr;
1509 return tipc_forward2name(ref, name, domain, num_sect, msg_sect, &orig,
1510 TIPC_PORT_IMPORTANCE);
1511}
1512
1513/**
1514 * tipc_forward_buf2name - forward message buffer to port name
1515 */
1516
1517int tipc_forward_buf2name(u32 ref,
1518 struct tipc_name const *name,
1519 u32 domain,
1520 struct sk_buff *buf,
1521 unsigned int dsz,
1522 struct tipc_portid const *orig,
1523 unsigned int importance)
1524{
1525 struct port *p_ptr;
1526 struct tipc_msg *msg;
1527 u32 destnode = domain;
1528 u32 destport = 0;
1529 int res;
1530
1531 p_ptr = (struct port *)tipc_ref_deref(ref);
1532 if (!p_ptr || p_ptr->publ.connected)
1533 return -EINVAL;
1534
1535 msg = &p_ptr->publ.phdr;
1536 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1537 msg_set_importance(msg, importance);
1538 msg_set_type(msg, TIPC_NAMED_MSG);
1539 msg_set_orignode(msg, orig->node);
1540 msg_set_origport(msg, orig->ref);
1541 msg_set_nametype(msg, name->type);
1542 msg_set_nameinst(msg, name->instance);
1543 msg_set_lookup_scope(msg, addr_scope(domain));
1544 msg_set_hdr_sz(msg, LONG_H_SIZE);
1545 msg_set_size(msg, LONG_H_SIZE + dsz);
1546 destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
1547 msg_set_destnode(msg, destnode);
1548 msg_set_destport(msg, destport);
1549 msg_dbg(msg, "forw2name ==> ");
1550 if (skb_cow(buf, LONG_H_SIZE))
1551 return -ENOMEM;
1552 skb_push(buf, LONG_H_SIZE);
1553 skb_copy_to_linear_data(buf, msg, LONG_H_SIZE);
1554 msg_dbg(buf_msg(buf),"PREP:");
1555 if (likely(destport || destnode)) {
1556 p_ptr->sent++;
1557 if (destnode == tipc_own_addr)
1558 return tipc_port_recv_msg(buf);
1559 res = tipc_send_buf_fast(buf, destnode);
1560 if (likely(res != -ELINKCONG))
1561 return res;
1562 if (port_unreliable(p_ptr))
1563 return dsz;
1564 return -ELINKCONG;
1565 }
1566 return tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
1567}
1568
1569/**
1570 * tipc_send_buf2name - send message buffer to port name
1571 */
1572
1573int tipc_send_buf2name(u32 ref,
1574 struct tipc_name const *dest,
1575 u32 domain,
1576 struct sk_buff *buf,
1577 unsigned int dsz)
1578{
1579 struct tipc_portid orig;
1580
1581 orig.ref = ref;
1582 orig.node = tipc_own_addr;
1583 return tipc_forward_buf2name(ref, dest, domain, buf, dsz, &orig,
1584 TIPC_PORT_IMPORTANCE);
1585}
1586
1587/**
1588 * tipc_forward2port - forward message sections to port identity
1589 */ 1285 */
1590 1286
1591int tipc_forward2port(u32 ref, 1287int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1592 struct tipc_portid const *dest, 1288 unsigned int num_sect, struct iovec const *msg_sect)
1593 unsigned int num_sect,
1594 struct iovec const *msg_sect,
1595 struct tipc_portid const *orig,
1596 unsigned int importance)
1597{ 1289{
1598 struct port *p_ptr; 1290 struct port *p_ptr;
1599 struct tipc_msg *msg; 1291 struct tipc_msg *msg;
@@ -1605,13 +1297,11 @@ int tipc_forward2port(u32 ref,
1605 1297
1606 msg = &p_ptr->publ.phdr; 1298 msg = &p_ptr->publ.phdr;
1607 msg_set_type(msg, TIPC_DIRECT_MSG); 1299 msg_set_type(msg, TIPC_DIRECT_MSG);
1608 msg_set_orignode(msg, orig->node); 1300 msg_set_orignode(msg, tipc_own_addr);
1609 msg_set_origport(msg, orig->ref); 1301 msg_set_origport(msg, ref);
1610 msg_set_destnode(msg, dest->node); 1302 msg_set_destnode(msg, dest->node);
1611 msg_set_destport(msg, dest->ref); 1303 msg_set_destport(msg, dest->ref);
1612 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1304 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1613 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1614 msg_set_importance(msg, importance);
1615 p_ptr->sent++; 1305 p_ptr->sent++;
1616 if (dest->node == tipc_own_addr) 1306 if (dest->node == tipc_own_addr)
1617 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1307 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
@@ -1620,37 +1310,17 @@ int tipc_forward2port(u32 ref,
1620 return res; 1310 return res;
1621 if (port_unreliable(p_ptr)) { 1311 if (port_unreliable(p_ptr)) {
1622 /* Just calculate msg length and return */ 1312 /* Just calculate msg length and return */
1623 return msg_calc_data_size(msg_sect, num_sect); 1313 return tipc_msg_calc_data_size(msg_sect, num_sect);
1624 } 1314 }
1625 return -ELINKCONG; 1315 return -ELINKCONG;
1626} 1316}
1627 1317
1628/** 1318/**
1629 * tipc_send2port - send message sections to port identity 1319 * tipc_send_buf2port - send message buffer to port identity
1630 */ 1320 */
1631 1321
1632int tipc_send2port(u32 ref, 1322int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1633 struct tipc_portid const *dest, 1323 struct sk_buff *buf, unsigned int dsz)
1634 unsigned int num_sect,
1635 struct iovec const *msg_sect)
1636{
1637 struct tipc_portid orig;
1638
1639 orig.ref = ref;
1640 orig.node = tipc_own_addr;
1641 return tipc_forward2port(ref, dest, num_sect, msg_sect, &orig,
1642 TIPC_PORT_IMPORTANCE);
1643}
1644
1645/**
1646 * tipc_forward_buf2port - forward message buffer to port identity
1647 */
1648int tipc_forward_buf2port(u32 ref,
1649 struct tipc_portid const *dest,
1650 struct sk_buff *buf,
1651 unsigned int dsz,
1652 struct tipc_portid const *orig,
1653 unsigned int importance)
1654{ 1324{
1655 struct port *p_ptr; 1325 struct port *p_ptr;
1656 struct tipc_msg *msg; 1326 struct tipc_msg *msg;
@@ -1662,20 +1332,17 @@ int tipc_forward_buf2port(u32 ref,
1662 1332
1663 msg = &p_ptr->publ.phdr; 1333 msg = &p_ptr->publ.phdr;
1664 msg_set_type(msg, TIPC_DIRECT_MSG); 1334 msg_set_type(msg, TIPC_DIRECT_MSG);
1665 msg_set_orignode(msg, orig->node); 1335 msg_set_orignode(msg, tipc_own_addr);
1666 msg_set_origport(msg, orig->ref); 1336 msg_set_origport(msg, ref);
1667 msg_set_destnode(msg, dest->node); 1337 msg_set_destnode(msg, dest->node);
1668 msg_set_destport(msg, dest->ref); 1338 msg_set_destport(msg, dest->ref);
1669 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1339 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1670 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1671 msg_set_importance(msg, importance);
1672 msg_set_size(msg, DIR_MSG_H_SIZE + dsz); 1340 msg_set_size(msg, DIR_MSG_H_SIZE + dsz);
1673 if (skb_cow(buf, DIR_MSG_H_SIZE)) 1341 if (skb_cow(buf, DIR_MSG_H_SIZE))
1674 return -ENOMEM; 1342 return -ENOMEM;
1675 1343
1676 skb_push(buf, DIR_MSG_H_SIZE); 1344 skb_push(buf, DIR_MSG_H_SIZE);
1677 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); 1345 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);
1678 msg_dbg(msg, "buf2port: ");
1679 p_ptr->sent++; 1346 p_ptr->sent++;
1680 if (dest->node == tipc_own_addr) 1347 if (dest->node == tipc_own_addr)
1681 return tipc_port_recv_msg(buf); 1348 return tipc_port_recv_msg(buf);
@@ -1687,20 +1354,3 @@ int tipc_forward_buf2port(u32 ref,
1687 return -ELINKCONG; 1354 return -ELINKCONG;
1688} 1355}
1689 1356
1690/**
1691 * tipc_send_buf2port - send message buffer to port identity
1692 */
1693
1694int tipc_send_buf2port(u32 ref,
1695 struct tipc_portid const *dest,
1696 struct sk_buff *buf,
1697 unsigned int dsz)
1698{
1699 struct tipc_portid orig;
1700
1701 orig.ref = ref;
1702 orig.node = tipc_own_addr;
1703 return tipc_forward_buf2port(ref, dest, buf, dsz, &orig,
1704 TIPC_PORT_IMPORTANCE);
1705}
1706
diff --git a/net/tipc/port.h b/net/tipc/port.h
index ff31ee4a1dc3..8e84b989949c 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -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,7 +92,34 @@ 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; 95};
96
97/**
98 * struct tipc_port - TIPC port info available to socket API
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
110 */
111struct tipc_port {
112 void *usr_handle;
113 spinlock_t *lock;
114 int connected;
115 u32 conn_type;
116 u32 conn_instance;
117 u32 conn_unacked;
118 int published;
119 u32 congested;
120 u32 max_pkt;
121 u32 ref;
122 struct tipc_msg phdr;
68}; 123};
69 124
70/** 125/**
@@ -75,7 +130,6 @@ struct user_port {
75 * @wakeup: ptr to routine to call when port is no longer congested 130 * @wakeup: ptr to routine to call when port is no longer congested
76 * @user_port: ptr to user port associated with port (if any) 131 * @user_port: ptr to user port associated with port (if any)
77 * @wait_list: adjacent ports in list of ports waiting on link congestion 132 * @wait_list: adjacent ports in list of ports waiting on link congestion
78 * @congested_link: ptr to congested link port is waiting on
79 * @waiting_pkts: 133 * @waiting_pkts:
80 * @sent: 134 * @sent:
81 * @acked: 135 * @acked:
@@ -95,7 +149,6 @@ struct port {
95 void (*wakeup)(struct tipc_port *); 149 void (*wakeup)(struct tipc_port *);
96 struct user_port *user_port; 150 struct user_port *user_port;
97 struct list_head wait_list; 151 struct list_head wait_list;
98 struct link *congested_link;
99 u32 waiting_pkts; 152 u32 waiting_pkts;
100 u32 sent; 153 u32 sent;
101 u32 acked; 154 u32 acked;
@@ -111,13 +164,76 @@ struct port {
111extern spinlock_t tipc_port_list_lock; 164extern spinlock_t tipc_port_list_lock;
112struct port_list; 165struct port_list;
113 166
114int tipc_port_recv_sections(struct port *p_ptr, u32 num_sect, 167/*
115 struct iovec const *msg_sect); 168 * TIPC port manipulation routines
169 */
170struct tipc_port *tipc_createport_raw(void *usr_handle,
171 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
172 void (*wakeup)(struct tipc_port *), const u32 importance);
173
174int tipc_reject_msg(struct sk_buff *buf, u32 err);
175
176int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode);
177
178void tipc_acknowledge(u32 port_ref, u32 ack);
179
180int tipc_createport(void *usr_handle,
181 unsigned int importance, tipc_msg_err_event error_cb,
182 tipc_named_msg_err_event named_error_cb,
183 tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb,
184 tipc_named_msg_event named_msg_cb,
185 tipc_conn_msg_event conn_msg_cb,
186 tipc_continue_event continue_event_cb, u32 *portref);
187
188int tipc_deleteport(u32 portref);
189
190int tipc_portimportance(u32 portref, unsigned int *importance);
191int tipc_set_portimportance(u32 portref, unsigned int importance);
192
193int tipc_portunreliable(u32 portref, unsigned int *isunreliable);
194int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
195
196int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
197int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
198
199int tipc_publish(u32 portref, unsigned int scope,
200 struct tipc_name_seq const *name_seq);
201int tipc_withdraw(u32 portref, unsigned int scope,
202 struct tipc_name_seq const *name_seq);
203
204int tipc_connect2port(u32 portref, struct tipc_portid const *port);
205
206int tipc_disconnect(u32 portref);
207
208int tipc_shutdown(u32 ref);
209
210
211/*
212 * The following routines require that the port be locked on entry
213 */
214int tipc_disconnect_port(struct tipc_port *tp_ptr);
215
216/*
217 * TIPC messaging routines
218 */
219int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect);
220
221int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
222 unsigned int num_sect, struct iovec const *msg_sect);
223
224int tipc_send2port(u32 portref, struct tipc_portid const *dest,
225 unsigned int num_sect, struct iovec const *msg_sect);
226
227int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
228 struct sk_buff *buf, unsigned int dsz);
229
230int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
231 unsigned int section_count, struct iovec const *msg);
232
116int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 233int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
117 struct iovec const *msg_sect, u32 num_sect, 234 struct iovec const *msg_sect, u32 num_sect,
118 int err); 235 int err);
119struct sk_buff *tipc_port_get_ports(void); 236struct sk_buff *tipc_port_get_ports(void);
120struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space);
121void tipc_port_recv_proto_msg(struct sk_buff *buf); 237void tipc_port_recv_proto_msg(struct sk_buff *buf);
122void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); 238void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
123void tipc_port_reinit(void); 239void tipc_port_reinit(void);
@@ -142,7 +258,7 @@ static inline void tipc_port_unlock(struct port *p_ptr)
142 spin_unlock_bh(p_ptr->publ.lock); 258 spin_unlock_bh(p_ptr->publ.lock);
143} 259}
144 260
145static inline struct port* tipc_port_deref(u32 ref) 261static inline struct port *tipc_port_deref(u32 ref)
146{ 262{
147 return (struct port *)tipc_ref_deref(ref); 263 return (struct port *)tipc_ref_deref(ref);
148} 264}
@@ -159,7 +275,7 @@ static inline u32 tipc_peer_node(struct port *p_ptr)
159 275
160static inline int tipc_port_congested(struct port *p_ptr) 276static inline int tipc_port_congested(struct port *p_ptr)
161{ 277{
162 return((p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2)); 278 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
163} 279}
164 280
165/** 281/**
@@ -200,7 +316,6 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
200 err = TIPC_ERR_NO_PORT; 316 err = TIPC_ERR_NO_PORT;
201 } 317 }
202reject: 318reject:
203 dbg("port->rejecting, err = %x..\n",err);
204 return tipc_reject_msg(buf, err); 319 return tipc_reject_msg(buf, err);
205} 320}
206 321
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 414fc34b8bea..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
@@ -153,11 +153,11 @@ void tipc_ref_table_stop(void)
153 153
154u32 tipc_ref_acquire(void *object, spinlock_t **lock) 154u32 tipc_ref_acquire(void *object, spinlock_t **lock)
155{ 155{
156 struct reference *entry;
157 u32 index; 156 u32 index;
158 u32 index_mask; 157 u32 index_mask;
159 u32 next_plus_upper; 158 u32 next_plus_upper;
160 u32 ref; 159 u32 ref;
160 struct reference *entry = NULL;
161 161
162 if (!object) { 162 if (!object) {
163 err("Attempt to acquire reference to non-existent object\n"); 163 err("Attempt to acquire reference to non-existent object\n");
@@ -175,29 +175,33 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
175 index = tipc_ref_table.first_free; 175 index = tipc_ref_table.first_free;
176 entry = &(tipc_ref_table.entries[index]); 176 entry = &(tipc_ref_table.entries[index]);
177 index_mask = tipc_ref_table.index_mask; 177 index_mask = tipc_ref_table.index_mask;
178 /* take lock in case a previous user of entry still holds it */
179 spin_lock_bh(&entry->lock);
180 next_plus_upper = entry->ref; 178 next_plus_upper = entry->ref;
181 tipc_ref_table.first_free = next_plus_upper & index_mask; 179 tipc_ref_table.first_free = next_plus_upper & index_mask;
182 ref = (next_plus_upper & ~index_mask) + index; 180 ref = (next_plus_upper & ~index_mask) + index;
183 entry->ref = ref; 181 } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
184 entry->object = object;
185 *lock = &entry->lock;
186 }
187 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
188 index = tipc_ref_table.init_point++; 182 index = tipc_ref_table.init_point++;
189 entry = &(tipc_ref_table.entries[index]); 183 entry = &(tipc_ref_table.entries[index]);
190 spin_lock_init(&entry->lock); 184 spin_lock_init(&entry->lock);
191 spin_lock_bh(&entry->lock);
192 ref = tipc_ref_table.start_mask + index; 185 ref = tipc_ref_table.start_mask + index;
186 } else {
187 ref = 0;
188 }
189 write_unlock_bh(&ref_table_lock);
190
191 /*
192 * Grab the lock so no one else can modify this entry
193 * While we assign its ref value & object pointer
194 */
195 if (entry) {
196 spin_lock_bh(&entry->lock);
193 entry->ref = ref; 197 entry->ref = ref;
194 entry->object = object; 198 entry->object = object;
195 *lock = &entry->lock; 199 *lock = &entry->lock;
200 /*
201 * keep it locked, the caller is responsible
202 * for unlocking this when they're done with it
203 */
196 } 204 }
197 else {
198 ref = 0;
199 }
200 write_unlock_bh(&ref_table_lock);
201 205
202 return ref; 206 return ref;
203} 207}
@@ -276,23 +280,6 @@ void *tipc_ref_lock(u32 ref)
276 return NULL; 280 return NULL;
277} 281}
278 282
279/**
280 * tipc_ref_unlock - unlock referenced object
281 */
282
283void tipc_ref_unlock(u32 ref)
284{
285 if (likely(tipc_ref_table.entries)) {
286 struct reference *entry;
287
288 entry = &tipc_ref_table.entries[ref &
289 tipc_ref_table.index_mask];
290 if (likely((entry->ref == ref) && (entry->object)))
291 spin_unlock_bh(&entry->lock);
292 else
293 err("Attempt to unlock non-existent reference\n");
294 }
295}
296 283
297/** 284/**
298 * tipc_ref_deref - return pointer referenced object (without locking it) 285 * tipc_ref_deref - return pointer referenced object (without locking it)
diff --git a/net/tipc/ref.h b/net/tipc/ref.h
index 7e3798ea93b9..5bc8e7ab84de 100644
--- a/net/tipc/ref.h
+++ b/net/tipc/ref.h
@@ -44,7 +44,6 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock);
44void tipc_ref_discard(u32 ref); 44void tipc_ref_discard(u32 ref);
45 45
46void *tipc_ref_lock(u32 ref); 46void *tipc_ref_lock(u32 ref);
47void tipc_ref_unlock(u32 ref);
48void *tipc_ref_deref(u32 ref); 47void *tipc_ref_deref(u32 ref);
49 48
50#endif 49#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 1848693ebb82..2b02a3a80313 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -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/slab.h>
44#include <linux/poll.h>
45#include <linux/fcntl.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 */
@@ -64,6 +52,7 @@ struct tipc_sock {
64 struct sock sk; 52 struct sock sk;
65 struct tipc_port *p; 53 struct tipc_port *p;
66 struct tipc_portid peer_name; 54 struct tipc_portid peer_name;
55 long conn_timeout;
67}; 56};
68 57
69#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 58#define tipc_sk(sk) ((struct tipc_sock *)(sk))
@@ -79,7 +68,7 @@ static const struct proto_ops msg_ops;
79 68
80static struct proto tipc_proto; 69static struct proto tipc_proto;
81 70
82static int sockets_enabled = 0; 71static int sockets_enabled;
83 72
84static atomic_t tipc_queue_size = ATOMIC_INIT(0); 73static atomic_t tipc_queue_size = ATOMIC_INIT(0);
85 74
@@ -177,6 +166,7 @@ static void reject_rx_queue(struct sock *sk)
177 * @net: network namespace (must be default network) 166 * @net: network namespace (must be default network)
178 * @sock: pre-allocated socket structure 167 * @sock: pre-allocated socket structure
179 * @protocol: protocol indicator (must be 0) 168 * @protocol: protocol indicator (must be 0)
169 * @kern: caused by kernel or by userspace?
180 * 170 *
181 * This routine creates additional data structures used by the TIPC socket, 171 * This routine creates additional data structures used by the TIPC socket,
182 * initializes them, and links them together. 172 * initializes them, and links them together.
@@ -184,7 +174,8 @@ static void reject_rx_queue(struct sock *sk)
184 * Returns 0 on success, errno otherwise 174 * Returns 0 on success, errno otherwise
185 */ 175 */
186 176
187static int tipc_create(struct net *net, struct socket *sock, int protocol) 177static int tipc_create(struct net *net, struct socket *sock, int protocol,
178 int kern)
188{ 179{
189 const struct proto_ops *ops; 180 const struct proto_ops *ops;
190 socket_state state; 181 socket_state state;
@@ -193,7 +184,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
193 184
194 /* Validate arguments */ 185 /* Validate arguments */
195 186
196 if (net != &init_net) 187 if (!net_eq(net, &init_net))
197 return -EAFNOSUPPORT; 188 return -EAFNOSUPPORT;
198 189
199 if (unlikely(protocol != 0)) 190 if (unlikely(protocol != 0))
@@ -238,9 +229,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
238 sock->state = state; 229 sock->state = state;
239 230
240 sock_init_data(sock, sk); 231 sock_init_data(sock, sk);
241 sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
242 sk->sk_backlog_rcv = backlog_rcv; 232 sk->sk_backlog_rcv = backlog_rcv;
243 tipc_sk(sk)->p = tp_ptr; 233 tipc_sk(sk)->p = tp_ptr;
234 tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
244 235
245 spin_unlock_bh(tp_ptr->lock); 236 spin_unlock_bh(tp_ptr->lock);
246 237
@@ -384,7 +375,7 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
384 * 375 *
385 * NOTE: This routine doesn't need to take the socket lock since it only 376 * NOTE: This routine doesn't need to take the socket lock since it only
386 * accesses socket information that is unchanging (or which changes in 377 * accesses socket information that is unchanging (or which changes in
387 * a completely predictable manner). 378 * a completely predictable manner).
388 */ 379 */
389 380
390static int get_name(struct socket *sock, struct sockaddr *uaddr, 381static int get_name(struct socket *sock, struct sockaddr *uaddr,
@@ -393,6 +384,7 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
393 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 384 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
394 struct tipc_sock *tsock = tipc_sk(sock->sk); 385 struct tipc_sock *tsock = tipc_sk(sock->sk);
395 386
387 memset(addr, 0, sizeof(*addr));
396 if (peer) { 388 if (peer) {
397 if ((sock->state != SS_CONNECTED) && 389 if ((sock->state != SS_CONNECTED) &&
398 ((peer != 2) || (sock->state != SS_DISCONNECTING))) 390 ((peer != 2) || (sock->state != SS_DISCONNECTING)))
@@ -400,7 +392,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
400 addr->addr.id.ref = tsock->peer_name.ref; 392 addr->addr.id.ref = tsock->peer_name.ref;
401 addr->addr.id.node = tsock->peer_name.node; 393 addr->addr.id.node = tsock->peer_name.node;
402 } else { 394 } else {
403 tipc_ownidentity(tsock->p->ref, &addr->addr.id); 395 addr->addr.id.ref = tsock->p->ref;
396 addr->addr.id.node = tipc_own_addr;
404 } 397 }
405 398
406 *uaddr_len = sizeof(*addr); 399 *uaddr_len = sizeof(*addr);
@@ -427,36 +420,55 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
427 * to handle any preventable race conditions, so TIPC will do the same ... 420 * to handle any preventable race conditions, so TIPC will do the same ...
428 * 421 *
429 * TIPC sets the returned events as follows: 422 * TIPC sets the returned events as follows:
430 * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty 423 *
431 * or if a connection-oriented socket is does not have an active connection 424 * socket state flags set
432 * (i.e. a read operation will not block). 425 * ------------ ---------
433 * b) POLLOUT is set except when a socket's connection has been terminated 426 * unconnected no read flags
434 * (i.e. a write operation will not block). 427 * no write flags
435 * c) POLLHUP is set when a socket's connection has been terminated. 428 *
436 * 429 * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue
437 * IMPORTANT: The fact that a read or write operation will not block does NOT 430 * no write flags
438 * imply that the operation will succeed! 431 *
432 * connected POLLIN/POLLRDNORM if data in rx queue
433 * POLLOUT if port is not congested
434 *
435 * disconnecting POLLIN/POLLRDNORM/POLLHUP
436 * no write flags
437 *
438 * listening POLLIN if SYN in rx queue
439 * no write flags
440 *
441 * ready POLLIN/POLLRDNORM if data in rx queue
442 * [connectionless] POLLOUT (since port cannot be congested)
443 *
444 * IMPORTANT: The fact that a read or write operation is indicated does NOT
445 * imply that the operation will succeed, merely that it should be performed
446 * and will not block.
439 */ 447 */
440 448
441static unsigned int poll(struct file *file, struct socket *sock, 449static unsigned int poll(struct file *file, struct socket *sock,
442 poll_table *wait) 450 poll_table *wait)
443{ 451{
444 struct sock *sk = sock->sk; 452 struct sock *sk = sock->sk;
445 u32 mask; 453 u32 mask = 0;
446 454
447 poll_wait(file, sk->sk_sleep, wait); 455 poll_wait(file, sk_sleep(sk), wait);
448
449 if (!skb_queue_empty(&sk->sk_receive_queue) ||
450 (sock->state == SS_UNCONNECTED) ||
451 (sock->state == SS_DISCONNECTING))
452 mask = (POLLRDNORM | POLLIN);
453 else
454 mask = 0;
455 456
456 if (sock->state == SS_DISCONNECTING) 457 switch ((int)sock->state) {
457 mask |= POLLHUP; 458 case SS_READY:
458 else 459 case SS_CONNECTED:
459 mask |= POLLOUT; 460 if (!tipc_sk_port(sk)->congested)
461 mask |= POLLOUT;
462 /* fall thru' */
463 case SS_CONNECTING:
464 case SS_LISTENING:
465 if (!skb_queue_empty(&sk->sk_receive_queue))
466 mask |= (POLLIN | POLLRDNORM);
467 break;
468 case SS_DISCONNECTING:
469 mask = (POLLIN | POLLRDNORM | POLLHUP);
470 break;
471 }
460 472
461 return mask; 473 return mask;
462} 474}
@@ -551,37 +563,35 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
551 563
552 do { 564 do {
553 if (dest->addrtype == TIPC_ADDR_NAME) { 565 if (dest->addrtype == TIPC_ADDR_NAME) {
554 if ((res = dest_name_check(dest, m))) 566 res = dest_name_check(dest, m);
567 if (res)
555 break; 568 break;
556 res = tipc_send2name(tport->ref, 569 res = tipc_send2name(tport->ref,
557 &dest->addr.name.name, 570 &dest->addr.name.name,
558 dest->addr.name.domain, 571 dest->addr.name.domain,
559 m->msg_iovlen, 572 m->msg_iovlen,
560 m->msg_iov); 573 m->msg_iov);
561 } 574 } else if (dest->addrtype == TIPC_ADDR_ID) {
562 else if (dest->addrtype == TIPC_ADDR_ID) {
563 res = tipc_send2port(tport->ref, 575 res = tipc_send2port(tport->ref,
564 &dest->addr.id, 576 &dest->addr.id,
565 m->msg_iovlen, 577 m->msg_iovlen,
566 m->msg_iov); 578 m->msg_iov);
567 } 579 } else if (dest->addrtype == TIPC_ADDR_MCAST) {
568 else if (dest->addrtype == TIPC_ADDR_MCAST) {
569 if (needs_conn) { 580 if (needs_conn) {
570 res = -EOPNOTSUPP; 581 res = -EOPNOTSUPP;
571 break; 582 break;
572 } 583 }
573 if ((res = dest_name_check(dest, m))) 584 res = dest_name_check(dest, m);
585 if (res)
574 break; 586 break;
575 res = tipc_multicast(tport->ref, 587 res = tipc_multicast(tport->ref,
576 &dest->addr.nameseq, 588 &dest->addr.nameseq,
577 0,
578 m->msg_iovlen, 589 m->msg_iovlen,
579 m->msg_iov); 590 m->msg_iov);
580 } 591 }
581 if (likely(res != -ELINKCONG)) { 592 if (likely(res != -ELINKCONG)) {
582 if (needs_conn && (res >= 0)) { 593 if (needs_conn && (res >= 0))
583 sock->state = SS_CONNECTING; 594 sock->state = SS_CONNECTING;
584 }
585 break; 595 break;
586 } 596 }
587 if (m->msg_flags & MSG_DONTWAIT) { 597 if (m->msg_flags & MSG_DONTWAIT) {
@@ -589,7 +599,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
589 break; 599 break;
590 } 600 }
591 release_sock(sk); 601 release_sock(sk);
592 res = wait_event_interruptible(*sk->sk_sleep, 602 res = wait_event_interruptible(*sk_sleep(sk),
593 !tport->congested); 603 !tport->congested);
594 lock_sock(sk); 604 lock_sock(sk);
595 if (res) 605 if (res)
@@ -640,15 +650,14 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
640 } 650 }
641 651
642 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); 652 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov);
643 if (likely(res != -ELINKCONG)) { 653 if (likely(res != -ELINKCONG))
644 break; 654 break;
645 }
646 if (m->msg_flags & MSG_DONTWAIT) { 655 if (m->msg_flags & MSG_DONTWAIT) {
647 res = -EWOULDBLOCK; 656 res = -EWOULDBLOCK;
648 break; 657 break;
649 } 658 }
650 release_sock(sk); 659 release_sock(sk);
651 res = wait_event_interruptible(*sk->sk_sleep, 660 res = wait_event_interruptible(*sk_sleep(sk),
652 (!tport->congested || !tport->connected)); 661 (!tport->congested || !tport->connected));
653 lock_sock(sk); 662 lock_sock(sk);
654 if (res) 663 if (res)
@@ -741,7 +750,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
741 bytes_to_send = curr_left; 750 bytes_to_send = curr_left;
742 my_iov.iov_base = curr_start; 751 my_iov.iov_base = curr_start;
743 my_iov.iov_len = bytes_to_send; 752 my_iov.iov_len = bytes_to_send;
744 if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) { 753 res = send_packet(NULL, sock, &my_msg, 0);
754 if (res < 0) {
745 if (bytes_sent) 755 if (bytes_sent)
746 res = bytes_sent; 756 res = bytes_sent;
747 goto exit; 757 goto exit;
@@ -801,8 +811,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
801 addr->addrtype = TIPC_ADDR_ID; 811 addr->addrtype = TIPC_ADDR_ID;
802 addr->addr.id.ref = msg_origport(msg); 812 addr->addr.id.ref = msg_origport(msg);
803 addr->addr.id.node = msg_orignode(msg); 813 addr->addr.id.node = msg_orignode(msg);
804 addr->addr.name.domain = 0; /* could leave uninitialized */ 814 addr->addr.name.domain = 0; /* could leave uninitialized */
805 addr->scope = 0; /* could leave uninitialized */ 815 addr->scope = 0; /* could leave uninitialized */
806 m->msg_namelen = sizeof(struct sockaddr_tipc); 816 m->msg_namelen = sizeof(struct sockaddr_tipc);
807 } 817 }
808} 818}
@@ -836,12 +846,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
836 if (unlikely(err)) { 846 if (unlikely(err)) {
837 anc_data[0] = err; 847 anc_data[0] = err;
838 anc_data[1] = msg_data_sz(msg); 848 anc_data[1] = msg_data_sz(msg);
839 if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data))) 849 res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data);
840 return res; 850 if (res)
841 if (anc_data[1] &&
842 (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
843 msg_data(msg))))
844 return res; 851 return res;
852 if (anc_data[1]) {
853 res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
854 msg_data(msg));
855 if (res)
856 return res;
857 }
845 } 858 }
846 859
847 /* Optionally capture message destination object */ 860 /* Optionally capture message destination object */
@@ -869,9 +882,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
869 default: 882 default:
870 has_name = 0; 883 has_name = 0;
871 } 884 }
872 if (has_name && 885 if (has_name) {
873 (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data))) 886 res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data);
874 return res; 887 if (res)
888 return res;
889 }
875 890
876 return 0; 891 return 0;
877} 892}
@@ -929,7 +944,7 @@ restart:
929 goto exit; 944 goto exit;
930 } 945 }
931 release_sock(sk); 946 release_sock(sk);
932 res = wait_event_interruptible(*sk->sk_sleep, 947 res = wait_event_interruptible(*sk_sleep(sk),
933 (!skb_queue_empty(&sk->sk_receive_queue) || 948 (!skb_queue_empty(&sk->sk_receive_queue) ||
934 (sock->state == SS_DISCONNECTING))); 949 (sock->state == SS_DISCONNECTING)));
935 lock_sock(sk); 950 lock_sock(sk);
@@ -1024,9 +1039,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1024 struct sk_buff *buf; 1039 struct sk_buff *buf;
1025 struct tipc_msg *msg; 1040 struct tipc_msg *msg;
1026 unsigned int sz; 1041 unsigned int sz;
1027 int sz_to_copy; 1042 int sz_to_copy, target, needed;
1028 int sz_copied = 0; 1043 int sz_copied = 0;
1029 int needed;
1030 char __user *crs = m->msg_iov->iov_base; 1044 char __user *crs = m->msg_iov->iov_base;
1031 unsigned char *buf_crs; 1045 unsigned char *buf_crs;
1032 u32 err; 1046 u32 err;
@@ -1048,6 +1062,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1048 goto exit; 1062 goto exit;
1049 } 1063 }
1050 1064
1065 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1066
1051restart: 1067restart:
1052 1068
1053 /* Look for a message in receive queue; wait if necessary */ 1069 /* Look for a message in receive queue; wait if necessary */
@@ -1062,7 +1078,7 @@ restart:
1062 goto exit; 1078 goto exit;
1063 } 1079 }
1064 release_sock(sk); 1080 release_sock(sk);
1065 res = wait_event_interruptible(*sk->sk_sleep, 1081 res = wait_event_interruptible(*sk_sleep(sk),
1066 (!skb_queue_empty(&sk->sk_receive_queue) || 1082 (!skb_queue_empty(&sk->sk_receive_queue) ||
1067 (sock->state == SS_DISCONNECTING))); 1083 (sock->state == SS_DISCONNECTING)));
1068 lock_sock(sk); 1084 lock_sock(sk);
@@ -1134,13 +1150,11 @@ restart:
1134 1150
1135 /* Loop around if more data is required */ 1151 /* Loop around if more data is required */
1136 1152
1137 if ((sz_copied < buf_len) /* didn't get all requested data */ 1153 if ((sz_copied < buf_len) && /* didn't get all requested data */
1138 && (!skb_queue_empty(&sk->sk_receive_queue) || 1154 (!skb_queue_empty(&sk->sk_receive_queue) ||
1139 (flags & MSG_WAITALL)) 1155 (sz_copied < target)) && /* and more is ready or required */
1140 /* ... and more is ready or required */ 1156 (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */
1141 && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ 1157 (!err)) /* and haven't reached a FIN */
1142 && (!err) /* ... and haven't reached a FIN */
1143 )
1144 goto restart; 1158 goto restart;
1145 1159
1146exit: 1160exit:
@@ -1174,7 +1188,7 @@ static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base)
1174 if (msg_connected(msg)) 1188 if (msg_connected(msg))
1175 threshold *= 4; 1189 threshold *= 4;
1176 1190
1177 return (queue_size >= threshold); 1191 return queue_size >= threshold;
1178} 1192}
1179 1193
1180/** 1194/**
@@ -1205,42 +1219,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1205 */ 1219 */
1206 1220
1207 if (sock->state == SS_READY) { 1221 if (sock->state == SS_READY) {
1208 if (msg_connected(msg)) { 1222 if (msg_connected(msg))
1209 msg_dbg(msg, "dispatch filter 1\n");
1210 return TIPC_ERR_NO_PORT; 1223 return TIPC_ERR_NO_PORT;
1211 }
1212 } else { 1224 } else {
1213 if (msg_mcast(msg)) { 1225 if (msg_mcast(msg))
1214 msg_dbg(msg, "dispatch filter 2\n");
1215 return TIPC_ERR_NO_PORT; 1226 return TIPC_ERR_NO_PORT;
1216 }
1217 if (sock->state == SS_CONNECTED) { 1227 if (sock->state == SS_CONNECTED) {
1218 if (!msg_connected(msg)) { 1228 if (!msg_connected(msg))
1219 msg_dbg(msg, "dispatch filter 3\n");
1220 return TIPC_ERR_NO_PORT; 1229 return TIPC_ERR_NO_PORT;
1221 } 1230 } else if (sock->state == SS_CONNECTING) {
1222 } 1231 if (!msg_connected(msg) && (msg_errcode(msg) == 0))
1223 else if (sock->state == SS_CONNECTING) {
1224 if (!msg_connected(msg) && (msg_errcode(msg) == 0)) {
1225 msg_dbg(msg, "dispatch filter 4\n");
1226 return TIPC_ERR_NO_PORT; 1232 return TIPC_ERR_NO_PORT;
1227 } 1233 } else if (sock->state == SS_LISTENING) {
1228 } 1234 if (msg_connected(msg) || msg_errcode(msg))
1229 else if (sock->state == SS_LISTENING) {
1230 if (msg_connected(msg) || msg_errcode(msg)) {
1231 msg_dbg(msg, "dispatch filter 5\n");
1232 return TIPC_ERR_NO_PORT; 1235 return TIPC_ERR_NO_PORT;
1233 } 1236 } else if (sock->state == SS_DISCONNECTING) {
1234 }
1235 else if (sock->state == SS_DISCONNECTING) {
1236 msg_dbg(msg, "dispatch filter 6\n");
1237 return TIPC_ERR_NO_PORT; 1237 return TIPC_ERR_NO_PORT;
1238 } 1238 } else /* (sock->state == SS_UNCONNECTED) */ {
1239 else /* (sock->state == SS_UNCONNECTED) */ { 1239 if (msg_connected(msg) || msg_errcode(msg))
1240 if (msg_connected(msg) || msg_errcode(msg)) {
1241 msg_dbg(msg, "dispatch filter 7\n");
1242 return TIPC_ERR_NO_PORT; 1240 return TIPC_ERR_NO_PORT;
1243 }
1244 } 1241 }
1245 } 1242 }
1246 1243
@@ -1259,7 +1256,6 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1259 1256
1260 /* Enqueue message (finally!) */ 1257 /* Enqueue message (finally!) */
1261 1258
1262 msg_dbg(msg, "<DISP<: ");
1263 TIPC_SKB_CB(buf)->handle = msg_data(msg); 1259 TIPC_SKB_CB(buf)->handle = msg_data(msg);
1264 atomic_inc(&tipc_queue_size); 1260 atomic_inc(&tipc_queue_size);
1265 __skb_queue_tail(&sk->sk_receive_queue, buf); 1261 __skb_queue_tail(&sk->sk_receive_queue, buf);
@@ -1271,8 +1267,8 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1271 tipc_disconnect_port(tipc_sk_port(sk)); 1267 tipc_disconnect_port(tipc_sk_port(sk));
1272 } 1268 }
1273 1269
1274 if (waitqueue_active(sk->sk_sleep)) 1270 if (waitqueue_active(sk_sleep(sk)))
1275 wake_up_interruptible(sk->sk_sleep); 1271 wake_up_interruptible(sk_sleep(sk));
1276 return TIPC_OK; 1272 return TIPC_OK;
1277} 1273}
1278 1274
@@ -1322,8 +1318,10 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
1322 if (!sock_owned_by_user(sk)) { 1318 if (!sock_owned_by_user(sk)) {
1323 res = filter_rcv(sk, buf); 1319 res = filter_rcv(sk, buf);
1324 } else { 1320 } else {
1325 sk_add_backlog(sk, buf); 1321 if (sk_add_backlog(sk, buf))
1326 res = TIPC_OK; 1322 res = TIPC_ERR_OVERLOAD;
1323 else
1324 res = TIPC_OK;
1327 } 1325 }
1328 bh_unlock_sock(sk); 1326 bh_unlock_sock(sk);
1329 1327
@@ -1341,8 +1339,8 @@ static void wakeupdispatch(struct tipc_port *tport)
1341{ 1339{
1342 struct sock *sk = (struct sock *)tport->usr_handle; 1340 struct sock *sk = (struct sock *)tport->usr_handle;
1343 1341
1344 if (waitqueue_active(sk->sk_sleep)) 1342 if (waitqueue_active(sk_sleep(sk)))
1345 wake_up_interruptible(sk->sk_sleep); 1343 wake_up_interruptible(sk_sleep(sk));
1346} 1344}
1347 1345
1348/** 1346/**
@@ -1363,6 +1361,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1363 struct msghdr m = {NULL,}; 1361 struct msghdr m = {NULL,};
1364 struct sk_buff *buf; 1362 struct sk_buff *buf;
1365 struct tipc_msg *msg; 1363 struct tipc_msg *msg;
1364 long timeout;
1366 int res; 1365 int res;
1367 1366
1368 lock_sock(sk); 1367 lock_sock(sk);
@@ -1377,7 +1376,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1377 /* For now, TIPC does not support the non-blocking form of connect() */ 1376 /* For now, TIPC does not support the non-blocking form of connect() */
1378 1377
1379 if (flags & O_NONBLOCK) { 1378 if (flags & O_NONBLOCK) {
1380 res = -EWOULDBLOCK; 1379 res = -EOPNOTSUPP;
1381 goto exit; 1380 goto exit;
1382 } 1381 }
1383 1382
@@ -1417,17 +1416,17 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1417 m.msg_name = dest; 1416 m.msg_name = dest;
1418 m.msg_namelen = destlen; 1417 m.msg_namelen = destlen;
1419 res = send_msg(NULL, sock, &m, 0); 1418 res = send_msg(NULL, sock, &m, 0);
1420 if (res < 0) { 1419 if (res < 0)
1421 goto exit; 1420 goto exit;
1422 }
1423 1421
1424 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ 1422 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
1425 1423
1424 timeout = tipc_sk(sk)->conn_timeout;
1426 release_sock(sk); 1425 release_sock(sk);
1427 res = wait_event_interruptible_timeout(*sk->sk_sleep, 1426 res = wait_event_interruptible_timeout(*sk_sleep(sk),
1428 (!skb_queue_empty(&sk->sk_receive_queue) || 1427 (!skb_queue_empty(&sk->sk_receive_queue) ||
1429 (sock->state != SS_CONNECTING)), 1428 (sock->state != SS_CONNECTING)),
1430 sk->sk_rcvtimeo); 1429 timeout ? timeout : MAX_SCHEDULE_TIMEOUT);
1431 lock_sock(sk); 1430 lock_sock(sk);
1432 1431
1433 if (res > 0) { 1432 if (res > 0) {
@@ -1440,11 +1439,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1440 advance_rx_queue(sk); 1439 advance_rx_queue(sk);
1441 } 1440 }
1442 } else { 1441 } else {
1443 if (sock->state == SS_CONNECTED) { 1442 if (sock->state == SS_CONNECTED)
1444 res = -EISCONN; 1443 res = -EISCONN;
1445 } else { 1444 else
1446 res = -ECONNREFUSED; 1445 res = -ECONNREFUSED;
1447 }
1448 } 1446 }
1449 } else { 1447 } else {
1450 if (res == 0) 1448 if (res == 0)
@@ -1519,7 +1517,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1519 goto exit; 1517 goto exit;
1520 } 1518 }
1521 release_sock(sk); 1519 release_sock(sk);
1522 res = wait_event_interruptible(*sk->sk_sleep, 1520 res = wait_event_interruptible(*sk_sleep(sk),
1523 (!skb_queue_empty(&sk->sk_receive_queue))); 1521 (!skb_queue_empty(&sk->sk_receive_queue)));
1524 lock_sock(sk); 1522 lock_sock(sk);
1525 if (res) 1523 if (res)
@@ -1528,7 +1526,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1528 1526
1529 buf = skb_peek(&sk->sk_receive_queue); 1527 buf = skb_peek(&sk->sk_receive_queue);
1530 1528
1531 res = tipc_create(sock_net(sock->sk), new_sock, 0); 1529 res = tipc_create(sock_net(sock->sk), new_sock, 0, 0);
1532 if (!res) { 1530 if (!res) {
1533 struct sock *new_sk = new_sock->sk; 1531 struct sock *new_sk = new_sock->sk;
1534 struct tipc_sock *new_tsock = tipc_sk(new_sk); 1532 struct tipc_sock *new_tsock = tipc_sk(new_sk);
@@ -1563,7 +1561,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1563 * Respond to 'SYN+' by queuing it on new socket. 1561 * Respond to 'SYN+' by queuing it on new socket.
1564 */ 1562 */
1565 1563
1566 msg_dbg(msg,"<ACC<: ");
1567 if (!msg_data_sz(msg)) { 1564 if (!msg_data_sz(msg)) {
1568 struct msghdr m = {NULL,}; 1565 struct msghdr m = {NULL,};
1569 1566
@@ -1630,8 +1627,8 @@ restart:
1630 /* Discard any unreceived messages; wake up sleeping tasks */ 1627 /* Discard any unreceived messages; wake up sleeping tasks */
1631 1628
1632 discard_rx_queue(sk); 1629 discard_rx_queue(sk);
1633 if (waitqueue_active(sk->sk_sleep)) 1630 if (waitqueue_active(sk_sleep(sk)))
1634 wake_up_interruptible(sk->sk_sleep); 1631 wake_up_interruptible(sk_sleep(sk));
1635 res = 0; 1632 res = 0;
1636 break; 1633 break;
1637 1634
@@ -1658,7 +1655,7 @@ restart:
1658 */ 1655 */
1659 1656
1660static int setsockopt(struct socket *sock, 1657static int setsockopt(struct socket *sock,
1661 int lvl, int opt, char __user *ov, int ol) 1658 int lvl, int opt, char __user *ov, unsigned int ol)
1662{ 1659{
1663 struct sock *sk = sock->sk; 1660 struct sock *sk = sock->sk;
1664 struct tipc_port *tport = tipc_sk_port(sk); 1661 struct tipc_port *tport = tipc_sk_port(sk);
@@ -1671,7 +1668,8 @@ static int setsockopt(struct socket *sock,
1671 return -ENOPROTOOPT; 1668 return -ENOPROTOOPT;
1672 if (ol < sizeof(value)) 1669 if (ol < sizeof(value))
1673 return -EINVAL; 1670 return -EINVAL;
1674 if ((res = get_user(value, (u32 __user *)ov))) 1671 res = get_user(value, (u32 __user *)ov);
1672 if (res)
1675 return res; 1673 return res;
1676 1674
1677 lock_sock(sk); 1675 lock_sock(sk);
@@ -1690,7 +1688,7 @@ static int setsockopt(struct socket *sock,
1690 res = tipc_set_portunreturnable(tport->ref, value); 1688 res = tipc_set_portunreturnable(tport->ref, value);
1691 break; 1689 break;
1692 case TIPC_CONN_TIMEOUT: 1690 case TIPC_CONN_TIMEOUT:
1693 sk->sk_rcvtimeo = msecs_to_jiffies(value); 1691 tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value);
1694 /* no need to set "res", since already 0 at this point */ 1692 /* no need to set "res", since already 0 at this point */
1695 break; 1693 break;
1696 default: 1694 default:
@@ -1729,7 +1727,8 @@ static int getsockopt(struct socket *sock,
1729 return put_user(0, ol); 1727 return put_user(0, ol);
1730 if (lvl != SOL_TIPC) 1728 if (lvl != SOL_TIPC)
1731 return -ENOPROTOOPT; 1729 return -ENOPROTOOPT;
1732 if ((res = get_user(len, ol))) 1730 res = get_user(len, ol);
1731 if (res)
1733 return res; 1732 return res;
1734 1733
1735 lock_sock(sk); 1734 lock_sock(sk);
@@ -1745,29 +1744,31 @@ static int getsockopt(struct socket *sock,
1745 res = tipc_portunreturnable(tport->ref, &value); 1744 res = tipc_portunreturnable(tport->ref, &value);
1746 break; 1745 break;
1747 case TIPC_CONN_TIMEOUT: 1746 case TIPC_CONN_TIMEOUT:
1748 value = jiffies_to_msecs(sk->sk_rcvtimeo); 1747 value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout);
1749 /* no need to set "res", since already 0 at this point */ 1748 /* no need to set "res", since already 0 at this point */
1750 break; 1749 break;
1750 case TIPC_NODE_RECVQ_DEPTH:
1751 value = (u32)atomic_read(&tipc_queue_size);
1752 break;
1753 case TIPC_SOCK_RECVQ_DEPTH:
1754 value = skb_queue_len(&sk->sk_receive_queue);
1755 break;
1751 default: 1756 default:
1752 res = -EINVAL; 1757 res = -EINVAL;
1753 } 1758 }
1754 1759
1755 release_sock(sk); 1760 release_sock(sk);
1756 1761
1757 if (res) { 1762 if (res)
1758 /* "get" failed */ 1763 return res; /* "get" failed */
1759 }
1760 else if (len < sizeof(value)) {
1761 res = -EINVAL;
1762 }
1763 else if (copy_to_user(ov, &value, sizeof(value))) {
1764 res = -EFAULT;
1765 }
1766 else {
1767 res = put_user(sizeof(value), ol);
1768 }
1769 1764
1770 return res; 1765 if (len < sizeof(value))
1766 return -EINVAL;
1767
1768 if (copy_to_user(ov, &value, sizeof(value)))
1769 return -EFAULT;
1770
1771 return put_user(sizeof(value), ol);
1771} 1772}
1772 1773
1773/** 1774/**
@@ -1775,7 +1776,7 @@ static int getsockopt(struct socket *sock,
1775 */ 1776 */
1776 1777
1777static const struct proto_ops msg_ops = { 1778static const struct proto_ops msg_ops = {
1778 .owner = THIS_MODULE, 1779 .owner = THIS_MODULE,
1779 .family = AF_TIPC, 1780 .family = AF_TIPC,
1780 .release = release, 1781 .release = release,
1781 .bind = bind, 1782 .bind = bind,
@@ -1796,7 +1797,7 @@ static const struct proto_ops msg_ops = {
1796}; 1797};
1797 1798
1798static const struct proto_ops packet_ops = { 1799static const struct proto_ops packet_ops = {
1799 .owner = THIS_MODULE, 1800 .owner = THIS_MODULE,
1800 .family = AF_TIPC, 1801 .family = AF_TIPC,
1801 .release = release, 1802 .release = release,
1802 .bind = bind, 1803 .bind = bind,
@@ -1817,7 +1818,7 @@ static const struct proto_ops packet_ops = {
1817}; 1818};
1818 1819
1819static const struct proto_ops stream_ops = { 1820static const struct proto_ops stream_ops = {
1820 .owner = THIS_MODULE, 1821 .owner = THIS_MODULE,
1821 .family = AF_TIPC, 1822 .family = AF_TIPC,
1822 .release = release, 1823 .release = release,
1823 .bind = bind, 1824 .bind = bind,
@@ -1838,7 +1839,7 @@ static const struct proto_ops stream_ops = {
1838}; 1839};
1839 1840
1840static const struct net_proto_family tipc_family_ops = { 1841static const struct net_proto_family tipc_family_ops = {
1841 .owner = THIS_MODULE, 1842 .owner = THIS_MODULE,
1842 .family = AF_TIPC, 1843 .family = AF_TIPC,
1843 .create = tipc_create 1844 .create = tipc_create
1844}; 1845};
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 0747d8a9232f..ca04479c3d42 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -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
@@ -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
@@ -364,9 +357,9 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
364 sub->seq.upper = htohl(s->seq.upper, swap); 357 sub->seq.upper = htohl(s->seq.upper, swap);
365 sub->timeout = htohl(s->timeout, swap); 358 sub->timeout = htohl(s->timeout, swap);
366 sub->filter = htohl(s->filter, swap); 359 sub->filter = htohl(s->filter, swap);
367 if ((!(sub->filter & TIPC_SUB_PORTS) 360 if ((!(sub->filter & TIPC_SUB_PORTS) ==
368 == !(sub->filter & TIPC_SUB_SERVICE)) 361 !(sub->filter & TIPC_SUB_SERVICE)) ||
369 || (sub->seq.lower > sub->seq.upper)) { 362 (sub->seq.lower > sub->seq.upper)) {
370 warn("Subscription rejected, illegal request\n"); 363 warn("Subscription rejected, illegal request\n");
371 kfree(sub); 364 kfree(sub);
372 subscr_terminate(subscriber); 365 subscr_terminate(subscriber);
@@ -496,8 +489,7 @@ static void subscr_named_msg_event(void *usr_handle,
496 489
497 /* Create server port & establish connection to subscriber */ 490 /* Create server port & establish connection to subscriber */
498 491
499 tipc_createport(topsrv.user_ref, 492 tipc_createport(subscriber,
500 subscriber,
501 importance, 493 importance,
502 NULL, 494 NULL,
503 NULL, 495 NULL,
@@ -544,21 +536,14 @@ static void subscr_named_msg_event(void *usr_handle,
544int tipc_subscr_start(void) 536int tipc_subscr_start(void)
545{ 537{
546 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV}; 538 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV};
547 int res = -1; 539 int res;
548 540
549 memset(&topsrv, 0, sizeof (topsrv)); 541 memset(&topsrv, 0, sizeof(topsrv));
550 spin_lock_init(&topsrv.lock); 542 spin_lock_init(&topsrv.lock);
551 INIT_LIST_HEAD(&topsrv.subscriber_list); 543 INIT_LIST_HEAD(&topsrv.subscriber_list);
552 544
553 spin_lock_bh(&topsrv.lock); 545 spin_lock_bh(&topsrv.lock);
554 res = tipc_attach(&topsrv.user_ref, NULL, NULL); 546 res = tipc_createport(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, 547 TIPC_CRITICAL_IMPORTANCE,
563 NULL, 548 NULL,
564 NULL, 549 NULL,
@@ -572,16 +557,17 @@ int tipc_subscr_start(void)
572 goto failed; 557 goto failed;
573 558
574 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq); 559 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
575 if (res) 560 if (res) {
561 tipc_deleteport(topsrv.setup_port);
562 topsrv.setup_port = 0;
576 goto failed; 563 goto failed;
564 }
577 565
578 spin_unlock_bh(&topsrv.lock); 566 spin_unlock_bh(&topsrv.lock);
579 return 0; 567 return 0;
580 568
581failed: 569failed:
582 err("Failed to create subscription service\n"); 570 err("Failed to create subscription service\n");
583 tipc_detach(topsrv.user_ref);
584 topsrv.user_ref = 0;
585 spin_unlock_bh(&topsrv.lock); 571 spin_unlock_bh(&topsrv.lock);
586 return res; 572 return res;
587} 573}
@@ -592,8 +578,10 @@ void tipc_subscr_stop(void)
592 struct subscriber *subscriber_temp; 578 struct subscriber *subscriber_temp;
593 spinlock_t *subscriber_lock; 579 spinlock_t *subscriber_lock;
594 580
595 if (topsrv.user_ref) { 581 if (topsrv.setup_port) {
596 tipc_deleteport(topsrv.setup_port); 582 tipc_deleteport(topsrv.setup_port);
583 topsrv.setup_port = 0;
584
597 list_for_each_entry_safe(subscriber, subscriber_temp, 585 list_for_each_entry_safe(subscriber, subscriber_temp,
598 &topsrv.subscriber_list, 586 &topsrv.subscriber_list,
599 subscriber_list) { 587 subscriber_list) {
@@ -602,16 +590,5 @@ void tipc_subscr_stop(void)
602 subscr_terminate(subscriber); 590 subscr_terminate(subscriber);
603 spin_unlock_bh(subscriber_lock); 591 spin_unlock_bh(subscriber_lock);
604 } 592 }
605 tipc_detach(topsrv.user_ref);
606 topsrv.user_ref = 0;
607 } 593 }
608} 594}
609
610
611int tipc_ispublished(struct tipc_name const *name)
612{
613 u32 domain = 0;
614
615 return(tipc_nametbl_translate(name->type, name->instance,&domain) != 0);
616}
617
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 2c01ba2d86bf..000000000000
--- a/net/tipc/zone.c
+++ /dev/null
@@ -1,173 +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}
163
164
165u32 tipc_zone_next_node(u32 addr)
166{
167 struct cluster *c_ptr = tipc_cltr_find(addr);
168
169 if (c_ptr)
170 return tipc_cltr_next_node(c_ptr, addr);
171 return 0;
172}
173
diff --git a/net/tipc/zone.h b/net/tipc/zone.h
deleted file mode 100644
index 7bdc3406ba9b..000000000000
--- a/net/tipc/zone.h
+++ /dev/null
@@ -1,71 +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);
64u32 tipc_zone_next_node(u32 addr);
65
66static inline struct _zone *tipc_zone_find(u32 addr)
67{
68 return tipc_net.zones[tipc_zone(addr)];
69}
70
71#endif