|
@@ -63,9 +63,9 @@
|
|
* address_mode is sam value or dam value.
|
|
* address_mode is sam value or dam value.
|
|
*/
|
|
*/
|
|
static int uncompress_addr(struct sk_buff *skb,
|
|
static int uncompress_addr(struct sk_buff *skb,
|
|
- struct in6_addr *ipaddr, const u8 address_mode,
|
|
|
|
- const u8 *lladdr, const u8 addr_type,
|
|
|
|
- const u8 addr_len)
|
|
|
|
|
|
+ struct in6_addr *ipaddr, const u8 address_mode,
|
|
|
|
+ const u8 *lladdr, const u8 addr_type,
|
|
|
|
+ const u8 addr_len)
|
|
{
|
|
{
|
|
bool fail;
|
|
bool fail;
|
|
|
|
|
|
@@ -142,8 +142,8 @@ static int uncompress_addr(struct sk_buff *skb,
|
|
* based address(non-multicast).
|
|
* based address(non-multicast).
|
|
*/
|
|
*/
|
|
static int uncompress_context_based_src_addr(struct sk_buff *skb,
|
|
static int uncompress_context_based_src_addr(struct sk_buff *skb,
|
|
- struct in6_addr *ipaddr,
|
|
|
|
- const u8 sam)
|
|
|
|
|
|
+ struct in6_addr *ipaddr,
|
|
|
|
+ const u8 sam)
|
|
{
|
|
{
|
|
switch (sam) {
|
|
switch (sam) {
|
|
case LOWPAN_IPHC_ADDR_00:
|
|
case LOWPAN_IPHC_ADDR_00:
|
|
@@ -172,13 +172,13 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb,
|
|
}
|
|
}
|
|
|
|
|
|
static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
|
|
static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
|
|
- struct net_device *dev, skb_delivery_cb deliver_skb)
|
|
|
|
|
|
+ struct net_device *dev, skb_delivery_cb deliver_skb)
|
|
{
|
|
{
|
|
struct sk_buff *new;
|
|
struct sk_buff *new;
|
|
int stat;
|
|
int stat;
|
|
|
|
|
|
new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
|
|
new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
|
|
- GFP_ATOMIC);
|
|
|
|
|
|
+ GFP_ATOMIC);
|
|
kfree_skb(skb);
|
|
kfree_skb(skb);
|
|
|
|
|
|
if (!new)
|
|
if (!new)
|
|
@@ -193,7 +193,7 @@ static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
|
|
new->dev = dev;
|
|
new->dev = dev;
|
|
|
|
|
|
raw_dump_table(__func__, "raw skb data dump before receiving",
|
|
raw_dump_table(__func__, "raw skb data dump before receiving",
|
|
- new->data, new->len);
|
|
|
|
|
|
+ new->data, new->len);
|
|
|
|
|
|
stat = deliver_skb(new, dev);
|
|
stat = deliver_skb(new, dev);
|
|
|
|
|
|
@@ -205,10 +205,9 @@ static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
|
|
/* Uncompress function for multicast destination address,
|
|
/* Uncompress function for multicast destination address,
|
|
* when M bit is set.
|
|
* when M bit is set.
|
|
*/
|
|
*/
|
|
-static int
|
|
|
|
-lowpan_uncompress_multicast_daddr(struct sk_buff *skb,
|
|
|
|
- struct in6_addr *ipaddr,
|
|
|
|
- const u8 dam)
|
|
|
|
|
|
+static int lowpan_uncompress_multicast_daddr(struct sk_buff *skb,
|
|
|
|
+ struct in6_addr *ipaddr,
|
|
|
|
+ const u8 dam)
|
|
{
|
|
{
|
|
bool fail;
|
|
bool fail;
|
|
|
|
|
|
@@ -254,13 +253,12 @@ lowpan_uncompress_multicast_daddr(struct sk_buff *skb,
|
|
}
|
|
}
|
|
|
|
|
|
raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is",
|
|
raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is",
|
|
- ipaddr->s6_addr, 16);
|
|
|
|
|
|
+ ipaddr->s6_addr, 16);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int
|
|
|
|
-uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh)
|
|
|
|
|
|
+static int uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh)
|
|
{
|
|
{
|
|
bool fail;
|
|
bool fail;
|
|
u8 tmp = 0, val = 0;
|
|
u8 tmp = 0, val = 0;
|
|
@@ -336,16 +334,16 @@ err:
|
|
static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
|
|
static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
|
|
|
|
|
|
int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
|
|
int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
|
|
- const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
|
|
|
|
- const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
|
|
|
|
- u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb)
|
|
|
|
|
|
+ const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
|
|
|
|
+ const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
|
|
|
|
+ u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb)
|
|
{
|
|
{
|
|
struct ipv6hdr hdr = {};
|
|
struct ipv6hdr hdr = {};
|
|
u8 tmp, num_context = 0;
|
|
u8 tmp, num_context = 0;
|
|
int err;
|
|
int err;
|
|
|
|
|
|
raw_dump_table(__func__, "raw skb data dump uncompressed",
|
|
raw_dump_table(__func__, "raw skb data dump uncompressed",
|
|
- skb->data, skb->len);
|
|
|
|
|
|
+ skb->data, skb->len);
|
|
|
|
|
|
/* another if the CID flag is set */
|
|
/* another if the CID flag is set */
|
|
if (iphc1 & LOWPAN_IPHC_CID) {
|
|
if (iphc1 & LOWPAN_IPHC_CID) {
|
|
@@ -424,13 +422,12 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
|
|
if (iphc1 & LOWPAN_IPHC_SAC) {
|
|
if (iphc1 & LOWPAN_IPHC_SAC) {
|
|
/* Source address context based uncompression */
|
|
/* Source address context based uncompression */
|
|
pr_debug("SAC bit is set. Handle context based source address.\n");
|
|
pr_debug("SAC bit is set. Handle context based source address.\n");
|
|
- err = uncompress_context_based_src_addr(
|
|
|
|
- skb, &hdr.saddr, tmp);
|
|
|
|
|
|
+ err = uncompress_context_based_src_addr(skb, &hdr.saddr, tmp);
|
|
} else {
|
|
} else {
|
|
/* Source address uncompression */
|
|
/* Source address uncompression */
|
|
pr_debug("source address stateless compression\n");
|
|
pr_debug("source address stateless compression\n");
|
|
err = uncompress_addr(skb, &hdr.saddr, tmp, saddr,
|
|
err = uncompress_addr(skb, &hdr.saddr, tmp, saddr,
|
|
- saddr_type, saddr_len);
|
|
|
|
|
|
+ saddr_type, saddr_len);
|
|
}
|
|
}
|
|
|
|
|
|
/* Check on error of previous branch */
|
|
/* Check on error of previous branch */
|
|
@@ -446,16 +443,17 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
|
|
pr_debug("dest: context-based mcast compression\n");
|
|
pr_debug("dest: context-based mcast compression\n");
|
|
/* TODO: implement this */
|
|
/* TODO: implement this */
|
|
} else {
|
|
} else {
|
|
- err = lowpan_uncompress_multicast_daddr(
|
|
|
|
- skb, &hdr.daddr, tmp);
|
|
|
|
|
|
+ err = lowpan_uncompress_multicast_daddr(skb, &hdr.daddr,
|
|
|
|
+ tmp);
|
|
|
|
+
|
|
if (err)
|
|
if (err)
|
|
goto drop;
|
|
goto drop;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
err = uncompress_addr(skb, &hdr.daddr, tmp, daddr,
|
|
err = uncompress_addr(skb, &hdr.daddr, tmp, daddr,
|
|
- daddr_type, daddr_len);
|
|
|
|
|
|
+ daddr_type, daddr_len);
|
|
pr_debug("dest: stateless compression mode %d dest %pI6c\n",
|
|
pr_debug("dest: stateless compression mode %d dest %pI6c\n",
|
|
- tmp, &hdr.daddr);
|
|
|
|
|
|
+ tmp, &hdr.daddr);
|
|
if (err)
|
|
if (err)
|
|
goto drop;
|
|
goto drop;
|
|
}
|
|
}
|
|
@@ -484,7 +482,7 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
|
|
skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr));
|
|
skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr));
|
|
|
|
|
|
raw_dump_table(__func__, "raw UDP header dump",
|
|
raw_dump_table(__func__, "raw UDP header dump",
|
|
- (u8 *)&uh, sizeof(uh));
|
|
|
|
|
|
+ (u8 *)&uh, sizeof(uh));
|
|
|
|
|
|
hdr.nexthdr = UIP_PROTO_UDP;
|
|
hdr.nexthdr = UIP_PROTO_UDP;
|
|
}
|
|
}
|
|
@@ -499,8 +497,7 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
|
|
hdr.version, ntohs(hdr.payload_len), hdr.nexthdr,
|
|
hdr.version, ntohs(hdr.payload_len), hdr.nexthdr,
|
|
hdr.hop_limit, &hdr.daddr);
|
|
hdr.hop_limit, &hdr.daddr);
|
|
|
|
|
|
- raw_dump_table(__func__, "raw header dump", (u8 *)&hdr,
|
|
|
|
- sizeof(hdr));
|
|
|
|
|
|
+ raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
|
|
|
|
|
|
return skb_deliver(skb, &hdr, dev, deliver_skb);
|
|
return skb_deliver(skb, &hdr, dev, deliver_skb);
|
|
|
|
|
|
@@ -594,8 +591,8 @@ static void compress_udp_header(u8 **hc_ptr, struct sk_buff *skb)
|
|
}
|
|
}
|
|
|
|
|
|
int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
|
|
int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
|
|
- unsigned short type, const void *_daddr,
|
|
|
|
- const void *_saddr, unsigned int len)
|
|
|
|
|
|
+ unsigned short type, const void *_daddr,
|
|
|
|
+ const void *_saddr, unsigned int len)
|
|
{
|
|
{
|
|
u8 tmp, iphc0, iphc1, *hc_ptr;
|
|
u8 tmp, iphc0, iphc1, *hc_ptr;
|
|
struct ipv6hdr *hdr;
|
|
struct ipv6hdr *hdr;
|
|
@@ -610,11 +607,11 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
|
|
|
|
|
|
pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n"
|
|
pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n"
|
|
"\tnexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n",
|
|
"\tnexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n",
|
|
- hdr->version, ntohs(hdr->payload_len), hdr->nexthdr,
|
|
|
|
- hdr->hop_limit, &hdr->daddr);
|
|
|
|
|
|
+ hdr->version, ntohs(hdr->payload_len), hdr->nexthdr,
|
|
|
|
+ hdr->hop_limit, &hdr->daddr);
|
|
|
|
|
|
raw_dump_table(__func__, "raw skb network header dump",
|
|
raw_dump_table(__func__, "raw skb network header dump",
|
|
- skb_network_header(skb), sizeof(struct ipv6hdr));
|
|
|
|
|
|
+ skb_network_header(skb), sizeof(struct ipv6hdr));
|
|
|
|
|
|
/* As we copy some bit-length fields, in the IPHC encoding bytes,
|
|
/* As we copy some bit-length fields, in the IPHC encoding bytes,
|
|
* we sometimes use |=
|
|
* we sometimes use |=
|
|
@@ -631,9 +628,8 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
|
|
raw_dump_inline(__func__, "daddr",
|
|
raw_dump_inline(__func__, "daddr",
|
|
(unsigned char *)_daddr, IEEE802154_ADDR_LEN);
|
|
(unsigned char *)_daddr, IEEE802154_ADDR_LEN);
|
|
|
|
|
|
- raw_dump_table(__func__,
|
|
|
|
- "sending raw skb network uncompressed packet",
|
|
|
|
- skb->data, skb->len);
|
|
|
|
|
|
+ raw_dump_table(__func__, "sending raw skb network uncompressed packet",
|
|
|
|
+ skb->data, skb->len);
|
|
|
|
|
|
/* Traffic class, flow label
|
|
/* Traffic class, flow label
|
|
* If flow label is 0, compress it. If traffic class is 0, compress it
|
|
* If flow label is 0, compress it. If traffic class is 0, compress it
|
|
@@ -763,7 +759,7 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
|
|
iphc1 |= lowpan_compress_addr_64(&hc_ptr,
|
|
iphc1 |= lowpan_compress_addr_64(&hc_ptr,
|
|
LOWPAN_IPHC_DAM_BIT, &hdr->daddr, _daddr);
|
|
LOWPAN_IPHC_DAM_BIT, &hdr->daddr, _daddr);
|
|
pr_debug("dest address unicast link-local %pI6c "
|
|
pr_debug("dest address unicast link-local %pI6c "
|
|
- "iphc1 0x%02x\n", &hdr->daddr, iphc1);
|
|
|
|
|
|
+ "iphc1 0x%02x\n", &hdr->daddr, iphc1);
|
|
} else {
|
|
} else {
|
|
pr_debug("dest address unicast %pI6c\n", &hdr->daddr);
|
|
pr_debug("dest address unicast %pI6c\n", &hdr->daddr);
|
|
lowpan_push_hc_data(&hc_ptr, hdr->daddr.s6_addr, 16);
|
|
lowpan_push_hc_data(&hc_ptr, hdr->daddr.s6_addr, 16);
|
|
@@ -785,7 +781,7 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
|
|
pr_debug("header len %d skb %u\n", (int)(hc_ptr - head), skb->len);
|
|
pr_debug("header len %d skb %u\n", (int)(hc_ptr - head), skb->len);
|
|
|
|
|
|
raw_dump_table(__func__, "raw skb data dump compressed",
|
|
raw_dump_table(__func__, "raw skb data dump compressed",
|
|
- skb->data, skb->len);
|
|
|
|
|
|
+ skb->data, skb->len);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(lowpan_header_compress);
|
|
EXPORT_SYMBOL_GPL(lowpan_header_compress);
|