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