libnm: add generic.device-handler property

Add a new "generic.device-handler" property that specifies the name of
a dispatcher script to be invoked to add and delete the interface for
this connection.

(cherry picked from commit e686ab35b3)
This commit is contained in:
Beniamino Galvani 2023-09-18 18:35:26 +02:00 committed by Íñigo Huguet
parent 5dea7f068b
commit 9322c3e9db
10 changed files with 190 additions and 15 deletions

View File

@ -172,6 +172,35 @@
looking at file <filename>/run/NetworkManager/resolv.conf</filename>
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>device-add</varname></term>
<listitem>
<para>
This action is called when a connection of type <literal>generic</literal>
has the <literal>generic.device-handler</literal> property set. The property
indicates the name of a dispatcher script to be executed in directory
<filename>/{etc,usr/lib}/NetworkManager/dispatcher.d/device</filename>. Note
that differently from other actions, only one script is executed.
</para>
<para>
The script needs to perform any action needed to create the device
for the generic connection. On successful termination, the script
returns zero. Otherwise, it returns a non-zero value to indicate an
error.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>device-delete</varname></term>
<listitem>
<para>
This action is the counterpart of <literal>device-add</literal> and
is called to delete the device for a generic connection. All the
aspects described for <literal>device-add</literal> also apply to
this action.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The environment contains more information about the interface and the connection.

View File

@ -1959,6 +1959,7 @@ global:
nm_setting_connection_get_autoconnect_ports;
nm_setting_connection_get_controller;
nm_setting_connection_get_port_type;
nm_setting_generic_get_device_handler;
nm_setting_get_enum_property_type;
nm_setting_hsr_get_multicast_spec;
nm_setting_hsr_get_port1;

View File

@ -1331,6 +1331,10 @@
<setting name="generic"
gtype="NMSettingGeneric"
>
<property name="device-handler"
dbus-type="s"
gprop-type="gchararray"
/>
</setting>
<setting name="gsm"
gtype="NMSettingGsm"

View File

@ -23,13 +23,20 @@
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE(NMSettingGeneric, PROP_DEVICE_HANDLER, );
typedef struct {
char *device_handler;
} NMSettingGenericPrivate;
/**
* NMSettingGeneric:
*
* Generic Link Settings
*/
struct _NMSettingGeneric {
NMSetting parent;
NMSetting parent;
NMSettingGenericPrivate _priv;
};
struct _NMSettingGenericClass {
@ -38,6 +45,82 @@ struct _NMSettingGenericClass {
G_DEFINE_TYPE(NMSettingGeneric, nm_setting_generic, NM_TYPE_SETTING)
#define NM_SETTING_GENERIC_GET_PRIVATE(self) \
_NM_GET_PRIVATE(self, NMSettingGeneric, NM_IS_SETTING_GENERIC, NMSetting)
/*****************************************************************************/
/**
* nm_setting_generic_get_device_handler:
* @setting: the #NMSettingGeneric
*
* Returns the #NMSettingGeneric:device-handler property of the connection.
*
* Returns: the device handler name, or %NULL if no device handler is set
*
* Since: 1.46
**/
const char *
nm_setting_generic_get_device_handler(NMSettingGeneric *setting)
{
g_return_val_if_fail(NM_IS_SETTING_GENERIC(setting), NULL);
return NM_SETTING_GENERIC_GET_PRIVATE(setting)->device_handler;
}
static gboolean
verify(NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingGenericPrivate *priv = NM_SETTING_GENERIC_GET_PRIVATE(setting);
if (priv->device_handler) {
if (NM_IN_SET(priv->device_handler[0], '\0', '.')
|| !NM_STRCHAR_ALL(priv->device_handler,
ch,
g_ascii_isalnum(ch) || NM_IN_SET(ch, '-', '_', '.'))) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("property is invalid"));
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_GENERIC_SETTING_NAME,
NM_SETTING_GENERIC_DEVICE_HANDLER);
return FALSE;
}
if (connection) {
NMSettingConnection *s_con;
s_con = nm_connection_get_setting_connection(connection);
if (!s_con) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("missing setting"));
g_prefix_error(error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME);
return FALSE;
}
if (!nm_setting_connection_get_interface_name(s_con)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("the property is required when %s.%s is set"),
NM_SETTING_GENERIC_SETTING_NAME,
NM_SETTING_GENERIC_DEVICE_HANDLER);
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_INTERFACE_NAME);
return FALSE;
}
}
}
return TRUE;
}
/*****************************************************************************/
static void
@ -60,7 +143,46 @@ nm_setting_generic_new(void)
static void
nm_setting_generic_class_init(NMSettingGenericClass *klass)
{
NMSettingClass *setting_class = NM_SETTING_CLASS(klass);
GObjectClass *object_class = G_OBJECT_CLASS(klass);
NMSettingClass *setting_class = NM_SETTING_CLASS(klass);
GArray *properties_override = _nm_sett_info_property_override_create_array();
_nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_GENERIC, NULL, NULL, 0);
object_class->get_property = _nm_setting_property_get_property_direct;
object_class->set_property = _nm_setting_property_set_property_direct;
setting_class->verify = verify;
/**
* NMSettingGeneric:device-handler:
*
* Name of the device handler that will be invoked to add and delete
* the device for this connection. The name can only contain ASCII
* alphanumeric characters and '-', '_', '.'. It cannot start with '.'.
*
* See the NetworkManager-dispatcher(8) man page for more details
* about how to write the device handler.
*
* By setting this property the generic connection becomes "virtual",
* meaning that it can be activated without an existing device; the device
* will be created at the time the connection is started by invoking the
* device-handler.
*
* Since: 1.46
**/
_nm_setting_property_define_direct_string(properties_override,
obj_properties,
NM_SETTING_GENERIC_DEVICE_HANDLER,
PROP_DEVICE_HANDLER,
NM_SETTING_PARAM_FUZZY_IGNORE
| NM_SETTING_PARAM_INFERRABLE,
NMSettingGeneric,
_priv.device_handler);
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit(setting_class,
NM_META_SETTING_TYPE_GENERIC,
NULL,
properties_override,
0);
}

