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: Tony Cheneau <tony.cheneau@amnesiak.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
43de7aa6ac
commit
24363b6732
1 changed files with 36 additions and 3 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue