mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 14:49:24 +01:00
hwsim: Keep track of interface types
This commit is contained in:
parent
d676f159d3
commit
1dcab170b6
@ -377,6 +377,8 @@ bin_PROGRAMS += tools/hwsim
|
|||||||
|
|
||||||
tools_hwsim_SOURCES = tools/hwsim.c src/mpdu.h \
|
tools_hwsim_SOURCES = tools/hwsim.c src/mpdu.h \
|
||||||
src/util.h src/util.c \
|
src/util.h src/util.c \
|
||||||
|
src/nl80211cmd.h src/nl80211cmd.c \
|
||||||
|
src/nl80211util.h src/nl80211util.c \
|
||||||
src/storage.h src/storage.c \
|
src/storage.h src/storage.c \
|
||||||
src/common.h src/common.c \
|
src/common.h src/common.c \
|
||||||
src/band.h src/band.c
|
src/band.h src/band.c
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
#include "src/storage.h"
|
#include "src/storage.h"
|
||||||
#include "src/mpdu.h"
|
#include "src/mpdu.h"
|
||||||
#include "src/crypto.h"
|
#include "src/crypto.h"
|
||||||
|
#include "src/nl80211util.h"
|
||||||
|
#include "src/nl80211cmd.h"
|
||||||
|
|
||||||
#define HWSIM_SERVICE "net.connman.hwsim"
|
#define HWSIM_SERVICE "net.connman.hwsim"
|
||||||
|
|
||||||
@ -419,6 +421,7 @@ struct interface_info_rec {
|
|||||||
struct radio_info_rec *radio_rec;
|
struct radio_info_rec *radio_rec;
|
||||||
uint8_t addr[ETH_ALEN];
|
uint8_t addr[ETH_ALEN];
|
||||||
char *name;
|
char *name;
|
||||||
|
uint32_t iftype;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct l_queue *radio_info;
|
static struct l_queue *radio_info;
|
||||||
@ -818,14 +821,11 @@ static void get_wiphy_callback(struct l_genl_msg *msg, void *user_data)
|
|||||||
|
|
||||||
static void get_interface_callback(struct l_genl_msg *msg, void *user_data)
|
static void get_interface_callback(struct l_genl_msg *msg, void *user_data)
|
||||||
{
|
{
|
||||||
struct l_genl_attr attr;
|
uint32_t ifindex;
|
||||||
uint16_t type, len;
|
uint32_t wiphy_id;
|
||||||
const void *data;
|
uint32_t iftype;
|
||||||
const uint8_t *addr = NULL;
|
const uint8_t *addr;
|
||||||
const uint32_t *wiphy_id = NULL;
|
const char *ifname;
|
||||||
const uint32_t *ifindex = NULL;
|
|
||||||
const char *ifname = NULL;
|
|
||||||
size_t ifname_len = 0;
|
|
||||||
struct interface_info_rec *rec;
|
struct interface_info_rec *rec;
|
||||||
struct radio_info_rec *radio_rec;
|
struct radio_info_rec *radio_rec;
|
||||||
bool old;
|
bool old;
|
||||||
@ -833,57 +833,28 @@ static void get_interface_callback(struct l_genl_msg *msg, void *user_data)
|
|||||||
struct interface_info_rec prev_rec;
|
struct interface_info_rec prev_rec;
|
||||||
bool name_change = false;
|
bool name_change = false;
|
||||||
|
|
||||||
if (!l_genl_attr_init(&attr, msg))
|
if (nl80211_parse_attrs(msg, NL80211_ATTR_IFINDEX, &ifindex,
|
||||||
return;
|
NL80211_ATTR_IFNAME, &ifname,
|
||||||
|
NL80211_ATTR_WIPHY, &wiphy_id,
|
||||||
while (l_genl_attr_next(&attr, &type, &len, &data)) {
|
NL80211_ATTR_IFTYPE, &iftype,
|
||||||
switch (type) {
|
NL80211_ATTR_MAC, &addr,
|
||||||
case NL80211_ATTR_MAC:
|
NL80211_ATTR_UNSPEC) < 0)
|
||||||
if (len != ETH_ALEN)
|
|
||||||
break;
|
|
||||||
|
|
||||||
addr = data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NL80211_ATTR_WIPHY:
|
|
||||||
if (len != 4)
|
|
||||||
break;
|
|
||||||
|
|
||||||
wiphy_id = data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NL80211_ATTR_IFINDEX:
|
|
||||||
if (len != 4)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ifindex = data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NL80211_ATTR_IFNAME:
|
|
||||||
ifname = data;
|
|
||||||
ifname_len = len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!addr || !wiphy_id || !ifindex || !ifname)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
radio_rec = l_queue_find(radio_info, radio_info_match_wiphy_id,
|
radio_rec = l_queue_find(radio_info, radio_info_match_wiphy_id,
|
||||||
L_UINT_TO_PTR(*wiphy_id));
|
L_UINT_TO_PTR(wiphy_id));
|
||||||
if (!radio_rec)
|
if (!radio_rec)
|
||||||
/* This is not a hwsim interface, don't track it */
|
/* This is not a hwsim interface, don't track it */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rec = l_queue_find(interface_info, interface_info_match_id,
|
rec = l_queue_find(interface_info, interface_info_match_id,
|
||||||
L_UINT_TO_PTR(*ifindex));
|
L_UINT_TO_PTR(ifindex));
|
||||||
if (rec) {
|
if (rec) {
|
||||||
old = true;
|
old = true;
|
||||||
|
|
||||||
memcpy(&prev_rec, rec, sizeof(prev_rec));
|
memcpy(&prev_rec, rec, sizeof(prev_rec));
|
||||||
|
|
||||||
if (strlen(rec->name) != ifname_len ||
|
if (strcmp(rec->name, ifname))
|
||||||
memcmp(rec->name, ifname, ifname_len))
|
|
||||||
name_change = true;
|
name_change = true;
|
||||||
|
|
||||||
l_free(rec->name);
|
l_free(rec->name);
|
||||||
@ -892,12 +863,13 @@ static void get_interface_callback(struct l_genl_msg *msg, void *user_data)
|
|||||||
|
|
||||||
rec = l_new(struct interface_info_rec, 1);
|
rec = l_new(struct interface_info_rec, 1);
|
||||||
|
|
||||||
rec->id = *ifindex;
|
rec->id = ifindex;
|
||||||
rec->radio_rec = radio_rec;
|
rec->radio_rec = radio_rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(rec->addr, addr, ETH_ALEN);
|
memcpy(rec->addr, addr, ETH_ALEN);
|
||||||
rec->name = l_strndup(ifname, ifname_len);
|
rec->name = l_strdup(ifname);
|
||||||
|
rec->iftype = iftype;
|
||||||
|
|
||||||
if (!interface_info)
|
if (!interface_info)
|
||||||
interface_info = l_queue_new();
|
interface_info = l_queue_new();
|
||||||
@ -987,6 +959,30 @@ static void del_radio_event(struct l_genl_msg *msg)
|
|||||||
radio_free(radio);
|
radio_free(radio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_interface_event(struct l_genl_msg *msg)
|
||||||
|
{
|
||||||
|
struct interface_info_rec *interface;
|
||||||
|
uint32_t ifindex;
|
||||||
|
uint32_t iftype;
|
||||||
|
|
||||||
|
if (nl80211_parse_attrs(msg, NL80211_ATTR_IFINDEX, &ifindex,
|
||||||
|
NL80211_ATTR_IFTYPE, &iftype,
|
||||||
|
NL80211_ATTR_UNSPEC) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
interface = l_queue_find(interface_info, interface_info_match_id,
|
||||||
|
L_UINT_TO_PTR(ifindex));
|
||||||
|
if (!interface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (interface->iftype == iftype)
|
||||||
|
return;
|
||||||
|
|
||||||
|
l_debug("Interface iftype changed for ifindex: %u, iftype: %u",
|
||||||
|
ifindex, iftype);
|
||||||
|
interface->iftype = iftype;
|
||||||
|
}
|
||||||
|
|
||||||
static void del_interface_event(struct l_genl_msg *msg)
|
static void del_interface_event(struct l_genl_msg *msg)
|
||||||
{
|
{
|
||||||
struct interface_info_rec *interface;
|
struct interface_info_rec *interface;
|
||||||
@ -1064,6 +1060,9 @@ static void nl80211_config_notify(struct l_genl_msg *msg, void *user_data)
|
|||||||
case NL80211_CMD_NEW_INTERFACE:
|
case NL80211_CMD_NEW_INTERFACE:
|
||||||
get_interface_callback(msg, NULL);
|
get_interface_callback(msg, NULL);
|
||||||
break;
|
break;
|
||||||
|
case NL80211_CMD_SET_INTERFACE:
|
||||||
|
set_interface_event(msg);
|
||||||
|
break;
|
||||||
case NL80211_CMD_DEL_INTERFACE:
|
case NL80211_CMD_DEL_INTERFACE:
|
||||||
del_interface_event(msg);
|
del_interface_event(msg);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user