ip_fragment.c 20.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6
/*
 * INET		An implementation of the TCP/IP protocol suite for the LINUX
 *		operating system.  INET is implemented using the  BSD Socket
 *		interface as the means of communication with the user level.
 *
 *		The IP fragmentation functionality.
7
 *
L
Linus Torvalds 已提交
8
 * Authors:	Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
9
 *		Alan Cox <alan@lxorguk.ukuu.org.uk>
L
Linus Torvalds 已提交
10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * Fixes:
 *		Alan Cox	:	Split from ip.c , see ip_input.c for history.
 *		David S. Miller :	Begin massive cleanup...
 *		Andi Kleen	:	Add sysctls.
 *		xxxx		:	Overlapfrag bug.
 *		Ultima          :       ip_expire() kernel panic.
 *		Bill Hawes	:	Frag accounting and evictor fixes.
 *		John McDonald	:	0 length frag bug.
 *		Alexey Kuznetsov:	SMP races, threading, cleanup.
 *		Patrick McHardy :	LRU queue of frag heads for evictor.
 */

23 24
#define pr_fmt(fmt) "IPv4: " fmt

H
Herbert Xu 已提交
25
#include <linux/compiler.h>
L
Linus Torvalds 已提交
26 27 28 29 30 31 32 33 34 35 36
#include <linux/module.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/jiffies.h>
#include <linux/skbuff.h>
#include <linux/list.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/netdevice.h>
#include <linux/jhash.h>
#include <linux/random.h>
37
#include <linux/slab.h>
38 39
#include <net/route.h>
#include <net/dst.h>
L
Linus Torvalds 已提交
40 41 42 43
#include <net/sock.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/checksum.h>
H
Herbert Xu 已提交
44
#include <net/inetpeer.h>
45
#include <net/inet_frag.h>
L
Linus Torvalds 已提交
46 47 48 49
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/inet.h>
#include <linux/netfilter_ipv4.h>
50
#include <net/inet_ecn.h>
L
Linus Torvalds 已提交
51 52 53 54 55 56

/* NOTE. Logic of IP defragmentation is parallel to corresponding IPv6
 * code now. If you change something here, _PLEASE_ update ipv6/reassembly.c
 * as well. Or notify me, at least. --ANK
 */

57
static int sysctl_ipfrag_max_dist __read_mostly = 64;
H
Herbert Xu 已提交
58

L
Linus Torvalds 已提交
59 60 61 62 63 64
struct ipfrag_skb_cb
{
	struct inet_skb_parm	h;
	int			offset;
};

65
#define FRAG_CB(skb)	((struct ipfrag_skb_cb *)((skb)->cb))
L
Linus Torvalds 已提交
66 67 68

/* Describe an entry in the "incomplete datagrams" queue. */
struct ipq {
69 70
	struct inet_frag_queue q;

L
Linus Torvalds 已提交
71
	u32		user;
72 73 74
	__be32		saddr;
	__be32		daddr;
	__be16		id;
L
Linus Torvalds 已提交
75
	u8		protocol;
76
	u8		ecn; /* RFC3168 support */
H
Herbert Xu 已提交
77 78 79
	int             iif;
	unsigned int    rid;
	struct inet_peer *peer;
L
Linus Torvalds 已提交
80 81
};

82 83 84 85
/* RFC 3168 support :
 * We want to check ECN values of all fragments, do detect invalid combinations.
 * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
 */
86 87 88 89
#define	IPFRAG_ECN_NOT_ECT	0x01 /* one frag had ECN_NOT_ECT */
#define	IPFRAG_ECN_ECT_1	0x02 /* one frag had ECN_ECT_1 */
#define	IPFRAG_ECN_ECT_0	0x04 /* one frag had ECN_ECT_0 */
#define	IPFRAG_ECN_CE		0x08 /* one frag had ECN_CE */
90 91 92

static inline u8 ip4_frag_ecn(u8 tos)
{
93
	return 1 << (tos & INET_ECN_MASK);
94 95
}

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
/* Given the OR values of all fragments, apply RFC 3168 5.3 requirements
 * Value : 0xff if frame should be dropped.
 *         0 or INET_ECN_CE value, to be ORed in to final iph->tos field
 */