View File

@ -27,12 +27,17 @@ G_BEGIN_DECLS
#define NM_SETTING_GENERIC_SETTING_NAME "generic"
#define NM_SETTING_GENERIC_DEVICE_HANDLER "device-handler"
typedef struct _NMSettingGenericClass NMSettingGenericClass;
GType nm_setting_generic_get_type(void);
NMSetting *nm_setting_generic_new(void);
NM_AVAILABLE_IN_1_46
const char *nm_setting_generic_get_device_handler(NMSettingGeneric *setting);
G_END_DECLS
#endif /* __NM_SETTING_GENERIC_H__ */

View File

@ -5985,6 +5985,15 @@ static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = {
NULL,
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_GENERIC
static const NMMetaPropertyInfo *const property_infos_GENERIC[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_GENERIC_DEVICE_HANDLER,
.property_type = &_pt_gobject_string,
),
NULL
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_GSM
static const NMMetaPropertyInfo *const property_infos_GSM[] = {
@ -8782,7 +8791,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO_EMPTY (GENERIC,
SETTING_INFO (GENERIC,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (GENERIC, TRUE),

View File

@ -140,6 +140,7 @@
#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_GROUP_ID N_("An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the Priority Group ID. Allowed Priority Group ID values are 0 - 7 or 15 for the unrestricted group.")
#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH N_("An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the priority may use all of the bandwidth allocated to its assigned group.")
#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS N_("An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the traffic class (0 - 7) to which the priority is mapped.")
#define DESCRIBE_DOC_NM_SETTING_GENERIC_DEVICE_HANDLER N_("Name of the device handler that will be invoked to add and delete the device for this connection. The name can only contain ASCII alphanumeric characters and '-', '_', '.'. It cannot start with '.'. See the NetworkManager-dispatcher(8) man page for more details about how to write the device handler. By setting this property the generic connection becomes \"virtual\", meaning that it can be activated without an existing device; the device will be created at the time the connection is started by invoking the device-handler.")
#define DESCRIBE_DOC_NM_SETTING_GSM_APN N_("The GPRS Access Point Name specifying the APN used when establishing a data session with the GSM-based network. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider-specific walled-garden, so it is important to use the correct APN for the user's mobile broadband plan. The APN may only be composed of the characters a-z, 0-9, ., and - per GSM 03.60 Section 14.9. If the APN is unset (the default) then it may be detected based on \"auto-config\" setting. The property can be explicitly set to the empty string to prevent that and use no APN.")
#define DESCRIBE_DOC_NM_SETTING_GSM_AUTO_CONFIG N_("When TRUE, the settings such as APN, username, or password will default to values that match the network the modem will register to in the Mobile Broadband Provider database.")
#define DESCRIBE_DOC_NM_SETTING_GSM_DEVICE_ID N_("The device unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will only apply to the specified device.")

View File

@ -416,10 +416,10 @@ script_watch_cb(GPid pid, int status, gpointer user_data)
}
if (script->result == DISPATCH_RESULT_SUCCESS) {
_LOG_S_T(script, "complete");
_LOG_S_T(script, "complete: process succeeded");
} else {
script->result = DISPATCH_RESULT_FAILED;
_LOG_S_W(script, "complete: failed with %s", script->error);
_LOG_S_W(script, "complete: process failed with %s", script->error);
}
g_spawn_close_pid(script->pid);

View File

@ -1066,15 +1066,16 @@ const NmcMetaGenericInfo
"," NM_SETTING_TEAM_SETTING_NAME "," NM_SETTING_TEAM_PORT_SETTING_NAME \
"," NM_SETTING_OVS_BRIDGE_SETTING_NAME "," NM_SETTING_OVS_INTERFACE_SETTING_NAME \
"," NM_SETTING_OVS_PATCH_SETTING_NAME "," NM_SETTING_OVS_PORT_SETTING_NAME \
"," NM_SETTING_DCB_SETTING_NAME "," NM_SETTING_TUN_SETTING_NAME \
"," NM_SETTING_IP_TUNNEL_SETTING_NAME "," NM_SETTING_MACSEC_SETTING_NAME \
"," NM_SETTING_MACVLAN_SETTING_NAME "," NM_SETTING_VXLAN_SETTING_NAME \
"," NM_SETTING_VRF_SETTING_NAME "," NM_SETTING_WPAN_SETTING_NAME \
"," NM_SETTING_6LOWPAN_SETTING_NAME "," NM_SETTING_WIREGUARD_SETTING_NAME \
"," NM_SETTING_LINK_SETTING_NAME "," NM_SETTING_PROXY_SETTING_NAME \
"," NM_SETTING_TC_CONFIG_SETTING_NAME "," NM_SETTING_SRIOV_SETTING_NAME \
"," NM_SETTING_ETHTOOL_SETTING_NAME "," NM_SETTING_OVS_DPDK_SETTING_NAME \
"," NM_SETTING_HOSTNAME_SETTING_NAME "," NM_SETTING_HSR_SETTING_NAME
"," NM_SETTING_GENERIC_SETTING_NAME "," NM_SETTING_DCB_SETTING_NAME \
"," NM_SETTING_TUN_SETTING_NAME "," NM_SETTING_IP_TUNNEL_SETTING_NAME \
"," NM_SETTING_MACSEC_SETTING_NAME "," NM_SETTING_MACVLAN_SETTING_NAME \
"," NM_SETTING_VXLAN_SETTING_NAME "," NM_SETTING_VRF_SETTING_NAME \
"," NM_SETTING_WPAN_SETTING_NAME "," NM_SETTING_6LOWPAN_SETTING_NAME \
"," NM_SETTING_WIREGUARD_SETTING_NAME "," NM_SETTING_LINK_SETTING_NAME \
"," NM_SETTING_PROXY_SETTING_NAME "," NM_SETTING_TC_CONFIG_SETTING_NAME \
"," NM_SETTING_SRIOV_SETTING_NAME "," NM_SETTING_ETHTOOL_SETTING_NAME \
"," NM_SETTING_OVS_DPDK_SETTING_NAME "," NM_SETTING_HOSTNAME_SETTING_NAME \
"," NM_SETTING_HSR_SETTING_NAME
/* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */
const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = {

View File

@ -1070,6 +1070,9 @@
values="0 - 4294967295" />
</setting>
<setting name="generic" >
<property name="device-handler"
nmcli-description="Name of the device handler that will be invoked to add and delete the device for this connection. The name can only contain ASCII alphanumeric characters and &apos;-&apos;, &apos;_&apos;, &apos;.&apos;. It cannot start with &apos;.&apos;. See the NetworkManager-dispatcher(8) man page for more details about how to write the device handler. By setting this property the generic connection becomes &quot;virtual&quot;, meaning that it can be activated without an existing device; the device will be created at the time the connection is started by invoking the device-handler."
format="string" />
</setting>
<setting name="gsm" >
<property name="auto-config"