ip_fragment.c 20.6 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 152 153 154 155 156
static int ip4_frag_match(struct inet_frag_queue *q, void *a)
{
	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
			qp->saddr == arg->iph->saddr &&
			qp->daddr == arg->iph->daddr &&
			qp->protocol == arg->iph->protocol &&
E
Eric Dumazet 已提交
161
			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
	u8 ecn;
L
Linus Torvalds 已提交
549 550 551

	ipq_kill(qp);

552 553 554 555 556
	ecn = ip4_frag_ecn_table[qp->ecn];
	if (unlikely(ecn == 0xff)) {
		err = -EINVAL;
		goto out_fail;
	}
557 558 559 560 561 562 563 564
	/* 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;
565 566
		if (!fp->next)
			qp->q.fragments_tail = fp;
567 568
		prev->next = fp;

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

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

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

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

583
	err = -E2BIG;
S
Stephen Hemminger 已提交
584
	if (len > 65535)
L
Linus Torvalds 已提交
585 586 587 588 589 590 591 592 593
		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. */
594
	if (skb_has_frag_list(head)) {
L
Linus Torvalds 已提交
595 596 597 598 599 600 601 602
		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;
603
		skb_frag_list_init(head);
E
Eric Dumazet 已提交
604 605
		for (i = 0; i < skb_shinfo(head)->nr_frags; i++)
			plen += skb_frag_size(&skb_shinfo(head)->frags[i]);
L
Linus Torvalds 已提交
606 607 608 609 610
		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;
611
		atomic_add(clone->truesize, &qp->q.net->mem);
L
Linus Torvalds 已提交
612 613 614
	}

	skb_shinfo(head)->frag_list = head->next;
615
	skb_push(head, head->data - skb_network_header(head));
L
Linus Torvalds 已提交
616 617 618 619 620 621

	for (fp=head->next; fp; fp = fp->next) {
		head->data_len += fp->len;
		head->len += fp->len;
		if (head->ip_summed != fp->ip_summed)
			head->ip_summed = CHECKSUM_NONE;
622
		else if (head->ip_summed == CHECKSUM_COMPLETE)
L
Linus Torvalds 已提交
623 624 625
			head->csum = csum_add(head->csum, fp->csum);
		head->truesize += fp->truesize;
	}
E
Eric Dumazet 已提交
626
	atomic_sub(head->truesize, &qp->q.net->mem);
L
Linus Torvalds 已提交
627 628 629

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

632
	iph = ip_hdr(head);
L
Linus Torvalds 已提交
633 634
	iph->frag_off = 0;
	iph->tot_len = htons(len);
635
	iph->tos |= ecn;
636
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
637
	qp->q.fragments = NULL;
638
	qp->q.fragments_tail = NULL;
639
	return 0;
L
Linus Torvalds 已提交
640 641

out_nomem:
642 643
	LIMIT_NETDEBUG(KERN_ERR pr_fmt("queue_glue: no memory for gluing queue %p\n"),
		       qp);
644
	err = -ENOMEM;
L
Linus Torvalds 已提交
645 646 647
	goto out_fail;
out_oversize:
	if (net_ratelimit())
J
Joe Perches 已提交
648
		pr_info("Oversized IP packet from %pI4\n", &qp->saddr);
L
Linus Torvalds 已提交
649
out_fail:
650
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
651
	return err;
L
Linus Torvalds 已提交
652 653 654
}

/* Process an incoming IP datagram fragment. */
655
int ip_defrag(struct sk_buff *skb, u32 user)
L
Linus Torvalds 已提交
656 657
{
	struct ipq *qp;
658
	struct net *net;
659

E
Eric Dumazet 已提交
660
	net = skb->dev ? dev_net(skb->dev) : dev_net(skb_dst(skb)->dev);
661
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
L
Linus Torvalds 已提交
662 663

	/* Start by cleaning up the memory. */
664
	if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh)
665
		ip_evictor(net);
L
Linus Torvalds 已提交
666 667

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

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

673
		ret = ip_frag_queue(qp, skb);
L
Linus Torvalds 已提交
674

675
		spin_unlock(&qp->q.lock);
676
		ipq_put(qp);
677
		return ret;
L
Linus Torvalds 已提交
678 679
	}

680
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
L
Linus Torvalds 已提交
681
	kfree_skb(skb);
682
	return -ENOMEM;
L
Linus Torvalds 已提交
683
}
E
Eric Dumazet 已提交
684
EXPORT_SYMBOL(ip_defrag);
L
Linus Torvalds 已提交
685

686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721
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);

