2015-01-09 15:42:56

by Alexander Aring

[permalink] [raw]
Subject: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

This patch series introduce the next header compression framework. Currently
we support udp compression/uncompression only. This framework allow to add new
next header compression formats easily.

If somebody wants to add a new header compression format and some information
are missing while calling compression and uncompression callbacks. Please
feel free to make framework changes according these callbacks.

changes since v2:
- make udp nhc as module as suggested by Marcel Holtmann
- fix comment header in nhc_udp.c

I didn't make the lowpan_nhc declaration "const" because this will occur
issues with rb_node, id and idmask array. Which will manipulated during
runtime.

changes since v3:
- add patch 3/3 for other known rfc6282 ipv6 extension headers compression
formats
- add request_modules for loading nhc default compression format modules.
Which was suggested by Jukka Rissanen. Thanks, this is really working.
- Add rtnl_lock for lowpan_nhc_add and del since we have no synced
request_modules call this could make trouble.
- Move some handling out of nhc_do_compression and uncompression function.
The complete handling is now inside of iphc.c and nhc_do_compression and
uncompression functions is only a wrapper call for the callback.
- rework some menuentries for Kconfig and compression format, they are
grouped by rfc now.
- move some generic handling like "skb_pull(skb, nhc->nexthdrlen);" into
iphc.c. It would be great if we have something also for uncompression
for the skb_cow. But this isn't possible right now.
- change warning if nhc was not found to "was not found" instead isn't
implemented. It isn't implemented if callbacks are NULL now.
- small cleanups.

changes since v4:
- add spinlock for to prevent nhc from deletion while using. This can occur
if nhc module is unloading while compression/uncompression.
- move nhc handling for nhc compression/uncompression completely into
nhc_do_compression/nhc_do_uncompression.

Note about locking:

We have now a spinlock nhc_lowpan_lock which prevents manipulating the nhc
datastructures while using it. On receiving side it's easy to handle, at the
end we check if 6lowpan nh compressed flag is set and run uncompression.
On the other hand the transmit side is complicated, we check if next_hdr field
is registrated and run some other compression routines, at least we do the
finally nhc compression which depends on the first check if next_hdr was
registrated. The kernel will crash if we remove the using module between
"next_hdr check" and "do nhc compression", the lock will prevent that now.

Now in the transmit path exist a little window to remove a lowpan_nhc while
compression. This is exactly the part between "check if we support" and
"doing compression". This is a very unlikely case, if this occurs we drop
the packet while compression. Don't know how to better deal with that right
now. I will try to search a better solution later.

changes since v5:
- s/rfc6282// on filenames and kconfig entries, suggested by Marcel Holtmann
and Stefan Schmidt
- s/FRAG/FRAGMENT/ - suggested by Stefan Schmidt
- s/MOBIL/MOBILITY/ - suggested by Stefan Schmidt
- s/ROUTE/ROUTING/ - suggested by Stefan Schmidt
- replace "depends on 6LOWPAN_NHC" with a global "if 6LOWPAN_NHC
$LOT_OF_ENTRIES endif" inside net/6lowpan/Kconfig
- fix small typo "nhc" -> "nhcs" in net/6lowpan/Makefile
- add MODULE_DESCRIPTION to each NHC module

Cc: Jukka Rissanen <[email protected]>
Cc: Martin Townsend <[email protected]>
Cc: Marcel Holtmann <[email protected]>
Cc: Stefan Schmidt <[email protected]>

Alexander Aring (3):
6lowpan: add generic nhc layer interface
6lowpan: add udp compression via nhc layer
6lowpan: nhc: add other known rfc6282 compressions

net/6lowpan/Kconfig | 57 ++++++++++-
net/6lowpan/Makefile | 13 ++-
net/6lowpan/iphc.c | 200 ++++++-------------------------------
net/6lowpan/nhc.c | 241 +++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc.h | 146 +++++++++++++++++++++++++++
net/6lowpan/nhc_dest.c | 28 ++++++
net/6lowpan/nhc_fragment.c | 27 +++++
net/6lowpan/nhc_hop.c | 27 +++++
net/6lowpan/nhc_ipv6.c | 27 +++++
net/6lowpan/nhc_mobility.c | 27 +++++
net/6lowpan/nhc_routing.c | 27 +++++
net/6lowpan/nhc_udp.c | 157 +++++++++++++++++++++++++++++
12 files changed, 806 insertions(+), 171 deletions(-)
create mode 100644 net/6lowpan/nhc.c
create mode 100644 net/6lowpan/nhc.h
create mode 100644 net/6lowpan/nhc_dest.c
create mode 100644 net/6lowpan/nhc_fragment.c
create mode 100644 net/6lowpan/nhc_hop.c
create mode 100644 net/6lowpan/nhc_ipv6.c
create mode 100644 net/6lowpan/nhc_mobility.c
create mode 100644 net/6lowpan/nhc_routing.c
create mode 100644 net/6lowpan/nhc_udp.c

--
2.2.1


2015-01-12 09:23:59

by Jukka Rissanen

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

Hi Alex,

On pe, 2015-01-09 at 16:42 +0100, Alexander Aring wrote:
> This patch series introduce the next header compression framework. Currently
> we support udp compression/uncompression only. This framework allow to add new
> next header compression formats easily.
>
> If somebody wants to add a new header compression format and some information
> are missing while calling compression and uncompression callbacks. Please
> feel free to make framework changes according these callbacks.
>
> changes since v2:
> - make udp nhc as module as suggested by Marcel Holtmann
> - fix comment header in nhc_udp.c
>
> I didn't make the lowpan_nhc declaration "const" because this will occur
> issues with rb_node, id and idmask array. Which will manipulated during
> runtime.
>
> changes since v3:
> - add patch 3/3 for other known rfc6282 ipv6 extension headers compression
> formats
> - add request_modules for loading nhc default compression format modules.
> Which was suggested by Jukka Rissanen. Thanks, this is really working.
> - Add rtnl_lock for lowpan_nhc_add and del since we have no synced
> request_modules call this could make trouble.
> - Move some handling out of nhc_do_compression and uncompression function.
> The complete handling is now inside of iphc.c and nhc_do_compression and
> uncompression functions is only a wrapper call for the callback.
> - rework some menuentries for Kconfig and compression format, they are
> grouped by rfc now.
> - move some generic handling like "skb_pull(skb, nhc->nexthdrlen);" into
> iphc.c. It would be great if we have something also for uncompression
> for the skb_cow. But this isn't possible right now.
> - change warning if nhc was not found to "was not found" instead isn't
> implemented. It isn't implemented if callbacks are NULL now.
> - small cleanups.
>
> changes since v4:
> - add spinlock for to prevent nhc from deletion while using. This can occur
> if nhc module is unloading while compression/uncompression.
> - move nhc handling for nhc compression/uncompression completely into
> nhc_do_compression/nhc_do_uncompression.
>
> Note about locking:
>
> We have now a spinlock nhc_lowpan_lock which prevents manipulating the nhc
> datastructures while using it. On receiving side it's easy to handle, at the
> end we check if 6lowpan nh compressed flag is set and run uncompression.
> On the other hand the transmit side is complicated, we check if next_hdr field
> is registrated and run some other compression routines, at least we do the
> finally nhc compression which depends on the first check if next_hdr was
> registrated. The kernel will crash if we remove the using module between
> "next_hdr check" and "do nhc compression", the lock will prevent that now.
>
> Now in the transmit path exist a little window to remove a lowpan_nhc while
> compression. This is exactly the part between "check if we support" and
> "doing compression". This is a very unlikely case, if this occurs we drop
> the packet while compression. Don't know how to better deal with that right
> now. I will try to search a better solution later.
>
> changes since v5:
> - s/rfc6282// on filenames and kconfig entries, suggested by Marcel Holtmann
> and Stefan Schmidt
> - s/FRAG/FRAGMENT/ - suggested by Stefan Schmidt
> - s/MOBIL/MOBILITY/ - suggested by Stefan Schmidt
> - s/ROUTE/ROUTING/ - suggested by Stefan Schmidt
> - replace "depends on 6LOWPAN_NHC" with a global "if 6LOWPAN_NHC
> $LOT_OF_ENTRIES endif" inside net/6lowpan/Kconfig
> - fix small typo "nhc" -> "nhcs" in net/6lowpan/Makefile
> - add MODULE_DESCRIPTION to each NHC module
>
> Cc: Jukka Rissanen <[email protected]>
> Cc: Martin Townsend <[email protected]>
> Cc: Marcel Holtmann <[email protected]>
> Cc: Stefan Schmidt <[email protected]>
>
> Alexander Aring (3):
> 6lowpan: add generic nhc layer interface
> 6lowpan: add udp compression via nhc layer
> 6lowpan: nhc: add other known rfc6282 compressions
>
> net/6lowpan/Kconfig | 57 ++++++++++-
> net/6lowpan/Makefile | 13 ++-
> net/6lowpan/iphc.c | 200 ++++++-------------------------------
> net/6lowpan/nhc.c | 241 +++++++++++++++++++++++++++++++++++++++++++++
> net/6lowpan/nhc.h | 146 +++++++++++++++++++++++++++
> net/6lowpan/nhc_dest.c | 28 ++++++
> net/6lowpan/nhc_fragment.c | 27 +++++
> net/6lowpan/nhc_hop.c | 27 +++++
> net/6lowpan/nhc_ipv6.c | 27 +++++
> net/6lowpan/nhc_mobility.c | 27 +++++
> net/6lowpan/nhc_routing.c | 27 +++++
> net/6lowpan/nhc_udp.c | 157 +++++++++++++++++++++++++++++
> 12 files changed, 806 insertions(+), 171 deletions(-)
> create mode 100644 net/6lowpan/nhc.c
> create mode 100644 net/6lowpan/nhc.h
> create mode 100644 net/6lowpan/nhc_dest.c
> create mode 100644 net/6lowpan/nhc_fragment.c
> create mode 100644 net/6lowpan/nhc_hop.c
> create mode 100644 net/6lowpan/nhc_ipv6.c
> create mode 100644 net/6lowpan/nhc_mobility.c
> create mode 100644 net/6lowpan/nhc_routing.c
> create mode 100644 net/6lowpan/nhc_udp.c
>


Acked-by: Jukka Rissanen <[email protected]>


Cheers,
Jukka

2015-01-09 16:30:10

by Stefan Schmidt

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 2/3] 6lowpan: add udp compression via nhc layer

Hello.

