aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/mcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r--net/ipv6/mcast.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index a51fb33e6864..4b264ed40a8c 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1448,8 +1448,10 @@ static void mld_sendpack(struct sk_buff *skb)
1448 struct net *net = dev_net(skb->dev); 1448 struct net *net = dev_net(skb->dev);
1449 int err; 1449 int err;
1450 struct flowi fl; 1450 struct flowi fl;
1451 struct dst_entry *dst;
1452
1453 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
1451 1454
1452 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
1453 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); 1455 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
1454 mldlen = skb->tail - skb->transport_header; 1456 mldlen = skb->tail - skb->transport_header;
1455 pip6->payload_len = htons(payload_len); 1457 pip6->payload_len = htons(payload_len);
@@ -1458,9 +1460,9 @@ static void mld_sendpack(struct sk_buff *skb)
1458 IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb), 1460 IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb),
1459 mldlen, 0)); 1461 mldlen, 0));
1460 1462
1461 skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); 1463 dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1462 1464
1463 if (!skb->dst) { 1465 if (!dst) {
1464 err = -ENOMEM; 1466 err = -ENOMEM;
1465 goto err_out; 1467 goto err_out;
1466 } 1468 }
@@ -1469,17 +1471,20 @@ static void mld_sendpack(struct sk_buff *skb)
1469 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 1471 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1470 skb->dev->ifindex); 1472 skb->dev->ifindex);
1471 1473
1472 err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0); 1474 err = xfrm_lookup(net, &dst, &fl, NULL, 0);
1475 skb_dst_set(skb, dst);
1473 if (err) 1476 if (err)
1474 goto err_out; 1477 goto err_out;
1475 1478
1479 payload_len = skb->len;
1480
1476 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1481 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
1477 dst_output); 1482 dst_output);
1478out: 1483out:
1479 if (!err) { 1484 if (!err) {
1480 ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT); 1485 ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
1481 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); 1486 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
1482 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTMCASTPKTS); 1487 IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
1483 } else 1488 } else
1484 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS); 1489 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
1485 1490
@@ -1772,11 +1777,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1772 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1777 IPV6_TLV_ROUTERALERT, 2, 0, 0,
1773 IPV6_TLV_PADN, 0 }; 1778 IPV6_TLV_PADN, 0 };
1774 struct flowi fl; 1779 struct flowi fl;
1780 struct dst_entry *dst;
1775 1781
1776 rcu_read_lock();
1777 IP6_INC_STATS(net, __in6_dev_get(dev),
1778 IPSTATS_MIB_OUTREQUESTS);
1779 rcu_read_unlock();
1780 if (type == ICMPV6_MGM_REDUCTION) 1782 if (type == ICMPV6_MGM_REDUCTION)
1781 snd_addr = &in6addr_linklocal_allrouters; 1783 snd_addr = &in6addr_linklocal_allrouters;
1782 else 1784 else
@@ -1786,6 +1788,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1786 payload_len = len + sizeof(ra); 1788 payload_len = len + sizeof(ra);
1787 full_len = sizeof(struct ipv6hdr) + payload_len; 1789 full_len = sizeof(struct ipv6hdr) + payload_len;
1788 1790
1791 rcu_read_lock();
1792 IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
1793 IPSTATS_MIB_OUT, full_len);
1794 rcu_read_unlock();
1795
1789 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); 1796 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
1790 1797
1791 if (skb == NULL) { 1798 if (skb == NULL) {
@@ -1824,8 +1831,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1824 1831
1825 idev = in6_dev_get(skb->dev); 1832 idev = in6_dev_get(skb->dev);
1826 1833
1827 skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); 1834 dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1828 if (!skb->dst) { 1835 if (!dst) {
1829 err = -ENOMEM; 1836 err = -ENOMEM;
1830 goto err_out; 1837 goto err_out;
1831 } 1838 }
@@ -1834,17 +1841,18 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1834 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 1841 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1835 skb->dev->ifindex); 1842 skb->dev->ifindex);
1836 1843
1837 err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0); 1844 err = xfrm_lookup(net, &dst, &fl, NULL, 0);
1838 if (err) 1845 if (err)
1839 goto err_out; 1846 goto err_out;
1840 1847
1848 skb_dst_set(skb, dst);
1841 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1849 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
1842 dst_output); 1850 dst_output);
1843out: 1851out:
1844 if (!err) { 1852 if (!err) {
1845 ICMP6MSGOUT_INC_STATS(net, idev, type); 1853 ICMP6MSGOUT_INC_STATS(net, idev, type);
1846 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); 1854 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
1847 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTMCASTPKTS); 1855 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
1848 } else 1856 } else
1849 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); 1857 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
1850 1858