722 723 724
#ifdef CONFIG_SYSCTL
static int zero;

725
static struct ctl_table ip4_frags_ns_ctl_table[] = {
726 727
	{
		.procname	= "ipfrag_high_thresh",
728
		.data		= &init_net.ipv4.frags.high_thresh,
729 730
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
731
		.proc_handler	= proc_dointvec
732 733 734
	},
	{
		.procname	= "ipfrag_low_thresh",
735
		.data		= &init_net.ipv4.frags.low_thresh,
736 737
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
738
		.proc_handler	= proc_dointvec
739 740 741
	},
	{
		.procname	= "ipfrag_time",
742
		.data		= &init_net.ipv4.frags.timeout,
743 744
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
745
		.proc_handler	= proc_dointvec_jiffies,
746
	},
747 748 749 750
	{ }
};

static struct ctl_table ip4_frags_ctl_table[] = {
751 752
	{
		.procname	= "ipfrag_secret_interval",
753
		.data		= &ip4_frags.secret_interval,
754 755
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
756
		.proc_handler	= proc_dointvec_jiffies,
757 758 759 760 761 762
	},
	{
		.procname	= "ipfrag_max_dist",
		.data		= &sysctl_ipfrag_max_dist,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
763
		.proc_handler	= proc_dointvec_minmax,
764 765 766 767 768
		.extra1		= &zero
	},
	{ }
};

769
static int __net_init ip4_frags_ns_ctl_register(struct net *net)
770
{
771
	struct ctl_table *table;
772 773
	struct ctl_table_header *hdr;

774
	table = ip4_frags_ns_ctl_table;
O
Octavian Purdila 已提交
775
	if (!net_eq(net, &init_net)) {
776
		table = kmemdup(table, sizeof(ip4_frags_ns_ctl_table), GFP_KERNEL);
777 778 779
		if (table == NULL)
			goto err_alloc;

780 781
		table[0].data = &net->ipv4.frags.high_thresh;
		table[1].data = &net->ipv4.frags.low_thresh;
782
		table[2].data = &net->ipv4.frags.timeout;
783 784
	}

785
	hdr = register_net_sysctl(net, "net/ipv4", table);
786 787 788 789 790 791 792
	if (hdr == NULL)
		goto err_reg;

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

err_reg:
O
Octavian Purdila 已提交
793
	if (!net_eq(net, &init_net))
794 795 796 797 798
		kfree(table);
err_alloc:
	return -ENOMEM;
}

799
static void __net_exit ip4_frags_ns_ctl_unregister(struct net *net)
800 801 802 803 804 805
{
	struct ctl_table *table;

	table = net->ipv4.frags_hdr->ctl_table_arg;
	unregister_net_sysctl_table(net->ipv4.frags_hdr);
	kfree(table);
806
}
807 808 809

static void ip4_frags_ctl_register(void)
{
810
	register_net_sysctl(&init_net, "net/ipv4", ip4_frags_ctl_table);
811
}
812
#else
813
static inline int ip4_frags_ns_ctl_register(struct net *net)
814 815 816
{
	return 0;
}
817

818
static inline void ip4_frags_ns_ctl_unregister(struct net *net)
819 820
{
}
821 822 823 824

static inline void ip4_frags_ctl_register(void)
{
}
825 826
#endif

827
static int __net_init ipv4_frags_init_net(struct net *net)
828
{
829 830 831 832 833 834 835 836
	/*
	 * 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;
837 838 839 840 841 842 843
	/*
	 * 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;

844 845
	inet_frags_init_net(&net->ipv4.frags);

846
	return ip4_frags_ns_ctl_register(net);
847 848
}

849
static void __net_exit ipv4_frags_exit_net(struct net *net)
850
{
851
	ip4_frags_ns_ctl_unregister(net);
852 853 854 855 856 857 858 859
	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,
};

860
void __init ipfrag_init(void)
L
Linus Torvalds 已提交
861
{
862
	ip4_frags_ctl_register();
863
	register_pernet_subsys(&ip4_frags_ops);
864
	ip4_frags.hashfn = ip4_hashfn;
865
	ip4_frags.constructor = ip4_frag_init;
866 867 868
	ip4_frags.destructor = ip4_frag_free;
	ip4_frags.skb_free = NULL;
	ip4_frags.qsize = sizeof(struct ipq);
869
	ip4_frags.match = ip4_frag_match;
870
	ip4_frags.frag_expire = ip_expire;
871
	ip4_frags.secret_interval = 10 * 60 * HZ;
872
	inet_frags_init(&ip4_frags);
L
Linus Torvalds 已提交
873
}