[TIPC] Initial merge
[linux-2.6] / net / tipc / cluster.c
1 /*
2  * net/tipc/cluster.c: TIPC cluster management routines
3  * 
4  * Copyright (c) 2003-2005, Ericsson Research Canada
5  * Copyright (c) 2005, Wind River Systems
6  * Copyright (c) 2005-2006, Ericsson AB
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * Redistributions of source code must retain the above copyright notice, this
13  * list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  * Neither the names of the copyright holders nor the names of its 
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "core.h"
35 #include "cluster.h"
36 #include "addr.h"
37 #include "node_subscr.h"
38 #include "link.h"
39 #include "node.h"
40 #include "net.h"
41 #include "msg.h"
42 #include "bearer.h"
43
44 void cluster_multicast(struct cluster *c_ptr, struct sk_buff *buf, 
45                        u32 lower, u32 upper);
46 struct sk_buff *cluster_prepare_routing_msg(u32 data_size, u32 dest);
47
48 struct node **local_nodes = 0;
49 struct node_map cluster_bcast_nodes = {0,{0,}};
50 u32 highest_allowed_slave = 0;
51
52 struct cluster *cluster_create(u32 addr)
53 {
54         struct _zone *z_ptr;
55         struct cluster *c_ptr;
56         int max_nodes; 
57         int alloc;
58
59         c_ptr = (struct cluster *)kmalloc(sizeof(*c_ptr), GFP_ATOMIC);
60         if (c_ptr == NULL)
61                 return 0;
62         memset(c_ptr, 0, sizeof(*c_ptr));
63
64         c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
65         if (in_own_cluster(addr))
66                 max_nodes = LOWEST_SLAVE + tipc_max_slaves;
67         else
68                 max_nodes = tipc_max_nodes + 1;
69         alloc = sizeof(void *) * (max_nodes + 1);
70         c_ptr->nodes = (struct node **)kmalloc(alloc, GFP_ATOMIC);
71         if (c_ptr->nodes == NULL) {
72                 kfree(c_ptr);
73                 return 0;
74         }
75         memset(c_ptr->nodes, 0, alloc);  
76         if (in_own_cluster(addr))
77                 local_nodes = c_ptr->nodes;
78         c_ptr->highest_slave = LOWEST_SLAVE - 1;
79         c_ptr->highest_node = 0;
80         
81         z_ptr = zone_find(tipc_zone(addr));
82         if (z_ptr == NULL) {
83                 z_ptr = zone_create(addr);
84         }
85         if (z_ptr != NULL) {
86                 zone_attach_cluster(z_ptr, c_ptr);
87                 c_ptr->owner = z_ptr;
88         }
89         else {
90                 kfree(c_ptr);
91                 c_ptr = 0;
92         }
93
94         return c_ptr;
95 }
96
97 void cluster_delete(struct cluster *c_ptr)
98 {
99         u32 n_num;
100
101         if (!c_ptr)
102                 return;
103         for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) {
104                 node_delete(c_ptr->nodes[n_num]);
105         }
106         for (n_num = LOWEST_SLAVE; n_num <= c_ptr->highest_slave; n_num++) {
107                 node_delete(c_ptr->nodes[n_num]);
108         }
109         kfree(c_ptr->nodes);
110         kfree(c_ptr);
111 }
112
113 u32 cluster_next_node(struct cluster *c_ptr, u32 addr)
114 {
115         struct node *n_ptr;
116         u32 n_num = tipc_node(addr) + 1;
117
118         if (!c_ptr)
119                 return addr;
120         for (; n_num <= c_ptr->highest_node; n_num++) {
121                 n_ptr = c_ptr->nodes[n_num];
122                 if (n_ptr && node_has_active_links(n_ptr))
123                         return n_ptr->addr;
124         }
125         for (n_num = 1; n_num < tipc_node(addr); n_num++) {
126                 n_ptr = c_ptr->nodes[n_num];
127                 if (n_ptr && node_has_active_links(n_ptr))
128                         return n_ptr->addr;
129         }
130         return 0;
131 }
132
133 void cluster_attach_node(struct cluster *c_ptr, struct node *n_ptr)
134 {
135         u32 n_num = tipc_node(n_ptr->addr);
136         u32 max_n_num = tipc_max_nodes;
137
138         if (in_own_cluster(n_ptr->addr))
139                 max_n_num = highest_allowed_slave;
140         assert(n_num > 0);
141         assert(n_num <= max_n_num);
142         assert(c_ptr->nodes[n_num] == 0);
143         c_ptr->nodes[n_num] = n_ptr;
144         if (n_num > c_ptr->highest_node)
145                 c_ptr->highest_node = n_num;
146 }
147
148 /**
149  * cluster_select_router - select router to a cluster
150  * 
151  * Uses deterministic and fair algorithm.
152  */
153
154 u32 cluster_select_router(struct cluster *c_ptr, u32 ref)
155 {
156         u32 n_num;
157         u32 ulim = c_ptr->highest_node;
158         u32 mask;
159         u32 tstart;
160
161         assert(!in_own_cluster(c_ptr->addr));
162         if (!ulim)
163                 return 0;
164
165         /* Start entry must be random */
166         mask = tipc_max_nodes;
167         while (mask > ulim)
168                 mask >>= 1;
169         tstart = ref & mask;
170         n_num = tstart;
171
172         /* Lookup upwards with wrap-around */
173         do {
174                 if (node_is_up(c_ptr->nodes[n_num]))
175                         break;
176         } while (++n_num <= ulim);
177         if (n_num > ulim) {
178                 n_num = 1;
179                 do {
180                         if (node_is_up(c_ptr->nodes[n_num]))
181                                 break;
182                 } while (++n_num < tstart);
183                 if (n_num == tstart)
184                         return 0;
185         }
186         assert(n_num <= ulim);
187         return node_select_router(c_ptr->nodes[n_num], ref);
188 }
189
190 /**
191  * cluster_select_node - select destination node within a remote cluster
192  * 
193  * Uses deterministic and fair algorithm.
194  */
195
196 struct node *cluster_select_node(struct cluster *c_ptr, u32 selector)
197 {
198         u32 n_num;
199         u32 mask = tipc_max_nodes;
200         u32 start_entry;
201
202         assert(!in_own_cluster(c_ptr->addr));
203         if (!c_ptr->highest_node)
204                 return 0;
205
206         /* Start entry must be random */
207         while (mask > c_ptr->highest_node) {
208                 mask >>= 1;
209         }
210         start_entry = (selector & mask) ? selector & mask : 1u;
211         assert(start_entry <= c_ptr->highest_node);
212
213         /* Lookup upwards with wrap-around */
214         for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) {
215                 if (node_has_active_links(c_ptr->nodes[n_num]))
216                         return c_ptr->nodes[n_num];
217         }
218         for (n_num = 1; n_num < start_entry; n_num++) {
219                 if (node_has_active_links(c_ptr->nodes[n_num]))
220                         return c_ptr->nodes[n_num];
221         }
222         return 0;
223 }
224
225 /*
226  *    Routing table management: See description in node.c
227  */
228
229 struct sk_buff *cluster_prepare_routing_msg(u32 data_size, u32 dest)
230 {
231         u32 size = INT_H_SIZE + data_size;
232         struct sk_buff *buf = buf_acquire(size);
233         struct tipc_msg *msg;
234
235         if (buf) {
236                 msg = buf_msg(buf);
237                 memset((char *)msg, 0, size);
238                 msg_init(msg, ROUTE_DISTRIBUTOR, 0, TIPC_OK, INT_H_SIZE, dest);
239         }
240         return buf;
241 }
242
243 void cluster_bcast_new_route(struct cluster *c_ptr, u32 dest,
244                              u32 lower, u32 upper)
245 {
246         struct sk_buff *buf = cluster_prepare_routing_msg(0, c_ptr->addr);
247         struct tipc_msg *msg;
248
249         if (buf) {
250                 msg = buf_msg(buf);
251                 msg_set_remote_node(msg, dest);
252                 msg_set_type(msg, ROUTE_ADDITION);
253                 cluster_multicast(c_ptr, buf, lower, upper);
254         } else {
255                 warn("Memory squeeze: broadcast of new route failed\n");
256         }
257 }
258
259 void cluster_bcast_lost_route(struct cluster *c_ptr, u32 dest,
260                               u32 lower, u32 upper)
261 {
262         struct sk_buff *buf = cluster_prepare_routing_msg(0, c_ptr->addr);
263         struct tipc_msg *msg;
264
265         if (buf) {
266                 msg = buf_msg(buf);
267                 msg_set_remote_node(msg, dest);
268                 msg_set_type(msg, ROUTE_REMOVAL);
269                 cluster_multicast(c_ptr, buf, lower, upper);
270         } else {
271                 warn("Memory squeeze: broadcast of lost route failed\n");
272         }
273 }
274
275 void cluster_send_slave_routes(struct cluster *c_ptr, u32 dest)
276 {
277         struct sk_buff *buf;
278         struct tipc_msg *msg;
279         u32 highest = c_ptr->highest_slave;
280         u32 n_num;
281         int send = 0;
282
283         assert(!is_slave(dest));
284         assert(in_own_cluster(dest));
285         assert(in_own_cluster(c_ptr->addr));
286         if (highest <= LOWEST_SLAVE)
287                 return;
288         buf = cluster_prepare_routing_msg(highest - LOWEST_SLAVE + 1,
289                                           c_ptr->addr);
290         if (buf) {
291                 msg = buf_msg(buf);
292                 msg_set_remote_node(msg, c_ptr->addr);
293                 msg_set_type(msg, SLAVE_ROUTING_TABLE);
294                 for (n_num = LOWEST_SLAVE; n_num <= highest; n_num++) {
295                         if (c_ptr->nodes[n_num] && 
296                             node_has_active_links(c_ptr->nodes[n_num])) {
297                                 send = 1;
298                                 msg_set_dataoctet(msg, n_num);
299                         }
300                 }
301                 if (send)
302                         link_send(buf, dest, dest);
303                 else
304                         buf_discard(buf);
305         } else {
306                 warn("Memory squeeze: broadcast of lost route failed\n");
307         }
308 }
309
310 void cluster_send_ext_routes(struct cluster *c_ptr, u32 dest)
311 {
312         struct sk_buff *buf;
313         struct tipc_msg *msg;
314         u32 highest = c_ptr->highest_node;
315         u32 n_num;
316         int send = 0;
317
318         if (in_own_cluster(c_ptr->addr))
319                 return;
320         assert(!is_slave(dest));
321         assert(in_own_cluster(dest));
322         highest = c_ptr->highest_node;
323         buf = cluster_prepare_routing_msg(highest + 1, c_ptr->addr);
324         if (buf) {
325                 msg = buf_msg(buf);
326                 msg_set_remote_node(msg, c_ptr->addr);
327                 msg_set_type(msg, EXT_ROUTING_TABLE);
328                 for (n_num = 1; n_num <= highest; n_num++) {
329                         if (c_ptr->nodes[n_num] && 
330                             node_has_active_links(c_ptr->nodes[n_num])) {
331                                 send = 1;
332                                 msg_set_dataoctet(msg, n_num);
333                         }
334                 }
335                 if (send)
336                         link_send(buf, dest, dest);
337                 else
338                         buf_discard(buf);
339         } else {
340                 warn("Memory squeeze: broadcast of external route failed\n");
341         }
342 }
343
344 void cluster_send_local_routes(struct cluster *c_ptr, u32 dest)
345 {
346         struct sk_buff *buf;
347         struct tipc_msg *msg;
348         u32 highest = c_ptr->highest_node;
349         u32 n_num;
350         int send = 0;
351
352         assert(is_slave(dest));
353         assert(in_own_cluster(c_ptr->addr));
354         buf = cluster_prepare_routing_msg(highest, c_ptr->addr);
355         if (buf) {
356                 msg = buf_msg(buf);
357                 msg_set_remote_node(msg, c_ptr->addr);
358                 msg_set_type(msg, LOCAL_ROUTING_TABLE);
359                 for (n_num = 1; n_num <= highest; n_num++) {
360                         if (c_ptr->nodes[n_num] && 
361                             node_has_active_links(c_ptr->nodes[n_num])) {
362                                 send = 1;
363                                 msg_set_dataoctet(msg, n_num);
364                         }
365                 }
366                 if (send)
367                         link_send(buf, dest, dest);
368                 else
369                         buf_discard(buf);
370         } else {
371                 warn("Memory squeeze: broadcast of local route failed\n");
372         }
373 }
374
375 void cluster_recv_routing_table(struct sk_buff *buf)
376 {
377         struct tipc_msg *msg = buf_msg(buf);
378         struct cluster *c_ptr;
379         struct node *n_ptr;
380         unchar *node_table;
381         u32 table_size;
382         u32 router;
383         u32 rem_node = msg_remote_node(msg);
384         u32 z_num;
385         u32 c_num;
386         u32 n_num;
387
388         c_ptr = cluster_find(rem_node);
389         if (!c_ptr) {
390                 c_ptr = cluster_create(rem_node);
391                 if (!c_ptr) {
392                         buf_discard(buf);
393                         return;
394                 }
395         }
396
397         node_table = buf->data + msg_hdr_sz(msg);
398         table_size = msg_size(msg) - msg_hdr_sz(msg);
399         router = msg_prevnode(msg);
400         z_num = tipc_zone(rem_node);
401         c_num = tipc_cluster(rem_node);
402
403         switch (msg_type(msg)) {
404         case LOCAL_ROUTING_TABLE:
405                 assert(is_slave(tipc_own_addr));
406         case EXT_ROUTING_TABLE:
407                 for (n_num = 1; n_num < table_size; n_num++) {
408                         if (node_table[n_num]) {
409                                 u32 addr = tipc_addr(z_num, c_num, n_num);
410                                 n_ptr = c_ptr->nodes[n_num];
411                                 if (!n_ptr) {
412                                         n_ptr = node_create(addr);
413                                 }
414                                 if (n_ptr)
415                                         node_add_router(n_ptr, router);
416                         }
417                 }
418                 break;
419         case SLAVE_ROUTING_TABLE:
420                 assert(!is_slave(tipc_own_addr));
421                 assert(in_own_cluster(c_ptr->addr));
422                 for (n_num = 1; n_num < table_size; n_num++) {
423                         if (node_table[n_num]) {
424                                 u32 slave_num = n_num + LOWEST_SLAVE;
425                                 u32 addr = tipc_addr(z_num, c_num, slave_num);
426                                 n_ptr = c_ptr->nodes[slave_num];
427                                 if (!n_ptr) {
428                                         n_ptr = node_create(addr);
429                                 }
430                                 if (n_ptr)
431                                         node_add_router(n_ptr, router);
432                         }
433                 }
434                 break;
435         case ROUTE_ADDITION:
436                 if (!is_slave(tipc_own_addr)) {
437                         assert(!in_own_cluster(c_ptr->addr)
438                                || is_slave(rem_node));
439                 } else {
440                         assert(in_own_cluster(c_ptr->addr)
441                                && !is_slave(rem_node));
442                 }
443                 n_ptr = c_ptr->nodes[tipc_node(rem_node)];
444                 if (!n_ptr)
445                         n_ptr = node_create(rem_node);
446                 if (n_ptr)
447                         node_add_router(n_ptr, router);
448                 break;
449         case ROUTE_REMOVAL:
450                 if (!is_slave(tipc_own_addr)) {
451                         assert(!in_own_cluster(c_ptr->addr)
452                                || is_slave(rem_node));
453                 } else {
454                         assert(in_own_cluster(c_ptr->addr)
455                                && !is_slave(rem_node));
456                 }
457                 n_ptr = c_ptr->nodes[tipc_node(rem_node)];
458                 if (n_ptr)
459                         node_remove_router(n_ptr, router);
460                 break;
461         default:
462                 assert(!"Illegal routing manager message received\n");
463         }
464         buf_discard(buf);
465 }
466
467 void cluster_remove_as_router(struct cluster *c_ptr, u32 router)
468 {
469         u32 start_entry;
470         u32 tstop;
471         u32 n_num;
472
473         if (is_slave(router))
474                 return; /* Slave nodes can not be routers */
475
476         if (in_own_cluster(c_ptr->addr)) {
477                 start_entry = LOWEST_SLAVE;
478                 tstop = c_ptr->highest_slave;
479         } else {
480                 start_entry = 1;
481                 tstop = c_ptr->highest_node;
482         }
483
484         for (n_num = start_entry; n_num <= tstop; n_num++) {
485                 if (c_ptr->nodes[n_num]) {
486                         node_remove_router(c_ptr->nodes[n_num], router);
487                 }
488         }
489 }
490
491 /**
492  * cluster_multicast - multicast message to local nodes 
493  */
494
495 void cluster_multicast(struct cluster *c_ptr, struct sk_buff *buf, 
496                        u32 lower, u32 upper)
497 {
498         struct sk_buff *buf_copy;
499         struct node *n_ptr;
500         u32 n_num;
501         u32 tstop;
502
503         assert(lower <= upper);
504         assert(((lower >= 1) && (lower <= tipc_max_nodes)) ||
505                ((lower >= LOWEST_SLAVE) && (lower <= highest_allowed_slave)));
506         assert(((upper >= 1) && (upper <= tipc_max_nodes)) ||
507                ((upper >= LOWEST_SLAVE) && (upper <= highest_allowed_slave)));
508         assert(in_own_cluster(c_ptr->addr));
509
510         tstop = is_slave(upper) ? c_ptr->highest_slave : c_ptr->highest_node;
511         if (tstop > upper)
512                 tstop = upper;
513         for (n_num = lower; n_num <= tstop; n_num++) {
514                 n_ptr = c_ptr->nodes[n_num];
515                 if (n_ptr && node_has_active_links(n_ptr)) {
516                         buf_copy = skb_copy(buf, GFP_ATOMIC);
517                         if (buf_copy == NULL)
518                                 break;
519                         msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
520                         link_send(buf_copy, n_ptr->addr, n_ptr->addr);
521                 }
522         }
523         buf_discard(buf);
524 }
525
526 /**
527  * cluster_broadcast - broadcast message to all nodes within cluster
528  */
529
530 void cluster_broadcast(struct sk_buff *buf)
531 {
532         struct sk_buff *buf_copy;
533         struct cluster *c_ptr;
534         struct node *n_ptr;
535         u32 n_num;
536         u32 tstart;
537         u32 tstop;
538         u32 node_type;
539
540         if (tipc_mode == TIPC_NET_MODE) {
541                 c_ptr = cluster_find(tipc_own_addr);
542                 assert(in_own_cluster(c_ptr->addr));    /* For now */
543
544                 /* Send to standard nodes, then repeat loop sending to slaves */
545                 tstart = 1;
546                 tstop = c_ptr->highest_node;
547                 for (node_type = 1; node_type <= 2; node_type++) {
548                         for (n_num = tstart; n_num <= tstop; n_num++) {
549                                 n_ptr = c_ptr->nodes[n_num];
550                                 if (n_ptr && node_has_active_links(n_ptr)) {
551                                         buf_copy = skb_copy(buf, GFP_ATOMIC);
552                                         if (buf_copy == NULL)
553                                                 goto exit;
554                                         msg_set_destnode(buf_msg(buf_copy), 
555                                                          n_ptr->addr);
556                                         link_send(buf_copy, n_ptr->addr, 
557                                                   n_ptr->addr);
558                                 }
559                         }
560                         tstart = LOWEST_SLAVE;
561                         tstop = c_ptr->highest_slave;
562                 }
563         }
564 exit:
565         buf_discard(buf);
566 }
567
568 int cluster_init(void)
569 {
570         highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves;
571         return cluster_create(tipc_own_addr) ? TIPC_OK : -ENOMEM;
572 }
573