summaryrefslogtreecommitdiffstats
path: root/kernel/net/mac802154/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/net/mac802154/rx.c')
-rw-r--r--kernel/net/mac802154/rx.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/kernel/net/mac802154/rx.c b/kernel/net/mac802154/rx.c
index c0d67b2b4..42e96729d 100644
--- a/kernel/net/mac802154/rx.c
+++ b/kernel/net/mac802154/rx.c
@@ -47,8 +47,6 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
pr_debug("getting packet via slave interface %s\n", sdata->dev->name);
- spin_lock_bh(&sdata->mib_lock);
-
span = wpan_dev->pan_id;
sshort = wpan_dev->short_addr;
@@ -83,15 +81,16 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
skb->pkt_type = PACKET_OTHERHOST;
break;
default:
- spin_unlock_bh(&sdata->mib_lock);
pr_debug("invalid dest mode\n");
goto fail;
}
- spin_unlock_bh(&sdata->mib_lock);
-
skb->dev = sdata->dev;
+ /* TODO this should be moved after netif_receive_skb call, otherwise
+ * wireshark will show a mac header with security fields and the
+ * payload is already decrypted.
+ */
rc = mac802154_llsec_decrypt(&sdata->sec, skb);
if (rc) {
pr_debug("decryption failed: %i\n", rc);
@@ -207,8 +206,10 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
}
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
- if (sdata->vif.type != NL802154_IFTYPE_NODE ||
- !netif_running(sdata->dev))
+ if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
+ continue;
+
+ if (!ieee802154_sdata_running(sdata))
continue;
ieee802154_subif_frame(sdata, skb, &hdr);
@@ -232,7 +233,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
skb->protocol = htons(ETH_P_IEEE802154);
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
- if (sdata->vif.type != NL802154_IFTYPE_MONITOR)
+ if (sdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
continue;
if (!ieee802154_sdata_running(sdata))
@@ -249,13 +250,15 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
}
}
-void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
+void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb)
{
- struct ieee802154_local *local = hw_to_local(hw);
u16 crc;
WARN_ON_ONCE(softirq_count() == 0);
+ if (local->suspended)
+ goto drop;
+
/* TODO: When a transceiver omits the checksum here, we
* add an own calculated one. This is currently an ugly
* solution because the monitor needs a crc here.
@@ -276,8 +279,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
crc = crc_ccitt(0, skb->data, skb->len);
if (crc) {
rcu_read_unlock();
- kfree_skb(skb);
- return;
+ goto drop;
}
}
/* remove crc */
@@ -286,8 +288,11 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
__ieee802154_rx_handle_packet(local, skb);
rcu_read_unlock();
+
+ return;
+drop:
+ kfree_skb(skb);
}
-EXPORT_SYMBOL(ieee802154_rx);
void
ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi)