[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/exports/sfe_api.h b/exports/sfe_api.h
index a69dfe9..75077b0 100644
--- a/exports/sfe_api.h
+++ b/exports/sfe_api.h
@@ -3,7 +3,7 @@
* SFE exported function headers for SFE engine
*
* Copyright (c) 2015,2016, The Linux Foundation. All rights reserved.
- * 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
diff --git a/sfe.c b/sfe.c
index 22ed43d..8968e94 100644
--- a/sfe.c
+++ b/sfe.c
@@ -3,7 +3,7 @@
* API for shortcut forwarding engine.
*
* Copyright (c) 2015,2016, The Linux Foundation. All rights reserved.
- * 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
@@ -473,7 +473,7 @@
* Parse only PPPoE session packets
* skb->data is pointing to PPPoE hdr
*/
- if (!sfe_pppoe_validate_hdr(skb, l2_info)) {
+ if (!sfe_pppoe_parse_hdr(skb, l2_info)) {
/*
* For exception from PPPoE return from here without modifying the skb->data
@@ -482,10 +482,6 @@
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, SFE_PPPOE_HEADER_SIZE);
-
/*
* Pull by L2 header size considering all L2.5 headers
*/
@@ -1143,6 +1139,11 @@
dev = skb->dev;
+ /*
+ * Setting parse flags to 0 since l2_info is passed for non L2.5 header case as well
+ */
+ l2_info.parse_flags = 0;
+
#ifdef CONFIG_NET_CLS_ACT
/*
* If ingress Qdisc configured, and packet not processed by ingress Qdisc yet
@@ -1166,7 +1167,7 @@
switch (ntohs(skb->protocol)) {
case ETH_P_IP:
if (likely(sfe_is_l2_feature_enabled()) || sfe_dev_is_layer_3_interface(dev, true)) {
- return sfe_ipv4_recv(dev, skb, NULL, false);
+ return sfe_ipv4_recv(dev, skb, &l2_info, false);
}
DEBUG_TRACE("No IPv4 address for device: %s\n", dev->name);
@@ -1174,7 +1175,7 @@
case ETH_P_IPV6:
if (likely(sfe_is_l2_feature_enabled()) || sfe_dev_is_layer_3_interface(dev, false)) {
- return sfe_ipv6_recv(dev, skb, NULL, false);
+ return sfe_ipv6_recv(dev, skb, &l2_info, false);
}
DEBUG_TRACE("No IPv6 address for device: %s\n", dev->name);
@@ -1196,13 +1197,13 @@
* Parse the L2 headers to find the L3 protocol and the L2 header offset
*/
if (unlikely(!sfe_recv_parse_l2(dev, skb, &l2_info))) {
- DEBUG_TRACE("%px: Invalid L2.5 header format\n", skb);
+ DEBUG_TRACE("%px: Invalid L2.5 header format with protocol : %d\n", skb, ntohs(skb->protocol));
return 0;
}
/*
- * Protocol in l2_info is expected to be in network byte order.
- * PPPoE is doing it in the sfe_pppoe_validate_hdr()
+ * Protocol in l2_info is expected to be in host byte order.
+ * PPPoE is doing it in the sfe_pppoe_parse_hdr()
*/
if (likely(l2_info.protocol == ETH_P_IP)) {
ret = sfe_ipv4_recv(dev, skb, &l2_info, false);
diff --git a/sfe.h b/sfe.h
index 01636f2..c6f8421 100644
--- a/sfe.h
+++ b/sfe.h
@@ -3,7 +3,7 @@
* Shortcut forwarding engine.
*
* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
- * 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
@@ -230,7 +230,7 @@
* sfe_l2_parse_flag_set()
* Set L2 parse flag
*/
-static inline void sfe_l2_parse_flag_set(struct sfe_l2_info *l2_info, u32 flag)
+static inline void sfe_l2_parse_flag_set(struct sfe_l2_info *l2_info, u16 flag)
{
l2_info->parse_flags |= flag;
}
@@ -239,7 +239,7 @@
* sfe_l2_parse_flag_get()
* Get L2 parse flag
*/
-static inline u32 sfe_l2_parse_flag_get(struct sfe_l2_info *l2_info)
+static inline u16 sfe_l2_parse_flag_get(struct sfe_l2_info *l2_info)
{
return l2_info->parse_flags;
}
@@ -248,9 +248,9 @@
* sfe_l2_parse_flag_check()
* Check L2 parse flag
*/
-static inline bool sfe_l2_parse_flag_check(struct sfe_l2_info *l2_info, u32 flag)
+static inline bool sfe_l2_parse_flag_check(struct sfe_l2_info *l2_info, u16 flag)
{
- return l2_info->parse_flags & flag;
+ return !!(l2_info->parse_flags & flag);
}
/*
diff --git a/sfe_ipv4.c b/sfe_ipv4.c
index 34fbe1e..154700f 100644
--- a/sfe_ipv4.c
+++ b/sfe_ipv4.c
@@ -3,7 +3,7 @@
* Shortcut forwarding engine - IPv4 edition.
*
* Copyright (c) 2013-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
@@ -2253,10 +2253,13 @@
*/
static unsigned int sfe_ipv4_local_out(void *priv, struct sk_buff *skb, const struct nf_hook_state *nhs)
{
+ struct sfe_l2_info l2_info;
+ l2_info.parse_flags = 0;
+
DEBUG_TRACE("%px: sfe: sfe_ipv4_local_out hook called.\n", skb);
if (likely(skb->skb_iif)) {
- return sfe_ipv4_recv(skb->dev, skb, NULL, true) ? NF_STOLEN : NF_ACCEPT;
+ return sfe_ipv4_recv(skb->dev, skb, &l2_info, true) ? NF_STOLEN : NF_ACCEPT;
}
return NF_ACCEPT;
diff --git a/sfe_ipv4.h b/sfe_ipv4.h
index e614cbc..9f2e1f4 100644
--- a/sfe_ipv4.h
+++ b/sfe_ipv4.h
@@ -3,7 +3,7 @@
* Shortcut forwarding engine header file for IPv4.
*
* Copyright (c) 2013-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
@@ -237,7 +237,7 @@
SFE_IPV4_EXCEPTION_EVENT_DATAGRAM_INCOMPLETE,
SFE_IPV4_EXCEPTION_EVENT_IP_OPTIONS_INCOMPLETE,
SFE_IPV4_EXCEPTION_EVENT_UNHANDLED_PROTOCOL,
- SFE_IPV4_EXCEPTION_EVENT_PPPOE_HEADER_ENCAP_FAILED,
+ SFE_IPV4_EXCEPTION_EVENT_NO_HEADROOM,
SFE_IPV4_EXCEPTION_EVENT_INVALID_PPPOE_SESSION,
SFE_IPV4_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING,
SFE_IPV4_EXCEPTION_EVENT_PPPOE_NOT_SET_IN_CME,
diff --git a/sfe_ipv4_tcp.c b/sfe_ipv4_tcp.c
index 8c229ba..1f8e3d0 100644
--- a/sfe_ipv4_tcp.c
+++ b/sfe_ipv4_tcp.c
@@ -3,7 +3,7 @@
* Shortcut forwarding engine - IPv4 TCP implementation
*
* Copyright (c) 2013-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
@@ -467,45 +467,6 @@
}
/*
- * For PPPoE packets, match server MAC and session id
- */
- if (unlikely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PPPOE_DECAP)) {
- struct pppoe_hdr *ph;
- struct ethhdr *eth;
-
- if (unlikely(!l2_info) || unlikely(!sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE is not parsed\n", skb);
- sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING);
- return 0;
- }
-
- ph = (struct pppoe_hdr *)(skb->head + sfe_l2_pppoe_hdr_offset_get(l2_info));
- eth = (struct ethhdr *)(skb->head + sfe_l2_hdr_offset_get(l2_info));
- if (unlikely(cm->pppoe_session_id != htons(ph->sid)) || unlikely(!(ether_addr_equal((u8*)cm->pppoe_remote_mac, (u8 *)eth->h_source)))) {
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE sessions did not match \n", skb);
- sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
- return 0;
- }
- this_cpu_inc(si->stats_pcpu->pppoe_decap_packets_forwarded64);
-
- } else if (unlikely(l2_info) && unlikely(sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
-
- /*
- * If packet contains PPPOE header but CME doesn't contain PPPoE flag yet we are exceptioning the packet to linux
- */
- rcu_read_unlock();
- DEBUG_TRACE("%px: CME doesn't contain PPPOE flag but packet has PPPoE header\n", skb);
- sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_PPPOE_NOT_SET_IN_CME);
- return 0;
- }
-
- /*
- * From this point on we're good to modify the packet.
- */
-
- /*
* Check if skb was cloned. If it was, unshare it. Because
* the data area is going to be written in this path and we don't want to
* change the cloned skb's data section.
@@ -527,13 +488,54 @@
}
/*
+ * For PPPoE packets, match server MAC and session id
+ */
+ if (unlikely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PPPOE_DECAP)) {
+ struct pppoe_hdr *ph;
+ struct ethhdr *eth;
+
+ if (unlikely(!sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
+ rcu_read_unlock();
+ DEBUG_TRACE("%px: PPPoE header not present in packet for PPPoE rule\n", skb);
+ sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING);
+ return 0;
+ }
+
+ ph = (struct pppoe_hdr *)(skb->head + sfe_l2_pppoe_hdr_offset_get(l2_info));
+ eth = (struct ethhdr *)(skb->head + sfe_l2_hdr_offset_get(l2_info));
+ if (unlikely(cm->pppoe_session_id != ntohs(ph->sid)) || unlikely(!(ether_addr_equal((u8*)cm->pppoe_remote_mac, (u8 *)eth->h_source)))) {
+ DEBUG_TRACE("%px: PPPoE sessions with session IDs %d and %d or server MACs %pM and %pM did not match\n",
+ skb, cm->pppoe_session_id, htons(ph->sid), cm->pppoe_remote_mac, eth->h_source);
+ rcu_read_unlock();
+ sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
+ return 0;
+ }
+ skb->protocol = htons(l2_info->protocol);
+ this_cpu_inc(si->stats_pcpu->pppoe_decap_packets_forwarded64);
+
+ } else if (unlikely(sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
+
+ /*
+ * If packet contains PPPOE header but CME doesn't contain PPPoE flag yet we are exceptioning the packet to linux
+ */
+ rcu_read_unlock();
+ DEBUG_TRACE("%px: CME doesn't contain PPPOE flag but packet has PPPoE header\n", skb);
+ sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_PPPOE_NOT_SET_IN_CME);
+ return 0;
+ }
+
+ /*
+ * From this point on we're good to modify the packet.
+ */
+
+ /*
* For PPPoE flows, add PPPoE header before L2 header is added.
*/
if (cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PPPOE_ENCAP) {
if (unlikely(!sfe_pppoe_add_header(skb, cm->pppoe_session_id, PPP_IP))) {
rcu_read_unlock();
DEBUG_WARN("%px: PPPoE header addition failed\n", skb);
- sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_PPPOE_HEADER_ENCAP_FAILED);
+ sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_NO_HEADROOM);
return 0;
}
this_cpu_inc(si->stats_pcpu->pppoe_encap_packets_forwarded64);
@@ -636,7 +638,7 @@
*/
if (likely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_WRITE_L2_HDR)) {
if (unlikely(!(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR))) {
- dev_hard_header(skb, xmit_dev, ETH_P_IP,
+ dev_hard_header(skb, xmit_dev, ntohs(skb->protocol),
cm->xmit_dest_mac, cm->xmit_src_mac, len);
} else {
/*
@@ -644,7 +646,7 @@
*/
struct ethhdr *eth = (struct ethhdr *)__skb_push(skb, ETH_HLEN);
- eth->h_proto = htons(ETH_P_IP);
+ eth->h_proto = skb->protocol;
ether_addr_copy((u8 *)eth->h_dest, (u8 *)cm->xmit_dest_mac);
ether_addr_copy((u8 *)eth->h_source, (u8 *)cm->xmit_src_mac);
diff --git a/sfe_ipv4_tcp.h b/sfe_ipv4_tcp.h
index 81b7baf..a52ab4f 100644
--- a/sfe_ipv4_tcp.h
+++ b/sfe_ipv4_tcp.h
@@ -3,7 +3,7 @@
* Shortcut forwarding engine - IPv4 TCP header file
*
* Copyright (c) 2013-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
diff --git a/sfe_ipv4_udp.c b/sfe_ipv4_udp.c
index 30aba15..c4847e2 100644
--- a/sfe_ipv4_udp.c
+++ b/sfe_ipv4_udp.c
@@ -3,7 +3,7 @@
* Shortcut forwarding engine - IPv4 UDP implementation
*
* Copyright (c) 2013-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
@@ -259,45 +259,6 @@
}
/*
- * For PPPoE packets, match server MAC and session id
- */
- if (unlikely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PPPOE_DECAP)) {
- struct pppoe_hdr *ph;
- struct ethhdr *eth;
-
- if (unlikely(!l2_info) || unlikely(!sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE is not parsed\n", skb);
- sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING);
- return 0;
- }
-
- ph = (struct pppoe_hdr *)(skb->head + sfe_l2_pppoe_hdr_offset_get(l2_info));
- eth = (struct ethhdr *)(skb->head + sfe_l2_hdr_offset_get(l2_info));
- if (unlikely(cm->pppoe_session_id != htons(ph->sid)) || unlikely(!(ether_addr_equal((u8*)cm->pppoe_remote_mac, (u8 *)eth->h_source)))) {
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE sessions did not match \n", skb);
- sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
- return 0;
- }
- this_cpu_inc(si->stats_pcpu->pppoe_decap_packets_forwarded64);
-
- } else if (unlikely(l2_info) && unlikely(sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
-
- /*
- * If packet contains PPPOE header but CME doesn't contain PPPoE flag yet we are exceptioning the packet to linux
- */
- rcu_read_unlock();
- DEBUG_TRACE("%px: CME doesn't contain PPPOE flag but packet has PPPoE header\n", skb);
- sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_PPPOE_NOT_SET_IN_CME);
- return 0;
- }
-
- /*
- * From this point on we're good to modify the packet.
- */
-
- /*
* Check if skb was cloned. If it was, unshare it. Because
* the data area is going to be written in this path and we don't want to
* change the cloned skb's data section.
@@ -319,13 +280,54 @@
}
/*
+ * For PPPoE packets, match server MAC and session id
+ */
+ if (unlikely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PPPOE_DECAP)) {
+ struct pppoe_hdr *ph;
+ struct ethhdr *eth;
+
+ if (unlikely(!sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
+ rcu_read_unlock();
+ DEBUG_TRACE("%px: PPPoE header not present in packet for PPPoE rule\n", skb);
+ sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING);
+ return 0;
+ }
+
+ ph = (struct pppoe_hdr *)(skb->head + sfe_l2_pppoe_hdr_offset_get(l2_info));
+ eth = (struct ethhdr *)(skb->head + sfe_l2_hdr_offset_get(l2_info));
+ if (unlikely(cm->pppoe_session_id != ntohs(ph->sid)) || unlikely(!(ether_addr_equal((u8*)cm->pppoe_remote_mac, (u8 *)eth->h_source)))) {
+ DEBUG_TRACE("%px: PPPoE sessions with session IDs %d and %d or server MACs %pM and %pM did not match\n",
+ skb, cm->pppoe_session_id, htons(ph->sid), cm->pppoe_remote_mac, eth->h_source);
+ rcu_read_unlock();
+ sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
+ return 0;
+ }
+ skb->protocol = htons(l2_info->protocol);
+ this_cpu_inc(si->stats_pcpu->pppoe_decap_packets_forwarded64);
+
+ } else if (unlikely(sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
+
+ /*
+ * If packet contains PPPOE header but CME doesn't contain PPPoE flag yet we are exceptioning the packet to linux
+ */
+ rcu_read_unlock();
+ DEBUG_TRACE("%px: CME doesn't contain PPPOE flag but packet has PPPoE header\n", skb);
+ sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_PPPOE_NOT_SET_IN_CME);
+ return 0;
+ }
+
+ /*
+ * From this point on we're good to modify the packet.
+ */
+
+ /*
* For PPPoE flows, add PPPoE header before L2 header is added.
*/
if (cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PPPOE_ENCAP) {
if (unlikely(!sfe_pppoe_add_header(skb, cm->pppoe_session_id, PPP_IP))) {
rcu_read_unlock();
DEBUG_WARN("%px: PPPoE header addition failed\n", skb);
- sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_PPPOE_HEADER_ENCAP_FAILED);
+ sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_NO_HEADROOM);
return 0;
}
this_cpu_inc(si->stats_pcpu->pppoe_encap_packets_forwarded64);
@@ -479,14 +481,14 @@
*/
if (likely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_WRITE_L2_HDR)) {
if (unlikely(!(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR))) {
- dev_hard_header(skb, xmit_dev, ETH_P_IP,
+ dev_hard_header(skb, xmit_dev, ntohs(skb->protocol),
cm->xmit_dest_mac, cm->xmit_src_mac, len);
} else {
/*
* For the simple case we write this really fast.
*/
struct ethhdr *eth = (struct ethhdr *)__skb_push(skb, ETH_HLEN);
- eth->h_proto = htons(ETH_P_IP);
+ eth->h_proto = skb->protocol;
ether_addr_copy((u8 *)eth->h_dest, (u8 *)cm->xmit_dest_mac);
ether_addr_copy((u8 *)eth->h_source, (u8 *)cm->xmit_src_mac);
}
diff --git a/sfe_ipv4_udp.h b/sfe_ipv4_udp.h
index 4cb8d47..8c64fcf 100644
--- a/sfe_ipv4_udp.h
+++ b/sfe_ipv4_udp.h
@@ -3,7 +3,7 @@
* Shortcut forwarding engine - IPv4 UDP header file
*
* Copyright (c) 2013-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
diff --git a/sfe_ipv6.c b/sfe_ipv6.c
index 7d75de7..813ce01 100644
--- a/sfe_ipv6.c
+++ b/sfe_ipv6.c
@@ -3,7 +3,7 @@
* Shortcut forwarding engine - IPv6 support.
*
* Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
diff --git a/sfe_ipv6.h b/sfe_ipv6.h
index f737f79..4cbcd50 100644
--- a/sfe_ipv6.h
+++ b/sfe_ipv6.h
@@ -3,7 +3,7 @@
* Shortcut forwarding engine header file for IPv6.
*
* Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
@@ -243,7 +243,7 @@
SFE_IPV6_EXCEPTION_EVENT_IP_OPTIONS_INCOMPLETE,
SFE_IPV6_EXCEPTION_EVENT_UNHANDLED_PROTOCOL,
SFE_IPV6_EXCEPTION_EVENT_FLOW_COOKIE_ADD_FAIL,
- SFE_IPV6_EXCEPTION_EVENT_PPPOE_HEADER_ENCAP_FAILED,
+ SFE_IPV6_EXCEPTION_EVENT_NO_HEADROOM,
SFE_IPV6_EXCEPTION_EVENT_INVALID_PPPOE_SESSION,
SFE_IPV6_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING,
SFE_IPV6_EXCEPTION_EVENT_PPPOE_NOT_SET_IN_CME,
diff --git a/sfe_ipv6_tcp.c b/sfe_ipv6_tcp.c
index f70fea5..11c81ba 100644
--- a/sfe_ipv6_tcp.c
+++ b/sfe_ipv6_tcp.c
@@ -3,7 +3,7 @@
* Shortcut forwarding engine file for IPv6 TCP
*
* Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
@@ -474,46 +474,6 @@
}
/*
- * For PPPoE packets, match server MAC and session id
- */
- if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PPPOE_DECAP)) {
- struct pppoe_hdr *ph;
- struct ethhdr *eth;
-
- if (unlikely(!l2_info) || unlikely(!sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE is not parsed\n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
- return 0;
- }
-
- ph = (struct pppoe_hdr *)(skb->head + sfe_l2_pppoe_hdr_offset_get(l2_info));
- eth = (struct ethhdr *)(skb->head + sfe_l2_hdr_offset_get(l2_info));
-
- if (unlikely(cm->pppoe_session_id != htons(ph->sid)) || unlikely(!(ether_addr_equal((u8*)cm->pppoe_remote_mac, (u8 *)eth->h_source)))) {
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE sessions did not match \n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
- return 0;
- }
- this_cpu_inc(si->stats_pcpu->pppoe_decap_packets_forwarded64);
-
- } else if (unlikely(l2_info) && unlikely(sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
-
- /*
- * If packet contains PPPOE header but CME doesn't contain PPPoE flag yet we are exceptioning the packet to linux
- */
- rcu_read_unlock();
- DEBUG_TRACE("%px: CME doesn't contain PPPOE flag but packet has PPPoE header\n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_PPPOE_NOT_SET_IN_CME);
- return 0;
- }
-
- /*
- * From this point on we're good to modify the packet.
- */
-
- /*
* Check if skb was cloned. If it was, unshare it. Because
* the data area is going to be written in this path and we don't want to
* change the cloned skb's data section.
@@ -535,14 +495,55 @@
}
/*
+ * For PPPoE packets, match server MAC and session id
+ */
+ if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PPPOE_DECAP)) {
+ struct pppoe_hdr *ph;
+ struct ethhdr *eth;
+
+ if (unlikely(!sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
+ rcu_read_unlock();
+ DEBUG_TRACE("%px: PPPoE header not present in packet for PPPoE rule\n", skb);
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
+ return 0;
+ }
+
+ ph = (struct pppoe_hdr *)(skb->head + sfe_l2_pppoe_hdr_offset_get(l2_info));
+ eth = (struct ethhdr *)(skb->head + sfe_l2_hdr_offset_get(l2_info));
+
+ if (unlikely(cm->pppoe_session_id != ntohs(ph->sid)) || unlikely(!(ether_addr_equal((u8*)cm->pppoe_remote_mac, (u8 *)eth->h_source)))) {
+ DEBUG_TRACE("%px: PPPoE sessions with session IDs %d and %d or server MACs %pM and %pM did not match \n",
+ skb, cm->pppoe_session_id, htons(ph->sid), cm->pppoe_remote_mac, eth->h_source);
+ rcu_read_unlock();
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
+ return 0;
+ }
+ skb->protocol = htons(l2_info->protocol);
+ this_cpu_inc(si->stats_pcpu->pppoe_decap_packets_forwarded64);
+
+ } else if (unlikely(sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
+
+ /*
+ * If packet contains PPPOE header but CME doesn't contain PPPoE flag yet we are exceptioning the packet to linux
+ */
+ rcu_read_unlock();
+ DEBUG_TRACE("%px: CME doesn't contain PPPOE flag but packet has PPPoE header\n", skb);
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_PPPOE_NOT_SET_IN_CME);
+ return 0;
+ }
+
+ /*
+ * From this point on we're good to modify the packet.
+ */
+
+ /*
* For PPPoE flows, add PPPoE header before L2 header is added.
*/
if (cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PPPOE_ENCAP) {
if (unlikely(!sfe_pppoe_add_header(skb, cm->pppoe_session_id, PPP_IPV6))) {
rcu_read_unlock();
DEBUG_WARN("%px: PPPoE header addition failed\n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_PPPOE_HEADER_ENCAP_FAILED);
- return 0;
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_NO_HEADROOM);
}
this_cpu_inc(si->stats_pcpu->pppoe_encap_packets_forwarded64);
}
@@ -639,7 +640,7 @@
*/
if (likely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_L2_HDR)) {
if (unlikely(!(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR))) {
- dev_hard_header(skb, xmit_dev, ETH_P_IPV6,
+ dev_hard_header(skb, xmit_dev, ntohs(skb->protocol),
cm->xmit_dest_mac, cm->xmit_src_mac, len);
} else {
/*
@@ -647,7 +648,7 @@
*/
struct ethhdr *eth = (struct ethhdr *)__skb_push(skb, ETH_HLEN);
- eth->h_proto = htons(ETH_P_IPV6);
+ eth->h_proto = skb->protocol;
ether_addr_copy((u8 *)eth->h_dest, (u8 *)cm->xmit_dest_mac);
ether_addr_copy((u8 *)eth->h_source, (u8 *)cm->xmit_src_mac);
}
diff --git a/sfe_ipv6_tcp.h b/sfe_ipv6_tcp.h
index 069dc41..5aecc3f 100644
--- a/sfe_ipv6_tcp.h
+++ b/sfe_ipv6_tcp.h
@@ -3,7 +3,7 @@
* Shortcut forwarding engine header file for IPv6 TCP
*
* Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
diff --git a/sfe_ipv6_udp.c b/sfe_ipv6_udp.c
index 5ddaef6..c5e522d 100644
--- a/sfe_ipv6_udp.c
+++ b/sfe_ipv6_udp.c
@@ -3,7 +3,7 @@
* Shortcut forwarding engine file for IPv6 UDP
*
* Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
@@ -266,45 +266,6 @@
}
/*
- * For PPPoE packets, match server MAC and session id
- */
- if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PPPOE_DECAP)) {
- struct pppoe_hdr *ph;
- struct ethhdr *eth;
-
- if (unlikely(!l2_info) || unlikely(!sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE is not parsed\n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING);
- return 0;
- }
-
- ph = (struct pppoe_hdr *)(skb->head + sfe_l2_pppoe_hdr_offset_get(l2_info));
- eth = (struct ethhdr *)(skb->head + sfe_l2_hdr_offset_get(l2_info));
- if (unlikely(cm->pppoe_session_id != htons(ph->sid)) || unlikely(!(ether_addr_equal((u8*)cm->pppoe_remote_mac, (u8 *)eth->h_source)))) {
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE sessions did not match \n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
- return 0;
- }
- this_cpu_inc(si->stats_pcpu->pppoe_decap_packets_forwarded64);
-
- } else if (unlikely(l2_info) && unlikely(sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
-
- /*
- * If packet contains PPPOE header but CME doesn't contain PPPoE flag yet we are exceptioning the packet to linux
- */
- rcu_read_unlock();
- DEBUG_TRACE("%px: PPPoE is not parsed\n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING);
- return 0;
- }
-
- /*
- * From this point on we're good to modify the packet.
- */
-
- /*
* Check if skb was cloned. If it was, unshare it. Because
* the data area is going to be written in this path and we don't want to
* change the cloned skb's data section.
@@ -326,14 +287,54 @@
}
/*
+ * For PPPoE packets, match server MAC and session id
+ */
+ if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PPPOE_DECAP)) {
+ struct pppoe_hdr *ph;
+ struct ethhdr *eth;
+
+ if (unlikely(!sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
+ rcu_read_unlock();
+ DEBUG_TRACE("%px: PPPoE header not present in packet for PPPoE rule\n", skb);
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING);
+ return 0;
+ }
+
+ ph = (struct pppoe_hdr *)(skb->head + sfe_l2_pppoe_hdr_offset_get(l2_info));
+ eth = (struct ethhdr *)(skb->head + sfe_l2_hdr_offset_get(l2_info));
+ if (unlikely(cm->pppoe_session_id != ntohs(ph->sid)) || unlikely(!(ether_addr_equal((u8*)cm->pppoe_remote_mac, (u8 *)eth->h_source)))) {
+ DEBUG_TRACE("%px: PPPoE sessions with session IDs %d and %d or server MACs %pM and %pM did not match\n",
+ skb, cm->pppoe_session_id, htons(ph->sid), cm->pppoe_remote_mac, eth->h_source);
+ rcu_read_unlock();
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INVALID_PPPOE_SESSION);
+ return 0;
+ }
+ skb->protocol = htons(l2_info->protocol);
+ this_cpu_inc(si->stats_pcpu->pppoe_decap_packets_forwarded64);
+
+ } else if (unlikely(sfe_l2_parse_flag_check(l2_info, SFE_L2_PARSE_FLAGS_PPPOE_INGRESS))) {
+
+ /*
+ * If packet contains PPPOE header but CME doesn't contain PPPoE flag yet we are exceptioning the packet to linux
+ */
+ rcu_read_unlock();
+ DEBUG_TRACE("%px: PPPoE is not parsed\n", skb);
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INCORRECT_PPPOE_PARSING);
+ return 0;
+ }
+
+ /*
+ * From this point on we're good to modify the packet.
+ */
+
+ /*
* For PPPoE flows, add PPPoE header before L2 header is added.
*/
if (cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PPPOE_ENCAP) {
if (unlikely(!sfe_pppoe_add_header(skb, cm->pppoe_session_id, PPP_IPV6))) {
rcu_read_unlock();
DEBUG_WARN("%px: PPPoE header addition failed\n", skb);
- sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_PPPOE_HEADER_ENCAP_FAILED);
- return 0;
+ sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_NO_HEADROOM);
}
this_cpu_inc(si->stats_pcpu->pppoe_encap_packets_forwarded64);
}
@@ -473,14 +474,14 @@
*/
if (likely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_L2_HDR)) {
if (unlikely(!(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR))) {
- dev_hard_header(skb, xmit_dev, ETH_P_IPV6,
+ dev_hard_header(skb, xmit_dev, ntohs(skb->protocol),
cm->xmit_dest_mac, cm->xmit_src_mac, len);
} else {
/*
* For the simple case we write this really fast.
*/
struct ethhdr *eth = (struct ethhdr *)__skb_push(skb, ETH_HLEN);
- eth->h_proto = htons(ETH_P_IPV6);
+ eth->h_proto = skb->protocol;
ether_addr_copy((u8 *)eth->h_dest, (u8 *)cm->xmit_dest_mac);
ether_addr_copy((u8 *)eth->h_source, (u8 *)cm->xmit_src_mac);
}
diff --git a/sfe_ipv6_udp.h b/sfe_ipv6_udp.h
index 2899be6..edab1f6 100644
--- a/sfe_ipv6_udp.h
+++ b/sfe_ipv6_udp.h
@@ -3,7 +3,7 @@
* Shortcut forwarding engine header file for IPv6 UDP
*
* Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * 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
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;
}
diff --git a/sfe_pppoe.h b/sfe_pppoe.h
index c5f97b2..4190b4e 100644
--- a/sfe_pppoe.h
+++ b/sfe_pppoe.h
@@ -2,7 +2,7 @@
* sfe_pppoe.h
* Shortcut flow acceleration for PPPoE flow
*
- * 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
@@ -16,10 +16,13 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+
#include <linux/ppp_defs.h>
#include <linux/if_pppox.h>
-#define SFE_PPPOE_HEADER_SIZE (sizeof(struct pppoe_hdr) + 2)
+struct sfe_ppp_hdr {
+ u16 protocol;
+};
bool sfe_pppoe_add_header(struct sk_buff *skb, u16 pppoe_session_id, u16 ppp_protocol);
-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);