From: Victor Nogueira <victor@mojatatu.com>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, jhs@mojatatu.com, jiri@resnulli.us
Cc: horms@kernel.org, yotam.gi@gmail.com, edragain@163.com,
vega@nebusec.ai, netdev@vger.kernel.org
Subject: [PATCH net] net/sched: act_ife: use mac_len for ingress header offset
Date: Mon, 10 Aug 2026 11:42:01 -0300 [thread overview]
Message-ID: <20260810144201.1563259-1-victor@mojatatu.com> (raw)
On ingress, the L2 header stripped from the frame is skb->mac_len, not
skb->dev->hard_header_len. Use it for the skb_push/skb_pull offsets in
tcf_ife_encode()/tcf_ife_decode() and the matching header length inside
ife_encode()/ife_decode(). On egress keep hard_header_len.
For devices where hard_header_len differs from mac_len (e.g. PPP, which
reports 4 vs 0), the previous code pushed/pulled the wrong amount and
could hit skb_under_panic on ingress when headroom was tight.
Fixes: 295a6e06d21e1 ("net/sched: act_ife: Change to use ife module")
Reported-by: vega@nebusec.ai
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
---
net/ife/ife.c | 18 +++++++++++-------
net/sched/act_ife.c | 6 +++---
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/net/ife/ife.c b/net/ife/ife.c
index 7a75947a31e3..3d31d68114ef 100644
--- a/net/ife/ife.c
+++ b/net/ife/ife.c
@@ -36,8 +36,10 @@ void *ife_encode(struct sk_buff *skb, u16 metalen)
/* OUTERHDR:TOTMETALEN:{TLVHDR:Metadatum:TLVHDR..}:ORIGDATA
* where ORIGDATA = original ethernet header ...
*/
+ unsigned int hdrlen = skb_at_tc_ingress(skb) ?
+ skb->mac_len : skb->dev->hard_header_len;
int hdrm = metalen + IFE_METAHDRLEN;
- int total_push = hdrm + skb->dev->hard_header_len;
+ int total_push = hdrm + hdrlen;
struct ifeheadr *ifehdr;
struct ethhdr *iethh; /* inner ether header */
int skboff = 0;
@@ -50,9 +52,9 @@ void *ife_encode(struct sk_buff *skb, u16 metalen)
iethh = (struct ethhdr *) skb->data;
__skb_push(skb, total_push);
- memcpy(skb->data, iethh, skb->dev->hard_header_len);
+ memcpy(skb->data, iethh, hdrlen);
skb_reset_mac_header(skb);
- skboff += skb->dev->hard_header_len;
+ skboff += hdrlen;
/* total metadata length */
ifehdr = (struct ifeheadr *) (skb->data + skboff);
@@ -65,16 +67,18 @@ EXPORT_SYMBOL_GPL(ife_encode);
void *ife_decode(struct sk_buff *skb, u16 *metalen)
{
+ unsigned int hdrlen = skb_at_tc_ingress(skb) ?
+ skb->mac_len : skb->dev->hard_header_len;
struct ifeheadr *ifehdr;
int total_pull;
u16 ifehdrln;
- if (!pskb_may_pull(skb, skb->dev->hard_header_len + IFE_METAHDRLEN))
+ if (!pskb_may_pull(skb, hdrlen + IFE_METAHDRLEN))
return NULL;
- ifehdr = (struct ifeheadr *) (skb->data + skb->dev->hard_header_len);
+ ifehdr = (struct ifeheadr *)(skb->data + hdrlen);
ifehdrln = ntohs(ifehdr->metalen);
- total_pull = skb->dev->hard_header_len + ifehdrln;
+ total_pull = hdrlen + ifehdrln;
if (unlikely(ifehdrln < 2))
return NULL;
@@ -82,7 +86,7 @@ void *ife_decode(struct sk_buff *skb, u16 *metalen)
if (unlikely(!pskb_may_pull(skb, total_pull + ETH_HLEN)))
return NULL;
- ifehdr = (struct ifeheadr *)(skb->data + skb->dev->hard_header_len);
+ ifehdr = (struct ifeheadr *)(skb->data + hdrlen);
skb_set_mac_header(skb, total_pull);
__skb_pull(skb, total_pull);
*metalen = ifehdrln - IFE_METAHDRLEN;
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index 065228026c58..ea7df36ab7e3 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -723,7 +723,7 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
tcf_lastuse_update(&ife->tcf_tm);
if (skb_at_tc_ingress(skb))
- skb_push(skb, skb->dev->hard_header_len);
+ skb_push(skb, skb->mac_len);
tlv_data = ife_decode(skb, &metalen);
if (unlikely(!tlv_data)) {
@@ -826,7 +826,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
}
if (skb_at_tc_ingress(skb))
- skb_push(skb, skb->dev->hard_header_len);
+ skb_push(skb, skb->mac_len);
ife_meta = ife_encode(skb, metalen);
if (!ife_meta)
@@ -856,7 +856,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
oethh->h_proto = htons(p->eth_type);
if (skb_at_tc_ingress(skb))
- skb_pull(skb, skb->dev->hard_header_len);
+ skb_pull(skb, skb->mac_len);
return action;
}
--
2.55.0
reply other threads:[~2026-08-10 14:42 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260810144201.1563259-1-victor@mojatatu.com \
--to=victor@mojatatu.com \
--cc=davem@davemloft.net \
--cc=edragain@163.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jhs@mojatatu.com \
--cc=jiri@resnulli.us \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=vega@nebusec.ai \
--cc=yotam.gi@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox