monitor.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. /*
  2. * net/tipc/monitor.c
  3. *
  4. * Copyright (c) 2016, Ericsson AB
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the names of the copyright holders nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * Alternatively, this software may be distributed under the terms of the
  20. * GNU General Public License ("GPL") version 2 as published by the Free
  21. * Software Foundation.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. #include <net/genetlink.h>
  36. #include "core.h"
  37. #include "addr.h"
  38. #include "monitor.h"
  39. #include "bearer.h"
  40. #define MAX_MON_DOMAIN 64
  41. #define MON_TIMEOUT 120000
  42. #define MAX_PEER_DOWN_EVENTS 4
  43. /* struct tipc_mon_domain: domain record to be transferred between peers
  44. * @len: actual size of domain record
  45. * @gen: current generation of sender's domain
  46. * @ack_gen: most recent generation of self's domain acked by peer
  47. * @member_cnt: number of domain member nodes described in this record
  48. * @up_map: bit map indicating which of the members the sender considers up
  49. * @members: identity of the domain members
  50. */
  51. struct tipc_mon_domain {
  52. u16 len;
  53. u16 gen;
  54. u16 ack_gen;
  55. u16 member_cnt;
  56. u64 up_map;
  57. u32 members[MAX_MON_DOMAIN];
  58. };
  59. /* struct tipc_peer: state of a peer node and its domain
  60. * @addr: tipc node identity of peer
  61. * @head_map: shows which other nodes currently consider peer 'up'
  62. * @domain: most recent domain record from peer
  63. * @hash: position in hashed lookup list
  64. * @list: position in linked list, in circular ascending order by 'addr'
  65. * @applied: number of reported domain members applied on this monitor list
  66. * @is_up: peer is up as seen from this node
  67. * @is_head: peer is assigned domain head as seen from this node
  68. * @is_local: peer is in local domain and should be continuously monitored
  69. * @down_cnt: - numbers of other peers which have reported this on lost
  70. */
  71. struct tipc_peer {
  72. u32 addr;
  73. struct tipc_mon_domain *domain;
  74. struct hlist_node hash;
  75. struct list_head list;
  76. u8 applied;
  77. u8 down_cnt;
  78. bool is_up;
  79. bool is_head;
  80. bool is_local;
  81. };
  82. struct tipc_monitor {
  83. struct hlist_head peers[NODE_HTABLE_SIZE];
  84. int peer_cnt;
  85. struct tipc_peer *self;
  86. rwlock_t lock;
  87. struct tipc_mon_domain cache;
  88. u16 list_gen;
  89. u16 dom_gen;
  90. struct net *net;
  91. struct timer_list timer;
  92. unsigned long timer_intv;
  93. };
  94. static struct tipc_monitor *tipc_monitor(struct net *net, int bearer_id)
  95. {
  96. return tipc_net(net)->monitors[bearer_id];
  97. }
  98. const int tipc_max_domain_size = sizeof(struct tipc_mon_domain);
  99. static inline u16 mon_cpu_to_le16(u16 val)
  100. {
  101. return (__force __u16)htons(val);
  102. }
  103. static inline u32 mon_cpu_to_le32(u32 val)
  104. {
  105. return (__force __u32)htonl(val);
  106. }
  107. static inline u64 mon_cpu_to_le64(u64 val)
  108. {
  109. return (__force __u64)cpu_to_be64(val);
  110. }
  111. static inline u16 mon_le16_to_cpu(u16 val)
  112. {
  113. return ntohs((__force __be16)val);
  114. }
  115. static inline u32 mon_le32_to_cpu(u32 val)
  116. {
  117. return ntohl((__force __be32)val);
  118. }
  119. static inline u64 mon_le64_to_cpu(u64 val)
  120. {
  121. return be64_to_cpu((__force __be64)val);
  122. }
  123. /* dom_rec_len(): actual length of domain record for transport
  124. */
  125. static int dom_rec_len(struct tipc_mon_domain *dom, u16 mcnt)
  126. {
  127. return (offsetof(struct tipc_mon_domain, members)) + (mcnt * sizeof(u32));
  128. }
  129. /* dom_size() : calculate size of own domain based on number of peers
  130. */
  131. static int dom_size(int peers)
  132. {
  133. int i = 0;
  134. while ((i * i) < peers)
  135. i++;
  136. return i < MAX_MON_DOMAIN ? i : MAX_MON_DOMAIN;
  137. }
  138. static void map_set(u64 *up_map, int i, unsigned int v)
  139. {
  140. *up_map &= ~(1ULL << i);
  141. *up_map |= ((u64)v << i);
  142. }
  143. static int map_get(u64 up_map, int i)
  144. {
  145. return (up_map & (1ULL << i)) >> i;
  146. }
  147. static struct tipc_peer *peer_prev(struct tipc_peer *peer)
  148. {
  149. return list_last_entry(&peer->list, struct tipc_peer, list);
  150. }
  151. static struct tipc_peer *peer_nxt(struct tipc_peer *peer)
  152. {
  153. return list_first_entry(&peer->list, struct tipc_peer, list);
  154. }
  155. static struct tipc_peer *peer_head(struct tipc_peer *peer)
  156. {
  157. while (!peer->is_head)
  158. peer = peer_prev(peer);
  159. return peer;
  160. }
  161. static struct tipc_peer *get_peer(struct tipc_monitor *mon, u32 addr)
  162. {
  163. struct tipc_peer *peer;
  164. unsigned int thash = tipc_hashfn(addr);
  165. hlist_for_each_entry(peer, &mon->peers[thash], hash) {
  166. if (peer->addr == addr)
  167. return peer;
  168. }
  169. return NULL;
  170. }
  171. static struct tipc_peer *get_self(struct net *net, int bearer_id)
  172. {
  173. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  174. return mon->self;
  175. }
  176. static inline bool tipc_mon_is_active(struct net *net, struct tipc_monitor *mon)
  177. {
  178. struct tipc_net *tn = tipc_net(net);
  179. return mon->peer_cnt > tn->mon_threshold;
  180. }
  181. /* mon_identify_lost_members() : - identify amd mark potentially lost members
  182. */
  183. static void mon_identify_lost_members(struct tipc_peer *peer,
  184. struct tipc_mon_domain *dom_bef,
  185. int applied_bef)
  186. {
  187. struct tipc_peer *member = peer;
  188. struct tipc_mon_domain *dom_aft = peer->domain;
  189. int applied_aft = peer->applied;
  190. int i;
  191. for (i = 0; i < applied_bef; i++) {
  192. member = peer_nxt(member);
  193. /* Do nothing if self or peer already see member as down */
  194. if (!member->is_up || !map_get(dom_bef->up_map, i))
  195. continue;
  196. /* Loss of local node must be detected by active probing */
  197. if (member->is_local)
  198. continue;
  199. /* Start probing if member was removed from applied domain */
  200. if (!applied_aft || (applied_aft < i)) {
  201. member->down_cnt = 1;
  202. continue;
  203. }
  204. /* Member loss is confirmed if it is still in applied domain */
  205. if (!map_get(dom_aft->up_map, i))
  206. member->down_cnt++;
  207. }
  208. }
  209. /* mon_apply_domain() : match a peer's domain record against monitor list
  210. */
  211. static void mon_apply_domain(struct tipc_monitor *mon,
  212. struct tipc_peer *peer)
  213. {
  214. struct tipc_mon_domain *dom = peer->domain;
  215. struct tipc_peer *member;
  216. u32 addr;
  217. int i;
  218. if (!dom || !peer->is_up)
  219. return;
  220. /* Scan across domain members and match against monitor list */
  221. peer->applied = 0;
  222. member = peer_nxt(peer);
  223. for (i = 0; i < dom->member_cnt; i++) {
  224. addr = dom->members[i];
  225. if (addr != member->addr)
  226. return;
  227. peer->applied++;
  228. member = peer_nxt(member);
  229. }
  230. }
  231. /* mon_update_local_domain() : update after peer addition/removal/up/down
  232. */
  233. static void mon_update_local_domain(struct tipc_monitor *mon)
  234. {
  235. struct tipc_peer *self = mon->self;
  236. struct tipc_mon_domain *cache = &mon->cache;
  237. struct tipc_mon_domain *dom = self->domain;
  238. struct tipc_peer *peer = self;
  239. u64 prev_up_map = dom->up_map;
  240. u16 member_cnt, i;
  241. bool diff;
  242. /* Update local domain size based on current size of cluster */
  243. member_cnt = dom_size(mon->peer_cnt) - 1;
  244. self->applied = member_cnt;
  245. /* Update native and cached outgoing local domain records */
  246. dom->len = dom_rec_len(dom, member_cnt);
  247. diff = dom->member_cnt != member_cnt;
  248. dom->member_cnt = member_cnt;
  249. for (i = 0; i < member_cnt; i++) {
  250. peer = peer_nxt(peer);
  251. diff |= dom->members[i] != peer->addr;
  252. dom->members[i] = peer->addr;
  253. map_set(&dom->up_map, i, peer->is_up);
  254. cache->members[i] = mon_cpu_to_le32(peer->addr);
  255. }
  256. diff |= dom->up_map != prev_up_map;
  257. if (!diff)
  258. return;
  259. dom->gen = ++mon->dom_gen;
  260. cache->len = mon_cpu_to_le16(dom->len);
  261. cache->gen = mon_cpu_to_le16(dom->gen);
  262. cache->member_cnt = mon_cpu_to_le16(member_cnt);
  263. cache->up_map = mon_cpu_to_le64(dom->up_map);
  264. mon_apply_domain(mon, self);
  265. }
  266. /* mon_update_neighbors() : update preceding neighbors of added/removed peer
  267. */
  268. static void mon_update_neighbors(struct tipc_monitor *mon,
  269. struct tipc_peer *peer)
  270. {
  271. int dz, i;
  272. dz = dom_size(mon->peer_cnt);
  273. for (i = 0; i < dz; i++) {
  274. mon_apply_domain(mon, peer);
  275. peer = peer_prev(peer);
  276. }
  277. }
  278. /* mon_assign_roles() : reassign peer roles after a network change
  279. * The monitor list is consistent at this stage; i.e., each peer is monitoring
  280. * a set of domain members as matched between domain record and the monitor list
  281. */
  282. static void mon_assign_roles(struct tipc_monitor *mon, struct tipc_peer *head)
  283. {
  284. struct tipc_peer *peer = peer_nxt(head);
  285. struct tipc_peer *self = mon->self;
  286. int i = 0;
  287. for (; peer != self; peer = peer_nxt(peer)) {
  288. peer->is_local = false;
  289. /* Update domain member */
  290. if (i++ < head->applied) {
  291. peer->is_head = false;
  292. if (head == self)
  293. peer->is_local = true;
  294. continue;
  295. }
  296. /* Assign next domain head */
  297. if (!peer->is_up)
  298. continue;
  299. if (peer->is_head)
  300. break;
  301. head = peer;
  302. head->is_head = true;
  303. i = 0;
  304. }
  305. mon->list_gen++;
  306. }
  307. void tipc_mon_remove_peer(struct net *net, u32 addr, int bearer_id)
  308. {
  309. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  310. struct tipc_peer *self;
  311. struct tipc_peer *peer, *prev, *head;
  312. if (!mon)
  313. return;
  314. self = get_self(net, bearer_id);
  315. write_lock_bh(&mon->lock);
  316. peer = get_peer(mon, addr);
  317. if (!peer)
  318. goto exit;
  319. prev = peer_prev(peer);
  320. list_del(&peer->list);
  321. hlist_del(&peer->hash);
  322. kfree(peer->domain);
  323. kfree(peer);
  324. mon->peer_cnt--;
  325. head = peer_head(prev);
  326. if (head == self)
  327. mon_update_local_domain(mon);
  328. mon_update_neighbors(mon, prev);
  329. /* Revert to full-mesh monitoring if we reach threshold */
  330. if (!tipc_mon_is_active(net, mon)) {
  331. list_for_each_entry(peer, &self->list, list) {
  332. kfree(peer->domain);
  333. peer->domain = NULL;
  334. peer->applied = 0;
  335. }
  336. }
  337. mon_assign_roles(mon, head);
  338. exit:
  339. write_unlock_bh(&mon->lock);
  340. }
  341. static bool tipc_mon_add_peer(struct tipc_monitor *mon, u32 addr,
  342. struct tipc_peer **peer)
  343. {
  344. struct tipc_peer *self = mon->self;
  345. struct tipc_peer *cur, *prev, *p;
  346. p = kzalloc(sizeof(*p), GFP_ATOMIC);
  347. *peer = p;
  348. if (!p)
  349. return false;
  350. p->addr = addr;
  351. /* Add new peer to lookup list */
  352. INIT_LIST_HEAD(&p->list);
  353. hlist_add_head(&p->hash, &mon->peers[tipc_hashfn(addr)]);
  354. /* Sort new peer into iterator list, in ascending circular order */
  355. prev = self;
  356. list_for_each_entry(cur, &self->list, list) {
  357. if ((addr > prev->addr) && (addr < cur->addr))
  358. break;
  359. if (((addr < cur->addr) || (addr > prev->addr)) &&
  360. (prev->addr > cur->addr))
  361. break;
  362. prev = cur;
  363. }
  364. list_add_tail(&p->list, &cur->list);
  365. mon->peer_cnt++;
  366. mon_update_neighbors(mon, p);
  367. return true;
  368. }
  369. void tipc_mon_peer_up(struct net *net, u32 addr, int bearer_id)
  370. {
  371. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  372. struct tipc_peer *self = get_self(net, bearer_id);
  373. struct tipc_peer *peer, *head;
  374. write_lock_bh(&mon->lock);
  375. peer = get_peer(mon, addr);
  376. if (!peer && !tipc_mon_add_peer(mon, addr, &peer))
  377. goto exit;
  378. peer->is_up = true;
  379. head = peer_head(peer);
  380. if (head == self)
  381. mon_update_local_domain(mon);
  382. mon_assign_roles(mon, head);
  383. exit:
  384. write_unlock_bh(&mon->lock);
  385. }
  386. void tipc_mon_peer_down(struct net *net, u32 addr, int bearer_id)
  387. {
  388. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  389. struct tipc_peer *self;
  390. struct tipc_peer *peer, *head;
  391. struct tipc_mon_domain *dom;
  392. int applied;
  393. if (!mon)
  394. return;
  395. self = get_self(net, bearer_id);
  396. write_lock_bh(&mon->lock);
  397. peer = get_peer(mon, addr);
  398. if (!peer) {
  399. pr_warn("Mon: unknown link %x/%u DOWN\n", addr, bearer_id);
  400. goto exit;
  401. }
  402. applied = peer->applied;
  403. peer->applied = 0;
  404. dom = peer->domain;
  405. peer->domain = NULL;
  406. if (peer->is_head)
  407. mon_identify_lost_members(peer, dom, applied);
  408. kfree(dom);
  409. peer->is_up = false;
  410. peer->is_head = false;
  411. peer->is_local = false;
  412. peer->down_cnt = 0;
  413. head = peer_head(peer);
  414. if (head == self)
  415. mon_update_local_domain(mon);
  416. mon_assign_roles(mon, head);
  417. exit:
  418. write_unlock_bh(&mon->lock);
  419. }
  420. /* tipc_mon_rcv - process monitor domain event message
  421. */
  422. void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr,
  423. struct tipc_mon_state *state, int bearer_id)
  424. {
  425. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  426. struct tipc_mon_domain *arrv_dom = data;
  427. struct tipc_mon_domain dom_bef;
  428. struct tipc_mon_domain *dom;
  429. struct tipc_peer *peer;
  430. u16 new_member_cnt = mon_le16_to_cpu(arrv_dom->member_cnt);
  431. int new_dlen = dom_rec_len(arrv_dom, new_member_cnt);
  432. u16 new_gen = mon_le16_to_cpu(arrv_dom->gen);
  433. u16 acked_gen = mon_le16_to_cpu(arrv_dom->ack_gen);
  434. u16 arrv_dlen = mon_le16_to_cpu(arrv_dom->len);
  435. bool probing = state->probing;
  436. int i, applied_bef;
  437. state->probing = false;
  438. /* Sanity check received domain record */
  439. if (new_member_cnt > MAX_MON_DOMAIN)
  440. return;
  441. if (dlen < dom_rec_len(arrv_dom, 0))
  442. return;
  443. if (dlen != dom_rec_len(arrv_dom, new_member_cnt))
  444. return;
  445. if (dlen < new_dlen || arrv_dlen != new_dlen)
  446. return;
  447. /* Synch generation numbers with peer if link just came up */
  448. if (!state->synched) {
  449. state->peer_gen = new_gen - 1;
  450. state->acked_gen = acked_gen;
  451. state->synched = true;
  452. }
  453. if (more(acked_gen, state->acked_gen))
  454. state->acked_gen = acked_gen;
  455. /* Drop duplicate unless we are waiting for a probe response */
  456. if (!more(new_gen, state->peer_gen) && !probing)
  457. return;
  458. write_lock_bh(&mon->lock);
  459. peer = get_peer(mon, addr);
  460. if (!peer || !peer->is_up)
  461. goto exit;
  462. /* Peer is confirmed, stop any ongoing probing */
  463. peer->down_cnt = 0;
  464. /* Task is done for duplicate record */
  465. if (!more(new_gen, state->peer_gen))
  466. goto exit;
  467. state->peer_gen = new_gen;
  468. /* Cache current domain record for later use */
  469. dom_bef.member_cnt = 0;
  470. dom = peer->domain;
  471. if (dom)
  472. memcpy(&dom_bef, dom, dom->len);
  473. /* Transform and store received domain record */
  474. if (!dom || (dom->len < new_dlen)) {
  475. kfree(dom);
  476. dom = kmalloc(new_dlen, GFP_ATOMIC);
  477. peer->domain = dom;
  478. if (!dom)
  479. goto exit;
  480. }
  481. dom->len = new_dlen;
  482. dom->gen = new_gen;
  483. dom->member_cnt = new_member_cnt;
  484. dom->up_map = mon_le64_to_cpu(arrv_dom->up_map);
  485. for (i = 0; i < new_member_cnt; i++)
  486. dom->members[i] = mon_le32_to_cpu(arrv_dom->members[i]);
  487. /* Update peers affected by this domain record */
  488. applied_bef = peer->applied;
  489. mon_apply_domain(mon, peer);
  490. mon_identify_lost_members(peer, &dom_bef, applied_bef);
  491. mon_assign_roles(mon, peer_head(peer));
  492. exit:
  493. write_unlock_bh(&mon->lock);
  494. }
  495. void tipc_mon_prep(struct net *net, void *data, int *dlen,
  496. struct tipc_mon_state *state, int bearer_id)
  497. {
  498. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  499. struct tipc_mon_domain *dom = data;
  500. u16 gen = mon->dom_gen;
  501. u16 len;
  502. /* Send invalid record if not active */
  503. if (!tipc_mon_is_active(net, mon)) {
  504. dom->len = 0;
  505. return;
  506. }
  507. /* Send only a dummy record with ack if peer has acked our last sent */
  508. if (likely(state->acked_gen == gen)) {
  509. len = dom_rec_len(dom, 0);
  510. *dlen = len;
  511. dom->len = mon_cpu_to_le16(len);
  512. dom->gen = mon_cpu_to_le16(gen);
  513. dom->ack_gen = mon_cpu_to_le16(state->peer_gen);
  514. dom->member_cnt = 0;
  515. return;
  516. }
  517. /* Send the full record */
  518. read_lock_bh(&mon->lock);
  519. len = mon_le16_to_cpu(mon->cache.len);
  520. *dlen = len;
  521. memcpy(data, &mon->cache, len);
  522. read_unlock_bh(&mon->lock);
  523. dom->ack_gen = mon_cpu_to_le16(state->peer_gen);
  524. }
  525. void tipc_mon_get_state(struct net *net, u32 addr,
  526. struct tipc_mon_state *state,
  527. int bearer_id)
  528. {
  529. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  530. struct tipc_peer *peer;
  531. if (!tipc_mon_is_active(net, mon)) {
  532. state->probing = false;
  533. state->monitoring = true;
  534. return;
  535. }
  536. /* Used cached state if table has not changed */
  537. if (!state->probing &&
  538. (state->list_gen == mon->list_gen) &&
  539. (state->acked_gen == mon->dom_gen))
  540. return;
  541. read_lock_bh(&mon->lock);
  542. peer = get_peer(mon, addr);
  543. if (peer) {
  544. state->probing = state->acked_gen != mon->dom_gen;
  545. state->probing |= peer->down_cnt;
  546. state->reset |= peer->down_cnt >= MAX_PEER_DOWN_EVENTS;
  547. state->monitoring = peer->is_local;
  548. state->monitoring |= peer->is_head;
  549. state->list_gen = mon->list_gen;
  550. }
  551. read_unlock_bh(&mon->lock);
  552. }
  553. static void mon_timeout(struct timer_list *t)
  554. {
  555. struct tipc_monitor *mon = from_timer(mon, t, timer);
  556. struct tipc_peer *self;
  557. int best_member_cnt = dom_size(mon->peer_cnt) - 1;
  558. write_lock_bh(&mon->lock);
  559. self = mon->self;
  560. if (self && (best_member_cnt != self->applied)) {
  561. mon_update_local_domain(mon);
  562. mon_assign_roles(mon, self);
  563. }
  564. write_unlock_bh(&mon->lock);
  565. mod_timer(&mon->timer, jiffies + mon->timer_intv);
  566. }
  567. int tipc_mon_create(struct net *net, int bearer_id)
  568. {
  569. struct tipc_net *tn = tipc_net(net);
  570. struct tipc_monitor *mon;
  571. struct tipc_peer *self;
  572. struct tipc_mon_domain *dom;
  573. if (tn->monitors[bearer_id])
  574. return 0;
  575. mon = kzalloc(sizeof(*mon), GFP_ATOMIC);
  576. self = kzalloc(sizeof(*self), GFP_ATOMIC);
  577. dom = kzalloc(sizeof(*dom), GFP_ATOMIC);
  578. if (!mon || !self || !dom) {
  579. kfree(mon);
  580. kfree(self);
  581. kfree(dom);
  582. return -ENOMEM;
  583. }
  584. tn->monitors[bearer_id] = mon;
  585. rwlock_init(&mon->lock);
  586. mon->net = net;
  587. mon->peer_cnt = 1;
  588. mon->self = self;
  589. self->domain = dom;
  590. self->addr = tipc_own_addr(net);
  591. self->is_up = true;
  592. self->is_head = true;
  593. INIT_LIST_HEAD(&self->list);
  594. timer_setup(&mon->timer, mon_timeout, 0);
  595. mon->timer_intv = msecs_to_jiffies(MON_TIMEOUT + (tn->random & 0xffff));
  596. mod_timer(&mon->timer, jiffies + mon->timer_intv);
  597. return 0;
  598. }
  599. void tipc_mon_delete(struct net *net, int bearer_id)
  600. {
  601. struct tipc_net *tn = tipc_net(net);
  602. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  603. struct tipc_peer *self;
  604. struct tipc_peer *peer, *tmp;
  605. if (!mon)
  606. return;
  607. self = get_self(net, bearer_id);
  608. write_lock_bh(&mon->lock);
  609. tn->monitors[bearer_id] = NULL;
  610. list_for_each_entry_safe(peer, tmp, &self->list, list) {
  611. list_del(&peer->list);
  612. hlist_del(&peer->hash);
  613. kfree(peer->domain);
  614. kfree(peer);
  615. }
  616. mon->self = NULL;
  617. write_unlock_bh(&mon->lock);
  618. del_timer_sync(&mon->timer);
  619. kfree(self->domain);
  620. kfree(self);
  621. kfree(mon);
  622. }
  623. void tipc_mon_reinit_self(struct net *net)
  624. {
  625. struct tipc_monitor *mon;
  626. int bearer_id;
  627. for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) {
  628. mon = tipc_monitor(net, bearer_id);
  629. if (!mon)
  630. continue;
  631. write_lock_bh(&mon->lock);
  632. mon->self->addr = tipc_own_addr(net);
  633. write_unlock_bh(&mon->lock);
  634. }
  635. }
  636. int tipc_nl_monitor_set_threshold(struct net *net, u32 cluster_size)
  637. {
  638. struct tipc_net *tn = tipc_net(net);
  639. if (cluster_size > TIPC_CLUSTER_SIZE)
  640. return -EINVAL;
  641. tn->mon_threshold = cluster_size;
  642. return 0;
  643. }
  644. int tipc_nl_monitor_get_threshold(struct net *net)
  645. {
  646. struct tipc_net *tn = tipc_net(net);
  647. return tn->mon_threshold;
  648. }
  649. static int __tipc_nl_add_monitor_peer(struct tipc_peer *peer,
  650. struct tipc_nl_msg *msg)
  651. {
  652. struct tipc_mon_domain *dom = peer->domain;
  653. struct nlattr *attrs;
  654. void *hdr;
  655. hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
  656. NLM_F_MULTI, TIPC_NL_MON_PEER_GET);
  657. if (!hdr)
  658. return -EMSGSIZE;
  659. attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MON_PEER);
  660. if (!attrs)
  661. goto msg_full;
  662. if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_ADDR, peer->addr))
  663. goto attr_msg_full;
  664. if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_APPLIED, peer->applied))
  665. goto attr_msg_full;
  666. if (peer->is_up)
  667. if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_UP))
  668. goto attr_msg_full;
  669. if (peer->is_local)
  670. if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_LOCAL))
  671. goto attr_msg_full;
  672. if (peer->is_head)
  673. if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_HEAD))
  674. goto attr_msg_full;
  675. if (dom) {
  676. if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_DOMGEN, dom->gen))
  677. goto attr_msg_full;
  678. if (nla_put_u64_64bit(msg->skb, TIPC_NLA_MON_PEER_UPMAP,
  679. dom->up_map, TIPC_NLA_MON_PEER_PAD))
  680. goto attr_msg_full;
  681. if (nla_put(msg->skb, TIPC_NLA_MON_PEER_MEMBERS,
  682. dom->member_cnt * sizeof(u32), &dom->members))
  683. goto attr_msg_full;
  684. }
  685. nla_nest_end(msg->skb, attrs);
  686. genlmsg_end(msg->skb, hdr);
  687. return 0;
  688. attr_msg_full:
  689. nla_nest_cancel(msg->skb, attrs);
  690. msg_full:
  691. genlmsg_cancel(msg->skb, hdr);
  692. return -EMSGSIZE;
  693. }
  694. int tipc_nl_add_monitor_peer(struct net *net, struct tipc_nl_msg *msg,
  695. u32 bearer_id, u32 *prev_node)
  696. {
  697. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  698. struct tipc_peer *peer;
  699. if (!mon)
  700. return -EINVAL;
  701. read_lock_bh(&mon->lock);
  702. peer = mon->self;
  703. do {
  704. if (*prev_node) {
  705. if (peer->addr == *prev_node)
  706. *prev_node = 0;
  707. else
  708. continue;
  709. }
  710. if (__tipc_nl_add_monitor_peer(peer, msg)) {
  711. *prev_node = peer->addr;
  712. read_unlock_bh(&mon->lock);
  713. return -EMSGSIZE;
  714. }
  715. } while ((peer = peer_nxt(peer)) != mon->self);
  716. read_unlock_bh(&mon->lock);
  717. return 0;
  718. }
  719. int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg,
  720. u32 bearer_id)
  721. {
  722. struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
  723. char bearer_name[TIPC_MAX_BEARER_NAME];
  724. struct nlattr *attrs;
  725. void *hdr;
  726. int ret;
  727. ret = tipc_bearer_get_name(net, bearer_name, bearer_id);
  728. if (ret || !mon)
  729. return 0;
  730. hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
  731. NLM_F_MULTI, TIPC_NL_MON_GET);
  732. if (!hdr)
  733. return -EMSGSIZE;
  734. attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_MON);
  735. if (!attrs)
  736. goto msg_full;
  737. read_lock_bh(&mon->lock);
  738. if (nla_put_u32(msg->skb, TIPC_NLA_MON_REF, bearer_id))
  739. goto attr_msg_full;
  740. if (tipc_mon_is_active(net, mon))
  741. if (nla_put_flag(msg->skb, TIPC_NLA_MON_ACTIVE))
  742. goto attr_msg_full;
  743. if (nla_put_string(msg->skb, TIPC_NLA_MON_BEARER_NAME, bearer_name))
  744. goto attr_msg_full;
  745. if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEERCNT, mon->peer_cnt))
  746. goto attr_msg_full;
  747. if (nla_put_u32(msg->skb, TIPC_NLA_MON_LISTGEN, mon->list_gen))
  748. goto attr_msg_full;
  749. read_unlock_bh(&mon->lock);
  750. nla_nest_end(msg->skb, attrs);
  751. genlmsg_end(msg->skb, hdr);
  752. return 0;
  753. attr_msg_full:
  754. read_unlock_bh(&mon->lock);
  755. nla_nest_cancel(msg->skb, attrs);
  756. msg_full:
  757. genlmsg_cancel(msg->skb, hdr);
  758. return -EMSGSIZE;
  759. }