static const u8 ip4_frag_ecn_table[16] = {
	/* at least one fragment had CE, and others ECT_0 or ECT_1 */
	[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0]			= INET_ECN_CE,
	[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1]			= INET_ECN_CE,
	[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1]	= INET_ECN_CE,

	/* invalid combinations : drop frame */
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_1] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
};

116
static struct inet_frags ip4_frags;
L
Linus Torvalds 已提交
117

118
int ip_frag_nqueues(struct net *net)
119
{
120
	return net->ipv4.frags.nqueues;
121
}
L
Linus Torvalds 已提交
122

123
int ip_frag_mem(struct net *net)
124
{
125
	return atomic_read(&net->ipv4.frags.mem);
126
}
L
Linus Torvalds 已提交
127

128 129 130
static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
			 struct net_device *dev);

131 132 133 134 135
struct ip4_create_arg {
	struct iphdr *iph;
	u32 user;
};

136
static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
L
Linus Torvalds 已提交
137
{
138 139
	return jhash_3words((__force u32)id << 16 | prot,
			    (__force u32)saddr, (__force u32)daddr,
140
			    ip4_frags.rnd) & (INETFRAGS_HASHSZ - 1);
L
Linus Torvalds 已提交
141 142
}

143
static unsigned int ip4_hashfn(struct inet_frag_queue *q)
L
Linus Torvalds 已提交
144
{
145
	struct ipq *ipq;
L
Linus Torvalds 已提交
146

147 148
	ipq = container_of(q, struct ipq, q);
	return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol);
L
Linus Torvalds 已提交
149 150
}

151
static bool ip4_frag_match(struct inet_frag_queue *q, void *a)
152 153 154 155 156
{
	struct ipq *qp;
	struct ip4_create_arg *arg = a;

	qp = container_of(q, struct ipq, q);
E
Eric Dumazet 已提交
157
	return	qp->id == arg->iph->id &&
158 159 160 161
		qp->saddr == arg->iph->saddr &&
		qp->daddr == arg->iph->daddr &&
		qp->protocol == arg->iph->protocol &&
		qp->user == arg->user;
162 163
}

L
Linus Torvalds 已提交
164
/* Memory Tracking Functions. */
E
Eric Dumazet 已提交
165
static void frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb)
L
Linus Torvalds 已提交
166
{
167
	atomic_sub(skb->truesize, &nf->mem);
L
Linus Torvalds 已提交
168 169 170
	kfree_skb(skb);
}

171 172 173 174 175 176 177
static void ip4_frag_init(struct inet_frag_queue *q, void *a)
{
	struct ipq *qp = container_of(q, struct ipq, q);
	struct ip4_create_arg *arg = a;

	qp->protocol = arg->iph->protocol;
	qp->id = arg->iph->id;
178
	qp->ecn = ip4_frag_ecn(arg->iph->tos);
179 180 181 182
	qp->saddr = arg->iph->saddr;
	qp->daddr = arg->iph->daddr;
	qp->user = arg->user;
	qp->peer = sysctl_ipfrag_max_dist ?
183
		inet_getpeer_v4(arg->iph->saddr, 1) : NULL;
184 185
}

186
static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
L
Linus Torvalds 已提交
187
{
188 189 190 191 192
	struct ipq *qp;

	qp = container_of(q, struct ipq, q);
	if (qp->peer)
		inet_putpeer(qp->peer);
L
Linus Torvalds 已提交
193 194 195 196 197
}


/* Destruction primitives. */

198
static __inline__ void ipq_put(struct ipq *ipq)
L
Linus Torvalds 已提交
199
{
P
Pavel Emelyanov 已提交
200
	inet_frag_put(&ipq->q, &ip4_frags);
L
Linus Torvalds 已提交
201 202 203 204 205 206 207
}

/* Kill ipq entry. It is not destroyed immediately,
 * because caller (and someone more) holds reference count.
 */
static void ipq_kill(struct ipq *ipq)
{
208
	inet_frag_kill(&ipq->q, &ip4_frags);
L
Linus Torvalds 已提交
209 210
}

211
/* Memory limiting on fragments.  Evictor trashes the oldest
L
Linus Torvalds 已提交
212 213
 * fragment queue until we are back under the threshold.
 */
214
static void ip_evictor(struct net *net)
L
Linus Torvalds 已提交
215
{
216 217
	int evicted;

218
	evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags);
