|
@@ -319,7 +319,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
if (iphc1 & LOWPAN_IPHC_CID) {
|
|
|
pr_debug("CID flag is set, increase header with one\n");
|
|
|
if (lowpan_fetch_skb(skb, &num_context, sizeof(num_context)))
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
hdr.version = 6;
|
|
@@ -331,7 +331,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
*/
|
|
|
case 0: /* 00b */
|
|
|
if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp)))
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
memcpy(&hdr.flow_lbl, &skb->data[0], 3);
|
|
|
skb_pull(skb, 3);
|
|
@@ -344,7 +344,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
*/
|
|
|
case 2: /* 10b */
|
|
|
if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp)))
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
hdr.priority = ((tmp >> 2) & 0x0f);
|
|
|
hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30);
|
|
@@ -354,7 +354,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
*/
|
|
|
case 1: /* 01b */
|
|
|
if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp)))
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30);
|
|
|
memcpy(&hdr.flow_lbl[1], &skb->data[0], 2);
|
|
@@ -371,7 +371,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) {
|
|
|
/* Next header is carried inline */
|
|
|
if (lowpan_fetch_skb(skb, &hdr.nexthdr, sizeof(hdr.nexthdr)))
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
pr_debug("NH flag is set, next header carried inline: %02x\n",
|
|
|
hdr.nexthdr);
|
|
@@ -383,7 +383,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
} else {
|
|
|
if (lowpan_fetch_skb(skb, &hdr.hop_limit,
|
|
|
sizeof(hdr.hop_limit)))
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
/* Extract SAM to the tmp variable */
|
|
@@ -402,7 +402,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
|
|
|
/* Check on error of previous branch */
|
|
|
if (err)
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
/* Extract DAM to the tmp variable */
|
|
|
tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03;
|
|
@@ -417,7 +417,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
tmp);
|
|
|
|
|
|
if (err)
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
} else {
|
|
|
err = uncompress_addr(skb, &hdr.daddr, tmp, daddr,
|
|
@@ -425,7 +425,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
pr_debug("dest: stateless compression mode %d dest %pI6c\n",
|
|
|
tmp, &hdr.daddr);
|
|
|
if (err)
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
/* UDP data uncompression */
|
|
@@ -434,16 +434,14 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
const int needed = sizeof(struct udphdr) + sizeof(hdr);
|
|
|
|
|
|
if (uncompress_udp_header(skb, &uh))
|
|
|
- goto drop;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
/* replace the compressed UDP head by the uncompressed UDP
|
|
|
* header
|
|
|
*/
|
|
|
err = skb_cow(skb, needed);
|
|
|
- if (unlikely(err)) {
|
|
|
- kfree_skb(skb);
|
|
|
+ if (unlikely(err))
|
|
|
return err;
|
|
|
- }
|
|
|
|
|
|
skb_push(skb, sizeof(struct udphdr));
|
|
|
skb_reset_transport_header(skb);
|
|
@@ -455,10 +453,8 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
hdr.nexthdr = UIP_PROTO_UDP;
|
|
|
} else {
|
|
|
err = skb_cow(skb, sizeof(hdr));
|
|
|
- if (unlikely(err)) {
|
|
|
- kfree_skb(skb);
|
|
|
+ if (unlikely(err))
|
|
|
return err;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
hdr.payload_len = htons(skb->len);
|
|
@@ -478,9 +474,6 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
|
|
|
raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
|
|
|
|
|
|
return 0;
|
|
|
-drop:
|
|
|
- kfree_skb(skb);
|
|
|
- return -EINVAL;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(lowpan_header_decompress);
|
|
|
|