aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorRichard Alpe <richard.alpe@ericsson.com>2014-11-20 04:29:10 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-21 15:01:30 -0500
commit34b78a127c4fd57cf3d5c64031693d10a8e0fae1 (patch)
treefbba2542705341c45f9a270e46aca9b819ed17f7 /net/tipc/socket.c
parent315c00bc9f2bd17f7ad7ed8119ca49b1125af507 (diff)
tipc: add sock dump to new netlink api
Add TIPC_NL_SOCK_GET command to the new tipc netlink API. This command supports dumping of all available sockets with their associated connection or publication(s). It could be extended to reply with a single socket if the NLM_F_DUMP isn't set. The information about a socket includes reference, address, connection information / publication information. Netlink logical layout of response message: -> socket -> reference -> address [ -> connection -> node -> socket [ -> connected flag -> type -> instance ] ] [ -> publication flag ] Signed-off-by: Richard Alpe <richard.alpe@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 591bbfa082a0..9e95c1ea5564 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2801,3 +2801,104 @@ void tipc_socket_stop(void)
2801 sock_unregister(tipc_family_ops.family); 2801 sock_unregister(tipc_family_ops.family);
2802 proto_unregister(&tipc_proto); 2802 proto_unregister(&tipc_proto);
2803} 2803}
2804
2805/* Caller should hold socket lock for the passed tipc socket. */
2806int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk)
2807{
2808 u32 peer_node;
2809 u32 peer_port;
2810 struct nlattr *nest;
2811
2812 peer_node = tsk_peer_node(tsk);
2813 peer_port = tsk_peer_port(tsk);
2814
2815 nest = nla_nest_start(skb, TIPC_NLA_SOCK_CON);
2816
2817 if (nla_put_u32(skb, TIPC_NLA_CON_NODE, peer_node))
2818 goto msg_full;
2819 if (nla_put_u32(skb, TIPC_NLA_CON_SOCK, peer_port))
2820 goto msg_full;
2821
2822 if (tsk->conn_type != 0) {
2823 if (nla_put_flag(skb, TIPC_NLA_CON_FLAG))
2824 goto msg_full;
2825 if (nla_put_u32(skb, TIPC_NLA_CON_TYPE, tsk->conn_type))
2826 goto msg_full;
2827 if (nla_put_u32(skb, TIPC_NLA_CON_INST, tsk->conn_instance))
2828 goto msg_full;
2829 }
2830 nla_nest_end(skb, nest);
2831
2832 return 0;
2833
2834msg_full:
2835 nla_nest_cancel(skb, nest);
2836
2837 return -EMSGSIZE;
2838}
2839
2840/* Caller should hold socket lock for the passed tipc socket. */
2841int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
2842 struct tipc_sock *tsk)
2843{
2844 int err;
2845 void *hdr;
2846 struct nlattr *attrs;
2847
2848 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
2849 &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_SOCK_GET);
2850 if (!hdr)
2851 goto msg_cancel;
2852
2853 attrs = nla_nest_start(skb, TIPC_NLA_SOCK);
2854 if (!attrs)
2855 goto genlmsg_cancel;
2856 if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->ref))
2857 goto attr_msg_cancel;
2858 if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tipc_own_addr))
2859 goto attr_msg_cancel;
2860
2861 if (tsk->connected) {
2862 err = __tipc_nl_add_sk_con(skb, tsk);
2863 if (err)
2864 goto attr_msg_cancel;
2865 } else if (!list_empty(&tsk->publications)) {
2866 if (nla_put_flag(skb, TIPC_NLA_SOCK_HAS_PUBL))
2867 goto attr_msg_cancel;
2868 }
2869 nla_nest_end(skb, attrs);
2870 genlmsg_end(skb, hdr);
2871
2872 return 0;
2873
2874attr_msg_cancel:
2875 nla_nest_cancel(skb, attrs);
2876genlmsg_cancel:
2877 genlmsg_cancel(skb, hdr);
2878msg_cancel:
2879 return -EMSGSIZE;
2880}
2881
2882int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb)
2883{
2884 int err;
2885 struct tipc_sock *tsk;
2886 u32 prev_ref = cb->args[0];
2887 u32 ref = prev_ref;
2888
2889 tsk = tipc_sk_get_next(&ref);
2890 for (; tsk; tsk = tipc_sk_get_next(&ref)) {
2891 lock_sock(&tsk->sk);
2892 err = __tipc_nl_add_sk(skb, cb, tsk);
2893 release_sock(&tsk->sk);
2894 tipc_sk_put(tsk);
2895 if (err)
2896 break;
2897
2898 prev_ref = ref;
2899 }
2900
2901 cb->args[0] = prev_ref;
2902
2903 return skb->len;
2904}