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