diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 434a26f76a80..a68230e2b25f 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -70,7 +70,8 @@ void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb) rcu_read_lock(); list_for_each_entry_rcu(sdata, &priv->slaves, list) { - if (sdata->type != IEEE802154_DEV_MONITOR) + if (sdata->type != IEEE802154_DEV_MONITOR || + !netif_running(sdata->dev)) continue; skb2 = skb_clone(skb, GFP_ATOMIC); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 0597b96dc9ba..7f820a108a9c 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -64,20 +64,23 @@ mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) if (skb->len < 2) { pr_debug("got invalid frame\n"); - goto out; + goto fail; } crc = crc_ccitt(0, skb->data, skb->len); if (crc) { pr_debug("CRC mismatch\n"); - goto out; + goto fail; } skb_trim(skb, skb->len - 2); /* CRC */ } mac802154_monitors_rx(priv, skb); mac802154_wpans_rx(priv, skb); -out: - dev_kfree_skb(skb); + + return; + +fail: + kfree_skb(skb); } static void mac802154_rx_worker(struct work_struct *work) diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c index 23bc91cf99c4..3c3069fd6971 100644 --- a/net/mac802154/wpan.c +++ b/net/mac802154/wpan.c @@ -472,6 +472,7 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, rc = mac802154_llsec_decrypt(&sdata->sec, skb); if (rc) { pr_debug("decryption failed: %i\n", rc); + kfree_skb(skb); return NET_RX_DROP; } @@ -566,7 +567,6 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) { int ret; - struct sk_buff *sskb; struct mac802154_sub_if_data *sdata; struct ieee802154_hdr hdr; @@ -578,12 +578,16 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) rcu_read_lock(); list_for_each_entry_rcu(sdata, &priv->slaves, list) { - if (sdata->type != IEEE802154_DEV_WPAN) + if (sdata->type != IEEE802154_DEV_WPAN || + !netif_running(sdata->dev)) continue; - sskb = skb_clone(skb, GFP_ATOMIC); - if (sskb) - mac802154_subif_frame(sdata, sskb, &hdr); + mac802154_subif_frame(sdata, skb, &hdr); + skb = NULL; + break; } rcu_read_unlock(); + + if (skb) + kfree_skb(skb); }