On 09/01/15 16:42, Alexander Aring wrote:
> This patch move UDP header compression and uncompression into the
> generic 6LoWPAN nhc header compression layer. Moreover this patch
> activates the nhc layer compression in iphc compression and
> uncompression functions.
>
> Signed-off-by: Alexander Aring <[email protected]>
> Cc: Jukka Rissanen <[email protected]>
> Cc: Martin Townsend <[email protected]>
> ---
> net/6lowpan/Kconfig | 19 ++++-
> net/6lowpan/Makefile | 5 +-
> net/6lowpan/iphc.c | 194
> +++++++-------------------------------------------
> net/6lowpan/nhc_udp.c | 157 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 205 insertions(+), 170 deletions(-)
> create mode 100644 net/6lowpan/nhc_udp.c
>
> diff --git a/net/6lowpan/Kconfig b/net/6lowpan/Kconfig
> index e4a02ef..e45c963 100644
> --- a/net/6lowpan/Kconfig
> +++ b/net/6lowpan/Kconfig
> @@ -1,6 +1,23 @@
> -config 6LOWPAN
> +menuconfig 6LOWPAN
> tristate "6LoWPAN Support"
> depends on IPV6
> ---help---
> This enables IPv6 over Low power Wireless Personal Area Network
> -
> "6LoWPAN" which is supported by IEEE 802.15.4 or Bluetooth
> stacks.
> +
> +menuconfig 6LOWPAN_NHC
> + tristate "Next Header Compression Support"
> + depends on 6LOWPAN
> + default y
> + ---help---
> + Support for next header compression.
> +
> +if 6LOWPAN_NHC
> +
> +config 6LOWPAN_NHC_UDP
> + tristate "UDP Header Support"
> + default y
> + ---help---
> + 6LoWPAN IPv6 UDP Header compression according to RFC6282.
> +
> +endif
> diff --git a/net/6lowpan/Makefile b/net/6lowpan/Makefile
> index 4215602..abf551d 100644
> --- a/net/6lowpan/Makefile
> +++ b/net/6lowpan/Makefile
> @@ -1,3 +1,6 @@
> -obj-$(CONFIG_6LOWPAN) := 6lowpan.o
> +obj-$(CONFIG_6LOWPAN) += 6lowpan.o
>
> 6lowpan-y := iphc.o nhc.o
> +
> +#rfc6282 nhcs
> +obj-$(CONFIG_6LOWPAN_NHC_UDP) += nhc_udp.o
> diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
> index 32ffec6..390bdd9 100644
> --- a/net/6lowpan/iphc.c
> +++ b/net/6lowpan/iphc.c
> @@ -54,6 +54,8 @@
> #include <net/ipv6.h>
> #include <net/af_ieee802154.h>
>
> +#include "nhc.h"
> +
> /* Uncompress address function for source and
> * destination address(non-multicast).
> *
> @@ -224,77 +226,6 @@ static int lowpan_uncompress_multicast_daddr(struct
> sk_buff *skb,
> return 0;
> }
>
> -static int uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh)
> -{
> - bool fail;
> - u8 tmp = 0, val = 0;
> -
> - fail = lowpan_fetch_skb(skb, &tmp, sizeof(tmp));
> -
> - if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) {
> - pr_debug("UDP header uncompression\n");
> - switch (tmp & LOWPAN_NHC_UDP_CS_P_11) {
> - case LOWPAN_NHC_UDP_CS_P_00:
> - fail |= lowpan_fetch_skb(skb, &uh->source,
> - sizeof(uh->source));
> - fail |= lowpan_fetch_skb(skb, &uh->dest,
> - sizeof(uh->dest));
> - break;
> - case LOWPAN_NHC_UDP_CS_P_01:
> - fail |= lowpan_fetch_skb(skb, &uh->source,
> - sizeof(uh->source));
> - fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
> - uh->dest = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
> - break;
> - case LOWPAN_NHC_UDP_CS_P_10:
> - fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
> - uh->source = htons(val +
> LOWPAN_NHC_UDP_8BIT_PORT);
> - fail |= lowpan_fetch_skb(skb, &uh->dest,
> - sizeof(uh->dest));
> - break;
> - case LOWPAN_NHC_UDP_CS_P_11:
> - fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
> - uh->source = htons(LOWPAN_NHC_UDP_4BIT_PORT +
> - (val >> 4));
> - uh->dest = htons(LOWPAN_NHC_UDP_4BIT_PORT +
> - (val & 0x0f));
> - break;
> - default:
> - pr_debug("ERROR: unknown UDP format\n");
> - goto err;
> - }
> -
> - pr_debug("uncompressed UDP ports: src = %d, dst = %d\n",
> - ntohs(uh->source), ntohs(uh->dest));
> -
> - /* checksum */
> - if (tmp & LOWPAN_NHC_UDP_CS_C) {
> - pr_debug_ratelimited("checksum elided currently
> not supported\n");
> - goto err;
> - } else {
> - fail |= lowpan_fetch_skb(skb, &uh->check,
> - sizeof(uh->check));
> - }
> -
> - /* UDP length needs to be infered from the lower layers
> - * here, we obtain the hint from the remaining size of the
> - * frame
> - */
> - uh->len = htons(skb->len + sizeof(struct udphdr));
> - pr_debug("uncompressed UDP length: src = %d",
> ntohs(uh->len));
> - } else {
> - pr_debug("ERROR: unsupported NH format\n");
> - goto err;
> - }
> -
> - if (fail)
> - goto err;
> -
> - return 0;
> -err:
> - return -EINVAL;
> -}
> -
> /* TTL uncompression values */
> static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
>
> @@ -425,29 +356,11 @@ lowpan_header_decompress(struct sk_buff *skb, struct
> net_device *dev,
> return -EINVAL;
> }
>
> - /* UDP data uncompression */
> + /* Next header data uncompression */
> if (iphc0 & LOWPAN_IPHC_NH_C) {
> - struct udphdr uh;
> - const int needed = sizeof(struct udphdr) + sizeof(hdr);
> -
> - if (uncompress_udp_header(skb, &uh))
> - return -EINVAL;
> -
> - /* replace the compressed UDP head by the uncompressed UDP
> - * header
> - */
> - err = skb_cow(skb, needed);
> - if (unlikely(err))
> + err = lowpan_nhc_do_uncompression(skb, dev, &hdr);
> + if (err < 0)
> return err;
> -
> - skb_push(skb, sizeof(struct udphdr));
> - skb_reset_transport_header(skb);
> - skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr));
> -
> - raw_dump_table(__func__, "raw UDP header dump",
> - (u8 *)&uh, sizeof(uh));
> -
> - hdr.nexthdr = UIP_PROTO_UDP;
> } else {
> err = skb_cow(skb, sizeof(hdr));
> if (unlikely(err))
> @@ -500,71 +413,6 @@ static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8
> shift,
> return rol8(val, shift);
> }
>
> -static void compress_udp_header(u8 **hc_ptr, struct sk_buff *skb)
> -{
> - struct udphdr *uh;
> - u8 tmp;
> -
> - /* In the case of RAW sockets the transport header is not set by
> - * the ip6 stack so we must set it ourselves
> - */
> - if (skb->transport_header == skb->network_header)
> - skb_set_transport_header(skb, sizeof(struct ipv6hdr));
> -
> - uh = udp_hdr(skb);
> -
> - if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) ==
> - LOWPAN_NHC_UDP_4BIT_PORT) &&
> - ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) ==
> - LOWPAN_NHC_UDP_4BIT_PORT)) {
> - pr_debug("UDP header: both ports compression to 4
> bits\n");
> - /* compression value */
> - tmp = LOWPAN_NHC_UDP_CS_P_11;
> - lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> - /* source and destination port */
> - tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_4BIT_PORT +
> - ((ntohs(uh->source) - LOWPAN_NHC_UDP_4BIT_PORT) <<
> 4);
> - lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> - } else if ((ntohs(uh->dest) & LOWPAN_NHC_UDP_8BIT_MASK) ==
> - LOWPAN_NHC_UDP_8BIT_PORT) {
> - pr_debug("UDP header: remove 8 bits of dest\n");
> - /* compression value */
> - tmp = LOWPAN_NHC_UDP_CS_P_01;
> - lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> - /* source port */
> - lowpan_push_hc_data(hc_ptr, &uh->source,
> sizeof(uh->source));
> - /* destination port */
> - tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_8BIT_PORT;
> - lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> - } else if ((ntohs(uh->source) & LOWPAN_NHC_UDP_8BIT_MASK) ==
> - LOWPAN_NHC_UDP_8BIT_PORT) {
> - pr_debug("UDP header: remove 8 bits of source\n");
> - /* compression value */
> - tmp = LOWPAN_NHC_UDP_CS_P_10;
> - lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> - /* source port */
> - tmp = ntohs(uh->source) - LOWPAN_NHC_UDP_8BIT_PORT;
> - lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> - /* destination port */
> - lowpan_push_hc_data(hc_ptr, &uh->dest, sizeof(uh->dest));
> - } else {
> - pr_debug("UDP header: can't compress\n");
> - /* compression value */
> - tmp = LOWPAN_NHC_UDP_CS_P_00;
> - lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> - /* source port */
> - lowpan_push_hc_data(hc_ptr, &uh->source,
> sizeof(uh->source));
> - /* destination port */
> - lowpan_push_hc_data(hc_ptr, &uh->dest, sizeof(uh->dest));
> - }
> -
> - /* checksum is always inline */
> - lowpan_push_hc_data(hc_ptr, &uh->check, sizeof(uh->check));
> -
> - /* skip the UDP header */
> - skb_pull(skb, sizeof(struct udphdr));
> -}
> -
> int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
> unsigned short type, const void *_daddr,
> const void *_saddr, unsigned int len)
> @@ -572,7 +420,7 @@ int lowpan_header_compress(struct sk_buff *skb, struct
> net_device *dev,
> u8 tmp, iphc0, iphc1, *hc_ptr;
> struct ipv6hdr *hdr;
> u8 head[100] = {};
> - int addr_type;
> + int ret, addr_type;
>
> if (type != ETH_P_IPV6)
> return -EINVAL;
> @@ -649,13 +497,12 @@ int lowpan_header_compress(struct sk_buff *skb,
> struct net_device *dev,
>
> /* NOTE: payload length is always compressed */
>
> - /* Next Header is compress if UDP */
> - if (hdr->nexthdr == UIP_PROTO_UDP)
> - iphc0 |= LOWPAN_IPHC_NH_C;
> -
> - if ((iphc0 & LOWPAN_IPHC_NH_C) == 0)
> - lowpan_push_hc_data(&hc_ptr, &hdr->nexthdr,
> - sizeof(hdr->nexthdr));
> + /* Check if we provide the nhc format for nexthdr and compression
> + * functionality. If not nexthdr is handled inline and not
> compressed.
> + */
> + ret = lowpan_nhc_check_compression(skb, hdr, &hc_ptr, &iphc0);
> + if (ret < 0)
> + return ret;
>
> /* Hop limit
> * if 1: compress, encoding is 01
> @@ -741,9 +588,12 @@ int lowpan_header_compress(struct sk_buff *skb,
> struct net_device *dev,
> }
> }
>
> - /* UDP header compression */
> - if (hdr->nexthdr == UIP_PROTO_UDP)
> - compress_udp_header(&hc_ptr, skb);
> + /* next header compression */
> + if (iphc0 & LOWPAN_IPHC_NH_C) {
> + ret = lowpan_nhc_do_compression(skb, hdr, &hc_ptr);
> + if (ret < 0)
> + return ret;
> + }
>
> head[0] = iphc0;
> head[1] = iphc1;
> @@ -761,4 +611,12 @@ int lowpan_header_compress(struct sk_buff *skb,
> struct net_device *dev,
> }
> EXPORT_SYMBOL_GPL(lowpan_header_compress);
>
> +static int __init lowpan_module_init(void)
> +{
> + request_module_nowait("nhc_udp");
> +
> + return 0;
> +}
> +module_init(lowpan_module_init);
> +
> MODULE_LICENSE("GPL");
> diff --git a/net/6lowpan/nhc_udp.c b/net/6lowpan/nhc_udp.c
> new file mode 100644
> index 0000000..c6bcaeb
> --- /dev/null
> +++ b/net/6lowpan/nhc_udp.c
> @@ -0,0 +1,157 @@
> +/*
> + * 6LoWPAN IPv6 UDP compression according to RFC6282
> + *
> + *
> + * Authors:
> + * Alexander Aring <[email protected]>
> + *
> + * Orignal written by:
> + * Alexander Smirnov <[email protected]>
> + * Jon Smirl <[email protected]>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include "nhc.h"
> +
> +#define LOWPAN_NHC_UDP_IDLEN 1
> +
> +static int udp_uncompress(struct sk_buff *skb, size_t needed)
> +{
> + u8 tmp = 0, val = 0;
> + struct udphdr uh;
> + bool fail;
> + int err;
> +
> + fail = lowpan_fetch_skb(skb, &tmp, sizeof(tmp));
> +
> + pr_debug("UDP header uncompression\n");
> + switch (tmp & LOWPAN_NHC_UDP_CS_P_11) {
> + case LOWPAN_NHC_UDP_CS_P_00:
> + fail |= lowpan_fetch_skb(skb, &uh.source,
> sizeof(uh.source));
> + fail |= lowpan_fetch_skb(skb, &uh.dest, sizeof(uh.dest));
> + break;
> + case LOWPAN_NHC_UDP_CS_P_01:
> + fail |= lowpan_fetch_skb(skb, &uh.source,
> sizeof(uh.source));
> + fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
> + uh.dest = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
> + break;
> + case LOWPAN_NHC_UDP_CS_P_10:
> + fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
> + uh.source = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
> + fail |= lowpan_fetch_skb(skb, &uh.dest, sizeof(uh.dest));
> + break;
> + case LOWPAN_NHC_UDP_CS_P_11:
> + fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
> + uh.source = htons(LOWPAN_NHC_UDP_4BIT_PORT + (val >> 4));
> + uh.dest = htons(LOWPAN_NHC_UDP_4BIT_PORT + (val & 0x0f));
> + break;
> + default:
> + BUG();
> + }
> +
> + pr_debug("uncompressed UDP ports: src = %d, dst = %d\n",
> + ntohs(uh.source), ntohs(uh.dest));
> +
> + /* checksum */
> + if (tmp & LOWPAN_NHC_UDP_CS_C) {
> + pr_debug_ratelimited("checksum elided currently not
> supported\n");
> + fail = true;
> + } else {
> + fail |= lowpan_fetch_skb(skb, &uh.check,
> sizeof(uh.check));
> + }
> +
> + if (fail)
> + return -EINVAL;
> +
> + /* UDP length needs to be infered from the lower layers
> + * here, we obtain the hint from the remaining size of the
> + * frame
> + */
> + uh.len = htons(skb->len + sizeof(struct udphdr));
> + pr_debug("uncompressed UDP length: src = %d", ntohs(uh.len));
> +
> + /* replace the compressed UDP head by the uncompressed UDP
> + * header
> + */
> + err = skb_cow(skb, needed);
> + if (unlikely(err))
> + return err;
> +
> + skb_push(skb, sizeof(struct udphdr));
> + skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr));
> +
> + return 0;
> +}
> +
> +static int udp_compress(struct sk_buff *skb, u8 **hc_ptr)
> +{
> + const struct udphdr *uh = udp_hdr(skb);
> + u8 tmp;
> +
> + if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) ==
> + LOWPAN_NHC_UDP_4BIT_PORT) &&
> + ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) ==
> + LOWPAN_NHC_UDP_4BIT_PORT)) {
> + pr_debug("UDP header: both ports compression to 4
> bits\n");
> + /* compression value */
> + tmp = LOWPAN_NHC_UDP_CS_P_11;
> + lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> + /* source and destination port */
> + tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_4BIT_PORT +
> + ((ntohs(uh->source) - LOWPAN_NHC_UDP_4BIT_PORT) <<
> 4);
> + lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> + } else if ((ntohs(uh->dest) & LOWPAN_NHC_UDP_8BIT_MASK) ==
> + LOWPAN_NHC_UDP_8BIT_PORT) {
> + pr_debug("UDP header: remove 8 bits of dest\n");
> + /* compression value */
> + tmp = LOWPAN_NHC_UDP_CS_P_01;
> + lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> + /* source port */
> + lowpan_push_hc_data(hc_ptr, &uh->source,
> sizeof(uh->source));
> + /* destination port */
> + tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_8BIT_PORT;
> + lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> + } else if ((ntohs(uh->source) & LOWPAN_NHC_UDP_8BIT_MASK) ==
> + LOWPAN_NHC_UDP_8BIT_PORT) {
> + pr_debug("UDP header: remove 8 bits of source\n");
> + /* compression value */
> + tmp = LOWPAN_NHC_UDP_CS_P_10;
> + lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> + /* source port */
> + tmp = ntohs(uh->source) - LOWPAN_NHC_UDP_8BIT_PORT;
> + lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> + /* destination port */
> + lowpan_push_hc_data(hc_ptr, &uh->dest, sizeof(uh->dest));
> + } else {
> + pr_debug("UDP header: can't compress\n");
> + /* compression value */
> + tmp = LOWPAN_NHC_UDP_CS_P_00;
> + lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
> + /* source port */
> + lowpan_push_hc_data(hc_ptr, &uh->source,
> sizeof(uh->source));
> + /* destination port */
> + lowpan_push_hc_data(hc_ptr, &uh->dest, sizeof(uh->dest));
> + }
> +
> + /* checksum is always inline */
> + lowpan_push_hc_data(hc_ptr, &uh->check, sizeof(uh->check));
> +
> + return 0;
> +}
> +
> +static void udp_nhid_setup(struct lowpan_nhc *nhc)
> +{
> + nhc->id[0] = LOWPAN_NHC_UDP_ID;
> + nhc->idmask[0] = LOWPAN_NHC_UDP_MASK;
> +}
> +
> +LOWPAN_NHC(nhc_udp, "RFC6282 UDP", NEXTHDR_UDP, sizeof(struct udphdr),
> + udp_nhid_setup, LOWPAN_NHC_UDP_IDLEN, udp_uncompress,
> udp_compress);
> +
> +module_lowpan_nhc(nhc_udp);
> +MODULE_DESCRIPTION("6LoWPAN next header RFC6282 UDP compression");
> +MODULE_LICENSE("GPL");
>

