1/*	6LoWPAN fragment reassembly
2 *
3 *
4 *	Authors:
5 *	Alexander Aring		<aar@pengutronix.de>
6 *
7 *	Based on: net/ipv6/reassembly.c
8 *
9 *	This program is free software; you can redistribute it and/or
10 *	modify it under the terms of the GNU General Public License
11 *	as published by the Free Software Foundation; either version
12 *	2 of the License, or (at your option) any later version.
13 */
14
15#define pr_fmt(fmt) "6LoWPAN: " fmt
16
17#include <linux/net.h>
18#include <linux/list.h>
19#include <linux/netdevice.h>
20#include <linux/random.h>
21#include <linux/jhash.h>
22#include <linux/skbuff.h>
23#include <linux/slab.h>
24#include <linux/export.h>
25
26#include <net/ieee802154_netdev.h>
27#include <net/6lowpan.h>
28#include <net/ipv6.h>
29#include <net/inet_frag.h>
30
31#include "6lowpan_i.h"
32
33static const char lowpan_frags_cache_name[] = "lowpan-frags";
34
35static struct inet_frags lowpan_frags;
36
37static int lowpan_frag_reasm(struct lowpan_frag_queue *fq,
38			     struct sk_buff *prev, struct net_device *ldev);
39
40static unsigned int lowpan_hash_frag(u16 tag, u16 d_size,
41				     const struct ieee802154_addr *saddr,
42				     const struct ieee802154_addr *daddr)
43{
44	net_get_random_once(&lowpan_frags.rnd, sizeof(lowpan_frags.rnd));
45	return jhash_3words(ieee802154_addr_hash(saddr),
46			    ieee802154_addr_hash(daddr),
47			    (__force u32)(tag + (d_size << 16)),
48			    lowpan_frags.rnd);
49}
50
51static unsigned int lowpan_hashfn(const struct inet_frag_queue *q)
52{
53	const struct lowpan_frag_queue *fq;
54
55	fq = container_of(q, struct lowpan_frag_queue, q);
56	return lowpan_hash_frag(fq->tag, fq->d_size, &fq->saddr, &fq->daddr);
57}
58
59static bool lowpan_frag_match(const struct inet_frag_queue *q, const void *a)
60{
61	const struct lowpan_frag_queue *fq;
62	const struct lowpan_create_arg *arg = a;
63
64	fq = container_of(q, struct lowpan_frag_queue, q);
65	return	fq->tag == arg->tag && fq->d_size == arg->d_size &&
66		ieee802154_addr_equal(&fq->saddr, arg->src) &&
67		ieee802154_addr_equal(&fq->daddr, arg->dst);
68}
69
70static void lowpan_frag_init(struct inet_frag_queue *q, const void *a)
71{
72	const struct lowpan_create_arg *arg = a;
73	struct lowpan_frag_queue *fq;
74
75	fq = container_of(q, struct lowpan_frag_queue, q);
76
77	fq->tag = arg->tag;
78	fq->d_size = arg->d_size;
79	fq->saddr = *arg->src;
80	fq->daddr = *arg->dst;
81}
82
83static void lowpan_frag_expire(unsigned long data)
84{
85	struct frag_queue *fq;
86	struct net *net;
87
88	fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
89	net = container_of(fq->q.net, struct net, ieee802154_lowpan.frags);
90
91	spin_lock(&fq->q.lock);
92
93	if (fq->q.flags & INET_FRAG_COMPLETE)
94		goto out;
95
96	inet_frag_kill(&fq->q, &lowpan_frags);
97out:
98	spin_unlock(&fq->q.lock);
99	inet_frag_put(&fq->q, &lowpan_frags);
100}
101
102static inline struct lowpan_frag_queue *
103fq_find(struct net *net, const struct lowpan_802154_cb *cb,
104	const struct ieee802154_addr *src,
105	const struct ieee802154_addr *dst)
106{
107	struct inet_frag_queue *q;
108	struct lowpan_create_arg arg;
109	unsigned int hash;
110	struct netns_ieee802154_lowpan *ieee802154_lowpan =
111		net_ieee802154_lowpan(net);
112
113	arg.tag = cb->d_tag;
114	arg.d_size = cb->d_size;
115	arg.src = src;
116	arg.dst = dst;
117
118	hash = lowpan_hash_frag(cb->d_tag, cb->d_size, src, dst);
119
120	q = inet_frag_find(&ieee802154_lowpan->frags,
121			   &lowpan_frags, &arg, hash);
122	if (IS_ERR_OR_NULL(q)) {
123		inet_frag_maybe_warn_overflow(q, pr_fmt());
124		return NULL;
125	}
126	return container_of(q, struct lowpan_frag_queue, q);
127}
128
129static int lowpan_frag_queue(struct lowpan_frag_queue *fq,
130			     struct sk_buff *skb, u8 frag_type)
131{
132	struct sk_buff *prev, *next;
133	struct net_device *ldev;
134	int end, offset;
135
136	if (fq->q.flags & INET_FRAG_COMPLETE)
137		goto err;
138
139	offset = lowpan_802154_cb(skb)->d_offset << 3;
140	end = lowpan_802154_cb(skb)->d_size;
141
142	/* Is this the final fragment? */
143	if (offset + skb->len == end) {
144		/* If we already have some bits beyond end
145		 * or have different end, the segment is corrupted.
146		 */
147		if (end < fq->q.len ||
148		    ((fq->q.flags & INET_FRAG_LAST_IN) && end != fq->q.len))
149			goto err;
150		fq->q.flags |= INET_FRAG_LAST_IN;
151		fq->q.len = end;
152	} else {
153		if (end > fq->q.len) {
154			/* Some bits beyond end -> corruption. */
155			if (fq->q.flags & INET_FRAG_LAST_IN)
156				goto err;
157			fq->q.len = end;
158		}
159	}
160
161	/* Find out which fragments are in front and at the back of us
162	 * in the chain of fragments so far.  We must know where to put
163	 * this fragment, right?
164	 */
165	prev = fq->q.fragments_tail;
166	if (!prev ||
167	    lowpan_802154_cb(prev)->d_offset <
168	    lowpan_802154_cb(skb)->d_offset) {
169		next = NULL;
170		goto found;
171	}
172	prev = NULL;
173	for (next = fq->q.fragments; next != NULL; next = next->next) {
174		if (lowpan_802154_cb(next)->d_offset >=
175		    lowpan_802154_cb(skb)->d_offset)
176			break;	/* bingo! */
177		prev = next;
178	}
179
180found:
181	/* Insert this fragment in the chain of fragments. */
182	skb->next = next;
183	if (!next)
184		fq->q.fragments_tail = skb;
185	if (prev)
186		prev->next = skb;
187	else
188		fq->q.fragments = skb;
189
190	ldev = skb->dev;
191	if (ldev)
192		skb->dev = NULL;
193
194	fq->q.stamp = skb->tstamp;
195	if (frag_type == LOWPAN_DISPATCH_FRAG1)
196		fq->q.flags |= INET_FRAG_FIRST_IN;
197
198	fq->q.meat += skb->len;
199	add_frag_mem_limit(fq->q.net, skb->truesize);
200
201	if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
202	    fq->q.meat == fq->q.len) {
203		int res;
204		unsigned long orefdst = skb->_skb_refdst;
205
206		skb->_skb_refdst = 0UL;
207		res = lowpan_frag_reasm(fq, prev, ldev);
208		skb->_skb_refdst = orefdst;
209		return res;
210	}
211
212	return -1;
213err:
214	kfree_skb(skb);
215	return -1;
216}
217
218/*	Check if this packet is complete.
219 *	Returns NULL on failure by any reason, and pointer
220 *	to current nexthdr field in reassembled frame.
221 *
222 *	It is called with locked fq, and caller must check that
223 *	queue is eligible for reassembly i.e. it is not COMPLETE,
224 *	the last and the first frames arrived and all the bits are here.
225 */
226static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev,
227			     struct net_device *ldev)
228{
229	struct sk_buff *fp, *head = fq->q.fragments;
230	int sum_truesize;
231
232	inet_frag_kill(&fq->q, &lowpan_frags);
233
234	/* Make the one we just received the head. */
235	if (prev) {
236		head = prev->next;
237		fp = skb_clone(head, GFP_ATOMIC);
238
239		if (!fp)
240			goto out_oom;
241
242		fp->next = head->next;
243		if (!fp->next)
244			fq->q.fragments_tail = fp;
245		prev->next = fp;
246
247		skb_morph(head, fq->q.fragments);
248		head->next = fq->q.fragments->next;
249
250		consume_skb(fq->q.fragments);
251		fq->q.fragments = head;
252	}
253
254	/* Head of list must not be cloned. */
255	if (skb_unclone(head, GFP_ATOMIC))
256		goto out_oom;
257
258	/* If the first fragment is fragmented itself, we split
259	 * it to two chunks: the first with data and paged part
260	 * and the second, holding only fragments.
261	 */
262	if (skb_has_frag_list(head)) {
263		struct sk_buff *clone;
264		int i, plen = 0;
265
266		clone = alloc_skb(0, GFP_ATOMIC);
267		if (!clone)
268			goto out_oom;
269		clone->next = head->next;
270		head->next = clone;
271		skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
272		skb_frag_list_init(head);
273		for (i = 0; i < skb_shinfo(head)->nr_frags; i++)
274			plen += skb_frag_size(&skb_shinfo(head)->frags[i]);
275		clone->len = head->data_len - plen;
276		clone->data_len = clone->len;
277		head->data_len -= clone->len;
278		head->len -= clone->len;
279		add_frag_mem_limit(fq->q.net, clone->truesize);
280	}
281
282	WARN_ON(head == NULL);
283
284	sum_truesize = head->truesize;
285	for (fp = head->next; fp;) {
286		bool headstolen;
287		int delta;
288		struct sk_buff *next = fp->next;
289
290		sum_truesize += fp->truesize;
291		if (skb_try_coalesce(head, fp, &headstolen, &delta)) {
292			kfree_skb_partial(fp, headstolen);
293		} else {
294			if (!skb_shinfo(head)->frag_list)
295				skb_shinfo(head)->frag_list = fp;
296			head->data_len += fp->len;
297			head->len += fp->len;
298			head->truesize += fp->truesize;
299		}
300		fp = next;
301	}
302	sub_frag_mem_limit(fq->q.net, sum_truesize);
303
304	head->next = NULL;
305	head->dev = ldev;
306	head->tstamp = fq->q.stamp;
307
308	fq->q.fragments = NULL;
309	fq->q.fragments_tail = NULL;
310
311	return 1;
312out_oom:
313	net_dbg_ratelimited("lowpan_frag_reasm: no memory for reassembly\n");
314	return -1;
315}
316
317static int lowpan_frag_rx_handlers_result(struct sk_buff *skb,
318					  lowpan_rx_result res)
319{
320	switch (res) {
321	case RX_QUEUED:
322		return NET_RX_SUCCESS;
323	case RX_CONTINUE:
324		/* nobody cared about this packet */
325		net_warn_ratelimited("%s: received unknown dispatch\n",
326				     __func__);
327
328		/* fall-through */
329	default:
330		/* all others failure */
331		return NET_RX_DROP;
332	}
333}
334
335static lowpan_rx_result lowpan_frag_rx_h_iphc(struct sk_buff *skb)
336{
337	int ret;
338
339	if (!lowpan_is_iphc(*skb_network_header(skb)))
340		return RX_CONTINUE;
341
342	ret = lowpan_iphc_decompress(skb);
343	if (ret < 0)
344		return RX_DROP;
345
346	return RX_QUEUED;
347}
348
349static int lowpan_invoke_frag_rx_handlers(struct sk_buff *skb)
350{
351	lowpan_rx_result res;
352
353#define CALL_RXH(rxh)			\
354	do {				\
355		res = rxh(skb);	\
356		if (res != RX_CONTINUE)	\
357			goto rxh_next;	\
358	} while (0)
359
360	/* likely at first */
361	CALL_RXH(lowpan_frag_rx_h_iphc);
362	CALL_RXH(lowpan_rx_h_ipv6);
363
364rxh_next:
365	return lowpan_frag_rx_handlers_result(skb, res);
366#undef CALL_RXH
367}
368
369#define LOWPAN_FRAG_DGRAM_SIZE_HIGH_MASK	0x07
370#define LOWPAN_FRAG_DGRAM_SIZE_HIGH_SHIFT	8
371
372static int lowpan_get_cb(struct sk_buff *skb, u8 frag_type,
373			 struct lowpan_802154_cb *cb)
374{
375	bool fail;
376	u8 high = 0, low = 0;
377	__be16 d_tag = 0;
378
379	fail = lowpan_fetch_skb(skb, &high, 1);
380	fail |= lowpan_fetch_skb(skb, &low, 1);
381	/* remove the dispatch value and use first three bits as high value
382	 * for the datagram size
383	 */
384	cb->d_size = (high & LOWPAN_FRAG_DGRAM_SIZE_HIGH_MASK) <<
385		LOWPAN_FRAG_DGRAM_SIZE_HIGH_SHIFT | low;
386	fail |= lowpan_fetch_skb(skb, &d_tag, 2);
387	cb->d_tag = ntohs(d_tag);
388
389	if (frag_type == LOWPAN_DISPATCH_FRAGN) {
390		fail |= lowpan_fetch_skb(skb, &cb->d_offset, 1);
391	} else {
392		skb_reset_network_header(skb);
393		cb->d_offset = 0;
394		/* check if datagram_size has ipv6hdr on FRAG1 */
395		fail |= cb->d_size < sizeof(struct ipv6hdr);
396		/* check if we can dereference the dispatch value */
397		fail |= !skb->len;
398	}
399
400	if (unlikely(fail))
401		return -EIO;
402
403	return 0;
404}
405
406int lowpan_frag_rcv(struct sk_buff *skb, u8 frag_type)
407{
408	struct lowpan_frag_queue *fq;
409	struct net *net = dev_net(skb->dev);
410	struct lowpan_802154_cb *cb = lowpan_802154_cb(skb);
411	struct ieee802154_hdr hdr;
412	int err;
413
414	if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
415		goto err;
416
417	err = lowpan_get_cb(skb, frag_type, cb);
418	if (err < 0)
419		goto err;
420
421	if (frag_type == LOWPAN_DISPATCH_FRAG1) {
422		err = lowpan_invoke_frag_rx_handlers(skb);
423		if (err == NET_RX_DROP)
424			goto err;
425	}
426
427	if (cb->d_size > IPV6_MIN_MTU) {
428		net_warn_ratelimited("lowpan_frag_rcv: datagram size exceeds MTU\n");
429		goto err;
430	}
431
432	fq = fq_find(net, cb, &hdr.source, &hdr.dest);
433	if (fq != NULL) {
434		int ret;
435
436		spin_lock(&fq->q.lock);
437		ret = lowpan_frag_queue(fq, skb, frag_type);
438		spin_unlock(&fq->q.lock);
439
440		inet_frag_put(&fq->q, &lowpan_frags);
441		return ret;
442	}
443
444err:
445	kfree_skb(skb);
446	return -1;
447}
448
449#ifdef CONFIG_SYSCTL
450static int zero;
451
452static struct ctl_table lowpan_frags_ns_ctl_table[] = {
453	{
454		.procname	= "6lowpanfrag_high_thresh",
455		.data		= &init_net.ieee802154_lowpan.frags.high_thresh,
456		.maxlen		= sizeof(int),
457		.mode		= 0644,
458		.proc_handler	= proc_dointvec_minmax,
459		.extra1		= &init_net.ieee802154_lowpan.frags.low_thresh
460	},
461	{
462		.procname	= "6lowpanfrag_low_thresh",
463		.data		= &init_net.ieee802154_lowpan.frags.low_thresh,
464		.maxlen		= sizeof(int),
465		.mode		= 0644,
466		.proc_handler	= proc_dointvec_minmax,
467		.extra1		= &zero,
468		.extra2		= &init_net.ieee802154_lowpan.frags.high_thresh
469	},
470	{
471		.procname	= "6lowpanfrag_time",
472		.data		= &init_net.ieee802154_lowpan.frags.timeout,
473		.maxlen		= sizeof(int),
474		.mode		= 0644,
475		.proc_handler	= proc_dointvec_jiffies,
476	},
477	{ }
478};
479
480/* secret interval has been deprecated */
481static int lowpan_frags_secret_interval_unused;
482static struct ctl_table lowpan_frags_ctl_table[] = {
483	{
484		.procname	= "6lowpanfrag_secret_interval",
485		.data		= &lowpan_frags_secret_interval_unused,
486		.maxlen		= sizeof(int),
487		.mode		= 0644,
488		.proc_handler	= proc_dointvec_jiffies,
489	},
490	{ }
491};
492
493static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
494{
495	struct ctl_table *table;
496	struct ctl_table_header *hdr;
497	struct netns_ieee802154_lowpan *ieee802154_lowpan =
498		net_ieee802154_lowpan(net);
499
500	table = lowpan_frags_ns_ctl_table;
501	if (!net_eq(net, &init_net)) {
502		table = kmemdup(table, sizeof(lowpan_frags_ns_ctl_table),
503				GFP_KERNEL);
504		if (table == NULL)
505			goto err_alloc;
506
507		table[0].data = &ieee802154_lowpan->frags.high_thresh;
508		table[0].extra1 = &ieee802154_lowpan->frags.low_thresh;
509		table[0].extra2 = &init_net.ieee802154_lowpan.frags.high_thresh;
510		table[1].data = &ieee802154_lowpan->frags.low_thresh;
511		table[1].extra2 = &ieee802154_lowpan->frags.high_thresh;
512		table[2].data = &ieee802154_lowpan->frags.timeout;
513
514		/* Don't export sysctls to unprivileged users */
515		if (net->user_ns != &init_user_ns)
516			table[0].procname = NULL;
517	}
518
519	hdr = register_net_sysctl(net, "net/ieee802154/6lowpan", table);
520	if (hdr == NULL)
521		goto err_reg;
522
523	ieee802154_lowpan->sysctl.frags_hdr = hdr;
524	return 0;
525
526err_reg:
527	if (!net_eq(net, &init_net))
528		kfree(table);
529err_alloc:
530	return -ENOMEM;
531}
532
533static void __net_exit lowpan_frags_ns_sysctl_unregister(struct net *net)
534{
535	struct ctl_table *table;
536	struct netns_ieee802154_lowpan *ieee802154_lowpan =
537		net_ieee802154_lowpan(net);
538
539	table = ieee802154_lowpan->sysctl.frags_hdr->ctl_table_arg;
540	unregister_net_sysctl_table(ieee802154_lowpan->sysctl.frags_hdr);
541	if (!net_eq(net, &init_net))
542		kfree(table);
543}
544
545static struct ctl_table_header *lowpan_ctl_header;
546
547static int __init lowpan_frags_sysctl_register(void)
548{
549	lowpan_ctl_header = register_net_sysctl(&init_net,
550						"net/ieee802154/6lowpan",
551						lowpan_frags_ctl_table);
552	return lowpan_ctl_header == NULL ? -ENOMEM : 0;
553}
554
555static void lowpan_frags_sysctl_unregister(void)
556{
557	unregister_net_sysctl_table(lowpan_ctl_header);
558}
559#else
560static inline int lowpan_frags_ns_sysctl_register(struct net *net)
561{
562	return 0;
563}
564
565static inline void lowpan_frags_ns_sysctl_unregister(struct net *net)
566{
567}
568
569static inline int __init lowpan_frags_sysctl_register(void)
570{
571	return 0;
572}
573
574static inline void lowpan_frags_sysctl_unregister(void)
575{
576}
577#endif
578
579static int __net_init lowpan_frags_init_net(struct net *net)
580{
581	struct netns_ieee802154_lowpan *ieee802154_lowpan =
582		net_ieee802154_lowpan(net);
583	int res;
584
585	ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
586	ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
587	ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
588
589	res = inet_frags_init_net(&ieee802154_lowpan->frags);
590	if (res)
591		return res;
592	res = lowpan_frags_ns_sysctl_register(net);
593	if (res)
594		inet_frags_uninit_net(&ieee802154_lowpan->frags);
595	return res;
596}
597
598static void __net_exit lowpan_frags_exit_net(struct net *net)
599{
600	struct netns_ieee802154_lowpan *ieee802154_lowpan =
601		net_ieee802154_lowpan(net);
602
603	lowpan_frags_ns_sysctl_unregister(net);
604	inet_frags_exit_net(&ieee802154_lowpan->frags, &lowpan_frags);
605}
606
607static struct pernet_operations lowpan_frags_ops = {
608	.init = lowpan_frags_init_net,
609	.exit = lowpan_frags_exit_net,
610};
611
612int __init lowpan_net_frag_init(void)
613{
614	int ret;
615
616	ret = lowpan_frags_sysctl_register();
617	if (ret)
618		return ret;
619
620	ret = register_pernet_subsys(&lowpan_frags_ops);
621	if (ret)
622		goto err_pernet;
623
624	lowpan_frags.hashfn = lowpan_hashfn;
625	lowpan_frags.constructor = lowpan_frag_init;
626	lowpan_frags.destructor = NULL;
627	lowpan_frags.skb_free = NULL;
628	lowpan_frags.qsize = sizeof(struct frag_queue);
629	lowpan_frags.match = lowpan_frag_match;
630	lowpan_frags.frag_expire = lowpan_frag_expire;
631	lowpan_frags.frags_cache_name = lowpan_frags_cache_name;
632	ret = inet_frags_init(&lowpan_frags);
633	if (ret)
634		goto err_pernet;
635
636	return ret;
637err_pernet:
638	lowpan_frags_sysctl_unregister();
639	return ret;
640}
641
642void lowpan_net_frag_exit(void)
643{
644	inet_frags_fini(&lowpan_frags);
645	lowpan_frags_sysctl_unregister();
646	unregister_pernet_subsys(&lowpan_frags_ops);
647}
648