1 #include <linux/mutex.h>
2 #include <linux/socket.h>
3 #include <linux/skbuff.h>
4 #include <net/netlink.h>
5 #include <net/net_namespace.h>
6 #include <linux/module.h>
8 #include <linux/kernel.h>
10 #include <linux/workqueue.h>
12 #include <linux/inet_diag.h>
13 #include <linux/sock_diag.h>
15 static const struct sock_diag_handler
*sock_diag_handlers
[AF_MAX
];
16 static int (*inet_rcv_compat
)(struct sk_buff
*skb
, struct nlmsghdr
*nlh
);
17 static DEFINE_MUTEX(sock_diag_table_mutex
);
18 static struct workqueue_struct
*broadcast_wq
;
20 static u64
sock_gen_cookie(struct sock
*sk
)
23 u64 res
= atomic64_read(&sk
->sk_cookie
);
27 res
= atomic64_inc_return(&sock_net(sk
)->cookie_gen
);
28 atomic64_cmpxchg(&sk
->sk_cookie
, 0, res
);
32 int sock_diag_check_cookie(struct sock
*sk
, const __u32
*cookie
)
36 if (cookie
[0] == INET_DIAG_NOCOOKIE
&& cookie
[1] == INET_DIAG_NOCOOKIE
)
39 res
= sock_gen_cookie(sk
);
40 if ((u32
)res
!= cookie
[0] || (u32
)(res
>> 32) != cookie
[1])
45 EXPORT_SYMBOL_GPL(sock_diag_check_cookie
);
47 void sock_diag_save_cookie(struct sock
*sk
, __u32
*cookie
)
49 u64 res
= sock_gen_cookie(sk
);
52 cookie
[1] = (u32
)(res
>> 32);
54 EXPORT_SYMBOL_GPL(sock_diag_save_cookie
);
56 int sock_diag_put_meminfo(struct sock
*sk
, struct sk_buff
*skb
, int attrtype
)
58 u32 mem
[SK_MEMINFO_VARS
];
60 mem
[SK_MEMINFO_RMEM_ALLOC
] = sk_rmem_alloc_get(sk
);
61 mem
[SK_MEMINFO_RCVBUF
] = sk
->sk_rcvbuf
;
62 mem
[SK_MEMINFO_WMEM_ALLOC
] = sk_wmem_alloc_get(sk
);
63 mem
[SK_MEMINFO_SNDBUF
] = sk
->sk_sndbuf
;
64 mem
[SK_MEMINFO_FWD_ALLOC
] = sk
->sk_forward_alloc
;
65 mem
[SK_MEMINFO_WMEM_QUEUED
] = sk
->sk_wmem_queued
;
66 mem
[SK_MEMINFO_OPTMEM
] = atomic_read(&sk
->sk_omem_alloc
);
67 mem
[SK_MEMINFO_BACKLOG
] = sk
->sk_backlog
.len
;
69 return nla_put(skb
, attrtype
, sizeof(mem
), &mem
);
71 EXPORT_SYMBOL_GPL(sock_diag_put_meminfo
);
73 int sock_diag_put_filterinfo(bool may_report_filterinfo
, struct sock
*sk
,
74 struct sk_buff
*skb
, int attrtype
)
76 struct sock_fprog_kern
*fprog
;
77 struct sk_filter
*filter
;
82 if (!may_report_filterinfo
) {
83 nla_reserve(skb
, attrtype
, 0);
88 filter
= rcu_dereference(sk
->sk_filter
);
92 fprog
= filter
->prog
->orig_prog
;
96 flen
= bpf_classic_proglen(fprog
);
98 attr
= nla_reserve(skb
, attrtype
, flen
);
104 memcpy(nla_data(attr
), fprog
->filter
, flen
);
109 EXPORT_SYMBOL(sock_diag_put_filterinfo
);
111 struct broadcast_sk
{
113 struct work_struct work
;
116 static size_t sock_diag_nlmsg_size(void)
118 return NLMSG_ALIGN(sizeof(struct inet_diag_msg
)
119 + nla_total_size(sizeof(u8
)) /* INET_DIAG_PROTOCOL */
120 + nla_total_size(sizeof(struct tcp_info
))); /* INET_DIAG_INFO */
123 static void sock_diag_broadcast_destroy_work(struct work_struct
*work
)
125 struct broadcast_sk
*bsk
=
126 container_of(work
, struct broadcast_sk
, work
);
127 struct sock
*sk
= bsk
->sk
;
128 const struct sock_diag_handler
*hndl
;
130 const enum sknetlink_groups group
= sock_diag_destroy_group(sk
);
133 WARN_ON(group
== SKNLGRP_NONE
);
135 skb
= nlmsg_new(sock_diag_nlmsg_size(), GFP_KERNEL
);
139 mutex_lock(&sock_diag_table_mutex
);
140 hndl
= sock_diag_handlers
[sk
->sk_family
];
141 if (hndl
&& hndl
->get_info
)
142 err
= hndl
->get_info(skb
, sk
);
143 mutex_unlock(&sock_diag_table_mutex
);
146 nlmsg_multicast(sock_net(sk
)->diag_nlsk
, skb
, 0, group
,
155 void sock_diag_broadcast_destroy(struct sock
*sk
)
157 /* Note, this function is often called from an interrupt context. */
158 struct broadcast_sk
*bsk
=
159 kmalloc(sizeof(struct broadcast_sk
), GFP_ATOMIC
);
161 return sk_destruct(sk
);
163 INIT_WORK(&bsk
->work
, sock_diag_broadcast_destroy_work
);
164 queue_work(broadcast_wq
, &bsk
->work
);
167 void sock_diag_register_inet_compat(int (*fn
)(struct sk_buff
*skb
, struct nlmsghdr
*nlh
))
169 mutex_lock(&sock_diag_table_mutex
);
170 inet_rcv_compat
= fn
;
171 mutex_unlock(&sock_diag_table_mutex
);
173 EXPORT_SYMBOL_GPL(sock_diag_register_inet_compat
);
175 void sock_diag_unregister_inet_compat(int (*fn
)(struct sk_buff
*skb
, struct nlmsghdr
*nlh
))
177 mutex_lock(&sock_diag_table_mutex
);
178 inet_rcv_compat
= NULL
;
179 mutex_unlock(&sock_diag_table_mutex
);
181 EXPORT_SYMBOL_GPL(sock_diag_unregister_inet_compat
);
183 int sock_diag_register(const struct sock_diag_handler
*hndl
)
187 if (hndl
->family
>= AF_MAX
)
190 mutex_lock(&sock_diag_table_mutex
);
191 if (sock_diag_handlers
[hndl
->family
])
194 sock_diag_handlers
[hndl
->family
] = hndl
;
195 mutex_unlock(&sock_diag_table_mutex
);
199 EXPORT_SYMBOL_GPL(sock_diag_register
);
201 void sock_diag_unregister(const struct sock_diag_handler
*hnld
)
203 int family
= hnld
->family
;
205 if (family
>= AF_MAX
)
208 mutex_lock(&sock_diag_table_mutex
);
209 BUG_ON(sock_diag_handlers
[family
] != hnld
);
210 sock_diag_handlers
[family
] = NULL
;
211 mutex_unlock(&sock_diag_table_mutex
);
213 EXPORT_SYMBOL_GPL(sock_diag_unregister
);
215 static int __sock_diag_rcv_msg(struct sk_buff
*skb
, struct nlmsghdr
*nlh
)
218 struct sock_diag_req
*req
= nlmsg_data(nlh
);
219 const struct sock_diag_handler
*hndl
;
221 if (nlmsg_len(nlh
) < sizeof(*req
))
224 if (req
->sdiag_family
>= AF_MAX
)
227 if (sock_diag_handlers
[req
->sdiag_family
] == NULL
)
228 request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK
,
229 NETLINK_SOCK_DIAG
, req
->sdiag_family
);
231 mutex_lock(&sock_diag_table_mutex
);
232 hndl
= sock_diag_handlers
[req
->sdiag_family
];
236 err
= hndl
->dump(skb
, nlh
);
237 mutex_unlock(&sock_diag_table_mutex
);
242 static int sock_diag_rcv_msg(struct sk_buff
*skb
, struct nlmsghdr
*nlh
)
246 switch (nlh
->nlmsg_type
) {
247 case TCPDIAG_GETSOCK
:
248 case DCCPDIAG_GETSOCK
:
249 if (inet_rcv_compat
== NULL
)
250 request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK
,
251 NETLINK_SOCK_DIAG
, AF_INET
);
253 mutex_lock(&sock_diag_table_mutex
);
254 if (inet_rcv_compat
!= NULL
)
255 ret
= inet_rcv_compat(skb
, nlh
);
258 mutex_unlock(&sock_diag_table_mutex
);
261 case SOCK_DIAG_BY_FAMILY
:
262 return __sock_diag_rcv_msg(skb
, nlh
);
268 static DEFINE_MUTEX(sock_diag_mutex
);
270 static void sock_diag_rcv(struct sk_buff
*skb
)
272 mutex_lock(&sock_diag_mutex
);
273 netlink_rcv_skb(skb
, &sock_diag_rcv_msg
);
274 mutex_unlock(&sock_diag_mutex
);
277 static int sock_diag_bind(struct net
*net
, int group
)
280 case SKNLGRP_INET_TCP_DESTROY
:
281 case SKNLGRP_INET_UDP_DESTROY
:
282 if (!sock_diag_handlers
[AF_INET
])
283 request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK
,
284 NETLINK_SOCK_DIAG
, AF_INET
);
286 case SKNLGRP_INET6_TCP_DESTROY
:
287 case SKNLGRP_INET6_UDP_DESTROY
:
288 if (!sock_diag_handlers
[AF_INET6
])
289 request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK
,
290 NETLINK_SOCK_DIAG
, AF_INET
);
296 static int __net_init
diag_net_init(struct net
*net
)
298 struct netlink_kernel_cfg cfg
= {
299 .groups
= SKNLGRP_MAX
,
300 .input
= sock_diag_rcv
,
301 .bind
= sock_diag_bind
,
302 .flags
= NL_CFG_F_NONROOT_RECV
,
305 net
->diag_nlsk
= netlink_kernel_create(net
, NETLINK_SOCK_DIAG
, &cfg
);
306 return net
->diag_nlsk
== NULL
? -ENOMEM
: 0;
309 static void __net_exit
diag_net_exit(struct net
*net
)
311 netlink_kernel_release(net
->diag_nlsk
);
312 net
->diag_nlsk
= NULL
;
315 static struct pernet_operations diag_net_ops
= {
316 .init
= diag_net_init
,
317 .exit
= diag_net_exit
,
320 static int __init
sock_diag_init(void)
322 broadcast_wq
= alloc_workqueue("sock_diag_events", 0, 0);
323 BUG_ON(!broadcast_wq
);
324 return register_pernet_subsys(&diag_net_ops
);
327 static void __exit
sock_diag_exit(void)
329 unregister_pernet_subsys(&diag_net_ops
);
330 destroy_workqueue(broadcast_wq
);
333 module_init(sock_diag_init
);
334 module_exit(sock_diag_exit
);
335 MODULE_LICENSE("GPL");
336 MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK
, NETLINK_SOCK_DIAG
);