Reviewed-by: Stefan Schmidt <[email protected]>

regards
Stefan Schmidt



2015-01-09 16:30:27

by Stefan Schmidt

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 3/3] 6lowpan: nhc: add other known rfc6282 compressions

Hello.

On 09/01/15 16:42, Alexander Aring wrote:
> This patch adds other known rfc6282 compression formats to the nhc
> framework. These compression formats are known but not implemented yet.
> For now this is useful to printout a warning which compression format
> isn't supported.
>
> Signed-off-by: Alexander Aring <[email protected]>
> Cc: Jukka Rissanen <[email protected]>
> Cc: Martin Townsend <[email protected]>
> ---
> net/6lowpan/Kconfig | 38 ++++++++++++++++++++++++++++++++++++++
> net/6lowpan/Makefile | 6 ++++++
> net/6lowpan/iphc.c | 6 ++++++
> net/6lowpan/nhc_dest.c | 28 ++++++++++++++++++++++++++++
> net/6lowpan/nhc_fragment.c | 27 +++++++++++++++++++++++++++
> net/6lowpan/nhc_hop.c | 27 +++++++++++++++++++++++++++
> net/6lowpan/nhc_ipv6.c | 27 +++++++++++++++++++++++++++
> net/6lowpan/nhc_mobility.c | 27 +++++++++++++++++++++++++++
> net/6lowpan/nhc_routing.c | 27 +++++++++++++++++++++++++++
> 9 files changed, 213 insertions(+)
> create mode 100644 net/6lowpan/nhc_dest.c
> create mode 100644 net/6lowpan/nhc_fragment.c
> create mode 100644 net/6lowpan/nhc_hop.c
> create mode 100644 net/6lowpan/nhc_ipv6.c
> create mode 100644 net/6lowpan/nhc_mobility.c
> create mode 100644 net/6lowpan/nhc_routing.c
>
> diff --git a/net/6lowpan/Kconfig b/net/6lowpan/Kconfig
> index e45c963..7fa0f38 100644
> --- a/net/6lowpan/Kconfig
> +++ b/net/6lowpan/Kconfig
> @@ -14,6 +14,44 @@ menuconfig 6LOWPAN_NHC
>
> if 6LOWPAN_NHC
>
> +config 6LOWPAN_NHC_DEST
> + tristate "Destination Options Header Support"
> + default y
> + ---help---
> + 6LoWPAN IPv6 Destination Options Header compression according to
> + RFC6282.
> +
> +config 6LOWPAN_NHC_FRAGMENT
> + tristate "Fragment Header Support"
> + default y
> + ---help---
> + 6LoWPAN IPv6 Fragment Header compression according to RFC6282.
> +
> +config 6LOWPAN_NHC_HOP
> + tristate "Hop-by-Hop Options Header Support"
> + default y
> + ---help---
> + 6LoWPAN IPv6 Hop-by-Hop Options Header compression according to
> + RFC6282.
> +
> +config 6LOWPAN_NHC_IPV6
> + tristate "IPv6 Header Support"
> + default y
> + ---help---
> + 6LoWPAN IPv6 Header compression according to RFC6282.
> +
> +config 6LOWPAN_NHC_MOBILITY
> + tristate "Mobility Header Support"
> + default y
> + ---help---
> + 6LoWPAN IPv6 Mobility Header compression according to RFC6282.
> +
> +config 6LOWPAN_NHC_ROUTING
> + tristate "Routing Header Support"
> + default y
> + ---help---
> + 6LoWPAN IPv6 Routing Header compression according to RFC6282.
> +
> config 6LOWPAN_NHC_UDP
> tristate "UDP Header Support"
> default y
> diff --git a/net/6lowpan/Makefile b/net/6lowpan/Makefile
> index abf551d..eb8baa7 100644
> --- a/net/6lowpan/Makefile
> +++ b/net/6lowpan/Makefile
> @@ -3,4 +3,10 @@ obj-$(CONFIG_6LOWPAN) += 6lowpan.o
> 6lowpan-y := iphc.o nhc.o
>
> #rfc6282 nhcs
> +obj-$(CONFIG_6LOWPAN_NHC_DEST) += nhc_dest.o
> +obj-$(CONFIG_6LOWPAN_NHC_FRAGMENT) += nhc_fragment.o
> +obj-$(CONFIG_6LOWPAN_NHC_HOP) += nhc_hop.o
> +obj-$(CONFIG_6LOWPAN_NHC_IPV6) += nhc_ipv6.o
> +obj-$(CONFIG_6LOWPAN_NHC_MOBILITY) += nhc_mobility.o
> +obj-$(CONFIG_6LOWPAN_NHC_ROUTING) += nhc_routing.o
> obj-$(CONFIG_6LOWPAN_NHC_UDP) += nhc_udp.o
> diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
> index 390bdd9..94a375c 100644
> --- a/net/6lowpan/iphc.c
> +++ b/net/6lowpan/iphc.c
> @@ -613,6 +613,12 @@ EXPORT_SYMBOL_GPL(lowpan_header_compress);
>
> static int __init lowpan_module_init(void)
> {
> + request_module_nowait("nhc_dest");
> + request_module_nowait("nhc_fragment");
> + request_module_nowait("nhc_hop");
> + request_module_nowait("nhc_ipv6");
> + request_module_nowait("nhc_mobility");
> + request_module_nowait("nhc_routing");
> request_module_nowait("nhc_udp");
>
> return 0;
> diff --git a/net/6lowpan/nhc_dest.c b/net/6lowpan/nhc_dest.c
> new file mode 100644
> index 0000000..0b292c9
> --- /dev/null
> +++ b/net/6lowpan/nhc_dest.c
> @@ -0,0 +1,28 @@
> +/*
> + * 6LoWPAN IPv6 Destination Options Header compression according to
> + * RFC6282
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include "nhc.h"
> +
> +#define LOWPAN_NHC_DEST_IDLEN 1
> +#define LOWPAN_NHC_DEST_ID_0 0xe6
> +#define LOWPAN_NHC_DEST_MASK_0 0xfe
> +
> +static void dest_nhid_setup(struct lowpan_nhc *nhc)
> +{
> + nhc->id[0] = LOWPAN_NHC_DEST_ID_0;
> + nhc->idmask[0] = LOWPAN_NHC_DEST_MASK_0;
> +}
> +
> +LOWPAN_NHC(nhc_dest, "RFC6282 Destination Options", NEXTHDR_DEST, 0,
> + dest_nhid_setup, LOWPAN_NHC_DEST_IDLEN, NULL, NULL);
> +
> +module_lowpan_nhc(nhc_dest);
> +MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Destination Options
> compression");
> +MODULE_LICENSE("GPL");
> diff --git a/net/6lowpan/nhc_fragment.c b/net/6lowpan/nhc_fragment.c
> new file mode 100644
> index 0000000..473dbc5
> --- /dev/null
> +++ b/net/6lowpan/nhc_fragment.c
> @@ -0,0 +1,27 @@
> +/*
> + * 6LoWPAN IPv6 Fragment Header compression according to RFC6282
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include "nhc.h"
> +
> +#define LOWPAN_NHC_FRAGMENT_IDLEN 1
> +#define LOWPAN_NHC_FRAGMENT_ID_0 0xe4
> +#define LOWPAN_NHC_FRAGMENT_MASK_0 0xfe
> +
> +static void fragment_nhid_setup(struct lowpan_nhc *nhc)
> +{
> + nhc->id[0] = LOWPAN_NHC_FRAGMENT_ID_0;
> + nhc->idmask[0] = LOWPAN_NHC_FRAGMENT_MASK_0;
> +}
> +
> +LOWPAN_NHC(nhc_fragment, "RFC6282 Fragment", NEXTHDR_FRAGMENT, 0,
> + fragment_nhid_setup, LOWPAN_NHC_FRAGMENT_IDLEN, NULL, NULL);
> +
> +module_lowpan_nhc(nhc_fragment);
> +MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Fragment compression");
> +MODULE_LICENSE("GPL");
> diff --git a/net/6lowpan/nhc_hop.c b/net/6lowpan/nhc_hop.c
> new file mode 100644
> index 0000000..1eb66be
> --- /dev/null
> +++ b/net/6lowpan/nhc_hop.c
> @@ -0,0 +1,27 @@
> +/*
> + * 6LoWPAN IPv6 Hop-by-Hop Options Header compression according to
> RFC6282
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include "nhc.h"
> +
> +#define LOWPAN_NHC_HOP_IDLEN 1
> +#define LOWPAN_NHC_HOP_ID_0 0xe0
> +#define LOWPAN_NHC_HOP_MASK_0 0xfe
> +
> +static void hop_nhid_setup(struct lowpan_nhc *nhc)
> +{
> + nhc->id[0] = LOWPAN_NHC_HOP_ID_0;
> + nhc->idmask[0] = LOWPAN_NHC_HOP_MASK_0;
> +}
> +
> +LOWPAN_NHC(nhc_hop, "RFC6282 Hop-by-Hop Options", NEXTHDR_HOP, 0,
> + hop_nhid_setup, LOWPAN_NHC_HOP_IDLEN, NULL, NULL);
> +
> +module_lowpan_nhc(nhc_hop);
> +MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Hop-by-Hop Options
> compression");
> +MODULE_LICENSE("GPL");
> diff --git a/net/6lowpan/nhc_ipv6.c b/net/6lowpan/nhc_ipv6.c
> new file mode 100644
> index 0000000..2313d16
> --- /dev/null
> +++ b/net/6lowpan/nhc_ipv6.c
> @@ -0,0 +1,27 @@
> +/*
> + * 6LoWPAN IPv6 Header compression according to RFC6282
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include "nhc.h"
> +
> +#define LOWPAN_NHC_IPV6_IDLEN 1
> +#define LOWPAN_NHC_IPV6_ID_0 0xee
> +#define LOWPAN_NHC_IPV6_MASK_0 0xfe
> +
> +static void ipv6_nhid_setup(struct lowpan_nhc *nhc)
> +{
> + nhc->id[0] = LOWPAN_NHC_IPV6_ID_0;
> + nhc->idmask[0] = LOWPAN_NHC_IPV6_MASK_0;
> +}
> +
> +LOWPAN_NHC(nhc_ipv6, "RFC6282 IPv6", NEXTHDR_IPV6, 0, ipv6_nhid_setup,
> + LOWPAN_NHC_IPV6_IDLEN, NULL, NULL);
> +
> +module_lowpan_nhc(nhc_ipv6);
> +MODULE_DESCRIPTION("6LoWPAN next header RFC6282 IPv6 compression");
> +MODULE_LICENSE("GPL");
> diff --git a/net/6lowpan/nhc_mobility.c b/net/6lowpan/nhc_mobility.c
> new file mode 100644
> index 0000000..60d3f38
> --- /dev/null
> +++ b/net/6lowpan/nhc_mobility.c
> @@ -0,0 +1,27 @@
> +/*
> + * 6LoWPAN IPv6 Mobility Header compression according to RFC6282
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include "nhc.h"
> +
> +#define LOWPAN_NHC_MOBILITY_IDLEN 1
> +#define LOWPAN_NHC_MOBILITY_ID_0 0xe8
> +#define LOWPAN_NHC_MOBILITY_MASK_0 0xfe
> +
> +static void mobility_nhid_setup(struct lowpan_nhc *nhc)
> +{
> + nhc->id[0] = LOWPAN_NHC_MOBILITY_ID_0;
> + nhc->idmask[0] = LOWPAN_NHC_MOBILITY_MASK_0;
> +}
> +
> +LOWPAN_NHC(nhc_mobility, "RFC6282 Mobility", NEXTHDR_MOBILITY, 0,
> + mobility_nhid_setup, LOWPAN_NHC_MOBILITY_IDLEN, NULL, NULL);
> +
> +module_lowpan_nhc(nhc_mobility);
> +MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Mobility compression");
> +MODULE_LICENSE("GPL");
> diff --git a/net/6lowpan/nhc_routing.c b/net/6lowpan/nhc_routing.c
> new file mode 100644
> index 0000000..c393280
> --- /dev/null
> +++ b/net/6lowpan/nhc_routing.c
> @@ -0,0 +1,27 @@
> +/*
> + * 6LoWPAN IPv6 Routing Header compression according to RFC6282
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include "nhc.h"
> +
> +#define LOWPAN_NHC_ROUTING_IDLEN 1
> +#define LOWPAN_NHC_ROUTING_ID_0 0xe2
> +#define LOWPAN_NHC_ROUTING_MASK_0 0xfe
> +
> +static void routing_nhid_setup(struct lowpan_nhc *nhc)
> +{
> + nhc->id[0] = LOWPAN_NHC_ROUTING_ID_0;
> + nhc->idmask[0] = LOWPAN_NHC_ROUTING_MASK_0;
> +}
> +
> +LOWPAN_NHC(nhc_routing, "RFC6282 Routing", NEXTHDR_ROUTING, 0,
> + routing_nhid_setup, LOWPAN_NHC_ROUTING_IDLEN, NULL, NULL);
> +
> +module_lowpan_nhc(nhc_routing);
> +MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Routing compression");
> +MODULE_LICENSE("GPL");
>

Reviewed-by: Stefan Schmidt <[email protected]>

regards
Stefan Schmidt



2015-01-09 16:30:06

by Stefan Schmidt

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 1/3] 6lowpan: add generic nhc layer interface

Hello.

On 09/01/15 16:42, Alexander Aring wrote:
> This patch adds a generic next header compression layer interface. There
> exists various methods to do a header compression after 6LoWPAN header
> to save payload. This introduce a generic nhc header which allow a
> simple adding of a new header compression format instead of a static
> implementation inside the 6LoWPAN header compression and uncompression
> function.
>
> Signed-off-by: Alexander Aring <[email protected]>
> Cc: Jukka Rissanen <[email protected]>
> Cc: Martin Townsend <[email protected]>
> ---
> net/6lowpan/Makefile | 2 +-
> net/6lowpan/nhc.c | 241
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> net/6lowpan/nhc.h | 146 +++++++++++++++++++++++++++++++
> 3 files changed, 388 insertions(+), 1 deletion(-)
> create mode 100644 net/6lowpan/nhc.c
> create mode 100644 net/6lowpan/nhc.h
>
> diff --git a/net/6lowpan/Makefile b/net/6lowpan/Makefile
> index 415886b..4215602 100644
> --- a/net/6lowpan/Makefile
> +++ b/net/6lowpan/Makefile
> @@ -1,3 +1,3 @@
> obj-$(CONFIG_6LOWPAN) := 6lowpan.o
>
> -6lowpan-y := iphc.o
> +6lowpan-y := iphc.o nhc.o
> diff --git a/net/6lowpan/nhc.c b/net/6lowpan/nhc.c
> new file mode 100644
> index 0000000..3c0dc77b0
> --- /dev/null
> +++ b/net/6lowpan/nhc.c
> @@ -0,0 +1,241 @@
> +/*
> + * 6LoWPAN next header compression
> + *
> + *
> + * Authors:
> + * Alexander Aring <[email protected]>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/netdevice.h>
> +
> +#include <net/ipv6.h>
> +
> +#include "nhc.h"
> +
> +static struct rb_root rb_root = RB_ROOT;
> +static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
> +static DEFINE_SPINLOCK(lowpan_nhc_lock);
> +
> +static int lowpan_nhc_insert(struct lowpan_nhc *nhc)
> +{
> + struct rb_node **new = &rb_root.rb_node, *parent = NULL;
> +
> + /* Figure out where to put new node */
> + while (*new) {
> + struct lowpan_nhc *this = container_of(*new, struct
> lowpan_nhc,
> + node);
> + int result, len_dif, len;
> +
> + len_dif = nhc->idlen - this->idlen;
> +
> + if (nhc->idlen < this->idlen)
> + len = nhc->idlen;
> + else
> + len = this->idlen;
> +
> + result = memcmp(nhc->id, this->id, len);
> + if (!result)
> + result = len_dif;
> +
> + parent = *new;
> + if (result < 0)
> + new = &((*new)->rb_left);
> + else if (result > 0)
> + new = &((*new)->rb_right);
> + else
> + return -EEXIST;
> + }
> +
> + /* Add new node and rebalance tree. */
> + rb_link_node(&nhc->node, parent, new);
> + rb_insert_color(&nhc->node, &rb_root);
> +
> + return 0;
> +}
> +
> +static void lowpan_nhc_remove(struct lowpan_nhc *nhc)
> +{
> + rb_erase(&nhc->node, &rb_root);
> +}
> +
> +static struct lowpan_nhc *lowpan_nhc_by_nhcid(const struct sk_buff *skb)
> +{
> + struct rb_node *node = rb_root.rb_node;
> + const u8 *nhcid_skb_ptr = skb->data;
> +
> + while (node) {
> + struct lowpan_nhc *nhc = container_of(node, struct
> lowpan_nhc,
> + node);
> + u8 nhcid_skb_ptr_masked[LOWPAN_NHC_MAX_ID_LEN];
> + int result, i;
> +
> + if (nhcid_skb_ptr + nhc->idlen > skb->data + skb->len)
> + return NULL;
> +
> + /* copy and mask afterwards the nhid value from skb */
> + memcpy(nhcid_skb_ptr_masked, nhcid_skb_ptr, nhc->idlen);
> + for (i = 0; i < nhc->idlen; i++)
> + nhcid_skb_ptr_masked[i] &= nhc->idmask[i];
> +
> + result = memcmp(nhcid_skb_ptr_masked, nhc->id,
> nhc->idlen);
> + if (result < 0)
> + node = node->rb_left;
> + else if (result > 0)
> + node = node->rb_right;
> + else
> + return nhc;
> + }
> +
> + return NULL;
> +}
> +
> +int lowpan_nhc_check_compression(struct sk_buff *skb,
> + const struct ipv6hdr *hdr, u8 **hc_ptr,
> + u8 *iphc0)
> +{
> + struct lowpan_nhc *nhc;
> +
> + spin_lock_bh(&lowpan_nhc_lock);
> +
> + nhc = lowpan_nexthdr_nhcs[hdr->nexthdr];
> + if (nhc && nhc->compress)
> + *iphc0 |= LOWPAN_IPHC_NH_C;
> + else
> + lowpan_push_hc_data(hc_ptr, &hdr->nexthdr,
> + sizeof(hdr->nexthdr));
> +
> + spin_unlock_bh(&lowpan_nhc_lock);
> +
> + return 0;
> +}
> +
> +int lowpan_nhc_do_compression(struct sk_buff *skb, const struct ipv6hdr
> *hdr,
> + u8 **hc_ptr)
> +{
> + int ret;
> + struct lowpan_nhc *nhc;
> +
> + spin_lock_bh(&lowpan_nhc_lock);
> +
> + nhc = lowpan_nexthdr_nhcs[hdr->nexthdr];
> + /* check if the nhc module was removed in unlocked part.
> + * TODO: this is a workaround we should prevent unloading
> + * of nhc modules while unlocked part, this will always drop
> + * the lowpan packet but it's very unlikely.
> + *
> + * Solution isn't easy because we need to decide at
> + * lowpan_nhc_check_compression if we do a compression or not.
> + * Because the inline data which is added to skb, we can't move
> this
> + * handling.
> + */
> + if (unlikely(!nhc || !nhc->compress)) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + /* In the case of RAW sockets the transport header is not set by
> + * the ip6 stack so we must set it ourselves
> + */
> + if (skb->transport_header == skb->network_header)
> + skb_set_transport_header(skb, sizeof(struct ipv6hdr));
> +
> + ret = nhc->compress(skb, hc_ptr);
> + if (ret < 0)
> + goto out;
> +
> + /* skip the transport header */
> + skb_pull(skb, nhc->nexthdrlen);
> +
> +out:
> + spin_unlock_bh(&lowpan_nhc_lock);
> +
> + return ret;
> +}
> +
> +int lowpan_nhc_do_uncompression(struct sk_buff *skb, struct net_device
> *dev,
> + struct ipv6hdr *hdr)
> +{
> + struct lowpan_nhc *nhc;
> + int ret;
> +
> + spin_lock_bh(&lowpan_nhc_lock);
> +
> + nhc = lowpan_nhc_by_nhcid(skb);
> + if (nhc) {
> + if (nhc->uncompress) {
> + ret = nhc->uncompress(skb, sizeof(struct ipv6hdr)
> +
> + nhc->nexthdrlen);
> + if (ret < 0) {
> + spin_unlock_bh(&lowpan_nhc_lock);
> + return ret;
> + }
> + } else {
> + spin_unlock_bh(&lowpan_nhc_lock);
> + netdev_warn(dev, "received nhc id for %s which is
> not implemented.\n",
> + nhc->name);
> + return -ENOTSUPP;
> + }
> + } else {
> + spin_unlock_bh(&lowpan_nhc_lock);
> + netdev_warn(dev, "received unknown nhc id which was not
> found.\n");
> + return -ENOENT;
> + }
> +
> + hdr->nexthdr = nhc->nexthdr;
> + skb_reset_transport_header(skb);
> + raw_dump_table(__func__, "raw transport header dump",
> + skb_transport_header(skb), nhc->nexthdrlen);
> +
> + spin_unlock_bh(&lowpan_nhc_lock);
> +
> + return 0;
> +}
> +
> +int lowpan_nhc_add(struct lowpan_nhc *nhc)
> +{
> + int ret;
> +
> + if (!nhc->idlen || !nhc->idsetup)
> + return -EINVAL;
> +
> + WARN_ONCE(nhc->idlen > LOWPAN_NHC_MAX_ID_LEN,
> + "LOWPAN_NHC_MAX_ID_LEN should be updated to %d.\n",
> + nhc->idlen);
> +
> + nhc->idsetup(nhc);
> +
> + spin_lock_bh(&lowpan_nhc_lock);
> +
> + if (lowpan_nexthdr_nhcs[nhc->nexthdr]) {
> + ret = -EEXIST;
> + goto out;
> + }
> +
> + ret = lowpan_nhc_insert(nhc);
> + if (ret < 0)
> + goto out;
> +
> + lowpan_nexthdr_nhcs[nhc->nexthdr] = nhc;
> +out:
> + spin_unlock_bh(&lowpan_nhc_lock);
> + return ret;
> +}
> +EXPORT_SYMBOL(lowpan_nhc_add);
> +
> +void lowpan_nhc_del(struct lowpan_nhc *nhc)
> +{
> + spin_lock_bh(&lowpan_nhc_lock);
> +
> + lowpan_nhc_remove(nhc);
> + lowpan_nexthdr_nhcs[nhc->nexthdr] = NULL;
> +
> + spin_unlock_bh(&lowpan_nhc_lock);
> +
> + synchronize_net();
> +}
> +EXPORT_SYMBOL(lowpan_nhc_del);
> diff --git a/net/6lowpan/nhc.h b/net/6lowpan/nhc.h
> new file mode 100644
> index 0000000..ed44938
> --- /dev/null
> +++ b/net/6lowpan/nhc.h
> @@ -0,0 +1,146 @@
> +#ifndef __6LOWPAN_NHC_H
> +#define __6LOWPAN_NHC_H
> +
> +#include <linux/skbuff.h>
> +#include <linux/rbtree.h>
> +#include <linux/module.h>
> +
> +#include <net/6lowpan.h>
> +#include <net/ipv6.h>
> +
> +#define LOWPAN_NHC_MAX_ID_LEN 1
> +
> +/**
> + * LOWPAN_NHC - helper macro to generate nh id fields and lowpan_nhc
> struct
> + *
> + * @__nhc: variable name of the lowpan_nhc struct.
> + * @_name: const char * of common header compression name.
> + * @_nexthdr: ipv6 nexthdr field for the header compression.
> + * @_nexthdrlen: ipv6 nexthdr len for the reserved space.
> + * @_idsetup: callback to setup id and mask values.
> + * @_idlen: len for the next header id and mask, should be always the
> same.
> + * @_uncompress: callback for uncompression call.
> + * @_compress: callback for compression call.
> + */
> +#define LOWPAN_NHC(__nhc, _name, _nexthdr, \
> + _hdrlen, _idsetup, _idlen, \
> + _uncompress, _compress) \
> +static u8 __nhc##_val[_idlen]; \
> +static u8 __nhc##_mask[_idlen]; \
> +static struct lowpan_nhc __nhc = { \
> + .name = _name, \
> + .nexthdr = _nexthdr, \
> + .nexthdrlen = _hdrlen, \
> + .id = __nhc##_val, \
> + .idmask = __nhc##_mask, \
> + .idlen = _idlen, \
> + .idsetup = _idsetup, \
> + .uncompress = _uncompress, \
> + .compress = _compress, \
> +}
> +
> +#define module_lowpan_nhc(__nhc) \
> +static int __init __nhc##_init(void) \
> +{ \
> + return lowpan_nhc_add(&(__nhc)); \
> +} \
> +module_init(__nhc##_init); \
> +static void __exit __nhc##_exit(void) \
> +{ \
> + lowpan_nhc_del(&(__nhc)); \
> +} \
> +module_exit(__nhc##_exit);
> +
> +/**
> + * struct lowpan_nhc - hold 6lowpan next hdr compression ifnformation
> + *
> + * @node: holder for the rbtree.
> + * @name: name of the specific next header compression
> + * @nexthdr: next header value of the protocol which should be
> compressed.
> + * @nexthdrlen: ipv6 nexthdr len for the reserved space.
> + * @id: array for nhc id. Note this need to be in network byteorder.
> + * @mask: array for nhc id mask. Note this need to be in network
> byteorder.
> + * @len: the length of the next header id and mask.
> + * @setup: callback to setup fill the next header id value and mask.
> + * @compress: callback to do the header compression.
> + * @uncompress: callback to do the header uncompression.
> + */
> +struct lowpan_nhc {
> + struct rb_node node;
> + const char *name;
> + const u8 nexthdr;
> + const size_t nexthdrlen;
> + u8 *id;
> + u8 *idmask;
> + const size_t idlen;
> +
> + void (*idsetup)(struct lowpan_nhc *nhc);
> + int (*uncompress)(struct sk_buff *skb, size_t needed);
> + int (*compress)(struct sk_buff *skb, u8 **hc_ptr);
> +};
> +
> +/**
> + * lowpan_nhc_by_nexthdr - return the 6lowpan nhc by ipv6 nexthdr.
> + *
> + * @nexthdr: ipv6 nexthdr value.
> + */
> +struct lowpan_nhc *lowpan_nhc_by_nexthdr(u8 nexthdr);
> +
> +/**
> + * lowpan_nhc_check_compression - checks if we support compression
> format. If
> + * we support the nhc by nexthdr field, the 6LoWPAN iphc NHC bit will
> be
> + * set. If we don't support nexthdr will be added as inline data to
> the
> + * 6LoWPAN header.
> + *
> + * @skb: skb of 6LoWPAN header to read nhc and replace header.
> + * @hdr: ipv6hdr to check the nexthdr value
> + * @hc_ptr: pointer for 6LoWPAN header which should increment at the end
> of
> + * replaced header.
> + * @iphc0: iphc0 pointer to set the 6LoWPAN NHC bit
> + */
> +int lowpan_nhc_check_compression(struct sk_buff *skb,
> + const struct ipv6hdr *hdr, u8 **hc_ptr,
> + u8 *iphc0);
> +
> +/**
> + * lowpan_nhc_do_compression - calling compress callback for nhc
> + *
> + * @skb: skb of 6LoWPAN header to read nhc and replace header.
> + * @hdr: ipv6hdr to set the nexthdr value
> + * @hc_ptr: pointer for 6LoWPAN header which should increment at the end
> of
> + * replaced header.
> + */
> +int lowpan_nhc_do_compression(struct sk_buff *skb, const struct ipv6hdr
> *hdr,
> + u8 **hc_ptr);
> +
> +/**
> + * lowpan_nhc_do_uncompression - calling uncompress callback for nhc
> + *
> + * @nhc: 6LoWPAN nhc context, get by lowpan_nhc_by_ functions.
> + * @skb: skb of 6LoWPAN header, skb->data should be pointed to nhc id
> value.
> + * @dev: netdevice for print logging information.
> + * @hdr: ipv6hdr for setting nexthdr value.
> + */
> +int lowpan_nhc_do_uncompression(struct sk_buff *skb, struct net_device
> *dev,
> + struct ipv6hdr *hdr);
> +
> +/**
> + * lowpan_nhc_add - register a next header compression to framework
> + *
> + * @nhc: nhc which should be add.
> + */
> +int lowpan_nhc_add(struct lowpan_nhc *nhc);
> +
> +/**
> + * lowpan_nhc_del - delete a next header compression from framework
> + *
> + * @nhc: nhc which should be delete.
> + */
> +void lowpan_nhc_del(struct lowpan_nhc *nhc);
> +
> +/**
> + * lowpan_nhc_init - adding all default nhcs
> + */
> +void lowpan_nhc_init(void);
> +
> +#endif /* __6LOWPAN_NHC_H */
>

Reviewed-by: Stefan Schmidt <[email protected]>

regards
Stefan Schmidt



2015-01-09 15:42:59

by Alexander Aring

[permalink] [raw]
Subject: [PATCHv5 bluetooth-next 3/3] 6lowpan: nhc: add other known rfc6282 compressions

This patch adds other known rfc6282 compression formats to the nhc
framework. These compression formats are known but not implemented yet.
For now this is useful to printout a warning which compression format
isn't supported.

Signed-off-by: Alexander Aring <[email protected]>
Cc: Jukka Rissanen <[email protected]>
Cc: Martin Townsend <[email protected]>
---
net/6lowpan/Kconfig | 38 ++++++++++++++++++++++++++++++++++++++
net/6lowpan/Makefile | 6 ++++++
net/6lowpan/iphc.c | 6 ++++++
net/6lowpan/nhc_dest.c | 28 ++++++++++++++++++++++++++++
net/6lowpan/nhc_fragment.c | 27 +++++++++++++++++++++++++++
net/6lowpan/nhc_hop.c | 27 +++++++++++++++++++++++++++
net/6lowpan/nhc_ipv6.c | 27 +++++++++++++++++++++++++++
net/6lowpan/nhc_mobility.c | 27 +++++++++++++++++++++++++++
net/6lowpan/nhc_routing.c | 27 +++++++++++++++++++++++++++
9 files changed, 213 insertions(+)
create mode 100644 net/6lowpan/nhc_dest.c
create mode 100644 net/6lowpan/nhc_fragment.c
create mode 100644 net/6lowpan/nhc_hop.c
create mode 100644 net/6lowpan/nhc_ipv6.c
create mode 100644 net/6lowpan/nhc_mobility.c
create mode 100644 net/6lowpan/nhc_routing.c

diff --git a/net/6lowpan/Kconfig b/net/6lowpan/Kconfig
index e45c963..7fa0f38 100644
--- a/net/6lowpan/Kconfig
+++ b/net/6lowpan/Kconfig
@@ -14,6 +14,44 @@ menuconfig 6LOWPAN_NHC

if 6LOWPAN_NHC

+config 6LOWPAN_NHC_DEST
+ tristate "Destination Options Header Support"
+ default y
+ ---help---
+ 6LoWPAN IPv6 Destination Options Header compression according to
+ RFC6282.
+
+config 6LOWPAN_NHC_FRAGMENT
+ tristate "Fragment Header Support"
+ default y
+ ---help---
+ 6LoWPAN IPv6 Fragment Header compression according to RFC6282.
+
+config 6LOWPAN_NHC_HOP
+ tristate "Hop-by-Hop Options Header Support"
+ default y
+ ---help---
+ 6LoWPAN IPv6 Hop-by-Hop Options Header compression according to
+ RFC6282.
+
+config 6LOWPAN_NHC_IPV6
+ tristate "IPv6 Header Support"
+ default y
+ ---help---
+ 6LoWPAN IPv6 Header compression according to RFC6282.
+
+config 6LOWPAN_NHC_MOBILITY
+ tristate "Mobility Header Support"
+ default y
+ ---help---
+ 6LoWPAN IPv6 Mobility Header compression according to RFC6282.
+
+config 6LOWPAN_NHC_ROUTING
+ tristate "Routing Header Support"
+ default y
+ ---help---
+ 6LoWPAN IPv6 Routing Header compression according to RFC6282.
+
config 6LOWPAN_NHC_UDP
tristate "UDP Header Support"
default y
diff --git a/net/6lowpan/Makefile b/net/6lowpan/Makefile
index abf551d..eb8baa7 100644
--- a/net/6lowpan/Makefile
+++ b/net/6lowpan/Makefile
@@ -3,4 +3,10 @@ obj-$(CONFIG_6LOWPAN) += 6lowpan.o
6lowpan-y := iphc.o nhc.o

#rfc6282 nhcs
+obj-$(CONFIG_6LOWPAN_NHC_DEST) += nhc_dest.o
+obj-$(CONFIG_6LOWPAN_NHC_FRAGMENT) += nhc_fragment.o
+obj-$(CONFIG_6LOWPAN_NHC_HOP) += nhc_hop.o
+obj-$(CONFIG_6LOWPAN_NHC_IPV6) += nhc_ipv6.o
+obj-$(CONFIG_6LOWPAN_NHC_MOBILITY) += nhc_mobility.o
+obj-$(CONFIG_6LOWPAN_NHC_ROUTING) += nhc_routing.o
obj-$(CONFIG_6LOWPAN_NHC_UDP) += nhc_udp.o
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 390bdd9..94a375c 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -613,6 +613,12 @@ EXPORT_SYMBOL_GPL(lowpan_header_compress);

static int __init lowpan_module_init(void)
{
+ request_module_nowait("nhc_dest");
+ request_module_nowait("nhc_fragment");
+ request_module_nowait("nhc_hop");
+ request_module_nowait("nhc_ipv6");
+ request_module_nowait("nhc_mobility");
+ request_module_nowait("nhc_routing");
request_module_nowait("nhc_udp");

return 0;
diff --git a/net/6lowpan/nhc_dest.c b/net/6lowpan/nhc_dest.c
new file mode 100644
index 0000000..0b292c9
--- /dev/null
+++ b/net/6lowpan/nhc_dest.c
@@ -0,0 +1,28 @@
+/*
+ * 6LoWPAN IPv6 Destination Options Header compression according to
+ * RFC6282
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_NHC_DEST_IDLEN 1
+#define LOWPAN_NHC_DEST_ID_0 0xe6
+#define LOWPAN_NHC_DEST_MASK_0 0xfe
+
+static void dest_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_DEST_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_DEST_MASK_0;
+}
+
+LOWPAN_NHC(nhc_dest, "RFC6282 Destination Options", NEXTHDR_DEST, 0,
+ dest_nhid_setup, LOWPAN_NHC_DEST_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(nhc_dest);
+MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Destination Options compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_fragment.c b/net/6lowpan/nhc_fragment.c
new file mode 100644
index 0000000..473dbc5
--- /dev/null
+++ b/net/6lowpan/nhc_fragment.c
@@ -0,0 +1,27 @@
+/*
+ * 6LoWPAN IPv6 Fragment Header compression according to RFC6282
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_NHC_FRAGMENT_IDLEN 1
+#define LOWPAN_NHC_FRAGMENT_ID_0 0xe4
+#define LOWPAN_NHC_FRAGMENT_MASK_0 0xfe
+
+static void fragment_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_FRAGMENT_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_FRAGMENT_MASK_0;
+}
+
+LOWPAN_NHC(nhc_fragment, "RFC6282 Fragment", NEXTHDR_FRAGMENT, 0,
+ fragment_nhid_setup, LOWPAN_NHC_FRAGMENT_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(nhc_fragment);
+MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Fragment compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_hop.c b/net/6lowpan/nhc_hop.c
new file mode 100644
index 0000000..1eb66be
--- /dev/null
+++ b/net/6lowpan/nhc_hop.c
@@ -0,0 +1,27 @@
+/*
+ * 6LoWPAN IPv6 Hop-by-Hop Options Header compression according to RFC6282
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_NHC_HOP_IDLEN 1
+#define LOWPAN_NHC_HOP_ID_0 0xe0
+#define LOWPAN_NHC_HOP_MASK_0 0xfe
+
+static void hop_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_HOP_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_HOP_MASK_0;
+}
+
+LOWPAN_NHC(nhc_hop, "RFC6282 Hop-by-Hop Options", NEXTHDR_HOP, 0,
+ hop_nhid_setup, LOWPAN_NHC_HOP_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(nhc_hop);
+MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Hop-by-Hop Options compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_ipv6.c b/net/6lowpan/nhc_ipv6.c
new file mode 100644
index 0000000..2313d16
--- /dev/null
+++ b/net/6lowpan/nhc_ipv6.c
@@ -0,0 +1,27 @@
+/*
+ * 6LoWPAN IPv6 Header compression according to RFC6282
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_NHC_IPV6_IDLEN 1
+#define LOWPAN_NHC_IPV6_ID_0 0xee
+#define LOWPAN_NHC_IPV6_MASK_0 0xfe
+
+static void ipv6_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_IPV6_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_IPV6_MASK_0;
+}
+
+LOWPAN_NHC(nhc_ipv6, "RFC6282 IPv6", NEXTHDR_IPV6, 0, ipv6_nhid_setup,
+ LOWPAN_NHC_IPV6_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(nhc_ipv6);
+MODULE_DESCRIPTION("6LoWPAN next header RFC6282 IPv6 compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_mobility.c b/net/6lowpan/nhc_mobility.c
new file mode 100644
index 0000000..60d3f38
--- /dev/null
+++ b/net/6lowpan/nhc_mobility.c
@@ -0,0 +1,27 @@
+/*
+ * 6LoWPAN IPv6 Mobility Header compression according to RFC6282
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_NHC_MOBILITY_IDLEN 1
+#define LOWPAN_NHC_MOBILITY_ID_0 0xe8
+#define LOWPAN_NHC_MOBILITY_MASK_0 0xfe
+
+static void mobility_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_MOBILITY_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_MOBILITY_MASK_0;
+}
+
+LOWPAN_NHC(nhc_mobility, "RFC6282 Mobility", NEXTHDR_MOBILITY, 0,
+ mobility_nhid_setup, LOWPAN_NHC_MOBILITY_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(nhc_mobility);
+MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Mobility compression");
+MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_routing.c b/net/6lowpan/nhc_routing.c
new file mode 100644
index 0000000..c393280
--- /dev/null
+++ b/net/6lowpan/nhc_routing.c
@@ -0,0 +1,27 @@
+/*
+ * 6LoWPAN IPv6 Routing Header compression according to RFC6282
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_NHC_ROUTING_IDLEN 1
+#define LOWPAN_NHC_ROUTING_ID_0 0xe2
+#define LOWPAN_NHC_ROUTING_MASK_0 0xfe
+
+static void routing_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_ROUTING_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_ROUTING_MASK_0;
+}
+
+LOWPAN_NHC(nhc_routing, "RFC6282 Routing", NEXTHDR_ROUTING, 0,
+ routing_nhid_setup, LOWPAN_NHC_ROUTING_IDLEN, NULL, NULL);
+
+module_lowpan_nhc(nhc_routing);
+MODULE_DESCRIPTION("6LoWPAN next header RFC6282 Routing compression");
+MODULE_LICENSE("GPL");
--
2.2.1


2015-01-09 15:42:58

by Alexander Aring

[permalink] [raw]
Subject: [PATCHv5 bluetooth-next 2/3] 6lowpan: add udp compression via nhc layer

This patch move UDP header compression and uncompression into the
generic 6LoWPAN nhc header compression layer. Moreover this patch
activates the nhc layer compression in iphc compression and
uncompression functions.

Signed-off-by: Alexander Aring <[email protected]>
Cc: Jukka Rissanen <[email protected]>
Cc: Martin Townsend <[email protected]>
---
net/6lowpan/Kconfig | 19 ++++-
net/6lowpan/Makefile | 5 +-
net/6lowpan/iphc.c | 194 +++++++-------------------------------------------
net/6lowpan/nhc_udp.c | 157 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 205 insertions(+), 170 deletions(-)
create mode 100644 net/6lowpan/nhc_udp.c

diff --git a/net/6lowpan/Kconfig b/net/6lowpan/Kconfig
index e4a02ef..e45c963 100644
--- a/net/6lowpan/Kconfig
+++ b/net/6lowpan/Kconfig
@@ -1,6 +1,23 @@
-config 6LOWPAN
+menuconfig 6LOWPAN
tristate "6LoWPAN Support"
depends on IPV6
---help---
This enables IPv6 over Low power Wireless Personal Area Network -
"6LoWPAN" which is supported by IEEE 802.15.4 or Bluetooth stacks.
+
+menuconfig 6LOWPAN_NHC
+ tristate "Next Header Compression Support"
+ depends on 6LOWPAN
+ default y
+ ---help---
+ Support for next header compression.
+
+if 6LOWPAN_NHC
+
+config 6LOWPAN_NHC_UDP
+ tristate "UDP Header Support"
+ default y
+ ---help---
+ 6LoWPAN IPv6 UDP Header compression according to RFC6282.
+
+endif
diff --git a/net/6lowpan/Makefile b/net/6lowpan/Makefile
index 4215602..abf551d 100644
--- a/net/6lowpan/Makefile
+++ b/net/6lowpan/Makefile
@@ -1,3 +1,6 @@
-obj-$(CONFIG_6LOWPAN) := 6lowpan.o
+obj-$(CONFIG_6LOWPAN) += 6lowpan.o

6lowpan-y := iphc.o nhc.o
+
+#rfc6282 nhcs
+obj-$(CONFIG_6LOWPAN_NHC_UDP) += nhc_udp.o
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 32ffec6..390bdd9 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -54,6 +54,8 @@
#include <net/ipv6.h>
#include <net/af_ieee802154.h>

+#include "nhc.h"
+
/* Uncompress address function for source and
* destination address(non-multicast).
*
@@ -224,77 +226,6 @@ static int lowpan_uncompress_multicast_daddr(struct sk_buff *skb,
return 0;
}

-static int uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh)
-{
- bool fail;
- u8 tmp = 0, val = 0;
-
- fail = lowpan_fetch_skb(skb, &tmp, sizeof(tmp));
-
- if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) {
- pr_debug("UDP header uncompression\n");
- switch (tmp & LOWPAN_NHC_UDP_CS_P_11) {
- case LOWPAN_NHC_UDP_CS_P_00:
- fail |= lowpan_fetch_skb(skb, &uh->source,
- sizeof(uh->source));
- fail |= lowpan_fetch_skb(skb, &uh->dest,
- sizeof(uh->dest));
- break;
- case LOWPAN_NHC_UDP_CS_P_01:
- fail |= lowpan_fetch_skb(skb, &uh->source,
- sizeof(uh->source));
- fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
- uh->dest = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
- break;
- case LOWPAN_NHC_UDP_CS_P_10:
- fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
- uh->source = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
- fail |= lowpan_fetch_skb(skb, &uh->dest,
- sizeof(uh->dest));
- break;
- case LOWPAN_NHC_UDP_CS_P_11:
- fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
- uh->source = htons(LOWPAN_NHC_UDP_4BIT_PORT +
- (val >> 4));
- uh->dest = htons(LOWPAN_NHC_UDP_4BIT_PORT +
- (val & 0x0f));
- break;
- default:
- pr_debug("ERROR: unknown UDP format\n");
- goto err;
- }
-
- pr_debug("uncompressed UDP ports: src = %d, dst = %d\n",
- ntohs(uh->source), ntohs(uh->dest));
-
- /* checksum */
- if (tmp & LOWPAN_NHC_UDP_CS_C) {
- pr_debug_ratelimited("checksum elided currently not supported\n");
- goto err;
- } else {
- fail |= lowpan_fetch_skb(skb, &uh->check,
- sizeof(uh->check));
- }
-
- /* UDP length needs to be infered from the lower layers
- * here, we obtain the hint from the remaining size of the
- * frame
- */
- uh->len = htons(skb->len + sizeof(struct udphdr));
- pr_debug("uncompressed UDP length: src = %d", ntohs(uh->len));
- } else {
- pr_debug("ERROR: unsupported NH format\n");
- goto err;
- }
-
- if (fail)
- goto err;
-
- return 0;
-err:
- return -EINVAL;
-}
-
/* TTL uncompression values */
static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };

