filter: new plugin whitelist logic
Several plugins define specific udev tags that must be available in the device in order for the plugins to use them. Let's use these tags as a direct indication that ModemManager can probe the devices. In particular, this change would make all Ericsson MBM modems probed right away also in STRICT filter mode, without needing to check the ttyACM interface type or the available net ports.
This commit is contained in:
@@ -34,11 +34,24 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct _MMFilterPrivate {
|
struct _MMFilterPrivate {
|
||||||
MMFilterRule enabled_rules;
|
MMFilterRule enabled_rules;
|
||||||
|
GList *plugin_whitelist_tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_filter_register_plugin_whitelist_tag (MMFilter *self,
|
||||||
|
const gchar *tag)
|
||||||
|
{
|
||||||
|
if (!g_list_find_custom (self->priv->plugin_whitelist_tags, tag, (GCompareFunc) g_strcmp0)) {
|
||||||
|
mm_dbg ("[filter] registered plugin whitelist tag: %s", tag);
|
||||||
|
self->priv->plugin_whitelist_tags = g_list_prepend (self->priv->plugin_whitelist_tags, g_strdup (tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
mm_filter_port (MMFilter *self,
|
mm_filter_port (MMFilter *self,
|
||||||
MMKernelDevice *port,
|
MMKernelDevice *port,
|
||||||
@@ -67,6 +80,19 @@ mm_filter_port (MMFilter *self,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the device is whitelisted by a plugin, we allow it. */
|
||||||
|
if (self->priv->enabled_rules & MM_FILTER_RULE_PLUGIN_WHITELIST) {
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = self->priv->plugin_whitelist_tags; l; l = g_list_next (l)) {
|
||||||
|
if (mm_kernel_device_get_global_property_as_boolean (port, (const gchar *)(l->data)) ||
|
||||||
|
mm_kernel_device_get_property_as_boolean (port, (const gchar *)(l->data))) {
|
||||||
|
mm_dbg ("[filter] (%s/%s) port allowed: device is whitelisted by plugin", subsystem, name);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If this is a virtual device, don't allow it */
|
/* If this is a virtual device, don't allow it */
|
||||||
if ((self->priv->enabled_rules & MM_FILTER_RULE_VIRTUAL) &&
|
if ((self->priv->enabled_rules & MM_FILTER_RULE_VIRTUAL) &&
|
||||||
(!mm_kernel_device_get_physdev_sysfs_path (port))) {
|
(!mm_kernel_device_get_physdev_sysfs_path (port))) {
|
||||||
@@ -258,6 +284,15 @@ filter_rule_env_process (MMFilterRule enabled_rules)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mm_filter_check_rule_enabled (MMFilter *self,
|
||||||
|
MMFilterRule rule)
|
||||||
|
{
|
||||||
|
return !!(self->priv->enabled_rules & rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
/* If TTY rule enabled, either DEFAULT_ALLOWED or DEFAULT_FORBIDDEN must be set. */
|
/* If TTY rule enabled, either DEFAULT_ALLOWED or DEFAULT_FORBIDDEN must be set. */
|
||||||
#define VALIDATE_RULE_TTY(rules) (!(rules & MM_FILTER_RULE_TTY) || \
|
#define VALIDATE_RULE_TTY(rules) (!(rules & MM_FILTER_RULE_TTY) || \
|
||||||
((rules & (MM_FILTER_RULE_TTY_DEFAULT_ALLOWED | MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN)) && \
|
((rules & (MM_FILTER_RULE_TTY_DEFAULT_ALLOWED | MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN)) && \
|
||||||
@@ -289,6 +324,7 @@ mm_filter_new (MMFilterRule enabled_rules,
|
|||||||
mm_dbg ("[filter] created");
|
mm_dbg ("[filter] created");
|
||||||
mm_dbg ("[filter] explicit whitelist: %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_WHITELIST));
|
mm_dbg ("[filter] explicit whitelist: %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_WHITELIST));
|
||||||
mm_dbg ("[filter] explicit blacklist: %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_BLACKLIST));
|
mm_dbg ("[filter] explicit blacklist: %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_BLACKLIST));
|
||||||
|
mm_dbg ("[filter] plugin whitelist: %s", RULE_ENABLED_STR (MM_FILTER_RULE_PLUGIN_WHITELIST));
|
||||||
mm_dbg ("[filter] virtual devices forbidden: %s", RULE_ENABLED_STR (MM_FILTER_RULE_VIRTUAL));
|
mm_dbg ("[filter] virtual devices forbidden: %s", RULE_ENABLED_STR (MM_FILTER_RULE_VIRTUAL));
|
||||||
mm_dbg ("[filter] net devices allowed: %s", RULE_ENABLED_STR (MM_FILTER_RULE_NET));
|
mm_dbg ("[filter] net devices allowed: %s", RULE_ENABLED_STR (MM_FILTER_RULE_NET));
|
||||||
mm_dbg ("[filter] cdc-wdm devices allowed: %s", RULE_ENABLED_STR (MM_FILTER_RULE_CDC_WDM));
|
mm_dbg ("[filter] cdc-wdm devices allowed: %s", RULE_ENABLED_STR (MM_FILTER_RULE_CDC_WDM));
|
||||||
@@ -356,6 +392,16 @@ mm_filter_init (MMFilter *self)
|
|||||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_FILTER, MMFilterPrivate);
|
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_FILTER, MMFilterPrivate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MMFilter *self = MM_FILTER (object);
|
||||||
|
|
||||||
|
g_list_free_full (self->priv->plugin_whitelist_tags, g_free);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (mm_filter_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mm_filter_class_init (MMFilterClass *klass)
|
mm_filter_class_init (MMFilterClass *klass)
|
||||||
{
|
{
|
||||||
@@ -366,6 +412,7 @@ mm_filter_class_init (MMFilterClass *klass)
|
|||||||
/* Virtual methods */
|
/* Virtual methods */
|
||||||
object_class->set_property = set_property;
|
object_class->set_property = set_property;
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
|
object_class->finalize = finalize;
|
||||||
|
|
||||||
g_object_class_install_property (
|
g_object_class_install_property (
|
||||||
object_class, PROP_ENABLED_RULES,
|
object_class, PROP_ENABLED_RULES,
|
||||||
|
@@ -48,23 +48,25 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/
|
|||||||
MM_FILTER_RULE_NONE = 0,
|
MM_FILTER_RULE_NONE = 0,
|
||||||
MM_FILTER_RULE_EXPLICIT_WHITELIST = 1 << 0,
|
MM_FILTER_RULE_EXPLICIT_WHITELIST = 1 << 0,
|
||||||
MM_FILTER_RULE_EXPLICIT_BLACKLIST = 1 << 1,
|
MM_FILTER_RULE_EXPLICIT_BLACKLIST = 1 << 1,
|
||||||
MM_FILTER_RULE_VIRTUAL = 1 << 2,
|
MM_FILTER_RULE_PLUGIN_WHITELIST = 1 << 2,
|
||||||
MM_FILTER_RULE_NET = 1 << 3,
|
MM_FILTER_RULE_VIRTUAL = 1 << 3,
|
||||||
MM_FILTER_RULE_CDC_WDM = 1 << 4,
|
MM_FILTER_RULE_NET = 1 << 4,
|
||||||
MM_FILTER_RULE_TTY = 1 << 5,
|
MM_FILTER_RULE_CDC_WDM = 1 << 5,
|
||||||
MM_FILTER_RULE_TTY_BLACKLIST = 1 << 6,
|
MM_FILTER_RULE_TTY = 1 << 6,
|
||||||
MM_FILTER_RULE_TTY_MANUAL_SCAN_ONLY = 1 << 7,
|
MM_FILTER_RULE_TTY_BLACKLIST = 1 << 7,
|
||||||
MM_FILTER_RULE_TTY_PLATFORM_DRIVER = 1 << 8,
|
MM_FILTER_RULE_TTY_MANUAL_SCAN_ONLY = 1 << 8,
|
||||||
MM_FILTER_RULE_TTY_DEFAULT_ALLOWED = 1 << 9,
|
MM_FILTER_RULE_TTY_PLATFORM_DRIVER = 1 << 9,
|
||||||
MM_FILTER_RULE_TTY_DRIVER = 1 << 10,
|
MM_FILTER_RULE_TTY_DEFAULT_ALLOWED = 1 << 10,
|
||||||
MM_FILTER_RULE_TTY_ACM_INTERFACE = 1 << 11,
|
MM_FILTER_RULE_TTY_DRIVER = 1 << 11,
|
||||||
MM_FILTER_RULE_TTY_WITH_NET = 1 << 12,
|
MM_FILTER_RULE_TTY_ACM_INTERFACE = 1 << 12,
|
||||||
MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN = 1 << 13,
|
MM_FILTER_RULE_TTY_WITH_NET = 1 << 13,
|
||||||
|
MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN = 1 << 14,
|
||||||
} MMFilterRule;
|
} MMFilterRule;
|
||||||
|
|
||||||
#define MM_FILTER_RULE_ALL \
|
#define MM_FILTER_RULE_ALL \
|
||||||
(MM_FILTER_RULE_EXPLICIT_WHITELIST | \
|
(MM_FILTER_RULE_EXPLICIT_WHITELIST | \
|
||||||
MM_FILTER_RULE_EXPLICIT_BLACKLIST | \
|
MM_FILTER_RULE_EXPLICIT_BLACKLIST | \
|
||||||
|
MM_FILTER_RULE_PLUGIN_WHITELIST | \
|
||||||
MM_FILTER_RULE_VIRTUAL | \
|
MM_FILTER_RULE_VIRTUAL | \
|
||||||
MM_FILTER_RULE_NET | \
|
MM_FILTER_RULE_NET | \
|
||||||
MM_FILTER_RULE_CDC_WDM | \
|
MM_FILTER_RULE_CDC_WDM | \
|
||||||
@@ -97,6 +99,7 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/
|
|||||||
#define MM_FILTER_POLICY_STRICT \
|
#define MM_FILTER_POLICY_STRICT \
|
||||||
(MM_FILTER_RULE_EXPLICIT_WHITELIST | \
|
(MM_FILTER_RULE_EXPLICIT_WHITELIST | \
|
||||||
MM_FILTER_RULE_EXPLICIT_BLACKLIST | \
|
MM_FILTER_RULE_EXPLICIT_BLACKLIST | \
|
||||||
|
MM_FILTER_RULE_PLUGIN_WHITELIST | \
|
||||||
MM_FILTER_RULE_VIRTUAL | \
|
MM_FILTER_RULE_VIRTUAL | \
|
||||||
MM_FILTER_RULE_NET | \
|
MM_FILTER_RULE_NET | \
|
||||||
MM_FILTER_RULE_CDC_WDM | \
|
MM_FILTER_RULE_CDC_WDM | \
|
||||||
@@ -112,6 +115,7 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/
|
|||||||
#define MM_FILTER_POLICY_PARANOID \
|
#define MM_FILTER_POLICY_PARANOID \
|
||||||
(MM_FILTER_RULE_EXPLICIT_WHITELIST | \
|
(MM_FILTER_RULE_EXPLICIT_WHITELIST | \
|
||||||
MM_FILTER_RULE_EXPLICIT_BLACKLIST | \
|
MM_FILTER_RULE_EXPLICIT_BLACKLIST | \
|
||||||
|
MM_FILTER_RULE_PLUGIN_WHITELIST | \
|
||||||
MM_FILTER_RULE_VIRTUAL | \
|
MM_FILTER_RULE_VIRTUAL | \
|
||||||
MM_FILTER_RULE_NET | \
|
MM_FILTER_RULE_NET | \
|
||||||
MM_FILTER_RULE_CDC_WDM | \
|
MM_FILTER_RULE_CDC_WDM | \
|
||||||
@@ -139,4 +143,10 @@ gboolean mm_filter_device_and_port (MMFilter *self,
|
|||||||
MMDevice *device,
|
MMDevice *device,
|
||||||
MMKernelDevice *port);
|
MMKernelDevice *port);
|
||||||
|
|
||||||
|
void mm_filter_register_plugin_whitelist_tag (MMFilter *self,
|
||||||
|
const gchar *tag);
|
||||||
|
|
||||||
|
gboolean mm_filter_check_rule_enabled (MMFilter *self,
|
||||||
|
MMFilterRule rule);
|
||||||
|
|
||||||
#endif /* MM_FILTER_H */
|
#endif /* MM_FILTER_H */
|
||||||
|
@@ -1496,6 +1496,21 @@ mm_plugin_manager_peek_plugin (MMPluginManager *self,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
register_plugin_whitelist_tags (MMPluginManager *self,
|
||||||
|
MMPlugin *plugin)
|
||||||
|
{
|
||||||
|
const gchar **tags;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (!mm_filter_check_rule_enabled (self->priv->filter, MM_FILTER_RULE_PLUGIN_WHITELIST))
|
||||||
|
return;
|
||||||
|
|
||||||
|
tags = mm_plugin_get_allowed_udev_tags (plugin);
|
||||||
|
for (i = 0; tags && tags[i]; i++)
|
||||||
|
mm_filter_register_plugin_whitelist_tag (self->priv->filter, tags[i]);
|
||||||
|
}
|
||||||
|
|
||||||
static MMPlugin *
|
static MMPlugin *
|
||||||
load_plugin (const gchar *path)
|
load_plugin (const gchar *path)
|
||||||
{
|
{
|
||||||
@@ -1609,6 +1624,9 @@ load_plugins (MMPluginManager *self,
|
|||||||
else
|
else
|
||||||
/* Vendor specific plugin */
|
/* Vendor specific plugin */
|
||||||
self->priv->plugins = g_list_append (self->priv->plugins, plugin);
|
self->priv->plugins = g_list_append (self->priv->plugins, plugin);
|
||||||
|
|
||||||
|
/* Register plugin whitelist tags in filter, if any */
|
||||||
|
register_plugin_whitelist_tags (self, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the generic plugin once all looped */
|
/* Check the generic plugin once all looped */
|
||||||
|
@@ -141,6 +141,12 @@ mm_plugin_get_name (MMPlugin *self)
|
|||||||
return self->priv->name;
|
return self->priv->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const gchar **
|
||||||
|
mm_plugin_get_allowed_udev_tags (MMPlugin *self)
|
||||||
|
{
|
||||||
|
return (const gchar **) self->priv->udev_tags;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@@ -124,7 +124,8 @@ struct _MMPluginClass {
|
|||||||
|
|
||||||
GType mm_plugin_get_type (void);
|
GType mm_plugin_get_type (void);
|
||||||
|
|
||||||
const gchar *mm_plugin_get_name (MMPlugin *self);
|
const gchar *mm_plugin_get_name (MMPlugin *self);
|
||||||
|
const gchar **mm_plugin_get_allowed_udev_tags (MMPlugin *self);
|
||||||
|
|
||||||
/* This method will run all pre-probing filters, to see if we can discard this
|
/* This method will run all pre-probing filters, to see if we can discard this
|
||||||
* plugin from the probing logic as soon as possible. */
|
* plugin from the probing logic as soon as possible. */
|
||||||
|
Reference in New Issue
Block a user