]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - net/ipv6/netfilter/ip6t_REJECT.c
netfilter: ip[6]t_REJECT: tcp-reset using wrong MAC source if bridged
[mirror_ubuntu-jammy-kernel.git] / net / ipv6 / netfilter / ip6t_REJECT.c
index 70f9abc0efe9a0ba0bc8fdbb6060f3bfe593291f..56eef30ee5f6afb2ad1338649b30ffe8a5c5b948 100644 (file)
@@ -169,7 +169,25 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
 
        nf_ct_attach(nskb, oldskb);
 
-       ip6_local_out(nskb);
+#ifdef CONFIG_BRIDGE_NETFILTER
+       /* If we use ip6_local_out for bridged traffic, the MAC source on
+        * the RST will be ours, instead of the destination's.  This confuses
+        * some routers/firewalls, and they drop the packet.  So we need to
+        * build the eth header using the original destination's MAC as the
+        * source, and send the RST packet directly.
+        */
+       if (oldskb->nf_bridge) {
+               struct ethhdr *oeth = eth_hdr(oldskb);
+               nskb->dev = oldskb->nf_bridge->physindev;
+               nskb->protocol = htons(ETH_P_IPV6);
+               ip6h->payload_len = htons(sizeof(struct tcphdr));
+               if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
+                                   oeth->h_source, oeth->h_dest, nskb->len) < 0)
+                       return;
+               dev_queue_xmit(nskb);
+       } else
+#endif
+               ip6_local_out(nskb);
 }
 
 static inline void