summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-11-19 14:30:45 -0500
committerDavid S. Miller <davem@davemloft.net>2015-11-20 14:06:10 -0500
commit5be9c086715c10fb9ae3ffc0ef580dc3a165f98a (patch)
tree33ceb909dd758e3b96d48bb5fc8c3e0211c42555
parent5405ff6e15f40f2f53e37d2dcd7de521e2b7a96f (diff)
tipc: narrow down exposure of struct tipc_node
In our effort to have less code and include dependencies between entities such as node, link and bearer, we try to narrow down the exposed interface towards the node as much as possible. In this commit, we move the definition of struct tipc_node, along with many of its associated function declarations, from node.h to node.c. We also move some function definitions from link.c and name_distr.c to node.c, since they access fields in struct tipc_node that should not be externally visible. The moved functions are renamed according to new location, and made static whenever possible. There are no functional changes in this commit. Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/tipc/bcast.h1
-rw-r--r--net/tipc/link.c337
-rw-r--r--net/tipc/link.h9
-rw-r--r--net/tipc/netlink.c6
-rw-r--r--net/tipc/netlink_compat.c4
-rw-r--r--net/tipc/node.c449
-rw-r--r--net/tipc/node.h117
7 files changed, 462 insertions, 461 deletions
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 2855b9356a15..1944c6c00bb9 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -43,6 +43,7 @@ struct tipc_node;
43struct tipc_msg; 43struct tipc_msg;
44struct tipc_nl_msg; 44struct tipc_nl_msg;
45struct tipc_node_map; 45struct tipc_node_map;
46extern const char tipc_bclink_name[];
46 47
47int tipc_bcast_init(struct net *net); 48int tipc_bcast_init(struct net *net);
48void tipc_bcast_reinit(struct net *net); 49void tipc_bcast_reinit(struct net *net);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 1dda46e5dd83..c513a807b3a1 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -50,23 +50,6 @@
50 */ 50 */
51static const char *link_co_err = "Link tunneling error, "; 51static const char *link_co_err = "Link tunneling error, ";
52static const char *link_rst_msg = "Resetting link "; 52static const char *link_rst_msg = "Resetting link ";
53static const char tipc_bclink_name[] = "broadcast-link";
54
55static const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
56 [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC },
57 [TIPC_NLA_LINK_NAME] = {
58 .type = NLA_STRING,
59 .len = TIPC_MAX_LINK_NAME
60 },
61 [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 },
62 [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG },
63 [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG },
64 [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG },
65 [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED },
66 [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED },
67 [TIPC_NLA_LINK_RX] = { .type = NLA_U32 },
68 [TIPC_NLA_LINK_TX] = { .type = NLA_U32 }
69};
70 53
71/* Properties valid for media, bearar and link */ 54/* Properties valid for media, bearar and link */
72static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { 55static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
@@ -117,7 +100,6 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
117static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, 100static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
118 u16 rcvgap, int tolerance, int priority, 101 u16 rcvgap, int tolerance, int priority,
119 struct sk_buff_head *xmitq); 102 struct sk_buff_head *xmitq);
120static void link_reset_statistics(struct tipc_link *l_ptr);
121static void link_print(struct tipc_link *l_ptr, const char *str); 103static void link_print(struct tipc_link *l_ptr, const char *str);
122static void tipc_link_build_nack_msg(struct tipc_link *l, 104static void tipc_link_build_nack_msg(struct tipc_link *l,
123 struct sk_buff_head *xmitq); 105 struct sk_buff_head *xmitq);
@@ -1527,49 +1509,11 @@ void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
1527 l->backlog[TIPC_SYSTEM_IMPORTANCE].limit = max_bulk; 1509 l->backlog[TIPC_SYSTEM_IMPORTANCE].limit = max_bulk;
1528} 1510}
1529 1511
1530/* tipc_link_find_owner - locate owner node of link by link's name
1531 * @net: the applicable net namespace
1532 * @name: pointer to link name string
1533 * @bearer_id: pointer to index in 'node->links' array where the link was found.
1534 *
1535 * Returns pointer to node owning the link, or 0 if no matching link is found.
1536 */
1537static struct tipc_node *tipc_link_find_owner(struct net *net,
1538 const char *link_name,
1539 unsigned int *bearer_id)
1540{
1541 struct tipc_net *tn = net_generic(net, tipc_net_id);
1542 struct tipc_link *l_ptr;
1543 struct tipc_node *n_ptr;
1544 struct tipc_node *found_node = NULL;
1545 int i;
1546
1547 *bearer_id = 0;
1548 rcu_read_lock();
1549 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
1550 tipc_node_read_lock(n_ptr);
1551 for (i = 0; i < MAX_BEARERS; i++) {
1552 l_ptr = n_ptr->links[i].link;
1553 if (l_ptr && !strcmp(l_ptr->name, link_name)) {
1554 *bearer_id = i;
1555 found_node = n_ptr;
1556 break;
1557 }
1558 }
1559 tipc_node_read_unlock(n_ptr);
1560 if (found_node)
1561 break;
1562 }
1563 rcu_read_unlock();
1564
1565 return found_node;
1566}
1567
1568/** 1512/**
1569 * link_reset_statistics - reset link statistics 1513 * link_reset_statistics - reset link statistics
1570 * @l_ptr: pointer to link 1514 * @l_ptr: pointer to link
1571 */ 1515 */
1572static void link_reset_statistics(struct tipc_link *l_ptr) 1516void link_reset_statistics(struct tipc_link *l_ptr)
1573{ 1517{
1574 memset(&l_ptr->stats, 0, sizeof(l_ptr->stats)); 1518 memset(&l_ptr->stats, 0, sizeof(l_ptr->stats));
1575 l_ptr->stats.sent_info = l_ptr->snd_nxt; 1519 l_ptr->stats.sent_info = l_ptr->snd_nxt;
@@ -1626,84 +1570,6 @@ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[])
1626 return 0; 1570 return 0;
1627} 1571}
1628 1572
1629int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info)
1630{
1631 int err;
1632 int res = 0;
1633 int bearer_id;
1634 char *name;
1635 struct tipc_link *link;
1636 struct tipc_node *node;
1637 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
1638 struct net *net = sock_net(skb->sk);
1639
1640 if (!info->attrs[TIPC_NLA_LINK])
1641 return -EINVAL;
1642
1643 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
1644 info->attrs[TIPC_NLA_LINK],
1645 tipc_nl_link_policy);
1646 if (err)
1647 return err;
1648
1649 if (!attrs[TIPC_NLA_LINK_NAME])
1650 return -EINVAL;
1651
1652 name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
1653
1654 if (strcmp(name, tipc_bclink_name) == 0)
1655 return tipc_nl_bc_link_set(net, attrs);
1656
1657 node = tipc_link_find_owner(net, name, &bearer_id);
1658 if (!node)
1659 return -EINVAL;
1660
1661 tipc_node_read_lock(node);
1662
1663 link = node->links[bearer_id].link;
1664 if (!link) {
1665 res = -EINVAL;
1666 goto out;
1667 }
1668
1669 if (attrs[TIPC_NLA_LINK_PROP]) {
1670 struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
1671
1672 err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_LINK_PROP],
1673 props);
1674 if (err) {
1675 res = err;
1676 goto out;
1677 }
1678
1679 if (props[TIPC_NLA_PROP_TOL]) {
1680 u32 tol;
1681
1682 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1683 link->tolerance = tol;
1684 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, tol, 0);
1685 }
1686 if (props[TIPC_NLA_PROP_PRIO]) {
1687 u32 prio;
1688
1689 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1690 link->priority = prio;
1691 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, 0, prio);
1692 }
1693 if (props[TIPC_NLA_PROP_WIN]) {
1694 u32 win;
1695
1696 win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
1697 tipc_link_set_queue_limits(link, win);
1698 }
1699 }
1700
1701out:
1702 tipc_node_read_unlock(node);
1703
1704 return res;
1705}
1706
1707static int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s) 1573static int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s)
1708{ 1574{
1709 int i; 1575 int i;
@@ -1770,8 +1636,8 @@ msg_full:
1770} 1636}
1771 1637
1772/* Caller should hold appropriate locks to protect the link */ 1638/* Caller should hold appropriate locks to protect the link */
1773static int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg, 1639int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
1774 struct tipc_link *link, int nlflags) 1640 struct tipc_link *link, int nlflags)
1775{ 1641{
1776 int err; 1642 int err;
1777 void *hdr; 1643 void *hdr;
@@ -1839,200 +1705,3 @@ msg_full:
1839 1705
1840 return -EMSGSIZE; 1706 return -EMSGSIZE;
1841} 1707}
1842
1843/* Caller should hold node lock */
1844static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
1845 struct tipc_node *node, u32 *prev_link)
1846{
1847 u32 i;
1848 int err;
1849
1850 for (i = *prev_link; i < MAX_BEARERS; i++) {
1851 *prev_link = i;
1852
1853 if (!node->links[i].link)
1854 continue;
1855
1856 err = __tipc_nl_add_link(net, msg,
1857 node->links[i].link, NLM_F_MULTI);
1858 if (err)
1859 return err;
1860 }
1861 *prev_link = 0;
1862
1863 return 0;
1864}
1865
1866int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb)
1867{
1868 struct net *net = sock_net(skb->sk);
1869 struct tipc_net *tn = net_generic(net, tipc_net_id);
1870 struct tipc_node *node;
1871 struct tipc_nl_msg msg;
1872 u32 prev_node = cb->args[0];
1873 u32 prev_link = cb->args[1];
1874 int done = cb->args[2];
1875 int err;
1876
1877 if (done)
1878 return 0;
1879
1880 msg.skb = skb;
1881 msg.portid = NETLINK_CB(cb->skb).portid;
1882 msg.seq = cb->nlh->nlmsg_seq;
1883
1884 rcu_read_lock();
1885 if (prev_node) {
1886 node = tipc_node_find(net, prev_node);
1887 if (!node) {
1888 /* We never set seq or call nl_dump_check_consistent()
1889 * this means that setting prev_seq here will cause the
1890 * consistence check to fail in the netlink callback
1891 * handler. Resulting in the last NLMSG_DONE message
1892 * having the NLM_F_DUMP_INTR flag set.
1893 */
1894 cb->prev_seq = 1;
1895 goto out;
1896 }
1897 tipc_node_put(node);
1898
1899 list_for_each_entry_continue_rcu(node, &tn->node_list,
1900 list) {
1901 tipc_node_read_lock(node);
1902 err = __tipc_nl_add_node_links(net, &msg, node,
1903 &prev_link);
1904 tipc_node_read_unlock(node);
1905 if (err)
1906 goto out;
1907
1908 prev_node = node->addr;
1909 }
1910 } else {
1911 err = tipc_nl_add_bc_link(net, &msg);
1912 if (err)
1913 goto out;
1914
1915 list_for_each_entry_rcu(node, &tn->node_list, list) {
1916 tipc_node_read_lock(node);
1917 err = __tipc_nl_add_node_links(net, &msg, node,
1918 &prev_link);
1919 tipc_node_read_unlock(node);
1920 if (err)
1921 goto out;
1922
1923 prev_node = node->addr;
1924 }
1925 }
1926 done = 1;
1927out:
1928 rcu_read_unlock();
1929
1930 cb->args[0] = prev_node;
1931 cb->args[1] = prev_link;
1932 cb->args[2] = done;
1933
1934 return skb->len;
1935}
1936
1937int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info)
1938{
1939 struct net *net = genl_info_net(info);
1940 struct tipc_nl_msg msg;
1941 char *name;
1942 int err;
1943
1944 msg.portid = info->snd_portid;
1945 msg.seq = info->snd_seq;
1946
1947 if (!info->attrs[TIPC_NLA_LINK_NAME])
1948 return -EINVAL;
1949 name = nla_data(info->attrs[TIPC_NLA_LINK_NAME]);
1950
1951 msg.skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1952 if (!msg.skb)
1953 return -ENOMEM;
1954
1955 if (strcmp(name, tipc_bclink_name) == 0) {
1956 err = tipc_nl_add_bc_link(net, &msg);
1957 if (err) {
1958 nlmsg_free(msg.skb);
1959 return err;
1960 }
1961 } else {
1962 int bearer_id;
1963 struct tipc_node *node;
1964 struct tipc_link *link;
1965
1966 node = tipc_link_find_owner(net, name, &bearer_id);
1967 if (!node)
1968 return -EINVAL;
1969
1970 tipc_node_read_lock(node);
1971 link = node->links[bearer_id].link;
1972 if (!link) {
1973 tipc_node_read_unlock(node);
1974 nlmsg_free(msg.skb);
1975 return -EINVAL;
1976 }
1977
1978 err = __tipc_nl_add_link(net, &msg, link, 0);
1979 tipc_node_read_unlock(node);
1980 if (err) {
1981 nlmsg_free(msg.skb);
1982 return err;
1983 }
1984 }
1985
1986 return genlmsg_reply(msg.skb, info);
1987}
1988
1989int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info)
1990{
1991 int err;
1992 char *link_name;
1993 unsigned int bearer_id;
1994 struct tipc_link *link;
1995 struct tipc_node *node;
1996 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
1997 struct net *net = sock_net(skb->sk);
1998 struct tipc_link_entry *le;
1999
2000 if (!info->attrs[TIPC_NLA_LINK])
2001 return -EINVAL;
2002
2003 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
2004 info->attrs[TIPC_NLA_LINK],
2005 tipc_nl_link_policy);
2006 if (err)
2007 return err;
2008
2009 if (!attrs[TIPC_NLA_LINK_NAME])
2010 return -EINVAL;
2011
2012 link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
2013
2014 if (strcmp(link_name, tipc_bclink_name) == 0) {
2015 err = tipc_bclink_reset_stats(net);
2016 if (err)
2017 return err;
2018 return 0;
2019 }
2020
2021 node = tipc_link_find_owner(net, link_name, &bearer_id);
2022 if (!node)
2023 return -EINVAL;
2024
2025 le = &node->links[bearer_id];
2026 tipc_node_read_lock(node);
2027 spin_lock_bh(&le->lock);
2028 link = le->link;
2029 if (!link) {
2030 spin_unlock_bh(&le->lock);
2031 tipc_node_read_unlock(node);
2032 return -EINVAL;
2033 }
2034 link_reset_statistics(link);
2035 spin_unlock_bh(&le->lock);
2036 tipc_node_read_unlock(node);
2037 return 0;
2038}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 66d859b66c84..a7ee806e1ee4 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -249,14 +249,15 @@ bool tipc_link_is_failingover(struct tipc_link *l);
249bool tipc_link_is_blocked(struct tipc_link *l); 249bool tipc_link_is_blocked(struct tipc_link *l);
250void tipc_link_set_active(struct tipc_link *l, bool active); 250void tipc_link_set_active(struct tipc_link *l, bool active);
251void tipc_link_reset(struct tipc_link *l_ptr); 251void tipc_link_reset(struct tipc_link *l_ptr);
252void link_reset_statistics(struct tipc_link *l);
252int tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list, 253int tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list,
253 struct sk_buff_head *xmitq); 254 struct sk_buff_head *xmitq);
255void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ, int probe_msg,
256 u32 gap, u32 tolerance, u32 priority);
254void tipc_link_set_queue_limits(struct tipc_link *l, u32 window); 257void tipc_link_set_queue_limits(struct tipc_link *l, u32 window);
255 258int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
259 struct tipc_link *link, int nlflags);
256int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb); 260int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb);
257int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info);
258int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info);
259int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info);
260int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); 261int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
261int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq); 262int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq);
262int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, 263int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 7f6475efc984..29dfcc94b6a5 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -101,18 +101,18 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
101 }, 101 },
102 { 102 {
103 .cmd = TIPC_NL_LINK_GET, 103 .cmd = TIPC_NL_LINK_GET,
104 .doit = tipc_nl_link_get, 104 .doit = tipc_nl_node_get_link,
105 .dumpit = tipc_nl_link_dump, 105 .dumpit = tipc_nl_link_dump,
106 .policy = tipc_nl_policy, 106 .policy = tipc_nl_policy,
107 }, 107 },
108 { 108 {
109 .cmd = TIPC_NL_LINK_SET, 109 .cmd = TIPC_NL_LINK_SET,
110 .doit = tipc_nl_link_set, 110 .doit = tipc_nl_node_set_link,
111 .policy = tipc_nl_policy, 111 .policy = tipc_nl_policy,
112 }, 112 },
113 { 113 {
114 .cmd = TIPC_NL_LINK_RESET_STATS, 114 .cmd = TIPC_NL_LINK_RESET_STATS,
115 .doit = tipc_nl_link_reset_stats, 115 .doit = tipc_nl_node_reset_link_stats,
116 .policy = tipc_nl_policy, 116 .policy = tipc_nl_policy,
117 }, 117 },
118 { 118 {
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index 1eadc95e1132..acda1ce57151 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -1036,12 +1036,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg)
1036 case TIPC_CMD_SET_LINK_PRI: 1036 case TIPC_CMD_SET_LINK_PRI:
1037 case TIPC_CMD_SET_LINK_WINDOW: 1037 case TIPC_CMD_SET_LINK_WINDOW:
1038 msg->req_type = TIPC_TLV_LINK_CONFIG; 1038 msg->req_type = TIPC_TLV_LINK_CONFIG;
1039 doit.doit = tipc_nl_link_set; 1039 doit.doit = tipc_nl_node_set_link;
1040 doit.transcode = tipc_nl_compat_link_set; 1040 doit.transcode = tipc_nl_compat_link_set;
1041 return tipc_nl_compat_doit(&doit, msg); 1041 return tipc_nl_compat_doit(&doit, msg);
1042 case TIPC_CMD_RESET_LINK_STATS: 1042 case TIPC_CMD_RESET_LINK_STATS:
1043 msg->req_type = TIPC_TLV_LINK_NAME; 1043 msg->req_type = TIPC_TLV_LINK_NAME;
1044 doit.doit = tipc_nl_link_reset_stats; 1044 doit.doit = tipc_nl_node_reset_link_stats;
1045 doit.transcode = tipc_nl_compat_link_reset_stats; 1045 doit.transcode = tipc_nl_compat_link_reset_stats;
1046 return tipc_nl_compat_doit(&doit, msg); 1046 return tipc_nl_compat_doit(&doit, msg);
1047 case TIPC_CMD_SHOW_NAME_TABLE: 1047 case TIPC_CMD_SHOW_NAME_TABLE:
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 47d5f84c90c5..e110ba67422e 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -42,6 +42,87 @@
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
47
48#define INVALID_BEARER_ID -1
49
50/* Flags used to take different actions according to flag type
51 * TIPC_NOTIFY_NODE_DOWN: notify node is down
52 * TIPC_NOTIFY_NODE_UP: notify node is up
53 * TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type
54 */
55enum {
56 TIPC_NOTIFY_NODE_DOWN = (1 << 3),
57 TIPC_NOTIFY_NODE_UP = (1 << 4),
58 TIPC_NOTIFY_LINK_UP = (1 << 6),
59 TIPC_NOTIFY_LINK_DOWN = (1 << 7)
60};
61
62struct tipc_link_entry {
63 struct tipc_link *link;
64 spinlock_t lock; /* per link */
65 u32 mtu;
66 struct sk_buff_head inputq;
67 struct tipc_media_addr maddr;
68};
69
70struct tipc_bclink_entry {
71 struct tipc_link *link;
72 struct sk_buff_head inputq1;
73 struct sk_buff_head arrvq;
74 struct sk_buff_head inputq2;
75 struct sk_buff_head namedq;
76};
77
78/**
79 * struct tipc_node - TIPC node structure
80 * @addr: network address of node
81 * @ref: reference counter to node object
82 * @lock: rwlock governing access to structure
83 * @net: the applicable net namespace
84 * @hash: links to adjacent nodes in unsorted hash chain
85 * @inputq: pointer to input queue containing messages for msg event
86 * @namedq: pointer to name table input queue with name table messages
87 * @active_links: bearer ids of active links, used as index into links[] array
88 * @links: array containing references to all links to node
89 * @action_flags: bit mask of different types of node actions
90 * @state: connectivity state vs peer node
91 * @sync_point: sequence number where synch/failover is finished
92 * @list: links to adjacent nodes in sorted list of cluster's nodes
93 * @working_links: number of working links to node (both active and standby)
94 * @link_cnt: number of links to node
95 * @capabilities: bitmap, indicating peer node's functional capabilities
96 * @signature: node instance identifier
97 * @link_id: local and remote bearer ids of changing link, if any
98 * @publ_list: list of publications
99 * @rcu: rcu struct for tipc_node
100 */
101struct tipc_node {
102 u32 addr;
103 struct kref kref;
104 rwlock_t lock;
105 struct net *net;
106 struct hlist_node hash;
107 int active_links[2];
108 struct tipc_link_entry links[MAX_BEARERS];
109 struct tipc_bclink_entry bc_entry;
110 int action_flags;
111 struct list_head list;
112 int state;
113 u16 sync_point;
114 int link_cnt;
115 u16 working_links;
116 u16 capabilities;
117 u32 signature;
118 u32 link_id;
119 struct list_head publ_list;
120 struct list_head conn_sks;
121 unsigned long keepalive_intv;
122 struct timer_list timer;
123 struct rcu_head rcu;
124};
125
45/* Node FSM states and events: 126/* Node FSM states and events:
46 */ 127 */
47enum { 128enum {
@@ -75,6 +156,9 @@ static void node_lost_contact(struct tipc_node *n, struct sk_buff_head *inputq);
75static void tipc_node_delete(struct tipc_node *node); 156static void tipc_node_delete(struct tipc_node *node);
76static void tipc_node_timeout(unsigned long data); 157static void tipc_node_timeout(unsigned long data);
77static void tipc_node_fsm_evt(struct tipc_node *n, int evt); 158static void tipc_node_fsm_evt(struct tipc_node *n, int evt);
159static struct tipc_node *tipc_node_find(struct net *net, u32 addr);
160static void tipc_node_put(struct tipc_node *node);
161static bool tipc_node_is_up(struct tipc_node *n);
78 162
79struct tipc_sock_conn { 163struct tipc_sock_conn {
80 u32 port; 164 u32 port;
@@ -83,12 +167,54 @@ struct tipc_sock_conn {
83 struct list_head list; 167 struct list_head list;
84}; 168};
85 169
170static const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
171 [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC },
172 [TIPC_NLA_LINK_NAME] = {
173 .type = NLA_STRING,
174 .len = TIPC_MAX_LINK_NAME
175 },
176 [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 },
177 [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG },
178 [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG },
179 [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG },
180 [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED },
181 [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED },
182 [TIPC_NLA_LINK_RX] = { .type = NLA_U32 },
183 [TIPC_NLA_LINK_TX] = { .type = NLA_U32 }
184};
185
86static const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = { 186static const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = {
87 [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC }, 187 [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC },
88 [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 }, 188 [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 },
89 [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG } 189 [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG }
90}; 190};
91 191
192static struct tipc_link *node_active_link(struct tipc_node *n, int sel)
193{
194 int bearer_id = n->active_links[sel & 1];
195
196 if (unlikely(bearer_id == INVALID_BEARER_ID))
197 return NULL;
198
199 return n->links[bearer_id].link;
200}
201
202int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel)
203{
204 struct tipc_node *n;
205 int bearer_id;
206 unsigned int mtu = MAX_MSG_SIZE;
207
208 n = tipc_node_find(net, addr);
209 if (unlikely(!n))
210 return mtu;
211
212 bearer_id = n->active_links[sel & 1];
213 if (likely(bearer_id != INVALID_BEARER_ID))
214 mtu = n->links[bearer_id].mtu;
215 tipc_node_put(n);
216 return mtu;
217}
92/* 218/*
93 * A trivial power-of-two bitmask technique is used for speed, since this 219 * A trivial power-of-two bitmask technique is used for speed, since this
94 * operation is done for every incoming TIPC packet. The number of hash table 220 * operation is done for every incoming TIPC packet. The number of hash table
@@ -107,7 +233,7 @@ static void tipc_node_kref_release(struct kref *kref)
107 tipc_node_delete(node); 233 tipc_node_delete(node);
108} 234}
109 235
110void tipc_node_put(struct tipc_node *node) 236static void tipc_node_put(struct tipc_node *node)
111{ 237{
112 kref_put(&node->kref, tipc_node_kref_release); 238 kref_put(&node->kref, tipc_node_kref_release);
113} 239}
@@ -120,7 +246,7 @@ static void tipc_node_get(struct tipc_node *node)
120/* 246/*
121 * tipc_node_find - locate specified node object, if it exists 247 * tipc_node_find - locate specified node object, if it exists
122 */ 248 */
123struct tipc_node *tipc_node_find(struct net *net, u32 addr) 249static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
124{ 250{
125 struct tipc_net *tn = net_generic(net, tipc_net_id); 251 struct tipc_net *tn = net_generic(net, tipc_net_id);
126 struct tipc_node *node; 252 struct tipc_node *node;
@@ -141,12 +267,12 @@ struct tipc_node *tipc_node_find(struct net *net, u32 addr)
141 return NULL; 267 return NULL;
142} 268}
143 269
144void tipc_node_read_lock(struct tipc_node *n) 270static void tipc_node_read_lock(struct tipc_node *n)
145{ 271{
146 read_lock_bh(&n->lock); 272 read_lock_bh(&n->lock);
147} 273}
148 274
149void tipc_node_read_unlock(struct tipc_node *n) 275static void tipc_node_read_unlock(struct tipc_node *n)
150{ 276{
151 read_unlock_bh(&n->lock); 277 read_unlock_bh(&n->lock);
152} 278}
@@ -588,7 +714,7 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete)
588 tipc_sk_rcv(n->net, &le->inputq); 714 tipc_sk_rcv(n->net, &le->inputq);
589} 715}
590 716
591bool tipc_node_is_up(struct tipc_node *n) 717static bool tipc_node_is_up(struct tipc_node *n)
592{ 718{
593 return n->active_links[0] != INVALID_BEARER_ID; 719 return n->active_links[0] != INVALID_BEARER_ID;
594} 720}
@@ -1465,3 +1591,316 @@ out:
1465 1591
1466 return skb->len; 1592 return skb->len;
1467} 1593}
1594
1595/* tipc_link_find_owner - locate owner node of link by link's name
1596 * @net: the applicable net namespace
1597 * @name: pointer to link name string
1598 * @bearer_id: pointer to index in 'node->links' array where the link was found.
1599 *
1600 * Returns pointer to node owning the link, or 0 if no matching link is found.
1601 */
1602static struct tipc_node *tipc_link_find_owner(struct net *net,
1603 const char *link_name,
1604 unsigned int *bearer_id)
1605{
1606 struct tipc_net *tn = net_generic(net, tipc_net_id);
1607 struct tipc_link *l_ptr;
1608 struct tipc_node *n_ptr;
1609 struct tipc_node *found_node = NULL;
1610 int i;
1611
1612 *bearer_id = 0;
1613 rcu_read_lock();
1614 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
1615 tipc_node_read_lock(n_ptr);
1616 for (i = 0; i < MAX_BEARERS; i++) {
1617 l_ptr = n_ptr->links[i].link;
1618 if (l_ptr && !strcmp(l_ptr->name, link_name)) {
1619 *bearer_id = i;
1620 found_node = n_ptr;
1621 break;
1622 }
1623 }
1624 tipc_node_read_unlock(n_ptr);
1625 if (found_node)
1626 break;
1627 }
1628 rcu_read_unlock();
1629
1630 return found_node;
1631}
1632
1633int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1634{
1635 int err;
1636 int res = 0;
1637 int bearer_id;
1638 char *name;
1639 struct tipc_link *link;
1640 struct tipc_node *node;
1641 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
1642 struct net *net = sock_net(skb->sk);
1643
1644 if (!info->attrs[TIPC_NLA_LINK])
1645 return -EINVAL;
1646
1647 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
1648 info->attrs[TIPC_NLA_LINK],
1649 tipc_nl_link_policy);
1650 if (err)
1651 return err;
1652
1653 if (!attrs[TIPC_NLA_LINK_NAME])
1654 return -EINVAL;
1655
1656 name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
1657
1658 if (strcmp(name, tipc_bclink_name) == 0)
1659 return tipc_nl_bc_link_set(net, attrs);
1660
1661 node = tipc_link_find_owner(net, name, &bearer_id);
1662 if (!node)
1663 return -EINVAL;
1664
1665 tipc_node_read_lock(node);
1666
1667 link = node->links[bearer_id].link;
1668 if (!link) {
1669 res = -EINVAL;
1670 goto out;
1671 }
1672
1673 if (attrs[TIPC_NLA_LINK_PROP]) {
1674 struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
1675
1676 err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_LINK_PROP],
1677 props);
1678 if (err) {
1679 res = err;
1680 goto out;
1681 }
1682
1683 if (props[TIPC_NLA_PROP_TOL]) {
1684 u32 tol;
1685
1686 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1687 link->tolerance = tol;
1688 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, tol, 0);
1689 }
1690 if (props[TIPC_NLA_PROP_PRIO]) {
1691 u32 prio;
1692
1693 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1694 link->priority = prio;
1695 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, 0, prio);
1696 }
1697 if (props[TIPC_NLA_PROP_WIN]) {
1698 u32 win;
1699
1700 win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
1701 tipc_link_set_queue_limits(link, win);
1702 }
1703 }
1704
1705out:
1706 tipc_node_read_unlock(node);
1707
1708 return res;
1709}
1710
1711int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info)
1712{
1713 struct net *net = genl_info_net(info);
1714 struct tipc_nl_msg msg;
1715 char *name;
1716 int err;
1717
1718 msg.portid = info->snd_portid;
1719 msg.seq = info->snd_seq;
1720
1721 if (!info->attrs[TIPC_NLA_LINK_NAME])
1722 return -EINVAL;
1723 name = nla_data(info->attrs[TIPC_NLA_LINK_NAME]);
1724
1725 msg.skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1726 if (!msg.skb)
1727 return -ENOMEM;
1728
1729 if (strcmp(name, tipc_bclink_name) == 0) {
1730 err = tipc_nl_add_bc_link(net, &msg);
1731 if (err) {
1732 nlmsg_free(msg.skb);
1733 return err;
1734 }
1735 } else {
1736 int bearer_id;
1737 struct tipc_node *node;
1738 struct tipc_link *link;
1739
1740 node = tipc_link_find_owner(net, name, &bearer_id);
1741 if (!node)
1742 return -EINVAL;
1743
1744 tipc_node_read_lock(node);
1745 link = node->links[bearer_id].link;
1746 if (!link) {
1747 tipc_node_read_unlock(node);
1748 nlmsg_free(msg.skb);
1749 return -EINVAL;
1750 }
1751
1752 err = __tipc_nl_add_link(net, &msg, link, 0);
1753 tipc_node_read_unlock(node);
1754 if (err) {
1755 nlmsg_free(msg.skb);
1756 return err;
1757 }
1758 }
1759
1760 return genlmsg_reply(msg.skb, info);
1761}
1762
1763int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
1764{
1765 int err;
1766 char *link_name;
1767 unsigned int bearer_id;
1768 struct tipc_link *link;
1769 struct tipc_node *node;
1770 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
1771 struct net *net = sock_net(skb->sk);
1772 struct tipc_link_entry *le;
1773
1774 if (!info->attrs[TIPC_NLA_LINK])
1775 return -EINVAL;
1776
1777 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
1778 info->attrs[TIPC_NLA_LINK],
1779 tipc_nl_link_policy);
1780 if (err)
1781 return err;
1782
1783 if (!attrs[TIPC_NLA_LINK_NAME])
1784 return -EINVAL;
1785
1786 link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
1787
1788 if (strcmp(link_name, tipc_bclink_name) == 0) {
1789 err = tipc_bclink_reset_stats(net);
1790 if (err)
1791 return err;
1792 return 0;
1793 }
1794
1795 node = tipc_link_find_owner(net, link_name, &bearer_id);
1796 if (!node)
1797 return -EINVAL;
1798
1799 le = &node->links[bearer_id];
1800 tipc_node_read_lock(node);
1801 spin_lock_bh(&le->lock);
1802 link = node->links[bearer_id].link;
1803 if (!link) {
1804 spin_unlock_bh(&le->lock);
1805 tipc_node_read_unlock(node);
1806 return -EINVAL;
1807 }
1808 link_reset_statistics(link);
1809 spin_unlock_bh(&le->lock);
1810 tipc_node_read_unlock(node);
1811 return 0;
1812}
1813
1814/* Caller should hold node lock */
1815static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
1816 struct tipc_node *node, u32 *prev_link)
1817{
1818 u32 i;
1819 int err;
1820
1821 for (i = *prev_link; i < MAX_BEARERS; i++) {
1822 *prev_link = i;
1823
1824 if (!node->links[i].link)
1825 continue;
1826
1827 err = __tipc_nl_add_link(net, msg,
1828 node->links[i].link, NLM_F_MULTI);
1829 if (err)
1830 return err;
1831 }
1832 *prev_link = 0;
1833
1834 return 0;
1835}
1836
1837int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb)
1838{
1839 struct net *net = sock_net(skb->sk);
1840 struct tipc_net *tn = net_generic(net, tipc_net_id);
1841 struct tipc_node *node;
1842 struct tipc_nl_msg msg;
1843 u32 prev_node = cb->args[0];
1844 u32 prev_link = cb->args[1];
1845 int done = cb->args[2];
1846 int err;
1847
1848 if (done)
1849 return 0;
1850
1851 msg.skb = skb;
1852 msg.portid = NETLINK_CB(cb->skb).portid;
1853 msg.seq = cb->nlh->nlmsg_seq;
1854
1855 rcu_read_lock();
1856 if (prev_node) {
1857 node = tipc_node_find(net, prev_node);
1858 if (!node) {
1859 /* We never set seq or call nl_dump_check_consistent()
1860 * this means that setting prev_seq here will cause the
1861 * consistence check to fail in the netlink callback
1862 * handler. Resulting in the last NLMSG_DONE message
1863 * having the NLM_F_DUMP_INTR flag set.
1864 */
1865 cb->prev_seq = 1;
1866 goto out;
1867 }
1868 tipc_node_put(node);
1869
1870 list_for_each_entry_continue_rcu(node, &tn->node_list,
1871 list) {
1872 tipc_node_read_lock(node);
1873 err = __tipc_nl_add_node_links(net, &msg, node,
1874 &prev_link);
1875 tipc_node_read_unlock(node);
1876 if (err)
1877 goto out;
1878
1879 prev_node = node->addr;
1880 }
1881 } else {
1882 err = tipc_nl_add_bc_link(net, &msg);
1883 if (err)
1884 goto out;
1885
1886 list_for_each_entry_rcu(node, &tn->node_list, list) {
1887 tipc_node_read_lock(node);
1888 err = __tipc_nl_add_node_links(net, &msg, node,
1889 &prev_link);
1890 tipc_node_read_unlock(node);
1891 if (err)
1892 goto out;
1893
1894 prev_node = node->addr;
1895 }
1896 }
1897 done = 1;
1898out:
1899 rcu_read_unlock();
1900
1901 cb->args[0] = prev_node;
1902 cb->args[1] = prev_link;
1903 cb->args[2] = done;
1904
1905 return skb->len;
1906}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 651a1581a210..1fbed29d9a25 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -42,23 +42,8 @@
42#include "bearer.h" 42#include "bearer.h"
43#include "msg.h" 43#include "msg.h"
44 44
45/* Out-of-range value for node signature */
46#define INVALID_NODE_SIG 0x10000
47
48#define INVALID_BEARER_ID -1 45#define INVALID_BEARER_ID -1
49 46
50/* Flags used to take different actions according to flag type
51 * TIPC_NOTIFY_NODE_DOWN: notify node is down
52 * TIPC_NOTIFY_NODE_UP: notify node is up
53 * TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type
54 */
55enum {
56 TIPC_NOTIFY_NODE_DOWN = (1 << 3),
57 TIPC_NOTIFY_NODE_UP = (1 << 4),
58 TIPC_NOTIFY_LINK_UP = (1 << 6),
59 TIPC_NOTIFY_LINK_DOWN = (1 << 7)
60};
61
62/* Optional capabilities supported by this code version 47/* Optional capabilities supported by this code version
63 */ 48 */
64enum { 49enum {
@@ -67,72 +52,6 @@ enum {
67 52
68#define TIPC_NODE_CAPABILITIES TIPC_BCAST_SYNCH 53#define TIPC_NODE_CAPABILITIES TIPC_BCAST_SYNCH
69 54
70struct tipc_link_entry {
71 struct tipc_link *link;
72 spinlock_t lock; /* per-link */
73 u32 mtu;
74 struct sk_buff_head inputq;
75 struct tipc_media_addr maddr;
76};
77
78struct tipc_bclink_entry {
79 struct tipc_link *link;
80 struct sk_buff_head inputq1;
81 struct sk_buff_head arrvq;
82 struct sk_buff_head inputq2;
83 struct sk_buff_head namedq;
84};
85
86/**
87 * struct tipc_node - TIPC node structure
88 * @addr: network address of node
89 * @ref: reference counter to node object
90 * @lock: rwlock governing access to structure
91 * @net: the applicable net namespace
92 * @hash: links to adjacent nodes in unsorted hash chain
93 * @inputq: pointer to input queue containing messages for msg event
94 * @namedq: pointer to name table input queue with name table messages
95 * @active_links: bearer ids of active links, used as index into links[] array
96 * @links: array containing references to all links to node
97 * @action_flags: bit mask of different types of node actions
98 * @state: connectivity state vs peer node
99 * @sync_point: sequence number where synch/failover is finished
100 * @list: links to adjacent nodes in sorted list of cluster's nodes
101 * @working_links: number of working links to node (both active and standby)
102 * @link_cnt: number of links to node
103 * @capabilities: bitmap, indicating peer node's functional capabilities
104 * @signature: node instance identifier
105 * @link_id: local and remote bearer ids of changing link, if any
106 * @publ_list: list of publications
107 * @rcu: rcu struct for tipc_node
108 */
109struct tipc_node {
110 u32 addr;
111 struct kref kref;
112 rwlock_t lock;
113 struct net *net;
114 struct hlist_node hash;
115 int active_links[2];
116 struct tipc_link_entry links[MAX_BEARERS];
117 struct tipc_bclink_entry bc_entry;
118 int action_flags;
119 struct list_head list;
120 int state;
121 u16 sync_point;
122 int link_cnt;
123 u16 working_links;
124 u16 capabilities;
125 u32 signature;
126 u32 link_id;
127 struct list_head publ_list;
128 struct list_head conn_sks;
129 unsigned long keepalive_intv;
130 struct timer_list timer;
131 struct rcu_head rcu;
132};
133
134struct tipc_node *tipc_node_find(struct net *net, u32 addr);
135void tipc_node_put(struct tipc_node *node);
136void tipc_node_stop(struct net *net); 55void tipc_node_stop(struct net *net);
137void tipc_node_check_dest(struct net *net, u32 onode, 56void tipc_node_check_dest(struct net *net, u32 onode,
138 struct tipc_bearer *bearer, 57 struct tipc_bearer *bearer,
@@ -140,13 +59,8 @@ void tipc_node_check_dest(struct net *net, u32 onode,
140 struct tipc_media_addr *maddr, 59 struct tipc_media_addr *maddr,
141 bool *respond, bool *dupl_addr); 60 bool *respond, bool *dupl_addr);
142void tipc_node_delete_links(struct net *net, int bearer_id); 61void tipc_node_delete_links(struct net *net, int bearer_id);
143void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
144void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
145bool tipc_node_is_up(struct tipc_node *n);
146int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, 62int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node,
147 char *linkname, size_t len); 63 char *linkname, size_t len);
148void tipc_node_read_lock(struct tipc_node *n);
149void tipc_node_read_unlock(struct tipc_node *node);
150int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, 64int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
151 int selector); 65 int selector);
152int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest, 66int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest,
@@ -156,33 +70,10 @@ void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr);
156void tipc_node_broadcast(struct net *net, struct sk_buff *skb); 70void tipc_node_broadcast(struct net *net, struct sk_buff *skb);
157int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port); 71int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port);
158void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port); 72void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port);
73int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel);
159int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb); 74int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb);
160 75int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info);
161static inline struct tipc_link *node_active_link(struct tipc_node *n, int sel) 76int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info);
162{ 77int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info);
163 int bearer_id = n->active_links[sel & 1];
164
165 if (unlikely(bearer_id == INVALID_BEARER_ID))
166 return NULL;
167
168 return n->links[bearer_id].link;
169}
170
171static inline unsigned int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel)
172{
173 struct tipc_node *n;
174 int bearer_id;
175 unsigned int mtu = MAX_MSG_SIZE;
176
177 n = tipc_node_find(net, addr);
178 if (unlikely(!n))
179 return mtu;
180
181 bearer_id = n->active_links[sel & 1];
182 if (likely(bearer_id != INVALID_BEARER_ID))
183 mtu = n->links[bearer_id].mtu;
184 tipc_node_put(n);
185 return mtu;
186}
187 78
188#endif 79#endif