NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n")); 
NETDEBUG(KERN_INFO "IP: frag: no memory for new fragment!\n"); 
int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)){	struct iphdr *iph;	int raw = 0;	int ptr;	struct net_device *dev;	struct sk_buff *skb2;	unsigned int mtu, hlen, left, len, ll_rs;	int offset;	int not_last_frag;	struct rtable *rt = (struct rtable*)skb->dst;	int err = 0;	dev = rt->u.dst.dev;	/*	 *	Point into the IP datagram header.	 */	iph = skb->nh.iph;	if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) {		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,			  htonl(dst_mtu(&rt->u.dst)));		kfree_skb(skb);		return -EMSGSIZE;	}	/*	 *	Setup starting values.	 */	hlen = iph->ihl * 4;	mtu = dst_mtu(&rt->u.dst) - hlen;	/* Size of data space */	/* When frag_list is given, use it. First, check its validity:	 * some transformers could create wrong frag_list or break existing	 * one, it is not prohibited. In this case fall back to copying.	 *	 * LATER: this step can be merged to real generation of fragments,	 * we can switch to copy when see the first bad fragment.	 */	if (skb_shinfo(skb)->frag_list) {		struct sk_buff *frag;		int first_len = skb_pagelen(skb);		if (first_len - hlen > mtu ||		    ((first_len - hlen) & 7) ||		    (iph->frag_off & htons(IP_MF|IP_OFFSET)) ||		    skb_cloned(skb))			goto slow_path;		for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {			/* Correct geometry. */			if (frag->len > mtu ||			    ((frag->len & 7) && frag->next) ||			    skb_headroom(frag) < hlen)			    goto slow_path;			/* Partially cloned skb? */			if (skb_shared(frag))				goto slow_path;			BUG_ON(frag->sk);			if (skb->sk) {				sock_hold(skb->sk);				frag->sk = skb->sk;				frag->destructor = sock_wfree;				skb->truesize -= frag->truesize;			}		}		/* Everything is OK. Generate! */		err = 0;		offset = 0;		frag = skb_shinfo(skb)->frag_list;		skb_shinfo(skb)->frag_list = NULL;		skb->data_len = first_len - skb_headlen(skb);		skb->len = first_len;		iph->tot_len = htons(first_len);		iph->frag_off = htons(IP_MF);		ip_send_check(iph);		for (;;) {			/* Prepare header of the next frame,			 * before previous one went down. */			if (frag) {				frag->ip_summed = CHECKSUM_NONE;				frag->h.raw = frag->data;				frag->nh.raw = __skb_push(frag, hlen);				memcpy(frag->nh.raw, iph, hlen);				iph = frag->nh.iph;				iph->tot_len = htons(frag->len);				ip_copy_metadata(frag, skb);				if (offset == 0)					ip_options_fragment(frag);				offset += skb->len - hlen;				iph->frag_off = htons(offset>>3);				if (frag->next != NULL)					iph->frag_off |= htons(IP_MF);				/* Ready, complete checksum */				ip_send_check(iph);			}			err = output(skb);			if (err || !frag)				break;			skb = frag;			frag = skb->next;			skb->next = NULL;		}		if (err == 0) {			IP_INC_STATS(IPSTATS_MIB_FRAGOKS);			return 0;		}		while (frag) {			skb = frag->next;			kfree_skb(frag);			frag = skb;		}		IP_INC_STATS(IPSTATS_MIB_FRAGFAILS);		return err;	}slow_path:	left = skb->len - hlen;		/* Space per frame */	ptr = raw + hlen;		/* Where to start from */#ifdef CONFIG_BRIDGE_NETFILTER	/* for bridged IP traffic encapsulated inside f.e. a vlan header,	 * we need to make room for the encapsulating header */	ll_rs = LL_RESERVED_SPACE_EXTRA(rt->u.dst.dev, nf_bridge_pad(skb));	mtu -= nf_bridge_pad(skb);#else	ll_rs = LL_RESERVED_SPACE(rt->u.dst.dev);#endif	/*	 *	Fragment the datagram.	 */	offset = (ntohs(iph->frag_off) & IP_OFFSET) << 3;	not_last_frag = iph->frag_off & htons(IP_MF);	/*	 *	Keep copying data until we run out.	 */	while(left > 0)	{		len = left;		/* IF: it doesn't fit, use 'mtu' - the data space left */		if (len > mtu)			len = mtu;		/* IF: we are not sending upto and including the packet end		   then align the next start on an eight byte boundary */		if (len < left)	{			len &= ~7;		}		/*		 *	Allocate buffer.		 */		if ((skb2 = alloc_skb(len+hlen+ll_rs, GFP_ATOMIC)) == NULL) {			NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n"));			err = -ENOMEM;			goto fail;		}		/*		 *	Set up data on packet		 */		ip_copy_metadata(skb2, skb);		skb_reserve(skb2, ll_rs);		skb_put(skb2, len + hlen);		skb2->nh.raw = skb2->data;		skb2->h.raw = skb2->data + hlen;		/*		 *	Charge the memory for the fragment to any owner		 *	it might possess		 */		if (skb->sk)			skb_set_owner_w(skb2, skb->sk);		/*		 *	Copy the packet header into the new buffer.		 */		memcpy(skb2->nh.raw, skb->data, hlen);		/*		 *	Copy a block of the IP datagram.		 */		if (skb_copy_bits(skb, ptr, skb2->h.raw, len))			BUG();		left -= len;		/*		 *	Fill in the new header fields.		 */		iph = skb2->nh.iph;		iph->frag_off = htons((offset >> 3));		/* ANK: dirty, but effective trick. Upgrade options only if		 * the segment to be fragmented was THE FIRST (otherwise,		 * options are already fixed) and make it ONCE		 * on the initial skb, so that all the following fragments		 * will inherit fixed options.		 */		if (offset == 0)			ip_options_fragment(skb);		/*		 *	Added AC : If we are fragmenting a fragment that's not the		 *		   last fragment then keep MF on each bit		 */		if (left > 0 || not_last_frag)			iph->frag_off |= htons(IP_MF);		ptr += len;		offset += len;		/*		 *	Put this fragment into the sending queue.		 */		IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);		iph->tot_len = htons(len + hlen);		ip_send_check(iph);		err = output(skb2);		if (err)			goto fail;	}	kfree_skb(skb);	IP_INC_STATS(IPSTATS_MIB_FRAGOKS);	return err;fail:	kfree_skb(skb); 	IP_INC_STATS(IPSTATS_MIB_FRAGFAILS);	return err;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/64ce207306debd7157f47282be94770407bec01c/ip_output.c/clean/net/ipv4/ip_output.c