diff options
| author | Richard Alpe <richard.alpe@ericsson.com> | 2015-02-09 03:50:11 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-02-09 16:20:48 -0500 |
| commit | 487d2a3a1326d339ce273ffbcd03247f2b7b052e (patch) | |
| tree | 6ffa649e50216a6a894cf4fe0143b587ee2e190d | |
| parent | 44a8ae94fd5525aa06a8c71cb52efbc418fb8b7c (diff) | |
tipc: convert legacy nl socket dump to nl compat
Convert socket (port) listing to compat dumpit call. If a socket
(port) has publications a second dumpit call is issued to collect them
and format then into the legacy buffer before continuing to process
the sockets (ports).
Command converted in this patch:
TIPC_CMD_SHOW_PORTS
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/tipc/config.c | 3 | ||||
| -rw-r--r-- | net/tipc/netlink_compat.c | 111 | ||||
| -rw-r--r-- | net/tipc/socket.c | 85 | ||||
| -rw-r--r-- | net/tipc/socket.h | 1 |
4 files changed, 111 insertions, 89 deletions
diff --git a/net/tipc/config.c b/net/tipc/config.c index 7b053fcc4b87..6e4c215879c8 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c | |||
| @@ -212,9 +212,6 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, | |||
| 212 | case TIPC_CMD_GET_MEDIA_NAMES: | 212 | case TIPC_CMD_GET_MEDIA_NAMES: |
| 213 | rep_tlv_buf = tipc_media_get_names(); | 213 | rep_tlv_buf = tipc_media_get_names(); |
| 214 | break; | 214 | break; |
| 215 | case TIPC_CMD_SHOW_PORTS: | ||
| 216 | rep_tlv_buf = tipc_sk_socks_show(net); | ||
| 217 | break; | ||
| 218 | case TIPC_CMD_SHOW_STATS: | 215 | case TIPC_CMD_SHOW_STATS: |
| 219 | rep_tlv_buf = tipc_show_stats(); | 216 | rep_tlv_buf = tipc_show_stats(); |
| 220 | break; | 217 | break; |
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 40c24ea31231..48e15a4a36d8 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include "bearer.h" | 36 | #include "bearer.h" |
| 37 | #include "link.h" | 37 | #include "link.h" |
| 38 | #include "name_table.h" | 38 | #include "name_table.h" |
| 39 | #include "socket.h" | ||
| 39 | #include <net/genetlink.h> | 40 | #include <net/genetlink.h> |
| 40 | #include <linux/tipc_config.h> | 41 | #include <linux/tipc_config.h> |
| 41 | 42 | ||
| @@ -718,6 +719,109 @@ out: | |||
| 718 | return 0; | 719 | return 0; |
| 719 | } | 720 | } |
| 720 | 721 | ||
| 722 | static int __tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, | ||
| 723 | struct nlattr **attrs) | ||
| 724 | { | ||
| 725 | u32 type, lower, upper; | ||
| 726 | struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1]; | ||
| 727 | |||
| 728 | nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, attrs[TIPC_NLA_PUBL], NULL); | ||
| 729 | |||
| 730 | type = nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]); | ||
| 731 | lower = nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]); | ||
| 732 | upper = nla_get_u32(publ[TIPC_NLA_PUBL_UPPER]); | ||
| 733 | |||
| 734 | if (lower == upper) | ||
| 735 | tipc_tlv_sprintf(msg->rep, " {%u,%u}", type, lower); | ||
| 736 | else | ||
| 737 | tipc_tlv_sprintf(msg->rep, " {%u,%u,%u}", type, lower, upper); | ||
| 738 | |||
| 739 | return 0; | ||
| 740 | } | ||
| 741 | |||
| 742 | static int tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, u32 sock) | ||
| 743 | { | ||
| 744 | int err; | ||
| 745 | void *hdr; | ||
| 746 | struct nlattr *nest; | ||
| 747 | struct sk_buff *args; | ||
| 748 | struct tipc_nl_compat_cmd_dump dump; | ||
| 749 | |||
| 750 | args = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
| 751 | if (!args) | ||
| 752 | return -ENOMEM; | ||
| 753 | |||
| 754 | hdr = genlmsg_put(args, 0, 0, &tipc_genl_family, NLM_F_MULTI, | ||
| 755 | TIPC_NL_PUBL_GET); | ||
| 756 | |||
| 757 | nest = nla_nest_start(args, TIPC_NLA_SOCK); | ||
| 758 | if (!nest) { | ||
| 759 | kfree_skb(args); | ||
| 760 | return -EMSGSIZE; | ||
| 761 | } | ||
| 762 | |||
| 763 | if (nla_put_u32(args, TIPC_NLA_SOCK_REF, sock)) { | ||
| 764 | kfree_skb(args); | ||
| 765 | return -EMSGSIZE; | ||
| 766 | } | ||
| 767 | |||
| 768 | nla_nest_end(args, nest); | ||
| 769 | genlmsg_end(args, hdr); | ||
| 770 | |||
| 771 | dump.dumpit = tipc_nl_publ_dump; | ||
| 772 | dump.format = __tipc_nl_compat_publ_dump; | ||
| 773 | |||
| 774 | err = __tipc_nl_compat_dumpit(&dump, msg, args); | ||
| 775 | |||
| 776 | kfree_skb(args); | ||
| 777 | |||
| 778 | return err; | ||
| 779 | } | ||
| 780 | |||
| 781 | static int tipc_nl_compat_sk_dump(struct tipc_nl_compat_msg *msg, | ||
| 782 | struct nlattr **attrs) | ||
| 783 | { | ||
| 784 | int err; | ||
| 785 | u32 sock_ref; | ||
| 786 | struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1]; | ||
| 787 | |||
| 788 | nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, attrs[TIPC_NLA_SOCK], NULL); | ||
| 789 | |||
| 790 | sock_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]); | ||
| 791 | tipc_tlv_sprintf(msg->rep, "%u:", sock_ref); | ||
| 792 | |||
| 793 | if (sock[TIPC_NLA_SOCK_CON]) { | ||
| 794 | u32 node; | ||
| 795 | struct nlattr *con[TIPC_NLA_CON_MAX + 1]; | ||
| 796 | |||
| 797 | nla_parse_nested(con, TIPC_NLA_CON_MAX, sock[TIPC_NLA_SOCK_CON], | ||
| 798 | NULL); | ||
| 799 | |||
| 800 | node = nla_get_u32(con[TIPC_NLA_CON_NODE]); | ||
| 801 | tipc_tlv_sprintf(msg->rep, " connected to <%u.%u.%u:%u>", | ||
| 802 | tipc_zone(node), | ||
| 803 | tipc_cluster(node), | ||
| 804 | tipc_node(node), | ||
| 805 | nla_get_u32(con[TIPC_NLA_CON_SOCK])); | ||
| 806 | |||
| 807 | if (con[TIPC_NLA_CON_FLAG]) | ||
| 808 | tipc_tlv_sprintf(msg->rep, " via {%u,%u}\n", | ||
| 809 | nla_get_u32(con[TIPC_NLA_CON_TYPE]), | ||
| 810 | nla_get_u32(con[TIPC_NLA_CON_INST])); | ||
| 811 | else | ||
| 812 | tipc_tlv_sprintf(msg->rep, "\n"); | ||
| 813 | } else if (sock[TIPC_NLA_SOCK_HAS_PUBL]) { | ||
| 814 | tipc_tlv_sprintf(msg->rep, " bound to"); | ||
| 815 | |||
| 816 | err = tipc_nl_compat_publ_dump(msg, sock_ref); | ||
| 817 | if (err) | ||
| 818 | return err; | ||
| 819 | } | ||
| 820 | tipc_tlv_sprintf(msg->rep, "\n"); | ||
| 821 | |||
| 822 | return 0; | ||
| 823 | } | ||
| 824 | |||
| 721 | static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) | 825 | static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) |
| 722 | { | 826 | { |
| 723 | struct tipc_nl_compat_cmd_dump dump; | 827 | struct tipc_nl_compat_cmd_dump dump; |
| @@ -775,6 +879,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) | |||
| 775 | dump.dumpit = tipc_nl_name_table_dump; | 879 | dump.dumpit = tipc_nl_name_table_dump; |
| 776 | dump.format = tipc_nl_compat_name_table_dump; | 880 | dump.format = tipc_nl_compat_name_table_dump; |
| 777 | return tipc_nl_compat_dumpit(&dump, msg); | 881 | return tipc_nl_compat_dumpit(&dump, msg); |
| 882 | case TIPC_CMD_SHOW_PORTS: | ||
| 883 | msg->rep_size = ULTRA_STRING_MAX_LEN; | ||
| 884 | msg->rep_type = TIPC_TLV_ULTRA_STRING; | ||
| 885 | dump.dumpit = tipc_nl_sk_dump; | ||
| 886 | dump.format = tipc_nl_compat_sk_dump; | ||
| 887 | return tipc_nl_compat_dumpit(&dump, msg); | ||
| 778 | } | 888 | } |
| 779 | 889 | ||
| 780 | return -EOPNOTSUPP; | 890 | return -EOPNOTSUPP; |
| @@ -881,6 +991,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) | |||
| 881 | case TIPC_CMD_SET_LINK_WINDOW: | 991 | case TIPC_CMD_SET_LINK_WINDOW: |
| 882 | case TIPC_CMD_RESET_LINK_STATS: | 992 | case TIPC_CMD_RESET_LINK_STATS: |
| 883 | case TIPC_CMD_SHOW_NAME_TABLE: | 993 | case TIPC_CMD_SHOW_NAME_TABLE: |
| 994 | case TIPC_CMD_SHOW_PORTS: | ||
| 884 | return tipc_nl_compat_recv(skb, info); | 995 | return tipc_nl_compat_recv(skb, info); |
| 885 | } | 996 | } |
| 886 | 997 | ||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index d76c171f7b7e..e77d738bb771 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -2281,91 +2281,6 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | |||
| 2281 | return rc; | 2281 | return rc; |
| 2282 | } | 2282 | } |
| 2283 | 2283 | ||
| 2284 | static int tipc_sk_show(struct tipc_sock *tsk, char *buf, | ||
| 2285 | int len, int full_id) | ||
| 2286 | { | ||
| 2287 | struct net *net = sock_net(&tsk->sk); | ||
| 2288 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 2289 | struct publication *publ; | ||
| 2290 | int ret; | ||
| 2291 | |||
| 2292 | if (full_id) | ||
| 2293 | ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:", | ||
| 2294 | tipc_zone(tn->own_addr), | ||
| 2295 | tipc_cluster(tn->own_addr), | ||
| 2296 | tipc_node(tn->own_addr), tsk->portid); | ||
| 2297 | else | ||
| 2298 | ret = tipc_snprintf(buf, len, "%-10u:", tsk->portid); | ||
| 2299 | |||
| 2300 | if (tsk->connected) { | ||
| 2301 | u32 dport = tsk_peer_port(tsk); | ||
| 2302 | u32 destnode = tsk_peer_node(tsk); | ||
| 2303 | |||
| 2304 | ret += tipc_snprintf(buf + ret, len - ret, | ||
| 2305 | " connected to <%u.%u.%u:%u>", | ||
| 2306 | tipc_zone(destnode), | ||
| 2307 | tipc_cluster(destnode), | ||
| 2308 | tipc_node(destnode), dport); | ||
| 2309 | if (tsk->conn_type != 0) | ||
| 2310 | ret += tipc_snprintf(buf + ret, len - ret, | ||
| 2311 | " via {%u,%u}", tsk->conn_type, | ||
| 2312 | tsk->conn_instance); | ||
| 2313 | } else if (tsk->published) { | ||
| 2314 | ret += tipc_snprintf(buf + ret, len - ret, " bound to"); | ||
| 2315 | list_for_each_entry(publ, &tsk->publications, pport_list) { | ||
| 2316 | if (publ->lower == publ->upper) | ||
| 2317 | ret += tipc_snprintf(buf + ret, len - ret, | ||
| 2318 | " {%u,%u}", publ->type, | ||
| 2319 | publ->lower); | ||
| 2320 | else | ||
| 2321 | ret += tipc_snprintf(buf + ret, len - ret, | ||
| 2322 | " {%u,%u,%u}", publ->type, | ||
| 2323 | publ->lower, publ->upper); | ||
| 2324 | } | ||
| 2325 | } | ||
| 2326 | ret += tipc_snprintf(buf + ret, len - ret, "\n"); | ||
| 2327 | return ret; | ||
| 2328 | } | ||
| 2329 | |||
| 2330 | struct sk_buff *tipc_sk_socks_show(struct net *net) | ||
| 2331 | { | ||
| 2332 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 2333 | const struct bucket_table *tbl; | ||
| 2334 | struct rhash_head *pos; | ||
| 2335 | struct sk_buff *buf; | ||
| 2336 | struct tlv_desc *rep_tlv; | ||
| 2337 | char *pb; | ||
| 2338 | int pb_len; | ||
| 2339 | struct tipc_sock *tsk; | ||
| 2340 | int str_len = 0; | ||
| 2341 | int i; | ||
| 2342 | |||
| 2343 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); | ||
| 2344 | if (!buf) | ||
| 2345 | return NULL; | ||
| 2346 | rep_tlv = (struct tlv_desc *)buf->data; | ||
| 2347 | pb = TLV_DATA(rep_tlv); | ||
| 2348 | pb_len = ULTRA_STRING_MAX_LEN; | ||
| 2349 | |||
| 2350 | rcu_read_lock(); | ||
| 2351 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); | ||
| 2352 | for (i = 0; i < tbl->size; i++) { | ||
| 2353 | rht_for_each_entry_rcu(tsk, pos, tbl, i, node) { | ||
| 2354 | spin_lock_bh(&tsk->sk.sk_lock.slock); | ||
| 2355 | str_len += tipc_sk_show(tsk, pb + str_len, | ||
| 2356 | pb_len - str_len, 0); | ||
| 2357 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
| 2358 | } | ||
| 2359 | } | ||
| 2360 | rcu_read_unlock(); | ||
| 2361 | |||
| 2362 | str_len += 1; /* for "\0" */ | ||
| 2363 | skb_put(buf, TLV_SPACE(str_len)); | ||
| 2364 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | ||
| 2365 | |||
| 2366 | return buf; | ||
| 2367 | } | ||
| 2368 | |||
| 2369 | /* tipc_sk_reinit: set non-zero address in all existing sockets | 2284 | /* tipc_sk_reinit: set non-zero address in all existing sockets |
| 2370 | * when we go from standalone to network mode. | 2285 | * when we go from standalone to network mode. |
| 2371 | */ | 2286 | */ |
diff --git a/net/tipc/socket.h b/net/tipc/socket.h index 8be0da7df8fc..238f1b7bd9bd 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h | |||
| @@ -49,7 +49,6 @@ void tipc_sock_release_local(struct socket *sock); | |||
| 49 | int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, | 49 | int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, |
| 50 | int flags); | 50 | int flags); |
| 51 | int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); | 51 | int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); |
| 52 | struct sk_buff *tipc_sk_socks_show(struct net *net); | ||
| 53 | void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, | 52 | void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, |
| 54 | struct sk_buff_head *inputq); | 53 | struct sk_buff_head *inputq); |
| 55 | void tipc_sk_reinit(struct net *net); | 54 | void tipc_sk_reinit(struct net *net); |
