summaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
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 /net/tipc/link.c
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>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c337
1 files changed, 3 insertions, 334 deletions
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}