diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 17:54:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 17:54:29 -0400 |
commit | cc998ff8811530be521f6b316f37ab7676a07938 (patch) | |
tree | a054b3bf4b2ef406bf756a6cfc9be2f9115f17ae /net/ieee802154 | |
parent | 57d730924d5cc2c3e280af16a9306587c3a511db (diff) | |
parent | 0d40f75bdab241868c0eb6f97aef9f8b3a66f7b3 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller:
"Noteworthy changes this time around:
1) Multicast rejoin support for team driver, from Jiri Pirko.
2) Centralize and simplify TCP RTT measurement handling in order to
reduce the impact of bad RTO seeding from SYN/ACKs. Also, when
both timestamps and local RTT measurements are available prefer
the later because there are broken middleware devices which
scramble the timestamp.
From Yuchung Cheng.
3) Add TCP_NOTSENT_LOWAT socket option to limit the amount of kernel
memory consumed to queue up unsend user data. From Eric Dumazet.
4) Add a "physical port ID" abstraction for network devices, from
Jiri Pirko.
5) Add a "suppress" operation to influence fib_rules lookups, from
Stefan Tomanek.
6) Add a networking development FAQ, from Paul Gortmaker.
7) Extend the information provided by tcp_probe and add ipv6 support,
from Daniel Borkmann.
8) Use RCU locking more extensively in openvswitch data paths, from
Pravin B Shelar.
9) Add SCTP support to openvswitch, from Joe Stringer.
10) Add EF10 chip support to SFC driver, from Ben Hutchings.
11) Add new SYNPROXY netfilter target, from Patrick McHardy.
12) Compute a rate approximation for sending in TCP sockets, and use
this to more intelligently coalesce TSO frames. Furthermore, add
a new packet scheduler which takes advantage of this estimate when
available. From Eric Dumazet.
13) Allow AF_PACKET fanouts with random selection, from Daniel
Borkmann.
14) Add ipv6 support to vxlan driver, from Cong Wang"
Resolved conflicts as per discussion.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1218 commits)
openvswitch: Fix alignment of struct sw_flow_key.
netfilter: Fix build errors with xt_socket.c
tcp: Add missing braces to do_tcp_setsockopt
caif: Add missing braces to multiline if in cfctrl_linkup_request
bnx2x: Add missing braces in bnx2x:bnx2x_link_initialize
vxlan: Fix kernel panic on device delete.
net: mvneta: implement ->ndo_do_ioctl() to support PHY ioctls
net: mvneta: properly disable HW PHY polling and ensure adjust_link() works
icplus: Use netif_running to determine device state
ethernet/arc/arc_emac: Fix huge delays in large file copies
tuntap: orphan frags before trying to set tx timestamp
tuntap: purge socket error queue on detach
qlcnic: use standard NAPI weights
ipv6:introduce function to find route for redirect
bnx2x: VF RSS support - VF side
bnx2x: VF RSS support - PF side
vxlan: Notify drivers for listening UDP port changes
net: usbnet: update addr_assign_type if appropriate
driver/net: enic: update enic maintainers and driver
driver/net: enic: Exposing symbols for Cisco's low latency driver
...
Diffstat (limited to 'net/ieee802154')
-rw-r--r-- | net/ieee802154/6lowpan.c | 286 | ||||
-rw-r--r-- | net/ieee802154/6lowpan.h | 20 |
2 files changed, 204 insertions, 102 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 3b9d5f20bd1c..c85e71e0c7ff 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -67,39 +67,6 @@ static const u8 lowpan_ttl_values[] = {0, 1, 64, 255}; | |||
67 | 67 | ||
68 | static LIST_HEAD(lowpan_devices); | 68 | static LIST_HEAD(lowpan_devices); |
69 | 69 | ||
70 | /* | ||
71 | * Uncompression of linklocal: | ||
72 | * 0 -> 16 bytes from packet | ||
73 | * 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet | ||
74 | * 2 -> 2 bytes from prefix - zeroes + 2 from packet | ||
75 | * 3 -> 2 bytes from prefix - infer 8 bytes from lladdr | ||
76 | * | ||
77 | * NOTE: => the uncompress function does change 0xf to 0x10 | ||
78 | * NOTE: 0x00 => no-autoconfig => unspecified | ||
79 | */ | ||
80 | static const u8 lowpan_unc_llconf[] = {0x0f, 0x28, 0x22, 0x20}; | ||
81 | |||
82 | /* | ||
83 | * Uncompression of ctx-based: | ||
84 | * 0 -> 0 bits from packet [unspecified / reserved] | ||
85 | * 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet | ||
86 | * 2 -> 8 bytes from prefix - zeroes + 2 from packet | ||
87 | * 3 -> 8 bytes from prefix - infer 8 bytes from lladdr | ||
88 | */ | ||
89 | static const u8 lowpan_unc_ctxconf[] = {0x00, 0x88, 0x82, 0x80}; | ||
90 | |||
91 | /* | ||
92 | * Uncompression of ctx-base | ||
93 | * 0 -> 0 bits from packet | ||
94 | * 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet | ||
95 | * 2 -> 2 bytes from prefix - zeroes + 3 from packet | ||
96 | * 3 -> 2 bytes from prefix - infer 1 bytes from lladdr | ||
97 | */ | ||
98 | static const u8 lowpan_unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21}; | ||
99 | |||
100 | /* Link local prefix */ | ||
101 | static const u8 lowpan_llprefix[] = {0xfe, 0x80}; | ||
102 | |||
103 | /* private device info */ | 70 | /* private device info */ |
104 | struct lowpan_dev_info { | 71 | struct lowpan_dev_info { |
105 | struct net_device *real_dev; /* real WPAN device ptr */ | 72 | struct net_device *real_dev; /* real WPAN device ptr */ |
@@ -191,55 +158,177 @@ lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift, const struct in6_addr *ipaddr, | |||
191 | return rol8(val, shift); | 158 | return rol8(val, shift); |
192 | } | 159 | } |
193 | 160 | ||
194 | static void | 161 | /* |
195 | lowpan_uip_ds6_set_addr_iid(struct in6_addr *ipaddr, unsigned char *lladdr) | 162 | * Uncompress address function for source and |
163 | * destination address(non-multicast). | ||
164 | * | ||
165 | * address_mode is sam value or dam value. | ||
166 | */ | ||
167 | static int | ||
168 | lowpan_uncompress_addr(struct sk_buff *skb, | ||
169 | struct in6_addr *ipaddr, | ||
170 | const u8 address_mode, | ||
171 | const struct ieee802154_addr *lladdr) | ||
196 | { | 172 | { |
197 | memcpy(&ipaddr->s6_addr[8], lladdr, IEEE802154_ADDR_LEN); | 173 | bool fail; |
198 | /* second bit-flip (Universe/Local) is done according RFC2464 */ | 174 | |
199 | ipaddr->s6_addr[8] ^= 0x02; | 175 | switch (address_mode) { |
176 | case LOWPAN_IPHC_ADDR_00: | ||
177 | /* for global link addresses */ | ||
178 | fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); | ||
179 | break; | ||
180 | case LOWPAN_IPHC_ADDR_01: | ||
181 | /* fe:80::XXXX:XXXX:XXXX:XXXX */ | ||
182 | ipaddr->s6_addr[0] = 0xFE; | ||
183 | ipaddr->s6_addr[1] = 0x80; | ||
184 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8); | ||
185 | break; | ||
186 | case LOWPAN_IPHC_ADDR_02: | ||
187 | /* fe:80::ff:fe00:XXXX */ | ||
188 | ipaddr->s6_addr[0] = 0xFE; | ||
189 | ipaddr->s6_addr[1] = 0x80; | ||
190 | ipaddr->s6_addr[11] = 0xFF; | ||
191 | ipaddr->s6_addr[12] = 0xFE; | ||
192 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2); | ||
193 | break; | ||
194 | case LOWPAN_IPHC_ADDR_03: | ||
195 | fail = false; | ||
196 | switch (lladdr->addr_type) { | ||
197 | case IEEE802154_ADDR_LONG: | ||
198 | /* fe:80::XXXX:XXXX:XXXX:XXXX | ||
199 | * \_________________/ | ||
200 | * hwaddr | ||
201 | */ | ||
202 | ipaddr->s6_addr[0] = 0xFE; | ||
203 | ipaddr->s6_addr[1] = 0x80; | ||
204 | memcpy(&ipaddr->s6_addr[8], lladdr->hwaddr, | ||
205 | IEEE802154_ADDR_LEN); | ||
206 | /* second bit-flip (Universe/Local) | ||
207 | * is done according RFC2464 | ||
208 | */ | ||
209 | ipaddr->s6_addr[8] ^= 0x02; | ||
210 | break; | ||
211 | case IEEE802154_ADDR_SHORT: | ||
212 | /* fe:80::ff:fe00:XXXX | ||
213 | * \__/ | ||
214 | * short_addr | ||
215 | * | ||
216 | * Universe/Local bit is zero. | ||
217 | */ | ||
218 | ipaddr->s6_addr[0] = 0xFE; | ||
219 | ipaddr->s6_addr[1] = 0x80; | ||
220 | ipaddr->s6_addr[11] = 0xFF; | ||
221 | ipaddr->s6_addr[12] = 0xFE; | ||
222 | ipaddr->s6_addr16[7] = htons(lladdr->short_addr); | ||
223 | break; | ||
224 | default: | ||
225 | pr_debug("Invalid addr_type set\n"); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | break; | ||
229 | default: | ||
230 | pr_debug("Invalid address mode value: 0x%x\n", address_mode); | ||
231 | return -EINVAL; | ||
232 | } | ||
233 | |||
234 | if (fail) { | ||
235 | pr_debug("Failed to fetch skb data\n"); | ||
236 | return -EIO; | ||
237 | } | ||
238 | |||
239 | lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 addr is:\n", | ||
240 | ipaddr->s6_addr, 16); | ||
241 | |||
242 | return 0; | ||
200 | } | 243 | } |
201 | 244 | ||
202 | /* | 245 | /* Uncompress address function for source context |
203 | * Uncompress addresses based on a prefix and a postfix with zeroes in | 246 | * based address(non-multicast). |
204 | * between. If the postfix is zero in length it will use the link address | ||
205 | * to configure the IP address (autoconf style). | ||
206 | * pref_post_count takes a byte where the first nibble specify prefix count | ||
207 | * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). | ||
208 | */ | 247 | */ |
209 | static int | 248 | static int |
210 | lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, | 249 | lowpan_uncompress_context_based_src_addr(struct sk_buff *skb, |
211 | u8 const *prefix, u8 pref_post_count, unsigned char *lladdr) | 250 | struct in6_addr *ipaddr, |
251 | const u8 sam) | ||
212 | { | 252 | { |
213 | u8 prefcount = pref_post_count >> 4; | 253 | switch (sam) { |
214 | u8 postcount = pref_post_count & 0x0f; | 254 | case LOWPAN_IPHC_ADDR_00: |
215 | 255 | /* unspec address :: | |
216 | /* full nibble 15 => 16 */ | 256 | * Do nothing, address is already :: |
217 | prefcount = (prefcount == 15 ? 16 : prefcount); | 257 | */ |
218 | postcount = (postcount == 15 ? 16 : postcount); | 258 | break; |
219 | 259 | case LOWPAN_IPHC_ADDR_01: | |
220 | if (lladdr) | 260 | /* TODO */ |
221 | lowpan_raw_dump_inline(__func__, "linklocal address", | 261 | case LOWPAN_IPHC_ADDR_02: |
222 | lladdr, IEEE802154_ADDR_LEN); | 262 | /* TODO */ |
223 | if (prefcount > 0) | 263 | case LOWPAN_IPHC_ADDR_03: |
224 | memcpy(ipaddr, prefix, prefcount); | 264 | /* TODO */ |
225 | 265 | netdev_warn(skb->dev, "SAM value 0x%x not supported\n", sam); | |
226 | if (prefcount + postcount < 16) | 266 | return -EINVAL; |
227 | memset(&ipaddr->s6_addr[prefcount], 0, | 267 | default: |
228 | 16 - (prefcount + postcount)); | 268 | pr_debug("Invalid sam value: 0x%x\n", sam); |
229 | 269 | return -EINVAL; | |
230 | if (postcount > 0) { | 270 | } |
231 | memcpy(&ipaddr->s6_addr[16 - postcount], skb->data, postcount); | 271 | |
232 | skb_pull(skb, postcount); | 272 | lowpan_raw_dump_inline(NULL, |
233 | } else if (prefcount > 0) { | 273 | "Reconstructed context based ipv6 src addr is:\n", |
234 | if (lladdr == NULL) | 274 | ipaddr->s6_addr, 16); |
235 | return -EINVAL; | 275 | |
276 | return 0; | ||
277 | } | ||
236 | 278 | ||
237 | /* no IID based configuration if no prefix and no data */ | 279 | /* Uncompress function for multicast destination address, |
238 | lowpan_uip_ds6_set_addr_iid(ipaddr, lladdr); | 280 | * when M bit is set. |
281 | */ | ||
282 | static int | ||
283 | lowpan_uncompress_multicast_daddr(struct sk_buff *skb, | ||
284 | struct in6_addr *ipaddr, | ||
285 | const u8 dam) | ||
286 | { | ||
287 | bool fail; | ||
288 | |||
289 | switch (dam) { | ||
290 | case LOWPAN_IPHC_DAM_00: | ||
291 | /* 00: 128 bits. The full address | ||
292 | * is carried in-line. | ||
293 | */ | ||
294 | fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); | ||
295 | break; | ||
296 | case LOWPAN_IPHC_DAM_01: | ||
297 | /* 01: 48 bits. The address takes | ||
298 | * the form ffXX::00XX:XXXX:XXXX. | ||
299 | */ | ||
300 | ipaddr->s6_addr[0] = 0xFF; | ||
301 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); | ||
302 | fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5); | ||
303 | break; | ||
304 | case LOWPAN_IPHC_DAM_10: | ||
305 | /* 10: 32 bits. The address takes | ||
306 | * the form ffXX::00XX:XXXX. | ||
307 | */ | ||
308 | ipaddr->s6_addr[0] = 0xFF; | ||
309 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); | ||
310 | fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3); | ||
311 | break; | ||
312 | case LOWPAN_IPHC_DAM_11: | ||
313 | /* 11: 8 bits. The address takes | ||
314 | * the form ff02::00XX. | ||
315 | */ | ||
316 | ipaddr->s6_addr[0] = 0xFF; | ||
317 | ipaddr->s6_addr[1] = 0x02; | ||
318 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1); | ||
319 | break; | ||
320 | default: | ||
321 | pr_debug("DAM value has a wrong value: 0x%x\n", dam); | ||
322 | return -EINVAL; | ||
323 | } | ||
324 | |||
325 | if (fail) { | ||
326 | pr_debug("Failed to fetch skb data\n"); | ||
327 | return -EIO; | ||
239 | } | 328 | } |
240 | 329 | ||
241 | pr_debug("uncompressing %d + %d => ", prefcount, postcount); | 330 | lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is:\n", |
242 | lowpan_raw_dump_inline(NULL, NULL, ipaddr->s6_addr, 16); | 331 | ipaddr->s6_addr, 16); |
243 | 332 | ||
244 | return 0; | 333 | return 0; |
245 | } | 334 | } |
@@ -702,6 +791,12 @@ lowpan_alloc_new_frame(struct sk_buff *skb, u16 len, u16 tag) | |||
702 | skb_reserve(frame->skb, sizeof(struct ipv6hdr)); | 791 | skb_reserve(frame->skb, sizeof(struct ipv6hdr)); |
703 | skb_put(frame->skb, frame->length); | 792 | skb_put(frame->skb, frame->length); |
704 | 793 | ||
794 | /* copy the first control block to keep a | ||
795 | * trace of the link-layer addresses in case | ||
796 | * of a link-local compressed address | ||
797 | */ | ||
798 | memcpy(frame->skb->cb, skb->cb, sizeof(skb->cb)); | ||
799 | |||
705 | init_timer(&frame->timer); | 800 | init_timer(&frame->timer); |
706 | /* time out is the same as for ipv6 - 60 sec */ | 801 | /* time out is the same as for ipv6 - 60 sec */ |
707 | frame->timer.expires = jiffies + LOWPAN_FRAG_TIMEOUT; | 802 | frame->timer.expires = jiffies + LOWPAN_FRAG_TIMEOUT; |
@@ -723,9 +818,9 @@ frame_err: | |||
723 | static int | 818 | static int |
724 | lowpan_process_data(struct sk_buff *skb) | 819 | lowpan_process_data(struct sk_buff *skb) |
725 | { | 820 | { |
726 | struct ipv6hdr hdr; | 821 | struct ipv6hdr hdr = {}; |
727 | u8 tmp, iphc0, iphc1, num_context = 0; | 822 | u8 tmp, iphc0, iphc1, num_context = 0; |
728 | u8 *_saddr, *_daddr; | 823 | const struct ieee802154_addr *_saddr, *_daddr; |
729 | int err; | 824 | int err; |
730 | 825 | ||
731 | lowpan_raw_dump_table(__func__, "raw skb data dump", skb->data, | 826 | lowpan_raw_dump_table(__func__, "raw skb data dump", skb->data, |
@@ -828,8 +923,8 @@ lowpan_process_data(struct sk_buff *skb) | |||
828 | if (lowpan_fetch_skb_u8(skb, &iphc1)) | 923 | if (lowpan_fetch_skb_u8(skb, &iphc1)) |
829 | goto drop; | 924 | goto drop; |
830 | 925 | ||
831 | _saddr = mac_cb(skb)->sa.hwaddr; | 926 | _saddr = &mac_cb(skb)->sa; |
832 | _daddr = mac_cb(skb)->da.hwaddr; | 927 | _daddr = &mac_cb(skb)->da; |
833 | 928 | ||
834 | pr_debug("iphc0 = %02x, iphc1 = %02x\n", iphc0, iphc1); | 929 | pr_debug("iphc0 = %02x, iphc1 = %02x\n", iphc0, iphc1); |
835 | 930 | ||
@@ -868,8 +963,6 @@ lowpan_process_data(struct sk_buff *skb) | |||
868 | 963 | ||
869 | hdr.priority = ((tmp >> 2) & 0x0f); | 964 | hdr.priority = ((tmp >> 2) & 0x0f); |
870 | hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); | 965 | hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); |
871 | hdr.flow_lbl[1] = 0; | ||
872 | hdr.flow_lbl[2] = 0; | ||
873 | break; | 966 | break; |
874 | /* | 967 | /* |
875 | * Flow Label carried in-line | 968 | * Flow Label carried in-line |
@@ -885,10 +978,6 @@ lowpan_process_data(struct sk_buff *skb) | |||
885 | break; | 978 | break; |
886 | /* Traffic Class and Flow Label are elided */ | 979 | /* Traffic Class and Flow Label are elided */ |
887 | case 3: /* 11b */ | 980 | case 3: /* 11b */ |
888 | hdr.priority = 0; | ||
889 | hdr.flow_lbl[0] = 0; | ||
890 | hdr.flow_lbl[1] = 0; | ||
891 | hdr.flow_lbl[2] = 0; | ||
892 | break; | 981 | break; |
893 | default: | 982 | default: |
894 | break; | 983 | break; |
@@ -915,10 +1004,18 @@ lowpan_process_data(struct sk_buff *skb) | |||
915 | /* Extract SAM to the tmp variable */ | 1004 | /* Extract SAM to the tmp variable */ |
916 | tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; | 1005 | tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; |
917 | 1006 | ||
918 | /* Source address uncompression */ | 1007 | if (iphc1 & LOWPAN_IPHC_SAC) { |
919 | pr_debug("source address stateless compression\n"); | 1008 | /* Source address context based uncompression */ |
920 | err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix, | 1009 | pr_debug("SAC bit is set. Handle context based source address.\n"); |
921 | lowpan_unc_llconf[tmp], skb->data); | 1010 | err = lowpan_uncompress_context_based_src_addr( |
1011 | skb, &hdr.saddr, tmp); | ||
1012 | } else { | ||
1013 | /* Source address uncompression */ | ||
1014 | pr_debug("source address stateless compression\n"); | ||
1015 | err = lowpan_uncompress_addr(skb, &hdr.saddr, tmp, _saddr); | ||
1016 | } | ||
1017 | |||
1018 | /* Check on error of previous branch */ | ||
922 | if (err) | 1019 | if (err) |
923 | goto drop; | 1020 | goto drop; |
924 | 1021 | ||
@@ -931,23 +1028,14 @@ lowpan_process_data(struct sk_buff *skb) | |||
931 | pr_debug("dest: context-based mcast compression\n"); | 1028 | pr_debug("dest: context-based mcast compression\n"); |
932 | /* TODO: implement this */ | 1029 | /* TODO: implement this */ |
933 | } else { | 1030 | } else { |
934 | u8 prefix[] = {0xff, 0x02}; | 1031 | err = lowpan_uncompress_multicast_daddr( |
935 | 1032 | skb, &hdr.daddr, tmp); | |
936 | pr_debug("dest: non context-based mcast compression\n"); | ||
937 | if (0 < tmp && tmp < 3) { | ||
938 | if (lowpan_fetch_skb_u8(skb, &prefix[1])) | ||
939 | goto drop; | ||
940 | } | ||
941 | |||
942 | err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix, | ||
943 | lowpan_unc_mxconf[tmp], NULL); | ||
944 | if (err) | 1033 | if (err) |
945 | goto drop; | 1034 | goto drop; |
946 | } | 1035 | } |
947 | } else { | 1036 | } else { |
948 | pr_debug("dest: stateless compression\n"); | 1037 | pr_debug("dest: stateless compression\n"); |
949 | err = lowpan_uncompress_addr(skb, &hdr.daddr, lowpan_llprefix, | 1038 | err = lowpan_uncompress_addr(skb, &hdr.daddr, tmp, _daddr); |
950 | lowpan_unc_llconf[tmp], skb->data); | ||
951 | if (err) | 1039 | if (err) |
952 | goto drop; | 1040 | goto drop; |
953 | } | 1041 | } |
diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h index 4b8f917658b5..2869c0526dad 100644 --- a/net/ieee802154/6lowpan.h +++ b/net/ieee802154/6lowpan.h | |||
@@ -193,10 +193,12 @@ | |||
193 | /* Values of fields within the IPHC encoding second byte */ | 193 | /* Values of fields within the IPHC encoding second byte */ |
194 | #define LOWPAN_IPHC_CID 0x80 | 194 | #define LOWPAN_IPHC_CID 0x80 |
195 | 195 | ||
196 | #define LOWPAN_IPHC_ADDR_00 0x00 | ||
197 | #define LOWPAN_IPHC_ADDR_01 0x01 | ||
198 | #define LOWPAN_IPHC_ADDR_02 0x02 | ||
199 | #define LOWPAN_IPHC_ADDR_03 0x03 | ||
200 | |||
196 | #define LOWPAN_IPHC_SAC 0x40 | 201 | #define LOWPAN_IPHC_SAC 0x40 |
197 | #define LOWPAN_IPHC_SAM_00 0x00 | ||
198 | #define LOWPAN_IPHC_SAM_01 0x10 | ||
199 | #define LOWPAN_IPHC_SAM_10 0x20 | ||
200 | #define LOWPAN_IPHC_SAM 0x30 | 202 | #define LOWPAN_IPHC_SAM 0x30 |
201 | 203 | ||
202 | #define LOWPAN_IPHC_SAM_BIT 4 | 204 | #define LOWPAN_IPHC_SAM_BIT 4 |
@@ -230,4 +232,16 @@ | |||
230 | dest = 16 bit inline */ | 232 | dest = 16 bit inline */ |
231 | #define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ | 233 | #define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ |
232 | 234 | ||
235 | static inline bool lowpan_fetch_skb(struct sk_buff *skb, | ||
236 | void *data, const unsigned int len) | ||
237 | { | ||
238 | if (unlikely(!pskb_may_pull(skb, len))) | ||
239 | return true; | ||
240 | |||
241 | skb_copy_from_linear_data(skb, data, len); | ||
242 | skb_pull(skb, len); | ||
243 | |||
244 | return false; | ||
245 | } | ||
246 | |||
233 | #endif /* __6LOWPAN_H__ */ | 247 | #endif /* __6LOWPAN_H__ */ |