X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv6%2Fip6_output.c;h=81eed71ddfe3fd5a82755306b2506b5392615427;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=d6f0db4aaa069a781b3497a622388ec725e0dbb5;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d6f0db4aa..81eed71dd 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -55,7 +55,7 @@ #include #include -static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)); +static int ip6_fragment(struct sk_buff **pskb, int (*output)(struct sk_buff**)); static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr) { @@ -87,7 +87,7 @@ static inline int ip6_output_finish(struct sk_buff *skb) } else if (dst->neighbour) return dst->neighbour->output(skb); - IP6_INC_STATS_BH(Ip6OutNoRoutes); + IP6_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); kfree_skb(skb); return -EINVAL; @@ -107,8 +107,9 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) } -int ip6_output2(struct sk_buff *skb) +static int ip6_output2(struct sk_buff **pskb) { + struct sk_buff *skb = *pskb; struct dst_entry *dst = skb->dst; struct net_device *dev = dst->dev; @@ -132,24 +133,26 @@ int ip6_output2(struct sk_buff *skb) ip6_dev_loopback_xmit); if (skb->nh.ipv6h->hop_limit == 0) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); return 0; } } - IP6_INC_STATS(Ip6OutMcastPkts); + IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); } return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish); } -int ip6_output(struct sk_buff *skb) +int ip6_output(struct sk_buff **pskb) { + struct sk_buff *skb = *pskb; + if ((skb->len > dst_pmtu(skb->dst) || skb_shinfo(skb)->frag_list)) - return ip6_fragment(skb, ip6_output2); + return ip6_fragment(pskb, ip6_output2); else - return ip6_output2(skb); + return ip6_output2(pskb); } #ifdef CONFIG_NETFILTER @@ -169,7 +172,7 @@ int ip6_route_me_harder(struct sk_buff *skb) dst = ip6_route_output(skb->sk, &fl); if (dst->error) { - IP6_INC_STATS(Ip6OutNoRoutes); + IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); LIMIT_NETDEBUG( printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n")); dst_release(dst); @@ -228,7 +231,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, kfree_skb(skb); skb = skb2; if (skb == NULL) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); return -ENOBUFS; } if (sk) @@ -262,7 +265,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, mtu = dst_pmtu(dst); if ((skb->len <= mtu) || ipfragok) { - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute); } @@ -270,7 +273,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); kfree_skb(skb); return -EMSGSIZE; } @@ -346,13 +349,13 @@ int ip6_forward(struct sk_buff *skb) { struct dst_entry *dst = skb->dst; struct ipv6hdr *hdr = skb->nh.ipv6h; - struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb; + struct inet6_skb_parm *opt = IP6CB(skb); if (ipv6_devconf.forwarding == 0) goto error; if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { - IP6_INC_STATS(Ip6InDiscards); + IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); goto drop; } @@ -391,7 +394,7 @@ int ip6_forward(struct sk_buff *skb) } if (!xfrm6_route_forward(skb)) { - IP6_INC_STATS(Ip6InDiscards); + IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); goto drop; } @@ -429,14 +432,14 @@ int ip6_forward(struct sk_buff *skb) /* Again, force OUTPUT device used as source address */ skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_pmtu(dst), skb->dev); - IP6_INC_STATS_BH(Ip6InTooBigErrors); - IP6_INC_STATS_BH(Ip6FragFails); + IP6_INC_STATS_BH(IPSTATS_MIB_INTOOBIGERRORS); + IP6_INC_STATS_BH(IPSTATS_MIB_FRAGFAILS); kfree_skb(skb); return -EMSGSIZE; } if (skb_cow(skb, dst->dev->hard_header_len)) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); goto drop; } @@ -446,11 +449,11 @@ int ip6_forward(struct sk_buff *skb) hdr->hop_limit--; - IP6_INC_STATS_BH(Ip6OutForwDatagrams); + IP6_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS); return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish); error: - IP6_INC_STATS_BH(Ip6InAddrErrors); + IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); drop: kfree_skb(skb); return -EINVAL; @@ -513,11 +516,11 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) return offset; } -static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) +static int ip6_fragment(struct sk_buff **pskb, int (*output)(struct sk_buff**)) { struct net_device *dev; + struct sk_buff *frag, *skb = *pskb; struct rt6_info *rt = (struct rt6_info*)skb->dst; - struct sk_buff *frag; struct ipv6hdr *tmp_hdr; struct frag_hdr *fh; unsigned int mtu, hlen, left, len; @@ -558,12 +561,12 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) err = 0; offset = 0; frag = skb_shinfo(skb)->frag_list; - skb_shinfo(skb)->frag_list = 0; + skb_shinfo(skb)->frag_list = NULL; /* BUILD HEADER */ tmp_hdr = kmalloc(hlen, GFP_ATOMIC); if (!tmp_hdr) { - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); return -ENOMEM; } @@ -604,8 +607,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr)); ip6_copy_metadata(frag, skb); } - err = output(skb); - + + err = output(&skb); if (err || !frag) break; @@ -618,7 +621,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) kfree(tmp_hdr); if (err == 0) { - IP6_INC_STATS(Ip6FragOKs); + IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); return 0; } @@ -628,7 +631,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) frag = skb; } - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); return err; } @@ -661,7 +664,7 @@ slow_path: if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n")); - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); err = -ENOMEM; goto fail; } @@ -719,19 +722,19 @@ slow_path: * Put this fragment into the sending queue. */ - IP6_INC_STATS(Ip6FragCreates); + IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); - err = output(frag); + err = output(&frag); if (err) goto fail; } kfree_skb(skb); - IP6_INC_STATS(Ip6FragOKs); + IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); return err; fail: kfree_skb(skb); - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); return err; } @@ -849,8 +852,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse np->cork.hop_limit = hlimit; inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst); inet->cork.length = 0; - inet->sndmsg_page = NULL; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = NULL; + sk->sk_sndmsg_off = 0; exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0); length += exthdrlen; transhdrlen += exthdrlen; @@ -966,8 +969,8 @@ alloc_new_skb: } else { int i = skb_shinfo(skb)->nr_frags; skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1]; - struct page *page = inet->sndmsg_page; - int off = inet->sndmsg_off; + struct page *page = sk->sk_sndmsg_page; + int off = sk->sk_sndmsg_off; unsigned int left; if (page && (left = PAGE_SIZE - off) > 0) { @@ -979,7 +982,7 @@ alloc_new_skb: goto error; } get_page(page); - skb_fill_page_desc(skb, i, page, inet->sndmsg_off, 0); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); frag = &skb_shinfo(skb)->frags[i]; } } else if(i < MAX_SKB_FRAGS) { @@ -990,8 +993,8 @@ alloc_new_skb: err = -ENOMEM; goto error; } - inet->sndmsg_page = page; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = page; + sk->sk_sndmsg_off = 0; skb_fill_page_desc(skb, i, page, 0, 0); frag = &skb_shinfo(skb)->frags[i]; @@ -1005,7 +1008,7 @@ alloc_new_skb: err = -EFAULT; goto error; } - inet->sndmsg_off += copy; + sk->sk_sndmsg_off += copy; frag->size += copy; skb->len += copy; skb->data_len += copy; @@ -1016,7 +1019,7 @@ alloc_new_skb: return 0; error: inet->cork.length -= length; - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); return err; } @@ -1076,7 +1079,7 @@ int ip6_push_pending_frames(struct sock *sk) ipv6_addr_copy(&hdr->daddr, final_dst); skb->dst = dst_clone(&rt->u.dst); - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); if (err) { if (err > 0) @@ -1108,7 +1111,7 @@ void ip6_flush_pending_frames(struct sock *sk) struct sk_buff *skb; while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); }