cluster.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  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. #include "core.h"
  37. #include "cluster.h"
  38. #include "addr.h"
  39. #include "node_subscr.h"
  40. #include "link.h"
  41. #include "node.h"
  42. #include "net.h"
  43. #include "msg.h"
  44. #include "bearer.h"
  45. static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
  46. u32 lower, u32 upper);
  47. static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest);
  48. struct tipc_node **tipc_local_nodes = NULL;
  49. struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}};
  50. u32 tipc_highest_allowed_slave = 0;
  51. struct cluster *tipc_cltr_create(u32 addr)
  52. {
  53. struct _zone *z_ptr;
  54. struct cluster *c_ptr;
  55. int max_nodes;
  56. c_ptr = kzalloc(sizeof(*c_ptr), GFP_ATOMIC);
  57. if (c_ptr == NULL) {
  58. warn("Cluster creation failure, no memory\n");
  59. return NULL;
  60. }
  61. c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
  62. if (in_own_cluster(addr))
  63. max_nodes = LOWEST_SLAVE + tipc_max_slaves;
  64. else
  65. max_nodes = tipc_max_nodes + 1;
  66. c_ptr->nodes = kcalloc(max_nodes + 1, sizeof(void*), GFP_ATOMIC);
  67. if (c_ptr->nodes == NULL) {
  68. warn("Cluster creation failure, no memory for node area\n");
  69. kfree(c_ptr);
  70. return NULL;
  71. }
  72. if (in_own_cluster(addr))
  73. tipc_local_nodes = c_ptr->nodes;
  74. c_ptr->highest_slave = LOWEST_SLAVE - 1;
  75. c_ptr->highest_node = 0;
  76. z_ptr = tipc_zone_find(tipc_zone(addr));
  77. if (!z_ptr) {
  78. z_ptr = tipc_zone_create(addr);
  79. }
  80. if (!z_ptr) {
  81. kfree(c_ptr->nodes);
  82. kfree(c_ptr);
  83. return NULL;
  84. }
  85. tipc_zone_attach_cluster(z_ptr, c_ptr);
  86. c_ptr->owner = z_ptr;
  87. return c_ptr;
  88. }
  89. void tipc_cltr_delete(struct cluster *c_ptr)
  90. {
  91. u32 n_num;
  92. if (!c_ptr)
  93. return;
  94. for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) {
  95. tipc_node_delete(c_ptr->nodes[n_num]);
  96. }
  97. for (n_num = LOWEST_SLAVE; n_num <= c_ptr->highest_slave; n_num++) {
  98. tipc_node_delete(c_ptr->nodes[n_num]);
  99. }
  100. kfree(c_ptr->nodes);
  101. kfree(c_ptr);
  102. }
  103. void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr)
  104. {
  105. u32 n_num = tipc_node(n_ptr->addr);
  106. u32 max_n_num = tipc_max_nodes;
  107. if (in_own_cluster(n_ptr->addr))
  108. max_n_num = tipc_highest_allowed_slave;
  109. assert(n_num > 0);
  110. assert(n_num <= max_n_num);
  111. assert(c_ptr->nodes[n_num] == NULL);
  112. c_ptr->nodes[n_num] = n_ptr;
  113. if (n_num > c_ptr->highest_node)
  114. c_ptr->highest_node = n_num;
  115. }
  116. /**
  117. * tipc_cltr_select_router - select router to a cluster
  118. *
  119. * Uses deterministic and fair algorithm.
  120. */
  121. u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref)
  122. {
  123. u32 n_num;
  124. u32 ulim = c_ptr->highest_node;
  125. u32 mask;
  126. u32 tstart;
  127. assert(!in_own_cluster(c_ptr->addr));
  128. if (!ulim)
  129. return 0;
  130. /* Start entry must be random */
  131. mask = tipc_max_nodes;
  132. while (mask > ulim)
  133. mask >>= 1;
  134. tstart = ref & mask;
  135. n_num = tstart;
  136. /* Lookup upwards with wrap-around */
  137. do {
  138. if (tipc_node_is_up(c_ptr->nodes[n_num]))
  139. break;
  140. } while (++n_num <= ulim);
  141. if (n_num > ulim) {
  142. n_num = 1;
  143. do {
  144. if (tipc_node_is_up(c_ptr->nodes[n_num]))
  145. break;
  146. } while (++n_num < tstart);
  147. if (n_num == tstart)
  148. return 0;
  149. }
  150. assert(n_num <= ulim);
  151. return tipc_node_select_router(c_ptr->nodes[n_num], ref);
  152. }
  153. /**
  154. * tipc_cltr_select_node - select destination node within a remote cluster
  155. *
  156. * Uses deterministic and fair algorithm.
  157. */
  158. struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
  159. {
  160. u32 n_num;
  161. u32 mask = tipc_max_nodes;
  162. u32 start_entry;
  163. assert(!in_own_cluster(c_ptr->addr));
  164. if (!c_ptr->highest_node)
  165. return NULL;
  166. /* Start entry must be random */
  167. while (mask > c_ptr->highest_node) {
  168. mask >>= 1;
  169. }
  170. start_entry = (selector & mask) ? selector & mask : 1u;
  171. assert(start_entry <= c_ptr->highest_node);
  172. /* Lookup upwards with wrap-around */
  173. for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) {
  174. if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
  175. return c_ptr->nodes[n_num];
  176. }
  177. for (n_num = 1; n_num < start_entry; n_num++) {
  178. if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
  179. return c_ptr->nodes[n_num];
  180. }
  181. return NULL;
  182. }
  183. /*
  184. * Routing table management: See description in node.c
  185. */
  186. static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
  187. {
  188. u32 size = INT_H_SIZE + data_size;
  189. struct sk_buff *buf = tipc_buf_acquire(size);
  190. struct tipc_msg *msg;
  191. if (buf) {
  192. msg = buf_msg(buf);
  193. memset((char *)msg, 0, size);
  194. tipc_msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest);
  195. }
  196. return buf;
  197. }
  198. void 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. if (buf) {
  204. msg = buf_msg(buf);
  205. msg_set_remote_node(msg, dest);
  206. msg_set_type(msg, ROUTE_ADDITION);
  207. tipc_cltr_multicast(c_ptr, buf, lower, upper);
  208. } else {
  209. warn("Memory squeeze: broadcast of new route failed\n");
  210. }
  211. }
  212. void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest,
  213. u32 lower, u32 upper)
  214. {
  215. struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
  216. struct tipc_msg *msg;
  217. if (buf) {
  218. msg = buf_msg(buf);
  219. msg_set_remote_node(msg, dest);
  220. msg_set_type(msg, ROUTE_REMOVAL);
  221. tipc_cltr_multicast(c_ptr, buf, lower, upper);
  222. } else {
  223. warn("Memory squeeze: broadcast of lost route failed\n");
  224. }
  225. }
  226. void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest)
  227. {
  228. struct sk_buff *buf;
  229. struct tipc_msg *msg;
  230. u32 highest = c_ptr->highest_slave;
  231. u32 n_num;
  232. int send = 0;
  233. assert(!is_slave(dest));
  234. assert(in_own_cluster(dest));
  235. assert(in_own_cluster(c_ptr->addr));
  236. if (highest <= LOWEST_SLAVE)
  237. return;
  238. buf = tipc_cltr_prepare_routing_msg(highest - LOWEST_SLAVE + 1,
  239. c_ptr->addr);
  240. if (buf) {
  241. msg = buf_msg(buf);
  242. msg_set_remote_node(msg, c_ptr->addr);
  243. msg_set_type(msg, SLAVE_ROUTING_TABLE);
  244. for (n_num = LOWEST_SLAVE; n_num <= highest; n_num++) {
  245. if (c_ptr->nodes[n_num] &&
  246. tipc_node_has_active_links(c_ptr->nodes[n_num])) {
  247. send = 1;
  248. msg_set_dataoctet(msg, n_num);
  249. }
  250. }
  251. if (send)
  252. tipc_link_send(buf, dest, dest);
  253. else
  254. buf_discard(buf);
  255. } else {
  256. warn("Memory squeeze: broadcast of lost route failed\n");
  257. }
  258. }
  259. void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest)
  260. {
  261. struct sk_buff *buf;
  262. struct tipc_msg *msg;
  263. u32 highest = c_ptr->highest_node;
  264. u32 n_num;
  265. int send = 0;
  266. if (in_own_cluster(c_ptr->addr))
  267. return;
  268. assert(!is_slave(dest));
  269. assert(in_own_cluster(dest));
  270. highest = c_ptr->highest_node;
  271. buf = tipc_cltr_prepare_routing_msg(highest + 1, c_ptr->addr);
  272. if (buf) {
  273. msg = buf_msg(buf);
  274. msg_set_remote_node(msg, c_ptr->addr);
  275. msg_set_type(msg, EXT_ROUTING_TABLE);
  276. for (n_num = 1; n_num <= highest; n_num++) {
  277. if (c_ptr->nodes[n_num] &&
  278. tipc_node_has_active_links(c_ptr->nodes[n_num])) {
  279. send = 1;
  280. msg_set_dataoctet(msg, n_num);
  281. }
  282. }
  283. if (send)
  284. tipc_link_send(buf, dest, dest);
  285. else
  286. buf_discard(buf);
  287. } else {
  288. warn("Memory squeeze: broadcast of external route failed\n");
  289. }
  290. }
  291. void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest)
  292. {
  293. struct sk_buff *buf;
  294. struct tipc_msg *msg;
  295. u32 highest = c_ptr->highest_node;
  296. u32 n_num;
  297. int send = 0;
  298. assert(is_slave(dest));
  299. assert(in_own_cluster(c_ptr->addr));
  300. buf = tipc_cltr_prepare_routing_msg(highest, c_ptr->addr);
  301. if (buf) {
  302. msg = buf_msg(buf);
  303. msg_set_remote_node(msg, c_ptr->addr);
  304. msg_set_type(msg, LOCAL_ROUTING_TABLE);
  305. for (n_num = 1; n_num <= highest; n_num++) {
  306. if (c_ptr->nodes[n_num] &&
  307. tipc_node_has_active_links(c_ptr->nodes[n_num])) {
  308. send = 1;
  309. msg_set_dataoctet(msg, n_num);
  310. }
  311. }
  312. if (send)
  313. tipc_link_send(buf, dest, dest);
  314. else
  315. buf_discard(buf);
  316. } else {
  317. warn("Memory squeeze: broadcast of local route failed\n");
  318. }
  319. }
  320. void tipc_cltr_recv_routing_table(struct sk_buff *buf)
  321. {
  322. struct tipc_msg *msg = buf_msg(buf);
  323. struct cluster *c_ptr;
  324. struct tipc_node *n_ptr;
  325. unchar *node_table;
  326. u32 table_size;
  327. u32 router;
  328. u32 rem_node = msg_remote_node(msg);
  329. u32 z_num;
  330. u32 c_num;
  331. u32 n_num;
  332. c_ptr = tipc_cltr_find(rem_node);
  333. if (!c_ptr) {
  334. c_ptr = tipc_cltr_create(rem_node);
  335. if (!c_ptr) {
  336. buf_discard(buf);
  337. return;
  338. }
  339. }
  340. node_table = buf->data + msg_hdr_sz(msg);
  341. table_size = msg_size(msg) - msg_hdr_sz(msg);
  342. router = msg_prevnode(msg);
  343. z_num = tipc_zone(rem_node);
  344. c_num = tipc_cluster(rem_node);
  345. switch (msg_type(msg)) {
  346. case LOCAL_ROUTING_TABLE:
  347. assert(is_slave(tipc_own_addr));
  348. case EXT_ROUTING_TABLE:
  349. for (n_num = 1; n_num < table_size; n_num++) {
  350. if (node_table[n_num]) {
  351. u32 addr = tipc_addr(z_num, c_num, n_num);
  352. n_ptr = c_ptr->nodes[n_num];
  353. if (!n_ptr) {
  354. n_ptr = tipc_node_create(addr);
  355. }
  356. if (n_ptr)
  357. tipc_node_add_router(n_ptr, router);
  358. }
  359. }
  360. break;
  361. case SLAVE_ROUTING_TABLE:
  362. assert(!is_slave(tipc_own_addr));
  363. assert(in_own_cluster(c_ptr->addr));
  364. for (n_num = 1; n_num < table_size; n_num++) {
  365. if (node_table[n_num]) {
  366. u32 slave_num = n_num + LOWEST_SLAVE;
  367. u32 addr = tipc_addr(z_num, c_num, slave_num);
  368. n_ptr = c_ptr->nodes[slave_num];
  369. if (!n_ptr) {
  370. n_ptr = tipc_node_create(addr);
  371. }
  372. if (n_ptr)
  373. tipc_node_add_router(n_ptr, router);
  374. }
  375. }
  376. break;
  377. case ROUTE_ADDITION:
  378. if (!is_slave(tipc_own_addr)) {
  379. assert(!in_own_cluster(c_ptr->addr) ||
  380. is_slave(rem_node));
  381. } else {
  382. assert(in_own_cluster(c_ptr->addr) &&
  383. !is_slave(rem_node));
  384. }
  385. n_ptr = c_ptr->nodes[tipc_node(rem_node)];
  386. if (!n_ptr)
  387. n_ptr = tipc_node_create(rem_node);
  388. if (n_ptr)
  389. tipc_node_add_router(n_ptr, router);
  390. break;
  391. case ROUTE_REMOVAL:
  392. if (!is_slave(tipc_own_addr)) {
  393. assert(!in_own_cluster(c_ptr->addr) ||
  394. is_slave(rem_node));
  395. } else {
  396. assert(in_own_cluster(c_ptr->addr) &&
  397. !is_slave(rem_node));
  398. }
  399. n_ptr = c_ptr->nodes[tipc_node(rem_node)];
  400. if (n_ptr)
  401. tipc_node_remove_router(n_ptr, router);
  402. break;
  403. default:
  404. assert(!"Illegal routing manager message received\n");
  405. }
  406. buf_discard(buf);
  407. }
  408. void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router)
  409. {
  410. u32 start_entry;
  411. u32 tstop;
  412. u32 n_num;
  413. if (is_slave(router))
  414. return; /* Slave nodes can not be routers */
  415. if (in_own_cluster(c_ptr->addr)) {
  416. start_entry = LOWEST_SLAVE;
  417. tstop = c_ptr->highest_slave;
  418. } else {
  419. start_entry = 1;
  420. tstop = c_ptr->highest_node;
  421. }
  422. for (n_num = start_entry; n_num <= tstop; n_num++) {
  423. if (c_ptr->nodes[n_num]) {
  424. tipc_node_remove_router(c_ptr->nodes[n_num], router);
  425. }
  426. }
  427. }
  428. /**
  429. * tipc_cltr_multicast - multicast message to local nodes
  430. */
  431. static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
  432. u32 lower, u32 upper)
  433. {
  434. struct sk_buff *buf_copy;
  435. struct tipc_node *n_ptr;
  436. u32 n_num;
  437. u32 tstop;
  438. assert(lower <= upper);
  439. assert(((lower >= 1) && (lower <= tipc_max_nodes)) ||
  440. ((lower >= LOWEST_SLAVE) && (lower <= tipc_highest_allowed_slave)));
  441. assert(((upper >= 1) && (upper <= tipc_max_nodes)) ||
  442. ((upper >= LOWEST_SLAVE) && (upper <= tipc_highest_allowed_slave)));
  443. assert(in_own_cluster(c_ptr->addr));
  444. tstop = is_slave(upper) ? c_ptr->highest_slave : c_ptr->highest_node;
  445. if (tstop > upper)
  446. tstop = upper;
  447. for (n_num = lower; n_num <= tstop; n_num++) {
  448. n_ptr = c_ptr->nodes[n_num];
  449. if (n_ptr && tipc_node_has_active_links(n_ptr)) {
  450. buf_copy = skb_copy(buf, GFP_ATOMIC);
  451. if (buf_copy == NULL)
  452. break;
  453. msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
  454. tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
  455. }
  456. }
  457. buf_discard(buf);
  458. }
  459. /**
  460. * tipc_cltr_broadcast - broadcast message to all nodes within cluster
  461. */
  462. void tipc_cltr_broadcast(struct sk_buff *buf)
  463. {
  464. struct sk_buff *buf_copy;
  465. struct cluster *c_ptr;
  466. struct tipc_node *n_ptr;
  467. u32 n_num;
  468. u32 tstart;
  469. u32 tstop;
  470. u32 node_type;
  471. if (tipc_mode == TIPC_NET_MODE) {
  472. c_ptr = tipc_cltr_find(tipc_own_addr);
  473. assert(in_own_cluster(c_ptr->addr)); /* For now */
  474. /* Send to standard nodes, then repeat loop sending to slaves */
  475. tstart = 1;
  476. tstop = c_ptr->highest_node;
  477. for (node_type = 1; node_type <= 2; node_type++) {
  478. for (n_num = tstart; n_num <= tstop; n_num++) {
  479. n_ptr = c_ptr->nodes[n_num];
  480. if (n_ptr && tipc_node_has_active_links(n_ptr)) {
  481. buf_copy = skb_copy(buf, GFP_ATOMIC);
  482. if (buf_copy == NULL)
  483. goto exit;
  484. msg_set_destnode(buf_msg(buf_copy),
  485. n_ptr->addr);
  486. tipc_link_send(buf_copy, n_ptr->addr,
  487. n_ptr->addr);
  488. }
  489. }
  490. tstart = LOWEST_SLAVE;
  491. tstop = c_ptr->highest_slave;
  492. }
  493. }
  494. exit:
  495. buf_discard(buf);
  496. }
  497. int tipc_cltr_init(void)
  498. {
  499. tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves;
  500. return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM;
  501. }