diff --git a/man/NetworkManager-dispatcher.xml b/man/NetworkManager-dispatcher.xml index e0c9b572d7..8d7f0c59ba 100644 --- a/man/NetworkManager-dispatcher.xml +++ b/man/NetworkManager-dispatcher.xml @@ -172,6 +172,35 @@ looking at file /run/NetworkManager/resolv.conf + + device-add + + + This action is called when a connection of type generic + has the generic.device-handler property set. The property + indicates the name of a dispatcher script to be executed in directory + /{etc,usr/lib}/NetworkManager/dispatcher.d/device. Note + that differently from other actions, only one script is executed. + + + 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. + + + + + device-delete + + + This action is the counterpart of device-add and + is called to delete the device for a generic connection. All the + aspects described for device-add also apply to + this action. + + + The environment contains more information about the interface and the connection. diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index 0655d2dea4..5442377ae6 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -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; diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in index 57337c6069..146f92829e 100644 --- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in +++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in @@ -1331,6 +1331,10 @@ + 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); } diff --git a/src/libnm-core-public/nm-setting-generic.h b/src/libnm-core-public/nm-setting-generic.h index 9bdcd11d5f..d735513ffc 100644 --- a/src/libnm-core-public/nm-setting-generic.h +++ b/src/libnm-core-public/nm-setting-generic.h @@ -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__ */ diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c index 16cc003a93..2871ccb6b0 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.c +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -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), diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in index d56a3d8ab5..c40141669e 100644 --- a/src/libnmc-setting/settings-docs.h.in +++ b/src/libnmc-setting/settings-docs.h.in @@ -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.") diff --git a/src/nm-dispatcher/nm-dispatcher.c b/src/nm-dispatcher/nm-dispatcher.c index 28ac51bf07..86277931df 100644 --- a/src/nm-dispatcher/nm-dispatcher.c +++ b/src/nm-dispatcher/nm-dispatcher.c @@ -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); diff --git a/src/nmcli/connections.c b/src/nmcli/connections.c index ac2a53c5ba..72a1fc1897 100644 --- a/src/nmcli/connections.c +++ b/src/nmcli/connections.c @@ -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[] = { diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in index 2c71865fca..160ae32f8c 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in @@ -1070,6 +1070,9 @@ values="0 - 4294967295" /> +