diff options
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r-- | net/ipv6/mcast.c | 71 |
1 files changed, 34 insertions, 37 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 49f986d626a0..3e6ebcdb4779 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -92,16 +92,16 @@ static void mld_gq_timer_expire(unsigned long data); | |||
92 | static void mld_ifc_timer_expire(unsigned long data); | 92 | static void mld_ifc_timer_expire(unsigned long data); |
93 | static void mld_ifc_event(struct inet6_dev *idev); | 93 | static void mld_ifc_event(struct inet6_dev *idev); |
94 | static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc); | 94 | static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc); |
95 | static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *addr); | 95 | static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *addr); |
96 | static void mld_clear_delrec(struct inet6_dev *idev); | 96 | static void mld_clear_delrec(struct inet6_dev *idev); |
97 | static int sf_setstate(struct ifmcaddr6 *pmc); | 97 | static int sf_setstate(struct ifmcaddr6 *pmc); |
98 | static void sf_markstate(struct ifmcaddr6 *pmc); | 98 | static void sf_markstate(struct ifmcaddr6 *pmc); |
99 | static void ip6_mc_clear_src(struct ifmcaddr6 *pmc); | 99 | static void ip6_mc_clear_src(struct ifmcaddr6 *pmc); |
100 | static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, | 100 | static 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); |
103 | static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, | 103 | static 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); |
106 | static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, | 106 | static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, |
107 | struct inet6_dev *idev); | 107 | struct inet6_dev *idev); |
@@ -201,10 +201,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | 203 | ||
204 | static void ipv6_mc_socklist_reclaim(struct rcu_head *head) | ||
205 | { | ||
206 | kfree(container_of(head, struct ipv6_mc_socklist, rcu)); | ||
207 | } | ||
208 | /* | 204 | /* |
209 | * socket leave on multicast group | 205 | * socket leave on multicast group |
210 | */ | 206 | */ |
@@ -239,7 +235,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
239 | (void) ip6_mc_leave_src(sk, mc_lst, NULL); | 235 | (void) ip6_mc_leave_src(sk, mc_lst, NULL); |
240 | rcu_read_unlock(); | 236 | rcu_read_unlock(); |
241 | atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); | 237 | atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); |
242 | call_rcu(&mc_lst->rcu, ipv6_mc_socklist_reclaim); | 238 | kfree_rcu(mc_lst, rcu); |
243 | return 0; | 239 | return 0; |
244 | } | 240 | } |
245 | } | 241 | } |
@@ -250,7 +246,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
250 | 246 | ||
251 | /* called with rcu_read_lock() */ | 247 | /* called with rcu_read_lock() */ |
252 | static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, | 248 | static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, |
253 | struct in6_addr *group, | 249 | const struct in6_addr *group, |
254 | int ifindex) | 250 | int ifindex) |
255 | { | 251 | { |
256 | struct net_device *dev = NULL; | 252 | struct net_device *dev = NULL; |
@@ -307,7 +303,7 @@ void ipv6_sock_mc_close(struct sock *sk) | |||
307 | rcu_read_unlock(); | 303 | rcu_read_unlock(); |
308 | 304 | ||
309 | atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); | 305 | atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); |
310 | call_rcu(&mc_lst->rcu, ipv6_mc_socklist_reclaim); | 306 | kfree_rcu(mc_lst, rcu); |
311 | 307 | ||
312 | spin_lock(&ipv6_sk_mc_lock); | 308 | spin_lock(&ipv6_sk_mc_lock); |
313 | } | 309 | } |
@@ -319,7 +315,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
319 | { | 315 | { |
320 | struct in6_addr *source, *group; | 316 | struct in6_addr *source, *group; |
321 | struct ipv6_mc_socklist *pmc; | 317 | struct ipv6_mc_socklist *pmc; |
322 | struct net_device *dev; | ||
323 | struct inet6_dev *idev; | 318 | struct inet6_dev *idev; |
324 | struct ipv6_pinfo *inet6 = inet6_sk(sk); | 319 | struct ipv6_pinfo *inet6 = inet6_sk(sk); |
325 | struct ip6_sf_socklist *psl; | 320 | struct ip6_sf_socklist *psl; |
@@ -341,7 +336,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
341 | rcu_read_unlock(); | 336 | rcu_read_unlock(); |
342 | return -ENODEV; | 337 | return -ENODEV; |
343 | } | 338 | } |
344 | dev = idev->dev; | ||
345 | 339 | ||
346 | err = -EADDRNOTAVAIL; | 340 | err = -EADDRNOTAVAIL; |
347 | 341 | ||
@@ -453,9 +447,8 @@ done: | |||
453 | 447 | ||
454 | int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) | 448 | int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) |
455 | { | 449 | { |
456 | struct in6_addr *group; | 450 | const struct in6_addr *group; |
457 | struct ipv6_mc_socklist *pmc; | 451 | struct ipv6_mc_socklist *pmc; |
458 | struct net_device *dev; | ||
459 | struct inet6_dev *idev; | 452 | struct inet6_dev *idev; |
460 | struct ipv6_pinfo *inet6 = inet6_sk(sk); | 453 | struct ipv6_pinfo *inet6 = inet6_sk(sk); |
461 | struct ip6_sf_socklist *newpsl, *psl; | 454 | struct ip6_sf_socklist *newpsl, *psl; |
@@ -478,7 +471,6 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) | |||
478 | rcu_read_unlock(); | 471 | rcu_read_unlock(); |
479 | return -ENODEV; | 472 | return -ENODEV; |
480 | } | 473 | } |
481 | dev = idev->dev; | ||
482 | 474 | ||
483 | err = 0; | 475 | err = 0; |
484 | 476 | ||
@@ -546,10 +538,9 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, | |||
546 | struct group_filter __user *optval, int __user *optlen) | 538 | struct group_filter __user *optval, int __user *optlen) |
547 | { | 539 | { |
548 | int err, i, count, copycount; | 540 | int err, i, count, copycount; |
549 | struct in6_addr *group; | 541 | const struct in6_addr *group; |
550 | struct ipv6_mc_socklist *pmc; | 542 | struct ipv6_mc_socklist *pmc; |
551 | struct inet6_dev *idev; | 543 | struct inet6_dev *idev; |
552 | struct net_device *dev; | ||
553 | struct ipv6_pinfo *inet6 = inet6_sk(sk); | 544 | struct ipv6_pinfo *inet6 = inet6_sk(sk); |
554 | struct ip6_sf_socklist *psl; | 545 | struct ip6_sf_socklist *psl; |
555 | struct net *net = sock_net(sk); | 546 | struct net *net = sock_net(sk); |
@@ -566,7 +557,6 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, | |||
566 | rcu_read_unlock(); | 557 | rcu_read_unlock(); |
567 | return -ENODEV; | 558 | return -ENODEV; |
568 | } | 559 | } |
569 | dev = idev->dev; | ||
570 | 560 | ||
571 | err = -EADDRNOTAVAIL; | 561 | err = -EADDRNOTAVAIL; |
572 | /* | 562 | /* |
@@ -758,7 +748,7 @@ static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im) | |||
758 | spin_unlock_bh(&idev->mc_lock); | 748 | spin_unlock_bh(&idev->mc_lock); |
759 | } | 749 | } |
760 | 750 | ||
761 | static void mld_del_delrec(struct inet6_dev *idev, struct in6_addr *pmca) | 751 | static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *pmca) |
762 | { | 752 | { |
763 | struct ifmcaddr6 *pmc, *pmc_prev; | 753 | struct ifmcaddr6 *pmc, *pmc_prev; |
764 | struct ip6_sf_list *psf, *psf_next; | 754 | struct ip6_sf_list *psf, *psf_next; |
@@ -1058,7 +1048,7 @@ static void igmp6_group_queried(struct ifmcaddr6 *ma, unsigned long resptime) | |||
1058 | 1048 | ||
1059 | /* mark EXCLUDE-mode sources */ | 1049 | /* mark EXCLUDE-mode sources */ |
1060 | static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, | 1050 | static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, |
1061 | struct in6_addr *srcs) | 1051 | const struct in6_addr *srcs) |
1062 | { | 1052 | { |
1063 | struct ip6_sf_list *psf; | 1053 | struct ip6_sf_list *psf; |
1064 | int i, scount; | 1054 | int i, scount; |
@@ -1086,7 +1076,7 @@ static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, | |||
1086 | } | 1076 | } |
1087 | 1077 | ||
1088 | static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, | 1078 | static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, |
1089 | struct in6_addr *srcs) | 1079 | const struct in6_addr *srcs) |
1090 | { | 1080 | { |
1091 | struct ip6_sf_list *psf; | 1081 | struct ip6_sf_list *psf; |
1092 | int i, scount; | 1082 | int i, scount; |
@@ -1121,7 +1111,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1121 | { | 1111 | { |
1122 | struct mld2_query *mlh2 = NULL; | 1112 | struct mld2_query *mlh2 = NULL; |
1123 | struct ifmcaddr6 *ma; | 1113 | struct ifmcaddr6 *ma; |
1124 | struct in6_addr *group; | 1114 | const struct in6_addr *group; |
1125 | unsigned long max_delay; | 1115 | unsigned long max_delay; |
1126 | struct inet6_dev *idev; | 1116 | struct inet6_dev *idev; |
1127 | struct mld_msg *mld; | 1117 | struct mld_msg *mld; |
@@ -1402,7 +1392,7 @@ static void mld_sendpack(struct sk_buff *skb) | |||
1402 | struct inet6_dev *idev; | 1392 | struct inet6_dev *idev; |
1403 | struct net *net = dev_net(skb->dev); | 1393 | struct net *net = dev_net(skb->dev); |
1404 | int err; | 1394 | int err; |
1405 | struct flowi fl; | 1395 | struct flowi6 fl6; |
1406 | struct dst_entry *dst; | 1396 | struct dst_entry *dst; |
1407 | 1397 | ||
1408 | rcu_read_lock(); | 1398 | rcu_read_lock(); |
@@ -1425,11 +1415,16 @@ static void mld_sendpack(struct sk_buff *skb) | |||
1425 | goto err_out; | 1415 | goto err_out; |
1426 | } | 1416 | } |
1427 | 1417 | ||
1428 | icmpv6_flow_init(net->ipv6.igmp_sk, &fl, ICMPV6_MLD2_REPORT, | 1418 | icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT, |
1429 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, | 1419 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
1430 | skb->dev->ifindex); | 1420 | skb->dev->ifindex); |
1431 | 1421 | ||
1432 | 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 | } | ||
1433 | skb_dst_set(skb, dst); | 1428 | skb_dst_set(skb, dst); |
1434 | if (err) | 1429 | if (err) |
1435 | goto err_out; | 1430 | goto err_out; |
@@ -1732,7 +1727,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1732 | u8 ra[8] = { IPPROTO_ICMPV6, 0, | 1727 | u8 ra[8] = { IPPROTO_ICMPV6, 0, |
1733 | IPV6_TLV_ROUTERALERT, 2, 0, 0, | 1728 | IPV6_TLV_ROUTERALERT, 2, 0, 0, |
1734 | IPV6_TLV_PADN, 0 }; | 1729 | IPV6_TLV_PADN, 0 }; |
1735 | struct flowi fl; | 1730 | struct flowi6 fl6; |
1736 | struct dst_entry *dst; | 1731 | struct dst_entry *dst; |
1737 | 1732 | ||
1738 | if (type == ICMPV6_MGM_REDUCTION) | 1733 | if (type == ICMPV6_MGM_REDUCTION) |
@@ -1792,13 +1787,15 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1792 | goto err_out; | 1787 | goto err_out; |
1793 | } | 1788 | } |
1794 | 1789 | ||
1795 | icmpv6_flow_init(sk, &fl, type, | 1790 | icmpv6_flow_init(sk, &fl6, type, |
1796 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, | 1791 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
1797 | skb->dev->ifindex); | 1792 | skb->dev->ifindex); |
1798 | 1793 | ||
1799 | err = xfrm_lookup(net, &dst, &fl, NULL, 0); | 1794 | dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); |
1800 | if (err) | 1795 | if (IS_ERR(dst)) { |
1796 | err = PTR_ERR(dst); | ||
1801 | goto err_out; | 1797 | goto err_out; |
1798 | } | ||
1802 | 1799 | ||
1803 | skb_dst_set(skb, dst); | 1800 | skb_dst_set(skb, dst); |
1804 | 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, |
@@ -1820,7 +1817,7 @@ err_out: | |||
1820 | } | 1817 | } |
1821 | 1818 | ||
1822 | static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, | 1819 | static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, |
1823 | struct in6_addr *psfsrc) | 1820 | const struct in6_addr *psfsrc) |
1824 | { | 1821 | { |
1825 | struct ip6_sf_list *psf, *psf_prev; | 1822 | struct ip6_sf_list *psf, *psf_prev; |
1826 | int rv = 0; | 1823 | int rv = 0; |
@@ -1856,8 +1853,8 @@ static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, | |||
1856 | return rv; | 1853 | return rv; |
1857 | } | 1854 | } |
1858 | 1855 | ||
1859 | static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, | 1856 | static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca, |
1860 | int sfmode, int sfcount, struct in6_addr *psfsrc, | 1857 | int sfmode, int sfcount, const struct in6_addr *psfsrc, |
1861 | int delta) | 1858 | int delta) |
1862 | { | 1859 | { |
1863 | struct ifmcaddr6 *pmc; | 1860 | struct ifmcaddr6 *pmc; |
@@ -1917,7 +1914,7 @@ static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, | |||
1917 | * Add multicast single-source filter to the interface list | 1914 | * Add multicast single-source filter to the interface list |
1918 | */ | 1915 | */ |
1919 | static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode, | 1916 | static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode, |
1920 | struct in6_addr *psfsrc, int delta) | 1917 | const struct in6_addr *psfsrc, int delta) |
1921 | { | 1918 | { |
1922 | struct ip6_sf_list *psf, *psf_prev; | 1919 | struct ip6_sf_list *psf, *psf_prev; |
1923 | 1920 | ||
@@ -2020,8 +2017,8 @@ static int sf_setstate(struct ifmcaddr6 *pmc) | |||
2020 | /* | 2017 | /* |
2021 | * Add multicast source filter list to the interface list | 2018 | * Add multicast source filter list to the interface list |
2022 | */ | 2019 | */ |
2023 | static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, | 2020 | static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca, |
2024 | int sfmode, int sfcount, struct in6_addr *psfsrc, | 2021 | int sfmode, int sfcount, const struct in6_addr *psfsrc, |
2025 | int delta) | 2022 | int delta) |
2026 | { | 2023 | { |
2027 | struct ifmcaddr6 *pmc; | 2024 | struct ifmcaddr6 *pmc; |