@@ -425,29 +356,11 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
return -EINVAL;
}

- /* UDP data uncompression */
+ /* Next header data uncompression */
if (iphc0 & LOWPAN_IPHC_NH_C) {
- struct udphdr uh;
- const int needed = sizeof(struct udphdr) + sizeof(hdr);
-
- if (uncompress_udp_header(skb, &uh))
- return -EINVAL;
-
- /* replace the compressed UDP head by the uncompressed UDP
- * header
- */
- err = skb_cow(skb, needed);
- if (unlikely(err))
+ err = lowpan_nhc_do_uncompression(skb, dev, &hdr);
+ if (err < 0)
return err;
-
- skb_push(skb, sizeof(struct udphdr));
- skb_reset_transport_header(skb);
- skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr));
-
- raw_dump_table(__func__, "raw UDP header dump",
- (u8 *)&uh, sizeof(uh));
-
- hdr.nexthdr = UIP_PROTO_UDP;
} else {
err = skb_cow(skb, sizeof(hdr));
if (unlikely(err))
@@ -500,71 +413,6 @@ static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift,
return rol8(val, shift);
}

-static void compress_udp_header(u8 **hc_ptr, struct sk_buff *skb)
-{
- struct udphdr *uh;
- u8 tmp;
-
- /* In the case of RAW sockets the transport header is not set by
- * the ip6 stack so we must set it ourselves
- */
- if (skb->transport_header == skb->network_header)
- skb_set_transport_header(skb, sizeof(struct ipv6hdr));
-
- uh = udp_hdr(skb);
-
- if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) ==
- LOWPAN_NHC_UDP_4BIT_PORT) &&
- ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) ==
- LOWPAN_NHC_UDP_4BIT_PORT)) {
- pr_debug("UDP header: both ports compression to 4 bits\n");
- /* compression value */
- tmp = LOWPAN_NHC_UDP_CS_P_11;
- lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
- /* source and destination port */
- tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_4BIT_PORT +
- ((ntohs(uh->source) - LOWPAN_NHC_UDP_4BIT_PORT) << 4);
- lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
- } else if ((ntohs(uh->dest) & LOWPAN_NHC_UDP_8BIT_MASK) ==
- LOWPAN_NHC_UDP_8BIT_PORT) {
- pr_debug("UDP header: remove 8 bits of dest\n");
- /* compression value */
- tmp = LOWPAN_NHC_UDP_CS_P_01;
- lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
- /* source port */
- lowpan_push_hc_data(hc_ptr, &uh->source, sizeof(uh->source));
- /* destination port */
- tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_8BIT_PORT;
- lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
- } else if ((ntohs(uh->source) & LOWPAN_NHC_UDP_8BIT_MASK) ==
- LOWPAN_NHC_UDP_8BIT_PORT) {
- pr_debug("UDP header: remove 8 bits of source\n");
- /* compression value */
- tmp = LOWPAN_NHC_UDP_CS_P_10;
- lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
- /* source port */
- tmp = ntohs(uh->source) - LOWPAN_NHC_UDP_8BIT_PORT;
- lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
- /* destination port */
- lowpan_push_hc_data(hc_ptr, &uh->dest, sizeof(uh->dest));
- } else {
- pr_debug("UDP header: can't compress\n");
- /* compression value */
- tmp = LOWPAN_NHC_UDP_CS_P_00;
- lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
- /* source port */
- lowpan_push_hc_data(hc_ptr, &uh->source, sizeof(uh->source));
- /* destination port */
- lowpan_push_hc_data(hc_ptr, &uh->dest, sizeof(uh->dest));
- }
-
- /* checksum is always inline */
- lowpan_push_hc_data(hc_ptr, &uh->check, sizeof(uh->check));
-
- /* skip the UDP header */
- skb_pull(skb, sizeof(struct udphdr));
-}
-
int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *_daddr,
const void *_saddr, unsigned int len)
@@ -572,7 +420,7 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
u8 tmp, iphc0, iphc1, *hc_ptr;
struct ipv6hdr *hdr;
u8 head[100] = {};
- int addr_type;
+ int ret, addr_type;

