]>
Commit | Line | Data |
---|---|---|
1d34c510 SL |
1 | From 41b5528da82176293450cbcd7828aa73da9634b0 Mon Sep 17 00:00:00 2001 |
2 | From: Sasha Levin <sashal@kernel.org> | |
3 | Date: Sun, 5 May 2024 20:42:38 +0200 | |
4 | Subject: net: bridge: fix corrupted ethernet header on multicast-to-unicast | |
5 | ||
6 | From: Felix Fietkau <nbd@nbd.name> | |
7 | ||
8 | [ Upstream commit 86b29d830ad69eecff25b22dc96c14c6573718e6 ] | |
9 | ||
10 | The change from skb_copy to pskb_copy unfortunately changed the data | |
11 | copying to omit the ethernet header, since it was pulled before reaching | |
12 | this point. Fix this by calling __skb_push/pull around pskb_copy. | |
13 | ||
14 | Fixes: 59c878cbcdd8 ("net: bridge: fix multicast-to-unicast with fraglist GSO") | |
15 | Signed-off-by: Felix Fietkau <nbd@nbd.name> | |
16 | Acked-by: Nikolay Aleksandrov <razor@blackwall.org> | |
17 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
18 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
19 | --- | |
20 | net/bridge/br_forward.c | 9 +++++++-- | |
21 | 1 file changed, 7 insertions(+), 2 deletions(-) | |
22 | ||
23 | diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c | |
24 | index 3a70682e63524..ada03d49e7c1a 100644 | |
25 | --- a/net/bridge/br_forward.c | |
26 | +++ b/net/bridge/br_forward.c | |
27 | @@ -245,6 +245,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, | |
28 | { | |
29 | struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev; | |
30 | const unsigned char *src = eth_hdr(skb)->h_source; | |
31 | + struct sk_buff *nskb; | |
32 | ||
33 | if (!should_deliver(p, skb)) | |
34 | return; | |
35 | @@ -253,12 +254,16 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, | |
36 | if (skb->dev == p->dev && ether_addr_equal(src, addr)) | |
37 | return; | |
38 | ||
39 | - skb = pskb_copy(skb, GFP_ATOMIC); | |
40 | - if (!skb) { | |
41 | + __skb_push(skb, ETH_HLEN); | |
42 | + nskb = pskb_copy(skb, GFP_ATOMIC); | |
43 | + __skb_pull(skb, ETH_HLEN); | |
44 | + if (!nskb) { | |
45 | DEV_STATS_INC(dev, tx_dropped); | |
46 | return; | |
47 | } | |
48 | ||
49 | + skb = nskb; | |
50 | + __skb_pull(skb, ETH_HLEN); | |
51 | if (!is_broadcast_ether_addr(addr)) | |
52 | memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN); | |
53 | ||
54 | -- | |
55 | 2.43.0 | |
56 |