219
	if (evicted)
220
		IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted);
L
Linus Torvalds 已提交
221 222 223 224 225 226 227
}

/*
 * Oops, a fragment queue timed out.  Kill it and send an ICMP reply.
 */
static void ip_expire(unsigned long arg)
{
228
	struct ipq *qp;
229
	struct net *net;
230 231

	qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
232
	net = container_of(qp->q.net, struct net, ipv4.frags);
L
Linus Torvalds 已提交
233

234
	spin_lock(&qp->q.lock);
L
Linus Torvalds 已提交
235

236
	if (qp->q.last_in & INET_FRAG_COMPLETE)
L
Linus Torvalds 已提交
237 238 239 240
		goto out;

	ipq_kill(qp);

241 242
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMTIMEOUT);
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
L
Linus Torvalds 已提交
243

244
	if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) {
245
		struct sk_buff *head = qp->q.fragments;
246 247
		const struct iphdr *iph;
		int err;
248

E
Eric Dumazet 已提交
249 250
		rcu_read_lock();
		head->dev = dev_get_by_index_rcu(net, qp->iif);
251 252 253
		if (!head->dev)
			goto out_rcu_unlock;

254 255 256 257 258 259 260 261
		/* skb dst is stale, drop it, and perform route lookup again */
		skb_dst_drop(head);
		iph = ip_hdr(head);
		err = ip_route_input_noref(head, iph->daddr, iph->saddr,
					   iph->tos, head->dev);
		if (err)
			goto out_rcu_unlock;

262
		/*
263 264
		 * Only an end host needs to send an ICMP
		 * "Fragment Reassembly Timeout" message, per RFC792.
265
		 */
266 267 268
		if (qp->user == IP_DEFRAG_AF_PACKET ||
		    (qp->user == IP_DEFRAG_CONNTRACK_IN &&
		     skb_rtable(head)->rt_type != RTN_LOCAL))
269 270
			goto out_rcu_unlock;

271 272 273 274

		/* Send an ICMP "Fragment Reassembly Timeout" message. */
		icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
out_rcu_unlock:
275 276
		rcu_read_unlock();
	}
L
Linus Torvalds 已提交
277
out:
278
	spin_unlock(&qp->q.lock);
279
	ipq_put(qp);
L
Linus Torvalds 已提交
280 281
}

282 283 284
/* Find the correct entry in the "incomplete datagrams" queue for
 * this IP datagram, and create new one, if nothing is found.
 */
285
static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
L
Linus Torvalds 已提交
286
{
287 288
	struct inet_frag_queue *q;
	struct ip4_create_arg arg;
289
	unsigned int hash;
L
Linus Torvalds 已提交
290

291 292
	arg.iph = iph;
	arg.user = user;
293 294

	read_lock(&ip4_frags.lock);
295
	hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
L
Linus Torvalds 已提交
296

297
	q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
298 299
	if (q == NULL)
		goto out_nomem;
L
Linus Torvalds 已提交
300

301
	return container_of(q, struct ipq, q);
L
Linus Torvalds 已提交
302 303

out_nomem:
304
	LIMIT_NETDEBUG(KERN_ERR pr_fmt("ip_frag_create: no memory left !\n"));
L
Linus Torvalds 已提交
305 306 307
	return NULL;
}

H
Herbert Xu 已提交
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
/* Is the fragment too far ahead to be part of ipq? */
static inline int ip_frag_too_far(struct ipq *qp)
{
	struct inet_peer *peer = qp->peer;
	unsigned int max = sysctl_ipfrag_max_dist;
	unsigned int start, end;

	int rc;

	if (!peer || !max)
		return 0;

	start = qp->rid;
	end = atomic_inc_return(&peer->rid);
	qp->rid = end;

324
	rc = qp->q.fragments && (end - start) > max;
H
Herbert Xu 已提交
325 326

	if (rc) {
327 328 329 330
		struct net *net;

		net = container_of(qp->q.net, struct net, ipv4.frags);
		IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
H
Herbert Xu 已提交
331 332 333 334 335 336 337 338 339
	}

	return rc;
}

