BUG_ON(len >= skb->len);
if (unlikely(len >= skb->len)) { printk(KERN_DEBUG "TCP: seg_size=%u, mss=%u, seq=%u, " "end_seq=%u, skb->len=%u.\n", len, mss_now, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq, skb->len); WARN_ON(1); return 0; }
int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss_now){	struct tcp_sock *tp = tcp_sk(sk);	struct sk_buff *buff;	int nsize, old_factor;	u16 flags;	BUG_ON(len >= skb->len);	nsize = skb_headlen(skb) - len;	if (nsize < 0)		nsize = 0;	if (skb_cloned(skb) &&	    skb_is_nonlinear(skb) &&	    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))		return -ENOMEM;	/* Get a new skb... force flag on. */	buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC);	if (buff == NULL)		return -ENOMEM; /* We'll just try again later. */	sk_charge_skb(sk, buff);	/* Correct the sequence numbers. */	TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;	TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;	/* PSH and FIN should only be set in the second packet. */	flags = TCP_SKB_CB(skb)->flags;	TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);	TCP_SKB_CB(buff)->flags = flags;	TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked;	TCP_SKB_CB(skb)->sacked &= ~TCPCB_AT_TAIL;	if (!skb_shinfo(skb)->nr_frags && skb->ip_summed != CHECKSUM_HW) {		/* Copy and checksum data tail into the new buffer. */		buff->csum = csum_partial_copy_nocheck(skb->data + len, skb_put(buff, nsize),						       nsize, 0);		skb_trim(skb, len);		skb->csum = csum_block_sub(skb->csum, buff->csum, len);	} else {		skb->ip_summed = CHECKSUM_HW;		skb_split(skb, buff, len);	}	buff->ip_summed = skb->ip_summed;	/* Looks stupid, but our code really uses when of	 * skbs, which it never sent before. --ANK	 */	TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;	buff->tstamp = skb->tstamp;	old_factor = tcp_skb_pcount(skb);	/* Fix up tso_factor for both original and new SKB.  */	tcp_set_skb_tso_segs(sk, skb, mss_now);	tcp_set_skb_tso_segs(sk, buff, mss_now);	/* If this packet has been sent out already, we must	 * adjust the various packet counters.	 */	if (!before(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {		int diff = old_factor - tcp_skb_pcount(skb) -			tcp_skb_pcount(buff);		tp->packets_out -= diff;		if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)			tp->sacked_out -= diff;		if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)			tp->retrans_out -= diff;		if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {			tp->lost_out -= diff;			tp->left_out -= diff;		}		if (diff > 0) {			/* Adjust Reno SACK estimate. */			if (!tp->rx_opt.sack_ok) {				tp->sacked_out -= diff;				if ((int)tp->sacked_out < 0)					tp->sacked_out = 0;				tcp_sync_left_out(tp);			}			tp->fackets_out -= diff;			if ((int)tp->fackets_out < 0)				tp->fackets_out = 0;		}	}	/* Link BUFF into the send queue. */	skb_header_release(buff);	__skb_append(skb, buff, &sk->sk_write_queue);	return 0;}