18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci#include <linux/types.h> 38c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 48c2ecf20Sopenharmony_ci#include <linux/sock_diag.h> 58c2ecf20Sopenharmony_ci#include <linux/unix_diag.h> 68c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 78c2ecf20Sopenharmony_ci#include <linux/module.h> 88c2ecf20Sopenharmony_ci#include <linux/uidgid.h> 98c2ecf20Sopenharmony_ci#include <net/netlink.h> 108c2ecf20Sopenharmony_ci#include <net/af_unix.h> 118c2ecf20Sopenharmony_ci#include <net/tcp_states.h> 128c2ecf20Sopenharmony_ci#include <net/sock.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci /* might or might not have unix_table_lock */ 178c2ecf20Sopenharmony_ci struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci if (!addr) 208c2ecf20Sopenharmony_ci return 0; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci return nla_put(nlskb, UNIX_DIAG_NAME, addr->len - sizeof(short), 238c2ecf20Sopenharmony_ci addr->name->sun_path); 248c2ecf20Sopenharmony_ci} 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistatic int sk_diag_dump_vfs(struct sock *sk, struct sk_buff *nlskb) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci struct dentry *dentry = unix_sk(sk)->path.dentry; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci if (dentry) { 318c2ecf20Sopenharmony_ci struct unix_diag_vfs uv = { 328c2ecf20Sopenharmony_ci .udiag_vfs_ino = d_backing_inode(dentry)->i_ino, 338c2ecf20Sopenharmony_ci .udiag_vfs_dev = dentry->d_sb->s_dev, 348c2ecf20Sopenharmony_ci }; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci return nla_put(nlskb, UNIX_DIAG_VFS, sizeof(uv), &uv); 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci return 0; 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci struct sock *peer; 458c2ecf20Sopenharmony_ci int ino; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci peer = unix_peer_get(sk); 488c2ecf20Sopenharmony_ci if (peer) { 498c2ecf20Sopenharmony_ci unix_state_lock(peer); 508c2ecf20Sopenharmony_ci ino = sock_i_ino(peer); 518c2ecf20Sopenharmony_ci unix_state_unlock(peer); 528c2ecf20Sopenharmony_ci sock_put(peer); 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci return nla_put_u32(nlskb, UNIX_DIAG_PEER, ino); 558c2ecf20Sopenharmony_ci } 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci return 0; 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci struct sk_buff *skb; 638c2ecf20Sopenharmony_ci struct nlattr *attr; 648c2ecf20Sopenharmony_ci u32 *buf; 658c2ecf20Sopenharmony_ci int i; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci if (sk->sk_state == TCP_LISTEN) { 688c2ecf20Sopenharmony_ci spin_lock(&sk->sk_receive_queue.lock); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci attr = nla_reserve(nlskb, UNIX_DIAG_ICONS, 718c2ecf20Sopenharmony_ci sk->sk_receive_queue.qlen * sizeof(u32)); 728c2ecf20Sopenharmony_ci if (!attr) 738c2ecf20Sopenharmony_ci goto errout; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci buf = nla_data(attr); 768c2ecf20Sopenharmony_ci i = 0; 778c2ecf20Sopenharmony_ci skb_queue_walk(&sk->sk_receive_queue, skb) { 788c2ecf20Sopenharmony_ci struct sock *req, *peer; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci req = skb->sk; 818c2ecf20Sopenharmony_ci /* 828c2ecf20Sopenharmony_ci * The state lock is outer for the same sk's 838c2ecf20Sopenharmony_ci * queue lock. With the other's queue locked it's 848c2ecf20Sopenharmony_ci * OK to lock the state. 858c2ecf20Sopenharmony_ci */ 868c2ecf20Sopenharmony_ci unix_state_lock_nested(req, U_LOCK_DIAG); 878c2ecf20Sopenharmony_ci peer = unix_sk(req)->peer; 888c2ecf20Sopenharmony_ci buf[i++] = (peer ? sock_i_ino(peer) : 0); 898c2ecf20Sopenharmony_ci unix_state_unlock(req); 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci spin_unlock(&sk->sk_receive_queue.lock); 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci return 0; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cierrout: 978c2ecf20Sopenharmony_ci spin_unlock(&sk->sk_receive_queue.lock); 988c2ecf20Sopenharmony_ci return -EMSGSIZE; 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistatic int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci struct unix_diag_rqlen rql; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci if (sk->sk_state == TCP_LISTEN) { 1068c2ecf20Sopenharmony_ci rql.udiag_rqueue = sk->sk_receive_queue.qlen; 1078c2ecf20Sopenharmony_ci rql.udiag_wqueue = sk->sk_max_ack_backlog; 1088c2ecf20Sopenharmony_ci } else { 1098c2ecf20Sopenharmony_ci rql.udiag_rqueue = (u32) unix_inq_len(sk); 1108c2ecf20Sopenharmony_ci rql.udiag_wqueue = (u32) unix_outq_len(sk); 1118c2ecf20Sopenharmony_ci } 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql); 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb, 1178c2ecf20Sopenharmony_ci struct user_namespace *user_ns) 1188c2ecf20Sopenharmony_ci{ 1198c2ecf20Sopenharmony_ci uid_t uid = from_kuid_munged(user_ns, sock_i_uid(sk)); 1208c2ecf20Sopenharmony_ci return nla_put(nlskb, UNIX_DIAG_UID, sizeof(uid_t), &uid); 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req, 1248c2ecf20Sopenharmony_ci struct user_namespace *user_ns, 1258c2ecf20Sopenharmony_ci u32 portid, u32 seq, u32 flags, int sk_ino) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci struct nlmsghdr *nlh; 1288c2ecf20Sopenharmony_ci struct unix_diag_msg *rep; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci nlh = nlmsg_put(skb, portid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep), 1318c2ecf20Sopenharmony_ci flags); 1328c2ecf20Sopenharmony_ci if (!nlh) 1338c2ecf20Sopenharmony_ci return -EMSGSIZE; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci rep = nlmsg_data(nlh); 1368c2ecf20Sopenharmony_ci rep->udiag_family = AF_UNIX; 1378c2ecf20Sopenharmony_ci rep->udiag_type = sk->sk_type; 1388c2ecf20Sopenharmony_ci rep->udiag_state = sk->sk_state; 1398c2ecf20Sopenharmony_ci rep->pad = 0; 1408c2ecf20Sopenharmony_ci rep->udiag_ino = sk_ino; 1418c2ecf20Sopenharmony_ci sock_diag_save_cookie(sk, rep->udiag_cookie); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci if ((req->udiag_show & UDIAG_SHOW_NAME) && 1448c2ecf20Sopenharmony_ci sk_diag_dump_name(sk, skb)) 1458c2ecf20Sopenharmony_ci goto out_nlmsg_trim; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci if ((req->udiag_show & UDIAG_SHOW_VFS) && 1488c2ecf20Sopenharmony_ci sk_diag_dump_vfs(sk, skb)) 1498c2ecf20Sopenharmony_ci goto out_nlmsg_trim; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if ((req->udiag_show & UDIAG_SHOW_PEER) && 1528c2ecf20Sopenharmony_ci sk_diag_dump_peer(sk, skb)) 1538c2ecf20Sopenharmony_ci goto out_nlmsg_trim; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci if ((req->udiag_show & UDIAG_SHOW_ICONS) && 1568c2ecf20Sopenharmony_ci sk_diag_dump_icons(sk, skb)) 1578c2ecf20Sopenharmony_ci goto out_nlmsg_trim; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci if ((req->udiag_show & UDIAG_SHOW_RQLEN) && 1608c2ecf20Sopenharmony_ci sk_diag_show_rqlen(sk, skb)) 1618c2ecf20Sopenharmony_ci goto out_nlmsg_trim; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci if ((req->udiag_show & UDIAG_SHOW_MEMINFO) && 1648c2ecf20Sopenharmony_ci sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) 1658c2ecf20Sopenharmony_ci goto out_nlmsg_trim; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown)) 1688c2ecf20Sopenharmony_ci goto out_nlmsg_trim; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci if ((req->udiag_show & UDIAG_SHOW_UID) && 1718c2ecf20Sopenharmony_ci sk_diag_dump_uid(sk, skb, user_ns)) 1728c2ecf20Sopenharmony_ci goto out_nlmsg_trim; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci nlmsg_end(skb, nlh); 1758c2ecf20Sopenharmony_ci return 0; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ciout_nlmsg_trim: 1788c2ecf20Sopenharmony_ci nlmsg_cancel(skb, nlh); 1798c2ecf20Sopenharmony_ci return -EMSGSIZE; 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req, 1838c2ecf20Sopenharmony_ci struct user_namespace *user_ns, 1848c2ecf20Sopenharmony_ci u32 portid, u32 seq, u32 flags) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci int sk_ino; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci unix_state_lock(sk); 1898c2ecf20Sopenharmony_ci sk_ino = sock_i_ino(sk); 1908c2ecf20Sopenharmony_ci unix_state_unlock(sk); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci if (!sk_ino) 1938c2ecf20Sopenharmony_ci return 0; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci return sk_diag_fill(sk, skb, req, user_ns, portid, seq, flags, sk_ino); 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci struct unix_diag_req *req; 2018c2ecf20Sopenharmony_ci int num, s_num, slot, s_slot; 2028c2ecf20Sopenharmony_ci struct net *net = sock_net(skb->sk); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci req = nlmsg_data(cb->nlh); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci s_slot = cb->args[0]; 2078c2ecf20Sopenharmony_ci num = s_num = cb->args[1]; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci spin_lock(&unix_table_lock); 2108c2ecf20Sopenharmony_ci for (slot = s_slot; 2118c2ecf20Sopenharmony_ci slot < ARRAY_SIZE(unix_socket_table); 2128c2ecf20Sopenharmony_ci s_num = 0, slot++) { 2138c2ecf20Sopenharmony_ci struct sock *sk; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci num = 0; 2168c2ecf20Sopenharmony_ci sk_for_each(sk, &unix_socket_table[slot]) { 2178c2ecf20Sopenharmony_ci if (!net_eq(sock_net(sk), net)) 2188c2ecf20Sopenharmony_ci continue; 2198c2ecf20Sopenharmony_ci if (num < s_num) 2208c2ecf20Sopenharmony_ci goto next; 2218c2ecf20Sopenharmony_ci if (!(req->udiag_states & (1 << sk->sk_state))) 2228c2ecf20Sopenharmony_ci goto next; 2238c2ecf20Sopenharmony_ci if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk), 2248c2ecf20Sopenharmony_ci NETLINK_CB(cb->skb).portid, 2258c2ecf20Sopenharmony_ci cb->nlh->nlmsg_seq, 2268c2ecf20Sopenharmony_ci NLM_F_MULTI) < 0) 2278c2ecf20Sopenharmony_ci goto done; 2288c2ecf20Sopenharmony_cinext: 2298c2ecf20Sopenharmony_ci num++; 2308c2ecf20Sopenharmony_ci } 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_cidone: 2338c2ecf20Sopenharmony_ci spin_unlock(&unix_table_lock); 2348c2ecf20Sopenharmony_ci cb->args[0] = slot; 2358c2ecf20Sopenharmony_ci cb->args[1] = num; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci return skb->len; 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic struct sock *unix_lookup_by_ino(unsigned int ino) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci int i; 2438c2ecf20Sopenharmony_ci struct sock *sk; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci spin_lock(&unix_table_lock); 2468c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(unix_socket_table); i++) { 2478c2ecf20Sopenharmony_ci sk_for_each(sk, &unix_socket_table[i]) 2488c2ecf20Sopenharmony_ci if (ino == sock_i_ino(sk)) { 2498c2ecf20Sopenharmony_ci sock_hold(sk); 2508c2ecf20Sopenharmony_ci spin_unlock(&unix_table_lock); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci return sk; 2538c2ecf20Sopenharmony_ci } 2548c2ecf20Sopenharmony_ci } 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci spin_unlock(&unix_table_lock); 2578c2ecf20Sopenharmony_ci return NULL; 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_cistatic int unix_diag_get_exact(struct sk_buff *in_skb, 2618c2ecf20Sopenharmony_ci const struct nlmsghdr *nlh, 2628c2ecf20Sopenharmony_ci struct unix_diag_req *req) 2638c2ecf20Sopenharmony_ci{ 2648c2ecf20Sopenharmony_ci int err = -EINVAL; 2658c2ecf20Sopenharmony_ci struct sock *sk; 2668c2ecf20Sopenharmony_ci struct sk_buff *rep; 2678c2ecf20Sopenharmony_ci unsigned int extra_len; 2688c2ecf20Sopenharmony_ci struct net *net = sock_net(in_skb->sk); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci if (req->udiag_ino == 0) 2718c2ecf20Sopenharmony_ci goto out_nosk; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci sk = unix_lookup_by_ino(req->udiag_ino); 2748c2ecf20Sopenharmony_ci err = -ENOENT; 2758c2ecf20Sopenharmony_ci if (sk == NULL) 2768c2ecf20Sopenharmony_ci goto out_nosk; 2778c2ecf20Sopenharmony_ci if (!net_eq(sock_net(sk), net)) 2788c2ecf20Sopenharmony_ci goto out; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci err = sock_diag_check_cookie(sk, req->udiag_cookie); 2818c2ecf20Sopenharmony_ci if (err) 2828c2ecf20Sopenharmony_ci goto out; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci extra_len = 256; 2858c2ecf20Sopenharmony_ciagain: 2868c2ecf20Sopenharmony_ci err = -ENOMEM; 2878c2ecf20Sopenharmony_ci rep = nlmsg_new(sizeof(struct unix_diag_msg) + extra_len, GFP_KERNEL); 2888c2ecf20Sopenharmony_ci if (!rep) 2898c2ecf20Sopenharmony_ci goto out; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci err = sk_diag_fill(sk, rep, req, sk_user_ns(NETLINK_CB(in_skb).sk), 2928c2ecf20Sopenharmony_ci NETLINK_CB(in_skb).portid, 2938c2ecf20Sopenharmony_ci nlh->nlmsg_seq, 0, req->udiag_ino); 2948c2ecf20Sopenharmony_ci if (err < 0) { 2958c2ecf20Sopenharmony_ci nlmsg_free(rep); 2968c2ecf20Sopenharmony_ci extra_len += 256; 2978c2ecf20Sopenharmony_ci if (extra_len >= PAGE_SIZE) 2988c2ecf20Sopenharmony_ci goto out; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci goto again; 3018c2ecf20Sopenharmony_ci } 3028c2ecf20Sopenharmony_ci err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid, 3038c2ecf20Sopenharmony_ci MSG_DONTWAIT); 3048c2ecf20Sopenharmony_ci if (err > 0) 3058c2ecf20Sopenharmony_ci err = 0; 3068c2ecf20Sopenharmony_ciout: 3078c2ecf20Sopenharmony_ci if (sk) 3088c2ecf20Sopenharmony_ci sock_put(sk); 3098c2ecf20Sopenharmony_ciout_nosk: 3108c2ecf20Sopenharmony_ci return err; 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cistatic int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) 3148c2ecf20Sopenharmony_ci{ 3158c2ecf20Sopenharmony_ci int hdrlen = sizeof(struct unix_diag_req); 3168c2ecf20Sopenharmony_ci struct net *net = sock_net(skb->sk); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci if (nlmsg_len(h) < hdrlen) 3198c2ecf20Sopenharmony_ci return -EINVAL; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci if (h->nlmsg_flags & NLM_F_DUMP) { 3228c2ecf20Sopenharmony_ci struct netlink_dump_control c = { 3238c2ecf20Sopenharmony_ci .dump = unix_diag_dump, 3248c2ecf20Sopenharmony_ci }; 3258c2ecf20Sopenharmony_ci return netlink_dump_start(net->diag_nlsk, skb, h, &c); 3268c2ecf20Sopenharmony_ci } else 3278c2ecf20Sopenharmony_ci return unix_diag_get_exact(skb, h, nlmsg_data(h)); 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_cistatic const struct sock_diag_handler unix_diag_handler = { 3318c2ecf20Sopenharmony_ci .family = AF_UNIX, 3328c2ecf20Sopenharmony_ci .dump = unix_diag_handler_dump, 3338c2ecf20Sopenharmony_ci}; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_cistatic int __init unix_diag_init(void) 3368c2ecf20Sopenharmony_ci{ 3378c2ecf20Sopenharmony_ci return sock_diag_register(&unix_diag_handler); 3388c2ecf20Sopenharmony_ci} 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic void __exit unix_diag_exit(void) 3418c2ecf20Sopenharmony_ci{ 3428c2ecf20Sopenharmony_ci sock_diag_unregister(&unix_diag_handler); 3438c2ecf20Sopenharmony_ci} 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_cimodule_init(unix_diag_init); 3468c2ecf20Sopenharmony_cimodule_exit(unix_diag_exit); 3478c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 3488c2ecf20Sopenharmony_ciMODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 1 /* AF_LOCAL */); 349