static int ip_frag_reinit(struct ipq *qp)
{
	struct sk_buff *fp;

340
	if (!mod_timer(&qp->q.timer, jiffies + qp->q.net->timeout)) {
341
		atomic_inc(&qp->q.refcnt);
H
Herbert Xu 已提交
342 343 344
		return -ETIMEDOUT;
	}

345
	fp = qp->q.fragments;
H
Herbert Xu 已提交
346 347
	do {
		struct sk_buff *xp = fp->next;
E
Eric Dumazet 已提交
348
		frag_kfree_skb(qp->q.net, fp);
H
Herbert Xu 已提交
349 350 351
		fp = xp;
	} while (fp);

352 353 354 355
	qp->q.last_in = 0;
	qp->q.len = 0;
	qp->q.meat = 0;
	qp->q.fragments = NULL;
356
	qp->q.fragments_tail = NULL;
H
Herbert Xu 已提交
357
	qp->iif = 0;
358
	qp->ecn = 0;
H
Herbert Xu 已提交
359 360 361 362

	return 0;
}

L
Linus Torvalds 已提交
363
/* Add new segment to existing queue. */
364
static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
L
Linus Torvalds 已提交
365 366
{
	struct sk_buff *prev, *next;
367
	struct net_device *dev;
L
Linus Torvalds 已提交
368 369
	int flags, offset;
	int ihl, end;
370
	int err = -ENOENT;
371
	u8 ecn;
L
Linus Torvalds 已提交
372

373
	if (qp->q.last_in & INET_FRAG_COMPLETE)
L
Linus Torvalds 已提交
374 375
		goto err;

H
Herbert Xu 已提交
376
	if (!(IPCB(skb)->flags & IPSKB_FRAG_COMPLETE) &&
377 378
	    unlikely(ip_frag_too_far(qp)) &&
	    unlikely(err = ip_frag_reinit(qp))) {
H
Herbert Xu 已提交
379 380 381 382
		ipq_kill(qp);
		goto err;
	}

383
	ecn = ip4_frag_ecn(ip_hdr(skb)->tos);
384
	offset = ntohs(ip_hdr(skb)->frag_off);
L
Linus Torvalds 已提交
385 386 387
	flags = offset & ~IP_OFFSET;
	offset &= IP_OFFSET;
	offset <<= 3;		/* offset is in 8-byte chunks */
388
	ihl = ip_hdrlen(skb);
L
Linus Torvalds 已提交
389 390

	/* Determine the position of this fragment. */
391
	end = offset + skb->len - ihl;
392
	err = -EINVAL;
L
Linus Torvalds 已提交
393 394 395 396

	/* Is this the final fragment? */
	if ((flags & IP_MF) == 0) {
		/* If we already have some bits beyond end
397
		 * or have different end, the segment is corrupted.
L
Linus Torvalds 已提交
398
		 */
399
		if (end < qp->q.len ||
400
		    ((qp->q.last_in & INET_FRAG_LAST_IN) && end != qp->q.len))
L
Linus Torvalds 已提交
401
			goto err;
402
		qp->q.last_in |= INET_FRAG_LAST_IN;
403
		qp->q.len = end;
L
Linus Torvalds 已提交
404 405 406 407 408 409
	} else {
		if (end&7) {
			end &= ~7;
			if (skb->ip_summed != CHECKSUM_UNNECESSARY)
				skb->ip_summed = CHECKSUM_NONE;
		}
410
		if (end > qp->q.len) {
L
Linus Torvalds 已提交
411
			/* Some bits beyond end -> corruption. */
412
			if (qp->q.last_in & INET_FRAG_LAST_IN)
L
Linus Torvalds 已提交
413
				goto err;
414
			qp->q.len = end;
L
Linus Torvalds 已提交
415 416 417 418 419
		}
	}
	if (end == offset)
		goto err;

420
	err = -ENOMEM;
L
Linus Torvalds 已提交
421 422
	if (pskb_pull(skb, ihl) == NULL)
		goto err;
423 424 425

	err = pskb_trim_rcsum(skb, end - offset);
	if (err)
L
Linus Torvalds 已提交
426 427 428 429 430 431
		goto err;

	/* Find out which fragments are in front and at the back of us
	 * in the chain of fragments so far.  We must know where to put
	 * this fragment, right?
	 */
432 433 434 435 436
	prev = qp->q.fragments_tail;
	if (!prev || FRAG_CB(prev)->offset < offset) {
		next = NULL;
		goto found;
	}
L
Linus Torvalds 已提交
437
	prev = NULL;
438
	for (next = qp->q.fragments; next != NULL; next = next->next) {
L
Linus Torvalds 已提交
439 440 441 442 443
		if (FRAG_CB(next)->offset >= offset)
			break;	/* bingo! */
		prev = next;
	}

444
found:
L
Linus Torvalds 已提交
445 446 447 448 449 450 451 452 453
	/* We found where to put this one.  Check for overlap with
	 * preceding fragment, and, if needed, align things so that
	 * any overlaps are eliminated.
	 */
	if (prev) {
		int i = (FRAG_CB(prev)->offset + prev->len) - offset;

		if (i > 0) {
			offset += i;
454
			err = -EINVAL;
L
Linus Torvalds 已提交
455 456
			if (end <= offset)
				goto err;
457
			err = -ENOMEM;
L
Linus Torvalds 已提交
458 459 460 461 462 463 464
			if (!pskb_pull(skb, i))
				goto err;
			if (skb->ip_summed != CHECKSUM_UNNECESSARY)
				skb->ip_summed = CHECKSUM_NONE;
		}
	}

465 466
	err = -ENOMEM;

L
Linus Torvalds 已提交
467 468 469 470 471 472 473 474 475 476
	while (next && FRAG_CB(next)->offset < end) {
		int i = end - FRAG_CB(next)->offset; /* overlap is 'i' bytes */

		if (i < next->len) {
			/* Eat head of the next overlapped fragment
			 * and leave the loop. The next ones cannot overlap.
			 */
			if (!pskb_pull(next, i))
				goto err;
			FRAG_CB(next)->offset += i;
477
			qp->q.meat -= i;
L
Linus Torvalds 已提交
478 479 480 481 482 483
			if (next->ip_summed != CHECKSUM_UNNECESSARY)
				next->ip_summed = CHECKSUM_NONE;
			break;
		} else {
			struct sk_buff *free_it = next;

484
			/* Old fragment is completely overridden with
L
Linus Torvalds 已提交
485 486 487 488 489 490 491
			 * new one drop it.
			 */
			next = next->next;

			if (prev)
				prev->next = next;
			else
492
				qp->q.fragments = next;
L
Linus Torvalds 已提交
493

494
			qp->q.meat -= free_it->len;
E
Eric Dumazet 已提交
495
			frag_kfree_skb(qp->q.net, free_it);
L
Linus Torvalds 已提交
496 497 498 499 500 501 502
		}
	}

	FRAG_CB(skb)->offset = offset;

	/* Insert this fragment in the chain of fragments. */
	skb->next = next;
503 504
	if (!next)
		qp->q.fragments_tail = skb;
L
Linus Torvalds 已提交
505 506 507
	if (prev)
		prev->next = skb;
	else
508
		qp->q.fragments = skb;
L
Linus Torvalds 已提交
509

510 511 512 513 514
	dev = skb->dev;
	if (dev) {
		qp->iif = dev->ifindex;
		skb->dev = NULL;
	}
515 516
	qp->q.stamp = skb->tstamp;
	qp->q.meat += skb->len;
517
	qp->ecn |= ecn;
518
	atomic_add(skb->truesize, &qp->q.net->mem);
L
Linus Torvalds 已提交
519
	if (offset == 0)
520
		qp->q.last_in |= INET_FRAG_FIRST_IN;
L
Linus Torvalds 已提交
521

522 523
	if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
	    qp->q.meat == qp->q.len)
