diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-05-12 11:55:52 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-07-24 14:02:59 +0200 |
commit | 2e0d0bc050b44afaeb017cc30ac409c743b9b171 (patch) | |
tree | 04ace55551a8c139dc04611213bf29f97f054c85 | |
parent | 5622461c04d16ef80187ffdcf8b902ce95549273 (diff) | |
download | NetworkManager-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>
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; |