aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorParthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>2016-07-26 02:47:22 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-26 17:26:42 -0400
commitcf6f7e1d51090772d5ff7355aaf0fcff17f20d1a (patch)
treef80b57ee326824ceda895bab95b821eb14b9b9d1
parentff0d3e78a67a8edd09688f073361de9ed8abf9dc (diff)
tipc: dump monitor attributes
In this commit, we dump the monitor attributes when queried. The link monitor attributes are separated into two kinds: 1. general attributes per bearer 2. specific attributes per node/peer This style resembles the socket attributes and the nametable publications per socket. Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/tipc_netlink.h25
-rw-r--r--net/tipc/monitor.c133
-rw-r--r--net/tipc/monitor.h6
-rw-r--r--net/tipc/netlink.c7
-rw-r--r--net/tipc/node.c86
-rw-r--r--net/tipc/node.h3
6 files changed, 260 insertions, 0 deletions
diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h
index d07c6ec76062..5f3f6d09fb79 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -58,6 +58,7 @@ enum {
58 TIPC_NL_NAME_TABLE_GET, 58 TIPC_NL_NAME_TABLE_GET,
59 TIPC_NL_MON_SET, 59 TIPC_NL_MON_SET,
60 TIPC_NL_MON_GET, 60 TIPC_NL_MON_GET,
61 TIPC_NL_MON_PEER_GET,
61 62
62 __TIPC_NL_CMD_MAX, 63 __TIPC_NL_CMD_MAX,
63 TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 64 TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -75,6 +76,7 @@ enum {
75 TIPC_NLA_NET, /* nest */ 76 TIPC_NLA_NET, /* nest */
76 TIPC_NLA_NAME_TABLE, /* nest */ 77 TIPC_NLA_NAME_TABLE, /* nest */
77 TIPC_NLA_MON, /* nest */ 78 TIPC_NLA_MON, /* nest */
79 TIPC_NLA_MON_PEER, /* nest */
78 80
79 __TIPC_NLA_MAX, 81 __TIPC_NLA_MAX,
80 TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 82 TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -173,6 +175,11 @@ enum {
173enum { 175enum {
174 TIPC_NLA_MON_UNSPEC, 176 TIPC_NLA_MON_UNSPEC,
175 TIPC_NLA_MON_ACTIVATION_THRESHOLD, /* u32 */ 177 TIPC_NLA_MON_ACTIVATION_THRESHOLD, /* u32 */
178 TIPC_NLA_MON_REF, /* u32 */
179 TIPC_NLA_MON_ACTIVE, /* flag */
180 TIPC_NLA_MON_BEARER_NAME, /* string */
181 TIPC_NLA_MON_PEERCNT, /* u32 */
182 TIPC_NLA_MON_LISTGEN, /* u32 */
176 183
177 __TIPC_NLA_MON_MAX, 184 __TIPC_NLA_MON_MAX,
178 TIPC_NLA_MON_MAX = __TIPC_NLA_MON_MAX - 1 185 TIPC_NLA_MON_MAX = __TIPC_NLA_MON_MAX - 1
@@ -194,6 +201,24 @@ enum {
194 TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1 201 TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1
195}; 202};
196 203
204/* Monitor peer info */
205enum {
206 TIPC_NLA_MON_PEER_UNSPEC,
207
208 TIPC_NLA_MON_PEER_ADDR, /* u32 */
209 TIPC_NLA_MON_PEER_DOMGEN, /* u32 */
210 TIPC_NLA_MON_PEER_APPLIED, /* u32 */
211 TIPC_NLA_MON_PEER_UPMAP, /* u64 */
212 TIPC_NLA_MON_PEER_MEMBERS, /* tlv */
213 TIPC_NLA_MON_PEER_UP, /* flag */
214 TIPC_NLA_MON_PEER_HEAD, /* flag */
215 TIPC_NLA_MON_PEER_LOCAL, /* flag */
216 TIPC_NLA_MON_PEER_PAD, /* flag */
217
218 __TIPC_NLA_MON_PEER_MAX,
219 TIPC_NLA_MON_PEER_MAX = __TIPC_NLA_MON_PEER_MAX - 1
220};
221
197/* Nest, connection info */ 222/* Nest, connection info */
198enum { 223enum {
199 TIPC_NLA_CON_UNSPEC, 224 TIPC_NLA_CON_UNSPEC,
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
index 3579126e2ac8..be70a57c1ff9 100644
--- a/net/tipc/monitor.c
+++ b/net/tipc/monitor.c
@@ -33,9 +33,11 @@
33 * POSSIBILITY OF SUCH DAMAGE. 33 * POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36#include <net/genetlink.h>
36#include "core.h" 37#include "core.h"
37#include "addr.h" 38#include "addr.h"
38#include "monitor.h" 39#include "monitor.h"
40#include "bearer.h"
39 41
40#define MAX_MON_DOMAIN 64 42#define MAX_MON_DOMAIN 64
41#define MON_TIMEOUT 120000 43#define MON_TIMEOUT 120000
@@ -668,3 +670,134 @@ int tipc_nl_monitor_get_threshold(struct net *net)
668 670
669 return tn->mon_threshold; 671 return tn->mon_threshold;
670} 672}
673
674int __tipc_nl_add_monitor_peer(struct tipc_peer *peer, struct tipc_nl_msg *msg)
675{
676 struct tipc_mon_domain *dom = peer->domain;
677 struct nlattr *attrs;
678 void *hdr;
679
680 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
681 NLM_F_MULTI, TIPC_NL_MON_PEER_GET);
682 if (!hdr)
683 return -EMSGSIZE;
684
685 attrs = nla_nest_start(msg->skb, TIPC_NLA_MON_PEER);
686 if (!attrs)
687 goto msg_full;
688
689 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_ADDR, peer->addr))
690 goto attr_msg_full;
691 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_APPLIED, peer->applied))
692 goto attr_msg_full;
693
694 if (peer->is_up)
695 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_UP))
696 goto attr_msg_full;
697 if (peer->is_local)
698 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_LOCAL))
699 goto attr_msg_full;
700 if (peer->is_head)
701 if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_HEAD))
702 goto attr_msg_full;
703
704 if (dom) {
705 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_DOMGEN, dom->gen))
706 goto attr_msg_full;
707 if (nla_put_u64_64bit(msg->skb, TIPC_NLA_MON_PEER_UPMAP,
708 dom->up_map, TIPC_NLA_MON_PEER_PAD))
709 goto attr_msg_full;
710 if (nla_put(msg->skb, TIPC_NLA_MON_PEER_MEMBERS,
711 dom->member_cnt * sizeof(u32), &dom->members))
712 goto attr_msg_full;
713 }
714
715 nla_nest_end(msg->skb, attrs);
716 genlmsg_end(msg->skb, hdr);
717 return 0;
718
719attr_msg_full:
720 nla_nest_cancel(msg->skb, attrs);
721msg_full:
722 genlmsg_cancel(msg->skb, hdr);
723
724 return -EMSGSIZE;
725}
726
727int tipc_nl_add_monitor_peer(struct net *net, struct tipc_nl_msg *msg,
728 u32 bearer_id, u32 *prev_node)
729{
730 struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
731 struct tipc_peer *peer = mon->self;
732
733 if (!mon)
734 return -EINVAL;
735
736 read_lock_bh(&mon->lock);
737 do {
738 if (*prev_node) {
739 if (peer->addr == *prev_node)
740 *prev_node = 0;
741 else
742 continue;
743 }
744 if (__tipc_nl_add_monitor_peer(peer, msg)) {
745 *prev_node = peer->addr;
746 read_unlock_bh(&mon->lock);
747 return -EMSGSIZE;
748 }
749 } while ((peer = peer_nxt(peer)) != mon->self);
750 read_unlock_bh(&mon->lock);
751
752 return 0;
753}
754
755int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg,
756 u32 bearer_id)
757{
758 struct tipc_monitor *mon = tipc_monitor(net, bearer_id);
759 char bearer_name[TIPC_MAX_BEARER_NAME];
760 struct nlattr *attrs;
761 void *hdr;
762 int ret;
763
764 ret = tipc_bearer_get_name(net, bearer_name, bearer_id);
765 if (ret || !mon)
766 return -EINVAL;
767
768 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
769 NLM_F_MULTI, TIPC_NL_MON_GET);
770 if (!hdr)
771 return -EMSGSIZE;
772
773 attrs = nla_nest_start(msg->skb, TIPC_NLA_MON);
774 if (!attrs)
775 goto msg_full;
776
777 read_lock_bh(&mon->lock);
778 if (nla_put_u32(msg->skb, TIPC_NLA_MON_REF, bearer_id))
779 goto attr_msg_full;
780 if (tipc_mon_is_active(net, mon))
781 if (nla_put_flag(msg->skb, TIPC_NLA_MON_ACTIVE))
782 goto attr_msg_full;
783 if (nla_put_string(msg->skb, TIPC_NLA_MON_BEARER_NAME, bearer_name))
784 goto attr_msg_full;
785 if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEERCNT, mon->peer_cnt))
786 goto attr_msg_full;
787 if (nla_put_u32(msg->skb, TIPC_NLA_MON_LISTGEN, mon->list_gen))
788 goto attr_msg_full;
789
790 read_unlock_bh(&mon->lock);
791 nla_nest_end(msg->skb, attrs);
792 genlmsg_end(msg->skb, hdr);
793
794 return 0;
795
796attr_msg_full:
797 nla_nest_cancel(msg->skb, attrs);
798msg_full:
799 genlmsg_cancel(msg->skb, hdr);
800 read_unlock_bh(&mon->lock);
801
802 return -EMSGSIZE;
803}
diff --git a/net/tipc/monitor.h b/net/tipc/monitor.h
index aedf62c60bd3..2a21b93e0d04 100644
--- a/net/tipc/monitor.h
+++ b/net/tipc/monitor.h
@@ -36,6 +36,8 @@
36#ifndef _TIPC_MONITOR_H 36#ifndef _TIPC_MONITOR_H
37#define _TIPC_MONITOR_H 37#define _TIPC_MONITOR_H
38 38
39#include "netlink.h"
40
39/* struct tipc_mon_state: link instance's cache of monitor list and domain state 41/* struct tipc_mon_state: link instance's cache of monitor list and domain state
40 * @list_gen: current generation of this node's monitor list 42 * @list_gen: current generation of this node's monitor list
41 * @gen: current generation of this node's local domain 43 * @gen: current generation of this node's local domain
@@ -71,6 +73,10 @@ void tipc_mon_remove_peer(struct net *net, u32 addr, int bearer_id);
71 73
72int tipc_nl_monitor_set_threshold(struct net *net, u32 cluster_size); 74int tipc_nl_monitor_set_threshold(struct net *net, u32 cluster_size);
73int tipc_nl_monitor_get_threshold(struct net *net); 75int tipc_nl_monitor_get_threshold(struct net *net);
76int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg,
77 u32 bearer_id);
78int tipc_nl_add_monitor_peer(struct net *net, struct tipc_nl_msg *msg,
79 u32 bearer_id, u32 *prev_node);
74 80
75extern const int tipc_max_domain_size; 81extern const int tipc_max_domain_size;
76#endif 82#endif
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 2cfc5f7c6380..a84daec0afe9 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -64,6 +64,7 @@ tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = {
64 64
65const struct nla_policy tipc_nl_monitor_policy[TIPC_NLA_MON_MAX + 1] = { 65const struct nla_policy tipc_nl_monitor_policy[TIPC_NLA_MON_MAX + 1] = {
66 [TIPC_NLA_MON_UNSPEC] = { .type = NLA_UNSPEC }, 66 [TIPC_NLA_MON_UNSPEC] = { .type = NLA_UNSPEC },
67 [TIPC_NLA_MON_REF] = { .type = NLA_U32 },
67 [TIPC_NLA_MON_ACTIVATION_THRESHOLD] = { .type = NLA_U32 }, 68 [TIPC_NLA_MON_ACTIVATION_THRESHOLD] = { .type = NLA_U32 },
68}; 69};
69 70
@@ -229,6 +230,12 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
229 { 230 {
230 .cmd = TIPC_NL_MON_GET, 231 .cmd = TIPC_NL_MON_GET,
231 .doit = tipc_nl_node_get_monitor, 232 .doit = tipc_nl_node_get_monitor,
233 .dumpit = tipc_nl_node_dump_monitor,
234 .policy = tipc_nl_policy,
235 },
236 {
237 .cmd = TIPC_NL_MON_PEER_GET,
238 .dumpit = tipc_nl_node_dump_monitor_peer,
232 .policy = tipc_nl_policy, 239 .policy = tipc_nl_policy,
233 }, 240 },
234}; 241};
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 2a7e74753f9f..21974191e425 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -2007,3 +2007,89 @@ int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info)
2007 2007
2008 return genlmsg_reply(msg.skb, info); 2008 return genlmsg_reply(msg.skb, info);
2009} 2009}
2010
2011int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb)
2012{
2013 struct net *net = sock_net(skb->sk);
2014 u32 prev_bearer = cb->args[0];
2015 struct tipc_nl_msg msg;
2016 int err;
2017 int i;
2018
2019 if (prev_bearer == MAX_BEARERS)
2020 return 0;
2021
2022 msg.skb = skb;
2023 msg.portid = NETLINK_CB(cb->skb).portid;
2024 msg.seq = cb->nlh->nlmsg_seq;
2025
2026 rtnl_lock();
2027 for (i = prev_bearer; i < MAX_BEARERS; i++) {
2028 prev_bearer = i;
2029 err = __tipc_nl_add_monitor(net, &msg, prev_bearer);
2030 if (err)
2031 goto out;
2032 }
2033
2034out:
2035 rtnl_unlock();
2036 cb->args[0] = prev_bearer;
2037
2038 return skb->len;
2039}
2040
2041int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb,
2042 struct netlink_callback *cb)
2043{
2044 struct net *net = sock_net(skb->sk);
2045 u32 prev_node = cb->args[1];
2046 u32 bearer_id = cb->args[2];
2047 int done = cb->args[0];
2048 struct tipc_nl_msg msg;
2049 int err;
2050
2051 if (!prev_node) {
2052 struct nlattr **attrs;
2053 struct nlattr *mon[TIPC_NLA_MON_MAX + 1];
2054
2055 err = tipc_nlmsg_parse(cb->nlh, &attrs);
2056 if (err)
2057 return err;
2058
2059 if (!attrs[TIPC_NLA_MON])
2060 return -EINVAL;
2061
2062 err = nla_parse_nested(mon, TIPC_NLA_MON_MAX,
2063 attrs[TIPC_NLA_MON],
2064 tipc_nl_monitor_policy);
2065 if (err)
2066 return err;
2067
2068 if (!mon[TIPC_NLA_MON_REF])
2069 return -EINVAL;
2070
2071 bearer_id = nla_get_u32(mon[TIPC_NLA_MON_REF]);
2072
2073 if (bearer_id >= MAX_BEARERS)
2074 return -EINVAL;
2075 }
2076
2077 if (done)
2078 return 0;
2079
2080 msg.skb = skb;
2081 msg.portid = NETLINK_CB(cb->skb).portid;
2082 msg.seq = cb->nlh->nlmsg_seq;
2083
2084 rtnl_lock();
2085 err = tipc_nl_add_monitor_peer(net, &msg, bearer_id, &prev_node);
2086 if (!err)
2087 done = 1;
2088
2089 rtnl_unlock();
2090 cb->args[0] = done;
2091 cb->args[1] = prev_node;
2092 cb->args[2] = bearer_id;
2093
2094 return skb->len;
2095}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 216f053b817f..d69fdfcc0ec9 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -80,4 +80,7 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info);
80 80
81int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info); 81int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info);
82int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info); 82int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info);
83int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb);
84int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb,
85 struct netlink_callback *cb);
83#endif 86#endif