524 525
		return ip_frag_reasm(qp, prev, dev);

526
	write_lock(&ip4_frags.lock);
527
	list_move_tail(&qp->q.lru_list, &qp->q.net->lru_list);
528
	write_unlock(&ip4_frags.lock);
529
	return -EINPROGRESS;
L
Linus Torvalds 已提交
530 531 532

err:
	kfree_skb(skb);
533
	return err;
L
Linus Torvalds 已提交
534 535 536 537 538
}


/* Build a new IP datagram from all its fragments. */

539 540
static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
			 struct net_device *dev)
L
Linus Torvalds 已提交
541
{
542
	struct net *net = container_of(qp->q.net, struct net, ipv4.frags);
L
Linus Torvalds 已提交
543
	struct iphdr *iph;
544
	struct sk_buff *fp, *head = qp->q.fragments;
L
Linus Torvalds 已提交
545 546
	int len;
	int ihlen;
547
	int err;
548
	int sum_truesize;
549
	u8 ecn;
L
Linus Torvalds 已提交
550 551 552

	ipq_kill(qp);

553 554 555 556 557
	ecn = ip4_frag_ecn_table[qp->ecn];
	if (unlikely(ecn == 0xff)) {
		err = -EINVAL;
		goto out_fail;
	}
558 559 560 561 562 563 564 565
	/* Make the one we just received the head. */
	if (prev) {
		head = prev->next;
		fp = skb_clone(head, GFP_ATOMIC);
		if (!fp)
			goto out_nomem;

		fp->next = head->next;
566 567
		if (!fp->next)
			qp->q.fragments_tail = fp;
568 569
		prev->next = fp;

570 571
		skb_morph(head, qp->q.fragments);
		head->next = qp->q.fragments->next;
572

573
		consume_skb(qp->q.fragments);
574
		qp->q.fragments = head;
575 576
	}

577 578
	WARN_ON(head == NULL);
	WARN_ON(FRAG_CB(head)->offset != 0);
L
Linus Torvalds 已提交
579 580

	/* Allocate a new buffer for the datagram. */
581
	ihlen = ip_hdrlen(head);
582
	len = ihlen + qp->q.len;
L
Linus Torvalds 已提交
583

584
	err = -E2BIG;
S
Stephen Hemminger 已提交
585
	if (len > 65535)
L
Linus Torvalds 已提交
586 587 588 589 590 591 592 593 594
		goto out_oversize;

	/* Head of list must not be cloned. */
	if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC))
		goto out_nomem;

	/* If the first fragment is fragmented itself, we split
	 * it to two chunks: the first with data and paged part
	 * and the second, holding only fragments. */
