* [RFC bluetooth-next 1/8] 6lowpan: add generic nhc layer interface
2014-08-09 19:02 [RFC bluetooth-next 0/8] 6lowpan: introduce generic next header compression layer Alexander Aring
@ 2014-08-09 19:02 ` Alexander Aring
2014-08-10 15:02 ` Alexander Aring
2014-08-10 15:14 ` Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 2/8] 6lowpan: nhc layer udp compression Alexander Aring
` (6 subsequent siblings)
7 siblings, 2 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-09 19:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen, Alexander Aring
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 <alex.aring@gmail.com>
---
net/6lowpan/Makefile | 1 +
net/6lowpan/nhc/Makefile | 3 +
net/6lowpan/nhc/core.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc/core.h | 122 ++++++++++++++++++++++++++++++++
4 files changed, 306 insertions(+)
create mode 100644 net/6lowpan/nhc/Makefile
create mode 100644 net/6lowpan/nhc/core.c
create mode 100644 net/6lowpan/nhc/core.h
diff --git a/net/6lowpan/Makefile b/net/6lowpan/Makefile
index 415886b..d23d569 100644
--- a/net/6lowpan/Makefile
+++ b/net/6lowpan/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_6LOWPAN) := 6lowpan.o
+obj-$(CONFIG_6LOWPAN) += nhc/
6lowpan-y := iphc.o
diff --git a/net/6lowpan/nhc/Makefile b/net/6lowpan/nhc/Makefile
new file mode 100644
index 0000000..5fe76e47
--- /dev/null
+++ b/net/6lowpan/nhc/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_6LOWPAN) += nhc.o
+
+nhc-y := core.o
diff --git a/net/6lowpan/nhc/core.c b/net/6lowpan/nhc/core.c
new file mode 100644
index 0000000..0bf103d
--- /dev/null
+++ b/net/6lowpan/nhc/core.c
@@ -0,0 +1,180 @@
+/* 6LoWPAN next header compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ *
+ * 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 "core.h"
+
+static struct rb_root rb_root = RB_ROOT;
+static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
+
+static int lowpan_insert_nhc(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_remove_nhc(struct lowpan_nhc *nhc)
+{
+ rb_erase(&nhc->node, &rb_root);
+}
+
+struct lowpan_nhc *lowpan_search_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[nhc->idlen];
+ 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;
+}
+EXPORT_SYMBOL(lowpan_search_nhc_by_nhcid);
+
+struct lowpan_nhc *lowpan_search_nhc_by_nexthdr(const u8 nexthdr)
+{
+ return lowpan_nexthdr_nhcs[nexthdr];
+}
+EXPORT_SYMBOL(lowpan_search_nhc_by_nexthdr);
+
+int lowpan_nhc_do_compression(struct lowpan_nhc *nhc, struct sk_buff *skb,
+ u8 **hc_ptr, u8 *iphc0)
+{
+ int ret = 0;
+
+ if (!nhc)
+ return 0;
+
+ ret = nhc->compress(skb, hc_ptr);
+ if (!ret)
+ *iphc0 |= LOWPAN_IPHC_NH_C;
+ else if (ret == -ENOTSUPP)
+ return 0;
+
+ return ret;
+}
+EXPORT_SYMBOL(lowpan_nhc_do_compression);
+
+int lowpan_nhc_do_uncompression(struct sk_buff **skb, struct ipv6hdr *hdr)
+{
+ struct lowpan_nhc *nhc;
+ int ret = 0;
+
+ nhc = lowpan_search_nhc_by_nhcid(*skb);
+ if (nhc) {
+ ret = nhc->uncompress(skb);
+ if (!ret) {
+ skb_reset_transport_header(*skb);
+ hdr->nexthdr = nhc->nexthdr;
+ } else if (ret == -ENOTSUPP) {
+ net_warn_ratelimited("%s received %s which is not supported.\n",
+ (*skb)->dev->name, nhc->name);
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(lowpan_nhc_do_uncompression);
+
+int lowpan_add_nhc(struct lowpan_nhc *nhc)
+{
+ int ret = -ENOMEM;
+
+ if (!nhc->uncompress || !nhc->idlen || !nhc->idsetup || !nhc->compress)
+ return -EINVAL;
+
+ nhc->idsetup(nhc);
+
+ if (lowpan_nexthdr_nhcs[nhc->nexthdr])
+ return -EEXIST;
+
+ ret = lowpan_insert_nhc(nhc);
+ if (ret < 0)
+ goto out;
+
+ lowpan_nexthdr_nhcs[nhc->nexthdr] = nhc;
+out:
+ return ret;
+}
+EXPORT_SYMBOL(lowpan_add_nhc);
+
+void lowpan_del_nhc(struct lowpan_nhc *nhc)
+{
+ lowpan_remove_nhc(nhc);
+ lowpan_nexthdr_nhcs[nhc->nexthdr] = NULL;
+
+ synchronize_net();
+}
+EXPORT_SYMBOL(lowpan_del_nhc);
+
+int lowpan_init_nhc(void)
+{
+ return 0;
+}
+
+void lowpan_cleanup_nhc(void)
+{
+}
diff --git a/net/6lowpan/nhc/core.h b/net/6lowpan/nhc/core.h
new file mode 100644
index 0000000..5613fae
--- /dev/null
+++ b/net/6lowpan/nhc/core.h
@@ -0,0 +1,122 @@
+#ifndef __6LOWPAN_NHC_H
+#define __6LOWPAN_NHC_H
+
+#include <linux/skbuff.h>
+#include <linux/rbtree.h>
+#include <linux/list.h>
+
+#include <net/6lowpan.h>
+#include <net/ipv6.h>
+
+/**
+ * LOWPAN_NHC - helper macro to generate nh id fields and lowpan_nhc struct
+ *
+ * @varname: variable name of the lowpan_nhc struct.
+ * @nhcname: const char * of common header compression name.
+ * @nexthdr: ipv6 nexthdr field for the header compression.
+ * @nhidsetup: callback to setup id and mask values.
+ * @nhidlen: len for the next header id and mask, should be always the same.
+ * @nhuncompress: callback for uncompression call.
+ * @nhcompress: callback for compression call.
+ */
+#define LOWPAN_NHC(varname, nhcname, nhnexthdr, \
+ nhidsetup, nhidlen, \
+ nhuncompress, nhcompress) \
+ static u8 name##_val[nhidlen]; \
+ static u8 name##_mask[nhidlen]; \
+ static struct lowpan_nhc varname = { \
+ .name = nhcname, \
+ .nexthdr = nhnexthdr, \
+ .id = name##_val, \
+ .idmask = name##_mask, \
+ .idlen = nhidlen, \
+ .idsetup = nhidsetup, \
+ .uncompress = nhuncompress, \
+ .compress = nhcompress, \
+ }
+
+/**
+ * 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.
+ * @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;
+ u8 *id;
+ u8 *idmask;
+ const size_t idlen;
+
+ void (*idsetup)(struct lowpan_nhc *nhc);
+ int (*uncompress)(struct sk_buff **skb);
+ int (*compress)(struct sk_buff *skb, u8 **hc_ptr);
+};
+
+/**
+ * lowpan_search_nhc_by_nhcid - returns the 6lowpan nhc by nhcid
+ *
+ * @skb: skb with skb->data which is pointed to 6lowpan nhc id.
+ */
+struct lowpan_nhc *lowpan_search_nhc_by_nhcid(const struct sk_buff *skb);
+
+/**
+ * lowpan_search_nhc_by_nexthdr - return the 6lowpan nhc by ipv6 nexthdr.
+ *
+ * @nexthdr: ipv6 nexthdr value.
+ */
+struct lowpan_nhc *lowpan_search_nhc_by_nexthdr(const u8 nexthdr);
+
+/**
+ * lowpan_add_nhc - register a next header compression to framework
+ *
+ * @nhc: nhc which should be add.
+ */
+int lowpan_add_nhc(struct lowpan_nhc *nhc);
+
+/**
+ * lowpan_del_nhc - delete a next header compression from framework
+ *
+ * @nhc: nhc which should be delete.
+ */
+void lowpan_del_nhc(struct lowpan_nhc *nhc);
+
+/**
+ * lowpan_nhc_do_compression - wrapper for calling compress callback
+ *
+ * @nhc: 6LoWPAN nhc context, get by lowpan_search_nhc_*.
+ * @skb: skb of 6LoWPAN header to read nhc and replace header.
+ * @hc_ptr: pointer for 6LoWPAN header which should increment at the end of
+ * replaced header.
+ * @iphc0: First iphc byte, to set NHC bit.
+ */
+int lowpan_nhc_do_compression(struct lowpan_nhc *nhc, struct sk_buff *skb,
+ u8 **hc_ptr, u8 *iphc0);
+
+/**
+ * lowpan_nhc_do_uncompression - wrapper for calling uncompress callback
+ *
+ * @skb: skb of 6LoWPAN header, skb->data should be pointed to nhc id value.
+ * @hdr: ipv6 header to set the according nexthdr value.
+ */
+int lowpan_nhc_do_uncompression(struct sk_buff **skb, struct ipv6hdr *hdr);
+
+/**
+ * lowpan_init_nhc - init all nhcs
+ */
+int lowpan_init_nhc(void);
+
+/**
+ * lowpan_cleanup_nhc - cleanup all registered nhcs
+ */
+void lowpan_cleanup_nhc(void);
+
+#endif /* __6LOWPAN_NHC_H */
--
2.0.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [RFC bluetooth-next 1/8] 6lowpan: add generic nhc layer interface
2014-08-09 19:02 ` [RFC bluetooth-next 1/8] 6lowpan: add generic nhc layer interface Alexander Aring
@ 2014-08-10 15:02 ` Alexander Aring
2014-08-10 15:14 ` Alexander Aring
1 sibling, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-10 15:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen
Hi,
On Sat, Aug 09, 2014 at 09:02:16PM +0200, Alexander Aring wrote:
...
> +
> +/**
> + * LOWPAN_NHC - helper macro to generate nh id fields and lowpan_nhc struct
> + *
> + * @varname: variable name of the lowpan_nhc struct.
> + * @nhcname: const char * of common header compression name.
> + * @nexthdr: ipv6 nexthdr field for the header compression.
> + * @nhidsetup: callback to setup id and mask values.
> + * @nhidlen: len for the next header id and mask, should be always the same.
> + * @nhuncompress: callback for uncompression call.
> + * @nhcompress: callback for compression call.
> + */
> +#define LOWPAN_NHC(varname, nhcname, nhnexthdr, \
> + nhidsetup, nhidlen, \
> + nhuncompress, nhcompress) \
> + static u8 name##_val[nhidlen]; \
> + static u8 name##_mask[nhidlen]; \
this should be varname instead name. I will fix it for the next version.
> + static struct lowpan_nhc varname = { \
> + .name = nhcname, \
> + .nexthdr = nhnexthdr, \
> + .id = name##_val, \
> + .idmask = name##_mask, \
> + .idlen = nhidlen, \
> + .idsetup = nhidsetup, \
> + .uncompress = nhuncompress, \
> + .compress = nhcompress, \
> + }
> +
- Alex
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [RFC bluetooth-next 1/8] 6lowpan: add generic nhc layer interface
2014-08-09 19:02 ` [RFC bluetooth-next 1/8] 6lowpan: add generic nhc layer interface Alexander Aring
2014-08-10 15:02 ` Alexander Aring
@ 2014-08-10 15:14 ` Alexander Aring
1 sibling, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-10 15:14 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen
On Sat, Aug 09, 2014 at 09:02:16PM +0200, Alexander Aring wrote:
....
> +
> + nhc = lowpan_search_nhc_by_nhcid(*skb);
> + if (nhc) {
> + ret = nhc->uncompress(skb);
> + if (!ret) {
> + skb_reset_transport_header(*skb);
> + hdr->nexthdr = nhc->nexthdr;
> + } else if (ret == -ENOTSUPP) {
> + net_warn_ratelimited("%s received %s which is not supported.\n",
> + (*skb)->dev->name, nhc->name);
> + }
> + }
here we need a else branch and return -ENOENT or something similar to
drop the packet afterwards.
Thanks Phoebe for the hint.
- Alex
^ permalink raw reply [flat|nested] 11+ messages in thread
* [RFC bluetooth-next 2/8] 6lowpan: nhc layer udp compression
2014-08-09 19:02 [RFC bluetooth-next 0/8] 6lowpan: introduce generic next header compression layer Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 1/8] 6lowpan: add generic nhc layer interface Alexander Aring
@ 2014-08-09 19:02 ` Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 3/8] 6lowpan: add hop-by-hop options skeleton Alexander Aring
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-09 19:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen, Alexander Aring
This patch move UDP header compression and uncompression into the
generic 6LoWPAN nhc header compression layer and activate the nhc compression
via the new nhc layer.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/6lowpan/iphc.c | 184 ++++++-----------------------------------------
net/6lowpan/nhc/Makefile | 3 +-
net/6lowpan/nhc/core.c | 4 +-
net/6lowpan/nhc/udp.c | 173 ++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc/udp.h | 9 +++
5 files changed, 208 insertions(+), 165 deletions(-)
create mode 100644 net/6lowpan/nhc/udp.c
create mode 100644 net/6lowpan/nhc/udp.h
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 142eef5..a2ed820 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -57,6 +57,8 @@
#include <net/ipv6.h>
#include <net/af_ieee802154.h>
+#include "nhc/core.h"
+
/* Uncompress address function for source and
* destination address(non-multicast).
*
@@ -258,77 +260,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 };
@@ -457,34 +388,10 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
goto drop;
}
- /* UDP data uncompression */
if (iphc0 & LOWPAN_IPHC_NH_C) {
- struct udphdr uh;
- struct sk_buff *new;
-
- if (uncompress_udp_header(skb, &uh))
+ err = lowpan_nhc_do_uncompression(&skb, &hdr);
+ if (err < 0)
goto drop;
-
- /* replace the compressed UDP head by the uncompressed UDP
- * header
- */
- new = skb_copy_expand(skb, sizeof(struct udphdr),
- skb_tailroom(skb), GFP_ATOMIC);
- kfree_skb(skb);
-
- if (!new)
- return -ENOMEM;
-
- skb = new;
-
- 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;
}
hdr.payload_len = htons(skb->len);
@@ -533,68 +440,12 @@ 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 = 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));
-
- /* 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)
{
u8 tmp, iphc0, iphc1, *hc_ptr;
+ struct lowpan_nhc *nhc;
struct ipv6hdr *hdr;
u8 head[100] = {};
int addr_type;
@@ -672,13 +523,10 @@ 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)
+ nhc = lowpan_search_nhc_by_nexthdr(hdr->nexthdr);
+ if (nhc)
iphc0 |= LOWPAN_IPHC_NH_C;
-
- if ((iphc0 & LOWPAN_IPHC_NH_C) == 0)
+ else
lowpan_push_hc_data(&hc_ptr, &hdr->nexthdr,
sizeof(hdr->nexthdr));
@@ -766,9 +614,7 @@ 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);
+ lowpan_nhc_do_compression(nhc, skb, &hc_ptr, &iphc0);
head[0] = iphc0;
head[1] = iphc1;
@@ -786,4 +632,16 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
}
EXPORT_SYMBOL_GPL(lowpan_header_compress);
+static int __init iphc_init_module(void)
+{
+ return lowpan_init_nhc();
+}
+
+static void __exit iphc_cleanup_module(void)
+{
+ lowpan_cleanup_nhc();
+}
+
MODULE_LICENSE("GPL");
+module_init(iphc_init_module);
+module_exit(iphc_cleanup_module);
diff --git a/net/6lowpan/nhc/Makefile b/net/6lowpan/nhc/Makefile
index 5fe76e47..07431c2 100644
--- a/net/6lowpan/nhc/Makefile
+++ b/net/6lowpan/nhc/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_6LOWPAN) += nhc.o
-nhc-y := core.o
+nhc-y := core.o \
+ udp.o
diff --git a/net/6lowpan/nhc/core.c b/net/6lowpan/nhc/core.c
index 0bf103d..0f98132 100644
--- a/net/6lowpan/nhc/core.c
+++ b/net/6lowpan/nhc/core.c
@@ -15,6 +15,7 @@
#include <net/ipv6.h>
#include "core.h"
+#include "udp.h"
static struct rb_root rb_root = RB_ROOT;
static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
@@ -172,9 +173,10 @@ EXPORT_SYMBOL(lowpan_del_nhc);
int lowpan_init_nhc(void)
{
- return 0;
+ return lowpan_init_nhc_udp();
}
void lowpan_cleanup_nhc(void)
{
+ lowpan_cleanup_nhc_udp();
}
diff --git a/net/6lowpan/nhc/udp.c b/net/6lowpan/nhc/udp.c
new file mode 100644
index 0000000..42368b8
--- /dev/null
+++ b/net/6lowpan/nhc/udp.c
@@ -0,0 +1,173 @@
+/* 6LoWPAN IPv6 UDP compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ *
+ * Orignal written by:
+ * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
+ * Jon Smirl <jonsmirl@gmail.com>
+ *
+ * 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 <net/6lowpan.h>
+#include <linux/skbuff.h>
+
+#include "core.h"
+#include "udp.h"
+
+static int udp_uncompress(struct sk_buff **skb)
+{
+ struct udphdr uh;
+ struct sk_buff *new;
+ bool fail;
+ u8 tmp = 0, val = 0;
+
+ 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:
+ pr_debug("ERROR: unknown UDP format\n");
+ return -EINVAL;
+ }
+
+ 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 lenght 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
+ */
+ new = skb_copy_expand(*skb, sizeof(struct udphdr),
+ skb_tailroom(*skb), GFP_ATOMIC);
+ kfree_skb(*skb);
+ if (!new)
+ return -ENOMEM;
+ *skb = new;
+
+ skb_push(*skb, sizeof(uh));
+ skb_copy_to_linear_data(*skb, &uh, sizeof(struct udphdr));
+
+ return 0;
+}
+
+static int udp_compress(struct sk_buff *skb, u8 **hc_ptr)
+{
+ 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));
+
+ /* skip the UDP header */
+ skb_pull(skb, sizeof(struct udphdr));
+
+ 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(udp_nhc, "IPv6 UDP Header", NEXTHDR_UDP, udp_nhid_setup,
+ LOWPAN_NHC_UDP_LEN, udp_uncompress, udp_compress);
+
+int lowpan_init_nhc_udp(void)
+{
+ return lowpan_add_nhc(&udp_nhc);
+}
+EXPORT_SYMBOL(lowpan_init_nhc_udp);
+
+void lowpan_cleanup_nhc_udp(void)
+{
+ lowpan_del_nhc(&udp_nhc);
+}
+EXPORT_SYMBOL(lowpan_cleanup_nhc_udp);
diff --git a/net/6lowpan/nhc/udp.h b/net/6lowpan/nhc/udp.h
new file mode 100644
index 0000000..ae99448
--- /dev/null
+++ b/net/6lowpan/nhc/udp.h
@@ -0,0 +1,9 @@
+#ifndef __6LOWPAN_NHC_UDP_H
+#define __6LOWPAN_NHC_UDP_H
+
+#define LOWPAN_NHC_UDP_LEN 1
+
+int lowpan_init_nhc_udp(void);
+void lowpan_cleanup_nhc_udp(void);
+
+#endif /* __6LOWPAN_NHC_UDP_H */
--
2.0.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [RFC bluetooth-next 3/8] 6lowpan: add hop-by-hop options skeleton
2014-08-09 19:02 [RFC bluetooth-next 0/8] 6lowpan: introduce generic next header compression layer Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 1/8] 6lowpan: add generic nhc layer interface Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 2/8] 6lowpan: nhc layer udp compression Alexander Aring
@ 2014-08-09 19:02 ` Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 4/8] 6lowpan: add routing skeleton Alexander Aring
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-09 19:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen, Alexander Aring
Currenlty not support. Received packets with this nhc id should be
dropped.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/6lowpan/nhc/Makefile | 3 ++-
net/6lowpan/nhc/core.c | 18 +++++++++++++++++-
net/6lowpan/nhc/hop.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc/hop.h | 11 +++++++++++
4 files changed, 78 insertions(+), 2 deletions(-)
create mode 100644 net/6lowpan/nhc/hop.c
create mode 100644 net/6lowpan/nhc/hop.h
diff --git a/net/6lowpan/nhc/Makefile b/net/6lowpan/nhc/Makefile
index 07431c2..b82135a 100644
--- a/net/6lowpan/nhc/Makefile
+++ b/net/6lowpan/nhc/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_6LOWPAN) += nhc.o
nhc-y := core.o \
- udp.o
+ udp.o \
+ hop.o
diff --git a/net/6lowpan/nhc/core.c b/net/6lowpan/nhc/core.c
index 0f98132..80ed357 100644
--- a/net/6lowpan/nhc/core.c
+++ b/net/6lowpan/nhc/core.c
@@ -16,6 +16,7 @@
#include "core.h"
#include "udp.h"
+#include "hop.h"
static struct rb_root rb_root = RB_ROOT;
static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
@@ -173,10 +174,25 @@ EXPORT_SYMBOL(lowpan_del_nhc);
int lowpan_init_nhc(void)
{
- return lowpan_init_nhc_udp();
+ int ret;
+
+ ret = lowpan_init_nhc_udp();
+ if (ret < 0)
+ goto out;
+
+ ret = lowpan_init_nhc_hop();
+ if (ret < 0)
+ goto hop_fail;
+out:
+ return ret;
+
+hop_fail:
+ lowpan_cleanup_nhc_udp();
+ goto out;
}
void lowpan_cleanup_nhc(void)
{
lowpan_cleanup_nhc_udp();
+ lowpan_cleanup_nhc_hop();
}
diff --git a/net/6lowpan/nhc/hop.c b/net/6lowpan/nhc/hop.c
new file mode 100644
index 0000000..f74ac72
--- /dev/null
+++ b/net/6lowpan/nhc/hop.c
@@ -0,0 +1,48 @@
+/* 6LoWPAN IPv6 Hop-by-Hop Options Header compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ *
+ * 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 <net/6lowpan.h>
+#include <linux/skbuff.h>
+
+#include "core.h"
+#include "hop.h"
+
+static int hop_uncompress(struct sk_buff **skb)
+{
+ return -ENOTSUPP;
+}
+
+static int hop_compress(struct sk_buff *skb, u8 **hc_ptr)
+{
+ return -ENOTSUPP;
+}
+
+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(hop_nhc, "IPv6 Hop-by-Hop Options Header", NEXTHDR_HOP,
+ hop_nhid_setup, LOWPAN_NHC_HOP_LEN, hop_uncompress, hop_compress);
+
+int lowpan_init_nhc_hop(void)
+{
+ return lowpan_add_nhc(&hop_nhc);
+}
+EXPORT_SYMBOL(lowpan_init_nhc_hop);
+
+void lowpan_cleanup_nhc_hop(void)
+{
+ lowpan_del_nhc(&hop_nhc);
+}
+EXPORT_SYMBOL(lowpan_cleanup_nhc_hop);
diff --git a/net/6lowpan/nhc/hop.h b/net/6lowpan/nhc/hop.h
new file mode 100644
index 0000000..c03fc58
--- /dev/null
+++ b/net/6lowpan/nhc/hop.h
@@ -0,0 +1,11 @@
+#ifndef __6LOWPAN_NHC_HOP_H
+#define __6LOWPAN_NHC_HOP_H
+
+#define LOWPAN_NHC_HOP_LEN 1
+#define LOWPAN_NHC_HOP_ID_0 0xe0
+#define LOWPAN_NHC_HOP_MASK_0 0xfe
+
+int lowpan_init_nhc_hop(void);
+void lowpan_cleanup_nhc_hop(void);
+
+#endif /* __6LOWPAN_NHC_HOP_H */
--
2.0.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [RFC bluetooth-next 4/8] 6lowpan: add routing skeleton
2014-08-09 19:02 [RFC bluetooth-next 0/8] 6lowpan: introduce generic next header compression layer Alexander Aring
` (2 preceding siblings ...)
2014-08-09 19:02 ` [RFC bluetooth-next 3/8] 6lowpan: add hop-by-hop options skeleton Alexander Aring
@ 2014-08-09 19:02 ` Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 5/8] 6lowpan: add fragment skeleton Alexander Aring
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-09 19:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen, Alexander Aring
Currenlty not support. Received packets with this nhc id should be
dropped.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/6lowpan/nhc/Makefile | 3 ++-
net/6lowpan/nhc/core.c | 8 ++++++++
net/6lowpan/nhc/route.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc/route.h | 11 +++++++++++
4 files changed, 69 insertions(+), 1 deletion(-)
create mode 100644 net/6lowpan/nhc/route.c
create mode 100644 net/6lowpan/nhc/route.h
diff --git a/net/6lowpan/nhc/Makefile b/net/6lowpan/nhc/Makefile
index b82135a..81aa18d 100644
--- a/net/6lowpan/nhc/Makefile
+++ b/net/6lowpan/nhc/Makefile
@@ -2,4 +2,5 @@ obj-$(CONFIG_6LOWPAN) += nhc.o
nhc-y := core.o \
udp.o \
- hop.o
+ hop.o \
+ route.o
diff --git a/net/6lowpan/nhc/core.c b/net/6lowpan/nhc/core.c
index 80ed357..db499bb 100644
--- a/net/6lowpan/nhc/core.c
+++ b/net/6lowpan/nhc/core.c
@@ -17,6 +17,7 @@
#include "core.h"
#include "udp.h"
#include "hop.h"
+#include "route.h"
static struct rb_root rb_root = RB_ROOT;
static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
@@ -183,9 +184,15 @@ int lowpan_init_nhc(void)
ret = lowpan_init_nhc_hop();
if (ret < 0)
goto hop_fail;
+
+ ret = lowpan_init_nhc_route();
+ if (ret < 0)
+ goto route_fail;
out:
return ret;
+route_fail:
+ lowpan_cleanup_nhc_hop();
hop_fail:
lowpan_cleanup_nhc_udp();
goto out;
@@ -195,4 +202,5 @@ void lowpan_cleanup_nhc(void)
{
lowpan_cleanup_nhc_udp();
lowpan_cleanup_nhc_hop();
+ lowpan_cleanup_nhc_route();
}
diff --git a/net/6lowpan/nhc/route.c b/net/6lowpan/nhc/route.c
new file mode 100644
index 0000000..e5d8045
--- /dev/null
+++ b/net/6lowpan/nhc/route.c
@@ -0,0 +1,48 @@
+/* 6LoWPAN IPv6 Routing Header compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ *
+ * 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 <net/6lowpan.h>
+#include <linux/skbuff.h>
+
+#include "core.h"
+#include "route.h"
+
+static int route_uncompress(struct sk_buff **skb)
+{
+ return -ENOTSUPP;
+}
+
+static int route_compress(struct sk_buff *skb, u8 **hc_ptr)
+{
+ return -ENOTSUPP;
+}
+
+static void route_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_ROUTE_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_ROUTE_MASK_0;
+}
+
+LOWPAN_NHC(route_nhc, "IPv6 Routing Header", NEXTHDR_ROUTING, route_nhid_setup,
+ LOWPAN_NHC_ROUTE_LEN, route_uncompress, route_compress);
+
+int lowpan_init_nhc_route(void)
+{
+ return lowpan_add_nhc(&route_nhc);
+}
+EXPORT_SYMBOL(lowpan_init_nhc_route);
+
+void lowpan_cleanup_nhc_route(void)
+{
+ lowpan_del_nhc(&route_nhc);
+}
+EXPORT_SYMBOL(lowpan_cleanup_nhc_route);
diff --git a/net/6lowpan/nhc/route.h b/net/6lowpan/nhc/route.h
new file mode 100644
index 0000000..78cd6b5
--- /dev/null
+++ b/net/6lowpan/nhc/route.h
@@ -0,0 +1,11 @@
+#ifndef __6LOWPAN_NHC_ROUTE_H
+#define __6LOWPAN_NHC_ROUTE_H
+
+#define LOWPAN_NHC_ROUTE_LEN 1
+#define LOWPAN_NHC_ROUTE_ID_0 0xe2
+#define LOWPAN_NHC_ROUTE_MASK_0 0xfe
+
+int lowpan_init_nhc_route(void);
+void lowpan_cleanup_nhc_route(void);
+
+#endif /* __6LOWPAN_NHC_ROUTE_H */
--
2.0.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [RFC bluetooth-next 5/8] 6lowpan: add fragment skeleton
2014-08-09 19:02 [RFC bluetooth-next 0/8] 6lowpan: introduce generic next header compression layer Alexander Aring
` (3 preceding siblings ...)
2014-08-09 19:02 ` [RFC bluetooth-next 4/8] 6lowpan: add routing skeleton Alexander Aring
@ 2014-08-09 19:02 ` Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 6/8] 6lowpan: add destination options skeleton Alexander Aring
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-09 19:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen, Alexander Aring
Currenlty not support. Received packets with this nhc id should be
dropped.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/6lowpan/nhc/Makefile | 3 ++-
net/6lowpan/nhc/core.c | 8 ++++++++
net/6lowpan/nhc/frag.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc/frag.h | 11 +++++++++++
4 files changed, 70 insertions(+), 1 deletion(-)
create mode 100644 net/6lowpan/nhc/frag.c
create mode 100644 net/6lowpan/nhc/frag.h
diff --git a/net/6lowpan/nhc/Makefile b/net/6lowpan/nhc/Makefile
index 81aa18d..e524c57 100644
--- a/net/6lowpan/nhc/Makefile
+++ b/net/6lowpan/nhc/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_6LOWPAN) += nhc.o
nhc-y := core.o \
udp.o \
hop.o \
- route.o
+ route.o \
+ frag.o
diff --git a/net/6lowpan/nhc/core.c b/net/6lowpan/nhc/core.c
index db499bb..728dd06 100644
--- a/net/6lowpan/nhc/core.c
+++ b/net/6lowpan/nhc/core.c
@@ -18,6 +18,7 @@
#include "udp.h"
#include "hop.h"
#include "route.h"
+#include "frag.h"
static struct rb_root rb_root = RB_ROOT;
static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
@@ -188,9 +189,15 @@ int lowpan_init_nhc(void)
ret = lowpan_init_nhc_route();
if (ret < 0)
goto route_fail;
+
+ ret = lowpan_init_nhc_frag();
+ if (ret < 0)
+ goto frag_fail;
out:
return ret;
+frag_fail:
+ lowpan_cleanup_nhc_route();
route_fail:
lowpan_cleanup_nhc_hop();
hop_fail:
@@ -203,4 +210,5 @@ void lowpan_cleanup_nhc(void)
lowpan_cleanup_nhc_udp();
lowpan_cleanup_nhc_hop();
lowpan_cleanup_nhc_route();
+ lowpan_cleanup_nhc_frag();
}
diff --git a/net/6lowpan/nhc/frag.c b/net/6lowpan/nhc/frag.c
new file mode 100644
index 0000000..ac07a73
--- /dev/null
+++ b/net/6lowpan/nhc/frag.c
@@ -0,0 +1,49 @@
+/* 6LoWPAN IPv6 Fragment Header compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ *
+ * 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 <net/6lowpan.h>
+#include <linux/skbuff.h>
+
+#include "core.h"
+#include "frag.h"
+
+static int frag_uncompress(struct sk_buff **skb)
+{
+ return -ENOTSUPP;
+}
+
+static int frag_compress(struct sk_buff *skb, u8 **hc_ptr)
+{
+ return -ENOTSUPP;
+}
+
+static void frag_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_FRAG_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_FRAG_MASK_0;
+}
+
+LOWPAN_NHC(frag_nhc, "IPv6 Fragment Header", NEXTHDR_FRAGMENT,
+ frag_nhid_setup, LOWPAN_NHC_FRAG_LEN, frag_uncompress,
+ frag_compress);
+
+int lowpan_init_nhc_frag(void)
+{
+ return lowpan_add_nhc(&frag_nhc);
+}
+EXPORT_SYMBOL(lowpan_init_nhc_frag);
+
+void lowpan_cleanup_nhc_frag(void)
+{
+ lowpan_del_nhc(&frag_nhc);
+}
+EXPORT_SYMBOL(lowpan_cleanup_nhc_frag);
diff --git a/net/6lowpan/nhc/frag.h b/net/6lowpan/nhc/frag.h
new file mode 100644
index 0000000..e760720
--- /dev/null
+++ b/net/6lowpan/nhc/frag.h
@@ -0,0 +1,11 @@
+#ifndef __6LOWPAN_NHC_FRAG_H
+#define __6LOWPAN_NHC_FRAG_H
+
+#define LOWPAN_NHC_FRAG_LEN 1
+#define LOWPAN_NHC_FRAG_ID_0 0xe4
+#define LOWPAN_NHC_FRAG_MASK_0 0xfe
+
+int lowpan_init_nhc_frag(void);
+void lowpan_cleanup_nhc_frag(void);
+
+#endif /* __6LOWPAN_NHC_FRAG_H */
--
2.0.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [RFC bluetooth-next 6/8] 6lowpan: add destination options skeleton
2014-08-09 19:02 [RFC bluetooth-next 0/8] 6lowpan: introduce generic next header compression layer Alexander Aring
` (4 preceding siblings ...)
2014-08-09 19:02 ` [RFC bluetooth-next 5/8] 6lowpan: add fragment skeleton Alexander Aring
@ 2014-08-09 19:02 ` Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 7/8] 6lowpan: add mobility skeleton Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 8/8] 6lowpan: add ipv6 skeleton Alexander Aring
7 siblings, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-09 19:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen, Alexander Aring
Currenlty not support. Received packets with this nhc id should be
dropped.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/6lowpan/nhc/Makefile | 3 ++-
net/6lowpan/nhc/core.c | 8 ++++++++
net/6lowpan/nhc/dest.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc/dest.h | 11 +++++++++++
4 files changed, 70 insertions(+), 1 deletion(-)
create mode 100644 net/6lowpan/nhc/dest.c
create mode 100644 net/6lowpan/nhc/dest.h
diff --git a/net/6lowpan/nhc/Makefile b/net/6lowpan/nhc/Makefile
index e524c57..1b67930 100644
--- a/net/6lowpan/nhc/Makefile
+++ b/net/6lowpan/nhc/Makefile
@@ -4,4 +4,5 @@ nhc-y := core.o \
udp.o \
hop.o \
route.o \
- frag.o
+ frag.o \
+ dest.o
diff --git a/net/6lowpan/nhc/core.c b/net/6lowpan/nhc/core.c
index 728dd06..73d9e1e 100644
--- a/net/6lowpan/nhc/core.c
+++ b/net/6lowpan/nhc/core.c
@@ -19,6 +19,7 @@
#include "hop.h"
#include "route.h"
#include "frag.h"
+#include "dest.h"
static struct rb_root rb_root = RB_ROOT;
static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
@@ -193,9 +194,15 @@ int lowpan_init_nhc(void)
ret = lowpan_init_nhc_frag();
if (ret < 0)
goto frag_fail;
+
+ ret = lowpan_init_nhc_dest();
+ if (ret < 0)
+ goto dest_fail;
out:
return ret;
+dest_fail:
+ lowpan_cleanup_nhc_frag();
frag_fail:
lowpan_cleanup_nhc_route();
route_fail:
@@ -211,4 +218,5 @@ void lowpan_cleanup_nhc(void)
lowpan_cleanup_nhc_hop();
lowpan_cleanup_nhc_route();
lowpan_cleanup_nhc_frag();
+ lowpan_cleanup_nhc_dest();
}
diff --git a/net/6lowpan/nhc/dest.c b/net/6lowpan/nhc/dest.c
new file mode 100644
index 0000000..29469f3
--- /dev/null
+++ b/net/6lowpan/nhc/dest.c
@@ -0,0 +1,49 @@
+/* 6LoWPAN IPv6 Destination Options Header compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ *
+ * 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 <net/6lowpan.h>
+#include <linux/skbuff.h>
+
+#include "core.h"
+#include "dest.h"
+
+static int dest_uncompress(struct sk_buff **skb)
+{
+ return -ENOTSUPP;
+}
+
+static int dest_compress(struct sk_buff *skb, u8 **hc_ptr)
+{
+ return -ENOTSUPP;
+}
+
+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(dest_nhc, "IPv6 Destination Options Header", NEXTHDR_DEST,
+ dest_nhid_setup, LOWPAN_NHC_DEST_LEN, dest_uncompress,
+ dest_compress);
+
+int lowpan_init_nhc_dest(void)
+{
+ return lowpan_add_nhc(&dest_nhc);
+}
+EXPORT_SYMBOL(lowpan_init_nhc_dest);
+
+void lowpan_cleanup_nhc_dest(void)
+{
+ lowpan_del_nhc(&dest_nhc);
+}
+EXPORT_SYMBOL(lowpan_cleanup_nhc_dest);
diff --git a/net/6lowpan/nhc/dest.h b/net/6lowpan/nhc/dest.h
new file mode 100644
index 0000000..f537e3f
--- /dev/null
+++ b/net/6lowpan/nhc/dest.h
@@ -0,0 +1,11 @@
+#ifndef __6LOWPAN_NHC_DEST_H
+#define __6LOWPAN_NHC_DEST_H
+
+#define LOWPAN_NHC_DEST_LEN 1
+#define LOWPAN_NHC_DEST_ID_0 0xe6
+#define LOWPAN_NHC_DEST_MASK_0 0xfe
+
+int lowpan_init_nhc_dest(void);
+void lowpan_cleanup_nhc_dest(void);
+
+#endif /* __6LOWPAN_NHC_DEST_H */
--
2.0.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [RFC bluetooth-next 7/8] 6lowpan: add mobility skeleton
2014-08-09 19:02 [RFC bluetooth-next 0/8] 6lowpan: introduce generic next header compression layer Alexander Aring
` (5 preceding siblings ...)
2014-08-09 19:02 ` [RFC bluetooth-next 6/8] 6lowpan: add destination options skeleton Alexander Aring
@ 2014-08-09 19:02 ` Alexander Aring
2014-08-09 19:02 ` [RFC bluetooth-next 8/8] 6lowpan: add ipv6 skeleton Alexander Aring
7 siblings, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-09 19:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen, Alexander Aring
Currenlty not support. Received packets with this nhc id should be
dropped.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/6lowpan/nhc/Makefile | 3 ++-
net/6lowpan/nhc/core.c | 8 ++++++++
net/6lowpan/nhc/mobil.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc/mobil.h | 11 +++++++++++
4 files changed, 70 insertions(+), 1 deletion(-)
create mode 100644 net/6lowpan/nhc/mobil.c
create mode 100644 net/6lowpan/nhc/mobil.h
diff --git a/net/6lowpan/nhc/Makefile b/net/6lowpan/nhc/Makefile
index 1b67930..9915c31 100644
--- a/net/6lowpan/nhc/Makefile
+++ b/net/6lowpan/nhc/Makefile
@@ -5,4 +5,5 @@ nhc-y := core.o \
hop.o \
route.o \
frag.o \
- dest.o
+ dest.o \
+ mobil.o
diff --git a/net/6lowpan/nhc/core.c b/net/6lowpan/nhc/core.c
index 73d9e1e..1ee9750 100644
--- a/net/6lowpan/nhc/core.c
+++ b/net/6lowpan/nhc/core.c
@@ -20,6 +20,7 @@
#include "route.h"
#include "frag.h"
#include "dest.h"
+#include "mobil.h"
static struct rb_root rb_root = RB_ROOT;
static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
@@ -198,9 +199,15 @@ int lowpan_init_nhc(void)
ret = lowpan_init_nhc_dest();
if (ret < 0)
goto dest_fail;
+
+ ret = lowpan_init_nhc_mobil();
+ if (ret < 0)
+ goto mobil_fail;
out:
return ret;
+mobil_fail:
+ lowpan_cleanup_nhc_dest();
dest_fail:
lowpan_cleanup_nhc_frag();
frag_fail:
@@ -219,4 +226,5 @@ void lowpan_cleanup_nhc(void)
lowpan_cleanup_nhc_route();
lowpan_cleanup_nhc_frag();
lowpan_cleanup_nhc_dest();
+ lowpan_cleanup_nhc_mobil();
}
diff --git a/net/6lowpan/nhc/mobil.c b/net/6lowpan/nhc/mobil.c
new file mode 100644
index 0000000..66c7817
--- /dev/null
+++ b/net/6lowpan/nhc/mobil.c
@@ -0,0 +1,49 @@
+/* 6LoWPAN IPv6 Mobility Header compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ *
+ * 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 <net/6lowpan.h>
+#include <linux/skbuff.h>
+
+#include "core.h"
+#include "mobil.h"
+
+static int mobil_uncompress(struct sk_buff **skb)
+{
+ return -ENOTSUPP;
+}
+
+static int mobil_compress(struct sk_buff *skb, u8 **hc_ptr)
+{
+ return -ENOTSUPP;
+}
+
+static void mobil_nhid_setup(struct lowpan_nhc *nhc)
+{
+ nhc->id[0] = LOWPAN_NHC_MOBIL_ID_0;
+ nhc->idmask[0] = LOWPAN_NHC_MOBIL_MASK_0;
+}
+
+LOWPAN_NHC(mobil_nhc, "IPv6 Mobility Header", NEXTHDR_MOBILITY,
+ mobil_nhid_setup, LOWPAN_NHC_MOBIL_LEN, mobil_uncompress,
+ mobil_compress);
+
+int lowpan_init_nhc_mobil(void)
+{
+ return lowpan_add_nhc(&mobil_nhc);
+}
+EXPORT_SYMBOL(lowpan_init_nhc_mobil);
+
+void lowpan_cleanup_nhc_mobil(void)
+{
+ lowpan_del_nhc(&mobil_nhc);
+}
+EXPORT_SYMBOL(lowpan_cleanup_nhc_mobil);
diff --git a/net/6lowpan/nhc/mobil.h b/net/6lowpan/nhc/mobil.h
new file mode 100644
index 0000000..fcfdb55
--- /dev/null
+++ b/net/6lowpan/nhc/mobil.h
@@ -0,0 +1,11 @@
+#ifndef __6LOWPAN_NHC_MOBIL_H
+#define __6LOWPAN_NHC_MOBIL_H
+
+#define LOWPAN_NHC_MOBIL_LEN 1
+#define LOWPAN_NHC_MOBIL_ID_0 0xe8
+#define LOWPAN_NHC_MOBIL_MASK_0 0xfe
+
+int lowpan_init_nhc_mobil(void);
+void lowpan_cleanup_nhc_mobil(void);
+
+#endif /* __6LOWPAN_NHC_MOBIL_H */
--
2.0.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [RFC bluetooth-next 8/8] 6lowpan: add ipv6 skeleton
2014-08-09 19:02 [RFC bluetooth-next 0/8] 6lowpan: introduce generic next header compression layer Alexander Aring
` (6 preceding siblings ...)
2014-08-09 19:02 ` [RFC bluetooth-next 7/8] 6lowpan: add mobility skeleton Alexander Aring
@ 2014-08-09 19:02 ` Alexander Aring
7 siblings, 0 replies; 11+ messages in thread
From: Alexander Aring @ 2014-08-09 19:02 UTC (permalink / raw)
To: linux-wpan; +Cc: linux-bluetooth, jukka.rissanen, Alexander Aring
Currenlty not support. Received packets with this nhc id should be
dropped.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/6lowpan/nhc/Makefile | 3 ++-
net/6lowpan/nhc/core.c | 8 ++++++++
net/6lowpan/nhc/ipv6.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
net/6lowpan/nhc/ipv6.h | 11 +++++++++++
4 files changed, 69 insertions(+), 1 deletion(-)
create mode 100644 net/6lowpan/nhc/ipv6.c
create mode 100644 net/6lowpan/nhc/ipv6.h
diff --git a/net/6lowpan/nhc/Makefile b/net/6lowpan/nhc/Makefile
index 9915c31..4d91480 100644
--- a/net/6lowpan/nhc/Makefile
+++ b/net/6lowpan/nhc/Makefile
@@ -6,4 +6,5 @@ nhc-y := core.o \
route.o \
frag.o \
dest.o \
- mobil.o
+ mobil.o \
+ ipv6.o
diff --git a/net/6lowpan/nhc/core.c b/net/6lowpan/nhc/core.c
index 1ee9750..66907ff 100644
--- a/net/6lowpan/nhc/core.c
+++ b/net/6lowpan/nhc/core.c
@@ -21,6 +21,7 @@
#include "frag.h"
#include "dest.h"
#include "mobil.h"
+#include "ipv6.h"
static struct rb_root rb_root = RB_ROOT;
static struct lowpan_nhc *lowpan_nexthdr_nhcs[NEXTHDR_MAX];
@@ -203,9 +204,15 @@ int lowpan_init_nhc(void)
ret = lowpan_init_nhc_mobil();
if (ret < 0)
goto mobil_fail;
+
+ ret = lowpan_init_nhc_ipv6();
+ if (ret < 0)
+ goto ipv6_fail;
out:
return ret;
+ipv6_fail:
+ lowpan_cleanup_nhc_mobil();
mobil_fail:
lowpan_cleanup_nhc_dest();
dest_fail:
@@ -227,4 +234,5 @@ void lowpan_cleanup_nhc(void)
lowpan_cleanup_nhc_frag();
lowpan_cleanup_nhc_dest();
lowpan_cleanup_nhc_mobil();
+ lowpan_cleanup_nhc_ipv6();
}
diff --git a/net/6lowpan/nhc/ipv6.c b/net/6lowpan/nhc/ipv6.c
new file mode 100644
index 0000000..59202cf
--- /dev/null
+++ b/net/6lowpan/nhc/ipv6.c
@@ -0,0 +1,48 @@
+/* 6LoWPAN IPv6 Header compression
+ *
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ *
+ * 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 <net/6lowpan.h>
+#include <linux/skbuff.h>
+
+#include "core.h"
+#include "ipv6.h"
+
+static int ipv6_uncompress(struct sk_buff **skb)
+{
+ return -ENOTSUPP;
+}
+
+static int ipv6_compress(struct sk_buff *skb, u8 **hc_ptr)
+{
+ return -ENOTSUPP;
+}
+
+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(ipv6_nhc, "IPv6 Header", NEXTHDR_IPV6, ipv6_nhid_setup,
+ LOWPAN_NHC_IPV6_LEN, ipv6_uncompress, ipv6_compress);
+
+int lowpan_init_nhc_ipv6(void)
+{
+ return lowpan_add_nhc(&ipv6_nhc);
+}
+EXPORT_SYMBOL(lowpan_init_nhc_ipv6);
+
+void lowpan_cleanup_nhc_ipv6(void)
+{
+ lowpan_del_nhc(&ipv6_nhc);
+}
+EXPORT_SYMBOL(lowpan_cleanup_nhc_ipv6);
diff --git a/net/6lowpan/nhc/ipv6.h b/net/6lowpan/nhc/ipv6.h
new file mode 100644
index 0000000..defc183
--- /dev/null
+++ b/net/6lowpan/nhc/ipv6.h
@@ -0,0 +1,11 @@
+#ifndef __6LOWPAN_NHC_IPV6_H
+#define __6LOWPAN_NHC_IPV6_H
+
+#define LOWPAN_NHC_IPV6_LEN 1
+#define LOWPAN_NHC_IPV6_ID_0 0xee
+#define LOWPAN_NHC_IPV6_MASK_0 0xfe
+
+int lowpan_init_nhc_ipv6(void);
+void lowpan_cleanup_nhc_ipv6(void);
+
+#endif /* __6LOWPAN_NHC_IPV6_H */
--
2.0.3
^ permalink raw reply related [flat|nested] 11+ messages in thread