if (type != ETH_P_IPV6)
return -EINVAL;
@@ -649,13 +497,12 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,

/* NOTE: payload length is always compressed */

- /* Next Header is compress if UDP */
- if (hdr->nexthdr == UIP_PROTO_UDP)
- iphc0 |= LOWPAN_IPHC_NH_C;
-
- if ((iphc0 & LOWPAN_IPHC_NH_C) == 0)
- lowpan_push_hc_data(&hc_ptr, &hdr->nexthdr,
- sizeof(hdr->nexthdr));
+ /* Check if we provide the nhc format for nexthdr and compression
+ * functionality. If not nexthdr is handled inline and not compressed.
+ */
+ ret = lowpan_nhc_check_compression(skb, hdr, &hc_ptr, &iphc0);
+ if (ret < 0)
+ return ret;

/* Hop limit
* if 1: compress, encoding is 01
@@ -741,9 +588,12 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
}
}

- /* UDP header compression */
- if (hdr->nexthdr == UIP_PROTO_UDP)
- compress_udp_header(&hc_ptr, skb);
+ /* next header compression */
+ if (iphc0 & LOWPAN_IPHC_NH_C) {
+ ret = lowpan_nhc_do_compression(skb, hdr, &hc_ptr);
+ if (ret < 0)
+ return ret;
+ }

