aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac802154/iface.c
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/iface.c
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/iface.c')
-rw-r--r--net/mac802154/iface.c186
1 files changed, 0 insertions, 186 deletions
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}