595
	if (skb_has_frag_list(head)) {
L
Linus Torvalds 已提交
596 597 598 599 600 601 602 603
		struct sk_buff *clone;
		int i, plen = 0;

		if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL)
			goto out_nomem;
		clone->next = head->next;
		head->next = clone;
		skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
604
		skb_frag_list_init(head);
E
Eric Dumazet 已提交
605 606
		for (i = 0; i < skb_shinfo(head)->nr_frags; i++)
			plen += skb_frag_size(&skb_shinfo(head)->frags[i]);
L
Linus Torvalds 已提交
607 608 609 610 611
		clone->len = clone->data_len = head->data_len - plen;
		head->data_len -= clone->len;
		head->len -= clone->len;
		clone->csum = 0;
		clone->ip_summed = head->ip_summed;
612
		atomic_add(clone->truesize, &qp->q.net->mem);
L
Linus Torvalds 已提交
613 614
	}

615
	skb_push(head, head->data - skb_network_header(head));
L
Linus Torvalds 已提交
616

617 618 619 620 621 622 623
	sum_truesize = head->truesize;
	for (fp = head->next; fp;) {
		bool headstolen;
		int delta;
		struct sk_buff *next = fp->next;

		sum_truesize += fp->truesize;
L
Linus Torvalds 已提交
624 625
		if (head->ip_summed != fp->ip_summed)
			head->ip_summed = CHECKSUM_NONE;
626
		else if (head->ip_summed == CHECKSUM_COMPLETE)
L
Linus Torvalds 已提交
627
			head->csum = csum_add(head->csum, fp->csum);
628 629 630 631 632 633 634 635 636 637 638

		if (skb_try_coalesce(head, fp, &headstolen, &delta)) {
			kfree_skb_partial(fp, headstolen);
		} else {
			if (!skb_shinfo(head)->frag_list)
				skb_shinfo(head)->frag_list = fp;
			head->data_len += fp->len;
			head->len += fp->len;
			head->truesize += fp->truesize;
		}
		fp = next;
L
Linus Torvalds 已提交
639
	}
640
	atomic_sub(sum_truesize, &qp->q.net->mem);
L
Linus Torvalds 已提交
641 642 643

	head->next = NULL;
	head->dev = dev;
644
	head->tstamp = qp->q.stamp;
L
Linus Torvalds 已提交
645

646
	iph = ip_hdr(head);
