aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/Kconfig47
-rw-r--r--net/tipc/Makefile4
-rw-r--r--net/tipc/addr.c32
-rw-r--r--net/tipc/addr.h31
-rw-r--r--net/tipc/bcast.c168
-rw-r--r--net/tipc/bcast.h7
-rw-r--r--net/tipc/bearer.c201
-rw-r--r--net/tipc/bearer.h102
-rw-r--r--net/tipc/cluster.c576
-rw-r--r--net/tipc/cluster.h92
-rw-r--r--net/tipc/config.c297
-rw-r--r--net/tipc/config.h7
-rw-r--r--net/tipc/core.c151
-rw-r--r--net/tipc/core.h87
-rw-r--r--net/tipc/discover.c326
-rw-r--r--net/tipc/discover.h23
-rw-r--r--net/tipc/eth_media.c63
-rw-r--r--net/tipc/handler.c2
-rw-r--r--net/tipc/link.c789
-rw-r--r--net/tipc/link.h62
-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.c127
-rw-r--r--net/tipc/msg.h328
-rw-r--r--net/tipc/name_distr.c61
-rw-r--r--net/tipc/name_table.c127
-rw-r--r--net/tipc/name_table.h2
-rw-r--r--net/tipc/net.c86
-rw-r--r--net/tipc/net.h19
-rw-r--r--net/tipc/node.c421
-rw-r--r--net/tipc/node.h64
-rw-r--r--net/tipc/node_subscr.c23
-rw-r--r--net/tipc/node_subscr.h3
-rw-r--r--net/tipc/port.c764
-rw-r--r--net/tipc/port.h184
-rw-r--r--net/tipc/ref.c25
-rw-r--r--net/tipc/ref.h1
-rw-r--r--net/tipc/socket.c338
-rw-r--r--net/tipc/subscr.c128
-rw-r--r--net/tipc/subscr.h2
-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
44 files changed, 1878 insertions, 4577 deletions
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index b74f78d0c033..2c5954b85933 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -29,40 +29,6 @@ config TIPC_ADVANCED
29 Saying Y here will open some advanced configuration for TIPC. 29 Saying Y here will open some advanced configuration for TIPC.
30 Most users do not need to bother; if unsure, just say N. 30 Most users do not need to bother; if unsure, just say N.
31 31
32config TIPC_ZONES
33 int "Maximum number of zones in a network"
34 depends on TIPC_ADVANCED
35 range 1 255
36 default "3"
37 help
38 Specifies how many zones can be supported in a TIPC network.
39 Can range from 1 to 255 zones; default is 3.
40
41 Setting this to a smaller value saves some memory;
42 setting it to a higher value allows for more zones.
43
44config TIPC_CLUSTERS
45 int "Maximum number of clusters in a zone"
46 depends on TIPC_ADVANCED
47 range 1 1
48 default "1"
49 help
50 Specifies how many clusters can be supported in a TIPC zone.
51
52 *** Currently TIPC only supports a single cluster per zone. ***
53
54config TIPC_NODES
55 int "Maximum number of nodes in a cluster"
56 depends on TIPC_ADVANCED
57 range 8 2047
58 default "255"
59 help
60 Specifies how many nodes can be supported in a TIPC cluster.
61 Can range from 8 to 2047 nodes; default is 255.
62
63 Setting this to a smaller value saves some memory;
64 setting it to higher allows for more nodes.
65
66config TIPC_PORTS 32config TIPC_PORTS
67 int "Maximum number of ports in a node" 33 int "Maximum number of ports in a node"
68 depends on TIPC_ADVANCED 34 depends on TIPC_ADVANCED
@@ -72,7 +38,7 @@ config TIPC_PORTS
72 Specifies how many ports can be supported by a node. 38 Specifies how many ports can be supported by a node.
73 Can range from 127 to 65535 ports; default is 8191. 39 Can range from 127 to 65535 ports; default is 8191.
74 40
75 Setting this to a smaller value saves some memory, 41 Setting this to a smaller value saves some memory,
76 setting it to higher allows for more ports. 42 setting it to higher allows for more ports.
77 43
78config TIPC_LOG 44config TIPC_LOG
@@ -89,12 +55,15 @@ config TIPC_LOG
89 managed remotely via TIPC. 55 managed remotely via TIPC.
90 56
91config TIPC_DEBUG 57config TIPC_DEBUG
92 bool "Enable debug messages" 58 bool "Enable debugging support"
93 default n 59 default n
94 help 60 help
95 This enables debugging of TIPC. 61 Saying Y here enables TIPC debugging capabilities used by developers.
62 Most users do not need to bother; if unsure, just say N.
96 63
97 Only say Y here if you are having trouble with TIPC. It will 64 Enabling debugging support causes TIPC to display data about its
98 enable the display of detailed information about what is going on. 65 internal state when certain abnormal conditions occur. It also
66 makes it easy for developers to capture additional information of
67 interest using the dbg() or msg_dbg() macros.
99 68
100endif # TIPC 69endif # TIPC
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index dceb7027946c..521d24d04ab2 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -4,10 +4,10 @@
4 4
5obj-$(CONFIG_TIPC) := tipc.o 5obj-$(CONFIG_TIPC) := tipc.o
6 6
7tipc-y += addr.o bcast.o bearer.o config.o cluster.o \ 7tipc-y += addr.o bcast.o bearer.o config.o \
8 core.o handler.o link.o discover.o msg.o \ 8 core.o handler.o link.o discover.o msg.o \
9 name_distr.o subscr.o name_table.o net.o \ 9 name_distr.o subscr.o name_table.o net.o \
10 netlink.o node.o node_subscr.o port.o ref.o \ 10 netlink.o node.o node_subscr.o port.o ref.o \
11 socket.o user_reg.o zone.o dbg.o eth_media.o 11 socket.o log.o eth_media.o
12 12
13# End of file 13# End of file
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index c048543ffbeb..a6fdab33877e 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -2,7 +2,7 @@
2 * net/tipc/addr.c: TIPC address utility routines 2 * net/tipc/addr.c: TIPC address utility routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,22 +35,13 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "addr.h" 38#include "addr.h"
40#include "zone.h"
41#include "cluster.h"
42#include "net.h"
43
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
51 * 42 *
52 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>, 43 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>,
53 * where Z, C, and N are non-zero and do not exceed the configured limits. 44 * where Z, C, and N are non-zero.
54 * 45 *
55 * Returns 1 if domain address is valid, otherwise 0 46 * Returns 1 if domain address is valid, otherwise 0
56 */ 47 */
@@ -60,16 +51,6 @@ int tipc_addr_domain_valid(u32 addr)
60 u32 n = tipc_node(addr); 51 u32 n = tipc_node(addr);
61 u32 c = tipc_cluster(addr); 52 u32 c = tipc_cluster(addr);
62 u32 z = tipc_zone(addr); 53 u32 z = tipc_zone(addr);
63 u32 max_nodes = tipc_max_nodes;
64
65 if (is_slave(addr))
66 max_nodes = LOWEST_SLAVE + tipc_max_slaves;
67 if (n > max_nodes)
68 return 0;
69 if (c > tipc_max_clusters)
70 return 0;
71 if (z > tipc_max_zones)
72 return 0;
73 54
74 if (n && (!z || !c)) 55 if (n && (!z || !c))
75 return 0; 56 return 0;
@@ -81,24 +62,23 @@ int tipc_addr_domain_valid(u32 addr)
81/** 62/**
82 * tipc_addr_node_valid - validates a proposed network address for this node 63 * tipc_addr_node_valid - validates a proposed network address for this node
83 * 64 *
84 * Accepts <Z.C.N>, where Z, C, and N are non-zero and do not exceed 65 * Accepts <Z.C.N>, where Z, C, and N are non-zero.
85 * the configured limits.
86 * 66 *
87 * Returns 1 if address can be used, otherwise 0 67 * Returns 1 if address can be used, otherwise 0
88 */ 68 */
89 69
90int tipc_addr_node_valid(u32 addr) 70int tipc_addr_node_valid(u32 addr)
91{ 71{
92 return (tipc_addr_domain_valid(addr) && tipc_node(addr)); 72 return tipc_addr_domain_valid(addr) && tipc_node(addr);
93} 73}
94 74
95int tipc_in_scope(u32 domain, u32 addr) 75int tipc_in_scope(u32 domain, u32 addr)
96{ 76{
97 if (!domain || (domain == addr)) 77 if (!domain || (domain == addr))
98 return 1; 78 return 1;
99 if (domain == (addr & 0xfffff000u)) /* domain <Z.C.0> */ 79 if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */
100 return 1; 80 return 1;
101 if (domain == (addr & 0xff000000u)) /* domain <Z.0.0> */ 81 if (domain == tipc_zone_mask(addr)) /* domain <Z.0.0> */
102 return 1; 82 return 1;
103 return 0; 83 return 0;
104} 84}
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index c1cc5724d8cc..e4f35afe3207 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,19 +37,17 @@
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) 40#define TIPC_ZONE_MASK 0xff000000u
41{ 41#define TIPC_CLUSTER_MASK 0xfffff000u
42 return tipc_node(tipc_own_addr);
43}
44 42
45static inline u32 own_cluster(void) 43static inline u32 tipc_zone_mask(u32 addr)
46{ 44{
47 return tipc_cluster(tipc_own_addr); 45 return addr & TIPC_ZONE_MASK;
48} 46}
49 47
50static inline u32 own_zone(void) 48static inline u32 tipc_cluster_mask(u32 addr)
51{ 49{
52 return tipc_zone(tipc_own_addr); 50 return addr & TIPC_CLUSTER_MASK;
53} 51}
54 52
55static inline int in_own_cluster(u32 addr) 53static inline int in_own_cluster(u32 addr)
@@ -57,16 +55,6 @@ static inline int in_own_cluster(u32 addr)
57 return !((addr ^ tipc_own_addr) >> 12); 55 return !((addr ^ tipc_own_addr) >> 12);
58} 56}
59 57
60static inline int is_slave(u32 addr)
61{
62 return addr & 0x800;
63}
64
65static inline int may_route(u32 addr)
66{
67 return(addr ^ tipc_own_addr) >> 11;
68}
69
70/** 58/**
71 * addr_domain - convert 2-bit scope value to equivalent message lookup domain 59 * addr_domain - convert 2-bit scope value to equivalent message lookup domain
72 * 60 *
@@ -74,14 +62,13 @@ static inline int may_route(u32 addr)
74 * after a network hop. 62 * after a network hop.
75 */ 63 */
76 64
77static inline int addr_domain(int sc) 65static inline u32 addr_domain(u32 sc)
78{ 66{
79 if (likely(sc == TIPC_NODE_SCOPE)) 67 if (likely(sc == TIPC_NODE_SCOPE))
80 return tipc_own_addr; 68 return tipc_own_addr;
81 if (sc == TIPC_CLUSTER_SCOPE) 69 if (sc == TIPC_CLUSTER_SCOPE)
82 return tipc_addr(tipc_zone(tipc_own_addr), 70 return tipc_cluster_mask(tipc_own_addr);
83 tipc_cluster(tipc_own_addr), 0); 71 return tipc_zone_mask(tipc_own_addr);
84 return tipc_addr(tipc_zone(tipc_own_addr), 0, 0);
85} 72}
86 73
87int tipc_addr_domain_valid(u32); 74int tipc_addr_domain_valid(u32);
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index a008c6689305..fa68d1e9ff4b 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004-2006, Ericsson AB 4 * Copyright (c) 2004-2006, Ericsson AB
5 * Copyright (c) 2004, Intel Corporation. 5 * Copyright (c) 2004, Intel Corporation.
6 * Copyright (c) 2005, Wind River Systems 6 * Copyright (c) 2005, 2010-2011, Wind River Systems
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
@@ -36,32 +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/*
59 * 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.
61 */
62
63#define TIPC_BCAST_LOSS_RATE 0
64
65/** 47/**
66 * struct bcbearer_pair - a pair of bearers used by broadcast link 48 * struct bcbearer_pair - a pair of bearers used by broadcast link
67 * @primary: pointer to primary bearer 49 * @primary: pointer to primary bearer
@@ -72,8 +54,8 @@
72 */ 54 */
73 55
74struct bcbearer_pair { 56struct bcbearer_pair {
75 struct bearer *primary; 57 struct tipc_bearer *primary;
76 struct bearer *secondary; 58 struct tipc_bearer *secondary;
77}; 59};
78 60
79/** 61/**
@@ -92,7 +74,7 @@ struct bcbearer_pair {
92 */ 74 */
93 75
94struct bcbearer { 76struct bcbearer {
95 struct bearer bearer; 77 struct tipc_bearer bearer;
96 struct media media; 78 struct media media;
97 struct bcbearer_pair bpairs[MAX_BEARERS]; 79 struct bcbearer_pair bpairs[MAX_BEARERS];
98 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; 80 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
@@ -104,6 +86,7 @@ struct bcbearer {
104 * struct bclink - link used for broadcast messages 86 * struct bclink - link used for broadcast messages
105 * @link: (non-standard) broadcast link structure 87 * @link: (non-standard) broadcast link structure
106 * @node: (non-standard) node structure representing b'cast link's peer node 88 * @node: (non-standard) node structure representing b'cast link's peer node
89 * @retransmit_to: node that most recently requested a retransmit
107 * 90 *
108 * Handles sequence numbering, fragmentation, bundling, etc. 91 * Handles sequence numbering, fragmentation, bundling, etc.
109 */ 92 */
@@ -111,16 +94,23 @@ struct bcbearer {
111struct bclink { 94struct bclink {
112 struct link link; 95 struct link link;
113 struct tipc_node node; 96 struct tipc_node node;
97 struct tipc_node *retransmit_to;
114}; 98};
115 99
116 100
117static struct bcbearer *bcbearer = NULL; 101static struct bcbearer *bcbearer;
118static struct bclink *bclink = NULL; 102static struct bclink *bclink;
119static struct link *bcl = NULL; 103static struct link *bcl;
120static DEFINE_SPINLOCK(bc_lock); 104static DEFINE_SPINLOCK(bc_lock);
121 105
106/* broadcast-capable node map */
107struct tipc_node_map tipc_bcast_nmap;
108
122const char tipc_bclink_name[] = "broadcast-link"; 109const char tipc_bclink_name[] = "broadcast-link";
123 110
111static void tipc_nmap_diff(struct tipc_node_map *nm_a,
112 struct tipc_node_map *nm_b,
113 struct tipc_node_map *nm_diff);
124 114
125static u32 buf_seqno(struct sk_buff *buf) 115static u32 buf_seqno(struct sk_buff *buf)
126{ 116{
@@ -143,6 +133,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
143} 133}
144 134
145 135
136static void bclink_set_last_sent(void)
137{
138 if (bcl->next_out)
139 bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1);
140 else
141 bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1);
142}
143
144u32 tipc_bclink_get_last_sent(void)
145{
146 return bcl->fsm_msg_cnt;
147}
148
146/** 149/**
147 * bclink_set_gap - set gap according to contents of current deferred pkt queue 150 * bclink_set_gap - set gap according to contents of current deferred pkt queue
148 * 151 *
@@ -171,11 +174,22 @@ static void bclink_set_gap(struct tipc_node *n_ptr)
171 174
172static int bclink_ack_allowed(u32 n) 175static int bclink_ack_allowed(u32 n)
173{ 176{
174 return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag); 177 return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag;
175} 178}
176 179
177 180
178/** 181/**
182 * tipc_bclink_retransmit_to - get most recent node to request retransmission
183 *
184 * Called with bc_lock locked
185 */
186
187struct tipc_node *tipc_bclink_retransmit_to(void)
188{
189 return bclink->retransmit_to;
190}
191
192/**
179 * bclink_retransmit_pkt - retransmit broadcast packets 193 * bclink_retransmit_pkt - retransmit broadcast packets
180 * @after: sequence number of last packet to *not* retransmit 194 * @after: sequence number of last packet to *not* retransmit
181 * @to: sequence number of last packet to retransmit 195 * @to: sequence number of last packet to retransmit
@@ -188,9 +202,8 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
188 struct sk_buff *buf; 202 struct sk_buff *buf;
189 203
190 buf = bcl->first_out; 204 buf = bcl->first_out;
191 while (buf && less_eq(buf_seqno(buf), after)) { 205 while (buf && less_eq(buf_seqno(buf), after))
192 buf = buf->next; 206 buf = buf->next;
193 }
194 tipc_link_retransmit(bcl, buf, mod(to - after)); 207 tipc_link_retransmit(bcl, buf, mod(to - after));
195} 208}
196 209
@@ -216,9 +229,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
216 /* Skip over packets that node has previously acknowledged */ 229 /* Skip over packets that node has previously acknowledged */
217 230
218 crs = bcl->first_out; 231 crs = bcl->first_out;
219 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) { 232 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
220 crs = crs->next; 233 crs = crs->next;
221 }
222 234
223 /* Update packets that node is now acknowledging */ 235 /* Update packets that node is now acknowledging */
224 236
@@ -237,8 +249,10 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
237 249
238 /* Try resolving broadcast link congestion, if necessary */ 250 /* Try resolving broadcast link congestion, if necessary */
239 251
240 if (unlikely(bcl->next_out)) 252 if (unlikely(bcl->next_out)) {
241 tipc_link_push_queue(bcl); 253 tipc_link_push_queue(bcl);
254 bclink_set_last_sent();
255 }
242 if (unlikely(released && !list_empty(&bcl->waiting_ports))) 256 if (unlikely(released && !list_empty(&bcl->waiting_ports)))
243 tipc_link_wakeup_ports(bcl, 0); 257 tipc_link_wakeup_ports(bcl, 0);
244 spin_unlock_bh(&bc_lock); 258 spin_unlock_bh(&bc_lock);
@@ -272,11 +286,12 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
272 if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to)) 286 if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to))
273 return; 287 return;
274 288
275 buf = buf_acquire(INT_H_SIZE); 289 buf = tipc_buf_acquire(INT_H_SIZE);
276 if (buf) { 290 if (buf) {
277 msg = buf_msg(buf); 291 msg = buf_msg(buf);
278 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 292 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
279 INT_H_SIZE, n_ptr->addr); 293 INT_H_SIZE, n_ptr->addr);
294 msg_set_non_seq(msg, 1);
280 msg_set_mc_netid(msg, tipc_net_id); 295 msg_set_mc_netid(msg, tipc_net_id);
281 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 296 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
282 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); 297 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after);
@@ -392,13 +407,9 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
392 spin_lock_bh(&bc_lock); 407 spin_lock_bh(&bc_lock);
393 408
394 res = tipc_link_send_buf(bcl, buf); 409 res = tipc_link_send_buf(bcl, buf);
395 if (unlikely(res == -ELINKCONG)) 410 if (likely(res > 0))
396 buf_discard(buf); 411 bclink_set_last_sent();
397 else
398 bcl->stats.sent_info++;
399 412
400 if (bcl->out_queue_size > bcl->stats.max_queue_sz)
401 bcl->stats.max_queue_sz = bcl->out_queue_size;
402 bcl->stats.queue_sz_counts++; 413 bcl->stats.queue_sz_counts++;
403 bcl->stats.accu_queue_sz += bcl->out_queue_size; 414 bcl->stats.accu_queue_sz += bcl->out_queue_size;
404 415
@@ -414,17 +425,12 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
414 425
415void tipc_bclink_recv_pkt(struct sk_buff *buf) 426void tipc_bclink_recv_pkt(struct sk_buff *buf)
416{ 427{
417#if (TIPC_BCAST_LOSS_RATE)
418 static int rx_count = 0;
419#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,17 +438,15 @@ 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));
439 tipc_node_unlock(node); 444 tipc_node_unlock(node);
440 spin_lock_bh(&bc_lock); 445 spin_lock_bh(&bc_lock);
441 bcl->stats.recv_nacks++; 446 bcl->stats.recv_nacks++;
442 bcl->owner->next = node; /* remember requestor */ 447 bclink->retransmit_to = node;
443 bclink_retransmit_pkt(msg_bcgap_after(msg), 448 bclink_retransmit_pkt(msg_bcgap_after(msg),
444 msg_bcgap_to(msg)); 449 msg_bcgap_to(msg));
445 bcl->owner->next = NULL;
446 spin_unlock_bh(&bc_lock); 450 spin_unlock_bh(&bc_lock);
447 } else { 451 } else {
448 tipc_bclink_peek_nack(msg_destnode(msg), 452 tipc_bclink_peek_nack(msg_destnode(msg),
@@ -454,14 +458,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
454 return; 458 return;
455 } 459 }
456 460
457#if (TIPC_BCAST_LOSS_RATE)
458 if (++rx_count == TIPC_BCAST_LOSS_RATE) {
459 rx_count = 0;
460 buf_discard(buf);
461 return;
462 }
463#endif
464
465 tipc_node_lock(node); 461 tipc_node_lock(node);
466receive: 462receive:
467 deferred = node->bclink.deferred_head; 463 deferred = node->bclink.deferred_head;
@@ -529,15 +525,6 @@ receive:
529 tipc_node_unlock(node); 525 tipc_node_unlock(node);
530} 526}
531 527
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) 528u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
542{ 529{
543 return (n_ptr->bclink.supported && 530 return (n_ptr->bclink.supported &&
@@ -565,20 +552,21 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
565 if (likely(!msg_non_seq(buf_msg(buf)))) { 552 if (likely(!msg_non_seq(buf_msg(buf)))) {
566 struct tipc_msg *msg; 553 struct tipc_msg *msg;
567 554
568 assert(tipc_cltr_bcast_nodes.count != 0); 555 assert(tipc_bcast_nmap.count != 0);
569 bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); 556 bcbuf_set_acks(buf, tipc_bcast_nmap.count);
570 msg = buf_msg(buf); 557 msg = buf_msg(buf);
571 msg_set_non_seq(msg, 1); 558 msg_set_non_seq(msg, 1);
572 msg_set_mc_netid(msg, tipc_net_id); 559 msg_set_mc_netid(msg, tipc_net_id);
560 bcl->stats.sent_info++;
573 } 561 }
574 562
575 /* Send buffer over bearers until all targets reached */ 563 /* Send buffer over bearers until all targets reached */
576 564
577 bcbearer->remains = tipc_cltr_bcast_nodes; 565 bcbearer->remains = tipc_bcast_nmap;
578 566
579 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 567 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
580 struct bearer *p = bcbearer->bpairs[bp_index].primary; 568 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;
581 struct bearer *s = bcbearer->bpairs[bp_index].secondary; 569 struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary;
582 570
583 if (!p) 571 if (!p)
584 break; /* no more bearers to try */ 572 break; /* no more bearers to try */
@@ -587,11 +575,11 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
587 if (bcbearer->remains_new.count == bcbearer->remains.count) 575 if (bcbearer->remains_new.count == bcbearer->remains.count)
588 continue; /* bearer pair doesn't add anything */ 576 continue; /* bearer pair doesn't add anything */
589 577
590 if (p->publ.blocked || 578 if (p->blocked ||
591 p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { 579 p->media->send_msg(buf, p, &p->media->bcast_addr)) {
592 /* unable to send on primary bearer */ 580 /* unable to send on primary bearer */
593 if (!s || s->publ.blocked || 581 if (!s || s->blocked ||
594 s->media->send_msg(buf, &s->publ, 582 s->media->send_msg(buf, s,
595 &s->media->bcast_addr)) { 583 &s->media->bcast_addr)) {
596 /* unable to send on either bearer */ 584 /* unable to send on either bearer */
597 continue; 585 continue;
@@ -609,11 +597,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
609 bcbearer->remains = bcbearer->remains_new; 597 bcbearer->remains = bcbearer->remains_new;
610 } 598 }
611 599
612 /* Unable to reach all targets */ 600 /*
601 * Unable to reach all targets (indicate success, since currently
602 * there isn't code in place to properly block & unblock the
603 * pseudo-bearer used by the broadcast link)
604 */
613 605
614 bcbearer->bearer.publ.blocked = 1; 606 return TIPC_OK;
615 bcl->stats.bearer_congs++;
616 return 1;
617} 607}
618 608
619/** 609/**
@@ -634,7 +624,7 @@ void tipc_bcbearer_sort(void)
634 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp)); 624 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));
635 625
636 for (b_index = 0; b_index < MAX_BEARERS; b_index++) { 626 for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
637 struct bearer *b = &tipc_bearers[b_index]; 627 struct tipc_bearer *b = &tipc_bearers[b_index];
638 628
639 if (!b->active || !b->nodes.count) 629 if (!b->active || !b->nodes.count)
640 continue; 630 continue;
@@ -683,12 +673,12 @@ void tipc_bcbearer_sort(void)
683 673
684void tipc_bcbearer_push(void) 674void tipc_bcbearer_push(void)
685{ 675{
686 struct bearer *b_ptr; 676 struct tipc_bearer *b_ptr;
687 677
688 spin_lock_bh(&bc_lock); 678 spin_lock_bh(&bc_lock);
689 b_ptr = &bcbearer->bearer; 679 b_ptr = &bcbearer->bearer;
690 if (b_ptr->publ.blocked) { 680 if (b_ptr->blocked) {
691 b_ptr->publ.blocked = 0; 681 b_ptr->blocked = 0;
692 tipc_bearer_lock_push(b_ptr); 682 tipc_bearer_lock_push(b_ptr);
693 } 683 }
694 spin_unlock_bh(&bc_lock); 684 spin_unlock_bh(&bc_lock);
@@ -770,7 +760,6 @@ int tipc_bclink_init(void)
770 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); 760 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
771 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); 761 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
772 if (!bcbearer || !bclink) { 762 if (!bcbearer || !bclink) {
773 nomem:
774 warn("Multicast link creation failed, no memory\n"); 763 warn("Multicast link creation failed, no memory\n");
775 kfree(bcbearer); 764 kfree(bcbearer);
776 bcbearer = NULL; 765 bcbearer = NULL;
@@ -795,14 +784,6 @@ int tipc_bclink_init(void)
795 bcl->state = WORKING_WORKING; 784 bcl->state = WORKING_WORKING;
796 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); 785 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
797 786
798 if (BCLINK_LOG_BUF_SIZE) {
799 char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC);
800
801 if (!pb)
802 goto nomem;
803 tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE);
804 }
805
806 return 0; 787 return 0;
807} 788}
808 789
@@ -811,8 +792,6 @@ void tipc_bclink_stop(void)
811 spin_lock_bh(&bc_lock); 792 spin_lock_bh(&bc_lock);
812 if (bcbearer) { 793 if (bcbearer) {
813 tipc_link_stop(bcl); 794 tipc_link_stop(bcl);
814 if (BCLINK_LOG_BUF_SIZE)
815 kfree(bcl->print_buf.buf);
816 bcl = NULL; 795 bcl = NULL;
817 kfree(bclink); 796 kfree(bclink);
818 bclink = NULL; 797 bclink = NULL;
@@ -862,8 +841,9 @@ void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
862 * @nm_diff: output node map A-B (i.e. nodes of A that are not in B) 841 * @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
863 */ 842 */
864 843
865void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b, 844static void tipc_nmap_diff(struct tipc_node_map *nm_a,
866 struct tipc_node_map *nm_diff) 845 struct tipc_node_map *nm_b,
846 struct tipc_node_map *nm_diff)
867{ 847{
868 int stop = ARRAY_SIZE(nm_a->map); 848 int stop = ARRAY_SIZE(nm_a->map);
869 int w; 849 int w;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index e8c2b81658c7..500c97f1c859 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -2,7 +2,7 @@
2 * net/tipc/bcast.h: Include file for TIPC broadcast code 2 * net/tipc/bcast.h: Include file for TIPC broadcast code
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -51,6 +51,7 @@ struct tipc_node_map {
51 u32 map[MAX_NODES / WSIZE]; 51 u32 map[MAX_NODES / WSIZE];
52}; 52};
53 53
54extern struct tipc_node_map tipc_bcast_nmap;
54 55
55#define PLSIZE 32 56#define PLSIZE 32
56 57
@@ -84,14 +85,12 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_m
84 return !memcmp(nm_a, nm_b, sizeof(*nm_a)); 85 return !memcmp(nm_a, nm_b, sizeof(*nm_a));
85} 86}
86 87
87void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b,
88 struct tipc_node_map *nm_diff);
89
90void tipc_port_list_add(struct port_list *pl_ptr, u32 port); 88void tipc_port_list_add(struct port_list *pl_ptr, u32 port);
91void tipc_port_list_free(struct port_list *pl_ptr); 89void tipc_port_list_free(struct port_list *pl_ptr);
92 90
93int tipc_bclink_init(void); 91int tipc_bclink_init(void);
94void tipc_bclink_stop(void); 92void tipc_bclink_stop(void);
93struct tipc_node *tipc_bclink_retransmit_to(void);
95void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked); 94void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
96int tipc_bclink_send_msg(struct sk_buff *buf); 95int tipc_bclink_send_msg(struct sk_buff *buf);
97void tipc_bclink_recv_pkt(struct sk_buff *buf); 96void tipc_bclink_recv_pkt(struct sk_buff *buf);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 52ae17b2583e..85209eadfae6 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -2,7 +2,7 @@
2 * net/tipc/bearer.c: TIPC bearer code 2 * net/tipc/bearer.c: TIPC bearer code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2004-2006, Wind River Systems 5 * Copyright (c) 2004-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -36,19 +36,17 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "config.h"
39#include "dbg.h"
40#include "bearer.h" 39#include "bearer.h"
41#include "link.h"
42#include "port.h"
43#include "discover.h" 40#include "discover.h"
44#include "bcast.h"
45 41
46#define MAX_ADDR_STR 32 42#define MAX_ADDR_STR 32
47 43
48static struct media media_list[MAX_MEDIA]; 44static struct media media_list[MAX_MEDIA];
49static u32 media_count = 0; 45static u32 media_count;
50 46
51struct bearer tipc_bearers[MAX_BEARERS]; 47struct tipc_bearer tipc_bearers[MAX_BEARERS];
48
49static void bearer_disable(struct tipc_bearer *b_ptr);
52 50
53/** 51/**
54 * media_name_valid - validate media name 52 * media_name_valid - validate media name
@@ -63,7 +61,7 @@ static int media_name_valid(const char *name)
63 len = strlen(name); 61 len = strlen(name);
64 if ((len + 1) > TIPC_MAX_MEDIA_NAME) 62 if ((len + 1) > TIPC_MAX_MEDIA_NAME)
65 return 0; 63 return 0;
66 return (strspn(name, tipc_alphabet) == len); 64 return strspn(name, tipc_alphabet) == len;
67} 65}
68 66
69/** 67/**
@@ -162,12 +160,10 @@ int tipc_register_media(u32 media_type,
162 m_ptr->disable_bearer = disable; 160 m_ptr->disable_bearer = disable;
163 m_ptr->addr2str = addr2str; 161 m_ptr->addr2str = addr2str;
164 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr)); 162 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr));
165 m_ptr->bcast = 1;
166 strcpy(m_ptr->name, name); 163 strcpy(m_ptr->name, name);
167 m_ptr->priority = bearer_priority; 164 m_ptr->priority = bearer_priority;
168 m_ptr->tolerance = link_tolerance; 165 m_ptr->tolerance = link_tolerance;
169 m_ptr->window = send_window_limit; 166 m_ptr->window = send_window_limit;
170 dbg("Media <%s> registered\n", name);
171 res = 0; 167 res = 0;
172exit: 168exit:
173 write_unlock_bh(&tipc_net_lock); 169 write_unlock_bh(&tipc_net_lock);
@@ -199,9 +195,8 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
199 unchar *addr = (unchar *)&a->dev_addr; 195 unchar *addr = (unchar *)&a->dev_addr;
200 196
201 tipc_printf(pb, "UNKNOWN(%u)", media_type); 197 tipc_printf(pb, "UNKNOWN(%u)", media_type);
202 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { 198 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++)
203 tipc_printf(pb, "-%02x", addr[i]); 199 tipc_printf(pb, "-%02x", addr[i]);
204 }
205 } 200 }
206} 201}
207 202
@@ -256,7 +251,8 @@ static int bearer_name_validate(const char *name,
256 /* ensure all component parts of bearer name are present */ 251 /* ensure all component parts of bearer name are present */
257 252
258 media_name = name_copy; 253 media_name = name_copy;
259 if ((if_name = strchr(media_name, ':')) == NULL) 254 if_name = strchr(media_name, ':');
255 if (if_name == NULL)
260 return 0; 256 return 0;
261 *(if_name++) = 0; 257 *(if_name++) = 0;
262 media_len = if_name - media_name; 258 media_len = if_name - media_name;
@@ -283,16 +279,13 @@ static int bearer_name_validate(const char *name,
283 * bearer_find - locates bearer object with matching bearer name 279 * bearer_find - locates bearer object with matching bearer name
284 */ 280 */
285 281
286static struct bearer *bearer_find(const char *name) 282static struct tipc_bearer *bearer_find(const char *name)
287{ 283{
288 struct bearer *b_ptr; 284 struct tipc_bearer *b_ptr;
289 u32 i; 285 u32 i;
290 286
291 if (tipc_mode != TIPC_NET_MODE)
292 return NULL;
293
294 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 287 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
295 if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) 288 if (b_ptr->active && (!strcmp(b_ptr->name, name)))
296 return b_ptr; 289 return b_ptr;
297 } 290 }
298 return NULL; 291 return NULL;
@@ -302,16 +295,16 @@ static struct bearer *bearer_find(const char *name)
302 * tipc_bearer_find_interface - locates bearer object with matching interface name 295 * tipc_bearer_find_interface - locates bearer object with matching interface name
303 */ 296 */
304 297
305struct bearer *tipc_bearer_find_interface(const char *if_name) 298struct tipc_bearer *tipc_bearer_find_interface(const char *if_name)
306{ 299{
307 struct bearer *b_ptr; 300 struct tipc_bearer *b_ptr;
308 char *b_if_name; 301 char *b_if_name;
309 u32 i; 302 u32 i;
310 303
311 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 304 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
312 if (!b_ptr->active) 305 if (!b_ptr->active)
313 continue; 306 continue;
314 b_if_name = strchr(b_ptr->publ.name, ':') + 1; 307 b_if_name = strchr(b_ptr->name, ':') + 1;
315 if (!strcmp(b_if_name, if_name)) 308 if (!strcmp(b_if_name, if_name))
316 return b_ptr; 309 return b_ptr;
317 } 310 }
@@ -326,7 +319,7 @@ struct sk_buff *tipc_bearer_get_names(void)
326{ 319{
327 struct sk_buff *buf; 320 struct sk_buff *buf;
328 struct media *m_ptr; 321 struct media *m_ptr;
329 struct bearer *b_ptr; 322 struct tipc_bearer *b_ptr;
330 int i, j; 323 int i, j;
331 324
332 buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME)); 325 buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME));
@@ -339,8 +332,8 @@ struct sk_buff *tipc_bearer_get_names(void)
339 b_ptr = &tipc_bearers[j]; 332 b_ptr = &tipc_bearers[j];
340 if (b_ptr->active && (b_ptr->media == m_ptr)) { 333 if (b_ptr->active && (b_ptr->media == m_ptr)) {
341 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 334 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME,
342 b_ptr->publ.name, 335 b_ptr->name,
343 strlen(b_ptr->publ.name) + 1); 336 strlen(b_ptr->name) + 1);
344 } 337 }
345 } 338 }
346 } 339 }
@@ -348,18 +341,18 @@ struct sk_buff *tipc_bearer_get_names(void)
348 return buf; 341 return buf;
349} 342}
350 343
351void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest) 344void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest)
352{ 345{
353 tipc_nmap_add(&b_ptr->nodes, dest); 346 tipc_nmap_add(&b_ptr->nodes, dest);
354 tipc_disc_update_link_req(b_ptr->link_req);
355 tipc_bcbearer_sort(); 347 tipc_bcbearer_sort();
348 tipc_disc_add_dest(b_ptr->link_req);
356} 349}
357 350
358void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest) 351void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
359{ 352{
360 tipc_nmap_remove(&b_ptr->nodes, dest); 353 tipc_nmap_remove(&b_ptr->nodes, dest);
361 tipc_disc_update_link_req(b_ptr->link_req);
362 tipc_bcbearer_sort(); 354 tipc_bcbearer_sort();
355 tipc_disc_remove_dest(b_ptr->link_req);
363} 356}
364 357
365/* 358/*
@@ -370,12 +363,12 @@ void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest)
370 * bearer.lock must be taken before calling 363 * bearer.lock must be taken before calling
371 * Returns binary true(1) ore false(0) 364 * Returns binary true(1) ore false(0)
372 */ 365 */
373static int bearer_push(struct bearer *b_ptr) 366static int bearer_push(struct tipc_bearer *b_ptr)
374{ 367{
375 u32 res = 0; 368 u32 res = 0;
376 struct link *ln, *tln; 369 struct link *ln, *tln;
377 370
378 if (b_ptr->publ.blocked) 371 if (b_ptr->blocked)
379 return 0; 372 return 0;
380 373
381 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) { 374 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) {
@@ -390,13 +383,13 @@ static int bearer_push(struct bearer *b_ptr)
390 return list_empty(&b_ptr->cong_links); 383 return list_empty(&b_ptr->cong_links);
391} 384}
392 385
393void tipc_bearer_lock_push(struct bearer *b_ptr) 386void tipc_bearer_lock_push(struct tipc_bearer *b_ptr)
394{ 387{
395 int res; 388 int res;
396 389
397 spin_lock_bh(&b_ptr->publ.lock); 390 spin_lock_bh(&b_ptr->lock);
398 res = bearer_push(b_ptr); 391 res = bearer_push(b_ptr);
399 spin_unlock_bh(&b_ptr->publ.lock); 392 spin_unlock_bh(&b_ptr->lock);
400 if (res) 393 if (res)
401 tipc_bcbearer_push(); 394 tipc_bcbearer_push();
402} 395}
@@ -406,16 +399,14 @@ void tipc_bearer_lock_push(struct bearer *b_ptr)
406 * Interrupt enabling new requests after bearer congestion or blocking: 399 * Interrupt enabling new requests after bearer congestion or blocking:
407 * See bearer_send(). 400 * See bearer_send().
408 */ 401 */
409void tipc_continue(struct tipc_bearer *tb_ptr) 402void tipc_continue(struct tipc_bearer *b_ptr)
410{ 403{
411 struct bearer *b_ptr = (struct bearer *)tb_ptr; 404 spin_lock_bh(&b_ptr->lock);
412
413 spin_lock_bh(&b_ptr->publ.lock);
414 b_ptr->continue_count++; 405 b_ptr->continue_count++;
415 if (!list_empty(&b_ptr->cong_links)) 406 if (!list_empty(&b_ptr->cong_links))
416 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr); 407 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr);
417 b_ptr->publ.blocked = 0; 408 b_ptr->blocked = 0;
418 spin_unlock_bh(&b_ptr->publ.lock); 409 spin_unlock_bh(&b_ptr->lock);
419} 410}
420 411
421/* 412/*
@@ -426,7 +417,7 @@ void tipc_continue(struct tipc_bearer *tb_ptr)
426 * bearer.lock is busy 417 * bearer.lock is busy
427 */ 418 */
428 419
429static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr) 420static void tipc_bearer_schedule_unlocked(struct tipc_bearer *b_ptr, struct link *l_ptr)
430{ 421{
431 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links); 422 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links);
432} 423}
@@ -439,11 +430,11 @@ static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_p
439 * bearer.lock is free 430 * bearer.lock is free
440 */ 431 */
441 432
442void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr) 433void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr)
443{ 434{
444 spin_lock_bh(&b_ptr->publ.lock); 435 spin_lock_bh(&b_ptr->lock);
445 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 436 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
446 spin_unlock_bh(&b_ptr->publ.lock); 437 spin_unlock_bh(&b_ptr->lock);
447} 438}
448 439
449 440
@@ -452,18 +443,18 @@ void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr)
452 * and if there is, try to resolve it before returning. 443 * and if there is, try to resolve it before returning.
453 * 'tipc_net_lock' is read_locked when this function is called 444 * 'tipc_net_lock' is read_locked when this function is called
454 */ 445 */
455int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr) 446int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr)
456{ 447{
457 int res = 1; 448 int res = 1;
458 449
459 if (list_empty(&b_ptr->cong_links)) 450 if (list_empty(&b_ptr->cong_links))
460 return 1; 451 return 1;
461 spin_lock_bh(&b_ptr->publ.lock); 452 spin_lock_bh(&b_ptr->lock);
462 if (!bearer_push(b_ptr)) { 453 if (!bearer_push(b_ptr)) {
463 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 454 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
464 res = 0; 455 res = 0;
465 } 456 }
466 spin_unlock_bh(&b_ptr->publ.lock); 457 spin_unlock_bh(&b_ptr->lock);
467 return res; 458 return res;
468} 459}
469 460
@@ -471,9 +462,9 @@ int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr)
471 * tipc_bearer_congested - determines if bearer is currently congested 462 * tipc_bearer_congested - determines if bearer is currently congested
472 */ 463 */
473 464
474int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr) 465int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr)
475{ 466{
476 if (unlikely(b_ptr->publ.blocked)) 467 if (unlikely(b_ptr->blocked))
477 return 1; 468 return 1;
478 if (likely(list_empty(&b_ptr->cong_links))) 469 if (likely(list_empty(&b_ptr->cong_links)))
479 return 0; 470 return 0;
@@ -484,9 +475,9 @@ int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr)
484 * tipc_enable_bearer - enable bearer with the given name 475 * tipc_enable_bearer - enable bearer with the given name
485 */ 476 */
486 477
487int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority) 478int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
488{ 479{
489 struct bearer *b_ptr; 480 struct tipc_bearer *b_ptr;
490 struct media *m_ptr; 481 struct media *m_ptr;
491 struct bearer_name b_name; 482 struct bearer_name b_name;
492 char addr_string[16]; 483 char addr_string[16];
@@ -504,9 +495,16 @@ int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority)
504 warn("Bearer <%s> rejected, illegal name\n", name); 495 warn("Bearer <%s> rejected, illegal name\n", name);
505 return -EINVAL; 496 return -EINVAL;
506 } 497 }
507 if (!tipc_addr_domain_valid(bcast_scope) || 498 if (tipc_addr_domain_valid(disc_domain) &&
508 !tipc_in_scope(bcast_scope, tipc_own_addr)) { 499 (disc_domain != tipc_own_addr)) {
509 warn("Bearer <%s> rejected, illegal broadcast scope\n", name); 500 if (tipc_in_scope(disc_domain, tipc_own_addr)) {
501 disc_domain = tipc_own_addr & TIPC_CLUSTER_MASK;
502 res = 0; /* accept any node in own cluster */
503 } else if (in_own_cluster(disc_domain))
504 res = 0; /* accept specified node in own cluster */
505 }
506 if (res) {
507 warn("Bearer <%s> rejected, illegal discovery domain\n", name);
510 return -EINVAL; 508 return -EINVAL;
511 } 509 }
512 if ((priority < TIPC_MIN_LINK_PRI || 510 if ((priority < TIPC_MIN_LINK_PRI ||
@@ -522,7 +520,7 @@ int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority)
522 if (!m_ptr) { 520 if (!m_ptr) {
523 warn("Bearer <%s> rejected, media <%s> not registered\n", name, 521 warn("Bearer <%s> rejected, media <%s> not registered\n", name,
524 b_name.media_name); 522 b_name.media_name);
525 goto failed; 523 goto exit;
526 } 524 }
527 525
528 if (priority == TIPC_MEDIA_LINK_PRI) 526 if (priority == TIPC_MEDIA_LINK_PRI)
@@ -536,16 +534,16 @@ restart:
536 bearer_id = i; 534 bearer_id = i;
537 continue; 535 continue;
538 } 536 }
539 if (!strcmp(name, tipc_bearers[i].publ.name)) { 537 if (!strcmp(name, tipc_bearers[i].name)) {
540 warn("Bearer <%s> rejected, already enabled\n", name); 538 warn("Bearer <%s> rejected, already enabled\n", name);
541 goto failed; 539 goto exit;
542 } 540 }
543 if ((tipc_bearers[i].priority == priority) && 541 if ((tipc_bearers[i].priority == priority) &&
544 (++with_this_prio > 2)) { 542 (++with_this_prio > 2)) {
545 if (priority-- == 0) { 543 if (priority-- == 0) {
546 warn("Bearer <%s> rejected, duplicate priority\n", 544 warn("Bearer <%s> rejected, duplicate priority\n",
547 name); 545 name);
548 goto failed; 546 goto exit;
549 } 547 }
550 warn("Bearer <%s> priority adjustment required %u->%u\n", 548 warn("Bearer <%s> priority adjustment required %u->%u\n",
551 name, priority + 1, priority); 549 name, priority + 1, priority);
@@ -555,37 +553,36 @@ restart:
555 if (bearer_id >= MAX_BEARERS) { 553 if (bearer_id >= MAX_BEARERS) {
556 warn("Bearer <%s> rejected, bearer limit reached (%u)\n", 554 warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
557 name, MAX_BEARERS); 555 name, MAX_BEARERS);
558 goto failed; 556 goto exit;
559 } 557 }
560 558
561 b_ptr = &tipc_bearers[bearer_id]; 559 b_ptr = &tipc_bearers[bearer_id];
562 memset(b_ptr, 0, sizeof(struct bearer)); 560 strcpy(b_ptr->name, name);
563 561 res = m_ptr->enable_bearer(b_ptr);
564 strcpy(b_ptr->publ.name, name);
565 res = m_ptr->enable_bearer(&b_ptr->publ);
566 if (res) { 562 if (res) {
567 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); 563 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res);
568 goto failed; 564 goto exit;
569 } 565 }
570 566
571 b_ptr->identity = bearer_id; 567 b_ptr->identity = bearer_id;
572 b_ptr->media = m_ptr; 568 b_ptr->media = m_ptr;
573 b_ptr->net_plane = bearer_id + 'A'; 569 b_ptr->net_plane = bearer_id + 'A';
574 b_ptr->active = 1; 570 b_ptr->active = 1;
575 b_ptr->detect_scope = bcast_scope;
576 b_ptr->priority = priority; 571 b_ptr->priority = priority;
577 INIT_LIST_HEAD(&b_ptr->cong_links); 572 INIT_LIST_HEAD(&b_ptr->cong_links);
578 INIT_LIST_HEAD(&b_ptr->links); 573 INIT_LIST_HEAD(&b_ptr->links);
579 if (m_ptr->bcast) { 574 spin_lock_init(&b_ptr->lock);
580 b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, 575
581 bcast_scope, 2); 576 res = tipc_disc_create(b_ptr, &m_ptr->bcast_addr, disc_domain);
577 if (res) {
578 bearer_disable(b_ptr);
579 warn("Bearer <%s> rejected, discovery object creation failed\n",
580 name);
581 goto exit;
582 } 582 }
583 spin_lock_init(&b_ptr->publ.lock);
584 write_unlock_bh(&tipc_net_lock);
585 info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 583 info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
586 name, tipc_addr_string_fill(addr_string, bcast_scope), priority); 584 name, tipc_addr_string_fill(addr_string, disc_domain), priority);
587 return 0; 585exit:
588failed:
589 write_unlock_bh(&tipc_net_lock); 586 write_unlock_bh(&tipc_net_lock);
590 return res; 587 return res;
591} 588}
@@ -597,7 +594,7 @@ failed:
597 594
598int tipc_block_bearer(const char *name) 595int tipc_block_bearer(const char *name)
599{ 596{
600 struct bearer *b_ptr = NULL; 597 struct tipc_bearer *b_ptr = NULL;
601 struct link *l_ptr; 598 struct link *l_ptr;
602 struct link *temp_l_ptr; 599 struct link *temp_l_ptr;
603 600
@@ -610,8 +607,8 @@ int tipc_block_bearer(const char *name)
610 } 607 }
611 608
612 info("Blocking bearer <%s>\n", name); 609 info("Blocking bearer <%s>\n", name);
613 spin_lock_bh(&b_ptr->publ.lock); 610 spin_lock_bh(&b_ptr->lock);
614 b_ptr->publ.blocked = 1; 611 b_ptr->blocked = 1;
615 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 612 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
616 struct tipc_node *n_ptr = l_ptr->owner; 613 struct tipc_node *n_ptr = l_ptr->owner;
617 614
@@ -619,7 +616,7 @@ int tipc_block_bearer(const char *name)
619 tipc_link_reset(l_ptr); 616 tipc_link_reset(l_ptr);
620 spin_unlock_bh(&n_ptr->lock); 617 spin_unlock_bh(&n_ptr->lock);
621 } 618 }
622 spin_unlock_bh(&b_ptr->publ.lock); 619 spin_unlock_bh(&b_ptr->lock);
623 read_unlock_bh(&tipc_net_lock); 620 read_unlock_bh(&tipc_net_lock);
624 return 0; 621 return 0;
625} 622}
@@ -630,44 +627,38 @@ int tipc_block_bearer(const char *name)
630 * Note: This routine assumes caller holds tipc_net_lock. 627 * Note: This routine assumes caller holds tipc_net_lock.
631 */ 628 */
632 629
633static int bearer_disable(const char *name) 630static void bearer_disable(struct tipc_bearer *b_ptr)
634{ 631{
635 struct bearer *b_ptr;
636 struct link *l_ptr; 632 struct link *l_ptr;
637 struct link *temp_l_ptr; 633 struct link *temp_l_ptr;
638 634
639 b_ptr = bearer_find(name); 635 info("Disabling bearer <%s>\n", b_ptr->name);
640 if (!b_ptr) { 636 spin_lock_bh(&b_ptr->lock);
641 warn("Attempt to disable unknown bearer <%s>\n", name); 637 b_ptr->blocked = 1;
642 return -EINVAL; 638 b_ptr->media->disable_bearer(b_ptr);
643 }
644
645 info("Disabling bearer <%s>\n", name);
646 tipc_disc_stop_link_req(b_ptr->link_req);
647 spin_lock_bh(&b_ptr->publ.lock);
648 b_ptr->link_req = NULL;
649 b_ptr->publ.blocked = 1;
650 if (b_ptr->media->disable_bearer) {
651 spin_unlock_bh(&b_ptr->publ.lock);
652 write_unlock_bh(&tipc_net_lock);
653 b_ptr->media->disable_bearer(&b_ptr->publ);
654 write_lock_bh(&tipc_net_lock);
655 spin_lock_bh(&b_ptr->publ.lock);
656 }
657 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 639 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
658 tipc_link_delete(l_ptr); 640 tipc_link_delete(l_ptr);
659 } 641 }
660 spin_unlock_bh(&b_ptr->publ.lock); 642 if (b_ptr->link_req)
661 memset(b_ptr, 0, sizeof(struct bearer)); 643 tipc_disc_delete(b_ptr->link_req);
662 return 0; 644 spin_unlock_bh(&b_ptr->lock);
645 memset(b_ptr, 0, sizeof(struct tipc_bearer));
663} 646}
664 647
665int tipc_disable_bearer(const char *name) 648int tipc_disable_bearer(const char *name)
666{ 649{
650 struct tipc_bearer *b_ptr;
667 int res; 651 int res;
668 652
669 write_lock_bh(&tipc_net_lock); 653 write_lock_bh(&tipc_net_lock);
670 res = bearer_disable(name); 654 b_ptr = bearer_find(name);
655 if (b_ptr == NULL) {
656 warn("Attempt to disable unknown bearer <%s>\n", name);
657 res = -EINVAL;
658 } else {
659 bearer_disable(b_ptr);
660 res = 0;
661 }
671 write_unlock_bh(&tipc_net_lock); 662 write_unlock_bh(&tipc_net_lock);
672 return res; 663 return res;
673} 664}
@@ -680,13 +671,7 @@ void tipc_bearer_stop(void)
680 671
681 for (i = 0; i < MAX_BEARERS; i++) { 672 for (i = 0; i < MAX_BEARERS; i++) {
682 if (tipc_bearers[i].active) 673 if (tipc_bearers[i].active)
683 tipc_bearers[i].publ.blocked = 1; 674 bearer_disable(&tipc_bearers[i]);
684 }
685 for (i = 0; i < MAX_BEARERS; i++) {
686 if (tipc_bearers[i].active)
687 bearer_disable(tipc_bearers[i].publ.name);
688 } 675 }
689 media_count = 0; 676 media_count = 0;
690} 677}
691
692
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index a850b389663e..31d6172b20fd 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -2,7 +2,7 @@
2 * net/tipc/bearer.h: Include file for TIPC bearer code 2 * net/tipc/bearer.h: Include file for TIPC bearer code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,12 +37,31 @@
37#ifndef _TIPC_BEARER_H 37#ifndef _TIPC_BEARER_H
38#define _TIPC_BEARER_H 38#define _TIPC_BEARER_H
39 39
40#include "core.h"
41#include "bcast.h" 40#include "bcast.h"
42 41
43#define MAX_BEARERS 8 42#define MAX_BEARERS 8
44#define MAX_MEDIA 4 43#define MAX_MEDIA 4
45 44
45/*
46 * Identifiers of supported TIPC media types
47 */
48#define TIPC_MEDIA_TYPE_ETH 1
49
50/*
51 * Destination address structure used by TIPC bearers when sending messages
52 *
53 * IMPORTANT: The fields of this structure MUST be stored using the specified
54 * byte order indicated below, as the structure is exchanged between nodes
55 * as part of a link setup process.
56 */
57struct tipc_media_addr {
58 __be32 type; /* bearer type (network byte order) */
59 union {
60 __u8 eth_addr[6]; /* 48 bit Ethernet addr (byte array) */
61 } dev_addr;
62};
63
64struct tipc_bearer;
46 65
47/** 66/**
48 * struct media - TIPC media information available to internal users 67 * struct media - TIPC media information available to internal users
@@ -51,11 +70,10 @@
51 * @disable_bearer: routine which disables a bearer 70 * @disable_bearer: routine which disables a bearer
52 * @addr2str: routine which converts bearer's address to string form 71 * @addr2str: routine which converts bearer's address to string form
53 * @bcast_addr: media address used in broadcasting 72 * @bcast_addr: media address used in broadcasting
54 * @bcast: non-zero if media supports broadcasting [currently mandatory]
55 * @priority: default link (and bearer) priority 73 * @priority: default link (and bearer) priority
56 * @tolerance: default time (in ms) before declaring link failure 74 * @tolerance: default time (in ms) before declaring link failure
57 * @window: default window (in packets) before declaring link congestion 75 * @window: default window (in packets) before declaring link congestion
58 * @type_id: TIPC media identifier [defined in tipc_bearer.h] 76 * @type_id: TIPC media identifier
59 * @name: media name 77 * @name: media name
60 */ 78 */
61 79
@@ -68,7 +86,6 @@ struct media {
68 char *(*addr2str)(struct tipc_media_addr *a, 86 char *(*addr2str)(struct tipc_media_addr *a,
69 char *str_buf, int str_size); 87 char *str_buf, int str_size);
70 struct tipc_media_addr bcast_addr; 88 struct tipc_media_addr bcast_addr;
71 int bcast;
72 u32 priority; 89 u32 priority;
73 u32 tolerance; 90 u32 tolerance;
74 u32 window; 91 u32 window;
@@ -77,11 +94,15 @@ struct media {
77}; 94};
78 95
79/** 96/**
80 * struct bearer - TIPC bearer information available to internal users 97 * struct tipc_bearer - TIPC bearer structure
81 * @publ: bearer information available to privileged users 98 * @usr_handle: pointer to additional media-specific information about bearer
99 * @mtu: max packet size bearer can support
100 * @blocked: non-zero if bearer is blocked
101 * @lock: spinlock for controlling access to bearer
102 * @addr: media-specific address associated with bearer
103 * @name: bearer name (format = media:interface)
82 * @media: ptr to media structure associated with bearer 104 * @media: ptr to media structure associated with bearer
83 * @priority: default link priority for bearer 105 * @priority: default link priority for bearer
84 * @detect_scope: network address mask used during automatic link creation
85 * @identity: array index of this bearer within TIPC bearer array 106 * @identity: array index of this bearer within TIPC bearer array
86 * @link_req: ptr to (optional) structure making periodic link setup requests 107 * @link_req: ptr to (optional) structure making periodic link setup requests
87 * @links: list of non-congested links associated with bearer 108 * @links: list of non-congested links associated with bearer
@@ -90,13 +111,20 @@ struct media {
90 * @active: non-zero if bearer structure is represents a bearer 111 * @active: non-zero if bearer structure is represents a bearer
91 * @net_plane: network plane ('A' through 'H') currently associated with bearer 112 * @net_plane: network plane ('A' through 'H') currently associated with bearer
92 * @nodes: indicates which nodes in cluster can be reached through bearer 113 * @nodes: indicates which nodes in cluster can be reached through bearer
114 *
115 * Note: media-specific code is responsible for initialization of the fields
116 * indicated below when a bearer is enabled; TIPC's generic bearer code takes
117 * care of initializing all other fields.
93 */ 118 */
94 119struct tipc_bearer {
95struct bearer { 120 void *usr_handle; /* initalized by media */
96 struct tipc_bearer publ; 121 u32 mtu; /* initalized by media */
122 int blocked; /* initalized by media */
123 struct tipc_media_addr addr; /* initalized by media */
124 char name[TIPC_MAX_BEARER_NAME];
125 spinlock_t lock;
97 struct media *media; 126 struct media *media;
98 u32 priority; 127 u32 priority;
99 u32 detect_scope;
100 u32 identity; 128 u32 identity;
101 struct link_req *link_req; 129 struct link_req *link_req;
102 struct list_head links; 130 struct list_head links;
@@ -114,21 +142,48 @@ struct bearer_name {
114 142
115struct link; 143struct link;
116 144
117extern struct bearer tipc_bearers[]; 145extern struct tipc_bearer tipc_bearers[];
146
147/*
148 * TIPC routines available to supported media types
149 */
150int tipc_register_media(u32 media_type,
151 char *media_name, int (*enable)(struct tipc_bearer *),
152 void (*disable)(struct tipc_bearer *),
153 int (*send_msg)(struct sk_buff *,
154 struct tipc_bearer *, struct tipc_media_addr *),
155 char *(*addr2str)(struct tipc_media_addr *a,
156 char *str_buf, int str_size),
157 struct tipc_media_addr *bcast_addr, const u32 bearer_priority,
158 const u32 link_tolerance, /* [ms] */
159 const u32 send_window_limit);
160
161void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
162
163int tipc_block_bearer(const char *name);
164void tipc_continue(struct tipc_bearer *tb_ptr);
165
166int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
167int tipc_disable_bearer(const char *name);
168
169/*
170 * Routines made available to TIPC by supported media types
171 */
172int tipc_eth_media_start(void);
173void tipc_eth_media_stop(void);
118 174
119void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); 175void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
120struct sk_buff *tipc_media_get_names(void); 176struct sk_buff *tipc_media_get_names(void);
121 177
122struct sk_buff *tipc_bearer_get_names(void); 178struct sk_buff *tipc_bearer_get_names(void);
123void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest); 179void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest);
124void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest); 180void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest);
125void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr); 181void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr);
126struct bearer *tipc_bearer_find_interface(const char *if_name); 182struct tipc_bearer *tipc_bearer_find_interface(const char *if_name);
127int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr); 183int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr);
128int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr); 184int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr);
129int tipc_bearer_init(void);
130void tipc_bearer_stop(void); 185void tipc_bearer_stop(void);
131void tipc_bearer_lock_push(struct bearer *b_ptr); 186void tipc_bearer_lock_push(struct tipc_bearer *b_ptr);
132 187
133 188
134/** 189/**
@@ -149,10 +204,11 @@ void tipc_bearer_lock_push(struct bearer *b_ptr);
149 * and let TIPC's link code deal with the undelivered message. 204 * and let TIPC's link code deal with the undelivered message.
150 */ 205 */
151 206
152static inline int tipc_bearer_send(struct bearer *b_ptr, struct sk_buff *buf, 207static inline int tipc_bearer_send(struct tipc_bearer *b_ptr,
208 struct sk_buff *buf,
153 struct tipc_media_addr *dest) 209 struct tipc_media_addr *dest)
154{ 210{
155 return !b_ptr->media->send_msg(buf, &b_ptr->publ, dest); 211 return !b_ptr->media->send_msg(buf, b_ptr, dest);
156} 212}
157 213
158#endif /* _TIPC_BEARER_H */ 214#endif /* _TIPC_BEARER_H */
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
deleted file mode 100644
index e68f705381bc..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 tipc_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 961d1b097146..b25a396b7e1e 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -2,7 +2,7 @@
2 * net/tipc/config.c: TIPC configuration management code 2 * net/tipc/config.c: TIPC configuration management code
3 * 3 *
4 * Copyright (c) 2002-2006, Ericsson AB 4 * Copyright (c) 2002-2006, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,30 +35,11 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "bearer.h"
40#include "port.h" 38#include "port.h"
41#include "link.h"
42#include "zone.h"
43#include "addr.h"
44#include "name_table.h" 39#include "name_table.h"
45#include "node.h"
46#include "config.h" 40#include "config.h"
47#include "discover.h"
48 41
49struct subscr_data { 42static u32 config_port_ref;
50 char usr_handle[8];
51 u32 domain;
52 u32 port_ref;
53 struct list_head subd_list;
54};
55
56struct manager {
57 u32 user_ref;
58 u32 port_ref;
59};
60
61static struct manager mng = { 0};
62 43
63static DEFINE_SPINLOCK(config_lock); 44static DEFINE_SPINLOCK(config_lock);
64 45
@@ -83,10 +64,8 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
83 struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf); 64 struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf);
84 int new_tlv_space = TLV_SPACE(tlv_data_size); 65 int new_tlv_space = TLV_SPACE(tlv_data_size);
85 66
86 if (skb_tailroom(buf) < new_tlv_space) { 67 if (skb_tailroom(buf) < new_tlv_space)
87 dbg("tipc_cfg_append_tlv unable to append TLV\n");
88 return 0; 68 return 0;
89 }
90 skb_put(buf, new_tlv_space); 69 skb_put(buf, new_tlv_space);
91 tlv->tlv_type = htons(tlv_type); 70 tlv->tlv_type = htons(tlv_type);
92 tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size)); 71 tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size));
@@ -95,7 +74,7 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
95 return 1; 74 return 1;
96} 75}
97 76
98struct 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)
99{ 78{
100 struct sk_buff *buf; 79 struct sk_buff *buf;
101 __be32 value_net; 80 __be32 value_net;
@@ -109,6 +88,11 @@ struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
109 return buf; 88 return buf;
110} 89}
111 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
112struct 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)
113{ 97{
114 struct sk_buff *buf; 98 struct sk_buff *buf;
@@ -120,139 +104,6 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
120 return buf; 104 return buf;
121} 105}
122 106
123
124#if 0
125
126/* Now obsolete code for handling commands not yet implemented the new way */
127
128/*
129 * Some of this code assumed that the manager structure contains two added
130 * fields:
131 * u32 link_subscriptions;
132 * struct list_head link_subscribers;
133 * which are currently not present. These fields may need to be re-introduced
134 * if and when support for link subscriptions is added.
135 */
136
137void tipc_cfg_link_event(u32 addr, char *name, int up)
138{
139 /* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */
140}
141
142int tipc_cfg_cmd(const struct tipc_cmd_msg * msg,
143 char *data,
144 u32 sz,
145 u32 *ret_size,
146 struct tipc_portid *orig)
147{
148 int rv = -EINVAL;
149 u32 cmd = msg->cmd;
150
151 *ret_size = 0;
152 switch (cmd) {
153 case TIPC_REMOVE_LINK:
154 case TIPC_CMD_BLOCK_LINK:
155 case TIPC_CMD_UNBLOCK_LINK:
156 if (!cfg_check_connection(orig))
157 rv = link_control(msg->argv.link_name, msg->cmd, 0);
158 break;
159 case TIPC_ESTABLISH:
160 {
161 int connected;
162
163 tipc_isconnected(mng.conn_port_ref, &connected);
164 if (connected || !orig) {
165 rv = TIPC_FAILURE;
166 break;
167 }
168 rv = tipc_connect2port(mng.conn_port_ref, orig);
169 if (rv == TIPC_OK)
170 orig = 0;
171 break;
172 }
173 case TIPC_GET_PEER_ADDRESS:
174 *ret_size = link_peer_addr(msg->argv.link_name, data, sz);
175 break;
176 case TIPC_GET_ROUTES:
177 rv = TIPC_OK;
178 break;
179 default: {}
180 }
181 if (*ret_size)
182 rv = TIPC_OK;
183 return rv;
184}
185
186static void cfg_cmd_event(struct tipc_cmd_msg *msg,
187 char *data,
188 u32 sz,
189 struct tipc_portid const *orig)
190{
191 int rv = -EINVAL;
192 struct tipc_cmd_result_msg rmsg;
193 struct iovec msg_sect[2];
194 int *arg;
195
196 msg->cmd = ntohl(msg->cmd);
197
198 cfg_prepare_res_msg(msg->cmd, msg->usr_handle, rv, &rmsg, msg_sect,
199 data, 0);
200 if (ntohl(msg->magic) != TIPC_MAGIC)
201 goto exit;
202
203 switch (msg->cmd) {
204 case TIPC_CREATE_LINK:
205 if (!cfg_check_connection(orig))
206 rv = disc_create_link(&msg->argv.create_link);
207 break;
208 case TIPC_LINK_SUBSCRIBE:
209 {
210 struct subscr_data *sub;
211
212 if (mng.link_subscriptions > 64)
213 break;
214 sub = kmalloc(sizeof(*sub),
215 GFP_ATOMIC);
216 if (sub == NULL) {
217 warn("Memory squeeze; dropped remote link subscription\n");
218 break;
219 }
220 INIT_LIST_HEAD(&sub->subd_list);
221 tipc_createport(mng.user_ref,
222 (void *)sub,
223 TIPC_HIGH_IMPORTANCE,
224 0,
225 0,
226 (tipc_conn_shutdown_event)cfg_linksubscr_cancel,
227 0,
228 0,
229 (tipc_conn_msg_event)cfg_linksubscr_cancel,
230 0,
231 &sub->port_ref);
232 if (!sub->port_ref) {
233 kfree(sub);
234 break;
235 }
236 memcpy(sub->usr_handle,msg->usr_handle,
237 sizeof(sub->usr_handle));
238 sub->domain = msg->argv.domain;
239 list_add_tail(&sub->subd_list, &mng.link_subscribers);
240 tipc_connect2port(sub->port_ref, orig);
241 rmsg.retval = TIPC_OK;
242 tipc_send(sub->port_ref, 2u, msg_sect);
243 mng.link_subscriptions++;
244 return;
245 }
246 default:
247 rv = tipc_cfg_cmd(msg, data, sz, (u32 *)&msg_sect[1].iov_len, orig);
248 }
249exit:
250 rmsg.result_len = htonl(msg_sect[1].iov_len);
251 rmsg.retval = htonl(rv);
252 tipc_cfg_respond(msg_sect, 2u, orig);
253}
254#endif
255
256#define MAX_STATS_INFO 2000 107#define MAX_STATS_INFO 2000
257 108
258static struct sk_buff *tipc_show_stats(void) 109static struct sk_buff *tipc_show_stats(void)
@@ -297,7 +148,7 @@ static struct sk_buff *cfg_enable_bearer(void)
297 148
298 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area); 149 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area);
299 if (tipc_enable_bearer(args->name, 150 if (tipc_enable_bearer(args->name,
300 ntohl(args->detect_scope), 151 ntohl(args->disc_domain),
301 ntohl(args->priority))) 152 ntohl(args->priority)))
302 return tipc_cfg_reply_error_string("unable to enable bearer"); 153 return tipc_cfg_reply_error_string("unable to enable bearer");
303 154
@@ -409,70 +260,6 @@ static struct sk_buff *cfg_set_max_ports(void)
409 return tipc_cfg_reply_none(); 260 return tipc_cfg_reply_none();
410} 261}
411 262
412static struct sk_buff *cfg_set_max_zones(void)
413{
414 u32 value;
415
416 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
417 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
418 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
419 if (value == tipc_max_zones)
420 return tipc_cfg_reply_none();
421 if (value != delimit(value, 1, 255))
422 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
423 " (max zones must be 1-255)");
424 if (tipc_mode == TIPC_NET_MODE)
425 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
426 " (cannot change max zones once TIPC has joined a network)");
427 tipc_max_zones = value;
428 return tipc_cfg_reply_none();
429}
430
431static struct sk_buff *cfg_set_max_clusters(void)
432{
433 u32 value;
434
435 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
436 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
437 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
438 if (value != delimit(value, 1, 1))
439 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
440 " (max clusters fixed at 1)");
441 return tipc_cfg_reply_none();
442}
443
444static struct sk_buff *cfg_set_max_nodes(void)
445{
446 u32 value;
447
448 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
449 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
450 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
451 if (value == tipc_max_nodes)
452 return tipc_cfg_reply_none();
453 if (value != delimit(value, 8, 2047))
454 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
455 " (max nodes must be 8-2047)");
456 if (tipc_mode == TIPC_NET_MODE)
457 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
458 " (cannot change max nodes once TIPC has joined a network)");
459 tipc_max_nodes = value;
460 return tipc_cfg_reply_none();
461}
462
463static struct sk_buff *cfg_set_max_slaves(void)
464{
465 u32 value;
466
467 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
468 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
469 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
470 if (value != 0)
471 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
472 " (max secondary nodes fixed at 0)");
473 return tipc_cfg_reply_none();
474}
475
476static struct sk_buff *cfg_set_netid(void) 263static struct sk_buff *cfg_set_netid(void)
477{ 264{
478 u32 value; 265 u32 value;
@@ -516,8 +303,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
516 } else if (!tipc_remote_management) { 303 } else if (!tipc_remote_management) {
517 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE); 304 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
518 goto exit; 305 goto exit;
519 } 306 } else if (cmd >= 0x4000) {
520 else if (cmd >= 0x4000) {
521 u32 domain = 0; 307 u32 domain = 0;
522 308
523 if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) || 309 if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
@@ -557,14 +343,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
557 case TIPC_CMD_SHOW_PORTS: 343 case TIPC_CMD_SHOW_PORTS:
558 rep_tlv_buf = tipc_port_get_ports(); 344 rep_tlv_buf = tipc_port_get_ports();
559 break; 345 break;
560#if 0
561 case TIPC_CMD_SHOW_PORT_STATS:
562 rep_tlv_buf = port_show_stats(req_tlv_area, req_tlv_space);
563 break;
564 case TIPC_CMD_RESET_PORT_STATS:
565 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED);
566 break;
567#endif
568 case TIPC_CMD_SET_LOG_SIZE: 346 case TIPC_CMD_SET_LOG_SIZE:
569 rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space); 347 rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space);
570 break; 348 break;
@@ -600,18 +378,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
600 case TIPC_CMD_SET_MAX_SUBSCR: 378 case TIPC_CMD_SET_MAX_SUBSCR:
601 rep_tlv_buf = cfg_set_max_subscriptions(); 379 rep_tlv_buf = cfg_set_max_subscriptions();
602 break; 380 break;
603 case TIPC_CMD_SET_MAX_ZONES:
604 rep_tlv_buf = cfg_set_max_zones();
605 break;
606 case TIPC_CMD_SET_MAX_CLUSTERS:
607 rep_tlv_buf = cfg_set_max_clusters();
608 break;
609 case TIPC_CMD_SET_MAX_NODES:
610 rep_tlv_buf = cfg_set_max_nodes();
611 break;
612 case TIPC_CMD_SET_MAX_SLAVES:
613 rep_tlv_buf = cfg_set_max_slaves();
614 break;
615 case TIPC_CMD_SET_NETID: 381 case TIPC_CMD_SET_NETID:
616 rep_tlv_buf = cfg_set_netid(); 382 rep_tlv_buf = cfg_set_netid();
617 break; 383 break;
@@ -627,18 +393,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
627 case TIPC_CMD_GET_MAX_SUBSCR: 393 case TIPC_CMD_GET_MAX_SUBSCR:
628 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions); 394 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions);
629 break; 395 break;
630 case TIPC_CMD_GET_MAX_ZONES:
631 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_zones);
632 break;
633 case TIPC_CMD_GET_MAX_CLUSTERS:
634 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_clusters);
635 break;
636 case TIPC_CMD_GET_MAX_NODES:
637 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes);
638 break;
639 case TIPC_CMD_GET_MAX_SLAVES:
640 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_slaves);
641 break;
642 case TIPC_CMD_GET_NETID: 396 case TIPC_CMD_GET_NETID:
643 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 397 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
644 break; 398 break;
@@ -646,6 +400,17 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
646 rep_tlv_buf = 400 rep_tlv_buf =
647 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); 401 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
648 break; 402 break;
403 case TIPC_CMD_SET_MAX_ZONES:
404 case TIPC_CMD_GET_MAX_ZONES:
405 case TIPC_CMD_SET_MAX_SLAVES:
406 case TIPC_CMD_GET_MAX_SLAVES:
407 case TIPC_CMD_SET_MAX_CLUSTERS:
408 case TIPC_CMD_GET_MAX_CLUSTERS:
409 case TIPC_CMD_SET_MAX_NODES:
410 case TIPC_CMD_GET_MAX_NODES:
411 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
412 " (obsolete command)");
413 break;
649 default: 414 default:
650 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 415 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
651 " (unknown command)"); 416 " (unknown command)");
@@ -708,20 +473,16 @@ int tipc_cfg_init(void)
708 struct tipc_name_seq seq; 473 struct tipc_name_seq seq;
709 int res; 474 int res;
710 475
711 res = tipc_attach(&mng.user_ref, NULL, NULL); 476 res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
712 if (res)
713 goto failed;
714
715 res = tipc_createport(mng.user_ref, NULL, TIPC_CRITICAL_IMPORTANCE,
716 NULL, NULL, NULL, 477 NULL, NULL, NULL,
717 NULL, cfg_named_msg_event, NULL, 478 NULL, cfg_named_msg_event, NULL,
718 NULL, &mng.port_ref); 479 NULL, &config_port_ref);
719 if (res) 480 if (res)
720 goto failed; 481 goto failed;
721 482
722 seq.type = TIPC_CFG_SRV; 483 seq.type = TIPC_CFG_SRV;
723 seq.lower = seq.upper = tipc_own_addr; 484 seq.lower = seq.upper = tipc_own_addr;
724 res = tipc_nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq); 485 res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq);
725 if (res) 486 if (res)
726 goto failed; 487 goto failed;
727 488
@@ -729,15 +490,13 @@ int tipc_cfg_init(void)
729 490
730failed: 491failed:
731 err("Unable to create configuration service\n"); 492 err("Unable to create configuration service\n");
732 tipc_detach(mng.user_ref);
733 mng.user_ref = 0;
734 return res; 493 return res;
735} 494}
736 495
737void tipc_cfg_stop(void) 496void tipc_cfg_stop(void)
738{ 497{
739 if (mng.user_ref) { 498 if (config_port_ref) {
740 tipc_detach(mng.user_ref); 499 tipc_deleteport(config_port_ref);
741 mng.user_ref = 0; 500 config_port_ref = 0;
742 } 501 }
743} 502}
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 696468117985..943b6af84265 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -2,7 +2,7 @@
2 * net/tipc/core.c: TIPC module code 2 * net/tipc/core.c: TIPC module code
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -34,37 +34,13 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <linux/init.h>
38#include <linux/module.h>
39#include <linux/kernel.h>
40#include <linux/random.h>
41
42#include "core.h" 37#include "core.h"
43#include "dbg.h"
44#include "ref.h" 38#include "ref.h"
45#include "net.h"
46#include "user_reg.h"
47#include "name_table.h" 39#include "name_table.h"
48#include "subscr.h" 40#include "subscr.h"
49#include "config.h" 41#include "config.h"
50 42
51 43
52#ifndef CONFIG_TIPC_ZONES
53#define CONFIG_TIPC_ZONES 3
54#endif
55
56#ifndef CONFIG_TIPC_CLUSTERS
57#define CONFIG_TIPC_CLUSTERS 1
58#endif
59
60#ifndef CONFIG_TIPC_NODES
61#define CONFIG_TIPC_NODES 255
62#endif
63
64#ifndef CONFIG_TIPC_SLAVE_NODES
65#define CONFIG_TIPC_SLAVE_NODES 0
66#endif
67
68#ifndef CONFIG_TIPC_PORTS 44#ifndef CONFIG_TIPC_PORTS
69#define CONFIG_TIPC_PORTS 8191 45#define CONFIG_TIPC_PORTS 8191
70#endif 46#endif
@@ -77,7 +53,6 @@
77 53
78int tipc_mode = TIPC_NOT_RUNNING; 54int tipc_mode = TIPC_NOT_RUNNING;
79int tipc_random; 55int tipc_random;
80atomic_t tipc_user_count = ATOMIC_INIT(0);
81 56
82const char tipc_alphabet[] = 57const char tipc_alphabet[] =
83 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."; 58 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";
@@ -85,10 +60,6 @@ const char tipc_alphabet[] =
85/* configurable TIPC parameters */ 60/* configurable TIPC parameters */
86 61
87u32 tipc_own_addr; 62u32 tipc_own_addr;
88int tipc_max_zones;
89int tipc_max_clusters;
90int tipc_max_nodes;
91int tipc_max_slaves;
92int tipc_max_ports; 63int tipc_max_ports;
93int tipc_max_subscriptions; 64int tipc_max_subscriptions;
94int tipc_max_publications; 65int tipc_max_publications;
@@ -96,13 +67,8 @@ int tipc_net_id;
96int tipc_remote_management; 67int tipc_remote_management;
97 68
98 69
99int tipc_get_mode(void)
100{
101 return tipc_mode;
102}
103
104/** 70/**
105 * buf_acquire - creates a TIPC message buffer 71 * tipc_buf_acquire - creates a TIPC message buffer
106 * @size: message size (including TIPC header) 72 * @size: message size (including TIPC header)
107 * 73 *
108 * Returns a new buffer with data pointers set to the specified size. 74 * Returns a new buffer with data pointers set to the specified size.
@@ -111,7 +77,7 @@ int tipc_get_mode(void)
111 * There may also be unrequested tailroom present at the buffer's end. 77 * There may also be unrequested tailroom present at the buffer's end.
112 */ 78 */
113 79
114struct sk_buff *buf_acquire(u32 size) 80struct sk_buff *tipc_buf_acquire(u32 size)
115{ 81{
116 struct sk_buff *skb; 82 struct sk_buff *skb;
117 unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u; 83 unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
@@ -129,7 +95,7 @@ struct sk_buff *buf_acquire(u32 size)
129 * tipc_core_stop_net - shut down TIPC networking sub-systems 95 * tipc_core_stop_net - shut down TIPC networking sub-systems
130 */ 96 */
131 97
132void tipc_core_stop_net(void) 98static void tipc_core_stop_net(void)
133{ 99{
134 tipc_eth_media_stop(); 100 tipc_eth_media_stop();
135 tipc_net_stop(); 101 tipc_net_stop();
@@ -143,10 +109,11 @@ int tipc_core_start_net(unsigned long addr)
143{ 109{
144 int res; 110 int res;
145 111
146 if ((res = tipc_net_start(addr)) || 112 res = tipc_net_start(addr);
147 (res = tipc_eth_media_start())) { 113 if (!res)
114 res = tipc_eth_media_start();
115 if (res)
148 tipc_core_stop_net(); 116 tipc_core_stop_net();
149 }
150 return res; 117 return res;
151} 118}
152 119
@@ -154,7 +121,7 @@ int tipc_core_start_net(unsigned long addr)
154 * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode 121 * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode
155 */ 122 */
156 123
157void tipc_core_stop(void) 124static void tipc_core_stop(void)
158{ 125{
159 if (tipc_mode != TIPC_NODE_MODE) 126 if (tipc_mode != TIPC_NODE_MODE)
160 return; 127 return;
@@ -165,17 +132,17 @@ void tipc_core_stop(void)
165 tipc_handler_stop(); 132 tipc_handler_stop();
166 tipc_cfg_stop(); 133 tipc_cfg_stop();
167 tipc_subscr_stop(); 134 tipc_subscr_stop();
168 tipc_reg_stop();
169 tipc_nametbl_stop(); 135 tipc_nametbl_stop();
170 tipc_ref_table_stop(); 136 tipc_ref_table_stop();
171 tipc_socket_stop(); 137 tipc_socket_stop();
138 tipc_log_resize(0);
172} 139}
173 140
174/** 141/**
175 * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode 142 * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode
176 */ 143 */
177 144
178int tipc_core_start(void) 145static int tipc_core_start(void)
179{ 146{
180 int res; 147 int res;
181 148
@@ -185,16 +152,22 @@ int tipc_core_start(void)
185 get_random_bytes(&tipc_random, sizeof(tipc_random)); 152 get_random_bytes(&tipc_random, sizeof(tipc_random));
186 tipc_mode = TIPC_NODE_MODE; 153 tipc_mode = TIPC_NODE_MODE;
187 154
188 if ((res = tipc_handler_start()) || 155 res = tipc_handler_start();
189 (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) || 156 if (!res)
190 (res = tipc_reg_start()) || 157 res = tipc_ref_table_init(tipc_max_ports, tipc_random);
191 (res = tipc_nametbl_init()) || 158 if (!res)
192 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || 159 res = tipc_nametbl_init();
193 (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) || 160 if (!res)
194 (res = tipc_netlink_start()) || 161 res = tipc_k_signal((Handler)tipc_subscr_start, 0);
195 (res = tipc_socket_init())) { 162 if (!res)
163 res = tipc_k_signal((Handler)tipc_cfg_init, 0);
164 if (!res)
165 res = tipc_netlink_start();
166 if (!res)
167 res = tipc_socket_init();
168 if (res)
196 tipc_core_stop(); 169 tipc_core_stop();
197 } 170
198 return res; 171 return res;
199} 172}
200 173
@@ -203,22 +176,20 @@ static int __init tipc_init(void)
203{ 176{
204 int res; 177 int res;
205 178
206 tipc_log_resize(CONFIG_TIPC_LOG); 179 if (tipc_log_resize(CONFIG_TIPC_LOG) != 0)
207 info("Activated (version " TIPC_MOD_VER 180 warn("Unable to create log buffer\n");
208 " compiled " __DATE__ " " __TIME__ ")\n"); 181
182 info("Activated (version " TIPC_MOD_VER ")\n");
209 183
210 tipc_own_addr = 0; 184 tipc_own_addr = 0;
211 tipc_remote_management = 1; 185 tipc_remote_management = 1;
212 tipc_max_publications = 10000; 186 tipc_max_publications = 10000;
213 tipc_max_subscriptions = 2000; 187 tipc_max_subscriptions = 2000;
214 tipc_max_ports = CONFIG_TIPC_PORTS; 188 tipc_max_ports = CONFIG_TIPC_PORTS;
215 tipc_max_zones = CONFIG_TIPC_ZONES;
216 tipc_max_clusters = CONFIG_TIPC_CLUSTERS;
217 tipc_max_nodes = CONFIG_TIPC_NODES;
218 tipc_max_slaves = CONFIG_TIPC_SLAVE_NODES;
219 tipc_net_id = 4711; 189 tipc_net_id = 4711;
220 190
221 if ((res = tipc_core_start())) 191 res = tipc_core_start();
192 if (res)
222 err("Unable to start in single node mode\n"); 193 err("Unable to start in single node mode\n");
223 else 194 else
224 info("Started in single node mode\n"); 195 info("Started in single node mode\n");
@@ -230,7 +201,6 @@ static void __exit tipc_exit(void)
230 tipc_core_stop_net(); 201 tipc_core_stop_net();
231 tipc_core_stop(); 202 tipc_core_stop();
232 info("Deactivated\n"); 203 info("Deactivated\n");
233 tipc_log_resize(0);
234} 204}
235 205
236module_init(tipc_init); 206module_init(tipc_init);
@@ -239,60 +209,3 @@ module_exit(tipc_exit);
239MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication"); 209MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication");
240MODULE_LICENSE("Dual BSD/GPL"); 210MODULE_LICENSE("Dual BSD/GPL");
241MODULE_VERSION(TIPC_MOD_VER); 211MODULE_VERSION(TIPC_MOD_VER);
242
243/* Native TIPC API for kernel-space applications (see tipc.h) */
244
245EXPORT_SYMBOL(tipc_attach);
246EXPORT_SYMBOL(tipc_detach);
247EXPORT_SYMBOL(tipc_get_addr);
248EXPORT_SYMBOL(tipc_get_mode);
249EXPORT_SYMBOL(tipc_createport);
250EXPORT_SYMBOL(tipc_deleteport);
251EXPORT_SYMBOL(tipc_ownidentity);
252EXPORT_SYMBOL(tipc_portimportance);
253EXPORT_SYMBOL(tipc_set_portimportance);
254EXPORT_SYMBOL(tipc_portunreliable);
255EXPORT_SYMBOL(tipc_set_portunreliable);
256EXPORT_SYMBOL(tipc_portunreturnable);
257EXPORT_SYMBOL(tipc_set_portunreturnable);
258EXPORT_SYMBOL(tipc_publish);
259EXPORT_SYMBOL(tipc_withdraw);
260EXPORT_SYMBOL(tipc_connect2port);
261EXPORT_SYMBOL(tipc_disconnect);
262EXPORT_SYMBOL(tipc_shutdown);
263EXPORT_SYMBOL(tipc_isconnected);
264EXPORT_SYMBOL(tipc_peer);
265EXPORT_SYMBOL(tipc_ref_valid);
266EXPORT_SYMBOL(tipc_send);
267EXPORT_SYMBOL(tipc_send_buf);
268EXPORT_SYMBOL(tipc_send2name);
269EXPORT_SYMBOL(tipc_forward2name);
270EXPORT_SYMBOL(tipc_send_buf2name);
271EXPORT_SYMBOL(tipc_forward_buf2name);
272EXPORT_SYMBOL(tipc_send2port);
273EXPORT_SYMBOL(tipc_forward2port);
274EXPORT_SYMBOL(tipc_send_buf2port);
275EXPORT_SYMBOL(tipc_forward_buf2port);
276EXPORT_SYMBOL(tipc_multicast);
277/* EXPORT_SYMBOL(tipc_multicast_buf); not available yet */
278EXPORT_SYMBOL(tipc_ispublished);
279EXPORT_SYMBOL(tipc_available_nodes);
280
281/* TIPC API for external bearers (see tipc_bearer.h) */
282
283EXPORT_SYMBOL(tipc_block_bearer);
284EXPORT_SYMBOL(tipc_continue);
285EXPORT_SYMBOL(tipc_disable_bearer);
286EXPORT_SYMBOL(tipc_enable_bearer);
287EXPORT_SYMBOL(tipc_recv_msg);
288EXPORT_SYMBOL(tipc_register_media);
289
290/* TIPC API for external APIs (see tipc_port.h) */
291
292EXPORT_SYMBOL(tipc_createport_raw);
293EXPORT_SYMBOL(tipc_reject_msg);
294EXPORT_SYMBOL(tipc_send_buf_fast);
295EXPORT_SYMBOL(tipc_acknowledge);
296EXPORT_SYMBOL(tipc_get_port);
297EXPORT_SYMBOL(tipc_get_handle);
298
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 188799017abd..436dda1159d2 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -2,7 +2,7 @@
2 * net/tipc/core.h: Include file for TIPC global declarations 2 * net/tipc/core.h: Include file for TIPC global declarations
3 * 3 *
4 * Copyright (c) 2005-2006, Ericsson AB 4 * Copyright (c) 2005-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -39,10 +39,6 @@
39 39
40#include <linux/tipc.h> 40#include <linux/tipc.h>
41#include <linux/tipc_config.h> 41#include <linux/tipc_config.h>
42#include <net/tipc/tipc_msg.h>
43#include <net/tipc/tipc_port.h>
44#include <net/tipc/tipc_bearer.h>
45#include <net/tipc/tipc.h>
46#include <linux/types.h> 42#include <linux/types.h>
47#include <linux/kernel.h> 43#include <linux/kernel.h>
48#include <linux/errno.h> 44#include <linux/errno.h>
@@ -62,6 +58,9 @@
62 58
63#define TIPC_MOD_VER "2.0.0" 59#define TIPC_MOD_VER "2.0.0"
64 60
61struct tipc_msg; /* msg.h */
62struct print_buf; /* log.h */
63
65/* 64/*
66 * TIPC sanity test macros 65 * TIPC sanity test macros
67 */ 66 */
@@ -83,7 +82,6 @@
83 * 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;
84 * user-defined buffers can be configured to do the same thing. 83 * user-defined buffers can be configured to do the same thing.
85 */ 84 */
86
87extern struct print_buf *const TIPC_NULL; 85extern struct print_buf *const TIPC_NULL;
88extern struct print_buf *const TIPC_CONS; 86extern struct print_buf *const TIPC_CONS;
89extern struct print_buf *const TIPC_LOG; 87extern struct print_buf *const TIPC_LOG;
@@ -98,73 +96,35 @@ void tipc_printf(struct print_buf *, const char *fmt, ...);
98#define TIPC_OUTPUT TIPC_LOG 96#define TIPC_OUTPUT TIPC_LOG
99#endif 97#endif
100 98
101/*
102 * TIPC can be configured to send system messages to TIPC_OUTPUT
103 * or to the system console only.
104 */
105
106#ifdef CONFIG_TIPC_DEBUG
107
108#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 99#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
109 KERN_ERR "TIPC: " fmt, ## arg) 100 KERN_ERR "TIPC: " fmt, ## arg)
110#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 101#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
111 KERN_WARNING "TIPC: " fmt, ## arg) 102 KERN_WARNING "TIPC: " fmt, ## arg)
112#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ 103#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
113 KERN_NOTICE "TIPC: " fmt, ## arg) 104 KERN_NOTICE "TIPC: " fmt, ## arg)
114
115#else
116
117#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg)
118#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg)
119#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg)
120 105
121#endif 106#ifdef CONFIG_TIPC_DEBUG
122 107
123/* 108/*
124 * DBG_OUTPUT is the destination print buffer for debug messages. 109 * DBG_OUTPUT is the destination print buffer for debug messages.
125 * It defaults to the the null print buffer, but can be redefined
126 * (typically in the individual .c files being debugged) to allow
127 * selected debug messages to be generated where needed.
128 */ 110 */
129 111
130#ifndef DBG_OUTPUT 112#ifndef DBG_OUTPUT
131#define DBG_OUTPUT TIPC_NULL 113#define DBG_OUTPUT TIPC_LOG
132#endif 114#endif
133 115
134/* 116#define dbg(fmt, arg...) tipc_printf(DBG_OUTPUT, KERN_DEBUG fmt, ## arg);
135 * TIPC can be configured to send debug messages to the specified print buffer
136 * (typically DBG_OUTPUT) or to suppress them entirely.
137 */
138 117
139#ifdef CONFIG_TIPC_DEBUG 118#define msg_dbg(msg, txt) tipc_msg_dbg(DBG_OUTPUT, msg, txt);
140
141#define dbg(fmt, arg...) \
142 do { \
143 if (DBG_OUTPUT != TIPC_NULL) \
144 tipc_printf(DBG_OUTPUT, fmt, ## arg); \
145 } while (0)
146#define msg_dbg(msg, txt) \
147 do { \
148 if (DBG_OUTPUT != TIPC_NULL) \
149 tipc_msg_dbg(DBG_OUTPUT, msg, txt); \
150 } while (0)
151#define dump(fmt, arg...) \
152 do { \
153 if (DBG_OUTPUT != TIPC_NULL) \
154 tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \
155 } while (0)
156 119
157void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); 120void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
158void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
159 121
160#else 122#else
161 123
162#define dbg(fmt, arg...) do {} while (0) 124#define dbg(fmt, arg...) do {} while (0)
163#define msg_dbg(msg, txt) do {} while (0) 125#define msg_dbg(msg, txt) do {} while (0)
164#define dump(fmt, arg...) do {} while (0)
165 126
166#define tipc_msg_dbg(...) do {} while (0) 127#define tipc_msg_dbg(buf, msg, txt) do {} while (0)
167#define tipc_dump_dbg(...) do {} while (0)
168 128
169#endif 129#endif
170 130
@@ -176,14 +136,17 @@ void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
176#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */ 136#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
177 137
178/* 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/*
179 * Global configuration variables 146 * Global configuration variables
180 */ 147 */
181 148
182extern u32 tipc_own_addr; 149extern u32 tipc_own_addr;
183extern int tipc_max_zones;
184extern int tipc_max_clusters;
185extern int tipc_max_nodes;
186extern int tipc_max_slaves;
187extern int tipc_max_ports; 150extern int tipc_max_ports;
188extern int tipc_max_subscriptions; 151extern int tipc_max_subscriptions;
189extern int tipc_max_publications; 152extern int tipc_max_publications;
@@ -197,17 +160,13 @@ extern int tipc_remote_management;
197extern int tipc_mode; 160extern int tipc_mode;
198extern int tipc_random; 161extern int tipc_random;
199extern const char tipc_alphabet[]; 162extern const char tipc_alphabet[];
200extern atomic_t tipc_user_count;
201 163
202 164
203/* 165/*
204 * Routines available to privileged subsystems 166 * Routines available to privileged subsystems
205 */ 167 */
206 168
207extern int tipc_core_start(void); 169extern int tipc_core_start_net(unsigned long);
208extern void tipc_core_stop(void);
209extern int tipc_core_start_net(unsigned long addr);
210extern void tipc_core_stop_net(void);
211extern int tipc_handler_start(void); 170extern int tipc_handler_start(void);
212extern void tipc_handler_stop(void); 171extern void tipc_handler_stop(void);
213extern int tipc_netlink_start(void); 172extern int tipc_netlink_start(void);
@@ -245,7 +204,6 @@ u32 tipc_k_signal(Handler routine, unsigned long argument);
245static inline void k_init_timer(struct timer_list *timer, Handler routine, 204static inline void k_init_timer(struct timer_list *timer, Handler routine,
246 unsigned long argument) 205 unsigned long argument)
247{ 206{
248 dbg("initializing timer %p\n", timer);
249 setup_timer(timer, routine, argument); 207 setup_timer(timer, routine, argument);
250} 208}
251 209
@@ -265,7 +223,6 @@ static inline void k_init_timer(struct timer_list *timer, Handler routine,
265 223
266static inline void k_start_timer(struct timer_list *timer, unsigned long msec) 224static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
267{ 225{
268 dbg("starting timer %p for %u\n", timer, msec);
269 mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1); 226 mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1);
270} 227}
271 228
@@ -282,7 +239,6 @@ static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
282 239
283static inline void k_cancel_timer(struct timer_list *timer) 240static inline void k_cancel_timer(struct timer_list *timer)
284{ 241{
285 dbg("cancelling timer %p\n", timer);
286 del_timer_sync(timer); 242 del_timer_sync(timer);
287} 243}
288 244
@@ -300,7 +256,6 @@ static inline void k_cancel_timer(struct timer_list *timer)
300 256
301static inline void k_term_timer(struct timer_list *timer) 257static inline void k_term_timer(struct timer_list *timer)
302{ 258{
303 dbg("terminating timer %p\n", timer);
304} 259}
305 260
306 261
@@ -328,7 +283,7 @@ static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
328 return (struct tipc_msg *)skb->data; 283 return (struct tipc_msg *)skb->data;
329} 284}
330 285
331extern struct sk_buff *buf_acquire(u32 size); 286extern struct sk_buff *tipc_buf_acquire(u32 size);
332 287
333/** 288/**
334 * buf_discard - frees a TIPC message buffer 289 * buf_discard - frees a TIPC message buffer
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index fc1fcf5e6b53..0987933155b9 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -2,7 +2,7 @@
2 * net/tipc/discover.c 2 * net/tipc/discover.c
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,97 +35,56 @@
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 1000 /* max 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 60000 /* max delay if bearer has links */
48 44#define TIPC_LINK_REQ_INACTIVE 0xffffffff /* indicates no timer in use */
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/*
60 * TODO: Most of the inter-cluster setup stuff should be
61 * rewritten, and be made conformant with specification.
62 */
63 45
64 46
65/** 47/**
66 * struct link_req - information about an ongoing link setup request 48 * struct link_req - information about an ongoing link setup request
67 * @bearer: bearer issuing requests 49 * @bearer: bearer issuing requests
68 * @dest: destination address for request messages 50 * @dest: destination address for request messages
51 * @domain: network domain to which links can be established
52 * @num_nodes: number of nodes currently discovered (i.e. with an active link)
69 * @buf: request message to be (repeatedly) sent 53 * @buf: request message to be (repeatedly) sent
70 * @timer: timer governing period between requests 54 * @timer: timer governing period between requests
71 * @timer_intv: current interval between requests (in ms) 55 * @timer_intv: current interval between requests (in ms)
72 */ 56 */
73struct link_req { 57struct link_req {
74 struct bearer *bearer; 58 struct tipc_bearer *bearer;
75 struct tipc_media_addr dest; 59 struct tipc_media_addr dest;
60 u32 domain;
61 int num_nodes;
76 struct sk_buff *buf; 62 struct sk_buff *buf;
77 struct timer_list timer; 63 struct timer_list timer;
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)
108 * @req_links: number of links associated with message
109 * @dest_domain: network domain of node(s) which should respond to message 70 * @dest_domain: network domain of node(s) which should respond to message
110 * @b_ptr: ptr to bearer issuing message 71 * @b_ptr: ptr to bearer issuing message
111 */ 72 */
112 73
113static struct sk_buff *tipc_disc_init_msg(u32 type, 74static struct sk_buff *tipc_disc_init_msg(u32 type,
114 u32 req_links,
115 u32 dest_domain, 75 u32 dest_domain,
116 struct bearer *b_ptr) 76 struct tipc_bearer *b_ptr)
117{ 77{
118 struct sk_buff *buf = buf_acquire(DSC_H_SIZE); 78 struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE);
119 struct tipc_msg *msg; 79 struct tipc_msg *msg;
120 80
121 if (buf) { 81 if (buf) {
122 msg = buf_msg(buf); 82 msg = buf_msg(buf);
123 tipc_msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain); 83 tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
124 msg_set_non_seq(msg, 1); 84 msg_set_non_seq(msg, 1);
125 msg_set_req_links(msg, req_links);
126 msg_set_dest_domain(msg, dest_domain); 85 msg_set_dest_domain(msg, dest_domain);
127 msg_set_bc_netid(msg, tipc_net_id); 86 msg_set_bc_netid(msg, tipc_net_id);
128 msg_set_media_addr(msg, &b_ptr->publ.addr); 87 msg_set_media_addr(msg, &b_ptr->addr);
129 } 88 }
130 return buf; 89 return buf;
131} 90}
@@ -137,7 +96,7 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
137 * @media_addr: media address advertised by duplicated node 96 * @media_addr: media address advertised by duplicated node
138 */ 97 */
139 98
140static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr, 99static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr,
141 struct tipc_media_addr *media_addr) 100 struct tipc_media_addr *media_addr)
142{ 101{
143 char node_addr_str[16]; 102 char node_addr_str[16];
@@ -149,7 +108,7 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
149 tipc_media_addr_printf(&pb, media_addr); 108 tipc_media_addr_printf(&pb, media_addr);
150 tipc_printbuf_validate(&pb); 109 tipc_printbuf_validate(&pb);
151 warn("Duplicate %s using %s seen on <%s>\n", 110 warn("Duplicate %s using %s seen on <%s>\n",
152 node_addr_str, media_addr_str, b_ptr->publ.name); 111 node_addr_str, media_addr_str, b_ptr->name);
153} 112}
154 113
155/** 114/**
@@ -158,20 +117,23 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
158 * @b_ptr: bearer that message arrived on 117 * @b_ptr: bearer that message arrived on
159 */ 118 */
160 119
161void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) 120void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
162{ 121{
122 struct tipc_node *n_ptr;
163 struct link *link; 123 struct link *link;
164 struct tipc_media_addr media_addr; 124 struct tipc_media_addr media_addr, *addr;
125 struct sk_buff *rbuf;
165 struct tipc_msg *msg = buf_msg(buf); 126 struct tipc_msg *msg = buf_msg(buf);
166 u32 dest = msg_dest_domain(msg); 127 u32 dest = msg_dest_domain(msg);
167 u32 orig = msg_prevnode(msg); 128 u32 orig = msg_prevnode(msg);
168 u32 net_id = msg_bc_netid(msg); 129 u32 net_id = msg_bc_netid(msg);
169 u32 type = msg_type(msg); 130 u32 type = msg_type(msg);
131 int link_fully_up;
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
136 /* Validate discovery message from requesting node */
175 if (net_id != tipc_net_id) 137 if (net_id != tipc_net_id)
176 return; 138 return;
177 if (!tipc_addr_domain_valid(dest)) 139 if (!tipc_addr_domain_valid(dest))
@@ -179,103 +141,127 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
179 if (!tipc_addr_node_valid(orig)) 141 if (!tipc_addr_node_valid(orig))
180 return; 142 return;
181 if (orig == tipc_own_addr) { 143 if (orig == tipc_own_addr) {
182 if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr))) 144 if (memcmp(&media_addr, &b_ptr->addr, sizeof(media_addr)))
183 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr); 145 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr);
184 return; 146 return;
185 } 147 }
186 if (!tipc_in_scope(dest, tipc_own_addr)) 148 if (!tipc_in_scope(dest, tipc_own_addr))
187 return; 149 return;
188 if (is_slave(tipc_own_addr) && is_slave(orig)) 150 if (!tipc_in_scope(b_ptr->link_req->domain, orig))
189 return; 151 return;
190 if (is_slave(orig) && !in_own_cluster(orig)) 152
153 /* Locate structure corresponding to requesting node */
154 n_ptr = tipc_node_find(orig);
155 if (!n_ptr) {
156 n_ptr = tipc_node_create(orig);
157 if (!n_ptr)
158 return;
159 }
160 tipc_node_lock(n_ptr);
161
162 /* Don't talk to neighbor during cleanup after last session */
163 if (n_ptr->cleanup_required) {
164 tipc_node_unlock(n_ptr);
191 return; 165 return;
192 if (in_own_cluster(orig)) { 166 }
193 /* Always accept link here */ 167
194 struct sk_buff *rbuf; 168 link = n_ptr->links[b_ptr->identity];
195 struct tipc_media_addr *addr; 169
196 struct tipc_node *n_ptr = tipc_node_find(orig); 170 /* Create a link endpoint for this bearer, if necessary */
197 int link_fully_up; 171 if (!link) {
198 172 link = tipc_link_create(n_ptr, b_ptr, &media_addr);
199 dbg(" in own cluster\n");
200 if (n_ptr == NULL) {
201 n_ptr = tipc_node_create(orig);
202 if (!n_ptr)
203 return;
204 }
205 spin_lock_bh(&n_ptr->lock);
206 link = n_ptr->links[b_ptr->identity];
207 if (!link) { 173 if (!link) {
208 dbg("creating link\n"); 174 tipc_node_unlock(n_ptr);
209 link = tipc_link_create(b_ptr, orig, &media_addr); 175 return;
210 if (!link) {
211 spin_unlock_bh(&n_ptr->lock);
212 return;
213 }
214 }
215 addr = &link->media_addr;
216 if (memcmp(addr, &media_addr, sizeof(*addr))) {
217 if (tipc_link_is_up(link) || (!link->started)) {
218 disc_dupl_alert(b_ptr, orig, &media_addr);
219 spin_unlock_bh(&n_ptr->lock);
220 return;
221 }
222 warn("Resetting link <%s>, peer interface address changed\n",
223 link->name);
224 memcpy(addr, &media_addr, sizeof(*addr));
225 tipc_link_reset(link);
226 } 176 }
227 link_fully_up = link_working_working(link); 177 }
228 spin_unlock_bh(&n_ptr->lock); 178
229 if ((type == DSC_RESP_MSG) || link_fully_up) 179 /*
180 * Ensure requesting node's media address is correct
181 *
182 * If media address doesn't match and the link is working, reject the
183 * request (must be from a duplicate node).
184 *
185 * If media address doesn't match and the link is not working, accept
186 * the new media address and reset the link to ensure it starts up
187 * cleanly.
188 */
189 addr = &link->media_addr;
190 if (memcmp(addr, &media_addr, sizeof(*addr))) {
191 if (tipc_link_is_up(link) || (!link->started)) {
192 disc_dupl_alert(b_ptr, orig, &media_addr);
193 tipc_node_unlock(n_ptr);
230 return; 194 return;
231 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); 195 }
232 if (rbuf != NULL) { 196 warn("Resetting link <%s>, peer interface address changed\n",
233 msg_dbg(buf_msg(rbuf),"SEND:"); 197 link->name);
234 b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr); 198 memcpy(addr, &media_addr, sizeof(*addr));
199 tipc_link_reset(link);
200 }
201
202 /* Accept discovery message & send response, if necessary */
203 link_fully_up = link_working_working(link);
204
205 if ((type == DSC_REQ_MSG) && !link_fully_up && !b_ptr->blocked) {
206 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, orig, b_ptr);
207 if (rbuf) {
208 b_ptr->media->send_msg(rbuf, b_ptr, &media_addr);
235 buf_discard(rbuf); 209 buf_discard(rbuf);
236 } 210 }
237 } 211 }
212
213 tipc_node_unlock(n_ptr);
238} 214}
239 215
240/** 216/**
241 * tipc_disc_stop_link_req - stop sending periodic link setup requests 217 * disc_update - update frequency of periodic link setup requests
242 * @req: ptr to link request structure 218 * @req: ptr to link request structure
219 *
220 * Reinitiates discovery process if discovery object has no associated nodes
221 * and is either not currently searching or is searching at a slow rate
243 */ 222 */
244 223
245void tipc_disc_stop_link_req(struct link_req *req) 224static void disc_update(struct link_req *req)
246{ 225{
247 if (!req) 226 if (!req->num_nodes) {
248 return; 227 if ((req->timer_intv == TIPC_LINK_REQ_INACTIVE) ||
228 (req->timer_intv > TIPC_LINK_REQ_FAST)) {
229 req->timer_intv = TIPC_LINK_REQ_INIT;
230 k_start_timer(&req->timer, req->timer_intv);
231 }
232 }
233}
249 234
250 k_cancel_timer(&req->timer); 235/**
251 k_term_timer(&req->timer); 236 * tipc_disc_add_dest - increment set of discovered nodes
252 buf_discard(req->buf); 237 * @req: ptr to link request structure
253 kfree(req); 238 */
239
240void tipc_disc_add_dest(struct link_req *req)
241{
242 req->num_nodes++;
254} 243}
255 244
256/** 245/**
257 * tipc_disc_update_link_req - update frequency of periodic link setup requests 246 * tipc_disc_remove_dest - decrement set of discovered nodes
258 * @req: ptr to link request structure 247 * @req: ptr to link request structure
259 */ 248 */
260 249
261void tipc_disc_update_link_req(struct link_req *req) 250void tipc_disc_remove_dest(struct link_req *req)
262{ 251{
263 if (!req) 252 req->num_nodes--;
264 return; 253 disc_update(req);
254}
265 255
266 if (req->timer_intv == TIPC_LINK_REQ_SLOW) { 256/**
267 if (!req->bearer->nodes.count) { 257 * disc_send_msg - send link setup request message
268 req->timer_intv = TIPC_LINK_REQ_FAST; 258 * @req: ptr to link request structure
269 k_start_timer(&req->timer, req->timer_intv); 259 */
270 } 260
271 } else if (req->timer_intv == TIPC_LINK_REQ_FAST) { 261static void disc_send_msg(struct link_req *req)
272 if (req->bearer->nodes.count) { 262{
273 req->timer_intv = TIPC_LINK_REQ_SLOW; 263 if (!req->bearer->blocked)
274 k_start_timer(&req->timer, req->timer_intv); 264 tipc_bearer_send(req->bearer, req->buf, &req->dest);
275 }
276 } else {
277 /* leave timer "as is" if haven't yet reached a "normal" rate */
278 }
279} 265}
280 266
281/** 267/**
@@ -287,58 +273,86 @@ void tipc_disc_update_link_req(struct link_req *req)
287 273
288static void disc_timeout(struct link_req *req) 274static void disc_timeout(struct link_req *req)
289{ 275{
290 spin_lock_bh(&req->bearer->publ.lock); 276 int max_delay;
291 277
292 req->bearer->media->send_msg(req->buf, &req->bearer->publ, &req->dest); 278 spin_lock_bh(&req->bearer->lock);
293 279
294 if ((req->timer_intv == TIPC_LINK_REQ_SLOW) || 280 /* Stop searching if only desired node has been found */
295 (req->timer_intv == TIPC_LINK_REQ_FAST)) { 281
296 /* leave timer interval "as is" if already at a "normal" rate */ 282 if (tipc_node(req->domain) && req->num_nodes) {
297 } else { 283 req->timer_intv = TIPC_LINK_REQ_INACTIVE;
298 req->timer_intv *= 2; 284 goto exit;
299 if (req->timer_intv > TIPC_LINK_REQ_FAST)
300 req->timer_intv = TIPC_LINK_REQ_FAST;
301 if ((req->timer_intv == TIPC_LINK_REQ_FAST) &&
302 (req->bearer->nodes.count))
303 req->timer_intv = TIPC_LINK_REQ_SLOW;
304 } 285 }
305 k_start_timer(&req->timer, req->timer_intv);
306 286
307 spin_unlock_bh(&req->bearer->publ.lock); 287 /*
288 * Send discovery message, then update discovery timer
289 *
290 * Keep doubling time between requests until limit is reached;
291 * hold at fast polling rate if don't have any associated nodes,
292 * otherwise hold at slow polling rate
293 */
294
295 disc_send_msg(req);
296
297 req->timer_intv *= 2;
298 if (req->num_nodes)
299 max_delay = TIPC_LINK_REQ_SLOW;
300 else
301 max_delay = TIPC_LINK_REQ_FAST;
302 if (req->timer_intv > max_delay)
303 req->timer_intv = max_delay;
304
305 k_start_timer(&req->timer, req->timer_intv);
306exit:
307 spin_unlock_bh(&req->bearer->lock);
308} 308}
309 309
310/** 310/**
311 * tipc_disc_init_link_req - start sending periodic link setup requests 311 * tipc_disc_create - create object to send periodic link setup requests
312 * @b_ptr: ptr to bearer issuing requests 312 * @b_ptr: ptr to bearer issuing requests
313 * @dest: destination address for request messages 313 * @dest: destination address for request messages
314 * @dest_domain: network domain of node(s) which should respond to message 314 * @dest_domain: network domain to which links can be established
315 * @req_links: max number of desired links
316 * 315 *
317 * Returns pointer to link request structure, or NULL if unable to create. 316 * Returns 0 if successful, otherwise -errno.
318 */ 317 */
319 318
320struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, 319int tipc_disc_create(struct tipc_bearer *b_ptr,
321 const struct tipc_media_addr *dest, 320 struct tipc_media_addr *dest, u32 dest_domain)
322 u32 dest_domain,
323 u32 req_links)
324{ 321{
325 struct link_req *req; 322 struct link_req *req;
326 323
327 req = kmalloc(sizeof(*req), GFP_ATOMIC); 324 req = kmalloc(sizeof(*req), GFP_ATOMIC);
328 if (!req) 325 if (!req)
329 return NULL; 326 return -ENOMEM;
330 327
331 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr); 328 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr);
332 if (!req->buf) { 329 if (!req->buf) {
333 kfree(req); 330 kfree(req);
334 return NULL; 331 return -ENOMSG;
335 } 332 }
336 333
337 memcpy(&req->dest, dest, sizeof(*dest)); 334 memcpy(&req->dest, dest, sizeof(*dest));
338 req->bearer = b_ptr; 335 req->bearer = b_ptr;
336 req->domain = dest_domain;
337 req->num_nodes = 0;
339 req->timer_intv = TIPC_LINK_REQ_INIT; 338 req->timer_intv = TIPC_LINK_REQ_INIT;
340 k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req); 339 k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
341 k_start_timer(&req->timer, req->timer_intv); 340 k_start_timer(&req->timer, req->timer_intv);
342 return req; 341 b_ptr->link_req = req;
342 disc_send_msg(req);
343 return 0;
344}
345
346/**
347 * tipc_disc_delete - destroy object sending periodic link setup requests
348 * @req: ptr to link request structure
349 */
350
351void tipc_disc_delete(struct link_req *req)
352{
353 k_cancel_timer(&req->timer);
354 k_term_timer(&req->timer);
355 buf_discard(req->buf);
356 kfree(req);
343} 357}
344 358
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index c36eaeb7d5d0..a3af595b86cb 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -2,7 +2,7 @@
2 * net/tipc/discover.h 2 * net/tipc/discover.h
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,22 +37,13 @@
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, 42int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest,
45 const struct tipc_media_addr *dest, 43 u32 dest_domain);
46 u32 dest_domain, 44void tipc_disc_delete(struct link_req *req);
47 u32 req_links); 45void tipc_disc_add_dest(struct link_req *req);
48void tipc_disc_update_link_req(struct link_req *req); 46void tipc_disc_remove_dest(struct link_req *req);
49void tipc_disc_stop_link_req(struct link_req *req); 47void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr);
50
51void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr);
52
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 48
58#endif 49#endif
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 6230d16020c4..b69092eb95d8 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -34,12 +34,8 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <net/tipc/tipc.h> 37#include "core.h"
38#include <net/tipc/tipc_bearer.h> 38#include "bearer.h"
39#include <net/tipc/tipc_msg.h>
40#include <linux/netdevice.h>
41#include <linux/slab.h>
42#include <net/net_namespace.h>
43 39
44#define MAX_ETH_BEARERS 2 40#define MAX_ETH_BEARERS 2
45#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI 41#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI
@@ -60,7 +56,7 @@ struct eth_bearer {
60}; 56};
61 57
62static struct eth_bearer eth_bearers[MAX_ETH_BEARERS]; 58static struct eth_bearer eth_bearers[MAX_ETH_BEARERS];
63static int eth_started = 0; 59static int eth_started;
64static struct notifier_block notifier; 60static struct notifier_block notifier;
65 61
66/** 62/**
@@ -72,17 +68,26 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
72{ 68{
73 struct sk_buff *clone; 69 struct sk_buff *clone;
74 struct net_device *dev; 70 struct net_device *dev;
71 int delta;
75 72
76 clone = skb_clone(buf, GFP_ATOMIC); 73 clone = skb_clone(buf, GFP_ATOMIC);
77 if (clone) { 74 if (!clone)
78 skb_reset_network_header(clone); 75 return 0;
79 dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; 76
80 clone->dev = dev; 77 dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev;
81 dev_hard_header(clone, dev, ETH_P_TIPC, 78 delta = dev->hard_header_len - skb_headroom(buf);
82 &dest->dev_addr.eth_addr, 79
83 dev->dev_addr, clone->len); 80 if ((delta > 0) &&
84 dev_queue_xmit(clone); 81 pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
82 kfree_skb(clone);
83 return 0;
85 } 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);
86 return 0; 91 return 0;
87} 92}
88 93
@@ -92,15 +97,12 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
92 * Accept only packets explicitly sent to this node, or broadcast packets; 97 * Accept only packets explicitly sent to this node, or broadcast packets;
93 * ignores packets sent using Ethernet multicast, and traffic sent to other 98 * ignores packets sent using Ethernet multicast, and traffic sent to other
94 * nodes (which can happen if interface is running in promiscuous mode). 99 * nodes (which can happen if interface is running in promiscuous mode).
95 * Routine truncates any Ethernet padding/CRC appended to the message,
96 * and ensures message size matches actual length
97 */ 100 */
98 101
99static int recv_msg(struct sk_buff *buf, struct net_device *dev, 102static int recv_msg(struct sk_buff *buf, struct net_device *dev,
100 struct packet_type *pt, struct net_device *orig_dev) 103 struct packet_type *pt, struct net_device *orig_dev)
101{ 104{
102 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;
103 u32 size;
104 106
105 if (!net_eq(dev_net(dev), &init_net)) { 107 if (!net_eq(dev_net(dev), &init_net)) {
106 kfree_skb(buf); 108 kfree_skb(buf);
@@ -109,13 +111,9 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
109 111
110 if (likely(eb_ptr->bearer)) { 112 if (likely(eb_ptr->bearer)) {
111 if (likely(buf->pkt_type <= PACKET_BROADCAST)) { 113 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
112 size = msg_size((struct tipc_msg *)buf->data); 114 buf->next = NULL;
113 skb_trim(buf, size); 115 tipc_recv_msg(buf, eb_ptr->bearer);
114 if (likely(buf->len == size)) { 116 return 0;
115 buf->next = NULL;
116 tipc_recv_msg(buf, eb_ptr->bearer);
117 return 0;
118 }
119 } 117 }
120 } 118 }
121 kfree_skb(buf); 119 kfree_skb(buf);
@@ -133,10 +131,20 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
133 struct eth_bearer *eb_ptr = &eth_bearers[0]; 131 struct eth_bearer *eb_ptr = &eth_bearers[0];
134 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS]; 132 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
135 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 }
136 144
137 /* Find device with specified name */ 145 /* Find device with specified name */
138 146
139 for_each_netdev(&init_net, pdev){ 147 for_each_netdev(&init_net, pdev) {
140 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) { 148 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
141 dev = pdev; 149 dev = pdev;
142 break; 150 break;
@@ -147,7 +155,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
147 155
148 /* Find Ethernet bearer for device (or create one) */ 156 /* Find Ethernet bearer for device (or create one) */
149 157
150 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++;
151 if (eb_ptr == stop) 160 if (eb_ptr == stop)
152 return -EDQUOT; 161 return -EDQUOT;
153 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 a3616b99529b..5ed4b4f7452d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2,7 +2,7 @@
2 * net/tipc/link.c: TIPC link code 2 * net/tipc/link.c: TIPC link code
3 * 3 *
4 * Copyright (c) 1996-2007, Ericsson AB 4 * Copyright (c) 1996-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,19 +35,11 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "link.h" 38#include "link.h"
40#include "net.h"
41#include "node.h"
42#include "port.h" 39#include "port.h"
43#include "addr.h"
44#include "node_subscr.h"
45#include "name_distr.h" 40#include "name_distr.h"
46#include "bearer.h"
47#include "name_table.h"
48#include "discover.h" 41#include "discover.h"
49#include "config.h" 42#include "config.h"
50#include "bcast.h"
51 43
52 44
53/* 45/*
@@ -57,12 +49,6 @@
57#define INVALID_SESSION 0x10000 49#define INVALID_SESSION 0x10000
58 50
59/* 51/*
60 * Limit for deferred reception queue:
61 */
62
63#define DEF_QUEUE_LIMIT 256u
64
65/*
66 * Link state events: 52 * Link state events:
67 */ 53 */
68 54
@@ -99,99 +85,21 @@ 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);
122static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf); 91static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf);
123static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); 92static void link_set_supervision_props(struct link *l_ptr, u32 tolerance);
124static int link_send_sections_long(struct port *sender, 93static int link_send_sections_long(struct tipc_port *sender,
125 struct iovec const *msg_sect, 94 struct iovec const *msg_sect,
126 u32 num_sect, u32 destnode); 95 u32 num_sect, unsigned int total_len,
96 u32 destnode);
127static void link_check_defragm_bufs(struct link *l_ptr); 97static void link_check_defragm_bufs(struct link *l_ptr);
128static void link_state_event(struct link *l_ptr, u32 event); 98static void link_state_event(struct link *l_ptr, u32 event);
129static void link_reset_statistics(struct link *l_ptr); 99static void link_reset_statistics(struct link *l_ptr);
130static void link_print(struct link *l_ptr, struct print_buf *buf, 100static void link_print(struct link *l_ptr, const char *str);
131 const char *str); 101static void link_start(struct link *l_ptr);
132 102static 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 103
196/* 104/*
197 * Simple link routines 105 * Simple link routines
@@ -206,7 +114,7 @@ static void link_init_max_pkt(struct link *l_ptr)
206{ 114{
207 u32 max_pkt; 115 u32 max_pkt;
208 116
209 max_pkt = (l_ptr->b_ptr->publ.mtu & ~3); 117 max_pkt = (l_ptr->b_ptr->mtu & ~3);
210 if (max_pkt > MAX_MSG_SIZE) 118 if (max_pkt > MAX_MSG_SIZE)
211 max_pkt = MAX_MSG_SIZE; 119 max_pkt = MAX_MSG_SIZE;
212 120
@@ -239,13 +147,13 @@ int tipc_link_is_up(struct link *l_ptr)
239{ 147{
240 if (!l_ptr) 148 if (!l_ptr)
241 return 0; 149 return 0;
242 return (link_working_working(l_ptr) || link_working_unknown(l_ptr)); 150 return link_working_working(l_ptr) || link_working_unknown(l_ptr);
243} 151}
244 152
245int tipc_link_is_active(struct link *l_ptr) 153int tipc_link_is_active(struct link *l_ptr)
246{ 154{
247 return ((l_ptr->owner->active_links[0] == l_ptr) || 155 return (l_ptr->owner->active_links[0] == l_ptr) ||
248 (l_ptr->owner->active_links[1] == l_ptr)); 156 (l_ptr->owner->active_links[1] == l_ptr);
249} 157}
250 158
251/** 159/**
@@ -280,14 +188,17 @@ static int link_name_validate(const char *name, struct link_name *name_parts)
280 /* ensure all component parts of link name are present */ 188 /* ensure all component parts of link name are present */
281 189
282 addr_local = name_copy; 190 addr_local = name_copy;
283 if ((if_local = strchr(addr_local, ':')) == NULL) 191 if_local = strchr(addr_local, ':');
192 if (if_local == NULL)
284 return 0; 193 return 0;
285 *(if_local++) = 0; 194 *(if_local++) = 0;
286 if ((addr_peer = strchr(if_local, '-')) == NULL) 195 addr_peer = strchr(if_local, '-');
196 if (addr_peer == NULL)
287 return 0; 197 return 0;
288 *(addr_peer++) = 0; 198 *(addr_peer++) = 0;
289 if_local_len = addr_peer - if_local; 199 if_local_len = addr_peer - if_local;
290 if ((if_peer = strchr(addr_peer, ':')) == NULL) 200 if_peer = strchr(addr_peer, ':');
201 if (if_peer == NULL)
291 return 0; 202 return 0;
292 *(if_peer++) = 0; 203 *(if_peer++) = 0;
293 if_peer_len = strlen(if_peer) + 1; 204 if_peer_len = strlen(if_peer) + 1;
@@ -336,9 +247,6 @@ static void link_timeout(struct link *l_ptr)
336 l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size; 247 l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size;
337 l_ptr->stats.queue_sz_counts++; 248 l_ptr->stats.queue_sz_counts++;
338 249
339 if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz)
340 l_ptr->stats.max_queue_sz = l_ptr->out_queue_size;
341
342 if (l_ptr->first_out) { 250 if (l_ptr->first_out) {
343 struct tipc_msg *msg = buf_msg(l_ptr->first_out); 251 struct tipc_msg *msg = buf_msg(l_ptr->first_out);
344 u32 length = msg_size(msg); 252 u32 length = msg_size(msg);
@@ -386,39 +294,44 @@ static void link_set_timer(struct link *l_ptr, u32 time)
386 294
387/** 295/**
388 * tipc_link_create - create a new link 296 * tipc_link_create - create a new link
297 * @n_ptr: pointer to associated node
389 * @b_ptr: pointer to associated bearer 298 * @b_ptr: pointer to associated bearer
390 * @peer: network address of node at other end of link
391 * @media_addr: media address to use when sending messages over link 299 * @media_addr: media address to use when sending messages over link
392 * 300 *
393 * Returns pointer to link. 301 * Returns pointer to link.
394 */ 302 */
395 303
396struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, 304struct link *tipc_link_create(struct tipc_node *n_ptr,
305 struct tipc_bearer *b_ptr,
397 const struct tipc_media_addr *media_addr) 306 const struct tipc_media_addr *media_addr)
398{ 307{
399 struct link *l_ptr; 308 struct link *l_ptr;
400 struct tipc_msg *msg; 309 struct tipc_msg *msg;
401 char *if_name; 310 char *if_name;
311 char addr_string[16];
312 u32 peer = n_ptr->addr;
402 313
403 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); 314 if (n_ptr->link_cnt >= 2) {
404 if (!l_ptr) { 315 tipc_addr_string_fill(addr_string, n_ptr->addr);
405 warn("Link creation failed, no memory\n"); 316 err("Attempt to establish third link to %s\n", addr_string);
406 return NULL; 317 return NULL;
407 } 318 }
408 319
409 if (LINK_LOG_BUF_SIZE) { 320 if (n_ptr->links[b_ptr->identity]) {
410 char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); 321 tipc_addr_string_fill(addr_string, n_ptr->addr);
322 err("Attempt to establish second link on <%s> to %s\n",
323 b_ptr->name, addr_string);
324 return NULL;
325 }
411 326
412 if (!pb) { 327 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC);
413 kfree(l_ptr); 328 if (!l_ptr) {
414 warn("Link creation failed, no memory for print buffer\n"); 329 warn("Link creation failed, no memory\n");
415 return NULL; 330 return NULL;
416 }
417 tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
418 } 331 }
419 332
420 l_ptr->addr = peer; 333 l_ptr->addr = peer;
421 if_name = strchr(b_ptr->publ.name, ':') + 1; 334 if_name = strchr(b_ptr->name, ':') + 1;
422 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 335 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:",
423 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 336 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
424 tipc_node(tipc_own_addr), 337 tipc_node(tipc_own_addr),
@@ -426,6 +339,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
426 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 339 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
427 /* note: peer i/f is appended to link name by reset/activate */ 340 /* note: peer i/f is appended to link name by reset/activate */
428 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 341 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
342 l_ptr->owner = n_ptr;
429 l_ptr->checkpoint = 1; 343 l_ptr->checkpoint = 1;
430 l_ptr->b_ptr = b_ptr; 344 l_ptr->b_ptr = b_ptr;
431 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); 345 link_set_supervision_props(l_ptr, b_ptr->media->tolerance);
@@ -449,20 +363,11 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
449 363
450 link_reset_statistics(l_ptr); 364 link_reset_statistics(l_ptr);
451 365
452 l_ptr->owner = tipc_node_attach_link(l_ptr); 366 tipc_node_attach_link(n_ptr, l_ptr);
453 if (!l_ptr->owner) {
454 if (LINK_LOG_BUF_SIZE)
455 kfree(l_ptr->print_buf.buf);
456 kfree(l_ptr);
457 return NULL;
458 }
459 367
460 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); 368 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
461 list_add_tail(&l_ptr->link_list, &b_ptr->links); 369 list_add_tail(&l_ptr->link_list, &b_ptr->links);
462 tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr); 370 tipc_k_signal((Handler)link_start, (unsigned long)l_ptr);
463
464 dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",
465 l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit);
466 371
467 return l_ptr; 372 return l_ptr;
468} 373}
@@ -483,8 +388,6 @@ void tipc_link_delete(struct link *l_ptr)
483 return; 388 return;
484 } 389 }
485 390
486 dbg("tipc_link_delete()\n");
487
488 k_cancel_timer(&l_ptr->timer); 391 k_cancel_timer(&l_ptr->timer);
489 392
490 tipc_node_lock(l_ptr->owner); 393 tipc_node_lock(l_ptr->owner);
@@ -492,17 +395,16 @@ void tipc_link_delete(struct link *l_ptr)
492 tipc_node_detach_link(l_ptr->owner, l_ptr); 395 tipc_node_detach_link(l_ptr->owner, l_ptr);
493 tipc_link_stop(l_ptr); 396 tipc_link_stop(l_ptr);
494 list_del_init(&l_ptr->link_list); 397 list_del_init(&l_ptr->link_list);
495 if (LINK_LOG_BUF_SIZE)
496 kfree(l_ptr->print_buf.buf);
497 tipc_node_unlock(l_ptr->owner); 398 tipc_node_unlock(l_ptr->owner);
498 k_term_timer(&l_ptr->timer); 399 k_term_timer(&l_ptr->timer);
499 kfree(l_ptr); 400 kfree(l_ptr);
500} 401}
501 402
502void tipc_link_start(struct link *l_ptr) 403static void link_start(struct link *l_ptr)
503{ 404{
504 dbg("tipc_link_start %x\n", l_ptr); 405 tipc_node_lock(l_ptr->owner);
505 link_state_event(l_ptr, STARTING_EVT); 406 link_state_event(l_ptr, STARTING_EVT);
407 tipc_node_unlock(l_ptr->owner);
506} 408}
507 409
508/** 410/**
@@ -517,7 +419,7 @@ void tipc_link_start(struct link *l_ptr)
517 419
518static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz) 420static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
519{ 421{
520 struct port *p_ptr; 422 struct tipc_port *p_ptr;
521 423
522 spin_lock_bh(&tipc_port_list_lock); 424 spin_lock_bh(&tipc_port_list_lock);
523 p_ptr = tipc_port_lock(origport); 425 p_ptr = tipc_port_lock(origport);
@@ -526,7 +428,7 @@ static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
526 goto exit; 428 goto exit;
527 if (!list_empty(&p_ptr->wait_list)) 429 if (!list_empty(&p_ptr->wait_list))
528 goto exit; 430 goto exit;
529 p_ptr->publ.congested = 1; 431 p_ptr->congested = 1;
530 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt); 432 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt);
531 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); 433 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports);
532 l_ptr->stats.link_congs++; 434 l_ptr->stats.link_congs++;
@@ -539,8 +441,8 @@ exit:
539 441
540void tipc_link_wakeup_ports(struct link *l_ptr, int all) 442void tipc_link_wakeup_ports(struct link *l_ptr, int all)
541{ 443{
542 struct port *p_ptr; 444 struct tipc_port *p_ptr;
543 struct port *temp_p_ptr; 445 struct tipc_port *temp_p_ptr;
544 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size; 446 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size;
545 447
546 if (all) 448 if (all)
@@ -556,11 +458,11 @@ void tipc_link_wakeup_ports(struct link *l_ptr, int all)
556 if (win <= 0) 458 if (win <= 0)
557 break; 459 break;
558 list_del_init(&p_ptr->wait_list); 460 list_del_init(&p_ptr->wait_list);
559 spin_lock_bh(p_ptr->publ.lock); 461 spin_lock_bh(p_ptr->lock);
560 p_ptr->publ.congested = 0; 462 p_ptr->congested = 0;
561 p_ptr->wakeup(&p_ptr->publ); 463 p_ptr->wakeup(p_ptr);
562 win -= p_ptr->waiting_pkts; 464 win -= p_ptr->waiting_pkts;
563 spin_unlock_bh(p_ptr->publ.lock); 465 spin_unlock_bh(p_ptr->lock);
564 } 466 }
565 467
566exit: 468exit:
@@ -634,39 +536,9 @@ void tipc_link_stop(struct link *l_ptr)
634 l_ptr->proto_msg_queue = NULL; 536 l_ptr->proto_msg_queue = NULL;
635} 537}
636 538
637#if 0
638
639/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ 539/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
640
641static void link_recv_event(struct link_event *ev)
642{
643 ev->fcn(ev->addr, ev->name, ev->up);
644 kfree(ev);
645}
646
647static void link_send_event(void (*fcn)(u32 a, char *n, int up),
648 struct link *l_ptr, int up)
649{
650 struct link_event *ev;
651
652 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
653 if (!ev) {
654 warn("Link event allocation failure\n");
655 return;
656 }
657 ev->addr = l_ptr->addr;
658 ev->up = up;
659 ev->fcn = fcn;
660 memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME);
661 tipc_k_signal((Handler)link_recv_event, (unsigned long)ev);
662}
663
664#else
665
666#define link_send_event(fcn, l_ptr, up) do { } while (0) 540#define link_send_event(fcn, l_ptr, up) do { } while (0)
667 541
668#endif
669
670void tipc_link_reset(struct link *l_ptr) 542void tipc_link_reset(struct link *l_ptr)
671{ 543{
672 struct sk_buff *buf; 544 struct sk_buff *buf;
@@ -683,18 +555,14 @@ void tipc_link_reset(struct link *l_ptr)
683 link_init_max_pkt(l_ptr); 555 link_init_max_pkt(l_ptr);
684 556
685 l_ptr->state = RESET_UNKNOWN; 557 l_ptr->state = RESET_UNKNOWN;
686 dbg_link_state("Resetting Link\n");
687 558
688 if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) 559 if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET))
689 return; 560 return;
690 561
691 tipc_node_link_down(l_ptr->owner, l_ptr); 562 tipc_node_link_down(l_ptr->owner, l_ptr);
692 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); 563 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
693#if 0 564
694 tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name); 565 if (was_active_link && tipc_node_active_links(l_ptr->owner) &&
695 dbg_link_dump();
696#endif
697 if (was_active_link && tipc_node_has_active_links(l_ptr->owner) &&
698 l_ptr->owner->permit_changeover) { 566 l_ptr->owner->permit_changeover) {
699 l_ptr->reset_checkpoint = checkpoint; 567 l_ptr->reset_checkpoint = checkpoint;
700 l_ptr->exp_msg_count = START_CHANGEOVER; 568 l_ptr->exp_msg_count = START_CHANGEOVER;
@@ -760,25 +628,18 @@ static void link_state_event(struct link *l_ptr, unsigned event)
760 return; /* Not yet. */ 628 return; /* Not yet. */
761 629
762 if (link_blocked(l_ptr)) { 630 if (link_blocked(l_ptr)) {
763 if (event == TIMEOUT_EVT) { 631 if (event == TIMEOUT_EVT)
764 link_set_timer(l_ptr, cont_intv); 632 link_set_timer(l_ptr, cont_intv);
765 }
766 return; /* Changeover going on */ 633 return; /* Changeover going on */
767 } 634 }
768 dbg_link("STATE_EV: <%s> ", l_ptr->name);
769 635
770 switch (l_ptr->state) { 636 switch (l_ptr->state) {
771 case WORKING_WORKING: 637 case WORKING_WORKING:
772 dbg_link("WW/");
773 switch (event) { 638 switch (event) {
774 case TRAFFIC_MSG_EVT: 639 case TRAFFIC_MSG_EVT:
775 dbg_link("TRF-");
776 /* fall through */
777 case ACTIVATE_MSG: 640 case ACTIVATE_MSG:
778 dbg_link("ACT\n");
779 break; 641 break;
780 case TIMEOUT_EVT: 642 case TIMEOUT_EVT:
781 dbg_link("TIM ");
782 if (l_ptr->next_in_no != l_ptr->checkpoint) { 643 if (l_ptr->next_in_no != l_ptr->checkpoint) {
783 l_ptr->checkpoint = l_ptr->next_in_no; 644 l_ptr->checkpoint = l_ptr->next_in_no;
784 if (tipc_bclink_acks_missing(l_ptr->owner)) { 645 if (tipc_bclink_acks_missing(l_ptr->owner)) {
@@ -793,7 +654,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
793 link_set_timer(l_ptr, cont_intv); 654 link_set_timer(l_ptr, cont_intv);
794 break; 655 break;
795 } 656 }
796 dbg_link(" -> WU\n");
797 l_ptr->state = WORKING_UNKNOWN; 657 l_ptr->state = WORKING_UNKNOWN;
798 l_ptr->fsm_msg_cnt = 0; 658 l_ptr->fsm_msg_cnt = 0;
799 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); 659 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
@@ -801,7 +661,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
801 link_set_timer(l_ptr, cont_intv / 4); 661 link_set_timer(l_ptr, cont_intv / 4);
802 break; 662 break;
803 case RESET_MSG: 663 case RESET_MSG:
804 dbg_link("RES -> RR\n");
805 info("Resetting link <%s>, requested by peer\n", 664 info("Resetting link <%s>, requested by peer\n",
806 l_ptr->name); 665 l_ptr->name);
807 tipc_link_reset(l_ptr); 666 tipc_link_reset(l_ptr);
@@ -816,18 +675,14 @@ static void link_state_event(struct link *l_ptr, unsigned event)
816 } 675 }
817 break; 676 break;
818 case WORKING_UNKNOWN: 677 case WORKING_UNKNOWN:
819 dbg_link("WU/");
820 switch (event) { 678 switch (event) {
821 case TRAFFIC_MSG_EVT: 679 case TRAFFIC_MSG_EVT:
822 dbg_link("TRF-");
823 case ACTIVATE_MSG: 680 case ACTIVATE_MSG:
824 dbg_link("ACT -> WW\n");
825 l_ptr->state = WORKING_WORKING; 681 l_ptr->state = WORKING_WORKING;
826 l_ptr->fsm_msg_cnt = 0; 682 l_ptr->fsm_msg_cnt = 0;
827 link_set_timer(l_ptr, cont_intv); 683 link_set_timer(l_ptr, cont_intv);
828 break; 684 break;
829 case RESET_MSG: 685 case RESET_MSG:
830 dbg_link("RES -> RR\n");
831 info("Resetting link <%s>, requested by peer " 686 info("Resetting link <%s>, requested by peer "
832 "while probing\n", l_ptr->name); 687 "while probing\n", l_ptr->name);
833 tipc_link_reset(l_ptr); 688 tipc_link_reset(l_ptr);
@@ -838,9 +693,7 @@ static void link_state_event(struct link *l_ptr, unsigned event)
838 link_set_timer(l_ptr, cont_intv); 693 link_set_timer(l_ptr, cont_intv);
839 break; 694 break;
840 case TIMEOUT_EVT: 695 case TIMEOUT_EVT:
841 dbg_link("TIM ");
842 if (l_ptr->next_in_no != l_ptr->checkpoint) { 696 if (l_ptr->next_in_no != l_ptr->checkpoint) {
843 dbg_link("-> WW\n");
844 l_ptr->state = WORKING_WORKING; 697 l_ptr->state = WORKING_WORKING;
845 l_ptr->fsm_msg_cnt = 0; 698 l_ptr->fsm_msg_cnt = 0;
846 l_ptr->checkpoint = l_ptr->next_in_no; 699 l_ptr->checkpoint = l_ptr->next_in_no;
@@ -851,16 +704,11 @@ static void link_state_event(struct link *l_ptr, unsigned event)
851 } 704 }
852 link_set_timer(l_ptr, cont_intv); 705 link_set_timer(l_ptr, cont_intv);
853 } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) { 706 } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) {
854 dbg_link("Probing %u/%u,timer = %u ms)\n",
855 l_ptr->fsm_msg_cnt, l_ptr->abort_limit,
856 cont_intv / 4);
857 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 707 tipc_link_send_proto_msg(l_ptr, STATE_MSG,
858 1, 0, 0, 0, 0); 708 1, 0, 0, 0, 0);
859 l_ptr->fsm_msg_cnt++; 709 l_ptr->fsm_msg_cnt++;
860 link_set_timer(l_ptr, cont_intv / 4); 710 link_set_timer(l_ptr, cont_intv / 4);
861 } else { /* Link has failed */ 711 } else { /* Link has failed */
862 dbg_link("-> RU (%u probes unanswered)\n",
863 l_ptr->fsm_msg_cnt);
864 warn("Resetting link <%s>, peer not responding\n", 712 warn("Resetting link <%s>, peer not responding\n",
865 l_ptr->name); 713 l_ptr->name);
866 tipc_link_reset(l_ptr); 714 tipc_link_reset(l_ptr);
@@ -877,18 +725,13 @@ static void link_state_event(struct link *l_ptr, unsigned event)
877 } 725 }
878 break; 726 break;
879 case RESET_UNKNOWN: 727 case RESET_UNKNOWN:
880 dbg_link("RU/");
881 switch (event) { 728 switch (event) {
882 case TRAFFIC_MSG_EVT: 729 case TRAFFIC_MSG_EVT:
883 dbg_link("TRF-\n");
884 break; 730 break;
885 case ACTIVATE_MSG: 731 case ACTIVATE_MSG:
886 other = l_ptr->owner->active_links[0]; 732 other = l_ptr->owner->active_links[0];
887 if (other && link_working_unknown(other)) { 733 if (other && link_working_unknown(other))
888 dbg_link("ACT\n");
889 break; 734 break;
890 }
891 dbg_link("ACT -> WW\n");
892 l_ptr->state = WORKING_WORKING; 735 l_ptr->state = WORKING_WORKING;
893 l_ptr->fsm_msg_cnt = 0; 736 l_ptr->fsm_msg_cnt = 0;
894 link_activate(l_ptr); 737 link_activate(l_ptr);
@@ -897,8 +740,6 @@ static void link_state_event(struct link *l_ptr, unsigned event)
897 link_set_timer(l_ptr, cont_intv); 740 link_set_timer(l_ptr, cont_intv);
898 break; 741 break;
899 case RESET_MSG: 742 case RESET_MSG:
900 dbg_link("RES\n");
901 dbg_link(" -> RR\n");
902 l_ptr->state = RESET_RESET; 743 l_ptr->state = RESET_RESET;
903 l_ptr->fsm_msg_cnt = 0; 744 l_ptr->fsm_msg_cnt = 0;
904 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0); 745 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0);
@@ -906,11 +747,9 @@ static void link_state_event(struct link *l_ptr, unsigned event)
906 link_set_timer(l_ptr, cont_intv); 747 link_set_timer(l_ptr, cont_intv);
907 break; 748 break;
908 case STARTING_EVT: 749 case STARTING_EVT:
909 dbg_link("START-");
910 l_ptr->started = 1; 750 l_ptr->started = 1;
911 /* fall through */ 751 /* fall through */
912 case TIMEOUT_EVT: 752 case TIMEOUT_EVT:
913 dbg_link("TIM\n");
914 tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0); 753 tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
915 l_ptr->fsm_msg_cnt++; 754 l_ptr->fsm_msg_cnt++;
916 link_set_timer(l_ptr, cont_intv); 755 link_set_timer(l_ptr, cont_intv);
@@ -920,18 +759,12 @@ static void link_state_event(struct link *l_ptr, unsigned event)
920 } 759 }
921 break; 760 break;
922 case RESET_RESET: 761 case RESET_RESET:
923 dbg_link("RR/ ");
924 switch (event) { 762 switch (event) {
925 case TRAFFIC_MSG_EVT: 763 case TRAFFIC_MSG_EVT:
926 dbg_link("TRF-");
927 /* fall through */
928 case ACTIVATE_MSG: 764 case ACTIVATE_MSG:
929 other = l_ptr->owner->active_links[0]; 765 other = l_ptr->owner->active_links[0];
930 if (other && link_working_unknown(other)) { 766 if (other && link_working_unknown(other))
931 dbg_link("ACT\n");
932 break; 767 break;
933 }
934 dbg_link("ACT -> WW\n");
935 l_ptr->state = WORKING_WORKING; 768 l_ptr->state = WORKING_WORKING;
936 l_ptr->fsm_msg_cnt = 0; 769 l_ptr->fsm_msg_cnt = 0;
937 link_activate(l_ptr); 770 link_activate(l_ptr);
@@ -940,14 +773,11 @@ static void link_state_event(struct link *l_ptr, unsigned event)
940 link_set_timer(l_ptr, cont_intv); 773 link_set_timer(l_ptr, cont_intv);
941 break; 774 break;
942 case RESET_MSG: 775 case RESET_MSG:
943 dbg_link("RES\n");
944 break; 776 break;
945 case TIMEOUT_EVT: 777 case TIMEOUT_EVT:
946 dbg_link("TIM\n");
947 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); 778 tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
948 l_ptr->fsm_msg_cnt++; 779 l_ptr->fsm_msg_cnt++;
949 link_set_timer(l_ptr, cont_intv); 780 link_set_timer(l_ptr, cont_intv);
950 dbg_link("fsm_msg_cnt %u\n", l_ptr->fsm_msg_cnt);
951 break; 781 break;
952 default: 782 default:
953 err("Unknown link event %u in RR state\n", event); 783 err("Unknown link event %u in RR state\n", event);
@@ -987,9 +817,6 @@ static int link_bundle_buf(struct link *l_ptr,
987 skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); 817 skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size);
988 msg_set_size(bundler_msg, to_pos + size); 818 msg_set_size(bundler_msg, to_pos + size);
989 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); 819 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1);
990 dbg("Packed msg # %u(%u octets) into pos %u in buf(#%u)\n",
991 msg_msgcnt(bundler_msg), size, to_pos, msg_seqno(bundler_msg));
992 msg_dbg(msg, "PACKD:");
993 buf_discard(buf); 820 buf_discard(buf);
994 l_ptr->stats.sent_bundled++; 821 l_ptr->stats.sent_bundled++;
995 return 1; 822 return 1;
@@ -1010,7 +837,29 @@ static void link_add_to_outqueue(struct link *l_ptr,
1010 l_ptr->last_out = buf; 837 l_ptr->last_out = buf;
1011 } else 838 } else
1012 l_ptr->first_out = l_ptr->last_out = buf; 839 l_ptr->first_out = l_ptr->last_out = buf;
840
1013 l_ptr->out_queue_size++; 841 l_ptr->out_queue_size++;
842 if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz)
843 l_ptr->stats.max_queue_sz = l_ptr->out_queue_size;
844}
845
846static void link_add_chain_to_outqueue(struct link *l_ptr,
847 struct sk_buff *buf_chain,
848 u32 long_msgno)
849{
850 struct sk_buff *buf;
851 struct tipc_msg *msg;
852
853 if (!l_ptr->next_out)
854 l_ptr->next_out = buf_chain;
855 while (buf_chain) {
856 buf = buf_chain;
857 buf_chain = buf_chain->next;
858
859 msg = buf_msg(buf);
860 msg_set_long_msgno(msg, long_msgno);
861 link_add_to_outqueue(l_ptr, buf, msg);
862 }
1014} 863}
1015 864
1016/* 865/*
@@ -1035,10 +884,10 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1035 884
1036 if (unlikely(queue_size >= queue_limit)) { 885 if (unlikely(queue_size >= queue_limit)) {
1037 if (imp <= TIPC_CRITICAL_IMPORTANCE) { 886 if (imp <= TIPC_CRITICAL_IMPORTANCE) {
1038 return link_schedule_port(l_ptr, msg_origport(msg), 887 link_schedule_port(l_ptr, msg_origport(msg), size);
1039 size); 888 buf_discard(buf);
889 return -ELINKCONG;
1040 } 890 }
1041 msg_dbg(msg, "TIPC: Congestion, throwing away\n");
1042 buf_discard(buf); 891 buf_discard(buf);
1043 if (imp > CONN_MANAGER) { 892 if (imp > CONN_MANAGER) {
1044 warn("Resetting link <%s>, send queue full", l_ptr->name); 893 warn("Resetting link <%s>, send queue full", l_ptr->name);
@@ -1050,13 +899,10 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1050 /* Fragmentation needed ? */ 899 /* Fragmentation needed ? */
1051 900
1052 if (size > max_packet) 901 if (size > max_packet)
1053 return tipc_link_send_long_buf(l_ptr, buf); 902 return link_send_long_buf(l_ptr, buf);
1054 903
1055 /* Packet can be queued or sent: */ 904 /* Packet can be queued or sent: */
1056 905
1057 if (queue_size > l_ptr->stats.max_queue_sz)
1058 l_ptr->stats.max_queue_sz = queue_size;
1059
1060 if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && 906 if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) &&
1061 !link_congested(l_ptr))) { 907 !link_congested(l_ptr))) {
1062 link_add_to_outqueue(l_ptr, buf, msg); 908 link_add_to_outqueue(l_ptr, buf, msg);
@@ -1086,7 +932,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1086 /* Try creating a new bundle */ 932 /* Try creating a new bundle */
1087 933
1088 if (size <= max_packet * 2 / 3) { 934 if (size <= max_packet * 2 / 3) {
1089 struct sk_buff *bundler = buf_acquire(max_packet); 935 struct sk_buff *bundler = tipc_buf_acquire(max_packet);
1090 struct tipc_msg bundler_hdr; 936 struct tipc_msg bundler_hdr;
1091 937
1092 if (bundler) { 938 if (bundler) {
@@ -1122,22 +968,16 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
1122 int res = -ELINKCONG; 968 int res = -ELINKCONG;
1123 969
1124 read_lock_bh(&tipc_net_lock); 970 read_lock_bh(&tipc_net_lock);
1125 n_ptr = tipc_node_select(dest, selector); 971 n_ptr = tipc_node_find(dest);
1126 if (n_ptr) { 972 if (n_ptr) {
1127 tipc_node_lock(n_ptr); 973 tipc_node_lock(n_ptr);
1128 l_ptr = n_ptr->active_links[selector & 1]; 974 l_ptr = n_ptr->active_links[selector & 1];
1129 if (l_ptr) { 975 if (l_ptr)
1130 dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest);
1131 res = tipc_link_send_buf(l_ptr, buf); 976 res = tipc_link_send_buf(l_ptr, buf);
1132 } else { 977 else
1133 dbg("Attempt to send msg to unreachable node:\n");
1134 msg_dbg(buf_msg(buf),">>>");
1135 buf_discard(buf); 978 buf_discard(buf);
1136 }
1137 tipc_node_unlock(n_ptr); 979 tipc_node_unlock(n_ptr);
1138 } else { 980 } else {
1139 dbg("Attempt to send msg to unknown node:\n");
1140 msg_dbg(buf_msg(buf),">>>");
1141 buf_discard(buf); 981 buf_discard(buf);
1142 } 982 }
1143 read_unlock_bh(&tipc_net_lock); 983 read_unlock_bh(&tipc_net_lock);
@@ -1164,17 +1004,14 @@ static int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf,
1164 if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, 1004 if (likely(tipc_bearer_send(l_ptr->b_ptr, buf,
1165 &l_ptr->media_addr))) { 1005 &l_ptr->media_addr))) {
1166 l_ptr->unacked_window = 0; 1006 l_ptr->unacked_window = 0;
1167 msg_dbg(msg,"SENT_FAST:");
1168 return res; 1007 return res;
1169 } 1008 }
1170 dbg("failed sent fast...\n");
1171 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); 1009 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
1172 l_ptr->stats.bearer_congs++; 1010 l_ptr->stats.bearer_congs++;
1173 l_ptr->next_out = buf; 1011 l_ptr->next_out = buf;
1174 return res; 1012 return res;
1175 } 1013 }
1176 } 1014 } else
1177 else
1178 *used_max_pkt = l_ptr->max_pkt; 1015 *used_max_pkt = l_ptr->max_pkt;
1179 } 1016 }
1180 return tipc_link_send_buf(l_ptr, buf); /* All other cases */ 1017 return tipc_link_send_buf(l_ptr, buf); /* All other cases */
@@ -1198,12 +1035,10 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1198 return tipc_port_recv_msg(buf); 1035 return tipc_port_recv_msg(buf);
1199 1036
1200 read_lock_bh(&tipc_net_lock); 1037 read_lock_bh(&tipc_net_lock);
1201 n_ptr = tipc_node_select(destnode, selector); 1038 n_ptr = tipc_node_find(destnode);
1202 if (likely(n_ptr)) { 1039 if (likely(n_ptr)) {
1203 tipc_node_lock(n_ptr); 1040 tipc_node_lock(n_ptr);
1204 l_ptr = n_ptr->active_links[selector]; 1041 l_ptr = n_ptr->active_links[selector];
1205 dbg("send_fast: buf %x selected %x, destnode = %x\n",
1206 buf, l_ptr, destnode);
1207 if (likely(l_ptr)) { 1042 if (likely(l_ptr)) {
1208 res = link_send_buf_fast(l_ptr, buf, &dummy); 1043 res = link_send_buf_fast(l_ptr, buf, &dummy);
1209 tipc_node_unlock(n_ptr); 1044 tipc_node_unlock(n_ptr);
@@ -1225,12 +1060,13 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1225 * except for total message length. 1060 * except for total message length.
1226 * Returns user data length or errno. 1061 * Returns user data length or errno.
1227 */ 1062 */
1228int tipc_link_send_sections_fast(struct port *sender, 1063int tipc_link_send_sections_fast(struct tipc_port *sender,
1229 struct iovec const *msg_sect, 1064 struct iovec const *msg_sect,
1230 const u32 num_sect, 1065 const u32 num_sect,
1066 unsigned int total_len,
1231 u32 destaddr) 1067 u32 destaddr)
1232{ 1068{
1233 struct tipc_msg *hdr = &sender->publ.phdr; 1069 struct tipc_msg *hdr = &sender->phdr;
1234 struct link *l_ptr; 1070 struct link *l_ptr;
1235 struct sk_buff *buf; 1071 struct sk_buff *buf;
1236 struct tipc_node *node; 1072 struct tipc_node *node;
@@ -1243,20 +1079,18 @@ again:
1243 * (Must not hold any locks while building message.) 1079 * (Must not hold any locks while building message.)
1244 */ 1080 */
1245 1081
1246 res = tipc_msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt, 1082 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
1247 !sender->user_port, &buf); 1083 sender->max_pkt, !sender->user_port, &buf);
1248 1084
1249 read_lock_bh(&tipc_net_lock); 1085 read_lock_bh(&tipc_net_lock);
1250 node = tipc_node_select(destaddr, selector); 1086 node = tipc_node_find(destaddr);
1251 if (likely(node)) { 1087 if (likely(node)) {
1252 tipc_node_lock(node); 1088 tipc_node_lock(node);
1253 l_ptr = node->active_links[selector]; 1089 l_ptr = node->active_links[selector];
1254 if (likely(l_ptr)) { 1090 if (likely(l_ptr)) {
1255 if (likely(buf)) { 1091 if (likely(buf)) {
1256 res = link_send_buf_fast(l_ptr, buf, 1092 res = link_send_buf_fast(l_ptr, buf,
1257 &sender->publ.max_pkt); 1093 &sender->max_pkt);
1258 if (unlikely(res < 0))
1259 buf_discard(buf);
1260exit: 1094exit:
1261 tipc_node_unlock(node); 1095 tipc_node_unlock(node);
1262 read_unlock_bh(&tipc_net_lock); 1096 read_unlock_bh(&tipc_net_lock);
@@ -1273,7 +1107,7 @@ exit:
1273 if (link_congested(l_ptr) || 1107 if (link_congested(l_ptr) ||
1274 !list_empty(&l_ptr->b_ptr->cong_links)) { 1108 !list_empty(&l_ptr->b_ptr->cong_links)) {
1275 res = link_schedule_port(l_ptr, 1109 res = link_schedule_port(l_ptr,
1276 sender->publ.ref, res); 1110 sender->ref, res);
1277 goto exit; 1111 goto exit;
1278 } 1112 }
1279 1113
@@ -1282,16 +1116,17 @@ exit:
1282 * then re-try fast path or fragment the message 1116 * then re-try fast path or fragment the message
1283 */ 1117 */
1284 1118
1285 sender->publ.max_pkt = l_ptr->max_pkt; 1119 sender->max_pkt = l_ptr->max_pkt;
1286 tipc_node_unlock(node); 1120 tipc_node_unlock(node);
1287 read_unlock_bh(&tipc_net_lock); 1121 read_unlock_bh(&tipc_net_lock);
1288 1122
1289 1123
1290 if ((msg_hdr_sz(hdr) + res) <= sender->publ.max_pkt) 1124 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
1291 goto again; 1125 goto again;
1292 1126
1293 return link_send_sections_long(sender, msg_sect, 1127 return link_send_sections_long(sender, msg_sect,
1294 num_sect, destaddr); 1128 num_sect, total_len,
1129 destaddr);
1295 } 1130 }
1296 tipc_node_unlock(node); 1131 tipc_node_unlock(node);
1297 } 1132 }
@@ -1303,7 +1138,7 @@ exit:
1303 return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); 1138 return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
1304 if (res >= 0) 1139 if (res >= 0)
1305 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1140 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
1306 TIPC_ERR_NO_NODE); 1141 total_len, TIPC_ERR_NO_NODE);
1307 return res; 1142 return res;
1308} 1143}
1309 1144
@@ -1321,26 +1156,27 @@ exit:
1321 * 1156 *
1322 * Returns user data length or errno. 1157 * Returns user data length or errno.
1323 */ 1158 */
1324static int link_send_sections_long(struct port *sender, 1159static int link_send_sections_long(struct tipc_port *sender,
1325 struct iovec const *msg_sect, 1160 struct iovec const *msg_sect,
1326 u32 num_sect, 1161 u32 num_sect,
1162 unsigned int total_len,
1327 u32 destaddr) 1163 u32 destaddr)
1328{ 1164{
1329 struct link *l_ptr; 1165 struct link *l_ptr;
1330 struct tipc_node *node; 1166 struct tipc_node *node;
1331 struct tipc_msg *hdr = &sender->publ.phdr; 1167 struct tipc_msg *hdr = &sender->phdr;
1332 u32 dsz = msg_data_sz(hdr); 1168 u32 dsz = total_len;
1333 u32 max_pkt,fragm_sz,rest; 1169 u32 max_pkt, fragm_sz, rest;
1334 struct tipc_msg fragm_hdr; 1170 struct tipc_msg fragm_hdr;
1335 struct sk_buff *buf,*buf_chain,*prev; 1171 struct sk_buff *buf, *buf_chain, *prev;
1336 u32 fragm_crs,fragm_rest,hsz,sect_rest; 1172 u32 fragm_crs, fragm_rest, hsz, sect_rest;
1337 const unchar *sect_crs; 1173 const unchar *sect_crs;
1338 int curr_sect; 1174 int curr_sect;
1339 u32 fragm_no; 1175 u32 fragm_no;
1340 1176
1341again: 1177again:
1342 fragm_no = 1; 1178 fragm_no = 1;
1343 max_pkt = sender->publ.max_pkt - INT_H_SIZE; 1179 max_pkt = sender->max_pkt - INT_H_SIZE;
1344 /* leave room for tunnel header in case of link changeover */ 1180 /* leave room for tunnel header in case of link changeover */
1345 fragm_sz = max_pkt - INT_H_SIZE; 1181 fragm_sz = max_pkt - INT_H_SIZE;
1346 /* leave room for fragmentation header in each fragment */ 1182 /* leave room for fragmentation header in each fragment */
@@ -1353,23 +1189,20 @@ again:
1353 1189
1354 /* Prepare reusable fragment header: */ 1190 /* Prepare reusable fragment header: */
1355 1191
1356 msg_dbg(hdr, ">FRAGMENTING>");
1357 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 1192 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1358 INT_H_SIZE, msg_destnode(hdr)); 1193 INT_H_SIZE, msg_destnode(hdr));
1359 msg_set_link_selector(&fragm_hdr, sender->publ.ref);
1360 msg_set_size(&fragm_hdr, max_pkt); 1194 msg_set_size(&fragm_hdr, max_pkt);
1361 msg_set_fragm_no(&fragm_hdr, 1); 1195 msg_set_fragm_no(&fragm_hdr, 1);
1362 1196
1363 /* Prepare header of first fragment: */ 1197 /* Prepare header of first fragment: */
1364 1198
1365 buf_chain = buf = buf_acquire(max_pkt); 1199 buf_chain = buf = tipc_buf_acquire(max_pkt);
1366 if (!buf) 1200 if (!buf)
1367 return -ENOMEM; 1201 return -ENOMEM;
1368 buf->next = NULL; 1202 buf->next = NULL;
1369 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); 1203 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
1370 hsz = msg_hdr_sz(hdr); 1204 hsz = msg_hdr_sz(hdr);
1371 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz); 1205 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz);
1372 msg_dbg(buf_msg(buf), ">BUILD>");
1373 1206
1374 /* Chop up message: */ 1207 /* Chop up message: */
1375 1208
@@ -1412,14 +1245,14 @@ error:
1412 /* Initiate new fragment: */ 1245 /* Initiate new fragment: */
1413 if (rest <= fragm_sz) { 1246 if (rest <= fragm_sz) {
1414 fragm_sz = rest; 1247 fragm_sz = rest;
1415 msg_set_type(&fragm_hdr,LAST_FRAGMENT); 1248 msg_set_type(&fragm_hdr, LAST_FRAGMENT);
1416 } else { 1249 } else {
1417 msg_set_type(&fragm_hdr, FRAGMENT); 1250 msg_set_type(&fragm_hdr, FRAGMENT);
1418 } 1251 }
1419 msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); 1252 msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE);
1420 msg_set_fragm_no(&fragm_hdr, ++fragm_no); 1253 msg_set_fragm_no(&fragm_hdr, ++fragm_no);
1421 prev = buf; 1254 prev = buf;
1422 buf = buf_acquire(fragm_sz + INT_H_SIZE); 1255 buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
1423 if (!buf) 1256 if (!buf)
1424 goto error; 1257 goto error;
1425 1258
@@ -1428,25 +1261,23 @@ error:
1428 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); 1261 skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE);
1429 fragm_crs = INT_H_SIZE; 1262 fragm_crs = INT_H_SIZE;
1430 fragm_rest = fragm_sz; 1263 fragm_rest = fragm_sz;
1431 msg_dbg(buf_msg(buf)," >BUILD>");
1432 } 1264 }
1433 } 1265 } while (rest > 0);
1434 while (rest > 0);
1435 1266
1436 /* 1267 /*
1437 * Now we have a buffer chain. Select a link and check 1268 * Now we have a buffer chain. Select a link and check
1438 * that packet size is still OK 1269 * that packet size is still OK
1439 */ 1270 */
1440 node = tipc_node_select(destaddr, sender->publ.ref & 1); 1271 node = tipc_node_find(destaddr);
1441 if (likely(node)) { 1272 if (likely(node)) {
1442 tipc_node_lock(node); 1273 tipc_node_lock(node);
1443 l_ptr = node->active_links[sender->publ.ref & 1]; 1274 l_ptr = node->active_links[sender->ref & 1];
1444 if (!l_ptr) { 1275 if (!l_ptr) {
1445 tipc_node_unlock(node); 1276 tipc_node_unlock(node);
1446 goto reject; 1277 goto reject;
1447 } 1278 }
1448 if (l_ptr->max_pkt < max_pkt) { 1279 if (l_ptr->max_pkt < max_pkt) {
1449 sender->publ.max_pkt = l_ptr->max_pkt; 1280 sender->max_pkt = l_ptr->max_pkt;
1450 tipc_node_unlock(node); 1281 tipc_node_unlock(node);
1451 for (; buf_chain; buf_chain = buf) { 1282 for (; buf_chain; buf_chain = buf) {
1452 buf = buf_chain->next; 1283 buf = buf_chain->next;
@@ -1461,29 +1292,15 @@ reject:
1461 buf_discard(buf_chain); 1292 buf_discard(buf_chain);
1462 } 1293 }
1463 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1294 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
1464 TIPC_ERR_NO_NODE); 1295 total_len, TIPC_ERR_NO_NODE);
1465 } 1296 }
1466 1297
1467 /* Append whole chain to send queue: */ 1298 /* Append chain of fragments to send queue & send them */
1468 1299
1469 buf = buf_chain; 1300 l_ptr->long_msg_seq_no++;
1470 l_ptr->long_msg_seq_no = mod(l_ptr->long_msg_seq_no + 1); 1301 link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no);
1471 if (!l_ptr->next_out) 1302 l_ptr->stats.sent_fragments += fragm_no;
1472 l_ptr->next_out = buf_chain;
1473 l_ptr->stats.sent_fragmented++; 1303 l_ptr->stats.sent_fragmented++;
1474 while (buf) {
1475 struct sk_buff *next = buf->next;
1476 struct tipc_msg *msg = buf_msg(buf);
1477
1478 l_ptr->stats.sent_fragments++;
1479 msg_set_long_msgno(msg, l_ptr->long_msg_seq_no);
1480 link_add_to_outqueue(l_ptr, buf, msg);
1481 msg_dbg(msg, ">ADD>");
1482 buf = next;
1483 }
1484
1485 /* Send it, if possible: */
1486
1487 tipc_link_push_queue(l_ptr); 1304 tipc_link_push_queue(l_ptr);
1488 tipc_node_unlock(node); 1305 tipc_node_unlock(node);
1489 return dsz; 1306 return dsz;
@@ -1520,14 +1337,12 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1520 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); 1337 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
1521 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); 1338 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
1522 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1339 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1523 msg_dbg(buf_msg(buf), ">DEF-RETR>");
1524 l_ptr->retransm_queue_head = mod(++r_q_head); 1340 l_ptr->retransm_queue_head = mod(++r_q_head);
1525 l_ptr->retransm_queue_size = --r_q_size; 1341 l_ptr->retransm_queue_size = --r_q_size;
1526 l_ptr->stats.retransmitted++; 1342 l_ptr->stats.retransmitted++;
1527 return 0; 1343 return 0;
1528 } else { 1344 } else {
1529 l_ptr->stats.bearer_congs++; 1345 l_ptr->stats.bearer_congs++;
1530 msg_dbg(buf_msg(buf), "|>DEF-RETR>");
1531 return PUSH_FAILED; 1346 return PUSH_FAILED;
1532 } 1347 }
1533 } 1348 }
@@ -1537,15 +1352,13 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1537 buf = l_ptr->proto_msg_queue; 1352 buf = l_ptr->proto_msg_queue;
1538 if (buf) { 1353 if (buf) {
1539 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); 1354 msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
1540 msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in); 1355 msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
1541 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1356 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1542 msg_dbg(buf_msg(buf), ">DEF-PROT>");
1543 l_ptr->unacked_window = 0; 1357 l_ptr->unacked_window = 0;
1544 buf_discard(buf); 1358 buf_discard(buf);
1545 l_ptr->proto_msg_queue = NULL; 1359 l_ptr->proto_msg_queue = NULL;
1546 return 0; 1360 return 0;
1547 } else { 1361 } else {
1548 msg_dbg(buf_msg(buf), "|>DEF-PROT>");
1549 l_ptr->stats.bearer_congs++; 1362 l_ptr->stats.bearer_congs++;
1550 return PUSH_FAILED; 1363 return PUSH_FAILED;
1551 } 1364 }
@@ -1565,11 +1378,9 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1565 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1378 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1566 if (msg_user(msg) == MSG_BUNDLER) 1379 if (msg_user(msg) == MSG_BUNDLER)
1567 msg_set_type(msg, CLOSED_MSG); 1380 msg_set_type(msg, CLOSED_MSG);
1568 msg_dbg(msg, ">PUSH-DATA>");
1569 l_ptr->next_out = buf->next; 1381 l_ptr->next_out = buf->next;
1570 return 0; 1382 return 0;
1571 } else { 1383 } else {
1572 msg_dbg(msg, "|PUSH-DATA|");
1573 l_ptr->stats.bearer_congs++; 1384 l_ptr->stats.bearer_congs++;
1574 return PUSH_FAILED; 1385 return PUSH_FAILED;
1575 } 1386 }
@@ -1617,8 +1428,7 @@ static void link_reset_all(unsigned long addr)
1617 1428
1618 for (i = 0; i < MAX_BEARERS; i++) { 1429 for (i = 0; i < MAX_BEARERS; i++) {
1619 if (n_ptr->links[i]) { 1430 if (n_ptr->links[i]) {
1620 link_print(n_ptr->links[i], TIPC_OUTPUT, 1431 link_print(n_ptr->links[i], "Resetting link\n");
1621 "Resetting link\n");
1622 tipc_link_reset(n_ptr->links[i]); 1432 tipc_link_reset(n_ptr->links[i]);
1623 } 1433 }
1624 } 1434 }
@@ -1632,13 +1442,12 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1632 struct tipc_msg *msg = buf_msg(buf); 1442 struct tipc_msg *msg = buf_msg(buf);
1633 1443
1634 warn("Retransmission failure on link <%s>\n", l_ptr->name); 1444 warn("Retransmission failure on link <%s>\n", l_ptr->name);
1635 tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>");
1636 1445
1637 if (l_ptr->addr) { 1446 if (l_ptr->addr) {
1638 1447
1639 /* Handle failure on standard link */ 1448 /* Handle failure on standard link */
1640 1449
1641 link_print(l_ptr, TIPC_OUTPUT, "Resetting link\n"); 1450 link_print(l_ptr, "Resetting link\n");
1642 tipc_link_reset(l_ptr); 1451 tipc_link_reset(l_ptr);
1643 1452
1644 } else { 1453 } else {
@@ -1648,21 +1457,21 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1648 struct tipc_node *n_ptr; 1457 struct tipc_node *n_ptr;
1649 char addr_string[16]; 1458 char addr_string[16];
1650 1459
1651 tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg)); 1460 info("Msg seq number: %u, ", msg_seqno(msg));
1652 tipc_printf(TIPC_OUTPUT, "Outstanding acks: %lu\n", 1461 info("Outstanding acks: %lu\n",
1653 (unsigned long) TIPC_SKB_CB(buf)->handle); 1462 (unsigned long) TIPC_SKB_CB(buf)->handle);
1654 1463
1655 n_ptr = l_ptr->owner->next; 1464 n_ptr = tipc_bclink_retransmit_to();
1656 tipc_node_lock(n_ptr); 1465 tipc_node_lock(n_ptr);
1657 1466
1658 tipc_addr_string_fill(addr_string, n_ptr->addr); 1467 tipc_addr_string_fill(addr_string, n_ptr->addr);
1659 tipc_printf(TIPC_OUTPUT, "Multicast link info for %s\n", addr_string); 1468 info("Multicast link info for %s\n", addr_string);
1660 tipc_printf(TIPC_OUTPUT, "Supported: %d, ", n_ptr->bclink.supported); 1469 info("Supported: %d, ", n_ptr->bclink.supported);
1661 tipc_printf(TIPC_OUTPUT, "Acked: %u\n", n_ptr->bclink.acked); 1470 info("Acked: %u\n", n_ptr->bclink.acked);
1662 tipc_printf(TIPC_OUTPUT, "Last in: %u, ", n_ptr->bclink.last_in); 1471 info("Last in: %u, ", n_ptr->bclink.last_in);
1663 tipc_printf(TIPC_OUTPUT, "Gap after: %u, ", n_ptr->bclink.gap_after); 1472 info("Gap after: %u, ", n_ptr->bclink.gap_after);
1664 tipc_printf(TIPC_OUTPUT, "Gap to: %u\n", n_ptr->bclink.gap_to); 1473 info("Gap to: %u\n", n_ptr->bclink.gap_to);
1665 tipc_printf(TIPC_OUTPUT, "Nack sync: %u\n\n", n_ptr->bclink.nack_sync); 1474 info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync);
1666 1475
1667 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); 1476 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
1668 1477
@@ -1682,12 +1491,8 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1682 1491
1683 msg = buf_msg(buf); 1492 msg = buf_msg(buf);
1684 1493
1685 dbg("Retransmitting %u in link %x\n", retransmits, l_ptr);
1686
1687 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { 1494 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
1688 if (l_ptr->retransm_queue_size == 0) { 1495 if (l_ptr->retransm_queue_size == 0) {
1689 msg_dbg(msg, ">NO_RETR->BCONG>");
1690 dbg_print_link(l_ptr, " ");
1691 l_ptr->retransm_queue_head = msg_seqno(msg); 1496 l_ptr->retransm_queue_head = msg_seqno(msg);
1692 l_ptr->retransm_queue_size = retransmits; 1497 l_ptr->retransm_queue_size = retransmits;
1693 } else { 1498 } else {
@@ -1714,7 +1519,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1714 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); 1519 msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
1715 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 1520 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
1716 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1521 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1717 msg_dbg(buf_msg(buf), ">RETR>");
1718 buf = buf->next; 1522 buf = buf->next;
1719 retransmits--; 1523 retransmits--;
1720 l_ptr->stats.retransmitted++; 1524 l_ptr->stats.retransmitted++;
@@ -1802,11 +1606,19 @@ static int link_recv_buf_validate(struct sk_buff *buf)
1802 return pskb_may_pull(buf, hdr_size); 1606 return pskb_may_pull(buf, hdr_size);
1803} 1607}
1804 1608
1805void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) 1609/**
1610 * tipc_recv_msg - process TIPC messages arriving from off-node
1611 * @head: pointer to message buffer chain
1612 * @tb_ptr: pointer to bearer message arrived on
1613 *
1614 * Invoked with no locks held. Bearer pointer must point to a valid bearer
1615 * structure (i.e. cannot be NULL), but bearer can be inactive.
1616 */
1617
1618void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1806{ 1619{
1807 read_lock_bh(&tipc_net_lock); 1620 read_lock_bh(&tipc_net_lock);
1808 while (head) { 1621 while (head) {
1809 struct bearer *b_ptr = (struct bearer *)tb_ptr;
1810 struct tipc_node *n_ptr; 1622 struct tipc_node *n_ptr;
1811 struct link *l_ptr; 1623 struct link *l_ptr;
1812 struct sk_buff *crs; 1624 struct sk_buff *crs;
@@ -1819,6 +1631,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1819 1631
1820 head = head->next; 1632 head = head->next;
1821 1633
1634 /* Ensure bearer is still enabled */
1635
1636 if (unlikely(!b_ptr->active))
1637 goto cont;
1638
1822 /* Ensure message is well-formed */ 1639 /* Ensure message is well-formed */
1823 1640
1824 if (unlikely(!link_recv_buf_validate(buf))) 1641 if (unlikely(!link_recv_buf_validate(buf)))
@@ -1826,9 +1643,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1826 1643
1827 /* Ensure message data is a single contiguous unit */ 1644 /* Ensure message data is a single contiguous unit */
1828 1645
1829 if (unlikely(buf_linearize(buf))) { 1646 if (unlikely(buf_linearize(buf)))
1830 goto cont; 1647 goto cont;
1831 }
1832 1648
1833 /* Handle arrival of a non-unicast link message */ 1649 /* Handle arrival of a non-unicast link message */
1834 1650
@@ -1855,13 +1671,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1855 goto cont; 1671 goto cont;
1856 } 1672 }
1857 1673
1858 /* Locate unicast link endpoint that should handle message */ 1674 /* Locate neighboring node that sent message */
1859 1675
1860 n_ptr = tipc_node_find(msg_prevnode(msg)); 1676 n_ptr = tipc_node_find(msg_prevnode(msg));
1861 if (unlikely(!n_ptr)) 1677 if (unlikely(!n_ptr))
1862 goto cont; 1678 goto cont;
1863 tipc_node_lock(n_ptr); 1679 tipc_node_lock(n_ptr);
1864 1680
1681 /* Don't talk to neighbor during cleanup after last session */
1682
1683 if (n_ptr->cleanup_required) {
1684 tipc_node_unlock(n_ptr);
1685 goto cont;
1686 }
1687
1688 /* Locate unicast link endpoint that should handle message */
1689
1865 l_ptr = n_ptr->links[b_ptr->identity]; 1690 l_ptr = n_ptr->links[b_ptr->identity];
1866 if (unlikely(!l_ptr)) { 1691 if (unlikely(!l_ptr)) {
1867 tipc_node_unlock(n_ptr); 1692 tipc_node_unlock(n_ptr);
@@ -1929,10 +1754,6 @@ deliver:
1929 tipc_node_unlock(n_ptr); 1754 tipc_node_unlock(n_ptr);
1930 tipc_link_recv_bundle(buf); 1755 tipc_link_recv_bundle(buf);
1931 continue; 1756 continue;
1932 case ROUTE_DISTRIBUTOR:
1933 tipc_node_unlock(n_ptr);
1934 tipc_cltr_recv_routing_table(buf);
1935 continue;
1936 case NAME_DISTRIBUTOR: 1757 case NAME_DISTRIBUTOR:
1937 tipc_node_unlock(n_ptr); 1758 tipc_node_unlock(n_ptr);
1938 tipc_named_recv(buf); 1759 tipc_named_recv(buf);
@@ -1959,6 +1780,10 @@ deliver:
1959 goto protocol_check; 1780 goto protocol_check;
1960 } 1781 }
1961 break; 1782 break;
1783 default:
1784 buf_discard(buf);
1785 buf = NULL;
1786 break;
1962 } 1787 }
1963 } 1788 }
1964 tipc_node_unlock(n_ptr); 1789 tipc_node_unlock(n_ptr);
@@ -1977,12 +1802,10 @@ deliver:
1977 tipc_node_unlock(n_ptr); 1802 tipc_node_unlock(n_ptr);
1978 continue; 1803 continue;
1979 } 1804 }
1980 msg_dbg(msg,"NSEQ<REC<");
1981 link_state_event(l_ptr, TRAFFIC_MSG_EVT); 1805 link_state_event(l_ptr, TRAFFIC_MSG_EVT);
1982 1806
1983 if (link_working_working(l_ptr)) { 1807 if (link_working_working(l_ptr)) {
1984 /* Re-insert in front of queue */ 1808 /* Re-insert in front of queue */
1985 msg_dbg(msg,"RECV-REINS:");
1986 buf->next = head; 1809 buf->next = head;
1987 head = buf; 1810 head = buf;
1988 tipc_node_unlock(n_ptr); 1811 tipc_node_unlock(n_ptr);
@@ -2036,13 +1859,11 @@ u32 tipc_link_defer_pkt(struct sk_buff **head,
2036 *head = buf; 1859 *head = buf;
2037 return 1; 1860 return 1;
2038 } 1861 }
2039 if (seq_no == msg_seqno(msg)) { 1862 if (seq_no == msg_seqno(msg))
2040 break; 1863 break;
2041 }
2042 prev = crs; 1864 prev = crs;
2043 crs = crs->next; 1865 crs = crs->next;
2044 } 1866 } while (crs);
2045 while (crs);
2046 1867
2047 /* Message is a duplicate of an existing message */ 1868 /* Message is a duplicate of an existing message */
2048 1869
@@ -2064,9 +1885,6 @@ static void link_handle_out_of_seq_msg(struct link *l_ptr,
2064 return; 1885 return;
2065 } 1886 }
2066 1887
2067 dbg("rx OOS msg: seq_no %u, expecting %u (%u)\n",
2068 seq_no, mod(l_ptr->next_in_no), l_ptr->next_in_no);
2069
2070 /* Record OOS packet arrival (force mismatch on next timeout) */ 1888 /* Record OOS packet arrival (force mismatch on next timeout) */
2071 1889
2072 l_ptr->checkpoint--; 1890 l_ptr->checkpoint--;
@@ -2101,6 +1919,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2101 struct sk_buff *buf = NULL; 1919 struct sk_buff *buf = NULL;
2102 struct tipc_msg *msg = l_ptr->pmsg; 1920 struct tipc_msg *msg = l_ptr->pmsg;
2103 u32 msg_size = sizeof(l_ptr->proto_msg); 1921 u32 msg_size = sizeof(l_ptr->proto_msg);
1922 int r_flag;
2104 1923
2105 if (link_blocked(l_ptr)) 1924 if (link_blocked(l_ptr))
2106 return; 1925 return;
@@ -2151,16 +1970,14 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2151 msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1)); 1970 msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1));
2152 msg_set_seq_gap(msg, 0); 1971 msg_set_seq_gap(msg, 0);
2153 msg_set_next_sent(msg, 1); 1972 msg_set_next_sent(msg, 1);
1973 msg_set_probe(msg, 0);
2154 msg_set_link_tolerance(msg, l_ptr->tolerance); 1974 msg_set_link_tolerance(msg, l_ptr->tolerance);
2155 msg_set_linkprio(msg, l_ptr->priority); 1975 msg_set_linkprio(msg, l_ptr->priority);
2156 msg_set_max_pkt(msg, l_ptr->max_pkt_target); 1976 msg_set_max_pkt(msg, l_ptr->max_pkt_target);
2157 } 1977 }
2158 1978
2159 if (tipc_node_has_redundant_links(l_ptr->owner)) { 1979 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr));
2160 msg_set_redundant_link(msg); 1980 msg_set_redundant_link(msg, r_flag);
2161 } else {
2162 msg_clear_redundant_link(msg);
2163 }
2164 msg_set_linkprio(msg, l_ptr->priority); 1981 msg_set_linkprio(msg, l_ptr->priority);
2165 1982
2166 /* Ensure sequence number will not fit : */ 1983 /* Ensure sequence number will not fit : */
@@ -2172,7 +1989,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2172 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { 1989 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
2173 if (!l_ptr->proto_msg_queue) { 1990 if (!l_ptr->proto_msg_queue) {
2174 l_ptr->proto_msg_queue = 1991 l_ptr->proto_msg_queue =
2175 buf_acquire(sizeof(l_ptr->proto_msg)); 1992 tipc_buf_acquire(sizeof(l_ptr->proto_msg));
2176 } 1993 }
2177 buf = l_ptr->proto_msg_queue; 1994 buf = l_ptr->proto_msg_queue;
2178 if (!buf) 1995 if (!buf)
@@ -2180,13 +1997,10 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
2180 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); 1997 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
2181 return; 1998 return;
2182 } 1999 }
2183 msg_set_timestamp(msg, jiffies_to_msecs(jiffies));
2184 2000
2185 /* Message can be sent */ 2001 /* Message can be sent */
2186 2002
2187 msg_dbg(msg, ">>"); 2003 buf = tipc_buf_acquire(msg_size);
2188
2189 buf = buf_acquire(msg_size);
2190 if (!buf) 2004 if (!buf)
2191 return; 2005 return;
2192 2006
@@ -2219,8 +2033,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2219 u32 msg_tol; 2033 u32 msg_tol;
2220 struct tipc_msg *msg = buf_msg(buf); 2034 struct tipc_msg *msg = buf_msg(buf);
2221 2035
2222 dbg("AT(%u):", jiffies_to_msecs(jiffies));
2223 msg_dbg(msg, "<<");
2224 if (link_blocked(l_ptr)) 2036 if (link_blocked(l_ptr))
2225 goto exit; 2037 goto exit;
2226 2038
@@ -2239,11 +2051,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2239 case RESET_MSG: 2051 case RESET_MSG:
2240 if (!link_working_unknown(l_ptr) && 2052 if (!link_working_unknown(l_ptr) &&
2241 (l_ptr->peer_session != INVALID_SESSION)) { 2053 (l_ptr->peer_session != INVALID_SESSION)) {
2242 if (msg_session(msg) == l_ptr->peer_session) { 2054 if (msg_session(msg) == l_ptr->peer_session)
2243 dbg("Duplicate RESET: %u<->%u\n",
2244 msg_session(msg), l_ptr->peer_session);
2245 break; /* duplicate: ignore */ 2055 break; /* duplicate: ignore */
2246 }
2247 } 2056 }
2248 /* fall thru' */ 2057 /* fall thru' */
2249 case ACTIVATE_MSG: 2058 case ACTIVATE_MSG:
@@ -2251,8 +2060,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2251 2060
2252 strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg)); 2061 strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg));
2253 2062
2254 if ((msg_tol = msg_link_tolerance(msg)) && 2063 msg_tol = msg_link_tolerance(msg);
2255 (msg_tol > l_ptr->tolerance)) 2064 if (msg_tol > l_ptr->tolerance)
2256 link_set_supervision_props(l_ptr, msg_tol); 2065 link_set_supervision_props(l_ptr, msg_tol);
2257 2066
2258 if (msg_linkprio(msg) > l_ptr->priority) 2067 if (msg_linkprio(msg) > l_ptr->priority)
@@ -2275,13 +2084,13 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2275 l_ptr->peer_bearer_id = msg_bearer_id(msg); 2084 l_ptr->peer_bearer_id = msg_bearer_id(msg);
2276 2085
2277 /* Synchronize broadcast sequence numbers */ 2086 /* Synchronize broadcast sequence numbers */
2278 if (!tipc_node_has_redundant_links(l_ptr->owner)) { 2087 if (!tipc_node_redundant_links(l_ptr->owner))
2279 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); 2088 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
2280 }
2281 break; 2089 break;
2282 case STATE_MSG: 2090 case STATE_MSG:
2283 2091
2284 if ((msg_tol = msg_link_tolerance(msg))) 2092 msg_tol = msg_link_tolerance(msg);
2093 if (msg_tol)
2285 link_set_supervision_props(l_ptr, msg_tol); 2094 link_set_supervision_props(l_ptr, msg_tol);
2286 2095
2287 if (msg_linkprio(msg) && 2096 if (msg_linkprio(msg) &&
@@ -2304,8 +2113,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2304 2113
2305 max_pkt_ack = msg_max_pkt(msg); 2114 max_pkt_ack = msg_max_pkt(msg);
2306 if (max_pkt_ack > l_ptr->max_pkt) { 2115 if (max_pkt_ack > l_ptr->max_pkt) {
2307 dbg("Link <%s> updated MTU %u -> %u\n",
2308 l_ptr->name, l_ptr->max_pkt, max_pkt_ack);
2309 l_ptr->max_pkt = max_pkt_ack; 2116 l_ptr->max_pkt = max_pkt_ack;
2310 l_ptr->max_pkt_probes = 0; 2117 l_ptr->max_pkt_probes = 0;
2311 } 2118 }
@@ -2313,9 +2120,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2313 max_pkt_ack = 0; 2120 max_pkt_ack = 0;
2314 if (msg_probe(msg)) { 2121 if (msg_probe(msg)) {
2315 l_ptr->stats.recv_probes++; 2122 l_ptr->stats.recv_probes++;
2316 if (msg_size(msg) > sizeof(l_ptr->proto_msg)) { 2123 if (msg_size(msg) > sizeof(l_ptr->proto_msg))
2317 max_pkt_ack = msg_size(msg); 2124 max_pkt_ack = msg_size(msg);
2318 }
2319 } 2125 }
2320 2126
2321 /* Protocol message before retransmits, reduce loss risk */ 2127 /* Protocol message before retransmits, reduce loss risk */
@@ -2327,14 +2133,11 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2327 0, rec_gap, 0, 0, max_pkt_ack); 2133 0, rec_gap, 0, 0, max_pkt_ack);
2328 } 2134 }
2329 if (msg_seq_gap(msg)) { 2135 if (msg_seq_gap(msg)) {
2330 msg_dbg(msg, "With Gap:");
2331 l_ptr->stats.recv_nacks++; 2136 l_ptr->stats.recv_nacks++;
2332 tipc_link_retransmit(l_ptr, l_ptr->first_out, 2137 tipc_link_retransmit(l_ptr, l_ptr->first_out,
2333 msg_seq_gap(msg)); 2138 msg_seq_gap(msg));
2334 } 2139 }
2335 break; 2140 break;
2336 default:
2337 msg_dbg(buf_msg(buf), "<DISCARDING UNKNOWN<");
2338 } 2141 }
2339exit: 2142exit:
2340 buf_discard(buf); 2143 buf_discard(buf);
@@ -2345,10 +2148,10 @@ exit:
2345 * tipc_link_tunnel(): Send one message via a link belonging to 2148 * tipc_link_tunnel(): Send one message via a link belonging to
2346 * another bearer. Owner node is locked. 2149 * another bearer. Owner node is locked.
2347 */ 2150 */
2348void tipc_link_tunnel(struct link *l_ptr, 2151static void tipc_link_tunnel(struct link *l_ptr,
2349 struct tipc_msg *tunnel_hdr, 2152 struct tipc_msg *tunnel_hdr,
2350 struct tipc_msg *msg, 2153 struct tipc_msg *msg,
2351 u32 selector) 2154 u32 selector)
2352{ 2155{
2353 struct link *tunnel; 2156 struct link *tunnel;
2354 struct sk_buff *buf; 2157 struct sk_buff *buf;
@@ -2361,7 +2164,7 @@ void tipc_link_tunnel(struct link *l_ptr,
2361 return; 2164 return;
2362 } 2165 }
2363 msg_set_size(tunnel_hdr, length + INT_H_SIZE); 2166 msg_set_size(tunnel_hdr, length + INT_H_SIZE);
2364 buf = buf_acquire(length + INT_H_SIZE); 2167 buf = tipc_buf_acquire(length + INT_H_SIZE);
2365 if (!buf) { 2168 if (!buf) {
2366 warn("Link changeover error, " 2169 warn("Link changeover error, "
2367 "unable to send tunnel msg\n"); 2170 "unable to send tunnel msg\n");
@@ -2369,8 +2172,6 @@ void tipc_link_tunnel(struct link *l_ptr,
2369 } 2172 }
2370 skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE); 2173 skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE);
2371 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length); 2174 skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length);
2372 dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane);
2373 msg_dbg(buf_msg(buf), ">SEND>");
2374 tipc_link_send_buf(tunnel, buf); 2175 tipc_link_send_buf(tunnel, buf);
2375} 2176}
2376 2177
@@ -2402,18 +2203,14 @@ void tipc_link_changeover(struct link *l_ptr)
2402 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); 2203 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
2403 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2204 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2404 msg_set_msgcnt(&tunnel_hdr, msgcount); 2205 msg_set_msgcnt(&tunnel_hdr, msgcount);
2405 dbg("Link changeover requires %u tunnel messages\n", msgcount);
2406 2206
2407 if (!l_ptr->first_out) { 2207 if (!l_ptr->first_out) {
2408 struct sk_buff *buf; 2208 struct sk_buff *buf;
2409 2209
2410 buf = buf_acquire(INT_H_SIZE); 2210 buf = tipc_buf_acquire(INT_H_SIZE);
2411 if (buf) { 2211 if (buf) {
2412 skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); 2212 skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE);
2413 msg_set_size(&tunnel_hdr, INT_H_SIZE); 2213 msg_set_size(&tunnel_hdr, INT_H_SIZE);
2414 dbg("%c->%c:", l_ptr->b_ptr->net_plane,
2415 tunnel->b_ptr->net_plane);
2416 msg_dbg(&tunnel_hdr, "EMPTY>SEND>");
2417 tipc_link_send_buf(tunnel, buf); 2214 tipc_link_send_buf(tunnel, buf);
2418 } else { 2215 } else {
2419 warn("Link changeover error, " 2216 warn("Link changeover error, "
@@ -2430,11 +2227,11 @@ void tipc_link_changeover(struct link *l_ptr)
2430 2227
2431 if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) { 2228 if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) {
2432 struct tipc_msg *m = msg_get_wrapped(msg); 2229 struct tipc_msg *m = msg_get_wrapped(msg);
2433 unchar* pos = (unchar*)m; 2230 unchar *pos = (unchar *)m;
2434 2231
2435 msgcount = msg_msgcnt(msg); 2232 msgcount = msg_msgcnt(msg);
2436 while (msgcount--) { 2233 while (msgcount--) {
2437 msg_set_seqno(m,msg_seqno(msg)); 2234 msg_set_seqno(m, msg_seqno(msg));
2438 tipc_link_tunnel(l_ptr, &tunnel_hdr, m, 2235 tipc_link_tunnel(l_ptr, &tunnel_hdr, m,
2439 msg_link_selector(m)); 2236 msg_link_selector(m));
2440 pos += align(msg_size(m)); 2237 pos += align(msg_size(m));
@@ -2468,7 +2265,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2468 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */ 2265 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */
2469 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 2266 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
2470 msg_set_size(&tunnel_hdr, length + INT_H_SIZE); 2267 msg_set_size(&tunnel_hdr, length + INT_H_SIZE);
2471 outbuf = buf_acquire(length + INT_H_SIZE); 2268 outbuf = tipc_buf_acquire(length + INT_H_SIZE);
2472 if (outbuf == NULL) { 2269 if (outbuf == NULL) {
2473 warn("Link changeover error, " 2270 warn("Link changeover error, "
2474 "unable to send duplicate msg\n"); 2271 "unable to send duplicate msg\n");
@@ -2477,9 +2274,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2477 skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE); 2274 skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE);
2478 skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data, 2275 skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data,
2479 length); 2276 length);
2480 dbg("%c->%c:", l_ptr->b_ptr->net_plane,
2481 tunnel->b_ptr->net_plane);
2482 msg_dbg(buf_msg(outbuf), ">SEND>");
2483 tipc_link_send_buf(tunnel, outbuf); 2277 tipc_link_send_buf(tunnel, outbuf);
2484 if (!tipc_link_is_up(l_ptr)) 2278 if (!tipc_link_is_up(l_ptr))
2485 return; 2279 return;
@@ -2504,7 +2298,7 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
2504 u32 size = msg_size(msg); 2298 u32 size = msg_size(msg);
2505 struct sk_buff *eb; 2299 struct sk_buff *eb;
2506 2300
2507 eb = buf_acquire(size); 2301 eb = tipc_buf_acquire(size);
2508 if (eb) 2302 if (eb)
2509 skb_copy_to_linear_data(eb, msg, size); 2303 skb_copy_to_linear_data(eb, msg, size);
2510 return eb; 2304 return eb;
@@ -2526,31 +2320,24 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2526 u32 msg_count = msg_msgcnt(tunnel_msg); 2320 u32 msg_count = msg_msgcnt(tunnel_msg);
2527 2321
2528 dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; 2322 dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)];
2529 if (!dest_link) { 2323 if (!dest_link)
2530 msg_dbg(tunnel_msg, "NOLINK/<REC<");
2531 goto exit; 2324 goto exit;
2532 }
2533 if (dest_link == *l_ptr) { 2325 if (dest_link == *l_ptr) {
2534 err("Unexpected changeover message on link <%s>\n", 2326 err("Unexpected changeover message on link <%s>\n",
2535 (*l_ptr)->name); 2327 (*l_ptr)->name);
2536 goto exit; 2328 goto exit;
2537 } 2329 }
2538 dbg("%c<-%c:", dest_link->b_ptr->net_plane,
2539 (*l_ptr)->b_ptr->net_plane);
2540 *l_ptr = dest_link; 2330 *l_ptr = dest_link;
2541 msg = msg_get_wrapped(tunnel_msg); 2331 msg = msg_get_wrapped(tunnel_msg);
2542 2332
2543 if (msg_typ == DUPLICATE_MSG) { 2333 if (msg_typ == DUPLICATE_MSG) {
2544 if (less(msg_seqno(msg), mod(dest_link->next_in_no))) { 2334 if (less(msg_seqno(msg), mod(dest_link->next_in_no)))
2545 msg_dbg(tunnel_msg, "DROP/<REC<");
2546 goto exit; 2335 goto exit;
2547 } 2336 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2548 *buf = buf_extract(tunnel_buf,INT_H_SIZE);
2549 if (*buf == NULL) { 2337 if (*buf == NULL) {
2550 warn("Link changeover error, duplicate msg dropped\n"); 2338 warn("Link changeover error, duplicate msg dropped\n");
2551 goto exit; 2339 goto exit;
2552 } 2340 }
2553 msg_dbg(tunnel_msg, "TNL<REC<");
2554 buf_discard(tunnel_buf); 2341 buf_discard(tunnel_buf);
2555 return 1; 2342 return 1;
2556 } 2343 }
@@ -2558,18 +2345,14 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2558 /* First original message ?: */ 2345 /* First original message ?: */
2559 2346
2560 if (tipc_link_is_up(dest_link)) { 2347 if (tipc_link_is_up(dest_link)) {
2561 msg_dbg(tunnel_msg, "UP/FIRST/<REC<");
2562 info("Resetting link <%s>, changeover initiated by peer\n", 2348 info("Resetting link <%s>, changeover initiated by peer\n",
2563 dest_link->name); 2349 dest_link->name);
2564 tipc_link_reset(dest_link); 2350 tipc_link_reset(dest_link);
2565 dest_link->exp_msg_count = msg_count; 2351 dest_link->exp_msg_count = msg_count;
2566 dbg("Expecting %u tunnelled messages\n", msg_count);
2567 if (!msg_count) 2352 if (!msg_count)
2568 goto exit; 2353 goto exit;
2569 } else if (dest_link->exp_msg_count == START_CHANGEOVER) { 2354 } else if (dest_link->exp_msg_count == START_CHANGEOVER) {
2570 msg_dbg(tunnel_msg, "BLK/FIRST/<REC<");
2571 dest_link->exp_msg_count = msg_count; 2355 dest_link->exp_msg_count = msg_count;
2572 dbg("Expecting %u tunnelled messages\n", msg_count);
2573 if (!msg_count) 2356 if (!msg_count)
2574 goto exit; 2357 goto exit;
2575 } 2358 }
@@ -2579,18 +2362,14 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2579 if (dest_link->exp_msg_count == 0) { 2362 if (dest_link->exp_msg_count == 0) {
2580 warn("Link switchover error, " 2363 warn("Link switchover error, "
2581 "got too many tunnelled messages\n"); 2364 "got too many tunnelled messages\n");
2582 msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<");
2583 dbg_print_link(dest_link, "LINK:");
2584 goto exit; 2365 goto exit;
2585 } 2366 }
2586 dest_link->exp_msg_count--; 2367 dest_link->exp_msg_count--;
2587 if (less(msg_seqno(msg), dest_link->reset_checkpoint)) { 2368 if (less(msg_seqno(msg), dest_link->reset_checkpoint)) {
2588 msg_dbg(tunnel_msg, "DROP/DUPL/<REC<");
2589 goto exit; 2369 goto exit;
2590 } else { 2370 } else {
2591 *buf = buf_extract(tunnel_buf, INT_H_SIZE); 2371 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2592 if (*buf != NULL) { 2372 if (*buf != NULL) {
2593 msg_dbg(tunnel_msg, "TNL<REC<");
2594 buf_discard(tunnel_buf); 2373 buf_discard(tunnel_buf);
2595 return 1; 2374 return 1;
2596 } else { 2375 } else {
@@ -2612,7 +2391,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2612 u32 pos = INT_H_SIZE; 2391 u32 pos = INT_H_SIZE;
2613 struct sk_buff *obuf; 2392 struct sk_buff *obuf;
2614 2393
2615 msg_dbg(buf_msg(buf), "<BNDL<: ");
2616 while (msgcount--) { 2394 while (msgcount--) {
2617 obuf = buf_extract(buf, pos); 2395 obuf = buf_extract(buf, pos);
2618 if (obuf == NULL) { 2396 if (obuf == NULL) {
@@ -2620,7 +2398,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2620 break; 2398 break;
2621 } 2399 }
2622 pos += align(msg_size(buf_msg(obuf))); 2400 pos += align(msg_size(buf_msg(obuf)));
2623 msg_dbg(buf_msg(obuf), " /");
2624 tipc_net_route_msg(obuf); 2401 tipc_net_route_msg(obuf);
2625 } 2402 }
2626 buf_discard(buf); 2403 buf_discard(buf);
@@ -2632,12 +2409,14 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2632 2409
2633 2410
2634/* 2411/*
2635 * tipc_link_send_long_buf: Entry for buffers needing fragmentation. 2412 * link_send_long_buf: Entry for buffers needing fragmentation.
2636 * The buffer is complete, inclusive total message length. 2413 * The buffer is complete, inclusive total message length.
2637 * Returns user data length. 2414 * Returns user data length.
2638 */ 2415 */
2639int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) 2416static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2640{ 2417{
2418 struct sk_buff *buf_chain = NULL;
2419 struct sk_buff *buf_chain_tail = (struct sk_buff *)&buf_chain;
2641 struct tipc_msg *inmsg = buf_msg(buf); 2420 struct tipc_msg *inmsg = buf_msg(buf);
2642 struct tipc_msg fragm_hdr; 2421 struct tipc_msg fragm_hdr;
2643 u32 insize = msg_size(inmsg); 2422 u32 insize = msg_size(inmsg);
@@ -2646,7 +2425,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2646 u32 rest = insize; 2425 u32 rest = insize;
2647 u32 pack_sz = l_ptr->max_pkt; 2426 u32 pack_sz = l_ptr->max_pkt;
2648 u32 fragm_sz = pack_sz - INT_H_SIZE; 2427 u32 fragm_sz = pack_sz - INT_H_SIZE;
2649 u32 fragm_no = 1; 2428 u32 fragm_no = 0;
2650 u32 destaddr; 2429 u32 destaddr;
2651 2430
2652 if (msg_short(inmsg)) 2431 if (msg_short(inmsg))
@@ -2654,17 +2433,10 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2654 else 2433 else
2655 destaddr = msg_destnode(inmsg); 2434 destaddr = msg_destnode(inmsg);
2656 2435
2657 if (msg_routed(inmsg))
2658 msg_set_prevnode(inmsg, tipc_own_addr);
2659
2660 /* Prepare reusable fragment header: */ 2436 /* Prepare reusable fragment header: */
2661 2437
2662 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 2438 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
2663 INT_H_SIZE, destaddr); 2439 INT_H_SIZE, destaddr);
2664 msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg));
2665 msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++));
2666 msg_set_fragm_no(&fragm_hdr, fragm_no);
2667 l_ptr->stats.sent_fragmented++;
2668 2440
2669 /* Chop up message: */ 2441 /* Chop up message: */
2670 2442
@@ -2675,29 +2447,39 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2675 fragm_sz = rest; 2447 fragm_sz = rest;
2676 msg_set_type(&fragm_hdr, LAST_FRAGMENT); 2448 msg_set_type(&fragm_hdr, LAST_FRAGMENT);
2677 } 2449 }
2678 fragm = buf_acquire(fragm_sz + INT_H_SIZE); 2450 fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
2679 if (fragm == NULL) { 2451 if (fragm == NULL) {
2680 warn("Link unable to fragment message\n"); 2452 buf_discard(buf);
2681 dsz = -ENOMEM; 2453 while (buf_chain) {
2682 goto exit; 2454 buf = buf_chain;
2455 buf_chain = buf_chain->next;
2456 buf_discard(buf);
2457 }
2458 return -ENOMEM;
2683 } 2459 }
2684 msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); 2460 msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE);
2461 fragm_no++;
2462 msg_set_fragm_no(&fragm_hdr, fragm_no);
2685 skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); 2463 skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE);
2686 skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, 2464 skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs,
2687 fragm_sz); 2465 fragm_sz);
2688 /* Send queued messages first, if any: */ 2466 buf_chain_tail->next = fragm;
2467 buf_chain_tail = fragm;
2689 2468
2690 l_ptr->stats.sent_fragments++;
2691 tipc_link_send_buf(l_ptr, fragm);
2692 if (!tipc_link_is_up(l_ptr))
2693 return dsz;
2694 msg_set_fragm_no(&fragm_hdr, ++fragm_no);
2695 rest -= fragm_sz; 2469 rest -= fragm_sz;
2696 crs += fragm_sz; 2470 crs += fragm_sz;
2697 msg_set_type(&fragm_hdr, FRAGMENT); 2471 msg_set_type(&fragm_hdr, FRAGMENT);
2698 } 2472 }
2699exit:
2700 buf_discard(buf); 2473 buf_discard(buf);
2474
2475 /* Append chain of fragments to send queue & send them */
2476
2477 l_ptr->long_msg_seq_no++;
2478 link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no);
2479 l_ptr->stats.sent_fragments += fragm_no;
2480 l_ptr->stats.sent_fragmented++;
2481 tipc_link_push_queue(l_ptr);
2482
2701 return dsz; 2483 return dsz;
2702} 2484}
2703 2485
@@ -2705,7 +2487,7 @@ exit:
2705 * A pending message being re-assembled must store certain values 2487 * A pending message being re-assembled must store certain values
2706 * to handle subsequent fragments correctly. The following functions 2488 * to handle subsequent fragments correctly. The following functions
2707 * help storing these values in unused, available fields in the 2489 * help storing these values in unused, available fields in the
2708 * pending message. This makes dynamic memory allocation unecessary. 2490 * pending message. This makes dynamic memory allocation unnecessary.
2709 */ 2491 */
2710 2492
2711static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno) 2493static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno)
@@ -2757,7 +2539,6 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2757 u32 long_msg_seq_no = msg_long_msgno(fragm); 2539 u32 long_msg_seq_no = msg_long_msgno(fragm);
2758 2540
2759 *fb = NULL; 2541 *fb = NULL;
2760 msg_dbg(fragm,"FRG<REC<");
2761 2542
2762 /* Is there an incomplete message waiting for this fragment? */ 2543 /* Is there an incomplete message waiting for this fragment? */
2763 2544
@@ -2776,11 +2557,10 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2776 if (msg_type(imsg) == TIPC_MCAST_MSG) 2557 if (msg_type(imsg) == TIPC_MCAST_MSG)
2777 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; 2558 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
2778 if (msg_size(imsg) > max) { 2559 if (msg_size(imsg) > max) {
2779 msg_dbg(fragm,"<REC<Oversized: ");
2780 buf_discard(fbuf); 2560 buf_discard(fbuf);
2781 return 0; 2561 return 0;
2782 } 2562 }
2783 pbuf = buf_acquire(msg_size(imsg)); 2563 pbuf = tipc_buf_acquire(msg_size(imsg));
2784 if (pbuf != NULL) { 2564 if (pbuf != NULL) {
2785 pbuf->next = *pending; 2565 pbuf->next = *pending;
2786 *pending = pbuf; 2566 *pending = pbuf;
@@ -2789,8 +2569,8 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2789 /* Prepare buffer for subsequent fragments. */ 2569 /* Prepare buffer for subsequent fragments. */
2790 2570
2791 set_long_msg_seqno(pbuf, long_msg_seq_no); 2571 set_long_msg_seqno(pbuf, long_msg_seq_no);
2792 set_fragm_size(pbuf,fragm_sz); 2572 set_fragm_size(pbuf, fragm_sz);
2793 set_expected_frags(pbuf,exp_fragm_cnt - 1); 2573 set_expected_frags(pbuf, exp_fragm_cnt - 1);
2794 } else { 2574 } else {
2795 warn("Link unable to reassemble fragmented message\n"); 2575 warn("Link unable to reassemble fragmented message\n");
2796 } 2576 }
@@ -2817,13 +2597,9 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2817 *m = buf_msg(pbuf); 2597 *m = buf_msg(pbuf);
2818 return 1; 2598 return 1;
2819 } 2599 }
2820 set_expected_frags(pbuf,exp_frags); 2600 set_expected_frags(pbuf, exp_frags);
2821 return 0; 2601 return 0;
2822 } 2602 }
2823 dbg(" Discarding orphan fragment %x\n",fbuf);
2824 msg_dbg(fragm,"ORPHAN:");
2825 dbg("Pending long buffers:\n");
2826 dbg_print_buf_chain(*pending);
2827 buf_discard(fbuf); 2603 buf_discard(fbuf);
2828 return 0; 2604 return 0;
2829} 2605}
@@ -2851,11 +2627,6 @@ static void link_check_defragm_bufs(struct link *l_ptr)
2851 incr_timer_cnt(buf); 2627 incr_timer_cnt(buf);
2852 prev = buf; 2628 prev = buf;
2853 } else { 2629 } else {
2854 dbg(" Discarding incomplete long buffer\n");
2855 msg_dbg(buf_msg(buf), "LONG:");
2856 dbg_print_link(l_ptr, "curr:");
2857 dbg("Pending long buffers:\n");
2858 dbg_print_buf_chain(l_ptr->defragm_buf);
2859 if (prev) 2630 if (prev)
2860 prev->next = buf->next; 2631 prev->next = buf->next;
2861 else 2632 else
@@ -2870,6 +2641,9 @@ static void link_check_defragm_bufs(struct link *l_ptr)
2870 2641
2871static void link_set_supervision_props(struct link *l_ptr, u32 tolerance) 2642static void link_set_supervision_props(struct link *l_ptr, u32 tolerance)
2872{ 2643{
2644 if ((tolerance < TIPC_MIN_LINK_TOL) || (tolerance > TIPC_MAX_LINK_TOL))
2645 return;
2646
2873 l_ptr->tolerance = tolerance; 2647 l_ptr->tolerance = tolerance;
2874 l_ptr->continuity_interval = 2648 l_ptr->continuity_interval =
2875 ((tolerance / 4) > 500) ? 500 : tolerance / 4; 2649 ((tolerance / 4) > 500) ? 500 : tolerance / 4;
@@ -2890,7 +2664,6 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
2890 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900; 2664 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900;
2891 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200; 2665 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200;
2892 l_ptr->queue_limit[CONN_MANAGER] = 1200; 2666 l_ptr->queue_limit[CONN_MANAGER] = 1200;
2893 l_ptr->queue_limit[ROUTE_DISTRIBUTOR] = 1200;
2894 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500; 2667 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500;
2895 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000; 2668 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000;
2896 /* FRAGMENT and LAST_FRAGMENT packets */ 2669 /* FRAGMENT and LAST_FRAGMENT packets */
@@ -2911,7 +2684,7 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
2911static struct link *link_find_link(const char *name, struct tipc_node **node) 2684static struct link *link_find_link(const char *name, struct tipc_node **node)
2912{ 2685{
2913 struct link_name link_name_parts; 2686 struct link_name link_name_parts;
2914 struct bearer *b_ptr; 2687 struct tipc_bearer *b_ptr;
2915 struct link *l_ptr; 2688 struct link *l_ptr;
2916 2689
2917 if (!link_name_validate(name, &link_name_parts)) 2690 if (!link_name_validate(name, &link_name_parts))
@@ -3174,44 +2947,6 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s
3174 return buf; 2947 return buf;
3175} 2948}
3176 2949
3177#if 0
3178int link_control(const char *name, u32 op, u32 val)
3179{
3180 int res = -EINVAL;
3181 struct link *l_ptr;
3182 u32 bearer_id;
3183 struct tipc_node * node;
3184 u32 a;
3185
3186 a = link_name2addr(name, &bearer_id);
3187 read_lock_bh(&tipc_net_lock);
3188 node = tipc_node_find(a);
3189 if (node) {
3190 tipc_node_lock(node);
3191 l_ptr = node->links[bearer_id];
3192 if (l_ptr) {
3193 if (op == TIPC_REMOVE_LINK) {
3194 struct bearer *b_ptr = l_ptr->b_ptr;
3195 spin_lock_bh(&b_ptr->publ.lock);
3196 tipc_link_delete(l_ptr);
3197 spin_unlock_bh(&b_ptr->publ.lock);
3198 }
3199 if (op == TIPC_CMD_BLOCK_LINK) {
3200 tipc_link_reset(l_ptr);
3201 l_ptr->blocked = 1;
3202 }
3203 if (op == TIPC_CMD_UNBLOCK_LINK) {
3204 l_ptr->blocked = 0;
3205 }
3206 res = 0;
3207 }
3208 tipc_node_unlock(node);
3209 }
3210 read_unlock_bh(&tipc_net_lock);
3211 return res;
3212}
3213#endif
3214
3215/** 2950/**
3216 * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination 2951 * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination
3217 * @dest: network address of destination node 2952 * @dest: network address of destination node
@@ -3230,7 +2965,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
3230 return MAX_MSG_SIZE; 2965 return MAX_MSG_SIZE;
3231 2966
3232 read_lock_bh(&tipc_net_lock); 2967 read_lock_bh(&tipc_net_lock);
3233 n_ptr = tipc_node_select(dest, selector); 2968 n_ptr = tipc_node_find(dest);
3234 if (n_ptr) { 2969 if (n_ptr) {
3235 tipc_node_lock(n_ptr); 2970 tipc_node_lock(n_ptr);
3236 l_ptr = n_ptr->active_links[selector & 1]; 2971 l_ptr = n_ptr->active_links[selector & 1];
@@ -3242,49 +2977,22 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
3242 return res; 2977 return res;
3243} 2978}
3244 2979
3245#if 0 2980static void link_print(struct link *l_ptr, const char *str)
3246static void link_dump_rec_queue(struct link *l_ptr)
3247{ 2981{
3248 struct sk_buff *crs; 2982 char print_area[256];
3249 2983 struct print_buf pb;
3250 if (!l_ptr->oldest_deferred_in) { 2984 struct print_buf *buf = &pb;
3251 info("Reception queue empty\n");
3252 return;
3253 }
3254 info("Contents of Reception queue:\n");
3255 crs = l_ptr->oldest_deferred_in;
3256 while (crs) {
3257 if (crs->data == (void *)0x0000a3a3) {
3258 info("buffer %x invalid\n", crs);
3259 return;
3260 }
3261 msg_dbg(buf_msg(crs), "In rec queue:\n");
3262 crs = crs->next;
3263 }
3264}
3265#endif
3266 2985
3267static void link_dump_send_queue(struct link *l_ptr) 2986 tipc_printbuf_init(buf, print_area, sizeof(print_area));
3268{
3269 if (l_ptr->next_out) {
3270 info("\nContents of unsent queue:\n");
3271 dbg_print_buf_chain(l_ptr->next_out);
3272 }
3273 info("\nContents of send queue:\n");
3274 if (l_ptr->first_out) {
3275 dbg_print_buf_chain(l_ptr->first_out);
3276 }
3277 info("Empty send queue\n");
3278}
3279 2987
3280static void link_print(struct link *l_ptr, struct print_buf *buf,
3281 const char *str)
3282{
3283 tipc_printf(buf, str); 2988 tipc_printf(buf, str);
3284 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
3285 return;
3286 tipc_printf(buf, "Link %x<%s>:", 2989 tipc_printf(buf, "Link %x<%s>:",
3287 l_ptr->addr, l_ptr->b_ptr->publ.name); 2990 l_ptr->addr, l_ptr->b_ptr->name);
2991
2992#ifdef CONFIG_TIPC_DEBUG
2993 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
2994 goto print_state;
2995
3288 tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no)); 2996 tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no));
3289 tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no)); 2997 tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no));
3290 tipc_printf(buf, "SQUE"); 2998 tipc_printf(buf, "SQUE");
@@ -3299,10 +3007,9 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
3299 != (l_ptr->out_queue_size - 1)) || 3007 != (l_ptr->out_queue_size - 1)) ||
3300 (l_ptr->last_out->next != NULL)) { 3008 (l_ptr->last_out->next != NULL)) {
3301 tipc_printf(buf, "\nSend queue inconsistency\n"); 3009 tipc_printf(buf, "\nSend queue inconsistency\n");
3302 tipc_printf(buf, "first_out= %x ", l_ptr->first_out); 3010 tipc_printf(buf, "first_out= %p ", l_ptr->first_out);
3303 tipc_printf(buf, "next_out= %x ", l_ptr->next_out); 3011 tipc_printf(buf, "next_out= %p ", l_ptr->next_out);
3304 tipc_printf(buf, "last_out= %x ", l_ptr->last_out); 3012 tipc_printf(buf, "last_out= %p ", l_ptr->last_out);
3305 link_dump_send_queue(l_ptr);
3306 } 3013 }
3307 } else 3014 } else
3308 tipc_printf(buf, "[]"); 3015 tipc_printf(buf, "[]");
@@ -3316,14 +3023,20 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
3316 l_ptr->deferred_inqueue_sz); 3023 l_ptr->deferred_inqueue_sz);
3317 } 3024 }
3318 } 3025 }
3026print_state:
3027#endif
3028
3319 if (link_working_unknown(l_ptr)) 3029 if (link_working_unknown(l_ptr))
3320 tipc_printf(buf, ":WU"); 3030 tipc_printf(buf, ":WU");
3321 if (link_reset_reset(l_ptr)) 3031 else if (link_reset_reset(l_ptr))
3322 tipc_printf(buf, ":RR"); 3032 tipc_printf(buf, ":RR");
3323 if (link_reset_unknown(l_ptr)) 3033 else if (link_reset_unknown(l_ptr))
3324 tipc_printf(buf, ":RU"); 3034 tipc_printf(buf, ":RU");
3325 if (link_working_working(l_ptr)) 3035 else if (link_working_working(l_ptr))
3326 tipc_printf(buf, ":WW"); 3036 tipc_printf(buf, ":WW");
3327 tipc_printf(buf, "\n"); 3037 tipc_printf(buf, "\n");
3038
3039 tipc_printbuf_validate(buf);
3040 info("%s", print_area);
3328} 3041}
3329 3042
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 2e5385c47d30..74fbecab1ea0 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -2,7 +2,7 @@
2 * net/tipc/link.h: Include file for TIPC link code 2 * net/tipc/link.h: Include file for TIPC link code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,9 +37,8 @@
37#ifndef _TIPC_LINK_H 37#ifndef _TIPC_LINK_H
38#define _TIPC_LINK_H 38#define _TIPC_LINK_H
39 39
40#include "dbg.h" 40#include "log.h"
41#include "msg.h" 41#include "msg.h"
42#include "bearer.h"
43#include "node.h" 42#include "node.h"
44 43
45#define PUSH_FAILED 1 44#define PUSH_FAILED 1
@@ -108,7 +107,6 @@
108 * @long_msg_seq_no: next identifier to use for outbound fragmented messages 107 * @long_msg_seq_no: next identifier to use for outbound fragmented messages
109 * @defragm_buf: list of partially reassembled inbound message fragments 108 * @defragm_buf: list of partially reassembled inbound message fragments
110 * @stats: collects statistics regarding link activity 109 * @stats: collects statistics regarding link activity
111 * @print_buf: print buffer used to log link activity
112 */ 110 */
113 111
114struct link { 112struct link {
@@ -124,7 +122,7 @@ struct link {
124 u32 checkpoint; 122 u32 checkpoint;
125 u32 peer_session; 123 u32 peer_session;
126 u32 peer_bearer_id; 124 u32 peer_bearer_id;
127 struct bearer *b_ptr; 125 struct tipc_bearer *b_ptr;
128 u32 tolerance; 126 u32 tolerance;
129 u32 continuity_interval; 127 u32 continuity_interval;
130 u32 abort_limit; 128 u32 abort_limit;
@@ -198,30 +196,19 @@ struct link {
198 u32 bearer_congs; 196 u32 bearer_congs;
199 u32 deferred_recv; 197 u32 deferred_recv;
200 u32 duplicates; 198 u32 duplicates;
201 199 u32 max_queue_sz; /* send queue size high water mark */
202 /* for statistical profiling of send queue size */ 200 u32 accu_queue_sz; /* used for send queue size profiling */
203 201 u32 queue_sz_counts; /* used for send queue size profiling */
204 u32 max_queue_sz; 202 u32 msg_length_counts; /* used for message length profiling */
205 u32 accu_queue_sz; 203 u32 msg_lengths_total; /* used for message length profiling */
206 u32 queue_sz_counts; 204 u32 msg_length_profile[7]; /* used for msg. length profiling */
207
208 /* for statistical profiling of message lengths */
209
210 u32 msg_length_counts;
211 u32 msg_lengths_total;
212 u32 msg_length_profile[7];
213#if 0
214 u32 sent_tunneled;
215 u32 recv_tunneled;
216#endif
217 } stats; 205 } stats;
218
219 struct print_buf print_buf;
220}; 206};
221 207
222struct port; 208struct tipc_port;
223 209
224struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, 210struct link *tipc_link_create(struct tipc_node *n_ptr,
211 struct tipc_bearer *b_ptr,
225 const struct tipc_media_addr *media_addr); 212 const struct tipc_media_addr *media_addr);
226void tipc_link_delete(struct link *l_ptr); 213void tipc_link_delete(struct link *l_ptr);
227void tipc_link_changeover(struct link *l_ptr); 214void tipc_link_changeover(struct link *l_ptr);
@@ -229,7 +216,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *dest);
229void tipc_link_reset_fragments(struct link *l_ptr); 216void tipc_link_reset_fragments(struct link *l_ptr);
230int tipc_link_is_up(struct link *l_ptr); 217int tipc_link_is_up(struct link *l_ptr);
231int tipc_link_is_active(struct link *l_ptr); 218int 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); 219u32 tipc_link_push_packet(struct link *l_ptr);
234void tipc_link_stop(struct link *l_ptr); 220void 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); 221struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd);
@@ -238,14 +224,12 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_
238void tipc_link_reset(struct link *l_ptr); 224void tipc_link_reset(struct link *l_ptr);
239int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector); 225int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
240int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf); 226int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf);
241u32 tipc_link_get_max_pkt(u32 dest,u32 selector); 227u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
242int tipc_link_send_sections_fast(struct port* sender, 228int tipc_link_send_sections_fast(struct tipc_port *sender,
243 struct iovec const *msg_sect, 229 struct iovec const *msg_sect,
244 const u32 num_sect, 230 const u32 num_sect,
231 unsigned int total_len,
245 u32 destnode); 232 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); 233void tipc_link_recv_bundle(struct sk_buff *buf);
250int tipc_link_recv_fragment(struct sk_buff **pending, 234int tipc_link_recv_fragment(struct sk_buff **pending,
251 struct sk_buff **fb, 235 struct sk_buff **fb,
@@ -279,12 +263,12 @@ static inline int between(u32 lower, u32 upper, u32 n)
279 263
280static inline int less_eq(u32 left, u32 right) 264static inline int less_eq(u32 left, u32 right)
281{ 265{
282 return (mod(right - left) < 32768u); 266 return mod(right - left) < 32768u;
283} 267}
284 268
285static inline int less(u32 left, u32 right) 269static inline int less(u32 left, u32 right)
286{ 270{
287 return (less_eq(left, right) && (mod(right) != mod(left))); 271 return less_eq(left, right) && (mod(right) != mod(left));
288} 272}
289 273
290static inline u32 lesser(u32 left, u32 right) 274static inline u32 lesser(u32 left, u32 right)
@@ -299,32 +283,32 @@ static inline u32 lesser(u32 left, u32 right)
299 283
300static inline int link_working_working(struct link *l_ptr) 284static inline int link_working_working(struct link *l_ptr)
301{ 285{
302 return (l_ptr->state == WORKING_WORKING); 286 return l_ptr->state == WORKING_WORKING;
303} 287}
304 288
305static inline int link_working_unknown(struct link *l_ptr) 289static inline int link_working_unknown(struct link *l_ptr)
306{ 290{
307 return (l_ptr->state == WORKING_UNKNOWN); 291 return l_ptr->state == WORKING_UNKNOWN;
308} 292}
309 293
310static inline int link_reset_unknown(struct link *l_ptr) 294static inline int link_reset_unknown(struct link *l_ptr)
311{ 295{
312 return (l_ptr->state == RESET_UNKNOWN); 296 return l_ptr->state == RESET_UNKNOWN;
313} 297}
314 298
315static inline int link_reset_reset(struct link *l_ptr) 299static inline int link_reset_reset(struct link *l_ptr)
316{ 300{
317 return (l_ptr->state == RESET_RESET); 301 return l_ptr->state == RESET_RESET;
318} 302}
319 303
320static inline int link_blocked(struct link *l_ptr) 304static inline int link_blocked(struct link *l_ptr)
321{ 305{
322 return (l_ptr->exp_msg_count || l_ptr->blocked); 306 return l_ptr->exp_msg_count || l_ptr->blocked;
323} 307}
324 308
325static inline int link_congested(struct link *l_ptr) 309static inline int link_congested(struct link *l_ptr)
326{ 310{
327 return (l_ptr->out_queue_size >= l_ptr->queue_limit[0]); 311 return l_ptr->out_queue_size >= l_ptr->queue_limit[0];
328} 312}
329 313
330#endif 314#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 381063817b41..03e57bf92c73 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -2,7 +2,7 @@
2 * net/tipc/msg.c: TIPC message header routines 2 * net/tipc/msg.c: TIPC message header routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,10 +35,7 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "addr.h"
39#include "dbg.h"
40#include "msg.h" 38#include "msg.h"
41#include "bearer.h"
42 39
43u32 tipc_msg_tot_importance(struct tipc_msg *m) 40u32 tipc_msg_tot_importance(struct tipc_msg *m)
44{ 41{
@@ -71,20 +68,6 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
71} 68}
72 69
73/** 70/**
74 * tipc_msg_calc_data_size - determine total data size for message
75 */
76
77int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
78{
79 int dsz = 0;
80 int i;
81
82 for (i = 0; i < num_sect; i++)
83 dsz += msg_sect[i].iov_len;
84 return dsz;
85}
86
87/**
88 * tipc_msg_build - create message using specified header and data 71 * tipc_msg_build - create message using specified header and data
89 * 72 *
90 * Note: Caller must not hold any locks in case copy_from_user() is interrupted! 73 * Note: Caller must not hold any locks in case copy_from_user() is interrupted!
@@ -92,18 +75,13 @@ int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
92 * Returns message data size or errno 75 * Returns message data size or errno
93 */ 76 */
94 77
95int tipc_msg_build(struct tipc_msg *hdr, 78int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
96 struct iovec const *msg_sect, u32 num_sect, 79 u32 num_sect, unsigned int total_len,
97 int max_size, int usrmem, struct sk_buff** buf) 80 int max_size, int usrmem, struct sk_buff **buf)
98{ 81{
99 int dsz, sz, hsz, pos, res, cnt; 82 int dsz, sz, hsz, pos, res, cnt;
100 83
101 dsz = tipc_msg_calc_data_size(msg_sect, num_sect); 84 dsz = total_len;
102 if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) {
103 *buf = NULL;
104 return -EINVAL;
105 }
106
107 pos = hsz = msg_hdr_sz(hdr); 85 pos = hsz = msg_hdr_sz(hdr);
108 sz = hsz + dsz; 86 sz = hsz + dsz;
109 msg_set_size(hdr, sz); 87 msg_set_size(hdr, sz);
@@ -112,7 +90,7 @@ int tipc_msg_build(struct tipc_msg *hdr,
112 return dsz; 90 return dsz;
113 } 91 }
114 92
115 *buf = buf_acquire(sz); 93 *buf = tipc_buf_acquire(sz);
116 if (!(*buf)) 94 if (!(*buf))
117 return -ENOMEM; 95 return -ENOMEM;
118 skb_copy_to_linear_data(*buf, hdr, hsz); 96 skb_copy_to_linear_data(*buf, hdr, hsz);
@@ -140,6 +118,7 @@ int tipc_msg_build(struct tipc_msg *hdr,
140void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) 118void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
141{ 119{
142 u32 usr = msg_user(msg); 120 u32 usr = msg_user(msg);
121 tipc_printf(buf, KERN_DEBUG);
143 tipc_printf(buf, str); 122 tipc_printf(buf, str);
144 123
145 switch (usr) { 124 switch (usr) {
@@ -163,10 +142,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
163 tipc_printf(buf, "LAST:"); 142 tipc_printf(buf, "LAST:");
164 break; 143 break;
165 default: 144 default:
166 tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); 145 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
167 146
168 } 147 }
169 tipc_printf(buf, "NO(%u/%u):",msg_long_msgno(msg), 148 tipc_printf(buf, "NO(%u/%u):", msg_long_msgno(msg),
170 msg_fragm_no(msg)); 149 msg_fragm_no(msg));
171 break; 150 break;
172 case TIPC_LOW_IMPORTANCE: 151 case TIPC_LOW_IMPORTANCE:
@@ -192,10 +171,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
192 tipc_printf(buf, "DIR:"); 171 tipc_printf(buf, "DIR:");
193 break; 172 break;
194 default: 173 default:
195 tipc_printf(buf, "UNKNOWN TYPE %u",msg_type(msg)); 174 tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg));
196 } 175 }
197 if (msg_routed(msg) && !msg_non_seq(msg))
198 tipc_printf(buf, "ROUT:");
199 if (msg_reroute_cnt(msg)) 176 if (msg_reroute_cnt(msg))
200 tipc_printf(buf, "REROUTED(%u):", 177 tipc_printf(buf, "REROUTED(%u):",
201 msg_reroute_cnt(msg)); 178 msg_reroute_cnt(msg));
@@ -210,10 +187,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
210 tipc_printf(buf, "WDRW:"); 187 tipc_printf(buf, "WDRW:");
211 break; 188 break;
212 default: 189 default:
213 tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); 190 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
214 } 191 }
215 if (msg_routed(msg))
216 tipc_printf(buf, "ROUT:");
217 if (msg_reroute_cnt(msg)) 192 if (msg_reroute_cnt(msg))
218 tipc_printf(buf, "REROUTED(%u):", 193 tipc_printf(buf, "REROUTED(%u):",
219 msg_reroute_cnt(msg)); 194 msg_reroute_cnt(msg));
@@ -229,39 +204,36 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
229 break; 204 break;
230 case CONN_ACK: 205 case CONN_ACK:
231 tipc_printf(buf, "CONN_ACK:"); 206 tipc_printf(buf, "CONN_ACK:");
232 tipc_printf(buf, "ACK(%u):",msg_msgcnt(msg)); 207 tipc_printf(buf, "ACK(%u):", msg_msgcnt(msg));
233 break; 208 break;
234 default: 209 default:
235 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 210 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
236 } 211 }
237 if (msg_routed(msg))
238 tipc_printf(buf, "ROUT:");
239 if (msg_reroute_cnt(msg)) 212 if (msg_reroute_cnt(msg))
240 tipc_printf(buf, "REROUTED(%u):",msg_reroute_cnt(msg)); 213 tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg));
241 break; 214 break;
242 case LINK_PROTOCOL: 215 case LINK_PROTOCOL:
243 tipc_printf(buf, "PROT:TIM(%u):",msg_timestamp(msg));
244 switch (msg_type(msg)) { 216 switch (msg_type(msg)) {
245 case STATE_MSG: 217 case STATE_MSG:
246 tipc_printf(buf, "STATE:"); 218 tipc_printf(buf, "STATE:");
247 tipc_printf(buf, "%s:",msg_probe(msg) ? "PRB" :""); 219 tipc_printf(buf, "%s:", msg_probe(msg) ? "PRB" : "");
248 tipc_printf(buf, "NXS(%u):",msg_next_sent(msg)); 220 tipc_printf(buf, "NXS(%u):", msg_next_sent(msg));
249 tipc_printf(buf, "GAP(%u):",msg_seq_gap(msg)); 221 tipc_printf(buf, "GAP(%u):", msg_seq_gap(msg));
250 tipc_printf(buf, "LSTBC(%u):",msg_last_bcast(msg)); 222 tipc_printf(buf, "LSTBC(%u):", msg_last_bcast(msg));
251 break; 223 break;
252 case RESET_MSG: 224 case RESET_MSG:
253 tipc_printf(buf, "RESET:"); 225 tipc_printf(buf, "RESET:");
254 if (msg_size(msg) != msg_hdr_sz(msg)) 226 if (msg_size(msg) != msg_hdr_sz(msg))
255 tipc_printf(buf, "BEAR:%s:",msg_data(msg)); 227 tipc_printf(buf, "BEAR:%s:", msg_data(msg));
256 break; 228 break;
257 case ACTIVATE_MSG: 229 case ACTIVATE_MSG:
258 tipc_printf(buf, "ACTIVATE:"); 230 tipc_printf(buf, "ACTIVATE:");
259 break; 231 break;
260 default: 232 default:
261 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 233 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
262 } 234 }
263 tipc_printf(buf, "PLANE(%c):",msg_net_plane(msg)); 235 tipc_printf(buf, "PLANE(%c):", msg_net_plane(msg));
264 tipc_printf(buf, "SESS(%u):",msg_session(msg)); 236 tipc_printf(buf, "SESS(%u):", msg_session(msg));
265 break; 237 break;
266 case CHANGEOVER_PROTOCOL: 238 case CHANGEOVER_PROTOCOL:
267 tipc_printf(buf, "TUNL:"); 239 tipc_printf(buf, "TUNL:");
@@ -271,37 +243,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
271 break; 243 break;
272 case ORIGINAL_MSG: 244 case ORIGINAL_MSG:
273 tipc_printf(buf, "ORIG:"); 245 tipc_printf(buf, "ORIG:");
274 tipc_printf(buf, "EXP(%u)",msg_msgcnt(msg)); 246 tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg));
275 break; 247 break;
276 default: 248 default:
277 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); 249 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
278 }
279 break;
280 case ROUTE_DISTRIBUTOR:
281 tipc_printf(buf, "ROUTING_MNG:");
282 switch (msg_type(msg)) {
283 case EXT_ROUTING_TABLE:
284 tipc_printf(buf, "EXT_TBL:");
285 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
286 break;
287 case LOCAL_ROUTING_TABLE:
288 tipc_printf(buf, "LOCAL_TBL:");
289 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
290 break;
291 case SLAVE_ROUTING_TABLE:
292 tipc_printf(buf, "DP_TBL:");
293 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
294 break;
295 case ROUTE_ADDITION:
296 tipc_printf(buf, "ADD:");
297 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
298 break;
299 case ROUTE_REMOVAL:
300 tipc_printf(buf, "REMOVE:");
301 tipc_printf(buf, "TO:%x:",msg_remote_node(msg));
302 break;
303 default:
304 tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg));
305 } 250 }
306 break; 251 break;
307 case LINK_CONFIG: 252 case LINK_CONFIG:
@@ -314,7 +259,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
314 tipc_printf(buf, "DSC_RESP:"); 259 tipc_printf(buf, "DSC_RESP:");
315 break; 260 break;
316 default: 261 default:
317 tipc_printf(buf, "UNKNOWN TYPE:%x:",msg_type(msg)); 262 tipc_printf(buf, "UNKNOWN TYPE:%x:", msg_type(msg));
318 break; 263 break;
319 } 264 }
320 break; 265 break;
@@ -350,7 +295,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
350 tipc_printf(buf, "UNKNOWN ERROR(%x):", 295 tipc_printf(buf, "UNKNOWN ERROR(%x):",
351 msg_errcode(msg)); 296 msg_errcode(msg));
352 } 297 }
353 default:{} 298 default:
299 break;
354 } 300 }
355 301
356 tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg)); 302 tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg));
@@ -359,9 +305,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
359 305
360 if (msg_non_seq(msg)) 306 if (msg_non_seq(msg))
361 tipc_printf(buf, "NOSEQ:"); 307 tipc_printf(buf, "NOSEQ:");
362 else { 308 else
363 tipc_printf(buf, "ACK(%u):", msg_ack(msg)); 309 tipc_printf(buf, "ACK(%u):", msg_ack(msg));
364 }
365 tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg)); 310 tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg));
366 tipc_printf(buf, "PRND(%x)", msg_prevnode(msg)); 311 tipc_printf(buf, "PRND(%x)", msg_prevnode(msg));
367 312
@@ -383,21 +328,15 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
383 tipc_printf(buf, ":OPRT(%u):", msg_origport(msg)); 328 tipc_printf(buf, ":OPRT(%u):", msg_origport(msg));
384 tipc_printf(buf, ":DPRT(%u):", msg_destport(msg)); 329 tipc_printf(buf, ":DPRT(%u):", msg_destport(msg));
385 } 330 }
386 if (msg_routed(msg) && !msg_non_seq(msg))
387 tipc_printf(buf, ":TSEQN(%u)", msg_transp_seqno(msg));
388 } 331 }
389 if (msg_user(msg) == NAME_DISTRIBUTOR) { 332 if (msg_user(msg) == NAME_DISTRIBUTOR) {
390 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); 333 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg));
391 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); 334 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg));
392 if (msg_routed(msg)) {
393 tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg));
394 }
395 } 335 }
396 336
397 if (msg_user(msg) == LINK_CONFIG) { 337 if (msg_user(msg) == LINK_CONFIG) {
398 u32* raw = (u32*)msg; 338 u32 *raw = (u32 *)msg;
399 struct tipc_media_addr* orig = (struct tipc_media_addr*)&raw[5]; 339 struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5];
400 tipc_printf(buf, ":REQL(%u):", msg_req_links(msg));
401 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); 340 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg));
402 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); 341 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg));
403 tipc_media_addr_printf(buf, orig); 342 tipc_media_addr_printf(buf, orig);
@@ -407,12 +346,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
407 tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg)); 346 tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg));
408 } 347 }
409 tipc_printf(buf, "\n"); 348 tipc_printf(buf, "\n");
410 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { 349 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg)))
411 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); 350 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
412 } 351 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT))
413 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) {
414 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); 352 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
415 }
416} 353}
417 354
418#endif 355#endif
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 995d2da35b01..8452454731fa 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -2,7 +2,7 @@
2 * net/tipc/msg.h: Include file for TIPC message header routines 2 * net/tipc/msg.h: Include file for TIPC message header routines
3 * 3 *
4 * Copyright (c) 2000-2007, Ericsson AB 4 * Copyright (c) 2000-2007, Ericsson AB
5 * Copyright (c) 2005-2008, Wind River Systems 5 * Copyright (c) 2005-2008, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,10 +37,37 @@
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
42/*
43 * Constants and routines used to read and write TIPC payload message headers
44 *
45 * Note: Some items are also used with TIPC internal message headers
46 */
41 47
42#define TIPC_VERSION 2 48#define TIPC_VERSION 2
43 49
50/*
51 * Payload message users are defined in TIPC's public API:
52 * - TIPC_LOW_IMPORTANCE
53 * - TIPC_MEDIUM_IMPORTANCE
54 * - TIPC_HIGH_IMPORTANCE
55 * - TIPC_CRITICAL_IMPORTANCE
56 */
57
58/*
59 * Payload message types
60 */
61
62#define TIPC_CONN_MSG 0
63#define TIPC_MCAST_MSG 1
64#define TIPC_NAMED_MSG 2
65#define TIPC_DIRECT_MSG 3
66
67/*
68 * Message header sizes
69 */
70
44#define SHORT_H_SIZE 24 /* Connected, in-cluster messages */ 71#define SHORT_H_SIZE 24 /* Connected, in-cluster messages */
45#define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ 72#define DIR_MSG_H_SIZE 32 /* Directly addressed messages */
46#define LONG_H_SIZE 40 /* Named messages */ 73#define LONG_H_SIZE 40 /* Named messages */
@@ -52,20 +79,26 @@
52#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) 79#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE)
53 80
54 81
55/* 82struct tipc_msg {
56 TIPC user data message header format, version 2 83 __be32 hdr[15];
84};
57 85
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 86
87static inline u32 msg_word(struct tipc_msg *m, u32 pos)
88{
89 return ntohl(m->hdr[pos]);
90}
63 91
64static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val) 92static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val)
65{ 93{
66 m->hdr[w] = htonl(val); 94 m->hdr[w] = htonl(val);
67} 95}
68 96
97static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask)
98{
99 return (msg_word(m, w) >> pos) & mask;
100}
101
69static inline void msg_set_bits(struct tipc_msg *m, u32 w, 102static inline void msg_set_bits(struct tipc_msg *m, u32 w,
70 u32 pos, u32 mask, u32 val) 103 u32 pos, u32 mask, u32 val)
71{ 104{
@@ -104,7 +137,7 @@ static inline u32 msg_user(struct tipc_msg *m)
104 137
105static inline u32 msg_isdata(struct tipc_msg *m) 138static inline u32 msg_isdata(struct tipc_msg *m)
106{ 139{
107 return (msg_user(m) <= TIPC_CRITICAL_IMPORTANCE); 140 return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE;
108} 141}
109 142
110static inline void msg_set_user(struct tipc_msg *m, u32 n) 143static inline void msg_set_user(struct tipc_msg *m, u32 n)
@@ -112,16 +145,36 @@ static inline void msg_set_user(struct tipc_msg *m, u32 n)
112 msg_set_bits(m, 0, 25, 0xf, n); 145 msg_set_bits(m, 0, 25, 0xf, n);
113} 146}
114 147
148static inline u32 msg_importance(struct tipc_msg *m)
149{
150 return msg_bits(m, 0, 25, 0xf);
151}
152
115static inline void msg_set_importance(struct tipc_msg *m, u32 i) 153static inline void msg_set_importance(struct tipc_msg *m, u32 i)
116{ 154{
117 msg_set_user(m, i); 155 msg_set_user(m, i);
118} 156}
119 157
120static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n) 158static inline u32 msg_hdr_sz(struct tipc_msg *m)
159{
160 return msg_bits(m, 0, 21, 0xf) << 2;
161}
162
163static inline void msg_set_hdr_sz(struct tipc_msg *m, u32 n)
121{ 164{
122 msg_set_bits(m, 0, 21, 0xf, n>>2); 165 msg_set_bits(m, 0, 21, 0xf, n>>2);
123} 166}
124 167
168static inline u32 msg_size(struct tipc_msg *m)
169{
170 return msg_bits(m, 0, 0, 0x1ffff);
171}
172
173static inline u32 msg_data_sz(struct tipc_msg *m)
174{
175 return msg_size(m) - msg_hdr_sz(m);
176}
177
125static inline int msg_non_seq(struct tipc_msg *m) 178static inline int msg_non_seq(struct tipc_msg *m)
126{ 179{
127 return msg_bits(m, 0, 20, 1); 180 return msg_bits(m, 0, 20, 1);
@@ -162,11 +215,36 @@ static inline void msg_set_size(struct tipc_msg *m, u32 sz)
162 * Word 1 215 * Word 1
163 */ 216 */
164 217
218static inline u32 msg_type(struct tipc_msg *m)
219{
220 return msg_bits(m, 1, 29, 0x7);
221}
222
165static inline void msg_set_type(struct tipc_msg *m, u32 n) 223static inline void msg_set_type(struct tipc_msg *m, u32 n)
166{ 224{
167 msg_set_bits(m, 1, 29, 0x7, n); 225 msg_set_bits(m, 1, 29, 0x7, n);
168} 226}
169 227
228static inline u32 msg_named(struct tipc_msg *m)
229{
230 return msg_type(m) == TIPC_NAMED_MSG;
231}
232
233static inline u32 msg_mcast(struct tipc_msg *m)
234{
235 return msg_type(m) == TIPC_MCAST_MSG;
236}
237
238static inline u32 msg_connected(struct tipc_msg *m)
239{
240 return msg_type(m) == TIPC_CONN_MSG;
241}
242
243static inline u32 msg_errcode(struct tipc_msg *m)
244{
245 return msg_bits(m, 1, 25, 0xf);
246}
247
170static inline void msg_set_errcode(struct tipc_msg *m, u32 err) 248static inline void msg_set_errcode(struct tipc_msg *m, u32 err)
171{ 249{
172 msg_set_bits(m, 1, 25, 0xf, err); 250 msg_set_bits(m, 1, 25, 0xf, err);
@@ -257,71 +335,96 @@ static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode)
257 */ 335 */
258 336
259 337
338static inline u32 msg_prevnode(struct tipc_msg *m)
339{
340 return msg_word(m, 3);
341}
342
260static inline void msg_set_prevnode(struct tipc_msg *m, u32 a) 343static inline void msg_set_prevnode(struct tipc_msg *m, u32 a)
261{ 344{
262 msg_set_word(m, 3, a); 345 msg_set_word(m, 3, a);
263} 346}
264 347
348static inline u32 msg_origport(struct tipc_msg *m)
349{
350 return msg_word(m, 4);
351}
352
265static inline void msg_set_origport(struct tipc_msg *m, u32 p) 353static inline void msg_set_origport(struct tipc_msg *m, u32 p)
266{ 354{
267 msg_set_word(m, 4, p); 355 msg_set_word(m, 4, p);
268} 356}
269 357
358static inline u32 msg_destport(struct tipc_msg *m)
359{
360 return msg_word(m, 5);
361}
362
270static inline void msg_set_destport(struct tipc_msg *m, u32 p) 363static inline void msg_set_destport(struct tipc_msg *m, u32 p)
271{ 364{
272 msg_set_word(m, 5, p); 365 msg_set_word(m, 5, p);
273} 366}
274 367
368static inline u32 msg_mc_netid(struct tipc_msg *m)
369{
370 return msg_word(m, 5);
371}
372
275static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p) 373static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p)
276{ 374{
277 msg_set_word(m, 5, p); 375 msg_set_word(m, 5, p);
278} 376}
279 377
280static inline void msg_set_orignode(struct tipc_msg *m, u32 a) 378static inline int msg_short(struct tipc_msg *m)
281{ 379{
282 msg_set_word(m, 6, a); 380 return msg_hdr_sz(m) == 24;
283} 381}
284 382
285static inline void msg_set_destnode(struct tipc_msg *m, u32 a) 383static inline u32 msg_orignode(struct tipc_msg *m)
286{ 384{
287 msg_set_word(m, 7, a); 385 if (likely(msg_short(m)))
386 return msg_prevnode(m);
387 return msg_word(m, 6);
288} 388}
289 389
290static inline int msg_is_dest(struct tipc_msg *m, u32 d) 390static inline void msg_set_orignode(struct tipc_msg *m, u32 a)
291{ 391{
292 return(msg_short(m) || (msg_destnode(m) == d)); 392 msg_set_word(m, 6, a);
293} 393}
294 394
295static inline u32 msg_routed(struct tipc_msg *m) 395static inline u32 msg_destnode(struct tipc_msg *m)
296{ 396{
297 if (likely(msg_short(m))) 397 return msg_word(m, 7);
298 return 0;
299 return(msg_destnode(m) ^ msg_orignode(m)) >> 11;
300} 398}
301 399
302static inline void msg_set_nametype(struct tipc_msg *m, u32 n) 400static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
303{ 401{
304 msg_set_word(m, 8, n); 402 msg_set_word(m, 7, a);
305} 403}
306 404
307static inline u32 msg_transp_seqno(struct tipc_msg *m) 405static inline int msg_is_dest(struct tipc_msg *m, u32 d)
406{
407 return msg_short(m) || (msg_destnode(m) == d);
408}
409
410static inline u32 msg_nametype(struct tipc_msg *m)
308{ 411{
309 return msg_word(m, 8); 412 return msg_word(m, 8);
310} 413}
311 414
312static inline void msg_set_timestamp(struct tipc_msg *m, u32 n) 415static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
313{ 416{
314 msg_set_word(m, 8, n); 417 msg_set_word(m, 8, n);
315} 418}
316 419
317static inline u32 msg_timestamp(struct tipc_msg *m) 420static inline u32 msg_nameinst(struct tipc_msg *m)
318{ 421{
319 return msg_word(m, 8); 422 return msg_word(m, 9);
320} 423}
321 424
322static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n) 425static inline u32 msg_namelower(struct tipc_msg *m)
323{ 426{
324 msg_set_word(m, 8, n); 427 return msg_nameinst(m);
325} 428}
326 429
327static inline void msg_set_namelower(struct tipc_msg *m, u32 n) 430static inline void msg_set_namelower(struct tipc_msg *m, u32 n)
@@ -334,11 +437,21 @@ static inline void msg_set_nameinst(struct tipc_msg *m, u32 n)
334 msg_set_namelower(m, n); 437 msg_set_namelower(m, n);
335} 438}
336 439
440static inline u32 msg_nameupper(struct tipc_msg *m)
441{
442 return msg_word(m, 10);
443}
444
337static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) 445static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
338{ 446{
339 msg_set_word(m, 10, n); 447 msg_set_word(m, 10, n);
340} 448}
341 449
450static inline unchar *msg_data(struct tipc_msg *m)
451{
452 return ((unchar *)m) + msg_hdr_sz(m);
453}
454
342static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) 455static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
343{ 456{
344 return (struct tipc_msg *)msg_data(m); 457 return (struct tipc_msg *)msg_data(m);
@@ -346,55 +459,25 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
346 459
347 460
348/* 461/*
349 TIPC internal message header format, version 2 462 * Constants and routines used to read and write TIPC internal message headers
350 463 */
351 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
352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
353 w0:|vers |msg usr|hdr sz |n|resrv| packet size |
354 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
355 w1:|m typ| sequence gap | broadcast ack no |
356 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
357 w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to |
358 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
359 w3:| previous node |
360 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
361 w4:| next sent broadcast/fragm no | next sent pkt/ fragm msg no |
362 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363 w5:| session no |rsv=0|r|berid|link prio|netpl|p|
364 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365 w6:| originating node |
366 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367 w7:| destination node |
368 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369 w8:| transport sequence number |
370 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
371 w9:| msg count / bcast tag | link tolerance |
372 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
373 \ \
374 / User Specific Data /
375 \ \
376 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
377
378 NB: CONN_MANAGER use data message format. LINK_CONFIG has own format.
379*/
380 464
381/* 465/*
382 * Internal users 466 * Internal message users
383 */ 467 */
384 468
385#define BCAST_PROTOCOL 5 469#define BCAST_PROTOCOL 5
386#define MSG_BUNDLER 6 470#define MSG_BUNDLER 6
387#define LINK_PROTOCOL 7 471#define LINK_PROTOCOL 7
388#define CONN_MANAGER 8 472#define CONN_MANAGER 8
389#define ROUTE_DISTRIBUTOR 9 473#define ROUTE_DISTRIBUTOR 9 /* obsoleted */
390#define CHANGEOVER_PROTOCOL 10 474#define CHANGEOVER_PROTOCOL 10
391#define NAME_DISTRIBUTOR 11 475#define NAME_DISTRIBUTOR 11
392#define MSG_FRAGMENTER 12 476#define MSG_FRAGMENTER 12
393#define LINK_CONFIG 13 477#define LINK_CONFIG 13
394#define DSC_H_SIZE 40
395 478
396/* 479/*
397 * Connection management protocol messages 480 * Connection management protocol message types
398 */ 481 */
399 482
400#define CONN_PROBE 0 483#define CONN_PROBE 0
@@ -402,12 +485,41 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
402#define CONN_ACK 2 485#define CONN_ACK 2
403 486
404/* 487/*
405 * Name distributor messages 488 * Name distributor message types
406 */ 489 */
407 490
408#define PUBLICATION 0 491#define PUBLICATION 0
409#define WITHDRAWAL 1 492#define WITHDRAWAL 1
410 493
494/*
495 * Segmentation message types
496 */
497
498#define FIRST_FRAGMENT 0
499#define FRAGMENT 1
500#define LAST_FRAGMENT 2
501
502/*
503 * Link management protocol message types
504 */
505
506#define STATE_MSG 0
507#define RESET_MSG 1
508#define ACTIVATE_MSG 2
509
510/*
511 * Changeover tunnel message types
512 */
513#define DUPLICATE_MSG 0
514#define ORIGINAL_MSG 1
515
516/*
517 * Config protocol message types
518 */
519
520#define DSC_REQ_MSG 0
521#define DSC_RESP_MSG 1
522
411 523
412/* 524/*
413 * Word 1 525 * Word 1
@@ -423,16 +535,6 @@ static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
423 msg_set_bits(m, 1, 16, 0x1fff, n); 535 msg_set_bits(m, 1, 16, 0x1fff, n);
424} 536}
425 537
426static inline u32 msg_req_links(struct tipc_msg *m)
427{
428 return msg_bits(m, 1, 16, 0xfff);
429}
430
431static inline void msg_set_req_links(struct tipc_msg *m, u32 n)
432{
433 msg_set_bits(m, 1, 16, 0xfff, n);
434}
435
436 538
437/* 539/*
438 * Word 2 540 * Word 2
@@ -595,14 +697,9 @@ static inline u32 msg_redundant_link(struct tipc_msg *m)
595 return msg_bits(m, 5, 12, 0x1); 697 return msg_bits(m, 5, 12, 0x1);
596} 698}
597 699
598static inline void msg_set_redundant_link(struct tipc_msg *m) 700static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r)
599{ 701{
600 msg_set_bits(m, 5, 12, 0x1, 1); 702 msg_set_bits(m, 5, 12, 0x1, r);
601}
602
603static inline void msg_clear_redundant_link(struct tipc_msg *m)
604{
605 msg_set_bits(m, 5, 12, 0x1, 0);
606} 703}
607 704
608 705
@@ -632,7 +729,7 @@ static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n)
632 729
633static inline u32 msg_max_pkt(struct tipc_msg *m) 730static inline u32 msg_max_pkt(struct tipc_msg *m)
634{ 731{
635 return (msg_bits(m, 9, 16, 0xffff) * 4); 732 return msg_bits(m, 9, 16, 0xffff) * 4;
636} 733}
637 734
638static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) 735static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n)
@@ -650,71 +747,12 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
650 msg_set_bits(m, 9, 0, 0xffff, n); 747 msg_set_bits(m, 9, 0, 0xffff, n);
651} 748}
652 749
653/*
654 * Routing table message data
655 */
656
657
658static inline u32 msg_remote_node(struct tipc_msg *m)
659{
660 return msg_word(m, msg_hdr_sz(m)/4);
661}
662
663static inline void msg_set_remote_node(struct tipc_msg *m, u32 a)
664{
665 msg_set_word(m, msg_hdr_sz(m)/4, a);
666}
667
668static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
669{
670 msg_data(m)[pos + 4] = 1;
671}
672
673/*
674 * Segmentation message types
675 */
676
677#define FIRST_FRAGMENT 0
678#define FRAGMENT 1
679#define LAST_FRAGMENT 2
680
681/*
682 * Link management protocol message types
683 */
684
685#define STATE_MSG 0
686#define RESET_MSG 1
687#define ACTIVATE_MSG 2
688
689/*
690 * Changeover tunnel message types
691 */
692#define DUPLICATE_MSG 0
693#define ORIGINAL_MSG 1
694
695/*
696 * Routing table message types
697 */
698#define EXT_ROUTING_TABLE 0
699#define LOCAL_ROUTING_TABLE 1
700#define SLAVE_ROUTING_TABLE 2
701#define ROUTE_ADDITION 3
702#define ROUTE_REMOVAL 4
703
704/*
705 * Config protocol message types
706 */
707
708#define DSC_REQ_MSG 0
709#define DSC_RESP_MSG 1
710
711u32 tipc_msg_tot_importance(struct tipc_msg *m); 750u32 tipc_msg_tot_importance(struct tipc_msg *m);
712void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, 751void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
713 u32 hsize, u32 destnode); 752 u32 hsize, u32 destnode);
714int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect); 753int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
715int tipc_msg_build(struct tipc_msg *hdr, 754 u32 num_sect, unsigned int total_len,
716 struct iovec const *msg_sect, u32 num_sect, 755 int max_size, int usrmem, struct sk_buff **buf);
717 int max_size, int usrmem, struct sk_buff** buf);
718 756
719static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 757static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
720{ 758{
@@ -723,7 +761,7 @@ static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr
723 761
724static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 762static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
725{ 763{
726 memcpy(a, &((int*)m)[5], sizeof(*a)); 764 memcpy(a, &((int *)m)[5], sizeof(*a));
727} 765}
728 766
729#endif 767#endif
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 6ac3c543250b..80025a1b3bfd 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -2,7 +2,7 @@
2 * net/tipc/name_distr.c: TIPC name distribution code 2 * net/tipc/name_distr.c: TIPC name distribution code
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,10 +35,7 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "cluster.h"
39#include "dbg.h"
40#include "link.h" 38#include "link.h"
41#include "msg.h"
42#include "name_distr.h" 39#include "name_distr.h"
43 40
44#define ITEM_SIZE sizeof(struct distr_item) 41#define ITEM_SIZE sizeof(struct distr_item)
@@ -76,7 +73,7 @@ struct distr_item {
76 */ 73 */
77 74
78static LIST_HEAD(publ_root); 75static LIST_HEAD(publ_root);
79static u32 publ_cnt = 0; 76static u32 publ_cnt;
80 77
81/** 78/**
82 * publ_to_item - add publication info to a publication message 79 * publ_to_item - add publication info to a publication message
@@ -89,7 +86,6 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
89 i->upper = htonl(p->upper); 86 i->upper = htonl(p->upper);
90 i->ref = htonl(p->ref); 87 i->ref = htonl(p->ref);
91 i->key = htonl(p->key); 88 i->key = htonl(p->key);
92 dbg("publ_to_item: %u, %u, %u\n", p->type, p->lower, p->upper);
93} 89}
94 90
95/** 91/**
@@ -98,7 +94,7 @@ 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) {
@@ -109,6 +105,24 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
109 return buf; 105 return buf;
110} 106}
111 107
108static void named_cluster_distribute(struct sk_buff *buf)
109{
110 struct sk_buff *buf_copy;
111 struct tipc_node *n_ptr;
112
113 list_for_each_entry(n_ptr, &tipc_node_list, list) {
114 if (tipc_node_active_links(n_ptr)) {
115 buf_copy = skb_copy(buf, GFP_ATOMIC);
116 if (!buf_copy)
117 break;
118 msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
119 tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
120 }
121 }
122
123 buf_discard(buf);
124}
125
112/** 126/**
113 * tipc_named_publish - tell other nodes about a new publication by this node 127 * tipc_named_publish - tell other nodes about a new publication by this node
114 */ 128 */
@@ -129,8 +143,7 @@ void tipc_named_publish(struct publication *publ)
129 143
130 item = (struct distr_item *)msg_data(buf_msg(buf)); 144 item = (struct distr_item *)msg_data(buf_msg(buf));
131 publ_to_item(item, publ); 145 publ_to_item(item, publ);
132 dbg("tipc_named_withdraw: broadcasting publish msg\n"); 146 named_cluster_distribute(buf);
133 tipc_cltr_broadcast(buf);
134} 147}
135 148
136/** 149/**
@@ -147,14 +160,13 @@ void tipc_named_withdraw(struct publication *publ)
147 160
148 buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0); 161 buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0);
149 if (!buf) { 162 if (!buf) {
150 warn("Withdrawl distribution failure\n"); 163 warn("Withdrawal distribution failure\n");
151 return; 164 return;
152 } 165 }
153 166
154 item = (struct distr_item *)msg_data(buf_msg(buf)); 167 item = (struct distr_item *)msg_data(buf_msg(buf));
155 publ_to_item(item, publ); 168 publ_to_item(item, publ);
156 dbg("tipc_named_withdraw: broadcasting withdraw msg\n"); 169 named_cluster_distribute(buf);
157 tipc_cltr_broadcast(buf);
158} 170}
159 171
160/** 172/**
@@ -191,9 +203,6 @@ void tipc_named_node_up(unsigned long node)
191 left -= ITEM_SIZE; 203 left -= ITEM_SIZE;
192 if (!left) { 204 if (!left) {
193 msg_set_link_selector(buf_msg(buf), node); 205 msg_set_link_selector(buf_msg(buf), node);
194 dbg("tipc_named_node_up: sending publish msg to "
195 "<%u.%u.%u>\n", tipc_zone(node),
196 tipc_cluster(node), tipc_node(node));
197 tipc_link_send(buf, node, node); 206 tipc_link_send(buf, node, node);
198 buf = NULL; 207 buf = NULL;
199 } 208 }
@@ -203,26 +212,25 @@ exit:
203} 212}
204 213
205/** 214/**
206 * node_is_down - remove publication associated with a failed node 215 * named_purge_publ - remove publication associated with a failed node
207 * 216 *
208 * Invoked for each publication issued by a newly failed node. 217 * Invoked for each publication issued by a newly failed node.
209 * Removes publication structure from name table & deletes it. 218 * Removes publication structure from name table & deletes it.
210 * In rare cases the link may have come back up again when this 219 * In rare cases the link may have come back up again when this
211 * function is called, and we have two items representing the same 220 * function is called, and we have two items representing the same
212 * publication. Nudge this item's key to distinguish it from the other. 221 * publication. Nudge this item's key to distinguish it from the other.
213 * (Note: Publication's node subscription is already unsubscribed.)
214 */ 222 */
215 223
216static void node_is_down(struct publication *publ) 224static void named_purge_publ(struct publication *publ)
217{ 225{
218 struct publication *p; 226 struct publication *p;
219 227
220 write_lock_bh(&tipc_nametbl_lock); 228 write_lock_bh(&tipc_nametbl_lock);
221 dbg("node_is_down: withdrawing %u, %u, %u\n",
222 publ->type, publ->lower, publ->upper);
223 publ->key += 1222345; 229 publ->key += 1222345;
224 p = tipc_nametbl_remove_publ(publ->type, publ->lower, 230 p = tipc_nametbl_remove_publ(publ->type, publ->lower,
225 publ->node, publ->ref, publ->key); 231 publ->node, publ->ref, publ->key);
232 if (p)
233 tipc_nodesub_unsubscribe(&p->subscr);
226 write_unlock_bh(&tipc_nametbl_lock); 234 write_unlock_bh(&tipc_nametbl_lock);
227 235
228 if (p != publ) { 236 if (p != publ) {
@@ -231,9 +239,7 @@ static void node_is_down(struct publication *publ)
231 publ->type, publ->lower, publ->node, publ->ref, publ->key); 239 publ->type, publ->lower, publ->node, publ->ref, publ->key);
232 } 240 }
233 241
234 if (p) { 242 kfree(p);
235 kfree(p);
236 }
237} 243}
238 244
239/** 245/**
@@ -250,9 +256,6 @@ void tipc_named_recv(struct sk_buff *buf)
250 write_lock_bh(&tipc_nametbl_lock); 256 write_lock_bh(&tipc_nametbl_lock);
251 while (count--) { 257 while (count--) {
252 if (msg_type(msg) == PUBLICATION) { 258 if (msg_type(msg) == PUBLICATION) {
253 dbg("tipc_named_recv: got publication for %u, %u, %u\n",
254 ntohl(item->type), ntohl(item->lower),
255 ntohl(item->upper));
256 publ = tipc_nametbl_insert_publ(ntohl(item->type), 259 publ = tipc_nametbl_insert_publ(ntohl(item->type),
257 ntohl(item->lower), 260 ntohl(item->lower),
258 ntohl(item->upper), 261 ntohl(item->upper),
@@ -264,12 +267,10 @@ void tipc_named_recv(struct sk_buff *buf)
264 tipc_nodesub_subscribe(&publ->subscr, 267 tipc_nodesub_subscribe(&publ->subscr,
265 msg_orignode(msg), 268 msg_orignode(msg),
266 publ, 269 publ,
267 (net_ev_handler)node_is_down); 270 (net_ev_handler)
271 named_purge_publ);
268 } 272 }
269 } else if (msg_type(msg) == WITHDRAWAL) { 273 } else if (msg_type(msg) == WITHDRAWAL) {
270 dbg("tipc_named_recv: got withdrawl for %u, %u, %u\n",
271 ntohl(item->type), ntohl(item->lower),
272 ntohl(item->upper));
273 publ = tipc_nametbl_remove_publ(ntohl(item->type), 274 publ = tipc_nametbl_remove_publ(ntohl(item->type),
274 ntohl(item->lower), 275 ntohl(item->lower),
275 msg_orignode(msg), 276 msg_orignode(msg),
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 8ba79620db3f..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)
@@ -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 f61b7694138b..68b3dd637291 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -2,7 +2,7 @@
2 * net/tipc/net.c: TIPC network routing code 2 * net/tipc/net.c: TIPC network routing code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,18 +35,11 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "bearer.h"
39#include "net.h" 38#include "net.h"
40#include "zone.h"
41#include "addr.h"
42#include "name_table.h"
43#include "name_distr.h" 39#include "name_distr.h"
44#include "subscr.h" 40#include "subscr.h"
45#include "link.h"
46#include "msg.h"
47#include "port.h" 41#include "port.h"
48#include "bcast.h" 42#include "node.h"
49#include "discover.h"
50#include "config.h" 43#include "config.h"
51 44
52/* 45/*
@@ -116,56 +109,6 @@
116*/ 109*/
117 110
118DEFINE_RWLOCK(tipc_net_lock); 111DEFINE_RWLOCK(tipc_net_lock);
119static struct _zone *tipc_zones[256] = { NULL, };
120struct network tipc_net = { tipc_zones };
121
122struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref)
123{
124 return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref);
125}
126
127u32 tipc_net_select_router(u32 addr, u32 ref)
128{
129 return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref);
130}
131
132#if 0
133u32 tipc_net_next_node(u32 a)
134{
135 if (tipc_net.zones[tipc_zone(a)])
136 return tipc_zone_next_node(a);
137 return 0;
138}
139#endif
140
141void tipc_net_remove_as_router(u32 router)
142{
143 u32 z_num;
144
145 for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
146 if (!tipc_net.zones[z_num])
147 continue;
148 tipc_zone_remove_as_router(tipc_net.zones[z_num], router);
149 }
150}
151
152void tipc_net_send_external_routes(u32 dest)
153{
154 u32 z_num;
155
156 for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
157 if (tipc_net.zones[z_num])
158 tipc_zone_send_external_routes(tipc_net.zones[z_num], dest);
159 }
160}
161
162static void net_stop(void)
163{
164 u32 z_num;
165
166 for (z_num = 1; z_num <= tipc_max_zones; z_num++)
167 tipc_zone_delete(tipc_net.zones[z_num]);
168}
169 112
170static void net_route_named_msg(struct sk_buff *buf) 113static void net_route_named_msg(struct sk_buff *buf)
171{ 114{
@@ -174,22 +117,18 @@ static void net_route_named_msg(struct sk_buff *buf)
174 u32 dport; 117 u32 dport;
175 118
176 if (!msg_named(msg)) { 119 if (!msg_named(msg)) {
177 msg_dbg(msg, "tipc_net->drop_nam:");
178 buf_discard(buf); 120 buf_discard(buf);
179 return; 121 return;
180 } 122 }
181 123
182 dnode = addr_domain(msg_lookup_scope(msg)); 124 dnode = addr_domain(msg_lookup_scope(msg));
183 dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode); 125 dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode);
184 dbg("tipc_net->lookup<%u,%u>-><%u,%x>\n",
185 msg_nametype(msg), msg_nameinst(msg), dport, dnode);
186 if (dport) { 126 if (dport) {
187 msg_set_destnode(msg, dnode); 127 msg_set_destnode(msg, dnode);
188 msg_set_destport(msg, dport); 128 msg_set_destport(msg, dport);
189 tipc_net_route_msg(buf); 129 tipc_net_route_msg(buf);
190 return; 130 return;
191 } 131 }
192 msg_dbg(msg, "tipc_net->rej:NO NAME: ");
193 tipc_reject_msg(buf, TIPC_ERR_NO_NAME); 132 tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
194} 133}
195 134
@@ -205,18 +144,14 @@ void tipc_net_route_msg(struct sk_buff *buf)
205 msg_incr_reroute_cnt(msg); 144 msg_incr_reroute_cnt(msg);
206 if (msg_reroute_cnt(msg) > 6) { 145 if (msg_reroute_cnt(msg) > 6) {
207 if (msg_errcode(msg)) { 146 if (msg_errcode(msg)) {
208 msg_dbg(msg, "NET>DISC>:");
209 buf_discard(buf); 147 buf_discard(buf);
210 } else { 148 } else {
211 msg_dbg(msg, "NET>REJ>:");
212 tipc_reject_msg(buf, msg_destport(msg) ? 149 tipc_reject_msg(buf, msg_destport(msg) ?
213 TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME); 150 TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME);
214 } 151 }
215 return; 152 return;
216 } 153 }
217 154
218 msg_dbg(msg, "tipc_net->rout: ");
219
220 /* Handle message for this node */ 155 /* Handle message for this node */
221 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); 156 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg);
222 if (tipc_in_scope(dnode, tipc_own_addr)) { 157 if (tipc_in_scope(dnode, tipc_own_addr)) {
@@ -230,9 +165,6 @@ void tipc_net_route_msg(struct sk_buff *buf)
230 return; 165 return;
231 } 166 }
232 switch (msg_user(msg)) { 167 switch (msg_user(msg)) {
233 case ROUTE_DISTRIBUTOR:
234 tipc_cltr_recv_routing_table(buf);
235 break;
236 case NAME_DISTRIBUTOR: 168 case NAME_DISTRIBUTOR:
237 tipc_named_recv(buf); 169 tipc_named_recv(buf);
238 break; 170 break;
@@ -240,14 +172,13 @@ void tipc_net_route_msg(struct sk_buff *buf)
240 tipc_port_recv_proto_msg(buf); 172 tipc_port_recv_proto_msg(buf);
241 break; 173 break;
242 default: 174 default:
243 msg_dbg(msg,"DROP/NET/<REC<");
244 buf_discard(buf); 175 buf_discard(buf);
245 } 176 }
246 return; 177 return;
247 } 178 }
248 179
249 /* Handle message for another node */ 180 /* Handle message for another node */
250 msg_dbg(msg, "NET>SEND>: "); 181 skb_trim(buf, msg_size(msg));
251 tipc_link_send(buf, dnode, msg_link_selector(msg)); 182 tipc_link_send(buf, dnode, msg_link_selector(msg));
252} 183}
253 184
@@ -267,10 +198,9 @@ int tipc_net_start(u32 addr)
267 tipc_named_reinit(); 198 tipc_named_reinit();
268 tipc_port_reinit(); 199 tipc_port_reinit();
269 200
270 if ((res = tipc_cltr_init()) || 201 res = tipc_bclink_init();
271 (res = tipc_bclink_init())) { 202 if (res)
272 return res; 203 return res;
273 }
274 204
275 tipc_k_signal((Handler)tipc_subscr_start, 0); 205 tipc_k_signal((Handler)tipc_subscr_start, 0);
276 tipc_k_signal((Handler)tipc_cfg_init, 0); 206 tipc_k_signal((Handler)tipc_cfg_init, 0);
@@ -283,14 +213,16 @@ int tipc_net_start(u32 addr)
283 213
284void tipc_net_stop(void) 214void tipc_net_stop(void)
285{ 215{
216 struct tipc_node *node, *t_node;
217
286 if (tipc_mode != TIPC_NET_MODE) 218 if (tipc_mode != TIPC_NET_MODE)
287 return; 219 return;
288 write_lock_bh(&tipc_net_lock); 220 write_lock_bh(&tipc_net_lock);
289 tipc_bearer_stop(); 221 tipc_bearer_stop();
290 tipc_mode = TIPC_NODE_MODE; 222 tipc_mode = TIPC_NODE_MODE;
291 tipc_bclink_stop(); 223 tipc_bclink_stop();
292 net_stop(); 224 list_for_each_entry_safe(node, t_node, &tipc_node_list, list)
225 tipc_node_delete(node);
293 write_unlock_bh(&tipc_net_lock); 226 write_unlock_bh(&tipc_net_lock);
294 info("Left network mode\n"); 227 info("Left network mode\n");
295} 228}
296
diff --git a/net/tipc/net.h b/net/tipc/net.h
index de2b9ad8f646..9eb4b9e220eb 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -2,7 +2,7 @@
2 * net/tipc/net.h: Include file for TIPC network routing code 2 * net/tipc/net.h: Include file for TIPC network routing code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,26 +37,9 @@
37#ifndef _TIPC_NET_H 37#ifndef _TIPC_NET_H
38#define _TIPC_NET_H 38#define _TIPC_NET_H
39 39
40struct _zone;
41
42/**
43 * struct network - TIPC network structure
44 * @zones: array of pointers to all zones within network
45 */
46
47struct network {
48 struct _zone **zones;
49};
50
51
52extern struct network tipc_net;
53extern rwlock_t tipc_net_lock; 40extern rwlock_t tipc_net_lock;
54 41
55void tipc_net_remove_as_router(u32 router);
56void tipc_net_send_external_routes(u32 dest);
57void tipc_net_route_msg(struct sk_buff *buf); 42void tipc_net_route_msg(struct sk_buff *buf);
58struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref);
59u32 tipc_net_select_router(u32 addr, u32 ref);
60 43
61int tipc_net_start(u32 addr); 44int tipc_net_start(u32 addr);
62void tipc_net_stop(void); 45void tipc_net_stop(void);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b634942caba5..2d106ef4fa4c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -2,7 +2,7 @@
2 * net/tipc/node.c: TIPC node management routines 2 * net/tipc/node.c: TIPC node management routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,24 +37,38 @@
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "config.h"
39#include "node.h" 39#include "node.h"
40#include "cluster.h"
41#include "net.h"
42#include "addr.h"
43#include "node_subscr.h"
44#include "link.h"
45#include "port.h"
46#include "bearer.h"
47#include "name_distr.h" 40#include "name_distr.h"
48 41
49void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str);
50static void node_lost_contact(struct tipc_node *n_ptr); 42static void node_lost_contact(struct tipc_node *n_ptr);
51static void node_established_contact(struct tipc_node *n_ptr); 43static void node_established_contact(struct tipc_node *n_ptr);
52 44
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; 47static struct hlist_head node_htable[NODE_HTABLE_SIZE];
48LIST_HEAD(tipc_node_list);
49static u32 tipc_num_nodes;
50
51static atomic_t tipc_num_links = ATOMIC_INIT(0);
52u32 tipc_own_tag;
53
54/**
55 * tipc_node_find - locate specified node object, if it exists
56 */
57
58struct tipc_node *tipc_node_find(u32 addr)
59{
60 struct tipc_node *node;
61 struct hlist_node *pos;
62
63 if (unlikely(!in_own_cluster(addr)))
64 return NULL;
65
66 hlist_for_each_entry(node, pos, &node_htable[tipc_hashfn(addr)], hash) {
67 if (node->addr == addr)
68 return node;
69 }
70 return NULL;
71}
58 72
59/** 73/**
60 * tipc_node_create - create neighboring node 74 * tipc_node_create - create neighboring node
@@ -68,75 +82,50 @@ u32 tipc_own_tag = 0;
68 82
69struct tipc_node *tipc_node_create(u32 addr) 83struct tipc_node *tipc_node_create(u32 addr)
70{ 84{
71 struct cluster *c_ptr; 85 struct tipc_node *n_ptr, *temp_node;
72 struct tipc_node *n_ptr;
73 struct tipc_node **curr_node;
74 86
75 spin_lock_bh(&node_create_lock); 87 spin_lock_bh(&node_create_lock);
76 88
77 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 89 n_ptr = tipc_node_find(addr);
78 if (addr < n_ptr->addr) 90 if (n_ptr) {
79 break; 91 spin_unlock_bh(&node_create_lock);
80 if (addr == n_ptr->addr) { 92 return n_ptr;
81 spin_unlock_bh(&node_create_lock);
82 return n_ptr;
83 }
84 } 93 }
85 94
86 n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); 95 n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC);
87 if (!n_ptr) { 96 if (!n_ptr) {
88 spin_unlock_bh(&node_create_lock); 97 spin_unlock_bh(&node_create_lock);
89 warn("Node creation failed, no memory\n"); 98 warn("Node creation failed, no memory\n");
90 return NULL; 99 return NULL;
91 } 100 }
92 101
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; 102 n_ptr->addr = addr;
104 spin_lock_init(&n_ptr->lock); 103 spin_lock_init(&n_ptr->lock);
104 INIT_HLIST_NODE(&n_ptr->hash);
105 INIT_LIST_HEAD(&n_ptr->list);
105 INIT_LIST_HEAD(&n_ptr->nsub); 106 INIT_LIST_HEAD(&n_ptr->nsub);
106 n_ptr->owner = c_ptr; 107
107 tipc_cltr_attach_node(c_ptr, n_ptr); 108 hlist_add_head(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
108 n_ptr->last_router = -1; 109
109 110 list_for_each_entry(temp_node, &tipc_node_list, list) {
110 /* Insert node into ordered list */ 111 if (n_ptr->addr < temp_node->addr)
111 for (curr_node = &tipc_nodes; *curr_node;
112 curr_node = &(*curr_node)->next) {
113 if (addr < (*curr_node)->addr) {
114 n_ptr->next = *curr_node;
115 break; 112 break;
116 }
117 } 113 }
118 (*curr_node) = n_ptr; 114 list_add_tail(&n_ptr->list, &temp_node->list);
115
116 tipc_num_nodes++;
117
119 spin_unlock_bh(&node_create_lock); 118 spin_unlock_bh(&node_create_lock);
120 return n_ptr; 119 return n_ptr;
121} 120}
122 121
123void tipc_node_delete(struct tipc_node *n_ptr) 122void tipc_node_delete(struct tipc_node *n_ptr)
124{ 123{
125 if (!n_ptr) 124 list_del(&n_ptr->list);
126 return; 125 hlist_del(&n_ptr->hash);
127
128#if 0
129 /* Not needed because links are already deleted via tipc_bearer_stop() */
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); 126 kfree(n_ptr);
127
128 tipc_num_nodes--;
140} 129}
141 130
142 131
@@ -156,7 +145,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); 145 l_ptr->name, l_ptr->b_ptr->net_plane);
157 146
158 if (!active[0]) { 147 if (!active[0]) {
159 dbg(" link %x into %x/%x\n", l_ptr, &active[0], &active[1]);
160 active[0] = active[1] = l_ptr; 148 active[0] = active[1] = l_ptr;
161 node_established_contact(n_ptr); 149 node_established_contact(n_ptr);
162 return; 150 return;
@@ -235,60 +223,32 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr)
235 node_lost_contact(n_ptr); 223 node_lost_contact(n_ptr);
236} 224}
237 225
238int tipc_node_has_active_links(struct tipc_node *n_ptr) 226int tipc_node_active_links(struct tipc_node *n_ptr)
239{ 227{
240 return (n_ptr && 228 return n_ptr->active_links[0] != NULL;
241 ((n_ptr->active_links[0]) || (n_ptr->active_links[1])));
242} 229}
243 230
244int tipc_node_has_redundant_links(struct tipc_node *n_ptr) 231int tipc_node_redundant_links(struct tipc_node *n_ptr)
245{ 232{
246 return (n_ptr->working_links > 1); 233 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} 234}
253 235
254int tipc_node_is_up(struct tipc_node *n_ptr) 236int tipc_node_is_up(struct tipc_node *n_ptr)
255{ 237{
256 return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr)); 238 return tipc_node_active_links(n_ptr);
257} 239}
258 240
259struct tipc_node *tipc_node_attach_link(struct link *l_ptr) 241void tipc_node_attach_link(struct tipc_node *n_ptr, struct link *l_ptr)
260{ 242{
261 struct tipc_node *n_ptr = tipc_node_find(l_ptr->addr); 243 n_ptr->links[l_ptr->b_ptr->identity] = l_ptr;
262 244 atomic_inc(&tipc_num_links);
263 if (!n_ptr) 245 n_ptr->link_cnt++;
264 n_ptr = tipc_node_create(l_ptr->addr);
265 if (n_ptr) {
266 u32 bearer_id = l_ptr->b_ptr->identity;
267 char addr_string[16];
268
269 if (n_ptr->link_cnt >= 2) {
270 err("Attempt to create third link to %s\n",
271 tipc_addr_string_fill(addr_string, n_ptr->addr));
272 return NULL;
273 }
274
275 if (!n_ptr->links[bearer_id]) {
276 n_ptr->links[bearer_id] = l_ptr;
277 tipc_net.zones[tipc_zone(l_ptr->addr)]->links++;
278 n_ptr->link_cnt++;
279 return n_ptr;
280 }
281 err("Attempt to establish second link on <%s> to %s\n",
282 l_ptr->b_ptr->publ.name,
283 tipc_addr_string_fill(addr_string, l_ptr->addr));
284 }
285 return NULL;
286} 246}
287 247
288void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr) 248void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
289{ 249{
290 n_ptr->links[l_ptr->b_ptr->identity] = NULL; 250 n_ptr->links[l_ptr->b_ptr->identity] = NULL;
291 tipc_net.zones[tipc_zone(l_ptr->addr)]->links--; 251 atomic_dec(&tipc_num_links);
292 n_ptr->link_cnt--; 252 n_ptr->link_cnt--;
293} 253}
294 254
@@ -340,61 +300,41 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
340 300
341static void node_established_contact(struct tipc_node *n_ptr) 301static void node_established_contact(struct tipc_node *n_ptr)
342{ 302{
343 struct cluster *c_ptr; 303 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 304
350 /* Syncronize broadcast acks */ 305 /* Syncronize broadcast acks */
351 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 306 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
352 307
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) { 308 if (n_ptr->bclink.supported) {
375 tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr); 309 tipc_nmap_add(&tipc_bcast_nmap, n_ptr->addr);
376 if (n_ptr->addr < tipc_own_addr) 310 if (n_ptr->addr < tipc_own_addr)
377 tipc_own_tag++; 311 tipc_own_tag++;
378 } 312 }
313}
314
315static void node_cleanup_finished(unsigned long node_addr)
316{
317 struct tipc_node *n_ptr;
379 318
380 /* Case 3 (see above) */ 319 read_lock_bh(&tipc_net_lock);
381 tipc_net_send_external_routes(n_ptr->addr); 320 n_ptr = tipc_node_find(node_addr);
382 tipc_cltr_send_slave_routes(c_ptr, n_ptr->addr); 321 if (n_ptr) {
383 tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, LOWEST_SLAVE, 322 tipc_node_lock(n_ptr);
384 tipc_highest_allowed_slave); 323 n_ptr->cleanup_required = 0;
324 tipc_node_unlock(n_ptr);
325 }
326 read_unlock_bh(&tipc_net_lock);
385} 327}
386 328
387static void node_lost_contact(struct tipc_node *n_ptr) 329static void node_lost_contact(struct tipc_node *n_ptr)
388{ 330{
389 struct cluster *c_ptr;
390 struct tipc_node_subscr *ns, *tns;
391 char addr_string[16]; 331 char addr_string[16];
392 u32 i; 332 u32 i;
393 333
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,41 +342,14 @@ 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 tipc_addr_string_fill(addr_string, n_ptr->addr)); 355 tipc_addr_string_fill(addr_string, n_ptr->addr));
@@ -452,163 +365,12 @@ static void node_lost_contact(struct tipc_node *n_ptr)
452 } 365 }
453 366
454 /* Notify subscribers */ 367 /* Notify subscribers */
455 list_for_each_entry_safe(ns, tns, &n_ptr->nsub, nodesub_list) { 368 tipc_nodesub_notify(n_ptr);
456 ns->node = NULL;
457 list_del_init(&ns->nodesub_list);
458 tipc_k_signal((Handler)ns->handle_node_down,
459 (unsigned long)ns->usr_handle);
460 }
461}
462
463/**
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
469struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector)
470{
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 369
558 n_ptr->routers[r_num / 32] = 370 /* Prevent re-contact with node until all cleanup is done */
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 371
582#if 0 372 n_ptr->cleanup_required = 1;
583void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str) 373 tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);
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 (!tipc_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} 374}
613 375
614struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) 376struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
@@ -628,15 +390,14 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
628 " (network address)"); 390 " (network address)");
629 391
630 read_lock_bh(&tipc_net_lock); 392 read_lock_bh(&tipc_net_lock);
631 if (!tipc_nodes) { 393 if (!tipc_num_nodes) {
632 read_unlock_bh(&tipc_net_lock); 394 read_unlock_bh(&tipc_net_lock);
633 return tipc_cfg_reply_none(); 395 return tipc_cfg_reply_none();
634 } 396 }
635 397
636 /* For now, get space for all other nodes 398 /* For now, get space for all other nodes */
637 (will need to modify this when slave nodes are supported */
638 399
639 payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); 400 payload_size = TLV_SPACE(sizeof(node_info)) * tipc_num_nodes;
640 if (payload_size > 32768u) { 401 if (payload_size > 32768u) {
641 read_unlock_bh(&tipc_net_lock); 402 read_unlock_bh(&tipc_net_lock);
642 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 403 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -650,7 +411,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
650 411
651 /* Add TLVs for all nodes in scope */ 412 /* Add TLVs for all nodes in scope */
652 413
653 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 414 list_for_each_entry(n_ptr, &tipc_node_list, list) {
654 if (!tipc_in_scope(domain, n_ptr->addr)) 415 if (!tipc_in_scope(domain, n_ptr->addr))
655 continue; 416 continue;
656 node_info.addr = htonl(n_ptr->addr); 417 node_info.addr = htonl(n_ptr->addr);
@@ -687,7 +448,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
687 /* Get space for all unicast links + multicast link */ 448 /* Get space for all unicast links + multicast link */
688 449
689 payload_size = TLV_SPACE(sizeof(link_info)) * 450 payload_size = TLV_SPACE(sizeof(link_info)) *
690 (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); 451 (atomic_read(&tipc_num_links) + 1);
691 if (payload_size > 32768u) { 452 if (payload_size > 32768u) {
692 read_unlock_bh(&tipc_net_lock); 453 read_unlock_bh(&tipc_net_lock);
693 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 454 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -701,14 +462,14 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
701 462
702 /* Add TLV for broadcast link */ 463 /* Add TLV for broadcast link */
703 464
704 link_info.dest = htonl(tipc_own_addr & 0xfffff00); 465 link_info.dest = htonl(tipc_cluster_mask(tipc_own_addr));
705 link_info.up = htonl(1); 466 link_info.up = htonl(1);
706 strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME); 467 strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME);
707 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info)); 468 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info));
708 469
709 /* Add TLVs for any other links in scope */ 470 /* Add TLVs for any other links in scope */
710 471
711 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 472 list_for_each_entry(n_ptr, &tipc_node_list, list) {
712 u32 i; 473 u32 i;
713 474
714 if (!tipc_in_scope(domain, n_ptr->addr)) 475 if (!tipc_in_scope(domain, n_ptr->addr))
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 6f990da5d143..5c61afc7a0b9 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -2,7 +2,7 @@
2 * net/tipc/node.h: Include file for TIPC node management routines 2 * net/tipc/node.h: Include file for TIPC node management routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -39,23 +39,22 @@
39 39
40#include "node_subscr.h" 40#include "node_subscr.h"
41#include "addr.h" 41#include "addr.h"
42#include "cluster.h" 42#include "net.h"
43#include "bearer.h" 43#include "bearer.h"
44 44
45/** 45/**
46 * struct tipc_node - TIPC node structure 46 * struct tipc_node - TIPC node structure
47 * @addr: network address of node 47 * @addr: network address of node
48 * @lock: spinlock governing access to structure 48 * @lock: spinlock governing access to structure
49 * @owner: pointer to cluster that node belongs to 49 * @hash: links to adjacent nodes in unsorted hash chain
50 * @next: pointer to next node in sorted list of cluster's nodes 50 * @list: links to adjacent nodes in sorted list of cluster's nodes
51 * @nsub: list of "node down" subscriptions monitoring node 51 * @nsub: list of "node down" subscriptions monitoring node
52 * @active_links: pointers to active links to node 52 * @active_links: pointers to active links to node
53 * @links: pointers to all links to node 53 * @links: pointers to all links to node
54 * @working_links: number of working links to node (both active and standby) 54 * @working_links: number of working links to node (both active and standby)
55 * @cleanup_required: non-zero if cleaning up after a prior loss of contact
55 * @link_cnt: number of links to node 56 * @link_cnt: number of links to node
56 * @permit_changeover: non-zero if node has redundant links to this system 57 * @permit_changeover: non-zero if node has redundant links to this system
57 * @routers: bitmap (used for multicluster communication)
58 * @last_router: (used for multicluster communication)
59 * @bclink: broadcast-related info 58 * @bclink: broadcast-related info
60 * @supported: non-zero if node supports TIPC b'cast capability 59 * @supported: non-zero if node supports TIPC b'cast capability
61 * @acked: sequence # of last outbound b'cast message acknowledged by node 60 * @acked: sequence # of last outbound b'cast message acknowledged by node
@@ -71,16 +70,15 @@
71struct tipc_node { 70struct tipc_node {
72 u32 addr; 71 u32 addr;
73 spinlock_t lock; 72 spinlock_t lock;
74 struct cluster *owner; 73 struct hlist_node hash;
75 struct tipc_node *next; 74 struct list_head list;
76 struct list_head nsub; 75 struct list_head nsub;
77 struct link *active_links[2]; 76 struct link *active_links[2];
78 struct link *links[MAX_BEARERS]; 77 struct link *links[MAX_BEARERS];
79 int link_cnt; 78 int link_cnt;
80 int working_links; 79 int working_links;
80 int cleanup_required;
81 int permit_changeover; 81 int permit_changeover;
82 u32 routers[512/32];
83 int last_router;
84 struct { 82 struct {
85 int supported; 83 int supported;
86 u32 acked; 84 u32 acked;
@@ -94,45 +92,35 @@ struct tipc_node {
94 } bclink; 92 } bclink;
95}; 93};
96 94
97extern struct tipc_node *tipc_nodes; 95#define NODE_HTABLE_SIZE 512
96extern struct list_head tipc_node_list;
97
98/*
99 * A trivial power-of-two bitmask technique is used for speed, since this
100 * operation is done for every incoming TIPC packet. The number of hash table
101 * entries has been chosen so that no hash chain exceeds 8 nodes and will
102 * usually be much smaller (typically only a single node).
103 */
104static inline unsigned int tipc_hashfn(u32 addr)
105{
106 return addr & (NODE_HTABLE_SIZE - 1);
107}
108
98extern u32 tipc_own_tag; 109extern u32 tipc_own_tag;
99 110
111struct tipc_node *tipc_node_find(u32 addr);
100struct tipc_node *tipc_node_create(u32 addr); 112struct tipc_node *tipc_node_create(u32 addr);
101void tipc_node_delete(struct tipc_node *n_ptr); 113void tipc_node_delete(struct tipc_node *n_ptr);
102struct tipc_node *tipc_node_attach_link(struct link *l_ptr); 114void tipc_node_attach_link(struct tipc_node *n_ptr, struct link *l_ptr);
103void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr); 115void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr);
104void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr); 116void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr);
105void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr); 117void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr);
106int tipc_node_has_active_links(struct tipc_node *n_ptr); 118int tipc_node_active_links(struct tipc_node *n_ptr);
107int tipc_node_has_redundant_links(struct tipc_node *n_ptr); 119int tipc_node_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); 120int 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); 121struct 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); 122struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
115 123
116static inline struct tipc_node *tipc_node_find(u32 addr)
117{
118 if (likely(in_own_cluster(addr)))
119 return tipc_local_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;
127}
128
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) 124static inline void tipc_node_lock(struct tipc_node *n_ptr)
137{ 125{
138 spin_lock_bh(&n_ptr->lock); 126 spin_lock_bh(&n_ptr->lock);
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 19194d476a9e..c3c2815ae630 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -2,7 +2,7 @@
2 * net/tipc/node_subscr.c: TIPC "node down" subscription handling 2 * net/tipc/node_subscr.c: TIPC "node down" subscription handling
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,10 +35,8 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "node_subscr.h" 38#include "node_subscr.h"
40#include "node.h" 39#include "node.h"
41#include "addr.h"
42 40
43/** 41/**
44 * tipc_nodesub_subscribe - create "node down" subscription for specified node 42 * tipc_nodesub_subscribe - create "node down" subscription for specified node
@@ -78,3 +76,22 @@ void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub)
78 list_del_init(&node_sub->nodesub_list); 76 list_del_init(&node_sub->nodesub_list);
79 tipc_node_unlock(node_sub->node); 77 tipc_node_unlock(node_sub->node);
80} 78}
79
80/**
81 * tipc_nodesub_notify - notify subscribers that a node is unreachable
82 *
83 * Note: node is locked by caller
84 */
85
86void tipc_nodesub_notify(struct tipc_node *node)
87{
88 struct tipc_node_subscr *ns;
89
90 list_for_each_entry(ns, &node->nsub, nodesub_list) {
91 if (ns->handle_node_down) {
92 tipc_k_signal((Handler)ns->handle_node_down,
93 (unsigned long)ns->usr_handle);
94 ns->handle_node_down = NULL;
95 }
96 }
97}
diff --git a/net/tipc/node_subscr.h b/net/tipc/node_subscr.h
index 006ed739f515..4bc2ca0867a1 100644
--- a/net/tipc/node_subscr.h
+++ b/net/tipc/node_subscr.h
@@ -2,7 +2,7 @@
2 * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling 2 * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -59,5 +59,6 @@ struct tipc_node_subscr {
59void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr, 59void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
60 void *usr_handle, net_ev_handler handle_down); 60 void *usr_handle, net_ev_handler handle_down);
61void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub); 61void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub);
62void tipc_nodesub_notify(struct tipc_node *node);
62 63
63#endif 64#endif
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 0737680e9266..c68dc956a423 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -2,7 +2,7 @@
2 * net/tipc/port.c: TIPC port code 2 * net/tipc/port.c: TIPC port code
3 * 3 *
4 * Copyright (c) 1992-2007, Ericsson AB 4 * Copyright (c) 1992-2007, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -36,15 +36,8 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "config.h"
39#include "dbg.h"
40#include "port.h" 39#include "port.h"
41#include "addr.h"
42#include "link.h"
43#include "node.h"
44#include "name_table.h" 40#include "name_table.h"
45#include "user_reg.h"
46#include "msg.h"
47#include "bcast.h"
48 41
49/* Connection management: */ 42/* Connection management: */
50#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ 43#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */
@@ -53,55 +46,42 @@
53 46
54#define MAX_REJECT_SIZE 1024 47#define MAX_REJECT_SIZE 1024
55 48
56static struct sk_buff *msg_queue_head = NULL; 49static struct sk_buff *msg_queue_head;
57static struct sk_buff *msg_queue_tail = NULL; 50static struct sk_buff *msg_queue_tail;
58 51
59DEFINE_SPINLOCK(tipc_port_list_lock); 52DEFINE_SPINLOCK(tipc_port_list_lock);
60static DEFINE_SPINLOCK(queue_lock); 53static DEFINE_SPINLOCK(queue_lock);
61 54
62static LIST_HEAD(ports); 55static LIST_HEAD(ports);
63static void port_handle_node_down(unsigned long ref); 56static void port_handle_node_down(unsigned long ref);
64static struct sk_buff* port_build_self_abort_msg(struct port *,u32 err); 57static struct sk_buff *port_build_self_abort_msg(struct tipc_port *, u32 err);
65static struct sk_buff* port_build_peer_abort_msg(struct port *,u32 err); 58static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *, u32 err);
66static void port_timeout(unsigned long ref); 59static void port_timeout(unsigned long ref);
67 60
68 61
69static u32 port_peernode(struct port *p_ptr) 62static u32 port_peernode(struct tipc_port *p_ptr)
70{ 63{
71 return msg_destnode(&p_ptr->publ.phdr); 64 return msg_destnode(&p_ptr->phdr);
72} 65}
73 66
74static u32 port_peerport(struct port *p_ptr) 67static u32 port_peerport(struct tipc_port *p_ptr)
75{ 68{
76 return msg_destport(&p_ptr->publ.phdr); 69 return msg_destport(&p_ptr->phdr);
77}
78
79static u32 port_out_seqno(struct port *p_ptr)
80{
81 return msg_transp_seqno(&p_ptr->publ.phdr);
82}
83
84static void port_incr_out_seqno(struct port *p_ptr)
85{
86 struct tipc_msg *m = &p_ptr->publ.phdr;
87
88 if (likely(!msg_routed(m)))
89 return;
90 msg_set_transp_seqno(m, (msg_transp_seqno(m) + 1));
91} 70}
92 71
93/** 72/**
94 * tipc_multicast - send a multicast message to local and remote destinations 73 * tipc_multicast - send a multicast message to local and remote destinations
95 */ 74 */
96 75
97int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain, 76int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
98 u32 num_sect, struct iovec const *msg_sect) 77 u32 num_sect, struct iovec const *msg_sect,
78 unsigned int total_len)
99{ 79{
100 struct tipc_msg *hdr; 80 struct tipc_msg *hdr;
101 struct sk_buff *buf; 81 struct sk_buff *buf;
102 struct sk_buff *ibuf = NULL; 82 struct sk_buff *ibuf = NULL;
103 struct port_list dports = {0, NULL, }; 83 struct port_list dports = {0, NULL, };
104 struct port *oport = tipc_port_deref(ref); 84 struct tipc_port *oport = tipc_port_deref(ref);
105 int ext_targets; 85 int ext_targets;
106 int res; 86 int res;
107 87
@@ -110,13 +90,16 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
110 90
111 /* Create multicast message */ 91 /* Create multicast message */
112 92
113 hdr = &oport->publ.phdr; 93 hdr = &oport->phdr;
114 msg_set_type(hdr, TIPC_MCAST_MSG); 94 msg_set_type(hdr, TIPC_MCAST_MSG);
95 msg_set_lookup_scope(hdr, TIPC_CLUSTER_SCOPE);
96 msg_set_destport(hdr, 0);
97 msg_set_destnode(hdr, 0);
115 msg_set_nametype(hdr, seq->type); 98 msg_set_nametype(hdr, seq->type);
116 msg_set_namelower(hdr, seq->lower); 99 msg_set_namelower(hdr, seq->lower);
117 msg_set_nameupper(hdr, seq->upper); 100 msg_set_nameupper(hdr, seq->upper);
118 msg_set_hdr_sz(hdr, MCAST_H_SIZE); 101 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
119 res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, 102 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
120 !oport->user_port, &buf); 103 !oport->user_port, &buf);
121 if (unlikely(!buf)) 104 if (unlikely(!buf))
122 return res; 105 return res;
@@ -138,9 +121,8 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
138 } 121 }
139 } 122 }
140 res = tipc_bclink_send_msg(buf); 123 res = tipc_bclink_send_msg(buf);
141 if ((res < 0) && (dports.count != 0)) { 124 if ((res < 0) && (dports.count != 0))
142 buf_discard(ibuf); 125 buf_discard(ibuf);
143 }
144 } else { 126 } else {
145 ibuf = buf; 127 ibuf = buf;
146 } 128 }
@@ -162,7 +144,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain,
162 144
163void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) 145void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
164{ 146{
165 struct tipc_msg* msg; 147 struct tipc_msg *msg;
166 struct port_list dports = {0, NULL, }; 148 struct port_list dports = {0, NULL, };
167 struct port_list *item = dp; 149 struct port_list *item = dp;
168 int cnt = 0; 150 int cnt = 0;
@@ -183,6 +165,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
183 /* Deliver a copy of message to each destination port */ 165 /* Deliver a copy of message to each destination port */
184 166
185 if (dp->count != 0) { 167 if (dp->count != 0) {
168 msg_set_destnode(msg, tipc_own_addr);
186 if (dp->count == 1) { 169 if (dp->count == 1) {
187 msg_set_destport(msg, dp->ports[0]); 170 msg_set_destport(msg, dp->ports[0]);
188 tipc_port_recv_msg(buf); 171 tipc_port_recv_msg(buf);
@@ -195,13 +178,11 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
195 178
196 if (b == NULL) { 179 if (b == NULL) {
197 warn("Unable to deliver multicast message(s)\n"); 180 warn("Unable to deliver multicast message(s)\n");
198 msg_dbg(msg, "LOST:");
199 goto exit; 181 goto exit;
200 } 182 }
201 if ((index == 0) && (cnt != 0)) { 183 if ((index == 0) && (cnt != 0))
202 item = item->next; 184 item = item->next;
203 } 185 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); 186 tipc_port_recv_msg(b);
206 } 187 }
207 } 188 }
@@ -221,7 +202,7 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
221 void (*wakeup)(struct tipc_port *), 202 void (*wakeup)(struct tipc_port *),
222 const u32 importance) 203 const u32 importance)
223{ 204{
224 struct port *p_ptr; 205 struct tipc_port *p_ptr;
225 struct tipc_msg *msg; 206 struct tipc_msg *msg;
226 u32 ref; 207 u32 ref;
227 208
@@ -230,21 +211,19 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
230 warn("Port creation failed, no memory\n"); 211 warn("Port creation failed, no memory\n");
231 return NULL; 212 return NULL;
232 } 213 }
233 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); 214 ref = tipc_ref_acquire(p_ptr, &p_ptr->lock);
234 if (!ref) { 215 if (!ref) {
235 warn("Port creation failed, reference table exhausted\n"); 216 warn("Port creation failed, reference table exhausted\n");
236 kfree(p_ptr); 217 kfree(p_ptr);
237 return NULL; 218 return NULL;
238 } 219 }
239 220
240 p_ptr->publ.usr_handle = usr_handle; 221 p_ptr->usr_handle = usr_handle;
241 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 222 p_ptr->max_pkt = MAX_PKT_DEFAULT;
242 p_ptr->publ.ref = ref; 223 p_ptr->ref = ref;
243 msg = &p_ptr->publ.phdr; 224 msg = &p_ptr->phdr;
244 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); 225 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
245 msg_set_origport(msg, ref); 226 msg_set_origport(msg, ref);
246 p_ptr->last_in_seqno = 41;
247 p_ptr->sent = 1;
248 INIT_LIST_HEAD(&p_ptr->wait_list); 227 INIT_LIST_HEAD(&p_ptr->wait_list);
249 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 228 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
250 p_ptr->dispatcher = dispatcher; 229 p_ptr->dispatcher = dispatcher;
@@ -256,12 +235,12 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
256 INIT_LIST_HEAD(&p_ptr->port_list); 235 INIT_LIST_HEAD(&p_ptr->port_list);
257 list_add_tail(&p_ptr->port_list, &ports); 236 list_add_tail(&p_ptr->port_list, &ports);
258 spin_unlock_bh(&tipc_port_list_lock); 237 spin_unlock_bh(&tipc_port_list_lock);
259 return &(p_ptr->publ); 238 return p_ptr;
260} 239}
261 240
262int tipc_deleteport(u32 ref) 241int tipc_deleteport(u32 ref)
263{ 242{
264 struct port *p_ptr; 243 struct tipc_port *p_ptr;
265 struct sk_buff *buf = NULL; 244 struct sk_buff *buf = NULL;
266 245
267 tipc_withdraw(ref, 0, NULL); 246 tipc_withdraw(ref, 0, NULL);
@@ -273,14 +252,11 @@ int tipc_deleteport(u32 ref)
273 tipc_port_unlock(p_ptr); 252 tipc_port_unlock(p_ptr);
274 253
275 k_cancel_timer(&p_ptr->timer); 254 k_cancel_timer(&p_ptr->timer);
276 if (p_ptr->publ.connected) { 255 if (p_ptr->connected) {
277 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 256 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
278 tipc_nodesub_unsubscribe(&p_ptr->subscription); 257 tipc_nodesub_unsubscribe(&p_ptr->subscription);
279 } 258 }
280 if (p_ptr->user_port) { 259 kfree(p_ptr->user_port);
281 tipc_reg_remove_port(p_ptr->user_port);
282 kfree(p_ptr->user_port);
283 }
284 260
285 spin_lock_bh(&tipc_port_list_lock); 261 spin_lock_bh(&tipc_port_list_lock);
286 list_del(&p_ptr->port_list); 262 list_del(&p_ptr->port_list);
@@ -288,47 +264,18 @@ int tipc_deleteport(u32 ref)
288 spin_unlock_bh(&tipc_port_list_lock); 264 spin_unlock_bh(&tipc_port_list_lock);
289 k_term_timer(&p_ptr->timer); 265 k_term_timer(&p_ptr->timer);
290 kfree(p_ptr); 266 kfree(p_ptr);
291 dbg("Deleted port %u\n", ref);
292 tipc_net_route_msg(buf); 267 tipc_net_route_msg(buf);
293 return 0; 268 return 0;
294} 269}
295 270
296/** 271static int port_unreliable(struct tipc_port *p_ptr)
297 * tipc_get_port() - return port associated with 'ref'
298 *
299 * Note: Port is not locked.
300 */
301
302struct tipc_port *tipc_get_port(const u32 ref)
303{ 272{
304 return (struct tipc_port *)tipc_ref_deref(ref); 273 return msg_src_droppable(&p_ptr->phdr);
305}
306
307/**
308 * tipc_get_handle - return user handle associated to port 'ref'
309 */
310
311void *tipc_get_handle(const u32 ref)
312{
313 struct port *p_ptr;
314 void * handle;
315
316 p_ptr = tipc_port_lock(ref);
317 if (!p_ptr)
318 return NULL;
319 handle = p_ptr->publ.usr_handle;
320 tipc_port_unlock(p_ptr);
321 return handle;
322}
323
324static int port_unreliable(struct port *p_ptr)
325{
326 return msg_src_droppable(&p_ptr->publ.phdr);
327} 274}
328 275
329int tipc_portunreliable(u32 ref, unsigned int *isunreliable) 276int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
330{ 277{
331 struct port *p_ptr; 278 struct tipc_port *p_ptr;
332 279
333 p_ptr = tipc_port_lock(ref); 280 p_ptr = tipc_port_lock(ref);
334 if (!p_ptr) 281 if (!p_ptr)
@@ -340,24 +287,24 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
340 287
341int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) 288int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
342{ 289{
343 struct port *p_ptr; 290 struct tipc_port *p_ptr;
344 291
345 p_ptr = tipc_port_lock(ref); 292 p_ptr = tipc_port_lock(ref);
346 if (!p_ptr) 293 if (!p_ptr)
347 return -EINVAL; 294 return -EINVAL;
348 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); 295 msg_set_src_droppable(&p_ptr->phdr, (isunreliable != 0));
349 tipc_port_unlock(p_ptr); 296 tipc_port_unlock(p_ptr);
350 return 0; 297 return 0;
351} 298}
352 299
353static int port_unreturnable(struct port *p_ptr) 300static int port_unreturnable(struct tipc_port *p_ptr)
354{ 301{
355 return msg_dest_droppable(&p_ptr->publ.phdr); 302 return msg_dest_droppable(&p_ptr->phdr);
356} 303}
357 304
358int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) 305int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
359{ 306{
360 struct port *p_ptr; 307 struct tipc_port *p_ptr;
361 308
362 p_ptr = tipc_port_lock(ref); 309 p_ptr = tipc_port_lock(ref);
363 if (!p_ptr) 310 if (!p_ptr)
@@ -369,12 +316,12 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
369 316
370int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) 317int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
371{ 318{
372 struct port *p_ptr; 319 struct tipc_port *p_ptr;
373 320
374 p_ptr = tipc_port_lock(ref); 321 p_ptr = tipc_port_lock(ref);
375 if (!p_ptr) 322 if (!p_ptr)
376 return -EINVAL; 323 return -EINVAL;
377 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); 324 msg_set_dest_droppable(&p_ptr->phdr, (isunrejectable != 0));
378 tipc_port_unlock(p_ptr); 325 tipc_port_unlock(p_ptr);
379 return 0; 326 return 0;
380} 327}
@@ -387,12 +334,12 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
387static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, 334static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
388 u32 origport, u32 orignode, 335 u32 origport, u32 orignode,
389 u32 usr, u32 type, u32 err, 336 u32 usr, u32 type, u32 err,
390 u32 seqno, u32 ack) 337 u32 ack)
391{ 338{
392 struct sk_buff *buf; 339 struct sk_buff *buf;
393 struct tipc_msg *msg; 340 struct tipc_msg *msg;
394 341
395 buf = buf_acquire(LONG_H_SIZE); 342 buf = tipc_buf_acquire(LONG_H_SIZE);
396 if (buf) { 343 if (buf) {
397 msg = buf_msg(buf); 344 msg = buf_msg(buf);
398 tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode); 345 tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode);
@@ -400,9 +347,7 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
400 msg_set_destport(msg, destport); 347 msg_set_destport(msg, destport);
401 msg_set_origport(msg, origport); 348 msg_set_origport(msg, origport);
402 msg_set_orignode(msg, orignode); 349 msg_set_orignode(msg, orignode);
403 msg_set_transp_seqno(msg, seqno);
404 msg_set_msgcnt(msg, ack); 350 msg_set_msgcnt(msg, ack);
405 msg_dbg(msg, "PORT>SEND>:");
406 } 351 }
407 return buf; 352 return buf;
408} 353}
@@ -420,7 +365,6 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
420 data_sz = MAX_REJECT_SIZE; 365 data_sz = MAX_REJECT_SIZE;
421 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE)) 366 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE))
422 imp++; 367 imp++;
423 msg_dbg(msg, "port->rej: ");
424 368
425 /* discard rejected message if it shouldn't be returned to sender */ 369 /* discard rejected message if it shouldn't be returned to sender */
426 if (msg_errcode(msg) || msg_dest_droppable(msg)) { 370 if (msg_errcode(msg) || msg_dest_droppable(msg)) {
@@ -433,7 +377,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
433 hdr_sz = MCAST_H_SIZE; 377 hdr_sz = MCAST_H_SIZE;
434 else 378 else
435 hdr_sz = LONG_H_SIZE; 379 hdr_sz = LONG_H_SIZE;
436 rbuf = buf_acquire(data_sz + hdr_sz); 380 rbuf = tipc_buf_acquire(data_sz + hdr_sz);
437 if (rbuf == NULL) { 381 if (rbuf == NULL) {
438 buf_discard(buf); 382 buf_discard(buf);
439 return data_sz; 383 return data_sz;
@@ -457,10 +401,10 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
457 /* send self-abort message when rejecting on a connected port */ 401 /* send self-abort message when rejecting on a connected port */
458 if (msg_connected(msg)) { 402 if (msg_connected(msg)) {
459 struct sk_buff *abuf = NULL; 403 struct sk_buff *abuf = NULL;
460 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 404 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
461 405
462 if (p_ptr) { 406 if (p_ptr) {
463 if (p_ptr->publ.connected) 407 if (p_ptr->connected)
464 abuf = port_build_self_abort_msg(p_ptr, err); 408 abuf = port_build_self_abort_msg(p_ptr, err);
465 tipc_port_unlock(p_ptr); 409 tipc_port_unlock(p_ptr);
466 } 410 }
@@ -473,14 +417,14 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
473 return data_sz; 417 return data_sz;
474} 418}
475 419
476int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 420int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
477 struct iovec const *msg_sect, u32 num_sect, 421 struct iovec const *msg_sect, u32 num_sect,
478 int err) 422 unsigned int total_len, int err)
479{ 423{
480 struct sk_buff *buf; 424 struct sk_buff *buf;
481 int res; 425 int res;
482 426
483 res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, 427 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
484 !p_ptr->user_port, &buf); 428 !p_ptr->user_port, &buf);
485 if (!buf) 429 if (!buf)
486 return res; 430 return res;
@@ -490,13 +434,13 @@ int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
490 434
491static void port_timeout(unsigned long ref) 435static void port_timeout(unsigned long ref)
492{ 436{
493 struct port *p_ptr = tipc_port_lock(ref); 437 struct tipc_port *p_ptr = tipc_port_lock(ref);
494 struct sk_buff *buf = NULL; 438 struct sk_buff *buf = NULL;
495 439
496 if (!p_ptr) 440 if (!p_ptr)
497 return; 441 return;
498 442
499 if (!p_ptr->publ.connected) { 443 if (!p_ptr->connected) {
500 tipc_port_unlock(p_ptr); 444 tipc_port_unlock(p_ptr);
501 return; 445 return;
502 } 446 }
@@ -507,14 +451,12 @@ static void port_timeout(unsigned long ref)
507 } else { 451 } else {
508 buf = port_build_proto_msg(port_peerport(p_ptr), 452 buf = port_build_proto_msg(port_peerport(p_ptr),
509 port_peernode(p_ptr), 453 port_peernode(p_ptr),
510 p_ptr->publ.ref, 454 p_ptr->ref,
511 tipc_own_addr, 455 tipc_own_addr,
512 CONN_MANAGER, 456 CONN_MANAGER,
513 CONN_PROBE, 457 CONN_PROBE,
514 TIPC_OK, 458 TIPC_OK,
515 port_out_seqno(p_ptr),
516 0); 459 0);
517 port_incr_out_seqno(p_ptr);
518 p_ptr->probing_state = PROBING; 460 p_ptr->probing_state = PROBING;
519 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 461 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
520 } 462 }
@@ -525,8 +467,8 @@ static void port_timeout(unsigned long ref)
525 467
526static void port_handle_node_down(unsigned long ref) 468static void port_handle_node_down(unsigned long ref)
527{ 469{
528 struct port *p_ptr = tipc_port_lock(ref); 470 struct tipc_port *p_ptr = tipc_port_lock(ref);
529 struct sk_buff* buf = NULL; 471 struct sk_buff *buf = NULL;
530 472
531 if (!p_ptr) 473 if (!p_ptr)
532 return; 474 return;
@@ -536,84 +478,71 @@ static void port_handle_node_down(unsigned long ref)
536} 478}
537 479
538 480
539static struct sk_buff *port_build_self_abort_msg(struct port *p_ptr, u32 err) 481static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
540{ 482{
541 u32 imp = msg_importance(&p_ptr->publ.phdr); 483 u32 imp = msg_importance(&p_ptr->phdr);
542 484
543 if (!p_ptr->publ.connected) 485 if (!p_ptr->connected)
544 return NULL; 486 return NULL;
545 if (imp < TIPC_CRITICAL_IMPORTANCE) 487 if (imp < TIPC_CRITICAL_IMPORTANCE)
546 imp++; 488 imp++;
547 return port_build_proto_msg(p_ptr->publ.ref, 489 return port_build_proto_msg(p_ptr->ref,
548 tipc_own_addr, 490 tipc_own_addr,
549 port_peerport(p_ptr), 491 port_peerport(p_ptr),
550 port_peernode(p_ptr), 492 port_peernode(p_ptr),
551 imp, 493 imp,
552 TIPC_CONN_MSG, 494 TIPC_CONN_MSG,
553 err, 495 err,
554 p_ptr->last_in_seqno + 1,
555 0); 496 0);
556} 497}
557 498
558 499
559static struct sk_buff *port_build_peer_abort_msg(struct port *p_ptr, u32 err) 500static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
560{ 501{
561 u32 imp = msg_importance(&p_ptr->publ.phdr); 502 u32 imp = msg_importance(&p_ptr->phdr);
562 503
563 if (!p_ptr->publ.connected) 504 if (!p_ptr->connected)
564 return NULL; 505 return NULL;
565 if (imp < TIPC_CRITICAL_IMPORTANCE) 506 if (imp < TIPC_CRITICAL_IMPORTANCE)
566 imp++; 507 imp++;
567 return port_build_proto_msg(port_peerport(p_ptr), 508 return port_build_proto_msg(port_peerport(p_ptr),
568 port_peernode(p_ptr), 509 port_peernode(p_ptr),
569 p_ptr->publ.ref, 510 p_ptr->ref,
570 tipc_own_addr, 511 tipc_own_addr,
571 imp, 512 imp,
572 TIPC_CONN_MSG, 513 TIPC_CONN_MSG,
573 err, 514 err,
574 port_out_seqno(p_ptr),
575 0); 515 0);
576} 516}
577 517
578void tipc_port_recv_proto_msg(struct sk_buff *buf) 518void tipc_port_recv_proto_msg(struct sk_buff *buf)
579{ 519{
580 struct tipc_msg *msg = buf_msg(buf); 520 struct tipc_msg *msg = buf_msg(buf);
581 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 521 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
582 u32 err = TIPC_OK; 522 u32 err = TIPC_OK;
583 struct sk_buff *r_buf = NULL; 523 struct sk_buff *r_buf = NULL;
584 struct sk_buff *abort_buf = NULL; 524 struct sk_buff *abort_buf = NULL;
585 525
586 msg_dbg(msg, "PORT<RECV<:");
587
588 if (!p_ptr) { 526 if (!p_ptr) {
589 err = TIPC_ERR_NO_PORT; 527 err = TIPC_ERR_NO_PORT;
590 } else if (p_ptr->publ.connected) { 528 } else if (p_ptr->connected) {
591 if (port_peernode(p_ptr) != msg_orignode(msg)) 529 if ((port_peernode(p_ptr) != msg_orignode(msg)) ||
592 err = TIPC_ERR_NO_PORT; 530 (port_peerport(p_ptr) != msg_origport(msg))) {
593 if (port_peerport(p_ptr) != msg_origport(msg))
594 err = TIPC_ERR_NO_PORT; 531 err = TIPC_ERR_NO_PORT;
595 if (!err && msg_routed(msg)) { 532 } else if (msg_type(msg) == CONN_ACK) {
596 u32 seqno = msg_transp_seqno(msg);
597 u32 myno = ++p_ptr->last_in_seqno;
598 if (seqno != myno) {
599 err = TIPC_ERR_NO_PORT;
600 abort_buf = port_build_self_abort_msg(p_ptr, err);
601 }
602 }
603 if (msg_type(msg) == CONN_ACK) {
604 int wakeup = tipc_port_congested(p_ptr) && 533 int wakeup = tipc_port_congested(p_ptr) &&
605 p_ptr->publ.congested && 534 p_ptr->congested &&
606 p_ptr->wakeup; 535 p_ptr->wakeup;
607 p_ptr->acked += msg_msgcnt(msg); 536 p_ptr->acked += msg_msgcnt(msg);
608 if (tipc_port_congested(p_ptr)) 537 if (tipc_port_congested(p_ptr))
609 goto exit; 538 goto exit;
610 p_ptr->publ.congested = 0; 539 p_ptr->congested = 0;
611 if (!wakeup) 540 if (!wakeup)
612 goto exit; 541 goto exit;
613 p_ptr->wakeup(&p_ptr->publ); 542 p_ptr->wakeup(p_ptr);
614 goto exit; 543 goto exit;
615 } 544 }
616 } else if (p_ptr->publ.published) { 545 } else if (p_ptr->published) {
617 err = TIPC_ERR_NO_PORT; 546 err = TIPC_ERR_NO_PORT;
618 } 547 }
619 if (err) { 548 if (err) {
@@ -624,7 +553,6 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
624 TIPC_HIGH_IMPORTANCE, 553 TIPC_HIGH_IMPORTANCE,
625 TIPC_CONN_MSG, 554 TIPC_CONN_MSG,
626 err, 555 err,
627 0,
628 0); 556 0);
629 goto exit; 557 goto exit;
630 } 558 }
@@ -638,11 +566,9 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
638 CONN_MANAGER, 566 CONN_MANAGER,
639 CONN_PROBE_REPLY, 567 CONN_PROBE_REPLY,
640 TIPC_OK, 568 TIPC_OK,
641 port_out_seqno(p_ptr),
642 0); 569 0);
643 } 570 }
644 p_ptr->probing_state = CONFIRMED; 571 p_ptr->probing_state = CONFIRMED;
645 port_incr_out_seqno(p_ptr);
646exit: 572exit:
647 if (p_ptr) 573 if (p_ptr)
648 tipc_port_unlock(p_ptr); 574 tipc_port_unlock(p_ptr);
@@ -651,30 +577,29 @@ exit:
651 buf_discard(buf); 577 buf_discard(buf);
652} 578}
653 579
654static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id) 580static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id)
655{ 581{
656 struct publication *publ; 582 struct publication *publ;
657 583
658 if (full_id) 584 if (full_id)
659 tipc_printf(buf, "<%u.%u.%u:%u>:", 585 tipc_printf(buf, "<%u.%u.%u:%u>:",
660 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 586 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
661 tipc_node(tipc_own_addr), p_ptr->publ.ref); 587 tipc_node(tipc_own_addr), p_ptr->ref);
662 else 588 else
663 tipc_printf(buf, "%-10u:", p_ptr->publ.ref); 589 tipc_printf(buf, "%-10u:", p_ptr->ref);
664 590
665 if (p_ptr->publ.connected) { 591 if (p_ptr->connected) {
666 u32 dport = port_peerport(p_ptr); 592 u32 dport = port_peerport(p_ptr);
667 u32 destnode = port_peernode(p_ptr); 593 u32 destnode = port_peernode(p_ptr);
668 594
669 tipc_printf(buf, " connected to <%u.%u.%u:%u>", 595 tipc_printf(buf, " connected to <%u.%u.%u:%u>",
670 tipc_zone(destnode), tipc_cluster(destnode), 596 tipc_zone(destnode), tipc_cluster(destnode),
671 tipc_node(destnode), dport); 597 tipc_node(destnode), dport);
672 if (p_ptr->publ.conn_type != 0) 598 if (p_ptr->conn_type != 0)
673 tipc_printf(buf, " via {%u,%u}", 599 tipc_printf(buf, " via {%u,%u}",
674 p_ptr->publ.conn_type, 600 p_ptr->conn_type,
675 p_ptr->publ.conn_instance); 601 p_ptr->conn_instance);
676 } 602 } else if (p_ptr->published) {
677 else if (p_ptr->publ.published) {
678 tipc_printf(buf, " bound to"); 603 tipc_printf(buf, " bound to");
679 list_for_each_entry(publ, &p_ptr->publications, pport_list) { 604 list_for_each_entry(publ, &p_ptr->publications, pport_list) {
680 if (publ->lower == publ->upper) 605 if (publ->lower == publ->upper)
@@ -695,7 +620,7 @@ struct sk_buff *tipc_port_get_ports(void)
695 struct sk_buff *buf; 620 struct sk_buff *buf;
696 struct tlv_desc *rep_tlv; 621 struct tlv_desc *rep_tlv;
697 struct print_buf pb; 622 struct print_buf pb;
698 struct port *p_ptr; 623 struct tipc_port *p_ptr;
699 int str_len; 624 int str_len;
700 625
701 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY)); 626 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY));
@@ -706,9 +631,9 @@ struct sk_buff *tipc_port_get_ports(void)
706 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY); 631 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY);
707 spin_lock_bh(&tipc_port_list_lock); 632 spin_lock_bh(&tipc_port_list_lock);
708 list_for_each_entry(p_ptr, &ports, port_list) { 633 list_for_each_entry(p_ptr, &ports, port_list) {
709 spin_lock_bh(p_ptr->publ.lock); 634 spin_lock_bh(p_ptr->lock);
710 port_print(p_ptr, &pb, 0); 635 port_print(p_ptr, &pb, 0);
711 spin_unlock_bh(p_ptr->publ.lock); 636 spin_unlock_bh(p_ptr->lock);
712 } 637 }
713 spin_unlock_bh(&tipc_port_list_lock); 638 spin_unlock_bh(&tipc_port_list_lock);
714 str_len = tipc_printbuf_validate(&pb); 639 str_len = tipc_printbuf_validate(&pb);
@@ -719,58 +644,14 @@ struct sk_buff *tipc_port_get_ports(void)
719 return buf; 644 return buf;
720} 645}
721 646
722#if 0
723
724#define MAX_PORT_STATS 2000
725
726struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space)
727{
728 u32 ref;
729 struct port *p_ptr;
730 struct sk_buff *buf;
731 struct tlv_desc *rep_tlv;
732 struct print_buf pb;
733 int str_len;
734
735 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_PORT_REF))
736 return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
737
738 ref = *(u32 *)TLV_DATA(req_tlv_area);
739 ref = ntohl(ref);
740
741 p_ptr = tipc_port_lock(ref);
742 if (!p_ptr)
743 return cfg_reply_error_string("port not found");
744
745 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS));
746 if (!buf) {
747 tipc_port_unlock(p_ptr);
748 return NULL;
749 }
750 rep_tlv = (struct tlv_desc *)buf->data;
751
752 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS);
753 port_print(p_ptr, &pb, 1);
754 /* NEED TO FILL IN ADDITIONAL PORT STATISTICS HERE */
755 tipc_port_unlock(p_ptr);
756 str_len = tipc_printbuf_validate(&pb);
757
758 skb_put(buf, TLV_SPACE(str_len));
759 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
760
761 return buf;
762}
763
764#endif
765
766void tipc_port_reinit(void) 647void tipc_port_reinit(void)
767{ 648{
768 struct port *p_ptr; 649 struct tipc_port *p_ptr;
769 struct tipc_msg *msg; 650 struct tipc_msg *msg;
770 651
771 spin_lock_bh(&tipc_port_list_lock); 652 spin_lock_bh(&tipc_port_list_lock);
772 list_for_each_entry(p_ptr, &ports, port_list) { 653 list_for_each_entry(p_ptr, &ports, port_list) {
773 msg = &p_ptr->publ.phdr; 654 msg = &p_ptr->phdr;
774 if (msg_orignode(msg) == tipc_own_addr) 655 if (msg_orignode(msg) == tipc_own_addr)
775 break; 656 break;
776 msg_set_prevnode(msg, tipc_own_addr); 657 msg_set_prevnode(msg, tipc_own_addr);
@@ -795,7 +676,7 @@ static void port_dispatcher_sigh(void *dummy)
795 spin_unlock_bh(&queue_lock); 676 spin_unlock_bh(&queue_lock);
796 677
797 while (buf) { 678 while (buf) {
798 struct port *p_ptr; 679 struct tipc_port *p_ptr;
799 struct user_port *up_ptr; 680 struct user_port *up_ptr;
800 struct tipc_portid orig; 681 struct tipc_portid orig;
801 struct tipc_name_seq dseq; 682 struct tipc_name_seq dseq;
@@ -820,8 +701,8 @@ static void port_dispatcher_sigh(void *dummy)
820 orig.node = msg_orignode(msg); 701 orig.node = msg_orignode(msg);
821 up_ptr = p_ptr->user_port; 702 up_ptr = p_ptr->user_port;
822 usr_handle = up_ptr->usr_handle; 703 usr_handle = up_ptr->usr_handle;
823 connected = p_ptr->publ.connected; 704 connected = p_ptr->connected;
824 published = p_ptr->publ.published; 705 published = p_ptr->published;
825 706
826 if (unlikely(msg_errcode(msg))) 707 if (unlikely(msg_errcode(msg)))
827 goto err; 708 goto err;
@@ -832,6 +713,7 @@ static void port_dispatcher_sigh(void *dummy)
832 tipc_conn_msg_event cb = up_ptr->conn_msg_cb; 713 tipc_conn_msg_event cb = up_ptr->conn_msg_cb;
833 u32 peer_port = port_peerport(p_ptr); 714 u32 peer_port = port_peerport(p_ptr);
834 u32 peer_node = port_peernode(p_ptr); 715 u32 peer_node = port_peernode(p_ptr);
716 u32 dsz;
835 717
836 tipc_port_unlock(p_ptr); 718 tipc_port_unlock(p_ptr);
837 if (unlikely(!cb)) 719 if (unlikely(!cb))
@@ -842,13 +724,14 @@ static void port_dispatcher_sigh(void *dummy)
842 } else if ((msg_origport(msg) != peer_port) || 724 } else if ((msg_origport(msg) != peer_port) ||
843 (msg_orignode(msg) != peer_node)) 725 (msg_orignode(msg) != peer_node))
844 goto reject; 726 goto reject;
845 if (unlikely(++p_ptr->publ.conn_unacked >= 727 dsz = msg_data_sz(msg);
846 TIPC_FLOW_CONTROL_WIN)) 728 if (unlikely(dsz &&
729 (++p_ptr->conn_unacked >=
730 TIPC_FLOW_CONTROL_WIN)))
847 tipc_acknowledge(dref, 731 tipc_acknowledge(dref,
848 p_ptr->publ.conn_unacked); 732 p_ptr->conn_unacked);
849 skb_pull(buf, msg_hdr_sz(msg)); 733 skb_pull(buf, msg_hdr_sz(msg));
850 cb(usr_handle, dref, &buf, msg_data(msg), 734 cb(usr_handle, dref, &buf, msg_data(msg), dsz);
851 msg_data_sz(msg));
852 break; 735 break;
853 } 736 }
854 case TIPC_DIRECT_MSG:{ 737 case TIPC_DIRECT_MSG:{
@@ -972,7 +855,7 @@ static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf)
972 855
973static void port_wakeup_sh(unsigned long ref) 856static void port_wakeup_sh(unsigned long ref)
974{ 857{
975 struct port *p_ptr; 858 struct tipc_port *p_ptr;
976 struct user_port *up_ptr; 859 struct user_port *up_ptr;
977 tipc_continue_event cb = NULL; 860 tipc_continue_event cb = NULL;
978 void *uh = NULL; 861 void *uh = NULL;
@@ -998,14 +881,14 @@ static void port_wakeup(struct tipc_port *p_ptr)
998 881
999void tipc_acknowledge(u32 ref, u32 ack) 882void tipc_acknowledge(u32 ref, u32 ack)
1000{ 883{
1001 struct port *p_ptr; 884 struct tipc_port *p_ptr;
1002 struct sk_buff *buf = NULL; 885 struct sk_buff *buf = NULL;
1003 886
1004 p_ptr = tipc_port_lock(ref); 887 p_ptr = tipc_port_lock(ref);
1005 if (!p_ptr) 888 if (!p_ptr)
1006 return; 889 return;
1007 if (p_ptr->publ.connected) { 890 if (p_ptr->connected) {
1008 p_ptr->publ.conn_unacked -= ack; 891 p_ptr->conn_unacked -= ack;
1009 buf = port_build_proto_msg(port_peerport(p_ptr), 892 buf = port_build_proto_msg(port_peerport(p_ptr),
1010 port_peernode(p_ptr), 893 port_peernode(p_ptr),
1011 ref, 894 ref,
@@ -1013,7 +896,6 @@ void tipc_acknowledge(u32 ref, u32 ack)
1013 CONN_MANAGER, 896 CONN_MANAGER,
1014 CONN_ACK, 897 CONN_ACK,
1015 TIPC_OK, 898 TIPC_OK,
1016 port_out_seqno(p_ptr),
1017 ack); 899 ack);
1018 } 900 }
1019 tipc_port_unlock(p_ptr); 901 tipc_port_unlock(p_ptr);
@@ -1021,12 +903,10 @@ void tipc_acknowledge(u32 ref, u32 ack)
1021} 903}
1022 904
1023/* 905/*
1024 * tipc_createport(): user level call. Will add port to 906 * tipc_createport(): user level call.
1025 * registry if non-zero user_ref.
1026 */ 907 */
1027 908
1028int tipc_createport(u32 user_ref, 909int tipc_createport(void *usr_handle,
1029 void *usr_handle,
1030 unsigned int importance, 910 unsigned int importance,
1031 tipc_msg_err_event error_cb, 911 tipc_msg_err_event error_cb,
1032 tipc_named_msg_err_event named_error_cb, 912 tipc_named_msg_err_event named_error_cb,
@@ -1038,14 +918,14 @@ int tipc_createport(u32 user_ref,
1038 u32 *portref) 918 u32 *portref)
1039{ 919{
1040 struct user_port *up_ptr; 920 struct user_port *up_ptr;
1041 struct port *p_ptr; 921 struct tipc_port *p_ptr;
1042 922
1043 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); 923 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
1044 if (!up_ptr) { 924 if (!up_ptr) {
1045 warn("Port creation failed, no memory\n"); 925 warn("Port creation failed, no memory\n");
1046 return -ENOMEM; 926 return -ENOMEM;
1047 } 927 }
1048 p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher, 928 p_ptr = (struct tipc_port *)tipc_createport_raw(NULL, port_dispatcher,
1049 port_wakeup, importance); 929 port_wakeup, importance);
1050 if (!p_ptr) { 930 if (!p_ptr) {
1051 kfree(up_ptr); 931 kfree(up_ptr);
@@ -1053,9 +933,8 @@ int tipc_createport(u32 user_ref,
1053 } 933 }
1054 934
1055 p_ptr->user_port = up_ptr; 935 p_ptr->user_port = up_ptr;
1056 up_ptr->user_ref = user_ref;
1057 up_ptr->usr_handle = usr_handle; 936 up_ptr->usr_handle = usr_handle;
1058 up_ptr->ref = p_ptr->publ.ref; 937 up_ptr->ref = p_ptr->ref;
1059 up_ptr->err_cb = error_cb; 938 up_ptr->err_cb = error_cb;
1060 up_ptr->named_err_cb = named_error_cb; 939 up_ptr->named_err_cb = named_error_cb;
1061 up_ptr->conn_err_cb = conn_error_cb; 940 up_ptr->conn_err_cb = conn_error_cb;
@@ -1063,35 +942,26 @@ int tipc_createport(u32 user_ref,
1063 up_ptr->named_msg_cb = named_msg_cb; 942 up_ptr->named_msg_cb = named_msg_cb;
1064 up_ptr->conn_msg_cb = conn_msg_cb; 943 up_ptr->conn_msg_cb = conn_msg_cb;
1065 up_ptr->continue_event_cb = continue_event_cb; 944 up_ptr->continue_event_cb = continue_event_cb;
1066 INIT_LIST_HEAD(&up_ptr->uport_list); 945 *portref = p_ptr->ref;
1067 tipc_reg_add_port(up_ptr);
1068 *portref = p_ptr->publ.ref;
1069 tipc_port_unlock(p_ptr); 946 tipc_port_unlock(p_ptr);
1070 return 0; 947 return 0;
1071} 948}
1072 949
1073int tipc_ownidentity(u32 ref, struct tipc_portid *id)
1074{
1075 id->ref = ref;
1076 id->node = tipc_own_addr;
1077 return 0;
1078}
1079
1080int tipc_portimportance(u32 ref, unsigned int *importance) 950int tipc_portimportance(u32 ref, unsigned int *importance)
1081{ 951{
1082 struct port *p_ptr; 952 struct tipc_port *p_ptr;
1083 953
1084 p_ptr = tipc_port_lock(ref); 954 p_ptr = tipc_port_lock(ref);
1085 if (!p_ptr) 955 if (!p_ptr)
1086 return -EINVAL; 956 return -EINVAL;
1087 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); 957 *importance = (unsigned int)msg_importance(&p_ptr->phdr);
1088 tipc_port_unlock(p_ptr); 958 tipc_port_unlock(p_ptr);
1089 return 0; 959 return 0;
1090} 960}
1091 961
1092int tipc_set_portimportance(u32 ref, unsigned int imp) 962int tipc_set_portimportance(u32 ref, unsigned int imp)
1093{ 963{
1094 struct port *p_ptr; 964 struct tipc_port *p_ptr;
1095 965
1096 if (imp > TIPC_CRITICAL_IMPORTANCE) 966 if (imp > TIPC_CRITICAL_IMPORTANCE)
1097 return -EINVAL; 967 return -EINVAL;
@@ -1099,7 +969,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
1099 p_ptr = tipc_port_lock(ref); 969 p_ptr = tipc_port_lock(ref);
1100 if (!p_ptr) 970 if (!p_ptr)
1101 return -EINVAL; 971 return -EINVAL;
1102 msg_set_importance(&p_ptr->publ.phdr, (u32)imp); 972 msg_set_importance(&p_ptr->phdr, (u32)imp);
1103 tipc_port_unlock(p_ptr); 973 tipc_port_unlock(p_ptr);
1104 return 0; 974 return 0;
1105} 975}
@@ -1107,7 +977,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
1107 977
1108int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 978int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1109{ 979{
1110 struct port *p_ptr; 980 struct tipc_port *p_ptr;
1111 struct publication *publ; 981 struct publication *publ;
1112 u32 key; 982 u32 key;
1113 int res = -EINVAL; 983 int res = -EINVAL;
@@ -1116,10 +986,7 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1116 if (!p_ptr) 986 if (!p_ptr)
1117 return -EINVAL; 987 return -EINVAL;
1118 988
1119 dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, " 989 if (p_ptr->connected)
1120 "lower = %u, upper = %u\n",
1121 ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);
1122 if (p_ptr->publ.connected)
1123 goto exit; 990 goto exit;
1124 if (seq->lower > seq->upper) 991 if (seq->lower > seq->upper)
1125 goto exit; 992 goto exit;
@@ -1131,11 +998,11 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1131 goto exit; 998 goto exit;
1132 } 999 }
1133 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, 1000 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
1134 scope, p_ptr->publ.ref, key); 1001 scope, p_ptr->ref, key);
1135 if (publ) { 1002 if (publ) {
1136 list_add(&publ->pport_list, &p_ptr->publications); 1003 list_add(&publ->pport_list, &p_ptr->publications);
1137 p_ptr->pub_count++; 1004 p_ptr->pub_count++;
1138 p_ptr->publ.published = 1; 1005 p_ptr->published = 1;
1139 res = 0; 1006 res = 0;
1140 } 1007 }
1141exit: 1008exit:
@@ -1145,7 +1012,7 @@ exit:
1145 1012
1146int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 1013int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1147{ 1014{
1148 struct port *p_ptr; 1015 struct tipc_port *p_ptr;
1149 struct publication *publ; 1016 struct publication *publ;
1150 struct publication *tpubl; 1017 struct publication *tpubl;
1151 int res = -EINVAL; 1018 int res = -EINVAL;
@@ -1178,49 +1045,46 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1178 } 1045 }
1179 } 1046 }
1180 if (list_empty(&p_ptr->publications)) 1047 if (list_empty(&p_ptr->publications))
1181 p_ptr->publ.published = 0; 1048 p_ptr->published = 0;
1182 tipc_port_unlock(p_ptr); 1049 tipc_port_unlock(p_ptr);
1183 return res; 1050 return res;
1184} 1051}
1185 1052
1186int tipc_connect2port(u32 ref, struct tipc_portid const *peer) 1053int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1187{ 1054{
1188 struct port *p_ptr; 1055 struct tipc_port *p_ptr;
1189 struct tipc_msg *msg; 1056 struct tipc_msg *msg;
1190 int res = -EINVAL; 1057 int res = -EINVAL;
1191 1058
1192 p_ptr = tipc_port_lock(ref); 1059 p_ptr = tipc_port_lock(ref);
1193 if (!p_ptr) 1060 if (!p_ptr)
1194 return -EINVAL; 1061 return -EINVAL;
1195 if (p_ptr->publ.published || p_ptr->publ.connected) 1062 if (p_ptr->published || p_ptr->connected)
1196 goto exit; 1063 goto exit;
1197 if (!peer->ref) 1064 if (!peer->ref)
1198 goto exit; 1065 goto exit;
1199 1066
1200 msg = &p_ptr->publ.phdr; 1067 msg = &p_ptr->phdr;
1201 msg_set_destnode(msg, peer->node); 1068 msg_set_destnode(msg, peer->node);
1202 msg_set_destport(msg, peer->ref); 1069 msg_set_destport(msg, peer->ref);
1203 msg_set_orignode(msg, tipc_own_addr); 1070 msg_set_orignode(msg, tipc_own_addr);
1204 msg_set_origport(msg, p_ptr->publ.ref); 1071 msg_set_origport(msg, p_ptr->ref);
1205 msg_set_transp_seqno(msg, 42);
1206 msg_set_type(msg, TIPC_CONN_MSG); 1072 msg_set_type(msg, TIPC_CONN_MSG);
1207 if (!may_route(peer->node)) 1073 msg_set_lookup_scope(msg, 0);
1208 msg_set_hdr_sz(msg, SHORT_H_SIZE); 1074 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1209 else
1210 msg_set_hdr_sz(msg, LONG_H_SIZE);
1211 1075
1212 p_ptr->probing_interval = PROBING_INTERVAL; 1076 p_ptr->probing_interval = PROBING_INTERVAL;
1213 p_ptr->probing_state = CONFIRMED; 1077 p_ptr->probing_state = CONFIRMED;
1214 p_ptr->publ.connected = 1; 1078 p_ptr->connected = 1;
1215 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 1079 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
1216 1080
1217 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, 1081 tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
1218 (void *)(unsigned long)ref, 1082 (void *)(unsigned long)ref,
1219 (net_ev_handler)port_handle_node_down); 1083 (net_ev_handler)port_handle_node_down);
1220 res = 0; 1084 res = 0;
1221exit: 1085exit:
1222 tipc_port_unlock(p_ptr); 1086 tipc_port_unlock(p_ptr);
1223 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); 1087 p_ptr->max_pkt = tipc_link_get_max_pkt(peer->node, ref);
1224 return res; 1088 return res;
1225} 1089}
1226 1090
@@ -1238,7 +1102,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1238 tp_ptr->connected = 0; 1102 tp_ptr->connected = 0;
1239 /* let timer expire on it's own to avoid deadlock! */ 1103 /* let timer expire on it's own to avoid deadlock! */
1240 tipc_nodesub_unsubscribe( 1104 tipc_nodesub_unsubscribe(
1241 &((struct port *)tp_ptr)->subscription); 1105 &((struct tipc_port *)tp_ptr)->subscription);
1242 res = 0; 1106 res = 0;
1243 } else { 1107 } else {
1244 res = -ENOTCONN; 1108 res = -ENOTCONN;
@@ -1253,7 +1117,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1253 1117
1254int tipc_disconnect(u32 ref) 1118int tipc_disconnect(u32 ref)
1255{ 1119{
1256 struct port *p_ptr; 1120 struct tipc_port *p_ptr;
1257 int res; 1121 int res;
1258 1122
1259 p_ptr = tipc_port_lock(ref); 1123 p_ptr = tipc_port_lock(ref);
@@ -1269,15 +1133,15 @@ int tipc_disconnect(u32 ref)
1269 */ 1133 */
1270int tipc_shutdown(u32 ref) 1134int tipc_shutdown(u32 ref)
1271{ 1135{
1272 struct port *p_ptr; 1136 struct tipc_port *p_ptr;
1273 struct sk_buff *buf = NULL; 1137 struct sk_buff *buf = NULL;
1274 1138
1275 p_ptr = tipc_port_lock(ref); 1139 p_ptr = tipc_port_lock(ref);
1276 if (!p_ptr) 1140 if (!p_ptr)
1277 return -EINVAL; 1141 return -EINVAL;
1278 1142
1279 if (p_ptr->publ.connected) { 1143 if (p_ptr->connected) {
1280 u32 imp = msg_importance(&p_ptr->publ.phdr); 1144 u32 imp = msg_importance(&p_ptr->phdr);
1281 if (imp < TIPC_CRITICAL_IMPORTANCE) 1145 if (imp < TIPC_CRITICAL_IMPORTANCE)
1282 imp++; 1146 imp++;
1283 buf = port_build_proto_msg(port_peerport(p_ptr), 1147 buf = port_build_proto_msg(port_peerport(p_ptr),
@@ -1287,7 +1151,6 @@ int tipc_shutdown(u32 ref)
1287 imp, 1151 imp,
1288 TIPC_CONN_MSG, 1152 TIPC_CONN_MSG,
1289 TIPC_CONN_SHUTDOWN, 1153 TIPC_CONN_SHUTDOWN,
1290 port_out_seqno(p_ptr),
1291 0); 1154 0);
1292 } 1155 }
1293 tipc_port_unlock(p_ptr); 1156 tipc_port_unlock(p_ptr);
@@ -1295,55 +1158,19 @@ int tipc_shutdown(u32 ref)
1295 return tipc_disconnect(ref); 1158 return tipc_disconnect(ref);
1296} 1159}
1297 1160
1298int tipc_isconnected(u32 ref, int *isconnected)
1299{
1300 struct port *p_ptr;
1301
1302 p_ptr = tipc_port_lock(ref);
1303 if (!p_ptr)
1304 return -EINVAL;
1305 *isconnected = p_ptr->publ.connected;
1306 tipc_port_unlock(p_ptr);
1307 return 0;
1308}
1309
1310int tipc_peer(u32 ref, struct tipc_portid *peer)
1311{
1312 struct port *p_ptr;
1313 int res;
1314
1315 p_ptr = tipc_port_lock(ref);
1316 if (!p_ptr)
1317 return -EINVAL;
1318 if (p_ptr->publ.connected) {
1319 peer->ref = port_peerport(p_ptr);
1320 peer->node = port_peernode(p_ptr);
1321 res = 0;
1322 } else
1323 res = -ENOTCONN;
1324 tipc_port_unlock(p_ptr);
1325 return res;
1326}
1327
1328int tipc_ref_valid(u32 ref)
1329{
1330 /* Works irrespective of type */
1331 return !!tipc_ref_deref(ref);
1332}
1333
1334
1335/* 1161/*
1336 * tipc_port_recv_sections(): Concatenate and deliver sectioned 1162 * tipc_port_recv_sections(): Concatenate and deliver sectioned
1337 * message for this node. 1163 * message for this node.
1338 */ 1164 */
1339 1165
1340int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, 1166static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect,
1341 struct iovec const *msg_sect) 1167 struct iovec const *msg_sect,
1168 unsigned int total_len)
1342{ 1169{
1343 struct sk_buff *buf; 1170 struct sk_buff *buf;
1344 int res; 1171 int res;
1345 1172
1346 res = tipc_msg_build(&sender->publ.phdr, msg_sect, num_sect, 1173 res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len,
1347 MAX_MSG_SIZE, !sender->user_port, &buf); 1174 MAX_MSG_SIZE, !sender->user_port, &buf);
1348 if (likely(buf)) 1175 if (likely(buf))
1349 tipc_port_recv_msg(buf); 1176 tipc_port_recv_msg(buf);
@@ -1354,352 +1181,175 @@ int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
1354 * tipc_send - send message sections on connection 1181 * tipc_send - send message sections on connection
1355 */ 1182 */
1356 1183
1357int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) 1184int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
1185 unsigned int total_len)
1358{ 1186{
1359 struct port *p_ptr; 1187 struct tipc_port *p_ptr;
1360 u32 destnode; 1188 u32 destnode;
1361 int res; 1189 int res;
1362 1190
1363 p_ptr = tipc_port_deref(ref); 1191 p_ptr = tipc_port_deref(ref);
1364 if (!p_ptr || !p_ptr->publ.connected) 1192 if (!p_ptr || !p_ptr->connected)
1365 return -EINVAL; 1193 return -EINVAL;
1366 1194
1367 p_ptr->publ.congested = 1; 1195 p_ptr->congested = 1;
1368 if (!tipc_port_congested(p_ptr)) { 1196 if (!tipc_port_congested(p_ptr)) {
1369 destnode = port_peernode(p_ptr); 1197 destnode = port_peernode(p_ptr);
1370 if (likely(destnode != tipc_own_addr)) 1198 if (likely(destnode != tipc_own_addr))
1371 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1199 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
1372 destnode); 1200 total_len, destnode);
1373 else 1201 else
1374 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1202 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
1203 total_len);
1375 1204
1376 if (likely(res != -ELINKCONG)) { 1205 if (likely(res != -ELINKCONG)) {
1377 port_incr_out_seqno(p_ptr); 1206 p_ptr->congested = 0;
1378 p_ptr->publ.congested = 0; 1207 if (res > 0)
1379 p_ptr->sent++; 1208 p_ptr->sent++;
1380 return res; 1209 return res;
1381 } 1210 }
1382 } 1211 }
1383 if (port_unreliable(p_ptr)) { 1212 if (port_unreliable(p_ptr)) {
1384 p_ptr->publ.congested = 0; 1213 p_ptr->congested = 0;
1385 /* Just calculate msg length and return */ 1214 return total_len;
1386 return tipc_msg_calc_data_size(msg_sect, num_sect);
1387 } 1215 }
1388 return -ELINKCONG; 1216 return -ELINKCONG;
1389} 1217}
1390 1218
1391/** 1219/**
1392 * tipc_send_buf - send message buffer on connection 1220 * tipc_send2name - send message sections to port name
1393 */
1394
1395int tipc_send_buf(u32 ref, struct sk_buff *buf, unsigned int dsz)
1396{
1397 struct port *p_ptr;
1398 struct tipc_msg *msg;
1399 u32 destnode;
1400 u32 hsz;
1401 u32 sz;
1402 u32 res;
1403
1404 p_ptr = tipc_port_deref(ref);
1405 if (!p_ptr || !p_ptr->publ.connected)
1406 return -EINVAL;
1407
1408 msg = &p_ptr->publ.phdr;
1409 hsz = msg_hdr_sz(msg);
1410 sz = hsz + dsz;
1411 msg_set_size(msg, sz);
1412 if (skb_cow(buf, hsz))
1413 return -ENOMEM;
1414
1415 skb_push(buf, hsz);
1416 skb_copy_to_linear_data(buf, msg, hsz);
1417 destnode = msg_destnode(msg);
1418 p_ptr->publ.congested = 1;
1419 if (!tipc_port_congested(p_ptr)) {
1420 if (likely(destnode != tipc_own_addr))
1421 res = tipc_send_buf_fast(buf, destnode);
1422 else {
1423 tipc_port_recv_msg(buf);
1424 res = sz;
1425 }
1426 if (likely(res != -ELINKCONG)) {
1427 port_incr_out_seqno(p_ptr);
1428 p_ptr->sent++;
1429 p_ptr->publ.congested = 0;
1430 return res;
1431 }
1432 }
1433 if (port_unreliable(p_ptr)) {
1434 p_ptr->publ.congested = 0;
1435 return dsz;
1436 }
1437 return -ELINKCONG;
1438}
1439
1440/**
1441 * tipc_forward2name - forward message sections to port name
1442 */ 1221 */
1443 1222
1444int tipc_forward2name(u32 ref, 1223int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1445 struct tipc_name const *name, 1224 unsigned int num_sect, struct iovec const *msg_sect,
1446 u32 domain, 1225 unsigned int total_len)
1447 u32 num_sect,
1448 struct iovec const *msg_sect,
1449 struct tipc_portid const *orig,
1450 unsigned int importance)
1451{ 1226{
1452 struct port *p_ptr; 1227 struct tipc_port *p_ptr;
1453 struct tipc_msg *msg; 1228 struct tipc_msg *msg;
1454 u32 destnode = domain; 1229 u32 destnode = domain;
1455 u32 destport; 1230 u32 destport;
1456 int res; 1231 int res;
1457 1232
1458 p_ptr = tipc_port_deref(ref); 1233 p_ptr = tipc_port_deref(ref);
1459 if (!p_ptr || p_ptr->publ.connected) 1234 if (!p_ptr || p_ptr->connected)
1460 return -EINVAL; 1235 return -EINVAL;
1461 1236
1462 msg = &p_ptr->publ.phdr; 1237 msg = &p_ptr->phdr;
1463 msg_set_type(msg, TIPC_NAMED_MSG); 1238 msg_set_type(msg, TIPC_NAMED_MSG);
1464 msg_set_orignode(msg, orig->node); 1239 msg_set_orignode(msg, tipc_own_addr);
1465 msg_set_origport(msg, orig->ref); 1240 msg_set_origport(msg, ref);
1466 msg_set_hdr_sz(msg, LONG_H_SIZE); 1241 msg_set_hdr_sz(msg, LONG_H_SIZE);
1467 msg_set_nametype(msg, name->type); 1242 msg_set_nametype(msg, name->type);
1468 msg_set_nameinst(msg, name->instance); 1243 msg_set_nameinst(msg, name->instance);
1469 msg_set_lookup_scope(msg, tipc_addr_scope(domain)); 1244 msg_set_lookup_scope(msg, tipc_addr_scope(domain));
1470 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1471 msg_set_importance(msg,importance);
1472 destport = tipc_nametbl_translate(name->type, name->instance, &destnode); 1245 destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
1473 msg_set_destnode(msg, destnode); 1246 msg_set_destnode(msg, destnode);
1474 msg_set_destport(msg, destport); 1247 msg_set_destport(msg, destport);
1475 1248
1476 if (likely(destport || destnode)) { 1249 if (likely(destport)) {
1477 p_ptr->sent++;
1478 if (likely(destnode == tipc_own_addr)) 1250 if (likely(destnode == tipc_own_addr))
1479 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1251 res = tipc_port_recv_sections(p_ptr, num_sect,
1480 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1252 msg_sect, total_len);
1481 destnode); 1253 else
1482 if (likely(res != -ELINKCONG)) 1254 res = tipc_link_send_sections_fast(p_ptr, msg_sect,
1255 num_sect, total_len,
1256 destnode);
1257 if (likely(res != -ELINKCONG)) {
1258 if (res > 0)
1259 p_ptr->sent++;
1483 return res; 1260 return res;
1261 }
1484 if (port_unreliable(p_ptr)) { 1262 if (port_unreliable(p_ptr)) {
1485 /* Just calculate msg length and return */ 1263 return total_len;
1486 return tipc_msg_calc_data_size(msg_sect, num_sect);
1487 } 1264 }
1488 return -ELINKCONG; 1265 return -ELINKCONG;
1489 } 1266 }
1490 return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, 1267 return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect,
1491 TIPC_ERR_NO_NAME); 1268 total_len, TIPC_ERR_NO_NAME);
1492}
1493
1494/**
1495 * tipc_send2name - send message sections to port name
1496 */
1497
1498int tipc_send2name(u32 ref,
1499 struct tipc_name const *name,
1500 unsigned int domain,
1501 unsigned int num_sect,
1502 struct iovec const *msg_sect)
1503{
1504 struct tipc_portid orig;
1505
1506 orig.ref = ref;
1507 orig.node = tipc_own_addr;
1508 return tipc_forward2name(ref, name, domain, num_sect, msg_sect, &orig,
1509 TIPC_PORT_IMPORTANCE);
1510} 1269}
1511 1270
1512/** 1271/**
1513 * tipc_forward_buf2name - forward message buffer to port name 1272 * tipc_send2port - send message sections to port identity
1514 */
1515
1516int tipc_forward_buf2name(u32 ref,
1517 struct tipc_name const *name,
1518 u32 domain,
1519 struct sk_buff *buf,
1520 unsigned int dsz,
1521 struct tipc_portid const *orig,
1522 unsigned int importance)
1523{
1524 struct port *p_ptr;
1525 struct tipc_msg *msg;
1526 u32 destnode = domain;
1527 u32 destport;
1528 int res;
1529
1530 p_ptr = (struct port *)tipc_ref_deref(ref);
1531 if (!p_ptr || p_ptr->publ.connected)
1532 return -EINVAL;
1533
1534 msg = &p_ptr->publ.phdr;
1535 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1536 msg_set_importance(msg, importance);
1537 msg_set_type(msg, TIPC_NAMED_MSG);
1538 msg_set_orignode(msg, orig->node);
1539 msg_set_origport(msg, orig->ref);
1540 msg_set_nametype(msg, name->type);
1541 msg_set_nameinst(msg, name->instance);
1542 msg_set_lookup_scope(msg, tipc_addr_scope(domain));
1543 msg_set_hdr_sz(msg, LONG_H_SIZE);
1544 msg_set_size(msg, LONG_H_SIZE + dsz);
1545 destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
1546 msg_set_destnode(msg, destnode);
1547 msg_set_destport(msg, destport);
1548 msg_dbg(msg, "forw2name ==> ");
1549 if (skb_cow(buf, LONG_H_SIZE))
1550 return -ENOMEM;
1551 skb_push(buf, LONG_H_SIZE);
1552 skb_copy_to_linear_data(buf, msg, LONG_H_SIZE);
1553 msg_dbg(buf_msg(buf),"PREP:");
1554 if (likely(destport || destnode)) {
1555 p_ptr->sent++;
1556 if (destnode == tipc_own_addr)
1557 return tipc_port_recv_msg(buf);
1558 res = tipc_send_buf_fast(buf, destnode);
1559 if (likely(res != -ELINKCONG))
1560 return res;
1561 if (port_unreliable(p_ptr))
1562 return dsz;
1563 return -ELINKCONG;
1564 }
1565 return tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
1566}
1567
1568/**
1569 * tipc_send_buf2name - send message buffer to port name
1570 */
1571
1572int tipc_send_buf2name(u32 ref,
1573 struct tipc_name const *dest,
1574 u32 domain,
1575 struct sk_buff *buf,
1576 unsigned int dsz)
1577{
1578 struct tipc_portid orig;
1579
1580 orig.ref = ref;
1581 orig.node = tipc_own_addr;
1582 return tipc_forward_buf2name(ref, dest, domain, buf, dsz, &orig,
1583 TIPC_PORT_IMPORTANCE);
1584}
1585
1586/**
1587 * tipc_forward2port - forward message sections to port identity
1588 */ 1273 */
1589 1274
1590int tipc_forward2port(u32 ref, 1275int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1591 struct tipc_portid const *dest, 1276 unsigned int num_sect, struct iovec const *msg_sect,
1592 unsigned int num_sect, 1277 unsigned int total_len)
1593 struct iovec const *msg_sect,
1594 struct tipc_portid const *orig,
1595 unsigned int importance)
1596{ 1278{
1597 struct port *p_ptr; 1279 struct tipc_port *p_ptr;
1598 struct tipc_msg *msg; 1280 struct tipc_msg *msg;
1599 int res; 1281 int res;
1600 1282
1601 p_ptr = tipc_port_deref(ref); 1283 p_ptr = tipc_port_deref(ref);
1602 if (!p_ptr || p_ptr->publ.connected) 1284 if (!p_ptr || p_ptr->connected)
1603 return -EINVAL; 1285 return -EINVAL;
1604 1286
1605 msg = &p_ptr->publ.phdr; 1287 msg = &p_ptr->phdr;
1606 msg_set_type(msg, TIPC_DIRECT_MSG); 1288 msg_set_type(msg, TIPC_DIRECT_MSG);
1607 msg_set_orignode(msg, orig->node); 1289 msg_set_lookup_scope(msg, 0);
1608 msg_set_origport(msg, orig->ref); 1290 msg_set_orignode(msg, tipc_own_addr);
1291 msg_set_origport(msg, ref);
1609 msg_set_destnode(msg, dest->node); 1292 msg_set_destnode(msg, dest->node);
1610 msg_set_destport(msg, dest->ref); 1293 msg_set_destport(msg, dest->ref);
1611 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1294 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1612 if (importance <= TIPC_CRITICAL_IMPORTANCE) 1295
1613 msg_set_importance(msg, importance);
1614 p_ptr->sent++;
1615 if (dest->node == tipc_own_addr) 1296 if (dest->node == tipc_own_addr)
1616 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1297 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
1617 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node); 1298 total_len);
1618 if (likely(res != -ELINKCONG)) 1299 else
1300 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
1301 total_len, dest->node);
1302 if (likely(res != -ELINKCONG)) {
1303 if (res > 0)
1304 p_ptr->sent++;
1619 return res; 1305 return res;
1306 }
1620 if (port_unreliable(p_ptr)) { 1307 if (port_unreliable(p_ptr)) {
1621 /* Just calculate msg length and return */ 1308 return total_len;
1622 return tipc_msg_calc_data_size(msg_sect, num_sect);
1623 } 1309 }
1624 return -ELINKCONG; 1310 return -ELINKCONG;
1625} 1311}
1626 1312
1627/** 1313/**
1628 * tipc_send2port - send message sections to port identity 1314 * tipc_send_buf2port - send message buffer to port identity
1629 */ 1315 */
1630 1316
1631int tipc_send2port(u32 ref, 1317int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1632 struct tipc_portid const *dest, 1318 struct sk_buff *buf, unsigned int dsz)
1633 unsigned int num_sect,
1634 struct iovec const *msg_sect)
1635{ 1319{
1636 struct tipc_portid orig; 1320 struct tipc_port *p_ptr;
1637
1638 orig.ref = ref;
1639 orig.node = tipc_own_addr;
1640 return tipc_forward2port(ref, dest, num_sect, msg_sect, &orig,
1641 TIPC_PORT_IMPORTANCE);
1642}
1643
1644/**
1645 * tipc_forward_buf2port - forward message buffer to port identity
1646 */
1647int tipc_forward_buf2port(u32 ref,
1648 struct tipc_portid const *dest,
1649 struct sk_buff *buf,
1650 unsigned int dsz,
1651 struct tipc_portid const *orig,
1652 unsigned int importance)
1653{
1654 struct port *p_ptr;
1655 struct tipc_msg *msg; 1321 struct tipc_msg *msg;
1656 int res; 1322 int res;
1657 1323
1658 p_ptr = (struct port *)tipc_ref_deref(ref); 1324 p_ptr = (struct tipc_port *)tipc_ref_deref(ref);
1659 if (!p_ptr || p_ptr->publ.connected) 1325 if (!p_ptr || p_ptr->connected)
1660 return -EINVAL; 1326 return -EINVAL;
1661 1327
1662 msg = &p_ptr->publ.phdr; 1328 msg = &p_ptr->phdr;
1663 msg_set_type(msg, TIPC_DIRECT_MSG); 1329 msg_set_type(msg, TIPC_DIRECT_MSG);
1664 msg_set_orignode(msg, orig->node); 1330 msg_set_orignode(msg, tipc_own_addr);
1665 msg_set_origport(msg, orig->ref); 1331 msg_set_origport(msg, ref);
1666 msg_set_destnode(msg, dest->node); 1332 msg_set_destnode(msg, dest->node);
1667 msg_set_destport(msg, dest->ref); 1333 msg_set_destport(msg, dest->ref);
1668 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1334 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1669 if (importance <= TIPC_CRITICAL_IMPORTANCE)
1670 msg_set_importance(msg, importance);
1671 msg_set_size(msg, DIR_MSG_H_SIZE + dsz); 1335 msg_set_size(msg, DIR_MSG_H_SIZE + dsz);
1672 if (skb_cow(buf, DIR_MSG_H_SIZE)) 1336 if (skb_cow(buf, DIR_MSG_H_SIZE))
1673 return -ENOMEM; 1337 return -ENOMEM;
1674 1338
1675 skb_push(buf, DIR_MSG_H_SIZE); 1339 skb_push(buf, DIR_MSG_H_SIZE);
1676 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); 1340 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);
1677 msg_dbg(msg, "buf2port: "); 1341
1678 p_ptr->sent++;
1679 if (dest->node == tipc_own_addr) 1342 if (dest->node == tipc_own_addr)
1680 return tipc_port_recv_msg(buf); 1343 res = tipc_port_recv_msg(buf);
1681 res = tipc_send_buf_fast(buf, dest->node); 1344 else
1682 if (likely(res != -ELINKCONG)) 1345 res = tipc_send_buf_fast(buf, dest->node);
1346 if (likely(res != -ELINKCONG)) {
1347 if (res > 0)
1348 p_ptr->sent++;
1683 return res; 1349 return res;
1350 }
1684 if (port_unreliable(p_ptr)) 1351 if (port_unreliable(p_ptr))
1685 return dsz; 1352 return dsz;
1686 return -ELINKCONG; 1353 return -ELINKCONG;
1687} 1354}
1688 1355
1689/**
1690 * tipc_send_buf2port - send message buffer to port identity
1691 */
1692
1693int tipc_send_buf2port(u32 ref,
1694 struct tipc_portid const *dest,
1695 struct sk_buff *buf,
1696 unsigned int dsz)
1697{
1698 struct tipc_portid orig;
1699
1700 orig.ref = ref;
1701 orig.node = tipc_own_addr;
1702 return tipc_forward_buf2port(ref, dest, buf, dsz, &orig,
1703 TIPC_PORT_IMPORTANCE);
1704}
1705
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 8d1652aab298..b9aa34195aec 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -2,7 +2,7 @@
2 * net/tipc/port.h: Include file for TIPC port code 2 * net/tipc/port.h: Include file for TIPC port code
3 * 3 *
4 * Copyright (c) 1994-2007, Ericsson AB 4 * Copyright (c) 1994-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,24 +37,52 @@
37#ifndef _TIPC_PORT_H 37#ifndef _TIPC_PORT_H
38#define _TIPC_PORT_H 38#define _TIPC_PORT_H
39 39
40#include "core.h"
41#include "ref.h" 40#include "ref.h"
42#include "net.h" 41#include "net.h"
43#include "msg.h" 42#include "msg.h"
44#include "dbg.h"
45#include "node_subscr.h" 43#include "node_subscr.h"
46 44
45#define TIPC_FLOW_CONTROL_WIN 512
46
47typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref,
48 struct sk_buff **buf, unsigned char const *data,
49 unsigned int size, int reason,
50 struct tipc_portid const *attmpt_destid);
51
52typedef void (*tipc_named_msg_err_event) (void *usr_handle, u32 portref,
53 struct sk_buff **buf, unsigned char const *data,
54 unsigned int size, int reason,
55 struct tipc_name_seq const *attmpt_dest);
56
57typedef void (*tipc_conn_shutdown_event) (void *usr_handle, u32 portref,
58 struct sk_buff **buf, unsigned char const *data,
59 unsigned int size, int reason);
60
61typedef void (*tipc_msg_event) (void *usr_handle, u32 portref,
62 struct sk_buff **buf, unsigned char const *data,
63 unsigned int size, unsigned int importance,
64 struct tipc_portid const *origin);
65
66typedef void (*tipc_named_msg_event) (void *usr_handle, u32 portref,
67 struct sk_buff **buf, unsigned char const *data,
68 unsigned int size, unsigned int importance,
69 struct tipc_portid const *orig,
70 struct tipc_name_seq const *dest);
71
72typedef void (*tipc_conn_msg_event) (void *usr_handle, u32 portref,
73 struct sk_buff **buf, unsigned char const *data,
74 unsigned int size);
75
76typedef void (*tipc_continue_event) (void *usr_handle, u32 portref);
77
47/** 78/**
48 * struct user_port - TIPC user port (used with native API) 79 * struct user_port - TIPC user port (used with native API)
49 * @user_ref: id of user who created user port
50 * @usr_handle: user-specified field 80 * @usr_handle: user-specified field
51 * @ref: object reference to associated TIPC port 81 * @ref: object reference to associated TIPC port
52 * <various callback routines> 82 * <various callback routines>
53 * @uport_list: adjacent user ports in list of ports held by user
54 */ 83 */
55 84
56struct user_port { 85struct user_port {
57 u32 user_ref;
58 void *usr_handle; 86 void *usr_handle;
59 u32 ref; 87 u32 ref;
60 tipc_msg_err_event err_cb; 88 tipc_msg_err_event err_cb;
@@ -64,31 +92,48 @@ struct user_port {
64 tipc_named_msg_event named_msg_cb; 92 tipc_named_msg_event named_msg_cb;
65 tipc_conn_msg_event conn_msg_cb; 93 tipc_conn_msg_event conn_msg_cb;
66 tipc_continue_event continue_event_cb; 94 tipc_continue_event continue_event_cb;
67 struct list_head uport_list;
68}; 95};
69 96
70/** 97/**
71 * struct port - TIPC port structure 98 * struct tipc_port - TIPC port structure
72 * @publ: TIPC port info available to privileged users 99 * @usr_handle: pointer to additional user-defined information about port
100 * @lock: pointer to spinlock for controlling access to port
101 * @connected: non-zero if port is currently connected to a peer port
102 * @conn_type: TIPC type used when connection was established
103 * @conn_instance: TIPC instance used when connection was established
104 * @conn_unacked: number of unacknowledged messages received from peer port
105 * @published: non-zero if port has one or more associated names
106 * @congested: non-zero if cannot send because of link or port congestion
107 * @max_pkt: maximum packet size "hint" used when building messages sent by port
108 * @ref: unique reference to port in TIPC object registry
109 * @phdr: preformatted message header used when sending messages
73 * @port_list: adjacent ports in TIPC's global list of ports 110 * @port_list: adjacent ports in TIPC's global list of ports
74 * @dispatcher: ptr to routine which handles received messages 111 * @dispatcher: ptr to routine which handles received messages
75 * @wakeup: ptr to routine to call when port is no longer congested 112 * @wakeup: ptr to routine to call when port is no longer congested
76 * @user_port: ptr to user port associated with port (if any) 113 * @user_port: ptr to user port associated with port (if any)
77 * @wait_list: adjacent ports in list of ports waiting on link congestion 114 * @wait_list: adjacent ports in list of ports waiting on link congestion
78 * @waiting_pkts: 115 * @waiting_pkts:
79 * @sent: 116 * @sent: # of non-empty messages sent by port
80 * @acked: 117 * @acked: # of non-empty message acknowledgements from connected port's peer
81 * @publications: list of publications for port 118 * @publications: list of publications for port
82 * @pub_count: total # of publications port has made during its lifetime 119 * @pub_count: total # of publications port has made during its lifetime
83 * @probing_state: 120 * @probing_state:
84 * @probing_interval: 121 * @probing_interval:
85 * @last_in_seqno:
86 * @timer_ref: 122 * @timer_ref:
87 * @subscription: "node down" subscription used to terminate failed connections 123 * @subscription: "node down" subscription used to terminate failed connections
88 */ 124 */
89 125struct tipc_port {
90struct port { 126 void *usr_handle;
91 struct tipc_port publ; 127 spinlock_t *lock;
128 int connected;
129 u32 conn_type;
130 u32 conn_instance;
131 u32 conn_unacked;
132 int published;
133 u32 congested;
134 u32 max_pkt;
135 u32 ref;
136 struct tipc_msg phdr;
92 struct list_head port_list; 137 struct list_head port_list;
93 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *); 138 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *);
94 void (*wakeup)(struct tipc_port *); 139 void (*wakeup)(struct tipc_port *);
@@ -101,7 +146,6 @@ struct port {
101 u32 pub_count; 146 u32 pub_count;
102 u32 probing_state; 147 u32 probing_state;
103 u32 probing_interval; 148 u32 probing_interval;
104 u32 last_in_seqno;
105 struct timer_list timer; 149 struct timer_list timer;
106 struct tipc_node_subscr subscription; 150 struct tipc_node_subscr subscription;
107}; 151};
@@ -109,13 +153,80 @@ struct port {
109extern spinlock_t tipc_port_list_lock; 153extern spinlock_t tipc_port_list_lock;
110struct port_list; 154struct port_list;
111 155
112int tipc_port_recv_sections(struct port *p_ptr, u32 num_sect, 156/*
113 struct iovec const *msg_sect); 157 * TIPC port manipulation routines
114int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 158 */
159struct tipc_port *tipc_createport_raw(void *usr_handle,
160 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
161 void (*wakeup)(struct tipc_port *), const u32 importance);
162
163int tipc_reject_msg(struct sk_buff *buf, u32 err);
164
165int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode);
166
167void tipc_acknowledge(u32 port_ref, u32 ack);
168
169int tipc_createport(void *usr_handle,
170 unsigned int importance, tipc_msg_err_event error_cb,
171 tipc_named_msg_err_event named_error_cb,
172 tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb,
173 tipc_named_msg_event named_msg_cb,
174 tipc_conn_msg_event conn_msg_cb,
175 tipc_continue_event continue_event_cb, u32 *portref);
176
177int tipc_deleteport(u32 portref);
178
179int tipc_portimportance(u32 portref, unsigned int *importance);
180int tipc_set_portimportance(u32 portref, unsigned int importance);
181
182int tipc_portunreliable(u32 portref, unsigned int *isunreliable);
183int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
184
185int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
186int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
187
188int tipc_publish(u32 portref, unsigned int scope,
189 struct tipc_name_seq const *name_seq);
190int tipc_withdraw(u32 portref, unsigned int scope,
191 struct tipc_name_seq const *name_seq);
192
193int tipc_connect2port(u32 portref, struct tipc_portid const *port);
194
195int tipc_disconnect(u32 portref);
196
197int tipc_shutdown(u32 ref);
198
199
200/*
201 * The following routines require that the port be locked on entry
202 */
203int tipc_disconnect_port(struct tipc_port *tp_ptr);
204
205/*
206 * TIPC messaging routines
207 */
208int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect,
209 unsigned int total_len);
210
211int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
212 unsigned int num_sect, struct iovec const *msg_sect,
213 unsigned int total_len);
214
215int tipc_send2port(u32 portref, struct tipc_portid const *dest,
216 unsigned int num_sect, struct iovec const *msg_sect,
217 unsigned int total_len);
218
219int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
220 struct sk_buff *buf, unsigned int dsz);
221
222int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
223 unsigned int section_count, struct iovec const *msg,
224 unsigned int total_len);
225
226int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
115 struct iovec const *msg_sect, u32 num_sect, 227 struct iovec const *msg_sect, u32 num_sect,
116 int err); 228 unsigned int total_len, int err);
117struct sk_buff *tipc_port_get_ports(void); 229struct sk_buff *tipc_port_get_ports(void);
118struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space);
119void tipc_port_recv_proto_msg(struct sk_buff *buf); 230void tipc_port_recv_proto_msg(struct sk_buff *buf);
120void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); 231void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
121void tipc_port_reinit(void); 232void tipc_port_reinit(void);
@@ -124,9 +235,9 @@ void tipc_port_reinit(void);
124 * tipc_port_lock - lock port instance referred to and return its pointer 235 * tipc_port_lock - lock port instance referred to and return its pointer
125 */ 236 */
126 237
127static inline struct port *tipc_port_lock(u32 ref) 238static inline struct tipc_port *tipc_port_lock(u32 ref)
128{ 239{
129 return (struct port *)tipc_ref_lock(ref); 240 return (struct tipc_port *)tipc_ref_lock(ref);
130} 241}
131 242
132/** 243/**
@@ -135,29 +246,29 @@ static inline struct port *tipc_port_lock(u32 ref)
135 * Can use pointer instead of tipc_ref_unlock() since port is already locked. 246 * Can use pointer instead of tipc_ref_unlock() since port is already locked.
136 */ 247 */
137 248
138static inline void tipc_port_unlock(struct port *p_ptr) 249static inline void tipc_port_unlock(struct tipc_port *p_ptr)
139{ 250{
140 spin_unlock_bh(p_ptr->publ.lock); 251 spin_unlock_bh(p_ptr->lock);
141} 252}
142 253
143static inline struct port* tipc_port_deref(u32 ref) 254static inline struct tipc_port *tipc_port_deref(u32 ref)
144{ 255{
145 return (struct port *)tipc_ref_deref(ref); 256 return (struct tipc_port *)tipc_ref_deref(ref);
146} 257}
147 258
148static inline u32 tipc_peer_port(struct port *p_ptr) 259static inline u32 tipc_peer_port(struct tipc_port *p_ptr)
149{ 260{
150 return msg_destport(&p_ptr->publ.phdr); 261 return msg_destport(&p_ptr->phdr);
151} 262}
152 263
153static inline u32 tipc_peer_node(struct port *p_ptr) 264static inline u32 tipc_peer_node(struct tipc_port *p_ptr)
154{ 265{
155 return msg_destnode(&p_ptr->publ.phdr); 266 return msg_destnode(&p_ptr->phdr);
156} 267}
157 268
158static inline int tipc_port_congested(struct port *p_ptr) 269static inline int tipc_port_congested(struct tipc_port *p_ptr)
159{ 270{
160 return((p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2)); 271 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
161} 272}
162 273
163/** 274/**
@@ -166,7 +277,7 @@ static inline int tipc_port_congested(struct port *p_ptr)
166 277
167static inline int tipc_port_recv_msg(struct sk_buff *buf) 278static inline int tipc_port_recv_msg(struct sk_buff *buf)
168{ 279{
169 struct port *p_ptr; 280 struct tipc_port *p_ptr;
170 struct tipc_msg *msg = buf_msg(buf); 281 struct tipc_msg *msg = buf_msg(buf);
171 u32 destport = msg_destport(msg); 282 u32 destport = msg_destport(msg);
172 u32 dsz = msg_data_sz(msg); 283 u32 dsz = msg_data_sz(msg);
@@ -181,7 +292,7 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
181 /* validate destination & pass to port, otherwise reject message */ 292 /* validate destination & pass to port, otherwise reject message */
182 p_ptr = tipc_port_lock(destport); 293 p_ptr = tipc_port_lock(destport);
183 if (likely(p_ptr)) { 294 if (likely(p_ptr)) {
184 if (likely(p_ptr->publ.connected)) { 295 if (likely(p_ptr->connected)) {
185 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) || 296 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) ||
186 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) || 297 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) ||
187 (unlikely(!msg_connected(msg)))) { 298 (unlikely(!msg_connected(msg)))) {
@@ -190,7 +301,7 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
190 goto reject; 301 goto reject;
191 } 302 }
192 } 303 }
193 err = p_ptr->dispatcher(&p_ptr->publ, buf); 304 err = p_ptr->dispatcher(p_ptr, buf);
194 tipc_port_unlock(p_ptr); 305 tipc_port_unlock(p_ptr);
195 if (likely(!err)) 306 if (likely(!err))
196 return dsz; 307 return dsz;
@@ -198,7 +309,6 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
198 err = TIPC_ERR_NO_PORT; 309 err = TIPC_ERR_NO_PORT;
199 } 310 }
200reject: 311reject:
201 dbg("port->rejecting, err = %x..\n",err);
202 return tipc_reject_msg(buf, err); 312 return tipc_reject_msg(buf, err);
203} 313}
204 314
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 8dea66500cf5..83116892528b 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -89,7 +89,7 @@ struct ref_table {
89 * have a reference value of 0 (although this is unlikely). 89 * have a reference value of 0 (although this is unlikely).
90 */ 90 */
91 91
92static struct ref_table tipc_ref_table = { NULL }; 92static struct ref_table tipc_ref_table;
93 93
94static DEFINE_RWLOCK(ref_table_lock); 94static DEFINE_RWLOCK(ref_table_lock);
95 95
@@ -178,14 +178,12 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
178 next_plus_upper = entry->ref; 178 next_plus_upper = entry->ref;
179 tipc_ref_table.first_free = next_plus_upper & index_mask; 179 tipc_ref_table.first_free = next_plus_upper & index_mask;
180 ref = (next_plus_upper & ~index_mask) + index; 180 ref = (next_plus_upper & ~index_mask) + index;
181 } 181 } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
182 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
183 index = tipc_ref_table.init_point++; 182 index = tipc_ref_table.init_point++;
184 entry = &(tipc_ref_table.entries[index]); 183 entry = &(tipc_ref_table.entries[index]);
185 spin_lock_init(&entry->lock); 184 spin_lock_init(&entry->lock);
186 ref = tipc_ref_table.start_mask + index; 185 ref = tipc_ref_table.start_mask + index;
187 } 186 } else {
188 else {
189 ref = 0; 187 ref = 0;
190 } 188 }
191 write_unlock_bh(&ref_table_lock); 189 write_unlock_bh(&ref_table_lock);
@@ -282,23 +280,6 @@ void *tipc_ref_lock(u32 ref)
282 return NULL; 280 return NULL;
283} 281}
284 282
285/**
286 * tipc_ref_unlock - unlock referenced object
287 */
288
289void tipc_ref_unlock(u32 ref)
290{
291 if (likely(tipc_ref_table.entries)) {
292 struct reference *entry;
293
294 entry = &tipc_ref_table.entries[ref &
295 tipc_ref_table.index_mask];
296 if (likely((entry->ref == ref) && (entry->object)))
297 spin_unlock_bh(&entry->lock);
298 else
299 err("Attempt to unlock non-existent reference\n");
300 }
301}
302 283
303/** 284/**
304 * 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 66e889ba48fd..338837396642 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2,7 +2,7 @@
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2007, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -34,25 +34,13 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <linux/module.h>
38#include <linux/types.h>
39#include <linux/net.h>
40#include <linux/socket.h>
41#include <linux/errno.h>
42#include <linux/mm.h>
43#include <linux/poll.h>
44#include <linux/fcntl.h>
45#include <linux/gfp.h>
46#include <asm/string.h>
47#include <asm/atomic.h>
48#include <net/sock.h> 37#include <net/sock.h>
49 38
50#include <linux/tipc.h> 39#include <linux/tipc.h>
51#include <linux/tipc_config.h> 40#include <linux/tipc_config.h>
52#include <net/tipc/tipc_msg.h>
53#include <net/tipc/tipc_port.h>
54 41
55#include "core.h" 42#include "core.h"
43#include "port.h"
56 44
57#define SS_LISTENING -1 /* socket is listening */ 45#define SS_LISTENING -1 /* socket is listening */
58#define SS_READY -2 /* socket is connectionless */ 46#define SS_READY -2 /* socket is connectionless */
@@ -64,11 +52,15 @@ 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))
70#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) 59#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p))
71 60
61#define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \
62 (sock->state == SS_DISCONNECTING))
63
72static int backlog_rcv(struct sock *sk, struct sk_buff *skb); 64static int backlog_rcv(struct sock *sk, struct sk_buff *skb);
73static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); 65static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
74static void wakeupdispatch(struct tipc_port *tport); 66static void wakeupdispatch(struct tipc_port *tport);
@@ -79,7 +71,7 @@ static const struct proto_ops msg_ops;
79 71
80static struct proto tipc_proto; 72static struct proto tipc_proto;
81 73
82static int sockets_enabled = 0; 74static int sockets_enabled;
83 75
84static atomic_t tipc_queue_size = ATOMIC_INIT(0); 76static atomic_t tipc_queue_size = ATOMIC_INIT(0);
85 77
@@ -240,9 +232,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
240 sock->state = state; 232 sock->state = state;
241 233
242 sock_init_data(sock, sk); 234 sock_init_data(sock, sk);
243 sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
244 sk->sk_backlog_rcv = backlog_rcv; 235 sk->sk_backlog_rcv = backlog_rcv;
245 tipc_sk(sk)->p = tp_ptr; 236 tipc_sk(sk)->p = tp_ptr;
237 tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
246 238
247 spin_unlock_bh(tp_ptr->lock); 239 spin_unlock_bh(tp_ptr->lock);
248 240
@@ -252,7 +244,6 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
252 tipc_set_portunreliable(tp_ptr->ref, 1); 244 tipc_set_portunreliable(tp_ptr->ref, 1);
253 } 245 }
254 246
255 atomic_inc(&tipc_user_count);
256 return 0; 247 return 0;
257} 248}
258 249
@@ -301,7 +292,7 @@ static int release(struct socket *sock)
301 if (buf == NULL) 292 if (buf == NULL)
302 break; 293 break;
303 atomic_dec(&tipc_queue_size); 294 atomic_dec(&tipc_queue_size);
304 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) 295 if (TIPC_SKB_CB(buf)->handle != 0)
305 buf_discard(buf); 296 buf_discard(buf);
306 else { 297 else {
307 if ((sock->state == SS_CONNECTING) || 298 if ((sock->state == SS_CONNECTING) ||
@@ -332,7 +323,6 @@ static int release(struct socket *sock)
332 sock_put(sk); 323 sock_put(sk);
333 sock->sk = NULL; 324 sock->sk = NULL;
334 325
335 atomic_dec(&tipc_user_count);
336 return res; 326 return res;
337} 327}
338 328
@@ -386,7 +376,7 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
386 * 376 *
387 * NOTE: This routine doesn't need to take the socket lock since it only 377 * NOTE: This routine doesn't need to take the socket lock since it only
388 * accesses socket information that is unchanging (or which changes in 378 * accesses socket information that is unchanging (or which changes in
389 * a completely predictable manner). 379 * a completely predictable manner).
390 */ 380 */
391 381
392static int get_name(struct socket *sock, struct sockaddr *uaddr, 382static int get_name(struct socket *sock, struct sockaddr *uaddr,
@@ -395,6 +385,7 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
395 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 385 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
396 struct tipc_sock *tsock = tipc_sk(sock->sk); 386 struct tipc_sock *tsock = tipc_sk(sock->sk);
397 387
388 memset(addr, 0, sizeof(*addr));
398 if (peer) { 389 if (peer) {
399 if ((sock->state != SS_CONNECTED) && 390 if ((sock->state != SS_CONNECTED) &&
400 ((peer != 2) || (sock->state != SS_DISCONNECTING))) 391 ((peer != 2) || (sock->state != SS_DISCONNECTING)))
@@ -402,7 +393,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
402 addr->addr.id.ref = tsock->peer_name.ref; 393 addr->addr.id.ref = tsock->peer_name.ref;
403 addr->addr.id.node = tsock->peer_name.node; 394 addr->addr.id.node = tsock->peer_name.node;
404 } else { 395 } else {
405 tipc_ownidentity(tsock->p->ref, &addr->addr.id); 396 addr->addr.id.ref = tsock->p->ref;
397 addr->addr.id.node = tipc_own_addr;
406 } 398 }
407 399
408 *uaddr_len = sizeof(*addr); 400 *uaddr_len = sizeof(*addr);
@@ -429,36 +421,55 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
429 * to handle any preventable race conditions, so TIPC will do the same ... 421 * to handle any preventable race conditions, so TIPC will do the same ...
430 * 422 *
431 * TIPC sets the returned events as follows: 423 * TIPC sets the returned events as follows:
432 * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty 424 *
433 * or if a connection-oriented socket is does not have an active connection 425 * socket state flags set
434 * (i.e. a read operation will not block). 426 * ------------ ---------
435 * b) POLLOUT is set except when a socket's connection has been terminated 427 * unconnected no read flags
436 * (i.e. a write operation will not block). 428 * no write flags
437 * c) POLLHUP is set when a socket's connection has been terminated. 429 *
438 * 430 * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue
439 * IMPORTANT: The fact that a read or write operation will not block does NOT 431 * no write flags
440 * imply that the operation will succeed! 432 *
433 * connected POLLIN/POLLRDNORM if data in rx queue
434 * POLLOUT if port is not congested
435 *
436 * disconnecting POLLIN/POLLRDNORM/POLLHUP
437 * no write flags
438 *
439 * listening POLLIN if SYN in rx queue
440 * no write flags
441 *
442 * ready POLLIN/POLLRDNORM if data in rx queue
443 * [connectionless] POLLOUT (since port cannot be congested)
444 *
445 * IMPORTANT: The fact that a read or write operation is indicated does NOT
446 * imply that the operation will succeed, merely that it should be performed
447 * and will not block.
441 */ 448 */
442 449
443static unsigned int poll(struct file *file, struct socket *sock, 450static unsigned int poll(struct file *file, struct socket *sock,
444 poll_table *wait) 451 poll_table *wait)
445{ 452{
446 struct sock *sk = sock->sk; 453 struct sock *sk = sock->sk;
447 u32 mask; 454 u32 mask = 0;
448 455
449 poll_wait(file, sk_sleep(sk), wait); 456 poll_wait(file, sk_sleep(sk), wait);
450 457
451 if (!skb_queue_empty(&sk->sk_receive_queue) || 458 switch ((int)sock->state) {
452 (sock->state == SS_UNCONNECTED) || 459 case SS_READY:
453 (sock->state == SS_DISCONNECTING)) 460 case SS_CONNECTED:
454 mask = (POLLRDNORM | POLLIN); 461 if (!tipc_sk_port(sk)->congested)
455 else 462 mask |= POLLOUT;
456 mask = 0; 463 /* fall thru' */
457 464 case SS_CONNECTING:
458 if (sock->state == SS_DISCONNECTING) 465 case SS_LISTENING:
459 mask |= POLLHUP; 466 if (!skb_queue_empty(&sk->sk_receive_queue))
460 else 467 mask |= (POLLIN | POLLRDNORM);
461 mask |= POLLOUT; 468 break;
469 case SS_DISCONNECTING:
470 mask = (POLLIN | POLLRDNORM | POLLHUP);
471 break;
472 }
462 473
463 return mask; 474 return mask;
464} 475}
@@ -485,6 +496,8 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m)
485 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV)) 496 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV))
486 return -EACCES; 497 return -EACCES;
487 498
499 if (!m->msg_iovlen || (m->msg_iov[0].iov_len < sizeof(hdr)))
500 return -EMSGSIZE;
488 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr))) 501 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr)))
489 return -EFAULT; 502 return -EFAULT;
490 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN))) 503 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN)))
@@ -522,6 +535,9 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
522 if (unlikely((m->msg_namelen < sizeof(*dest)) || 535 if (unlikely((m->msg_namelen < sizeof(*dest)) ||
523 (dest->family != AF_TIPC))) 536 (dest->family != AF_TIPC)))
524 return -EINVAL; 537 return -EINVAL;
538 if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
539 (m->msg_iovlen > (unsigned)INT_MAX))
540 return -EMSGSIZE;
525 541
526 if (iocb) 542 if (iocb)
527 lock_sock(sk); 543 lock_sock(sk);
@@ -553,37 +569,38 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
553 569
554 do { 570 do {
555 if (dest->addrtype == TIPC_ADDR_NAME) { 571 if (dest->addrtype == TIPC_ADDR_NAME) {
556 if ((res = dest_name_check(dest, m))) 572 res = dest_name_check(dest, m);
573 if (res)
557 break; 574 break;
558 res = tipc_send2name(tport->ref, 575 res = tipc_send2name(tport->ref,
559 &dest->addr.name.name, 576 &dest->addr.name.name,
560 dest->addr.name.domain, 577 dest->addr.name.domain,
561 m->msg_iovlen, 578 m->msg_iovlen,
562 m->msg_iov); 579 m->msg_iov,
563 } 580 total_len);
564 else if (dest->addrtype == TIPC_ADDR_ID) { 581 } else if (dest->addrtype == TIPC_ADDR_ID) {
565 res = tipc_send2port(tport->ref, 582 res = tipc_send2port(tport->ref,
566 &dest->addr.id, 583 &dest->addr.id,
567 m->msg_iovlen, 584 m->msg_iovlen,
568 m->msg_iov); 585 m->msg_iov,
569 } 586 total_len);
570 else if (dest->addrtype == TIPC_ADDR_MCAST) { 587 } else if (dest->addrtype == TIPC_ADDR_MCAST) {
571 if (needs_conn) { 588 if (needs_conn) {
572 res = -EOPNOTSUPP; 589 res = -EOPNOTSUPP;
573 break; 590 break;
574 } 591 }
575 if ((res = dest_name_check(dest, m))) 592 res = dest_name_check(dest, m);
593 if (res)
576 break; 594 break;
577 res = tipc_multicast(tport->ref, 595 res = tipc_multicast(tport->ref,
578 &dest->addr.nameseq, 596 &dest->addr.nameseq,
579 0,
580 m->msg_iovlen, 597 m->msg_iovlen,
581 m->msg_iov); 598 m->msg_iov,
599 total_len);
582 } 600 }
583 if (likely(res != -ELINKCONG)) { 601 if (likely(res != -ELINKCONG)) {
584 if (needs_conn && (res >= 0)) { 602 if (needs_conn && (res >= 0))
585 sock->state = SS_CONNECTING; 603 sock->state = SS_CONNECTING;
586 }
587 break; 604 break;
588 } 605 }
589 if (m->msg_flags & MSG_DONTWAIT) { 606 if (m->msg_flags & MSG_DONTWAIT) {
@@ -629,6 +646,10 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
629 if (unlikely(dest)) 646 if (unlikely(dest))
630 return send_msg(iocb, sock, m, total_len); 647 return send_msg(iocb, sock, m, total_len);
631 648
649 if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
650 (m->msg_iovlen > (unsigned)INT_MAX))
651 return -EMSGSIZE;
652
632 if (iocb) 653 if (iocb)
633 lock_sock(sk); 654 lock_sock(sk);
634 655
@@ -641,10 +662,10 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
641 break; 662 break;
642 } 663 }
643 664
644 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); 665 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov,
645 if (likely(res != -ELINKCONG)) { 666 total_len);
667 if (likely(res != -ELINKCONG))
646 break; 668 break;
647 }
648 if (m->msg_flags & MSG_DONTWAIT) { 669 if (m->msg_flags & MSG_DONTWAIT) {
649 res = -EWOULDBLOCK; 670 res = -EWOULDBLOCK;
650 break; 671 break;
@@ -713,6 +734,12 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
713 goto exit; 734 goto exit;
714 } 735 }
715 736
737 if ((total_len > (unsigned)INT_MAX) ||
738 (m->msg_iovlen > (unsigned)INT_MAX)) {
739 res = -EMSGSIZE;
740 goto exit;
741 }
742
716 /* 743 /*
717 * Send each iovec entry using one or more messages 744 * Send each iovec entry using one or more messages
718 * 745 *
@@ -743,7 +770,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
743 bytes_to_send = curr_left; 770 bytes_to_send = curr_left;
744 my_iov.iov_base = curr_start; 771 my_iov.iov_base = curr_start;
745 my_iov.iov_len = bytes_to_send; 772 my_iov.iov_len = bytes_to_send;
746 if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) { 773 res = send_packet(NULL, sock, &my_msg, bytes_to_send);
774 if (res < 0) {
747 if (bytes_sent) 775 if (bytes_sent)
748 res = bytes_sent; 776 res = bytes_sent;
749 goto exit; 777 goto exit;
@@ -803,8 +831,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
803 addr->addrtype = TIPC_ADDR_ID; 831 addr->addrtype = TIPC_ADDR_ID;
804 addr->addr.id.ref = msg_origport(msg); 832 addr->addr.id.ref = msg_origport(msg);
805 addr->addr.id.node = msg_orignode(msg); 833 addr->addr.id.node = msg_orignode(msg);
806 addr->addr.name.domain = 0; /* could leave uninitialized */ 834 addr->addr.name.domain = 0; /* could leave uninitialized */
807 addr->scope = 0; /* could leave uninitialized */ 835 addr->scope = 0; /* could leave uninitialized */
808 m->msg_namelen = sizeof(struct sockaddr_tipc); 836 m->msg_namelen = sizeof(struct sockaddr_tipc);
809 } 837 }
810} 838}
@@ -838,12 +866,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
838 if (unlikely(err)) { 866 if (unlikely(err)) {
839 anc_data[0] = err; 867 anc_data[0] = err;
840 anc_data[1] = msg_data_sz(msg); 868 anc_data[1] = msg_data_sz(msg);
841 if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data))) 869 res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data);
842 return res; 870 if (res)
843 if (anc_data[1] &&
844 (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
845 msg_data(msg))))
846 return res; 871 return res;
872 if (anc_data[1]) {
873 res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
874 msg_data(msg));
875 if (res)
876 return res;
877 }
847 } 878 }
848 879
849 /* Optionally capture message destination object */ 880 /* Optionally capture message destination object */
@@ -871,9 +902,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
871 default: 902 default:
872 has_name = 0; 903 has_name = 0;
873 } 904 }
874 if (has_name && 905 if (has_name) {
875 (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data))) 906 res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data);
876 return res; 907 if (res)
908 return res;
909 }
877 910
878 return 0; 911 return 0;
879} 912}
@@ -898,15 +931,13 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
898 struct tipc_port *tport = tipc_sk_port(sk); 931 struct tipc_port *tport = tipc_sk_port(sk);
899 struct sk_buff *buf; 932 struct sk_buff *buf;
900 struct tipc_msg *msg; 933 struct tipc_msg *msg;
934 long timeout;
901 unsigned int sz; 935 unsigned int sz;
902 u32 err; 936 u32 err;
903 int res; 937 int res;
904 938
905 /* Catch invalid receive requests */ 939 /* Catch invalid receive requests */
906 940
907 if (m->msg_iovlen != 1)
908 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
909
910 if (unlikely(!buf_len)) 941 if (unlikely(!buf_len))
911 return -EINVAL; 942 return -EINVAL;
912 943
@@ -917,6 +948,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
917 goto exit; 948 goto exit;
918 } 949 }
919 950
951 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
920restart: 952restart:
921 953
922 /* Look for a message in receive queue; wait if necessary */ 954 /* Look for a message in receive queue; wait if necessary */
@@ -926,17 +958,15 @@ restart:
926 res = -ENOTCONN; 958 res = -ENOTCONN;
927 goto exit; 959 goto exit;
928 } 960 }
929 if (flags & MSG_DONTWAIT) { 961 if (timeout <= 0L) {
930 res = -EWOULDBLOCK; 962 res = timeout ? timeout : -EWOULDBLOCK;
931 goto exit; 963 goto exit;
932 } 964 }
933 release_sock(sk); 965 release_sock(sk);
934 res = wait_event_interruptible(*sk_sleep(sk), 966 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
935 (!skb_queue_empty(&sk->sk_receive_queue) || 967 tipc_rx_ready(sock),
936 (sock->state == SS_DISCONNECTING))); 968 timeout);
937 lock_sock(sk); 969 lock_sock(sk);
938 if (res)
939 goto exit;
940 } 970 }
941 971
942 /* Look at first message in receive queue */ 972 /* Look at first message in receive queue */
@@ -978,11 +1008,10 @@ restart:
978 sz = buf_len; 1008 sz = buf_len;
979 m->msg_flags |= MSG_TRUNC; 1009 m->msg_flags |= MSG_TRUNC;
980 } 1010 }
981 if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg), 1011 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg),
982 sz))) { 1012 m->msg_iov, sz);
983 res = -EFAULT; 1013 if (res)
984 goto exit; 1014 goto exit;
985 }
986 res = sz; 1015 res = sz;
987 } else { 1016 } else {
988 if ((sock->state == SS_READY) || 1017 if ((sock->state == SS_READY) ||
@@ -1025,20 +1054,15 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1025 struct tipc_port *tport = tipc_sk_port(sk); 1054 struct tipc_port *tport = tipc_sk_port(sk);
1026 struct sk_buff *buf; 1055 struct sk_buff *buf;
1027 struct tipc_msg *msg; 1056 struct tipc_msg *msg;
1057 long timeout;
1028 unsigned int sz; 1058 unsigned int sz;
1029 int sz_to_copy; 1059 int sz_to_copy, target, needed;
1030 int sz_copied = 0; 1060 int sz_copied = 0;
1031 int needed;
1032 char __user *crs = m->msg_iov->iov_base;
1033 unsigned char *buf_crs;
1034 u32 err; 1061 u32 err;
1035 int res = 0; 1062 int res = 0;
1036 1063
1037 /* Catch invalid receive attempts */ 1064 /* Catch invalid receive attempts */
1038 1065
1039 if (m->msg_iovlen != 1)
1040 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
1041
1042 if (unlikely(!buf_len)) 1066 if (unlikely(!buf_len))
1043 return -EINVAL; 1067 return -EINVAL;
1044 1068
@@ -1050,6 +1074,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1050 goto exit; 1074 goto exit;
1051 } 1075 }
1052 1076
1077 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1078 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1053restart: 1079restart:
1054 1080
1055 /* Look for a message in receive queue; wait if necessary */ 1081 /* Look for a message in receive queue; wait if necessary */
@@ -1059,17 +1085,15 @@ restart:
1059 res = -ENOTCONN; 1085 res = -ENOTCONN;
1060 goto exit; 1086 goto exit;
1061 } 1087 }
1062 if (flags & MSG_DONTWAIT) { 1088 if (timeout <= 0L) {
1063 res = -EWOULDBLOCK; 1089 res = timeout ? timeout : -EWOULDBLOCK;
1064 goto exit; 1090 goto exit;
1065 } 1091 }
1066 release_sock(sk); 1092 release_sock(sk);
1067 res = wait_event_interruptible(*sk_sleep(sk), 1093 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
1068 (!skb_queue_empty(&sk->sk_receive_queue) || 1094 tipc_rx_ready(sock),
1069 (sock->state == SS_DISCONNECTING))); 1095 timeout);
1070 lock_sock(sk); 1096 lock_sock(sk);
1071 if (res)
1072 goto exit;
1073 } 1097 }
1074 1098
1075 /* Look at first message in receive queue */ 1099 /* Look at first message in receive queue */
@@ -1098,24 +1122,25 @@ restart:
1098 /* Capture message data (if valid) & compute return value (always) */ 1122 /* Capture message data (if valid) & compute return value (always) */
1099 1123
1100 if (!err) { 1124 if (!err) {
1101 buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle); 1125 u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle);
1102 sz = (unsigned char *)msg + msg_size(msg) - buf_crs;
1103 1126
1127 sz -= offset;
1104 needed = (buf_len - sz_copied); 1128 needed = (buf_len - sz_copied);
1105 sz_to_copy = (sz <= needed) ? sz : needed; 1129 sz_to_copy = (sz <= needed) ? sz : needed;
1106 if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) { 1130
1107 res = -EFAULT; 1131 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset,
1132 m->msg_iov, sz_to_copy);
1133 if (res)
1108 goto exit; 1134 goto exit;
1109 } 1135
1110 sz_copied += sz_to_copy; 1136 sz_copied += sz_to_copy;
1111 1137
1112 if (sz_to_copy < sz) { 1138 if (sz_to_copy < sz) {
1113 if (!(flags & MSG_PEEK)) 1139 if (!(flags & MSG_PEEK))
1114 TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy; 1140 TIPC_SKB_CB(buf)->handle =
1141 (void *)(unsigned long)(offset + sz_to_copy);
1115 goto exit; 1142 goto exit;
1116 } 1143 }
1117
1118 crs += sz_to_copy;
1119 } else { 1144 } else {
1120 if (sz_copied != 0) 1145 if (sz_copied != 0)
1121 goto exit; /* can't add error msg to valid data */ 1146 goto exit; /* can't add error msg to valid data */
@@ -1138,7 +1163,7 @@ restart:
1138 1163
1139 if ((sz_copied < buf_len) && /* didn't get all requested data */ 1164 if ((sz_copied < buf_len) && /* didn't get all requested data */
1140 (!skb_queue_empty(&sk->sk_receive_queue) || 1165 (!skb_queue_empty(&sk->sk_receive_queue) ||
1141 (flags & MSG_WAITALL)) && /* and more is ready or required */ 1166 (sz_copied < target)) && /* and more is ready or required */
1142 (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */ 1167 (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */
1143 (!err)) /* and haven't reached a FIN */ 1168 (!err)) /* and haven't reached a FIN */
1144 goto restart; 1169 goto restart;
@@ -1174,7 +1199,7 @@ static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base)
1174 if (msg_connected(msg)) 1199 if (msg_connected(msg))
1175 threshold *= 4; 1200 threshold *= 4;
1176 1201
1177 return (queue_size >= threshold); 1202 return queue_size >= threshold;
1178} 1203}
1179 1204
1180/** 1205/**
@@ -1205,42 +1230,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1205 */ 1230 */
1206 1231
1207 if (sock->state == SS_READY) { 1232 if (sock->state == SS_READY) {
1208 if (msg_connected(msg)) { 1233 if (msg_connected(msg))
1209 msg_dbg(msg, "dispatch filter 1\n");
1210 return TIPC_ERR_NO_PORT; 1234 return TIPC_ERR_NO_PORT;
1211 }
1212 } else { 1235 } else {
1213 if (msg_mcast(msg)) { 1236 if (msg_mcast(msg))
1214 msg_dbg(msg, "dispatch filter 2\n");
1215 return TIPC_ERR_NO_PORT; 1237 return TIPC_ERR_NO_PORT;
1216 }
1217 if (sock->state == SS_CONNECTED) { 1238 if (sock->state == SS_CONNECTED) {
1218 if (!msg_connected(msg)) { 1239 if (!msg_connected(msg))
1219 msg_dbg(msg, "dispatch filter 3\n");
1220 return TIPC_ERR_NO_PORT; 1240 return TIPC_ERR_NO_PORT;
1221 } 1241 } else if (sock->state == SS_CONNECTING) {
1222 } 1242 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; 1243 return TIPC_ERR_NO_PORT;
1227 } 1244 } else if (sock->state == SS_LISTENING) {
1228 } 1245 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; 1246 return TIPC_ERR_NO_PORT;
1233 } 1247 } 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; 1248 return TIPC_ERR_NO_PORT;
1238 } 1249 } else /* (sock->state == SS_UNCONNECTED) */ {
1239 else /* (sock->state == SS_UNCONNECTED) */ { 1250 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; 1251 return TIPC_ERR_NO_PORT;
1243 }
1244 } 1252 }
1245 } 1253 }
1246 1254
@@ -1259,8 +1267,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1259 1267
1260 /* Enqueue message (finally!) */ 1268 /* Enqueue message (finally!) */
1261 1269
1262 msg_dbg(msg, "<DISP<: "); 1270 TIPC_SKB_CB(buf)->handle = 0;
1263 TIPC_SKB_CB(buf)->handle = msg_data(msg);
1264 atomic_inc(&tipc_queue_size); 1271 atomic_inc(&tipc_queue_size);
1265 __skb_queue_tail(&sk->sk_receive_queue, buf); 1272 __skb_queue_tail(&sk->sk_receive_queue, buf);
1266 1273
@@ -1365,6 +1372,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1365 struct msghdr m = {NULL,}; 1372 struct msghdr m = {NULL,};
1366 struct sk_buff *buf; 1373 struct sk_buff *buf;
1367 struct tipc_msg *msg; 1374 struct tipc_msg *msg;
1375 long timeout;
1368 int res; 1376 int res;
1369 1377
1370 lock_sock(sk); 1378 lock_sock(sk);
@@ -1379,7 +1387,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1379 /* For now, TIPC does not support the non-blocking form of connect() */ 1387 /* For now, TIPC does not support the non-blocking form of connect() */
1380 1388
1381 if (flags & O_NONBLOCK) { 1389 if (flags & O_NONBLOCK) {
1382 res = -EWOULDBLOCK; 1390 res = -EOPNOTSUPP;
1383 goto exit; 1391 goto exit;
1384 } 1392 }
1385 1393
@@ -1419,17 +1427,17 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1419 m.msg_name = dest; 1427 m.msg_name = dest;
1420 m.msg_namelen = destlen; 1428 m.msg_namelen = destlen;
1421 res = send_msg(NULL, sock, &m, 0); 1429 res = send_msg(NULL, sock, &m, 0);
1422 if (res < 0) { 1430 if (res < 0)
1423 goto exit; 1431 goto exit;
1424 }
1425 1432
1426 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ 1433 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
1427 1434
1435 timeout = tipc_sk(sk)->conn_timeout;
1428 release_sock(sk); 1436 release_sock(sk);
1429 res = wait_event_interruptible_timeout(*sk_sleep(sk), 1437 res = wait_event_interruptible_timeout(*sk_sleep(sk),
1430 (!skb_queue_empty(&sk->sk_receive_queue) || 1438 (!skb_queue_empty(&sk->sk_receive_queue) ||
1431 (sock->state != SS_CONNECTING)), 1439 (sock->state != SS_CONNECTING)),
1432 sk->sk_rcvtimeo); 1440 timeout ? timeout : MAX_SCHEDULE_TIMEOUT);
1433 lock_sock(sk); 1441 lock_sock(sk);
1434 1442
1435 if (res > 0) { 1443 if (res > 0) {
@@ -1442,11 +1450,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1442 advance_rx_queue(sk); 1450 advance_rx_queue(sk);
1443 } 1451 }
1444 } else { 1452 } else {
1445 if (sock->state == SS_CONNECTED) { 1453 if (sock->state == SS_CONNECTED)
1446 res = -EISCONN; 1454 res = -EISCONN;
1447 } else { 1455 else
1448 res = -ECONNREFUSED; 1456 res = -ECONNREFUSED;
1449 }
1450 } 1457 }
1451 } else { 1458 } else {
1452 if (res == 0) 1459 if (res == 0)
@@ -1565,7 +1572,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1565 * Respond to 'SYN+' by queuing it on new socket. 1572 * Respond to 'SYN+' by queuing it on new socket.
1566 */ 1573 */
1567 1574
1568 msg_dbg(msg,"<ACC<: ");
1569 if (!msg_data_sz(msg)) { 1575 if (!msg_data_sz(msg)) {
1570 struct msghdr m = {NULL,}; 1576 struct msghdr m = {NULL,};
1571 1577
@@ -1613,7 +1619,7 @@ restart:
1613 buf = __skb_dequeue(&sk->sk_receive_queue); 1619 buf = __skb_dequeue(&sk->sk_receive_queue);
1614 if (buf) { 1620 if (buf) {
1615 atomic_dec(&tipc_queue_size); 1621 atomic_dec(&tipc_queue_size);
1616 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) { 1622 if (TIPC_SKB_CB(buf)->handle != 0) {
1617 buf_discard(buf); 1623 buf_discard(buf);
1618 goto restart; 1624 goto restart;
1619 } 1625 }
@@ -1673,7 +1679,8 @@ static int setsockopt(struct socket *sock,
1673 return -ENOPROTOOPT; 1679 return -ENOPROTOOPT;
1674 if (ol < sizeof(value)) 1680 if (ol < sizeof(value))
1675 return -EINVAL; 1681 return -EINVAL;
1676 if ((res = get_user(value, (u32 __user *)ov))) 1682 res = get_user(value, (u32 __user *)ov);
1683 if (res)
1677 return res; 1684 return res;
1678 1685
1679 lock_sock(sk); 1686 lock_sock(sk);
@@ -1692,7 +1699,7 @@ static int setsockopt(struct socket *sock,
1692 res = tipc_set_portunreturnable(tport->ref, value); 1699 res = tipc_set_portunreturnable(tport->ref, value);
1693 break; 1700 break;
1694 case TIPC_CONN_TIMEOUT: 1701 case TIPC_CONN_TIMEOUT:
1695 sk->sk_rcvtimeo = msecs_to_jiffies(value); 1702 tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value);
1696 /* no need to set "res", since already 0 at this point */ 1703 /* no need to set "res", since already 0 at this point */
1697 break; 1704 break;
1698 default: 1705 default:
@@ -1731,7 +1738,8 @@ static int getsockopt(struct socket *sock,
1731 return put_user(0, ol); 1738 return put_user(0, ol);
1732 if (lvl != SOL_TIPC) 1739 if (lvl != SOL_TIPC)
1733 return -ENOPROTOOPT; 1740 return -ENOPROTOOPT;
1734 if ((res = get_user(len, ol))) 1741 res = get_user(len, ol);
1742 if (res)
1735 return res; 1743 return res;
1736 1744
1737 lock_sock(sk); 1745 lock_sock(sk);
@@ -1747,13 +1755,13 @@ static int getsockopt(struct socket *sock,
1747 res = tipc_portunreturnable(tport->ref, &value); 1755 res = tipc_portunreturnable(tport->ref, &value);
1748 break; 1756 break;
1749 case TIPC_CONN_TIMEOUT: 1757 case TIPC_CONN_TIMEOUT:
1750 value = jiffies_to_msecs(sk->sk_rcvtimeo); 1758 value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout);
1751 /* no need to set "res", since already 0 at this point */ 1759 /* no need to set "res", since already 0 at this point */
1752 break; 1760 break;
1753 case TIPC_NODE_RECVQ_DEPTH: 1761 case TIPC_NODE_RECVQ_DEPTH:
1754 value = (u32)atomic_read(&tipc_queue_size); 1762 value = (u32)atomic_read(&tipc_queue_size);
1755 break; 1763 break;
1756 case TIPC_SOCK_RECVQ_DEPTH: 1764 case TIPC_SOCK_RECVQ_DEPTH:
1757 value = skb_queue_len(&sk->sk_receive_queue); 1765 value = skb_queue_len(&sk->sk_receive_queue);
1758 break; 1766 break;
1759 default: 1767 default:
@@ -1762,20 +1770,16 @@ static int getsockopt(struct socket *sock,
1762 1770
1763 release_sock(sk); 1771 release_sock(sk);
1764 1772
1765 if (res) { 1773 if (res)
1766 /* "get" failed */ 1774 return res; /* "get" failed */
1767 }
1768 else if (len < sizeof(value)) {
1769 res = -EINVAL;
1770 }
1771 else if (copy_to_user(ov, &value, sizeof(value))) {
1772 res = -EFAULT;
1773 }
1774 else {
1775 res = put_user(sizeof(value), ol);
1776 }
1777 1775
1778 return res; 1776 if (len < sizeof(value))
1777 return -EINVAL;
1778
1779 if (copy_to_user(ov, &value, sizeof(value)))
1780 return -EFAULT;
1781
1782 return put_user(sizeof(value), ol);
1779} 1783}
1780 1784
1781/** 1785/**
@@ -1783,7 +1787,7 @@ static int getsockopt(struct socket *sock,
1783 */ 1787 */
1784 1788
1785static const struct proto_ops msg_ops = { 1789static const struct proto_ops msg_ops = {
1786 .owner = THIS_MODULE, 1790 .owner = THIS_MODULE,
1787 .family = AF_TIPC, 1791 .family = AF_TIPC,
1788 .release = release, 1792 .release = release,
1789 .bind = bind, 1793 .bind = bind,
@@ -1804,7 +1808,7 @@ static const struct proto_ops msg_ops = {
1804}; 1808};
1805 1809
1806static const struct proto_ops packet_ops = { 1810static const struct proto_ops packet_ops = {
1807 .owner = THIS_MODULE, 1811 .owner = THIS_MODULE,
1808 .family = AF_TIPC, 1812 .family = AF_TIPC,
1809 .release = release, 1813 .release = release,
1810 .bind = bind, 1814 .bind = bind,
@@ -1825,7 +1829,7 @@ static const struct proto_ops packet_ops = {
1825}; 1829};
1826 1830
1827static const struct proto_ops stream_ops = { 1831static const struct proto_ops stream_ops = {
1828 .owner = THIS_MODULE, 1832 .owner = THIS_MODULE,
1829 .family = AF_TIPC, 1833 .family = AF_TIPC,
1830 .release = release, 1834 .release = release,
1831 .bind = bind, 1835 .bind = bind,
@@ -1846,7 +1850,7 @@ static const struct proto_ops stream_ops = {
1846}; 1850};
1847 1851
1848static const struct net_proto_family tipc_family_ops = { 1852static const struct net_proto_family tipc_family_ops = {
1849 .owner = THIS_MODULE, 1853 .owner = THIS_MODULE,
1850 .family = AF_TIPC, 1854 .family = AF_TIPC,
1851 .create = tipc_create 1855 .create = tipc_create
1852}; 1856};
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index ab6eab4c45e2..6cf726863485 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -2,7 +2,7 @@
2 * net/tipc/subscr.c: TIPC network topology service 2 * net/tipc/subscr.c: TIPC network topology service
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -35,10 +35,8 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h"
39#include "name_table.h" 38#include "name_table.h"
40#include "port.h" 39#include "port.h"
41#include "ref.h"
42#include "subscr.h" 40#include "subscr.h"
43 41
44/** 42/**
@@ -66,14 +64,26 @@ 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;
74
75/**
76 * htohl - convert value to endianness used by destination
77 * @in: value to convert
78 * @swap: non-zero if endianness must be reversed
79 *
80 * Returns converted value
81 */
82
83static u32 htohl(u32 in, int swap)
84{
85 return swap ? swab32(in) : in;
86}
77 87
78/** 88/**
79 * subscr_send_event - send a message containing a tipc_event to the subscriber 89 * subscr_send_event - send a message containing a tipc_event to the subscriber
@@ -94,12 +104,12 @@ static void subscr_send_event(struct subscription *sub,
94 msg_sect.iov_base = (void *)&sub->evt; 104 msg_sect.iov_base = (void *)&sub->evt;
95 msg_sect.iov_len = sizeof(struct tipc_event); 105 msg_sect.iov_len = sizeof(struct tipc_event);
96 106
97 sub->evt.event = htonl(event); 107 sub->evt.event = htohl(event, sub->swap);
98 sub->evt.found_lower = htonl(found_lower); 108 sub->evt.found_lower = htohl(found_lower, sub->swap);
99 sub->evt.found_upper = htonl(found_upper); 109 sub->evt.found_upper = htohl(found_upper, sub->swap);
100 sub->evt.port.ref = htonl(port_ref); 110 sub->evt.port.ref = htohl(port_ref, sub->swap);
101 sub->evt.port.node = htonl(node); 111 sub->evt.port.node = htohl(node, sub->swap);
102 tipc_send(sub->server_ref, 1, &msg_sect); 112 tipc_send(sub->server_ref, 1, &msg_sect, msg_sect.iov_len);
103} 113}
104 114
105/** 115/**
@@ -150,7 +160,7 @@ void tipc_subscr_report_overlap(struct subscription *sub,
150 160
151static void subscr_timeout(struct subscription *sub) 161static void subscr_timeout(struct subscription *sub)
152{ 162{
153 struct port *server_port; 163 struct tipc_port *server_port;
154 164
155 /* Validate server port reference (in case subscriber is terminating) */ 165 /* Validate server port reference (in case subscriber is terminating) */
156 166
@@ -239,8 +249,6 @@ static void subscr_terminate(struct subscriber *subscriber)
239 k_cancel_timer(&sub->timer); 249 k_cancel_timer(&sub->timer);
240 k_term_timer(&sub->timer); 250 k_term_timer(&sub->timer);
241 } 251 }
242 dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n",
243 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
244 subscr_del(sub); 252 subscr_del(sub);
245 } 253 }
246 254
@@ -274,29 +282,16 @@ static void subscr_cancel(struct tipc_subscr *s,
274{ 282{
275 struct subscription *sub; 283 struct subscription *sub;
276 struct subscription *sub_temp; 284 struct subscription *sub_temp;
277 __u32 type, lower, upper, timeout, filter;
278 int found = 0; 285 int found = 0;
279 286
280 /* Find first matching subscription, exit if not found */ 287 /* Find first matching subscription, exit if not found */
281 288
282 type = ntohl(s->seq.type);
283 lower = ntohl(s->seq.lower);
284 upper = ntohl(s->seq.upper);
285 timeout = ntohl(s->timeout);
286 filter = ntohl(s->filter) & ~TIPC_SUB_CANCEL;
287
288 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, 289 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
289 subscription_list) { 290 subscription_list) {
290 if ((type == sub->seq.type) && 291 if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
291 (lower == sub->seq.lower) && 292 found = 1;
292 (upper == sub->seq.upper) && 293 break;
293 (timeout == sub->timeout) && 294 }
294 (filter == sub->filter) &&
295 !memcmp(s->usr_handle,sub->evt.s.usr_handle,
296 sizeof(s->usr_handle)) ){
297 found = 1;
298 break;
299 }
300 } 295 }
301 if (!found) 296 if (!found)
302 return; 297 return;
@@ -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 %p 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
@@ -325,10 +318,16 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
325 struct subscriber *subscriber) 318 struct subscriber *subscriber)
326{ 319{
327 struct subscription *sub; 320 struct subscription *sub;
321 int swap;
322
323 /* Determine subscriber's endianness */
324
325 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
328 326
329 /* Detect & process a subscription cancellation request */ 327 /* Detect & process a subscription cancellation request */
330 328
331 if (ntohl(s->filter) & TIPC_SUB_CANCEL) { 329 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
330 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
332 subscr_cancel(s, subscriber); 331 subscr_cancel(s, subscriber);
333 return NULL; 332 return NULL;
334 } 333 }
@@ -353,12 +352,13 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
353 352
354 /* Initialize subscription object */ 353 /* Initialize subscription object */
355 354
356 sub->seq.type = ntohl(s->seq.type); 355 sub->seq.type = htohl(s->seq.type, swap);
357 sub->seq.lower = ntohl(s->seq.lower); 356 sub->seq.lower = htohl(s->seq.lower, swap);
358 sub->seq.upper = ntohl(s->seq.upper); 357 sub->seq.upper = htohl(s->seq.upper, swap);
359 sub->timeout = ntohl(s->timeout); 358 sub->timeout = htohl(s->timeout, swap);
360 sub->filter = ntohl(s->filter); 359 sub->filter = htohl(s->filter, swap);
361 if ((sub->filter && (sub->filter != TIPC_SUB_PORTS)) || 360 if ((!(sub->filter & TIPC_SUB_PORTS) ==
361 !(sub->filter & TIPC_SUB_SERVICE)) ||
362 (sub->seq.lower > sub->seq.upper)) { 362 (sub->seq.lower > sub->seq.upper)) {
363 warn("Subscription rejected, illegal request\n"); 363 warn("Subscription rejected, illegal request\n");
364 kfree(sub); 364 kfree(sub);
@@ -369,6 +369,7 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
369 INIT_LIST_HEAD(&sub->nameseq_list); 369 INIT_LIST_HEAD(&sub->nameseq_list);
370 list_add(&sub->subscription_list, &subscriber->subscription_list); 370 list_add(&sub->subscription_list, &subscriber->subscription_list);
371 sub->server_ref = subscriber->port_ref; 371 sub->server_ref = subscriber->port_ref;
372 sub->swap = swap;
372 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); 373 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
373 atomic_inc(&topsrv.subscription_count); 374 atomic_inc(&topsrv.subscription_count);
374 if (sub->timeout != TIPC_WAIT_FOREVER) { 375 if (sub->timeout != TIPC_WAIT_FOREVER) {
@@ -471,8 +472,6 @@ static void subscr_named_msg_event(void *usr_handle,
471 struct tipc_portid const *orig, 472 struct tipc_portid const *orig,
472 struct tipc_name_seq const *dest) 473 struct tipc_name_seq const *dest)
473{ 474{
474 static struct iovec msg_sect = {NULL, 0};
475
476 struct subscriber *subscriber; 475 struct subscriber *subscriber;
477 u32 server_port_ref; 476 u32 server_port_ref;
478 477
@@ -488,8 +487,7 @@ static void subscr_named_msg_event(void *usr_handle,
488 487
489 /* Create server port & establish connection to subscriber */ 488 /* Create server port & establish connection to subscriber */
490 489
491 tipc_createport(topsrv.user_ref, 490 tipc_createport(subscriber,
492 subscriber,
493 importance, 491 importance,
494 NULL, 492 NULL,
495 NULL, 493 NULL,
@@ -508,7 +506,7 @@ static void subscr_named_msg_event(void *usr_handle,
508 506
509 /* Lock server port (& save lock address for future use) */ 507 /* Lock server port (& save lock address for future use) */
510 508
511 subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock; 509 subscriber->lock = tipc_port_lock(subscriber->port_ref)->lock;
512 510
513 /* Add subscriber to topology server's subscriber list */ 511 /* Add subscriber to topology server's subscriber list */
514 512
@@ -523,7 +521,7 @@ static void subscr_named_msg_event(void *usr_handle,
523 521
524 /* Send an ACK- to complete connection handshaking */ 522 /* Send an ACK- to complete connection handshaking */
525 523
526 tipc_send(server_port_ref, 1, &msg_sect); 524 tipc_send(server_port_ref, 0, NULL, 0);
527 525
528 /* Handle optional subscription request */ 526 /* Handle optional subscription request */
529 527
@@ -536,21 +534,13 @@ static void subscr_named_msg_event(void *usr_handle,
536int tipc_subscr_start(void) 534int tipc_subscr_start(void)
537{ 535{
538 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV}; 536 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV};
539 int res = -1; 537 int res;
540 538
541 memset(&topsrv, 0, sizeof (topsrv)); 539 memset(&topsrv, 0, sizeof(topsrv));
542 spin_lock_init(&topsrv.lock); 540 spin_lock_init(&topsrv.lock);
543 INIT_LIST_HEAD(&topsrv.subscriber_list); 541 INIT_LIST_HEAD(&topsrv.subscriber_list);
544 542
545 spin_lock_bh(&topsrv.lock); 543 res = tipc_createport(NULL,
546 res = tipc_attach(&topsrv.user_ref, NULL, NULL);
547 if (res) {
548 spin_unlock_bh(&topsrv.lock);
549 return res;
550 }
551
552 res = tipc_createport(topsrv.user_ref,
553 NULL,
554 TIPC_CRITICAL_IMPORTANCE, 544 TIPC_CRITICAL_IMPORTANCE,
555 NULL, 545 NULL,
556 NULL, 546 NULL,
@@ -564,17 +554,16 @@ int tipc_subscr_start(void)
564 goto failed; 554 goto failed;
565 555
566 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq); 556 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
567 if (res) 557 if (res) {
558 tipc_deleteport(topsrv.setup_port);
559 topsrv.setup_port = 0;
568 goto failed; 560 goto failed;
561 }
569 562
570 spin_unlock_bh(&topsrv.lock);
571 return 0; 563 return 0;
572 564
573failed: 565failed:
574 err("Failed to create subscription service\n"); 566 err("Failed to create subscription service\n");
575 tipc_detach(topsrv.user_ref);
576 topsrv.user_ref = 0;
577 spin_unlock_bh(&topsrv.lock);
578 return res; 567 return res;
579} 568}
580 569
@@ -584,8 +573,10 @@ void tipc_subscr_stop(void)
584 struct subscriber *subscriber_temp; 573 struct subscriber *subscriber_temp;
585 spinlock_t *subscriber_lock; 574 spinlock_t *subscriber_lock;
586 575
587 if (topsrv.user_ref) { 576 if (topsrv.setup_port) {
588 tipc_deleteport(topsrv.setup_port); 577 tipc_deleteport(topsrv.setup_port);
578 topsrv.setup_port = 0;
579
589 list_for_each_entry_safe(subscriber, subscriber_temp, 580 list_for_each_entry_safe(subscriber, subscriber_temp,
590 &topsrv.subscriber_list, 581 &topsrv.subscriber_list,
591 subscriber_list) { 582 subscriber_list) {
@@ -594,16 +585,5 @@ void tipc_subscr_stop(void)
594 subscr_terminate(subscriber); 585 subscr_terminate(subscriber);
595 spin_unlock_bh(subscriber_lock); 586 spin_unlock_bh(subscriber_lock);
596 } 587 }
597 tipc_detach(topsrv.user_ref);
598 topsrv.user_ref = 0;
599 } 588 }
600} 589}
601
602
603int tipc_ispublished(struct tipc_name const *name)
604{
605 u32 domain = 0;
606
607 return(tipc_nametbl_translate(name->type, name->instance,&domain) != 0);
608}
609
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index c20f496d95b2..45d89bf4d202 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -53,6 +53,7 @@ typedef void (*tipc_subscr_event) (struct subscription *sub,
53 * @nameseq_list: adjacent subscriptions in name sequence's subscription list 53 * @nameseq_list: adjacent subscriptions in name sequence's subscription list
54 * @subscription_list: adjacent subscriptions in subscriber's subscription list 54 * @subscription_list: adjacent subscriptions in subscriber's subscription list
55 * @server_ref: object reference of server port associated with subscription 55 * @server_ref: object reference of server port associated with subscription
56 * @swap: indicates if subscriber uses opposite endianness in its messages
56 * @evt: template for events generated by subscription 57 * @evt: template for events generated by subscription
57 */ 58 */
58 59
@@ -65,6 +66,7 @@ struct subscription {
65 struct list_head nameseq_list; 66 struct list_head nameseq_list;
66 struct list_head subscription_list; 67 struct list_head subscription_list;
67 u32 server_ref; 68 u32 server_ref;
69 int swap;
68 struct tipc_event evt; 70 struct tipc_event evt;
69}; 71};
70 72
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