diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 27 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 2 | ||||
-rw-r--r-- | net/core/dev.c | 25 | ||||
-rw-r--r-- | net/core/net_namespace.c | 2 | ||||
-rw-r--r-- | net/ipv4/arp.c | 4 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 2 | ||||
-rw-r--r-- | net/mac80211/pm.c | 24 | ||||
-rw-r--r-- | net/mac80211/rx.c | 12 | ||||
-rw-r--r-- | net/netlabel/netlabel_kapi.c | 2 | ||||
-rw-r--r-- | net/wireless/reg.c | 9 | ||||
-rw-r--r-- | net/wireless/reg.h | 3 | ||||
-rw-r--r-- | net/wireless/scan.c | 4 |
12 files changed, 79 insertions, 37 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index e50566ebf9f9..94b3388c188b 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -2080,28 +2080,41 @@ static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL); | |||
2080 | /* ---- Initialization ---- */ | 2080 | /* ---- Initialization ---- */ |
2081 | static int __init rfcomm_init(void) | 2081 | static int __init rfcomm_init(void) |
2082 | { | 2082 | { |
2083 | int ret; | ||
2084 | |||
2083 | l2cap_load(); | 2085 | l2cap_load(); |
2084 | 2086 | ||
2085 | hci_register_cb(&rfcomm_cb); | 2087 | hci_register_cb(&rfcomm_cb); |
2086 | 2088 | ||
2087 | rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd"); | 2089 | rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd"); |
2088 | if (IS_ERR(rfcomm_thread)) { | 2090 | if (IS_ERR(rfcomm_thread)) { |
2089 | hci_unregister_cb(&rfcomm_cb); | 2091 | ret = PTR_ERR(rfcomm_thread); |
2090 | return PTR_ERR(rfcomm_thread); | 2092 | goto out_thread; |
2091 | } | 2093 | } |
2092 | 2094 | ||
2093 | if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) | 2095 | if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) |
2094 | BT_ERR("Failed to create RFCOMM info file"); | 2096 | BT_ERR("Failed to create RFCOMM info file"); |
2095 | 2097 | ||
2096 | rfcomm_init_sockets(); | 2098 | ret = rfcomm_init_ttys(); |
2099 | if (ret) | ||
2100 | goto out_tty; | ||
2097 | 2101 | ||
2098 | #ifdef CONFIG_BT_RFCOMM_TTY | 2102 | ret = rfcomm_init_sockets(); |
2099 | rfcomm_init_ttys(); | 2103 | if (ret) |
2100 | #endif | 2104 | goto out_sock; |
2101 | 2105 | ||
2102 | BT_INFO("RFCOMM ver %s", VERSION); | 2106 | BT_INFO("RFCOMM ver %s", VERSION); |
2103 | 2107 | ||
2104 | return 0; | 2108 | return 0; |
2109 | |||
2110 | out_sock: | ||
2111 | rfcomm_cleanup_ttys(); | ||
2112 | out_tty: | ||
2113 | kthread_stop(rfcomm_thread); | ||
2114 | out_thread: | ||
2115 | hci_unregister_cb(&rfcomm_cb); | ||
2116 | |||
2117 | return ret; | ||
2105 | } | 2118 | } |
2106 | 2119 | ||
2107 | static void __exit rfcomm_exit(void) | 2120 | static void __exit rfcomm_exit(void) |
@@ -2112,9 +2125,7 @@ static void __exit rfcomm_exit(void) | |||
2112 | 2125 | ||
2113 | kthread_stop(rfcomm_thread); | 2126 | kthread_stop(rfcomm_thread); |
2114 | 2127 | ||
2115 | #ifdef CONFIG_BT_RFCOMM_TTY | ||
2116 | rfcomm_cleanup_ttys(); | 2128 | rfcomm_cleanup_ttys(); |
2117 | #endif | ||
2118 | 2129 | ||
2119 | rfcomm_cleanup_sockets(); | 2130 | rfcomm_cleanup_sockets(); |
2120 | } | 2131 | } |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 7f482784e9f7..0b85e8116859 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -1132,7 +1132,7 @@ error: | |||
1132 | return err; | 1132 | return err; |
1133 | } | 1133 | } |
1134 | 1134 | ||
1135 | void __exit rfcomm_cleanup_sockets(void) | 1135 | void rfcomm_cleanup_sockets(void) |
1136 | { | 1136 | { |
1137 | class_remove_file(bt_class, &class_attr_rfcomm); | 1137 | class_remove_file(bt_class, &class_attr_rfcomm); |
1138 | 1138 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 70c27e0c7c32..43e61ba7bd95 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3865,10 +3865,12 @@ int dev_unicast_delete(struct net_device *dev, void *addr) | |||
3865 | 3865 | ||
3866 | ASSERT_RTNL(); | 3866 | ASSERT_RTNL(); |
3867 | 3867 | ||
3868 | netif_addr_lock_bh(dev); | ||
3868 | err = __hw_addr_del(&dev->uc, addr, dev->addr_len, | 3869 | err = __hw_addr_del(&dev->uc, addr, dev->addr_len, |
3869 | NETDEV_HW_ADDR_T_UNICAST); | 3870 | NETDEV_HW_ADDR_T_UNICAST); |
3870 | if (!err) | 3871 | if (!err) |
3871 | __dev_set_rx_mode(dev); | 3872 | __dev_set_rx_mode(dev); |
3873 | netif_addr_unlock_bh(dev); | ||
3872 | return err; | 3874 | return err; |
3873 | } | 3875 | } |
3874 | EXPORT_SYMBOL(dev_unicast_delete); | 3876 | EXPORT_SYMBOL(dev_unicast_delete); |
@@ -3889,10 +3891,12 @@ int dev_unicast_add(struct net_device *dev, void *addr) | |||
3889 | 3891 | ||
3890 | ASSERT_RTNL(); | 3892 | ASSERT_RTNL(); |
3891 | 3893 | ||
3894 | netif_addr_lock_bh(dev); | ||
3892 | err = __hw_addr_add(&dev->uc, addr, dev->addr_len, | 3895 | err = __hw_addr_add(&dev->uc, addr, dev->addr_len, |
3893 | NETDEV_HW_ADDR_T_UNICAST); | 3896 | NETDEV_HW_ADDR_T_UNICAST); |
3894 | if (!err) | 3897 | if (!err) |
3895 | __dev_set_rx_mode(dev); | 3898 | __dev_set_rx_mode(dev); |
3899 | netif_addr_unlock_bh(dev); | ||
3896 | return err; | 3900 | return err; |
3897 | } | 3901 | } |
3898 | EXPORT_SYMBOL(dev_unicast_add); | 3902 | EXPORT_SYMBOL(dev_unicast_add); |
@@ -3949,7 +3953,8 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, | |||
3949 | * @from: source device | 3953 | * @from: source device |
3950 | * | 3954 | * |
3951 | * Add newly added addresses to the destination device and release | 3955 | * Add newly added addresses to the destination device and release |
3952 | * addresses that have no users left. | 3956 | * addresses that have no users left. The source device must be |
3957 | * locked by netif_tx_lock_bh. | ||
3953 | * | 3958 | * |
3954 | * This function is intended to be called from the dev->set_rx_mode | 3959 | * This function is intended to be called from the dev->set_rx_mode |
3955 | * function of layered software devices. | 3960 | * function of layered software devices. |
@@ -3958,14 +3963,14 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) | |||
3958 | { | 3963 | { |
3959 | int err = 0; | 3964 | int err = 0; |
3960 | 3965 | ||
3961 | ASSERT_RTNL(); | ||
3962 | |||
3963 | if (to->addr_len != from->addr_len) | 3966 | if (to->addr_len != from->addr_len) |
3964 | return -EINVAL; | 3967 | return -EINVAL; |
3965 | 3968 | ||
3969 | netif_addr_lock_bh(to); | ||
3966 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); | 3970 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); |
3967 | if (!err) | 3971 | if (!err) |
3968 | __dev_set_rx_mode(to); | 3972 | __dev_set_rx_mode(to); |
3973 | netif_addr_unlock_bh(to); | ||
3969 | return err; | 3974 | return err; |
3970 | } | 3975 | } |
3971 | EXPORT_SYMBOL(dev_unicast_sync); | 3976 | EXPORT_SYMBOL(dev_unicast_sync); |
@@ -3981,28 +3986,30 @@ EXPORT_SYMBOL(dev_unicast_sync); | |||
3981 | */ | 3986 | */ |
3982 | void dev_unicast_unsync(struct net_device *to, struct net_device *from) | 3987 | void dev_unicast_unsync(struct net_device *to, struct net_device *from) |
3983 | { | 3988 | { |
3984 | ASSERT_RTNL(); | ||
3985 | |||
3986 | if (to->addr_len != from->addr_len) | 3989 | if (to->addr_len != from->addr_len) |
3987 | return; | 3990 | return; |
3988 | 3991 | ||
3992 | netif_addr_lock_bh(from); | ||
3993 | netif_addr_lock(to); | ||
3989 | __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); | 3994 | __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); |
3990 | __dev_set_rx_mode(to); | 3995 | __dev_set_rx_mode(to); |
3996 | netif_addr_unlock(to); | ||
3997 | netif_addr_unlock_bh(from); | ||
3991 | } | 3998 | } |
3992 | EXPORT_SYMBOL(dev_unicast_unsync); | 3999 | EXPORT_SYMBOL(dev_unicast_unsync); |
3993 | 4000 | ||
3994 | static void dev_unicast_flush(struct net_device *dev) | 4001 | static void dev_unicast_flush(struct net_device *dev) |
3995 | { | 4002 | { |
3996 | /* rtnl_mutex must be held here */ | 4003 | netif_addr_lock_bh(dev); |
3997 | |||
3998 | __hw_addr_flush(&dev->uc); | 4004 | __hw_addr_flush(&dev->uc); |
4005 | netif_addr_unlock_bh(dev); | ||
3999 | } | 4006 | } |
4000 | 4007 | ||
4001 | static void dev_unicast_init(struct net_device *dev) | 4008 | static void dev_unicast_init(struct net_device *dev) |
4002 | { | 4009 | { |
4003 | /* rtnl_mutex must be held here */ | 4010 | netif_addr_lock_bh(dev); |
4004 | |||
4005 | __hw_addr_init(&dev->uc); | 4011 | __hw_addr_init(&dev->uc); |
4012 | netif_addr_unlock_bh(dev); | ||
4006 | } | 4013 | } |
4007 | 4014 | ||
4008 | 4015 | ||
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index b7292a2719dc..197283072cc8 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -488,7 +488,7 @@ int net_assign_generic(struct net *net, int id, void *data) | |||
488 | */ | 488 | */ |
489 | 489 | ||
490 | ng->len = id; | 490 | ng->len = id; |
491 | memcpy(&ng->ptr, &old_ng->ptr, old_ng->len); | 491 | memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); |
492 | 492 | ||
493 | rcu_assign_pointer(net->gen, ng); | 493 | rcu_assign_pointer(net->gen, ng); |
494 | call_rcu(&old_ng->rcu, net_generic_release); | 494 | call_rcu(&old_ng->rcu, net_generic_release); |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index c29d75d8f1b1..090e9991ac2a 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -1304,7 +1304,9 @@ static void arp_format_neigh_entry(struct seq_file *seq, | |||
1304 | hbuffer[k++] = hex_asc_lo(n->ha[j]); | 1304 | hbuffer[k++] = hex_asc_lo(n->ha[j]); |
1305 | hbuffer[k++] = ':'; | 1305 | hbuffer[k++] = ':'; |
1306 | } | 1306 | } |
1307 | hbuffer[--k] = 0; | 1307 | if (k != 0) |
1308 | --k; | ||
1309 | hbuffer[k] = 0; | ||
1308 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) | 1310 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) |
1309 | } | 1311 | } |
1310 | #endif | 1312 | #endif |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index aca22b00b6a3..07e7e41816be 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -721,7 +721,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
721 | { | 721 | { |
722 | struct ieee80211_local *local = (void *) data; | 722 | struct ieee80211_local *local = (void *) data; |
723 | 723 | ||
724 | if (local->quiescing) | 724 | if (local->quiescing || local->suspended) |
725 | return; | 725 | return; |
726 | 726 | ||
727 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); | 727 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 7a549f9deb96..5e3d476972f9 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -55,15 +55,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
55 | 55 | ||
56 | rcu_read_unlock(); | 56 | rcu_read_unlock(); |
57 | 57 | ||
58 | /* flush again, in case driver queued work */ | ||
59 | flush_workqueue(local->hw.workqueue); | ||
60 | |||
61 | /* stop hardware - this must stop RX */ | ||
62 | if (local->open_count) { | ||
63 | ieee80211_led_radio(local, false); | ||
64 | drv_stop(local); | ||
65 | } | ||
66 | |||
67 | /* remove STAs */ | 58 | /* remove STAs */ |
68 | spin_lock_irqsave(&local->sta_lock, flags); | 59 | spin_lock_irqsave(&local->sta_lock, flags); |
69 | list_for_each_entry(sta, &local->sta_list, list) { | 60 | list_for_each_entry(sta, &local->sta_list, list) { |
@@ -111,7 +102,22 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
111 | drv_remove_interface(local, &conf); | 102 | drv_remove_interface(local, &conf); |
112 | } | 103 | } |
113 | 104 | ||
105 | /* stop hardware - this must stop RX */ | ||
106 | if (local->open_count) { | ||
107 | ieee80211_led_radio(local, false); | ||
108 | drv_stop(local); | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * flush again, in case driver queued work -- it | ||
113 | * shouldn't be doing (or cancel everything in the | ||
114 | * stop callback) that but better safe than sorry. | ||
115 | */ | ||
116 | flush_workqueue(local->hw.workqueue); | ||
117 | |||
114 | local->suspended = true; | 118 | local->suspended = true; |
119 | /* need suspended to be visible before quiescing is false */ | ||
120 | barrier(); | ||
115 | local->quiescing = false; | 121 | local->quiescing = false; |
116 | 122 | ||
117 | return 0; | 123 | return 0; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index de5bba7f910a..0936fc24942d 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2453,6 +2453,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2453 | return; | 2453 | return; |
2454 | } | 2454 | } |
2455 | 2455 | ||
2456 | /* | ||
2457 | * If we're suspending, it is possible although not too likely | ||
2458 | * that we'd be receiving frames after having already partially | ||
2459 | * quiesced the stack. We can't process such frames then since | ||
2460 | * that might, for example, cause stations to be added or other | ||
2461 | * driver callbacks be invoked. | ||
2462 | */ | ||
2463 | if (unlikely(local->quiescing || local->suspended)) { | ||
2464 | kfree_skb(skb); | ||
2465 | return; | ||
2466 | } | ||
2467 | |||
2456 | if (status->flag & RX_FLAG_HT) { | 2468 | if (status->flag & RX_FLAG_HT) { |
2457 | /* rate_idx is MCS index */ | 2469 | /* rate_idx is MCS index */ |
2458 | if (WARN_ON(status->rate_idx < 0 || | 2470 | if (WARN_ON(status->rate_idx < 0 || |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index b0e582f2d37a..16e6c4378ff1 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -151,7 +151,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, | |||
151 | addr6 = addr; | 151 | addr6 = addr; |
152 | mask6 = mask; | 152 | mask6 = mask; |
153 | map6 = kzalloc(sizeof(*map6), GFP_ATOMIC); | 153 | map6 = kzalloc(sizeof(*map6), GFP_ATOMIC); |
154 | if (map4 == NULL) | 154 | if (map6 == NULL) |
155 | goto cfg_unlbl_map_add_failure; | 155 | goto cfg_unlbl_map_add_failure; |
156 | map6->type = NETLBL_NLTYPE_UNLABELED; | 156 | map6->type = NETLBL_NLTYPE_UNLABELED; |
157 | ipv6_addr_copy(&map6->list.addr, addr6); | 157 | ipv6_addr_copy(&map6->list.addr, addr6); |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 5e14371cda70..75a406d33619 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -1089,17 +1089,18 @@ static void handle_reg_beacon(struct wiphy *wiphy, | |||
1089 | 1089 | ||
1090 | chan->beacon_found = true; | 1090 | chan->beacon_found = true; |
1091 | 1091 | ||
1092 | if (wiphy->disable_beacon_hints) | ||
1093 | return; | ||
1094 | |||
1092 | chan_before.center_freq = chan->center_freq; | 1095 | chan_before.center_freq = chan->center_freq; |
1093 | chan_before.flags = chan->flags; | 1096 | chan_before.flags = chan->flags; |
1094 | 1097 | ||
1095 | if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && | 1098 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) { |
1096 | !(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) { | ||
1097 | chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; | 1099 | chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; |
1098 | channel_changed = true; | 1100 | channel_changed = true; |
1099 | } | 1101 | } |
1100 | 1102 | ||
1101 | if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && | 1103 | if (chan->flags & IEEE80211_CHAN_NO_IBSS) { |
1102 | !(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) { | ||
1103 | chan->flags &= ~IEEE80211_CHAN_NO_IBSS; | 1104 | chan->flags &= ~IEEE80211_CHAN_NO_IBSS; |
1104 | channel_changed = true; | 1105 | channel_changed = true; |
1105 | } | 1106 | } |
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index e37829a49dc4..4e167a8e11be 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -30,7 +30,8 @@ int set_regdom(const struct ieee80211_regdomain *rd); | |||
30 | * non-radar 5 GHz channels. | 30 | * non-radar 5 GHz channels. |
31 | * | 31 | * |
32 | * Drivers do not need to call this, cfg80211 will do it for after a scan | 32 | * Drivers do not need to call this, cfg80211 will do it for after a scan |
33 | * on a newly found BSS. | 33 | * on a newly found BSS. If you cannot make use of this feature you can |
34 | * set the wiphy->disable_beacon_hints to true. | ||
34 | */ | 35 | */ |
35 | int regulatory_hint_found_beacon(struct wiphy *wiphy, | 36 | int regulatory_hint_found_beacon(struct wiphy *wiphy, |
36 | struct ieee80211_channel *beacon_chan, | 37 | struct ieee80211_channel *beacon_chan, |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 9271118e1fc4..7e595ce24eeb 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -118,7 +118,7 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) | |||
118 | 118 | ||
119 | if (!ie1 && !ie2) | 119 | if (!ie1 && !ie2) |
120 | return 0; | 120 | return 0; |
121 | if (!ie1) | 121 | if (!ie1 || !ie2) |
122 | return -1; | 122 | return -1; |
123 | 123 | ||
124 | r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1])); | 124 | r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1])); |
@@ -171,6 +171,8 @@ static bool is_mesh(struct cfg80211_bss *a, | |||
171 | ie = find_ie(WLAN_EID_MESH_CONFIG, | 171 | ie = find_ie(WLAN_EID_MESH_CONFIG, |
172 | a->information_elements, | 172 | a->information_elements, |
173 | a->len_information_elements); | 173 | a->len_information_elements); |
174 | if (!ie) | ||
175 | return false; | ||
174 | if (ie[1] != IEEE80211_MESH_CONFIG_LEN) | 176 | if (ie[1] != IEEE80211_MESH_CONFIG_LEN) |
175 | return false; | 177 | return false; |
176 | 178 | ||