diff options
-rw-r--r-- | libnm-util/libnm-util.ver | 3 | ||||
-rw-r--r-- | libnm-util/nm-setting-wired.c | 102 | ||||
-rw-r--r-- | libnm-util/nm-setting-wired.h | 28 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/reader.c | 55 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/writer.c | 32 |
5 files changed, 220 insertions, 0 deletions
diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 60614d2e4a..0e94096ce1 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -518,9 +518,12 @@ global: nm_setting_wired_get_speed; nm_setting_wired_get_type; nm_setting_wired_get_valid_s390_options; + nm_setting_wired_get_wake_on_lan; + nm_setting_wired_get_wake_on_lan_password; nm_setting_wired_new; nm_setting_wired_remove_mac_blacklist_item; nm_setting_wired_remove_s390_option; + nm_setting_wired_wake_on_lan_get_type; nm_setting_wireless_add_mac_blacklist_item; nm_setting_wireless_add_seen_bssid; nm_setting_wireless_ap_security_compatible; diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index b9fc07df87..d3999869ad 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -84,6 +84,8 @@ typedef struct { GPtrArray *s390_subchannels; char *s390_nettype; GHashTable *s390_options; + NMSettingWiredWakeOnLan wol; + GByteArray *wol_password; } NMSettingWiredPrivate; enum { @@ -99,6 +101,8 @@ enum { PROP_S390_SUBCHANNELS, PROP_S390_NETTYPE, PROP_S390_OPTIONS, + PROP_WAKE_ON_LAN, + PROP_WAKE_ON_LAN_PASSWORD, LAST_PROP }; @@ -544,6 +548,44 @@ nm_setting_wired_get_valid_s390_options (NMSettingWired *setting) return valid_s390_opts; } +/** + * nm_setting_wired_get_wake_on_lan: + * @setting: the #NMSettingWired + * + * Returns the Wake-on-LAN setting + * + * Returns: the Wake-on-LAN setting + * + * Since: 0.9.10 + */ +NMSettingWiredWakeOnLan +nm_setting_wired_get_wake_on_lan (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->wol; +} + +/** + * nm_setting_wired_get_wake_on_lan_password: + * @setting: the #NMSettingWired + * + * Returns the Wake-on-LAN password. This only applies to + * %NM_SETTING_WIRED_WAKE_ON_MAGIC. + * + * Returns: the Wake-on-LAN setting password, or %NULL if there is no + * password. + * + * Since: 0.9.10 + */ +const GByteArray * +nm_setting_wired_get_wake_on_lan_password (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->wol_password; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -642,6 +684,15 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (priv->wol_password && (priv->wol & NM_SETTING_WIRED_WAKE_ON_MAGIC) == 0) { + g_set_error_literal (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + _("Wake-on-LAN password can only be used with magic packet mode")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD); + return FALSE; + } + return TRUE; } @@ -677,6 +728,9 @@ finalize (GObject *object) g_ptr_array_free (priv->s390_subchannels, TRUE); } + if (priv->wol_password) + g_byte_array_free (priv->wol_password, TRUE); + G_OBJECT_CLASS (nm_setting_wired_parent_class)->finalize (object); } @@ -743,6 +797,14 @@ set_property (GObject *object, guint prop_id, if (new_hash) g_hash_table_foreach (new_hash, copy_hash, priv->s390_options); break; + case PROP_WAKE_ON_LAN: + priv->wol = g_value_get_flags (value); + break; + case PROP_WAKE_ON_LAN_PASSWORD: + if (priv->wol_password) + g_byte_array_free (priv->wol_password, TRUE); + priv->wol_password = g_value_dup_boxed (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -790,6 +852,12 @@ get_property (GObject *object, guint prop_id, case PROP_S390_OPTIONS: g_value_set_boxed (value, priv->s390_options); break; + case PROP_WAKE_ON_LAN: + g_value_set_flags (value, priv->wol); + break; + case PROP_WAKE_ON_LAN_PASSWORD: + g_value_set_boxed (value, priv->wol_password); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1009,5 +1077,39 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) "'layer2', 'portname', 'protocol', among others.", DBUS_TYPE_G_MAP_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + + /** + * NMSettingWired:wake-on-lan: + * + * The Wake-on-LAN modes to use. Not all devices support all modes. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_WAKE_ON_LAN, + g_param_spec_flags (NM_SETTING_WIRED_WAKE_ON_LAN, + "Wake-on-LAN", + "The Wake-on-LAN modes to use. " + "Not all devices support all modes.", + NM_TYPE_SETTING_WIRED_WAKE_ON_LAN, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + + /** + * NMSettingWired:wake-on-lan-password: + * + * If specified, the password used with magic-packet-based Wake-on-LAN. + * If %NULL, no password will be required. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_WAKE_ON_LAN_PASSWORD, + _nm_param_spec_specialized (NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, + "Wake-on-LAN Password", + "If specified, the password used with " + "magic-packet-based Wake-on-LAN. " + "If %NULL, no password will be required.", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); } diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index 45bec73623..480d633844 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -55,6 +55,29 @@ typedef enum { #define NM_SETTING_WIRED_ERROR nm_setting_wired_error_quark () GQuark nm_setting_wired_error_quark (void); +/** + * NMSettingWiredWakeOnLan: + * @NM_SETTING_WIRED_WAKE_ON_PHY: Wake on PHY activity + * @NM_SETTING_WIRED_WAKE_ON_UNICAST: Wake on unicast messages + * @NM_SETTING_WIRED_WAKE_ON_MULTICAST: Wake on multicast messages + * @NM_SETTING_WIRED_WAKE_ON_BROADCAST: Wake on broadcast messages + * @NM_SETTING_WIRED_WAKE_ON_ARP: Wake on ARP + * @NM_SETTING_WIRED_WAKE_ON_MAGIC: Wake on magic packet + * + * Options for #NMSettingWired:wake-on-lan. Note that not all options + * are supported by all devices. + * + * Since: 0.9.10 + */ +typedef enum { + NM_SETTING_WIRED_WAKE_ON_PHY = (1 << 0), + NM_SETTING_WIRED_WAKE_ON_UNICAST = (1 << 1), + NM_SETTING_WIRED_WAKE_ON_MULTICAST = (1 << 2), + NM_SETTING_WIRED_WAKE_ON_BROADCAST = (1 << 3), + NM_SETTING_WIRED_WAKE_ON_ARP = (1 << 4), + NM_SETTING_WIRED_WAKE_ON_MAGIC = (1 << 5) +} NMSettingWiredWakeOnLan; + #define NM_SETTING_WIRED_PORT "port" #define NM_SETTING_WIRED_SPEED "speed" #define NM_SETTING_WIRED_DUPLEX "duplex" @@ -66,6 +89,8 @@ GQuark nm_setting_wired_error_quark (void); #define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels" #define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype" #define NM_SETTING_WIRED_S390_OPTIONS "s390-options" +#define NM_SETTING_WIRED_WAKE_ON_LAN "wake-on-lan" +#define NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD "wake-on-lan-password" typedef struct { NMSetting parent; @@ -119,6 +144,9 @@ gboolean nm_setting_wired_remove_s390_option (NMSettingWired *setting const char *key); const char ** nm_setting_wired_get_valid_s390_options (NMSettingWired *setting); +NMSettingWiredWakeOnLan nm_setting_wired_get_wake_on_lan (NMSettingWired *setting); +const GByteArray *nm_setting_wired_get_wake_on_lan_password (NMSettingWired *setting); + G_END_DECLS #endif /* NM_SETTING_WIRED_H */ diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 41055a2d2e..f021903564 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -3853,6 +3853,61 @@ make_wired_setting (shvarFile *ifcfg, g_free (value); } + value = svGetValue (ifcfg, "ETHTOOL_OPTS", FALSE); + if (value && strlen (value)) { + char **words, **iter, *flag; + NMSettingWiredWakeOnLan wol_flags = 0; + gboolean use_password = FALSE; + GByteArray *password; + + iter = words = g_strsplit_set (value, " ", 0); + if ( iter[0] && g_str_equal (iter[0], "wol") + && iter[1] && *iter[1]) { + for (flag = iter[1]; *flag; flag++) { + switch (*flag) { + case 'p': wol_flags |= NM_SETTING_WIRED_WAKE_ON_PHY; break; + case 'u': wol_flags |= NM_SETTING_WIRED_WAKE_ON_UNICAST; break; + case 'm': wol_flags |= NM_SETTING_WIRED_WAKE_ON_MULTICAST; break; + case 'b': wol_flags |= NM_SETTING_WIRED_WAKE_ON_BROADCAST; break; + case 'a': wol_flags |= NM_SETTING_WIRED_WAKE_ON_ARP; break; + case 'g': wol_flags |= NM_SETTING_WIRED_WAKE_ON_MAGIC; break; + case 's': use_password = TRUE; break; + case 'd': wol_flags = 0; break; + default: + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: unrecognized Wake-on-LAN option '%c'", *flag); + break; + } + } + if (!(wol_flags & NM_SETTING_WIRED_WAKE_ON_MAGIC)) + use_password = FALSE; + + g_object_set (s_wired, NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags, NULL); + iter += 2; + } + + if (iter[0] && g_str_equal (iter[0], "sopass") && iter[1]) { + if (use_password) { + if (nm_utils_hwaddr_valid (words[1])) { + password = nm_utils_hwaddr_atoba (words[1], ARPHRD_ETHER); + g_object_set (s_wired, NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, password, NULL); + g_byte_array_unref (password); + } else + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: Wake-on-LAN password '%s' is invalid", words[1]); + } else + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: Wake-on-LAN password not expected"); + iter += 2; + } + + if (iter[0]) { + char *leftover = g_strjoinv (" ", iter); + + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: unrecognized ETHTOOL_OPTIONS '%s'", leftover); + g_free (leftover); + } + g_strfreev (words); + } + g_free (value); + return (NMSetting *) s_wired; error: diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index ec1478f24b..ceea950da0 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -1019,6 +1019,8 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) const GPtrArray *s390_subchannels; GString *str; const GSList *macaddr_blacklist; + NMSettingWiredWakeOnLan wol; + const GByteArray *wol_password; s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) { @@ -1125,6 +1127,36 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) g_string_free (str, TRUE); } + svSetValue (ifcfg, "ETHTOOL_OPTS", NULL, FALSE); + wol = nm_setting_wired_get_wake_on_lan (s_wired); + wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired); + if (wol) { + str = g_string_sized_new (30); + g_string_append (str, "wol "); + if (wol & NM_SETTING_WIRED_WAKE_ON_PHY) + g_string_append_c (str, 'p'); + if (wol & NM_SETTING_WIRED_WAKE_ON_UNICAST) + g_string_append_c (str, 'u'); + if (wol & NM_SETTING_WIRED_WAKE_ON_MULTICAST) + g_string_append_c (str, 'm'); + if (wol & NM_SETTING_WIRED_WAKE_ON_BROADCAST) + g_string_append_c (str, 'b'); + if (wol & NM_SETTING_WIRED_WAKE_ON_ARP) + g_string_append_c (str, 'a'); + if (wol & NM_SETTING_WIRED_WAKE_ON_MAGIC) + g_string_append_c (str, 'g'); + + if (wol_password && (wol & NM_SETTING_WIRED_WAKE_ON_MAGIC)) { + g_string_append_printf (str, "s sopass %02X:%02X:%02X:%02X:%02X:%02X", + wol_password->data[0], wol_password->data[1], + wol_password->data[2], wol_password->data[3], + wol_password->data[4], wol_password->data[5]); + } + + svSetValue (ifcfg, "ETHTOOL_OPTS", str->str, FALSE); + g_string_free (str, TRUE); + } + svSetValue (ifcfg, "TYPE", TYPE_ETHERNET, FALSE); return TRUE; |