diff options
author | alex.bluesman.smirnov@gmail.com <alex.bluesman.smirnov@gmail.com> | 2011-11-10 02:40:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-14 00:19:43 -0500 |
commit | 3bd5b958c2a2dd1a9b4c8d21e75fb47b062fc941 (patch) | |
tree | 6cdd68759b81cf7115976f730537da76b528723e /net/ieee802154/6lowpan.c | |
parent | 4d039f684314b707fdae3c7262faf4a80c548194 (diff) |
6LoWPAN: UDP header compression
This patch adds support for UDP header compression.
Derived from Contiki OS.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee802154/6lowpan.c')
-rw-r--r-- | net/ieee802154/6lowpan.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 39ec6e018227..9bf82d72bb9e 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -246,6 +246,50 @@ lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, | |||
246 | return 0; | 246 | return 0; |
247 | } | 247 | } |
248 | 248 | ||
249 | static void | ||
250 | lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) | ||
251 | { | ||
252 | struct udphdr *uh = udp_hdr(skb); | ||
253 | |||
254 | pr_debug("(%s): UDP header compression\n", __func__); | ||
255 | |||
256 | if (((uh->source & LOWPAN_NHC_UDP_4BIT_MASK) == | ||
257 | LOWPAN_NHC_UDP_4BIT_PORT) && | ||
258 | ((uh->dest & LOWPAN_NHC_UDP_4BIT_MASK) == | ||
259 | LOWPAN_NHC_UDP_4BIT_PORT)) { | ||
260 | pr_debug("(%s): both ports compression to 4 bits\n", __func__); | ||
261 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_11; | ||
262 | **(hc06_ptr + 1) = /* subtraction is faster */ | ||
263 | (u8)((uh->dest - LOWPAN_NHC_UDP_4BIT_PORT) + | ||
264 | ((uh->source & LOWPAN_NHC_UDP_4BIT_PORT) << 4)); | ||
265 | *hc06_ptr += 2; | ||
266 | } else if ((uh->dest & LOWPAN_NHC_UDP_8BIT_MASK) == | ||
267 | LOWPAN_NHC_UDP_8BIT_PORT) { | ||
268 | pr_debug("(%s): remove 8 bits of dest\n", __func__); | ||
269 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_01; | ||
270 | memcpy(*hc06_ptr + 1, &uh->source, 2); | ||
271 | **(hc06_ptr + 3) = (u8)(uh->dest - LOWPAN_NHC_UDP_8BIT_PORT); | ||
272 | *hc06_ptr += 4; | ||
273 | } else if ((uh->source & LOWPAN_NHC_UDP_8BIT_MASK) == | ||
274 | LOWPAN_NHC_UDP_8BIT_PORT) { | ||
275 | pr_debug("(%s): remove 8 bits of source\n", __func__); | ||
276 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_10; | ||
277 | memcpy(*hc06_ptr + 1, &uh->dest, 2); | ||
278 | **(hc06_ptr + 3) = (u8)(uh->source - LOWPAN_NHC_UDP_8BIT_PORT); | ||
279 | *hc06_ptr += 4; | ||
280 | } else { | ||
281 | pr_debug("(%s): can't compress header\n", __func__); | ||
282 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_00; | ||
283 | memcpy(*hc06_ptr + 1, &uh->source, 2); | ||
284 | memcpy(*hc06_ptr + 3, &uh->dest, 2); | ||
285 | *hc06_ptr += 5; | ||
286 | } | ||
287 | |||
288 | /* checksum is always inline */ | ||
289 | memcpy(*hc06_ptr, &uh->check, 2); | ||
290 | *hc06_ptr += 2; | ||
291 | } | ||
292 | |||
249 | static u8 lowpan_fetch_skb_u8(struct sk_buff *skb) | 293 | static u8 lowpan_fetch_skb_u8(struct sk_buff *skb) |
250 | { | 294 | { |
251 | u8 ret; | 295 | u8 ret; |
@@ -365,8 +409,6 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
365 | if (hdr->nexthdr == UIP_PROTO_UDP) | 409 | if (hdr->nexthdr == UIP_PROTO_UDP) |
366 | iphc0 |= LOWPAN_IPHC_NH_C; | 410 | iphc0 |= LOWPAN_IPHC_NH_C; |
367 | 411 | ||
368 | /* TODO: next header compression */ | ||
369 | |||
370 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { | 412 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { |
371 | *hc06_ptr = hdr->nexthdr; | 413 | *hc06_ptr = hdr->nexthdr; |
372 | hc06_ptr += 1; | 414 | hc06_ptr += 1; |
@@ -454,8 +496,9 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
454 | } | 496 | } |
455 | } | 497 | } |
456 | 498 | ||
457 | /* TODO: UDP header compression */ | 499 | /* UDP header compression */ |
458 | /* TODO: Next Header compression */ | 500 | if (hdr->nexthdr == UIP_PROTO_UDP) |
501 | lowpan_compress_udp_header(&hc06_ptr, skb); | ||
459 | 502 | ||
460 | head[0] = iphc0; | 503 | head[0] = iphc0; |
461 | head[1] = iphc1; | 504 | head[1] = iphc1; |