|
@@ -29,16 +29,16 @@ static struct genl_family nl80211_fam = {
|
|
};
|
|
};
|
|
|
|
|
|
/* internal helper: get drv and dev */
|
|
/* internal helper: get drv and dev */
|
|
-static int get_drv_dev_by_info_ifindex(struct genl_info *info,
|
|
|
|
|
|
+static int get_drv_dev_by_info_ifindex(struct nlattr **attrs,
|
|
struct cfg80211_registered_device **drv,
|
|
struct cfg80211_registered_device **drv,
|
|
struct net_device **dev)
|
|
struct net_device **dev)
|
|
{
|
|
{
|
|
int ifindex;
|
|
int ifindex;
|
|
|
|
|
|
- if (!info->attrs[NL80211_ATTR_IFINDEX])
|
|
|
|
|
|
+ if (!attrs[NL80211_ATTR_IFINDEX])
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
|
|
|
|
|
|
+ ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
|
|
*dev = dev_get_by_index(&init_net, ifindex);
|
|
*dev = dev_get_by_index(&init_net, ifindex);
|
|
if (!*dev)
|
|
if (!*dev)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
@@ -291,21 +291,31 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
|
|
|
|
|
|
mutex_lock(&cfg80211_drv_mutex);
|
|
mutex_lock(&cfg80211_drv_mutex);
|
|
list_for_each_entry(dev, &cfg80211_drv_list, list) {
|
|
list_for_each_entry(dev, &cfg80211_drv_list, list) {
|
|
- if (++wp_idx < wp_start)
|
|
|
|
|
|
+ if (wp_idx < wp_start) {
|
|
|
|
+ wp_idx++;
|
|
continue;
|
|
continue;
|
|
|
|
+ }
|
|
if_idx = 0;
|
|
if_idx = 0;
|
|
|
|
|
|
mutex_lock(&dev->devlist_mtx);
|
|
mutex_lock(&dev->devlist_mtx);
|
|
list_for_each_entry(wdev, &dev->netdev_list, list) {
|
|
list_for_each_entry(wdev, &dev->netdev_list, list) {
|
|
- if (++if_idx < if_start)
|
|
|
|
|
|
+ if (if_idx < if_start) {
|
|
|
|
+ if_idx++;
|
|
continue;
|
|
continue;
|
|
|
|
+ }
|
|
if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
|
|
if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
|
|
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
|
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
|
- wdev->netdev) < 0)
|
|
|
|
- break;
|
|
|
|
|
|
+ wdev->netdev) < 0) {
|
|
|
|
+ mutex_unlock(&dev->devlist_mtx);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ if_idx++;
|
|
}
|
|
}
|
|
mutex_unlock(&dev->devlist_mtx);
|
|
mutex_unlock(&dev->devlist_mtx);
|
|
|
|
+
|
|
|
|
+ wp_idx++;
|
|
}
|
|
}
|
|
|
|
+ out:
|
|
mutex_unlock(&cfg80211_drv_mutex);
|
|
mutex_unlock(&cfg80211_drv_mutex);
|
|
|
|
|
|
cb->args[0] = wp_idx;
|
|
cb->args[0] = wp_idx;
|
|
@@ -321,7 +331,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
|
|
struct net_device *netdev;
|
|
struct net_device *netdev;
|
|
int err;
|
|
int err;
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &dev, &netdev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -392,7 +402,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
|
} else
|
|
} else
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
ifindex = dev->ifindex;
|
|
ifindex = dev->ifindex;
|
|
@@ -477,7 +487,7 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
|
|
int ifindex, err;
|
|
int ifindex, err;
|
|
struct net_device *dev;
|
|
struct net_device *dev;
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
ifindex = dev->ifindex;
|
|
ifindex = dev->ifindex;
|
|
@@ -545,7 +555,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
|
|
if (info->attrs[NL80211_ATTR_MAC])
|
|
if (info->attrs[NL80211_ATTR_MAC])
|
|
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -618,7 +628,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
|
|
if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
|
|
if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -699,7 +709,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -735,7 +745,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
|
|
if (info->attrs[NL80211_ATTR_MAC])
|
|
if (info->attrs[NL80211_ATTR_MAC])
|
|
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -764,7 +774,7 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
struct beacon_parameters params;
|
|
struct beacon_parameters params;
|
|
int haveinfo = 0;
|
|
int haveinfo = 0;
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -843,7 +853,7 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
int err;
|
|
int err;
|
|
struct net_device *dev;
|
|
struct net_device *dev;
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -937,67 +947,78 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
|
|
}
|
|
}
|
|
|
|
|
|
static int nl80211_dump_station(struct sk_buff *skb,
|
|
static int nl80211_dump_station(struct sk_buff *skb,
|
|
- struct netlink_callback *cb)
|
|
|
|
|
|
+ struct netlink_callback *cb)
|
|
{
|
|
{
|
|
- int wp_idx = 0;
|
|
|
|
- int if_idx = 0;
|
|
|
|
- int sta_idx = cb->args[2];
|
|
|
|
- int wp_start = cb->args[0];
|
|
|
|
- int if_start = cb->args[1];
|
|
|
|
struct station_info sinfo;
|
|
struct station_info sinfo;
|
|
struct cfg80211_registered_device *dev;
|
|
struct cfg80211_registered_device *dev;
|
|
- struct wireless_dev *wdev;
|
|
|
|
|
|
+ struct net_device *netdev;
|
|
u8 mac_addr[ETH_ALEN];
|
|
u8 mac_addr[ETH_ALEN];
|
|
|
|
+ int ifidx = cb->args[0];
|
|
|
|
+ int sta_idx = cb->args[1];
|
|
int err;
|
|
int err;
|
|
- int exit = 0;
|
|
|
|
|
|
|
|
- /* TODO: filter by device */
|
|
|
|
- mutex_lock(&cfg80211_drv_mutex);
|
|
|
|
- list_for_each_entry(dev, &cfg80211_drv_list, list) {
|
|
|
|
- if (exit)
|
|
|
|
|
|
+ if (!ifidx) {
|
|
|
|
+ err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
|
|
|
|
+ nl80211_fam.attrbuf, nl80211_fam.maxattr,
|
|
|
|
+ nl80211_policy);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+
|
|
|
|
+ if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
|
|
|
|
+ if (!ifidx)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ netdev = dev_get_by_index(&init_net, ifidx);
|
|
|
|
+ if (!netdev)
|
|
|
|
+ return -ENODEV;
|
|
|
|
+
|
|
|
|
+ dev = cfg80211_get_dev_from_ifindex(ifidx);
|
|
|
|
+ if (IS_ERR(dev)) {
|
|
|
|
+ err = PTR_ERR(dev);
|
|
|
|
+ goto out_put_netdev;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!dev->ops->dump_station) {
|
|
|
|
+ err = -ENOSYS;
|
|
|
|
+ goto out_err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rtnl_lock();
|
|
|
|
+
|
|
|
|
+ while (1) {
|
|
|
|
+ err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
|
|
|
|
+ mac_addr, &sinfo);
|
|
|
|
+ if (err == -ENOENT)
|
|
break;
|
|
break;
|
|
- if (++wp_idx < wp_start)
|
|
|
|
- continue;
|
|
|
|
- if_idx = 0;
|
|
|
|
|
|
+ if (err)
|
|
|
|
+ goto out_err_rtnl;
|
|
|
|
|
|
- mutex_lock(&dev->devlist_mtx);
|
|
|
|
- list_for_each_entry(wdev, &dev->netdev_list, list) {
|
|
|
|
- if (exit)
|
|
|
|
- break;
|
|
|
|
- if (++if_idx < if_start)
|
|
|
|
- continue;
|
|
|
|
- if (!dev->ops->dump_station)
|
|
|
|
- continue;
|
|
|
|
|
|
+ if (nl80211_send_station(skb,
|
|
|
|
+ NETLINK_CB(cb->skb).pid,
|
|
|
|
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
|
|
|
+ netdev, mac_addr,
|
|
|
|
+ &sinfo) < 0)
|
|
|
|
+ goto out;
|
|
|
|
|
|
- for (;; ++sta_idx) {
|
|
|
|
- rtnl_lock();
|
|
|
|
- err = dev->ops->dump_station(&dev->wiphy,
|
|
|
|
- wdev->netdev, sta_idx, mac_addr,
|
|
|
|
- &sinfo);
|
|
|
|
- rtnl_unlock();
|
|
|
|
- if (err) {
|
|
|
|
- sta_idx = 0;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- if (nl80211_send_station(skb,
|
|
|
|
- NETLINK_CB(cb->skb).pid,
|
|
|
|
- cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
|
|
|
- wdev->netdev, mac_addr,
|
|
|
|
- &sinfo) < 0) {
|
|
|
|
- exit = 1;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- mutex_unlock(&dev->devlist_mtx);
|
|
|
|
|
|
+ sta_idx++;
|
|
}
|
|
}
|
|
- mutex_unlock(&cfg80211_drv_mutex);
|
|
|
|
|
|
|
|
- cb->args[0] = wp_idx;
|
|
|
|
- cb->args[1] = if_idx;
|
|
|
|
- cb->args[2] = sta_idx;
|
|
|
|
|
|
|
|
- return skb->len;
|
|
|
|
|
|
+ out:
|
|
|
|
+ cb->args[1] = sta_idx;
|
|
|
|
+ err = skb->len;
|
|
|
|
+ out_err_rtnl:
|
|
|
|
+ rtnl_unlock();
|
|
|
|
+ out_err:
|
|
|
|
+ cfg80211_put_dev(dev);
|
|
|
|
+ out_put_netdev:
|
|
|
|
+ dev_put(netdev);
|
|
|
|
+
|
|
|
|
+ return err;
|
|
}
|
|
}
|
|
|
|
|
|
static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
|
|
static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
|
|
@@ -1016,7 +1037,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
|
|
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -1112,7 +1133,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
params.plink_action =
|
|
params.plink_action =
|
|
nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
|
|
nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -1172,7 +1193,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
|
¶ms.station_flags))
|
|
¶ms.station_flags))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -1207,7 +1228,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
|
|
if (info->attrs[NL80211_ATTR_MAC])
|
|
if (info->attrs[NL80211_ATTR_MAC])
|
|
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -1277,68 +1298,78 @@ static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
|
|
}
|
|
}
|
|
|
|
|
|
static int nl80211_dump_mpath(struct sk_buff *skb,
|
|
static int nl80211_dump_mpath(struct sk_buff *skb,
|
|
- struct netlink_callback *cb)
|
|
|
|
|
|
+ struct netlink_callback *cb)
|
|
{
|
|
{
|
|
- int wp_idx = 0;
|
|
|
|
- int if_idx = 0;
|
|
|
|
- int sta_idx = cb->args[2];
|
|
|
|
- int wp_start = cb->args[0];
|
|
|
|
- int if_start = cb->args[1];
|
|
|
|
struct mpath_info pinfo;
|
|
struct mpath_info pinfo;
|
|
struct cfg80211_registered_device *dev;
|
|
struct cfg80211_registered_device *dev;
|
|
- struct wireless_dev *wdev;
|
|
|
|
|
|
+ struct net_device *netdev;
|
|
u8 dst[ETH_ALEN];
|
|
u8 dst[ETH_ALEN];
|
|
u8 next_hop[ETH_ALEN];
|
|
u8 next_hop[ETH_ALEN];
|
|
|
|
+ int ifidx = cb->args[0];
|
|
|
|
+ int path_idx = cb->args[1];
|
|
int err;
|
|
int err;
|
|
- int exit = 0;
|
|
|
|
|
|
|
|
- /* TODO: filter by device */
|
|
|
|
- mutex_lock(&cfg80211_drv_mutex);
|
|
|
|
- list_for_each_entry(dev, &cfg80211_drv_list, list) {
|
|
|
|
- if (exit)
|
|
|
|
|
|
+ if (!ifidx) {
|
|
|
|
+ err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
|
|
|
|
+ nl80211_fam.attrbuf, nl80211_fam.maxattr,
|
|
|
|
+ nl80211_policy);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+
|
|
|
|
+ if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
|
|
|
|
+ if (!ifidx)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ netdev = dev_get_by_index(&init_net, ifidx);
|
|
|
|
+ if (!netdev)
|
|
|
|
+ return -ENODEV;
|
|
|
|
+
|
|
|
|
+ dev = cfg80211_get_dev_from_ifindex(ifidx);
|
|
|
|
+ if (IS_ERR(dev)) {
|
|
|
|
+ err = PTR_ERR(dev);
|
|
|
|
+ goto out_put_netdev;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!dev->ops->dump_mpath) {
|
|
|
|
+ err = -ENOSYS;
|
|
|
|
+ goto out_err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rtnl_lock();
|
|
|
|
+
|
|
|
|
+ while (1) {
|
|
|
|
+ err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
|
|
|
|
+ dst, next_hop, &pinfo);
|
|
|
|
+ if (err == -ENOENT)
|
|
break;
|
|
break;
|
|
- if (++wp_idx < wp_start)
|
|
|
|
- continue;
|
|
|
|
- if_idx = 0;
|
|
|
|
|
|
+ if (err)
|
|
|
|
+ goto out_err_rtnl;
|
|
|
|
|
|
- mutex_lock(&dev->devlist_mtx);
|
|
|
|
- list_for_each_entry(wdev, &dev->netdev_list, list) {
|
|
|
|
- if (exit)
|
|
|
|
- break;
|
|
|
|
- if (++if_idx < if_start)
|
|
|
|
- continue;
|
|
|
|
- if (!dev->ops->dump_mpath)
|
|
|
|
- continue;
|
|
|
|
|
|
+ if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
|
|
|
|
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
|
|
|
+ netdev, dst, next_hop,
|
|
|
|
+ &pinfo) < 0)
|
|
|
|
+ goto out;
|
|
|
|
|
|
- for (;; ++sta_idx) {
|
|
|
|
- rtnl_lock();
|
|
|
|
- err = dev->ops->dump_mpath(&dev->wiphy,
|
|
|
|
- wdev->netdev, sta_idx, dst,
|
|
|
|
- next_hop, &pinfo);
|
|
|
|
- rtnl_unlock();
|
|
|
|
- if (err) {
|
|
|
|
- sta_idx = 0;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- if (nl80211_send_mpath(skb,
|
|
|
|
- NETLINK_CB(cb->skb).pid,
|
|
|
|
- cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
|
|
|
- wdev->netdev, dst, next_hop,
|
|
|
|
- &pinfo) < 0) {
|
|
|
|
- exit = 1;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- mutex_unlock(&dev->devlist_mtx);
|
|
|
|
|
|
+ path_idx++;
|
|
}
|
|
}
|
|
- mutex_unlock(&cfg80211_drv_mutex);
|
|
|
|
|
|
|
|
- cb->args[0] = wp_idx;
|
|
|
|
- cb->args[1] = if_idx;
|
|
|
|
- cb->args[2] = sta_idx;
|
|
|
|
|
|
|
|
- return skb->len;
|
|
|
|
|
|
+ out:
|
|
|
|
+ cb->args[1] = path_idx;
|
|
|
|
+ err = skb->len;
|
|
|
|
+ out_err_rtnl:
|
|
|
|
+ rtnl_unlock();
|
|
|
|
+ out_err:
|
|
|
|
+ cfg80211_put_dev(dev);
|
|
|
|
+ out_put_netdev:
|
|
|
|
+ dev_put(netdev);
|
|
|
|
+
|
|
|
|
+ return err;
|
|
}
|
|
}
|
|
|
|
|
|
static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
|
|
static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
|
|
@@ -1358,7 +1389,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
|
|
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -1411,7 +1442,7 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
|
|
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
|
|
next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -1446,7 +1477,7 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
|
|
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
|
|
next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -1475,7 +1506,7 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
|
|
if (info->attrs[NL80211_ATTR_MAC])
|
|
if (info->attrs[NL80211_ATTR_MAC])
|
|
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
|
|
|
|
|
- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
|
|
|
|
|
+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|