Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24363b67 authored by Tony Cheneau's avatar Tony Cheneau Committed by David S. Miller
Browse files

6lowpan: modify udp compression/uncompression to match the standard



The previous code would just compress the UDP header and send the compressed
UDP header along with the uncompressed one.

Signed-off-by: default avatarTony Cheneau <tony.cheneau@amnesiak.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 43de7aa6
Loading
Loading
Loading
Loading
+36 −3
Original line number Diff line number Diff line
@@ -284,6 +284,9 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb)
	/* checksum is always inline */
	memcpy(*hc06_ptr, &uh->check, 2);
	*hc06_ptr += 2;

	/* skip the UDP header */
	skb_pull(skb, sizeof(struct udphdr));
}

static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val)
@@ -309,9 +312,8 @@ static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val)
}

static int
lowpan_uncompress_udp_header(struct sk_buff *skb)
lowpan_uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh)
{
	struct udphdr *uh = udp_hdr(skb);
	u8 tmp;

	if (!uh)
@@ -358,6 +360,14 @@ lowpan_uncompress_udp_header(struct sk_buff *skb)
		/* copy checksum */
		memcpy(&uh->check, &skb->data[0], 2);
		skb_pull(skb, 2);

		/*
		 * 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", uh->len);
	} else {
		pr_debug("ERROR: unsupported NH format\n");
		goto err;
@@ -944,8 +954,31 @@ lowpan_process_data(struct sk_buff *skb)

	/* UDP data uncompression */
	if (iphc0 & LOWPAN_IPHC_NH_C) {
		if (lowpan_uncompress_udp_header(skb))
		struct udphdr uh;
		struct sk_buff *new;
		if (lowpan_uncompress_udp_header(skb, &uh))
			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));

		lowpan_raw_dump_table(__func__, "raw UDP header dump",
				      (u8 *)&uh, sizeof(uh));

		hdr.nexthdr = UIP_PROTO_UDP;
	}