summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-05-12 11:55:52 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-07-24 14:02:59 +0200
commit2e0d0bc050b44afaeb017cc30ac409c743b9b171 (patch)
tree04ace55551a8c139dc04611213bf29f97f054c85
parent5622461c04d16ef80187ffdcf8b902ce95549273 (diff)
downloadNetworkManager-2e0d0bc050b44afaeb017cc30ac409c743b9b171.tar.gz
ifcfg-rh: add support for Wake-on-LAN ethtool options
Based on branch danw/wip/ethtool by Dan Winship <danw@redhat.com>
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c78
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am3
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-wake-on-lan22
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c123
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c30
5 files changed, 255 insertions, 1 deletions
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index 6d61ec9cfd..ee407ea126 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -3547,6 +3547,80 @@ wireless_connection_from_ifcfg (const char *file,
return connection;
}
+static void
+parse_ethtool_options (shvarFile *ifcfg, NMSettingWired *s_wired, char *value)
+{
+ NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE;
+ gboolean use_password = FALSE;
+ char **words, **iter, *flag;
+
+ if (!value || !value[0])
+ return;
+
+ words = g_strsplit_set (value, " ", 0);
+ iter = words;
+
+ while (iter[0]) {
+ if (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_LAN_PHY;
+ break;
+ case 'u':
+ wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST;
+ break;
+ case 'm':
+ wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST;
+ break;
+ case 'b':
+ wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST;
+ break;
+ case 'a':
+ wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_ARP;
+ break;
+ case 'g':
+ wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC;
+ break;
+ case 's':
+ use_password = TRUE;
+ break;
+ case 'd':
+ wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE;
+ use_password = FALSE;
+ break;
+ default:
+ PARSE_WARNING ("unrecognized Wake-on-LAN option '%c'", *flag);
+ }
+ }
+
+ if (!NM_FLAGS_HAS (wol_flags, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC))
+ use_password = FALSE;
+
+ g_object_set (s_wired, NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags, NULL);
+ iter += 2;
+ continue;
+ }
+
+ if (g_str_equal (iter[0], "sopass") && iter[1] && *iter[1]) {
+ if (use_password) {
+ if (nm_utils_hwaddr_valid (iter[1], ETH_ALEN))
+ g_object_set (s_wired, NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, iter[1], NULL);
+ else
+ PARSE_WARNING ("Wake-on-LAN password '%s' is invalid", iter[1]);
+ } else
+ PARSE_WARNING ("Wake-on-LAN password not expected");
+ iter += 2;
+ continue;
+ }
+
+ /* Silently skip unknown options */
+ iter++;
+ }
+
+ g_strfreev (words);
+}
+
static NMSetting *
make_wired_setting (shvarFile *ifcfg,
const char *file,
@@ -3682,6 +3756,10 @@ make_wired_setting (shvarFile *ifcfg,
g_free (value);
}
+ value = svGetValue (ifcfg, "ETHTOOL_OPTS", FALSE);
+ parse_ethtool_options (ifcfg, s_wired, value);
+ g_free (value);
+
return (NMSetting *) s_wired;
error:
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
index 6e1fac9f5d..e133f8d340 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
@@ -124,7 +124,8 @@ EXTRA_DIST = \
ifcfg-test-team-port \
ifcfg-test-team-port-empty-config \
ifcfg-test-vlan-trailing-spaces \
- ifcfg-test-dns-options
+ ifcfg-test-dns-options \
+ ifcfg-test-wired-wake-on-lan
# make target dependencies can't have colons in their names, which ends up
# meaning that we can't add the alias files to EXTRA_DIST
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-wake-on-lan b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-wake-on-lan
new file mode 100644
index 0000000000..1dfc9a4331
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-wake-on-lan
@@ -0,0 +1,22 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+NETMASK=255.255.255.0
+GATEWAY=192.168.1.1
+IPV6INIT=yes
+IPV6_AUTOCONF=no
+IPV6ADDR=dead:beaf::1
+IPV6ADDR_SECONDARIES="dead:beaf::2/56"
+DNS3=1:2:3:4::a
+DNS4=1:2:3:4::b
+RES_OPTIONS=
+ETHTOOL_OPTS="speed 100 duplex full wol apgs sopass 00:11:22:33:44:55 autoneg off"
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index d541cd6151..14473ffbc5 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -5273,6 +5273,43 @@ test_read_wifi_wep_eap_ttls_chap (void)
}
static void
+test_read_wired_wake_on_lan (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ gboolean success;
+ GError *error = NULL;
+
+ connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-wake-on-lan",
+ NULL, TYPE_WIRELESS, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (connection);
+
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ s_con = nm_connection_get_setting_connection (connection);
+ g_assert (s_con);
+ g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME);
+
+ s_wired = nm_connection_get_setting_wired (connection);
+ g_assert (s_wired);
+ g_assert_cmpint (nm_setting_wired_get_wake_on_lan (s_wired),
+ ==,
+ NM_SETTING_WIRED_WAKE_ON_LAN_ARP |
+ NM_SETTING_WIRED_WAKE_ON_LAN_PHY |
+ NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC);
+
+ g_assert_cmpstr (nm_setting_wired_get_wake_on_lan_password (s_wired),
+ ==,
+ "00:11:22:33:44:55");
+
+ g_object_unref (connection);
+}
+
+static void
test_read_wifi_hidden (void)
{
NMConnection *connection;
@@ -5387,6 +5424,90 @@ test_write_wifi_hidden (void)
}
static void
+test_write_wired_wake_on_lan (void)
+{
+ NMConnection *connection, *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingWiredWakeOnLan wol;
+ char *uuid, *testfile = NULL, *val;
+ gboolean success;
+ GError *error = NULL;
+ shvarFile *f;
+
+ connection = nm_simple_connection_new ();
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired Wake-on-LAN",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ wol = NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST |
+ NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST |
+ NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC;
+
+ g_object_set (s_wired,
+ NM_SETTING_WIRED_WAKE_ON_LAN, wol,
+ NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, "00:00:00:11:22:33",
+ NULL);
+
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ f = svOpenFile (testfile, &error);
+ g_assert_no_error (error);
+ g_assert (f);
+
+ /* re-read the file to check that the key was written. */
+ val = svGetValue (f, "ETHTOOL_OPTS", FALSE);
+ g_assert (val);
+ g_assert (strstr (val, "wol"));
+ g_assert (strstr (val, "sopass 00:00:00:11:22:33"));
+ g_free (val);
+ svCloseFile (f);
+
+ /* reread will be normalized, so we must normalize connection too. */
+ nm_connection_normalize (connection, NULL, NULL, NULL);
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file_test (testfile, NULL, TYPE_ETHERNET,
+ NULL, &error);
+ unlink (testfile);
+ g_assert_no_error (error);
+ g_assert (reread);
+
+ success = nm_connection_verify (reread, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
test_read_wifi_band_a (void)
{
NMConnection *connection;
@@ -12703,6 +12824,7 @@ int main (int argc, char **argv)
test_read_vlan_only_vlan_id ();
test_read_vlan_only_device ();
g_test_add_func (TPATH "vlan/physdev", test_read_vlan_physdev);
+ g_test_add_func (TPATH "wired/read-wake-on-lan", test_read_wired_wake_on_lan);
test_write_wired_static ();
test_write_wired_static_ip6_only ();
@@ -12717,6 +12839,7 @@ int main (int argc, char **argv)
test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_BLOB, NM_SETTING_SECRET_FLAG_NONE);
test_write_wired_aliases ();
g_test_add_func (TPATH "ipv4/write-static-addresses-GATEWAY", test_write_gateway);
+ g_test_add_func (TPATH "wired/write-wake-on-lan", test_write_wired_wake_on_lan);
test_write_wifi_open ();
test_write_wifi_open_hex_ssid ();
test_write_wifi_wep ();
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index c93d167936..574a1bba7a 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -43,6 +43,7 @@
#include "nm-core-internal.h"
#include <nm-utils.h>
#include "nm-core-internal.h"
+#include "nm-macros-internal.h"
#include "nm-logging.h"
#include "gsystem-local-alloc.h"
@@ -1050,6 +1051,8 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
const char *const *s390_subchannels;
GString *str;
const char * const *macaddr_blacklist;
+ NMSettingWiredWakeOnLan wol;
+ const char *wol_password;
s_wired = nm_connection_get_setting_wired (connection);
if (!s_wired) {
@@ -1133,6 +1136,33 @@ 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 (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_PHY))
+ g_string_append (str, "p");
+ if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST))
+ g_string_append (str, "u");
+ if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST))
+ g_string_append (str, "m");
+ if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST))
+ g_string_append (str, "b");
+ if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ARP))
+ g_string_append (str, "a");
+ if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC))
+ g_string_append (str, "g");
+
+ if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC))
+ g_string_append_printf (str, "s sopass %s", wol_password);
+
+ svSetValue (ifcfg, "ETHTOOL_OPTS", str->str, FALSE);
+ g_string_free (str, TRUE);
+ }
+
svSetValue (ifcfg, "TYPE", TYPE_ETHERNET, FALSE);
return TRUE;