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 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 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 51 static 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 59 static 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 70 static 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 83 static 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); 97 out: 98 spin_unlock(&fq->q.lock); 99 inet_frag_put(&fq->q, &lowpan_frags); 100 } 101 102 static inline struct lowpan_frag_queue * 103 fq_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 129 static 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 180 found: 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; 213 err: 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 */ 226 static 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; 312 out_oom: 313 net_dbg_ratelimited("lowpan_frag_reasm: no memory for reassembly\n"); 314 return -1; 315 } 316 317 static 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 335 static 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 349 static 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 364 rxh_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 372 static 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 406 int 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 444 err: 445 kfree_skb(skb); 446 return -1; 447 } 448 449 #ifdef CONFIG_SYSCTL 450 static int zero; 451 452 static 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 */ 481 static int lowpan_frags_secret_interval_unused; 482 static 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 493 static 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 526 err_reg: 527 if (!net_eq(net, &init_net)) 528 kfree(table); 529 err_alloc: 530 return -ENOMEM; 531 } 532 533 static 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 545 static struct ctl_table_header *lowpan_ctl_header; 546 547 static 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 555 static void lowpan_frags_sysctl_unregister(void) 556 { 557 unregister_net_sysctl_table(lowpan_ctl_header); 558 } 559 #else 560 static inline int lowpan_frags_ns_sysctl_register(struct net *net) 561 { 562 return 0; 563 } 564 565 static inline void lowpan_frags_ns_sysctl_unregister(struct net *net) 566 { 567 } 568 569 static inline int __init lowpan_frags_sysctl_register(void) 570 { 571 return 0; 572 } 573 574 static inline void lowpan_frags_sysctl_unregister(void) 575 { 576 } 577 #endif 578 579 static 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 598 static 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 607 static struct pernet_operations lowpan_frags_ops = { 608 .init = lowpan_frags_init_net, 609 .exit = lowpan_frags_exit_net, 610 }; 611 612 int __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.qsize = sizeof(struct frag_queue); 628 lowpan_frags.match = lowpan_frag_match; 629 lowpan_frags.frag_expire = lowpan_frag_expire; 630 lowpan_frags.frags_cache_name = lowpan_frags_cache_name; 631 ret = inet_frags_init(&lowpan_frags); 632 if (ret) 633 goto err_pernet; 634 635 return ret; 636 err_pernet: 637 lowpan_frags_sysctl_unregister(); 638 return ret; 639 } 640 641 void lowpan_net_frag_exit(void) 642 { 643 inet_frags_fini(&lowpan_frags); 644 lowpan_frags_sysctl_unregister(); 645 unregister_pernet_subsys(&lowpan_frags_ops); 646 } 647