head[0] = iphc0;
head[1] = iphc1;
@@ -761,4 +611,12 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
}
EXPORT_SYMBOL_GPL(lowpan_header_compress);

+static int __init lowpan_module_init(void)
+{
+ request_module_nowait("nhc_udp");
+
+ return 0;
+}
+module_init(lowpan_module_init);
+
MODULE_LICENSE("GPL");
diff --git a/net/6lowpan/nhc_udp.c b/net/6lowpan/nhc_udp.c
new file mode 100644
index 0000000..c6bcaeb
--- /dev/null
+++ b/net/6lowpan/nhc_udp.c
@@ -0,0 +1,157 @@
+/*
+ * 6LoWPAN IPv6 UDP compression according to RFC6282
+ *
+ *
+ * Authors:
+ * Alexander Aring <[email protected]>
+ *
+ * Orignal written by:
+ * Alexander Smirnov <[email protected]>
+ * Jon Smirl <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "nhc.h"
+
+#define LOWPAN_NHC_UDP_IDLEN 1
+
+static int udp_uncompress(struct sk_buff *skb, size_t needed)
+{
+ u8 tmp = 0, val = 0;
+ struct udphdr uh;
+ bool fail;
+ int err;
+
+ fail = lowpan_fetch_skb(skb, &tmp, sizeof(tmp));
+
+ pr_debug("UDP header uncompression\n");
+ switch (tmp & LOWPAN_NHC_UDP_CS_P_11) {
+ case LOWPAN_NHC_UDP_CS_P_00:
+ fail |= lowpan_fetch_skb(skb, &uh.source, sizeof(uh.source));
+ fail |= lowpan_fetch_skb(skb, &uh.dest, sizeof(uh.dest));
+ break;
+ case LOWPAN_NHC_UDP_CS_P_01:
+ fail |= lowpan_fetch_skb(skb, &uh.source, sizeof(uh.source));
+ fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
+ uh.dest = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
+ break;
+ case LOWPAN_NHC_UDP_CS_P_10:
+ fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
+ uh.source = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
+ fail |= lowpan_fetch_skb(skb, &uh.dest, sizeof(uh.dest));
+ break;
+ case LOWPAN_NHC_UDP_CS_P_11:
+ fail |= lowpan_fetch_skb(skb, &val, sizeof(val));
+ uh.source = htons(LOWPAN_NHC_UDP_4BIT_PORT + (val >> 4));
+ uh.dest = htons(LOWPAN_NHC_UDP_4BIT_PORT + (val & 0x0f));
+ break;
+ default:
+ BUG();
+ }
+
+ pr_debug("uncompressed UDP ports: src = %d, dst = %d\n",
+ ntohs(uh.source), ntohs(uh.dest));
+
+ /* checksum */
+ if (tmp & LOWPAN_NHC_UDP_CS_C) {
+ pr_debug_ratelimited("checksum elided currently not supported\n");
+ fail = true;
+ } else {
+ fail |= lowpan_fetch_skb(skb, &uh.check, sizeof(uh.check));
+ }
+
+ if (fail)
+ return -EINVAL;
+
+ /* UDP length needs to be infered from the lower layers
+ * here, we obtain the hint from the remaining size of the
+ * frame
+ */
+ uh.len = htons(skb->len + sizeof(struct udphdr));
+ pr_debug("uncompressed UDP length: src = %d", ntohs(uh.len));
+
+ /* replace the compressed UDP head by the uncompressed UDP
+ * header
+ */
+ err = skb_cow(skb, needed);
+ if (unlikely(err))
+ return err;
+
+ skb_push(skb, sizeof(struct udphdr));
+ skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr));
+
+ return 0;
+}
+
+static int udp_compress(struct sk_buff *skb, u8 **hc_ptr)
+{
+ const struct udphdr *uh = udp_hdr(skb);
+ u8 tmp;
+
+ if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) ==
+ LOWPAN_NHC_UDP_4BIT_PORT) &&
+ ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) ==
+ LOWPAN_NHC_UDP_4BIT_PORT)) {
+ pr_debug("UDP header: both ports compression to 4 bits\n");
+ /* compression value */
+ tmp = LOWPAN_NHC_UDP_CS_P_11;
+ lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
+ /* source and destination port */
+ tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_4BIT_PORT +
+ ((ntohs(uh->source) - LOWPAN_NHC_UDP_4BIT_PORT) << 4);
+ lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
+ } else if ((ntohs(uh->dest) & LOWPAN_NHC_UDP_8BIT_MASK) ==
+ LOWPAN_NHC_UDP_8BIT_PORT) {
+ pr_debug("UDP header: remove 8 bits of dest\n");
+ /* compression value */
+ tmp = LOWPAN_NHC_UDP_CS_P_01;
+ lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
+ /* source port */
+ lowpan_push_hc_data(hc_ptr, &uh->source, sizeof(uh->source));
+ /* destination port */
+ tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_8BIT_PORT;
+ lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
+ } else if ((ntohs(uh->source) & LOWPAN_NHC_UDP_8BIT_MASK) ==
+ LOWPAN_NHC_UDP_8BIT_PORT) {
+ pr_debug("UDP header: remove 8 bits of source\n");
+ /* compression value */
+ tmp = LOWPAN_NHC_UDP_CS_P_10;
+ lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
+ /* source port */
+ tmp = ntohs(uh->source) - LOWPAN_NHC_UDP_8BIT_PORT;
+ lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
+ /* destination port */
+ lowpan_push_hc_data(hc_ptr, &uh->dest, sizeof(uh->dest));
+ } else {
+ pr_debug("UDP header: can't compress\n");
+ /* compression value */
+ tmp = LOWPAN_NHC_UDP_CS_P_00;
+ lowpan_push_hc_data(hc_ptr, &tmp, sizeof(tmp));
+ /* source port */
+ lowpan_push_hc_data(hc_ptr, &uh->source, sizeof(uh->source));
+ /* destination port */
+ lowpan_push_hc_data(hc_ptr, &uh->dest, sizeof(uh->dest));
+ }
+
+ /* checksum is always inline */
+ lowpan_push_hc_data(hc_ptr, &uh->check, sizeof(uh->check));
+
+ return 0;
+}
+
+static void udp_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_UDP_ID;
+ nhc->idmask[0] = LOWPAN_NHC_UDP_MASK;
+}
+
+LOWPAN_NHC(nhc_udp, "RFC6282 UDP", NEXTHDR_UDP, sizeof(struct udphdr),
+ udp_nhid_setup, LOWPAN_NHC_UDP_IDLEN, udp_uncompress, udp_compress);
+
+module_lowpan_nhc(nhc_udp);
+MODULE_DESCRIPTION("6LoWPAN next header RFC6282 UDP compression");
+MODULE_LICENSE("GPL");
--
2.2.1


2015-01-09 15:42:57

by Alexander Aring

[permalink] [raw]
Subject: [PATCHv5 bluetooth-next 1/3] 6lowpan: add generic nhc layer interface

