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 |
