[qca-nss-sfe] PPPoE offload fixes

1. Fix protocol and endianess
2. Fix copyright year style
3. Pass non-NULL l2_info and check parse flags before using l2_info

Change-Id: I7801834b224a39a04450fdacbbb9cb9620b4221c
Signed-off-by: Guduri Prathyusha <quic_gprathyu@quicinc.com>
diff --git a/sfe_pppoe.c b/sfe_pppoe.c
index 89e4a90..4f9341e 100644
--- a/sfe_pppoe.c
+++ b/sfe_pppoe.c
@@ -2,7 +2,7 @@
  * sfe_pppoe.c
  *     API for shortcut forwarding engine PPPoE flows
  *
- * Copyright (c) 2021,2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-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
@@ -36,66 +36,71 @@
 {
 	u16 *l2_header;
 	struct pppoe_hdr *ph;
+	struct sfe_ppp_hdr *ppp;
 	u16 *l3_header = (u16 *)skb->data;
 
 	/*
-	 * Check that we have space for PPPoE header and PPP header (2 bytes)
+	 * Check that we have space for PPPoE header, PPP header (2 bytes) and Ethernet header
+	 * TODO: Calculate the l2_hdr_len during rule push so that this is avoided in datapath
 	 */
-	if (unlikely(!pskb_may_pull(skb, SFE_PPPOE_HEADER_SIZE))) {
-		DEBUG_TRACE("%px: Not enough headroom for PPPoE header \n", skb);
+	if (unlikely(skb_headroom(skb) < ((sizeof(struct pppoe_hdr) + sizeof(struct sfe_ppp_hdr)) + ETH_HLEN))) {
+		DEBUG_TRACE("%px: Not enough headroom for PPPoE header\n", skb);
 		return false;
 	}
 
 	/*
-	 * PPPoE header (8 bytes) + PPP header (2 bytes)
+	 * PPPoE header (6 bytes) + PPP header (2 bytes)
 	 *
-	 * Hence move by 10 bytes to accomodate PPPoE header
+	 * Hence move by 8 bytes to accomodate PPPoE header
 	 */
-	l2_header = l3_header - (SFE_PPPOE_HEADER_SIZE / 2);
+	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(10 bytes) | L3 hdr |
+	 *	| 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 = pppoe_session_id;
-	ph->length = skb->len;
-	skb->protocol = cpu_to_be16(ETH_P_PPP_SES);
+	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
 	 */
-	*(l2_header + 4) = ppp_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,
-	 * since sfe_ipv4_recv_tcp/udp() does skb_push by ETH_HLEN before adding L2 header.
 	 */
-	__skb_push(skb, SFE_PPPOE_HEADER_SIZE);
+	__skb_push(skb, (sizeof(struct pppoe_hdr) + sizeof(struct sfe_ppp_hdr)));
 
 	return true;
 }
 
 /*
- * sfe_pppoe_validate_hdr()
- *	Validate PPPoE header
+ * sfe_pppoe_parse_hdr()
+ *	Parse PPPoE header
  *
  * Returns true if the packet is good for further processing.
  */
-bool sfe_pppoe_validate_hdr(struct sk_buff *skb, struct sfe_l2_info *l2_info)
+bool sfe_pppoe_parse_hdr(struct sk_buff *skb, struct sfe_l2_info *l2_info)
 {
-	u16 ppp_protocol;
 	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, SFE_PPPOE_HEADER_SIZE))) {
+	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;
 	}
@@ -107,28 +112,32 @@
 		return false;
 	}
 
-	ppp_protocol = htons((*(uint16_t *)((u8 *)ph + sizeof(*ph))));
+	ppp = (struct sfe_ppp_hdr *)((u8*)ph + sizeof(*ph));
 
 	/*
 	 * Converting PPP protocol values to ether type protocol values
 	 */
-	switch(ppp_protocol) {
+	switch(ntohs(ppp->protocol)) {
 	case PPP_IP:
 		sfe_l2_protocol_set(l2_info, ETH_P_IP);
-		return true;
+		break;
 
 	case PPP_IPV6:
 		sfe_l2_protocol_set(l2_info, ETH_P_IPV6);
-		return true;
+		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, ppp_protocol);
-		break;
+		DEBUG_TRACE("%px: Unsupported protocol : %d in PPP header\n", skb, ntohs(ppp->protocol));
+		return false;
 	}
 
-	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;
 }