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.c136
1 files changed, 73 insertions, 63 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index d1444b95ad7e..3e6ebcdb4779 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -82,7 +82,7 @@ static void *__mld2_query_bugs[] __attribute__((__unused__)) = {
82static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; 82static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
83 83
84/* Big mc list lock for all the sockets */ 84/* Big mc list lock for all the sockets */
85static DEFINE_RWLOCK(ipv6_sk_mc_lock); 85static DEFINE_SPINLOCK(ipv6_sk_mc_lock);
86 86
87static void igmp6_join_group(struct ifmcaddr6 *ma); 87static void igmp6_join_group(struct ifmcaddr6 *ma);
88static void igmp6_leave_group(struct ifmcaddr6 *ma); 88static void igmp6_leave_group(struct ifmcaddr6 *ma);
@@ -92,16 +92,16 @@ static void mld_gq_timer_expire(unsigned long data);
92static void mld_ifc_timer_expire(unsigned long data); 92static void mld_ifc_timer_expire(unsigned long data);
93static void mld_ifc_event(struct inet6_dev *idev); 93static void mld_ifc_event(struct inet6_dev *idev);
94static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc); 94static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
95static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *addr); 95static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *addr);
96static void mld_clear_delrec(struct inet6_dev *idev); 96static void mld_clear_delrec(struct inet6_dev *idev);
97static int sf_setstate(struct ifmcaddr6 *pmc); 97static int sf_setstate(struct ifmcaddr6 *pmc);
98static void sf_markstate(struct ifmcaddr6 *pmc); 98static void sf_markstate(struct ifmcaddr6 *pmc);
99static void ip6_mc_clear_src(struct ifmcaddr6 *pmc); 99static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
100static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, 100static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca,
101 int sfmode, int sfcount, struct in6_addr *psfsrc, 101 int sfmode, int sfcount, const struct in6_addr *psfsrc,
102 int delta); 102 int delta);
103static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, 103static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
104 int sfmode, int sfcount, struct in6_addr *psfsrc, 104 int sfmode, int sfcount, const struct in6_addr *psfsrc,
105 int delta); 105 int delta);
106static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, 106static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
107 struct inet6_dev *idev); 107 struct inet6_dev *idev);
@@ -123,6 +123,11 @@ int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
123 * socket join on multicast group 123 * socket join on multicast group
124 */ 124 */
125 125
126#define for_each_pmc_rcu(np, pmc) \
127 for (pmc = rcu_dereference(np->ipv6_mc_list); \
128 pmc != NULL; \
129 pmc = rcu_dereference(pmc->next))
130
126int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) 131int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
127{ 132{
128 struct net_device *dev = NULL; 133 struct net_device *dev = NULL;
@@ -134,15 +139,15 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
134 if (!ipv6_addr_is_multicast(addr)) 139 if (!ipv6_addr_is_multicast(addr))
135 return -EINVAL; 140 return -EINVAL;
136 141
137 read_lock_bh(&ipv6_sk_mc_lock); 142 rcu_read_lock();
138 for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) { 143 for_each_pmc_rcu(np, mc_lst) {
139 if ((ifindex == 0 || mc_lst->ifindex == ifindex) && 144 if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
140 ipv6_addr_equal(&mc_lst->addr, addr)) { 145 ipv6_addr_equal(&mc_lst->addr, addr)) {
141 read_unlock_bh(&ipv6_sk_mc_lock); 146 rcu_read_unlock();
142 return -EADDRINUSE; 147 return -EADDRINUSE;
143 } 148 }
144 } 149 }
145 read_unlock_bh(&ipv6_sk_mc_lock); 150 rcu_read_unlock();
146 151
147 mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL); 152 mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
148 153
@@ -186,10 +191,10 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
186 return err; 191 return err;
187 } 192 }
188 193
189 write_lock_bh(&ipv6_sk_mc_lock); 194 spin_lock(&ipv6_sk_mc_lock);
190 mc_lst->next = np->ipv6_mc_list; 195 mc_lst->next = np->ipv6_mc_list;
191 np->ipv6_mc_list = mc_lst; 196 rcu_assign_pointer(np->ipv6_mc_list, mc_lst);
192 write_unlock_bh(&ipv6_sk_mc_lock); 197 spin_unlock(&ipv6_sk_mc_lock);
193 198
194 rcu_read_unlock(); 199 rcu_read_unlock();
195 200
@@ -202,17 +207,21 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
202int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) 207int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
203{ 208{
204 struct ipv6_pinfo *np = inet6_sk(sk); 209 struct ipv6_pinfo *np = inet6_sk(sk);
205 struct ipv6_mc_socklist *mc_lst, **lnk; 210 struct ipv6_mc_socklist *mc_lst;
211 struct ipv6_mc_socklist __rcu **lnk;
206 struct net *net = sock_net(sk); 212 struct net *net = sock_net(sk);
207 213
208 write_lock_bh(&ipv6_sk_mc_lock); 214 spin_lock(&ipv6_sk_mc_lock);
209 for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) { 215 for (lnk = &np->ipv6_mc_list;
216 (mc_lst = rcu_dereference_protected(*lnk,
217 lockdep_is_held(&ipv6_sk_mc_lock))) !=NULL ;
218 lnk = &mc_lst->next) {
210 if ((ifindex == 0 || mc_lst->ifindex == ifindex) && 219 if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
211 ipv6_addr_equal(&mc_lst->addr, addr)) { 220 ipv6_addr_equal(&mc_lst->addr, addr)) {
212 struct net_device *dev; 221 struct net_device *dev;
213 222
214 *lnk = mc_lst->next; 223 *lnk = mc_lst->next;
215 write_unlock_bh(&ipv6_sk_mc_lock); 224 spin_unlock(&ipv6_sk_mc_lock);
216 225
217 rcu_read_lock(); 226 rcu_read_lock();
218 dev = dev_get_by_index_rcu(net, mc_lst->ifindex); 227 dev = dev_get_by_index_rcu(net, mc_lst->ifindex);
@@ -225,18 +234,19 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
225 } else 234 } else
226 (void) ip6_mc_leave_src(sk, mc_lst, NULL); 235 (void) ip6_mc_leave_src(sk, mc_lst, NULL);
227 rcu_read_unlock(); 236 rcu_read_unlock();
228 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); 237 atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
238 kfree_rcu(mc_lst, rcu);
229 return 0; 239 return 0;
230 } 240 }
231 } 241 }
232 write_unlock_bh(&ipv6_sk_mc_lock); 242 spin_unlock(&ipv6_sk_mc_lock);
233 243
234 return -EADDRNOTAVAIL; 244 return -EADDRNOTAVAIL;
235} 245}
236 246
237/* called with rcu_read_lock() */ 247/* called with rcu_read_lock() */
238static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, 248static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
239 struct in6_addr *group, 249 const struct in6_addr *group,
240 int ifindex) 250 int ifindex)
241{ 251{
242 struct net_device *dev = NULL; 252 struct net_device *dev = NULL;
@@ -257,7 +267,7 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
257 return NULL; 267 return NULL;
258 idev = __in6_dev_get(dev); 268 idev = __in6_dev_get(dev);
259 if (!idev) 269 if (!idev)
260 return NULL;; 270 return NULL;
261 read_lock_bh(&idev->lock); 271 read_lock_bh(&idev->lock);
262 if (idev->dead) { 272 if (idev->dead) {
263 read_unlock_bh(&idev->lock); 273 read_unlock_bh(&idev->lock);
@@ -272,12 +282,13 @@ void ipv6_sock_mc_close(struct sock *sk)
272 struct ipv6_mc_socklist *mc_lst; 282 struct ipv6_mc_socklist *mc_lst;
273 struct net *net = sock_net(sk); 283 struct net *net = sock_net(sk);
274 284
275 write_lock_bh(&ipv6_sk_mc_lock); 285 spin_lock(&ipv6_sk_mc_lock);
276 while ((mc_lst = np->ipv6_mc_list) != NULL) { 286 while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list,
287 lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) {
277 struct net_device *dev; 288 struct net_device *dev;
278 289
279 np->ipv6_mc_list = mc_lst->next; 290 np->ipv6_mc_list = mc_lst->next;
280 write_unlock_bh(&ipv6_sk_mc_lock); 291 spin_unlock(&ipv6_sk_mc_lock);
281 292
282 rcu_read_lock(); 293 rcu_read_lock();
283 dev = dev_get_by_index_rcu(net, mc_lst->ifindex); 294 dev = dev_get_by_index_rcu(net, mc_lst->ifindex);
@@ -290,11 +301,13 @@ void ipv6_sock_mc_close(struct sock *sk)
290 } else 301 } else
291 (void) ip6_mc_leave_src(sk, mc_lst, NULL); 302 (void) ip6_mc_leave_src(sk, mc_lst, NULL);
292 rcu_read_unlock(); 303 rcu_read_unlock();
293 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
294 304
295 write_lock_bh(&ipv6_sk_mc_lock); 305 atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
306 kfree_rcu(mc_lst, rcu);
307
308 spin_lock(&ipv6_sk_mc_lock);
296 } 309 }
297 write_unlock_bh(&ipv6_sk_mc_lock); 310 spin_unlock(&ipv6_sk_mc_lock);
298} 311}
299 312
300int ip6_mc_source(int add, int omode, struct sock *sk, 313int ip6_mc_source(int add, int omode, struct sock *sk,
@@ -302,7 +315,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
302{ 315{
303 struct in6_addr *source, *group; 316 struct in6_addr *source, *group;
304 struct ipv6_mc_socklist *pmc; 317 struct ipv6_mc_socklist *pmc;
305 struct net_device *dev;
306 struct inet6_dev *idev; 318 struct inet6_dev *idev;
307 struct ipv6_pinfo *inet6 = inet6_sk(sk); 319 struct ipv6_pinfo *inet6 = inet6_sk(sk);
308 struct ip6_sf_socklist *psl; 320 struct ip6_sf_socklist *psl;
@@ -324,12 +336,10 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
324 rcu_read_unlock(); 336 rcu_read_unlock();
325 return -ENODEV; 337 return -ENODEV;
326 } 338 }
327 dev = idev->dev;
328 339
329 err = -EADDRNOTAVAIL; 340 err = -EADDRNOTAVAIL;
330 341
331 read_lock(&ipv6_sk_mc_lock); 342 for_each_pmc_rcu(inet6, pmc) {
332 for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
333 if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface) 343 if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
334 continue; 344 continue;
335 if (ipv6_addr_equal(&pmc->addr, group)) 345 if (ipv6_addr_equal(&pmc->addr, group))
@@ -428,7 +438,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
428done: 438done:
429 if (pmclocked) 439 if (pmclocked)
430 write_unlock(&pmc->sflock); 440 write_unlock(&pmc->sflock);
431 read_unlock(&ipv6_sk_mc_lock);
432 read_unlock_bh(&idev->lock); 441 read_unlock_bh(&idev->lock);
433 rcu_read_unlock(); 442 rcu_read_unlock();
434 if (leavegroup) 443 if (leavegroup)
@@ -438,9 +447,8 @@ done:
438 447
439int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) 448int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
440{ 449{
441 struct in6_addr *group; 450 const struct in6_addr *group;
442 struct ipv6_mc_socklist *pmc; 451 struct ipv6_mc_socklist *pmc;
443 struct net_device *dev;
444 struct inet6_dev *idev; 452 struct inet6_dev *idev;
445 struct ipv6_pinfo *inet6 = inet6_sk(sk); 453 struct ipv6_pinfo *inet6 = inet6_sk(sk);
446 struct ip6_sf_socklist *newpsl, *psl; 454 struct ip6_sf_socklist *newpsl, *psl;
@@ -463,17 +471,15 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
463 rcu_read_unlock(); 471 rcu_read_unlock();
464 return -ENODEV; 472 return -ENODEV;
465 } 473 }
466 dev = idev->dev;
467 474
468 err = 0; 475 err = 0;
469 read_lock(&ipv6_sk_mc_lock);
470 476
471 if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) { 477 if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) {
472 leavegroup = 1; 478 leavegroup = 1;
473 goto done; 479 goto done;
474 } 480 }
475 481
476 for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { 482 for_each_pmc_rcu(inet6, pmc) {
477 if (pmc->ifindex != gsf->gf_interface) 483 if (pmc->ifindex != gsf->gf_interface)
478 continue; 484 continue;
479 if (ipv6_addr_equal(&pmc->addr, group)) 485 if (ipv6_addr_equal(&pmc->addr, group))
@@ -521,7 +527,6 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
521 write_unlock(&pmc->sflock); 527 write_unlock(&pmc->sflock);
522 err = 0; 528 err = 0;
523done: 529done:
524 read_unlock(&ipv6_sk_mc_lock);
525 read_unlock_bh(&idev->lock); 530 read_unlock_bh(&idev->lock);
526 rcu_read_unlock(); 531 rcu_read_unlock();
527 if (leavegroup) 532 if (leavegroup)
@@ -533,10 +538,9 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
533 struct group_filter __user *optval, int __user *optlen) 538 struct group_filter __user *optval, int __user *optlen)
534{ 539{
535 int err, i, count, copycount; 540 int err, i, count, copycount;
536 struct in6_addr *group; 541 const struct in6_addr *group;
537 struct ipv6_mc_socklist *pmc; 542 struct ipv6_mc_socklist *pmc;
538 struct inet6_dev *idev; 543 struct inet6_dev *idev;
539 struct net_device *dev;
540 struct ipv6_pinfo *inet6 = inet6_sk(sk); 544 struct ipv6_pinfo *inet6 = inet6_sk(sk);
541 struct ip6_sf_socklist *psl; 545 struct ip6_sf_socklist *psl;
542 struct net *net = sock_net(sk); 546 struct net *net = sock_net(sk);
@@ -553,7 +557,6 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
553 rcu_read_unlock(); 557 rcu_read_unlock();
554 return -ENODEV; 558 return -ENODEV;
555 } 559 }
556 dev = idev->dev;
557 560
558 err = -EADDRNOTAVAIL; 561 err = -EADDRNOTAVAIL;
559 /* 562 /*
@@ -562,7 +565,7 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
562 * so reading the list is safe. 565 * so reading the list is safe.
563 */ 566 */
564 567
565 for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { 568 for_each_pmc_rcu(inet6, pmc) {
566 if (pmc->ifindex != gsf->gf_interface) 569 if (pmc->ifindex != gsf->gf_interface)
567 continue; 570 continue;
568 if (ipv6_addr_equal(group, &pmc->addr)) 571 if (ipv6_addr_equal(group, &pmc->addr))
@@ -612,13 +615,13 @@ int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
612 struct ip6_sf_socklist *psl; 615 struct ip6_sf_socklist *psl;
613 int rv = 1; 616 int rv = 1;
614 617
615 read_lock(&ipv6_sk_mc_lock); 618 rcu_read_lock();
616 for (mc = np->ipv6_mc_list; mc; mc = mc->next) { 619 for_each_pmc_rcu(np, mc) {
617 if (ipv6_addr_equal(&mc->addr, mc_addr)) 620 if (ipv6_addr_equal(&mc->addr, mc_addr))
618 break; 621 break;
619 } 622 }
620 if (!mc) { 623 if (!mc) {
621 read_unlock(&ipv6_sk_mc_lock); 624 rcu_read_unlock();
622 return 1; 625 return 1;
623 } 626 }
624 read_lock(&mc->sflock); 627 read_lock(&mc->sflock);
@@ -638,7 +641,7 @@ int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
638 rv = 0; 641 rv = 0;
639 } 642 }
640 read_unlock(&mc->sflock); 643 read_unlock(&mc->sflock);
641 read_unlock(&ipv6_sk_mc_lock); 644 rcu_read_unlock();
642 645
643 return rv; 646 return rv;
644} 647}
@@ -745,7 +748,7 @@ static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
745 spin_unlock_bh(&idev->mc_lock); 748 spin_unlock_bh(&idev->mc_lock);
746} 749}
747 750
748static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca) 751static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *pmca)
749{ 752{
750 struct ifmcaddr6 *pmc, *pmc_prev; 753 struct ifmcaddr6 *pmc, *pmc_prev;
751 struct ip6_sf_list *psf, *psf_next; 754 struct ip6_sf_list *psf, *psf_next;
@@ -1045,7 +1048,7 @@ static void igmp6_group_queried(struct ifmcaddr6 *ma, unsigned long resptime)
1045 1048
1046/* mark EXCLUDE-mode sources */ 1049/* mark EXCLUDE-mode sources */
1047static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, 1050static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs,
1048 struct in6_addr *srcs) 1051 const struct in6_addr *srcs)
1049{ 1052{
1050 struct ip6_sf_list *psf; 1053 struct ip6_sf_list *psf;
1051 int i, scount; 1054 int i, scount;
@@ -1073,7 +1076,7 @@ static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs,
1073} 1076}
1074 1077
1075static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, 1078static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
1076 struct in6_addr *srcs) 1079 const struct in6_addr *srcs)
1077{ 1080{
1078 struct ip6_sf_list *psf; 1081 struct ip6_sf_list *psf;
1079 int i, scount; 1082 int i, scount;
@@ -1108,7 +1111,7 @@ int igmp6_event_query(struct sk_buff *skb)
1108{ 1111{
1109 struct mld2_query *mlh2 = NULL; 1112 struct mld2_query *mlh2 = NULL;
1110 struct ifmcaddr6 *ma; 1113 struct ifmcaddr6 *ma;
1111 struct in6_addr *group; 1114 const struct in6_addr *group;
1112 unsigned long max_delay; 1115 unsigned long max_delay;
1113 struct inet6_dev *idev; 1116 struct inet6_dev *idev;
1114 struct mld_msg *mld; 1117 struct mld_msg *mld;
@@ -1389,7 +1392,7 @@ static void mld_sendpack(struct sk_buff *skb)
1389 struct inet6_dev *idev; 1392 struct inet6_dev *idev;
1390 struct net *net = dev_net(skb->dev); 1393 struct net *net = dev_net(skb->dev);
1391 int err; 1394 int err;
1392 struct flowi fl; 1395 struct flowi6 fl6;
1393 struct dst_entry *dst; 1396 struct dst_entry *dst;
1394 1397
1395 rcu_read_lock(); 1398 rcu_read_lock();
@@ -1412,11 +1415,16 @@ static void mld_sendpack(struct sk_buff *skb)
1412 goto err_out; 1415 goto err_out;
1413 } 1416 }
1414 1417
1415 icmpv6_flow_init(net->ipv6.igmp_sk, &fl, ICMPV6_MLD2_REPORT, 1418 icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT,
1416 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 1419 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1417 skb->dev->ifindex); 1420 skb->dev->ifindex);
1418 1421
1419 err = xfrm_lookup(net, &dst, &fl, NULL, 0); 1422 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
1423 err = 0;
1424 if (IS_ERR(dst)) {
1425 err = PTR_ERR(dst);
1426 dst = NULL;
1427 }
1420 skb_dst_set(skb, dst); 1428 skb_dst_set(skb, dst);
1421 if (err) 1429 if (err)
1422 goto err_out; 1430 goto err_out;
@@ -1719,7 +1727,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1719 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1727 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1720 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1728 IPV6_TLV_ROUTERALERT, 2, 0, 0,
1721 IPV6_TLV_PADN, 0 }; 1729 IPV6_TLV_PADN, 0 };
1722 struct flowi fl; 1730 struct flowi6 fl6;
1723 struct dst_entry *dst; 1731 struct dst_entry *dst;
1724 1732
1725 if (type == ICMPV6_MGM_REDUCTION) 1733 if (type == ICMPV6_MGM_REDUCTION)
@@ -1779,13 +1787,15 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1779 goto err_out; 1787 goto err_out;
1780 } 1788 }
1781 1789
1782 icmpv6_flow_init(sk, &fl, type, 1790 icmpv6_flow_init(sk, &fl6, type,
1783 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 1791 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1784 skb->dev->ifindex); 1792 skb->dev->ifindex);
1785 1793
1786 err = xfrm_lookup(net, &dst, &fl, NULL, 0); 1794 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
1787 if (err) 1795 if (IS_ERR(dst)) {
1796 err = PTR_ERR(dst);
1788 goto err_out; 1797 goto err_out;
1798 }
1789 1799
1790 skb_dst_set(skb, dst); 1800 skb_dst_set(skb, dst);
1791 err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1801 err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
@@ -1807,7 +1817,7 @@ err_out:
1807} 1817}
1808 1818
1809static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, 1819static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
1810 struct in6_addr *psfsrc) 1820 const struct in6_addr *psfsrc)
1811{ 1821{
1812 struct ip6_sf_list *psf, *psf_prev; 1822 struct ip6_sf_list *psf, *psf_prev;
1813 int rv = 0; 1823 int rv = 0;
@@ -1843,8 +1853,8 @@ static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
1843 return rv; 1853 return rv;
1844} 1854}
1845 1855
1846static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, 1856static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca,
1847 int sfmode, int sfcount, struct in6_addr *psfsrc, 1857 int sfmode, int sfcount, const struct in6_addr *psfsrc,
1848 int delta) 1858 int delta)
1849{ 1859{
1850 struct ifmcaddr6 *pmc; 1860 struct ifmcaddr6 *pmc;
@@ -1904,7 +1914,7 @@ static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca,
1904 * Add multicast single-source filter to the interface list 1914 * Add multicast single-source filter to the interface list
1905 */ 1915 */
1906static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode, 1916static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode,
1907 struct in6_addr *psfsrc, int delta) 1917 const struct in6_addr *psfsrc, int delta)
1908{ 1918{
1909 struct ip6_sf_list *psf, *psf_prev; 1919 struct ip6_sf_list *psf, *psf_prev;
1910 1920
@@ -2007,8 +2017,8 @@ static int sf_setstate(struct ifmcaddr6 *pmc)
2007/* 2017/*
2008 * Add multicast source filter list to the interface list 2018 * Add multicast source filter list to the interface list
2009 */ 2019 */
2010static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, 2020static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2011 int sfmode, int sfcount, struct in6_addr *psfsrc, 2021 int sfmode, int sfcount, const struct in6_addr *psfsrc,
2012 int delta) 2022 int delta)
2013{ 2023{
2014 struct ifmcaddr6 *pmc; 2024 struct ifmcaddr6 *pmc;