6lowpan: remove skb_deliver from IPHC
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>
This commit is contained in:
parent
f81f466ca5
commit
f8b361768e
|
@ -372,12 +372,10 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
|
||||||
return skb->len + uncomp_header - ret;
|
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,
|
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 *saddr, const u8 saddr_type, const u8 saddr_len,
|
||||||
const u8 *daddr, const u8 daddr_type, const u8 daddr_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,
|
int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
|
||||||
unsigned short type, const void *_daddr,
|
unsigned short type, const void *_daddr,
|
||||||
const void *_saddr, unsigned int len);
|
const void *_saddr, unsigned int len);
|
||||||
|
|
|
@ -171,29 +171,6 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb,
|
||||||
return 0;
|
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,
|
/* Uncompress function for multicast destination address,
|
||||||
* when M bit is set.
|
* when M bit is set.
|
||||||
*/
|
*/
|
||||||
|
@ -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,
|
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 *saddr, const u8 saddr_type, const u8 saddr_len,
|
||||||
const u8 *daddr, const u8 daddr_type, const u8 daddr_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 = {};
|
struct ipv6hdr hdr = {};
|
||||||
u8 tmp, num_context = 0;
|
u8 tmp, num_context = 0;
|
||||||
|
@ -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.version, ntohs(hdr.payload_len), hdr.nexthdr,
|
||||||
hdr.hop_limit, &hdr.daddr);
|
hdr.hop_limit, &hdr.daddr);
|
||||||
|
|
||||||
|
skb_push(skb, sizeof(hdr));
|
||||||
|
skb_reset_network_header(skb);
|
||||||
|
skb_copy_to_linear_data(skb, &hdr, sizeof(hdr));
|
||||||
|
|
||||||
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 0;
|
||||||
|
|
||||||
drop:
|
drop:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -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);
|
skb_cp = skb_copy(skb, GFP_ATOMIC);
|
||||||
if (!skb_cp)
|
if (!skb_cp)
|
||||||
return -ENOMEM;
|
return NET_RX_DROP;
|
||||||
|
|
||||||
return netif_rx(skb_cp);
|
return netif_rx(skb_cp);
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
|
||||||
return lowpan_process_data(skb, netdev,
|
return lowpan_process_data(skb, netdev,
|
||||||
saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
|
saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
|
||||||
daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
|
daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
|
||||||
iphc0, iphc1, give_skb_to_upper);
|
iphc0, iphc1);
|
||||||
|
|
||||||
drop:
|
drop:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
|
||||||
if (ret != NET_RX_SUCCESS)
|
if (ret != NET_RX_SUCCESS)
|
||||||
goto drop;
|
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_bytes += skb->len;
|
||||||
dev->stats.rx_packets++;
|
dev->stats.rx_packets++;
|
||||||
|
|
||||||
|
|
|
@ -141,20 +141,28 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
|
||||||
struct sk_buff *skb_cp;
|
struct sk_buff *skb_cp;
|
||||||
int stat = NET_RX_SUCCESS;
|
int stat = NET_RX_SUCCESS;
|
||||||
|
|
||||||
|
skb->protocol = htons(ETH_P_IPV6);
|
||||||
|
skb->pkt_type = PACKET_HOST;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
list_for_each_entry_rcu(entry, &lowpan_devices, list)
|
list_for_each_entry_rcu(entry, &lowpan_devices, list)
|
||||||
if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
|
if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
|
||||||
skb_cp = skb_copy(skb, GFP_ATOMIC);
|
skb_cp = skb_copy(skb, GFP_ATOMIC);
|
||||||
if (!skb_cp) {
|
if (!skb_cp) {
|
||||||
stat = -ENOMEM;
|
kfree_skb(skb);
|
||||||
break;
|
rcu_read_unlock();
|
||||||
|
return NET_RX_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_cp->dev = entry->ldev;
|
skb_cp->dev = entry->ldev;
|
||||||
stat = netif_rx(skb_cp);
|
stat = netif_rx(skb_cp);
|
||||||
|
if (stat == NET_RX_DROP)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
consume_skb(skb);
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
return lowpan_process_data(skb, skb->dev, sap, sa.addr_type,
|
||||||
IEEE802154_ADDR_LEN, dap, da.addr_type,
|
IEEE802154_ADDR_LEN, dap, da.addr_type,
|
||||||
IEEE802154_ADDR_LEN, iphc0, iphc1,
|
IEEE802154_ADDR_LEN, iphc0, iphc1);
|
||||||
lowpan_give_skb_to_devices);
|
|
||||||
|
|
||||||
drop:
|
drop:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
@ -528,44 +535,48 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||||
|
|
||||||
/* check that it's our buffer */
|
/* check that it's our buffer */
|
||||||
if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
|
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. */
|
/* Pull off the 1-byte of 6lowpan header. */
|
||||||
skb_pull(skb, 1);
|
skb_pull(skb, 1);
|
||||||
|
return lowpan_give_skb_to_devices(skb, NULL);
|
||||||
ret = lowpan_give_skb_to_devices(skb, NULL);
|
|
||||||
if (ret == NET_RX_DROP)
|
|
||||||
goto drop;
|
|
||||||
} else {
|
} else {
|
||||||
switch (skb->data[0] & 0xe0) {
|
switch (skb->data[0] & 0xe0) {
|
||||||
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
|
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
|
||||||
ret = process_data(skb, &hdr);
|
ret = process_data(skb, &hdr);
|
||||||
if (ret == NET_RX_DROP)
|
if (ret == NET_RX_DROP)
|
||||||
goto drop;
|
goto drop;
|
||||||
break;
|
|
||||||
|
return lowpan_give_skb_to_devices(skb, NULL);
|
||||||
case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
|
case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
|
||||||
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
|
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
ret = process_data(skb, &hdr);
|
ret = process_data(skb, &hdr);
|
||||||
if (ret == NET_RX_DROP)
|
if (ret == NET_RX_DROP)
|
||||||
goto 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 */
|
case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
|
||||||
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
|
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
ret = process_data(skb, &hdr);
|
ret = process_data(skb, &hdr);
|
||||||
if (ret == NET_RX_DROP)
|
if (ret == NET_RX_DROP)
|
||||||
goto 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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NET_RX_SUCCESS;
|
|
||||||
drop_skb:
|
drop_skb:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
drop:
|
drop:
|
||||||
|
|
Loading…
Reference in a new issue