* [PATCH bluetooth-next 1/7] 6lowpan: allow pull only at lowpan_fetch_skb
2014-12-23 14:28 [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
@ 2014-12-23 14:28 ` Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 2/7] ieee802154: 6lowpan: skb_pull with error handling Alexander Aring
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Alexander Aring @ 2014-12-23 14:28 UTC (permalink / raw)
To: linux-wpan; +Cc: kernel, Alexander Aring, Jukka Rissanen
This patch adds a check on data pointer. If this pointer is NULL we
don't copy data from skb into data. This is useful if we only check if
we can run skb_pull and doing it afterwards.
Cc: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
include/net/6lowpan.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index dc03d77..c64d274 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -246,7 +246,9 @@ static inline bool lowpan_fetch_skb(struct sk_buff *skb,
if (unlikely(!pskb_may_pull(skb, len)))
return true;
- skb_copy_from_linear_data(skb, data, len);
+ if (likely(data))
+ skb_copy_from_linear_data(skb, data, len);
+
skb_pull(skb, len);
return false;
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH bluetooth-next 2/7] ieee802154: 6lowpan: skb_pull with error handling
2014-12-23 14:28 [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 1/7] 6lowpan: allow pull only at lowpan_fetch_skb Alexander Aring
@ 2014-12-23 14:28 ` Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 3/7] ieee802154: 6lowpan: use skb_network_header Alexander Aring
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Alexander Aring @ 2014-12-23 14:28 UTC (permalink / raw)
To: linux-wpan; +Cc: kernel, Alexander Aring
This patch replaces a skb_pull with a lowpan_fetch_skb with has some
error handling functionaltiy if the skb data isn't enough to run a
skb_pull.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/ieee802154/6lowpan/rx.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ieee802154/6lowpan/rx.c b/net/ieee802154/6lowpan/rx.c
index 4be1d28..22a1db4 100644
--- a/net/ieee802154/6lowpan/rx.c
+++ b/net/ieee802154/6lowpan/rx.c
@@ -108,7 +108,9 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
/* check that it's our buffer */
if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
/* Pull off the 1-byte of 6lowpan header. */
- skb_pull(skb, 1);
+ if (lowpan_fetch_skb(skb, NULL, 1))
+ goto drop_skb;
+
return lowpan_give_skb_to_devices(skb, NULL);
} else {
switch (skb->data[0] & 0xe0) {
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH bluetooth-next 3/7] ieee802154: 6lowpan: use skb_network_header
2014-12-23 14:28 [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 1/7] 6lowpan: allow pull only at lowpan_fetch_skb Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 2/7] ieee802154: 6lowpan: skb_pull with error handling Alexander Aring
@ 2014-12-23 14:28 ` Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 4/7] ieee802154: 6lowpan: remove rx full-size calc workaround Alexander Aring
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Alexander Aring @ 2014-12-23 14:28 UTC (permalink / raw)
To: linux-wpan; +Cc: kernel, Alexander Aring
This patch is just a little cleanup to use *skb_network_header(skb)
instead of skb->data[0].
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/ieee802154/6lowpan/rx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ieee802154/6lowpan/rx.c b/net/ieee802154/6lowpan/rx.c
index 22a1db4..a7b9d39 100644
--- a/net/ieee802154/6lowpan/rx.c
+++ b/net/ieee802154/6lowpan/rx.c
@@ -106,14 +106,14 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
goto drop_skb;
/* check that it's our buffer */
- if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
+ if (*skb_network_header(skb) == LOWPAN_DISPATCH_IPV6) {
/* Pull off the 1-byte of 6lowpan header. */
if (lowpan_fetch_skb(skb, NULL, 1))
goto drop_skb;
return lowpan_give_skb_to_devices(skb, NULL);
} else {
- switch (skb->data[0] & 0xe0) {
+ switch (*skb_network_header(skb) & 0xe0) {
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
ret = iphc_decompress(skb, &hdr);
if (ret < 0)
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH bluetooth-next 4/7] ieee802154: 6lowpan: remove rx full-size calc workaround
2014-12-23 14:28 [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
` (2 preceding siblings ...)
2014-12-23 14:28 ` [PATCH bluetooth-next 3/7] ieee802154: 6lowpan: use skb_network_header Alexander Aring
@ 2014-12-23 14:28 ` Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 5/7] ieee802154: 6lowpan: handle fragmented IPv6 Alexander Aring
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Alexander Aring @ 2014-12-23 14:28 UTC (permalink / raw)
To: linux-wpan; +Cc: kernel, Alexander Aring
This patch removes a workaround to call lowpan_uncompress_size while
receiving first fragment. The lowpan_uncompress_size function is very
statically and should not be used. Instead we do a uncompression
on-the-fly while receiving first fragment.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/ieee802154/6lowpan/6lowpan_i.h | 1 +
net/ieee802154/6lowpan/reassembly.c | 25 +++++++++++++++++++++----
net/ieee802154/6lowpan/rx.c | 21 ++++++++-------------
3 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/net/ieee802154/6lowpan/6lowpan_i.h b/net/ieee802154/6lowpan/6lowpan_i.h
index e50f69d..63a7ad7 100644
--- a/net/ieee802154/6lowpan/6lowpan_i.h
+++ b/net/ieee802154/6lowpan/6lowpan_i.h
@@ -60,6 +60,7 @@ extern struct list_head lowpan_devices;
int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type);
void lowpan_net_frag_exit(void);
int lowpan_net_frag_init(void);
+int iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr);
void lowpan_rx_init(void);
void lowpan_rx_exit(void);
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c
index f46e4d1..c76c0cb 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -201,12 +201,29 @@ found:
fq->q.stamp = skb->tstamp;
if (frag_type == LOWPAN_DISPATCH_FRAG1) {
- /* Calculate uncomp. 6lowpan header to estimate full size */
- fq->q.meat += lowpan_uncompress_size(skb, NULL);
+ int ret;
+ struct ieee802154_hdr hdr;
+
+ ret = ieee802154_hdr_peek_addrs(skb, &hdr);
+ if (ret < 0)
+ goto err;
+
+ /* TODO use CALL_RXH when parsing rework is done. */
+ switch (*skb_network_header(skb) & 0xe0) {
+ case LOWPAN_DISPATCH_IPHC:
+ /* uncompress ipv6 header */
+ ret = iphc_decompress(skb, &hdr);
+ if (ret < 0)
+ goto err;
+ break;
+ default:
+ goto err;
+ }
+
fq->q.flags |= INET_FRAG_FIRST_IN;
- } else {
- fq->q.meat += skb->len;
}
+
+ fq->q.meat += skb->len;
add_frag_mem_limit(&fq->q, skb->truesize);
if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
diff --git a/net/ieee802154/6lowpan/rx.c b/net/ieee802154/6lowpan/rx.c
index a7b9d39..158756f 100644
--- a/net/ieee802154/6lowpan/rx.c
+++ b/net/ieee802154/6lowpan/rx.c
@@ -47,8 +47,7 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
return stat;
}
-static int
-iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
+int iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
{
u8 iphc0, iphc1;
struct ieee802154_addr_sa sa, da;
@@ -102,9 +101,6 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
if (dev->type != ARPHRD_IEEE802154)
goto drop_skb;
- if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
- goto drop_skb;
-
/* check that it's our buffer */
if (*skb_network_header(skb) == LOWPAN_DISPATCH_IPV6) {
/* Pull off the 1-byte of 6lowpan header. */
@@ -115,6 +111,9 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
} else {
switch (*skb_network_header(skb) & 0xe0) {
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
+ if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
+ goto drop_skb;
+
ret = iphc_decompress(skb, &hdr);
if (ret < 0)
goto drop_skb;
@@ -123,10 +122,8 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
if (ret == 1) {
- ret = iphc_decompress(skb, &hdr);
- if (ret < 0)
- goto drop_skb;
-
+ ipv6_hdr(skb)->payload_len = htons(skb->len -
+ sizeof(struct ipv6hdr));
return lowpan_give_skb_to_devices(skb, NULL);
} else if (ret == -1) {
return NET_RX_DROP;
@@ -136,10 +133,8 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
if (ret == 1) {
- ret = iphc_decompress(skb, &hdr);
- if (ret < 0)
- goto drop_skb;
-
+ ipv6_hdr(skb)->payload_len = htons(skb->len -
+ sizeof(struct ipv6hdr));
return lowpan_give_skb_to_devices(skb, NULL);
} else if (ret == -1) {
return NET_RX_DROP;
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH bluetooth-next 5/7] ieee802154: 6lowpan: handle fragmented IPv6
2014-12-23 14:28 [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
` (3 preceding siblings ...)
2014-12-23 14:28 ` [PATCH bluetooth-next 4/7] ieee802154: 6lowpan: remove rx full-size calc workaround Alexander Aring
@ 2014-12-23 14:28 ` Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 6/7] ieee802154: 6lowpan: cleanup frag dispatch cases Alexander Aring
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Alexander Aring @ 2014-12-23 14:28 UTC (permalink / raw)
To: linux-wpan; +Cc: kernel, Alexander Aring
This patch adds handling for a fragmented uncompressed 6LoWPAN packet.
In case that the IPHC compression is above MTU 127, we should not run
IPHC compression. This is still a bug in transmit functionality that we
don't support that, but also not a bug because in worst-case we didn't
hit the case that IPHC compression doesn't fit into a single 802.15.4
frame. Nevertheless this patch adds this handling for receive functionality
only, so other 6LoWPAN stacks can send uncompressed fragmented 6LoWPAN
packets.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/ieee802154/6lowpan/reassembly.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c
index c76c0cb..d47b34e 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -209,15 +209,21 @@ found:
goto err;
/* TODO use CALL_RXH when parsing rework is done. */
- switch (*skb_network_header(skb) & 0xe0) {
- case LOWPAN_DISPATCH_IPHC:
- /* uncompress ipv6 header */
- ret = iphc_decompress(skb, &hdr);
- if (ret < 0)
+ if (*skb_network_header(skb) == LOWPAN_DISPATCH_IPV6) {
+ /* Pull off the 1-byte of 6lowpan header. */
+ if (lowpan_fetch_skb(skb, NULL, 1))
goto err;
- break;
- default:
- goto err;
+ } else {
+ switch (*skb_network_header(skb) & 0xe0) {
+ case LOWPAN_DISPATCH_IPHC:
+ /* uncompress ipv6 header */
+ ret = iphc_decompress(skb, &hdr);
+ if (ret < 0)
+ goto err;
+ break;
+ default:
+ goto err;
+ }
}
fq->q.flags |= INET_FRAG_FIRST_IN;
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH bluetooth-next 6/7] ieee802154: 6lowpan: cleanup frag dispatch cases
2014-12-23 14:28 [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
` (4 preceding siblings ...)
2014-12-23 14:28 ` [PATCH bluetooth-next 5/7] ieee802154: 6lowpan: handle fragmented IPv6 Alexander Aring
@ 2014-12-23 14:28 ` Alexander Aring
2014-12-23 14:28 ` [PATCH bluetooth-next 7/7] ieee802154: 6lowpan: remove tx full-size calc workaround Alexander Aring
2014-12-25 11:30 ` [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
7 siblings, 0 replies; 9+ messages in thread
From: Alexander Aring @ 2014-12-23 14:28 UTC (permalink / raw)
To: linux-wpan; +Cc: kernel, Alexander Aring
This patch is a cleanup because case for LOWPAN_DISPATCH_FRAG1 and
LOWPAN_DISPATCH_FRAGN looks almost the same except the dispatch value
which is stored in a variables before now.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/ieee802154/6lowpan/rx.c | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/net/ieee802154/6lowpan/rx.c b/net/ieee802154/6lowpan/rx.c
index 158756f..fc7228c 100644
--- a/net/ieee802154/6lowpan/rx.c
+++ b/net/ieee802154/6lowpan/rx.c
@@ -109,7 +109,9 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
return lowpan_give_skb_to_devices(skb, NULL);
} else {
- switch (*skb_network_header(skb) & 0xe0) {
+ u8 dispatch = *skb_network_header(skb) & 0xe0;
+
+ switch (dispatch) {
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
goto drop_skb;
@@ -120,18 +122,8 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
return lowpan_give_skb_to_devices(skb, NULL);
case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
- ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
- if (ret == 1) {
- ipv6_hdr(skb)->payload_len = htons(skb->len -
- sizeof(struct ipv6hdr));
- return lowpan_give_skb_to_devices(skb, NULL);
- } else if (ret == -1) {
- return NET_RX_DROP;
- } else {
- return NET_RX_SUCCESS;
- }
case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
- ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
+ ret = lowpan_frag_rcv(skb, dispatch);
if (ret == 1) {
ipv6_hdr(skb)->payload_len = htons(skb->len -
sizeof(struct ipv6hdr));
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH bluetooth-next 7/7] ieee802154: 6lowpan: remove tx full-size calc workaround
2014-12-23 14:28 [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
` (5 preceding siblings ...)
2014-12-23 14:28 ` [PATCH bluetooth-next 6/7] ieee802154: 6lowpan: cleanup frag dispatch cases Alexander Aring
@ 2014-12-23 14:28 ` Alexander Aring
2014-12-25 11:30 ` [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
7 siblings, 0 replies; 9+ messages in thread
From: Alexander Aring @ 2014-12-23 14:28 UTC (permalink / raw)
To: linux-wpan; +Cc: kernel, Alexander Aring, Jukka Rissanen
This patch removes a workaround in transmit fragmentation implementation
which use lowpan_uncompress_size to calculate the full size of
fragmented packet. Instead we calculate the size over skb->len before
and after iphc compression. Additional we remove the whole
lowpan_uncompress_size function which is used by 802154 6LoWPAN only.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Cc: Jukka Rissanen <jukka.rissanen@linux.intel.com>
---
include/net/6lowpan.h | 113 --------------------------------------------
net/ieee802154/6lowpan/tx.c | 18 ++++---
2 files changed, 11 insertions(+), 120 deletions(-)
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index c64d274..fd56994 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -261,119 +261,6 @@ static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data,
*hc_ptr += len;
}
-static inline u8 lowpan_addr_mode_size(const u8 addr_mode)
-{
- static const u8 addr_sizes[] = {
- [LOWPAN_IPHC_ADDR_00] = 16,
- [LOWPAN_IPHC_ADDR_01] = 8,
- [LOWPAN_IPHC_ADDR_02] = 2,
- [LOWPAN_IPHC_ADDR_03] = 0,
- };
- return addr_sizes[addr_mode];
-}
-
-static inline u8 lowpan_next_hdr_size(const u8 h_enc, u16 *uncomp_header)
-{
- u8 ret = 1;
-
- if ((h_enc & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) {
- *uncomp_header += sizeof(struct udphdr);
-
- switch (h_enc & LOWPAN_NHC_UDP_CS_P_11) {
- case LOWPAN_NHC_UDP_CS_P_00:
- ret += 4;
- break;
- case LOWPAN_NHC_UDP_CS_P_01:
- case LOWPAN_NHC_UDP_CS_P_10:
- ret += 3;
- break;
- case LOWPAN_NHC_UDP_CS_P_11:
- ret++;
- break;
- default:
- break;
- }
-
- if (!(h_enc & LOWPAN_NHC_UDP_CS_C))
- ret += 2;
- }
-
- return ret;
-}
-
-/**
- * lowpan_uncompress_size - returns skb->len size with uncompressed header
- * @skb: sk_buff with 6lowpan header inside
- * @datagram_offset: optional to get the datagram_offset value
- *
- * Returns the skb->len with uncompressed header
- */
-static inline u16
-lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
-{
- u16 ret = 2, uncomp_header = sizeof(struct ipv6hdr);
- u8 iphc0, iphc1, h_enc;
-
- iphc0 = skb_network_header(skb)[0];
- iphc1 = skb_network_header(skb)[1];
-
- switch ((iphc0 & LOWPAN_IPHC_TF) >> 3) {
- case 0:
- ret += 4;
- break;
- case 1:
- ret += 3;
- break;
- case 2:
- ret++;
- break;
- default:
- break;
- }
-
- if (!(iphc0 & LOWPAN_IPHC_NH_C))
- ret++;
-
- if (!(iphc0 & 0x03))
- ret++;
-
- ret += lowpan_addr_mode_size((iphc1 & LOWPAN_IPHC_SAM) >>
- LOWPAN_IPHC_SAM_BIT);
-
- if (iphc1 & LOWPAN_IPHC_M) {
- switch ((iphc1 & LOWPAN_IPHC_DAM_11) >>
- LOWPAN_IPHC_DAM_BIT) {
- case LOWPAN_IPHC_DAM_00:
- ret += 16;
- break;
- case LOWPAN_IPHC_DAM_01:
- ret += 6;
- break;
- case LOWPAN_IPHC_DAM_10:
- ret += 4;
- break;
- case LOWPAN_IPHC_DAM_11:
- ret++;
- break;
- default:
- break;
- }
- } else {
- ret += lowpan_addr_mode_size((iphc1 & LOWPAN_IPHC_DAM_11) >>
- LOWPAN_IPHC_DAM_BIT);
- }
-
- if (iphc0 & LOWPAN_IPHC_NH_C) {
- h_enc = skb_network_header(skb)[ret];
- ret += lowpan_next_hdr_size(h_enc, &uncomp_header);
- }
-
- if (dgram_offset)
- *dgram_offset = uncomp_header;
-
- return skb->len + uncomp_header - ret;
-}
-
int
lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
const u8 *saddr, const u8 saddr_type,
diff --git a/net/ieee802154/6lowpan/tx.c b/net/ieee802154/6lowpan/tx.c
index 2349070..102d0ec 100644
--- a/net/ieee802154/6lowpan/tx.c
+++ b/net/ieee802154/6lowpan/tx.c
@@ -124,16 +124,14 @@ lowpan_xmit_fragment(struct sk_buff *skb, const struct ieee802154_hdr *wpan_hdr,
static int
lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev,
- const struct ieee802154_hdr *wpan_hdr)
+ const struct ieee802154_hdr *wpan_hdr, u16 dgram_size,
+ u16 dgram_offset)
{
- u16 dgram_size, dgram_offset;
__be16 frag_tag;
u8 frag_hdr[5];
int frag_cap, frag_len, payload_cap, rc;
int skb_unprocessed, skb_offset;
- dgram_size = lowpan_uncompress_size(skb, &dgram_offset) -
- skb->mac_len;
frag_tag = htons(lowpan_dev_info(dev)->fragment_tag);
lowpan_dev_info(dev)->fragment_tag++;
@@ -188,7 +186,8 @@ err:
return rc;
}
-static int lowpan_header(struct sk_buff *skb, struct net_device *dev)
+static int lowpan_header(struct sk_buff *skb, struct net_device *dev,
+ u16 *dgram_size, u16 *dgram_offset)
{
struct ieee802154_addr sa, da;
struct ieee802154_mac_cb *cb = mac_cb_init(skb);
@@ -201,7 +200,10 @@ static int lowpan_header(struct sk_buff *skb, struct net_device *dev)
daddr = &info.daddr.u.extended_addr;
saddr = &info.saddr.u.extended_addr;
+ *dgram_size = skb->len;
lowpan_header_compress(skb, dev, ETH_P_IPV6, daddr, saddr, skb->len);
+ /* dgram_size = (saved bytes after compression) + lowpan header size */
+ *dgram_offset = (*dgram_size - skb->len) + skb_network_header_len(skb);
cb->type = IEEE802154_FC_TYPE_DATA;
@@ -234,6 +236,7 @@ netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ieee802154_hdr wpan_hdr;
int max_single, ret;
+ u16 dgram_size, dgram_offset;
pr_debug("package xmit\n");
@@ -244,7 +247,7 @@ netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
if (!skb)
return NET_XMIT_DROP;
- ret = lowpan_header(skb, dev);
+ ret = lowpan_header(skb, dev, &dgram_size, &dgram_offset);
if (ret < 0) {
kfree_skb(skb);
return NET_XMIT_DROP;
@@ -264,7 +267,8 @@ netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
netdev_tx_t rc;
pr_debug("frame is too big, fragmentation is needed\n");
- rc = lowpan_xmit_fragmented(skb, dev, &wpan_hdr);
+ rc = lowpan_xmit_fragmented(skb, dev, &wpan_hdr, dgram_size,
+ dgram_offset);
return rc < 0 ? NET_XMIT_DROP : rc;
}
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds
2014-12-23 14:28 [PATCH bluetooth-next 0/7] ieee802154: 6lowpan: remove full-size calculation workarounds Alexander Aring
` (6 preceding siblings ...)
2014-12-23 14:28 ` [PATCH bluetooth-next 7/7] ieee802154: 6lowpan: remove tx full-size calc workaround Alexander Aring
@ 2014-12-25 11:30 ` Alexander Aring
7 siblings, 0 replies; 9+ messages in thread
From: Alexander Aring @ 2014-12-25 11:30 UTC (permalink / raw)
To: linux-wpan; +Cc: kernel, Jukka Rissanen
Marcel,
please drop this series. I reconsider my change and detect that IPHC
uncompression use "uh->len = htons(skb->len + sizeof(struct udphdr))"
for udp next header compression.
This patch introduce now a iphc uncompression after first fragment and
skb->len isn't the full payload there. Need to look how we can deal with
that now. I really like to remove these workarounds to run a 6LoWPAN
header parse twice.
When the first fragment arrived we know the full payload but we can't
set skb->len with this value.
Need to look for another solution for this which can be used by btle
and 802154 6LoWPAN.
- Alex
^ permalink raw reply [flat|nested] 9+ messages in thread