aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac802154
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2014-10-27 12:13:32 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-10-27 13:07:42 -0400
commit2a9820c9e20a7889bf464e1edff5f75d685a8214 (patch)
treeda13a692aa54e96256161b43c75f605832261e98 /net/mac802154
parentc730c90316aa5753c6b2d3d5af40085c220e3a91 (diff)
mac802154: rx: move receive handling into rx.c
This patch removes all relevant receiving functions inclusive frame parsing into rx file. Like mac80211 we should implement the complete receive handling and parsing in this file. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/mac802154')
-rw-r--r--net/mac802154/ieee802154_i.h1
-rw-r--r--net/mac802154/iface.c186
-rw-r--r--net/mac802154/monitor.c27
-rw-r--r--net/mac802154/rx.c214
4 files changed, 214 insertions, 214 deletions
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 603509a94a86..be2f2f6774ae 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -131,7 +131,6 @@ void mac802154_monitor_setup(struct net_device *dev);
131netdev_tx_t 131netdev_tx_t
132ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); 132ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
133 133
134void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb);
135void mac802154_wpan_setup(struct net_device *dev); 134void mac802154_wpan_setup(struct net_device *dev);
136netdev_tx_t 135netdev_tx_t
137ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); 136ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 311f60c8629b..7e4bffcbcd4d 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -373,189 +373,3 @@ void mac802154_wpan_setup(struct net_device *dev)
373 373
374 mac802154_llsec_init(&sdata->sec); 374 mac802154_llsec_init(&sdata->sec);
375} 375}
376
377static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
378{
379 return netif_receive_skb(skb);
380}
381
382static int
383mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb,
384 const struct ieee802154_hdr *hdr)
385{
386 __le16 span, sshort;
387 int rc;
388
389 pr_debug("getting packet via slave interface %s\n", sdata->dev->name);
390
391 spin_lock_bh(&sdata->mib_lock);
392
393 span = sdata->pan_id;
394 sshort = sdata->short_addr;
395
396 switch (mac_cb(skb)->dest.mode) {
397 case IEEE802154_ADDR_NONE:
398 if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE)
399 /* FIXME: check if we are PAN coordinator */
400 skb->pkt_type = PACKET_OTHERHOST;
401 else
402 /* ACK comes with both addresses empty */
403 skb->pkt_type = PACKET_HOST;
404 break;
405 case IEEE802154_ADDR_LONG:
406 if (mac_cb(skb)->dest.pan_id != span &&
407 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
408 skb->pkt_type = PACKET_OTHERHOST;
409 else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr)
410 skb->pkt_type = PACKET_HOST;
411 else
412 skb->pkt_type = PACKET_OTHERHOST;
413 break;
414 case IEEE802154_ADDR_SHORT:
415 if (mac_cb(skb)->dest.pan_id != span &&
416 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
417 skb->pkt_type = PACKET_OTHERHOST;
418 else if (mac_cb(skb)->dest.short_addr == sshort)
419 skb->pkt_type = PACKET_HOST;
420 else if (mac_cb(skb)->dest.short_addr ==
421 cpu_to_le16(IEEE802154_ADDR_BROADCAST))
422 skb->pkt_type = PACKET_BROADCAST;
423 else
424 skb->pkt_type = PACKET_OTHERHOST;
425 break;
426 default:
427 spin_unlock_bh(&sdata->mib_lock);
428 pr_debug("invalid dest mode\n");
429 kfree_skb(skb);
430 return NET_RX_DROP;
431 }
432
433 spin_unlock_bh(&sdata->mib_lock);
434
435 skb->dev = sdata->dev;
436
437 rc = mac802154_llsec_decrypt(&sdata->sec, skb);
438 if (rc) {
439 pr_debug("decryption failed: %i\n", rc);
440 goto fail;
441 }
442
443 sdata->dev->stats.rx_packets++;
444 sdata->dev->stats.rx_bytes += skb->len;
445
446 switch (mac_cb(skb)->type) {
447 case IEEE802154_FC_TYPE_DATA:
448 return mac802154_process_data(sdata->dev, skb);
449 default:
450 pr_warn("ieee802154: bad frame received (type = %d)\n",
451 mac_cb(skb)->type);
452 goto fail;
453 }
454
455fail:
456 kfree_skb(skb);
457 return NET_RX_DROP;
458}
459
460static void mac802154_print_addr(const char *name,
461 const struct ieee802154_addr *addr)
462{
463 if (addr->mode == IEEE802154_ADDR_NONE)
464 pr_debug("%s not present\n", name);
465
466 pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id));
467 if (addr->mode == IEEE802154_ADDR_SHORT) {
468 pr_debug("%s is short: %04x\n", name,
469 le16_to_cpu(addr->short_addr));
470 } else {
471 u64 hw = swab64((__force u64) addr->extended_addr);
472
473 pr_debug("%s is hardware: %8phC\n", name, &hw);
474 }
475}
476
477static int mac802154_parse_frame_start(struct sk_buff *skb,
478 struct ieee802154_hdr *hdr)
479{
480 int hlen;
481 struct ieee802154_mac_cb *cb = mac_cb_init(skb);
482
483 hlen = ieee802154_hdr_pull(skb, hdr);
484 if (hlen < 0)
485 return -EINVAL;
486
487 skb->mac_len = hlen;
488
489 pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc),
490 hdr->seq);
491
492 cb->type = hdr->fc.type;
493 cb->ackreq = hdr->fc.ack_request;
494 cb->secen = hdr->fc.security_enabled;
495
496 mac802154_print_addr("destination", &hdr->dest);
497 mac802154_print_addr("source", &hdr->source);
498
499 cb->source = hdr->source;
500 cb->dest = hdr->dest;
501
502 if (hdr->fc.security_enabled) {
503 u64 key;
504
505 pr_debug("seclevel %i\n", hdr->sec.level);
506
507 switch (hdr->sec.key_id_mode) {
508 case IEEE802154_SCF_KEY_IMPLICIT:
509 pr_debug("implicit key\n");
510 break;
511
512 case IEEE802154_SCF_KEY_INDEX:
513 pr_debug("key %02x\n", hdr->sec.key_id);
514 break;
515
516 case IEEE802154_SCF_KEY_SHORT_INDEX:
517 pr_debug("key %04x:%04x %02x\n",
518 le32_to_cpu(hdr->sec.short_src) >> 16,
519 le32_to_cpu(hdr->sec.short_src) & 0xffff,
520 hdr->sec.key_id);
521 break;
522
523 case IEEE802154_SCF_KEY_HW_INDEX:
524 key = swab64((__force u64) hdr->sec.extended_src);
525 pr_debug("key source %8phC %02x\n", &key,
526 hdr->sec.key_id);
527 break;
528 }
529 }
530
531 return 0;
532}
533
534void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb)
535{
536 int ret;
537 struct ieee802154_sub_if_data *sdata;
538 struct ieee802154_hdr hdr;
539
540 ret = mac802154_parse_frame_start(skb, &hdr);
541 if (ret) {
542 pr_debug("got invalid frame\n");
543 kfree_skb(skb);
544 return;
545 }
546
547 rcu_read_lock();
548 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
549 if (sdata->type != IEEE802154_DEV_WPAN ||
550 !netif_running(sdata->dev))
551 continue;
552
553 mac802154_subif_frame(sdata, skb, &hdr);
554 skb = NULL;
555 break;
556 }
557 rcu_read_unlock();
558
559 if (skb)
560 kfree_skb(skb);
561}
diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c
index 575832231fd6..dfdedc206c6a 100644
--- a/net/mac802154/monitor.c
+++ b/net/mac802154/monitor.c
@@ -18,9 +18,7 @@
18 */ 18 */
19 19
20#include <linux/netdevice.h> 20#include <linux/netdevice.h>
21#include <linux/skbuff.h>
22#include <linux/if_arp.h> 21#include <linux/if_arp.h>
23#include <linux/crc-ccitt.h>
24#include <linux/ieee802154.h> 22#include <linux/ieee802154.h>
25 23
26#include <net/mac802154.h> 24#include <net/mac802154.h>
@@ -30,31 +28,6 @@
30 28
31#include "ieee802154_i.h" 29#include "ieee802154_i.h"
32 30
33void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
34{
35 struct sk_buff *skb2;
36 struct ieee802154_sub_if_data *sdata;
37 u16 crc = crc_ccitt(0, skb->data, skb->len);
38 u8 *data;
39
40 rcu_read_lock();
41 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
42 if (sdata->type != IEEE802154_DEV_MONITOR ||
43 !netif_running(sdata->dev))
44 continue;
45
46 skb2 = skb_clone(skb, GFP_ATOMIC);
47 skb2->dev = sdata->dev;
48 skb2->pkt_type = PACKET_HOST;
49 data = skb_put(skb2, 2);
50 data[0] = crc & 0xff;
51 data[1] = crc >> 8;
52
53 netif_rx_ni(skb2);
54 }
55 rcu_read_unlock();
56}
57
58static const struct net_device_ops mac802154_monitor_ops = { 31static const struct net_device_ops mac802154_monitor_ops = {
59 .ndo_open = mac802154_slave_open, 32 .ndo_open = mac802154_slave_open,
60 .ndo_stop = mac802154_slave_close, 33 .ndo_stop = mac802154_slave_close,
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index c4df3210c5e6..d8498c5fc297 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -24,9 +24,223 @@
24 24
25#include <net/mac802154.h> 25#include <net/mac802154.h>
26#include <net/ieee802154_netdev.h> 26#include <net/ieee802154_netdev.h>
27#include <net/rtnetlink.h>
28#include <linux/nl802154.h>
27 29
28#include "ieee802154_i.h" 30#include "ieee802154_i.h"
29 31
32static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
33{
34 return netif_receive_skb(skb);
35}
36
37static int
38mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb,
39 const struct ieee802154_hdr *hdr)
40{
41 __le16 span, sshort;
42 int rc;
43
44 pr_debug("getting packet via slave interface %s\n", sdata->dev->name);
45
46 spin_lock_bh(&sdata->mib_lock);
47
48 span = sdata->pan_id;
49 sshort = sdata->short_addr;
50
51 switch (mac_cb(skb)->dest.mode) {
52 case IEEE802154_ADDR_NONE:
53 if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE)
54 /* FIXME: check if we are PAN coordinator */
55 skb->pkt_type = PACKET_OTHERHOST;
56 else
57 /* ACK comes with both addresses empty */
58 skb->pkt_type = PACKET_HOST;
59 break;
60 case IEEE802154_ADDR_LONG:
61 if (mac_cb(skb)->dest.pan_id != span &&
62 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
63 skb->pkt_type = PACKET_OTHERHOST;
64 else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr)
65 skb->pkt_type = PACKET_HOST;
66 else
67 skb->pkt_type = PACKET_OTHERHOST;
68 break;
69 case IEEE802154_ADDR_SHORT:
70 if (mac_cb(skb)->dest.pan_id != span &&
71 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
72 skb->pkt_type = PACKET_OTHERHOST;
73 else if (mac_cb(skb)->dest.short_addr == sshort)
74 skb->pkt_type = PACKET_HOST;
75 else if (mac_cb(skb)->dest.short_addr ==
76 cpu_to_le16(IEEE802154_ADDR_BROADCAST))
77 skb->pkt_type = PACKET_BROADCAST;
78 else
79 skb->pkt_type = PACKET_OTHERHOST;
80 break;
81 default:
82 spin_unlock_bh(&sdata->mib_lock);
83 pr_debug("invalid dest mode\n");
84 kfree_skb(skb);
85 return NET_RX_DROP;
86 }
87
88 spin_unlock_bh(&sdata->mib_lock);
89
90 skb->dev = sdata->dev;
91
92 rc = mac802154_llsec_decrypt(&sdata->sec, skb);
93 if (rc) {
94 pr_debug("decryption failed: %i\n", rc);
95 goto fail;
96 }
97
98 sdata->dev->stats.rx_packets++;
99 sdata->dev->stats.rx_bytes += skb->len;
100
101 switch (mac_cb(skb)->type) {
102 case IEEE802154_FC_TYPE_DATA:
103 return mac802154_process_data(sdata->dev, skb);
104 default:
105 pr_warn("ieee802154: bad frame received (type = %d)\n",
106 mac_cb(skb)->type);
107 goto fail;
108 }
109
110fail:
111 kfree_skb(skb);
112 return NET_RX_DROP;
113}
114
115static void mac802154_print_addr(const char *name,
116 const struct ieee802154_addr *addr)
117{
118 if (addr->mode == IEEE802154_ADDR_NONE)
119 pr_debug("%s not present\n", name);
120
121 pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id));
122 if (addr->mode == IEEE802154_ADDR_SHORT) {
123 pr_debug("%s is short: %04x\n", name,
124 le16_to_cpu(addr->short_addr));
125 } else {
126 u64 hw = swab64((__force u64)addr->extended_addr);
127
128 pr_debug("%s is hardware: %8phC\n", name, &hw);
129 }
130}
131
132static int mac802154_parse_frame_start(struct sk_buff *skb,
133 struct ieee802154_hdr *hdr)
134{
135 int hlen;
136 struct ieee802154_mac_cb *cb = mac_cb_init(skb);
137
138 hlen = ieee802154_hdr_pull(skb, hdr);
139 if (hlen < 0)
140 return -EINVAL;
141
142 skb->mac_len = hlen;
143
144 pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc),
145 hdr->seq);
146
147 cb->type = hdr->fc.type;
148 cb->ackreq = hdr->fc.ack_request;
149 cb->secen = hdr->fc.security_enabled;
150
151 mac802154_print_addr("destination", &hdr->dest);
152 mac802154_print_addr("source", &hdr->source);
153
154 cb->source = hdr->source;
155 cb->dest = hdr->dest;
156
157 if (hdr->fc.security_enabled) {
158 u64 key;
159
160 pr_debug("seclevel %i\n", hdr->sec.level);
161
162 switch (hdr->sec.key_id_mode) {
163 case IEEE802154_SCF_KEY_IMPLICIT:
164 pr_debug("implicit key\n");
165 break;
166
167 case IEEE802154_SCF_KEY_INDEX:
168 pr_debug("key %02x\n", hdr->sec.key_id);
169 break;
170
171 case IEEE802154_SCF_KEY_SHORT_INDEX:
172 pr_debug("key %04x:%04x %02x\n",
173 le32_to_cpu(hdr->sec.short_src) >> 16,
174 le32_to_cpu(hdr->sec.short_src) & 0xffff,
175 hdr->sec.key_id);
176 break;
177
178 case IEEE802154_SCF_KEY_HW_INDEX:
179 key = swab64((__force u64)hdr->sec.extended_src);
180 pr_debug("key source %8phC %02x\n", &key,
181 hdr->sec.key_id);
182 break;
183 }
184 }
185
186 return 0;
187}
188
189static void
190mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb)
191{
192 int ret;
193 struct ieee802154_sub_if_data *sdata;
194 struct ieee802154_hdr hdr;
195
196 ret = mac802154_parse_frame_start(skb, &hdr);
197 if (ret) {
198 pr_debug("got invalid frame\n");
199 kfree_skb(skb);
200 return;
201 }
202
203 rcu_read_lock();
204 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
205 if (sdata->type != IEEE802154_DEV_WPAN ||
206 !netif_running(sdata->dev))
207 continue;
208
209 mac802154_subif_frame(sdata, skb, &hdr);
210 skb = NULL;
211 break;
212 }
213 rcu_read_unlock();
214
215 if (skb)
216 kfree_skb(skb);
217}
218
219void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
220{
221 struct sk_buff *skb2;
222 struct ieee802154_sub_if_data *sdata;
223 u16 crc = crc_ccitt(0, skb->data, skb->len);
224 u8 *data;
225
226 rcu_read_lock();
227 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
228 if (sdata->type != IEEE802154_DEV_MONITOR ||
229 !netif_running(sdata->dev))
230 continue;
231
232 skb2 = skb_clone(skb, GFP_ATOMIC);
233 skb2->dev = sdata->dev;
234 skb2->pkt_type = PACKET_HOST;
235 data = skb_put(skb2, 2);
236 data[0] = crc & 0xff;
237 data[1] = crc >> 8;
238
239 netif_rx_ni(skb2);
240 }
241 rcu_read_unlock();
242}
243
30static void 244static void
31mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) 245mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
32{ 246{