aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>2014-06-11 06:03:07 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-11 15:10:19 -0400
commit2d3b5b0a90e5370ad13ca98d95519c3e41d2c925 (patch)
treebad4e444da804759fe1d8f91d4a940cdcb4ca1fb
parenta374eeb5e5b35c877a890dce5d3f7cca5a3e33f6 (diff)
mac802154: don't deliver packets to devices that are down
Only one WPAN devices can be active at any given time, so only deliver packets to that one interface that is actually up. Multiple monitors may be up at any given time, but we don't have to deliver to monitors that are down either. Signed-off-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/mac802154/monitor.c3
-rw-r--r--net/mac802154/rx.c11
-rw-r--r--net/mac802154/wpan.c13
3 files changed, 17 insertions, 10 deletions
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)
70 70
71 rcu_read_lock(); 71 rcu_read_lock();
72 list_for_each_entry_rcu(sdata, &priv->slaves, list) { 72 list_for_each_entry_rcu(sdata, &priv->slaves, list) {
73 if (sdata->type != IEEE802154_DEV_MONITOR) 73 if (sdata->type != IEEE802154_DEV_MONITOR ||
74 !netif_running(sdata->dev))
74 continue; 75 continue;
75 76
76 skb2 = skb_clone(skb, GFP_ATOMIC); 77 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)
64 64
65 if (skb->len < 2) { 65 if (skb->len < 2) {
66 pr_debug("got invalid frame\n"); 66 pr_debug("got invalid frame\n");
67 goto out; 67 goto fail;
68 } 68 }
69 crc = crc_ccitt(0, skb->data, skb->len); 69 crc = crc_ccitt(0, skb->data, skb->len);
70 if (crc) { 70 if (crc) {
71 pr_debug("CRC mismatch\n"); 71 pr_debug("CRC mismatch\n");
72 goto out; 72 goto fail;
73 } 73 }
74 skb_trim(skb, skb->len - 2); /* CRC */ 74 skb_trim(skb, skb->len - 2); /* CRC */
75 } 75 }
76 76
77 mac802154_monitors_rx(priv, skb); 77 mac802154_monitors_rx(priv, skb);
78 mac802154_wpans_rx(priv, skb); 78 mac802154_wpans_rx(priv, skb);
79out: 79
80 dev_kfree_skb(skb); 80 return;
81
82fail:
83 kfree_skb(skb);
81} 84}
82 85
83static void mac802154_rx_worker(struct work_struct *work) 86static void mac802154_rx_worker(struct work_struct *work)
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
index c8cfd54f3711..3c3069fd6971 100644
--- a/net/mac802154/wpan.c
+++ b/net/mac802154/wpan.c
@@ -567,7 +567,6 @@ static int mac802154_parse_frame_start(struct sk_buff *skb,
567void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) 567void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
568{ 568{
569 int ret; 569 int ret;
570 struct sk_buff *sskb;
571 struct mac802154_sub_if_data *sdata; 570 struct mac802154_sub_if_data *sdata;
572 struct ieee802154_hdr hdr; 571 struct ieee802154_hdr hdr;
573 572
@@ -579,12 +578,16 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
579 578
580 rcu_read_lock(); 579 rcu_read_lock();
581 list_for_each_entry_rcu(sdata, &priv->slaves, list) { 580 list_for_each_entry_rcu(sdata, &priv->slaves, list) {
582 if (sdata->type != IEEE802154_DEV_WPAN) 581 if (sdata->type != IEEE802154_DEV_WPAN ||
582 !netif_running(sdata->dev))
583 continue; 583 continue;
584 584
585 sskb = skb_clone(skb, GFP_ATOMIC); 585 mac802154_subif_frame(sdata, skb, &hdr);
586 if (sskb) 586 skb = NULL;
587 mac802154_subif_frame(sdata, sskb, &hdr); 587 break;
588 } 588 }
589 rcu_read_unlock(); 589 rcu_read_unlock();
590
591 if (skb)
592 kfree_skb(skb);
590} 593}