From: David S. Miller Date: Sat, 11 Jun 2016 06:13:32 +0000 (-0700) Subject: Merge tag 'mac80211-next-for-davem-2016-06-09' of git://git.kernel.org/pub/scm/linux... X-Git-Tag: v4.8-rc1~140^2~368 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=d6cf3a85b47424d6fc7b57129680097067cf95eb;hp=-c;p=cascardo%2Flinux.git Merge tag 'mac80211-next-for-davem-2016-06-09' of git://git./linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== For the next cycle, we have the following: * the biggest change is MichaƂ's work on integrating FQ/codel with the mac80211 internal software queues * cfg80211 connect result gets clarified for the "no connection at all" case * advertisement of per-interface type capabilities, in case they differ (which makes a lot of sense for some capabilities) * most of the nl80211 & hwsim unprivileged namespace operation changes * human-readable VHT capabilities in debugfs * some other cleanups, like spelling ==================== Signed-off-by: David S. Miller --- d6cf3a85b47424d6fc7b57129680097067cf95eb diff --combined drivers/net/wireless/mac80211_hwsim.c index 4dd5adcdd29b,0c75e8d9d953..a1e28a4fd658 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@@ -30,6 -30,8 +30,8 @@@ #include #include #include + #include + #include #include "mac80211_hwsim.h" #define WARN_QUEUE 100 @@@ -250,6 -252,28 +252,28 @@@ static inline void hwsim_clear_chanctx_ cp->magic = 0; } + static unsigned int hwsim_net_id; + + static int hwsim_netgroup; + + struct hwsim_net { + int netgroup; + }; + + static inline int hwsim_net_get_netgroup(struct net *net) + { + struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id); + + return hwsim_net->netgroup; + } + + static inline void hwsim_net_set_netgroup(struct net *net) + { + struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id); + + hwsim_net->netgroup = hwsim_netgroup++; + } + static struct class *hwsim_class; static struct net_device *hwsim_mon; /* global monitor netdev */ @@@ -526,6 -550,9 +550,9 @@@ struct mac80211_hwsim_data */ u64 group; + /* group shared by radios created in the same netns */ + int netgroup; + int power_level; /* difference between this hw's clock and the real clock, in usecs */ @@@ -568,6 -595,7 +595,7 @@@ static struct genl_family hwsim_genl_fa .name = "MAC80211_HWSIM", .version = 1, .maxattr = HWSIM_ATTR_MAX, + .netnsok = true, }; enum hwsim_multicast_groups { @@@ -1202,6 -1230,9 +1230,9 @@@ static bool mac80211_hwsim_tx_frame_no_ if (!(data->group & data2->group)) continue; + if (data->netgroup != data2->netgroup) + continue; + if (!hwsim_chans_compat(chan, data2->tmp_chan) && !hwsim_chans_compat(chan, data2->channel)) { ieee80211_iterate_active_interfaces_atomic( @@@ -2349,6 -2380,7 +2380,7 @@@ static int mac80211_hwsim_new_radio(str struct ieee80211_hw *hw; enum nl80211_band band; const struct ieee80211_ops *ops = &mac80211_hwsim_ops; + struct net *net; int idx; if (WARN_ON(param->channels > 1 && !param->use_chanctx)) @@@ -2366,6 -2398,13 +2398,13 @@@ err = -ENOMEM; goto failed; } + + if (info) + net = genl_info_net(info); + else + net = &init_net; + wiphy_net_set(hw->wiphy, net); + data = hw->priv; data->hw = hw; @@@ -2541,6 -2580,8 +2580,8 @@@ data->group = 1; mutex_init(&data->mutex); + data->netgroup = hwsim_net_get_netgroup(net); + /* Enable frame retransmissions for lossy channels */ hw->max_rates = 4; hw->max_rate_tries = 11; @@@ -2776,7 -2817,6 +2817,7 @@@ static int hwsim_tx_info_frame_received if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || !info->attrs[HWSIM_ATTR_FLAGS] || !info->attrs[HWSIM_ATTR_COOKIE] || + !info->attrs[HWSIM_ATTR_SIGNAL] || !info->attrs[HWSIM_ATTR_TX_INFO]) goto out; @@@ -3014,6 -3054,9 +3055,9 @@@ static int hwsim_del_radio_nl(struct sk continue; } + if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info))) + continue; + list_del(&data->list); spin_unlock_bh(&hwsim_radio_lock); mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), @@@ -3040,6 -3083,9 +3084,9 @@@ static int hwsim_get_radio_nl(struct sk if (data->idx != idx) continue; + if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info))) + continue; + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!skb) { res = -ENOMEM; @@@ -3079,6 -3125,9 +3126,9 @@@ static int hwsim_dump_radio_nl(struct s if (data->idx < idx) continue; + if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk))) + continue; + res = mac80211_hwsim_get_radio(skb, data, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, cb, @@@ -3118,13 -3167,13 +3168,13 @@@ static const struct genl_ops hwsim_ops[ .cmd = HWSIM_CMD_NEW_RADIO, .policy = hwsim_genl_policy, .doit = hwsim_new_radio_nl, - .flags = GENL_ADMIN_PERM, + .flags = GENL_UNS_ADMIN_PERM, }, { .cmd = HWSIM_CMD_DEL_RADIO, .policy = hwsim_genl_policy, .doit = hwsim_del_radio_nl, - .flags = GENL_ADMIN_PERM, + .flags = GENL_UNS_ADMIN_PERM, }, { .cmd = HWSIM_CMD_GET_RADIO, @@@ -3206,6 -3255,40 +3256,40 @@@ failure return -EINVAL; } + static __net_init int hwsim_init_net(struct net *net) + { + hwsim_net_set_netgroup(net); + + return 0; + } + + static void __net_exit hwsim_exit_net(struct net *net) + { + struct mac80211_hwsim_data *data, *tmp; + + spin_lock_bh(&hwsim_radio_lock); + list_for_each_entry_safe(data, tmp, &hwsim_radios, list) { + if (!net_eq(wiphy_net(data->hw->wiphy), net)) + continue; + + /* Radios created in init_net are returned to init_net. */ + if (data->netgroup == hwsim_net_get_netgroup(&init_net)) + continue; + + list_del(&data->list); + INIT_WORK(&data->destroy_work, destroy_radio); + schedule_work(&data->destroy_work); + } + spin_unlock_bh(&hwsim_radio_lock); + } + + static struct pernet_operations hwsim_net_ops = { + .init = hwsim_init_net, + .exit = hwsim_exit_net, + .id = &hwsim_net_id, + .size = sizeof(struct hwsim_net), + }; + static void hwsim_exit_netlink(void) { /* unregister the notifier */ @@@ -3242,10 -3325,14 +3326,14 @@@ static int __init init_mac80211_hwsim(v spin_lock_init(&hwsim_radio_lock); INIT_LIST_HEAD(&hwsim_radios); - err = platform_driver_register(&mac80211_hwsim_driver); + err = register_pernet_device(&hwsim_net_ops); if (err) return err; + err = platform_driver_register(&mac80211_hwsim_driver); + if (err) + goto out_unregister_pernet; + hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); if (IS_ERR(hwsim_class)) { err = PTR_ERR(hwsim_class); @@@ -3363,6 -3450,8 +3451,8 @@@ out_free_radios mac80211_hwsim_free(); out_unregister_driver: platform_driver_unregister(&mac80211_hwsim_driver); + out_unregister_pernet: + unregister_pernet_device(&hwsim_net_ops); return err; } module_init(init_mac80211_hwsim); @@@ -3376,5 -3465,6 +3466,6 @@@ static void __exit exit_mac80211_hwsim( mac80211_hwsim_free(); unregister_netdev(hwsim_mon); platform_driver_unregister(&mac80211_hwsim_driver); + unregister_pernet_device(&hwsim_net_ops); } module_exit(exit_mac80211_hwsim); diff --combined net/wireless/core.c index ecca3896b9f7,b8e10a952111..39d9abd309ea --- a/net/wireless/core.c +++ b/net/wireless/core.c @@@ -363,6 -363,8 +363,6 @@@ struct wiphy *wiphy_new_nm(const struc WARN_ON(ops->remain_on_channel && !ops->cancel_remain_on_channel); WARN_ON(ops->tdls_channel_switch && !ops->tdls_cancel_channel_switch); WARN_ON(ops->add_tx_ts && !ops->del_tx_ts); - WARN_ON(ops->set_tx_power && !ops->get_tx_power); - WARN_ON(ops->set_antenna && !ops->get_antenna); alloc_size = sizeof(*rdev) + sizeof_priv; @@@ -748,6 -750,36 +748,36 @@@ int wiphy_register(struct wiphy *wiphy nl80211_send_reg_change_event(&request); } + /* Check that nobody globally advertises any capabilities they do not + * advertise on all possible interface types. + */ + if (wiphy->extended_capabilities_len && + wiphy->num_iftype_ext_capab && + wiphy->iftype_ext_capab) { + u8 supported_on_all, j; + const struct wiphy_iftype_ext_capab *capab; + + capab = wiphy->iftype_ext_capab; + for (j = 0; j < wiphy->extended_capabilities_len; j++) { + if (capab[0].extended_capabilities_len > j) + supported_on_all = + capab[0].extended_capabilities[j]; + else + supported_on_all = 0x00; + for (i = 1; i < wiphy->num_iftype_ext_capab; i++) { + if (j >= capab[i].extended_capabilities_len) { + supported_on_all = 0x00; + break; + } + supported_on_all &= + capab[i].extended_capabilities[j]; + } + if (WARN_ON(wiphy->extended_capabilities[j] & + ~supported_on_all)) + break; + } + } + rdev->wiphy.registered = true; rtnl_unlock();