1 /* 2 * Copyright 2011, Siemens AG 3 * written by Alexander Smirnov <alex.bluesman.smirnov@gmail.com> 4 */ 5 6 /* Based on patches from Jon Smirl <jonsmirl@gmail.com> 7 * Copyright (c) 2011 Jon Smirl <jonsmirl@gmail.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 11 * as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 */ 19 20 /* Jon's code is based on 6lowpan implementation for Contiki which is: 21 * Copyright (c) 2008, Swedish Institute of Computer Science. 22 * All rights reserved. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 3. Neither the name of the Institute nor the names of its contributors 33 * may be used to endorse or promote products derived from this software 34 * without specific prior written permission. 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 39 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 */ 48 49 #include <linux/bitops.h> 50 #include <linux/if_arp.h> 51 #include <linux/netdevice.h> 52 53 #include <net/6lowpan.h> 54 #include <net/ipv6.h> 55 56 #include "6lowpan_i.h" 57 #include "nhc.h" 58 59 /* Values of fields within the IPHC encoding first byte */ 60 #define LOWPAN_IPHC_TF_MASK 0x18 61 #define LOWPAN_IPHC_TF_00 0x00 62 #define LOWPAN_IPHC_TF_01 0x08 63 #define LOWPAN_IPHC_TF_10 0x10 64 #define LOWPAN_IPHC_TF_11 0x18 65 66 #define LOWPAN_IPHC_NH 0x04 67 68 #define LOWPAN_IPHC_HLIM_MASK 0x03 69 #define LOWPAN_IPHC_HLIM_00 0x00 70 #define LOWPAN_IPHC_HLIM_01 0x01 71 #define LOWPAN_IPHC_HLIM_10 0x02 72 #define LOWPAN_IPHC_HLIM_11 0x03 73 74 /* Values of fields within the IPHC encoding second byte */ 75 #define LOWPAN_IPHC_CID 0x80 76 77 #define LOWPAN_IPHC_SAC 0x40 78 79 #define LOWPAN_IPHC_SAM_MASK 0x30 80 #define LOWPAN_IPHC_SAM_00 0x00 81 #define LOWPAN_IPHC_SAM_01 0x10 82 #define LOWPAN_IPHC_SAM_10 0x20 83 #define LOWPAN_IPHC_SAM_11 0x30 84 85 #define LOWPAN_IPHC_M 0x08 86 87 #define LOWPAN_IPHC_DAC 0x04 88 89 #define LOWPAN_IPHC_DAM_MASK 0x03 90 #define LOWPAN_IPHC_DAM_00 0x00 91 #define LOWPAN_IPHC_DAM_01 0x01 92 #define LOWPAN_IPHC_DAM_10 0x02 93 #define LOWPAN_IPHC_DAM_11 0x03 94 95 /* ipv6 address based on mac 96 * second bit-flip (Universe/Local) is done according RFC2464 97 */ 98 #define is_addr_mac_addr_based(a, m) \ 99 ((((a)->s6_addr[8]) == (((m)[0]) ^ 0x02)) && \ 100 (((a)->s6_addr[9]) == (m)[1]) && \ 101 (((a)->s6_addr[10]) == (m)[2]) && \ 102 (((a)->s6_addr[11]) == (m)[3]) && \ 103 (((a)->s6_addr[12]) == (m)[4]) && \ 104 (((a)->s6_addr[13]) == (m)[5]) && \ 105 (((a)->s6_addr[14]) == (m)[6]) && \ 106 (((a)->s6_addr[15]) == (m)[7])) 107 108 /* check whether we can compress the IID to 16 bits, 109 * it's possible for unicast addresses with first 49 bits are zero only. 110 */ 111 #define lowpan_is_iid_16_bit_compressable(a) \ 112 ((((a)->s6_addr16[4]) == 0) && \ 113 (((a)->s6_addr[10]) == 0) && \ 114 (((a)->s6_addr[11]) == 0xff) && \ 115 (((a)->s6_addr[12]) == 0xfe) && \ 116 (((a)->s6_addr[13]) == 0)) 117 118 /* check whether the 112-bit gid of the multicast address is mappable to: */ 119 120 /* 48 bits, FFXX::00XX:XXXX:XXXX */ 121 #define lowpan_is_mcast_addr_compressable48(a) \ 122 ((((a)->s6_addr16[1]) == 0) && \ 123 (((a)->s6_addr16[2]) == 0) && \ 124 (((a)->s6_addr16[3]) == 0) && \ 125 (((a)->s6_addr16[4]) == 0) && \ 126 (((a)->s6_addr[10]) == 0)) 127 128 /* 32 bits, FFXX::00XX:XXXX */ 129 #define lowpan_is_mcast_addr_compressable32(a) \ 130 ((((a)->s6_addr16[1]) == 0) && \ 131 (((a)->s6_addr16[2]) == 0) && \ 132 (((a)->s6_addr16[3]) == 0) && \ 133 (((a)->s6_addr16[4]) == 0) && \ 134 (((a)->s6_addr16[5]) == 0) && \ 135 (((a)->s6_addr[12]) == 0)) 136 137 /* 8 bits, FF02::00XX */ 138 #define lowpan_is_mcast_addr_compressable8(a) \ 139 ((((a)->s6_addr[1]) == 2) && \ 140 (((a)->s6_addr16[1]) == 0) && \ 141 (((a)->s6_addr16[2]) == 0) && \ 142 (((a)->s6_addr16[3]) == 0) && \ 143 (((a)->s6_addr16[4]) == 0) && \ 144 (((a)->s6_addr16[5]) == 0) && \ 145 (((a)->s6_addr16[6]) == 0) && \ 146 (((a)->s6_addr[14]) == 0)) 147 148 #define lowpan_is_linklocal_zero_padded(a) \ 149 (!(hdr->saddr.s6_addr[1] & 0x3f) && \ 150 !hdr->saddr.s6_addr16[1] && \ 151 !hdr->saddr.s6_addr32[1]) 152 153 #define LOWPAN_IPHC_CID_DCI(cid) (cid & 0x0f) 154 #define LOWPAN_IPHC_CID_SCI(cid) ((cid & 0xf0) >> 4) 155 156 static inline void 157 lowpan_iphc_uncompress_802154_lladdr(struct in6_addr *ipaddr, 158 const void *lladdr) 159 { 160 const struct ieee802154_addr *addr = lladdr; 161 u8 eui64[EUI64_ADDR_LEN]; 162 163 switch (addr->mode) { 164 case IEEE802154_ADDR_LONG: 165 ieee802154_le64_to_be64(eui64, &addr->extended_addr); 166 lowpan_iphc_uncompress_eui64_lladdr(ipaddr, eui64); 167 break; 168 case IEEE802154_ADDR_SHORT: 169 /* fe:80::ff:fe00:XXXX 170 * \__/ 171 * short_addr 172 * 173 * Universe/Local bit is zero. 174 */ 175 ipaddr->s6_addr[0] = 0xFE; 176 ipaddr->s6_addr[1] = 0x80; 177 ipaddr->s6_addr[11] = 0xFF; 178 ipaddr->s6_addr[12] = 0xFE; 179 ieee802154_le16_to_be16(&ipaddr->s6_addr16[7], 180 &addr->short_addr); 181 break; 182 default: 183 /* should never handled and filtered by 802154 6lowpan */ 184 WARN_ON_ONCE(1); 185 break; 186 } 187 } 188 189 static struct lowpan_iphc_ctx * 190 lowpan_iphc_ctx_get_by_id(const struct net_device *dev, u8 id) 191 { 192 struct lowpan_iphc_ctx *ret = &lowpan_dev(dev)->ctx.table[id]; 193 194 if (!lowpan_iphc_ctx_is_active(ret)) 195 return NULL; 196 197 return ret; 198 } 199 200 static struct lowpan_iphc_ctx * 201 lowpan_iphc_ctx_get_by_addr(const struct net_device *dev, 202 const struct in6_addr *addr) 203 { 204 struct lowpan_iphc_ctx *table = lowpan_dev(dev)->ctx.table; 205 struct lowpan_iphc_ctx *ret = NULL; 206 struct in6_addr addr_pfx; 207 u8 addr_plen; 208 int i; 209 210 for (i = 0; i < LOWPAN_IPHC_CTX_TABLE_SIZE; i++) { 211 /* Check if context is valid. A context that is not valid 212 * MUST NOT be used for compression. 213 */ 214 if (!lowpan_iphc_ctx_is_active(&table[i]) || 215 !lowpan_iphc_ctx_is_compression(&table[i])) 216 continue; 217 218 ipv6_addr_prefix(&addr_pfx, addr, table[i].plen); 219 220 /* if prefix len < 64, the remaining bits until 64th bit is 221 * zero. Otherwise we use table[i]->plen. 222 */ 223 if (table[i].plen < 64) 224 addr_plen = 64; 225 else 226 addr_plen = table[i].plen; 227 228 if (ipv6_prefix_equal(&addr_pfx, &table[i].pfx, addr_plen)) { 229 /* remember first match */ 230 if (!ret) { 231 ret = &table[i]; 232 continue; 233 } 234 235 /* get the context with longest prefix len */ 236 if (table[i].plen > ret->plen) 237 ret = &table[i]; 238 } 239 } 240 241 return ret; 242 } 243 244 static struct lowpan_iphc_ctx * 245 lowpan_iphc_ctx_get_by_mcast_addr(const struct net_device *dev, 246 const struct in6_addr *addr) 247 { 248 struct lowpan_iphc_ctx *table = lowpan_dev(dev)->ctx.table; 249 struct lowpan_iphc_ctx *ret = NULL; 250 struct in6_addr addr_mcast, network_pfx = {}; 251 int i; 252 253 /* init mcast address with */ 254 memcpy(&addr_mcast, addr, sizeof(*addr)); 255 256 for (i = 0; i < LOWPAN_IPHC_CTX_TABLE_SIZE; i++) { 257 /* Check if context is valid. A context that is not valid 258 * MUST NOT be used for compression. 259 */ 260 if (!lowpan_iphc_ctx_is_active(&table[i]) || 261 !lowpan_iphc_ctx_is_compression(&table[i])) 262 continue; 263 264 /* setting plen */ 265 addr_mcast.s6_addr[3] = table[i].plen; 266 /* get network prefix to copy into multicast address */ 267 ipv6_addr_prefix(&network_pfx, &table[i].pfx, 268 table[i].plen); 269 /* setting network prefix */ 270 memcpy(&addr_mcast.s6_addr[4], &network_pfx, 8); 271 272 if (ipv6_addr_equal(addr, &addr_mcast)) { 273 ret = &table[i]; 274 break; 275 } 276 } 277 278 return ret; 279 } 280 281 static void lowpan_iphc_uncompress_lladdr(const struct net_device *dev, 282 struct in6_addr *ipaddr, 283 const void *lladdr) 284 { 285 switch (dev->addr_len) { 286 case ETH_ALEN: 287 lowpan_iphc_uncompress_eui48_lladdr(ipaddr, lladdr); 288 break; 289 case EUI64_ADDR_LEN: 290 lowpan_iphc_uncompress_eui64_lladdr(ipaddr, lladdr); 291 break; 292 default: 293 WARN_ON_ONCE(1); 294 break; 295 } 296 } 297 298 /* Uncompress address function for source and 299 * destination address(non-multicast). 300 * 301 * address_mode is the masked value for sam or dam value 302 */ 303 static int lowpan_iphc_uncompress_addr(struct sk_buff *skb, 304 const struct net_device *dev, 305 struct in6_addr *ipaddr, 306 u8 address_mode, const void *lladdr) 307 { 308 bool fail; 309 310 switch (address_mode) { 311 /* SAM and DAM are the same here */ 312 case LOWPAN_IPHC_DAM_00: 313 /* for global link addresses */ 314 fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); 315 break; 316 case LOWPAN_IPHC_SAM_01: 317 case LOWPAN_IPHC_DAM_01: 318 /* fe:80::XXXX:XXXX:XXXX:XXXX */ 319 ipaddr->s6_addr[0] = 0xFE; 320 ipaddr->s6_addr[1] = 0x80; 321 fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8); 322 break; 323 case LOWPAN_IPHC_SAM_10: 324 case LOWPAN_IPHC_DAM_10: 325 /* fe:80::ff:fe00:XXXX */ 326 ipaddr->s6_addr[0] = 0xFE; 327 ipaddr->s6_addr[1] = 0x80; 328 ipaddr->s6_addr[11] = 0xFF; 329 ipaddr->s6_addr[12] = 0xFE; 330 fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2); 331 break; 332 case LOWPAN_IPHC_SAM_11: 333 case LOWPAN_IPHC_DAM_11: 334 fail = false; 335 switch (lowpan_dev(dev)->lltype) { 336 case LOWPAN_LLTYPE_IEEE802154: 337 lowpan_iphc_uncompress_802154_lladdr(ipaddr, lladdr); 338 break; 339 default: 340 lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr); 341 break; 342 } 343 break; 344 default: 345 pr_debug("Invalid address mode value: 0x%x\n", address_mode); 346 return -EINVAL; 347 } 348 349 if (fail) { 350 pr_debug("Failed to fetch skb data\n"); 351 return -EIO; 352 } 353 354 raw_dump_inline(NULL, "Reconstructed ipv6 addr is", 355 ipaddr->s6_addr, 16); 356 357 return 0; 358 } 359 360 /* Uncompress address function for source context 361 * based address(non-multicast). 362 */ 363 static int lowpan_iphc_uncompress_ctx_addr(struct sk_buff *skb, 364 const struct net_device *dev, 365 const struct lowpan_iphc_ctx *ctx, 366 struct in6_addr *ipaddr, 367 u8 address_mode, const void *lladdr) 368 { 369 bool fail; 370 371 switch (address_mode) { 372 /* SAM and DAM are the same here */ 373 case LOWPAN_IPHC_DAM_00: 374 fail = false; 375 /* SAM_00 -> unspec address :: 376 * Do nothing, address is already :: 377 * 378 * DAM 00 -> reserved should never occur. 379 */ 380 break; 381 case LOWPAN_IPHC_SAM_01: 382 case LOWPAN_IPHC_DAM_01: 383 fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8); 384 ipv6_addr_prefix_copy(ipaddr, &ctx->pfx, ctx->plen); 385 break; 386 case LOWPAN_IPHC_SAM_10: 387 case LOWPAN_IPHC_DAM_10: 388 ipaddr->s6_addr[11] = 0xFF; 389 ipaddr->s6_addr[12] = 0xFE; 390 fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2); 391 ipv6_addr_prefix_copy(ipaddr, &ctx->pfx, ctx->plen); 392 break; 393 case LOWPAN_IPHC_SAM_11: 394 case LOWPAN_IPHC_DAM_11: 395 fail = false; 396 switch (lowpan_dev(dev)->lltype) { 397 case LOWPAN_LLTYPE_IEEE802154: 398 lowpan_iphc_uncompress_802154_lladdr(ipaddr, lladdr); 399 break; 400 default: 401 lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr); 402 break; 403 } 404 ipv6_addr_prefix_copy(ipaddr, &ctx->pfx, ctx->plen); 405 break; 406 default: 407 pr_debug("Invalid sam value: 0x%x\n", address_mode); 408 return -EINVAL; 409 } 410 411 if (fail) { 412 pr_debug("Failed to fetch skb data\n"); 413 return -EIO; 414 } 415 416 raw_dump_inline(NULL, 417 "Reconstructed context based ipv6 src addr is", 418 ipaddr->s6_addr, 16); 419 420 return 0; 421 } 422 423 /* Uncompress function for multicast destination address, 424 * when M bit is set. 425 */ 426 static int lowpan_uncompress_multicast_daddr(struct sk_buff *skb, 427 struct in6_addr *ipaddr, 428 u8 address_mode) 429 { 430 bool fail; 431 432 switch (address_mode) { 433 case LOWPAN_IPHC_DAM_00: 434 /* 00: 128 bits. The full address 435 * is carried in-line. 436 */ 437 fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); 438 break; 439 case LOWPAN_IPHC_DAM_01: 440 /* 01: 48 bits. The address takes 441 * the form ffXX::00XX:XXXX:XXXX. 442 */ 443 ipaddr->s6_addr[0] = 0xFF; 444 fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); 445 fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5); 446 break; 447 case LOWPAN_IPHC_DAM_10: 448 /* 10: 32 bits. The address takes 449 * the form ffXX::00XX:XXXX. 450 */ 451 ipaddr->s6_addr[0] = 0xFF; 452 fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); 453 fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3); 454 break; 455 case LOWPAN_IPHC_DAM_11: 456 /* 11: 8 bits. The address takes 457 * the form ff02::00XX. 458 */ 459 ipaddr->s6_addr[0] = 0xFF; 460 ipaddr->s6_addr[1] = 0x02; 461 fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1); 462 break; 463 default: 464 pr_debug("DAM value has a wrong value: 0x%x\n", address_mode); 465 return -EINVAL; 466 } 467 468 if (fail) { 469 pr_debug("Failed to fetch skb data\n"); 470 return -EIO; 471 } 472 473 raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is", 474 ipaddr->s6_addr, 16); 475 476 return 0; 477 } 478 479 static int lowpan_uncompress_multicast_ctx_daddr(struct sk_buff *skb, 480 struct lowpan_iphc_ctx *ctx, 481 struct in6_addr *ipaddr, 482 u8 address_mode) 483 { 484 struct in6_addr network_pfx = {}; 485 bool fail; 486 487 ipaddr->s6_addr[0] = 0xFF; 488 fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 2); 489 fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[12], 4); 490 if (fail) 491 return -EIO; 492 493 /* take prefix_len and network prefix from the context */ 494 ipaddr->s6_addr[3] = ctx->plen; 495 /* get network prefix to copy into multicast address */ 496 ipv6_addr_prefix(&network_pfx, &ctx->pfx, ctx->plen); 497 /* setting network prefix */ 498 memcpy(&ipaddr->s6_addr[4], &network_pfx, 8); 499 500 return 0; 501 } 502 503 /* get the ecn values from iphc tf format and set it to ipv6hdr */ 504 static inline void lowpan_iphc_tf_set_ecn(struct ipv6hdr *hdr, const u8 *tf) 505 { 506 /* get the two higher bits which is ecn */ 507 u8 ecn = tf[0] & 0xc0; 508 509 /* ECN takes 0x30 in hdr->flow_lbl[0] */ 510 hdr->flow_lbl[0] |= (ecn >> 2); 511 } 512 513 /* get the dscp values from iphc tf format and set it to ipv6hdr */ 514 static inline void lowpan_iphc_tf_set_dscp(struct ipv6hdr *hdr, const u8 *tf) 515 { 516 /* DSCP is at place after ECN */ 517 u8 dscp = tf[0] & 0x3f; 518 519 /* The four highest bits need to be set at hdr->priority */ 520 hdr->priority |= ((dscp & 0x3c) >> 2); 521 /* The two lower bits is part of hdr->flow_lbl[0] */ 522 hdr->flow_lbl[0] |= ((dscp & 0x03) << 6); 523 } 524 525 /* get the flow label values from iphc tf format and set it to ipv6hdr */ 526 static inline void lowpan_iphc_tf_set_lbl(struct ipv6hdr *hdr, const u8 *lbl) 527 { 528 /* flow label is always some array started with lower nibble of 529 * flow_lbl[0] and followed with two bytes afterwards. Inside inline 530 * data the flow_lbl position can be different, which will be handled 531 * by lbl pointer. E.g. case "01" vs "00" the traffic class is 8 bit 532 * shifted, the different lbl pointer will handle that. 533 * 534 * The flow label will started at lower nibble of flow_lbl[0], the 535 * higher nibbles are part of DSCP + ECN. 536 */ 537 hdr->flow_lbl[0] |= lbl[0] & 0x0f; 538 memcpy(&hdr->flow_lbl[1], &lbl[1], 2); 539 } 540 541 /* lowpan_iphc_tf_decompress - decompress the traffic class. 542 * This function will return zero on success, a value lower than zero if 543 * failed. 544 */ 545 static int lowpan_iphc_tf_decompress(struct sk_buff *skb, struct ipv6hdr *hdr, 546 u8 val) 547 { 548 u8 tf[4]; 549 550 /* Traffic Class and Flow Label */ 551 switch (val) { 552 case LOWPAN_IPHC_TF_00: 553 /* ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) */ 554 if (lowpan_fetch_skb(skb, tf, 4)) 555 return -EINVAL; 556 557 /* 1 2 3 558 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 559 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 560 * |ECN| DSCP | rsv | Flow Label | 561 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 562 */ 563 lowpan_iphc_tf_set_ecn(hdr, tf); 564 lowpan_iphc_tf_set_dscp(hdr, tf); 565 lowpan_iphc_tf_set_lbl(hdr, &tf[1]); 566 break; 567 case LOWPAN_IPHC_TF_01: 568 /* ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided. */ 569 if (lowpan_fetch_skb(skb, tf, 3)) 570 return -EINVAL; 571 572 /* 1 2 573 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 574 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 575 * |ECN|rsv| Flow Label | 576 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 577 */ 578 lowpan_iphc_tf_set_ecn(hdr, tf); 579 lowpan_iphc_tf_set_lbl(hdr, &tf[0]); 580 break; 581 case LOWPAN_IPHC_TF_10: 582 /* ECN + DSCP (1 byte), Flow Label is elided. */ 583 if (lowpan_fetch_skb(skb, tf, 1)) 584 return -EINVAL; 585 586 /* 0 1 2 3 4 5 6 7 587 * +-+-+-+-+-+-+-+-+ 588 * |ECN| DSCP | 589 * +-+-+-+-+-+-+-+-+ 590 */ 591 lowpan_iphc_tf_set_ecn(hdr, tf); 592 lowpan_iphc_tf_set_dscp(hdr, tf); 593 break; 594 case LOWPAN_IPHC_TF_11: 595 /* Traffic Class and Flow Label are elided */ 596 break; 597 default: 598 WARN_ON_ONCE(1); 599 return -EINVAL; 600 } 601 602 return 0; 603 } 604 605 /* TTL uncompression values */ 606 static const u8 lowpan_ttl_values[] = { 607 [LOWPAN_IPHC_HLIM_01] = 1, 608 [LOWPAN_IPHC_HLIM_10] = 64, 609 [LOWPAN_IPHC_HLIM_11] = 255, 610 }; 611 612 int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev, 613 const void *daddr, const void *saddr) 614 { 615 struct ipv6hdr hdr = {}; 616 struct lowpan_iphc_ctx *ci; 617 u8 iphc0, iphc1, cid = 0; 618 int err; 619 620 raw_dump_table(__func__, "raw skb data dump uncompressed", 621 skb->data, skb->len); 622 623 if (lowpan_fetch_skb(skb, &iphc0, sizeof(iphc0)) || 624 lowpan_fetch_skb(skb, &iphc1, sizeof(iphc1))) 625 return -EINVAL; 626 627 hdr.version = 6; 628 629 /* default CID = 0, another if the CID flag is set */ 630 if (iphc1 & LOWPAN_IPHC_CID) { 631 if (lowpan_fetch_skb(skb, &cid, sizeof(cid))) 632 return -EINVAL; 633 } 634 635 err = lowpan_iphc_tf_decompress(skb, &hdr, 636 iphc0 & LOWPAN_IPHC_TF_MASK); 637 if (err < 0) 638 return err; 639 640 /* Next Header */ 641 if (!(iphc0 & LOWPAN_IPHC_NH)) { 642 /* Next header is carried inline */ 643 if (lowpan_fetch_skb(skb, &hdr.nexthdr, sizeof(hdr.nexthdr))) 644 return -EINVAL; 645 646 pr_debug("NH flag is set, next header carried inline: %02x\n", 647 hdr.nexthdr); 648 } 649 650 /* Hop Limit */ 651 if ((iphc0 & LOWPAN_IPHC_HLIM_MASK) != LOWPAN_IPHC_HLIM_00) { 652 hdr.hop_limit = lowpan_ttl_values[iphc0 & LOWPAN_IPHC_HLIM_MASK]; 653 } else { 654 if (lowpan_fetch_skb(skb, &hdr.hop_limit, 655 sizeof(hdr.hop_limit))) 656 return -EINVAL; 657 } 658 659 if (iphc1 & LOWPAN_IPHC_SAC) { 660 spin_lock_bh(&lowpan_dev(dev)->ctx.lock); 661 ci = lowpan_iphc_ctx_get_by_id(dev, LOWPAN_IPHC_CID_SCI(cid)); 662 if (!ci) { 663 spin_unlock_bh(&lowpan_dev(dev)->ctx.lock); 664 return -EINVAL; 665 } 666 667 pr_debug("SAC bit is set. Handle context based source address.\n"); 668 err = lowpan_iphc_uncompress_ctx_addr(skb, dev, ci, &hdr.saddr, 669 iphc1 & LOWPAN_IPHC_SAM_MASK, 670 saddr); 671 spin_unlock_bh(&lowpan_dev(dev)->ctx.lock); 672 } else { 673 /* Source address uncompression */ 674 pr_debug("source address stateless compression\n"); 675 err = lowpan_iphc_uncompress_addr(skb, dev, &hdr.saddr, 676 iphc1 & LOWPAN_IPHC_SAM_MASK, 677 saddr); 678 } 679 680 /* Check on error of previous branch */ 681 if (err) 682 return -EINVAL; 683 684 switch (iphc1 & (LOWPAN_IPHC_M | LOWPAN_IPHC_DAC)) { 685 case LOWPAN_IPHC_M | LOWPAN_IPHC_DAC: 686 skb->pkt_type = PACKET_BROADCAST; 687 688 spin_lock_bh(&lowpan_dev(dev)->ctx.lock); 689 ci = lowpan_iphc_ctx_get_by_id(dev, LOWPAN_IPHC_CID_DCI(cid)); 690 if (!ci) { 691 spin_unlock_bh(&lowpan_dev(dev)->ctx.lock); 692 return -EINVAL; 693 } 694 695 /* multicast with context */ 696 pr_debug("dest: context-based mcast compression\n"); 697 err = lowpan_uncompress_multicast_ctx_daddr(skb, ci, 698 &hdr.daddr, 699 iphc1 & LOWPAN_IPHC_DAM_MASK); 700 spin_unlock_bh(&lowpan_dev(dev)->ctx.lock); 701 break; 702 case LOWPAN_IPHC_M: 703 skb->pkt_type = PACKET_BROADCAST; 704 705 /* multicast */ 706 err = lowpan_uncompress_multicast_daddr(skb, &hdr.daddr, 707 iphc1 & LOWPAN_IPHC_DAM_MASK); 708 break; 709 case LOWPAN_IPHC_DAC: 710 skb->pkt_type = PACKET_HOST; 711 712 spin_lock_bh(&lowpan_dev(dev)->ctx.lock); 713 ci = lowpan_iphc_ctx_get_by_id(dev, LOWPAN_IPHC_CID_DCI(cid)); 714 if (!ci) { 715 spin_unlock_bh(&lowpan_dev(dev)->ctx.lock); 716 return -EINVAL; 717 } 718 719 /* Destination address context based uncompression */ 720 pr_debug("DAC bit is set. Handle context based destination address.\n"); 721 err = lowpan_iphc_uncompress_ctx_addr(skb, dev, ci, &hdr.daddr, 722 iphc1 & LOWPAN_IPHC_DAM_MASK, 723 daddr); 724 spin_unlock_bh(&lowpan_dev(dev)->ctx.lock); 725 break; 726 default: 727 skb->pkt_type = PACKET_HOST; 728 729 err = lowpan_iphc_uncompress_addr(skb, dev, &hdr.daddr, 730 iphc1 & LOWPAN_IPHC_DAM_MASK, 731 daddr); 732 pr_debug("dest: stateless compression mode %d dest %pI6c\n", 733 iphc1 & LOWPAN_IPHC_DAM_MASK, &hdr.daddr); 734 break; 735 } 736 737 if (err) 738 return -EINVAL; 739 740 /* Next header data uncompression */ 741 if (iphc0 & LOWPAN_IPHC_NH) { 742 err = lowpan_nhc_do_uncompression(skb, dev, &hdr); 743 if (err < 0) 744 return err; 745 } else { 746 err = skb_cow(skb, sizeof(hdr)); 747 if (unlikely(err)) 748 return err; 749 } 750 751 switch (lowpan_dev(dev)->lltype) { 752 case LOWPAN_LLTYPE_IEEE802154: 753 if (lowpan_802154_cb(skb)->d_size) 754 hdr.payload_len = htons(lowpan_802154_cb(skb)->d_size - 755 sizeof(struct ipv6hdr)); 756 else 757 hdr.payload_len = htons(skb->len); 758 break; 759 default: 760 hdr.payload_len = htons(skb->len); 761 break; 762 } 763 764 pr_debug("skb headroom size = %d, data length = %d\n", 765 skb_headroom(skb), skb->len); 766 767 pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t" 768 "nexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n", 769 hdr.version, ntohs(hdr.payload_len), hdr.nexthdr, 770 hdr.hop_limit, &hdr.daddr); 771 772 skb_push(skb, sizeof(hdr)); 773 skb_reset_network_header(skb); 774 skb_copy_to_linear_data(skb, &hdr, sizeof(hdr)); 775 776 raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); 777 778 return 0; 779 } 780 EXPORT_SYMBOL_GPL(lowpan_header_decompress); 781 782 static const u8 lowpan_iphc_dam_to_sam_value[] = { 783 [LOWPAN_IPHC_DAM_00] = LOWPAN_IPHC_SAM_00, 784 [LOWPAN_IPHC_DAM_01] = LOWPAN_IPHC_SAM_01, 785 [LOWPAN_IPHC_DAM_10] = LOWPAN_IPHC_SAM_10, 786 [LOWPAN_IPHC_DAM_11] = LOWPAN_IPHC_SAM_11, 787 }; 788 789 static inline bool 790 lowpan_iphc_compress_ctx_802154_lladdr(const struct in6_addr *ipaddr, 791 const struct lowpan_iphc_ctx *ctx, 792 const void *lladdr) 793 { 794 const struct ieee802154_addr *addr = lladdr; 795 unsigned char extended_addr[EUI64_ADDR_LEN]; 796 bool lladdr_compress = false; 797 struct in6_addr tmp = {}; 798 799 switch (addr->mode) { 800 case IEEE802154_ADDR_LONG: 801 ieee802154_le64_to_be64(&extended_addr, &addr->extended_addr); 802 /* check for SAM/DAM = 11 */ 803 memcpy(&tmp.s6_addr[8], &extended_addr, EUI64_ADDR_LEN); 804 /* second bit-flip (Universe/Local) is done according RFC2464 */ 805 tmp.s6_addr[8] ^= 0x02; 806 /* context information are always used */ 807 ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen); 808 if (ipv6_addr_equal(&tmp, ipaddr)) 809 lladdr_compress = true; 810 break; 811 case IEEE802154_ADDR_SHORT: 812 tmp.s6_addr[11] = 0xFF; 813 tmp.s6_addr[12] = 0xFE; 814 ieee802154_le16_to_be16(&tmp.s6_addr16[7], 815 &addr->short_addr); 816 /* context information are always used */ 817 ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen); 818 if (ipv6_addr_equal(&tmp, ipaddr)) 819 lladdr_compress = true; 820 break; 821 default: 822 /* should never handled and filtered by 802154 6lowpan */ 823 WARN_ON_ONCE(1); 824 break; 825 } 826 827 return lladdr_compress; 828 } 829 830 static bool lowpan_iphc_addr_equal(const struct net_device *dev, 831 const struct lowpan_iphc_ctx *ctx, 832 const struct in6_addr *ipaddr, 833 const void *lladdr) 834 { 835 struct in6_addr tmp = {}; 836 837 lowpan_iphc_uncompress_lladdr(dev, &tmp, lladdr); 838 839 if (ctx) 840 ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen); 841 842 return ipv6_addr_equal(&tmp, ipaddr); 843 } 844 845 static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct net_device *dev, 846 const struct in6_addr *ipaddr, 847 const struct lowpan_iphc_ctx *ctx, 848 const unsigned char *lladdr, bool sam) 849 { 850 struct in6_addr tmp = {}; 851 u8 dam; 852 853 switch (lowpan_dev(dev)->lltype) { 854 case LOWPAN_LLTYPE_IEEE802154: 855 if (lowpan_iphc_compress_ctx_802154_lladdr(ipaddr, ctx, 856 lladdr)) { 857 dam = LOWPAN_IPHC_DAM_11; 858 goto out; 859 } 860 break; 861 default: 862 if (lowpan_iphc_addr_equal(dev, ctx, ipaddr, lladdr)) { 863 dam = LOWPAN_IPHC_DAM_11; 864 goto out; 865 } 866 break; 867 } 868 869 memset(&tmp, 0, sizeof(tmp)); 870 /* check for SAM/DAM = 10 */ 871 tmp.s6_addr[11] = 0xFF; 872 tmp.s6_addr[12] = 0xFE; 873 memcpy(&tmp.s6_addr[14], &ipaddr->s6_addr[14], 2); 874 /* context information are always used */ 875 ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen); 876 if (ipv6_addr_equal(&tmp, ipaddr)) { 877 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[14], 2); 878 dam = LOWPAN_IPHC_DAM_10; 879 goto out; 880 } 881 882 memset(&tmp, 0, sizeof(tmp)); 883 /* check for SAM/DAM = 01, should always match */ 884 memcpy(&tmp.s6_addr[8], &ipaddr->s6_addr[8], 8); 885 /* context information are always used */ 886 ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen); 887 if (ipv6_addr_equal(&tmp, ipaddr)) { 888 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[8], 8); 889 dam = LOWPAN_IPHC_DAM_01; 890 goto out; 891 } 892 893 WARN_ONCE(1, "context found but no address mode matched\n"); 894 return LOWPAN_IPHC_DAM_00; 895 out: 896 897 if (sam) 898 return lowpan_iphc_dam_to_sam_value[dam]; 899 else 900 return dam; 901 } 902 903 static inline bool 904 lowpan_iphc_compress_802154_lladdr(const struct in6_addr *ipaddr, 905 const void *lladdr) 906 { 907 const struct ieee802154_addr *addr = lladdr; 908 unsigned char extended_addr[EUI64_ADDR_LEN]; 909 bool lladdr_compress = false; 910 struct in6_addr tmp = {}; 911 912 switch (addr->mode) { 913 case IEEE802154_ADDR_LONG: 914 ieee802154_le64_to_be64(&extended_addr, &addr->extended_addr); 915 if (is_addr_mac_addr_based(ipaddr, extended_addr)) 916 lladdr_compress = true; 917 break; 918 case IEEE802154_ADDR_SHORT: 919 /* fe:80::ff:fe00:XXXX 920 * \__/ 921 * short_addr 922 * 923 * Universe/Local bit is zero. 924 */ 925 tmp.s6_addr[0] = 0xFE; 926 tmp.s6_addr[1] = 0x80; 927 tmp.s6_addr[11] = 0xFF; 928 tmp.s6_addr[12] = 0xFE; 929 ieee802154_le16_to_be16(&tmp.s6_addr16[7], 930 &addr->short_addr); 931 if (ipv6_addr_equal(&tmp, ipaddr)) 932 lladdr_compress = true; 933 break; 934 default: 935 /* should never handled and filtered by 802154 6lowpan */ 936 WARN_ON_ONCE(1); 937 break; 938 } 939 940 return lladdr_compress; 941 } 942 943 static u8 lowpan_compress_addr_64(u8 **hc_ptr, const struct net_device *dev, 944 const struct in6_addr *ipaddr, 945 const unsigned char *lladdr, bool sam) 946 { 947 u8 dam = LOWPAN_IPHC_DAM_01; 948 949 switch (lowpan_dev(dev)->lltype) { 950 case LOWPAN_LLTYPE_IEEE802154: 951 if (lowpan_iphc_compress_802154_lladdr(ipaddr, lladdr)) { 952 dam = LOWPAN_IPHC_DAM_11; /* 0-bits */ 953 pr_debug("address compression 0 bits\n"); 954 goto out; 955 } 956 break; 957 default: 958 if (lowpan_iphc_addr_equal(dev, NULL, ipaddr, lladdr)) { 959 dam = LOWPAN_IPHC_DAM_11; 960 pr_debug("address compression 0 bits\n"); 961 goto out; 962 } 963 964 break; 965 } 966 967 if (lowpan_is_iid_16_bit_compressable(ipaddr)) { 968 /* compress IID to 16 bits xxxx::XXXX */ 969 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr16[7], 2); 970 dam = LOWPAN_IPHC_DAM_10; /* 16-bits */ 971 raw_dump_inline(NULL, "Compressed ipv6 addr is (16 bits)", 972 *hc_ptr - 2, 2); 973 goto out; 974 } 975 976 /* do not compress IID => xxxx::IID */ 977 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr16[4], 8); 978 raw_dump_inline(NULL, "Compressed ipv6 addr is (64 bits)", 979 *hc_ptr - 8, 8); 980 981 out: 982 983 if (sam) 984 return lowpan_iphc_dam_to_sam_value[dam]; 985 else 986 return dam; 987 } 988 989 /* lowpan_iphc_get_tc - get the ECN + DCSP fields in hc format */ 990 static inline u8 lowpan_iphc_get_tc(const struct ipv6hdr *hdr) 991 { 992 u8 dscp, ecn; 993 994 /* hdr->priority contains the higher bits of dscp, lower are part of 995 * flow_lbl[0]. Note ECN, DCSP is swapped in ipv6 hdr. 996 */ 997 dscp = (hdr->priority << 2) | ((hdr->flow_lbl[0] & 0xc0) >> 6); 998 /* ECN is at the two lower bits from first nibble of flow_lbl[0] */ 999 ecn = (hdr->flow_lbl[0] & 0x30); 1000 /* for pretty debug output, also shift ecn to get the ecn value */ 1001 pr_debug("ecn 0x%02x dscp 0x%02x\n", ecn >> 4, dscp); 1002 /* ECN is at 0x30 now, shift it to have ECN + DCSP */ 1003 return (ecn << 2) | dscp; 1004 } 1005 1006 /* lowpan_iphc_is_flow_lbl_zero - check if flow label is zero */ 1007 static inline bool lowpan_iphc_is_flow_lbl_zero(const struct ipv6hdr *hdr) 1008 { 1009 return ((!(hdr->flow_lbl[0] & 0x0f)) && 1010 !hdr->flow_lbl[1] && !hdr->flow_lbl[2]); 1011 } 1012 1013 /* lowpan_iphc_tf_compress - compress the traffic class which is set by 1014 * ipv6hdr. Return the corresponding format identifier which is used. 1015 */ 1016 static u8 lowpan_iphc_tf_compress(u8 **hc_ptr, const struct ipv6hdr *hdr) 1017 { 1018 /* get ecn dscp data in a byteformat as: ECN(hi) + DSCP(lo) */ 1019 u8 tc = lowpan_iphc_get_tc(hdr), tf[4], val; 1020 1021 /* printout the traffic class in hc format */ 1022 pr_debug("tc 0x%02x\n", tc); 1023 1024 if (lowpan_iphc_is_flow_lbl_zero(hdr)) { 1025 if (!tc) { 1026 /* 11: Traffic Class and Flow Label are elided. */ 1027 val = LOWPAN_IPHC_TF_11; 1028 } else { 1029 /* 10: ECN + DSCP (1 byte), Flow Label is elided. 1030 * 1031 * 0 1 2 3 4 5 6 7 1032 * +-+-+-+-+-+-+-+-+ 1033 * |ECN| DSCP | 1034 * +-+-+-+-+-+-+-+-+ 1035 */ 1036 lowpan_push_hc_data(hc_ptr, &tc, sizeof(tc)); 1037 val = LOWPAN_IPHC_TF_10; 1038 } 1039 } else { 1040 /* check if dscp is zero, it's after the first two bit */ 1041 if (!(tc & 0x3f)) { 1042 /* 01: ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided 1043 * 1044 * 1 2 1045 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 1046 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1047 * |ECN|rsv| Flow Label | 1048 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1049 */ 1050 memcpy(&tf[0], &hdr->flow_lbl[0], 3); 1051 /* zero the highest 4-bits, contains DCSP + ECN */ 1052 tf[0] &= ~0xf0; 1053 /* set ECN */ 1054 tf[0] |= (tc & 0xc0); 1055 1056 lowpan_push_hc_data(hc_ptr, tf, 3); 1057 val = LOWPAN_IPHC_TF_01; 1058 } else { 1059 /* 00: ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) 1060 * 1061 * 1 2 3 1062 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1063 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1064 * |ECN| DSCP | rsv | Flow Label | 1065 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1066 */ 1067 memcpy(&tf[0], &tc, sizeof(tc)); 1068 /* highest nibble of flow_lbl[0] is part of DSCP + ECN 1069 * which will be the 4-bit pad and will be filled with 1070 * zeros afterwards. 1071 */ 1072 memcpy(&tf[1], &hdr->flow_lbl[0], 3); 1073 /* zero the 4-bit pad, which is reserved */ 1074 tf[1] &= ~0xf0; 1075 1076 lowpan_push_hc_data(hc_ptr, tf, 4); 1077 val = LOWPAN_IPHC_TF_00; 1078 } 1079 } 1080 1081 return val; 1082 } 1083 1084 static u8 lowpan_iphc_mcast_ctx_addr_compress(u8 **hc_ptr, 1085 const struct lowpan_iphc_ctx *ctx, 1086 const struct in6_addr *ipaddr) 1087 { 1088 u8 data[6]; 1089 1090 /* flags/scope, reserved (RIID) */ 1091 memcpy(data, &ipaddr->s6_addr[1], 2); 1092 /* group ID */ 1093 memcpy(&data[1], &ipaddr->s6_addr[11], 4); 1094 lowpan_push_hc_data(hc_ptr, data, 6); 1095 1096 return LOWPAN_IPHC_DAM_00; 1097 } 1098 1099 static u8 lowpan_iphc_mcast_addr_compress(u8 **hc_ptr, 1100 const struct in6_addr *ipaddr) 1101 { 1102 u8 val; 1103 1104 if (lowpan_is_mcast_addr_compressable8(ipaddr)) { 1105 pr_debug("compressed to 1 octet\n"); 1106 /* use last byte */ 1107 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[15], 1); 1108 val = LOWPAN_IPHC_DAM_11; 1109 } else if (lowpan_is_mcast_addr_compressable32(ipaddr)) { 1110 pr_debug("compressed to 4 octets\n"); 1111 /* second byte + the last three */ 1112 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[1], 1); 1113 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[13], 3); 1114 val = LOWPAN_IPHC_DAM_10; 1115 } else if (lowpan_is_mcast_addr_compressable48(ipaddr)) { 1116 pr_debug("compressed to 6 octets\n"); 1117 /* second byte + the last five */ 1118 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[1], 1); 1119 lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[11], 5); 1120 val = LOWPAN_IPHC_DAM_01; 1121 } else { 1122 pr_debug("using full address\n"); 1123 lowpan_push_hc_data(hc_ptr, ipaddr->s6_addr, 16); 1124 val = LOWPAN_IPHC_DAM_00; 1125 } 1126 1127 return val; 1128 } 1129 1130 int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev, 1131 const void *daddr, const void *saddr) 1132 { 1133 u8 iphc0, iphc1, *hc_ptr, cid = 0; 1134 struct ipv6hdr *hdr; 1135 u8 head[LOWPAN_IPHC_MAX_HC_BUF_LEN] = {}; 1136 struct lowpan_iphc_ctx *dci, *sci, dci_entry, sci_entry; 1137 int ret, ipv6_daddr_type, ipv6_saddr_type; 1138 1139 if (skb->protocol != htons(ETH_P_IPV6)) 1140 return -EINVAL; 1141 1142 hdr = ipv6_hdr(skb); 1143 hc_ptr = head + 2; 1144 1145 pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n" 1146 "\tnexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n", 1147 hdr->version, ntohs(hdr->payload_len), hdr->nexthdr, 1148 hdr->hop_limit, &hdr->daddr); 1149 1150 raw_dump_table(__func__, "raw skb network header dump", 1151 skb_network_header(skb), sizeof(struct ipv6hdr)); 1152 1153 /* As we copy some bit-length fields, in the IPHC encoding bytes, 1154 * we sometimes use |= 1155 * If the field is 0, and the current bit value in memory is 1, 1156 * this does not work. We therefore reset the IPHC encoding here 1157 */ 1158 iphc0 = LOWPAN_DISPATCH_IPHC; 1159 iphc1 = 0; 1160 1161 raw_dump_table(__func__, "sending raw skb network uncompressed packet", 1162 skb->data, skb->len); 1163 1164 ipv6_daddr_type = ipv6_addr_type(&hdr->daddr); 1165 spin_lock_bh(&lowpan_dev(dev)->ctx.lock); 1166 if (ipv6_daddr_type & IPV6_ADDR_MULTICAST) 1167 dci = lowpan_iphc_ctx_get_by_mcast_addr(dev, &hdr->daddr); 1168 else 1169 dci = lowpan_iphc_ctx_get_by_addr(dev, &hdr->daddr); 1170 if (dci) { 1171 memcpy(&dci_entry, dci, sizeof(*dci)); 1172 cid |= dci->id; 1173 } 1174 spin_unlock_bh(&lowpan_dev(dev)->ctx.lock); 1175 1176 spin_lock_bh(&lowpan_dev(dev)->ctx.lock); 1177 sci = lowpan_iphc_ctx_get_by_addr(dev, &hdr->saddr); 1178 if (sci) { 1179 memcpy(&sci_entry, sci, sizeof(*sci)); 1180 cid |= (sci->id << 4); 1181 } 1182 spin_unlock_bh(&lowpan_dev(dev)->ctx.lock); 1183 1184 /* if cid is zero it will be compressed */ 1185 if (cid) { 1186 iphc1 |= LOWPAN_IPHC_CID; 1187 lowpan_push_hc_data(&hc_ptr, &cid, sizeof(cid)); 1188 } 1189 1190 /* Traffic Class, Flow Label compression */ 1191 iphc0 |= lowpan_iphc_tf_compress(&hc_ptr, hdr); 1192 1193 /* NOTE: payload length is always compressed */ 1194 1195 /* Check if we provide the nhc format for nexthdr and compression 1196 * functionality. If not nexthdr is handled inline and not compressed. 1197 */ 1198 ret = lowpan_nhc_check_compression(skb, hdr, &hc_ptr); 1199 if (ret == -ENOENT) 1200 lowpan_push_hc_data(&hc_ptr, &hdr->nexthdr, 1201 sizeof(hdr->nexthdr)); 1202 else 1203 iphc0 |= LOWPAN_IPHC_NH; 1204 1205 /* Hop limit 1206 * if 1: compress, encoding is 01 1207 * if 64: compress, encoding is 10 1208 * if 255: compress, encoding is 11 1209 * else do not compress 1210 */ 1211 switch (hdr->hop_limit) { 1212 case 1: 1213 iphc0 |= LOWPAN_IPHC_HLIM_01; 1214 break; 1215 case 64: 1216 iphc0 |= LOWPAN_IPHC_HLIM_10; 1217 break; 1218 case 255: 1219 iphc0 |= LOWPAN_IPHC_HLIM_11; 1220 break; 1221 default: 1222 lowpan_push_hc_data(&hc_ptr, &hdr->hop_limit, 1223 sizeof(hdr->hop_limit)); 1224 } 1225 1226 ipv6_saddr_type = ipv6_addr_type(&hdr->saddr); 1227 /* source address compression */ 1228 if (ipv6_saddr_type == IPV6_ADDR_ANY) { 1229 pr_debug("source address is unspecified, setting SAC\n"); 1230 iphc1 |= LOWPAN_IPHC_SAC; 1231 } else { 1232 if (sci) { 1233 iphc1 |= lowpan_compress_ctx_addr(&hc_ptr, dev, 1234 &hdr->saddr, 1235 &sci_entry, saddr, 1236 true); 1237 iphc1 |= LOWPAN_IPHC_SAC; 1238 } else { 1239 if (ipv6_saddr_type & IPV6_ADDR_LINKLOCAL && 1240 lowpan_is_linklocal_zero_padded(hdr->saddr)) { 1241 iphc1 |= lowpan_compress_addr_64(&hc_ptr, dev, 1242 &hdr->saddr, 1243 saddr, true); 1244 pr_debug("source address unicast link-local %pI6c iphc1 0x%02x\n", 1245 &hdr->saddr, iphc1); 1246 } else { 1247 pr_debug("send the full source address\n"); 1248 lowpan_push_hc_data(&hc_ptr, 1249 hdr->saddr.s6_addr, 16); 1250 } 1251 } 1252 } 1253 1254 /* destination address compression */ 1255 if (ipv6_daddr_type & IPV6_ADDR_MULTICAST) { 1256 pr_debug("destination address is multicast: "); 1257 iphc1 |= LOWPAN_IPHC_M; 1258 if (dci) { 1259 iphc1 |= lowpan_iphc_mcast_ctx_addr_compress(&hc_ptr, 1260 &dci_entry, 1261 &hdr->daddr); 1262 iphc1 |= LOWPAN_IPHC_DAC; 1263 } else { 1264 iphc1 |= lowpan_iphc_mcast_addr_compress(&hc_ptr, 1265 &hdr->daddr); 1266 } 1267 } else { 1268 if (dci) { 1269 iphc1 |= lowpan_compress_ctx_addr(&hc_ptr, dev, 1270 &hdr->daddr, 1271 &dci_entry, daddr, 1272 false); 1273 iphc1 |= LOWPAN_IPHC_DAC; 1274 } else { 1275 if (ipv6_daddr_type & IPV6_ADDR_LINKLOCAL && 1276 lowpan_is_linklocal_zero_padded(hdr->daddr)) { 1277 iphc1 |= lowpan_compress_addr_64(&hc_ptr, dev, 1278 &hdr->daddr, 1279 daddr, false); 1280 pr_debug("dest address unicast link-local %pI6c iphc1 0x%02x\n", 1281 &hdr->daddr, iphc1); 1282 } else { 1283 pr_debug("dest address unicast %pI6c\n", 1284 &hdr->daddr); 1285 lowpan_push_hc_data(&hc_ptr, 1286 hdr->daddr.s6_addr, 16); 1287 } 1288 } 1289 } 1290 1291 /* next header compression */ 1292 if (iphc0 & LOWPAN_IPHC_NH) { 1293 ret = lowpan_nhc_do_compression(skb, hdr, &hc_ptr); 1294 if (ret < 0) 1295 return ret; 1296 } 1297 1298 head[0] = iphc0; 1299 head[1] = iphc1; 1300 1301 skb_pull(skb, sizeof(struct ipv6hdr)); 1302 skb_reset_transport_header(skb); 1303 memcpy(skb_push(skb, hc_ptr - head), head, hc_ptr - head); 1304 skb_reset_network_header(skb); 1305 1306 pr_debug("header len %d skb %u\n", (int)(hc_ptr - head), skb->len); 1307 1308 raw_dump_table(__func__, "raw skb data dump compressed", 1309 skb->data, skb->len); 1310 return 0; 1311 } 1312 EXPORT_SYMBOL_GPL(lowpan_header_compress); 1313