L
Linus Torvalds 已提交
647 648
	iph->frag_off = 0;
	iph->tot_len = htons(len);
649
	iph->tos |= ecn;
650
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
651
	qp->q.fragments = NULL;
652
	qp->q.fragments_tail = NULL;
653
	return 0;
L
Linus Torvalds 已提交
654 655

out_nomem:
656 657
	LIMIT_NETDEBUG(KERN_ERR pr_fmt("queue_glue: no memory for gluing queue %p\n"),
		       qp);
658
	err = -ENOMEM;
L
Linus Torvalds 已提交
659 660
	goto out_fail;
out_oversize:
661
	net_info_ratelimited("Oversized IP packet from %pI4\n", &qp->saddr);
L
Linus Torvalds 已提交
662
out_fail:
663
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
664
	return err;
L
Linus Torvalds 已提交
665 666 667
}

/* Process an incoming IP datagram fragment. */
668
int ip_defrag(struct sk_buff *skb, u32 user)
L
Linus Torvalds 已提交
669 670
{
	struct ipq *qp;
671
	struct net *net;
672

E
Eric Dumazet 已提交
673
	net = skb->dev ? dev_net(skb->dev) : dev_net(skb_dst(skb)->dev);
674
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
L
Linus Torvalds 已提交
675 676

	/* Start by cleaning up the memory. */
677
	if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh)
678
		ip_evictor(net);
L
Linus Torvalds 已提交
679 680

	/* Lookup (or create) queue header */
681
	if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) {
682
		int ret;
L
Linus Torvalds 已提交
683

684
		spin_lock(&qp->q.lock);
L
Linus Torvalds 已提交
685

686
		ret = ip_frag_queue(qp, skb);
L
Linus Torvalds 已提交
687

688
		spin_unlock(&qp->q.lock);
689
		ipq_put(qp);
690
		return ret;
L
Linus Torvalds 已提交
691 692
	}

693
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
L
Linus Torvalds 已提交
694
	kfree_skb(skb);
695
	return -ENOMEM;
L
Linus Torvalds 已提交
696
}
E
Eric Dumazet 已提交
697
EXPORT_SYMBOL(ip_defrag);
L
Linus Torvalds 已提交
698

699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
{
	const struct iphdr *iph;
	u32 len;

	if (skb->protocol != htons(ETH_P_IP))
		return skb;

	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
		return skb;

	iph = ip_hdr(skb);
	if (iph->ihl < 5 || iph->version != 4)
		return skb;
	if (!pskb_may_pull(skb, iph->ihl*4))
		return skb;
	iph = ip_hdr(skb);
	len = ntohs(iph->tot_len);
	if (skb->len < len || len < (iph->ihl * 4))
		return skb;

	if (ip_is_fragment(ip_hdr(skb))) {
		skb = skb_share_check(skb, GFP_ATOMIC);
		if (skb) {
			if (pskb_trim_rcsum(skb, len))
				return skb;
			memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
			if (ip_defrag(skb, user))
				return NULL;
			skb->rxhash = 0;
		}
	}
	return skb;
}
EXPORT_SYMBOL(ip_check_defrag);

735 736 737
#ifdef CONFIG_SYSCTL
static int zero;

738
static struct ctl_table ip4_frags_ns_ctl_table[] = {
739 740
	{
		.procname	= "ipfrag_high_thresh",
741
		.data		= &init_net.ipv4.frags.high_thresh,
742 743
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
744
		.proc_handler	= proc_dointvec
745 746 747
	},
	{
		.procname	= "ipfrag_low_thresh",
748
		.data		= &init_net.ipv4.frags.low_thresh,
749 750
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
751
		.proc_handler	= proc_dointvec
752 753 754
	},
	{
		.procname	= "ipfrag_time",
755
		.data		= &init_net.ipv4.frags.timeout,
756 757
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
758
		.proc_handler	= proc_dointvec_jiffies,
759
	},
760 761 762 763
	{ }
};

static struct ctl_table ip4_frags_ctl_table[] = {
764 765
	{
		.procname	= "ipfrag_secret_interval",
766
		.data		= &ip4_frags.secret_interval,
767 768
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
769
		.proc_handler	= proc_dointvec_jiffies,
770 771 772 773 774 775
	},
	{
		.procname	= "ipfrag_max_dist",
		.data		= &sysctl_ipfrag_max_dist,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
776
		.proc_handler	= proc_dointvec_minmax,
777 778 779 780 781
		.extra1		= &zero
	},
	{ }
};

