Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Parthasarathy Bhuvaragan and committed by
David S. Miller
cf6f7e1d ff0d3e78

+260
+25
include/uapi/linux/tipc_netlink.h
··· 58 58 TIPC_NL_NAME_TABLE_GET, 59 59 TIPC_NL_MON_SET, 60 60 TIPC_NL_MON_GET, 61 + TIPC_NL_MON_PEER_GET, 61 62 62 63 __TIPC_NL_CMD_MAX, 63 64 TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 ··· 76 75 TIPC_NLA_NET, /* nest */ 77 76 TIPC_NLA_NAME_TABLE, /* nest */ 78 77 TIPC_NLA_MON, /* nest */ 78 + TIPC_NLA_MON_PEER, /* nest */ 79 79 80 80 __TIPC_NLA_MAX, 81 81 TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 ··· 175 173 enum { 176 174 TIPC_NLA_MON_UNSPEC, 177 175 TIPC_NLA_MON_ACTIVATION_THRESHOLD, /* u32 */ 176 + TIPC_NLA_MON_REF, /* u32 */ 177 + TIPC_NLA_MON_ACTIVE, /* flag */ 178 + TIPC_NLA_MON_BEARER_NAME, /* string */ 179 + TIPC_NLA_MON_PEERCNT, /* u32 */ 180 + TIPC_NLA_MON_LISTGEN, /* u32 */ 178 181 179 182 __TIPC_NLA_MON_MAX, 180 183 TIPC_NLA_MON_MAX = __TIPC_NLA_MON_MAX - 1 ··· 199 192 200 193 __TIPC_NLA_PUBL_MAX, 201 194 TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1 195 + }; 196 + 197 + /* Monitor peer info */ 198 + enum { 199 + TIPC_NLA_MON_PEER_UNSPEC, 200 + 201 + TIPC_NLA_MON_PEER_ADDR, /* u32 */ 202 + TIPC_NLA_MON_PEER_DOMGEN, /* u32 */ 203 + TIPC_NLA_MON_PEER_APPLIED, /* u32 */ 204 + TIPC_NLA_MON_PEER_UPMAP, /* u64 */ 205 + TIPC_NLA_MON_PEER_MEMBERS, /* tlv */ 206 + TIPC_NLA_MON_PEER_UP, /* flag */ 207 + TIPC_NLA_MON_PEER_HEAD, /* flag */ 208 + TIPC_NLA_MON_PEER_LOCAL, /* flag */ 209 + TIPC_NLA_MON_PEER_PAD, /* flag */ 210 + 211 + __TIPC_NLA_MON_PEER_MAX, 212 + TIPC_NLA_MON_PEER_MAX = __TIPC_NLA_MON_PEER_MAX - 1 202 213 }; 203 214 204 215 /* Nest, connection info */
+133
net/tipc/monitor.c
··· 33 33 * POSSIBILITY OF SUCH DAMAGE. 34 34 */ 35 35 36 + #include <net/genetlink.h> 36 37 #include "core.h" 37 38 #include "addr.h" 38 39 #include "monitor.h" 40 + #include "bearer.h" 39 41 40 42 #define MAX_MON_DOMAIN 64 41 43 #define MON_TIMEOUT 120000 ··· 669 667 struct tipc_net *tn = tipc_net(net); 670 668 671 669 return tn->mon_threshold; 670 + } 671 + 672 + int __tipc_nl_add_monitor_peer(struct tipc_peer *peer, struct tipc_nl_msg *msg) 673 + { 674 + struct tipc_mon_domain *dom = peer->domain; 675 + struct nlattr *attrs; 676 + void *hdr; 677 + 678 + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, 679 + NLM_F_MULTI, TIPC_NL_MON_PEER_GET); 680 + if (!hdr) 681 + return -EMSGSIZE; 682 + 683 + attrs = nla_nest_start(msg->skb, TIPC_NLA_MON_PEER); 684 + if (!attrs) 685 + goto msg_full; 686 + 687 + if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_ADDR, peer->addr)) 688 + goto attr_msg_full; 689 + if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_APPLIED, peer->applied)) 690 + goto attr_msg_full; 691 + 692 + if (peer->is_up) 693 + if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_UP)) 694 + goto attr_msg_full; 695 + if (peer->is_local) 696 + if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_LOCAL)) 697 + goto attr_msg_full; 698 + if (peer->is_head) 699 + if (nla_put_flag(msg->skb, TIPC_NLA_MON_PEER_HEAD)) 700 + goto attr_msg_full; 701 + 702 + if (dom) { 703 + if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEER_DOMGEN, dom->gen)) 704 + goto attr_msg_full; 705 + if (nla_put_u64_64bit(msg->skb, TIPC_NLA_MON_PEER_UPMAP, 706 + dom->up_map, TIPC_NLA_MON_PEER_PAD)) 707 + goto attr_msg_full; 708 + if (nla_put(msg->skb, TIPC_NLA_MON_PEER_MEMBERS, 709 + dom->member_cnt * sizeof(u32), &dom->members)) 710 + goto attr_msg_full; 711 + } 712 + 713 + nla_nest_end(msg->skb, attrs); 714 + genlmsg_end(msg->skb, hdr); 715 + return 0; 716 + 717 + attr_msg_full: 718 + nla_nest_cancel(msg->skb, attrs); 719 + msg_full: 720 + genlmsg_cancel(msg->skb, hdr); 721 + 722 + return -EMSGSIZE; 723 + } 724 + 725 + int tipc_nl_add_monitor_peer(struct net *net, struct tipc_nl_msg *msg, 726 + u32 bearer_id, u32 *prev_node) 727 + { 728 + struct tipc_monitor *mon = tipc_monitor(net, bearer_id); 729 + struct tipc_peer *peer = mon->self; 730 + 731 + if (!mon) 732 + return -EINVAL; 733 + 734 + read_lock_bh(&mon->lock); 735 + do { 736 + if (*prev_node) { 737 + if (peer->addr == *prev_node) 738 + *prev_node = 0; 739 + else 740 + continue; 741 + } 742 + if (__tipc_nl_add_monitor_peer(peer, msg)) { 743 + *prev_node = peer->addr; 744 + read_unlock_bh(&mon->lock); 745 + return -EMSGSIZE; 746 + } 747 + } while ((peer = peer_nxt(peer)) != mon->self); 748 + read_unlock_bh(&mon->lock); 749 + 750 + return 0; 751 + } 752 + 753 + int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg, 754 + u32 bearer_id) 755 + { 756 + struct tipc_monitor *mon = tipc_monitor(net, bearer_id); 757 + char bearer_name[TIPC_MAX_BEARER_NAME]; 758 + struct nlattr *attrs; 759 + void *hdr; 760 + int ret; 761 + 762 + ret = tipc_bearer_get_name(net, bearer_name, bearer_id); 763 + if (ret || !mon) 764 + return -EINVAL; 765 + 766 + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, 767 + NLM_F_MULTI, TIPC_NL_MON_GET); 768 + if (!hdr) 769 + return -EMSGSIZE; 770 + 771 + attrs = nla_nest_start(msg->skb, TIPC_NLA_MON); 772 + if (!attrs) 773 + goto msg_full; 774 + 775 + read_lock_bh(&mon->lock); 776 + if (nla_put_u32(msg->skb, TIPC_NLA_MON_REF, bearer_id)) 777 + goto attr_msg_full; 778 + if (tipc_mon_is_active(net, mon)) 779 + if (nla_put_flag(msg->skb, TIPC_NLA_MON_ACTIVE)) 780 + goto attr_msg_full; 781 + if (nla_put_string(msg->skb, TIPC_NLA_MON_BEARER_NAME, bearer_name)) 782 + goto attr_msg_full; 783 + if (nla_put_u32(msg->skb, TIPC_NLA_MON_PEERCNT, mon->peer_cnt)) 784 + goto attr_msg_full; 785 + if (nla_put_u32(msg->skb, TIPC_NLA_MON_LISTGEN, mon->list_gen)) 786 + goto attr_msg_full; 787 + 788 + read_unlock_bh(&mon->lock); 789 + nla_nest_end(msg->skb, attrs); 790 + genlmsg_end(msg->skb, hdr); 791 + 792 + return 0; 793 + 794 + attr_msg_full: 795 + nla_nest_cancel(msg->skb, attrs); 796 + msg_full: 797 + genlmsg_cancel(msg->skb, hdr); 798 + read_unlock_bh(&mon->lock); 799 + 800 + return -EMSGSIZE; 672 801 }
+6
net/tipc/monitor.h
··· 36 36 #ifndef _TIPC_MONITOR_H 37 37 #define _TIPC_MONITOR_H 38 38 39 + #include "netlink.h" 40 + 39 41 /* struct tipc_mon_state: link instance's cache of monitor list and domain state 40 42 * @list_gen: current generation of this node's monitor list 41 43 * @gen: current generation of this node's local domain ··· 73 71 74 72 int tipc_nl_monitor_set_threshold(struct net *net, u32 cluster_size); 75 73 int tipc_nl_monitor_get_threshold(struct net *net); 74 + int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg, 75 + u32 bearer_id); 76 + int tipc_nl_add_monitor_peer(struct net *net, struct tipc_nl_msg *msg, 77 + u32 bearer_id, u32 *prev_node); 76 78 77 79 extern const int tipc_max_domain_size; 78 80 #endif
+7
net/tipc/netlink.c
··· 64 64 65 65 const struct nla_policy tipc_nl_monitor_policy[TIPC_NLA_MON_MAX + 1] = { 66 66 [TIPC_NLA_MON_UNSPEC] = { .type = NLA_UNSPEC }, 67 + [TIPC_NLA_MON_REF] = { .type = NLA_U32 }, 67 68 [TIPC_NLA_MON_ACTIVATION_THRESHOLD] = { .type = NLA_U32 }, 68 69 }; 69 70 ··· 230 229 { 231 230 .cmd = TIPC_NL_MON_GET, 232 231 .doit = tipc_nl_node_get_monitor, 232 + .dumpit = tipc_nl_node_dump_monitor, 233 + .policy = tipc_nl_policy, 234 + }, 235 + { 236 + .cmd = TIPC_NL_MON_PEER_GET, 237 + .dumpit = tipc_nl_node_dump_monitor_peer, 233 238 .policy = tipc_nl_policy, 234 239 }, 235 240 };
+86
net/tipc/node.c
··· 2007 2007 2008 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 + }
+3
net/tipc/node.h
··· 80 80 81 81 int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info); 82 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 86 #endif