diff options
author | Felix Fietkau <nbd@openwrt.org> | 2013-09-14 14:47:26 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2013-09-14 14:47:26 +0000 |
commit | c006f10a35670bcf47e09799564cf16fe6e09094 (patch) | |
tree | 526f2c32504a2cd7ba2f3f90e2a3d6fc2e7b4d30 | |
parent | 71109355a8354c8dfb36e566a6628f763e025586 (diff) | |
download | upstream-c006f10a35670bcf47e09799564cf16fe6e09094.tar.gz upstream-c006f10a35670bcf47e09799564cf16fe6e09094.tar.bz2 upstream-c006f10a35670bcf47e09799564cf16fe6e09094.zip |
iwinfo: when using nl80211, parse interface combinations instead of creating/deleting interfaces
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Backport of r37983
git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@37984 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r-- | package/iwinfo/src/iwinfo_nl80211.c | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/package/iwinfo/src/iwinfo_nl80211.c b/package/iwinfo/src/iwinfo_nl80211.c index dd619e2d6f..544e701b9e 100644 --- a/package/iwinfo/src/iwinfo_nl80211.c +++ b/package/iwinfo/src/iwinfo_nl80211.c @@ -2155,22 +2155,70 @@ int nl80211_get_hwmodelist(const char *ifname, int *buf) return *buf ? 0 : -1; } -int nl80211_get_mbssid_support(const char *ifname, int *buf) +static int nl80211_get_ifcomb_cb(struct nl_msg *msg, void *arg) { - /* Test whether we can create another interface */ - char *nif = nl80211_ifadd(ifname); + struct nlattr **attr = nl80211_parse(msg); + struct nlattr *comb; + int *ret = arg; + int comb_rem, limit_rem, mode_rem; + + *ret = 0; + if (!attr[NL80211_ATTR_INTERFACE_COMBINATIONS]) + return NL_SKIP; - if (nif) + nla_for_each_nested(comb, attr[NL80211_ATTR_INTERFACE_COMBINATIONS], comb_rem) { - *buf = (iwinfo_ifmac(nif) && iwinfo_ifup(nif)); + static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = { + [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED }, + [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 }, + }; + struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB]; + static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = { + [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED }, + [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 }, + }; + struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT]; + struct nlattr *limit; - iwinfo_ifdown(nif); - nl80211_ifdel(nif); + nla_parse_nested(tb_comb, NL80211_BAND_ATTR_MAX, comb, iface_combination_policy); - return 0; + if (!tb_comb[NL80211_IFACE_COMB_LIMITS]) + continue; + + nla_for_each_nested(limit, tb_comb[NL80211_IFACE_COMB_LIMITS], limit_rem) + { + struct nlattr *mode; + + nla_parse_nested(tb_limit, NUM_NL80211_IFACE_LIMIT, limit, iface_limit_policy); + + if (!tb_limit[NL80211_IFACE_LIMIT_TYPES] || + !tb_limit[NL80211_IFACE_LIMIT_MAX]) + continue; + + if (nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX]) < 2) + continue; + + nla_for_each_nested(mode, tb_limit[NL80211_IFACE_LIMIT_TYPES], mode_rem) { + if (nla_type(mode) == NL80211_IFTYPE_AP) + *ret = 1; + } + } } - return -1; + return NL_SKIP; +} + +int nl80211_get_mbssid_support(const char *ifname, int *buf) +{ + struct nl80211_msg_conveyor *req; + + req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0); + if (!req) + return -1; + + nl80211_send(req, nl80211_get_ifcomb_cb, buf); + nl80211_free(req); + return 0; } int nl80211_get_hardware_id(const char *ifname, char *buf) |