// SPDX-License-Identifier: GPL-2.0-only
/*
 * xfrm_nat_keepalive.c
 *
 * (c) 2024 Eyal Birger <eyal.birger@gmail.com>
 */

#include <net/inet_common.h>
#include <net/ip6_checksum.h>
#include <net/xfrm.h>

static DEFINE_PER_CPU(struct sock_bh_locked, nat_keepalive_sk_ipv4) = {
	.bh_lock = INIT_LOCAL_LOCK(bh_lock),
};
#if IS_ENABLED(CONFIG_IPV6)
static DEFINE_PER_CPU(struct sock_bh_locked, nat_keepalive_sk_ipv6) = {
	.bh_lock = INIT_LOCAL_LOCK(bh_lock),
};
#endif

struct nat_keepalive {
	struct net *net;
	u16 family;
	xfrm_address_t saddr;
	xfrm_address_t daddr;
	__be16 encap_sport;
	__be16 encap_dport;
	__u32 smark;
};

static void nat_keepalive_init(struct nat_keepalive *ka, struct xfrm_state *x)
{
	ka->net = xs_net(x);
	ka->family = x->props.family;
	ka->saddr = x->props.saddr;
	ka->daddr = x->id.daddr;
	ka->encap_sport = x->encap->encap_sport;
	ka->encap_dport = x->encap->encap_dport;
	ka->smark = xfrm_smark_get(0, x);
}

static int nat_keepalive_send_ipv4(struct sk_buff *skb,
				   struct nat_keepalive *ka)
{
	struct net *net = ka->net;
	struct flowi4 fl4;
	struct rtable *rt;
	struct sock *sk;
	__u8 tos = 0;
	int err;

	flowi4_init_output(&fl4, 0 /* oif */, skb->mark, tos,
			   RT_SCOPE_UNIVERSE, IPPROTO_UDP, 0,
			   ka->daddr.a4, ka->saddr.a4, ka->encap_dport,
			   ka->encap_sport, sock_net_uid(net, NULL));

	rt = ip_route_output_key(net, &fl4);
	if (IS_ERR(rt))
		return PTR_ERR(rt);

	skb_dst_set(skb, &rt->dst);

	local_lock_nested_bh(&nat_keepalive_sk_ipv4.bh_lock);
	sk = this_cpu_read(nat_keepalive_sk_ipv4.sock);
	sock_net_set(sk, net);
	err = ip_build_and_send_pkt(skb, sk, fl4.saddr, fl4.daddr, NULL, tos);
	sock_net_set(sk, &init_net);
	local_unlock_nested_bh(&nat_keepalive_sk_ipv4.bh_lock);
	return err;
}

#if IS_ENABLED(CONFIG_IPV6)
static int nat_keepalive_send_ipv6(struct sk_buff *skb,
				   struct nat_keepalive *ka,
				   struct udphdr *uh)
{
	struct net *net = ka->net;
	struct dst_entry *dst;
	struct flowi6 fl6;
	struct sock *sk;
	__wsum csum;
	int err;

	csum = skb_checksum(skb, 0, skb->len, 0);
	uh->check = csum_ipv6_magic(&ka->saddr.in6, &ka->daddr.in6,
				    skb->len, IPPROTO_UDP, csum);
	if (uh->check == 0)
		uh->check = CSUM_MANGLED_0;

	memset(&fl6, 0, sizeof(fl6));
	fl6.flowi6_mark = skb->mark;
	fl6.saddr = ka->saddr.in6;
	fl6.daddr = ka->daddr.in6;
	fl6.flowi6_proto = IPPROTO_UDP;
	fl6.fl6_sport = ka->encap_sport;
	fl6.fl6_dport = ka->encap_dport;

	local_lock_nested_bh(&nat_keepalive_sk_ipv6.bh_lock);
	sk = this_cpu_read(nat_keepalive_sk_ipv6.sock);
	sock_net_set(sk, net);
	dst = ip6_dst_lookup_flow(net, sk, &fl6, NULL);
	if (IS_ERR(dst)) {
		local_unlock_nested_bh(&nat_keepalive_sk_ipv6.bh_lock);
		return PTR_ERR(dst);
	}

	skb_dst_set(skb, dst);
	err = ip6_xmit(sk, skb, &fl6, skb->mark, NULL, 0, 0);
	sock_net_set(sk, &init_net);
	local_unlock_nested_bh(&nat_keepalive_sk_ipv6.bh_lock);
	return err;
}
#endif

static void nat_keepalive_send(struct nat_keepalive *ka)
{
	const int nat_ka_hdrs_len = max(sizeof(struct iphdr),
					sizeof(struct ipv6hdr)) +
				    sizeof(struct udphdr);
	const u8 nat_ka_payload = 0xFF;
	int err = -EAFNOSUPPORT;
	struct sk_buff *skb;
	struct udphdr *uh;

	skb = alloc_skb(nat_ka_hdrs_len + sizeof(nat_ka_payload), GFP_ATOMIC);
	if (unlikely(!skb))
		return;

	skb_reserve(skb, nat_ka_hdrs_len);

	skb_put_u8(skb, nat_ka_payload);

	uh = skb_push(skb, sizeof(*uh));
	uh->source = ka->encap_sport;
	uh->dest = ka->encap_dport;
	uh->len = htons(skb->len);
	uh->check = 0;

	skb->mark = ka->smark;

	switch (ka->family) {
	case AF_INET:
		err = nat_keepalive_send_ipv4(skb, ka);
		break;
#if IS_ENABLED(CONFIG_IPV6)
	case AF_INET6:
		err = nat_keepalive_send_ipv6(skb, ka, uh);
		break;
#endif
	}
	if (err)
		kfree_skb(skb);
}

