cfg.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * mac80211 configuration hooks for cfg80211
  3. *
  4. * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
  5. *
  6. * This file is GPLv2 as found in COPYING.
  7. */
  8. #include <linux/nl80211.h>
  9. #include <linux/rtnetlink.h>
  10. #include <net/net_namespace.h>
  11. #include <net/cfg80211.h>
  12. #include "ieee80211_i.h"
  13. #include "cfg.h"
  14. static enum ieee80211_if_types
  15. nl80211_type_to_mac80211_type(enum nl80211_iftype type)
  16. {
  17. switch (type) {
  18. case NL80211_IFTYPE_UNSPECIFIED:
  19. return IEEE80211_IF_TYPE_STA;
  20. case NL80211_IFTYPE_ADHOC:
  21. return IEEE80211_IF_TYPE_IBSS;
  22. case NL80211_IFTYPE_STATION:
  23. return IEEE80211_IF_TYPE_STA;
  24. case NL80211_IFTYPE_MONITOR:
  25. return IEEE80211_IF_TYPE_MNTR;
  26. default:
  27. return IEEE80211_IF_TYPE_INVALID;
  28. }
  29. }
  30. static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
  31. enum nl80211_iftype type)
  32. {
  33. struct ieee80211_local *local = wiphy_priv(wiphy);
  34. enum ieee80211_if_types itype;
  35. if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
  36. return -ENODEV;
  37. itype = nl80211_type_to_mac80211_type(type);
  38. if (itype == IEEE80211_IF_TYPE_INVALID)
  39. return -EINVAL;
  40. return ieee80211_if_add(local->mdev, name, NULL, itype);
  41. }
  42. static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
  43. {
  44. struct ieee80211_local *local = wiphy_priv(wiphy);
  45. struct net_device *dev;
  46. char *name;
  47. if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
  48. return -ENODEV;
  49. /* we're under RTNL */
  50. dev = __dev_get_by_index(&init_net, ifindex);
  51. if (!dev)
  52. return 0;
  53. name = dev->name;
  54. return ieee80211_if_remove(local->mdev, name, -1);
  55. }
  56. static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
  57. enum nl80211_iftype type)
  58. {
  59. struct ieee80211_local *local = wiphy_priv(wiphy);
  60. struct net_device *dev;
  61. enum ieee80211_if_types itype;
  62. struct ieee80211_sub_if_data *sdata;
  63. if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
  64. return -ENODEV;
  65. /* we're under RTNL */
  66. dev = __dev_get_by_index(&init_net, ifindex);
  67. if (!dev)
  68. return -ENODEV;
  69. if (netif_running(dev))
  70. return -EBUSY;
  71. itype = nl80211_type_to_mac80211_type(type);
  72. if (itype == IEEE80211_IF_TYPE_INVALID)
  73. return -EINVAL;
  74. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  75. if (sdata->type == IEEE80211_IF_TYPE_VLAN)
  76. return -EOPNOTSUPP;
  77. ieee80211_if_reinit(dev);
  78. ieee80211_if_set_type(dev, itype);
  79. return 0;
  80. }
  81. struct cfg80211_ops mac80211_config_ops = {
  82. .add_virtual_intf = ieee80211_add_iface,
  83. .del_virtual_intf = ieee80211_del_iface,
  84. .change_virtual_intf = ieee80211_change_iface,
  85. };