Skip to content

Commit

Permalink
net: bridge: fix corrupted ethernet header on multicast-to-unicast
Browse files Browse the repository at this point in the history
[ Upstream commit 86b29d830ad69eecff25b22dc96c14c6573718e6 ]

The change from skb_copy to pskb_copy unfortunately changed the data
copying to omit the ethernet header, since it was pulled before reaching
this point. Fix this by calling __skb_push/pull around pskb_copy.

Fixes: 59c878cbcdd8 ("net: bridge: fix multicast-to-unicast with fraglist GSO")
Signed-off-by: Felix Fietkau <[email protected]>
Acked-by: Nikolay Aleksandrov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
(cherry picked from commit e96b4e3e5e2d03e72d251aa46853cf609f4f8960)
Signed-off-by: Harshit Mogalapalli <[email protected]>
Signed-off-by: Vegard Nossum <[email protected]>
  • Loading branch information
nbd168 authored and vegard committed Jun 3, 2024
1 parent b497c0e commit 71ccd14
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions net/bridge/br_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
{
struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
const unsigned char *src = eth_hdr(skb)->h_source;
struct sk_buff *nskb;

if (!should_deliver(p, skb))
return;
Expand All @@ -243,12 +244,16 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
if (skb->dev == p->dev && ether_addr_equal(src, addr))
return;

skb = pskb_copy(skb, GFP_ATOMIC);
if (!skb) {
__skb_push(skb, ETH_HLEN);
nskb = pskb_copy(skb, GFP_ATOMIC);
__skb_pull(skb, ETH_HLEN);
if (!nskb) {
DEV_STATS_INC(dev, tx_dropped);
return;
}

skb = nskb;
__skb_pull(skb, ETH_HLEN);
if (!is_broadcast_ether_addr(addr))
memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);

Expand Down

0 comments on commit 71ccd14

Please sign in to comment.