Skip to content

Commit

Permalink
6lowpan: remove skb_deliver from IPHC
Browse files Browse the repository at this point in the history
Separating skb delivery from decompression ensures that we can support further
decompression schemes and removes the mixed return value of error codes with
NET_RX_FOO.

Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
Acked-by: Alexander Aring <alex.aring@gmail.com>
Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Martin Townsend authored and Marcel Holtmann committed Oct 27, 2014
1 parent f81f466 commit f8b3617
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 46 deletions.
4 changes: 1 addition & 3 deletions include/net/6lowpan.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,10 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
return skb->len + uncomp_header - ret;
}

typedef int (*skb_delivery_cb)(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 skb_deliver);
u8 iphc0, u8 iphc1);
int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *_daddr,
const void *_saddr, unsigned int len);
Expand Down
32 changes: 6 additions & 26 deletions net/6lowpan/iphc.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,29 +171,6 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb,
return 0;
}

static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
struct net_device *dev, skb_delivery_cb deliver_skb)
{
int stat;

skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
skb_copy_to_linear_data(skb, hdr, sizeof(struct ipv6hdr));

skb->protocol = htons(ETH_P_IPV6);
skb->pkt_type = PACKET_HOST;
skb->dev = dev;

raw_dump_table(__func__, "raw skb data dump before receiving",
skb->data, skb->len);

stat = deliver_skb(skb, dev);

consume_skb(skb);

return stat;
}

/* Uncompress function for multicast destination address,
* when M bit is set.
*/
Expand Down Expand Up @@ -327,7 +304,7 @@ static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
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)
u8 iphc0, u8 iphc1)
{
struct ipv6hdr hdr = {};
u8 tmp, num_context = 0;
Expand Down Expand Up @@ -492,10 +469,13 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
hdr.version, ntohs(hdr.payload_len), hdr.nexthdr,
hdr.hop_limit, &hdr.daddr);

raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
skb_push(skb, sizeof(hdr));
skb_reset_network_header(skb);
skb_copy_to_linear_data(skb, &hdr, sizeof(hdr));

return skb_deliver(skb, &hdr, dev, deliver_skb);
raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));

return 0;
drop:
kfree_skb(skb);
return -EINVAL;
Expand Down
14 changes: 12 additions & 2 deletions net/bluetooth/6lowpan.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)

skb_cp = skb_copy(skb, GFP_ATOMIC);
if (!skb_cp)
return -ENOMEM;
return NET_RX_DROP;

return netif_rx(skb_cp);
}
Expand Down Expand Up @@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
return lowpan_process_data(skb, netdev,
saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
iphc0, iphc1, give_skb_to_upper);
iphc0, iphc1);

drop:
kfree_skb(skb);
Expand Down Expand Up @@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
if (ret != NET_RX_SUCCESS)
goto drop;

local_skb->protocol = htons(ETH_P_IPV6);
local_skb->pkt_type = PACKET_HOST;
local_skb->dev = dev;

if (give_skb_to_upper(local_skb, dev)
!= NET_RX_SUCCESS) {
kfree_skb(local_skb);
goto drop;
}

dev->stats.rx_bytes += skb->len;
dev->stats.rx_packets++;

Expand Down
41 changes: 26 additions & 15 deletions net/ieee802154/6lowpan_rtnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,28 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
struct sk_buff *skb_cp;
int stat = NET_RX_SUCCESS;

skb->protocol = htons(ETH_P_IPV6);
skb->pkt_type = PACKET_HOST;

rcu_read_lock();
list_for_each_entry_rcu(entry, &lowpan_devices, list)
if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
skb_cp = skb_copy(skb, GFP_ATOMIC);
if (!skb_cp) {
stat = -ENOMEM;
break;
kfree_skb(skb);
rcu_read_unlock();
return NET_RX_DROP;
}

skb_cp->dev = entry->ldev;
stat = netif_rx(skb_cp);
if (stat == NET_RX_DROP)
break;
}
rcu_read_unlock();

consume_skb(skb);

return stat;
}

Expand Down Expand Up @@ -190,8 +198,7 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr)

return lowpan_process_data(skb, skb->dev, sap, sa.addr_type,
IEEE802154_ADDR_LEN, dap, da.addr_type,
IEEE802154_ADDR_LEN, iphc0, iphc1,
lowpan_give_skb_to_devices);
IEEE802154_ADDR_LEN, iphc0, iphc1);

drop:
kfree_skb(skb);
Expand Down Expand Up @@ -528,44 +535,48 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,

/* check that it's our buffer */
if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
skb->protocol = htons(ETH_P_IPV6);
skb->pkt_type = PACKET_HOST;

/* Pull off the 1-byte of 6lowpan header. */
skb_pull(skb, 1);

ret = lowpan_give_skb_to_devices(skb, NULL);
if (ret == NET_RX_DROP)
goto drop;
return lowpan_give_skb_to_devices(skb, NULL);
} else {
switch (skb->data[0] & 0xe0) {
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
ret = process_data(skb, &hdr);
if (ret == NET_RX_DROP)
goto drop;
break;

return lowpan_give_skb_to_devices(skb, NULL);
case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
if (ret == 1) {
ret = process_data(skb, &hdr);
if (ret == NET_RX_DROP)
goto drop;

return lowpan_give_skb_to_devices(skb, NULL);
} else if (ret == -1) {
return NET_RX_DROP;
} else {
return NET_RX_SUCCESS;
}
break;
case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
if (ret == 1) {
ret = process_data(skb, &hdr);
if (ret == NET_RX_DROP)
goto drop;

return lowpan_give_skb_to_devices(skb, NULL);
} else if (ret == -1) {
return NET_RX_DROP;
} else {
return NET_RX_SUCCESS;
}
break;
default:
break;
}
}

return NET_RX_SUCCESS;
drop_skb:
kfree_skb(skb);
drop:
Expand Down

0 comments on commit f8b3617

Please sign in to comment.