aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Stephens <Allan.Stephens@windriver.com>2010-12-31 13:59:18 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-01 16:57:48 -0500
commit51a8e4dee7653698ba4c6e7de71053665f075273 (patch)
tree94d90bd650f0dd8ab542cc5c948d6ddf6501a107
parent08c80e9a031df0a8f0269477a32f5eae47d7a146 (diff)
tipc: Remove prototype code for supporting inter-cluster routing
Eliminates routines and data structures that were intended to allow TIPC to route messages to other clusters. Currently, TIPC supports only networks consisting of a single cluster within a single zone, so this code is unnecessary. Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/tipc_config.h5
-rw-r--r--net/tipc/addr.h15
-rw-r--r--net/tipc/cluster.c279
-rw-r--r--net/tipc/cluster.h8
-rw-r--r--net/tipc/link.c13
-rw-r--r--net/tipc/msg.h7
-rw-r--r--net/tipc/net.c45
-rw-r--r--net/tipc/net.h4
-rw-r--r--net/tipc/node.c166
-rw-r--r--net/tipc/node.h21
10 files changed, 15 insertions, 548 deletions
diff --git a/include/linux/tipc_config.h b/include/linux/tipc_config.h
index dcc2b8796d0a..1f38df1202ba 100644
--- a/include/linux/tipc_config.h
+++ b/include/linux/tipc_config.h
@@ -254,11 +254,6 @@ struct tipc_link_create {
254 struct tipc_media_addr peer_addr; 254 struct tipc_media_addr peer_addr;
255 char bearer_name[TIPC_MAX_BEARER_NAME]; 255 char bearer_name[TIPC_MAX_BEARER_NAME];
256}; 256};
257
258struct tipc_route_info {
259 __u32 dest;
260 __u32 router;
261};
262#endif 257#endif
263 258
264/* 259/*
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index a16c6c87208e..2490fadd0caf 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,21 +37,6 @@
37#ifndef _TIPC_ADDR_H 37#ifndef _TIPC_ADDR_H
38#define _TIPC_ADDR_H 38#define _TIPC_ADDR_H
39 39
40static inline u32 own_node(void)
41{
42 return tipc_node(tipc_own_addr);
43}
44
45static inline u32 own_cluster(void)
46{
47 return tipc_cluster(tipc_own_addr);
48}
49
50static inline u32 own_zone(void)
51{
52 return tipc_zone(tipc_own_addr);
53}
54
55static inline int in_own_cluster(u32 addr) 40static inline int in_own_cluster(u32 addr)
56{ 41{
57 return !((addr ^ tipc_own_addr) >> 12); 42 return !((addr ^ tipc_own_addr) >> 12);
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
index 6bc9f07be945..ba6f5bfa0cdb 100644
--- a/net/tipc/cluster.c
+++ b/net/tipc/cluster.c
@@ -38,9 +38,6 @@
38#include "cluster.h" 38#include "cluster.h"
39#include "link.h" 39#include "link.h"
40 40
41static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
42 u32 lower, u32 upper);
43
44struct tipc_node **tipc_local_nodes = NULL; 41struct tipc_node **tipc_local_nodes = NULL;
45struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}}; 42struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}};
46 43
@@ -65,8 +62,7 @@ struct cluster *tipc_cltr_create(u32 addr)
65 return NULL; 62 return NULL;
66 } 63 }
67 64
68 if (in_own_cluster(addr)) 65 tipc_local_nodes = c_ptr->nodes;
69 tipc_local_nodes = c_ptr->nodes;
70 c_ptr->highest_node = 0; 66 c_ptr->highest_node = 0;
71 67
72 tipc_net.clusters[1] = c_ptr; 68 tipc_net.clusters[1] = c_ptr;
@@ -101,278 +97,6 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr)
101} 97}
102 98
103/** 99/**
104 * tipc_cltr_select_router - select router to a cluster
105 *
106 * Uses deterministic and fair algorithm.
107 */
108
109u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref)
110{
111 u32 n_num;
112 u32 ulim = c_ptr->highest_node;
113 u32 mask;
114 u32 tstart;
115
116 assert(!in_own_cluster(c_ptr->addr));
117 if (!ulim)
118 return 0;
119
120 /* Start entry must be random */
121 mask = tipc_max_nodes;
122 while (mask > ulim)
123 mask >>= 1;
124 tstart = ref & mask;
125 n_num = tstart;
126
127 /* Lookup upwards with wrap-around */
128 do {
129 if (tipc_node_is_up(c_ptr->nodes[n_num]))
130 break;
131 } while (++n_num <= ulim);
132 if (n_num > ulim) {
133 n_num = 1;
134 do {
135 if (tipc_node_is_up(c_ptr->nodes[n_num]))
136 break;
137 } while (++n_num < tstart);
138 if (n_num == tstart)
139 return 0;
140 }
141 assert(n_num <= ulim);
142 return tipc_node_select_router(c_ptr->nodes[n_num], ref);
143}
144
145/**
146 * tipc_cltr_select_node - select destination node within a remote cluster
147 *
148 * Uses deterministic and fair algorithm.
149 */
150
151struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
152{
153 u32 n_num;
154 u32 mask = tipc_max_nodes;
155 u32 start_entry;
156
157 assert(!in_own_cluster(c_ptr->addr));
158 if (!c_ptr->highest_node)
159 return NULL;
160
161 /* Start entry must be random */
162 while (mask > c_ptr->highest_node) {
163 mask >>= 1;
164 }
165 start_entry = (selector & mask) ? selector & mask : 1u;
166 assert(start_entry <= c_ptr->highest_node);
167
168 /* Lookup upwards with wrap-around */
169 for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) {
170 if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
171 return c_ptr->nodes[n_num];
172 }
173 for (n_num = 1; n_num < start_entry; n_num++) {
174 if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
175 return c_ptr->nodes[n_num];
176 }
177 return NULL;
178}
179
180/*
181 * Routing table management: See description in node.c
182 */
183
184static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
185{
186 u32 size = INT_H_SIZE + data_size;
187 struct sk_buff *buf = tipc_buf_acquire(size);
188 struct tipc_msg *msg;
189
190 if (buf) {
191 msg = buf_msg(buf);
192 memset((char *)msg, 0, size);
193 tipc_msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest);
194 }
195 return buf;
196}
197
198void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest,
199 u32 lower, u32 upper)
200{
201 struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
202 struct tipc_msg *msg;
203
204 if (buf) {
205 msg = buf_msg(buf);
206 msg_set_remote_node(msg, dest);
207 msg_set_type(msg, ROUTE_ADDITION);
208 tipc_cltr_multicast(c_ptr, buf, lower, upper);
209 } else {
210 warn("Memory squeeze: broadcast of new route failed\n");
211 }
212}
213
214void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest,
215 u32 lower, u32 upper)
216{
217 struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
218 struct tipc_msg *msg;
219
220 if (buf) {
221 msg = buf_msg(buf);
222 msg_set_remote_node(msg, dest);
223 msg_set_type(msg, ROUTE_REMOVAL);
224 tipc_cltr_multicast(c_ptr, buf, lower, upper);
225 } else {
226 warn("Memory squeeze: broadcast of lost route failed\n");
227 }
228}
229
230void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest)
231{
232 struct sk_buff *buf;
233 struct tipc_msg *msg;
234 u32 highest = c_ptr->highest_node;
235 u32 n_num;
236 int send = 0;
237
238 if (in_own_cluster(c_ptr->addr))
239 return;
240 assert(in_own_cluster(dest));
241 highest = c_ptr->highest_node;
242 buf = tipc_cltr_prepare_routing_msg(highest + 1, c_ptr->addr);
243 if (buf) {
244 msg = buf_msg(buf);
245 msg_set_remote_node(msg, c_ptr->addr);
246 msg_set_type(msg, EXT_ROUTING_TABLE);
247 for (n_num = 1; n_num <= highest; n_num++) {
248 if (c_ptr->nodes[n_num] &&
249 tipc_node_has_active_links(c_ptr->nodes[n_num])) {
250 send = 1;
251 msg_set_dataoctet(msg, n_num);
252 }
253 }
254 if (send)
255 tipc_link_send(buf, dest, dest);
256 else
257 buf_discard(buf);
258 } else {
259 warn("Memory squeeze: broadcast of external route failed\n");
260 }
261}
262
263void tipc_cltr_recv_routing_table(struct sk_buff *buf)
264{
265 struct tipc_msg *msg = buf_msg(buf);
266 struct cluster *c_ptr;
267 struct tipc_node *n_ptr;
268 unchar *node_table;
269 u32 table_size;
270 u32 router;
271 u32 rem_node = msg_remote_node(msg);
272 u32 z_num;
273 u32 c_num;
274 u32 n_num;
275
276 c_ptr = tipc_cltr_find(rem_node);
277 if (!c_ptr) {
278 c_ptr = tipc_cltr_create(rem_node);
279 if (!c_ptr) {
280 buf_discard(buf);
281 return;
282 }
283 }
284
285 node_table = buf->data + msg_hdr_sz(msg);
286 table_size = msg_size(msg) - msg_hdr_sz(msg);
287 router = msg_prevnode(msg);
288 z_num = tipc_zone(rem_node);
289 c_num = tipc_cluster(rem_node);
290
291 switch (msg_type(msg)) {
292 case EXT_ROUTING_TABLE:
293 for (n_num = 1; n_num < table_size; n_num++) {
294 if (node_table[n_num]) {
295 u32 addr = tipc_addr(z_num, c_num, n_num);
296 n_ptr = c_ptr->nodes[n_num];
297 if (!n_ptr) {
298 n_ptr = tipc_node_create(addr);
299 }
300 if (n_ptr)
301 tipc_node_add_router(n_ptr, router);
302 }
303 }
304 break;
305 case SLAVE_ROUTING_TABLE:
306 assert(in_own_cluster(c_ptr->addr));
307 break;
308 case ROUTE_ADDITION:
309 assert(!in_own_cluster(c_ptr->addr));
310 n_ptr = c_ptr->nodes[tipc_node(rem_node)];
311 if (!n_ptr)
312 n_ptr = tipc_node_create(rem_node);
313 if (n_ptr)
314 tipc_node_add_router(n_ptr, router);
315 break;
316 case ROUTE_REMOVAL:
317 assert(!in_own_cluster(c_ptr->addr));
318 n_ptr = c_ptr->nodes[tipc_node(rem_node)];
319 if (n_ptr)
320 tipc_node_remove_router(n_ptr, router);
321 break;
322 default:
323 assert(!"Illegal routing manager message received\n");
324 }
325 buf_discard(buf);
326}
327
328void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router)
329{
330 u32 n_num;
331
332 if (in_own_cluster(c_ptr->addr))
333 return;
334
335 for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) {
336 if (c_ptr->nodes[n_num]) {
337 tipc_node_remove_router(c_ptr->nodes[n_num], router);
338 }
339 }
340}
341
342/**
343 * tipc_cltr_multicast - multicast message to local nodes
344 */
345
346static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
347 u32 lower, u32 upper)
348{
349 struct sk_buff *buf_copy;
350 struct tipc_node *n_ptr;
351 u32 n_num;
352 u32 tstop;
353
354 assert(lower <= upper);
355 assert((lower >= 1) && (lower <= tipc_max_nodes));
356 assert((upper >= 1) && (upper <= tipc_max_nodes));
357 assert(in_own_cluster(c_ptr->addr));
358
359 tstop = c_ptr->highest_node;
360 if (tstop > upper)
361 tstop = upper;
362 for (n_num = lower; n_num <= tstop; n_num++) {
363 n_ptr = c_ptr->nodes[n_num];
364 if (n_ptr && tipc_node_has_active_links(n_ptr)) {
365 buf_copy = skb_copy(buf, GFP_ATOMIC);
366 if (buf_copy == NULL)
367 break;
368 msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
369 tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
370 }
371 }
372 buf_discard(buf);
373}
374
375/**
376 * tipc_cltr_broadcast - broadcast message to all nodes within cluster 100 * tipc_cltr_broadcast - broadcast message to all nodes within cluster
377 */ 101 */
378 102
@@ -385,7 +109,6 @@ void tipc_cltr_broadcast(struct sk_buff *buf)
385 109
386 if (tipc_mode == TIPC_NET_MODE) { 110 if (tipc_mode == TIPC_NET_MODE) {
387 c_ptr = tipc_cltr_find(tipc_own_addr); 111 c_ptr = tipc_cltr_find(tipc_own_addr);
388 assert(in_own_cluster(c_ptr->addr)); /* For now */
389 112
390 /* Send to nodes */ 113 /* Send to nodes */
391 for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { 114 for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) {
diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h
index aa1fd6ab4d11..e4b6e4e27371 100644
--- a/net/tipc/cluster.h
+++ b/net/tipc/cluster.h
@@ -57,20 +57,12 @@ struct cluster {
57extern struct tipc_node **tipc_local_nodes; 57extern struct tipc_node **tipc_local_nodes;
58extern struct tipc_node_map tipc_cltr_bcast_nodes; 58extern struct tipc_node_map tipc_cltr_bcast_nodes;
59 59
60void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router);
61void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest);
62struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector);
63u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref);
64void tipc_cltr_recv_routing_table(struct sk_buff *buf);
65struct cluster *tipc_cltr_create(u32 addr); 60struct cluster *tipc_cltr_create(u32 addr);
66void tipc_cltr_delete(struct cluster *c_ptr); 61void tipc_cltr_delete(struct cluster *c_ptr);
67void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr); 62void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr);
68void tipc_cltr_broadcast(struct sk_buff *buf); 63void tipc_cltr_broadcast(struct sk_buff *buf);
69int tipc_cltr_init(void); 64int tipc_cltr_init(void);
70 65
71void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
72void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
73
74static inline struct cluster *tipc_cltr_find(u32 addr) 66static inline struct cluster *tipc_cltr_find(u32 addr)
75{ 67{
76 if (!in_own_cluster(addr)) 68 if (!in_own_cluster(addr))
diff --git a/net/tipc/link.c b/net/tipc/link.c
index cf414cf05e72..671ffd3c0e53 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1061,7 +1061,7 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
1061 int res = -ELINKCONG; 1061 int res = -ELINKCONG;
1062 1062
1063 read_lock_bh(&tipc_net_lock); 1063 read_lock_bh(&tipc_net_lock);
1064 n_ptr = tipc_node_select(dest, selector); 1064 n_ptr = tipc_node_find(dest);
1065 if (n_ptr) { 1065 if (n_ptr) {
1066 tipc_node_lock(n_ptr); 1066 tipc_node_lock(n_ptr);
1067 l_ptr = n_ptr->active_links[selector & 1]; 1067 l_ptr = n_ptr->active_links[selector & 1];
@@ -1137,7 +1137,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1137 return tipc_port_recv_msg(buf); 1137 return tipc_port_recv_msg(buf);
1138 1138
1139 read_lock_bh(&tipc_net_lock); 1139 read_lock_bh(&tipc_net_lock);
1140 n_ptr = tipc_node_select(destnode, selector); 1140 n_ptr = tipc_node_find(destnode);
1141 if (likely(n_ptr)) { 1141 if (likely(n_ptr)) {
1142 tipc_node_lock(n_ptr); 1142 tipc_node_lock(n_ptr);
1143 l_ptr = n_ptr->active_links[selector]; 1143 l_ptr = n_ptr->active_links[selector];
@@ -1186,7 +1186,7 @@ again:
1186 !sender->user_port, &buf); 1186 !sender->user_port, &buf);
1187 1187
1188 read_lock_bh(&tipc_net_lock); 1188 read_lock_bh(&tipc_net_lock);
1189 node = tipc_node_select(destaddr, selector); 1189 node = tipc_node_find(destaddr);
1190 if (likely(node)) { 1190 if (likely(node)) {
1191 tipc_node_lock(node); 1191 tipc_node_lock(node);
1192 l_ptr = node->active_links[selector]; 1192 l_ptr = node->active_links[selector];
@@ -1376,7 +1376,7 @@ error:
1376 * Now we have a buffer chain. Select a link and check 1376 * Now we have a buffer chain. Select a link and check
1377 * that packet size is still OK 1377 * that packet size is still OK
1378 */ 1378 */
1379 node = tipc_node_select(destaddr, sender->publ.ref & 1); 1379 node = tipc_node_find(destaddr);
1380 if (likely(node)) { 1380 if (likely(node)) {
1381 tipc_node_lock(node); 1381 tipc_node_lock(node);
1382 l_ptr = node->active_links[sender->publ.ref & 1]; 1382 l_ptr = node->active_links[sender->publ.ref & 1];
@@ -1893,7 +1893,7 @@ deliver:
1893 continue; 1893 continue;
1894 case ROUTE_DISTRIBUTOR: 1894 case ROUTE_DISTRIBUTOR:
1895 tipc_node_unlock(n_ptr); 1895 tipc_node_unlock(n_ptr);
1896 tipc_cltr_recv_routing_table(buf); 1896 buf_discard(buf);
1897 continue; 1897 continue;
1898 case NAME_DISTRIBUTOR: 1898 case NAME_DISTRIBUTOR:
1899 tipc_node_unlock(n_ptr); 1899 tipc_node_unlock(n_ptr);
@@ -2852,7 +2852,6 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
2852 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900; 2852 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900;
2853 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200; 2853 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200;
2854 l_ptr->queue_limit[CONN_MANAGER] = 1200; 2854 l_ptr->queue_limit[CONN_MANAGER] = 1200;
2855 l_ptr->queue_limit[ROUTE_DISTRIBUTOR] = 1200;
2856 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500; 2855 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500;
2857 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000; 2856 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000;
2858 /* FRAGMENT and LAST_FRAGMENT packets */ 2857 /* FRAGMENT and LAST_FRAGMENT packets */
@@ -3154,7 +3153,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
3154 return MAX_MSG_SIZE; 3153 return MAX_MSG_SIZE;
3155 3154
3156 read_lock_bh(&tipc_net_lock); 3155 read_lock_bh(&tipc_net_lock);
3157 n_ptr = tipc_node_select(dest, selector); 3156 n_ptr = tipc_node_find(dest);
3158 if (n_ptr) { 3157 if (n_ptr) {
3159 tipc_node_lock(n_ptr); 3158 tipc_node_lock(n_ptr);
3160 l_ptr = n_ptr->active_links[selector & 1]; 3159 l_ptr = n_ptr->active_links[selector & 1];
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index c1b6217838e6..68b65ef3e74b 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -540,7 +540,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
540#define MSG_BUNDLER 6 540#define MSG_BUNDLER 6
541#define LINK_PROTOCOL 7 541#define LINK_PROTOCOL 7
542#define CONN_MANAGER 8 542#define CONN_MANAGER 8
543#define ROUTE_DISTRIBUTOR 9 543#define ROUTE_DISTRIBUTOR 9 /* obsoleted */
544#define CHANGEOVER_PROTOCOL 10 544#define CHANGEOVER_PROTOCOL 10
545#define NAME_DISTRIBUTOR 11 545#define NAME_DISTRIBUTOR 11
546#define MSG_FRAGMENTER 12 546#define MSG_FRAGMENTER 12
@@ -819,11 +819,6 @@ static inline void msg_set_remote_node(struct tipc_msg *m, u32 a)
819 msg_set_word(m, msg_hdr_sz(m)/4, a); 819 msg_set_word(m, msg_hdr_sz(m)/4, a);
820} 820}
821 821
822static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
823{
824 msg_data(m)[pos + 4] = 1;
825}
826
827/* 822/*
828 * Segmentation message types 823 * Segmentation message types
829 */ 824 */
diff --git a/net/tipc/net.c b/net/tipc/net.c
index a25f8bb1e1d9..3967f1f6d97f 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -112,48 +112,6 @@
112DEFINE_RWLOCK(tipc_net_lock); 112DEFINE_RWLOCK(tipc_net_lock);
113struct network tipc_net; 113struct network tipc_net;
114 114
115struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref)
116{
117 struct cluster *c_ptr;
118
119 c_ptr = tipc_net.clusters[1];
120 if (!c_ptr)
121 return NULL;
122 return tipc_cltr_select_node(c_ptr, ref);
123}
124
125u32 tipc_net_select_router(u32 addr, u32 ref)
126{
127 struct cluster *c_ptr;
128
129 c_ptr = tipc_net.clusters[1];
130 if (!c_ptr)
131 return 0;
132 return tipc_cltr_select_router(c_ptr, ref);
133}
134
135void tipc_net_remove_as_router(u32 router)
136{
137 u32 c_num;
138
139 for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
140 if (!tipc_net.clusters[c_num])
141 continue;
142 tipc_cltr_remove_as_router(tipc_net.clusters[c_num], router);
143 }
144}
145
146void tipc_net_send_external_routes(u32 dest)
147{
148 u32 c_num;
149
150 for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
151 if (tipc_net.clusters[c_num])
152 tipc_cltr_send_ext_routes(tipc_net.clusters[c_num],
153 dest);
154 }
155}
156
157static void net_stop(void) 115static void net_stop(void)
158{ 116{
159 u32 c_num; 117 u32 c_num;
@@ -225,9 +183,6 @@ void tipc_net_route_msg(struct sk_buff *buf)
225 return; 183 return;
226 } 184 }
227 switch (msg_user(msg)) { 185 switch (msg_user(msg)) {
228 case ROUTE_DISTRIBUTOR:
229 tipc_cltr_recv_routing_table(buf);
230 break;
231 case NAME_DISTRIBUTOR: 186 case NAME_DISTRIBUTOR:
232 tipc_named_recv(buf); 187 tipc_named_recv(buf);
233 break; 188 break;
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 786c94007470..6e402d9b33e0 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -54,11 +54,7 @@ struct network {
54extern struct network tipc_net; 54extern struct network tipc_net;
55extern rwlock_t tipc_net_lock; 55extern rwlock_t tipc_net_lock;
56 56
57void tipc_net_remove_as_router(u32 router);
58void tipc_net_send_external_routes(u32 dest);
59void tipc_net_route_msg(struct sk_buff *buf); 57void tipc_net_route_msg(struct sk_buff *buf);
60struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref);
61u32 tipc_net_select_router(u32 addr, u32 ref);
62 58
63int tipc_net_start(u32 addr); 59int tipc_net_start(u32 addr);
64void tipc_net_stop(void); 60void tipc_net_stop(void);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 8ffbdb33b2cb..c47cc69eb575 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -95,11 +95,10 @@ struct tipc_node *tipc_node_create(u32 addr)
95 } 95 }
96 96
97 n_ptr->addr = addr; 97 n_ptr->addr = addr;
98 spin_lock_init(&n_ptr->lock); 98 spin_lock_init(&n_ptr->lock);
99 INIT_LIST_HEAD(&n_ptr->nsub); 99 INIT_LIST_HEAD(&n_ptr->nsub);
100 n_ptr->owner = c_ptr; 100 n_ptr->owner = c_ptr;
101 tipc_cltr_attach_node(c_ptr, n_ptr); 101 tipc_cltr_attach_node(c_ptr, n_ptr);
102 n_ptr->last_router = -1;
103 102
104 /* Insert node into ordered list */ 103 /* Insert node into ordered list */
105 for (curr_node = &tipc_nodes; *curr_node; 104 for (curr_node = &tipc_nodes; *curr_node;
@@ -229,14 +228,9 @@ int tipc_node_has_redundant_links(struct tipc_node *n_ptr)
229 return n_ptr->working_links > 1; 228 return n_ptr->working_links > 1;
230} 229}
231 230
232static int tipc_node_has_active_routes(struct tipc_node *n_ptr)
233{
234 return n_ptr && (n_ptr->last_router >= 0);
235}
236
237int tipc_node_is_up(struct tipc_node *n_ptr) 231int tipc_node_is_up(struct tipc_node *n_ptr)
238{ 232{
239 return tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr); 233 return tipc_node_has_active_links(n_ptr);
240} 234}
241 235
242struct tipc_node *tipc_node_attach_link(struct link *l_ptr) 236struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
@@ -323,36 +317,17 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
323 317
324static void node_established_contact(struct tipc_node *n_ptr) 318static void node_established_contact(struct tipc_node *n_ptr)
325{ 319{
326 struct cluster *c_ptr;
327
328 dbg("node_established_contact:-> %x\n", n_ptr->addr); 320 dbg("node_established_contact:-> %x\n", n_ptr->addr);
329 if (!tipc_node_has_active_routes(n_ptr) && in_own_cluster(n_ptr->addr)) { 321 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
330 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
331 }
332 322
333 /* Syncronize broadcast acks */ 323 /* Syncronize broadcast acks */
334 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 324 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
335 325
336 if (!in_own_cluster(n_ptr->addr)) {
337 /* Usage case 1 (see above) */
338 c_ptr = tipc_cltr_find(tipc_own_addr);
339 if (!c_ptr)
340 c_ptr = tipc_cltr_create(tipc_own_addr);
341 if (c_ptr)
342 tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1,
343 tipc_max_nodes);
344 return;
345 }
346
347 c_ptr = n_ptr->owner;
348 if (n_ptr->bclink.supported) { 326 if (n_ptr->bclink.supported) {
349 tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr); 327 tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr);
350 if (n_ptr->addr < tipc_own_addr) 328 if (n_ptr->addr < tipc_own_addr)
351 tipc_own_tag++; 329 tipc_own_tag++;
352 } 330 }
353
354 /* Case 3 (see above) */
355 tipc_net_send_external_routes(n_ptr->addr);
356} 331}
357 332
358static void node_cleanup_finished(unsigned long node_addr) 333static void node_cleanup_finished(unsigned long node_addr)
@@ -371,7 +346,6 @@ static void node_cleanup_finished(unsigned long node_addr)
371 346
372static void node_lost_contact(struct tipc_node *n_ptr) 347static void node_lost_contact(struct tipc_node *n_ptr)
373{ 348{
374 struct cluster *c_ptr;
375 struct tipc_node_subscr *ns, *tns; 349 struct tipc_node_subscr *ns, *tns;
376 char addr_string[16]; 350 char addr_string[16];
377 u32 i; 351 u32 i;
@@ -392,23 +366,11 @@ static void node_lost_contact(struct tipc_node *n_ptr)
392 } 366 }
393 367
394 /* Update routing tables */ 368 /* Update routing tables */
395 if (!in_own_cluster(n_ptr->addr)) { 369 if (n_ptr->bclink.supported) {
396 /* Case 4 (see above) */ 370 tipc_nmap_remove(&tipc_cltr_bcast_nodes, n_ptr->addr);
397 c_ptr = tipc_cltr_find(tipc_own_addr); 371 if (n_ptr->addr < tipc_own_addr)
398 tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1, 372 tipc_own_tag--;
399 tipc_max_nodes);
400 } else {
401 /* Case 5 (see above) */
402 c_ptr = tipc_cltr_find(n_ptr->addr);
403 if (n_ptr->bclink.supported) {
404 tipc_nmap_remove(&tipc_cltr_bcast_nodes, n_ptr->addr);
405 if (n_ptr->addr < tipc_own_addr)
406 tipc_own_tag--;
407 }
408 tipc_net_remove_as_router(n_ptr->addr);
409 } 373 }
410 if (tipc_node_has_active_routes(n_ptr))
411 return;
412 374
413 info("Lost contact with %s\n", 375 info("Lost contact with %s\n",
414 tipc_addr_string_fill(addr_string, n_ptr->addr)); 376 tipc_addr_string_fill(addr_string, n_ptr->addr));
@@ -437,120 +399,6 @@ static void node_lost_contact(struct tipc_node *n_ptr)
437 tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr); 399 tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);
438} 400}
439 401
440/**
441 * tipc_node_select_next_hop - find the next-hop node for a message
442 *
443 * Called by when cluster local lookup has failed.
444 */
445
446struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector)
447{
448 struct tipc_node *n_ptr;
449 u32 router_addr;
450
451 if (!tipc_addr_domain_valid(addr))
452 return NULL;
453
454 /* Look for direct link to destination processsor */
455 n_ptr = tipc_node_find(addr);
456 if (n_ptr && tipc_node_has_active_links(n_ptr))
457 return n_ptr;
458
459 /* Cluster local system nodes *must* have direct links */
460 if (in_own_cluster(addr))
461 return NULL;
462
463 /* Look for cluster local router with direct link to node */
464 router_addr = tipc_node_select_router(n_ptr, selector);
465 if (router_addr)
466 return tipc_node_select(router_addr, selector);
467
468 /* Inter zone/cluster -- find any direct link to remote cluster */
469 addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
470 n_ptr = tipc_net_select_remote_node(addr, selector);
471 if (n_ptr && tipc_node_has_active_links(n_ptr))
472 return n_ptr;
473
474 /* Last resort -- look for any router to anywhere in remote zone */
475 router_addr = tipc_net_select_router(addr, selector);
476 if (router_addr)
477 return tipc_node_select(router_addr, selector);
478
479 return NULL;
480}
481
482/**
483 * tipc_node_select_router - select router to reach specified node
484 *
485 * Uses a deterministic and fair algorithm for selecting router node.
486 */
487
488u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref)
489{
490 u32 ulim;
491 u32 mask;
492 u32 start;
493 u32 r;
494
495 if (!n_ptr)
496 return 0;
497
498 if (n_ptr->last_router < 0)
499 return 0;
500 ulim = ((n_ptr->last_router + 1) * 32) - 1;
501
502 /* Start entry must be random */
503 mask = tipc_max_nodes;
504 while (mask > ulim)
505 mask >>= 1;
506 start = ref & mask;
507 r = start;
508
509 /* Lookup upwards with wrap-around */
510 do {
511 if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1)
512 break;
513 } while (++r <= ulim);
514 if (r > ulim) {
515 r = 1;
516 do {
517 if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1)
518 break;
519 } while (++r < start);
520 assert(r != start);
521 }
522 assert(r && (r <= ulim));
523 return tipc_addr(own_zone(), own_cluster(), r);
524}
525
526void tipc_node_add_router(struct tipc_node *n_ptr, u32 router)
527{
528 u32 r_num = tipc_node(router);
529
530 n_ptr->routers[r_num / 32] =
531 ((1 << (r_num % 32)) | n_ptr->routers[r_num / 32]);
532 n_ptr->last_router = tipc_max_nodes / 32;
533 while ((--n_ptr->last_router >= 0) &&
534 !n_ptr->routers[n_ptr->last_router]);
535}
536
537void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router)
538{
539 u32 r_num = tipc_node(router);
540
541 if (n_ptr->last_router < 0)
542 return; /* No routes */
543
544 n_ptr->routers[r_num / 32] =
545 ((~(1 << (r_num % 32))) & (n_ptr->routers[r_num / 32]));
546 n_ptr->last_router = tipc_max_nodes / 32;
547 while ((--n_ptr->last_router >= 0) &&
548 !n_ptr->routers[n_ptr->last_router]);
549
550 if (!tipc_node_is_up(n_ptr))
551 node_lost_contact(n_ptr);
552}
553
554struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) 402struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
555{ 403{
556 u32 domain; 404 u32 domain;
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 7bfaf5e8c201..3abaaa24c77d 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -54,8 +54,6 @@
54 * @cleanup_required: non-zero if cleaning up after a prior loss of contact 54 * @cleanup_required: non-zero if cleaning up after a prior loss of contact
55 * @link_cnt: number of links to node 55 * @link_cnt: number of links to node
56 * @permit_changeover: non-zero if node has redundant links to this system 56 * @permit_changeover: non-zero if node has redundant links to this system
57 * @routers: bitmap (used for multicluster communication)
58 * @last_router: (used for multicluster communication)
59 * @bclink: broadcast-related info 57 * @bclink: broadcast-related info
60 * @supported: non-zero if node supports TIPC b'cast capability 58 * @supported: non-zero if node supports TIPC b'cast capability
61 * @acked: sequence # of last outbound b'cast message acknowledged by node 59 * @acked: sequence # of last outbound b'cast message acknowledged by node
@@ -80,8 +78,6 @@ struct tipc_node {
80 int working_links; 78 int working_links;
81 int cleanup_required; 79 int cleanup_required;
82 int permit_changeover; 80 int permit_changeover;
83 u32 routers[512/32];
84 int last_router;
85 struct { 81 struct {
86 int supported; 82 int supported;
87 u32 acked; 83 u32 acked;
@@ -105,11 +101,7 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr);
105void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr); 101void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr);
106int tipc_node_has_active_links(struct tipc_node *n_ptr); 102int tipc_node_has_active_links(struct tipc_node *n_ptr);
107int tipc_node_has_redundant_links(struct tipc_node *n_ptr); 103int tipc_node_has_redundant_links(struct tipc_node *n_ptr);
108u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref);
109struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector);
110int tipc_node_is_up(struct tipc_node *n_ptr); 104int 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); 105struct 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); 106struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
115 107
@@ -117,22 +109,9 @@ static inline struct tipc_node *tipc_node_find(u32 addr)
117{ 109{
118 if (likely(in_own_cluster(addr))) 110 if (likely(in_own_cluster(addr)))
119 return tipc_local_nodes[tipc_node(addr)]; 111 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; 112 return NULL;
127} 113}
128 114
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) 115static inline void tipc_node_lock(struct tipc_node *n_ptr)
137{ 116{
138 spin_lock_bh(&n_ptr->lock); 117 spin_lock_bh(&n_ptr->lock);