diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2008-01-11 22:14:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:53:47 -0500 |
commit | c439cb2e4b13cf1cb2abcd006b906315a3381323 (patch) | |
tree | 7bb9d27214e010d37d6a715d0533a7148a8f429a /net/ipv4/igmp.c | |
parent | 227620e295090629fcb2c46ad3828222ab65438d (diff) |
[IPV4]: Add ip_local_out
Most callers of the LOCAL_OUT chain will set the IP packet length and
header checksum before doing so. They also share the same output
function dst_output.
This patch creates a new function called ip_local_out which does all
of that and converts the appropriate users over to it.
Apart from removing duplicate code, it will also help in merging the
IPsec output path once the same thing is done for IPv6.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r-- | net/ipv4/igmp.c | 12 |
1 files changed, 2 insertions, 10 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 701558564e96..c560a9392b1d 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -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) |
@@ -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) |