This patch adds a generic next header compression layer interface. There
exists various methods to do a header compression after 6LoWPAN header
to save payload. This introduce a generic nhc header which allow a
simple adding of a new header compression format instead of a static
implementation inside the 6LoWPAN header compression and uncompression
function.

Signed-off-by: Alexander Aring <[email protected]>
Cc: Jukka Rissanen <[email protected]>
Cc: Martin Townsend <[email protected]>
---
net/6lowpan/Makefile | 2 +-
net/6lowpan/nhc.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc.h | 146 +++++++++++++++++++++++++++++++
3 files changed, 388 insertions(+), 1 deletion(-)
create mode 100644 net/6lowpan/nhc.c
create mode 100644 net/6lowpan/nhc.h

diff --git a/net/6lowpan/Makefile b/net/6lowpan/Makefile
index 415886b..4215602 100644
--- a/net/6lowpan/Makefile
+++ b/net/6lowpan/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_6LOWPAN) := 6lowpan.o

-6lowpan-y := iphc.o
+6lowpan-y := iphc.o nhc.o
diff --git a/net/6lowpan/nhc.c b/net/6lowpan/nhc.c
new file mode 100644
index 0000000..3c0dc77b0
--- /dev/null
+++ b/net/6lowpan/nhc.c
@@ -0,0 +1,241 @@
+/*
+ * 6LoWPAN next header compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/netdevice.h>
+
+#include <net/ipv6.h>
+
+#include "nhc.h"
+
+static struct rb_root rb_root = RB_ROOT;
+static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
+static DEFINE_SPINLOCK(lowpan_nhc_lock);
+
+static int lowpan_nhc_insert(struct lowpan_nhc *nhc)
+{
+ struct rb_node **new = &rb_root.rb_node, *parent = NULL;
+
+ /* Figure out where to put new node */
+ while (*new) {
+ struct lowpan_nhc *this = container_of(*new, struct lowpan_nhc,
+ node);
+ int result, len_dif, len;
+
+ len_dif = nhc->idlen - this->idlen;
+
+ if (nhc->idlen < this->idlen)
+ len = nhc->idlen;
+ else
+ len = this->idlen;
+
+ result = memcmp(nhc->id, this->id, len);
+ if (!result)
+ result = len_dif;
+
+ parent = *new;
+ if (result < 0)
+ new = &((*new)->rb_left);
+ else if (result > 0)
+ new = &((*new)->rb_right);
+ else
+ return -EEXIST;
+ }
+
+ /* Add new node and rebalance tree. */
+ rb_link_node(&nhc->node, parent, new);
+ rb_insert_color(&nhc->node, &rb_root);
+
+ return 0;
+}
+
+static void lowpan_nhc_remove(struct lowpan_nhc *nhc)
+{
+ rb_erase(&nhc->node, &rb_root);
+}
+
+static struct lowpan_nhc *lowpan_nhc_by_nhcid(const struct sk_buff *skb)
+{
+ struct rb_node *node = rb_root.rb_node;
+ const u8 *nhcid_skb_ptr = skb->data;
+
+ while (node) {
+ struct lowpan_nhc *nhc = container_of(node, struct lowpan_nhc,
+ node);
+ u8 nhcid_skb_ptr_masked[LOWPAN_NHC_MAX_ID_LEN];
+ int result, i;
+
+ if (nhcid_skb_ptr + nhc->idlen > skb->data + skb->len)
+ return NULL;
+
+ /* copy and mask afterwards the nhid value from skb */
+ memcpy(nhcid_skb_ptr_masked, nhcid_skb_ptr, nhc->idlen);
+ for (i = 0; i < nhc->idlen; i++)
+ nhcid_skb_ptr_masked[i] &= nhc->idmask[i];
+
+ result = memcmp(nhcid_skb_ptr_masked, nhc->id, nhc->idlen);
+ if (result < 0)
+ node = node->rb_left;
+ else if (result > 0)
+ node = node->rb_right;
+ else
+ return nhc;
+ }
+
+ return NULL;
+}
+
+int lowpan_nhc_check_compression(struct sk_buff *skb,
+ const struct ipv6hdr *hdr, u8 **hc_ptr,
+ u8 *iphc0)
+{
+ struct lowpan_nhc *nhc;
+
+ spin_lock_bh(&lowpan_nhc_lock);
+
+ nhc = lowpan_nexthdr_nhcs[hdr->nexthdr];
+ if (nhc && nhc->compress)
+ *iphc0 |= LOWPAN_IPHC_NH_C;
+ else
+ lowpan_push_hc_data(hc_ptr, &hdr->nexthdr,
+ sizeof(hdr->nexthdr));
+
+ spin_unlock_bh(&lowpan_nhc_lock);
+
+ return 0;
+}
+
+int lowpan_nhc_do_compression(struct sk_buff *skb, const struct ipv6hdr *hdr,
+ u8 **hc_ptr)
+{
+ int ret;
+ struct lowpan_nhc *nhc;
+
+ spin_lock_bh(&lowpan_nhc_lock);
+
+ nhc = lowpan_nexthdr_nhcs[hdr->nexthdr];
+ /* check if the nhc module was removed in unlocked part.
+ * TODO: this is a workaround we should prevent unloading
+ * of nhc modules while unlocked part, this will always drop
+ * the lowpan packet but it's very unlikely.
+ *
+ * Solution isn't easy because we need to decide at
+ * lowpan_nhc_check_compression if we do a compression or not.
+ * Because the inline data which is added to skb, we can't move this
+ * handling.
+ */
+ if (unlikely(!nhc || !nhc->compress)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* In the case of RAW sockets the transport header is not set by
+ * the ip6 stack so we must set it ourselves
+ */
+ if (skb->transport_header == skb->network_header)
+ skb_set_transport_header(skb, sizeof(struct ipv6hdr));
+
+ ret = nhc->compress(skb, hc_ptr);
+ if (ret < 0)
+ goto out;
+
+ /* skip the transport header */
+ skb_pull(skb, nhc->nexthdrlen);
+
+out:
+ spin_unlock_bh(&lowpan_nhc_lock);
+
+ return ret;
+}
+
+int lowpan_nhc_do_uncompression(struct sk_buff *skb, struct net_device *dev,
+ struct ipv6hdr *hdr)
+{
+ struct lowpan_nhc *nhc;
+ int ret;
+
+ spin_lock_bh(&lowpan_nhc_lock);
+
+ nhc = lowpan_nhc_by_nhcid(skb);
+ if (nhc) {
+ if (nhc->uncompress) {
+ ret = nhc->uncompress(skb, sizeof(struct ipv6hdr) +
+ nhc->nexthdrlen);
+ if (ret < 0) {
+ spin_unlock_bh(&lowpan_nhc_lock);
+ return ret;
+ }
+ } else {
+ spin_unlock_bh(&lowpan_nhc_lock);
+ netdev_warn(dev, "received nhc id for %s which is not implemented.\n",
+ nhc->name);
+ return -ENOTSUPP;
+ }
+ } else {
+ spin_unlock_bh(&lowpan_nhc_lock);
+ netdev_warn(dev, "received unknown nhc id which was not found.\n");
+ return -ENOENT;
+ }
+
+ hdr->nexthdr = nhc->nexthdr;
+ skb_reset_transport_header(skb);
+ raw_dump_table(__func__, "raw transport header dump",
+ skb_transport_header(skb), nhc->nexthdrlen);
+
+ spin_unlock_bh(&lowpan_nhc_lock);
+
+ return 0;
+}
+
+int lowpan_nhc_add(struct lowpan_nhc *nhc)
+{
+ int ret;
+
+ if (!nhc->idlen || !nhc->idsetup)
+ return -EINVAL;
+
+ WARN_ONCE(nhc->idlen > LOWPAN_NHC_MAX_ID_LEN,
+ "LOWPAN_NHC_MAX_ID_LEN should be updated to %d.\n",
+ nhc->idlen);
+
+ nhc->idsetup(nhc);
+
+ spin_lock_bh(&lowpan_nhc_lock);
+
+ if (lowpan_nexthdr_nhcs[nhc->nexthdr]) {
+ ret = -EEXIST;
+ goto out;
+ }
+
+ ret = lowpan_nhc_insert(nhc);
+ if (ret < 0)
+ goto out;
+
+ lowpan_nexthdr_nhcs[nhc->nexthdr] = nhc;
+out:
+ spin_unlock_bh(&lowpan_nhc_lock);
+ return ret;
+}
+EXPORT_SYMBOL(lowpan_nhc_add);
+
+void lowpan_nhc_del(struct lowpan_nhc *nhc)
+{
+ spin_lock_bh(&lowpan_nhc_lock);
+
+ lowpan_nhc_remove(nhc);
+ lowpan_nexthdr_nhcs[nhc->nexthdr] = NULL;
+
+ spin_unlock_bh(&lowpan_nhc_lock);
+
+ synchronize_net();
+}
+EXPORT_SYMBOL(lowpan_nhc_del);
diff --git a/net/6lowpan/nhc.h b/net/6lowpan/nhc.h
new file mode 100644
index 0000000..ed44938
--- /dev/null
+++ b/net/6lowpan/nhc.h
@@ -0,0 +1,146 @@
+#ifndef __6LOWPAN_NHC_H
+#define __6LOWPAN_NHC_H
+
+#include <linux/skbuff.h>
+#include <linux/rbtree.h>
+#include <linux/module.h>
+
+#include <net/6lowpan.h>
+#include <net/ipv6.h>
+
+#define LOWPAN_NHC_MAX_ID_LEN 1
+
+/**
+ * LOWPAN_NHC - helper macro to generate nh id fields and lowpan_nhc struct
+ *
+ * @__nhc: variable name of the lowpan_nhc struct.
+ * @_name: const char * of common header compression name.
+ * @_nexthdr: ipv6 nexthdr field for the header compression.
+ * @_nexthdrlen: ipv6 nexthdr len for the reserved space.
+ * @_idsetup: callback to setup id and mask values.
+ * @_idlen: len for the next header id and mask, should be always the same.
+ * @_uncompress: callback for uncompression call.
+ * @_compress: callback for compression call.
+ */
+#define LOWPAN_NHC(__nhc, _name, _nexthdr, \
+ _hdrlen, _idsetup, _idlen, \
+ _uncompress, _compress) \
+static u8 __nhc##_val[_idlen]; \
+static u8 __nhc##_mask[_idlen]; \
+static struct lowpan_nhc __nhc = { \
+ .name = _name, \
+ .nexthdr = _nexthdr, \
+ .nexthdrlen = _hdrlen, \
+ .id = __nhc##_val, \
+ .idmask = __nhc##_mask, \
+ .idlen = _idlen, \
+ .idsetup = _idsetup, \
+ .uncompress = _uncompress, \
+ .compress = _compress, \
+}
+
+#define module_lowpan_nhc(__nhc) \
+static int __init __nhc##_init(void) \
+{ \
+ return lowpan_nhc_add(&(__nhc)); \
+} \
+module_init(__nhc##_init); \
+static void __exit __nhc##_exit(void) \
+{ \
+ lowpan_nhc_del(&(__nhc)); \
+} \
+module_exit(__nhc##_exit);
+
+/**
+ * struct lowpan_nhc - hold 6lowpan next hdr compression ifnformation
+ *
+ * @node: holder for the rbtree.
+ * @name: name of the specific next header compression
+ * @nexthdr: next header value of the protocol which should be compressed.
+ * @nexthdrlen: ipv6 nexthdr len for the reserved space.
+ * @id: array for nhc id. Note this need to be in network byteorder.
+ * @mask: array for nhc id mask. Note this need to be in network byteorder.
+ * @len: the length of the next header id and mask.
+ * @setup: callback to setup fill the next header id value and mask.
+ * @compress: callback to do the header compression.
+ * @uncompress: callback to do the header uncompression.
+ */
+struct lowpan_nhc {
+ struct rb_node node;
+ const char *name;
+ const u8 nexthdr;
+ const size_t nexthdrlen;
+ u8 *id;
+ u8 *idmask;
+ const size_t idlen;
+
+ void (*idsetup)(struct lowpan_nhc *nhc);
+ int (*uncompress)(struct sk_buff *skb, size_t needed);
+ int (*compress)(struct sk_buff *skb, u8 **hc_ptr);
+};
+
+/**
+ * lowpan_nhc_by_nexthdr - return the 6lowpan nhc by ipv6 nexthdr.
+ *
+ * @nexthdr: ipv6 nexthdr value.
+ */
+struct lowpan_nhc *lowpan_nhc_by_nexthdr(u8 nexthdr);
+
+/**
+ * lowpan_nhc_check_compression - checks if we support compression format. If
+ * we support the nhc by nexthdr field, the 6LoWPAN iphc NHC bit will be
+ * set. If we don't support nexthdr will be added as inline data to the
+ * 6LoWPAN header.
+ *
+ * @skb: skb of 6LoWPAN header to read nhc and replace header.
+ * @hdr: ipv6hdr to check the nexthdr value
+ * @hc_ptr: pointer for 6LoWPAN header which should increment at the end of
+ * replaced header.
+ * @iphc0: iphc0 pointer to set the 6LoWPAN NHC bit
+ */
+int lowpan_nhc_check_compression(struct sk_buff *skb,
+ const struct ipv6hdr *hdr, u8 **hc_ptr,
+ u8 *iphc0);
+
+/**
+ * lowpan_nhc_do_compression - calling compress callback for nhc
+ *
+ * @skb: skb of 6LoWPAN header to read nhc and replace header.
+ * @hdr: ipv6hdr to set the nexthdr value
+ * @hc_ptr: pointer for 6LoWPAN header which should increment at the end of
+ * replaced header.
+ */
+int lowpan_nhc_do_compression(struct sk_buff *skb, const struct ipv6hdr *hdr,
+ u8 **hc_ptr);
+
+/**
+ * lowpan_nhc_do_uncompression - calling uncompress callback for nhc
+ *
+ * @nhc: 6LoWPAN nhc context, get by lowpan_nhc_by_ functions.
+ * @skb: skb of 6LoWPAN header, skb->data should be pointed to nhc id value.
+ * @dev: netdevice for print logging information.
+ * @hdr: ipv6hdr for setting nexthdr value.
+ */
+int lowpan_nhc_do_uncompression(struct sk_buff *skb, struct net_device *dev,
+ struct ipv6hdr *hdr);
+
+/**
+ * lowpan_nhc_add - register a next header compression to framework
+ *
+ * @nhc: nhc which should be add.
+ */
+int lowpan_nhc_add(struct lowpan_nhc *nhc);
+
+/**
+ * lowpan_nhc_del - delete a next header compression from framework
+ *
+ * @nhc: nhc which should be delete.
+ */
+void lowpan_nhc_del(struct lowpan_nhc *nhc);
+
+/**
+ * lowpan_nhc_init - adding all default nhcs
+ */
+void lowpan_nhc_init(void);
+
+#endif /* __6LOWPAN_NHC_H */
--
2.2.1


2015-02-14 22:42:43

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

Hi Marcel,

On Sat, Feb 14, 2015 at 02:10:33PM -0800, Marcel Holtmann wrote:
...
>
> all 3 patches have been applied to bluetooth-next tree.
>

thanks for fixing the format string issue!

- Alex

2015-02-14 22:10:33

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

Hi Alex,

> This patch series introduce the next header compression framework. Currently
> we support udp compression/uncompression only. This framework allow to add new
> next header compression formats easily.
>
> If somebody wants to add a new header compression format and some information
> are missing while calling compression and uncompression callbacks. Please
> feel free to make framework changes according these callbacks.
>
> changes since v2:
> - make udp nhc as module as suggested by Marcel Holtmann
> - fix comment header in nhc_udp.c
>
> I didn't make the lowpan_nhc declaration "const" because this will occur
> issues with rb_node, id and idmask array. Which will manipulated during
> runtime.
>
> changes since v3:
> - add patch 3/3 for other known rfc6282 ipv6 extension headers compression
> formats
> - add request_modules for loading nhc default compression format modules.
> Which was suggested by Jukka Rissanen. Thanks, this is really working.
> - Add rtnl_lock for lowpan_nhc_add and del since we have no synced
> request_modules call this could make trouble.
> - Move some handling out of nhc_do_compression and uncompression function.
> The complete handling is now inside of iphc.c and nhc_do_compression and
> uncompression functions is only a wrapper call for the callback.
> - rework some menuentries for Kconfig and compression format, they are
> grouped by rfc now.
> - move some generic handling like "skb_pull(skb, nhc->nexthdrlen);" into
> iphc.c. It would be great if we have something also for uncompression
> for the skb_cow. But this isn't possible right now.
> - change warning if nhc was not found to "was not found" instead isn't
> implemented. It isn't implemented if callbacks are NULL now.
> - small cleanups.
>
> changes since v4:
> - add spinlock for to prevent nhc from deletion while using. This can occur
> if nhc module is unloading while compression/uncompression.
> - move nhc handling for nhc compression/uncompression completely into
> nhc_do_compression/nhc_do_uncompression.
>
> Note about locking:
>
> We have now a spinlock nhc_lowpan_lock which prevents manipulating the nhc
> datastructures while using it. On receiving side it's easy to handle, at the
> end we check if 6lowpan nh compressed flag is set and run uncompression.
> On the other hand the transmit side is complicated, we check if next_hdr field
> is registrated and run some other compression routines, at least we do the
> finally nhc compression which depends on the first check if next_hdr was
> registrated. The kernel will crash if we remove the using module between
> "next_hdr check" and "do nhc compression", the lock will prevent that now.
>
> Now in the transmit path exist a little window to remove a lowpan_nhc while
> compression. This is exactly the part between "check if we support" and
> "doing compression". This is a very unlikely case, if this occurs we drop
> the packet while compression. Don't know how to better deal with that right
> now. I will try to search a better solution later.
>
> changes since v5:
> - s/rfc6282// on filenames and kconfig entries, suggested by Marcel Holtmann
> and Stefan Schmidt
> - s/FRAG/FRAGMENT/ - suggested by Stefan Schmidt
> - s/MOBIL/MOBILITY/ - suggested by Stefan Schmidt
> - s/ROUTE/ROUTING/ - suggested by Stefan Schmidt
> - replace "depends on 6LOWPAN_NHC" with a global "if 6LOWPAN_NHC
> $LOT_OF_ENTRIES endif" inside net/6lowpan/Kconfig
> - fix small typo "nhc" -> "nhcs" in net/6lowpan/Makefile
> - add MODULE_DESCRIPTION to each NHC module
>
> Cc: Jukka Rissanen <[email protected]>
> Cc: Martin Townsend <[email protected]>
> Cc: Marcel Holtmann <[email protected]>
> Cc: Stefan Schmidt <[email protected]>
>
> Alexander Aring (3):
> 6lowpan: add generic nhc layer interface
> 6lowpan: add udp compression via nhc layer
> 6lowpan: nhc: add other known rfc6282 compressions
>
> net/6lowpan/Kconfig | 57 ++++++++++-
> net/6lowpan/Makefile | 13 ++-
> net/6lowpan/iphc.c | 200 ++++++-------------------------------
> net/6lowpan/nhc.c | 241 +++++++++++++++++++++++++++++++++++++++++++++
> net/6lowpan/nhc.h | 146 +++++++++++++++++++++++++++
> net/6lowpan/nhc_dest.c | 28 ++++++
> net/6lowpan/nhc_fragment.c | 27 +++++
> net/6lowpan/nhc_hop.c | 27 +++++
> net/6lowpan/nhc_ipv6.c | 27 +++++
> net/6lowpan/nhc_mobility.c | 27 +++++
> net/6lowpan/nhc_routing.c | 27 +++++
> net/6lowpan/nhc_udp.c | 157 +++++++++++++++++++++++++++++
> 12 files changed, 806 insertions(+), 171 deletions(-)
> create mode 100644 net/6lowpan/nhc.c
> create mode 100644 net/6lowpan/nhc.h
> create mode 100644 net/6lowpan/nhc_dest.c
> create mode 100644 net/6lowpan/nhc_fragment.c
> create mode 100644 net/6lowpan/nhc_hop.c
> create mode 100644 net/6lowpan/nhc_ipv6.c
> create mode 100644 net/6lowpan/nhc_mobility.c
> create mode 100644 net/6lowpan/nhc_routing.c
> create mode 100644 net/6lowpan/nhc_udp.c

all 3 patches have been applied to bluetooth-next tree.

Regards

Marcel


2015-02-14 22:08:56

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

Hi Alex,

>> so I collected the reviewed-by and acked-by statements, but when I did a simple compile test it failed badly.
>>
>> CC net/6lowpan/nhc.o
>> net/6lowpan/nhc.c: In function ‘lowpan_nhc_add’:
>> net/6lowpan/nhc.c:206:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘size_t’ [-Wformat=]
>> WARN_ONCE(nhc->idlen > LOWPAN_NHC_MAX_ID_LEN,
>> ^
>>
>
> mhh, okay. Should be fixed with a conversion from "%d" -> "%zd". I will
> resend a new series with this fix. Thanks.

I can do that change inline if that is the only change needed.

Regards

Marcel


2015-02-14 21:57:27

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

Hi Marcel,

On Sat, Feb 14, 2015 at 01:46:43PM -0800, Marcel Holtmann wrote:
...
>
> so I collected the reviewed-by and acked-by statements, but when I did a simple compile test it failed badly.
>
> CC net/6lowpan/nhc.o
> net/6lowpan/nhc.c: In function ‘lowpan_nhc_add’:
> net/6lowpan/nhc.c:206:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘size_t’ [-Wformat=]
> WARN_ONCE(nhc->idlen > LOWPAN_NHC_MAX_ID_LEN,
> ^
>

mhh, okay. Should be fixed with a conversion from "%d" -> "%zd". I will
resend a new series with this fix. Thanks.

- Alex

2015-02-14 21:46:43

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

Hi Alex,

> This patch series introduce the next header compression framework. Currently
> we support udp compression/uncompression only. This framework allow to add new
> next header compression formats easily.
>
> If somebody wants to add a new header compression format and some information
> are missing while calling compression and uncompression callbacks. Please
> feel free to make framework changes according these callbacks.
>
> changes since v2:
> - make udp nhc as module as suggested by Marcel Holtmann
> - fix comment header in nhc_udp.c
>
> I didn't make the lowpan_nhc declaration "const" because this will occur
> issues with rb_node, id and idmask array. Which will manipulated during
> runtime.
>
> changes since v3:
> - add patch 3/3 for other known rfc6282 ipv6 extension headers compression
> formats
> - add request_modules for loading nhc default compression format modules.
> Which was suggested by Jukka Rissanen. Thanks, this is really working.
> - Add rtnl_lock for lowpan_nhc_add and del since we have no synced
> request_modules call this could make trouble.
> - Move some handling out of nhc_do_compression and uncompression function.
> The complete handling is now inside of iphc.c and nhc_do_compression and
> uncompression functions is only a wrapper call for the callback.
> - rework some menuentries for Kconfig and compression format, they are
> grouped by rfc now.
> - move some generic handling like "skb_pull(skb, nhc->nexthdrlen);" into
> iphc.c. It would be great if we have something also for uncompression
> for the skb_cow. But this isn't possible right now.
> - change warning if nhc was not found to "was not found" instead isn't
> implemented. It isn't implemented if callbacks are NULL now.
> - small cleanups.
>
> changes since v4:
> - add spinlock for to prevent nhc from deletion while using. This can occur
> if nhc module is unloading while compression/uncompression.
> - move nhc handling for nhc compression/uncompression completely into
> nhc_do_compression/nhc_do_uncompression.
>
> Note about locking:
>
> We have now a spinlock nhc_lowpan_lock which prevents manipulating the nhc
> datastructures while using it. On receiving side it's easy to handle, at the
> end we check if 6lowpan nh compressed flag is set and run uncompression.
> On the other hand the transmit side is complicated, we check if next_hdr field
> is registrated and run some other compression routines, at least we do the
> finally nhc compression which depends on the first check if next_hdr was
> registrated. The kernel will crash if we remove the using module between
> "next_hdr check" and "do nhc compression", the lock will prevent that now.
>
> Now in the transmit path exist a little window to remove a lowpan_nhc while
> compression. This is exactly the part between "check if we support" and
> "doing compression". This is a very unlikely case, if this occurs we drop
> the packet while compression. Don't know how to better deal with that right
> now. I will try to search a better solution later.
>
> changes since v5:
> - s/rfc6282// on filenames and kconfig entries, suggested by Marcel Holtmann
> and Stefan Schmidt
> - s/FRAG/FRAGMENT/ - suggested by Stefan Schmidt
> - s/MOBIL/MOBILITY/ - suggested by Stefan Schmidt
> - s/ROUTE/ROUTING/ - suggested by Stefan Schmidt
> - replace "depends on 6LOWPAN_NHC" with a global "if 6LOWPAN_NHC
> $LOT_OF_ENTRIES endif" inside net/6lowpan/Kconfig
> - fix small typo "nhc" -> "nhcs" in net/6lowpan/Makefile
> - add MODULE_DESCRIPTION to each NHC module
>
> Cc: Jukka Rissanen <[email protected]>
> Cc: Martin Townsend <[email protected]>
> Cc: Marcel Holtmann <[email protected]>
> Cc: Stefan Schmidt <[email protected]>
>
> Alexander Aring (3):
> 6lowpan: add generic nhc layer interface
> 6lowpan: add udp compression via nhc layer
> 6lowpan: nhc: add other known rfc6282 compressions
>
> net/6lowpan/Kconfig | 57 ++++++++++-
> net/6lowpan/Makefile | 13 ++-
> net/6lowpan/iphc.c | 200 ++++++-------------------------------
> net/6lowpan/nhc.c | 241 +++++++++++++++++++++++++++++++++++++++++++++
> net/6lowpan/nhc.h | 146 +++++++++++++++++++++++++++
> net/6lowpan/nhc_dest.c | 28 ++++++
> net/6lowpan/nhc_fragment.c | 27 +++++
> net/6lowpan/nhc_hop.c | 27 +++++
> net/6lowpan/nhc_ipv6.c | 27 +++++
> net/6lowpan/nhc_mobility.c | 27 +++++
> net/6lowpan/nhc_routing.c | 27 +++++
> net/6lowpan/nhc_udp.c | 157 +++++++++++++++++++++++++++++
> 12 files changed, 806 insertions(+), 171 deletions(-)
> create mode 100644 net/6lowpan/nhc.c
> create mode 100644 net/6lowpan/nhc.h
> create mode 100644 net/6lowpan/nhc_dest.c
> create mode 100644 net/6lowpan/nhc_fragment.c
> create mode 100644 net/6lowpan/nhc_hop.c
> create mode 100644 net/6lowpan/nhc_ipv6.c
> create mode 100644 net/6lowpan/nhc_mobility.c
> create mode 100644 net/6lowpan/nhc_routing.c
> create mode 100644 net/6lowpan/nhc_udp.c

so I collected the reviewed-by and acked-by statements, but when I did a simple compile test it failed badly.

CC net/6lowpan/nhc.o
net/6lowpan/nhc.c: In function ‘lowpan_nhc_add’:
net/6lowpan/nhc.c:206:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘size_t’ [-Wformat=]
WARN_ONCE(nhc->idlen > LOWPAN_NHC_MAX_ID_LEN,
^

Regards

Marcel


2015-02-14 21:33:22

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

On Thu, Feb 05, 2015 at 10:07:47AM +0100, Alexander Aring wrote:
> On Fri, Jan 09, 2015 at 04:42:56PM +0100, Alexander Aring wrote:
> > This patch series introduce the next header compression framework. Currently
> > we support udp compression/uncompression only. This framework allow to add new
> > next header compression formats easily.
> >
> > If somebody wants to add a new header compression format and some information
> > are missing while calling compression and uncompression callbacks. Please
> > feel free to make framework changes according these callbacks.
> >
>
> Marcel, ping?
>

ping, again. :-)

- Alex

2015-02-05 09:07:50

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCHv5 bluetooth-next 0/3] 6lowpan: introduce nhc framework

On Fri, Jan 09, 2015 at 04:42:56PM +0100, Alexander Aring wrote:
> This patch series introduce the next header compression framework. Currently
> we support udp compression/uncompression only. This framework allow to add new
> next header compression formats easily.
>
> If somebody wants to add a new header compression format and some information
> are missing while calling compression and uncompression callbacks. Please
> feel free to make framework changes according these callbacks.
>

Marcel, ping?

Or should we apply it for the next release?

- Alex