[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;
}