Loading net/wireless/nl80211.c +59 −92 Original line number Diff line number Diff line Loading @@ -198,6 +198,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb) return res; } static int nl80211_prepare_netdev_dump(struct sk_buff *skb, struct netlink_callback *cb, struct cfg80211_registered_device **rdev, struct net_device **dev) { int ifidx = cb->args[0]; int err; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; cb->args[0] = ifidx; rtnl_lock(); *dev = __dev_get_by_index(sock_net(skb->sk), ifidx); if (!*dev) { err = -ENODEV; goto out_rtnl; } *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out_rtnl; } return 0; out_rtnl: rtnl_unlock(); return err; } static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev) { cfg80211_unlock_rdev(rdev); rtnl_unlock(); } /* IE validation */ static bool is_valid_ie_attr(const struct nlattr *attr) { Loading Loading @@ -1796,28 +1837,12 @@ static int nl80211_dump_station(struct sk_buff *skb, struct cfg80211_registered_device *dev; struct net_device *netdev; u8 mac_addr[ETH_ALEN]; int ifidx = cb->args[0]; int sta_idx = cb->args[1]; int err; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; rtnl_lock(); netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); if (!netdev) { err = -ENODEV; goto out_rtnl; } dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out_rtnl; } err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); if (err) return err; if (!dev->ops->dump_station) { err = -EOPNOTSUPP; Loading Loading @@ -1847,9 +1872,7 @@ static int nl80211_dump_station(struct sk_buff *skb, cb->args[1] = sta_idx; err = skb->len; out_err: cfg80211_unlock_rdev(dev); out_rtnl: rtnl_unlock(); nl80211_finish_netdev_dump(dev); return err; } Loading Loading @@ -2169,28 +2192,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb, struct net_device *netdev; u8 dst[ETH_ALEN]; u8 next_hop[ETH_ALEN]; int ifidx = cb->args[0]; int path_idx = cb->args[1]; int err; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; rtnl_lock(); netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); if (!netdev) { err = -ENODEV; goto out_rtnl; } dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out_rtnl; } err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); if (err) return err; if (!dev->ops->dump_mpath) { err = -EOPNOTSUPP; Loading Loading @@ -2224,10 +2231,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, cb->args[1] = path_idx; err = skb->len; out_err: cfg80211_unlock_rdev(dev); out_rtnl: rtnl_unlock(); nl80211_finish_netdev_dump(dev); return err; } Loading Loading @@ -3034,25 +3038,12 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct net_device *dev; struct cfg80211_internal_bss *scan; struct wireless_dev *wdev; int ifidx = cb->args[0]; int start = cb->args[1], idx = 0; int err; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; cb->args[0] = ifidx; dev = dev_get_by_index(sock_net(skb->sk), ifidx); if (!dev) return -ENODEV; rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(rdev)) { err = PTR_ERR(rdev); goto out_put_netdev; } err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev); if (err) return err; wdev = dev->ieee80211_ptr; Loading @@ -3068,21 +3059,17 @@ static int nl80211_dump_scan(struct sk_buff *skb, cb->nlh->nlmsg_seq, NLM_F_MULTI, rdev, wdev, scan) < 0) { idx--; goto out; break; } } out: spin_unlock_bh(&rdev->bss_lock); wdev_unlock(wdev); cb->args[1] = idx; err = skb->len; cfg80211_unlock_rdev(rdev); out_put_netdev: dev_put(dev); nl80211_finish_netdev_dump(rdev); return err; return skb->len; } static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, Loading Loading @@ -3130,29 +3117,12 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct survey_info survey; struct cfg80211_registered_device *dev; struct net_device *netdev; int ifidx = cb->args[0]; int survey_idx = cb->args[1]; int res; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; cb->args[0] = ifidx; rtnl_lock(); netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); if (!netdev) { res = -ENODEV; goto out_rtnl; } dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(dev)) { res = PTR_ERR(dev); goto out_rtnl; } res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); if (res) return res; if (!dev->ops->dump_survey) { res = -EOPNOTSUPP; Loading Loading @@ -3180,10 +3150,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, cb->args[1] = survey_idx; res = skb->len; out_err: cfg80211_unlock_rdev(dev); out_rtnl: rtnl_unlock(); nl80211_finish_netdev_dump(dev); return res; } Loading Loading
net/wireless/nl80211.c +59 −92 Original line number Diff line number Diff line Loading @@ -198,6 +198,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb) return res; } static int nl80211_prepare_netdev_dump(struct sk_buff *skb, struct netlink_callback *cb, struct cfg80211_registered_device **rdev, struct net_device **dev) { int ifidx = cb->args[0]; int err; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; cb->args[0] = ifidx; rtnl_lock(); *dev = __dev_get_by_index(sock_net(skb->sk), ifidx); if (!*dev) { err = -ENODEV; goto out_rtnl; } *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out_rtnl; } return 0; out_rtnl: rtnl_unlock(); return err; } static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev) { cfg80211_unlock_rdev(rdev); rtnl_unlock(); } /* IE validation */ static bool is_valid_ie_attr(const struct nlattr *attr) { Loading Loading @@ -1796,28 +1837,12 @@ static int nl80211_dump_station(struct sk_buff *skb, struct cfg80211_registered_device *dev; struct net_device *netdev; u8 mac_addr[ETH_ALEN]; int ifidx = cb->args[0]; int sta_idx = cb->args[1]; int err; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; rtnl_lock(); netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); if (!netdev) { err = -ENODEV; goto out_rtnl; } dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out_rtnl; } err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); if (err) return err; if (!dev->ops->dump_station) { err = -EOPNOTSUPP; Loading Loading @@ -1847,9 +1872,7 @@ static int nl80211_dump_station(struct sk_buff *skb, cb->args[1] = sta_idx; err = skb->len; out_err: cfg80211_unlock_rdev(dev); out_rtnl: rtnl_unlock(); nl80211_finish_netdev_dump(dev); return err; } Loading Loading @@ -2169,28 +2192,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb, struct net_device *netdev; u8 dst[ETH_ALEN]; u8 next_hop[ETH_ALEN]; int ifidx = cb->args[0]; int path_idx = cb->args[1]; int err; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; rtnl_lock(); netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); if (!netdev) { err = -ENODEV; goto out_rtnl; } dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out_rtnl; } err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); if (err) return err; if (!dev->ops->dump_mpath) { err = -EOPNOTSUPP; Loading Loading @@ -2224,10 +2231,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, cb->args[1] = path_idx; err = skb->len; out_err: cfg80211_unlock_rdev(dev); out_rtnl: rtnl_unlock(); nl80211_finish_netdev_dump(dev); return err; } Loading Loading @@ -3034,25 +3038,12 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct net_device *dev; struct cfg80211_internal_bss *scan; struct wireless_dev *wdev; int ifidx = cb->args[0]; int start = cb->args[1], idx = 0; int err; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; cb->args[0] = ifidx; dev = dev_get_by_index(sock_net(skb->sk), ifidx); if (!dev) return -ENODEV; rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(rdev)) { err = PTR_ERR(rdev); goto out_put_netdev; } err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev); if (err) return err; wdev = dev->ieee80211_ptr; Loading @@ -3068,21 +3059,17 @@ static int nl80211_dump_scan(struct sk_buff *skb, cb->nlh->nlmsg_seq, NLM_F_MULTI, rdev, wdev, scan) < 0) { idx--; goto out; break; } } out: spin_unlock_bh(&rdev->bss_lock); wdev_unlock(wdev); cb->args[1] = idx; err = skb->len; cfg80211_unlock_rdev(rdev); out_put_netdev: dev_put(dev); nl80211_finish_netdev_dump(rdev); return err; return skb->len; } static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, Loading Loading @@ -3130,29 +3117,12 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct survey_info survey; struct cfg80211_registered_device *dev; struct net_device *netdev; int ifidx = cb->args[0]; int survey_idx = cb->args[1]; int res; if (!ifidx) ifidx = nl80211_get_ifidx(cb); if (ifidx < 0) return ifidx; cb->args[0] = ifidx; rtnl_lock(); netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); if (!netdev) { res = -ENODEV; goto out_rtnl; } dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); if (IS_ERR(dev)) { res = PTR_ERR(dev); goto out_rtnl; } res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); if (res) return res; if (!dev->ops->dump_survey) { res = -EOPNOTSUPP; Loading Loading @@ -3180,10 +3150,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, cb->args[1] = survey_idx; res = skb->len; out_err: cfg80211_unlock_rdev(dev); out_rtnl: rtnl_unlock(); nl80211_finish_netdev_dump(dev); return res; } Loading