aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_multicast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r--net/bridge/br_multicast.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 2d85ca7111d..e79ff75b0e7 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1456,7 +1456,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1456{ 1456{
1457 struct sk_buff *skb2; 1457 struct sk_buff *skb2;
1458 const struct ipv6hdr *ip6h; 1458 const struct ipv6hdr *ip6h;
1459 struct icmp6hdr *icmp6h; 1459 u8 icmp6_type;
1460 u8 nexthdr; 1460 u8 nexthdr;
1461 unsigned len; 1461 unsigned len;
1462 int offset; 1462 int offset;
@@ -1501,10 +1501,12 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1501 1501
1502 __skb_pull(skb2, offset); 1502 __skb_pull(skb2, offset);
1503 skb_reset_transport_header(skb2); 1503 skb_reset_transport_header(skb2);
1504 skb_postpull_rcsum(skb2, skb_network_header(skb2),
1505 skb_network_header_len(skb2));
1504 1506
1505 icmp6h = icmp6_hdr(skb2); 1507 icmp6_type = icmp6_hdr(skb2)->icmp6_type;
1506 1508
1507 switch (icmp6h->icmp6_type) { 1509 switch (icmp6_type) {
1508 case ICMPV6_MGM_QUERY: 1510 case ICMPV6_MGM_QUERY:
1509 case ICMPV6_MGM_REPORT: 1511 case ICMPV6_MGM_REPORT:
1510 case ICMPV6_MGM_REDUCTION: 1512 case ICMPV6_MGM_REDUCTION:
@@ -1520,16 +1522,23 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1520 err = pskb_trim_rcsum(skb2, len); 1522 err = pskb_trim_rcsum(skb2, len);
1521 if (err) 1523 if (err)
1522 goto out; 1524 goto out;
1525 err = -EINVAL;
1523 } 1526 }
1524 1527
1528 ip6h = ipv6_hdr(skb2);
1529
1525 switch (skb2->ip_summed) { 1530 switch (skb2->ip_summed) {
1526 case CHECKSUM_COMPLETE: 1531 case CHECKSUM_COMPLETE:
1527 if (!csum_fold(skb2->csum)) 1532 if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, skb2->len,
1533 IPPROTO_ICMPV6, skb2->csum))
1528 break; 1534 break;
1529 /*FALLTHROUGH*/ 1535 /*FALLTHROUGH*/
1530 case CHECKSUM_NONE: 1536 case CHECKSUM_NONE:
1531 skb2->csum = 0; 1537 skb2->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
1532 if (skb_checksum_complete(skb2)) 1538 &ip6h->daddr,
1539 skb2->len,
1540 IPPROTO_ICMPV6, 0));
1541 if (__skb_checksum_complete(skb2))
1533 goto out; 1542 goto out;
1534 } 1543 }
1535 1544
@@ -1537,7 +1546,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1537 1546
1538 BR_INPUT_SKB_CB(skb)->igmp = 1; 1547 BR_INPUT_SKB_CB(skb)->igmp = 1;
1539 1548
1540 switch (icmp6h->icmp6_type) { 1549 switch (icmp6_type) {
1541 case ICMPV6_MGM_REPORT: 1550 case ICMPV6_MGM_REPORT:
1542 { 1551 {
1543 struct mld_msg *mld; 1552 struct mld_msg *mld;