iphc.c 33 KB

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