// SPDX-License-Identifier: GPL-2.0-only
/* Support ct functions for openvswitch and used by OVS and TC conntrack. */

#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_seqadj.h>
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#include <net/ipv6_frag.h>
#include <net/ip.h>
#include <linux/netfilter_ipv6.h>

/* 'skb' should already be pulled to nh_ofs. */
int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
		 enum ip_conntrack_info ctinfo, u16 proto)
{
	const struct nf_conntrack_helper *helper;
	const struct nf_conn_help *help;
	unsigned int protoff;
	int err;

	if (ctinfo == IP_CT_RELATED_REPLY)
		return NF_ACCEPT;

	help = nfct_help(ct);
	if (!help)
		return NF_ACCEPT;

	helper = rcu_dereference(help->helper);
	if (!helper)
		return NF_ACCEPT;

	if (helper->tuple.src.l3num != NFPROTO_UNSPEC &&
	    helper->tuple.src.l3num != proto)
		return NF_ACCEPT;

	switch (proto) {
	case NFPROTO_IPV4:
		protoff = ip_hdrlen(skb);
		proto = ip_hdr(skb)->protocol;
		break;
	case NFPROTO_IPV6: {
		u8 nexthdr = ipv6_hdr(skb)->nexthdr;
		__be16 frag_off;
		int ofs;

		ofs = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
				       &frag_off);
		if (ofs < 0 || (frag_off & htons(~0x7)) != 0) {
			pr_debug("proto header not found\n");
			return NF_ACCEPT;
		}
		protoff = ofs;
		proto = nexthdr;
		break;
	}
	default:
		WARN_ONCE(1, "helper invoked on non-IP family!");
		return NF_DROP;
	}

	if (helper->tuple.dst.protonum != proto)
		return NF_ACCEPT;

	err = helper->help(skb, protoff, ct, ctinfo);
	if (err != NF_ACCEPT)
		return err;

	/* Adjust seqs after helper.  This is needed due to some helpers (e.g.,
	 * FTP with NAT) adusting the TCP payload size when mangling IP
	 * addresses and/or port numbers in the text-based control connection.
	 */
	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
	    !nf_ct_seq_adjust(skb, ct, ctinfo, protoff))
		return NF_DROP;
	return NF_ACCEPT;
}
EXPORT_SYMBOL_GPL(nf_ct_helper);

int nf_ct_add_helper(struct nf_conn *ct, const char *name, u8 family,
		     u8 proto, bool nat, struct nf_conntrack_helper **hp)
{
	struct nf_conntrack_helper *helper;
	struct nf_conn_help *help;
	int ret = 0;

	helper = nf_conntrack_helper_try_module_get(name, family, proto);
	if (!helper)
		return -EINVAL;

	help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
	if (!help) {
		nf_conntrack_helper_put(helper);
		return -ENOMEM;
	}
#if IS_ENABLED(CONFIG_NF_NAT)
	if (nat) {
		ret = nf_nat_helper_try_module_get(name, family, proto);
		if (ret) {
			nf_conntrack_helper_put(helper);
			return ret;
		}
	}
#endif
	rcu_assign_pointer(help->helper, helper);
	*hp = helper;
	return ret;
}
EXPORT_SYMBOL_GPL(nf_ct_add_helper);

/* Trim the skb to the length specified by the IP/IPv6 header,
 * removing any trailing lower-layer padding. This prepares the skb
 * for higher-layer processing that assumes skb->len excludes padding
 * (such as nf_ip_checksum). The caller needs to pull the skb to the
 * network header, and ensure ip_hdr/ipv6_hdr points to valid data.
 */
int nf_ct_skb_network_trim(struct sk_buff *skb, int family)
{
	unsigned int len;

	switch (family) {
	case NFPROTO_IPV4:
		len = skb_ip_totlen(skb);
		break;
	case NFPROTO_IPV6:
		len = ntohs(ipv6_hdr(skb)->payload_len);
		if (ipv6_hdr(skb)->nexthdr == NEXTHDR_HOP) {
			int err = nf_ip6_check_hbh_len(skb, &len);

			if (err)
				return err;
		}
		len += sizeof(struct ipv6hdr);
		break;
	default:
		len = skb->len;
	}

	return pskb_trim_rcsum(skb, len);
}
EXPORT_SYMBOL_GPL(nf_ct_skb_network_trim);

/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero
 * value if 'skb' is freed.
 */
int nf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
			   u16 zone, u8 family, u8 *proto, u16 *mru)
{
	int err;

	if (family == NFPROTO_IPV4) {
		enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone;

		memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
		local_bh_disable();
		err = ip_defrag(net, skb, user);
		local_bh_enable();
		if (err)
			return err;

		*mru = IPCB(skb)->frag_max_size;
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
	} else if (family == NFPROTO_IPV6) {
		enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone;

		memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
		err = nf_ct_frag6_gather(net, skb, user);
		if (err) {
			if (err != -EINPROGRESS)
				kfree_skb(skb);
			return err;
		}

		*proto = ipv6_hdr(skb)->nexthdr;
		*mru = IP6CB(skb)->frag_max_size;
#endif
	} else {
		kfree_skb(skb);
		return -EPFNOSUPPORT;
	}

	skb_clear_hash(skb);
	skb->ignore_df = 1;

	return 0;
}
EXPORT_SYMBOL_GPL(nf_ct_handle_fragments);
