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.c44
1 files changed, 17 insertions, 27 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index ee7839f4d6e3..b853f06cc148 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -155,14 +155,14 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
155 return -ENOMEM; 155 return -ENOMEM;
156 156
157 mc_lst->next = NULL; 157 mc_lst->next = NULL;
158 ipv6_addr_copy(&mc_lst->addr, addr); 158 mc_lst->addr = *addr;
159 159
160 rcu_read_lock(); 160 rcu_read_lock();
161 if (ifindex == 0) { 161 if (ifindex == 0) {
162 struct rt6_info *rt; 162 struct rt6_info *rt;
163 rt = rt6_lookup(net, addr, NULL, 0, 0); 163 rt = rt6_lookup(net, addr, NULL, 0, 0);
164 if (rt) { 164 if (rt) {
165 dev = rt->rt6i_dev; 165 dev = rt->dst.dev;
166 dst_release(&rt->dst); 166 dst_release(&rt->dst);
167 } 167 }
168 } else 168 } else
@@ -256,7 +256,7 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
256 struct rt6_info *rt = rt6_lookup(net, group, NULL, 0, 0); 256 struct rt6_info *rt = rt6_lookup(net, group, NULL, 0, 0);
257 257
258 if (rt) { 258 if (rt) {
259 dev = rt->rt6i_dev; 259 dev = rt->dst.dev;
260 dev_hold(dev); 260 dev_hold(dev);
261 dst_release(&rt->dst); 261 dst_release(&rt->dst);
262 } 262 }
@@ -858,7 +858,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr)
858 858
859 setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc); 859 setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc);
860 860
861 ipv6_addr_copy(&mc->mca_addr, addr); 861 mc->mca_addr = *addr;
862 mc->idev = idev; /* (reference taken) */ 862 mc->idev = idev; /* (reference taken) */
863 mc->mca_users = 1; 863 mc->mca_users = 1;
864 /* mca_stamp should be updated upon changes */ 864 /* mca_stamp should be updated upon changes */
@@ -1343,13 +1343,15 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1343 struct mld2_report *pmr; 1343 struct mld2_report *pmr;
1344 struct in6_addr addr_buf; 1344 struct in6_addr addr_buf;
1345 const struct in6_addr *saddr; 1345 const struct in6_addr *saddr;
1346 int hlen = LL_RESERVED_SPACE(dev);
1347 int tlen = dev->needed_tailroom;
1346 int err; 1348 int err;
1347 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1349 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1348 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1350 IPV6_TLV_ROUTERALERT, 2, 0, 0,
1349 IPV6_TLV_PADN, 0 }; 1351 IPV6_TLV_PADN, 0 };
1350 1352
1351 /* we assume size > sizeof(ra) here */ 1353 /* we assume size > sizeof(ra) here */
1352 size += LL_ALLOCATED_SPACE(dev); 1354 size += hlen + tlen;
1353 /* limit our allocations to order-0 page */ 1355 /* limit our allocations to order-0 page */
1354 size = min_t(int, size, SKB_MAX_ORDER(0, 0)); 1356 size = min_t(int, size, SKB_MAX_ORDER(0, 0));
1355 skb = sock_alloc_send_skb(sk, size, 1, &err); 1357 skb = sock_alloc_send_skb(sk, size, 1, &err);
@@ -1357,7 +1359,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1357 if (!skb) 1359 if (!skb)
1358 return NULL; 1360 return NULL;
1359 1361
1360 skb_reserve(skb, LL_RESERVED_SPACE(dev)); 1362 skb_reserve(skb, hlen);
1361 1363
1362 if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { 1364 if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) {
1363 /* <draft-ietf-magma-mld-source-05.txt>: 1365 /* <draft-ietf-magma-mld-source-05.txt>:
@@ -1408,18 +1410,11 @@ static void mld_sendpack(struct sk_buff *skb)
1408 csum_partial(skb_transport_header(skb), 1410 csum_partial(skb_transport_header(skb),
1409 mldlen, 0)); 1411 mldlen, 0));
1410 1412
1411 dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1412
1413 if (!dst) {
1414 err = -ENOMEM;
1415 goto err_out;
1416 }
1417
1418 icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT, 1413 icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT,
1419 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 1414 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1420 skb->dev->ifindex); 1415 skb->dev->ifindex);
1416 dst = icmp6_dst_alloc(skb->dev, NULL, &fl6);
1421 1417
1422 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
1423 err = 0; 1418 err = 0;
1424 if (IS_ERR(dst)) { 1419 if (IS_ERR(dst)) {
1425 err = PTR_ERR(dst); 1420 err = PTR_ERR(dst);
@@ -1723,6 +1718,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1723 struct mld_msg *hdr; 1718 struct mld_msg *hdr;
1724 const struct in6_addr *snd_addr, *saddr; 1719 const struct in6_addr *snd_addr, *saddr;
1725 struct in6_addr addr_buf; 1720 struct in6_addr addr_buf;
1721 int hlen = LL_RESERVED_SPACE(dev);
1722 int tlen = dev->needed_tailroom;
1726 int err, len, payload_len, full_len; 1723 int err, len, payload_len, full_len;
1727 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1724 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1728 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1725 IPV6_TLV_ROUTERALERT, 2, 0, 0,
@@ -1744,7 +1741,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1744 IPSTATS_MIB_OUT, full_len); 1741 IPSTATS_MIB_OUT, full_len);
1745 rcu_read_unlock(); 1742 rcu_read_unlock();
1746 1743
1747 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); 1744 skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err);
1748 1745
1749 if (skb == NULL) { 1746 if (skb == NULL) {
1750 rcu_read_lock(); 1747 rcu_read_lock();
@@ -1754,7 +1751,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1754 return; 1751 return;
1755 } 1752 }
1756 1753
1757 skb_reserve(skb, LL_RESERVED_SPACE(dev)); 1754 skb_reserve(skb, hlen);
1758 1755
1759 if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { 1756 if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) {
1760 /* <draft-ietf-magma-mld-source-05.txt>: 1757 /* <draft-ietf-magma-mld-source-05.txt>:
@@ -1772,7 +1769,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1772 hdr = (struct mld_msg *) skb_put(skb, sizeof(struct mld_msg)); 1769 hdr = (struct mld_msg *) skb_put(skb, sizeof(struct mld_msg));
1773 memset(hdr, 0, sizeof(struct mld_msg)); 1770 memset(hdr, 0, sizeof(struct mld_msg));
1774 hdr->mld_type = type; 1771 hdr->mld_type = type;
1775 ipv6_addr_copy(&hdr->mld_mca, addr); 1772 hdr->mld_mca = *addr;
1776 1773
1777 hdr->mld_cksum = csum_ipv6_magic(saddr, snd_addr, len, 1774 hdr->mld_cksum = csum_ipv6_magic(saddr, snd_addr, len,
1778 IPPROTO_ICMPV6, 1775 IPPROTO_ICMPV6,
@@ -1781,17 +1778,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1781 rcu_read_lock(); 1778 rcu_read_lock();
1782 idev = __in6_dev_get(skb->dev); 1779 idev = __in6_dev_get(skb->dev);
1783 1780
1784 dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1785 if (!dst) {
1786 err = -ENOMEM;
1787 goto err_out;
1788 }
1789
1790 icmpv6_flow_init(sk, &fl6, type, 1781 icmpv6_flow_init(sk, &fl6, type,
1791 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 1782 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1792 skb->dev->ifindex); 1783 skb->dev->ifindex);
1793 1784 dst = icmp6_dst_alloc(skb->dev, NULL, &fl6);
1794 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
1795 if (IS_ERR(dst)) { 1785 if (IS_ERR(dst)) {
1796 err = PTR_ERR(dst); 1786 err = PTR_ERR(dst);
1797 goto err_out; 1787 goto err_out;
@@ -1914,7 +1904,7 @@ static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca,
1914 * Add multicast single-source filter to the interface list 1904 * Add multicast single-source filter to the interface list
1915 */ 1905 */
1916static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode, 1906static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode,
1917 const struct in6_addr *psfsrc, int delta) 1907 const struct in6_addr *psfsrc)
1918{ 1908{
1919 struct ip6_sf_list *psf, *psf_prev; 1909 struct ip6_sf_list *psf, *psf_prev;
1920 1910
@@ -2045,7 +2035,7 @@ static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2045 pmc->mca_sfcount[sfmode]++; 2035 pmc->mca_sfcount[sfmode]++;
2046 err = 0; 2036 err = 0;
2047 for (i=0; i<sfcount; i++) { 2037 for (i=0; i<sfcount; i++) {
2048 err = ip6_mc_add1_src(pmc, sfmode, &psfsrc[i], delta); 2038 err = ip6_mc_add1_src(pmc, sfmode, &psfsrc[i]);
2049 if (err) 2039 if (err)
2050 break; 2040 break;
2051 } 2041 }