diff options
author | Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> | 2016-07-26 02:47:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-26 17:26:42 -0400 |
commit | cf6f7e1d51090772d5ff7355aaf0fcff17f20d1a (patch) | |
tree | f80b57ee326824ceda895bab95b821eb14b9b9d1 | |
parent | ff0d3e78a67a8edd09688f073361de9ed8abf9dc (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.h | 25 | ||||
-rw-r--r-- | net/tipc/monitor.c | 133 | ||||
-rw-r--r-- | net/tipc/monitor.h | 6 | ||||
-rw-r--r-- | net/tipc/netlink.c | 7 | ||||
-rw-r--r-- | net/tipc/node.c | 86 | ||||
-rw-r--r-- | net/tipc/node.h | 3 |
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 { | |||
173 | enum { | 175 | enum { |
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 */ | ||
205 | enum { | ||
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 */ |
198 | enum { | 223 | enum { |
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 | |||
674 | int __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 | |||
719 | attr_msg_full: | ||
720 | nla_nest_cancel(msg->skb, attrs); | ||
721 | msg_full: | ||
722 | genlmsg_cancel(msg->skb, hdr); | ||
723 | |||
724 | return -EMSGSIZE; | ||
725 | } | ||
726 | |||
727 | int 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 | |||
755 | int __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 | |||
796 | attr_msg_full: | ||
797 | nla_nest_cancel(msg->skb, attrs); | ||
798 | msg_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 | ||
72 | int tipc_nl_monitor_set_threshold(struct net *net, u32 cluster_size); | 74 | int tipc_nl_monitor_set_threshold(struct net *net, u32 cluster_size); |
73 | int tipc_nl_monitor_get_threshold(struct net *net); | 75 | int tipc_nl_monitor_get_threshold(struct net *net); |
76 | int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg, | ||
77 | u32 bearer_id); | ||
78 | int tipc_nl_add_monitor_peer(struct net *net, struct tipc_nl_msg *msg, | ||
79 | u32 bearer_id, u32 *prev_node); | ||
74 | 80 | ||
75 | extern const int tipc_max_domain_size; | 81 | extern 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 | ||
65 | const struct nla_policy tipc_nl_monitor_policy[TIPC_NLA_MON_MAX + 1] = { | 65 | const 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 | |||
2011 | int 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 | |||
2034 | out: | ||
2035 | rtnl_unlock(); | ||
2036 | cb->args[0] = prev_bearer; | ||
2037 | |||
2038 | return skb->len; | ||
2039 | } | ||
2040 | |||
2041 | int 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 | ||
81 | int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info); | 81 | int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info); |
82 | int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info); | 82 | int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info); |
83 | int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb); | ||
84 | int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb, | ||
85 | struct netlink_callback *cb); | ||
83 | #endif | 86 | #endif |