diff --git a/src/manager.c b/src/manager.c index 6266a134..15ed8856 100644 --- a/src/manager.c +++ b/src/manager.c @@ -68,25 +68,6 @@ struct wiphy_setup_state { static struct l_queue *pending_wiphys; -/* With these drivers don't even try creating our interfaces */ -static const char *default_if_driver_list[] = { - /* - * The out-of-tree rtl88x2bu crashes the kernel hard. Seemingly - * many other drivers are built from the same source code so - * blacklist all of them. Unfortunately there are in-tree drivers - * that also match these names and may be fine. Use - * UseDefaultInterface to override. - */ - "rtl81*", - "rtl87*", - "rtl88*", - "rtw_*", - "brcmfmac", - "bcmsdh_sdmmc", - - NULL, -}; - static void wiphy_setup_state_free(void *data) { struct wiphy_setup_state *state = data; @@ -579,18 +560,9 @@ static void manager_wiphy_dump_done(void *user_data) if (whitelist_filter || blacklist_filter) state->use_default = true; - if (!state->use_default) { - const char *driver = wiphy_get_driver(state->wiphy); - - if (driver) { - const char **e; - - for (e = default_if_driver_list; *e; e++) - if (fnmatch(*e, driver, 0) == 0) - state->use_default = true; - } else - state->use_default = true; - } + if (!state->use_default) + state->use_default = + wiphy_uses_default_if(state->wiphy); if (state->use_default) l_info("Wiphy %s will only use the default interface", diff --git a/src/wiphy.c b/src/wiphy.c index e2222887..4de6869d 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -67,6 +67,30 @@ static int mac_randomize_bytes = 6; static char regdom_country[2]; static uint32_t work_ids; +enum driver_flag { + DEFAULT_IF = 0x1, +}; + +struct driver_info { + const char *prefix; + unsigned int flags; +}; + +/* + * The out-of-tree rtl88x2bu crashes the kernel hard if default interface is + * destroyed. It seems many other drivers are built from the same source code + * so we set the DEFAULT_IF flag for all of them. Unfortunately there are + * in-tree drivers that also match these names and may be fine. + */ +static const struct driver_info driver_infos[] = { + { "rtl81*", DEFAULT_IF }, + { "rtl87*", DEFAULT_IF }, + { "rtl88*", DEFAULT_IF }, + { "rtw_*", DEFAULT_IF }, + { "brcmfmac", DEFAULT_IF }, + { "bcmsdh_sdmmc", DEFAULT_IF }, +}; + struct wiphy { uint32_t id; char name[20]; @@ -84,6 +108,7 @@ struct wiphy { char *model_str; char *vendor_str; char *driver_str; + const struct driver_info *driver_info; struct watchlist state_watches; uint8_t extended_capabilities[EXT_CAP_LEN + 2]; /* max bitmap size + IE header */ uint8_t *iftype_extended_capabilities[NUM_NL80211_IFTYPES]; @@ -512,6 +537,18 @@ const char *wiphy_get_name(struct wiphy *wiphy) return wiphy->name; } +bool wiphy_uses_default_if(struct wiphy *wiphy) +{ + if (!wiphy_get_driver(wiphy)) + return true; + + if (wiphy->driver_info && + wiphy->driver_info->flags & DEFAULT_IF) + return true; + + return false; +} + const uint8_t *wiphy_get_permanent_address(struct wiphy *wiphy) { return wiphy->permanent_addr; @@ -1340,6 +1377,7 @@ static bool wiphy_get_driver_name(struct wiphy *wiphy) L_AUTO_FREE_VAR(char *, driver_link) = NULL; char driver_path[256]; ssize_t len; + unsigned int i; driver_link = l_strdup_printf("/sys/class/ieee80211/%s/device/driver", wiphy->name); @@ -1352,6 +1390,11 @@ static bool wiphy_get_driver_name(struct wiphy *wiphy) driver_path[len] = '\0'; wiphy->driver_str = l_strdup(basename(driver_path)); + + for (i = 0; i < L_ARRAY_SIZE(driver_infos); i++) + if (!fnmatch(driver_infos[i].prefix, wiphy->driver_str, 0)) + wiphy->driver_info = &driver_infos[i]; + return true; } diff --git a/src/wiphy.h b/src/wiphy.h index c32fd21e..6efcd9ff 100644 --- a/src/wiphy.h +++ b/src/wiphy.h @@ -100,6 +100,7 @@ bool wiphy_supports_qos_set_map(struct wiphy *wiphy); bool wiphy_supports_firmware_roam(struct wiphy *wiphy); const char *wiphy_get_driver(struct wiphy *wiphy); const char *wiphy_get_name(struct wiphy *wiphy); +bool wiphy_uses_default_if(struct wiphy *wiphy); const uint8_t *wiphy_get_permanent_address(struct wiphy *wiphy); const uint8_t *wiphy_get_extended_capabilities(struct wiphy *wiphy, uint32_t iftype);