aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/igmp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 16:43:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 16:43:21 -0400
commit06f4e926d256d902dd9a53dcb400fd74974ce087 (patch)
tree0b438b67f5f0eff6fd617bc497a9dace6164a488 /net/ipv4/igmp.c
parent8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff)
parentd93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits) macvlan: fix panic if lowerdev in a bond tg3: Add braces around 5906 workaround. tg3: Fix NETIF_F_LOOPBACK error macvlan: remove one synchronize_rcu() call networking: NET_CLS_ROUTE4 depends on INET irda: Fix error propagation in ircomm_lmp_connect_response() irda: Kill set but unused variable 'bytes' in irlan_check_command_param() irda: Kill set but unused variable 'clen' in ircomm_connect_indication() rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport() be2net: Kill set but unused variable 'req' in lancer_fw_download() irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication() atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer(). rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler() rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection() rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window() pkt_sched: Kill set but unused variable 'protocol' in tc_classify() isdn: capi: Use pr_debug() instead of ifdefs. tg3: Update version to 3.119 tg3: Apply rx_discards fix to 5719/5720 ... Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c as per Davem.
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r--net/ipv4/igmp.c22
1 files changed, 7 insertions, 15 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 8f62d66d0857..672e476c8c8a 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -303,6 +303,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
303 struct iphdr *pip; 303 struct iphdr *pip;
304 struct igmpv3_report *pig; 304 struct igmpv3_report *pig;
305 struct net *net = dev_net(dev); 305 struct net *net = dev_net(dev);
306 struct flowi4 fl4;
306 307
307 while (1) { 308 while (1) {
308 skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), 309 skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev),
@@ -315,18 +316,13 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
315 } 316 }
316 igmp_skb_size(skb) = size; 317 igmp_skb_size(skb) = size;
317 318
318 rt = ip_route_output_ports(net, NULL, IGMPV3_ALL_MCR, 0, 319 rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0,
319 0, 0, 320 0, 0,
320 IPPROTO_IGMP, 0, dev->ifindex); 321 IPPROTO_IGMP, 0, dev->ifindex);
321 if (IS_ERR(rt)) { 322 if (IS_ERR(rt)) {
322 kfree_skb(skb); 323 kfree_skb(skb);
323 return NULL; 324 return NULL;
324 } 325 }
325 if (rt->rt_src == 0) {
326 kfree_skb(skb);
327 ip_rt_put(rt);
328 return NULL;
329 }
330 326
331 skb_dst_set(skb, &rt->dst); 327 skb_dst_set(skb, &rt->dst);
332 skb->dev = dev; 328 skb->dev = dev;
@@ -342,8 +338,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
342 pip->tos = 0xc0; 338 pip->tos = 0xc0;
343 pip->frag_off = htons(IP_DF); 339 pip->frag_off = htons(IP_DF);
344 pip->ttl = 1; 340 pip->ttl = 1;
345 pip->daddr = rt->rt_dst; 341 pip->daddr = fl4.daddr;
346 pip->saddr = rt->rt_src; 342 pip->saddr = fl4.saddr;
347 pip->protocol = IPPROTO_IGMP; 343 pip->protocol = IPPROTO_IGMP;
348 pip->tot_len = 0; /* filled in later */ 344 pip->tot_len = 0; /* filled in later */
349 ip_select_ident(pip, &rt->dst, NULL); 345 ip_select_ident(pip, &rt->dst, NULL);
@@ -649,6 +645,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
649 struct net_device *dev = in_dev->dev; 645 struct net_device *dev = in_dev->dev;
650 struct net *net = dev_net(dev); 646 struct net *net = dev_net(dev);
651 __be32 group = pmc ? pmc->multiaddr : 0; 647 __be32 group = pmc ? pmc->multiaddr : 0;
648 struct flowi4 fl4;
652 __be32 dst; 649 __be32 dst;
653 650
654 if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) 651 if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
@@ -658,17 +655,12 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
658 else 655 else
659 dst = group; 656 dst = group;
660 657
661 rt = ip_route_output_ports(net, NULL, dst, 0, 658 rt = ip_route_output_ports(net, &fl4, NULL, dst, 0,
662 0, 0, 659 0, 0,
663 IPPROTO_IGMP, 0, dev->ifindex); 660 IPPROTO_IGMP, 0, dev->ifindex);
664 if (IS_ERR(rt)) 661 if (IS_ERR(rt))
665 return -1; 662 return -1;
666 663
667 if (rt->rt_src == 0) {
668 ip_rt_put(rt);
669 return -1;
670 }
671
672 skb = alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); 664 skb = alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
673 if (skb == NULL) { 665 if (skb == NULL) {
674 ip_rt_put(rt); 666 ip_rt_put(rt);
@@ -689,7 +681,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
689 iph->frag_off = htons(IP_DF); 681 iph->frag_off = htons(IP_DF);
690 iph->ttl = 1; 682 iph->ttl = 1;
691 iph->daddr = dst; 683 iph->daddr = dst;
692 iph->saddr = rt->rt_src; 684 iph->saddr = fl4.saddr;
693 iph->protocol = IPPROTO_IGMP; 685 iph->protocol = IPPROTO_IGMP;
694 ip_select_ident(iph, &rt->dst, NULL); 686 ip_select_ident(iph, &rt->dst, NULL);
695 ((u8*)&iph[1])[0] = IPOPT_RA; 687 ((u8*)&iph[1])[0] = IPOPT_RA;