@@ -3159,8 +3159,20 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff,
static u32 __bpf_skb_max_len(const struct sk_buff *skb)
{
- return skb->dev ? skb->dev->mtu + skb->dev->hard_header_len :
- SKB_MAX_ALLOC;
+ if (skb->dev) {
+ unsigned short header_len = skb->dev->hard_header_len;
+
+ /* HACK: Treat 0 as ETH_HLEN to allow redirect while
+ * adding ethernet header from an L3 (tun, rawip, cellular)
+ * to an L2 device (tap, ethernet, wifi)
+ */
+ if (!header_len)
+ header_len = ETH_HLEN;
+
+ return skb->dev->mtu + header_len;
+ } else {
+ return SKB_MAX_ALLOC;
+ }
}
BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,