diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9f40c4d417d72fb3d1accae81ea64cff87d7dd45..0e85ec39b6380de904efe8c2ac0c89b3cb6f12e0 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -363,11 +363,13 @@ struct wiphy; * wireless extensions but this is subject to reevaluation as soon as this * code is used more widely and we have a first user without wext. * - * @add_virtual_intf: create a new virtual interface with the given name + * @add_virtual_intf: create a new virtual interface with the given name, + * must set the struct wireless_dev's iftype. * * @del_virtual_intf: remove the virtual interface determined by ifindex. * - * @change_virtual_intf: change type of virtual interface + * @change_virtual_intf: change type/configuration of virtual interface, + * keep the struct wireless_dev's iftype updated. * * @add_key: add a key with the given parameters. @mac_addr will be %NULL * when adding a group key. diff --git a/include/net/wireless.h b/include/net/wireless.h index 0de7fde9f336870983ef42ae151512dc2ddaf80e..721efb363db73cd0bb06270e5c1463a6e7ffe930 100644 --- a/include/net/wireless.h +++ b/include/net/wireless.h @@ -223,9 +223,11 @@ struct wiphy { * the netdev.) * * @wiphy: pointer to hardware description + * @iftype: interface type */ struct wireless_dev { struct wiphy *wiphy; + enum nl80211_iftype iftype; /* private to the generic wireless code */ struct list_head list; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index a72fbebb8ea2bd199b5aac9f53ece22e88ab57ed..b5cd91e8971292d3342d63d828f45f761ece7da6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -625,6 +625,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, /* and set some type-dependent values */ sdata->vif.type = type; sdata->dev->hard_start_xmit = ieee80211_subif_start_xmit; + sdata->wdev.iftype = type; /* only monitor differs */ sdata->dev->type = ARPHRD_ETHER; diff --git a/net/wireless/core.c b/net/wireless/core.c index 88cb73394864015f692a33327fd2481938e54dde..d6940085d59c33c6e3e6000abe01d928adddd478 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -384,6 +384,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); + WARN_ON(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_UNSPECIFIED); + switch (state) { case NETDEV_REGISTER: mutex_lock(&rdev->devlist_mtx); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1221d726ed50024a3ff0397bfec13371915a27ab..44771a690d53d70f1a8c2281387b7fb4e72b4fec 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -299,7 +299,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); - /* TODO: interface type */ + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype); return genlmsg_end(msg, hdr); nla_put_failure: @@ -453,6 +453,10 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) &flags); err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, type, err ? NULL : &flags, ¶ms); + + dev = __dev_get_by_index(&init_net, ifindex); + WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type)); + rtnl_unlock(); unlock: