// SPDX-License-Identifier: GPL-2.0-only
#include <linux/module.h>

#include <linux/inet_diag.h>
#include <linux/sock_diag.h>

#include <net/inet_sock.h>
#include <net/raw.h>
#include <net/rawv6.h>

#ifdef pr_fmt
# undef pr_fmt
#endif

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

static struct raw_hashinfo *
raw_get_hashinfo(const struct inet_diag_req_v2 *r)
{
	if (r->sdiag_family == AF_INET) {
		return &raw_v4_hashinfo;
#if IS_ENABLED(CONFIG_IPV6)
	} else if (r->sdiag_family == AF_INET6) {
		return &raw_v6_hashinfo;
#endif
	} else {
		return ERR_PTR(-EINVAL);
	}
}

/*
 * Due to requirement of not breaking user API we can't simply
 * rename @pad field in inet_diag_req_v2 structure, instead
 * use helper to figure it out.
 */

static bool raw_lookup(struct net *net, const struct sock *sk,
		       const struct inet_diag_req_v2 *req)
{
	struct inet_diag_req_raw *r = (void *)req;

	if (r->sdiag_family == AF_INET)
		return raw_v4_match(net, sk, r->sdiag_raw_protocol,
				    r->id.idiag_dst[0],
				    r->id.idiag_src[0],
				    r->id.idiag_if, 0);
#if IS_ENABLED(CONFIG_IPV6)
	else
		return raw_v6_match(net, sk, r->sdiag_raw_protocol,
				    (const struct in6_addr *)r->id.idiag_src,
				    (const struct in6_addr *)r->id.idiag_dst,
				    r->id.idiag_if, 0);
#endif
	return false;
}

static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2 *r)
{
	struct raw_hashinfo *hashinfo = raw_get_hashinfo(r);
	struct hlist_head *hlist;
	struct sock *sk;
	int slot;

	if (IS_ERR(hashinfo))
		return ERR_CAST(hashinfo);

	rcu_read_lock();
	for (slot = 0; slot < RAW_HTABLE_SIZE; slot++) {
		hlist = &hashinfo->ht[slot];
		sk_for_each_rcu(sk, hlist) {
			if (raw_lookup(net, sk, r)) {
				/*
				 * Grab it and keep until we fill
				 * diag message to be reported, so
				 * caller should call sock_put then.
				 */
				if (refcount_inc_not_zero(&sk->sk_refcnt))
					goto out_unlock;
			}
		}
	}
	sk = ERR_PTR(-ENOENT);
out_unlock:
	rcu_read_unlock();

	return sk;
}

static int raw_diag_dump_one(struct netlink_callback *cb,
			     const struct inet_diag_req_v2 *r)
{
	struct sk_buff *in_skb = cb->skb;
	struct sk_buff *rep;
	struct sock *sk;
	struct net *net;
	int err;

	net = sock_net(in_skb->sk);
	sk = raw_sock_get(net, r);
	if (IS_ERR(sk))
		return PTR_ERR(sk);

	rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) +
			inet_diag_msg_attrs_size() +
			nla_total_size(sizeof(struct inet_diag_meminfo)) + 64,
			GFP_KERNEL);
	if (!rep) {
		sock_put(sk);
		return -ENOMEM;
	}

	err = inet_sk_diag_fill(sk, NULL, rep, cb, r, 0,
				netlink_net_capable(in_skb, CAP_NET_ADMIN));
	sock_put(sk);

	if (err < 0) {
		kfree_skb(rep);
		return err;
	}

	err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);

	return err;
}

static int sk_diag_dump(struct sock *sk, struct sk_buff *skb,
			struct netlink_callback *cb,
			const struct inet_diag_req_v2 *r,
			struct nlattr *bc, bool net_admin)
{
	if (!inet_diag_bc_sk(bc, sk))
		return 0;

	return inet_sk_diag_fill(sk, NULL, skb, cb, r, NLM_F_MULTI, net_admin);
}