struct nat_keepalive_work_ctx {
	time64_t next_run;
	time64_t now;
};

static int nat_keepalive_work_single(struct xfrm_state *x, int count, void *ptr)
{
	struct nat_keepalive_work_ctx *ctx = ptr;
	bool send_keepalive = false;
	struct nat_keepalive ka;
	time64_t next_run;
	u32 interval;
	int delta;

	interval = x->nat_keepalive_interval;
	if (!interval)
		return 0;

	spin_lock(&x->lock);

	delta = (int)(ctx->now - x->lastused);
	if (delta < interval) {
		x->nat_keepalive_expiration = ctx->now + interval - delta;
		next_run = x->nat_keepalive_expiration;
	} else if (x->nat_keepalive_expiration > ctx->now) {
		next_run = x->nat_keepalive_expiration;
	} else {
		next_run = ctx->now + interval;
		nat_keepalive_init(&ka, x);
		send_keepalive = true;
	}

	spin_unlock(&x->lock);

	if (send_keepalive)
		nat_keepalive_send(&ka);

	if (!ctx->next_run || next_run < ctx->next_run)
		ctx->next_run = next_run;
	return 0;
}

static void nat_keepalive_work(struct work_struct *work)
{
	struct nat_keepalive_work_ctx ctx;
	struct xfrm_state_walk walk;
	struct net *net;

	ctx.next_run = 0;
	ctx.now = ktime_get_real_seconds();

	net = container_of(work, struct net, xfrm.nat_keepalive_work.work);
	xfrm_state_walk_init(&walk, IPPROTO_ESP, NULL);
	xfrm_state_walk(net, &walk, nat_keepalive_work_single, &ctx);
	xfrm_state_walk_done(&walk, net);
	if (ctx.next_run)
		schedule_delayed_work(&net->xfrm.nat_keepalive_work,
				      (ctx.next_run - ctx.now) * HZ);
}

static int nat_keepalive_sk_init(struct sock_bh_locked __percpu *socks,
				 unsigned short family)
{
	struct sock *sk;
	int err, i;

	for_each_possible_cpu(i) {
		err = inet_ctl_sock_create(&sk, family, SOCK_RAW, IPPROTO_UDP,
					   &init_net);
		if (err < 0)
			goto err;

		per_cpu_ptr(socks, i)->sock = sk;
	}

	return 0;
err:
	for_each_possible_cpu(i)
		inet_ctl_sock_destroy(per_cpu_ptr(socks, i)->sock);
	return err;
}

static void nat_keepalive_sk_fini(struct sock_bh_locked __percpu *socks)
{
	int i;

	for_each_possible_cpu(i)
		inet_ctl_sock_destroy(per_cpu_ptr(socks, i)->sock);
}

void xfrm_nat_keepalive_state_updated(struct xfrm_state *x)
{
	struct net *net;

	if (!x->nat_keepalive_interval)
		return;

	net = xs_net(x);
	schedule_delayed_work(&net->xfrm.nat_keepalive_work, 0);
}

int __net_init xfrm_nat_keepalive_net_init(struct net *net)
{
	INIT_DELAYED_WORK(&net->xfrm.nat_keepalive_work, nat_keepalive_work);
	return 0;
}

int xfrm_nat_keepalive_net_fini(struct net *net)
{
	disable_delayed_work_sync(&net->xfrm.nat_keepalive_work);
	return 0;
}

int xfrm_nat_keepalive_init(unsigned short family)
{
	int err = -EAFNOSUPPORT;

	switch (family) {
	case AF_INET:
		err = nat_keepalive_sk_init(&nat_keepalive_sk_ipv4, PF_INET);
		break;
#if IS_ENABLED(CONFIG_IPV6)
	case AF_INET6:
		err = nat_keepalive_sk_init(&nat_keepalive_sk_ipv6, PF_INET6);
		break;
#endif
	}

	if (err)
		pr_err("xfrm nat keepalive init: failed to init err:%d\n", err);
	return err;
}
EXPORT_SYMBOL_GPL(xfrm_nat_keepalive_init);

void xfrm_nat_keepalive_fini(unsigned short family)
{
	switch (family) {
	case AF_INET:
		nat_keepalive_sk_fini(&nat_keepalive_sk_ipv4);
		break;
#if IS_ENABLED(CONFIG_IPV6)
	case AF_INET6:
		nat_keepalive_sk_fini(&nat_keepalive_sk_ipv6);
		break;
#endif
	}
}
EXPORT_SYMBOL_GPL(xfrm_nat_keepalive_fini);
