// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2021-2022 Intel Corporation
 */

#include <uapi/linux/if_ether.h>
#include <uapi/linux/if_arp.h>
#include <uapi/linux/icmp.h>

#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ieee80211.h>

#include <net/cfg80211.h>
#include <net/ip.h>

#include <linux/if_arp.h>
#include <linux/icmp.h>
#include <linux/udp.h>
#include <linux/ip.h>
#include <linux/mm.h>

#include "internal.h"
#include "sap.h"
#include "iwl-mei.h"

/*
 * Returns true if further filtering should be stopped. Only in that case
 * pass_to_csme and rx_handler_res are set. Otherwise, next level of filters
 * should be checked.
 */
static bool iwl_mei_rx_filter_eth(const struct ethhdr *ethhdr,
				  const struct iwl_sap_oob_filters *filters,
				  bool *pass_to_csme,
				  rx_handler_result_t *rx_handler_res)
{
	const struct iwl_sap_eth_filter *filt;

	/* This filter is not relevant for UCAST packet */
	if (!is_multicast_ether_addr(ethhdr->h_dest) ||
	    is_broadcast_ether_addr(ethhdr->h_dest))
		return false;

	for (filt = &filters->eth_filters[0];
	     filt < &filters->eth_filters[0] + ARRAY_SIZE(filters->eth_filters);
	     filt++) {
		/* Assume there are no enabled filter after a disabled one */
		if (!(filt->flags & SAP_ETH_FILTER_ENABLED))
			break;

		if (compare_ether_header(filt->mac_address, ethhdr->h_dest))
			continue;

		/* Packet needs to reach the host's stack */
		if (filt->flags & SAP_ETH_FILTER_COPY)
			*rx_handler_res = RX_HANDLER_PASS;
		else
			*rx_handler_res = RX_HANDLER_CONSUMED;

		/* We have an authoritative answer, stop filtering */
		if (filt->flags & SAP_ETH_FILTER_STOP) {
			*pass_to_csme = true;
			return true;
		}

		return false;
	}

	 /* MCAST frames that don't match layer 2 filters are not sent to ME */
	*pass_to_csme  = false;

	return true;
}

/*
 * Returns true iff the frame should be passed to CSME in which case
 * rx_handler_res is set.
 */
static bool iwl_mei_rx_filter_arp(struct sk_buff *skb,
				  const struct iwl_sap_oob_filters *filters,
				  rx_handler_result_t *rx_handler_res)
{
	const struct iwl_sap_ipv4_filter *filt = &filters->ipv4_filter;
	const struct arphdr *arp;
	const __be32 *target_ip;
	u32 flags = le32_to_cpu(filt->flags);

	if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
		return false;

	arp = arp_hdr(skb);

	/* Handle only IPv4 over ethernet ARP frames */
	if (arp->ar_hrd != htons(ARPHRD_ETHER) ||
	    arp->ar_pro != htons(ETH_P_IP))
		return false;

	/*
	 * After the ARP header, we have:
	 * src MAC address   - 6 bytes
	 * src IP address    - 4 bytes
	 * target MAC addess - 6 bytes
	 */
	target_ip = (const void *)((const u8 *)(arp + 1) +
				   ETH_ALEN + sizeof(__be32) + ETH_ALEN);

	/*
	 * ARP request is forwarded to ME only if IP address match in the
	 * ARP request's target ip field.
	 */
	if (arp->ar_op == htons(ARPOP_REQUEST) &&
	    (filt->flags & cpu_to_le32(SAP_IPV4_FILTER_ARP_REQ_PASS)) &&
	    (filt->ipv4_addr == 0 || filt->ipv4_addr == *target_ip)) {
		if (flags & SAP_IPV4_FILTER_ARP_REQ_COPY)
			*rx_handler_res = RX_HANDLER_PASS;
		else
			*rx_handler_res = RX_HANDLER_CONSUMED;

		return true;
	}

	/* ARP reply is always forwarded to ME regardless of the IP */
	if (flags & SAP_IPV4_FILTER_ARP_RESP_PASS &&
	    arp->ar_op == htons(ARPOP_REPLY)) {
		if (flags & SAP_IPV4_FILTER_ARP_RESP_COPY)
			*rx_handler_res = RX_HANDLER_PASS;
		else
			*rx_handler_res = RX_HANDLER_CONSUMED;

		return true;
	}

	return false;
}

