[PATCH bluetooth-next 4/7] ieee802154: 6lowpan: remove rx full-size calc workaround

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-wpan" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux