aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c108
1 files changed, 53 insertions, 55 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index e110ba67422e..82c05e9dd0ee 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -42,11 +42,8 @@
42#include "bcast.h" 42#include "bcast.h"
43#include "discover.h" 43#include "discover.h"
44 44
45/* Out-of-range value for node signature */
46#define INVALID_NODE_SIG 0x10000 45#define INVALID_NODE_SIG 0x10000
47 46
48#define INVALID_BEARER_ID -1
49
50/* Flags used to take different actions according to flag type 47/* Flags used to take different actions according to flag type
51 * TIPC_NOTIFY_NODE_DOWN: notify node is down 48 * TIPC_NOTIFY_NODE_DOWN: notify node is down
52 * TIPC_NOTIFY_NODE_UP: notify node is up 49 * TIPC_NOTIFY_NODE_UP: notify node is up
@@ -360,7 +357,8 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
360 n_ptr->active_links[0] = INVALID_BEARER_ID; 357 n_ptr->active_links[0] = INVALID_BEARER_ID;
361 n_ptr->active_links[1] = INVALID_BEARER_ID; 358 n_ptr->active_links[1] = INVALID_BEARER_ID;
362 if (!tipc_link_bc_create(net, tipc_own_addr(net), n_ptr->addr, 359 if (!tipc_link_bc_create(net, tipc_own_addr(net), n_ptr->addr,
363 U16_MAX, tipc_bc_sndlink(net)->window, 360 U16_MAX,
361 tipc_link_window(tipc_bc_sndlink(net)),
364 n_ptr->capabilities, 362 n_ptr->capabilities,
365 &n_ptr->bc_entry.inputq1, 363 &n_ptr->bc_entry.inputq1,
366 &n_ptr->bc_entry.namedq, 364 &n_ptr->bc_entry.namedq,
@@ -381,7 +379,7 @@ exit:
381 379
382static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l) 380static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
383{ 381{
384 unsigned long tol = l->tolerance; 382 unsigned long tol = tipc_link_tolerance(l);
385 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4; 383 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
386 unsigned long keepalive_intv = msecs_to_jiffies(intv); 384 unsigned long keepalive_intv = msecs_to_jiffies(intv);
387 385
@@ -390,7 +388,7 @@ static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
390 n->keepalive_intv = keepalive_intv; 388 n->keepalive_intv = keepalive_intv;
391 389
392 /* Ensure link's abort limit corresponds to current interval */ 390 /* Ensure link's abort limit corresponds to current interval */
393 l->abort_limit = l->tolerance / jiffies_to_msecs(n->keepalive_intv); 391 tipc_link_set_abort_limit(l, tol / jiffies_to_msecs(n->keepalive_intv));
394} 392}
395 393
396static void tipc_node_delete(struct tipc_node *node) 394static void tipc_node_delete(struct tipc_node *node)
@@ -559,16 +557,16 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
559 557
560 n->working_links++; 558 n->working_links++;
561 n->action_flags |= TIPC_NOTIFY_LINK_UP; 559 n->action_flags |= TIPC_NOTIFY_LINK_UP;
562 n->link_id = nl->peer_bearer_id << 16 | bearer_id; 560 n->link_id = tipc_link_id(nl);
563 561
564 /* Leave room for tunnel header when returning 'mtu' to users: */ 562 /* Leave room for tunnel header when returning 'mtu' to users: */
565 n->links[bearer_id].mtu = nl->mtu - INT_H_SIZE; 563 n->links[bearer_id].mtu = tipc_link_mtu(nl) - INT_H_SIZE;
566 564
567 tipc_bearer_add_dest(n->net, bearer_id, n->addr); 565 tipc_bearer_add_dest(n->net, bearer_id, n->addr);
568 tipc_bcast_inc_bearer_dst_cnt(n->net, bearer_id); 566 tipc_bcast_inc_bearer_dst_cnt(n->net, bearer_id);
569 567
570 pr_debug("Established link <%s> on network plane %c\n", 568 pr_debug("Established link <%s> on network plane %c\n",
571 nl->name, nl->net_plane); 569 tipc_link_name(nl), tipc_link_plane(nl));
572 570
573 /* First link? => give it both slots */ 571 /* First link? => give it both slots */
574 if (!ol) { 572 if (!ol) {
@@ -581,17 +579,17 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
581 } 579 }
582 580
583 /* Second link => redistribute slots */ 581 /* Second link => redistribute slots */
584 if (nl->priority > ol->priority) { 582 if (tipc_link_prio(nl) > tipc_link_prio(ol)) {
585 pr_debug("Old link <%s> becomes standby\n", ol->name); 583 pr_debug("Old link <%s> becomes standby\n", tipc_link_name(ol));
586 *slot0 = bearer_id; 584 *slot0 = bearer_id;
587 *slot1 = bearer_id; 585 *slot1 = bearer_id;
588 tipc_link_set_active(nl, true); 586 tipc_link_set_active(nl, true);
589 tipc_link_set_active(ol, false); 587 tipc_link_set_active(ol, false);
590 } else if (nl->priority == ol->priority) { 588 } else if (tipc_link_prio(nl) == tipc_link_prio(ol)) {
591 tipc_link_set_active(nl, true); 589 tipc_link_set_active(nl, true);
592 *slot1 = bearer_id; 590 *slot1 = bearer_id;
593 } else { 591 } else {
594 pr_debug("New link <%s> is standby\n", nl->name); 592 pr_debug("New link <%s> is standby\n", tipc_link_name(nl));
595 } 593 }
596 594
597 /* Prepare synchronization with first link */ 595 /* Prepare synchronization with first link */
@@ -621,7 +619,7 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
621 struct tipc_link_entry *le = &n->links[*bearer_id]; 619 struct tipc_link_entry *le = &n->links[*bearer_id];
622 int *slot0 = &n->active_links[0]; 620 int *slot0 = &n->active_links[0];
623 int *slot1 = &n->active_links[1]; 621 int *slot1 = &n->active_links[1];
624 int i, highest = 0; 622 int i, highest = 0, prio;
625 struct tipc_link *l, *_l, *tnl; 623 struct tipc_link *l, *_l, *tnl;
626 624
627 l = n->links[*bearer_id].link; 625 l = n->links[*bearer_id].link;
@@ -630,12 +628,12 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
630 628
631 n->working_links--; 629 n->working_links--;
632 n->action_flags |= TIPC_NOTIFY_LINK_DOWN; 630 n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
633 n->link_id = l->peer_bearer_id << 16 | *bearer_id; 631 n->link_id = tipc_link_id(l);
634 632
635 tipc_bearer_remove_dest(n->net, *bearer_id, n->addr); 633 tipc_bearer_remove_dest(n->net, *bearer_id, n->addr);
636 634
637 pr_debug("Lost link <%s> on network plane %c\n", 635 pr_debug("Lost link <%s> on network plane %c\n",
638 l->name, l->net_plane); 636 tipc_link_name(l), tipc_link_plane(l));
639 637
640 /* Select new active link if any available */ 638 /* Select new active link if any available */
641 *slot0 = INVALID_BEARER_ID; 639 *slot0 = INVALID_BEARER_ID;
@@ -646,10 +644,11 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
646 continue; 644 continue;
647 if (_l == l) 645 if (_l == l)
648 continue; 646 continue;
649 if (_l->priority < highest) 647 prio = tipc_link_prio(_l);
648 if (prio < highest)
650 continue; 649 continue;
651 if (_l->priority > highest) { 650 if (prio > highest) {
652 highest = _l->priority; 651 highest = prio;
653 *slot0 = i; 652 *slot0 = i;
654 *slot1 = i; 653 *slot1 = i;
655 continue; 654 continue;
@@ -672,17 +671,17 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
672 tipc_bcast_dec_bearer_dst_cnt(n->net, *bearer_id); 671 tipc_bcast_dec_bearer_dst_cnt(n->net, *bearer_id);
673 672
674 /* There is still a working link => initiate failover */ 673 /* There is still a working link => initiate failover */
675 tnl = node_active_link(n, 0); 674 *bearer_id = n->active_links[0];
675 tnl = n->links[*bearer_id].link;
676 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT); 676 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT);
677 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT); 677 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT);
678 n->sync_point = tnl->rcv_nxt + (U16_MAX / 2 - 1); 678 n->sync_point = tipc_link_rcv_nxt(tnl) + (U16_MAX / 2 - 1);
679 tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, xmitq); 679 tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, xmitq);
680 tipc_link_reset(l); 680 tipc_link_reset(l);
681 tipc_link_fsm_evt(l, LINK_RESET_EVT); 681 tipc_link_fsm_evt(l, LINK_RESET_EVT);
682 tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT); 682 tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT);
683 tipc_node_fsm_evt(n, NODE_FAILOVER_BEGIN_EVT); 683 tipc_node_fsm_evt(n, NODE_FAILOVER_BEGIN_EVT);
684 *maddr = &n->links[tnl->bearer_id].maddr; 684 *maddr = &n->links[*bearer_id].maddr;
685 *bearer_id = tnl->bearer_id;
686} 685}
687 686
688static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) 687static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete)
@@ -1117,7 +1116,7 @@ int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr,
1117 tipc_node_read_lock(node); 1116 tipc_node_read_lock(node);
1118 link = node->links[bearer_id].link; 1117 link = node->links[bearer_id].link;
1119 if (link) { 1118 if (link) {
1120 strncpy(linkname, link->name, len); 1119 strncpy(linkname, tipc_link_name(link), len);
1121 err = 0; 1120 err = 0;
1122 } 1121 }
1123exit: 1122exit:
@@ -1328,25 +1327,25 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
1328 u16 oseqno = msg_seqno(hdr); 1327 u16 oseqno = msg_seqno(hdr);
1329 u16 iseqno = msg_seqno(msg_get_wrapped(hdr)); 1328 u16 iseqno = msg_seqno(msg_get_wrapped(hdr));
1330 u16 exp_pkts = msg_msgcnt(hdr); 1329 u16 exp_pkts = msg_msgcnt(hdr);
1331 u16 rcv_nxt, syncpt, dlv_nxt; 1330 u16 rcv_nxt, syncpt, dlv_nxt, inputq_len;
1332 int state = n->state; 1331 int state = n->state;
1333 struct tipc_link *l, *tnl, *pl = NULL; 1332 struct tipc_link *l, *tnl, *pl = NULL;
1334 struct tipc_media_addr *maddr; 1333 struct tipc_media_addr *maddr;
1335 int i, pb_id; 1334 int pb_id;
1336 1335
1337 l = n->links[bearer_id].link; 1336 l = n->links[bearer_id].link;
1338 if (!l) 1337 if (!l)
1339 return false; 1338 return false;
1340 rcv_nxt = l->rcv_nxt; 1339 rcv_nxt = tipc_link_rcv_nxt(l);
1341 1340
1342 1341
1343 if (likely((state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) 1342 if (likely((state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL)))
1344 return true; 1343 return true;
1345 1344
1346 /* Find parallel link, if any */ 1345 /* Find parallel link, if any */
1347 for (i = 0; i < MAX_BEARERS; i++) { 1346 for (pb_id = 0; pb_id < MAX_BEARERS; pb_id++) {
1348 if ((i != bearer_id) && n->links[i].link) { 1347 if ((pb_id != bearer_id) && n->links[pb_id].link) {
1349 pl = n->links[i].link; 1348 pl = n->links[pb_id].link;
1350 break; 1349 break;
1351 } 1350 }
1352 } 1351 }
@@ -1378,9 +1377,9 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
1378 if ((usr == TUNNEL_PROTOCOL) && (mtyp == FAILOVER_MSG)) { 1377 if ((usr == TUNNEL_PROTOCOL) && (mtyp == FAILOVER_MSG)) {
1379 syncpt = oseqno + exp_pkts - 1; 1378 syncpt = oseqno + exp_pkts - 1;
1380 if (pl && tipc_link_is_up(pl)) { 1379 if (pl && tipc_link_is_up(pl)) {
1381 pb_id = pl->bearer_id;
1382 __tipc_node_link_down(n, &pb_id, xmitq, &maddr); 1380 __tipc_node_link_down(n, &pb_id, xmitq, &maddr);
1383 tipc_skb_queue_splice_tail_init(pl->inputq, l->inputq); 1381 tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl),
1382 tipc_link_inputq(l));
1384 } 1383 }
1385 /* If pkts arrive out of order, use lowest calculated syncpt */ 1384 /* If pkts arrive out of order, use lowest calculated syncpt */
1386 if (less(syncpt, n->sync_point)) 1385 if (less(syncpt, n->sync_point))
@@ -1423,7 +1422,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
1423 tnl = pl; 1422 tnl = pl;
1424 pl = l; 1423 pl = l;
1425 } 1424 }
1426 dlv_nxt = pl->rcv_nxt - mod(skb_queue_len(pl->inputq)); 1425 inputq_len = skb_queue_len(tipc_link_inputq(pl));
1426 dlv_nxt = tipc_link_rcv_nxt(pl) - inputq_len;
1427 if (more(dlv_nxt, n->sync_point)) { 1427 if (more(dlv_nxt, n->sync_point)) {
1428 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT); 1428 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT);
1429 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT); 1429 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT);
@@ -1483,7 +1483,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
1483 /* Ensure broadcast reception is in synch with peer's send state */ 1483 /* Ensure broadcast reception is in synch with peer's send state */
1484 if (unlikely(usr == LINK_PROTOCOL)) 1484 if (unlikely(usr == LINK_PROTOCOL))
1485 tipc_bcast_sync_rcv(net, n->bc_entry.link, hdr); 1485 tipc_bcast_sync_rcv(net, n->bc_entry.link, hdr);
1486 else if (unlikely(n->bc_entry.link->acked != bc_ack)) 1486 else if (unlikely(tipc_link_acked(n->bc_entry.link) != bc_ack))
1487 tipc_bcast_ack_rcv(net, n->bc_entry.link, bc_ack); 1487 tipc_bcast_ack_rcv(net, n->bc_entry.link, bc_ack);
1488 1488
1489 /* Receive packet directly if conditions permit */ 1489 /* Receive packet directly if conditions permit */
@@ -1592,36 +1592,36 @@ out:
1592 return skb->len; 1592 return skb->len;
1593} 1593}
1594 1594
1595/* tipc_link_find_owner - locate owner node of link by link's name 1595/* tipc_node_find_by_name - locate owner node of link by link's name
1596 * @net: the applicable net namespace 1596 * @net: the applicable net namespace
1597 * @name: pointer to link name string 1597 * @name: pointer to link name string
1598 * @bearer_id: pointer to index in 'node->links' array where the link was found. 1598 * @bearer_id: pointer to index in 'node->links' array where the link was found.
1599 * 1599 *
1600 * Returns pointer to node owning the link, or 0 if no matching link is found. 1600 * Returns pointer to node owning the link, or 0 if no matching link is found.
1601 */ 1601 */
1602static struct tipc_node *tipc_link_find_owner(struct net *net, 1602static struct tipc_node *tipc_node_find_by_name(struct net *net,
1603 const char *link_name, 1603 const char *link_name,
1604 unsigned int *bearer_id) 1604 unsigned int *bearer_id)
1605{ 1605{
1606 struct tipc_net *tn = net_generic(net, tipc_net_id); 1606 struct tipc_net *tn = net_generic(net, tipc_net_id);
1607 struct tipc_link *l_ptr; 1607 struct tipc_link *l;
1608 struct tipc_node *n_ptr; 1608 struct tipc_node *n;
1609 struct tipc_node *found_node = NULL; 1609 struct tipc_node *found_node = NULL;
1610 int i; 1610 int i;
1611 1611
1612 *bearer_id = 0; 1612 *bearer_id = 0;
1613 rcu_read_lock(); 1613 rcu_read_lock();
1614 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { 1614 list_for_each_entry_rcu(n, &tn->node_list, list) {
1615 tipc_node_read_lock(n_ptr); 1615 tipc_node_read_lock(n);
1616 for (i = 0; i < MAX_BEARERS; i++) { 1616 for (i = 0; i < MAX_BEARERS; i++) {
1617 l_ptr = n_ptr->links[i].link; 1617 l = n->links[i].link;
1618 if (l_ptr && !strcmp(l_ptr->name, link_name)) { 1618 if (l && !strcmp(tipc_link_name(l), link_name)) {
1619 *bearer_id = i; 1619 *bearer_id = i;
1620 found_node = n_ptr; 1620 found_node = n;
1621 break; 1621 break;
1622 } 1622 }
1623 } 1623 }
1624 tipc_node_read_unlock(n_ptr); 1624 tipc_node_read_unlock(n);
1625 if (found_node) 1625 if (found_node)
1626 break; 1626 break;
1627 } 1627 }
@@ -1658,7 +1658,7 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1658 if (strcmp(name, tipc_bclink_name) == 0) 1658 if (strcmp(name, tipc_bclink_name) == 0)
1659 return tipc_nl_bc_link_set(net, attrs); 1659 return tipc_nl_bc_link_set(net, attrs);
1660 1660
1661 node = tipc_link_find_owner(net, name, &bearer_id); 1661 node = tipc_node_find_by_name(net, name, &bearer_id);
1662 if (!node) 1662 if (!node)
1663 return -EINVAL; 1663 return -EINVAL;
1664 1664
@@ -1684,15 +1684,13 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1684 u32 tol; 1684 u32 tol;
1685 1685
1686 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]); 1686 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1687 link->tolerance = tol; 1687 tipc_link_set_tolerance(link, tol);
1688 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, tol, 0);
1689 } 1688 }
1690 if (props[TIPC_NLA_PROP_PRIO]) { 1689 if (props[TIPC_NLA_PROP_PRIO]) {
1691 u32 prio; 1690 u32 prio;
1692 1691
1693 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); 1692 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1694 link->priority = prio; 1693 tipc_link_set_prio(link, prio);
1695 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, 0, prio);
1696 } 1694 }
1697 if (props[TIPC_NLA_PROP_WIN]) { 1695 if (props[TIPC_NLA_PROP_WIN]) {
1698 u32 win; 1696 u32 win;
@@ -1737,7 +1735,7 @@ int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info)
1737 struct tipc_node *node; 1735 struct tipc_node *node;
1738 struct tipc_link *link; 1736 struct tipc_link *link;
1739 1737
1740 node = tipc_link_find_owner(net, name, &bearer_id); 1738 node = tipc_node_find_by_name(net, name, &bearer_id);
1741 if (!node) 1739 if (!node)
1742 return -EINVAL; 1740 return -EINVAL;
1743 1741
@@ -1792,7 +1790,7 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
1792 return 0; 1790 return 0;
1793 } 1791 }
1794 1792
1795 node = tipc_link_find_owner(net, link_name, &bearer_id); 1793 node = tipc_node_find_by_name(net, link_name, &bearer_id);
1796 if (!node) 1794 if (!node)
1797 return -EINVAL; 1795 return -EINVAL;
1798 1796
@@ -1805,7 +1803,7 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
1805 tipc_node_read_unlock(node); 1803 tipc_node_read_unlock(node);
1806 return -EINVAL; 1804 return -EINVAL;
1807 } 1805 }
1808 link_reset_statistics(link); 1806 tipc_link_reset_stats(link);
1809 spin_unlock_bh(&le->lock); 1807 spin_unlock_bh(&le->lock);
1810 tipc_node_read_unlock(node); 1808 tipc_node_read_unlock(node);
1811 return 0; 1809 return 0;
@@ -1834,7 +1832,7 @@ static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
1834 return 0; 1832 return 0;
1835} 1833}
1836 1834
1837int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb) 1835int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb)
1838{ 1836{
1839 struct net *net = sock_net(skb->sk); 1837 struct net *net = sock_net(skb->sk);
1840 struct tipc_net *tn = net_generic(net, tipc_net_id); 1838 struct tipc_net *tn = net_generic(net, tipc_net_id);