static bool
iwl_mei_rx_filter_tcp_udp(struct sk_buff *skb, bool  ip_match,
			  const struct iwl_sap_oob_filters *filters,
			  rx_handler_result_t *rx_handler_res)
{
	const struct iwl_sap_flex_filter *filt;

	for (filt = &filters->flex_filters[0];
	     filt < &filters->flex_filters[0] + ARRAY_SIZE(filters->flex_filters);
	     filt++) {
		if (!(filt->flags & SAP_FLEX_FILTER_ENABLED))
			break;

		/*
		 * We are required to have a match on the IP level and we didn't
		 * have such match.
		 */
		if ((filt->flags &
		     (SAP_FLEX_FILTER_IPV4 | SAP_FLEX_FILTER_IPV6)) &&
		    !ip_match)
			continue;

		if ((filt->flags & SAP_FLEX_FILTER_UDP) &&
		    ip_hdr(skb)->protocol != IPPROTO_UDP)
			continue;

		if ((filt->flags & SAP_FLEX_FILTER_TCP) &&
		    ip_hdr(skb)->protocol != IPPROTO_TCP)
			continue;

		/*
		 * We must have either a TCP header or a UDP header, both
		 * starts with a source port and then a destination port.
		 * Both are big endian words.
		 * Use a UDP header and that will work for TCP as well.
		 */
		if ((filt->src_port && filt->src_port != udp_hdr(skb)->source) ||
		    (filt->dst_port && filt->dst_port != udp_hdr(skb)->dest))
			continue;

		if (filt->flags & SAP_FLEX_FILTER_COPY)
			*rx_handler_res = RX_HANDLER_PASS;
		else
			*rx_handler_res = RX_HANDLER_CONSUMED;

		return true;
	}

	return false;
}

static bool iwl_mei_rx_filter_ipv4(struct sk_buff *skb,
				   const struct iwl_sap_oob_filters *filters,
				   rx_handler_result_t *rx_handler_res)
{
	const struct iwl_sap_ipv4_filter *filt = &filters->ipv4_filter;
	const struct iphdr *iphdr;
	unsigned int iphdrlen;
	bool match;

	if (!pskb_may_pull(skb, skb_network_offset(skb) + sizeof(*iphdr)) ||
	    !pskb_may_pull(skb, skb_network_offset(skb) + ip_hdrlen(skb)))
		return false;

	iphdrlen = ip_hdrlen(skb);
	iphdr = ip_hdr(skb);
	match = !filters->ipv4_filter.ipv4_addr ||
		filters->ipv4_filter.ipv4_addr == iphdr->daddr;

	skb_set_transport_header(skb, skb_network_offset(skb) + iphdrlen);

	switch (ip_hdr(skb)->protocol) {
	case IPPROTO_UDP:
	case IPPROTO_TCP:
		/*
		 * UDP header is shorter than TCP header and we look at the first bytes
		 * of the header anyway (see below).
		 * If we have a truncated TCP packet, let CSME handle this.
		 */
		if (!pskb_may_pull(skb, skb_transport_offset(skb) +
				   sizeof(struct udphdr)))
			return false;

		return iwl_mei_rx_filter_tcp_udp(skb, match,
						 filters, rx_handler_res);

	case IPPROTO_ICMP: {
		struct icmphdr *icmp;

		if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(*icmp)))
			return false;

		icmp = icmp_hdr(skb);

		/*
		 * Don't pass echo requests to ME even if it wants it as we
		 * want the host to answer.
		 */
		if ((filt->flags & cpu_to_le32(SAP_IPV4_FILTER_ICMP_PASS)) &&
		    match && (icmp->type != ICMP_ECHO || icmp->code != 0)) {
			if (filt->flags & cpu_to_le32(SAP_IPV4_FILTER_ICMP_COPY))
				*rx_handler_res = RX_HANDLER_PASS;
			else
				*rx_handler_res = RX_HANDLER_CONSUMED;

			return true;
		}
		break;
		}
	case IPPROTO_ICMPV6:
		/* TODO: Should we have the same ICMP request logic here too? */
		if ((filters->icmpv6_flags & cpu_to_le32(SAP_ICMPV6_FILTER_ENABLED) &&
		     match)) {
			if (filters->icmpv6_flags &
			    cpu_to_le32(SAP_ICMPV6_FILTER_COPY))
				*rx_handler_res = RX_HANDLER_PASS;
			else
				*rx_handler_res = RX_HANDLER_CONSUMED;

			return true;
		}
		break;
	default:
		return false;
	}

	return false;
}

static bool iwl_mei_rx_filter_ipv6(struct sk_buff *skb,
				   const struct iwl_sap_oob_filters *filters,
				   rx_handler_result_t *rx_handler_res)
{
	*rx_handler_res = RX_HANDLER_PASS;

	/* TODO */

	return false;
}

