/*
 * sfe_pppoe.c
 *     API for shortcut forwarding engine PPPoE flows
 *
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/skbuff.h>
#include <linux/if_pppox.h>
#include <linux/ppp_defs.h>

#include "sfe_debug.h"
#include "sfe_api.h"
#include "sfe.h"
#include "sfe_pppoe.h"

/*
 * sfe_pppoe_add_header()
 *	Add PPPoE header.
 *
 * skb->data will point to PPPoE header after the function
 */
void sfe_pppoe_add_header(struct sk_buff *skb, u16 pppoe_session_id, u16 ppp_protocol)
{
	u16 *l2_header;
	struct pppoe_hdr *ph;
	struct sfe_ppp_hdr *ppp;
	u16 *l3_header = (u16 *)skb->data;

	/*
	 * PPPoE header (6 bytes) + PPP header (2 bytes)
	 *
	 * Hence move by 8 bytes to accomodate PPPoE header
	 */
	l2_header = l3_header - ((sizeof(struct pppoe_hdr) + sizeof(struct sfe_ppp_hdr)) / 2);

	/*
	 * Headers in skb will look like in below sequence
	 *	| PPPoE hdr(6 bytes) | PPP hdr (2 bytes) | L3 hdr |
	 *
	 *	The length field in the PPPoE header indicates the length of the PPPoE payload which
	 *	consists of a 2-byte PPP header plus a skb->len.
	 */
	ph = (struct pppoe_hdr *)l2_header;
	ph->ver = 1;
	ph->type = 1;
	ph->code = 0;
	ph->sid = htons(pppoe_session_id);
	ph->length = htons(skb->len + sizeof(struct sfe_ppp_hdr));
	skb->protocol = htons(ETH_P_PPP_SES);

	/*
	 * Insert the PPP header protocol
	 */
	ppp = (struct sfe_ppp_hdr *)(l2_header + (sizeof(struct pppoe_hdr) / 2));
	ppp->protocol = htons(ppp_protocol);

	/*
	 * L2 header offset will point to PPPoE header,
	 */
	__skb_push(skb, (sizeof(struct pppoe_hdr) + sizeof(struct sfe_ppp_hdr)));
}

/*
 * sfe_pppoe_parse_hdr()
 *	Parse PPPoE header
 *
 * Returns true if the packet is good for further processing.
 */
bool sfe_pppoe_parse_hdr(struct sk_buff *skb, struct sfe_l2_info *l2_info)
{
	unsigned int len;
	int pppoe_len;
	struct sfe_ppp_hdr *ppp;
	struct pppoe_hdr *ph = (struct pppoe_hdr *)skb->data;

	/*
	 * Check that we have space for PPPoE header here.
	 */
	if (unlikely(!pskb_may_pull(skb, (sizeof(struct pppoe_hdr) + sizeof(struct sfe_ppp_hdr))))) {
		DEBUG_TRACE("%px: packet too short for PPPoE header\n", skb);
		return false;
	}

	len = skb->len;
	pppoe_len = ntohs(ph->length);
	if (unlikely(len < pppoe_len)) {
		DEBUG_TRACE("%px: len: %u is too short to %u\n", skb, len, pppoe_len);
		return false;
	}

	ppp = (struct sfe_ppp_hdr *)((u8*)ph + sizeof(*ph));

	/*
	 * Converting PPP protocol values to ether type protocol values
	 */
	switch(ntohs(ppp->protocol)) {
	case PPP_IP:
		sfe_l2_protocol_set(l2_info, ETH_P_IP);
		break;

	case PPP_IPV6:
		sfe_l2_protocol_set(l2_info, ETH_P_IPV6);
		break;

	case PPP_LCP:
		DEBUG_TRACE("%px: LCP packets are not supported in SFE\n", skb);
		return false;

	default:
		DEBUG_TRACE("%px: Unsupported protocol : %d in PPP header\n", skb, ntohs(ppp->protocol));
		return false;
	}

	sfe_l2_parse_flag_set(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS);
	sfe_l2_pppoe_hdr_offset_set(l2_info, (skb->data - skb->head));
	sfe_l2_hdr_size_set(l2_info, (sizeof(struct pppoe_hdr) + sizeof(struct sfe_ppp_hdr)));

	return true;
}