static void raw_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
			  const struct inet_diag_req_v2 *r)
{
	bool net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN);
	struct raw_hashinfo *hashinfo = raw_get_hashinfo(r);
	struct net *net = sock_net(skb->sk);
	struct inet_diag_dump_data *cb_data;
	int num, s_num, slot, s_slot;
	struct hlist_head *hlist;
	struct sock *sk = NULL;
	struct nlattr *bc;

	if (IS_ERR(hashinfo))
		return;

	cb_data = cb->data;
	bc = cb_data->inet_diag_nla_bc;
	s_slot = cb->args[0];
	num = s_num = cb->args[1];

	rcu_read_lock();
	for (slot = s_slot; slot < RAW_HTABLE_SIZE; s_num = 0, slot++) {
		num = 0;

		hlist = &hashinfo->ht[slot];
		sk_for_each_rcu(sk, hlist) {
			struct inet_sock *inet = inet_sk(sk);

			if (!net_eq(sock_net(sk), net))
				continue;
			if (num < s_num)
				goto next;
			if (sk->sk_family != r->sdiag_family)
				goto next;
			if (r->id.idiag_sport != inet->inet_sport &&
			    r->id.idiag_sport)
				goto next;
			if (r->id.idiag_dport != inet->inet_dport &&
			    r->id.idiag_dport)
				goto next;
			if (sk_diag_dump(sk, skb, cb, r, bc, net_admin) < 0)
				goto out_unlock;
next:
			num++;
		}
	}

out_unlock:
	rcu_read_unlock();

	cb->args[0] = slot;
	cb->args[1] = num;
}

static void raw_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
			      void *info)
{
	r->idiag_rqueue = sk_rmem_alloc_get(sk);
	r->idiag_wqueue = sk_wmem_alloc_get(sk);
}

#ifdef CONFIG_INET_DIAG_DESTROY
static int raw_diag_destroy(struct sk_buff *in_skb,
			    const struct inet_diag_req_v2 *r)
{
	struct net *net = sock_net(in_skb->sk);
	struct sock *sk;
	int err;

	sk = raw_sock_get(net, r);
	if (IS_ERR(sk))
		return PTR_ERR(sk);
	err = sock_diag_destroy(sk, ECONNABORTED);
	sock_put(sk);
	return err;
}
#endif

static const struct inet_diag_handler raw_diag_handler = {
	.owner			= THIS_MODULE,
	.dump			= raw_diag_dump,
	.dump_one		= raw_diag_dump_one,
	.idiag_get_info		= raw_diag_get_info,
	.idiag_type		= IPPROTO_RAW,
	.idiag_info_size	= 0,
#ifdef CONFIG_INET_DIAG_DESTROY
	.destroy		= raw_diag_destroy,
#endif
};

static void __always_unused __check_inet_diag_req_raw(void)
{
	/*
	 * Make sure the two structures are identical,
	 * except the @pad field.
	 */
#define __offset_mismatch(m1, m2)			\
	(offsetof(struct inet_diag_req_v2, m1) !=	\
	 offsetof(struct inet_diag_req_raw, m2))

	BUILD_BUG_ON(sizeof(struct inet_diag_req_v2) !=
		     sizeof(struct inet_diag_req_raw));
	BUILD_BUG_ON(__offset_mismatch(sdiag_family, sdiag_family));
	BUILD_BUG_ON(__offset_mismatch(sdiag_protocol, sdiag_protocol));
	BUILD_BUG_ON(__offset_mismatch(idiag_ext, idiag_ext));
	BUILD_BUG_ON(__offset_mismatch(pad, sdiag_raw_protocol));
	BUILD_BUG_ON(__offset_mismatch(idiag_states, idiag_states));
	BUILD_BUG_ON(__offset_mismatch(id, id));
#undef __offset_mismatch
}

static int __init raw_diag_init(void)
{
	return inet_diag_register(&raw_diag_handler);
}

static void __exit raw_diag_exit(void)
{
	inet_diag_unregister(&raw_diag_handler);
}

module_init(raw_diag_init);
module_exit(raw_diag_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("RAW socket monitoring via SOCK_DIAG");
MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 2-255 /* AF_INET - IPPROTO_RAW */);
MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 10-255 /* AF_INET6 - IPPROTO_RAW */);
