diff options
| author | Ying Xue <ying.xue@windriver.com> | 2014-01-14 21:23:45 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-01-14 21:50:47 -0500 |
| commit | 7f2b8562c2ee6e2a69c2715b9927f708f2f861dc (patch) | |
| tree | 7c61f45f6098356d80cdf16ee751d471804350f8 /net/wireless | |
| parent | 5af28de35342f630a91061e25cc976a01b7ca6c4 (diff) | |
net: nl80211: __dev_get_by_index instead of dev_get_by_index to find interface
As __cfg80211_rdev_from_attrs(), nl80211_dump_wiphy_parse() and
nl80211_set_wiphy() are all under rtnl_lock protection,
__dev_get_by_index() instead of dev_get_by_index() should be used
to find interface handler in them allowing us to avoid to change
interface reference counter.
Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/wireless')
| -rw-r--r-- | net/wireless/nl80211.c | 102 |
1 files changed, 37 insertions, 65 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b4f40fe84a01..4fa555e4dedc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -165,7 +165,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) | |||
| 165 | 165 | ||
| 166 | if (attrs[NL80211_ATTR_IFINDEX]) { | 166 | if (attrs[NL80211_ATTR_IFINDEX]) { |
| 167 | int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); | 167 | int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); |
| 168 | netdev = dev_get_by_index(netns, ifindex); | 168 | netdev = __dev_get_by_index(netns, ifindex); |
| 169 | if (netdev) { | 169 | if (netdev) { |
| 170 | if (netdev->ieee80211_ptr) | 170 | if (netdev->ieee80211_ptr) |
| 171 | tmp = wiphy_to_dev( | 171 | tmp = wiphy_to_dev( |
| @@ -173,8 +173,6 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) | |||
| 173 | else | 173 | else |
| 174 | tmp = NULL; | 174 | tmp = NULL; |
| 175 | 175 | ||
| 176 | dev_put(netdev); | ||
| 177 | |||
| 178 | /* not wireless device -- return error */ | 176 | /* not wireless device -- return error */ |
| 179 | if (!tmp) | 177 | if (!tmp) |
| 180 | return ERR_PTR(-EINVAL); | 178 | return ERR_PTR(-EINVAL); |
| @@ -1656,7 +1654,7 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb, | |||
| 1656 | struct cfg80211_registered_device *rdev; | 1654 | struct cfg80211_registered_device *rdev; |
| 1657 | int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); | 1655 | int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); |
| 1658 | 1656 | ||
| 1659 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); | 1657 | netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); |
| 1660 | if (!netdev) | 1658 | if (!netdev) |
| 1661 | return -ENODEV; | 1659 | return -ENODEV; |
| 1662 | if (netdev->ieee80211_ptr) { | 1660 | if (netdev->ieee80211_ptr) { |
| @@ -1664,7 +1662,6 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb, | |||
| 1664 | netdev->ieee80211_ptr->wiphy); | 1662 | netdev->ieee80211_ptr->wiphy); |
| 1665 | state->filter_wiphy = rdev->wiphy_idx; | 1663 | state->filter_wiphy = rdev->wiphy_idx; |
| 1666 | } | 1664 | } |
| 1667 | dev_put(netdev); | ||
| 1668 | } | 1665 | } |
| 1669 | 1666 | ||
| 1670 | return 0; | 1667 | return 0; |
| @@ -1987,7 +1984,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 1987 | if (info->attrs[NL80211_ATTR_IFINDEX]) { | 1984 | if (info->attrs[NL80211_ATTR_IFINDEX]) { |
| 1988 | int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); | 1985 | int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); |
| 1989 | 1986 | ||
| 1990 | netdev = dev_get_by_index(genl_info_net(info), ifindex); | 1987 | netdev = __dev_get_by_index(genl_info_net(info), ifindex); |
| 1991 | if (netdev && netdev->ieee80211_ptr) | 1988 | if (netdev && netdev->ieee80211_ptr) |
| 1992 | rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); | 1989 | rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); |
| 1993 | else | 1990 | else |
| @@ -2015,32 +2012,24 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 2015 | rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); | 2012 | rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); |
| 2016 | 2013 | ||
| 2017 | if (result) | 2014 | if (result) |
| 2018 | goto bad_res; | 2015 | return result; |
| 2019 | 2016 | ||
| 2020 | if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { | 2017 | if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { |
| 2021 | struct ieee80211_txq_params txq_params; | 2018 | struct ieee80211_txq_params txq_params; |
| 2022 | struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1]; | 2019 | struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1]; |
| 2023 | 2020 | ||
| 2024 | if (!rdev->ops->set_txq_params) { | 2021 | if (!rdev->ops->set_txq_params) |
| 2025 | result = -EOPNOTSUPP; | 2022 | return -EOPNOTSUPP; |
| 2026 | goto bad_res; | ||
| 2027 | } | ||
| 2028 | 2023 | ||
| 2029 | if (!netdev) { | 2024 | if (!netdev) |
| 2030 | result = -EINVAL; | 2025 | return -EINVAL; |
| 2031 | goto bad_res; | ||
| 2032 | } | ||
| 2033 | 2026 | ||
| 2034 | if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 2027 | if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
| 2035 | netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { | 2028 | netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
| 2036 | result = -EINVAL; | 2029 | return -EINVAL; |
| 2037 | goto bad_res; | ||
| 2038 | } | ||
| 2039 | 2030 | ||
| 2040 | if (!netif_running(netdev)) { | 2031 | if (!netif_running(netdev)) |
| 2041 | result = -ENETDOWN; | 2032 | return -ENETDOWN; |
| 2042 | goto bad_res; | ||
| 2043 | } | ||
| 2044 | 2033 | ||
| 2045 | nla_for_each_nested(nl_txq_params, | 2034 | nla_for_each_nested(nl_txq_params, |
| 2046 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], | 2035 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], |
| @@ -2051,12 +2040,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 2051 | txq_params_policy); | 2040 | txq_params_policy); |
| 2052 | result = parse_txq_params(tb, &txq_params); | 2041 | result = parse_txq_params(tb, &txq_params); |
| 2053 | if (result) | 2042 | if (result) |
| 2054 | goto bad_res; | 2043 | return result; |
| 2055 | 2044 | ||
| 2056 | result = rdev_set_txq_params(rdev, netdev, | 2045 | result = rdev_set_txq_params(rdev, netdev, |
| 2057 | &txq_params); | 2046 | &txq_params); |
| 2058 | if (result) | 2047 | if (result) |
| 2059 | goto bad_res; | 2048 | return result; |
| 2060 | } | 2049 | } |
| 2061 | } | 2050 | } |
| 2062 | 2051 | ||
| @@ -2065,7 +2054,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 2065 | nl80211_can_set_dev_channel(wdev) ? wdev : NULL, | 2054 | nl80211_can_set_dev_channel(wdev) ? wdev : NULL, |
| 2066 | info); | 2055 | info); |
| 2067 | if (result) | 2056 | if (result) |
| 2068 | goto bad_res; | 2057 | return result; |
| 2069 | } | 2058 | } |
| 2070 | 2059 | ||
| 2071 | if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { | 2060 | if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { |
| @@ -2076,19 +2065,15 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 2076 | if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER)) | 2065 | if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER)) |
| 2077 | txp_wdev = NULL; | 2066 | txp_wdev = NULL; |
| 2078 | 2067 | ||
| 2079 | if (!rdev->ops->set_tx_power) { | 2068 | if (!rdev->ops->set_tx_power) |
| 2080 | result = -EOPNOTSUPP; | 2069 | return -EOPNOTSUPP; |
| 2081 | goto bad_res; | ||
| 2082 | } | ||
| 2083 | 2070 | ||
| 2084 | idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING; | 2071 | idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING; |
| 2085 | type = nla_get_u32(info->attrs[idx]); | 2072 | type = nla_get_u32(info->attrs[idx]); |
| 2086 | 2073 | ||
| 2087 | if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] && | 2074 | if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] && |
| 2088 | (type != NL80211_TX_POWER_AUTOMATIC)) { | 2075 | (type != NL80211_TX_POWER_AUTOMATIC)) |
| 2089 | result = -EINVAL; | 2076 | return -EINVAL; |
| 2090 | goto bad_res; | ||
| 2091 | } | ||
| 2092 | 2077 | ||
| 2093 | if (type != NL80211_TX_POWER_AUTOMATIC) { | 2078 | if (type != NL80211_TX_POWER_AUTOMATIC) { |
| 2094 | idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL; | 2079 | idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL; |
| @@ -2097,7 +2082,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 2097 | 2082 | ||
| 2098 | result = rdev_set_tx_power(rdev, txp_wdev, type, mbm); | 2083 | result = rdev_set_tx_power(rdev, txp_wdev, type, mbm); |
| 2099 | if (result) | 2084 | if (result) |
| 2100 | goto bad_res; | 2085 | return result; |
| 2101 | } | 2086 | } |
| 2102 | 2087 | ||
| 2103 | if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && | 2088 | if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && |
| @@ -2105,10 +2090,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 2105 | u32 tx_ant, rx_ant; | 2090 | u32 tx_ant, rx_ant; |
| 2106 | if ((!rdev->wiphy.available_antennas_tx && | 2091 | if ((!rdev->wiphy.available_antennas_tx && |
| 2107 | !rdev->wiphy.available_antennas_rx) || | 2092 | !rdev->wiphy.available_antennas_rx) || |
| 2108 | !rdev->ops->set_antenna) { | 2093 | !rdev->ops->set_antenna) |
| 2109 | result = -EOPNOTSUPP; | 2094 | return -EOPNOTSUPP; |
| 2110 | goto bad_res; | ||
| 2111 | } | ||
| 2112 | 2095 | ||
