diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-10-13 04:33:06 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-10-25 01:56:24 -0400 |
commit | 1ae2605e55c6ef640238fb2e03d044119acd9a37 (patch) | |
tree | a433a7037d4be8123eef1ae610d45568e8cf55c5 /net/ieee802154 | |
parent | ddbea5cff7d5e2a9727f72c948e92b676a061fc5 (diff) |
ieee802154: 6lowpan: improve packet registration
This patch improves the packet registration handling. Instead of
registration with module init we have a open count variable and
registration the lowpan packet handler when it's needed.
The open count variable should be protected by RTNL.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/ieee802154')
-rw-r--r-- | net/ieee802154/6lowpan_rtnl.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index c7e07b8a8f9f..da78fae5b301 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include "reassembly.h" | 58 | #include "reassembly.h" |
59 | 59 | ||
60 | static LIST_HEAD(lowpan_devices); | 60 | static LIST_HEAD(lowpan_devices); |
61 | static int lowpan_open_count; | ||
61 | 62 | ||
62 | /* private device info */ | 63 | /* private device info */ |
63 | struct lowpan_dev_info { | 64 | struct lowpan_dev_info { |
@@ -571,11 +572,17 @@ drop: | |||
571 | return NET_RX_DROP; | 572 | return NET_RX_DROP; |
572 | } | 573 | } |
573 | 574 | ||
575 | static struct packet_type lowpan_packet_type = { | ||
576 | .type = htons(ETH_P_IEEE802154), | ||
577 | .func = lowpan_rcv, | ||
578 | }; | ||
579 | |||
574 | static int lowpan_newlink(struct net *src_net, struct net_device *dev, | 580 | static int lowpan_newlink(struct net *src_net, struct net_device *dev, |
575 | struct nlattr *tb[], struct nlattr *data[]) | 581 | struct nlattr *tb[], struct nlattr *data[]) |
576 | { | 582 | { |
577 | struct net_device *real_dev; | 583 | struct net_device *real_dev; |
578 | struct lowpan_dev_record *entry; | 584 | struct lowpan_dev_record *entry; |
585 | int ret; | ||
579 | 586 | ||
580 | pr_debug("adding new link\n"); | 587 | pr_debug("adding new link\n"); |
581 | 588 | ||
@@ -610,9 +617,14 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, | |||
610 | list_add_tail(&entry->list, &lowpan_devices); | 617 | list_add_tail(&entry->list, &lowpan_devices); |
611 | mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); | 618 | mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); |
612 | 619 | ||
613 | register_netdevice(dev); | 620 | ret = register_netdevice(dev); |
621 | if (ret >= 0) { | ||
622 | if (!lowpan_open_count) | ||
623 | dev_add_pack(&lowpan_packet_type); | ||
624 | lowpan_open_count++; | ||
625 | } | ||
614 | 626 | ||
615 | return 0; | 627 | return ret; |
616 | } | 628 | } |
617 | 629 | ||
618 | static void lowpan_dellink(struct net_device *dev, struct list_head *head) | 630 | static void lowpan_dellink(struct net_device *dev, struct list_head *head) |
@@ -623,6 +635,10 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) | |||
623 | 635 | ||
624 | ASSERT_RTNL(); | 636 | ASSERT_RTNL(); |
625 | 637 | ||
638 | lowpan_open_count--; | ||
639 | if (!lowpan_open_count) | ||
640 | dev_remove_pack(&lowpan_packet_type); | ||
641 | |||
626 | mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); | 642 | mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); |
627 | list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { | 643 | list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { |
628 | if (entry->ldev == dev) { | 644 | if (entry->ldev == dev) { |
@@ -685,11 +701,6 @@ static struct notifier_block lowpan_dev_notifier = { | |||
685 | .notifier_call = lowpan_device_event, | 701 | .notifier_call = lowpan_device_event, |
686 | }; | 702 | }; |
687 | 703 | ||
688 | static struct packet_type lowpan_packet_type = { | ||
689 | .type = htons(ETH_P_IEEE802154), | ||
690 | .func = lowpan_rcv, | ||
691 | }; | ||
692 | |||
693 | static int __init lowpan_init_module(void) | 704 | static int __init lowpan_init_module(void) |
694 | { | 705 | { |
695 | int err = 0; | 706 | int err = 0; |
@@ -702,8 +713,6 @@ static int __init lowpan_init_module(void) | |||
702 | if (err < 0) | 713 | if (err < 0) |
703 | goto out_frag; | 714 | goto out_frag; |
704 | 715 | ||
705 | dev_add_pack(&lowpan_packet_type); | ||
706 | |||
707 | err = register_netdevice_notifier(&lowpan_dev_notifier); | 716 | err = register_netdevice_notifier(&lowpan_dev_notifier); |
708 | if (err < 0) | 717 | if (err < 0) |
709 | goto out_pack; | 718 | goto out_pack; |
@@ -711,7 +720,6 @@ static int __init lowpan_init_module(void) | |||
711 | return 0; | 720 | return 0; |
712 | 721 | ||
713 | out_pack: | 722 | out_pack: |
714 | dev_remove_pack(&lowpan_packet_type); | ||
715 | lowpan_netlink_fini(); | 723 | lowpan_netlink_fini(); |
716 | out_frag: | 724 | out_frag: |
717 | lowpan_net_frag_exit(); | 725 | lowpan_net_frag_exit(); |
@@ -723,8 +731,6 @@ static void __exit lowpan_cleanup_module(void) | |||
723 | { | 731 | { |
724 | lowpan_netlink_fini(); | 732 | lowpan_netlink_fini(); |
725 | 733 | ||
726 | dev_remove_pack(&lowpan_packet_type); | ||
727 | |||
728 | lowpan_net_frag_exit(); | 734 | lowpan_net_frag_exit(); |
729 | 735 | ||
730 | unregister_netdevice_notifier(&lowpan_dev_notifier); | 736 | unregister_netdevice_notifier(&lowpan_dev_notifier); |