aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/igmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r--net/ipv4/igmp.c56
1 files changed, 23 insertions, 33 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 7dbc282d4f9f..994648be80ab 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -130,12 +130,12 @@
130 */ 130 */
131 131
132#define IGMP_V1_SEEN(in_dev) \ 132#define IGMP_V1_SEEN(in_dev) \
133 (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \ 133 (IPV4_DEVCONF_ALL(in_dev->dev->nd_net, FORCE_IGMP_VERSION) == 1 || \
134 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \ 134 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
135 ((in_dev)->mr_v1_seen && \ 135 ((in_dev)->mr_v1_seen && \
136 time_before(jiffies, (in_dev)->mr_v1_seen))) 136 time_before(jiffies, (in_dev)->mr_v1_seen)))
137#define IGMP_V2_SEEN(in_dev) \ 137#define IGMP_V2_SEEN(in_dev) \
138 (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \ 138 (IPV4_DEVCONF_ALL(in_dev->dev->nd_net, FORCE_IGMP_VERSION) == 2 || \
139 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \ 139 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
140 ((in_dev)->mr_v2_seen && \ 140 ((in_dev)->mr_v2_seen && \
141 time_before(jiffies, (in_dev)->mr_v2_seen))) 141 time_before(jiffies, (in_dev)->mr_v2_seen)))
@@ -301,7 +301,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
301 .nl_u = { .ip4_u = { 301 .nl_u = { .ip4_u = {
302 .daddr = IGMPV3_ALL_MCR } }, 302 .daddr = IGMPV3_ALL_MCR } },
303 .proto = IPPROTO_IGMP }; 303 .proto = IPPROTO_IGMP };
304 if (ip_route_output_key(&rt, &fl)) { 304 if (ip_route_output_key(&init_net, &rt, &fl)) {
305 kfree_skb(skb); 305 kfree_skb(skb);
306 return NULL; 306 return NULL;
307 } 307 }
@@ -349,17 +349,12 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
349 349
350static int igmpv3_sendpack(struct sk_buff *skb) 350static int igmpv3_sendpack(struct sk_buff *skb)
351{ 351{
352 struct iphdr *pip = ip_hdr(skb);
353 struct igmphdr *pig = igmp_hdr(skb); 352 struct igmphdr *pig = igmp_hdr(skb);
354 const int iplen = skb->tail - skb->network_header;
355 const int igmplen = skb->tail - skb->transport_header; 353 const int igmplen = skb->tail - skb->transport_header;
356 354
357 pip->tot_len = htons(iplen);
358 ip_send_check(pip);
359 pig->csum = ip_compute_csum(igmp_hdr(skb), igmplen); 355 pig->csum = ip_compute_csum(igmp_hdr(skb), igmplen);
360 356
361 return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dev, 357 return ip_local_out(skb);
362 dst_output);
363} 358}
364 359
365static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel) 360static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
@@ -650,7 +645,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
650 struct flowi fl = { .oif = dev->ifindex, 645 struct flowi fl = { .oif = dev->ifindex,
651 .nl_u = { .ip4_u = { .daddr = dst } }, 646 .nl_u = { .ip4_u = { .daddr = dst } },
652 .proto = IPPROTO_IGMP }; 647 .proto = IPPROTO_IGMP };
653 if (ip_route_output_key(&rt, &fl)) 648 if (ip_route_output_key(&init_net, &rt, &fl))
654 return -1; 649 return -1;
655 } 650 }
656 if (rt->rt_src == 0) { 651 if (rt->rt_src == 0) {
@@ -680,13 +675,11 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
680 iph->daddr = dst; 675 iph->daddr = dst;
681 iph->saddr = rt->rt_src; 676 iph->saddr = rt->rt_src;
682 iph->protocol = IPPROTO_IGMP; 677 iph->protocol = IPPROTO_IGMP;
683 iph->tot_len = htons(IGMP_SIZE);
684 ip_select_ident(iph, &rt->u.dst, NULL); 678 ip_select_ident(iph, &rt->u.dst, NULL);
685 ((u8*)&iph[1])[0] = IPOPT_RA; 679 ((u8*)&iph[1])[0] = IPOPT_RA;
686 ((u8*)&iph[1])[1] = 4; 680 ((u8*)&iph[1])[1] = 4;
687 ((u8*)&iph[1])[2] = 0; 681 ((u8*)&iph[1])[2] = 0;
688 ((u8*)&iph[1])[3] = 0; 682 ((u8*)&iph[1])[3] = 0;
689 ip_send_check(iph);
690 683
691 ih = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr)); 684 ih = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
692 ih->type=type; 685 ih->type=type;
@@ -695,8 +688,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
695 ih->group=group; 688 ih->group=group;
696 ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr)); 689 ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
697 690
698 return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, 691 return ip_local_out(skb);
699 dst_output);
700} 692}
701 693
702static void igmp_gq_timer_expire(unsigned long data) 694static void igmp_gq_timer_expire(unsigned long data)
@@ -1234,9 +1226,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
1234 spin_lock_init(&im->lock); 1226 spin_lock_init(&im->lock);
1235#ifdef CONFIG_IP_MULTICAST 1227#ifdef CONFIG_IP_MULTICAST
1236 im->tm_running=0; 1228 im->tm_running=0;
1237 init_timer(&im->timer); 1229 setup_timer(&im->timer, &igmp_timer_expire, (unsigned long)im);
1238 im->timer.data=(unsigned long)im;
1239 im->timer.function=&igmp_timer_expire;
1240 im->unsolicit_count = IGMP_Unsolicited_Report_Count; 1230 im->unsolicit_count = IGMP_Unsolicited_Report_Count;
1241 im->reporter = 0; 1231 im->reporter = 0;
1242 im->gsquery = 0; 1232 im->gsquery = 0;
@@ -1338,13 +1328,11 @@ void ip_mc_init_dev(struct in_device *in_dev)
1338 in_dev->mc_tomb = NULL; 1328 in_dev->mc_tomb = NULL;
1339#ifdef CONFIG_IP_MULTICAST 1329#ifdef CONFIG_IP_MULTICAST
1340 in_dev->mr_gq_running = 0; 1330 in_dev->mr_gq_running = 0;
1341 init_timer(&in_dev->mr_gq_timer); 1331 setup_timer(&in_dev->mr_gq_timer, igmp_gq_timer_expire,
1342 in_dev->mr_gq_timer.data=(unsigned long) in_dev; 1332 (unsigned long)in_dev);
1343 in_dev->mr_gq_timer.function=&igmp_gq_timer_expire;
1344 in_dev->mr_ifc_count = 0; 1333 in_dev->mr_ifc_count = 0;
1345 init_timer(&in_dev->mr_ifc_timer); 1334 setup_timer(&in_dev->mr_ifc_timer, igmp_ifc_timer_expire,
1346 in_dev->mr_ifc_timer.data=(unsigned long) in_dev; 1335 (unsigned long)in_dev);
1347 in_dev->mr_ifc_timer.function=&igmp_ifc_timer_expire;
1348 in_dev->mr_qrv = IGMP_Unsolicited_Report_Count; 1336 in_dev->mr_qrv = IGMP_Unsolicited_Report_Count;
1349#endif 1337#endif
1350 1338
@@ -1401,19 +1389,19 @@ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
1401 struct in_device *idev = NULL; 1389 struct in_device *idev = NULL;
1402 1390
1403 if (imr->imr_ifindex) { 1391 if (imr->imr_ifindex) {
1404 idev = inetdev_by_index(imr->imr_ifindex); 1392 idev = inetdev_by_index(&init_net, imr->imr_ifindex);
1405 if (idev) 1393 if (idev)
1406 __in_dev_put(idev); 1394 __in_dev_put(idev);
1407 return idev; 1395 return idev;
1408 } 1396 }
1409 if (imr->imr_address.s_addr) { 1397 if (imr->imr_address.s_addr) {
1410 dev = ip_dev_find(imr->imr_address.s_addr); 1398 dev = ip_dev_find(&init_net, imr->imr_address.s_addr);
1411 if (!dev) 1399 if (!dev)
1412 return NULL; 1400 return NULL;
1413 dev_put(dev); 1401 dev_put(dev);
1414 } 1402 }
1415 1403
1416 if (!dev && !ip_route_output_key(&rt, &fl)) { 1404 if (!dev && !ip_route_output_key(&init_net, &rt, &fl)) {
1417 dev = rt->u.dst.dev; 1405 dev = rt->u.dst.dev;
1418 ip_rt_put(rt); 1406 ip_rt_put(rt);
1419 } 1407 }
@@ -1754,7 +1742,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
1754 int ifindex; 1742 int ifindex;
1755 int count = 0; 1743 int count = 0;
1756 1744
1757 if (!MULTICAST(addr)) 1745 if (!ipv4_is_multicast(addr))
1758 return -EINVAL; 1746 return -EINVAL;
1759 1747
1760 rtnl_lock(); 1748 rtnl_lock();
@@ -1867,7 +1855,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1867 int leavegroup = 0; 1855 int leavegroup = 0;
1868 int i, j, rv; 1856 int i, j, rv;
1869 1857
1870 if (!MULTICAST(addr)) 1858 if (!ipv4_is_multicast(addr))
1871 return -EINVAL; 1859 return -EINVAL;
1872 1860
1873 rtnl_lock(); 1861 rtnl_lock();
@@ -1997,7 +1985,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
1997 struct ip_sf_socklist *newpsl, *psl; 1985 struct ip_sf_socklist *newpsl, *psl;
1998 int leavegroup = 0; 1986 int leavegroup = 0;
1999 1987
2000 if (!MULTICAST(addr)) 1988 if (!ipv4_is_multicast(addr))
2001 return -EINVAL; 1989 return -EINVAL;
2002 if (msf->imsf_fmode != MCAST_INCLUDE && 1990 if (msf->imsf_fmode != MCAST_INCLUDE &&
2003 msf->imsf_fmode != MCAST_EXCLUDE) 1991 msf->imsf_fmode != MCAST_EXCLUDE)
@@ -2080,7 +2068,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
2080 struct inet_sock *inet = inet_sk(sk); 2068 struct inet_sock *inet = inet_sk(sk);
2081 struct ip_sf_socklist *psl; 2069 struct ip_sf_socklist *psl;
2082 2070
2083 if (!MULTICAST(addr)) 2071 if (!ipv4_is_multicast(addr))
2084 return -EINVAL; 2072 return -EINVAL;
2085 2073
2086 rtnl_lock(); 2074 rtnl_lock();
@@ -2142,7 +2130,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
2142 if (psin->sin_family != AF_INET) 2130 if (psin->sin_family != AF_INET)
2143 return -EINVAL; 2131 return -EINVAL;
2144 addr = psin->sin_addr.s_addr; 2132 addr = psin->sin_addr.s_addr;
2145 if (!MULTICAST(addr)) 2133 if (!ipv4_is_multicast(addr))
2146 return -EINVAL; 2134 return -EINVAL;
2147 2135
2148 rtnl_lock(); 2136 rtnl_lock();
@@ -2192,7 +2180,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
2192 struct ip_sf_socklist *psl; 2180 struct ip_sf_socklist *psl;
2193 int i; 2181 int i;
2194 2182
2195 if (!MULTICAST(loc_addr)) 2183 if (!ipv4_is_multicast(loc_addr))
2196 return 1; 2184 return 1;
2197 2185
2198 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { 2186 for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
@@ -2234,7 +2222,7 @@ void ip_mc_drop_socket(struct sock *sk)
2234 struct in_device *in_dev; 2222 struct in_device *in_dev;
2235 inet->mc_list = iml->next; 2223 inet->mc_list = iml->next;
2236 2224
2237 in_dev = inetdev_by_index(iml->multi.imr_ifindex); 2225 in_dev = inetdev_by_index(&init_net, iml->multi.imr_ifindex);
2238 (void) ip_mc_leave_src(sk, iml, in_dev); 2226 (void) ip_mc_leave_src(sk, iml, in_dev);
2239 if (in_dev != NULL) { 2227 if (in_dev != NULL) {
2240 ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); 2228 ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
@@ -2341,6 +2329,7 @@ static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos)
2341} 2329}
2342 2330
2343static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos) 2331static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
2332 __acquires(dev_base_lock)
2344{ 2333{
2345 read_lock(&dev_base_lock); 2334 read_lock(&dev_base_lock);
2346 return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; 2335 return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
@@ -2358,6 +2347,7 @@ static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2358} 2347}
2359 2348
2360static void igmp_mc_seq_stop(struct seq_file *seq, void *v) 2349static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
2350 __releases(dev_base_lock)
2361{ 2351{
2362 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); 2352 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
2363 if (likely(state->in_dev != NULL)) { 2353 if (likely(state->in_dev != NULL)) {