diff options
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r-- | net/ipv6/mcast.c | 34 |
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); |
1478 | out: | 1483 | out: |
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); |
1843 | out: | 1851 | out: |
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 | ||