static rx_handler_result_t
iwl_mei_rx_pass_to_csme(struct sk_buff *skb,
			const struct iwl_sap_oob_filters *filters,
			bool *pass_to_csme)
{
	const struct ethhdr *ethhdr = (void *)skb_mac_header(skb);
	rx_handler_result_t rx_handler_res = RX_HANDLER_PASS;
	bool (*filt_handler)(struct sk_buff *skb,
			     const struct iwl_sap_oob_filters *filters,
			     rx_handler_result_t *rx_handler_res);

	/*
	 * skb->data points the IP header / ARP header and the ETH header
	 * is in the headroom.
	 */
	skb_reset_network_header(skb);

	/*
	 * MCAST IP packets sent by us are received again here without
	 * an ETH header. Drop them here.
	 */
	if (!skb_mac_offset(skb))
		return RX_HANDLER_PASS;

	if (skb_headroom(skb) < sizeof(*ethhdr))
		return RX_HANDLER_PASS;

	if (iwl_mei_rx_filter_eth(ethhdr, filters,
				  pass_to_csme, &rx_handler_res))
		return rx_handler_res;

	switch (skb->protocol) {
	case htons(ETH_P_IP):
		filt_handler = iwl_mei_rx_filter_ipv4;
		break;
	case htons(ETH_P_ARP):
		filt_handler = iwl_mei_rx_filter_arp;
		break;
	case htons(ETH_P_IPV6):
		filt_handler = iwl_mei_rx_filter_ipv6;
		break;
	default:
		*pass_to_csme = false;
		return rx_handler_res;
	}

	*pass_to_csme = filt_handler(skb, filters, &rx_handler_res);

	return rx_handler_res;
}

rx_handler_result_t iwl_mei_rx_filter(struct sk_buff *orig_skb,
				      const struct iwl_sap_oob_filters *filters,
				      bool *pass_to_csme)
{
	rx_handler_result_t ret;
	struct sk_buff *skb;

	ret = iwl_mei_rx_pass_to_csme(orig_skb, filters, pass_to_csme);

	if (!*pass_to_csme)
		return RX_HANDLER_PASS;

	if (ret == RX_HANDLER_PASS) {
		skb = skb_copy(orig_skb, GFP_ATOMIC);

		if (!skb)
			return RX_HANDLER_PASS;
	} else {
		skb = orig_skb;
	}

	/* CSME wants the MAC header as well, push it back */
	skb_push(skb, skb->data - skb_mac_header(skb));

	/*
	 * Add the packet that CSME wants to get to the ring. Don't send the
	 * Check Shared Area HECI message since this is not possible from the
	 * Rx context. The caller will schedule a worker to do just that.
	 */
	iwl_mei_add_data_to_ring(skb, false);

	/*
	 * In case we drop the packet, don't free it, the caller will do that
	 * for us
	 */
	if (ret == RX_HANDLER_PASS)
		dev_kfree_skb(skb);

	return ret;
}

#define DHCP_SERVER_PORT 67
#define DHCP_CLIENT_PORT 68
void iwl_mei_tx_copy_to_csme(struct sk_buff *origskb, unsigned int ivlen)
{
	struct ieee80211_hdr *hdr;
	struct sk_buff *skb;
	struct ethhdr ethhdr;
	struct ethhdr *eth;

	/* Catch DHCP packets */
	if (origskb->protocol != htons(ETH_P_IP) ||
	    ip_hdr(origskb)->protocol != IPPROTO_UDP ||
	    udp_hdr(origskb)->source != htons(DHCP_CLIENT_PORT) ||
	    udp_hdr(origskb)->dest != htons(DHCP_SERVER_PORT))
		return;

	/*
	 * We could be a bit less aggressive here and not copy everything, but
	 * this is very rare anyway, do don't bother much.
	 */
	skb = skb_copy(origskb, GFP_ATOMIC);
	if (!skb)
		return;

	skb->protocol = origskb->protocol;

	hdr = (void *)skb->data;

	memcpy(ethhdr.h_dest, ieee80211_get_DA(hdr), ETH_ALEN);
	memcpy(ethhdr.h_source, ieee80211_get_SA(hdr), ETH_ALEN);

	/*
	 * Remove the ieee80211 header + IV + SNAP but leave the ethertype
	 * We still have enough headroom for the sap header.
	 */
	pskb_pull(skb, ieee80211_hdrlen(hdr->frame_control) + ivlen + 6);
	eth = skb_push(skb, sizeof(ethhdr.h_dest) + sizeof(ethhdr.h_source));
	memcpy(eth, &ethhdr, sizeof(ethhdr.h_dest) + sizeof(ethhdr.h_source));

	iwl_mei_add_data_to_ring(skb, true);

	dev_kfree_skb(skb);
}
EXPORT_SYMBOL_GPL(iwl_mei_tx_copy_to_csme);