782
static int __net_init ip4_frags_ns_ctl_register(struct net *net)
783
{
784
	struct ctl_table *table;
785 786
	struct ctl_table_header *hdr;

787
	table = ip4_frags_ns_ctl_table;
O
Octavian Purdila 已提交
788
	if (!net_eq(net, &init_net)) {
789
		table = kmemdup(table, sizeof(ip4_frags_ns_ctl_table), GFP_KERNEL);
790 791 792
		if (table == NULL)
			goto err_alloc;

793 794
		table[0].data = &net->ipv4.frags.high_thresh;
		table[1].data = &net->ipv4.frags.low_thresh;
795
		table[2].data = &net->ipv4.frags.timeout;
796 797
	}

798
	hdr = register_net_sysctl(net, "net/ipv4", table);
799 800 801 802 803 804 805
	if (hdr == NULL)
		goto err_reg;

	net->ipv4.frags_hdr = hdr;
	return 0;

err_reg:
O
Octavian Purdila 已提交
806
	if (!net_eq(net, &init_net))
807 808 809 810 811
		kfree(table);
err_alloc:
	return -ENOMEM;
}

812
static void __net_exit ip4_frags_ns_ctl_unregister(struct net *net)
813 814 815 816 817 818
{
	struct ctl_table *table;

	table = net->ipv4.frags_hdr->ctl_table_arg;
	unregister_net_sysctl_table(net->ipv4.frags_hdr);
	kfree(table);
819
}
820 821 822

static void ip4_frags_ctl_register(void)
{
823
	register_net_sysctl(&init_net, "net/ipv4", ip4_frags_ctl_table);
824
}
825
#else
826
static inline int ip4_frags_ns_ctl_register(struct net *net)
827 828 829
{
	return 0;
}
830

831
static inline void ip4_frags_ns_ctl_unregister(struct net *net)
832 833
{
}
834 835 836 837

static inline void ip4_frags_ctl_register(void)
{
}
838 839
#endif

840
static int __net_init ipv4_frags_init_net(struct net *net)
841
{
842 843 844 845 846 847 848 849
	/*
	 * Fragment cache limits. We will commit 256K at one time. Should we
	 * cross that limit we will prune down to 192K. This should cope with
	 * even the most extreme cases without allowing an attacker to
	 * measurably harm machine performance.
	 */
	net->ipv4.frags.high_thresh = 256 * 1024;
	net->ipv4.frags.low_thresh = 192 * 1024;
850 851 852 853 854 855 856
	/*
	 * Important NOTE! Fragment queue must be destroyed before MSL expires.
	 * RFC791 is wrong proposing to prolongate timer each fragment arrival
	 * by TTL.
	 */
	net->ipv4.frags.timeout = IP_FRAG_TIME;

857 858
	inet_frags_init_net(&net->ipv4.frags);

859
	return ip4_frags_ns_ctl_register(net);
860 861
}

862
static void __net_exit ipv4_frags_exit_net(struct net *net)
863
{
864
	ip4_frags_ns_ctl_unregister(net);
865 866 867 868 869 870 871 872
	inet_frags_exit_net(&net->ipv4.frags, &ip4_frags);
}

static struct pernet_operations ip4_frags_ops = {
	.init = ipv4_frags_init_net,
	.exit = ipv4_frags_exit_net,
};

873
void __init ipfrag_init(void)
L
Linus Torvalds 已提交
874
{
875
	ip4_frags_ctl_register();
876
	register_pernet_subsys(&ip4_frags_ops);
877
	ip4_frags.hashfn = ip4_hashfn;
878
	ip4_frags.constructor = ip4_frag_init;
879 880 881
	ip4_frags.destructor = ip4_frag_free;
	ip4_frags.skb_free = NULL;
	ip4_frags.qsize = sizeof(struct ipq);
882
	ip4_frags.match = ip4_frag_match;
883
	ip4_frags.frag_expire = ip_expire;
884
	ip4_frags.secret_interval = 10 * 60 * HZ;
885
	inet_frags_init(&ip4_frags);
L
Linus Torvalds 已提交
886
}