diff options
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r-- | net/ipv4/igmp.c | 56 |
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 | ||
350 | static int igmpv3_sendpack(struct sk_buff *skb) | 350 | static 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 | ||
365 | static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel) | 360 | static 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 | ||
702 | static void igmp_gq_timer_expire(unsigned long data) | 694 | static 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 | ||
2343 | static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos) | 2331 | static 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 | ||
2360 | static void igmp_mc_seq_stop(struct seq_file *seq, void *v) | 2349 | static 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)) { |