Sfoglia il codice sorgente

bridge: Pseudo-header required for the checksum of ICMPv6

Checksum of ICMPv6 is not properly computed because the pseudo header is not used.
Thus, the MLD packet gets dropped by the bridge.

Signed-off-by: Zheng Yan <zheng.z.yan@intel.com>
Reported-by: Ang Way Chuang <wcang@sfc.wide.ad.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
Yan, Zheng 14 anni fa
parent
commit
4b275d7efa
1 ha cambiato i file con 10 aggiunte e 3 eliminazioni
  1. 10 3
      net/bridge/br_multicast.c

+ 10 - 3
net/bridge/br_multicast.c

@@ -1520,16 +1520,23 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
 		err = pskb_trim_rcsum(skb2, len);
 		err = pskb_trim_rcsum(skb2, len);
 		if (err)
 		if (err)
 			goto out;
 			goto out;
+		err = -EINVAL;
 	}
 	}
 
 
+	ip6h = ipv6_hdr(skb2);
+
 	switch (skb2->ip_summed) {
 	switch (skb2->ip_summed) {
 	case CHECKSUM_COMPLETE:
 	case CHECKSUM_COMPLETE:
-		if (!csum_fold(skb2->csum))
+		if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, skb2->len,
+					IPPROTO_ICMPV6, skb2->csum))
 			break;
 			break;
 		/*FALLTHROUGH*/
 		/*FALLTHROUGH*/
 	case CHECKSUM_NONE:
 	case CHECKSUM_NONE:
-		skb2->csum = 0;
-		if (skb_checksum_complete(skb2))
+		skb2->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
+							&ip6h->daddr,
+							skb2->len,
+							IPPROTO_ICMPV6, 0));
+		if (__skb_checksum_complete(skb2))
 			goto out;
 			goto out;
 	}
 	}