From b7bdde6e0b42c4408a520ec2dfcbecad7326264e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 10 Aug 2018 09:21:32 +0200 Subject: [PATCH 01/32] platform/tests: increase wait timeout in test_cleanup_internal() Seems this assertion still can fail. Dunno, maybe the timeout was just too short. Increase it. --- src/platform/tests/test-cleanup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index 8b8c87d833..12d9181208 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -60,7 +60,7 @@ test_cleanup_internal (void) g_assert (ifindex > 0); /* wait for kernel to add the IPv6 link local address... it takes a bit. */ - NMTST_WAIT_ASSERT (100, { + NMTST_WAIT_ASSERT (300, { gs_unref_array GArray *addrs = NULL; const NMPlatformIP6Address *a; From b6c094e55ec448dc6e468625b64158b5ce55a73b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 2 Aug 2018 10:58:24 +0200 Subject: [PATCH 02/32] build/meson: fix naming of shared_nm_meta_setting_c variable --- clients/common/meson.build | 2 +- libnm-core/meson.build | 2 +- shared/meson.build | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/common/meson.build b/clients/common/meson.build index f0c8160083..1f0bf17b01 100644 --- a/clients/common/meson.build +++ b/clients/common/meson.build @@ -59,7 +59,7 @@ libnmc = static_library( sources: files( 'nm-meta-setting-access.c', 'nm-meta-setting-desc.c' - ) + shared_nm_utils_nm_meta_setting_c + [settings_docs_source], + ) + shared_nm_meta_setting_c + [settings_docs_source], dependencies: deps, c_args: cflags, link_with: libnmc_base, diff --git a/libnm-core/meson.build b/libnm-core/meson.build index 686f6ad360..ab740cac0a 100644 --- a/libnm-core/meson.build +++ b/libnm-core/meson.build @@ -153,7 +153,7 @@ endif libnm_core_sources_all = libnm_core_sources libnm_core_sources_all += libnm_core_enum -libnm_core_sources_all += shared_nm_utils_nm_meta_setting_c +libnm_core_sources_all += shared_nm_meta_setting_c libnm_core_sources_all += shared_files_libnm_core libnm_core_sources_all += [version_header] diff --git a/shared/meson.build b/shared/meson.build index db6b8a40d8..26ce317495 100644 --- a/shared/meson.build +++ b/shared/meson.build @@ -36,7 +36,7 @@ version_header = configure_file( configuration: version_conf, ) -shared_nm_utils_nm_meta_setting_c = files('nm-meta-setting.c') +shared_nm_meta_setting_c = files('nm-meta-setting.c') shared_nm_test_utils_impl_c = files('nm-test-utils-impl.c') From 09031978bbb0e0d7f7f8ef2e79eee8dc2466fb2e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 1 Aug 2018 21:38:39 +0200 Subject: [PATCH 03/32] keyfile: fix asserting for absolute base-dir in nm_keyfile_read() --- libnm-core/nm-keyfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c index dbc0b187f1..70572b18f1 100644 --- a/libnm-core/nm-keyfile.c +++ b/libnm-core/nm-keyfile.c @@ -2778,7 +2778,7 @@ nm_keyfile_read (GKeyFile *keyfile, base_dir = base_dir_free = g_get_current_dir (); } } else - g_return_val_if_fail ("/", NULL); + g_return_val_if_fail (base_dir[0] == '/', NULL); connection = nm_simple_connection_new (); From f69fb04cd08601d74d092de2806ef51f7b02fc6d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 2 Aug 2018 13:56:27 +0200 Subject: [PATCH 04/32] ifcfg-rh/tests: regenerate .cexpected files with NM_TEST_REGENERATE=1 The tests already honored the environment variable $NMTST_IFCFG_RH_UPDATE_EXPECTED to indicate that the .cexpected files should be written by the tests. However, in the meantime, we instead use NM_TEST_REGENERATE=1 at various places for this purpose. Honor that flag as well. --- src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 8d4efbbfd1..67431c18a4 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -185,7 +185,8 @@ _assert_expected_content (NMConnection *connection, const char *filename, const if ( len_expectd != len_written || memcmp (content_expectd, content_written, len_expectd) != 0) { - if (g_getenv ("NMTST_IFCFG_RH_UPDATE_EXPECTED")) { + if ( g_getenv ("NMTST_IFCFG_RH_UPDATE_EXPECTED") + || nm_streq0 (g_getenv ("NM_TEST_REGENERATE"), "1")) { if (uuid) { gs_free char *search = g_strdup_printf ("UUID=%s\n", uuid); const char *s; From 1bcf1047822225544091a11f92c507aafb53732e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 2 Aug 2018 12:05:39 +0200 Subject: [PATCH 05/32] ifcfg-rh: cleanup write_wired_setting() Drop some local variables, or move them inside a nested scope, closer to where they are used. --- .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 86 +++++++++---------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index f29017e3a7..e978139b0a 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -809,7 +809,7 @@ write_wireless_setting (NMConnection *connection, const char *device_mac, *cloned_mac; guint32 mtu, chan, i; gboolean adhoc = FALSE, hex_ssid = FALSE; - const char * const *macaddr_blacklist; + const char *const*macaddr_blacklist; s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) { @@ -1041,13 +1041,11 @@ static gboolean write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingWired *s_wired; - const char *device_mac, *cloned_mac; - char *tmp; - const char *nettype, *portname, *ctcprot, *s390_key, *s390_val, *duplex; + const char *const*s390_subchannels; + const char *duplex; guint32 mtu, num_opts, speed, i; - const char *const *s390_subchannels; GString *str = NULL; - const char * const *macaddr_blacklist; + const char *const*macaddr_blacklist; gboolean auto_negotiate; NMSettingWiredWakeOnLan wol; const char *wol_password; @@ -1059,77 +1057,78 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return FALSE; } - device_mac = nm_setting_wired_get_mac_address (s_wired); - svSetValueStr (ifcfg, "HWADDR", device_mac); + svSetValueStr (ifcfg, "HWADDR", + nm_setting_wired_get_mac_address (s_wired)); - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - svSetValueStr (ifcfg, "MACADDR", cloned_mac); + svSetValueStr (ifcfg, "MACADDR", + nm_setting_wired_get_cloned_mac_address (s_wired)); svSetValueStr (ifcfg, "GENERATE_MAC_ADDRESS_MASK", nm_setting_wired_get_generate_mac_address_mask (s_wired)); - svUnsetValue (ifcfg, "HWADDR_BLACKLIST"); macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); if (macaddr_blacklist[0]) { - char *blacklist_str; + gs_free char *blacklist_str = NULL; blacklist_str = g_strjoinv (" ", (char **) macaddr_blacklist); svSetValueStr (ifcfg, "HWADDR_BLACKLIST", blacklist_str); - g_free (blacklist_str); - } + } else + svUnsetValue (ifcfg, "HWADDR_BLACKLIST"); mtu = nm_setting_wired_get_mtu (s_wired); svSetValueInt64_cond (ifcfg, "MTU", mtu != 0, mtu); - svUnsetValue (ifcfg, "SUBCHANNELS"); s390_subchannels = nm_setting_wired_get_s390_subchannels (s_wired); - if (s390_subchannels) { - int len = g_strv_length ((char **)s390_subchannels); - tmp = NULL; + { + gs_free char *tmp = NULL; + gsize len = NM_PTRARRAY_LEN (s390_subchannels); + if (len == 2) { - tmp = g_strdup_printf ("%s,%s", s390_subchannels[0], s390_subchannels[1]); + tmp = g_strdup_printf ("%s,%s", + s390_subchannels[0], + s390_subchannels[1]); } else if (len == 3) { - tmp = g_strdup_printf ("%s,%s,%s", s390_subchannels[0], s390_subchannels[1], + tmp = g_strdup_printf ("%s,%s,%s", + s390_subchannels[0], + s390_subchannels[1], s390_subchannels[2]); } + svSetValueStr (ifcfg, "SUBCHANNELS", tmp); - g_free (tmp); } - svUnsetValue (ifcfg, "NETTYPE"); - nettype = nm_setting_wired_get_s390_nettype (s_wired); - if (nettype) - svSetValueStr (ifcfg, "NETTYPE", nettype); + svSetValueStr (ifcfg, "NETTYPE", + nm_setting_wired_get_s390_nettype (s_wired)); - svUnsetValue (ifcfg, "PORTNAME"); - portname = nm_setting_wired_get_s390_option_by_key (s_wired, "portname"); - if (portname) - svSetValueStr (ifcfg, "PORTNAME", portname); + svSetValueStr (ifcfg, "PORTNAME", + nm_setting_wired_get_s390_option_by_key (s_wired, "portname")); - svUnsetValue (ifcfg, "CTCPROT"); - ctcprot = nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot"); - if (ctcprot) - svSetValueStr (ifcfg, "CTCPROT", ctcprot); + svSetValueStr (ifcfg, "CTCPROT", + nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot")); svUnsetValue (ifcfg, "OPTIONS"); num_opts = nm_setting_wired_get_num_s390_options (s_wired); if (s390_subchannels && num_opts) { - str = g_string_sized_new (30); + nm_auto_free_gstring GString *tmp = NULL; + for (i = 0; i < num_opts; i++) { + const char *s390_key, *s390_val; + nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val); /* portname is handled separately */ if (!strcmp (s390_key, "portname") || !strcmp (s390_key, "ctcprot")) continue; - if (str->len) - g_string_append_c (str, ' '); - g_string_append_printf (str, "%s=%s", s390_key, s390_val); + if (!tmp) + tmp = g_string_sized_new (30); + else + g_string_append_c (tmp, ' '); + g_string_append_printf (tmp, "%s=%s", s390_key, s390_val); } - if (str->len) - svSetValueStr (ifcfg, "OPTIONS", str->str); - g_string_free (str, TRUE); + if (tmp) + svSetValueStr (ifcfg, "OPTIONS", tmp->str); } /* Stuff ETHTOOL_OPT with required options */ @@ -1161,8 +1160,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE) svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", "ignore"); else if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT) { - if (!str) - svUnsetValue (ifcfg, "ETHTOOL_OPTS"); + /* pass */ } else { if (!str) str = g_string_sized_new (30); @@ -1193,8 +1191,8 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) if (str) { svSetValueStr (ifcfg, "ETHTOOL_OPTS", str->str); g_string_free (str, TRUE); - } - /* End ETHTOOL_OPT stuffing */ + } else + svUnsetValue (ifcfg, "ETHTOOL_OPTS"); svSetValueStr (ifcfg, "TYPE", TYPE_ETHERNET); From cd442112c6390e03d51bb69c656d9302616cb6c8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 2 Aug 2018 13:33:10 +0200 Subject: [PATCH 06/32] ifcfg-rh: split setting ETHTOOL_OPTS from write_wired_setting() Will be used later, because we will not only have ethtool options in conjunction with wired settings. --- .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 35 +++++++++++++------ ...-Test_Write_Wired_Auto-Negotiate.cexpected | 2 +- ...cfg-Test_Write_Wired_Wake-on-LAN.cexpected | 2 +- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index e978139b0a..d3d531ebdc 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -1042,13 +1042,8 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingWired *s_wired; const char *const*s390_subchannels; - const char *duplex; - guint32 mtu, num_opts, speed, i; - GString *str = NULL; + guint32 mtu, num_opts, i; const char *const*macaddr_blacklist; - gboolean auto_negotiate; - NMSettingWiredWakeOnLan wol; - const char *wol_password; s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) { @@ -1131,8 +1126,27 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValueStr (ifcfg, "OPTIONS", tmp->str); } - /* Stuff ETHTOOL_OPT with required options */ - str = NULL; + svSetValueStr (ifcfg, "TYPE", TYPE_ETHERNET); + + return TRUE; +} + +static gboolean +write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingWired *s_wired; + const char *duplex; + guint32 speed; + GString *str = NULL; + gboolean auto_negotiate; + NMSettingWiredWakeOnLan wol; + const char *wol_password; + + s_wired = nm_connection_get_setting_wired (connection); + + if (!s_wired) + return TRUE; + auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired); speed = nm_setting_wired_get_speed (s_wired); duplex = nm_setting_wired_get_duplex (s_wired); @@ -1194,8 +1208,6 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) } else svUnsetValue (ifcfg, "ETHTOOL_OPTS"); - svSetValueStr (ifcfg, "TYPE", TYPE_ETHERNET); - return TRUE; } @@ -2960,6 +2972,9 @@ do_write_construct (NMConnection *connection, if (!write_proxy_setting (connection, ifcfg, error)) return FALSE; + if (!write_ethtool_setting (connection, ifcfg, error)) + return FALSE; + if (!write_user_setting (connection, ifcfg, error)) return FALSE; diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected index 8f421cfbda..214f5da55b 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected @@ -1,7 +1,7 @@ -ETHTOOL_OPTS="autoneg off speed 10 duplex half" TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no +ETHTOOL_OPTS="autoneg off speed 10 duplex half" BOOTPROTO=dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected index 398a301780..de66dcddb8 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected @@ -1,7 +1,7 @@ -ETHTOOL_OPTS="wol umgs sopass 00:00:00:11:22:33" TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no +ETHTOOL_OPTS="wol umgs sopass 00:00:00:11:22:33" BOOTPROTO=dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no From 64e0e241c0f1d455d2de1e036cd13bba40b442c8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 2 Aug 2018 14:48:22 +0200 Subject: [PATCH 07/32] ifcfg-rh: always reset ETHTOOL_WAKE_ON_LAN value We must always set all variables, because othewise a previously set value might be merged into the new setting. --- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index d3d531ebdc..4fed68a254 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -1171,11 +1171,12 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro wol = nm_setting_wired_get_wake_on_lan (s_wired); wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired); - if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE) - svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", "ignore"); - else if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT) { - /* pass */ - } else { + svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", + wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE + ? "ignore" + : NULL); + if (!NM_IN_SET (wol, NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE, + NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)) { if (!str) str = g_string_sized_new (30); else @@ -1202,6 +1203,7 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) g_string_append_printf (str, "s sopass %s", wol_password); } + if (str) { svSetValueStr (ifcfg, "ETHTOOL_OPTS", str->str); g_string_free (str, TRUE); From bcbea6fe35dbf9305adab2f157c8ff6da45eec10 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 2 Aug 2018 15:28:03 +0200 Subject: [PATCH 08/32] ifcfg-rh: refactor parsing in parse_ethtool_option() to not call helper functions Parsing can be complicated enough. It's simpler to just work top-to-bottom, without calling various helper functions. This was, you can see all the code in one place, without need to jump to the helper function to see what it is doing. In general, a static function that is only called once, does sometimes not simplify but obfuscate the code. --- .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 241 ++++++++---------- 1 file changed, 113 insertions(+), 128 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index f5bd0820e5..ee9e28571d 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -4045,111 +4045,6 @@ wireless_connection_from_ifcfg (const char *file, return connection; } -static void -parse_ethtool_option_autoneg (const char *value, gboolean *out_autoneg) -{ - if (!value) { - PARSE_WARNING ("Auto-negotiation option missing"); - return; - } - - if (g_str_equal (value, "off")) - *out_autoneg = FALSE; - else if (g_str_equal (value, "on")) - *out_autoneg = TRUE; - else - PARSE_WARNING ("Auto-negotiation unknown value: %s", value); -} - -static void -parse_ethtool_option_speed (const char *value, guint32 *out_speed) -{ - if (!value) { - PARSE_WARNING ("Speed option missing"); - return; - } - - *out_speed = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, 0); - if (errno) - PARSE_WARNING ("Speed value '%s' is invalid", value); -} - -static void -parse_ethtool_option_duplex (const char *value, const char **out_duplex) -{ - if (!value) { - PARSE_WARNING ("Duplex option missing"); - return; - } - - if (g_str_equal (value, "half")) - *out_duplex = "half"; - else if (g_str_equal (value, "full")) - *out_duplex = "full"; - else - PARSE_WARNING ("Duplex unknown value: %s", value); - -} - -static void -parse_ethtool_option_wol (const char *value, NMSettingWiredWakeOnLan *out_flags) -{ - NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; - - if (!value) { - PARSE_WARNING ("Wake-on-LAN options missing"); - return; - } - - for (; *value; value++) { - switch (*value) { - 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': - break; - case 'd': - wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; - break; - default: - PARSE_WARNING ("unrecognized Wake-on-LAN option '%c'", *value); - } - } - - *out_flags = wol_flags; -} - -static void parse_ethtool_option_sopass (const char *value, char **out_password) -{ - if (!value) { - PARSE_WARNING ("Wake-on-LAN password missing"); - return; - } - - g_clear_pointer (out_password, g_free); - if (!nm_utils_hwaddr_valid (value, ETH_ALEN)) { - PARSE_WARNING ("Wake-on-LAN password '%s' is invalid", value); - return; - } - - *out_password = g_strdup (value); -} - static void parse_ethtool_option (const char *value, NMSettingWiredWakeOnLan *out_flags, @@ -4159,36 +4054,124 @@ parse_ethtool_option (const char *value, const char **out_duplex) { gs_free const char **words = NULL; - const char *const *iter; - const char *opt_val, *opt; + guint i; - words = nm_utils_strsplit_set (value, "\t "); + words = nm_utils_strsplit_set (value, "\t \n"); if (!words) return; - iter = words; + for (i = 0; words[i]; ) { + const char *opt = words[i]; + const char *opt_val = words[++i]; - while (iter[0]) { - opt = iter++[0]; - opt_val = iter[0]; + if (nm_streq (opt, "autoneg")) { + if (!opt_val) { + PARSE_WARNING ("Auto-negotiation option missing"); + break; + } + i++; - if (nm_streq (opt, "autoneg")) - parse_ethtool_option_autoneg (opt_val, out_autoneg); - else if (nm_streq (opt, "speed")) - parse_ethtool_option_speed (opt_val, out_speed); - else if (nm_streq (opt, "duplex")) - parse_ethtool_option_duplex (opt_val, out_duplex); - else if (nm_streq (opt, "wol")) - parse_ethtool_option_wol (opt_val, out_flags); - else if (nm_streq (opt, "sopass")) - parse_ethtool_option_sopass (opt_val, out_password); - else { - /* Silently skip unknown options */ + if (nm_streq (opt_val, "off")) + *out_autoneg = FALSE; + else if (nm_streq (opt_val, "on")) + *out_autoneg = TRUE; + else + PARSE_WARNING ("Auto-negotiation unknown value: %s", opt_val); continue; } - if (iter[0]) - iter++; + if (nm_streq (opt, "speed")) { + guint32 speed; + + if (!opt_val) { + PARSE_WARNING ("Speed option missing"); + break; + } + i++; + + speed = _nm_utils_ascii_str_to_int64 (opt_val, 10, 0, G_MAXUINT32, 0); + if (errno == 0) + *out_speed = speed; + else + PARSE_WARNING ("Speed value '%s' is invalid", opt_val); + continue; + } + + if (nm_streq (opt, "duplex")) { + if (!opt_val) { + PARSE_WARNING ("Duplex option missing"); + break; + } + i++; + + if (nm_streq (opt_val, "half")) + *out_duplex = "half"; + else if (nm_streq (opt_val, "full")) + *out_duplex = "full"; + else + PARSE_WARNING ("Duplex unknown value: %s", opt_val); + continue; + } + + if (nm_streq (opt, "wol")) { + NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; + + if (!opt_val) { + PARSE_WARNING ("Wake-on-LAN options missing"); + break; + } + i++; + + for (; *opt_val; opt_val++) { + switch (*opt_val) { + 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': + break; + case 'd': + wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; + break; + default: + PARSE_WARNING ("unrecognized Wake-on-LAN option '%c'", *opt_val); + } + } + + *out_flags = wol_flags; + continue; + } + + if (nm_streq (opt, "sopass")) { + if (!opt_val) { + PARSE_WARNING ("Wake-on-LAN password missing"); + break; + } + i++; + + if (nm_utils_hwaddr_valid (opt_val, ETH_ALEN)) { + g_clear_pointer (out_password, g_free); + *out_password = g_strdup (opt_val); + } else + PARSE_WARNING ("Wake-on-LAN password '%s' is invalid", opt_val); + continue; + } + + /* Silently skip unknown options */ } } @@ -4196,8 +4179,10 @@ static void parse_ethtool_options (shvarFile *ifcfg, NMSettingWired *s_wired, const char *value) { NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; - gs_free char *wol_password = NULL, *wol_value = NULL; - gboolean ignore_wol_password = FALSE, autoneg = FALSE; + gs_free char *wol_password = NULL; + gs_free char *wol_value = NULL; + gboolean ignore_wol_password = FALSE; + gboolean autoneg = FALSE; guint32 speed = 0; const char *duplex = NULL; From 64f1e78e285bfa50078dd2a1585be919c85345eb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 1 Aug 2018 17:59:21 +0200 Subject: [PATCH 09/32] cli: drop NMCTriStateValue for NMTernary --- clients/common/nm-client-utils.c | 8 ++++---- clients/common/nm-client-utils.h | 8 +------- clients/common/nm-meta-setting-desc.c | 10 +++++----- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c index 2e3d45ca38..8c7553d83f 100644 --- a/clients/common/nm-client-utils.c +++ b/clients/common/nm-client-utils.c @@ -132,7 +132,7 @@ nmc_string_to_bool (const char *str, gboolean *val_bool, GError **error) } gboolean -nmc_string_to_tristate (const char *str, NMCTriStateValue *val, GError **error) +nmc_string_to_ternary (const char *str, NMTernary *val, GError **error) { const char *s_true[] = { "true", "yes", "on", NULL }; const char *s_false[] = { "false", "no", "off", NULL }; @@ -150,11 +150,11 @@ nmc_string_to_tristate (const char *str, NMCTriStateValue *val, GError **error) } if (nmc_string_is_valid (str, s_true, NULL)) - *val = NMC_TRI_STATE_YES; + *val = NM_TERNARY_TRUE; else if (nmc_string_is_valid (str, s_false, NULL)) - *val = NMC_TRI_STATE_NO; + *val = NM_TERNARY_FALSE; else if (nmc_string_is_valid (str, s_unknown, NULL)) - *val = NMC_TRI_STATE_UNKNOWN; + *val = NM_TERNARY_DEFAULT; else { g_set_error (error, 1, 0, _("'%s' is not valid; use [%s], [%s] or [%s]"), diff --git a/clients/common/nm-client-utils.h b/clients/common/nm-client-utils.h index cc0b7330ac..9d818873c0 100644 --- a/clients/common/nm-client-utils.h +++ b/clients/common/nm-client-utils.h @@ -24,12 +24,6 @@ #include "nm-active-connection.h" #include "nm-device.h" -typedef enum { - NMC_TRI_STATE_NO, - NMC_TRI_STATE_YES, - NMC_TRI_STATE_UNKNOWN, -} NMCTriStateValue; - const NMObject **nmc_objects_sort_by_path (const NMObject *const*objs, gssize len); const char *nmc_string_is_valid (const char *input, const char **allowed, GError **error); @@ -40,7 +34,7 @@ gboolean nmc_string_to_uint (const char *str, unsigned long int max, unsigned long int *value); gboolean nmc_string_to_bool (const char *str, gboolean *val_bool, GError **error); -gboolean nmc_string_to_tristate (const char *str, NMCTriStateValue *val, GError **error); +gboolean nmc_string_to_ternary (const char *str, NMTernary *val, GError **error); gboolean matches (const char *cmd, const char *pattern); diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index aa21ce1023..5dbbc50384 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -2719,19 +2719,19 @@ static gboolean _set_fcn_connection_metered (ARGS_SET_FCN) { NMMetered metered; - NMCTriStateValue ts_val; + NMTernary ts_val; - if (!nmc_string_to_tristate (value, &ts_val, error)) + if (!nmc_string_to_ternary (value, &ts_val, error)) return FALSE; switch (ts_val) { - case NMC_TRI_STATE_YES: + case NM_TERNARY_TRUE: metered = NM_METERED_YES; break; - case NMC_TRI_STATE_NO: + case NM_TERNARY_FALSE: metered = NM_METERED_NO; break; - case NMC_TRI_STATE_UNKNOWN: + case NM_TERNARY_DEFAULT: metered = NM_METERED_UNKNOWN; break; default: From b5bdfdc773872ea7be179b80b0bb1e25514d9928 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 26 Jul 2018 17:44:21 +0200 Subject: [PATCH 10/32] shared: add nm_utils_hash_table_equal() util Add utility function to compare the content of two hash tables for equality. --- shared/nm-utils/nm-shared-utils.c | 57 +++++++++++++++++++++++++++++++ shared/nm-utils/nm-shared-utils.h | 12 +++++++ 2 files changed, 69 insertions(+) diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index 1b76b2d794..75624d081d 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -1350,6 +1350,63 @@ nm_utils_strv_make_deep_copied (const char **strv) /*****************************************************************************/ +/** + * nm_utils_hash_table_equal: + * @a: one #GHashTable + * @b: other #GHashTable + * @treat_null_as_empty: if %TRUE, when either @a or @b is %NULL, it is + * treated like an empty hash. It means, a %NULL hash will compare equal + * to an empty hash. + * @equal_func: the equality function, for comparing the values. + * If %NULL, the values are not compared. In that case, the function + * only checks, if both dictionaries have the same keys -- according + * to @b's key equality function. + * Note that the values of @a will be passed as first argument + * to @equal_func. + * + * Compares two hash tables, whether they have equal content. + * This only makes sense, if @a and @b have the same key types and + * the same key compare-function. + * + * Returns: %TRUE, if both dictionaries have the same content. + */ +gboolean +nm_utils_hash_table_equal (const GHashTable *a, + const GHashTable *b, + gboolean treat_null_as_empty, + NMUtilsHashTableEqualFunc equal_func) +{ + guint n; + GHashTableIter iter; + gconstpointer key, v_a, v_b; + + if (a == b) + return TRUE; + if (!treat_null_as_empty) { + if (!a || !b) + return FALSE; + } + + n = a ? g_hash_table_size ((GHashTable *) a) : 0; + if (n != (b ? g_hash_table_size ((GHashTable *) b) : 0)) + return FALSE; + + if (n > 0) { + g_hash_table_iter_init (&iter, (GHashTable *) a); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &v_a)) { + if (!g_hash_table_lookup_extended ((GHashTable *) b, key, NULL, (gpointer *) &v_b)) + return FALSE; + if ( equal_func + && !equal_func (v_a, v_b)) + return FALSE; + } + } + + return TRUE; +} + +/*****************************************************************************/ + /** * nm_utils_get_start_time_for_pid: * @pid: the process identifier diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index e9885c6e35..cb042d9a73 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -555,6 +555,18 @@ nm_utils_strv_make_deep_copied_nonnull (const char **strv) return nm_utils_strv_make_deep_copied (strv) ?: g_new0 (char *, 1); } +/*****************************************************************************/ + +typedef gboolean (*NMUtilsHashTableEqualFunc) (gconstpointer a, + gconstpointer b); + +gboolean nm_utils_hash_table_equal (const GHashTable *a, + const GHashTable *b, + gboolean treat_null_as_empty, + NMUtilsHashTableEqualFunc equal_func); + +/*****************************************************************************/ + void _nm_utils_strv_sort (const char **strv, gssize len); #define nm_utils_strv_sort(strv, len) _nm_utils_strv_sort (NM_CAST_STRV_MC (strv), len) From d32da2daaa1b37a72a4a1c7ad23850a69ddceb42 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 28 Jul 2018 12:26:37 +0200 Subject: [PATCH 11/32] shared: move nm_utils_array_find_binary_search() to shared utils --- libnm-core/nm-core-internal.h | 1 - libnm-core/nm-keyfile.c | 12 +++--- libnm-core/nm-utils.c | 34 ---------------- libnm-core/tests/test-general.c | 14 +++---- shared/nm-utils/nm-shared-utils.c | 65 +++++++++++++++++++++++++++++++ shared/nm-utils/nm-shared-utils.h | 9 +++++ src/nm-config-data.c | 12 +++--- src/nm-manager.c | 12 +++--- 8 files changed, 99 insertions(+), 60 deletions(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 38caa66ff9..e826a9fba2 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -262,7 +262,6 @@ gssize _nm_utils_ptrarray_find_binary_search (gconstpointer *list, gpointer user_data, gssize *out_idx_first, gssize *out_idx_last); -gssize _nm_utils_array_find_binary_search (gconstpointer list, gsize elem_size, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data); GSList * _nm_utils_strv_to_slist (char **strv, gboolean deep_copy); char ** _nm_utils_slist_to_strv (GSList *slist, gboolean deep_copy); diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c index 70572b18f1..c87c68e3bf 100644 --- a/libnm-core/nm-keyfile.c +++ b/libnm-core/nm-keyfile.c @@ -2462,12 +2462,12 @@ _parse_info_find (const char *setting_name, const char *property_name) #endif G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (ParseInfoSetting, setting_name) == 0); - idx = _nm_utils_array_find_binary_search (parse_infos, - sizeof (ParseInfoSetting), - G_N_ELEMENTS (parse_infos), - &setting_name, - nm_strcmp_p_with_data, - NULL); + idx = nm_utils_array_find_binary_search (parse_infos, + sizeof (ParseInfoSetting), + G_N_ELEMENTS (parse_infos), + &setting_name, + nm_strcmp_p_with_data, + NULL); if (idx >= 0) { const ParseInfoSetting *pis = &parse_infos[idx]; diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 2c9c1fd0ef..5665743c03 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -726,40 +726,6 @@ _nm_utils_ptrarray_find_binary_search (gconstpointer *list, return imin; } -gssize -_nm_utils_array_find_binary_search (gconstpointer list, gsize elem_size, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data) -{ - gssize imin, imax, imid; - int cmp; - - g_return_val_if_fail (list || !len, ~((gssize) 0)); - g_return_val_if_fail (cmpfcn, ~((gssize) 0)); - g_return_val_if_fail (elem_size > 0, ~((gssize) 0)); - - imin = 0; - if (len == 0) - return ~imin; - - imax = len - 1; - - while (imin <= imax) { - imid = imin + (imax - imin) / 2; - - cmp = cmpfcn (&((const char *) list)[elem_size * imid], needle, user_data); - if (cmp == 0) - return imid; - - if (cmp < 0) - imin = imid + 1; - else - imax = imid - 1; - } - - /* return the inverse of @imin. This is a negative number, but - * also is ~imin the position where the value should be inserted. */ - return ~imin; -} - GVariant * _nm_utils_bytes_to_dbus (const GValue *prop_value) { diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index e4a9e8f952..adf42cca1f 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -6188,12 +6188,12 @@ _test_find_binary_search_do_uint32 (const int *int_array, gsize len) expected_result = idx; } - idx = _nm_utils_array_find_binary_search (array, - sizeof (guint32), - len, - &NEEDLE, - nm_cmp_uint32_p_with_data, - NULL); + idx = nm_utils_array_find_binary_search (array, + sizeof (guint32), + len, + &NEEDLE, + nm_cmp_uint32_p_with_data, + NULL); if (expected_result >= 0) g_assert_cmpint (expected_result, ==, idx); else { @@ -6297,7 +6297,7 @@ test_nm_utils_ptrarray_find_binary_search_with_duplicates (void) idx_first2 = _nm_utils_ptrarray_find_first (arr, i_len, p); - idx2 = _nm_utils_array_find_binary_search (arr, sizeof (gpointer), i_len, &p, _test_bin_search2_cmp_p, NULL); + idx2 = nm_utils_array_find_binary_search (arr, sizeof (gpointer), i_len, &p, _test_bin_search2_cmp_p, NULL); g_assert_cmpint (idx, ==, idx2); if (idx_first2 < 0) { diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index 75624d081d..a9c7ab7e9d 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -1350,6 +1350,71 @@ nm_utils_strv_make_deep_copied (const char **strv) /*****************************************************************************/ +/** + * nm_utils_array_find_binary_search: + * @list: the list to search. It must be sorted according to @cmpfcn ordering. + * @elem_size: the size in bytes of each element in the list + * @len: the number of elements in @list + * @needle: the value that is searched + * @cmpfcn: the compare function. The elements @list are passed as first + * argument to @cmpfcn, while @needle is passed as second. Usually, the + * needle is the same data type as inside the list, however, that is + * not necessary, as long as @cmpfcn takes care to cast the two arguments + * accordingly. + * @user_data: optional argument passed to @cmpfcn + * + * Performs binary search for @needle in @list. On success, returns the + * (non-negative) index where the compare function found the searched element. + * On success, it returns a negative value. Note that the return negative value + * is the bitwise inverse of the position where the element should be inserted. + * + * If the list contains multiple matching elements, an arbitrary index is + * returned. + * + * Returns: the index to the element in the list, or the (negative, bitwise inverted) + * position where it should be. + */ +gssize +nm_utils_array_find_binary_search (gconstpointer list, + gsize elem_size, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data) +{ + gssize imin, imax, imid; + int cmp; + + g_return_val_if_fail (list || !len, ~((gssize) 0)); + g_return_val_if_fail (cmpfcn, ~((gssize) 0)); + g_return_val_if_fail (elem_size > 0, ~((gssize) 0)); + + imin = 0; + if (len == 0) + return ~imin; + + imax = len - 1; + + while (imin <= imax) { + imid = imin + (imax - imin) / 2; + + cmp = cmpfcn (&((const char *) list)[elem_size * imid], needle, user_data); + if (cmp == 0) + return imid; + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + } + + /* return the inverse of @imin. This is a negative number, but + * also is ~imin the position where the value should be inserted. */ + return ~imin; +} + +/*****************************************************************************/ + /** * nm_utils_hash_table_equal: * @a: one #GHashTable diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index cb042d9a73..feb93f2c5a 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -557,6 +557,15 @@ nm_utils_strv_make_deep_copied_nonnull (const char **strv) /*****************************************************************************/ +gssize nm_utils_array_find_binary_search (gconstpointer list, + gsize elem_size, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data); + +/*****************************************************************************/ + typedef gboolean (*NMUtilsHashTableEqualFunc) (gconstpointer a, gconstpointer b); diff --git a/src/nm-config-data.c b/src/nm-config-data.c index f0ec8a882e..d8ad07c054 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -655,12 +655,12 @@ nm_config_data_log (const NMConfigData *self, const char *group = default_values[g].group; gssize idx; - idx = _nm_utils_array_find_binary_search ((gconstpointer *) groups_full->pdata, - sizeof (char *), - groups_full->len, - &group, - (GCompareDataFunc) _nm_config_data_log_sort, - NULL); + idx = nm_utils_array_find_binary_search ((gconstpointer *) groups_full->pdata, + sizeof (char *), + groups_full->len, + &group, + (GCompareDataFunc) _nm_config_data_log_sort, + NULL); if (idx < 0) g_ptr_array_insert (groups_full, (~idx), (gpointer) group); } diff --git a/src/nm-manager.c b/src/nm-manager.c index b0387749fd..769afc700d 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -6796,12 +6796,12 @@ nm_manager_set_capability (NMManager *self, priv = NM_MANAGER_GET_PRIVATE (self); - idx = _nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0), - sizeof (guint32), - priv->capabilities->len, - &cap_i, - nm_cmp_uint32_p_with_data, - NULL); + idx = nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0), + sizeof (guint32), + priv->capabilities->len, + &cap_i, + nm_cmp_uint32_p_with_data, + NULL); if (idx >= 0) return; From a587d32467e8666b41299a283c24201cf24b95d1 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 1 Aug 2018 11:03:02 +0200 Subject: [PATCH 12/32] shared: move nm_utils_ptrarray_find_binary_search() to shared utils --- libnm-core/nm-core-internal.h | 8 --- libnm-core/nm-keyfile.c | 14 +++--- libnm-core/nm-utils.c | 79 ------------------------------ libnm-core/tests/test-general.c | 8 +-- shared/nm-utils/nm-shared-utils.c | 81 +++++++++++++++++++++++++++++++ shared/nm-utils/nm-shared-utils.h | 8 +++ 6 files changed, 100 insertions(+), 98 deletions(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index e826a9fba2..966566481b 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -255,14 +255,6 @@ GPtrArray *_nm_utils_copy_object_array (const GPtrArray *array); gssize _nm_utils_ptrarray_find_first (gconstpointer *list, gssize len, gconstpointer needle); -gssize _nm_utils_ptrarray_find_binary_search (gconstpointer *list, - gsize len, - gconstpointer needle, - GCompareDataFunc cmpfcn, - gpointer user_data, - gssize *out_idx_first, - gssize *out_idx_last); - GSList * _nm_utils_strv_to_slist (char **strv, gboolean deep_copy); char ** _nm_utils_slist_to_strv (GSList *slist, gboolean deep_copy); diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c index c87c68e3bf..a9f15455f4 100644 --- a/libnm-core/nm-keyfile.c +++ b/libnm-core/nm-keyfile.c @@ -2473,13 +2473,13 @@ _parse_info_find (const char *setting_name, const char *property_name) G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (ParseInfoProperty, property_name) == 0); nm_assert (nm_streq (pis->setting_name, setting_name)); - idx = _nm_utils_ptrarray_find_binary_search ((gconstpointer *) pis->properties, - NM_PTRARRAY_LEN (pis->properties), - &property_name, - nm_strcmp_p_with_data, - NULL, - NULL, - NULL); + idx = nm_utils_ptrarray_find_binary_search ((gconstpointer *) pis->properties, + NM_PTRARRAY_LEN (pis->properties), + &property_name, + nm_strcmp_p_with_data, + NULL, + NULL, + NULL); if (idx >= 0) return pis->properties[idx]; } diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 5665743c03..f481f11fe5 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -647,85 +647,6 @@ _nm_utils_ptrarray_find_first (gconstpointer *list, gssize len, gconstpointer ne return -1; } -gssize -_nm_utils_ptrarray_find_binary_search (gconstpointer *list, - gsize len, - gconstpointer needle, - GCompareDataFunc cmpfcn, - gpointer user_data, - gssize *out_idx_first, - gssize *out_idx_last) -{ - gssize imin, imax, imid, i2min, i2max, i2mid; - int cmp; - - g_return_val_if_fail (list || !len, ~((gssize) 0)); - g_return_val_if_fail (cmpfcn, ~((gssize) 0)); - - imin = 0; - if (len > 0) { - imax = len - 1; - - while (imin <= imax) { - imid = imin + (imax - imin) / 2; - - cmp = cmpfcn (list[imid], needle, user_data); - if (cmp == 0) { - /* we found a matching entry at index imid. - * - * Does the caller request the first/last index as well (in case that - * there are multiple entries which compare equal). */ - - if (out_idx_first) { - i2min = imin; - i2max = imid + 1; - while (i2min <= i2max) { - i2mid = i2min + (i2max - i2min) / 2; - - cmp = cmpfcn (list[i2mid], needle, user_data); - if (cmp == 0) - i2max = i2mid -1; - else { - nm_assert (cmp < 0); - i2min = i2mid + 1; - } - } - *out_idx_first = i2min; - } - if (out_idx_last) { - i2min = imid + 1; - i2max = imax; - while (i2min <= i2max) { - i2mid = i2min + (i2max - i2min) / 2; - - cmp = cmpfcn (list[i2mid], needle, user_data); - if (cmp == 0) - i2min = i2mid + 1; - else { - nm_assert (cmp > 0); - i2max = i2mid - 1; - } - } - *out_idx_last = i2min - 1; - } - return imid; - } - - if (cmp < 0) - imin = imid + 1; - else - imax = imid - 1; - } - } - - /* return the inverse of @imin. This is a negative number, but - * also is ~imin the position where the value should be inserted. */ - imin = ~imin; - NM_SET_OUT (out_idx_first, imin); - NM_SET_OUT (out_idx_last, imin); - return imin; -} - GVariant * _nm_utils_bytes_to_dbus (const GValue *prop_value) { diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index adf42cca1f..39e2cf90e4 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -6126,7 +6126,7 @@ _test_find_binary_search_do (const int *array, gsize len) expected_result = _nm_utils_ptrarray_find_first (parray, len, pneedle); - idx = _nm_utils_ptrarray_find_binary_search (parray, len, pneedle, _test_find_binary_search_cmp, NULL, &idx_first, &idx_last); + idx = nm_utils_ptrarray_find_binary_search (parray, len, pneedle, _test_find_binary_search_cmp, NULL, &idx_first, &idx_last); if (expected_result >= 0) { g_assert_cmpint (expected_result, ==, idx); } else { @@ -6293,7 +6293,7 @@ test_nm_utils_ptrarray_find_binary_search_with_duplicates (void) for (i = 0; i < i_len + BIN_SEARCH_W_DUPS_JITTER; i++) { gconstpointer p = GINT_TO_POINTER (i); - idx = _nm_utils_ptrarray_find_binary_search (arr, i_len, p, _test_bin_search2_cmp, NULL, &idx_first, &idx_last); + idx = nm_utils_ptrarray_find_binary_search (arr, i_len, p, _test_bin_search2_cmp, NULL, &idx_first, &idx_last); idx_first2 = _nm_utils_ptrarray_find_first (arr, i_len, p); @@ -7197,8 +7197,8 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/_nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64); g_test_add_func ("/core/general/nm_utils_is_power_of_two", test_nm_utils_is_power_of_two); - g_test_add_func ("/core/general/_nm_utils_ptrarray_find_binary_search", test_nm_utils_ptrarray_find_binary_search); - g_test_add_func ("/core/general/_nm_utils_ptrarray_find_binary_search_with_duplicates", test_nm_utils_ptrarray_find_binary_search_with_duplicates); + g_test_add_func ("/core/general/nm_utils_ptrarray_find_binary_search", test_nm_utils_ptrarray_find_binary_search); + g_test_add_func ("/core/general/nm_utils_ptrarray_find_binary_search_with_duplicates", test_nm_utils_ptrarray_find_binary_search_with_duplicates); g_test_add_func ("/core/general/_nm_utils_strstrdictkey", test_nm_utils_strstrdictkey); g_test_add_func ("/core/general/nm_ptrarray_len", test_nm_ptrarray_len); diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index a9c7ab7e9d..34c93c8108 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -1350,6 +1350,87 @@ nm_utils_strv_make_deep_copied (const char **strv) /*****************************************************************************/ +gssize +nm_utils_ptrarray_find_binary_search (gconstpointer *list, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data, + gssize *out_idx_first, + gssize *out_idx_last) +{ + gssize imin, imax, imid, i2min, i2max, i2mid; + int cmp; + + g_return_val_if_fail (list || !len, ~((gssize) 0)); + g_return_val_if_fail (cmpfcn, ~((gssize) 0)); + + imin = 0; + if (len > 0) { + imax = len - 1; + + while (imin <= imax) { + imid = imin + (imax - imin) / 2; + + cmp = cmpfcn (list[imid], needle, user_data); + if (cmp == 0) { + /* we found a matching entry at index imid. + * + * Does the caller request the first/last index as well (in case that + * there are multiple entries which compare equal). */ + + if (out_idx_first) { + i2min = imin; + i2max = imid + 1; + while (i2min <= i2max) { + i2mid = i2min + (i2max - i2min) / 2; + + cmp = cmpfcn (list[i2mid], needle, user_data); + if (cmp == 0) + i2max = i2mid -1; + else { + nm_assert (cmp < 0); + i2min = i2mid + 1; + } + } + *out_idx_first = i2min; + } + if (out_idx_last) { + i2min = imid + 1; + i2max = imax; + while (i2min <= i2max) { + i2mid = i2min + (i2max - i2min) / 2; + + cmp = cmpfcn (list[i2mid], needle, user_data); + if (cmp == 0) + i2min = i2mid + 1; + else { + nm_assert (cmp > 0); + i2max = i2mid - 1; + } + } + *out_idx_last = i2min - 1; + } + return imid; + } + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + } + } + + /* return the inverse of @imin. This is a negative number, but + * also is ~imin the position where the value should be inserted. */ + imin = ~imin; + NM_SET_OUT (out_idx_first, imin); + NM_SET_OUT (out_idx_last, imin); + return imin; +} + +/*****************************************************************************/ + /** * nm_utils_array_find_binary_search: * @list: the list to search. It must be sorted according to @cmpfcn ordering. diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index feb93f2c5a..6ee77b989f 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -557,6 +557,14 @@ nm_utils_strv_make_deep_copied_nonnull (const char **strv) /*****************************************************************************/ +gssize nm_utils_ptrarray_find_binary_search (gconstpointer *list, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data, + gssize *out_idx_first, + gssize *out_idx_last); + gssize nm_utils_array_find_binary_search (gconstpointer list, gsize elem_size, gsize len, From 332592ef4f6315b955d5c1c0d520b2aafe939787 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 26 Jul 2018 17:44:36 +0200 Subject: [PATCH 13/32] libnm: use nm_utils_hash_table_equal() in nm-setting-user --- libnm-core/nm-setting-user.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/libnm-core/nm-setting-user.c b/libnm-core/nm-setting-user.c index 56dd71e93f..db28c554c1 100644 --- a/libnm-core/nm-setting-user.c +++ b/libnm-core/nm-setting-user.c @@ -396,29 +396,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return TRUE; } -static gboolean -hash_table_equal (GHashTable *a, GHashTable *b) -{ - guint n; - GHashTableIter iter; - const char *key, *value, *valu2; - - n = a ? g_hash_table_size (a) : 0; - if (n != (b ? g_hash_table_size (b) : 0)) - return FALSE; - if (n > 0) { - g_hash_table_iter_init (&iter, a); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) { - if (!g_hash_table_lookup_extended (b, key, NULL, (gpointer *) &valu2)) - return FALSE; - if (!nm_streq (value, valu2)) - return FALSE; - } - } - return TRUE; - -} - static gboolean compare_property (NMSetting *setting, NMSetting *other, @@ -436,10 +413,10 @@ compare_property (NMSetting *setting, priv = NM_SETTING_USER_GET_PRIVATE (NM_SETTING_USER (setting)); pri2 = NM_SETTING_USER_GET_PRIVATE (NM_SETTING_USER (other)); - if (!hash_table_equal (priv->data, pri2->data)) + if (!nm_utils_hash_table_equal (priv->data, pri2->data, TRUE, g_str_equal)) return FALSE; - if (!hash_table_equal (priv->data_invalid, pri2->data_invalid)) + if (!nm_utils_hash_table_equal (priv->data_invalid, pri2->data_invalid, TRUE, g_str_equal)) return FALSE; return TRUE; From a67a3439b0eb59a854c0b0d0fedd5b4726ffa8a9 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 29 Jul 2018 14:32:36 +0200 Subject: [PATCH 14/32] libnm: minor rework checking property flags in _nm_setting_to_dbus() Properties that are backed by a GObject property are fundamentally different. I think it's clearer to rework the check, to first check whether we have a param_spec, and then implement different checks. --- libnm-core/nm-setting.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 1b4f3b23e9..3d0726c7e6 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -794,26 +794,29 @@ _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionS const NMSettingProperty *property = &properties[i]; GParamSpec *prop_spec = property->param_spec; - if (!prop_spec && !property->synth_func) { - /* D-Bus-only property with no synth_func, so we skip it. */ - continue; + if (!prop_spec) { + if (!property->synth_func) + continue; + + if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + continue; + } else { + if (!(prop_spec->flags & G_PARAM_WRITABLE)) + continue; + + if ( (prop_spec->flags & NM_SETTING_PARAM_LEGACY) + && !_nm_utils_is_manager_process) + continue; + + if ( (flags & NM_CONNECTION_SERIALIZE_NO_SECRETS) + && (prop_spec->flags & NM_SETTING_PARAM_SECRET)) + continue; + + if ( (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + && !(prop_spec->flags & NM_SETTING_PARAM_SECRET)) + continue; } - if (prop_spec && !(prop_spec->flags & G_PARAM_WRITABLE)) - continue; - - if ( prop_spec && (prop_spec->flags & NM_SETTING_PARAM_LEGACY) - && !_nm_utils_is_manager_process) - continue; - - if ( (flags & NM_CONNECTION_SERIALIZE_NO_SECRETS) - && (prop_spec && (prop_spec->flags & NM_SETTING_PARAM_SECRET))) - continue; - - if ( (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) - && !(prop_spec && (prop_spec->flags & NM_SETTING_PARAM_SECRET))) - continue; - if (property->synth_func) dbus_value = property->synth_func (setting, connection, property->name); else From 19ef103e39236c5a980955930a8e52be0ff69c95 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 29 Jul 2018 13:25:49 +0200 Subject: [PATCH 15/32] libnm-core/trivial: move code --- libnm-core/nm-setting.c | 74 +++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 3d0726c7e6..887e8aeb4f 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -549,42 +549,6 @@ _nm_setting_class_transform_property (NMSettingClass *setting_class, to_dbus, from_dbus); } -gboolean -_nm_setting_use_legacy_property (NMSetting *setting, - GVariant *connection_dict, - const char *legacy_property, - const char *new_property) -{ - GVariant *setting_dict, *value; - - setting_dict = g_variant_lookup_value (connection_dict, nm_setting_get_name (NM_SETTING (setting)), NM_VARIANT_TYPE_SETTING); - g_return_val_if_fail (setting_dict != NULL, FALSE); - - /* If the new property isn't set, we have to use the legacy property. */ - value = g_variant_lookup_value (setting_dict, new_property, NULL); - if (!value) { - g_variant_unref (setting_dict); - return TRUE; - } - g_variant_unref (value); - - /* Otherwise, clients always prefer new properties sent from the daemon. */ - if (!_nm_utils_is_manager_process) { - g_variant_unref (setting_dict); - return FALSE; - } - - /* The daemon prefers the legacy property if it exists. */ - value = g_variant_lookup_value (setting_dict, legacy_property, NULL); - g_variant_unref (setting_dict); - - if (value) { - g_variant_unref (value); - return TRUE; - } else - return FALSE; -} - static GArray * nm_setting_class_ensure_properties (NMSettingClass *setting_class) { @@ -658,6 +622,44 @@ nm_setting_class_find_property (NMSettingClass *setting_class, const char *prope /*****************************************************************************/ +gboolean +_nm_setting_use_legacy_property (NMSetting *setting, + GVariant *connection_dict, + const char *legacy_property, + const char *new_property) +{ + GVariant *setting_dict, *value; + + setting_dict = g_variant_lookup_value (connection_dict, nm_setting_get_name (NM_SETTING (setting)), NM_VARIANT_TYPE_SETTING); + g_return_val_if_fail (setting_dict != NULL, FALSE); + + /* If the new property isn't set, we have to use the legacy property. */ + value = g_variant_lookup_value (setting_dict, new_property, NULL); + if (!value) { + g_variant_unref (setting_dict); + return TRUE; + } + g_variant_unref (value); + + /* Otherwise, clients always prefer new properties sent from the daemon. */ + if (!_nm_utils_is_manager_process) { + g_variant_unref (setting_dict); + return FALSE; + } + + /* The daemon prefers the legacy property if it exists. */ + value = g_variant_lookup_value (setting_dict, legacy_property, NULL); + g_variant_unref (setting_dict); + + if (value) { + g_variant_unref (value); + return TRUE; + } else + return FALSE; +} + +/*****************************************************************************/ + static const GVariantType * variant_type_for_gtype (GType type) { From 23adc373777d923de43626c028cbb1e0d649154a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 28 Jul 2018 10:43:21 +0200 Subject: [PATCH 16/32] libnm/trivial: cleanup variable names in settings' class-init functions - Don't use @parent_class name. This local variable (and @object_class) is the class instance up-cast to the pointer types of the parents. The point here is not that it is the direct parent. The point is, that it's the NMSettingClass type. Also, it can only be used inconsistently, in face of NMSettingIP4Config, who's parent type is NMSettingIPConfig. Clearly, inside nm-setting-ip4-config.c we wouldn't want to use the "parent_class" name. Consistently rename @parent_class to @setting_class. - Also rename the pointer to the own class to @klass. "setting_class" is also the wrong name for that, because the right name would be something like "setting_6lowpan_class". However, "klass" is preferred over the latter, because we commonly create new GObject implementations by copying an existing one. Generic names like "klass" and "self" inside a type implementation make that simpler. - drop useless comments like /* virtual functions */ /* Properties */ It's better to logically and visually structure the code, and avoid trival remarks about that. They only end up being used inconsistently. If you even need a stronger visual separator, then an 80 char /****/ line should be preferred. --- libnm-core/nm-setting-6lowpan.c | 11 ++++--- libnm-core/nm-setting-8021x.c | 15 ++++----- libnm-core/nm-setting-adsl.c | 16 +++++----- libnm-core/nm-setting-bluetooth.c | 14 ++++----- libnm-core/nm-setting-bond.c | 38 +++++++++++------------ libnm-core/nm-setting-bridge-port.c | 13 ++++---- libnm-core/nm-setting-bridge.c | 17 +++++----- libnm-core/nm-setting-cdma.c | 16 +++++----- libnm-core/nm-setting-connection.c | 17 +++++----- libnm-core/nm-setting-dcb.c | 25 +++++++-------- libnm-core/nm-setting-dummy.c | 6 ++-- libnm-core/nm-setting-generic.c | 4 +-- libnm-core/nm-setting-gsm.c | 20 ++++++------ libnm-core/nm-setting-infiniband.c | 14 ++++----- libnm-core/nm-setting-ip-config.c | 23 ++++++-------- libnm-core/nm-setting-ip-tunnel.c | 12 +++---- libnm-core/nm-setting-ip4-config.c | 10 +++--- libnm-core/nm-setting-ip6-config.c | 14 ++++----- libnm-core/nm-setting-macsec.c | 13 ++++---- libnm-core/nm-setting-macvlan.c | 12 +++---- libnm-core/nm-setting-olpc-mesh.c | 15 +++++---- libnm-core/nm-setting-ovs-bridge.c | 11 ++++--- libnm-core/nm-setting-ovs-interface.c | 11 ++++--- libnm-core/nm-setting-ovs-patch.c | 11 ++++--- libnm-core/nm-setting-ovs-port.c | 11 ++++--- libnm-core/nm-setting-ppp.c | 13 ++++---- libnm-core/nm-setting-pppoe.c | 15 +++++---- libnm-core/nm-setting-proxy.c | 14 ++++----- libnm-core/nm-setting-serial.c | 13 +++----- libnm-core/nm-setting-sriov.c | 22 ++++++------- libnm-core/nm-setting-tc-config.c | 23 ++++++-------- libnm-core/nm-setting-team-port.c | 24 +++++++------- libnm-core/nm-setting-team.c | 26 +++++++--------- libnm-core/nm-setting-tun.c | 13 ++++---- libnm-core/nm-setting-user.c | 3 +- libnm-core/nm-setting-vlan.c | 16 +++++----- libnm-core/nm-setting-vpn.c | 28 ++++++++--------- libnm-core/nm-setting-vxlan.c | 12 +++---- libnm-core/nm-setting-wimax.c | 15 +++++---- libnm-core/nm-setting-wired.c | 19 ++++++------ libnm-core/nm-setting-wireless-security.c | 22 ++++++------- libnm-core/nm-setting-wireless.c | 19 ++++++------ libnm-core/nm-setting-wpan.c | 11 ++++--- libnm-util/nm-setting-connection.c | 1 - 44 files changed, 315 insertions(+), 363 deletions(-) diff --git a/libnm-core/nm-setting-6lowpan.c b/libnm-core/nm-setting-6lowpan.c index 647fef3f5d..bcfb2fbf4d 100644 --- a/libnm-core/nm-setting-6lowpan.c +++ b/libnm-core/nm-setting-6lowpan.c @@ -196,17 +196,18 @@ finalize (GObject *object) } static void -nm_setting_6lowpan_class_init (NMSetting6LowpanClass *setting_class) +nm_setting_6lowpan_class_init (NMSetting6LowpanClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSetting6LowpanPrivate)); + g_type_class_add_private (klass, sizeof (NMSetting6LowpanPrivate)); object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; + + setting_class->verify = verify; /** * NMSetting6Lowpan:parent: diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index c21197ee25..2581eb15a8 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -3761,22 +3761,19 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) +nm_setting_802_1x_class_init (NMSetting8021xClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSetting8021xPrivate)); + g_type_class_add_private (klass, sizeof (NMSetting8021xPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->need_secrets = need_secrets; - - /* Properties */ + setting_class->verify = verify; + setting_class->need_secrets = need_secrets; /** * NMSetting8021x:eap: diff --git a/libnm-core/nm-setting-adsl.c b/libnm-core/nm-setting-adsl.c index 278efe780e..b8e85bb609 100644 --- a/libnm-core/nm-setting-adsl.c +++ b/libnm-core/nm-setting-adsl.c @@ -345,22 +345,20 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) +nm_setting_adsl_class_init (NMSettingAdslClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingAdslPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingAdslPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->verify_secrets = verify_secrets; - parent_class->need_secrets = need_secrets; - /* Properties */ + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; /** * NMSettingAdsl:username: diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index 21401489c5..43573c4fee 100644 --- a/libnm-core/nm-setting-bluetooth.c +++ b/libnm-core/nm-setting-bluetooth.c @@ -282,20 +282,18 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_bluetooth_class_init (NMSettingBluetoothClass *setting_class) +nm_setting_bluetooth_class_init (NMSettingBluetoothClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingBluetoothPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingBluetoothPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; /** * NMSettingBluetooth:bdaddr: @@ -309,7 +307,7 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_BLUETOOTH_BDADDR, + _nm_setting_class_transform_property (setting_class, NM_SETTING_BLUETOOTH_BDADDR, G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index a35e48529a..8a81f4baa3 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -872,7 +872,7 @@ compare_property (NMSetting *setting, const GParamSpec *prop_spec, NMSettingCompareFlags flags) { - NMSettingClass *parent_class; + NMSettingClass *setting_class; if (nm_streq0 (prop_spec->name, NM_SETTING_BOND_OPTIONS)) { return options_equal (NM_SETTING_BOND (setting), @@ -881,9 +881,8 @@ compare_property (NMSetting *setting, flags); } - /* Otherwise chain up to parent to handle generic compare */ - parent_class = NM_SETTING_CLASS (nm_setting_bond_parent_class); - return parent_class->compare_property (setting, other, prop_spec, flags); + setting_class = NM_SETTING_CLASS (nm_setting_bond_parent_class); + return setting_class->compare_property (setting, other, prop_spec, flags); } /*****************************************************************************/ @@ -960,21 +959,20 @@ finalize (GObject *object) } static void -nm_setting_bond_class_init (NMSettingBondClass *setting_class) +nm_setting_bond_class_init (NMSettingBondClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingBondPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingBondPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->compare_property = compare_property; - /* Properties */ + setting_class->verify = verify; + setting_class->compare_property = compare_property; + /** * NMSettingBond:options: (type GHashTable(utf8,utf8)): * @@ -996,10 +994,10 @@ nm_setting_bond_class_init (NMSettingBondClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_BOND_OPTIONS, - G_VARIANT_TYPE ("a{ss}"), - _nm_utils_strdict_to_dbus, - _nm_utils_strdict_from_dbus); + _nm_setting_class_transform_property (setting_class, NM_SETTING_BOND_OPTIONS, + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); /* ---dbus--- * property: interface-name @@ -1009,8 +1007,8 @@ nm_setting_bond_class_init (NMSettingBondClass *setting_class) * bond's interface name. * ---end--- */ - _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", - G_VARIANT_TYPE_STRING, - _nm_setting_get_deprecated_virtual_interface_name, - NULL); + _nm_setting_class_add_dbus_only_property (setting_class, "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); } diff --git a/libnm-core/nm-setting-bridge-port.c b/libnm-core/nm-setting-bridge-port.c index 9ca478c8d3..c5df109101 100644 --- a/libnm-core/nm-setting-bridge-port.c +++ b/libnm-core/nm-setting-bridge-port.c @@ -211,19 +211,18 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_bridge_port_class_init (NMSettingBridgePortClass *setting_class) +nm_setting_bridge_port_class_init (NMSettingBridgePortClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingBridgePortPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingBridgePortPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; + /** * NMSettingBridgePort:priority: * diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c index 1011dc9d53..d8efca6eae 100644 --- a/libnm-core/nm-setting-bridge.c +++ b/libnm-core/nm-setting-bridge.c @@ -392,20 +392,19 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) +nm_setting_bridge_class_init (NMSettingBridgeClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingBridgePrivate)); + g_type_class_add_private (klass, sizeof (NMSettingBridgePrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; + /** * NMSettingBridge:mac-address: * @@ -443,7 +442,7 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_BRIDGE_MAC_ADDRESS, + _nm_setting_class_transform_property (setting_class, NM_SETTING_BRIDGE_MAC_ADDRESS, G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); @@ -637,7 +636,7 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) * bridge's interface name. * ---end--- */ - _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + _nm_setting_class_add_dbus_only_property (setting_class, "interface-name", G_VARIANT_TYPE_STRING, _nm_setting_get_deprecated_virtual_interface_name, NULL); diff --git a/libnm-core/nm-setting-cdma.c b/libnm-core/nm-setting-cdma.c index bf606f9022..880f926eff 100644 --- a/libnm-core/nm-setting-cdma.c +++ b/libnm-core/nm-setting-cdma.c @@ -284,22 +284,20 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) +nm_setting_cdma_class_init (NMSettingCdmaClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingCdmaPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingCdmaPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->verify_secrets = verify_secrets; - parent_class->need_secrets = need_secrets; - /* Properties */ + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; /** * NMSettingCdma:number: diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index c4190831b1..b7066fc48f 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -1268,7 +1268,6 @@ compare_property (NMSetting *setting, && g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_TIMESTAMP) == 0) return TRUE; - /* Otherwise chain up to parent to handle generic compare */ return NM_SETTING_CLASS (nm_setting_connection_parent_class)->compare_property (setting, other, prop_spec, flags); } @@ -1503,21 +1502,19 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) +nm_setting_connection_class_init (NMSettingConnectionClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingConnectionPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingConnectionPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->compare_property = compare_property; - /* Properties */ + setting_class->verify = verify; + setting_class->compare_property = compare_property; /** * NMSettingConnection:id: @@ -1654,7 +1651,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (parent_class, NM_SETTING_CONNECTION_INTERFACE_NAME, + _nm_setting_class_override_property (setting_class, NM_SETTING_CONNECTION_INTERFACE_NAME, G_VARIANT_TYPE_STRING, NULL, nm_setting_connection_set_interface_name, diff --git a/libnm-core/nm-setting-dcb.c b/libnm-core/nm-setting-dcb.c index 6471519607..f57f2694a6 100644 --- a/libnm-core/nm-setting-dcb.c +++ b/libnm-core/nm-setting-dcb.c @@ -906,20 +906,19 @@ finalize (GObject *object) } static void -nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) +nm_setting_dcb_class_init (NMSettingDcbClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingDcbPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingDcbPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; + /** * NMSettingDcb:app-fcoe-flags: * @@ -1118,7 +1117,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, + _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1166,7 +1165,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_GROUP_ID, + _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_GROUP_ID, G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1192,7 +1191,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, + _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1220,7 +1219,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_BANDWIDTH, + _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_BANDWIDTH, G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1246,7 +1245,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, + _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1271,7 +1270,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, + _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); diff --git a/libnm-core/nm-setting-dummy.c b/libnm-core/nm-setting-dummy.c index 38c361f198..d43bbc7e53 100644 --- a/libnm-core/nm-setting-dummy.c +++ b/libnm-core/nm-setting-dummy.c @@ -67,9 +67,9 @@ nm_setting_dummy_init (NMSettingDummy *setting) } static void -nm_setting_dummy_class_init (NMSettingDummyClass *setting_class) +nm_setting_dummy_class_init (NMSettingDummyClass *klass) { - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - parent_class->verify = verify; + setting_class->verify = verify; } diff --git a/libnm-core/nm-setting-generic.c b/libnm-core/nm-setting-generic.c index 0c85d448ce..566d5826ae 100644 --- a/libnm-core/nm-setting-generic.c +++ b/libnm-core/nm-setting-generic.c @@ -66,7 +66,7 @@ nm_setting_generic_init (NMSettingGeneric *setting) } static void -nm_setting_generic_class_init (NMSettingGenericClass *setting_class) +nm_setting_generic_class_init (NMSettingGenericClass *klass) { - g_type_class_add_private (setting_class, sizeof (NMSettingGenericPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingGenericPrivate)); } diff --git a/libnm-core/nm-setting-gsm.c b/libnm-core/nm-setting-gsm.c index b1ab193aa1..fce5fe262f 100644 --- a/libnm-core/nm-setting-gsm.c +++ b/libnm-core/nm-setting-gsm.c @@ -603,22 +603,20 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) +nm_setting_gsm_class_init (NMSettingGsmClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingGsmPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingGsmPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->verify_secrets = verify_secrets; - parent_class->need_secrets = need_secrets; - /* Properties */ + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; /** * NMSettingGsm:number: @@ -821,10 +819,10 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) G_PARAM_STATIC_STRINGS)); /* Ignore incoming deprecated properties */ - _nm_setting_class_add_dbus_only_property (parent_class, "allowed-bands", + _nm_setting_class_add_dbus_only_property (setting_class, "allowed-bands", G_VARIANT_TYPE_UINT32, NULL, NULL); - _nm_setting_class_add_dbus_only_property (parent_class, "network-type", + _nm_setting_class_add_dbus_only_property (setting_class, "network-type", G_VARIANT_TYPE_INT32, NULL, NULL); } diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index b22a260e5e..75a2b3c92e 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -377,21 +377,19 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) +nm_setting_infiniband_class_init (NMSettingInfinibandClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingInfinibandPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingInfinibandPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; + setting_class->verify = verify; - /* Properties */ /** * NMSettingInfiniband:mac-address: * @@ -424,7 +422,7 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_INFINIBAND_MAC_ADDRESS, + _nm_setting_class_transform_property (setting_class, NM_SETTING_INFINIBAND_MAC_ADDRESS, G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index fa5aa60f1a..c3ad316632 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -2621,7 +2621,7 @@ compare_property (NMSetting *setting, NMSettingCompareFlags flags) { NMSettingIPConfigPrivate *a_priv, *b_priv; - NMSettingClass *parent_class; + NMSettingClass *setting_class; guint i; if (nm_streq (prop_spec->name, NM_SETTING_IP_CONFIG_ADDRESSES)) { @@ -2650,9 +2650,8 @@ compare_property (NMSetting *setting, return TRUE; } - /* Otherwise chain up to parent to handle generic compare */ - parent_class = NM_SETTING_CLASS (nm_setting_ip_config_parent_class); - return parent_class->compare_property (setting, other, prop_spec, flags); + setting_class = NM_SETTING_CLASS (nm_setting_ip_config_parent_class); + return setting_class->compare_property (setting, other, prop_spec, flags); } /*****************************************************************************/ @@ -2880,21 +2879,19 @@ ip_gateway_set (NMSetting *setting, } static void -nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class) +nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingIPConfigPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingIPConfigPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->compare_property = compare_property; - /* Properties */ + setting_class->verify = verify; + setting_class->compare_property = compare_property; /** * NMSettingIPConfig:method: @@ -3044,7 +3041,7 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (parent_class, + _nm_setting_class_override_property (setting_class, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING, NULL, diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c index 12ccd6a949..5dcb4d62ef 100644 --- a/libnm-core/nm-setting-ip-tunnel.c +++ b/libnm-core/nm-setting-ip-tunnel.c @@ -622,18 +622,18 @@ finalize (GObject *object) } static void -nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *setting_class) +nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingIPTunnelPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingIPTunnelPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; + + setting_class->verify = verify; /** * NMSettingIPTunnel:parent: diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index a88a3f2b9c..d3e2ca3708 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -524,20 +524,18 @@ ip4_route_data_set (NMSetting *setting, } static void -nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class) +nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *klass) { - NMSettingClass *setting_class = NM_SETTING_CLASS (ip4_class); - GObjectClass *object_class = G_OBJECT_CLASS (ip4_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); g_type_class_add_private (setting_class, sizeof (NMSettingIP4ConfigPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; - /* properties */ + setting_class->verify = verify; /* ---ifcfg-rh--- * property: method diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 76a68aa085..3f49fc976e 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -548,20 +548,18 @@ finalize (GObject *object) } static void -nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) +nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (ip6_class); - NMSettingClass *setting_class = NM_SETTING_CLASS (ip6_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (ip6_class, sizeof (NMSettingIP6ConfigPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingIP6ConfigPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; - setting_class->verify = verify; + object_class->finalize = finalize; - /* Properties */ + setting_class->verify = verify; /* ---ifcfg-rh--- * property: method diff --git a/libnm-core/nm-setting-macsec.c b/libnm-core/nm-setting-macsec.c index aca6d6cf70..c8969f068a 100644 --- a/libnm-core/nm-setting-macsec.c +++ b/libnm-core/nm-setting-macsec.c @@ -473,18 +473,19 @@ finalize (GObject *object) } static void -nm_setting_macsec_class_init (NMSettingMacsecClass *setting_class) +nm_setting_macsec_class_init (NMSettingMacsecClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingMacsecPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingMacsecPrivate)); object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->need_secrets = need_secrets; + + setting_class->verify = verify; + setting_class->need_secrets = need_secrets; /** * NMSettingMacsec:parent: diff --git a/libnm-core/nm-setting-macvlan.c b/libnm-core/nm-setting-macvlan.c index b3934bb58d..90934555fa 100644 --- a/libnm-core/nm-setting-macvlan.c +++ b/libnm-core/nm-setting-macvlan.c @@ -259,20 +259,18 @@ finalize (GObject *object) } static void -nm_setting_macvlan_class_init (NMSettingMacvlanClass *setting_class) +nm_setting_macvlan_class_init (NMSettingMacvlanClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingMacvlanPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingMacvlanPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; /** * NMSettingMacvlan:parent: diff --git a/libnm-core/nm-setting-olpc-mesh.c b/libnm-core/nm-setting-olpc-mesh.c index 13ba22f0d0..68e84db0dd 100644 --- a/libnm-core/nm-setting-olpc-mesh.c +++ b/libnm-core/nm-setting-olpc-mesh.c @@ -213,20 +213,19 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *setting_class) +nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingOlpcMeshPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingOlpcMeshPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; + /** * NMSettingOlpcMesh:ssid: * @@ -267,7 +266,7 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *setting_class) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, + _nm_setting_class_transform_property (setting_class, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); diff --git a/libnm-core/nm-setting-ovs-bridge.c b/libnm-core/nm-setting-ovs-bridge.c index cf7495bed5..1ec364b6df 100644 --- a/libnm-core/nm-setting-ovs-bridge.c +++ b/libnm-core/nm-setting-ovs-bridge.c @@ -263,15 +263,16 @@ finalize (GObject *object) } static void -nm_setting_ovs_bridge_class_init (NMSettingOvsBridgeClass *setting_class) +nm_setting_ovs_bridge_class_init (NMSettingOvsBridgeClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; - parent_class->verify = verify; + object_class->finalize = finalize; + + setting_class->verify = verify; /** * NMSettingOvsBridge:fail-mode: diff --git a/libnm-core/nm-setting-ovs-interface.c b/libnm-core/nm-setting-ovs-interface.c index f674f3655c..51e6e47bc7 100644 --- a/libnm-core/nm-setting-ovs-interface.c +++ b/libnm-core/nm-setting-ovs-interface.c @@ -362,15 +362,16 @@ finalize (GObject *object) } static void -nm_setting_ovs_interface_class_init (NMSettingOvsInterfaceClass *setting_class) +nm_setting_ovs_interface_class_init (NMSettingOvsInterfaceClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; - parent_class->verify = verify; + object_class->finalize = finalize; + + setting_class->verify = verify; /** * NMSettingOvsInterface:type: diff --git a/libnm-core/nm-setting-ovs-patch.c b/libnm-core/nm-setting-ovs-patch.c index bed46256fb..0986af8f93 100644 --- a/libnm-core/nm-setting-ovs-patch.c +++ b/libnm-core/nm-setting-ovs-patch.c @@ -181,15 +181,16 @@ finalize (GObject *object) } static void -nm_setting_ovs_patch_class_init (NMSettingOvsPatchClass *setting_class) +nm_setting_ovs_patch_class_init (NMSettingOvsPatchClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; - parent_class->verify = verify; + object_class->finalize = finalize; + + setting_class->verify = verify; /** * NMSettingOvsPatch:peer: diff --git a/libnm-core/nm-setting-ovs-port.c b/libnm-core/nm-setting-ovs-port.c index df18ec0a97..eb593e8042 100644 --- a/libnm-core/nm-setting-ovs-port.c +++ b/libnm-core/nm-setting-ovs-port.c @@ -360,15 +360,16 @@ finalize (GObject *object) } static void -nm_setting_ovs_port_class_init (NMSettingOvsPortClass *setting_class) +nm_setting_ovs_port_class_init (NMSettingOvsPortClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; - parent_class->verify = verify; + object_class->finalize = finalize; + + setting_class->verify = verify; /** * NMSettingOvsPort:vlan-mode: diff --git a/libnm-core/nm-setting-ppp.c b/libnm-core/nm-setting-ppp.c index 4702d8a042..0388884a5c 100644 --- a/libnm-core/nm-setting-ppp.c +++ b/libnm-core/nm-setting-ppp.c @@ -524,19 +524,18 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_ppp_class_init (NMSettingPppClass *setting_class) +nm_setting_ppp_class_init (NMSettingPppClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingPppPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingPppPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; + /** * NMSettingPpp:noauth: * diff --git a/libnm-core/nm-setting-pppoe.c b/libnm-core/nm-setting-pppoe.c index da5bfc9d0c..e3c126a001 100644 --- a/libnm-core/nm-setting-pppoe.c +++ b/libnm-core/nm-setting-pppoe.c @@ -287,21 +287,20 @@ finalize (GObject *object) } static void -nm_setting_pppoe_class_init (NMSettingPppoeClass *setting_class) +nm_setting_pppoe_class_init (NMSettingPppoeClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingPppoePrivate)); + g_type_class_add_private (klass, sizeof (NMSettingPppoePrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->need_secrets = need_secrets; - /* Properties */ + setting_class->verify = verify; + setting_class->need_secrets = need_secrets; + /** * NMSettingPppoe:parent: * diff --git a/libnm-core/nm-setting-proxy.c b/libnm-core/nm-setting-proxy.c index c32abd824e..6a30ffd9e2 100644 --- a/libnm-core/nm-setting-proxy.c +++ b/libnm-core/nm-setting-proxy.c @@ -284,18 +284,18 @@ set_property (GObject *object, guint prop_id, } static void -nm_setting_proxy_class_init (NMSettingProxyClass *setting_class) +nm_setting_proxy_class_init (NMSettingProxyClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingProxyPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingProxyPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; - parent_class->verify = verify; + object_class->finalize = finalize; + + setting_class->verify = verify; /** * NMSettingProxy:method: diff --git a/libnm-core/nm-setting-serial.c b/libnm-core/nm-setting-serial.c index e73bac8d8a..33414430f9 100644 --- a/libnm-core/nm-setting-serial.c +++ b/libnm-core/nm-setting-serial.c @@ -237,19 +237,16 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_serial_class_init (NMSettingSerialClass *setting_class) +nm_setting_serial_class_init (NMSettingSerialClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingSerialPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingSerialPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; - /* Properties */ - /** * NMSettingSerial:baud: * @@ -306,7 +303,7 @@ nm_setting_serial_class_init (NMSettingSerialClass *setting_class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, + _nm_setting_class_transform_property (setting_class, NM_SETTING_SERIAL_PARITY, G_VARIANT_TYPE_BYTE, parity_to_dbus, diff --git a/libnm-core/nm-setting-sriov.c b/libnm-core/nm-setting-sriov.c index 29161c8cd9..4947ede4e3 100644 --- a/libnm-core/nm-setting-sriov.c +++ b/libnm-core/nm-setting-sriov.c @@ -1197,7 +1197,7 @@ compare_property (NMSetting *setting, { NMSettingSriov *a = NM_SETTING_SRIOV (setting); NMSettingSriov *b = NM_SETTING_SRIOV (other); - NMSettingClass *parent_class; + NMSettingClass *setting_class; guint i; if (nm_streq (prop_spec->name, NM_SETTING_SRIOV_VFS)) { @@ -1210,9 +1210,8 @@ compare_property (NMSetting *setting, return TRUE; } - /* Otherwise chain up to parent to handle generic compare */ - parent_class = NM_SETTING_CLASS (nm_setting_sriov_parent_class); - return parent_class->compare_property (setting, other, prop_spec, flags); + setting_class = NM_SETTING_CLASS (nm_setting_sriov_parent_class); + return setting_class->compare_property (setting, other, prop_spec, flags); } static void @@ -1232,16 +1231,17 @@ finalize (GObject *object) } static void -nm_setting_sriov_class_init (NMSettingSriovClass *setting_class) +nm_setting_sriov_class_init (NMSettingSriovClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - object_class->finalize = finalize; object_class->get_property = get_property; object_class->set_property = set_property; - parent_class->compare_property = compare_property; - parent_class->verify = verify; + object_class->finalize = finalize; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; /** * NMSettingSriov:total-vfs @@ -1308,7 +1308,7 @@ nm_setting_sriov_class_init (NMSettingSriovClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (parent_class, + _nm_setting_class_override_property (setting_class, NM_SETTING_SRIOV_VFS, G_VARIANT_TYPE ("aa{sv}"), vfs_to_dbus, diff --git a/libnm-core/nm-setting-tc-config.c b/libnm-core/nm-setting-tc-config.c index 588446e5dd..619881ab0a 100644 --- a/libnm-core/nm-setting-tc-config.c +++ b/libnm-core/nm-setting-tc-config.c @@ -1242,7 +1242,7 @@ compare_property (NMSetting *setting, { NMSettingTCConfig *a_tc_config = NM_SETTING_TC_CONFIG (setting); NMSettingTCConfig *b_tc_config = NM_SETTING_TC_CONFIG (other); - NMSettingClass *parent_class; + NMSettingClass *setting_class; guint i; if (nm_streq (prop_spec->name, NM_SETTING_TC_CONFIG_QDISCS)) { @@ -1265,9 +1265,8 @@ compare_property (NMSetting *setting, return TRUE; } - /* Otherwise chain up to parent to handle generic compare */ - parent_class = NM_SETTING_CLASS (nm_setting_tc_config_parent_class); - return parent_class->compare_property (setting, other, prop_spec, flags); + setting_class = NM_SETTING_CLASS (nm_setting_tc_config_parent_class); + return setting_class->compare_property (setting, other, prop_spec, flags); } static void @@ -1589,19 +1588,17 @@ tc_tfilters_set (NMSetting *setting, } static void -nm_setting_tc_config_class_init (NMSettingTCConfigClass *setting_class) +nm_setting_tc_config_class_init (NMSettingTCConfigClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->compare_property = compare_property; - parent_class->verify = verify; - /* Properties */ + setting_class->compare_property = compare_property; + setting_class->verify = verify; /** * NMSettingTCConfig:qdiscs: (type GPtrArray(NMTCQdisc)) @@ -1623,7 +1620,7 @@ nm_setting_tc_config_class_init (NMSettingTCConfigClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (parent_class, + _nm_setting_class_override_property (setting_class, NM_SETTING_TC_CONFIG_QDISCS, G_VARIANT_TYPE ("aa{sv}"), tc_qdiscs_get, @@ -1650,7 +1647,7 @@ nm_setting_tc_config_class_init (NMSettingTCConfigClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (parent_class, + _nm_setting_class_override_property (setting_class, NM_SETTING_TC_CONFIG_TFILTERS, G_VARIANT_TYPE ("aa{sv}"), tc_tfilters_get, diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index d6412224e2..343f1e727b 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -408,7 +408,7 @@ compare_property (NMSetting *setting, const GParamSpec *prop_spec, NMSettingCompareFlags flags) { - NMSettingClass *parent_class; + NMSettingClass *setting_class; NMSettingTeamPortPrivate *a_priv, *b_priv; guint i, j; @@ -442,9 +442,8 @@ compare_property (NMSetting *setting, return TRUE; } - /* Otherwise chain up to parent to handle generic compare */ - parent_class = NM_SETTING_CLASS (nm_setting_team_port_parent_class); - return parent_class->compare_property (setting, other, prop_spec, flags); + setting_class = NM_SETTING_CLASS (nm_setting_team_port_parent_class); + return setting_class->compare_property (setting, other, prop_spec, flags); } static void @@ -587,21 +586,20 @@ finalize (GObject *object) } static void -nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class) +nm_setting_team_port_class_init (NMSettingTeamPortClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingTeamPortPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingTeamPortPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->compare_property = compare_property; - parent_class->verify = verify; - /* Properties */ + setting_class->compare_property = compare_property; + setting_class->verify = verify; + /** * NMSettingTeamPort:config: * @@ -715,7 +713,7 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class) G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, + _nm_setting_class_transform_property (setting_class, NM_SETTING_TEAM_PORT_LINK_WATCHERS, G_VARIANT_TYPE ("aa{sv}"), team_link_watchers_to_dbus, diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index 1718b3e55f..fce3c42d51 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -1238,7 +1238,7 @@ compare_property (NMSetting *setting, NMSettingCompareFlags flags) { NMSettingTeamPrivate *a_priv, *b_priv; - NMSettingClass *parent_class; + NMSettingClass *setting_class; guint i, j; /* If we are trying to match a connection in order to assume it (and thus @@ -1271,9 +1271,8 @@ compare_property (NMSetting *setting, return TRUE; } - /* Otherwise chain up to parent to handle generic compare */ - parent_class = NM_SETTING_CLASS (nm_setting_team_parent_class); - return parent_class->compare_property (setting, other, prop_spec, flags); + setting_class = NM_SETTING_CLASS (nm_setting_team_parent_class); + return setting_class->compare_property (setting, other, prop_spec, flags); } static void @@ -1558,21 +1557,20 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_team_class_init (NMSettingTeamClass *setting_class) +nm_setting_team_class_init (NMSettingTeamClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingTeamPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingTeamPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->compare_property = compare_property; - parent_class->verify = verify; - /* Properties */ + setting_class->compare_property = compare_property; + setting_class->verify = verify; + /** * NMSettingTeam:config: * @@ -1818,7 +1816,7 @@ nm_setting_team_class_init (NMSettingTeamClass *setting_class) G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, + _nm_setting_class_transform_property (setting_class, NM_SETTING_TEAM_LINK_WATCHERS, G_VARIANT_TYPE ("aa{sv}"), team_link_watchers_to_dbus, @@ -1832,7 +1830,7 @@ nm_setting_team_class_init (NMSettingTeamClass *setting_class) * team's interface name. * ---end--- */ - _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + _nm_setting_class_add_dbus_only_property (setting_class, "interface-name", G_VARIANT_TYPE_STRING, _nm_setting_get_deprecated_virtual_interface_name, NULL); diff --git a/libnm-core/nm-setting-tun.c b/libnm-core/nm-setting-tun.c index de39439557..a723bf3eb5 100644 --- a/libnm-core/nm-setting-tun.c +++ b/libnm-core/nm-setting-tun.c @@ -291,20 +291,19 @@ finalize (GObject *object) } static void -nm_setting_tun_class_init (NMSettingTunClass *setting_class) +nm_setting_tun_class_init (NMSettingTunClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingTunPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingTunPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; + /** * NMSettingTun:mode: * diff --git a/libnm-core/nm-setting-user.c b/libnm-core/nm-setting-user.c index db28c554c1..1a6ddf220e 100644 --- a/libnm-core/nm-setting-user.c +++ b/libnm-core/nm-setting-user.c @@ -552,8 +552,9 @@ nm_setting_user_class_init (NMSettingUserClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->compare_property = compare_property; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingUser:data: (type GHashTable(utf8,utf8)) diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index b9bea9e4cd..897a66b75a 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -830,20 +830,18 @@ finalize (GObject *object) } static void -nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) +nm_setting_vlan_class_init (NMSettingVlanClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingVlanPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingVlanPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; /** * NMSettingVlan:parent: @@ -920,7 +918,7 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (parent_class, NM_SETTING_VLAN_FLAGS, + _nm_setting_class_override_property (setting_class, NM_SETTING_VLAN_FLAGS, NULL, _override_flags_get, NULL, @@ -986,7 +984,7 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) * vlan's interface name. * ---end--- */ - _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + _nm_setting_class_add_dbus_only_property (setting_class, "interface-name", G_VARIANT_TYPE_STRING, _nm_setting_get_deprecated_virtual_interface_name, NULL); diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c index d36ce93485..0672a8101f 100644 --- a/libnm-core/nm-setting-vpn.c +++ b/libnm-core/nm-setting-vpn.c @@ -888,27 +888,25 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_vpn_class_init (NMSettingVpnClass *setting_class) +nm_setting_vpn_class_init (NMSettingVpnClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingVpnPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingVpnPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->update_one_secret = update_one_secret; - parent_class->get_secret_flags = get_secret_flags; - parent_class->set_secret_flags = set_secret_flags; - parent_class->need_secrets = need_secrets; - parent_class->compare_property = compare_property; - parent_class->clear_secrets_with_flags = clear_secrets_with_flags; + setting_class->verify = verify; + setting_class->update_one_secret = update_one_secret; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; + setting_class->need_secrets = need_secrets; + setting_class->compare_property = compare_property; + setting_class->clear_secrets_with_flags = clear_secrets_with_flags; - /* Properties */ /** * NMSettingVpn:service-type: * @@ -974,7 +972,7 @@ nm_setting_vpn_class_init (NMSettingVpnClass *setting_class) G_TYPE_HASH_TABLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_VPN_DATA, + _nm_setting_class_transform_property (setting_class, NM_SETTING_VPN_DATA, G_VARIANT_TYPE ("a{ss}"), _nm_utils_strdict_to_dbus, _nm_utils_strdict_from_dbus); @@ -1000,7 +998,7 @@ nm_setting_vpn_class_init (NMSettingVpnClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_VPN_SECRETS, + _nm_setting_class_transform_property (setting_class, NM_SETTING_VPN_SECRETS, G_VARIANT_TYPE ("a{ss}"), _nm_utils_strdict_to_dbus, _nm_utils_strdict_from_dbus); diff --git a/libnm-core/nm-setting-vxlan.c b/libnm-core/nm-setting-vxlan.c index c76ac6229b..443ebdafb8 100644 --- a/libnm-core/nm-setting-vxlan.c +++ b/libnm-core/nm-setting-vxlan.c @@ -564,20 +564,18 @@ finalize (GObject *object) } static void -nm_setting_vxlan_class_init (NMSettingVxlanClass *setting_class) +nm_setting_vxlan_class_init (NMSettingVxlanClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingVxlanPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingVxlanPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; /** * NMSettingVxlan:parent: diff --git a/libnm-core/nm-setting-wimax.c b/libnm-core/nm-setting-wimax.c index 0669b09e4f..852ba755ec 100644 --- a/libnm-core/nm-setting-wimax.c +++ b/libnm-core/nm-setting-wimax.c @@ -206,20 +206,19 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) +nm_setting_wimax_class_init (NMSettingWimaxClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingWimaxPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingWimaxPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - /* Properties */ + setting_class->verify = verify; + /** * NMSettingWimax:network-name: * @@ -250,7 +249,7 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, NM_SETTING_WIMAX_MAC_ADDRESS, + _nm_setting_class_transform_property (setting_class, NM_SETTING_WIMAX_MAC_ADDRESS, G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c index 104451e2d0..0dcd1c25b4 100644 --- a/libnm-core/nm-setting-wired.c +++ b/libnm-core/nm-setting-wired.c @@ -782,15 +782,15 @@ compare_property (NMSetting *setting, const GParamSpec *prop_spec, NMSettingCompareFlags flags) { - NMSettingClass *parent_class; + NMSettingClass *setting_class; if (nm_streq (prop_spec->name, NM_SETTING_WIRED_CLONED_MAC_ADDRESS)) { return nm_streq0 (NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address, NM_SETTING_WIRED_GET_PRIVATE (other)->cloned_mac_address); } - parent_class = NM_SETTING_CLASS (nm_setting_wired_parent_class); - return parent_class->compare_property (setting, other, prop_spec, flags); + setting_class = NM_SETTING_CLASS (nm_setting_wired_parent_class); + return setting_class->compare_property (setting, other, prop_spec, flags); } static GVariant * @@ -977,21 +977,20 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_wired_class_init (NMSettingWiredClass *setting_wired_class) +nm_setting_wired_class_init (NMSettingWiredClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_wired_class); - NMSettingClass *setting_class = NM_SETTING_CLASS (setting_wired_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_wired_class, sizeof (NMSettingWiredPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingWiredPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + + setting_class->verify = verify; setting_class->compare_property = compare_property; - /* Properties */ /** * NMSettingWired:port: * diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c index 7ba038e490..22177c46b5 100644 --- a/libnm-core/nm-setting-wireless-security.c +++ b/libnm-core/nm-setting-wireless-security.c @@ -1430,25 +1430,23 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting_class) +nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_class, sizeof (NMSettingWirelessSecurityPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingWirelessSecurityPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->verify_secrets = verify_secrets; - parent_class->need_secrets = need_secrets; - parent_class->get_secret_flags = get_secret_flags; - parent_class->set_secret_flags = set_secret_flags; + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; - /* Properties */ /** * NMSettingWirelessSecurity:key-mgmt: * @@ -1855,7 +1853,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (parent_class, + _nm_setting_class_transform_property (setting_class, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, G_VARIANT_TYPE_UINT32, wep_key_type_to_dbus, diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 40708e1729..bebfade5c7 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -936,15 +936,15 @@ compare_property (NMSetting *setting, const GParamSpec *prop_spec, NMSettingCompareFlags flags) { - NMSettingClass *parent_class; + NMSettingClass *setting_class; if (nm_streq (prop_spec->name, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS)) { return nm_streq0 (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address, NM_SETTING_WIRELESS_GET_PRIVATE (other)->cloned_mac_address); } - parent_class = NM_SETTING_CLASS (nm_setting_wireless_parent_class); - return parent_class->compare_property (setting, other, prop_spec, flags); + setting_class = NM_SETTING_CLASS (nm_setting_wireless_parent_class); + return setting_class->compare_property (setting, other, prop_spec, flags); } /*****************************************************************************/ @@ -1175,21 +1175,20 @@ get_property (GObject *object, guint prop_id, } static void -nm_setting_wireless_class_init (NMSettingWirelessClass *setting_wireless_class) +nm_setting_wireless_class_init (NMSettingWirelessClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_wireless_class); - NMSettingClass *setting_class = NM_SETTING_CLASS (setting_wireless_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - g_type_class_add_private (setting_wireless_class, sizeof (NMSettingWirelessPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingWirelessPrivate)); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + + setting_class->verify = verify; setting_class->compare_property = compare_property; - /* Properties */ /** * NMSettingWireless:ssid: * diff --git a/libnm-core/nm-setting-wpan.c b/libnm-core/nm-setting-wpan.c index 32a9dd0050..4ba64158f8 100644 --- a/libnm-core/nm-setting-wpan.c +++ b/libnm-core/nm-setting-wpan.c @@ -214,17 +214,18 @@ finalize (GObject *object) } static void -nm_setting_wpan_class_init (NMSettingWpanClass *setting_wpan_class) +nm_setting_wpan_class_init (NMSettingWpanClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (setting_wpan_class); - NMSettingClass *setting_class = NM_SETTING_CLASS (setting_wpan_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); g_type_class_add_private (setting_class, sizeof (NMSettingWpanPrivate)); object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; - setting_class->verify = verify; + object_class->finalize = finalize; + + setting_class->verify = verify; /** * NMSettingWpan:mac-address: diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index e51d2c91da..c7da1aa46c 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -912,7 +912,6 @@ compare_property (NMSetting *setting, && g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_ID) == 0) return TRUE; - /* Otherwise chain up to parent to handle generic compare */ return NM_SETTING_CLASS (nm_setting_connection_parent_class)->compare_property (setting, other, prop_spec, flags); } From d70dcb16da42edcc8541f3816c45c181cd1d6947 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 1 Aug 2018 17:24:16 +0200 Subject: [PATCH 17/32] cli: fix nmc_setting_get_valid_properties() to use setting metadata Not all properties that we want to handle in nmcli are actual GObject properties. For the moment that was the case, but that's about to change. This is a change in behavior with respect of the order in which properties are reported. For example, print_setting_description() now prints the property descriptions in a different order. However, one might argue that this order makes more sense because: - it's the same order as properties are listed in "nm-meta-setting-desc.c". At that place, we have explict control over the order and set it intentionally to suite our needs best. The order of the GObject properties is much less well defined. - the order from "nm-meta-setting-desc.c" is used at several other places. So, it makes sense to use the same order everywhere. --- clients/cli/settings.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/clients/cli/settings.c b/clients/cli/settings.c index b39713f901..2c6baeb426 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -662,25 +662,19 @@ nmc_setting_remove_property_option (NMSetting *setting, char ** nmc_setting_get_valid_properties (NMSetting *setting) { - char **valid_props = NULL; - GParamSpec **props, **iter; - guint num; - int i; + const NMMetaSettingInfoEditor *setting_info; + char **valid_props; + guint i, num; - /* Iterate through properties */ - i = 0; - props = g_object_class_list_properties (G_OBJECT_GET_CLASS (G_OBJECT (setting)), &num); - valid_props = g_malloc0 (sizeof (char*) * (num + 1)); - for (iter = props; iter && *iter; iter++) { - const char *key_name = g_param_spec_get_name (*iter); + setting_info = nm_meta_setting_info_editor_find_by_setting (setting); - /* Add all properties except for "name" that is non-editable */ - if (g_strcmp0 (key_name, "name") != 0) - valid_props[i++] = g_strdup (key_name); - } - valid_props[i] = NULL; - g_free (props); + num = setting_info ? setting_info->properties_num : 0; + valid_props = g_new (char *, num + 1); + for (i = 0; i < num; i++) + valid_props[i] = g_strdup (setting_info->properties[i]->property_name); + + valid_props[num] = NULL; return valid_props; } From 9c47e2ce30e7b1f78c59fc72edca2def935261e0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 27 Jul 2018 14:08:14 +0200 Subject: [PATCH 18/32] libnm: use NMMetaSettingInfo for tracking setting priority Previously, each (non abstract) NMSetting class had to register its name and priority via _nm_register_setting(). Note, that libnm-core.la already links against "nm-meta-setting.c", which also redundantly keeps track of the settings name and gtype as well. Re-use NMMetaSettingInfo also in libnm-core.la, to track this meta data. The goal is to get rid of private data structures that track meta data about NMSetting classes. In this case, "registered_settings" hash. Instead, we should have one place where all this meta data is tracked. This was, it is also accessible as internal API, which can be useful (for keyfile). Note that NMSettingClass has some overlap with NMMetaSettingInfo. One difference is, that NMMetaSettingInfo is const, while NMSettingClass is only initialized during the class_init() method. Appart from that, it's mostly a matter of taste, whether we attach meta data to NMSettingClass, to NMMetaSettingInfo, or to a static-array indexed by NMMetaSettingType. Note, that previously, _nm_register_setting() was private API. That means, no user could subclass a functioning NMSetting instance. The same is still true: NMMetaSettingInfo is internal API and users cannot access it to create their own NMSetting subclasses. But that is almost desired. libnm is not designed, to be extensible via subclassing, nor is it clear why that would be a useful thing to do. One day, we should remove the NMSetting and NMSettingClass definitions from public headers. Their only use is subclassing the types, which however does not work. While libnm-core was linking already against nm-meta-setting.c, nm_meta_setting_infos was unreferenced. So, this change increases the binary size of libnm and NetworkManager (1032 bytes). Note however that roughly the same information was previously allocated at runtime. --- clients/common/nm-meta-setting-access.c | 55 ++--- libnm-core/nm-core-internal.h | 40 +--- libnm-core/nm-setting-6lowpan.c | 6 +- libnm-core/nm-setting-8021x.c | 4 +- libnm-core/nm-setting-adsl.c | 4 +- libnm-core/nm-setting-bluetooth.c | 6 +- libnm-core/nm-setting-bond.c | 4 +- libnm-core/nm-setting-bridge-port.c | 6 +- libnm-core/nm-setting-bridge.c | 6 +- libnm-core/nm-setting-cdma.c | 4 +- libnm-core/nm-setting-connection.c | 4 +- libnm-core/nm-setting-dcb.c | 6 +- libnm-core/nm-setting-dummy.c | 6 +- libnm-core/nm-setting-generic.c | 7 +- libnm-core/nm-setting-gsm.c | 4 +- libnm-core/nm-setting-infiniband.c | 6 +- libnm-core/nm-setting-ip-tunnel.c | 6 +- libnm-core/nm-setting-ip4-config.c | 6 +- libnm-core/nm-setting-ip6-config.c | 6 +- libnm-core/nm-setting-macsec.c | 4 +- libnm-core/nm-setting-macvlan.c | 6 +- libnm-core/nm-setting-olpc-mesh.c | 6 +- libnm-core/nm-setting-ovs-bridge.c | 6 +- libnm-core/nm-setting-ovs-interface.c | 6 +- libnm-core/nm-setting-ovs-patch.c | 6 +- libnm-core/nm-setting-ovs-port.c | 6 +- libnm-core/nm-setting-ppp.c | 4 +- libnm-core/nm-setting-pppoe.c | 4 +- libnm-core/nm-setting-private.h | 11 +- libnm-core/nm-setting-proxy.c | 6 +- libnm-core/nm-setting-serial.c | 5 +- libnm-core/nm-setting-sriov.c | 4 +- libnm-core/nm-setting-tc-config.c | 4 +- libnm-core/nm-setting-team-port.c | 4 +- libnm-core/nm-setting-team.c | 4 +- libnm-core/nm-setting-tun.c | 6 +- libnm-core/nm-setting-user.c | 4 +- libnm-core/nm-setting-vlan.c | 6 +- libnm-core/nm-setting-vpn.c | 4 +- libnm-core/nm-setting-vxlan.c | 6 +- libnm-core/nm-setting-wimax.c | 6 +- libnm-core/nm-setting-wired.c | 4 +- libnm-core/nm-setting-wireless-security.c | 4 +- libnm-core/nm-setting-wireless.c | 4 +- libnm-core/nm-setting-wpan.c | 6 +- libnm-core/nm-setting.c | 259 ++++------------------ libnm-core/nm-setting.h | 7 +- shared/nm-meta-setting.c | 87 +++++++- shared/nm-meta-setting.h | 83 ++++++- 49 files changed, 352 insertions(+), 406 deletions(-) diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index cebf8ba8af..bd4064ded9 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -23,24 +23,32 @@ /*****************************************************************************/ +static const NMMetaSettingInfoEditor * +_get_meta_setting_info_editor_from_msi (const NMMetaSettingInfo *meta_setting_info) +{ + const NMMetaSettingInfoEditor *setting_info; + + if (!meta_setting_info) + return NULL; + + nm_assert (meta_setting_info->get_setting_gtype); + nm_assert (meta_setting_info->meta_type < G_N_ELEMENTS (nm_meta_setting_infos_editor)); + + setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type]; + + nm_assert (setting_info->general == meta_setting_info); + return setting_info; +} + const NMMetaSettingInfoEditor * nm_meta_setting_info_editor_find_by_name (const char *setting_name, gboolean use_alias) { - const NMMetaSettingInfo *meta_setting_info; const NMMetaSettingInfoEditor *setting_info; guint i; g_return_val_if_fail (setting_name, NULL); - meta_setting_info = nm_meta_setting_infos_by_name (setting_name); - setting_info = NULL; - if (meta_setting_info) { - nm_assert (nm_streq0 (meta_setting_info->setting_name, setting_name)); - if (meta_setting_info->meta_type < G_N_ELEMENTS (nm_meta_setting_infos_editor)) { - setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type]; - nm_assert (setting_info->general == meta_setting_info); - } - } + setting_info = _get_meta_setting_info_editor_from_msi (nm_meta_setting_infos_by_name (setting_name)); if (!setting_info && use_alias) { for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { if (nm_streq0 (nm_meta_setting_infos_editor[i].alias, setting_name)) { @@ -56,25 +64,7 @@ nm_meta_setting_info_editor_find_by_name (const char *setting_name, gboolean use const NMMetaSettingInfoEditor * nm_meta_setting_info_editor_find_by_gtype (GType gtype) { - const NMMetaSettingInfo *meta_setting_info; - const NMMetaSettingInfoEditor *setting_info; - - meta_setting_info = nm_meta_setting_infos_by_gtype (gtype); - - if (!meta_setting_info) - return NULL; - - g_return_val_if_fail (meta_setting_info->get_setting_gtype, NULL); - g_return_val_if_fail (meta_setting_info->get_setting_gtype () == gtype, NULL); - - if (meta_setting_info->meta_type >= G_N_ELEMENTS (nm_meta_setting_infos_editor)) - return NULL; - - setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type]; - - g_return_val_if_fail (setting_info->general == meta_setting_info, NULL); - - return setting_info; + return _get_meta_setting_info_editor_from_msi (nm_meta_setting_infos_by_gtype (gtype)); } const NMMetaSettingInfoEditor * @@ -86,12 +76,13 @@ nm_meta_setting_info_editor_find_by_setting (NMSetting *setting) setting_info = nm_meta_setting_info_editor_find_by_gtype (G_OBJECT_TYPE (setting)); - nm_assert (setting_info == nm_meta_setting_info_editor_find_by_name (nm_setting_get_name (setting), FALSE)); - nm_assert (!setting_info || G_TYPE_CHECK_INSTANCE_TYPE (setting, setting_info->general->get_setting_gtype ())); - + nm_assert (setting_info); + nm_assert (G_TYPE_CHECK_INSTANCE_TYPE (setting, setting_info->general->get_setting_gtype ())); return setting_info; } +/*****************************************************************************/ + const NMMetaPropertyInfo * nm_meta_setting_info_editor_get_property_info (const NMMetaSettingInfoEditor *setting_info, const char *property_name) { diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 966566481b..b53f5c02f8 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -84,6 +84,7 @@ #include "nm-vpn-dbus-interface.h" #include "nm-core-types-internal.h" #include "nm-vpn-editor-plugin.h" +#include "nm-meta-setting.h" /* IEEE 802.1D-1998 timer values */ #define NM_BR_MIN_HELLO_TIME 1 @@ -168,45 +169,6 @@ NMConnection *_nm_simple_connection_new_from_dbus (GVariant *dict, NMSettingParseFlags parse_flags, GError **error); -/* - * A setting's priority should roughly follow the OSI layer model, but it also - * controls which settings get asked for secrets first. Thus settings which - * relate to things that must be working first, like hardware, should get a - * higher priority than things which layer on top of the hardware. For example, - * the GSM/CDMA settings should provide secrets before the PPP setting does, - * because a PIN is required to unlock the device before PPP can even start. - * Even settings without secrets should be assigned the right priority. - * - * 0: reserved for invalid - * - * 1: reserved for the Connection setting - * - * 2,3: hardware-related settings like Ethernet, Wi-Fi, InfiniBand, Bridge, etc. - * These priority 1 settings are also "base types", which means that at least - * one of them is required for the connection to be valid, and their name is - * valid in the 'type' property of the Connection setting. - * - * 4: hardware-related auxiliary settings that require a base setting to be - * successful first, like Wi-Fi security, 802.1x, etc. - * - * 5: hardware-independent settings that are required before IP connectivity - * can be established, like PPP, PPPoE, etc. - * - * 6: IP-level stuff - * - * 10: NMSettingUser - */ -typedef enum { /*< skip >*/ - NM_SETTING_PRIORITY_INVALID = 0, - NM_SETTING_PRIORITY_CONNECTION = 1, - NM_SETTING_PRIORITY_HW_BASE = 2, - NM_SETTING_PRIORITY_HW_NON_BASE = 3, - NM_SETTING_PRIORITY_HW_AUX = 4, - NM_SETTING_PRIORITY_AUX = 5, - NM_SETTING_PRIORITY_IP = 6, - NM_SETTING_PRIORITY_USER = 10, -} NMSettingPriority; - NMSettingPriority _nm_setting_get_setting_priority (NMSetting *setting); gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value); diff --git a/libnm-core/nm-setting-6lowpan.c b/libnm-core/nm-setting-6lowpan.c index bcfb2fbf4d..6d2b510799 100644 --- a/libnm-core/nm-setting-6lowpan.c +++ b/libnm-core/nm-setting-6lowpan.c @@ -51,8 +51,7 @@ struct _NMSetting6LowpanClass { * necessary for connection to 6LoWPAN interfaces. **/ -G_DEFINE_TYPE_WITH_CODE (NMSetting6Lowpan, nm_setting_6lowpan, NM_TYPE_SETTING, - _nm_register_setting (6LOWPAN, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSetting6Lowpan, nm_setting_6lowpan, NM_TYPE_SETTING) #define NM_SETTING_6LOWPAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_6LOWPAN, NMSetting6LowpanPrivate)) @@ -207,7 +206,8 @@ nm_setting_6lowpan_class_init (NMSetting6LowpanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_6LOWPAN]; + setting_class->verify = verify; /** * NMSetting6Lowpan:parent: diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 2581eb15a8..8c08bfa53b 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -60,8 +60,7 @@ * ISBN: 978-1587051548 **/ -G_DEFINE_TYPE_WITH_CODE (NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING, - _nm_register_setting (802_1X, NM_SETTING_PRIORITY_HW_AUX)) +G_DEFINE_TYPE (NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING) #define NM_SETTING_802_1X_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_802_1X, NMSetting8021xPrivate)) @@ -3772,6 +3771,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_802_1X]; setting_class->verify = verify; setting_class->need_secrets = need_secrets; diff --git a/libnm-core/nm-setting-adsl.c b/libnm-core/nm-setting-adsl.c index b8e85bb609..eb9aad41ab 100644 --- a/libnm-core/nm-setting-adsl.c +++ b/libnm-core/nm-setting-adsl.c @@ -37,8 +37,7 @@ * properties of ADSL connections. */ -G_DEFINE_TYPE_WITH_CODE (NMSettingAdsl, nm_setting_adsl, NM_TYPE_SETTING, - _nm_register_setting (ADSL, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingAdsl, nm_setting_adsl, NM_TYPE_SETTING) #define NM_SETTING_ADSL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_ADSL, NMSettingAdslPrivate)) @@ -356,6 +355,7 @@ nm_setting_adsl_class_init (NMSettingAdslClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_ADSL]; setting_class->verify = verify; setting_class->verify_secrets = verify_secrets; setting_class->need_secrets = need_secrets; diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index 43573c4fee..2cc3d7ad41 100644 --- a/libnm-core/nm-setting-bluetooth.c +++ b/libnm-core/nm-setting-bluetooth.c @@ -43,8 +43,7 @@ * Point (NAP) profiles. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingBluetooth, nm_setting_bluetooth, NM_TYPE_SETTING, - _nm_register_setting (BLUETOOTH, NM_SETTING_PRIORITY_HW_NON_BASE)) +G_DEFINE_TYPE (NMSettingBluetooth, nm_setting_bluetooth, NM_TYPE_SETTING) #define NM_SETTING_BLUETOOTH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothPrivate)) @@ -293,7 +292,8 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_BLUETOOTH]; + setting_class->verify = verify; /** * NMSettingBluetooth:bdaddr: diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 8a81f4baa3..53db178218 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -57,8 +57,7 @@ typedef struct { NMUtilsNamedValue *options_idx_cache; } NMSettingBondPrivate; -G_DEFINE_TYPE_WITH_CODE (NMSettingBond, nm_setting_bond, NM_TYPE_SETTING, - _nm_register_setting (BOND, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingBond, nm_setting_bond, NM_TYPE_SETTING) #define NM_SETTING_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BOND, NMSettingBondPrivate)) @@ -970,6 +969,7 @@ nm_setting_bond_class_init (NMSettingBondClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_BOND]; setting_class->verify = verify; setting_class->compare_property = compare_property; diff --git a/libnm-core/nm-setting-bridge-port.c b/libnm-core/nm-setting-bridge-port.c index c5df109101..23a431f4fe 100644 --- a/libnm-core/nm-setting-bridge-port.c +++ b/libnm-core/nm-setting-bridge-port.c @@ -40,8 +40,7 @@ * optional properties that apply to bridge ports. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingBridgePort, nm_setting_bridge_port, NM_TYPE_SETTING, - _nm_register_setting (BRIDGE_PORT, NM_SETTING_PRIORITY_AUX)) +G_DEFINE_TYPE (NMSettingBridgePort, nm_setting_bridge_port, NM_TYPE_SETTING) #define NM_SETTING_BRIDGE_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortPrivate)) @@ -221,7 +220,8 @@ nm_setting_bridge_port_class_init (NMSettingBridgePortClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_BRIDGE_PORT]; + setting_class->verify = verify; /** * NMSettingBridgePort:priority: diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c index d8efca6eae..951f35888b 100644 --- a/libnm-core/nm-setting-bridge.c +++ b/libnm-core/nm-setting-bridge.c @@ -38,8 +38,7 @@ * necessary for bridging connections. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingBridge, nm_setting_bridge, NM_TYPE_SETTING, - _nm_register_setting (BRIDGE, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingBridge, nm_setting_bridge, NM_TYPE_SETTING) #define NM_SETTING_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BRIDGE, NMSettingBridgePrivate)) @@ -403,7 +402,8 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_BRIDGE]; + setting_class->verify = verify; /** * NMSettingBridge:mac-address: diff --git a/libnm-core/nm-setting-cdma.c b/libnm-core/nm-setting-cdma.c index 880f926eff..bb49ec9d3f 100644 --- a/libnm-core/nm-setting-cdma.c +++ b/libnm-core/nm-setting-cdma.c @@ -37,8 +37,7 @@ * networks, including those using CDMA2000/EVDO technology. */ -G_DEFINE_TYPE_WITH_CODE (NMSettingCdma, nm_setting_cdma, NM_TYPE_SETTING, - _nm_register_setting (CDMA, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingCdma, nm_setting_cdma, NM_TYPE_SETTING) #define NM_SETTING_CDMA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_CDMA, NMSettingCdmaPrivate)) @@ -295,6 +294,7 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_CDMA]; setting_class->verify = verify; setting_class->verify_secrets = verify_secrets; setting_class->need_secrets = need_secrets; diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index b7066fc48f..6a6c76036f 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -45,8 +45,7 @@ * a #NMSettingConnection setting. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING, - _nm_register_setting (CONNECTION, NM_SETTING_PRIORITY_CONNECTION)) +G_DEFINE_TYPE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING) #define NM_SETTING_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionPrivate)) @@ -1513,6 +1512,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_CONNECTION]; setting_class->verify = verify; setting_class->compare_property = compare_property; diff --git a/libnm-core/nm-setting-dcb.c b/libnm-core/nm-setting-dcb.c index f57f2694a6..f306b77b16 100644 --- a/libnm-core/nm-setting-dcb.c +++ b/libnm-core/nm-setting-dcb.c @@ -40,8 +40,7 @@ * of storage technologies like Fibre Channel over Ethernet (FCoE) and iSCSI. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingDcb, nm_setting_dcb, NM_TYPE_SETTING, - _nm_register_setting (DCB, NM_SETTING_PRIORITY_HW_AUX)) +G_DEFINE_TYPE (NMSettingDcb, nm_setting_dcb, NM_TYPE_SETTING) #define NM_SETTING_DCB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_DCB, NMSettingDcbPrivate)) @@ -917,7 +916,8 @@ nm_setting_dcb_class_init (NMSettingDcbClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_DCB]; + setting_class->verify = verify; /** * NMSettingDcb:app-fcoe-flags: diff --git a/libnm-core/nm-setting-dummy.c b/libnm-core/nm-setting-dummy.c index d43bbc7e53..78e67d1dd7 100644 --- a/libnm-core/nm-setting-dummy.c +++ b/libnm-core/nm-setting-dummy.c @@ -34,8 +34,7 @@ * necessary for connection to dummy devices **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingDummy, nm_setting_dummy, NM_TYPE_SETTING, - _nm_register_setting (DUMMY, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingDummy, nm_setting_dummy, NM_TYPE_SETTING) /** * nm_setting_dummy_new: @@ -71,5 +70,6 @@ nm_setting_dummy_class_init (NMSettingDummyClass *klass) { NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_DUMMY]; + setting_class->verify = verify; } diff --git a/libnm-core/nm-setting-generic.c b/libnm-core/nm-setting-generic.c index 566d5826ae..762062417e 100644 --- a/libnm-core/nm-setting-generic.c +++ b/libnm-core/nm-setting-generic.c @@ -36,8 +36,7 @@ * the "connection type" setting on #NMConnections for generic devices. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingGeneric, nm_setting_generic, NM_TYPE_SETTING, - _nm_register_setting (GENERIC, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingGeneric, nm_setting_generic, NM_TYPE_SETTING) #define NM_SETTING_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_GENERIC, NMSettingGenericPrivate)) @@ -68,5 +67,9 @@ nm_setting_generic_init (NMSettingGeneric *setting) static void nm_setting_generic_class_init (NMSettingGenericClass *klass) { + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); + g_type_class_add_private (klass, sizeof (NMSettingGenericPrivate)); + + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_GENERIC]; } diff --git a/libnm-core/nm-setting-gsm.c b/libnm-core/nm-setting-gsm.c index fce5fe262f..3b4f604628 100644 --- a/libnm-core/nm-setting-gsm.c +++ b/libnm-core/nm-setting-gsm.c @@ -38,8 +38,7 @@ * networks, including those using GPRS/EDGE and UMTS/HSPA technology. */ -G_DEFINE_TYPE_WITH_CODE (NMSettingGsm, nm_setting_gsm, NM_TYPE_SETTING, - _nm_register_setting (GSM, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingGsm, nm_setting_gsm, NM_TYPE_SETTING) #define NM_SETTING_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_GSM, NMSettingGsmPrivate)) @@ -614,6 +613,7 @@ nm_setting_gsm_class_init (NMSettingGsmClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_GSM]; setting_class->verify = verify; setting_class->verify_secrets = verify_secrets; setting_class->need_secrets = need_secrets; diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index 75a2b3c92e..96997e9ebd 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -37,8 +37,7 @@ * necessary for connection to IP-over-InfiniBand networks. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingInfiniband, nm_setting_infiniband, NM_TYPE_SETTING, - _nm_register_setting (INFINIBAND, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingInfiniband, nm_setting_infiniband, NM_TYPE_SETTING) #define NM_SETTING_INFINIBAND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_INFINIBAND, NMSettingInfinibandPrivate)) @@ -388,7 +387,8 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_INFINIBAND]; + setting_class->verify = verify; /** * NMSettingInfiniband:mac-address: diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c index 5dcb4d62ef..b255edf339 100644 --- a/libnm-core/nm-setting-ip-tunnel.c +++ b/libnm-core/nm-setting-ip-tunnel.c @@ -30,8 +30,7 @@ * @short_description: Describes connection properties for IP tunnel devices **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingIPTunnel, nm_setting_ip_tunnel, NM_TYPE_SETTING, - _nm_register_setting (IP_TUNNEL, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingIPTunnel, nm_setting_ip_tunnel, NM_TYPE_SETTING) #define NM_SETTING_IP_TUNNEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelPrivate)) @@ -633,7 +632,8 @@ nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_IP_TUNNEL]; + setting_class->verify = verify; /** * NMSettingIPTunnel:parent: diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index d3e2ca3708..95ff57ca1b 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -50,8 +50,7 @@ * connection. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING_IP_CONFIG, - _nm_register_setting (IP4_CONFIG, NM_SETTING_PRIORITY_IP)) +G_DEFINE_TYPE (NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING_IP_CONFIG) #define NM_SETTING_IP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4ConfigPrivate)) @@ -535,7 +534,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_IP4_CONFIG]; + setting_class->verify = verify; /* ---ifcfg-rh--- * property: method diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 3f49fc976e..3f7dd00ce0 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -52,8 +52,7 @@ * supported. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG, - _nm_register_setting (IP6_CONFIG, NM_SETTING_PRIORITY_IP)) +G_DEFINE_TYPE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG) #define NM_SETTING_IP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigPrivate)) @@ -559,7 +558,8 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_IP6_CONFIG]; + setting_class->verify = verify; /* ---ifcfg-rh--- * property: method diff --git a/libnm-core/nm-setting-macsec.c b/libnm-core/nm-setting-macsec.c index c8969f068a..9705a31040 100644 --- a/libnm-core/nm-setting-macsec.c +++ b/libnm-core/nm-setting-macsec.c @@ -40,8 +40,7 @@ * necessary for connection to MACsec (IEEE 802.1AE) interfaces. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingMacsec, nm_setting_macsec, NM_TYPE_SETTING, - _nm_register_setting (MACSEC, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingMacsec, nm_setting_macsec, NM_TYPE_SETTING) #define NM_SETTING_MACSEC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_MACSEC, NMSettingMacsecPrivate)) @@ -484,6 +483,7 @@ nm_setting_macsec_class_init (NMSettingMacsecClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_MACSEC]; setting_class->verify = verify; setting_class->need_secrets = need_secrets; diff --git a/libnm-core/nm-setting-macvlan.c b/libnm-core/nm-setting-macvlan.c index 90934555fa..133131fa5d 100644 --- a/libnm-core/nm-setting-macvlan.c +++ b/libnm-core/nm-setting-macvlan.c @@ -39,8 +39,7 @@ * necessary for connection to macvlan interfaces. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingMacvlan, nm_setting_macvlan, NM_TYPE_SETTING, - _nm_register_setting (MACVLAN, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingMacvlan, nm_setting_macvlan, NM_TYPE_SETTING) #define NM_SETTING_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanPrivate)) @@ -270,7 +269,8 @@ nm_setting_macvlan_class_init (NMSettingMacvlanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_MACVLAN]; + setting_class->verify = verify; /** * NMSettingMacvlan:parent: diff --git a/libnm-core/nm-setting-olpc-mesh.c b/libnm-core/nm-setting-olpc-mesh.c index 68e84db0dd..9e215dc60d 100644 --- a/libnm-core/nm-setting-olpc-mesh.c +++ b/libnm-core/nm-setting-olpc-mesh.c @@ -39,8 +39,7 @@ static void nm_setting_olpc_mesh_init (NMSettingOlpcMesh *setting); -G_DEFINE_TYPE_WITH_CODE (NMSettingOlpcMesh, nm_setting_olpc_mesh, NM_TYPE_SETTING, - _nm_register_setting (OLPC_MESH, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingOlpcMesh, nm_setting_olpc_mesh, NM_TYPE_SETTING) #define NM_SETTING_OLPC_MESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMeshPrivate)) @@ -224,7 +223,8 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OLPC_MESH]; + setting_class->verify = verify; /** * NMSettingOlpcMesh:ssid: diff --git a/libnm-core/nm-setting-ovs-bridge.c b/libnm-core/nm-setting-ovs-bridge.c index 1ec364b6df..669bae9631 100644 --- a/libnm-core/nm-setting-ovs-bridge.c +++ b/libnm-core/nm-setting-ovs-bridge.c @@ -61,8 +61,7 @@ struct _NMSettingOvsBridgeClass { NMSettingClass parent; }; -G_DEFINE_TYPE_WITH_CODE (NMSettingOvsBridge, nm_setting_ovs_bridge, NM_TYPE_SETTING, - _nm_register_setting (OVS_BRIDGE, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingOvsBridge, nm_setting_ovs_bridge, NM_TYPE_SETTING) /*****************************************************************************/ @@ -272,7 +271,8 @@ nm_setting_ovs_bridge_class_init (NMSettingOvsBridgeClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OVS_BRIDGE]; + setting_class->verify = verify; /** * NMSettingOvsBridge:fail-mode: diff --git a/libnm-core/nm-setting-ovs-interface.c b/libnm-core/nm-setting-ovs-interface.c index 51e6e47bc7..23325eb957 100644 --- a/libnm-core/nm-setting-ovs-interface.c +++ b/libnm-core/nm-setting-ovs-interface.c @@ -54,8 +54,7 @@ struct _NMSettingOvsInterfaceClass { NMSettingClass parent; }; -G_DEFINE_TYPE_WITH_CODE (NMSettingOvsInterface, nm_setting_ovs_interface, NM_TYPE_SETTING, - _nm_register_setting (OVS_INTERFACE, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingOvsInterface, nm_setting_ovs_interface, NM_TYPE_SETTING) /*****************************************************************************/ @@ -371,7 +370,8 @@ nm_setting_ovs_interface_class_init (NMSettingOvsInterfaceClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OVS_INTERFACE]; + setting_class->verify = verify; /** * NMSettingOvsInterface:type: diff --git a/libnm-core/nm-setting-ovs-patch.c b/libnm-core/nm-setting-ovs-patch.c index 0986af8f93..0acdcb9d03 100644 --- a/libnm-core/nm-setting-ovs-patch.c +++ b/libnm-core/nm-setting-ovs-patch.c @@ -55,8 +55,7 @@ struct _NMSettingOvsPatchClass { NMSettingClass parent; }; -G_DEFINE_TYPE_WITH_CODE (NMSettingOvsPatch, nm_setting_ovs_patch, NM_TYPE_SETTING, - _nm_register_setting (OVS_PATCH, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingOvsPatch, nm_setting_ovs_patch, NM_TYPE_SETTING) /*****************************************************************************/ @@ -190,7 +189,8 @@ nm_setting_ovs_patch_class_init (NMSettingOvsPatchClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OVS_PATCH]; + setting_class->verify = verify; /** * NMSettingOvsPatch:peer: diff --git a/libnm-core/nm-setting-ovs-port.c b/libnm-core/nm-setting-ovs-port.c index eb593e8042..8fc19fc3c1 100644 --- a/libnm-core/nm-setting-ovs-port.c +++ b/libnm-core/nm-setting-ovs-port.c @@ -65,8 +65,7 @@ struct _NMSettingOvsPortClass { NMSettingClass parent; }; -G_DEFINE_TYPE_WITH_CODE (NMSettingOvsPort, nm_setting_ovs_port, NM_TYPE_SETTING, - _nm_register_setting (OVS_PORT, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingOvsPort, nm_setting_ovs_port, NM_TYPE_SETTING) /*****************************************************************************/ @@ -369,7 +368,8 @@ nm_setting_ovs_port_class_init (NMSettingOvsPortClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OVS_PORT]; + setting_class->verify = verify; /** * NMSettingOvsPort:vlan-mode: diff --git a/libnm-core/nm-setting-ppp.c b/libnm-core/nm-setting-ppp.c index 0388884a5c..905ec146a7 100644 --- a/libnm-core/nm-setting-ppp.c +++ b/libnm-core/nm-setting-ppp.c @@ -35,8 +35,7 @@ * cable and DSL modems and some mobile broadband devices. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingPpp, nm_setting_ppp, NM_TYPE_SETTING, - _nm_register_setting (PPP, NM_SETTING_PRIORITY_AUX)) +G_DEFINE_TYPE (NMSettingPpp, nm_setting_ppp, NM_TYPE_SETTING) #define NM_SETTING_PPP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PPP, NMSettingPppPrivate)) @@ -534,6 +533,7 @@ nm_setting_ppp_class_init (NMSettingPppClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_PPP]; setting_class->verify = verify; /** diff --git a/libnm-core/nm-setting-pppoe.c b/libnm-core/nm-setting-pppoe.c index e3c126a001..679a30cebb 100644 --- a/libnm-core/nm-setting-pppoe.c +++ b/libnm-core/nm-setting-pppoe.c @@ -38,8 +38,7 @@ * to provide IP transport, for example cable or DSL modems. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingPppoe, nm_setting_pppoe, NM_TYPE_SETTING, - _nm_register_setting (PPPOE, NM_SETTING_PRIORITY_AUX)) +G_DEFINE_TYPE (NMSettingPppoe, nm_setting_pppoe, NM_TYPE_SETTING) #define NM_SETTING_PPPOE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PPPOE, NMSettingPppoePrivate)) @@ -298,6 +297,7 @@ nm_setting_pppoe_class_init (NMSettingPppoeClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_PPPOE]; setting_class->verify = verify; setting_class->need_secrets = need_secrets; diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h index 043836a0f0..4a92264b7c 100644 --- a/libnm-core/nm-setting-private.h +++ b/libnm-core/nm-setting-private.h @@ -31,19 +31,14 @@ #include "nm-core-internal.h" -void _nm_register_setting_impl (const char *name, - GType type, - NMSettingPriority priority); - -#define _nm_register_setting(name, priority) \ - G_STMT_START { \ - _nm_register_setting_impl ("" NM_SETTING_ ## name ## _SETTING_NAME "", g_define_type_id, priority); \ - } G_STMT_END +/*****************************************************************************/ NMSettingPriority _nm_setting_get_base_type_priority (NMSetting *setting); NMSettingPriority _nm_setting_type_get_base_type_priority (GType type); int _nm_setting_compare_priority (gconstpointer a, gconstpointer b); +/*****************************************************************************/ + typedef enum NMSettingUpdateSecretResult { NM_SETTING_UPDATE_SECRET_ERROR = FALSE, NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED = TRUE, diff --git a/libnm-core/nm-setting-proxy.c b/libnm-core/nm-setting-proxy.c index 6a30ffd9e2..8faf9ba4e7 100644 --- a/libnm-core/nm-setting-proxy.c +++ b/libnm-core/nm-setting-proxy.c @@ -39,8 +39,7 @@ * to fulfill client queries. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingProxy, nm_setting_proxy, NM_TYPE_SETTING, - _nm_register_setting (PROXY, NM_SETTING_PRIORITY_IP)) +G_DEFINE_TYPE (NMSettingProxy, nm_setting_proxy, NM_TYPE_SETTING) #define NM_SETTING_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PROXY, NMSettingProxyPrivate)) @@ -295,7 +294,8 @@ nm_setting_proxy_class_init (NMSettingProxyClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_PROXY]; + setting_class->verify = verify; /** * NMSettingProxy:method: diff --git a/libnm-core/nm-setting-serial.c b/libnm-core/nm-setting-serial.c index 33414430f9..26baf95011 100644 --- a/libnm-core/nm-setting-serial.c +++ b/libnm-core/nm-setting-serial.c @@ -37,8 +37,7 @@ * such as mobile broadband or analog telephone connections. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingSerial, nm_setting_serial, NM_TYPE_SETTING, - _nm_register_setting (SERIAL, NM_SETTING_PRIORITY_HW_AUX)) +G_DEFINE_TYPE (NMSettingSerial, nm_setting_serial, NM_TYPE_SETTING) #define NM_SETTING_SERIAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_SERIAL, NMSettingSerialPrivate)) @@ -247,6 +246,8 @@ nm_setting_serial_class_init (NMSettingSerialClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_SERIAL]; + /** * NMSettingSerial:baud: * diff --git a/libnm-core/nm-setting-sriov.c b/libnm-core/nm-setting-sriov.c index 4947ede4e3..90108ca721 100644 --- a/libnm-core/nm-setting-sriov.c +++ b/libnm-core/nm-setting-sriov.c @@ -42,8 +42,7 @@ struct _NMSettingSriovClass { NMSettingClass parent; }; -G_DEFINE_TYPE_WITH_CODE (NMSettingSriov, nm_setting_sriov, NM_TYPE_SETTING, - _nm_register_setting (SRIOV, NM_SETTING_PRIORITY_HW_AUX)) +G_DEFINE_TYPE (NMSettingSriov, nm_setting_sriov, NM_TYPE_SETTING) enum { PROP_0, @@ -1240,6 +1239,7 @@ nm_setting_sriov_class_init (NMSettingSriovClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_SRIOV]; setting_class->compare_property = compare_property; setting_class->verify = verify; diff --git a/libnm-core/nm-setting-tc-config.c b/libnm-core/nm-setting-tc-config.c index 619881ab0a..01e2e34fb9 100644 --- a/libnm-core/nm-setting-tc-config.c +++ b/libnm-core/nm-setting-tc-config.c @@ -834,8 +834,7 @@ struct _NMSettingTCConfigClass { NMSettingClass parent; }; -G_DEFINE_TYPE_WITH_CODE (NMSettingTCConfig, nm_setting_tc_config, NM_TYPE_SETTING, - _nm_register_setting (TC_CONFIG, NM_SETTING_PRIORITY_IP)) +G_DEFINE_TYPE (NMSettingTCConfig, nm_setting_tc_config, NM_TYPE_SETTING) /** * nm_setting_tc_config_new: @@ -1597,6 +1596,7 @@ nm_setting_tc_config_class_init (NMSettingTCConfigClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_TC_CONFIG]; setting_class->compare_property = compare_property; setting_class->verify = verify; diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index 343f1e727b..4eb33050ee 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -39,8 +39,7 @@ * optional properties that apply to team ports. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingTeamPort, nm_setting_team_port, NM_TYPE_SETTING, - _nm_register_setting (TEAM_PORT, NM_SETTING_PRIORITY_AUX)) +G_DEFINE_TYPE (NMSettingTeamPort, nm_setting_team_port, NM_TYPE_SETTING) #define NM_SETTING_TEAM_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortPrivate)) @@ -597,6 +596,7 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_TEAM_PORT]; setting_class->compare_property = compare_property; setting_class->verify = verify; diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index fce3c42d51..f0120ff114 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -557,8 +557,7 @@ nm_team_link_watcher_get_flags (NMTeamLinkWatcher *watcher) /*****************************************************************************/ -G_DEFINE_TYPE_WITH_CODE (NMSettingTeam, nm_setting_team, NM_TYPE_SETTING, - _nm_register_setting (TEAM, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingTeam, nm_setting_team, NM_TYPE_SETTING) #define NM_SETTING_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_TEAM, NMSettingTeamPrivate)) @@ -1568,6 +1567,7 @@ nm_setting_team_class_init (NMSettingTeamClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_TEAM]; setting_class->compare_property = compare_property; setting_class->verify = verify; diff --git a/libnm-core/nm-setting-tun.c b/libnm-core/nm-setting-tun.c index a723bf3eb5..0fbb6375e0 100644 --- a/libnm-core/nm-setting-tun.c +++ b/libnm-core/nm-setting-tun.c @@ -38,8 +38,7 @@ * necessary for connection to TUN/TAP interfaces. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingTun, nm_setting_tun, NM_TYPE_SETTING, - _nm_register_setting (TUN, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingTun, nm_setting_tun, NM_TYPE_SETTING) #define NM_SETTING_TUN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_TUN, NMSettingTunPrivate)) @@ -302,7 +301,8 @@ nm_setting_tun_class_init (NMSettingTunClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_TUN]; + setting_class->verify = verify; /** * NMSettingTun:mode: diff --git a/libnm-core/nm-setting-user.c b/libnm-core/nm-setting-user.c index 1a6ddf220e..c5d763e77e 100644 --- a/libnm-core/nm-setting-user.c +++ b/libnm-core/nm-setting-user.c @@ -63,8 +63,7 @@ struct _NMSettingUserClass { NMSettingClass parent; }; -G_DEFINE_TYPE_WITH_CODE (NMSettingUser, nm_setting_user, NM_TYPE_SETTING, - _nm_register_setting (USER, NM_SETTING_PRIORITY_USER)) +G_DEFINE_TYPE (NMSettingUser, nm_setting_user, NM_TYPE_SETTING) #define NM_SETTING_USER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMSettingUser, NM_IS_SETTING_USER) @@ -553,6 +552,7 @@ nm_setting_user_class_init (NMSettingUserClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_USER]; setting_class->compare_property = compare_property; setting_class->verify = verify; diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index 897a66b75a..54a3145ee9 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -41,8 +41,7 @@ * necessary for connection to VLAN interfaces. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingVlan, nm_setting_vlan, NM_TYPE_SETTING, - _nm_register_setting (VLAN, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingVlan, nm_setting_vlan, NM_TYPE_SETTING) #define NM_SETTING_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VLAN, NMSettingVlanPrivate)) @@ -841,7 +840,8 @@ nm_setting_vlan_class_init (NMSettingVlanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_VLAN]; + setting_class->verify = verify; /** * NMSettingVlan:parent: diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c index 0672a8101f..39126421ee 100644 --- a/libnm-core/nm-setting-vpn.c +++ b/libnm-core/nm-setting-vpn.c @@ -43,8 +43,7 @@ * properties. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingVpn, nm_setting_vpn, NM_TYPE_SETTING, - _nm_register_setting (VPN, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingVpn, nm_setting_vpn, NM_TYPE_SETTING) #define NM_SETTING_VPN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VPN, NMSettingVpnPrivate)) @@ -899,6 +898,7 @@ nm_setting_vpn_class_init (NMSettingVpnClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_VPN]; setting_class->verify = verify; setting_class->update_one_secret = update_one_secret; setting_class->get_secret_flags = get_secret_flags; diff --git a/libnm-core/nm-setting-vxlan.c b/libnm-core/nm-setting-vxlan.c index 443ebdafb8..2f906f8ac5 100644 --- a/libnm-core/nm-setting-vxlan.c +++ b/libnm-core/nm-setting-vxlan.c @@ -36,8 +36,7 @@ * necessary for connection to VXLAN interfaces. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingVxlan, nm_setting_vxlan, NM_TYPE_SETTING, - _nm_register_setting (VXLAN, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingVxlan, nm_setting_vxlan, NM_TYPE_SETTING) #define NM_SETTING_VXLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VXLAN, NMSettingVxlanPrivate)) @@ -575,7 +574,8 @@ nm_setting_vxlan_class_init (NMSettingVxlanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_VXLAN]; + setting_class->verify = verify; /** * NMSettingVxlan:parent: diff --git a/libnm-core/nm-setting-wimax.c b/libnm-core/nm-setting-wimax.c index 852ba755ec..12ab0da374 100644 --- a/libnm-core/nm-setting-wimax.c +++ b/libnm-core/nm-setting-wimax.c @@ -42,8 +42,7 @@ * connections cannot be activated. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingWimax, nm_setting_wimax, NM_TYPE_SETTING, - _nm_register_setting (WIMAX, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingWimax, nm_setting_wimax, NM_TYPE_SETTING) #define NM_SETTING_WIMAX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIMAX, NMSettingWimaxPrivate)) @@ -217,7 +216,8 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WIMAX]; + setting_class->verify = verify; /** * NMSettingWimax:network-name: diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c index 0dcd1c25b4..212ddb6218 100644 --- a/libnm-core/nm-setting-wired.c +++ b/libnm-core/nm-setting-wired.c @@ -40,8 +40,7 @@ * necessary for connection to Ethernet networks. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingWired, nm_setting_wired, NM_TYPE_SETTING, - _nm_register_setting (WIRED, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingWired, nm_setting_wired, NM_TYPE_SETTING) #define NM_SETTING_WIRED_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRED, NMSettingWiredPrivate)) @@ -988,6 +987,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WIRED]; setting_class->verify = verify; setting_class->compare_property = compare_property; diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c index 22177c46b5..e4d3454107 100644 --- a/libnm-core/nm-setting-wireless-security.c +++ b/libnm-core/nm-setting-wireless-security.c @@ -53,8 +53,7 @@ * ISBN: 978-1587051548 **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING, - _nm_register_setting (WIRELESS_SECURITY, NM_SETTING_PRIORITY_HW_AUX)) +G_DEFINE_TYPE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING) #define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityPrivate)) @@ -1441,6 +1440,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WIRELESS_SECURITY]; setting_class->verify = verify; setting_class->verify_secrets = verify_secrets; setting_class->need_secrets = need_secrets; diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index bebfade5c7..47e78d18e7 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -40,8 +40,7 @@ * necessary for connection to 802.11 Wi-Fi networks. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingWireless, nm_setting_wireless, NM_TYPE_SETTING, - _nm_register_setting (WIRELESS, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingWireless, nm_setting_wireless, NM_TYPE_SETTING) #define NM_SETTING_WIRELESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessPrivate)) @@ -1186,6 +1185,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WIRELESS]; setting_class->verify = verify; setting_class->compare_property = compare_property; diff --git a/libnm-core/nm-setting-wpan.c b/libnm-core/nm-setting-wpan.c index 4ba64158f8..462f054344 100644 --- a/libnm-core/nm-setting-wpan.c +++ b/libnm-core/nm-setting-wpan.c @@ -65,8 +65,7 @@ struct _NMSettingWpanClass { * necessary for configuring IEEE 802.15.4 (WPAN) MAC layer devices. **/ -G_DEFINE_TYPE_WITH_CODE (NMSettingWpan, nm_setting_wpan, NM_TYPE_SETTING, - _nm_register_setting (WPAN, NM_SETTING_PRIORITY_HW_BASE)) +G_DEFINE_TYPE (NMSettingWpan, nm_setting_wpan, NM_TYPE_SETTING) #define NM_SETTING_WPAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WPAN, NMSettingWpanPrivate)) @@ -225,7 +224,8 @@ nm_setting_wpan_class_init (NMSettingWpanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; + setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WPAN]; + setting_class->verify = verify; /** * NMSettingWpan:mac-address: diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 887e8aeb4f..86acc04e6b 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -69,7 +69,7 @@ enum { }; typedef struct { - const SettingInfo *info; + int dummy; } NMSettingPrivate; G_DEFINE_ABSTRACT_TYPE (NMSetting, nm_setting, G_TYPE_OBJECT) @@ -78,213 +78,52 @@ G_DEFINE_ABSTRACT_TYPE (NMSetting, nm_setting, G_TYPE_OBJECT) /*****************************************************************************/ -static GHashTable *registered_settings = NULL; -static GHashTable *registered_settings_by_type = NULL; - -static gboolean -_nm_gtype_equal (gconstpointer v1, gconstpointer v2) -{ - return *((const GType *) v1) == *((const GType *) v2); -} -static guint -_nm_gtype_hash (gconstpointer v) -{ - return *((const GType *) v); -} - -/*****************************************************************************/ - -static void -_register_settings_ensure_types (void) -{ -#define ENSURE_TYPE(get_type) \ - G_STMT_START { \ - GType get_type (void); \ - \ - get_type (); \ - } G_STMT_END - - ENSURE_TYPE (nm_setting_6lowpan_get_type); - ENSURE_TYPE (nm_setting_802_1x_get_type); - ENSURE_TYPE (nm_setting_adsl_get_type); - ENSURE_TYPE (nm_setting_bluetooth_get_type); - ENSURE_TYPE (nm_setting_bond_get_type); - ENSURE_TYPE (nm_setting_bridge_get_type); - ENSURE_TYPE (nm_setting_bridge_port_get_type); - ENSURE_TYPE (nm_setting_cdma_get_type); - ENSURE_TYPE (nm_setting_connection_get_type); - ENSURE_TYPE (nm_setting_dcb_get_type); - ENSURE_TYPE (nm_setting_dummy_get_type); - ENSURE_TYPE (nm_setting_generic_get_type); - ENSURE_TYPE (nm_setting_gsm_get_type); - ENSURE_TYPE (nm_setting_infiniband_get_type); - ENSURE_TYPE (nm_setting_ip4_config_get_type); - ENSURE_TYPE (nm_setting_ip6_config_get_type); - ENSURE_TYPE (nm_setting_ip_tunnel_get_type); - ENSURE_TYPE (nm_setting_macsec_get_type); - ENSURE_TYPE (nm_setting_macvlan_get_type); - ENSURE_TYPE (nm_setting_olpc_mesh_get_type); - ENSURE_TYPE (nm_setting_ovs_bridge_get_type); - ENSURE_TYPE (nm_setting_ovs_interface_get_type); - ENSURE_TYPE (nm_setting_ovs_patch_get_type); - ENSURE_TYPE (nm_setting_ovs_port_get_type); - ENSURE_TYPE (nm_setting_ppp_get_type); - ENSURE_TYPE (nm_setting_pppoe_get_type); - ENSURE_TYPE (nm_setting_proxy_get_type); - ENSURE_TYPE (nm_setting_serial_get_type); - ENSURE_TYPE (nm_setting_sriov_get_type); - ENSURE_TYPE (nm_setting_tc_config_get_type); - ENSURE_TYPE (nm_setting_team_get_type); - ENSURE_TYPE (nm_setting_team_port_get_type); - ENSURE_TYPE (nm_setting_tun_get_type); - ENSURE_TYPE (nm_setting_user_get_type); - ENSURE_TYPE (nm_setting_vlan_get_type); - ENSURE_TYPE (nm_setting_vpn_get_type); - ENSURE_TYPE (nm_setting_vxlan_get_type); - ENSURE_TYPE (nm_setting_wimax_get_type); - ENSURE_TYPE (nm_setting_wired_get_type); - ENSURE_TYPE (nm_setting_wireless_get_type); - ENSURE_TYPE (nm_setting_wireless_security_get_type); - ENSURE_TYPE (nm_setting_wpan_get_type); -} - -/*****************************************************************************/ - -static int volatile _register_settings_ensure_inited_val = 0; - -#define _register_settings_ensure_inited() \ - G_STMT_START { \ - if (G_UNLIKELY (_register_settings_ensure_inited_val == 0)) \ - _register_settings_ensure_inited_impl (); \ - } G_STMT_END - -static void -_register_settings_ensure_inited_impl (void) -{ - _register_settings_ensure_types (); - g_atomic_int_set (&_register_settings_ensure_inited_val, 1); -} - -/*****************************************************************************/ - -#define _ensure_setting_info(self, priv) \ - G_STMT_START { \ - NMSettingPrivate *_priv_esi = (priv); \ - if (G_UNLIKELY (!_priv_esi->info)) { \ - _priv_esi->info = _nm_setting_lookup_setting_by_type (G_OBJECT_TYPE (self)); \ - g_assert (_priv_esi->info); \ - } \ - } G_STMT_END - -/*****************************************************************************/ - -/* - * _nm_register_setting_impl: - * @name: the name of the #NMSetting object to register - * @type: the #GType of the #NMSetting - * @priority: the sort priority of the setting, see #NMSettingPriority - * - * INTERNAL ONLY: registers a setting's internal properties with libnm. - * - * This should be called from within G_DEFINE_TYPE_WITH_CODE() when initializing - * the setting type. - */ -void -_nm_register_setting_impl (const char *name, - GType type, - NMSettingPriority priority) -{ - static GMutex mutex; - SettingInfo *info; - - nm_assert (name && *name); - nm_assert (!NM_IN_SET (type, G_TYPE_INVALID, G_TYPE_NONE)); - nm_assert (priority != NM_SETTING_PRIORITY_INVALID); - - nm_assert ( priority != NM_SETTING_PRIORITY_CONNECTION - || nm_streq (name, NM_SETTING_CONNECTION_SETTING_NAME)); - - info = g_slice_new0 (SettingInfo); - info->type = type; - info->priority = priority; - info->name = name; - - g_mutex_lock (&mutex); - - if (!registered_settings) { - nm_assert (!registered_settings_by_type); - registered_settings = g_hash_table_new (nm_str_hash, g_str_equal); - registered_settings_by_type = g_hash_table_new (_nm_gtype_hash, _nm_gtype_equal); - } else { - nm_assert (!g_hash_table_contains (registered_settings, name)); - nm_assert (!g_hash_table_contains (registered_settings_by_type, &type)); - } - - g_hash_table_insert (registered_settings, (void *) info->name, info); - g_hash_table_insert (registered_settings_by_type, &info->type, info); - - g_mutex_unlock (&mutex); - - /* we cannot register types, after _register_settings_ensure_inited() is done. - * - * This means, you need to register the type in _register_settings_ensure_types() - * above. */ - nm_assert (g_atomic_int_get (&_register_settings_ensure_inited_val) == 0); -} - -static const SettingInfo * -_nm_setting_lookup_setting_by_type (GType type) -{ - _register_settings_ensure_inited (); - return g_hash_table_lookup (registered_settings_by_type, &type); -} - static NMSettingPriority -_get_setting_type_priority (GType type) +_get_base_type_priority (const NMMetaSettingInfo *setting_info, + GType gtype) { - const SettingInfo *info; - - g_return_val_if_fail (g_type_is_a (type, NM_TYPE_SETTING), G_MAXUINT32); - - info = _nm_setting_lookup_setting_by_type (type); - return info->priority; -} - -NMSettingPriority -_nm_setting_get_setting_priority (NMSetting *setting) -{ - NMSettingPrivate *priv; - - g_return_val_if_fail (NM_IS_SETTING (setting), G_MAXUINT32); - priv = NM_SETTING_GET_PRIVATE (setting); - _ensure_setting_info (setting, priv); - return priv->info->priority; -} - -NMSettingPriority -_nm_setting_type_get_base_type_priority (GType type) -{ - NMSettingPriority priority; - /* Historical oddity: PPPoE is a base-type even though it's not * priority 1. It needs to be sorted *after* lower-level stuff like * Wi-Fi security or 802.1x for secrets, but it's still allowed as a * base type. */ - priority = _get_setting_type_priority (type); - if ( NM_IN_SET (priority, - NM_SETTING_PRIORITY_HW_BASE, - NM_SETTING_PRIORITY_HW_NON_BASE) - || type == NM_TYPE_SETTING_PPPOE) - return priority; - else - return NM_SETTING_PRIORITY_INVALID; + + if (setting_info) { + if ( NM_IN_SET (setting_info->setting_priority, + NM_SETTING_PRIORITY_HW_BASE, + NM_SETTING_PRIORITY_HW_NON_BASE) + || gtype == NM_TYPE_SETTING_PPPOE) + return setting_info->setting_priority; + } + + return NM_SETTING_PRIORITY_INVALID; +} + +NMSettingPriority +_nm_setting_get_setting_priority (NMSetting *setting) +{ + const NMMetaSettingInfo *setting_info; + + g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_PRIORITY_INVALID); + + setting_info = NM_SETTING_GET_CLASS (setting)->setting_info; + return setting_info ? setting_info->setting_priority : NM_SETTING_PRIORITY_INVALID; +} + +NMSettingPriority +_nm_setting_type_get_base_type_priority (GType type) +{ + return _get_base_type_priority (nm_meta_setting_infos_by_gtype (type), + type); } NMSettingPriority _nm_setting_get_base_type_priority (NMSetting *setting) { - return _nm_setting_type_get_base_type_priority (G_OBJECT_TYPE (setting)); + g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_PRIORITY_INVALID); + + return _get_base_type_priority (NM_SETTING_GET_CLASS (setting)->setting_info, + G_OBJECT_TYPE (setting)); } /** @@ -299,14 +138,12 @@ _nm_setting_get_base_type_priority (NMSetting *setting) GType nm_setting_lookup_type (const char *name) { - const SettingInfo *info; + const NMMetaSettingInfo *setting_info; g_return_val_if_fail (name, G_TYPE_INVALID); - _register_settings_ensure_inited (); - - info = g_hash_table_lookup (registered_settings, name); - return info ? info->type : G_TYPE_INVALID; + setting_info = nm_meta_setting_infos_by_name (name); + return setting_info ? setting_info->get_setting_gtype () : G_TYPE_INVALID; } int @@ -1113,12 +950,12 @@ nm_setting_duplicate (NMSetting *setting) const char * nm_setting_get_name (NMSetting *setting) { - NMSettingPrivate *priv; + const NMMetaSettingInfo *setting_info; g_return_val_if_fail (NM_IS_SETTING (setting), NULL); - priv = NM_SETTING_GET_PRIVATE (setting); - _ensure_setting_info (setting, priv); - return priv->info->name; + + setting_info = NM_SETTING_GET_CLASS (setting)->setting_info; + return setting_info ? setting_info->setting_name : NULL; } /** @@ -2034,14 +1871,6 @@ nm_setting_init (NMSetting *setting) { } -static void -constructed (GObject *object) -{ - _ensure_setting_info (object, NM_SETTING_GET_PRIVATE (object)); - - G_OBJECT_CLASS (nm_setting_parent_class)->constructed (object); -} - static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -2080,8 +1909,6 @@ nm_setting_class_init (NMSettingClass *setting_class) g_type_class_add_private (setting_class, sizeof (NMSettingPrivate)); - /* virtual methods */ - object_class->constructed = constructed; object_class->get_property = get_property; setting_class->update_one_secret = update_one_secret; @@ -2090,8 +1917,6 @@ nm_setting_class_init (NMSettingClass *setting_class) setting_class->compare_property = compare_property; setting_class->clear_secrets_with_flags = clear_secrets_with_flags; - /* Properties */ - /** * NMSetting:name: * diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h index 536aea709d..d06527cdd7 100644 --- a/libnm-core/nm-setting.h +++ b/libnm-core/nm-setting.h @@ -168,6 +168,8 @@ typedef gboolean (*NMSettingClearSecretsWithFlagsFn) (NMSetting *setting, NMSettingSecretFlags flags, gpointer user_data); +struct _NMMetaSettingInfo; + typedef struct { GObjectClass parent; @@ -211,7 +213,10 @@ typedef struct { NMSettingCompareFlags flags); /*< private >*/ - gpointer padding[7]; + const struct _NMMetaSettingInfo *setting_info; + + /*< private >*/ + gpointer padding[6]; } NMSettingClass; /** diff --git a/shared/nm-meta-setting.c b/shared/nm-meta-setting.c index 148f3753f9..00221dac6a 100644 --- a/shared/nm-meta-setting.c +++ b/shared/nm-meta-setting.c @@ -149,211 +149,253 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = { const NMMetaSettingInfo nm_meta_setting_infos[] = { [NM_META_SETTING_TYPE_6LOWPAN] = { .meta_type = NM_META_SETTING_TYPE_6LOWPAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_6LOWPAN_SETTING_NAME, .get_setting_gtype = nm_setting_6lowpan_get_type, }, [NM_META_SETTING_TYPE_802_1X] = { .meta_type = NM_META_SETTING_TYPE_802_1X, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, .setting_name = NM_SETTING_802_1X_SETTING_NAME, .get_setting_gtype = nm_setting_802_1x_get_type, }, [NM_META_SETTING_TYPE_ADSL] = { .meta_type = NM_META_SETTING_TYPE_ADSL, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_ADSL_SETTING_NAME, .get_setting_gtype = nm_setting_adsl_get_type, }, [NM_META_SETTING_TYPE_BLUETOOTH] = { .meta_type = NM_META_SETTING_TYPE_BLUETOOTH, + .setting_priority = NM_SETTING_PRIORITY_HW_NON_BASE, .setting_name = NM_SETTING_BLUETOOTH_SETTING_NAME, .get_setting_gtype = nm_setting_bluetooth_get_type, }, [NM_META_SETTING_TYPE_BOND] = { .meta_type = NM_META_SETTING_TYPE_BOND, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_BOND_SETTING_NAME, .get_setting_gtype = nm_setting_bond_get_type, }, [NM_META_SETTING_TYPE_BRIDGE] = { .meta_type = NM_META_SETTING_TYPE_BRIDGE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_BRIDGE_SETTING_NAME, .get_setting_gtype = nm_setting_bridge_get_type, }, [NM_META_SETTING_TYPE_BRIDGE_PORT] = { .meta_type = NM_META_SETTING_TYPE_BRIDGE_PORT, + .setting_priority = NM_SETTING_PRIORITY_AUX, .setting_name = NM_SETTING_BRIDGE_PORT_SETTING_NAME, .get_setting_gtype = nm_setting_bridge_port_get_type, }, [NM_META_SETTING_TYPE_CDMA] = { .meta_type = NM_META_SETTING_TYPE_CDMA, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_CDMA_SETTING_NAME, .get_setting_gtype = nm_setting_cdma_get_type, }, [NM_META_SETTING_TYPE_CONNECTION] = { .meta_type = NM_META_SETTING_TYPE_CONNECTION, + .setting_priority = NM_SETTING_PRIORITY_CONNECTION, .setting_name = NM_SETTING_CONNECTION_SETTING_NAME, .get_setting_gtype = nm_setting_connection_get_type, }, [NM_META_SETTING_TYPE_DCB] = { .meta_type = NM_META_SETTING_TYPE_DCB, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, .setting_name = NM_SETTING_DCB_SETTING_NAME, .get_setting_gtype = nm_setting_dcb_get_type, }, [NM_META_SETTING_TYPE_DUMMY] = { .meta_type = NM_META_SETTING_TYPE_DUMMY, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_DUMMY_SETTING_NAME, .get_setting_gtype = nm_setting_dummy_get_type, }, [NM_META_SETTING_TYPE_GENERIC] = { .meta_type = NM_META_SETTING_TYPE_GENERIC, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_GENERIC_SETTING_NAME, .get_setting_gtype = nm_setting_generic_get_type, }, [NM_META_SETTING_TYPE_GSM] = { .meta_type = NM_META_SETTING_TYPE_GSM, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_GSM_SETTING_NAME, .get_setting_gtype = nm_setting_gsm_get_type, }, [NM_META_SETTING_TYPE_INFINIBAND] = { .meta_type = NM_META_SETTING_TYPE_INFINIBAND, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_INFINIBAND_SETTING_NAME, .get_setting_gtype = nm_setting_infiniband_get_type, }, [NM_META_SETTING_TYPE_IP4_CONFIG] = { .meta_type = NM_META_SETTING_TYPE_IP4_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, .setting_name = NM_SETTING_IP4_CONFIG_SETTING_NAME, .get_setting_gtype = nm_setting_ip4_config_get_type, }, [NM_META_SETTING_TYPE_IP6_CONFIG] = { .meta_type = NM_META_SETTING_TYPE_IP6_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, .setting_name = NM_SETTING_IP6_CONFIG_SETTING_NAME, .get_setting_gtype = nm_setting_ip6_config_get_type, }, [NM_META_SETTING_TYPE_IP_TUNNEL] = { .meta_type = NM_META_SETTING_TYPE_IP_TUNNEL, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME, .get_setting_gtype = nm_setting_ip_tunnel_get_type, }, [NM_META_SETTING_TYPE_MACSEC] = { .meta_type = NM_META_SETTING_TYPE_MACSEC, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_MACSEC_SETTING_NAME, .get_setting_gtype = nm_setting_macsec_get_type, }, [NM_META_SETTING_TYPE_MACVLAN] = { .meta_type = NM_META_SETTING_TYPE_MACVLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_MACVLAN_SETTING_NAME, .get_setting_gtype = nm_setting_macvlan_get_type, }, [NM_META_SETTING_TYPE_OLPC_MESH] = { .meta_type = NM_META_SETTING_TYPE_OLPC_MESH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_OLPC_MESH_SETTING_NAME, .get_setting_gtype = nm_setting_olpc_mesh_get_type, }, [NM_META_SETTING_TYPE_OVS_BRIDGE] = { .meta_type = NM_META_SETTING_TYPE_OVS_BRIDGE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_OVS_BRIDGE_SETTING_NAME, .get_setting_gtype = nm_setting_ovs_bridge_get_type, }, [NM_META_SETTING_TYPE_OVS_INTERFACE] = { .meta_type = NM_META_SETTING_TYPE_OVS_INTERFACE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_OVS_INTERFACE_SETTING_NAME, .get_setting_gtype = nm_setting_ovs_interface_get_type, }, [NM_META_SETTING_TYPE_OVS_PATCH] = { .meta_type = NM_META_SETTING_TYPE_OVS_PATCH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_OVS_PATCH_SETTING_NAME, .get_setting_gtype = nm_setting_ovs_patch_get_type, }, [NM_META_SETTING_TYPE_OVS_PORT] = { .meta_type = NM_META_SETTING_TYPE_OVS_PORT, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_OVS_PORT_SETTING_NAME, .get_setting_gtype = nm_setting_ovs_port_get_type, }, [NM_META_SETTING_TYPE_PPPOE] = { .meta_type = NM_META_SETTING_TYPE_PPPOE, + .setting_priority = NM_SETTING_PRIORITY_AUX, .setting_name = NM_SETTING_PPPOE_SETTING_NAME, .get_setting_gtype = nm_setting_pppoe_get_type, }, [NM_META_SETTING_TYPE_PPP] = { .meta_type = NM_META_SETTING_TYPE_PPP, + .setting_priority = NM_SETTING_PRIORITY_AUX, .setting_name = NM_SETTING_PPP_SETTING_NAME, .get_setting_gtype = nm_setting_ppp_get_type, }, [NM_META_SETTING_TYPE_PROXY] = { .meta_type = NM_META_SETTING_TYPE_PROXY, + .setting_priority = NM_SETTING_PRIORITY_IP, .setting_name = NM_SETTING_PROXY_SETTING_NAME, .get_setting_gtype = nm_setting_proxy_get_type, }, [NM_META_SETTING_TYPE_SERIAL] = { .meta_type = NM_META_SETTING_TYPE_SERIAL, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, .setting_name = NM_SETTING_SERIAL_SETTING_NAME, .get_setting_gtype = nm_setting_serial_get_type, }, [NM_META_SETTING_TYPE_SRIOV] = { .meta_type = NM_META_SETTING_TYPE_SRIOV, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, .setting_name = NM_SETTING_SRIOV_SETTING_NAME, .get_setting_gtype = nm_setting_sriov_get_type, }, [NM_META_SETTING_TYPE_TC_CONFIG] = { .meta_type = NM_META_SETTING_TYPE_TC_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, .setting_name = NM_SETTING_TC_CONFIG_SETTING_NAME, .get_setting_gtype = nm_setting_tc_config_get_type, }, [NM_META_SETTING_TYPE_TEAM] = { .meta_type = NM_META_SETTING_TYPE_TEAM, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_TEAM_SETTING_NAME, .get_setting_gtype = nm_setting_team_get_type, }, [NM_META_SETTING_TYPE_TEAM_PORT] = { .meta_type = NM_META_SETTING_TYPE_TEAM_PORT, + .setting_priority = NM_SETTING_PRIORITY_AUX, .setting_name = NM_SETTING_TEAM_PORT_SETTING_NAME, .get_setting_gtype = nm_setting_team_port_get_type, }, [NM_META_SETTING_TYPE_TUN] = { .meta_type = NM_META_SETTING_TYPE_TUN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_TUN_SETTING_NAME, .get_setting_gtype = nm_setting_tun_get_type, }, [NM_META_SETTING_TYPE_USER] = { .meta_type = NM_META_SETTING_TYPE_USER, + .setting_priority = NM_SETTING_PRIORITY_USER, .setting_name = NM_SETTING_USER_SETTING_NAME, .get_setting_gtype = nm_setting_user_get_type, }, [NM_META_SETTING_TYPE_VLAN] = { .meta_type = NM_META_SETTING_TYPE_VLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_VLAN_SETTING_NAME, .get_setting_gtype = nm_setting_vlan_get_type, }, [NM_META_SETTING_TYPE_VPN] = { .meta_type = NM_META_SETTING_TYPE_VPN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_VPN_SETTING_NAME, .get_setting_gtype = nm_setting_vpn_get_type, }, [NM_META_SETTING_TYPE_VXLAN] = { .meta_type = NM_META_SETTING_TYPE_VXLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_VXLAN_SETTING_NAME, .get_setting_gtype = nm_setting_vxlan_get_type, }, [NM_META_SETTING_TYPE_WIMAX] = { .meta_type = NM_META_SETTING_TYPE_WIMAX, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_WIMAX_SETTING_NAME, .get_setting_gtype = nm_setting_wimax_get_type, }, [NM_META_SETTING_TYPE_WIRED] = { .meta_type = NM_META_SETTING_TYPE_WIRED, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_WIRED_SETTING_NAME, .get_setting_gtype = nm_setting_wired_get_type, }, [NM_META_SETTING_TYPE_WIRELESS] = { .meta_type = NM_META_SETTING_TYPE_WIRELESS, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_WIRELESS_SETTING_NAME, .get_setting_gtype = nm_setting_wireless_get_type, }, [NM_META_SETTING_TYPE_WIRELESS_SECURITY] = { .meta_type = NM_META_SETTING_TYPE_WIRELESS_SECURITY, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, .setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, .get_setting_gtype = nm_setting_wireless_security_get_type, }, [NM_META_SETTING_TYPE_WPAN] = { .meta_type = NM_META_SETTING_TYPE_WPAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, .setting_name = NM_SETTING_WPAN_SETTING_NAME, .get_setting_gtype = nm_setting_wpan_get_type, }, @@ -380,13 +422,56 @@ nm_meta_setting_infos_by_name (const char *name) const NMMetaSettingInfo * nm_meta_setting_infos_by_gtype (GType gtype) { - int i; +#if ((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) + nm_auto_unref_gtypeclass GTypeClass *gtypeclass_unref = NULL; + GTypeClass *gtypeclass; + NMSettingClass *klass; + + if (!g_type_is_a (gtype, NM_TYPE_SETTING)) + goto out_none; + + gtypeclass = g_type_class_peek (gtype); + if (!gtypeclass) + gtypeclass = gtypeclass_unref = g_type_class_ref (gtype); + + nm_assert (NM_IS_SETTING_CLASS (gtypeclass)); + + klass = (NMSettingClass *) gtypeclass; + + if (!klass->setting_info) + goto out_none; + + nm_assert (klass->setting_info->get_setting_gtype); + nm_assert (klass->setting_info->get_setting_gtype () == gtype); + + return klass->setting_info; + +out_none: + +#if NM_MORE_ASSERTS > 10 + { + int i; + + /* this might hint to a bug, but it would be expected for NM_TYPE_SETTING + * and NM_TYPE_SETTING_IP_CONFIG. + * + * Assert that we didn't lookup for a gtype, which we would expect to find. + * An assertion failure here, hints to a bug in nm_setting_*_class_init(). + */ + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) + nm_assert (nm_meta_setting_infos[i].get_setting_gtype () != gtype); + } +#endif + return NULL; +#else + guint i; for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { if (nm_meta_setting_infos[i].get_setting_gtype () == gtype) return &nm_meta_setting_infos[i]; } return NULL; +#endif } /*****************************************************************************/ diff --git a/shared/nm-meta-setting.h b/shared/nm-meta-setting.h index dd4780c5d9..28091ff98e 100644 --- a/shared/nm-meta-setting.h +++ b/shared/nm-meta-setting.h @@ -26,6 +26,47 @@ /*****************************************************************************/ +/* + * A setting's priority should roughly follow the OSI layer model, but it also + * controls which settings get asked for secrets first. Thus settings which + * relate to things that must be working first, like hardware, should get a + * higher priority than things which layer on top of the hardware. For example, + * the GSM/CDMA settings should provide secrets before the PPP setting does, + * because a PIN is required to unlock the device before PPP can even start. + * Even settings without secrets should be assigned the right priority. + * + * 0: reserved for invalid + * + * 1: reserved for the Connection setting + * + * 2,3: hardware-related settings like Ethernet, Wi-Fi, InfiniBand, Bridge, etc. + * These priority 1 settings are also "base types", which means that at least + * one of them is required for the connection to be valid, and their name is + * valid in the 'type' property of the Connection setting. + * + * 4: hardware-related auxiliary settings that require a base setting to be + * successful first, like Wi-Fi security, 802.1x, etc. + * + * 5: hardware-independent settings that are required before IP connectivity + * can be established, like PPP, PPPoE, etc. + * + * 6: IP-level stuff + * + * 10: NMSettingUser + */ +typedef enum { /*< skip >*/ + NM_SETTING_PRIORITY_INVALID = 0, + NM_SETTING_PRIORITY_CONNECTION = 1, + NM_SETTING_PRIORITY_HW_BASE = 2, + NM_SETTING_PRIORITY_HW_NON_BASE = 3, + NM_SETTING_PRIORITY_HW_AUX = 4, + NM_SETTING_PRIORITY_AUX = 5, + NM_SETTING_PRIORITY_IP = 6, + NM_SETTING_PRIORITY_USER = 10, +} NMSettingPriority; + +/*****************************************************************************/ + typedef enum { NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT, NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT, @@ -104,12 +145,50 @@ typedef enum { _NM_META_SETTING_TYPE_NUM = NM_META_SETTING_TYPE_UNKNOWN, } NMMetaSettingType; -typedef struct { +/* this header is statically linked with both libnm-core.la and libnmc.la. + * Though, there is no stable API/ABI, so whenever on of these components + * accesses NMMetaSettingInfo or NMMetaSettingType, it only has meaning + * inside the same component. + * + * Note how NMSettingClass has field of type "struct _NMMetaSettingInfo". + * It would be a serious bug, if libnmc tries to interpret this pointer + * with the meaning of NMMetaSettingInfo. They might be different, because + * libnm.so (libnm-core.la) might be a newer version than nmcli (libnmc.la). + * + * This define helps to ensure that we don't accidentally use the pointer + * in different contexts. */ +#if ((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) +#define _NMMetaSettingInfoXX _NMMetaSettingInfo +#else +#define _NMMetaSettingInfoXX _NMMetaSettingInfoCli +#endif +struct _NMMetaSettingInfoXX { NMMetaSettingType meta_type; + NMSettingPriority setting_priority; const char *setting_name; GType (*get_setting_gtype) (void); -} NMMetaSettingInfo; +}; +typedef struct _NMMetaSettingInfoXX NMMetaSettingInfo; + +/* note that we statically link nm-meta-setting.h both to libnm-core.la and + * libnmc.la. That means, there are two versions of nm_meta_setting_infos + * in nmcli. That is not easily avoidable, because at this point, we don't + * want yet to making it public API. + * + * Eventually, this should become public API of libnm, and nmcli/libnmc.la + * should use that version. + * + * Downsides of the current solution: + * + * - duplication of the array in nmcli. + * + * - there is no stable API/ABI. That means, when you have a NMMetaSettingInfo + * pointer, or a NMMetaSettingType value, the value can only be used within + * the current context (libnm-core.la or libnmc.la). In other words, libnmc.la + * (and nmcli) must never access a NMMetaSettingInfo/NMMetaSettingType value, + * that comes from libnm-core.la. + */ extern const NMMetaSettingInfo nm_meta_setting_infos[_NM_META_SETTING_TYPE_NUM + 1]; const NMMetaSettingInfo *nm_meta_setting_infos_by_name (const char *name); From f77f74f273374a44bc7bd23543832b894f472aad Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 28 Jul 2018 12:56:57 +0200 Subject: [PATCH 19/32] shared: use binary search in nm_meta_setting_infos_by_name() nm_meta_setting_infos_by_name() did a naive search by name by iterating over all 42 setting types. Reorder nm_meta_setting_infos array, and use binary search instead. --- shared/nm-meta-setting.c | 39 ++++++++++++++++++++++++++++++++++----- shared/nm-meta-setting.h | 20 +++++++++++++------- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/shared/nm-meta-setting.c b/shared/nm-meta-setting.c index 00221dac6a..4ef07d85e5 100644 --- a/shared/nm-meta-setting.c +++ b/shared/nm-meta-setting.c @@ -408,15 +408,44 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { const NMMetaSettingInfo * nm_meta_setting_infos_by_name (const char *name) { - int i; + gssize idx; + +#if NM_MORE_ASSERTS > 10 + { + guint i, j; - if (name) { for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { - if (nm_streq (nm_meta_setting_infos[i].setting_name, name)) - return &nm_meta_setting_infos[i]; + const NMMetaSettingInfo *setting_info = &nm_meta_setting_infos[i]; + + nm_assert (setting_info->meta_type == (NMMetaSettingType) i); + nm_assert (setting_info->setting_name); + nm_assert (setting_info->setting_name[0]); + nm_assert (setting_info->get_setting_gtype); + nm_assert (setting_info->setting_priority != NM_SETTING_PRIORITY_INVALID); + if ( i > 0 + && strcmp (nm_meta_setting_infos[i - 1].setting_name, setting_info->setting_name) >= 0) { + g_error ("nm_meta_setting_infos[%u, \"%s\"] is wrongly sorted before nm_meta_setting_infos[%u, \"%s\"]. Rearange NMMetaSettingType enum", + i - 1, nm_meta_setting_infos[i - 1].setting_name, + i, setting_info->setting_name); + } + for (j = 0; j < i; j++) { + const NMMetaSettingInfo *s = &nm_meta_setting_infos[j]; + + nm_assert (setting_info->get_setting_gtype != s->get_setting_gtype); + } } } - return NULL; +#endif + + G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMMetaSettingInfo, setting_name) == 0); + idx = nm_utils_array_find_binary_search (nm_meta_setting_infos, + sizeof (NMMetaSettingInfo), + _NM_META_SETTING_TYPE_NUM, + &name, + nm_strcmp_p_with_data, + NULL); + + return idx >= 0 ? &nm_meta_setting_infos[idx] : NULL; } const NMMetaSettingInfo * diff --git a/shared/nm-meta-setting.h b/shared/nm-meta-setting.h index 28091ff98e..677ae4c00d 100644 --- a/shared/nm-meta-setting.h +++ b/shared/nm-meta-setting.h @@ -97,8 +97,18 @@ extern const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[_NM_SETTI /*****************************************************************************/ typedef enum { + /* the enum (and their numeric values) are internal API. Do not assign + * any meaning the numeric values, because they already have one: + * + * they are sorted in a way, that corresponds to the asciibetical sort + * order of the corresponding setting-name. */ + NM_META_SETTING_TYPE_6LOWPAN, + NM_META_SETTING_TYPE_OLPC_MESH, + NM_META_SETTING_TYPE_WIRELESS, + NM_META_SETTING_TYPE_WIRELESS_SECURITY, NM_META_SETTING_TYPE_802_1X, + NM_META_SETTING_TYPE_WIRED, NM_META_SETTING_TYPE_ADSL, NM_META_SETTING_TYPE_BLUETOOTH, NM_META_SETTING_TYPE_BOND, @@ -111,12 +121,11 @@ typedef enum { NM_META_SETTING_TYPE_GENERIC, NM_META_SETTING_TYPE_GSM, NM_META_SETTING_TYPE_INFINIBAND, + NM_META_SETTING_TYPE_IP_TUNNEL, NM_META_SETTING_TYPE_IP4_CONFIG, NM_META_SETTING_TYPE_IP6_CONFIG, - NM_META_SETTING_TYPE_IP_TUNNEL, NM_META_SETTING_TYPE_MACSEC, NM_META_SETTING_TYPE_MACVLAN, - NM_META_SETTING_TYPE_OLPC_MESH, NM_META_SETTING_TYPE_OVS_BRIDGE, NM_META_SETTING_TYPE_OVS_INTERFACE, NM_META_SETTING_TYPE_OVS_PATCH, @@ -135,9 +144,6 @@ typedef enum { NM_META_SETTING_TYPE_VPN, NM_META_SETTING_TYPE_VXLAN, NM_META_SETTING_TYPE_WIMAX, - NM_META_SETTING_TYPE_WIRED, - NM_META_SETTING_TYPE_WIRELESS, - NM_META_SETTING_TYPE_WIRELESS_SECURITY, NM_META_SETTING_TYPE_WPAN, NM_META_SETTING_TYPE_UNKNOWN, @@ -163,10 +169,10 @@ typedef enum { #define _NMMetaSettingInfoXX _NMMetaSettingInfoCli #endif struct _NMMetaSettingInfoXX { - NMMetaSettingType meta_type; - NMSettingPriority setting_priority; const char *setting_name; GType (*get_setting_gtype) (void); + NMMetaSettingType meta_type; + NMSettingPriority setting_priority; }; typedef struct _NMMetaSettingInfoXX NMMetaSettingInfo; From 2b43ce3a940664a063f49c167abb614c241940cf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 27 Jul 2018 16:11:41 +0200 Subject: [PATCH 20/32] libnm/keyfile: use NMMetaSettingInfo for indexing keyfile vtable We have NMMetaSettingType enum, which is an enum of all setting types. We also have an efficient way to get the enum (and its NMMetaSettingInfo) from an NMSetting, setting-name and GType. No longer maintain the vtable for keyfile by "setting-name". Instead, index it by NMMetaSettingType enum. That way, we get efficient lookup, and don't need to duplicate the functionality of finding the vtable entry for a setting. --- libnm-core/nm-keyfile.c | 112 ++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 49 deletions(-) diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c index a9f15455f4..6ea42d13bc 100644 --- a/libnm-core/nm-keyfile.c +++ b/libnm-core/nm-keyfile.c @@ -2096,18 +2096,16 @@ typedef struct { }) typedef struct { - const char *setting_name; const ParseInfoProperty*const*properties; } ParseInfoSetting; -#define PARSE_INFO_SETTING(_setting_name, ...) \ - { \ - .setting_name = _setting_name, \ +#define PARSE_INFO_SETTING(setting_type, ...) \ + [setting_type] = (&((const ParseInfoSetting) { \ __VA_ARGS__ \ - } + })) -static const ParseInfoSetting parse_infos[] = { - PARSE_INFO_SETTING (NM_SETTING_WIRELESS_SETTING_NAME, +static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIRELESS, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_WIRELESS_BSSID, .parser = mac_address_parser_ETHER, @@ -2124,7 +2122,7 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_802_1X_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_802_1X, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_802_1X_CA_CERT, .parser = cert_parser, @@ -2156,7 +2154,7 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_WIRED_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIRED, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, .parser = mac_address_parser_ETHER_cloned, @@ -2166,28 +2164,28 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_BLUETOOTH_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BLUETOOTH, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_BLUETOOTH_BDADDR, .parser = mac_address_parser_ETHER, ), ), ), - PARSE_INFO_SETTING (NM_SETTING_BOND_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BOND, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_BOND_OPTIONS, .parser_no_check_key = TRUE, ), ), ), - PARSE_INFO_SETTING (NM_SETTING_BRIDGE_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BRIDGE, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_BRIDGE_MAC_ADDRESS, .parser = mac_address_parser_ETHER, ), ), ), - PARSE_INFO_SETTING (NM_SETTING_CONNECTION_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_CONNECTION, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_CONNECTION_READ_ONLY, .parser_skip = TRUE, @@ -2199,14 +2197,14 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_INFINIBAND_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_INFINIBAND, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_INFINIBAND_MAC_ADDRESS, .parser = mac_address_parser_INFINIBAND, ), ), ), - PARSE_INFO_SETTING (NM_SETTING_IP4_CONFIG_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_IP4_CONFIG, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ADDRESSES, .parser_no_check_key = TRUE, @@ -2228,7 +2226,7 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_IP6_CONFIG_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_IP6_CONFIG, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, .parser_no_check_key = TRUE, @@ -2256,14 +2254,14 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_SERIAL_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_SERIAL, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_SERIAL_PARITY, .parser = parity_parser, ), ), ), - PARSE_INFO_SETTING (NM_SETTING_SRIOV_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_SRIOV, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_SRIOV_VFS, .parser_no_check_key = TRUE, @@ -2272,7 +2270,7 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_TC_CONFIG_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TC_CONFIG, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_TC_CONFIG_QDISCS, .parser_no_check_key = TRUE, @@ -2286,7 +2284,7 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_TEAM_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TEAM, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_TEAM_CONFIG, .parser = team_config_parser, @@ -2353,7 +2351,7 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_TEAM_PORT_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TEAM_PORT, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_TEAM_CONFIG, .parser = team_config_parser, @@ -2384,21 +2382,21 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_USER_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_USER, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_USER_DATA, .parser_no_check_key = TRUE, ), ), ), - PARSE_INFO_SETTING (NM_SETTING_VLAN_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_VLAN, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_VLAN_FLAGS, .writer_persist_default = TRUE, ), ), ), - PARSE_INFO_SETTING (NM_SETTING_VPN_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_VPN, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_VPN_DATA, .parser_no_check_key = TRUE, @@ -2420,7 +2418,7 @@ static const ParseInfoSetting parse_infos[] = { ), ), ), - PARSE_INFO_SETTING (NM_SETTING_WIMAX_SETTING_NAME, + PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIMAX, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_WIMAX_MAC_ADDRESS, .parser = mac_address_parser_ETHER, @@ -2430,21 +2428,24 @@ static const ParseInfoSetting parse_infos[] = { }; static const ParseInfoProperty * -_parse_info_find (const char *setting_name, const char *property_name) +_parse_info_find (NMSetting *setting, + const char *property_name, + const char **out_setting_name) { + const NMMetaSettingInfo *setting_info; + const ParseInfoSetting *pis; gssize idx; -#if NM_MORE_ASSERTS > 5 +#if NM_MORE_ASSERTS > 10 { guint i, j; for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) { - const ParseInfoSetting *pis = &parse_infos[i]; + pis = parse_infos[i]; + + if (!pis) + continue; - g_assert (pis->setting_name); - if ( i > 0 - && strcmp (pis[-1].setting_name, pis->setting_name) >= 0) - g_error ("Wrong order at index #%d: \"%s\" before \"%s\"", i - 1, pis[-1].setting_name, pis->setting_name); g_assert (pis->properties); g_assert (pis->properties[0]); for (j = 0; pis->properties[j]; j++) { @@ -2454,25 +2455,28 @@ _parse_info_find (const char *setting_name, const char *property_name) g_assert (pip->property_name); if ( j > 0 && (pip0 = pis->properties[j - 1]) - && strcmp (pip0->property_name, pip->property_name) >= 0) - g_error ("Wrong order at index #%d.%d: \"%s.%s\" before \"%s.%s\"", i, j - 1, pis->setting_name, pip0->property_name, pis->setting_name, pip->property_name); + && strcmp (pip0->property_name, pip->property_name) >= 0) { + g_error ("Wrong order at index #%d.%d: \"%s.%s\" before \"%s.%s\"", + i, j - 1, + nm_meta_setting_infos[i].setting_name, pip0->property_name, + nm_meta_setting_infos[i].setting_name, pip->property_name); + } } } } #endif - G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (ParseInfoSetting, setting_name) == 0); - idx = nm_utils_array_find_binary_search (parse_infos, - sizeof (ParseInfoSetting), - G_N_ELEMENTS (parse_infos), - &setting_name, - nm_strcmp_p_with_data, - NULL); - if (idx >= 0) { - const ParseInfoSetting *pis = &parse_infos[idx]; + if ( !NM_IS_SETTING (setting) + || !(setting_info = NM_SETTING_GET_CLASS (setting)->setting_info)) { + /* handle invalid setting objects gracefully. */ + *out_setting_name = NULL; + return NULL; + } + *out_setting_name = setting_info->setting_name; + + if ((pis = parse_infos[setting_info->meta_type])) { G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (ParseInfoProperty, property_name) == 0); - nm_assert (nm_streq (pis->setting_name, setting_name)); idx = nm_utils_ptrarray_find_binary_search ((gconstpointer *) pis->properties, NM_PTRARRAY_LEN (pis->properties), &property_name, @@ -2510,9 +2514,9 @@ read_one_setting_value (NMSetting *setting, if (!(flags & G_PARAM_WRITABLE)) return; - setting_name = nm_setting_get_name (setting); + pip = _parse_info_find (setting, key, &setting_name); - pip = _parse_info_find (setting_name, key); + nm_assert (setting_name); if ( !pip && nm_streq (key, NM_SETTING_NAME)) @@ -2884,12 +2888,22 @@ write_setting_value (NMSetting *setting, if (info->error) return; - setting_name = nm_setting_get_name (setting); - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key); nm_assert (pspec); - pip = _parse_info_find (setting_name, key); + pip = _parse_info_find (setting, key, &setting_name); + + if (!setting_name) { + /* the setting type is unknown. That is highly unexpected + * (and as this is currently only called from NetworkManager + * daemon, not possible). + * + * Still, handle it gracefully, because later keyfile writer will become + * public API of libnm, where @setting is (untrusted) user input. + * + * Gracefully here just means: ignore the setting. */ + return; + } if ( !pip && nm_streq (key, NM_SETTING_NAME)) From 3793804314c32b7199311736a8b1638c8f28d9fc Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 28 Jul 2018 15:26:03 +0200 Subject: [PATCH 21/32] libnm: rework setting metadata for property handling NMSetting internally already tracked a list of all proper GObject properties and D-Bus-only properties. Rework the tracking of the list, so that: - instead of attaching the data to the GType of the setting via g_type_set_qdata(), it is tracked in a static array indexed by NMMetaSettingType. This allows to find the setting-data by simple pointer arithmetic, instead of taking a look and iterating (like g_type_set_qdata() does). Note, that this is still thread safe, because the static table entry is initialized in the class-init function with _nm_setting_class_commit(). And it only accessed by following a NMSettingClass instance, thus the class constructor already ran (maybe not for all setting classes, but for the particular one that we look up). I think this makes initialization of the metadata simpler to understand. Previously, in a first phase each class would attach the metadata to the GType as setting_property_overrides_quark(). Then during nm_setting_class_ensure_properties() it would merge them and set as setting_properties_quark(). Now, during the first phase, we only incrementally build a properties_override GArray, which we finally hand over during nm_setting_class_commit(). - sort the property infos by name and do binary search. Also expose this meta data types as internal API in nm-setting-private.h. While not accessed yet, it can prove beneficial, to have direct (internal) access to these structures. Also, rename NMSettingProperty to NMSettInfoProperty to use a distinct naming scheme. We already have 40+ subclasses of NMSetting that are called NMSetting*. Likewise, NMMetaSetting* is heavily used already. So, choose a new, distinct name. --- libnm-core/nm-core-internal.h | 53 +++ libnm-core/nm-setting-6lowpan.c | 5 +- libnm-core/nm-setting-8021x.c | 3 +- libnm-core/nm-setting-adsl.c | 3 +- libnm-core/nm-setting-bluetooth.c | 16 +- libnm-core/nm-setting-bond.c | 25 +- libnm-core/nm-setting-bridge-port.c | 5 +- libnm-core/nm-setting-bridge.c | 27 +- libnm-core/nm-setting-cdma.c | 2 +- libnm-core/nm-setting-connection.c | 18 +- libnm-core/nm-setting-dcb.c | 73 ++-- libnm-core/nm-setting-dummy.c | 5 +- libnm-core/nm-setting-generic.c | 2 +- libnm-core/nm-setting-gsm.c | 22 +- libnm-core/nm-setting-infiniband.c | 17 +- libnm-core/nm-setting-ip-config.c | 24 +- libnm-core/nm-setting-ip-tunnel.c | 5 +- libnm-core/nm-setting-ip4-config.c | 73 ++-- libnm-core/nm-setting-ip6-config.c | 64 ++-- libnm-core/nm-setting-macsec.c | 3 +- libnm-core/nm-setting-macvlan.c | 5 +- libnm-core/nm-setting-olpc-mesh.c | 18 +- libnm-core/nm-setting-ovs-bridge.c | 5 +- libnm-core/nm-setting-ovs-interface.c | 5 +- libnm-core/nm-setting-ovs-patch.c | 5 +- libnm-core/nm-setting-ovs-port.c | 5 +- libnm-core/nm-setting-ppp.c | 5 +- libnm-core/nm-setting-pppoe.c | 3 +- libnm-core/nm-setting-private.h | 95 ++++-- libnm-core/nm-setting-proxy.c | 5 +- libnm-core/nm-setting-serial.c | 18 +- libnm-core/nm-setting-sriov.c | 18 +- libnm-core/nm-setting-tc-config.c | 31 +- libnm-core/nm-setting-team-port.c | 16 +- libnm-core/nm-setting-team.c | 26 +- libnm-core/nm-setting-tun.c | 5 +- libnm-core/nm-setting-user.c | 15 +- libnm-core/nm-setting-vlan.c | 29 +- libnm-core/nm-setting-vpn.c | 27 +- libnm-core/nm-setting-vxlan.c | 5 +- libnm-core/nm-setting-wimax.c | 18 +- libnm-core/nm-setting-wired.c | 57 ++-- libnm-core/nm-setting-wireless-security.c | 17 +- libnm-core/nm-setting-wireless.c | 59 ++-- libnm-core/nm-setting-wpan.c | 5 +- libnm-core/nm-setting.c | 384 +++++++++++----------- 46 files changed, 798 insertions(+), 528 deletions(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index b53f5c02f8..21c45ab425 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -479,4 +479,57 @@ gboolean _nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin); gboolean _nm_setting_sriov_sort_vfs (NMSettingSriov *setting); +/*****************************************************************************/ + +typedef GVariant *(*NMSettingPropertyGetFunc) (NMSetting *setting, + const char *property); +typedef GVariant *(*NMSettingPropertySynthFunc) (NMSetting *setting, + NMConnection *connection, + const char *property); +typedef gboolean (*NMSettingPropertySetFunc) (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value, + NMSettingParseFlags parse_flags, + GError **error); +typedef gboolean (*NMSettingPropertyNotSetFunc) (NMSetting *setting, + GVariant *connection_dict, + const char *property, + NMSettingParseFlags parse_flags, + GError **error); +typedef GVariant *(*NMSettingPropertyTransformToFunc) (const GValue *from); +typedef void (*NMSettingPropertyTransformFromFunc) (GVariant *from, + GValue *to); + +typedef struct { + const char *name; + GParamSpec *param_spec; + const GVariantType *dbus_type; + + NMSettingPropertyGetFunc get_func; + NMSettingPropertySynthFunc synth_func; + NMSettingPropertySetFunc set_func; + NMSettingPropertyNotSetFunc not_set_func; + + NMSettingPropertyTransformToFunc to_dbus; + NMSettingPropertyTransformFromFunc from_dbus; +} NMSettInfoProperty; + +typedef struct { +} NMSettInfoSettDetail; + +typedef struct { + NMSettingClass *setting_class; + const NMSettInfoProperty *property_infos; + guint property_infos_len; + NMSettInfoSettDetail detail; +} NMSettInfoSetting; + +const NMSettInfoSetting *_nm_sett_info_setting_get (NMSettingClass *setting_class); + +const NMSettInfoProperty *_nm_sett_info_property_get (NMSettingClass *setting_class, + const char *property_name); + +/*****************************************************************************/ + #endif diff --git a/libnm-core/nm-setting-6lowpan.c b/libnm-core/nm-setting-6lowpan.c index 6d2b510799..c0ce232dab 100644 --- a/libnm-core/nm-setting-6lowpan.c +++ b/libnm-core/nm-setting-6lowpan.c @@ -206,8 +206,7 @@ nm_setting_6lowpan_class_init (NMSetting6LowpanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_6LOWPAN]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSetting6Lowpan:parent: @@ -226,4 +225,6 @@ nm_setting_6lowpan_class_init (NMSetting6LowpanClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_6LOWPAN); } diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 8c08bfa53b..0d61f91c5d 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -3771,7 +3771,6 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_802_1X]; setting_class->verify = verify; setting_class->need_secrets = need_secrets; @@ -4803,4 +4802,6 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_802_1X); } diff --git a/libnm-core/nm-setting-adsl.c b/libnm-core/nm-setting-adsl.c index eb9aad41ab..9ffff92783 100644 --- a/libnm-core/nm-setting-adsl.c +++ b/libnm-core/nm-setting-adsl.c @@ -355,7 +355,6 @@ nm_setting_adsl_class_init (NMSettingAdslClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_ADSL]; setting_class->verify = verify; setting_class->verify_secrets = verify_secrets; setting_class->need_secrets = need_secrets; @@ -445,4 +444,6 @@ nm_setting_adsl_class_init (NMSettingAdslClass *klass) 0, 65536, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_ADSL); } diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index 2cc3d7ad41..bbc6a83de3 100644 --- a/libnm-core/nm-setting-bluetooth.c +++ b/libnm-core/nm-setting-bluetooth.c @@ -285,6 +285,7 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingBluetoothPrivate)); @@ -292,7 +293,6 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_BLUETOOTH]; setting_class->verify = verify; /** @@ -307,10 +307,13 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_BLUETOOTH_BDADDR, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_BLUETOOTH_BDADDR), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); /** * NMSettingBluetooth:type: @@ -325,4 +328,7 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_BLUETOOTH, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 53db178218..0c84b3a01c 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -962,6 +962,7 @@ nm_setting_bond_class_init (NMSettingBondClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingBondPrivate)); @@ -969,7 +970,6 @@ nm_setting_bond_class_init (NMSettingBondClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_BOND]; setting_class->verify = verify; setting_class->compare_property = compare_property; @@ -994,10 +994,13 @@ nm_setting_bond_class_init (NMSettingBondClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_BOND_OPTIONS, - G_VARIANT_TYPE ("a{ss}"), - _nm_utils_strdict_to_dbus, - _nm_utils_strdict_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_BOND_OPTIONS), + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); /* ---dbus--- * property: interface-name @@ -1007,8 +1010,12 @@ nm_setting_bond_class_init (NMSettingBondClass *klass) * bond's interface name. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, "interface-name", - G_VARIANT_TYPE_STRING, - _nm_setting_get_deprecated_virtual_interface_name, - NULL); + _properties_override_add_dbus_only (properties_override, + "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_BOND, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-bridge-port.c b/libnm-core/nm-setting-bridge-port.c index 23a431f4fe..4104f8c5cc 100644 --- a/libnm-core/nm-setting-bridge-port.c +++ b/libnm-core/nm-setting-bridge-port.c @@ -220,8 +220,7 @@ nm_setting_bridge_port_class_init (NMSettingBridgePortClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_BRIDGE_PORT]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingBridgePort:priority: @@ -288,4 +287,6 @@ nm_setting_bridge_port_class_init (NMSettingBridgePortClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_BRIDGE_PORT); } diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c index 951f35888b..71fe2ed234 100644 --- a/libnm-core/nm-setting-bridge.c +++ b/libnm-core/nm-setting-bridge.c @@ -395,6 +395,7 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingBridgePrivate)); @@ -402,8 +403,7 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_BRIDGE]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingBridge:mac-address: @@ -442,10 +442,13 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_BRIDGE_MAC_ADDRESS, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_BRIDGE_MAC_ADDRESS), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); /** * NMSettingBridge:stp: @@ -636,8 +639,12 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass) * bridge's interface name. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, "interface-name", - G_VARIANT_TYPE_STRING, - _nm_setting_get_deprecated_virtual_interface_name, - NULL); + _properties_override_add_dbus_only (properties_override, + "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_BRIDGE, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-cdma.c b/libnm-core/nm-setting-cdma.c index bb49ec9d3f..a5d5428d4b 100644 --- a/libnm-core/nm-setting-cdma.c +++ b/libnm-core/nm-setting-cdma.c @@ -294,7 +294,6 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_CDMA]; setting_class->verify = verify; setting_class->verify_secrets = verify_secrets; setting_class->need_secrets = need_secrets; @@ -372,4 +371,5 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *klass) NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS)); + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_CDMA); } diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 6a6c76036f..a7d1777f01 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -1505,6 +1505,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingConnectionPrivate)); @@ -1512,7 +1513,6 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_CONNECTION]; setting_class->verify = verify; setting_class->compare_property = compare_property; @@ -1651,11 +1651,14 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, NM_SETTING_CONNECTION_INTERFACE_NAME, - G_VARIANT_TYPE_STRING, - NULL, - nm_setting_connection_set_interface_name, - nm_setting_connection_no_interface_name); + + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_CONNECTION_INTERFACE_NAME), + G_VARIANT_TYPE_STRING, + NULL, + nm_setting_connection_set_interface_name, + nm_setting_connection_no_interface_name); /** * NMSettingConnection:type: @@ -2125,4 +2128,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) NM_SETTING_CONNECTION_MDNS_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_CONNECTION, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-dcb.c b/libnm-core/nm-setting-dcb.c index f306b77b16..dabcbbaf19 100644 --- a/libnm-core/nm-setting-dcb.c +++ b/libnm-core/nm-setting-dcb.c @@ -909,6 +909,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingDcbPrivate)); @@ -916,8 +917,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_DCB]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingDcb:app-fcoe-flags: @@ -1117,10 +1117,13 @@ nm_setting_dcb_class_init (NMSettingDcbClass *klass) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, - G_VARIANT_TYPE ("au"), - _nm_setting_dcb_uint_array_to_dbus, - _nm_setting_dcb_uint_array_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_DCB_PRIORITY_FLOW_CONTROL), + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); /** * NMSettingDcb:priority-group-flags: @@ -1165,10 +1168,13 @@ nm_setting_dcb_class_init (NMSettingDcbClass *klass) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_GROUP_ID, - G_VARIANT_TYPE ("au"), - _nm_setting_dcb_uint_array_to_dbus, - _nm_setting_dcb_uint_array_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_DCB_PRIORITY_GROUP_ID), + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); /** * NMSettingDcb:priority-group-bandwidth: (type GArray(guint)) @@ -1191,10 +1197,13 @@ nm_setting_dcb_class_init (NMSettingDcbClass *klass) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, - G_VARIANT_TYPE ("au"), - _nm_setting_dcb_uint_array_to_dbus, - _nm_setting_dcb_uint_array_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH), + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); /** * NMSettingDcb:priority-bandwidth: (type GArray(guint)) @@ -1219,10 +1228,13 @@ nm_setting_dcb_class_init (NMSettingDcbClass *klass) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_BANDWIDTH, - G_VARIANT_TYPE ("au"), - _nm_setting_dcb_uint_array_to_dbus, - _nm_setting_dcb_uint_array_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_DCB_PRIORITY_BANDWIDTH), + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); /** * NMSettingDcb:priority-strict-bandwidth: (type GArray(gboolean)) @@ -1245,10 +1257,13 @@ nm_setting_dcb_class_init (NMSettingDcbClass *klass) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, - G_VARIANT_TYPE ("au"), - _nm_setting_dcb_uint_array_to_dbus, - _nm_setting_dcb_uint_array_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH), + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); /** * NMSettingDcb:priority-traffic-class: (type GArray(guint)) @@ -1270,8 +1285,14 @@ nm_setting_dcb_class_init (NMSettingDcbClass *klass) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, - G_VARIANT_TYPE ("au"), - _nm_setting_dcb_uint_array_to_dbus, - _nm_setting_dcb_uint_array_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS), + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_DCB, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-dummy.c b/libnm-core/nm-setting-dummy.c index 78e67d1dd7..9ae05ec4e7 100644 --- a/libnm-core/nm-setting-dummy.c +++ b/libnm-core/nm-setting-dummy.c @@ -70,6 +70,7 @@ nm_setting_dummy_class_init (NMSettingDummyClass *klass) { NMSettingClass *setting_class = NM_SETTING_CLASS (klass); - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_DUMMY]; - setting_class->verify = verify; + setting_class->verify = verify; + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_DUMMY); } diff --git a/libnm-core/nm-setting-generic.c b/libnm-core/nm-setting-generic.c index 762062417e..44402e397d 100644 --- a/libnm-core/nm-setting-generic.c +++ b/libnm-core/nm-setting-generic.c @@ -71,5 +71,5 @@ nm_setting_generic_class_init (NMSettingGenericClass *klass) g_type_class_add_private (klass, sizeof (NMSettingGenericPrivate)); - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_GENERIC]; + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_GENERIC); } diff --git a/libnm-core/nm-setting-gsm.c b/libnm-core/nm-setting-gsm.c index 3b4f604628..b31da68912 100644 --- a/libnm-core/nm-setting-gsm.c +++ b/libnm-core/nm-setting-gsm.c @@ -606,6 +606,7 @@ nm_setting_gsm_class_init (NMSettingGsmClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingGsmPrivate)); @@ -613,7 +614,6 @@ nm_setting_gsm_class_init (NMSettingGsmClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_GSM]; setting_class->verify = verify; setting_class->verify_secrets = verify_secrets; setting_class->need_secrets = need_secrets; @@ -819,10 +819,18 @@ nm_setting_gsm_class_init (NMSettingGsmClass *klass) G_PARAM_STATIC_STRINGS)); /* Ignore incoming deprecated properties */ - _nm_setting_class_add_dbus_only_property (setting_class, "allowed-bands", - G_VARIANT_TYPE_UINT32, - NULL, NULL); - _nm_setting_class_add_dbus_only_property (setting_class, "network-type", - G_VARIANT_TYPE_INT32, - NULL, NULL); + _properties_override_add_dbus_only (properties_override, + "allowed-bands", + G_VARIANT_TYPE_UINT32, + NULL, + NULL); + + _properties_override_add_dbus_only (properties_override, + "network-type", + G_VARIANT_TYPE_INT32, + NULL, + NULL); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_GSM, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index 96997e9ebd..d5ae708530 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -380,6 +380,7 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingInfinibandPrivate)); @@ -387,8 +388,7 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_INFINIBAND]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingInfiniband:mac-address: @@ -422,10 +422,13 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_INFINIBAND_MAC_ADDRESS, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_INFINIBAND_MAC_ADDRESS), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); /** * NMSettingInfiniband:mtu: @@ -523,4 +526,6 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *klass) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_INFINIBAND, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index c3ad316632..5af9b64041 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -2878,6 +2878,23 @@ ip_gateway_set (NMSetting *setting, return TRUE; } +GArray * +_nm_sett_info_property_override_create_array_ip_config (void) +{ + nm_auto_unref_gtypeclass NMSettingClass *setting_class = g_type_class_ref (NM_TYPE_SETTING_IP_CONFIG); + GArray *properties_override = _nm_sett_info_property_override_create_array (); + + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_IP_CONFIG_GATEWAY), + G_VARIANT_TYPE_STRING, + NULL, + ip_gateway_set, + NULL); + + return properties_override; +} + static void nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass) { @@ -3041,13 +3058,6 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, - NM_SETTING_IP_CONFIG_GATEWAY, - G_VARIANT_TYPE_STRING, - NULL, - ip_gateway_set, - NULL); - /** * NMSettingIPConfig:routes: (type GPtrArray(NMIPRoute)) * diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c index b255edf339..41314f5894 100644 --- a/libnm-core/nm-setting-ip-tunnel.c +++ b/libnm-core/nm-setting-ip-tunnel.c @@ -632,8 +632,7 @@ nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_IP_TUNNEL]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingIPTunnel:parent: @@ -851,4 +850,6 @@ nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_IP_TUNNEL); } diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index 95ff57ca1b..44de154ec0 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -527,6 +527,7 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *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_ip_config (); g_type_class_add_private (setting_class, sizeof (NMSettingIP4ConfigPrivate)); @@ -534,8 +535,7 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_IP4_CONFIG]; - setting_class->verify = verify; + setting_class->verify = verify; /* ---ifcfg-rh--- * property: method @@ -795,11 +795,12 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *klass) * integers) * ---end--- */ - _nm_setting_class_transform_property (setting_class, - NM_SETTING_IP_CONFIG_DNS, - G_VARIANT_TYPE ("au"), - ip4_dns_to_dbus, - ip4_dns_from_dbus); + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_IP_CONFIG_DNS), + G_VARIANT_TYPE ("au"), + ip4_dns_to_dbus, + ip4_dns_from_dbus); /* ---dbus--- * property: addresses @@ -816,18 +817,19 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *klass) * for that subnet. * ---end--- */ - _nm_setting_class_override_property (setting_class, - NM_SETTING_IP_CONFIG_ADDRESSES, - G_VARIANT_TYPE ("aau"), - ip4_addresses_get, - ip4_addresses_set, - NULL); + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_IP_CONFIG_ADDRESSES), + G_VARIANT_TYPE ("aau"), + ip4_addresses_get, + ip4_addresses_set, + NULL); - _nm_setting_class_add_dbus_only_property (setting_class, - "address-labels", - G_VARIANT_TYPE_STRING_ARRAY, - ip4_address_labels_get, - NULL); + _properties_override_add_dbus_only (properties_override, + "address-labels", + G_VARIANT_TYPE_STRING_ARRAY, + ip4_address_labels_get, + NULL); /* ---dbus--- * property: address-data @@ -838,11 +840,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *klass) * also exist on some addresses. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, - "address-data", - G_VARIANT_TYPE ("aa{sv}"), - ip4_address_data_get, - ip4_address_data_set); + _properties_override_add_dbus_only (properties_override, + "address-data", + G_VARIANT_TYPE ("aa{sv}"), + ip4_address_data_get, + ip4_address_data_set); /* ---dbus--- * property: routes @@ -861,12 +863,13 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *klass) * property.) * ---end--- */ - _nm_setting_class_override_property (setting_class, - NM_SETTING_IP_CONFIG_ROUTES, - G_VARIANT_TYPE ("aau"), - ip4_routes_get, - ip4_routes_set, - NULL); + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_IP_CONFIG_ROUTES), + G_VARIANT_TYPE ("aau"), + ip4_routes_get, + ip4_routes_set, + NULL); /* ---dbus--- * property: route-data @@ -881,10 +884,12 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *klass) * also exist on some routes. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, - "route-data", - G_VARIANT_TYPE ("aa{sv}"), - ip4_route_data_get, - ip4_route_data_set); + _properties_override_add_dbus_only (properties_override, + "route-data", + G_VARIANT_TYPE ("aa{sv}"), + ip4_route_data_get, + ip4_route_data_set); + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_IP4_CONFIG, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 3f7dd00ce0..a55fd80195 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -551,6 +551,7 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *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_ip_config (); g_type_class_add_private (klass, sizeof (NMSettingIP6ConfigPrivate)); @@ -558,8 +559,7 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_IP6_CONFIG]; - setting_class->verify = verify; + setting_class->verify = verify; /* ---ifcfg-rh--- * property: method @@ -888,11 +888,12 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) * description: Array of IP addresses of DNS servers (in network byte order) * ---end--- */ - _nm_setting_class_transform_property (setting_class, - NM_SETTING_IP_CONFIG_DNS, - G_VARIANT_TYPE ("aay"), - ip6_dns_to_dbus, - ip6_dns_from_dbus); + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_IP_CONFIG_DNS), + G_VARIANT_TYPE ("aay"), + ip6_dns_to_dbus, + ip6_dns_from_dbus); /* ---dbus--- * property: addresses @@ -908,12 +909,13 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) * that subnet. * ---end--- */ - _nm_setting_class_override_property (setting_class, - NM_SETTING_IP_CONFIG_ADDRESSES, - G_VARIANT_TYPE ("a(ayuay)"), - ip6_addresses_get, - ip6_addresses_set, - NULL); + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_IP_CONFIG_ADDRESSES), + G_VARIANT_TYPE ("a(ayuay)"), + ip6_addresses_get, + ip6_addresses_set, + NULL); /* ---dbus--- * property: address-data @@ -924,11 +926,11 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) * also exist on some addresses. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, - "address-data", - G_VARIANT_TYPE ("aa{sv}"), - ip6_address_data_get, - ip6_address_data_set); + _properties_override_add_dbus_only (properties_override, + "address-data", + G_VARIANT_TYPE ("aa{sv}"), + ip6_address_data_get, + ip6_address_data_set); /* ---dbus--- * property: routes @@ -944,12 +946,13 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) * default metric for the device. * ---end--- */ - _nm_setting_class_override_property (setting_class, - NM_SETTING_IP_CONFIG_ROUTES, - G_VARIANT_TYPE ("a(ayuayu)"), - ip6_routes_get, - ip6_routes_set, - NULL); + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_IP_CONFIG_ROUTES), + G_VARIANT_TYPE ("a(ayuayu)"), + ip6_routes_get, + ip6_routes_set, + NULL); /* ---dbus--- * property: route-data @@ -964,9 +967,12 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) * also exist on some routes. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, - "route-data", - G_VARIANT_TYPE ("aa{sv}"), - ip6_route_data_get, - ip6_route_data_set); + _properties_override_add_dbus_only (properties_override, + "route-data", + G_VARIANT_TYPE ("aa{sv}"), + ip6_route_data_get, + ip6_route_data_set); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_IP6_CONFIG, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-macsec.c b/libnm-core/nm-setting-macsec.c index 9705a31040..2c7cff23b1 100644 --- a/libnm-core/nm-setting-macsec.c +++ b/libnm-core/nm-setting-macsec.c @@ -483,7 +483,6 @@ nm_setting_macsec_class_init (NMSettingMacsecClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_MACSEC]; setting_class->verify = verify; setting_class->need_secrets = need_secrets; @@ -627,4 +626,6 @@ nm_setting_macsec_class_init (NMSettingMacsecClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_MACSEC); } diff --git a/libnm-core/nm-setting-macvlan.c b/libnm-core/nm-setting-macvlan.c index 133131fa5d..1fc16116e0 100644 --- a/libnm-core/nm-setting-macvlan.c +++ b/libnm-core/nm-setting-macvlan.c @@ -269,8 +269,7 @@ nm_setting_macvlan_class_init (NMSettingMacvlanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_MACVLAN]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingMacvlan:parent: @@ -339,4 +338,6 @@ nm_setting_macvlan_class_init (NMSettingMacvlanClass *klass) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_MACVLAN); } diff --git a/libnm-core/nm-setting-olpc-mesh.c b/libnm-core/nm-setting-olpc-mesh.c index 9e215dc60d..7f4a1bbf11 100644 --- a/libnm-core/nm-setting-olpc-mesh.c +++ b/libnm-core/nm-setting-olpc-mesh.c @@ -216,6 +216,7 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingOlpcMeshPrivate)); @@ -223,8 +224,7 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OLPC_MESH]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingOlpcMesh:ssid: @@ -266,8 +266,14 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_OLPC_MESH, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-ovs-bridge.c b/libnm-core/nm-setting-ovs-bridge.c index 669bae9631..9ca5566fb9 100644 --- a/libnm-core/nm-setting-ovs-bridge.c +++ b/libnm-core/nm-setting-ovs-bridge.c @@ -271,8 +271,7 @@ nm_setting_ovs_bridge_class_init (NMSettingOvsBridgeClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OVS_BRIDGE]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingOvsBridge:fail-mode: @@ -334,4 +333,6 @@ nm_setting_ovs_bridge_class_init (NMSettingOvsBridgeClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_OVS_BRIDGE); } diff --git a/libnm-core/nm-setting-ovs-interface.c b/libnm-core/nm-setting-ovs-interface.c index 23325eb957..a177098dbf 100644 --- a/libnm-core/nm-setting-ovs-interface.c +++ b/libnm-core/nm-setting-ovs-interface.c @@ -370,8 +370,7 @@ nm_setting_ovs_interface_class_init (NMSettingOvsInterfaceClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OVS_INTERFACE]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingOvsInterface:type: @@ -388,4 +387,6 @@ nm_setting_ovs_interface_class_init (NMSettingOvsInterfaceClass *klass) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_OVS_INTERFACE); } diff --git a/libnm-core/nm-setting-ovs-patch.c b/libnm-core/nm-setting-ovs-patch.c index 0acdcb9d03..15005eeaef 100644 --- a/libnm-core/nm-setting-ovs-patch.c +++ b/libnm-core/nm-setting-ovs-patch.c @@ -189,8 +189,7 @@ nm_setting_ovs_patch_class_init (NMSettingOvsPatchClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OVS_PATCH]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingOvsPatch:peer: @@ -208,4 +207,6 @@ nm_setting_ovs_patch_class_init (NMSettingOvsPatchClass *klass) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_OVS_PATCH); } diff --git a/libnm-core/nm-setting-ovs-port.c b/libnm-core/nm-setting-ovs-port.c index 8fc19fc3c1..10e542e7d2 100644 --- a/libnm-core/nm-setting-ovs-port.c +++ b/libnm-core/nm-setting-ovs-port.c @@ -368,8 +368,7 @@ nm_setting_ovs_port_class_init (NMSettingOvsPortClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_OVS_PORT]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingOvsPort:vlan-mode: @@ -467,4 +466,6 @@ nm_setting_ovs_port_class_init (NMSettingOvsPortClass *klass) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_OVS_PORT); } diff --git a/libnm-core/nm-setting-ppp.c b/libnm-core/nm-setting-ppp.c index 905ec146a7..7425da193b 100644 --- a/libnm-core/nm-setting-ppp.c +++ b/libnm-core/nm-setting-ppp.c @@ -533,8 +533,7 @@ nm_setting_ppp_class_init (NMSettingPppClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_PPP]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingPpp:noauth: @@ -796,4 +795,6 @@ nm_setting_ppp_class_init (NMSettingPppClass *klass) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_PPP); } diff --git a/libnm-core/nm-setting-pppoe.c b/libnm-core/nm-setting-pppoe.c index 679a30cebb..793d93cea2 100644 --- a/libnm-core/nm-setting-pppoe.c +++ b/libnm-core/nm-setting-pppoe.c @@ -297,7 +297,6 @@ nm_setting_pppoe_class_init (NMSettingPppoeClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_PPPOE]; setting_class->verify = verify; setting_class->need_secrets = need_secrets; @@ -372,4 +371,6 @@ nm_setting_pppoe_class_init (NMSettingPppoeClass *klass) NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_PPPOE); } diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h index 4a92264b7c..99c7b69ccd 100644 --- a/libnm-core/nm-setting-private.h +++ b/libnm-core/nm-setting-private.h @@ -105,44 +105,69 @@ NMSetting *_nm_setting_new_from_dbus (GType setting_type, NMSettingParseFlags parse_flags, GError **error); -typedef GVariant * (*NMSettingPropertyGetFunc) (NMSetting *setting, - const char *property); -typedef GVariant * (*NMSettingPropertySynthFunc) (NMSetting *setting, - NMConnection *connection, - const char *property); -typedef gboolean (*NMSettingPropertySetFunc) (NMSetting *setting, - GVariant *connection_dict, - const char *property, - GVariant *value, - NMSettingParseFlags parse_flags, - GError **error); -typedef gboolean (*NMSettingPropertyNotSetFunc) (NMSetting *setting, - GVariant *connection_dict, - const char *property, - NMSettingParseFlags parse_flags, - GError **error); +/*****************************************************************************/ -void _nm_setting_class_add_dbus_only_property (NMSettingClass *setting_class, - const char *property_name, - const GVariantType *dbus_type, - NMSettingPropertySynthFunc synth_func, - NMSettingPropertySetFunc set_func); +static inline GArray * +_nm_sett_info_property_override_create_array (void) +{ + return g_array_new (FALSE, FALSE, sizeof (NMSettInfoProperty)); +} -void _nm_setting_class_override_property (NMSettingClass *setting_class, - const char *property_name, - const GVariantType *dbus_type, - NMSettingPropertyGetFunc get_func, - NMSettingPropertySetFunc set_func, - NMSettingPropertyNotSetFunc not_set_func); +GArray *_nm_sett_info_property_override_create_array_ip_config (void); -typedef GVariant * (*NMSettingPropertyTransformToFunc) (const GValue *from); -typedef void (*NMSettingPropertyTransformFromFunc) (GVariant *from, GValue *to); +void _nm_setting_class_commit_full (NMSettingClass *setting_class, + NMMetaSettingType meta_type, + const NMSettInfoSettDetail *detail, + GArray *properties_override); -void _nm_setting_class_transform_property (NMSettingClass *setting_class, - const char *property_name, - const GVariantType *dbus_type, - NMSettingPropertyTransformToFunc to_dbus, - NMSettingPropertyTransformFromFunc from_dbus); +static inline void +_nm_setting_class_commit (NMSettingClass *setting_class, + NMMetaSettingType meta_type) +{ + _nm_setting_class_commit_full (setting_class, meta_type, NULL, NULL); +} + +#define NM_SETT_INFO_SETT_DETAIL(...) \ + (&((const NMSettInfoSettDetail) { \ + __VA_ARGS__ \ + })) + +#define NM_SETT_INFO_PROPERTY(...) \ + (&((const NMSettInfoProperty) { \ + __VA_ARGS__ \ + })) + +void _properties_override_add_struct (GArray *properties_override, + const NMSettInfoProperty *prop_info); + +void _properties_override_add__helper (GArray *properties_override, + NMSettInfoProperty *prop_info); + +#define _properties_override_add(properties_override, \ + ...) \ + (_properties_override_add_struct (properties_override, \ + NM_SETT_INFO_PROPERTY (__VA_ARGS__))) + +void _properties_override_add_dbus_only (GArray *properties_override, + const char *property_name, + const GVariantType *dbus_type, + NMSettingPropertySynthFunc synth_func, + NMSettingPropertySetFunc set_func); + +void _properties_override_add_override (GArray *properties_override, + GParamSpec *param_spec, + const GVariantType *dbus_type, + NMSettingPropertyGetFunc get_func, + NMSettingPropertySetFunc set_func, + NMSettingPropertyNotSetFunc not_set_func); + +void _properties_override_add_transform (GArray *properties_override, + GParamSpec *param_spec, + const GVariantType *dbus_type, + NMSettingPropertyTransformToFunc to_dbus, + NMSettingPropertyTransformFromFunc from_dbus); + +/*****************************************************************************/ gboolean _nm_setting_use_legacy_property (NMSetting *setting, GVariant *connection_dict, @@ -151,4 +176,6 @@ gboolean _nm_setting_use_legacy_property (NMSetting *setting, GPtrArray *_nm_setting_need_secrets (NMSetting *setting); +/*****************************************************************************/ + #endif /* NM_SETTING_PRIVATE_H */ diff --git a/libnm-core/nm-setting-proxy.c b/libnm-core/nm-setting-proxy.c index 8faf9ba4e7..d544c7fa14 100644 --- a/libnm-core/nm-setting-proxy.c +++ b/libnm-core/nm-setting-proxy.c @@ -294,8 +294,7 @@ nm_setting_proxy_class_init (NMSettingProxyClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_PROXY]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingProxy:method: @@ -383,4 +382,6 @@ nm_setting_proxy_class_init (NMSettingProxyClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_PROXY); } diff --git a/libnm-core/nm-setting-serial.c b/libnm-core/nm-setting-serial.c index 26baf95011..b173197db8 100644 --- a/libnm-core/nm-setting-serial.c +++ b/libnm-core/nm-setting-serial.c @@ -240,14 +240,13 @@ nm_setting_serial_class_init (NMSettingSerialClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingSerialPrivate)); object_class->set_property = set_property; object_class->get_property = get_property; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_SERIAL]; - /** * NMSettingSerial:baud: * @@ -304,11 +303,13 @@ nm_setting_serial_class_init (NMSettingSerialClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, - NM_SETTING_SERIAL_PARITY, - G_VARIANT_TYPE_BYTE, - parity_to_dbus, - parity_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_SERIAL_PARITY), + G_VARIANT_TYPE_BYTE, + parity_to_dbus, + parity_from_dbus); /** * NMSettingSerial:stopbits: @@ -336,4 +337,7 @@ nm_setting_serial_class_init (NMSettingSerialClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_SERIAL, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-sriov.c b/libnm-core/nm-setting-sriov.c index 90108ca721..45b3a1d2f5 100644 --- a/libnm-core/nm-setting-sriov.c +++ b/libnm-core/nm-setting-sriov.c @@ -1234,12 +1234,12 @@ nm_setting_sriov_class_init (NMSettingSriovClass *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 (); object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_SRIOV]; setting_class->compare_property = compare_property; setting_class->verify = verify; @@ -1308,12 +1308,13 @@ nm_setting_sriov_class_init (NMSettingSriovClass *klass) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, - NM_SETTING_SRIOV_VFS, - G_VARIANT_TYPE ("aa{sv}"), - vfs_to_dbus, - vfs_from_dbus, - NULL); + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_SRIOV_VFS), + G_VARIANT_TYPE ("aa{sv}"), + vfs_to_dbus, + vfs_from_dbus, + NULL); /** * NMSettingSriov:autoprobe-drivers @@ -1350,4 +1351,7 @@ nm_setting_sriov_class_init (NMSettingSriovClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_SRIOV, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-tc-config.c b/libnm-core/nm-setting-tc-config.c index 01e2e34fb9..43015d3708 100644 --- a/libnm-core/nm-setting-tc-config.c +++ b/libnm-core/nm-setting-tc-config.c @@ -1591,12 +1591,12 @@ nm_setting_tc_config_class_init (NMSettingTCConfigClass *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 (); object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_TC_CONFIG]; setting_class->compare_property = compare_property; setting_class->verify = verify; @@ -1620,12 +1620,13 @@ nm_setting_tc_config_class_init (NMSettingTCConfigClass *klass) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, - NM_SETTING_TC_CONFIG_QDISCS, - G_VARIANT_TYPE ("aa{sv}"), - tc_qdiscs_get, - tc_qdiscs_set, - NULL); + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_TC_CONFIG_QDISCS), + G_VARIANT_TYPE ("aa{sv}"), + tc_qdiscs_get, + tc_qdiscs_set, + NULL); /** * NMSettingTCConfig:tfilters: (type GPtrArray(NMTCTfilter)) @@ -1647,10 +1648,14 @@ nm_setting_tc_config_class_init (NMSettingTCConfigClass *klass) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, - NM_SETTING_TC_CONFIG_TFILTERS, - G_VARIANT_TYPE ("aa{sv}"), - tc_tfilters_get, - tc_tfilters_set, - NULL); + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_TC_CONFIG_TFILTERS), + G_VARIANT_TYPE ("aa{sv}"), + tc_tfilters_get, + tc_tfilters_set, + NULL); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_TC_CONFIG, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index 4eb33050ee..ee84aaf72e 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -589,6 +589,7 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingTeamPortPrivate)); @@ -596,7 +597,6 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_TEAM_PORT]; setting_class->compare_property = compare_property; setting_class->verify = verify; @@ -713,10 +713,14 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass) G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, - NM_SETTING_TEAM_PORT_LINK_WATCHERS, - G_VARIANT_TYPE ("aa{sv}"), - team_link_watchers_to_dbus, - team_link_watchers_from_dbus); + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_TEAM_PORT_LINK_WATCHERS), + G_VARIANT_TYPE ("aa{sv}"), + team_link_watchers_to_dbus, + team_link_watchers_from_dbus); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_TEAM_PORT, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index f0120ff114..e6737e48ce 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -1560,6 +1560,7 @@ nm_setting_team_class_init (NMSettingTeamClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingTeamPrivate)); @@ -1567,7 +1568,6 @@ nm_setting_team_class_init (NMSettingTeamClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_TEAM]; setting_class->compare_property = compare_property; setting_class->verify = verify; @@ -1816,11 +1816,13 @@ nm_setting_team_class_init (NMSettingTeamClass *klass) G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, - NM_SETTING_TEAM_LINK_WATCHERS, - G_VARIANT_TYPE ("aa{sv}"), - team_link_watchers_to_dbus, - team_link_watchers_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_TEAM_LINK_WATCHERS), + G_VARIANT_TYPE ("aa{sv}"), + team_link_watchers_to_dbus, + team_link_watchers_from_dbus); /* ---dbus--- * property: interface-name @@ -1830,8 +1832,12 @@ nm_setting_team_class_init (NMSettingTeamClass *klass) * team's interface name. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, "interface-name", - G_VARIANT_TYPE_STRING, - _nm_setting_get_deprecated_virtual_interface_name, - NULL); + _properties_override_add_dbus_only (properties_override, + "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_TEAM, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-tun.c b/libnm-core/nm-setting-tun.c index 0fbb6375e0..3e033e2586 100644 --- a/libnm-core/nm-setting-tun.c +++ b/libnm-core/nm-setting-tun.c @@ -301,8 +301,7 @@ nm_setting_tun_class_init (NMSettingTunClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_TUN]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingTun:mode: @@ -404,4 +403,6 @@ nm_setting_tun_class_init (NMSettingTunClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_TUN); } diff --git a/libnm-core/nm-setting-user.c b/libnm-core/nm-setting-user.c index c5d763e77e..d72c909462 100644 --- a/libnm-core/nm-setting-user.c +++ b/libnm-core/nm-setting-user.c @@ -547,12 +547,12 @@ nm_setting_user_class_init (NMSettingUserClass *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 (); object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_USER]; setting_class->compare_property = compare_property; setting_class->verify = verify; @@ -585,8 +585,13 @@ nm_setting_user_class_init (NMSettingUserClass *klass) g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - _nm_setting_class_transform_property (setting_class, NM_SETTING_USER_DATA, - G_VARIANT_TYPE ("a{ss}"), - _nm_utils_strdict_to_dbus, - _nm_utils_strdict_from_dbus); + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_USER_DATA), + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_USER, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index 54a3145ee9..1b61da5578 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -833,6 +833,7 @@ nm_setting_vlan_class_init (NMSettingVlanClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingVlanPrivate)); @@ -840,8 +841,7 @@ nm_setting_vlan_class_init (NMSettingVlanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_VLAN]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingVlan:parent: @@ -918,11 +918,14 @@ nm_setting_vlan_class_init (NMSettingVlanClass *klass) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, NM_SETTING_VLAN_FLAGS, - NULL, - _override_flags_get, - NULL, - _override_flags_not_set); + + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_VLAN_FLAGS), + NULL, + _override_flags_get, + NULL, + _override_flags_not_set); /** * NMSettingVlan:ingress-priority-map: @@ -984,8 +987,12 @@ nm_setting_vlan_class_init (NMSettingVlanClass *klass) * vlan's interface name. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, "interface-name", - G_VARIANT_TYPE_STRING, - _nm_setting_get_deprecated_virtual_interface_name, - NULL); + _properties_override_add_dbus_only (properties_override, + "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_VLAN, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c index 39126421ee..3b61736128 100644 --- a/libnm-core/nm-setting-vpn.c +++ b/libnm-core/nm-setting-vpn.c @@ -891,6 +891,7 @@ nm_setting_vpn_class_init (NMSettingVpnClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingVpnPrivate)); @@ -898,7 +899,6 @@ nm_setting_vpn_class_init (NMSettingVpnClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_VPN]; setting_class->verify = verify; setting_class->update_one_secret = update_one_secret; setting_class->get_secret_flags = get_secret_flags; @@ -972,10 +972,13 @@ nm_setting_vpn_class_init (NMSettingVpnClass *klass) G_TYPE_HASH_TABLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_VPN_DATA, - G_VARIANT_TYPE ("a{ss}"), - _nm_utils_strdict_to_dbus, - _nm_utils_strdict_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_VPN_DATA), + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); /** * NMSettingVpn:secrets: (type GHashTable(utf8,utf8)): @@ -998,10 +1001,13 @@ nm_setting_vpn_class_init (NMSettingVpnClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_VPN_SECRETS, - G_VARIANT_TYPE ("a{ss}"), - _nm_utils_strdict_to_dbus, - _nm_utils_strdict_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_VPN_SECRETS), + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); /** * NMSettingVpn:timeout: @@ -1020,4 +1026,7 @@ nm_setting_vpn_class_init (NMSettingVpnClass *klass) 0, G_MAXUINT32, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_VPN, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-vxlan.c b/libnm-core/nm-setting-vxlan.c index 2f906f8ac5..d00c5a7abd 100644 --- a/libnm-core/nm-setting-vxlan.c +++ b/libnm-core/nm-setting-vxlan.c @@ -574,8 +574,7 @@ nm_setting_vxlan_class_init (NMSettingVxlanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_VXLAN]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingVxlan:parent: @@ -837,4 +836,6 @@ nm_setting_vxlan_class_init (NMSettingVxlanClass *klass) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_VXLAN); } diff --git a/libnm-core/nm-setting-wimax.c b/libnm-core/nm-setting-wimax.c index 12ab0da374..4c1a572ee0 100644 --- a/libnm-core/nm-setting-wimax.c +++ b/libnm-core/nm-setting-wimax.c @@ -209,6 +209,7 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingWimaxPrivate)); @@ -216,8 +217,7 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WIMAX]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingWimax:network-name: @@ -249,8 +249,14 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_WIMAX_MAC_ADDRESS, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIMAX_MAC_ADDRESS), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_WIMAX, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c index 212ddb6218..baa40cc4f4 100644 --- a/libnm-core/nm-setting-wired.c +++ b/libnm-core/nm-setting-wired.c @@ -980,6 +980,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingWiredPrivate)); @@ -987,7 +988,6 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WIRED]; setting_class->verify = verify; setting_class->compare_property = compare_property; @@ -1101,12 +1101,14 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, - NM_SETTING_WIRED_AUTO_NEGOTIATE, - G_VARIANT_TYPE_BOOLEAN, - _override_autoneg_get, - NULL, - NULL); + + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIRED_AUTO_NEGOTIATE), + G_VARIANT_TYPE_BOOLEAN, + _override_autoneg_get, + NULL, + NULL); /** * NMSettingWired:mac-address: @@ -1139,10 +1141,13 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_WIRED_MAC_ADDRESS, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIRED_MAC_ADDRESS), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); /** * NMSettingWired:cloned-mac-address: @@ -1194,8 +1199,10 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, - NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIRED_CLONED_MAC_ADDRESS), G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_cloned_get, _nm_utils_hwaddr_cloned_set, @@ -1213,11 +1220,11 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) * "cloned-mac-address". * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, - "assigned-mac-address", - G_VARIANT_TYPE_STRING, - _nm_utils_hwaddr_cloned_data_synth, - _nm_utils_hwaddr_cloned_data_set); + _properties_override_add_dbus_only (properties_override, + "assigned-mac-address", + G_VARIANT_TYPE_STRING, + _nm_utils_hwaddr_cloned_data_synth, + _nm_utils_hwaddr_cloned_data_set); /** * NMSettingWired:generate-mac-address-mask: @@ -1387,10 +1394,13 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_WIRED_S390_OPTIONS, - G_VARIANT_TYPE ("a{ss}"), - _nm_utils_strdict_to_dbus, - _nm_utils_strdict_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIRED_S390_OPTIONS), + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); /** * NMSettingWired:wake-on-lan: @@ -1429,4 +1439,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_WIRED, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c index e4d3454107..d152782168 100644 --- a/libnm-core/nm-setting-wireless-security.c +++ b/libnm-core/nm-setting-wireless-security.c @@ -1433,6 +1433,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingWirelessSecurityPrivate)); @@ -1440,7 +1441,6 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WIRELESS_SECURITY]; setting_class->verify = verify; setting_class->verify_secrets = verify_secrets; setting_class->need_secrets = need_secrets; @@ -1853,11 +1853,13 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, - NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, - G_VARIANT_TYPE_UINT32, - wep_key_type_to_dbus, - NULL); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE), + G_VARIANT_TYPE_UINT32, + wep_key_type_to_dbus, + NULL); /** * NMSettingWirelessSecurity:wps-method: * @@ -1919,4 +1921,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_WIRELESS_SECURITY, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 47e78d18e7..a9cae6c0db 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -1178,6 +1178,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *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 (); g_type_class_add_private (klass, sizeof (NMSettingWirelessPrivate)); @@ -1185,7 +1186,6 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WIRELESS]; setting_class->verify = verify; setting_class->compare_property = compare_property; @@ -1306,10 +1306,13 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_WIRELESS_BSSID, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIRELESS_BSSID), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); /** * NMSettingWireless:rate: @@ -1386,10 +1389,13 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_transform_property (setting_class, NM_SETTING_WIRELESS_MAC_ADDRESS, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + + _properties_override_add_transform (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIRELESS_MAC_ADDRESS), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); /** * NMSettingWireless:cloned-mac-address: @@ -1439,12 +1445,14 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_override_property (setting_class, - NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_cloned_get, - _nm_utils_hwaddr_cloned_set, - _nm_utils_hwaddr_cloned_not_set); + + _properties_override_add_override (properties_override, + g_object_class_find_property (G_OBJECT_CLASS (setting_class), + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS), + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_cloned_get, + _nm_utils_hwaddr_cloned_set, + _nm_utils_hwaddr_cloned_not_set); /* ---dbus--- * property: assigned-mac-address @@ -1458,11 +1466,11 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) * "cloned-mac-address". * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, - "assigned-mac-address", - G_VARIANT_TYPE_STRING, - _nm_utils_hwaddr_cloned_data_synth, - _nm_utils_hwaddr_cloned_data_set); + _properties_override_add_dbus_only (properties_override, + "assigned-mac-address", + G_VARIANT_TYPE_STRING, + _nm_utils_hwaddr_cloned_data_synth, + _nm_utils_hwaddr_cloned_data_set); /** * NMSettingWireless:generate-mac-address-mask: @@ -1677,9 +1685,11 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) * NetworkManager daemons. * ---end--- */ - _nm_setting_class_add_dbus_only_property (setting_class, "security", - G_VARIANT_TYPE_STRING, - nm_setting_wireless_get_security, NULL); + _properties_override_add_dbus_only (properties_override, + "security", + G_VARIANT_TYPE_STRING, + nm_setting_wireless_get_security, + NULL); /** * NMSettingWireless:wake-on-wlan: @@ -1706,4 +1716,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_WIRELESS, + NULL, properties_override); } diff --git a/libnm-core/nm-setting-wpan.c b/libnm-core/nm-setting-wpan.c index 462f054344..6e1aaadc45 100644 --- a/libnm-core/nm-setting-wpan.c +++ b/libnm-core/nm-setting-wpan.c @@ -224,8 +224,7 @@ nm_setting_wpan_class_init (NMSettingWpanClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->setting_info = &nm_meta_setting_infos[NM_META_SETTING_TYPE_WPAN]; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingWpan:mac-address: @@ -270,4 +269,6 @@ nm_setting_wpan_class_init (NMSettingWpanClass *klass) 0, G_MAXUINT16, G_MAXUINT16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_WPAN); } diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 86acc04e6b..2e884de7a0 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -191,90 +191,53 @@ _nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_t /*****************************************************************************/ -typedef struct { - const char *name; - GParamSpec *param_spec; - const GVariantType *dbus_type; - - NMSettingPropertyGetFunc get_func; - NMSettingPropertySynthFunc synth_func; - NMSettingPropertySetFunc set_func; - NMSettingPropertyNotSetFunc not_set_func; - - NMSettingPropertyTransformToFunc to_dbus; - NMSettingPropertyTransformFromFunc from_dbus; -} NMSettingProperty; - -static NM_CACHED_QUARK_FCN ("nm-setting-property-overrides", setting_property_overrides_quark) -static NM_CACHED_QUARK_FCN ("nm-setting-properties", setting_properties_quark) - -static NMSettingProperty * -find_property (GArray *properties, const char *name) +static const NMSettInfoProperty * +_nm_sett_info_property_find_in_array (const NMSettInfoProperty *properties, guint len, const char *name) { - NMSettingProperty *property; - int i; + guint i; - if (!properties) - return NULL; - - for (i = 0; i < properties->len; i++) { - property = &g_array_index (properties, NMSettingProperty, i); - if (strcmp (name, property->name) == 0) - return property; + for (i = 0; i < len; i++) { + if (nm_streq (name, properties[i].name)) + return &properties[i]; } - return NULL; } -static void -add_property_override (NMSettingClass *setting_class, - const char *property_name, - GParamSpec *param_spec, - const GVariantType *dbus_type, - NMSettingPropertyGetFunc get_func, - NMSettingPropertySynthFunc synth_func, - NMSettingPropertySetFunc set_func, - NMSettingPropertyNotSetFunc not_set_func, - NMSettingPropertyTransformToFunc to_dbus, - NMSettingPropertyTransformFromFunc from_dbus) +void +_properties_override_add_struct (GArray *properties_override, + const NMSettInfoProperty *prop_info) { - GType setting_type = G_TYPE_FROM_CLASS (setting_class); - GArray *overrides; - NMSettingProperty override; + nm_assert (properties_override); + nm_assert (prop_info); + nm_assert (prop_info->name || prop_info->param_spec); + nm_assert (!prop_info->param_spec || !prop_info->name || nm_streq0 (prop_info->name, prop_info->param_spec->name)); + nm_assert (!_nm_sett_info_property_find_in_array ((NMSettInfoProperty *) properties_override->data, + properties_override->len, + prop_info->name ?: prop_info->param_spec->name)); - g_return_if_fail (g_type_get_qdata (setting_type, setting_properties_quark ()) == NULL); + nm_assert (!prop_info->from_dbus || prop_info->dbus_type); + nm_assert (!prop_info->set_func || prop_info->dbus_type); - memset (&override, 0, sizeof (override)); - override.name = property_name; - override.param_spec = param_spec; - override.dbus_type = dbus_type; - override.get_func = get_func; - override.synth_func = synth_func; - override.set_func = set_func; - override.not_set_func = not_set_func; - override.to_dbus = to_dbus; - override.from_dbus = from_dbus; + g_array_append_vals (properties_override, prop_info, 1); - overrides = g_type_get_qdata (setting_type, setting_property_overrides_quark ()); - if (!overrides) { - overrides = g_array_new (FALSE, FALSE, sizeof (NMSettingProperty)); - g_type_set_qdata (setting_type, setting_property_overrides_quark (), overrides); + if (!prop_info->name) { + /* for convenience, allow omitting "name" if "param_spec" is given. */ + g_array_index (properties_override, + NMSettInfoProperty, + properties_override->len - 1).name = prop_info->param_spec->name; } - g_return_if_fail (find_property (overrides, property_name) == NULL); - - g_array_append_val (overrides, override); } /** - * _nm_setting_class_add_dbus_only_property: - * @setting_class: the setting class + * _properties_override_add_dbus_only: + * @properties_override: an array collecting the overrides * @property_name: the name of the property to override * @dbus_type: the type of the property (in its D-Bus representation) * @synth_func: (allow-none): function to call to synthesize a value for the property * @set_func: (allow-none): function to call to set the value of the property * * Registers a property named @property_name, which will be used in the D-Bus - * serialization of objects of @setting_class, but which does not correspond to + * serialization of objects of this setting type, but which does not correspond to * a #GObject property. * * When serializing a setting to D-Bus, @synth_func will be called to synthesize @@ -287,35 +250,30 @@ add_property_override (NMSettingClass *setting_class, * then the property will be ignored when deserializing.) */ void -_nm_setting_class_add_dbus_only_property (NMSettingClass *setting_class, - const char *property_name, - const GVariantType *dbus_type, - NMSettingPropertySynthFunc synth_func, - NMSettingPropertySetFunc set_func) +_properties_override_add_dbus_only (GArray *properties_override, + const char *property_name, + const GVariantType *dbus_type, + NMSettingPropertySynthFunc synth_func, + NMSettingPropertySetFunc set_func) { - g_return_if_fail (NM_IS_SETTING_CLASS (setting_class)); - g_return_if_fail (property_name != NULL); - - /* Must not match any GObject property. */ - g_return_if_fail (!g_object_class_find_property (G_OBJECT_CLASS (setting_class), property_name)); - - add_property_override (setting_class, - property_name, NULL, dbus_type, - NULL, synth_func, set_func, NULL, - NULL, NULL); + _properties_override_add (properties_override, + .name = property_name, + .dbus_type = dbus_type, + .synth_func = synth_func, + .set_func = set_func); } /** - * _nm_setting_class_override_property: - * @setting_class: the setting class - * @property_name: the name of the property to override + * _properties_override_add_override: + * @properties_override: an array collecting the overrides + * @param_spec: the name of the property to override * @dbus_type: the type of the property (in its D-Bus representation) * @get_func: (allow-none): function to call to get the value of the property * @set_func: (allow-none): function to call to set the value of the property * @not_set_func: (allow-none): function to call to indicate the property was not set * - * Overrides the D-Bus representation of the #GObject property named - * @property_name on @setting_class. + * Overrides the D-Bus representation of the #GObject property that shares the + * same name as @param_spec. * * When serializing a setting to D-Bus, if @get_func is non-%NULL, then it will * be called to get the property's value. If it returns a #GVariant, the @@ -324,38 +282,38 @@ _nm_setting_class_add_dbus_only_property (NMSettingClass *setting_class, * with g_object_get_property(), and added to the hash if it is not the default * value.) * - * When deserializing a D-Bus representation into a setting, if @property_name - * is present, then @set_func will be called to set it. (If @set_func is %NULL - * then the property will be set normally with g_object_set_property().) + * When deserializing a D-Bus representation into a setting, if a value with + * the name of @param_spec is present, then @set_func will be called to set it. + * (If @set_func is %NULL then the property will be set normally with + * g_object_set_property().) * * If @not_set_func is non-%NULL, then it will be called when deserializing a - * representation that does NOT contain @property_name. This can be used, eg, if - * a new property needs to be initialized from some older deprecated property + * representation that does NOT contain a value for the property. This can be used, + * eg, if a new property needs to be initialized from some older deprecated property * when it is not present. */ void -_nm_setting_class_override_property (NMSettingClass *setting_class, - const char *property_name, - const GVariantType *dbus_type, - NMSettingPropertyGetFunc get_func, - NMSettingPropertySetFunc set_func, - NMSettingPropertyNotSetFunc not_set_func) +_properties_override_add_override (GArray *properties_override, + GParamSpec *param_spec, + const GVariantType *dbus_type, + NMSettingPropertyGetFunc get_func, + NMSettingPropertySetFunc set_func, + NMSettingPropertyNotSetFunc not_set_func) { - GParamSpec *param_spec; + nm_assert (param_spec); - param_spec = g_object_class_find_property (G_OBJECT_CLASS (setting_class), property_name); - g_return_if_fail (param_spec != NULL); - - add_property_override (setting_class, - property_name, param_spec, dbus_type, - get_func, NULL, set_func, not_set_func, - NULL, NULL); + _properties_override_add (properties_override, + .param_spec = param_spec, + .dbus_type = dbus_type, + .get_func = get_func, + .set_func = set_func, + .not_set_func = not_set_func); } /** - * _nm_setting_class_transform_property: - * @setting_class: the setting class - * @property: the name of the property to transform + * _properties_override_add_transform: + * @properties_override: an array collecting the overrides + * @param_spec: the param spec of the property to transform. * @dbus_type: the type of the property (in its D-Bus representation) * @to_dbus: function to convert from object to D-Bus format * @from_dbus: function to convert from D-Bus to object format @@ -369,92 +327,139 @@ _nm_setting_class_override_property (NMSettingClass *setting_class, * nm_property_compare() recognizes, as long as it recognizes @dbus_type. */ void -_nm_setting_class_transform_property (NMSettingClass *setting_class, - const char *property, - const GVariantType *dbus_type, - NMSettingPropertyTransformToFunc to_dbus, - NMSettingPropertyTransformFromFunc from_dbus) +_properties_override_add_transform (GArray *properties_override, + GParamSpec *param_spec, + const GVariantType *dbus_type, + NMSettingPropertyTransformToFunc to_dbus, + NMSettingPropertyTransformFromFunc from_dbus) { - GParamSpec *param_spec; + nm_assert (param_spec); - param_spec = g_object_class_find_property (G_OBJECT_CLASS (setting_class), property); - g_return_if_fail (param_spec != NULL); - - add_property_override (setting_class, - property, param_spec, dbus_type, - NULL, NULL, NULL, NULL, - to_dbus, from_dbus); + _properties_override_add (properties_override, + .param_spec = param_spec, + .dbus_type = dbus_type, + .to_dbus = to_dbus, + .from_dbus = from_dbus); } -static GArray * -nm_setting_class_ensure_properties (NMSettingClass *setting_class) +static NMSettInfoSetting _sett_info_settings[_NM_META_SETTING_TYPE_NUM]; + +void +_nm_setting_class_commit_full (NMSettingClass *setting_class, + NMMetaSettingType meta_type, + const NMSettInfoSettDetail *detail, + GArray *properties_override) { - GType type = G_TYPE_FROM_CLASS (setting_class), otype; - NMSettingProperty property, *override; - GArray *overrides, *type_overrides, *properties; - GParamSpec **property_specs; - guint n_property_specs, i; + NMSettInfoSetting *sett_info; + gs_free GParamSpec **property_specs = NULL; + guint i, n_property_specs, override_len; - properties = g_type_get_qdata (type, setting_properties_quark ()); - if (properties) - return properties; + nm_assert (NM_IS_SETTING_CLASS (setting_class)); + nm_assert (!setting_class->setting_info); - /* Build overrides array from @setting_class and its superclasses */ - overrides = g_array_new (FALSE, FALSE, sizeof (NMSettingProperty)); - for (otype = type; otype != G_TYPE_OBJECT; otype = g_type_parent (otype)) { - type_overrides = g_type_get_qdata (otype, setting_property_overrides_quark ()); - if (type_overrides) - g_array_append_vals (overrides, (NMSettingProperty *)type_overrides->data, type_overrides->len); - } + nm_assert (meta_type < G_N_ELEMENTS (_sett_info_settings)); - /* Build the properties array from the GParamSpecs, obeying overrides */ - properties = g_array_new (FALSE, FALSE, sizeof (NMSettingProperty)); + sett_info = &_sett_info_settings[meta_type]; + + nm_assert (!sett_info->setting_class); + nm_assert (!sett_info->property_infos_len); + nm_assert (!sett_info->property_infos); + + if (!properties_override) { + override_len = 0; + properties_override = _nm_sett_info_property_override_create_array (); + } else + override_len = properties_override->len; property_specs = g_object_class_list_properties (G_OBJECT_CLASS (setting_class), &n_property_specs); - for (i = 0; i < n_property_specs; i++) { - override = find_property (overrides, property_specs[i]->name); - if (override) - property = *override; - else { - memset (&property, 0, sizeof (property)); - property.name = property_specs[i]->name; - property.param_spec = property_specs[i]; + +#if NM_MORE_ASSERTS > 10 + /* assert that properties_override is constructed consistently. */ + for (i = 0; i < override_len; i++) { + guint j; + const NMSettInfoProperty *p = &g_array_index (properties_override, NMSettInfoProperty, i); + + nm_assert (!_nm_sett_info_property_find_in_array ((NMSettInfoProperty *) properties_override->data, + i, + p->name)); + for (j = 0; j < n_property_specs; j++) { + if (nm_streq (property_specs[j]->name, p->name)) { + nm_assert (p->param_spec == property_specs[j]); + break; + } } - g_array_append_val (properties, property); + nm_assert ((j == n_property_specs) == (p->param_spec == NULL)); } - g_free (property_specs); +#endif - /* Add any remaining overrides not corresponding to GObject properties */ - for (i = 0; i < overrides->len; i++) { - override = &g_array_index (overrides, NMSettingProperty, i); - if (!g_object_class_find_property (G_OBJECT_CLASS (setting_class), override->name)) - g_array_append_val (properties, *override); + for (i = 0; i < n_property_specs; i++) { + const char *name = property_specs[i]->name; + NMSettInfoProperty *p; + + if (_nm_sett_info_property_find_in_array ((NMSettInfoProperty *) properties_override->data, + override_len, + name)) + continue; + + g_array_set_size (properties_override, properties_override->len + 1); + p = &g_array_index (properties_override, NMSettInfoProperty, properties_override->len - 1); + memset (p, 0, sizeof (*p)); + p->name = name; + p->param_spec = property_specs[i]; } - g_array_unref (overrides); - g_type_set_qdata (type, setting_properties_quark (), properties); - return properties; + G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMSettInfoProperty, name) == 0); + g_array_sort (properties_override, nm_strcmp_p); + + setting_class->setting_info = &nm_meta_setting_infos[meta_type]; + sett_info->setting_class = setting_class; + if (detail) + sett_info->detail = *detail; + sett_info->property_infos_len = properties_override->len; + sett_info->property_infos = (const NMSettInfoProperty *) g_array_free (properties_override, + properties_override->len == 0); } -static const NMSettingProperty * -nm_setting_class_get_properties (NMSettingClass *setting_class, guint *n_properties) +const NMSettInfoSetting * +_nm_sett_info_setting_get (NMSettingClass *setting_class) { - GArray *properties; - - properties = nm_setting_class_ensure_properties (setting_class); - - *n_properties = properties->len; - return (NMSettingProperty *) properties->data; + if ( NM_IS_SETTING_CLASS (setting_class) + && setting_class->setting_info) { + nm_assert (setting_class->setting_info->meta_type < G_N_ELEMENTS (_sett_info_settings)); + return &_sett_info_settings[setting_class->setting_info->meta_type]; + } + return NULL; } -static const NMSettingProperty * -nm_setting_class_find_property (NMSettingClass *setting_class, const char *property_name) +const NMSettInfoProperty * +_nm_sett_info_property_get (NMSettingClass *setting_class, + const char *property_name) { - GArray *properties; + const NMSettInfoSetting *sett_info = _nm_sett_info_setting_get (setting_class); + const NMSettInfoProperty *property; + gssize idx; - properties = nm_setting_class_ensure_properties (setting_class); - return find_property (properties, property_name); + if (!sett_info) + return NULL; + + G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMSettInfoProperty, name) == 0); + idx = nm_utils_array_find_binary_search (sett_info->property_infos, + sizeof (NMSettInfoProperty), + sett_info->property_infos_len, + &property_name, + nm_strcmp_p_with_data, + NULL); + + if (idx < 0) + return NULL; + + property = &sett_info->property_infos[idx]; + + nm_assert (idx == 0 || strcmp (property[-1].name, property[0].name) < 0); + nm_assert (idx == sett_info->property_infos_len - 1 || strcmp (property[0].name, property[1].name) < 0); + + return property; } /*****************************************************************************/ @@ -530,7 +535,7 @@ variant_type_for_gtype (GType type) static GVariant * get_property_for_dbus (NMSetting *setting, - const NMSettingProperty *property, + const NMSettInfoProperty *property, gboolean ignore_default) { GValue prop_value = { 0, }; @@ -567,7 +572,7 @@ get_property_for_dbus (NMSetting *setting, } static gboolean -set_property_from_dbus (const NMSettingProperty *property, +set_property_from_dbus (const NMSettInfoProperty *property, GVariant *src_value, GValue *dst_value) { @@ -620,17 +625,16 @@ _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionS { GVariantBuilder builder; GVariant *dbus_value; - const NMSettingProperty *properties; - guint n_properties, i; + const NMSettInfoSetting *sett_info; + guint i; g_return_val_if_fail (NM_IS_SETTING (setting), NULL); - properties = nm_setting_class_get_properties (NM_SETTING_GET_CLASS (setting), &n_properties); - g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); - for (i = 0; i < n_properties; i++) { - const NMSettingProperty *property = &properties[i]; + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); + for (i = 0; i < sett_info->property_infos_len; i++) { + const NMSettInfoProperty *property = &sett_info->property_infos[i]; GParamSpec *prop_spec = property->param_spec; if (!prop_spec) { @@ -701,8 +705,8 @@ _nm_setting_new_from_dbus (GType setting_type, { gs_unref_object NMSetting *setting = NULL; gs_unref_hashtable GHashTable *keys = NULL; - const NMSettingProperty *properties; - guint i, n_properties; + const NMSettInfoSetting *sett_info; + guint i; g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (setting_type), NULL); g_return_val_if_fail (g_variant_is_of_type (setting_dict, NM_VARIANT_TYPE_SETTING), NULL); @@ -746,9 +750,9 @@ _nm_setting_new_from_dbus (GType setting_type, } } - properties = nm_setting_class_get_properties (NM_SETTING_GET_CLASS (setting), &n_properties); - for (i = 0; i < n_properties; i++) { - const NMSettingProperty *property = &properties[i]; + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); + for (i = 0; i < sett_info->property_infos_len; i++) { + const NMSettInfoProperty *property = &sett_info->property_infos[i]; gs_unref_variant GVariant *value = NULL; gs_free_error GError *local = NULL; @@ -867,12 +871,12 @@ const GVariantType * nm_setting_get_dbus_property_type (NMSetting *setting, const char *property_name) { - const NMSettingProperty *property; + const NMSettInfoProperty *property; g_return_val_if_fail (NM_IS_SETTING (setting), NULL); g_return_val_if_fail (property_name != NULL, NULL); - property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), property_name); + property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), property_name); g_return_val_if_fail (property != NULL, NULL); if (property->dbus_type) @@ -1049,7 +1053,7 @@ compare_property (NMSetting *setting, const GParamSpec *prop_spec, NMSettingCompareFlags flags) { - const NMSettingProperty *property; + const NMSettInfoProperty *property; GVariant *value1, *value2; int cmp; @@ -1081,7 +1085,7 @@ compare_property (NMSetting *setting, return TRUE; } - property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), prop_spec->name); + property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), prop_spec->name); g_return_val_if_fail (property != NULL, FALSE); value1 = get_property_for_dbus (setting, property, TRUE); @@ -1595,11 +1599,11 @@ _nm_setting_need_secrets (NMSetting *setting) static int update_one_secret (NMSetting *setting, const char *key, GVariant *value, GError **error) { - const NMSettingProperty *property; + const NMSettInfoProperty *property; GParamSpec *prop_spec; GValue prop_value = { 0, }; - property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), key); + property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), key); if (!property) { g_set_error_literal (error, NM_CONNECTION_ERROR, @@ -1688,10 +1692,10 @@ _nm_setting_update_secrets (NMSetting *setting, GVariant *secrets, GError **erro static gboolean is_secret_prop (NMSetting *setting, const char *secret_name, GError **error) { - const NMSettingProperty *property; + const NMSettInfoProperty *property; GParamSpec *pspec; - property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), secret_name); + property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), secret_name); if (!property) { g_set_error_literal (error, NM_CONNECTION_ERROR, From 4e0f1b16b9472318b2e96b7357ce97ab58d7873f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 27 Jul 2018 10:05:40 +0200 Subject: [PATCH 22/32] libnm: add generic-data for implementing NMSetting Add a new way how NMSetting subclasses can be implemented. Currently, most NMSetting implementations realize all their properties via GObject properties. That has some downsides: - the biggest one, is the large effort to add new properties. Most of them are implemented on a one-by-one basis and they come with additional API (like native getter functions). It makes it cumbersome to add more properties. - for certain properties, it's hard to encode them entirely in a GObject property. That results in unusable API like NM_SETTING_IP_CONFIG_ADDRESSES, NM_SETTING_BOND_OPTIONS, NM_SETTING_USER_DATA. These complex valued properties only exist, because we currently always need GObject properties to even implement simple functionality. For example, nm_setting_duplicate() is entirely implemented via nm_setting_enumerate_values(), which can only iterate GObject properies. There is no reason why this is necessary. Note also how nmcli badly handles bond options and VPN data. That is only a shortcoming of nmcli and wouldn't need to be that way. But it happend, because we didn't keep an open mind that settings might be more than just accessing GObject properties. - a major point of NMSetting is to convert to/from a GVariant from the D-Bus API. As NMSetting needs to squeeze all values into the static GObject structure, there is no place to encode invalid or unknown properties. Optimally, _nm_setting_new_from_dbus() does not loose any information and a subsequent _nm_setting_to_dbus() can restore the original variant. That is interesting, because we want that an older libnm client can talk to a newer NetworkManager version. The client needs to handle unknown properties gracefully to stay forward compatible. However, it also should not just drop the properties on the floor. Note however, optimally we want that nm_setting_verify() still can reject settings that have such unknown/invalid values. So, it should be possible to create an NMSetting instance without error or loosing information. But verify() should be usable to identify such settings as invalid. They also have a few upsides. - libnm is heavily oriented around GObject. So, we generate our nm-settings manual based on the gtk-doc. Note however, how we fail to generate a useful manual for bond.options. Also note, that there is no reason we couldn't generate great documentation, even if the properties are not GObject properties. - GObject properties do give some functionality like meta-data, data binding and notification. However, the meta-data is not sufficient on its own. Note how keyfile and nmcli need extensive descriptor tables on top of GObject properties, to make this useful. Note how GObject notifications for NMSetting instances are usually not useful, aside for data binding like nmtui does. Also note how NMSettingBond already follows a different paradigm than using GObject properties. Nowdays, NMSettingBond is considered a mistake (related bug rh#1032808). Many ideas of NMSettingBond are flawed, like exposing an inferiour API that reduces everything to a string hash. Also, it only implemented the options hash inside NMSettingBond. That means, if we would consider this a good style, we would have to duplicate this approach in each new setting implementation. Add a new style to track data for NMSetting subclasses. It keeps an internal hash table with all GVariant properies. Also, the functionality is hooked into NMSetting base class, so all future subclasses that follow this way, can benefit from this. This approach has a few similiarties with NMSettingBond, but avoids its flaws. With this, we also no longer need GObject properties (if we would also implement generating useful documentation based on non-gkt-doc). They may be added as accessors if they are useful, but there is no need for them. Also, handling the properties as a hash of variants invites for a more generic approach when handling them. While we still could add accessors that operate on a one-by-one bases, this leads to a more generic usage where we apply common functionality to a set of properties. Also, this is for the moment entirely internal and an implementation detail. It's entirely up to the NMSetting subclass to make use of this new style. Also, there are little hooks for the subclass available. If they turn out to be necessary, they might be added. However, for the moment, the functionality is restricted to what is useful and necessary. --- libnm-core/nm-core-internal.h | 52 ++- libnm-core/nm-keyfile.c | 147 +++++++- libnm-core/nm-setting-private.h | 11 + libnm-core/nm-setting.c | 586 +++++++++++++++++++++++++++----- libnm-core/nm-setting.h | 8 +- 5 files changed, 708 insertions(+), 96 deletions(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 21c45ab425..7338cd27af 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -173,6 +173,34 @@ NMSettingPriority _nm_setting_get_setting_priority (NMSetting *setting); gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value); +/*****************************************************************************/ + +GHashTable *_nm_setting_gendata_hash (NMSetting *setting, + gboolean create_if_necessary); + +void _nm_setting_gendata_notify (NMSetting *setting, + gboolean keys_changed); + +guint _nm_setting_gendata_get_all (NMSetting *setting, + const char *const**out_names, + GVariant *const**out_values); + +gboolean _nm_setting_gendata_reset_from_hash (NMSetting *setting, + GHashTable *new); + +void _nm_setting_gendata_to_gvalue (NMSetting *setting, + GValue *value); + +GVariant *nm_setting_gendata_get (NMSetting *setting, + const char *name); + +const char *const*nm_setting_gendata_get_all_names (NMSetting *setting, + guint *out_len); + +GVariant *const*nm_setting_gendata_get_all_values (NMSetting *setting); + +/*****************************************************************************/ + #define NM_UTILS_HWADDR_LEN_MAX_STR (NM_UTILS_HWADDR_LEN_MAX * 3) guint8 *_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length); @@ -481,6 +509,8 @@ gboolean _nm_setting_sriov_sort_vfs (NMSettingSriov *setting); /*****************************************************************************/ +typedef struct _NMSettInfoSetting NMSettInfoSetting; + typedef GVariant *(*NMSettingPropertyGetFunc) (NMSetting *setting, const char *property); typedef GVariant *(*NMSettingPropertySynthFunc) (NMSetting *setting, @@ -516,14 +546,32 @@ typedef struct { } NMSettInfoProperty; typedef struct { -} NMSettInfoSettDetail; + const GVariantType *(*get_variant_type) (const struct _NMSettInfoSetting *sett_info, + const char *name, + GError **error); +} NMSettInfoSettGendata; typedef struct { + /* if set, then this setting class has no own fields. Instead, its + * data is entirely based on gendata. Meaning: it tracks all data + * as native GVariants. + * It might have some GObject properties, but these are merely accessors + * to the underlying gendata. + * + * Note, that at the moment there are few hooks, to customize the behavior + * of the setting further. They are currently unneeded. This is desired, + * but could be added when there is a good reason. + * + * However, a few hooks there are... see NMSettInfoSettGendata. */ + const NMSettInfoSettGendata *gendata_info; +} NMSettInfoSettDetail; + +struct _NMSettInfoSetting { NMSettingClass *setting_class; const NMSettInfoProperty *property_infos; guint property_infos_len; NMSettInfoSettDetail detail; -} NMSettInfoSetting; +}; const NMSettInfoSetting *_nm_sett_info_setting_get (NMSettingClass *setting_class); diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c index 6ea42d13bc..3f9d60bbb7 100644 --- a/libnm-core/nm-keyfile.c +++ b/libnm-core/nm-keyfile.c @@ -2684,6 +2684,8 @@ read_one_setting_value (NMSetting *setting, static NMSetting * read_setting (KeyfileReaderInfo *info) { + const NMSettInfoSetting *sett_info; + gs_unref_object NMSetting *setting = NULL; const char *alias; GType type; @@ -2692,22 +2694,92 @@ read_setting (KeyfileReaderInfo *info) alias = info->group; type = nm_setting_lookup_type (alias); - if (type) { - NMSetting *setting = g_object_new (type, NULL); - - info->setting = setting; - nm_setting_enumerate_values (setting, read_one_setting_value, info); - info->setting = NULL; - if (!info->error) - return setting; - - g_object_unref (setting); - } else { + if (!type) { handle_warn (info, NULL, NM_KEYFILE_WARN_SEVERITY_WARN, _("invalid setting name '%s'"), info->group); + return NULL; } - return NULL; + setting = g_object_new (type, NULL); + + info->setting = setting; + + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); + + if (sett_info->detail.gendata_info) { + gs_free char **keys = NULL; + gsize i, n_keys; + + keys = g_key_file_get_keys (info->keyfile, info->group, &n_keys, NULL); + if (n_keys > 0) { + GHashTable *h = _nm_setting_gendata_hash (setting, TRUE); + + nm_utils_strv_sort (keys, n_keys); + for (i = 0; i < n_keys; i++) { + gs_free char *key = keys[i]; + gs_free_error GError *local = NULL; + const GVariantType *variant_type; + GVariant *variant; + + /* a GKeyfile can return duplicate keys, there is just no API to make sense + * of them. Skip them. */ + if ( i + 1 < n_keys + && nm_streq (key, keys[i + 1])) + continue; + + /* currently, the API is very simple. The setting class just returns + * the desired variant type, and keyfile reader will try to parse + * it accordingly. Note, that this does currently not allow, that + * a particular key can contain different variant types, nor is it + * very flexible in general. + * + * We add flexibility when we need it. Keep it simple for now. */ + variant_type = sett_info->detail.gendata_info->get_variant_type (sett_info, + key, + &local); + if (!variant_type) { + if (!handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid key '%s.%s'"), + info->group, key)) + break; + continue; + } + + if (g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN)) { + gboolean v; + + v = g_key_file_get_boolean (info->keyfile, + info->group, + key, + &local); + if (local) { + if (!handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, + _("key '%s.%s' is not boolean"), + info->group, key)) + break; + continue; + } + variant = g_variant_new_boolean (v); + } else { + nm_assert_not_reached (); + continue; + } + + g_hash_table_insert (h, + g_steal_pointer (&key), + g_variant_take_ref (variant)); + } + for (; i < n_keys; i++) + g_free (keys[i]); + } + } else + nm_setting_enumerate_values (setting, read_one_setting_value, info); + + info->setting = NULL; + + if (info->error) + return NULL; + return g_steal_pointer (&setting); } static void @@ -2998,6 +3070,8 @@ nm_keyfile_write (NMConnection *connection, GError **error) { KeyfileWriterInfo info = { 0 }; + gs_free NMSetting **settings = NULL; + guint i, length = 0; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (!error || !*error, NULL); @@ -3010,12 +3084,59 @@ nm_keyfile_write (NMConnection *connection, info.error = NULL; info.handler = handler; info.user_data = user_data; - nm_connection_for_each_setting_value (connection, write_setting_value, &info); + + settings = nm_connection_get_settings (connection, &length); + for (i = 0; i < length; i++) { + const NMSettInfoSetting *sett_info; + NMSetting *setting = settings[i]; + + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); + + if (sett_info->detail.gendata_info) { + guint k, n_keys; + const char *const*keys; + + nm_assert (!nm_keyfile_plugin_get_alias_for_setting_name (sett_info->setting_class->setting_info->setting_name)); + + n_keys = _nm_setting_gendata_get_all (setting, &keys, NULL); + + if (n_keys > 0) { + const char *setting_name = sett_info->setting_class->setting_info->setting_name; + GHashTable *h = _nm_setting_gendata_hash (setting, FALSE); + + for (k = 0; k < n_keys; k++) { + const char *key = keys[k]; + GVariant *v; + + v = g_hash_table_lookup (h, key); + + if (g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) { + g_key_file_set_boolean (info.keyfile, + setting_name, + key, + g_variant_get_boolean (v)); + } else { + /* BUG: The variant type is not implemented. Since the connection + * verifies, this can only mean we either wrongly didn't reject + * the connection as invalid, or we didn't properly implement the + * variant type. */ + nm_assert_not_reached (); + continue; + } + } + } + } else + nm_setting_enumerate_values (setting, write_setting_value, &info); + + if (info.error) + break; + } if (info.error) { g_propagate_error (error, info.error); g_key_file_unref (info.keyfile); return NULL; } + return info.keyfile; } diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h index 99c7b69ccd..1e25226ede 100644 --- a/libnm-core/nm-setting-private.h +++ b/libnm-core/nm-setting-private.h @@ -80,6 +80,8 @@ gboolean _nm_setting_clear_secrets_with_flags (NMSetting *setting, */ #define NM_SETTING_PARAM_REAPPLY_IMMEDIATELY (1 << (6 + G_PARAM_USER_SHIFT)) +#define NM_SETTING_PARAM_GENDATA_BACKED (1 << (7 + G_PARAM_USER_SHIFT)) + GVariant *_nm_setting_get_deprecated_virtual_interface_name (NMSetting *setting, NMConnection *connection, const char *property); @@ -127,6 +129,15 @@ _nm_setting_class_commit (NMSettingClass *setting_class, _nm_setting_class_commit_full (setting_class, meta_type, NULL, NULL); } +#define NM_SETT_INFO_SETT_GENDATA(...) \ + ({ \ + static const NMSettInfoSettGendata _g = { \ + __VA_ARGS__ \ + }; \ + \ + &_g; \ + }) + #define NM_SETT_INFO_SETT_DETAIL(...) \ (&((const NMSettInfoSettDetail) { \ __VA_ARGS__ \ diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 2e884de7a0..53a2a22a16 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -55,6 +55,12 @@ /*****************************************************************************/ +typedef struct { + GHashTable *hash; + const char **names; + GVariant **values; +} GenData; + typedef struct { const char *name; GType type; @@ -69,7 +75,7 @@ enum { }; typedef struct { - int dummy; + GenData *gendata; } NMSettingPrivate; G_DEFINE_ABSTRACT_TYPE (NMSetting, nm_setting, G_TYPE_OBJECT) @@ -78,6 +84,10 @@ G_DEFINE_ABSTRACT_TYPE (NMSetting, nm_setting, G_TYPE_OBJECT) /*****************************************************************************/ +static GenData *_gendata_hash (NMSetting *setting, gboolean create_if_necessary); + +/*****************************************************************************/ + static NMSettingPriority _get_base_type_priority (const NMMetaSettingInfo *setting_info, GType gtype) @@ -623,15 +633,27 @@ set_property_from_dbus (const NMSettInfoProperty *property, GVariant * _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionSerializationFlags flags) { + NMSettingPrivate *priv; GVariantBuilder builder; GVariant *dbus_value; const NMSettInfoSetting *sett_info; - guint i; + guint n_properties, i; + const char *const*gendata_keys; g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + priv = NM_SETTING_GET_PRIVATE (setting); + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + n_properties = _nm_setting_gendata_get_all (setting, &gendata_keys, NULL); + for (i = 0; i < n_properties; i++) { + g_variant_builder_add (&builder, + "{sv}", + gendata_keys[i], + g_hash_table_lookup (priv->gendata->hash, gendata_keys[i])); + } + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); for (i = 0; i < sett_info->property_infos_len; i++) { const NMSettInfoProperty *property = &sett_info->property_infos[i]; @@ -647,6 +669,9 @@ _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionS if (!(prop_spec->flags & G_PARAM_WRITABLE)) continue; + if (NM_FLAGS_ANY (prop_spec->flags, NM_SETTING_PARAM_GENDATA_BACKED)) + continue; + if ( (prop_spec->flags & NM_SETTING_PARAM_LEGACY) && !_nm_utils_is_manager_process) continue; @@ -751,6 +776,26 @@ _nm_setting_new_from_dbus (GType setting_type, } sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); + + if (sett_info->detail.gendata_info) { + GHashTable *hash; + GVariantIter iter; + char *key; + GVariant *val; + + hash = _gendata_hash (setting, TRUE)->hash; + + g_variant_iter_init (&iter, setting_dict); + while (g_variant_iter_next (&iter, "{sv}", &key, &val)) { + g_hash_table_insert (hash, + key, + val); + } + + _nm_setting_gendata_notify (setting, TRUE); + return g_steal_pointer (&setting); + } + for (i = 0; i < sett_info->property_infos_len; i++) { const NMSettInfoProperty *property = &sett_info->property_infos[i]; gs_unref_variant GVariant *value = NULL; @@ -888,14 +933,32 @@ nm_setting_get_dbus_property_type (NMSetting *setting, gboolean _nm_setting_get_property (NMSetting *setting, const char *property_name, GValue *value) { + const NMSettInfoSetting *sett_info; GParamSpec *prop_spec; g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); g_return_val_if_fail (property_name, FALSE); g_return_val_if_fail (value, FALSE); - prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); + if (sett_info->detail.gendata_info) { + GVariant *variant; + GenData *gendata = _gendata_hash (setting, FALSE); + + variant = gendata ? g_hash_table_lookup (gendata->hash, property_name) : NULL; + + if (!variant) { + g_value_unset (value); + return FALSE; + } + + g_value_init (value, G_TYPE_VARIANT); + g_value_set_variant (value, variant); + return TRUE; + } + + prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); if (!prop_spec) { g_value_unset (value); return FALSE; @@ -929,16 +992,37 @@ duplicate_setting (NMSetting *setting, NMSetting * nm_setting_duplicate (NMSetting *setting) { + const NMSettInfoSetting *sett_info; GObject *dup; g_return_val_if_fail (NM_IS_SETTING (setting), NULL); dup = g_object_new (G_OBJECT_TYPE (setting), NULL); - g_object_freeze_notify (dup); - nm_setting_enumerate_values (setting, duplicate_setting, dup); - g_object_thaw_notify (dup); + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); + if (sett_info->detail.gendata_info) { + GenData *gendata = _gendata_hash (setting, FALSE); + + if ( gendata + && g_hash_table_size (gendata->hash) > 0) { + GHashTableIter iter; + GHashTable *h = _gendata_hash (NM_SETTING (dup), TRUE)->hash; + const char *key; + GVariant *val; + + g_hash_table_iter_init (&iter, gendata->hash); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &val)) { + g_hash_table_insert (h, + g_strdup (key), + g_variant_ref (val)); + } + } + } else { + g_object_freeze_notify (dup); + nm_setting_enumerate_values (setting, duplicate_setting, dup); + g_object_thaw_notify (dup); + } return NM_SETTING (dup); } @@ -1118,6 +1202,7 @@ nm_setting_compare (NMSetting *a, NMSetting *b, NMSettingCompareFlags flags) { + const NMSettInfoSetting *sett_info; GParamSpec **property_specs; guint n_property_specs; int same = TRUE; @@ -1130,6 +1215,18 @@ nm_setting_compare (NMSetting *a, if (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b)) return FALSE; + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (a)); + + if (sett_info->detail.gendata_info) { + GenData *a_gendata = _gendata_hash (a, FALSE); + GenData *b_gendata = _gendata_hash (b, FALSE); + + return nm_utils_hash_table_equal (a_gendata ? a_gendata->hash : NULL, + b_gendata ? b_gendata->hash : NULL, + TRUE, + g_variant_equal); + } + /* And now all properties */ property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (a), &n_property_specs); for (i = 0; i < n_property_specs && same; i++) { @@ -1215,6 +1312,21 @@ should_compare_prop (NMSetting *setting, return TRUE; } +static void +_setting_diff_add_result (GHashTable *results, const char *prop_name, NMSettingDiffResult r) +{ + void *p; + + if (r == NM_SETTING_DIFF_RESULT_UNKNOWN) + return; + + if (g_hash_table_lookup_extended (results, prop_name, NULL, &p)) { + if (!NM_FLAGS_ALL ((guint) r, GPOINTER_TO_UINT (p))) + g_hash_table_insert (results, g_strdup (prop_name), GUINT_TO_POINTER (((guint) r) | GPOINTER_TO_UINT (p))); + } else + g_hash_table_insert (results, g_strdup (prop_name), GUINT_TO_POINTER (r)); +} + /** * nm_setting_diff: * @a: a #NMSetting @@ -1243,8 +1355,7 @@ nm_setting_diff (NMSetting *a, gboolean invert_results, GHashTable **results) { - GParamSpec **property_specs; - guint n_property_specs; + const NMSettInfoSetting *sett_info; guint i; NMSettingDiffResult a_result = NM_SETTING_DIFF_RESULT_IN_A; NMSettingDiffResult b_result = NM_SETTING_DIFF_RESULT_IN_B; @@ -1288,78 +1399,117 @@ nm_setting_diff (NMSetting *a, results_created = TRUE; } - /* And now all properties */ - property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (a), &n_property_specs); + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (a)); - for (i = 0; i < n_property_specs; i++) { - GParamSpec *prop_spec = property_specs[i]; - NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN; + if (sett_info->detail.gendata_info) { + const char *key; + GVariant *val, *val2; + GHashTableIter iter; + GenData *a_gendata = _gendata_hash (a, FALSE); + GenData *b_gendata = b ? _gendata_hash (b, FALSE) : NULL; - /* Handle compare flags */ - if (!should_compare_prop (a, prop_spec->name, flags, prop_spec->flags)) - continue; - if (strcmp (prop_spec->name, NM_SETTING_NAME) == 0) - continue; + if (!a_gendata || !b_gendata) { + if (a_gendata || b_gendata) { + NMSettingDiffResult one_sided_result; - compared_any = TRUE; + one_sided_result = a_gendata ? a_result : b_result; + g_hash_table_iter_init (&iter, a_gendata ? a_gendata->hash : b_gendata->hash); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) { + diff_found = TRUE; + _setting_diff_add_result (*results, key, one_sided_result); + } + } + } else { + g_hash_table_iter_init (&iter, a_gendata->hash); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &val)) { + val2 = b_gendata ? g_hash_table_lookup (b_gendata->hash, key) : NULL; + compared_any = TRUE; + if ( !val2 + || !g_variant_equal (val, val2)) { + diff_found = TRUE; + _setting_diff_add_result (*results, key, a_result); + } + } + g_hash_table_iter_init (&iter, b_gendata->hash); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &val)) { + val2 = a_gendata ? g_hash_table_lookup (a_gendata->hash, key) : NULL; + compared_any = TRUE; + if ( !val2 + || !g_variant_equal (val, val2)) { + diff_found = TRUE; + _setting_diff_add_result (*results, key, b_result); + } + } + } + } else { + gs_free GParamSpec **property_specs = NULL; + guint n_property_specs; - if (b) { - gboolean different; + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (a), &n_property_specs); - different = !NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags); - if (different) { - gboolean a_is_default, b_is_default; + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN; + + /* Handle compare flags */ + if (!should_compare_prop (a, prop_spec->name, flags, prop_spec->flags)) + continue; + if (strcmp (prop_spec->name, NM_SETTING_NAME) == 0) + continue; + + compared_any = TRUE; + + if (b) { + gboolean different; + + different = !NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags); + if (different) { + gboolean a_is_default, b_is_default; + GValue value = G_VALUE_INIT; + + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (a), prop_spec->name, &value); + a_is_default = g_param_value_defaults (prop_spec, &value); + + g_value_reset (&value); + g_object_get_property (G_OBJECT (b), prop_spec->name, &value); + b_is_default = g_param_value_defaults (prop_spec, &value); + + g_value_unset (&value); + if ((flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) == 0) { + if (!a_is_default) + r |= a_result; + if (!b_is_default) + r |= b_result; + } else { + r |= a_result | b_result; + if (a_is_default) + r |= a_result_default; + if (b_is_default) + r |= b_result_default; + } + } + } else if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == 0) + r = a_result; /* only in A */ + else { GValue value = G_VALUE_INIT; g_value_init (&value, prop_spec->value_type); g_object_get_property (G_OBJECT (a), prop_spec->name, &value); - a_is_default = g_param_value_defaults (prop_spec, &value); - - g_value_reset (&value); - g_object_get_property (G_OBJECT (b), prop_spec->name, &value); - b_is_default = g_param_value_defaults (prop_spec, &value); + if (!g_param_value_defaults (prop_spec, &value)) + r |= a_result; + else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) + r |= a_result | a_result_default; g_value_unset (&value); - if ((flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) == 0) { - if (!a_is_default) - r |= a_result; - if (!b_is_default) - r |= b_result; - } else { - r |= a_result | b_result; - if (a_is_default) - r |= a_result_default; - if (b_is_default) - r |= b_result_default; - } } - } else if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == 0) - r = a_result; /* only in A */ - else { - GValue value = G_VALUE_INIT; - g_value_init (&value, prop_spec->value_type); - g_object_get_property (G_OBJECT (a), prop_spec->name, &value); - if (!g_param_value_defaults (prop_spec, &value)) - r |= a_result; - else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) - r |= a_result | a_result_default; - - g_value_unset (&value); - } - - if (r != NM_SETTING_DIFF_RESULT_UNKNOWN) { - void *p; - - diff_found = TRUE; - if (g_hash_table_lookup_extended (*results, prop_spec->name, NULL, &p)) { - if ((r & GPOINTER_TO_UINT (p)) != r) - g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r | GPOINTER_TO_UINT (p))); - } else - g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r)); + if (r != NM_SETTING_DIFF_RESULT_UNKNOWN) { + diff_found = TRUE; + _setting_diff_add_result (*results, prop_spec->name, r); + } } } - g_free (property_specs); if (!compared_any && !b) { /* special case: the setting has no properties, and the opposite @@ -1370,7 +1520,7 @@ nm_setting_diff (NMSetting *a, if (diff_found) { /* if there is a difference, we always return FALSE. It also means, we might - * have allocated a new @results hash, and return if to the caller. */ + * have allocated a new @results hash, and return it to the caller. */ return FALSE; } else { if (results_created) { @@ -1426,23 +1576,57 @@ nm_setting_enumerate_values (NMSetting *setting, NMSettingValueIterFn func, gpointer user_data) { + const NMSettInfoSetting *sett_info; GParamSpec **property_specs; - guint n_property_specs; - int i; + guint n_properties; + guint i; GType type; g_return_if_fail (NM_IS_SETTING (setting)); g_return_if_fail (func != NULL); - property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); + + if (sett_info->detail.gendata_info) { + const char *const*names; + + /* the properties of this setting are not real GObject properties. + * Hence, this API makes little sense (or does it?). Still, call + * @func with each value. */ + n_properties = _nm_setting_gendata_get_all (setting, &names, NULL); + if (n_properties > 0) { + gs_strfreev char **keys = g_strdupv ((char **) names); + GHashTable *h = _gendata_hash (setting, FALSE)->hash; + + for (i = 0; i < n_properties; i++) { + GValue value = G_VALUE_INIT; + GVariant *val = g_hash_table_lookup (h, keys[i]); + + if (!val) { + /* was deleted in the meantime? Skip */ + continue; + } + + g_value_init (&value, G_TYPE_VARIANT); + g_value_set_variant (&value, val); + /* call it will GParamFlags 0. It shall indicate that this + * is not a "real" GObject property. */ + func (setting, keys[i], &value, 0, user_data); + g_value_unset (&value); + } + } + return; + } + + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_properties); /* sort the properties. This has an effect on the order in which keyfile * prints them. */ type = G_OBJECT_TYPE (setting); - g_qsort_with_data (property_specs, n_property_specs, sizeof (gpointer), + g_qsort_with_data (property_specs, n_properties, sizeof (gpointer), (GCompareDataFunc) _enumerate_values_sort, &type); - for (i = 0; i < n_property_specs; i++) { + for (i = 0; i < n_properties; i++) { GParamSpec *prop_spec = property_specs[i]; GValue value = G_VALUE_INIT; @@ -1468,7 +1652,7 @@ nm_setting_enumerate_values (NMSetting *setting, gboolean _nm_setting_clear_secrets (NMSetting *setting) { - GParamSpec **property_specs; + gs_free GParamSpec **property_specs = NULL; guint n_property_specs; guint i; gboolean changed = FALSE; @@ -1476,7 +1660,6 @@ _nm_setting_clear_secrets (NMSetting *setting) g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); - for (i = 0; i < n_property_specs; i++) { GParamSpec *prop_spec = property_specs[i]; @@ -1493,9 +1676,6 @@ _nm_setting_clear_secrets (NMSetting *setting) g_value_unset (&value); } } - - g_free (property_specs); - return changed; } @@ -1546,7 +1726,7 @@ _nm_setting_clear_secrets_with_flags (NMSetting *setting, NMSettingClearSecretsWithFlagsFn func, gpointer user_data) { - GParamSpec **property_specs; + gs_free GParamSpec **property_specs = NULL; guint n_property_specs; guint i; gboolean changed = FALSE; @@ -1564,8 +1744,6 @@ _nm_setting_clear_secrets_with_flags (NMSetting *setting, user_data); } } - - g_free (property_specs); return changed; } @@ -1870,6 +2048,240 @@ _nm_setting_get_deprecated_virtual_interface_name (NMSetting *setting, /*****************************************************************************/ +static GenData * +_gendata_hash (NMSetting *setting, gboolean create_if_necessary) +{ + NMSettingPrivate *priv; + + nm_assert (NM_IS_SETTING (setting)); + + priv = NM_SETTING_GET_PRIVATE (setting); + + if (G_UNLIKELY (!priv->gendata)) { + if (!create_if_necessary) + return NULL; + priv->gendata = g_slice_new (GenData); + priv->gendata->hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + priv->gendata->names = NULL; + priv->gendata->values = NULL; + } + + return priv->gendata; +} + +GHashTable * +_nm_setting_gendata_hash (NMSetting *setting, gboolean create_if_necessary) +{ + GenData *gendata; + + gendata = _gendata_hash (setting, create_if_necessary); + return gendata ? gendata->hash : NULL; +} + +void +_nm_setting_gendata_notify (NMSetting *setting, + gboolean names_changed) +{ + GenData *gendata; + + gendata = _gendata_hash (setting, FALSE); + if (!gendata) + return; + + nm_clear_g_free (&gendata->values); + + if (names_changed) { + /* if only the values changed, it's sufficient to invalidate the + * values cache. Otherwise, the names cache must be invalidated too. */ + nm_clear_g_free (&gendata->names); + } +} + +GVariant * +nm_setting_gendata_get (NMSetting *setting, + const char *name) +{ + GenData *gendata; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + g_return_val_if_fail (name, NULL); + + gendata = _gendata_hash (setting, FALSE); + return gendata ? g_hash_table_lookup (gendata->hash, name) : NULL; +} + +guint +_nm_setting_gendata_get_all (NMSetting *setting, + const char *const**out_names, + GVariant *const**out_values) +{ + GenData *gendata; + GHashTable *hash; + guint i, len; + + nm_assert (NM_IS_SETTING (setting)); + + gendata = _gendata_hash (setting, FALSE); + if (!gendata) + goto out_zero; + + hash = gendata->hash; + len = g_hash_table_size (hash); + if (len == 0) + goto out_zero; + + if (!out_names && !out_values) + return len; + + if (G_UNLIKELY (!gendata->names)) { + gendata->names = nm_utils_strdict_get_keys (hash, + TRUE, + NULL); + } + + if (out_values) { + if (G_UNLIKELY (!gendata->values)) { + gendata->values = g_new (GVariant *, len + 1); + for (i = 0; i < len; i++) + gendata->values[i] = g_hash_table_lookup (hash, gendata->names[i]); + gendata->values[i] = NULL; + } + *out_values = gendata->values; + } + + NM_SET_OUT (out_names, (const char *const*) gendata->names); + return len; + +out_zero: + NM_SET_OUT (out_names, NULL); + NM_SET_OUT (out_values, NULL); + return 0; +} + +/** + * nm_setting_gendata_get_all_names: + * @setting: the #NMSetting + * @out_len: (allow-none): (out): + * + * Gives the number of generic data elements and optionally returns all their + * key names and values. This API is low level access and unless you know what you + * are doing, it might not be what you want. + * + * Returns: (array length=out_len zero-terminated=1) (transfer none): + * A %NULL terminated array of key names. If no names are present, this returns + * %NULL. The returned array and the names are owned by %NMSetting and might be invalidated + * soon. + * + * Since: 1.14 + **/ +const char *const* +nm_setting_gendata_get_all_names (NMSetting *setting, + guint *out_len) +{ + const char *const*names; + guint len; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + + len = _nm_setting_gendata_get_all (setting, &names, NULL); + NM_SET_OUT (out_len, len); + return names; +} + +/** + * nm_setting_gendata_get_all_values: + * @setting: the #NMSetting + * + * Gives the number of generic data elements and optionally returns all their + * key names and values. This API is low level access and unless you know what you + * are doing, it might not be what you want. + * + * Returns: (array zero-terminated=1) (transfer none): + * A %NULL terminated array of #GVariant. If no data is present, this returns + * %NULL. The returned array and the variants are owned by %NMSetting and might be invalidated + * soon. The sort order of nm_setting_gendata_get_all_names() and nm_setting_gendata_get_all_values() + * is consistent. That means, the nth value has the nth name returned by nm_setting_gendata_get_all_names(). + * + * Since: 1.14 + **/ +GVariant *const* +nm_setting_gendata_get_all_values (NMSetting *setting) +{ + GVariant *const*values; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + + _nm_setting_gendata_get_all (setting, NULL, &values); + return values; +} + +void +_nm_setting_gendata_to_gvalue (NMSetting *setting, + GValue *value) +{ + GenData *gendata; + GHashTable *new; + const char *key; + GVariant *val; + GHashTableIter iter; + + nm_assert (NM_IS_SETTING (setting)); + nm_assert (value); + nm_assert (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_HASH_TABLE)); + + new = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + + gendata = _gendata_hash (setting, FALSE); + if (gendata) { + g_hash_table_iter_init (&iter, gendata->hash); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &val)) + g_hash_table_insert (new, g_strdup (key), g_variant_ref (val)); + } + + g_value_take_boxed (value, new); +} + +gboolean +_nm_setting_gendata_reset_from_hash (NMSetting *setting, + GHashTable *new) +{ + GenData *gendata; + GHashTableIter iter; + const char *key; + GVariant *val; + guint num; + + nm_assert (NM_IS_SETTING (setting)); + nm_assert (new); + + num = new ? g_hash_table_size (new) : 0; + + gendata = _gendata_hash (setting, num > 0); + + if (num == 0) { + if ( !gendata + || g_hash_table_size (gendata->hash) == 0) + return FALSE; + + g_hash_table_remove_all (gendata->hash); + _nm_setting_gendata_notify (setting, TRUE); + return TRUE; + } + + /* let's not bother to find out whether the new hash has any different + * content the the current gendata. Just replace it. */ + g_hash_table_remove_all (gendata->hash); + if (num > 0) { + g_hash_table_iter_init (&iter, new); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &val)) + g_hash_table_insert (gendata->hash, g_strdup (key), g_variant_ref (val)); + } + _nm_setting_gendata_notify (setting, TRUE); + return TRUE; +} + +/*****************************************************************************/ + static void nm_setting_init (NMSetting *setting) { @@ -1891,6 +2303,21 @@ get_property (GObject *object, guint prop_id, } } +static void +finalize (GObject *object) +{ + NMSettingPrivate *priv = NM_SETTING_GET_PRIVATE (object); + + if (priv->gendata) { + g_free (priv->gendata->names); + g_free (priv->gendata->values); + g_hash_table_unref (priv->gendata->hash); + g_slice_free (GenData, priv->gendata); + } + + G_OBJECT_CLASS (nm_setting_parent_class)->finalize (object); +} + static void nm_setting_class_init (NMSettingClass *setting_class) { @@ -1914,6 +2341,7 @@ nm_setting_class_init (NMSettingClass *setting_class) g_type_class_add_private (setting_class, sizeof (NMSettingPrivate)); object_class->get_property = get_property; + object_class->finalize = finalize; setting_class->update_one_secret = update_one_secret; setting_class->get_secret_flags = get_secret_flags; diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h index d06527cdd7..a7a0f81f40 100644 --- a/libnm-core/nm-setting.h +++ b/libnm-core/nm-setting.h @@ -287,7 +287,8 @@ void nm_setting_enumerate_values (NMSetting *setting, char *nm_setting_to_string (NMSetting *setting); -/* Secrets */ +/*****************************************************************************/ + gboolean nm_setting_get_secret_flags (NMSetting *setting, const char *secret_name, NMSettingSecretFlags *out_flags, @@ -298,10 +299,13 @@ gboolean nm_setting_set_secret_flags (NMSetting *setting, NMSettingSecretFlags flags, GError **error); -/* Properties */ +/*****************************************************************************/ + const GVariantType *nm_setting_get_dbus_property_type (NMSetting *setting, const char *property_name); +/*****************************************************************************/ + G_END_DECLS #endif /* __NM_SETTING_H__ */ From df30651b8906cfe6a5cb7aef01a220d1f21b80f3 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 16 Jul 2018 23:37:55 +0200 Subject: [PATCH 23/32] libnm, cli, ifcfg-rh: add NMSettingEthtool setting Note that in NetworkManager API (D-Bus, libnm, and nmcli), the features are called "feature-xyz". The "feature-" prefix is used, because NMSettingEthtool possibly will gain support for options that are not only -K|--offload|--features, for example -C|--coalesce. The "xzy" suffix is either how ethtool utility calls the feature ("tso", "rx"). Or, if ethtool utility specifies no alias for that feature, it's the name from kernel's ETH_SS_FEATURES ("tx-tcp6-segmentation"). If possible, we prefer ethtool utility's naming. Also note, how the features "feature-sg", "feature-tso", and "feature-tx" actually refer to multiple underlying kernel features at once. This too follows what ethtool utility does. The functionality is not yet implemented server-side. --- Makefile.am | 8 + clients/cli/connections.c | 3 +- clients/common/meson.build | 2 +- clients/common/nm-meta-setting-desc.c | 126 +++++++ clients/common/nm-meta-setting-desc.h | 4 + docs/libnm/libnm-docs.xml | 1 + libnm-core/meson.build | 2 + libnm-core/nm-core-internal.h | 5 + libnm-core/nm-core-types.h | 1 + libnm-core/nm-setting-ethtool.c | 342 ++++++++++++++++++ libnm-core/nm-setting-ethtool.h | 83 +++++ libnm-core/nm-setting.c | 14 + libnm-core/tests/test-general.c | 20 +- libnm-core/tests/test-setting.c | 77 ++++ libnm/NetworkManager.h | 1 + libnm/libnm.ver | 5 + libnm/nm-autoptr.h | 1 + po/POTFILES.in | 1 + shared/meson.build | 2 + shared/nm-ethtool-utils.c | 143 ++++++++ shared/nm-ethtool-utils.h | 79 ++++ shared/nm-meta-setting.c | 7 + shared/nm-meta-setting.h | 1 + .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 137 +++++-- .../plugins/ifcfg-rh/nms-ifcfg-rh-utils.c | 60 +++ .../plugins/ifcfg-rh/nms-ifcfg-rh-utils.h | 17 + .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 144 +++++--- ...st_write_wired_auto_negotiate_on.cexpected | 15 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 19 +- 29 files changed, 1235 insertions(+), 85 deletions(-) create mode 100644 libnm-core/nm-setting-ethtool.c create mode 100644 libnm-core/nm-setting-ethtool.h create mode 100644 shared/nm-ethtool-utils.c create mode 100644 shared/nm-ethtool-utils.h create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected diff --git a/Makefile.am b/Makefile.am index 516e9acbf2..fe156f9284 100644 --- a/Makefile.am +++ b/Makefile.am @@ -453,6 +453,7 @@ libnm_core_lib_h_pub_real = \ libnm-core/nm-setting-connection.h \ libnm-core/nm-setting-dcb.h \ libnm-core/nm-setting-dummy.h \ + libnm-core/nm-setting-ethtool.h \ libnm-core/nm-setting-generic.h \ libnm-core/nm-setting-gsm.h \ libnm-core/nm-setting-infiniband.h \ @@ -502,6 +503,7 @@ libnm_core_lib_h_priv = \ shared/nm-utils/nm-shared-utils.h \ shared/nm-utils/nm-random-utils.h \ shared/nm-utils/nm-udev-utils.h \ + shared/nm-ethtool-utils.h \ shared/nm-meta-setting.h \ libnm-core/crypto.h \ libnm-core/nm-connection-private.h \ @@ -524,6 +526,7 @@ libnm_core_lib_c_settings_real = \ libnm-core/nm-setting-connection.c \ libnm-core/nm-setting-dcb.c \ libnm-core/nm-setting-dummy.c \ + libnm-core/nm-setting-ethtool.c \ libnm-core/nm-setting-generic.c \ libnm-core/nm-setting-gsm.c \ libnm-core/nm-setting-infiniband.c \ @@ -565,6 +568,7 @@ libnm_core_lib_c_real = \ shared/nm-utils/nm-shared-utils.c \ shared/nm-utils/nm-random-utils.c \ shared/nm-utils/nm-udev-utils.c \ + shared/nm-ethtool-utils.c \ shared/nm-meta-setting.c \ libnm-core/crypto.c \ libnm-core/nm-connection.c \ @@ -2390,6 +2394,7 @@ EXTRA_DIST += \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-3.expected \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4 \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected \ + src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected \ src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap \ src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap \ src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep \ @@ -3425,6 +3430,9 @@ clients_common_libnmc_la_SOURCES = \ shared/nm-meta-setting.c \ shared/nm-meta-setting.h \ \ + shared/nm-ethtool-utils.c \ + shared/nm-ethtool-utils.h \ + \ clients/common/nm-meta-setting-desc.c \ clients/common/nm-meta-setting-desc.h \ clients/common/nm-meta-setting-access.c \ diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 5d8c3daff7..5361e11fb1 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -770,7 +770,8 @@ const NmcMetaGenericInfo *const metagen_con_active_vpn[_NMC_GENERIC_INFO_TYPE_CO NM_SETTING_6LOWPAN_SETTING_NAME","\ NM_SETTING_PROXY_SETTING_NAME"," \ NM_SETTING_TC_CONFIG_SETTING_NAME"," \ - NM_SETTING_SRIOV_SETTING_NAME + NM_SETTING_SRIOV_SETTING_NAME"," \ + NM_SETTING_ETHTOOL_SETTING_NAME // NM_SETTING_DUMMY_SETTING_NAME // NM_SETTING_WIMAX_SETTING_NAME diff --git a/clients/common/meson.build b/clients/common/meson.build index 1f0bf17b01..0db2868e7c 100644 --- a/clients/common/meson.build +++ b/clients/common/meson.build @@ -59,7 +59,7 @@ libnmc = static_library( sources: files( 'nm-meta-setting-access.c', 'nm-meta-setting-desc.c' - ) + shared_nm_meta_setting_c + [settings_docs_source], + ) + shared_nm_meta_setting_c + shared_nm_ethtool_utils_c + [settings_docs_source], dependencies: deps, c_args: cflags, link_with: libnmc_base, diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 5dbbc50384..a2833be1d3 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -4823,6 +4823,84 @@ _validate_fcn_wireless_security_psk (const char *value, char **out_to_free, GErr /*****************************************************************************/ +static gconstpointer +_get_fcn_ethtool (ARGS_GET_FCN) +{ + const char *s; + NMTernary val; + NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id; + + RETURN_UNSUPPORTED_GET_TYPE (); + + val = nm_setting_ethtool_get_feature (NM_SETTING_ETHTOOL (setting), + nm_ethtool_data[ethtool_id]->optname); + + if (val == NM_TERNARY_TRUE) + s = N_("on"); + else if (val == NM_TERNARY_FALSE) + s = N_("off"); + else { + s = NULL; + NM_SET_OUT (out_is_default, TRUE); + } + + if (s && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + s = gettext (s); + return s; +} + +static gboolean +_set_fcn_ethtool (ARGS_SET_FCN) +{ + gs_free char *value_clone = NULL; + NMTernary val; + NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id; + + value = nm_strstrip_avoid_copy (value, &value_clone); + + if (NM_IN_STRSET (value, "1", "yes", "true", "on")) + val = NM_TERNARY_TRUE; + else if (NM_IN_STRSET (value, "0", "no", "false", "off")) + val = NM_TERNARY_FALSE; + else if (NM_IN_STRSET (value, "", "ignore", "default")) + val = NM_TERNARY_DEFAULT; + else { + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is not valid; use 'on', 'off', or 'ignore'"), + value); + return FALSE; + } + + nm_setting_ethtool_set_feature (NM_SETTING_ETHTOOL (setting), + nm_ethtool_data[ethtool_id]->optname, + val); + return TRUE; +} + +static const char *const* +_complete_fcn_ethtool (ARGS_COMPLETE_FCN) +{ + static const char *const v[] = { + "true", + "false", + "1", + "0", + "yes", + "no", + "default", + "on", + "off", + "ignore", + NULL, + }; + + if (!text || !text[0]) + return &v[7]; + return v; +} + +/*****************************************************************************/ + static const NMMetaPropertyInfo property_info_BOND_OPTIONS; #define NESTED_PROPERTY_INFO_BOND(...) \ @@ -4979,6 +5057,12 @@ static const NMMetaPropertyType _pt_gobject_devices = { .complete_fcn = _complete_fcn_gobject_devices, }; +static const NMMetaPropertyType _pt_ethtool = { + .get_fcn = _get_fcn_ethtool, + .set_fcn = _set_fcn_ethtool, + .complete_fcn = _complete_fcn_ethtool, +}; + /*****************************************************************************/ #include "settings-docs.h" @@ -5775,6 +5859,31 @@ static const NMMetaPropertyInfo *const property_infos_DCB[] = { NULL }; +#define PROPERTY_INFO_ETHTOOL(xname) \ + PROPERTY_INFO (NM_ETHTOOL_OPTNAME_##xname, NULL, \ + .property_type = &_pt_ethtool, \ + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (ethtool, \ + .ethtool_id = NM_ETHTOOL_ID_##xname, \ + ), \ + ) + +#undef _CURRENT_NM_META_SETTING_TYPE +#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_ETHTOOL +static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = { + PROPERTY_INFO_ETHTOOL (FEATURE_GRO), + PROPERTY_INFO_ETHTOOL (FEATURE_GSO), + PROPERTY_INFO_ETHTOOL (FEATURE_LRO), + PROPERTY_INFO_ETHTOOL (FEATURE_NTUPLE), + PROPERTY_INFO_ETHTOOL (FEATURE_RX), + PROPERTY_INFO_ETHTOOL (FEATURE_RXHASH), + PROPERTY_INFO_ETHTOOL (FEATURE_RXVLAN), + PROPERTY_INFO_ETHTOOL (FEATURE_SG), + PROPERTY_INFO_ETHTOOL (FEATURE_TSO), + PROPERTY_INFO_ETHTOOL (FEATURE_TX), + PROPERTY_INFO_ETHTOOL (FEATURE_TXVLAN), + 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[] = { @@ -7740,6 +7849,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN) #define SETTING_PRETTY_NAME_CONNECTION N_("General settings") #define SETTING_PRETTY_NAME_DCB N_("DCB settings") #define SETTING_PRETTY_NAME_DUMMY N_("Dummy settings") +#define SETTING_PRETTY_NAME_ETHTOOL N_("Ethtool settings") #define SETTING_PRETTY_NAME_GENERIC N_("Generic settings") #define SETTING_PRETTY_NAME_GSM N_("GSM mobile broadband connection") #define SETTING_PRETTY_NAME_INFINIBAND N_("InfiniBand connection") @@ -7827,6 +7937,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (BOND, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (BRIDGE, @@ -7834,6 +7945,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (BRIDGE, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (BRIDGE_PORT), @@ -7848,11 +7960,13 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { ), SETTING_INFO (CONNECTION), SETTING_INFO (DCB), + SETTING_INFO (ETHTOOL), SETTING_INFO_EMPTY (DUMMY, .valid_parts = NM_META_SETTING_VALID_PARTS ( NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (DUMMY, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO_EMPTY (GENERIC, @@ -7875,6 +7989,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (INFINIBAND, TRUE), NM_META_SETTING_VALID_PART_ITEM (SRIOV, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), .setting_init_fcn = _setting_init_fcn_infiniband, ), @@ -7889,6 +8004,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (IP_TUNNEL, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (MACSEC, @@ -7897,6 +8013,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (MACSEC, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (MACVLAN, @@ -7904,6 +8021,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (MACVLAN, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (OLPC_MESH, @@ -7928,6 +8046,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (IP4_CONFIG, FALSE), NM_META_SETTING_VALID_PART_ITEM (IP6_CONFIG, FALSE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (OVS_PATCH), @@ -7947,6 +8066,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (WIRED, TRUE), NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE), NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (PPP), @@ -7961,6 +8081,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (TEAM, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (TEAM_PORT), @@ -7969,6 +8090,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (TUN, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), .setting_init_fcn = _setting_init_fcn_tun, ), @@ -7978,6 +8100,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (VLAN, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), .setting_init_fcn = _setting_init_fcn_vlan, ), @@ -7992,6 +8115,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (VXLAN, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (WIMAX, @@ -8008,6 +8132,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), NM_META_SETTING_VALID_PART_ITEM (DCB, FALSE), NM_META_SETTING_VALID_PART_ITEM (SRIOV, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), SETTING_INFO (WIRELESS, @@ -8017,6 +8142,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (WIRELESS, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRELESS_SECURITY, FALSE), NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), .setting_init_fcn = _setting_init_fcn_wireless, ), diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 2aa27f1b73..acb0a223b1 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -22,6 +22,7 @@ #include "nm-utils/nm-obj.h" #include "nm-meta-setting.h" +#include "nm-ethtool-utils.h" struct _NMDevice; @@ -263,6 +264,9 @@ struct _NMMetaPropertyTypData { struct { NMMetaPropertyTypeMacMode mode; } mac; + struct { + NMEthtoolID ethtool_id; + } ethtool; } subtype; const char *const*values_static; const NMMetaPropertyTypDataNested *nested; diff --git a/docs/libnm/libnm-docs.xml b/docs/libnm/libnm-docs.xml index cba1661045..94ef406a1d 100644 --- a/docs/libnm/libnm-docs.xml +++ b/docs/libnm/libnm-docs.xml @@ -202,6 +202,7 @@ print ("NetworkManager version " + client.get_version())]]> + diff --git a/libnm-core/meson.build b/libnm-core/meson.build index ab740cac0a..0a0406dfab 100644 --- a/libnm-core/meson.build +++ b/libnm-core/meson.build @@ -69,6 +69,7 @@ libnm_core_settings_sources = files( 'nm-setting-connection.c', 'nm-setting-dcb.c', 'nm-setting-dummy.c', + 'nm-setting-ethtool.c', 'nm-setting-generic.c', 'nm-setting-gsm.c', 'nm-setting-infiniband.c', @@ -154,6 +155,7 @@ endif libnm_core_sources_all = libnm_core_sources libnm_core_sources_all += libnm_core_enum libnm_core_sources_all += shared_nm_meta_setting_c +libnm_core_sources_all += shared_nm_ethtool_utils_c libnm_core_sources_all += shared_files_libnm_core libnm_core_sources_all += [version_header] diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 7338cd27af..0c999c8c84 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -201,6 +201,11 @@ GVariant *const*nm_setting_gendata_get_all_values (NMSetting *setting); /*****************************************************************************/ +guint nm_setting_ethtool_init_features (NMSettingEthtool *setting, + NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */); + +/*****************************************************************************/ + #define NM_UTILS_HWADDR_LEN_MAX_STR (NM_UTILS_HWADDR_LEN_MAX * 3) guint8 *_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length); diff --git a/libnm-core/nm-core-types.h b/libnm-core/nm-core-types.h index 622b104f60..4282fdfe5c 100644 --- a/libnm-core/nm-core-types.h +++ b/libnm-core/nm-core-types.h @@ -40,6 +40,7 @@ typedef struct _NMSettingCdma NMSettingCdma; typedef struct _NMSettingConnection NMSettingConnection; typedef struct _NMSettingDcb NMSettingDcb; typedef struct _NMSettingDummy NMSettingDummy; +typedef struct _NMSettingEthtool NMSettingEthtool; typedef struct _NMSettingGeneric NMSettingGeneric; typedef struct _NMSettingGsm NMSettingGsm; typedef struct _NMSettingInfiniband NMSettingInfiniband; diff --git a/libnm-core/nm-setting-ethtool.c b/libnm-core/nm-setting-ethtool.c new file mode 100644 index 0000000000..7bdbcb1a22 --- /dev/null +++ b/libnm-core/nm-setting-ethtool.c @@ -0,0 +1,342 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2018 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-setting-ethtool.h" + +#include "nm-setting-private.h" +#include "nm-ethtool-utils.h" + +/*****************************************************************************/ + +/** + * SECTION:nm-setting-ethtool + * @short_description: Describes connection properties for ethtool related options + * + * The #NMSettingEthtool object is a #NMSetting subclass that describes properties + * to control network driver and hardware settings. + **/ + +/*****************************************************************************/ + +/** + * nm_ethtool_optname_is_feature: + * @optname: the option name to check + * + * Checks whether @optname is a valid option name for an offload feature. + * + * %Returns: %TRUE, if @optname is valid + * + * Since: 1.14 + */ +gboolean +nm_ethtool_optname_is_feature (const char *optname) +{ + return optname && nm_ethtool_id_is_feature (nm_ethtool_id_get_by_name (optname)); +} + +/*****************************************************************************/ + +/** + * NMSettingEthtool: + * + * Ethtool Ethernet Settings + * + * Since: 1.14 + */ +struct _NMSettingEthtool { + NMSetting parent; +}; + +struct _NMSettingEthtoolClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE (NMSettingEthtool, nm_setting_ethtool, NM_TYPE_SETTING) + +#define NM_SETTING_ETHTOOL_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSettingEthtool, NM_IS_SETTING_ETHTOOL, NMSetting) + +/*****************************************************************************/ + +static void +_notify_attributes (NMSettingEthtool *self) +{ + _nm_setting_gendata_notify (NM_SETTING (self), TRUE); +} + +/*****************************************************************************/ + +/** + * nm_setting_ethtool_get_feature: + * @setting: the #NMSettingEthtool + * @optname: option name of the offload feature to get + * + * Gets and offload feature setting. Returns %NM_TERNARY_DEFAULT if the + * feature is not set. + * + * Returns: a #NMTernary value indicating whether the offload feature + * is enabled, disabled, or left untouched. + * + * Since: 1.14 + */ +NMTernary +nm_setting_ethtool_get_feature (NMSettingEthtool *setting, + const char *optname) +{ + GVariant *v; + + g_return_val_if_fail (NM_IS_SETTING_ETHTOOL (setting), NM_TERNARY_DEFAULT); + g_return_val_if_fail (optname && nm_ethtool_optname_is_feature (optname), NM_TERNARY_DEFAULT); + + v = nm_setting_gendata_get (NM_SETTING (setting), optname); + if ( v + && g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) { + return g_variant_get_boolean (v) + ? NM_TERNARY_TRUE + : NM_TERNARY_FALSE; + } + return NM_TERNARY_DEFAULT; +} + +/** + * nm_setting_ethtool_set_feature: + * @setting: the #NMSettingEthtool + * @optname: option name of the offload feature to get + * @value: the new value to set. The special value %NM_TERNARY_DEFAULT + * means to clear the offload feature setting. + * + * Sets and offload feature setting. + * + * Since: 1.14 + */ +void +nm_setting_ethtool_set_feature (NMSettingEthtool *setting, + const char *optname, + NMTernary value) +{ + GHashTable *hash; + GVariant *v; + + g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting)); + g_return_if_fail (optname && nm_ethtool_optname_is_feature (optname)); + g_return_if_fail (NM_IN_SET (value, NM_TERNARY_DEFAULT, + NM_TERNARY_FALSE, + NM_TERNARY_TRUE)); + + hash = _nm_setting_gendata_hash (NM_SETTING (setting), + value != NM_TERNARY_DEFAULT); + + if (value == NM_TERNARY_DEFAULT) { + if (hash) { + if (g_hash_table_remove (hash, optname)) + _notify_attributes (setting); + } + return; + } + + v = g_hash_table_lookup (hash, optname); + if ( v + && g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) { + if (g_variant_get_boolean (v)) { + if (value == NM_TERNARY_TRUE) + return; + } else { + if (value == NM_TERNARY_FALSE) + return; + } + } + + v = g_variant_ref_sink (g_variant_new_boolean (value != NM_TERNARY_FALSE)); + g_hash_table_insert (hash, + g_strdup (optname), + v); + _notify_attributes (setting); +} + +/** + * nm_setting_ethtool_clear_features: + * @setting: the #NMSettingEthtool + * + * Clears all offload features settings + * + * Since: 1.14 + */ +void +nm_setting_ethtool_clear_features (NMSettingEthtool *setting) +{ + GHashTable *hash; + GHashTableIter iter; + const char *name; + gboolean changed = FALSE; + + g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting)); + + hash = _nm_setting_gendata_hash (NM_SETTING (setting), FALSE); + if (!hash) + return; + + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, NULL)) { + if (nm_ethtool_optname_is_feature (name)) { + g_hash_table_iter_remove (&iter); + changed = TRUE; + } + } + + if (changed) + _notify_attributes (setting); +} + +guint +nm_setting_ethtool_init_features (NMSettingEthtool *setting, + NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */) +{ + GHashTable *hash; + GHashTableIter iter; + guint i; + guint n_req = 0; + const char *name; + GVariant *variant; + + nm_assert (NM_IS_SETTING_ETHTOOL (setting)); + nm_assert (requested); + + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) + requested[i] = NM_TERNARY_DEFAULT; + + hash = _nm_setting_gendata_hash (NM_SETTING (setting), FALSE); + if (!hash) + return 0; + + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) { + NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name (name); + + if (!nm_ethtool_id_is_feature (ethtool_id)) + continue; + if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)) + continue; + + requested[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST] = g_variant_get_boolean (variant) + ? NM_TERNARY_TRUE + : NM_TERNARY_FALSE; + n_req++; + } + + return n_req; +} + +/*****************************************************************************/ + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + GHashTable *hash; + GHashTableIter iter; + const char *optname; + GVariant *variant; + + hash = _nm_setting_gendata_hash (setting, FALSE); + + if (!hash) + goto out; + + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, (gpointer *) &optname, (gpointer *) &variant)) { + if (!nm_ethtool_optname_is_feature (optname)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unsupported offload feature")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname); + return FALSE; + } + if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("offload feature has invalid variant type")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname); + return FALSE; + } + } + +out: + return TRUE; +} + +/*****************************************************************************/ + +static const GVariantType * +get_variant_type (const NMSettInfoSetting *sett_info, + const char *name, + GError **error) +{ + if (nm_ethtool_optname_is_feature (name)) + return G_VARIANT_TYPE_BOOLEAN; + + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unknown ethtool option '%s'"), + name); + return NULL; +} + +/*****************************************************************************/ + +static void +nm_setting_ethtool_init (NMSettingEthtool *setting) +{ +} + +/** + * nm_setting_ethtool_new: + * + * Creates a new #NMSettingEthtool object with default values. + * + * Returns: (transfer full): the new empty #NMSettingEthtool object + * + * Since: 1.14 + **/ +NMSetting * +nm_setting_ethtool_new (void) +{ + return g_object_new (NM_TYPE_SETTING_ETHTOOL, NULL); +} + +static void +nm_setting_ethtool_class_init (NMSettingEthtoolClass *klass) +{ + NMSettingClass *setting_class = NM_SETTING_CLASS (klass); + + setting_class->verify = verify; + + _nm_setting_class_commit_full (setting_class, + NM_META_SETTING_TYPE_ETHTOOL, + NM_SETT_INFO_SETT_DETAIL ( + .gendata_info = NM_SETT_INFO_SETT_GENDATA ( + .get_variant_type = get_variant_type, + ), + ), + NULL); +} diff --git a/libnm-core/nm-setting-ethtool.h b/libnm-core/nm-setting-ethtool.h new file mode 100644 index 0000000000..763d2691ee --- /dev/null +++ b/libnm-core/nm-setting-ethtool.h @@ -0,0 +1,83 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2018 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_ETHTOOL_H__ +#define __NM_SETTING_ETHTOOL_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +/*****************************************************************************/ + +#define NM_ETHTOOL_OPTNAME_FEATURE_GRO "feature-gro" +#define NM_ETHTOOL_OPTNAME_FEATURE_GSO "feature-gso" +#define NM_ETHTOOL_OPTNAME_FEATURE_LRO "feature-lro" +#define NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE "feature-ntuple" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX "feature-rx" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXHASH "feature-rxhash" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN "feature-rxvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_SG "feature-sg" +#define NM_ETHTOOL_OPTNAME_FEATURE_TSO "feature-tso" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX "feature-tx" +#define NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN "feature-txvlan" + +gboolean nm_ethtool_optname_is_feature (const char *optname); + +/*****************************************************************************/ + +#define NM_TYPE_SETTING_ETHTOOL (nm_setting_ethtool_get_type ()) +#define NM_SETTING_ETHTOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtool)) +#define NM_SETTING_ETHTOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtoolClass)) +#define NM_IS_SETTING_ETHTOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_ETHTOOL)) +#define NM_IS_SETTING_ETHTOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_ETHTOOL)) +#define NM_SETTING_ETHTOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtoolClass)) + +#define NM_SETTING_ETHTOOL_SETTING_NAME "ethtool" + +/*****************************************************************************/ + +typedef struct _NMSettingEthtoolClass NMSettingEthtoolClass; + +NM_AVAILABLE_IN_1_14 +GType nm_setting_ethtool_get_type (void); + +NM_AVAILABLE_IN_1_14 +NMSetting *nm_setting_ethtool_new (void); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_14 +NMTernary nm_setting_ethtool_get_feature (NMSettingEthtool *setting, + const char *optname); +NM_AVAILABLE_IN_1_14 +void nm_setting_ethtool_set_feature (NMSettingEthtool *setting, + const char *optname, + NMTernary value); +NM_AVAILABLE_IN_1_14 +void nm_setting_ethtool_clear_features (NMSettingEthtool *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_ETHTOOL_H__ */ diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 53a2a22a16..d59e3df79d 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -2095,6 +2095,20 @@ _nm_setting_gendata_notify (NMSetting *setting, * values cache. Otherwise, the names cache must be invalidated too. */ nm_clear_g_free (&gendata->names); } + + /* Note, that currently there is now way to notify the subclass when gendata changed. + * gendata is only changed in two situations: + * 1) from within NMSetting itself, for example when creating a NMSetting instance + * from keyfile or a D-Bus GVariant. + * 2) actively from the subclass itself + * For 2), we don't need the notification, because the subclass knows that something + * changed. + * For 1), we currently don't need the notification either, because all that the subclass + * currently would do, is emit a g_object_notify() signal. However, 1) only happens when + * the setting instance is newly created, at that point, nobody listens to the signal. + * + * If we ever need it, then we would need to call a virtual function to notify the subclass + * that gendata changed. */ } GVariant * diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 39e2cf90e4..db1d1c1447 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -43,6 +43,7 @@ #include "nm-setting-bridge-port.h" #include "nm-setting-cdma.h" #include "nm-setting-connection.h" +#include "nm-setting-ethtool.h" #include "nm-setting-generic.h" #include "nm-setting-gsm.h" #include "nm-setting-infiniband.h" @@ -65,6 +66,7 @@ #include "nm-simple-connection.h" #include "nm-keyfile-internal.h" #include "nm-utils/nm-dedup-multi.h" +#include "nm-ethtool-utils.h" #include "test-general-enums.h" @@ -7058,6 +7060,22 @@ test_nm_va_args_macros (void) /*****************************************************************************/ +static void +test_ethtool_offload (void) +{ + const NMEthtoolData *d; + + g_assert_cmpint (nm_ethtool_id_get_by_name ("invalid"), ==, NM_ETHTOOL_ID_UNKNOWN); + g_assert_cmpint (nm_ethtool_id_get_by_name ("feature-rx"), ==, NM_ETHTOOL_ID_FEATURE_RX); + + d = nm_ethtool_data_get_by_optname (NM_ETHTOOL_OPTNAME_FEATURE_RXHASH); + g_assert (d); + g_assert_cmpint (d->id, ==, NM_ETHTOOL_ID_FEATURE_RXHASH); + g_assert_cmpstr (d->optname, ==, NM_ETHTOOL_OPTNAME_FEATURE_RXHASH); +} + +/*****************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -7212,8 +7230,8 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/route_attributes/format", test_route_attributes_format); g_test_add_func ("/core/general/get_start_time_for_pid", test_get_start_time_for_pid); - g_test_add_func ("/core/general/test_nm_va_args_macros", test_nm_va_args_macros); + g_test_add_func ("/core/general/test_ethtool_offload", test_ethtool_offload); return g_test_run (); } diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c index cb02d1c4a5..5526ad8a7e 100644 --- a/libnm-core/tests/test-setting.c +++ b/libnm-core/tests/test-setting.c @@ -28,6 +28,7 @@ #include "nm-setting-8021x.h" #include "nm-setting-bond.h" #include "nm-setting-dcb.h" +#include "nm-setting-ethtool.h" #include "nm-setting-team.h" #include "nm-setting-team-port.h" #include "nm-setting-tc-config.h" @@ -36,6 +37,7 @@ #include "nm-simple-connection.h" #include "nm-setting-connection.h" #include "nm-errors.h" +#include "nm-keyfile-internal.h" #include "nm-utils/nm-test-utils.h" @@ -1264,6 +1266,79 @@ test_team_port_full_config (void) /*****************************************************************************/ +static void +test_ethtool_1 (void) +{ + gs_unref_object NMConnection *con = NULL; + gs_unref_object NMConnection *con2 = NULL; + gs_unref_object NMConnection *con3 = NULL; + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; + gs_unref_keyfile GKeyFile *keyfile = NULL; + NMSettingConnection *s_con; + NMSettingEthtool *s_ethtool; + NMSettingEthtool *s_ethtool2; + NMSettingEthtool *s_ethtool3; + + con = nmtst_create_minimal_connection ("ethtool-1", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); + nm_connection_add_setting (con, NM_SETTING (s_ethtool)); + + nm_setting_ethtool_set_feature (s_ethtool, + NM_ETHTOOL_OPTNAME_FEATURE_RX, + NM_TERNARY_TRUE); + nm_setting_ethtool_set_feature (s_ethtool, + NM_ETHTOOL_OPTNAME_FEATURE_LRO, + NM_TERNARY_FALSE); + + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RX), ==, NM_TERNARY_TRUE); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_SG), ==, NM_TERNARY_DEFAULT); + + nmtst_connection_normalize (con); + + variant = nm_connection_to_dbus (con, NM_CONNECTION_SERIALIZE_ALL); + + con2 = nm_simple_connection_new_from_dbus (variant, &error); + nmtst_assert_success (con2, error); + + s_ethtool2 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con2, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_RX), ==, NM_TERNARY_TRUE); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_SG), ==, NM_TERNARY_DEFAULT); + + nmtst_assert_connection_verifies_without_normalization (con2); + + nmtst_assert_connection_equals (con, FALSE, con2, FALSE); + + keyfile = nm_keyfile_write (con, NULL, NULL, &error); + nmtst_assert_success (keyfile, error); + + con3 = nm_keyfile_read (keyfile, + "ethtool-keyfile-name", + NULL, + NULL, + NULL, + &error); + nmtst_assert_success (con3, error); + + nmtst_connection_normalize (con3); + + nmtst_assert_connection_equals (con, FALSE, con3, FALSE); + + s_ethtool3 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con3, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_RX), ==, NM_TERNARY_TRUE); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_SG), ==, NM_TERNARY_DEFAULT); +} + +/*****************************************************************************/ + static void test_sriov_vf (void) { @@ -1899,6 +1974,8 @@ main (int argc, char **argv) g_test_add_func ("/libnm/settings/dcb/priorities", test_dcb_priorities_valid); g_test_add_func ("/libnm/settings/dcb/bandwidth-sums", test_dcb_bandwidth_sums); + g_test_add_func ("/libnm/settings/ethtool/1", test_ethtool_1); + g_test_add_func ("/libnm/settings/sriov/vf", test_sriov_vf); g_test_add_func ("/libnm/settings/sriov/vf-dup", test_sriov_vf_dup); g_test_add_func ("/libnm/settings/sriov/vf-vlan", test_sriov_vf_vlan); diff --git a/libnm/NetworkManager.h b/libnm/NetworkManager.h index 070a02a9af..a4af9b0d8e 100644 --- a/libnm/NetworkManager.h +++ b/libnm/NetworkManager.h @@ -72,6 +72,7 @@ #include "nm-setting-connection.h" #include "nm-setting-dcb.h" #include "nm-setting-dummy.h" +#include "nm-setting-ethtool.h" #include "nm-setting-generic.h" #include "nm-setting-gsm.h" #include "nm-setting-infiniband.h" diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 15f7283fea..042453daa4 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1394,6 +1394,11 @@ global: nm_device_wpan_get_type; nm_setting_6lowpan_get_type; nm_setting_connection_get_multi_connect; + nm_setting_ethtool_clear_features; + nm_setting_ethtool_get_feature; + nm_setting_ethtool_get_type; + nm_setting_ethtool_new; + nm_setting_ethtool_set_feature; nm_setting_sriov_add_vf; nm_setting_sriov_clear_vfs; nm_setting_sriov_get_autoprobe_drivers; diff --git a/libnm/nm-autoptr.h b/libnm/nm-autoptr.h index c56f1ecfae..665c28c0e4 100644 --- a/libnm/nm-autoptr.h +++ b/libnm/nm-autoptr.h @@ -47,6 +47,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingCdma, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingConnection, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingDcb, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingDummy, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingEthtool, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingGeneric, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingGsm, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingInfiniband, g_object_unref) diff --git a/po/POTFILES.in b/po/POTFILES.in index fafc4225d2..ee78d29344 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -67,6 +67,7 @@ libnm-core/nm-setting-bridge.c libnm-core/nm-setting-cdma.c libnm-core/nm-setting-connection.c libnm-core/nm-setting-dcb.c +libnm-core/nm-setting-ethtool.c libnm-core/nm-setting-gsm.c libnm-core/nm-setting-infiniband.c libnm-core/nm-setting-ip-config.c diff --git a/shared/meson.build b/shared/meson.build index 26ce317495..8faec8765b 100644 --- a/shared/meson.build +++ b/shared/meson.build @@ -36,6 +36,8 @@ version_header = configure_file( configuration: version_conf, ) +shared_nm_ethtool_utils_c = files('nm-ethtool-utils.c') + shared_nm_meta_setting_c = files('nm-meta-setting.c') shared_nm_test_utils_impl_c = files('nm-test-utils-impl.c') diff --git a/shared/nm-ethtool-utils.c b/shared/nm-ethtool-utils.c new file mode 100644 index 0000000000..1e6d405a88 --- /dev/null +++ b/shared/nm-ethtool-utils.c @@ -0,0 +1,143 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2018 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-ethtool-utils.h" + +#include "nm-setting-ethtool.h" + +/*****************************************************************************/ + +#define ETHT_DATA(xname) \ + [NM_ETHTOOL_ID_##xname] = (&((const NMEthtoolData) { \ + .optname = NM_ETHTOOL_OPTNAME_##xname, \ + .id = NM_ETHTOOL_ID_##xname, \ + })) + +const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = { + /* indexed by NMEthtoolID */ + ETHT_DATA (FEATURE_GRO), + ETHT_DATA (FEATURE_GSO), + ETHT_DATA (FEATURE_LRO), + ETHT_DATA (FEATURE_NTUPLE), + ETHT_DATA (FEATURE_RX), + ETHT_DATA (FEATURE_RXHASH), + ETHT_DATA (FEATURE_RXVLAN), + ETHT_DATA (FEATURE_SG), + ETHT_DATA (FEATURE_TSO), + ETHT_DATA (FEATURE_TX), + ETHT_DATA (FEATURE_TXVLAN), + [_NM_ETHTOOL_ID_NUM] = NULL, +}; + +const guint8 const _by_name[_NM_ETHTOOL_ID_NUM] = { + /* sorted by optname. */ + NM_ETHTOOL_ID_FEATURE_GRO, + NM_ETHTOOL_ID_FEATURE_GSO, + NM_ETHTOOL_ID_FEATURE_LRO, + NM_ETHTOOL_ID_FEATURE_NTUPLE, + NM_ETHTOOL_ID_FEATURE_RX, + NM_ETHTOOL_ID_FEATURE_RXHASH, + NM_ETHTOOL_ID_FEATURE_RXVLAN, + NM_ETHTOOL_ID_FEATURE_SG, + NM_ETHTOOL_ID_FEATURE_TSO, + NM_ETHTOOL_ID_FEATURE_TX, + NM_ETHTOOL_ID_FEATURE_TXVLAN, +}; + +/*****************************************************************************/ + +static void +_ASSERT_data (void) +{ +#if NM_MORE_ASSERTS > 10 + int i; + + G_STATIC_ASSERT_EXPR (_NM_ETHTOOL_ID_FIRST == 0); + G_STATIC_ASSERT_EXPR (_NM_ETHTOOL_ID_LAST == _NM_ETHTOOL_ID_NUM - 1); + G_STATIC_ASSERT_EXPR (_NM_ETHTOOL_ID_NUM > 0); + + nm_assert (NM_PTRARRAY_LEN (nm_ethtool_data) == _NM_ETHTOOL_ID_NUM); + nm_assert (G_N_ELEMENTS (_by_name) == _NM_ETHTOOL_ID_NUM); + nm_assert (G_N_ELEMENTS (nm_ethtool_data) == _NM_ETHTOOL_ID_NUM + 1); + + for (i = 0; i < _NM_ETHTOOL_ID_NUM; i++) { + const NMEthtoolData *d = nm_ethtool_data[i]; + + nm_assert (d); + nm_assert (d->id == (NMEthtoolID) i); + nm_assert (d->optname && d->optname[0]); + } + + for (i = 0; i < _NM_ETHTOOL_ID_NUM; i++) { + NMEthtoolID id = _by_name[i]; + const NMEthtoolData *d; + + nm_assert (id >= 0); + nm_assert (id < _NM_ETHTOOL_ID_NUM); + + d = nm_ethtool_data[id]; + if (i > 0) { + /* since we assert that all optnames are sorted strictly monotonically increasing, + * it also follows that there are no duplicates in the _by_name. + * It also follows, that all names in nm_ethtool_data are unique. */ + if (strcmp (nm_ethtool_data[_by_name[i - 1]]->optname, d->optname) >= 0) { + g_error ("nm_ethtool_data is not sorted asciibetically: %u/%s should be after %u/%s", + i - 1, nm_ethtool_data[_by_name[i - 1]]->optname, + i, d->optname); + } + } + } +#endif +} + +static int +_by_name_cmp (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + const guint8 *p_id = a; + const char *optname = b; + + nm_assert (p_id && p_id >= _by_name && p_id <= &_by_name[_NM_ETHTOOL_ID_NUM]); + nm_assert (*p_id < _NM_ETHTOOL_ID_NUM); + + return strcmp (nm_ethtool_data[*p_id]->optname, optname); +} + +const NMEthtoolData * +nm_ethtool_data_get_by_optname (const char *optname) +{ + gssize idx; + + nm_assert (optname); + + _ASSERT_data (); + + idx = nm_utils_array_find_binary_search ((gconstpointer *) _by_name, + sizeof (_by_name[0]), + _NM_ETHTOOL_ID_NUM, + optname, + _by_name_cmp, + NULL); + return (idx < 0) ? NULL : nm_ethtool_data[_by_name[idx]]; +} diff --git a/shared/nm-ethtool-utils.h b/shared/nm-ethtool-utils.h new file mode 100644 index 0000000000..06956d0462 --- /dev/null +++ b/shared/nm-ethtool-utils.h @@ -0,0 +1,79 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2018 Red Hat, Inc. + */ + +#ifndef __NM_ETHTOOL_UTILS_H__ +#define __NM_ETHTOOL_UTILS_H__ + +/*****************************************************************************/ + +typedef enum { + NM_ETHTOOL_ID_UNKNOWN = -1, + + _NM_ETHTOOL_ID_FIRST = 0, + + _NM_ETHTOOL_ID_FEATURE_FIRST = _NM_ETHTOOL_ID_FIRST, + NM_ETHTOOL_ID_FEATURE_GRO = _NM_ETHTOOL_ID_FEATURE_FIRST, + NM_ETHTOOL_ID_FEATURE_GSO, + NM_ETHTOOL_ID_FEATURE_LRO, + NM_ETHTOOL_ID_FEATURE_NTUPLE, + NM_ETHTOOL_ID_FEATURE_RX, + NM_ETHTOOL_ID_FEATURE_RXHASH, + NM_ETHTOOL_ID_FEATURE_RXVLAN, + NM_ETHTOOL_ID_FEATURE_SG, + NM_ETHTOOL_ID_FEATURE_TSO, + NM_ETHTOOL_ID_FEATURE_TX, + NM_ETHTOOL_ID_FEATURE_TXVLAN, + _NM_ETHTOOL_ID_FEATURE_LAST = NM_ETHTOOL_ID_FEATURE_TXVLAN, + _NM_ETHTOOL_ID_FEATURE_NUM = (_NM_ETHTOOL_ID_FEATURE_LAST - _NM_ETHTOOL_ID_FEATURE_FIRST + 1), + + _NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_FEATURE_LAST, + + _NM_ETHTOOL_ID_NUM = (_NM_ETHTOOL_ID_LAST - _NM_ETHTOOL_ID_FIRST + 1), +} NMEthtoolID; + +typedef struct { + const char *optname; + NMEthtoolID id; +} NMEthtoolData; + +extern const NMEthtoolData *const nm_ethtool_data[/*_NM_ETHTOOL_ID_NUM + NULL-terminated*/]; + +const NMEthtoolData *nm_ethtool_data_get_by_optname (const char *optname); + +/****************************************************************************/ + +static inline NMEthtoolID +nm_ethtool_id_get_by_name (const char *optname) +{ + const NMEthtoolData *d; + + d = nm_ethtool_data_get_by_optname (optname); + return d ? d->id : NM_ETHTOOL_ID_UNKNOWN; +} + +static inline gboolean +nm_ethtool_id_is_feature (NMEthtoolID id) +{ + return id >= _NM_ETHTOOL_ID_FEATURE_FIRST && id <= _NM_ETHTOOL_ID_FEATURE_LAST; +} + +/****************************************************************************/ + +#endif /* __NM_ETHTOOL_UTILS_H__ */ diff --git a/shared/nm-meta-setting.c b/shared/nm-meta-setting.c index 4ef07d85e5..c565e55f38 100644 --- a/shared/nm-meta-setting.c +++ b/shared/nm-meta-setting.c @@ -34,6 +34,7 @@ #include "nm-setting-connection.h" #include "nm-setting-dcb.h" #include "nm-setting-dummy.h" +#include "nm-setting-ethtool.h" #include "nm-setting-generic.h" #include "nm-setting-gsm.h" #include "nm-setting-infiniband.h" @@ -213,6 +214,12 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { .setting_name = NM_SETTING_DUMMY_SETTING_NAME, .get_setting_gtype = nm_setting_dummy_get_type, }, + [NM_META_SETTING_TYPE_ETHTOOL] = { + .meta_type = NM_META_SETTING_TYPE_ETHTOOL, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_ETHTOOL_SETTING_NAME, + .get_setting_gtype = nm_setting_ethtool_get_type, + }, [NM_META_SETTING_TYPE_GENERIC] = { .meta_type = NM_META_SETTING_TYPE_GENERIC, .setting_priority = NM_SETTING_PRIORITY_HW_BASE, diff --git a/shared/nm-meta-setting.h b/shared/nm-meta-setting.h index 677ae4c00d..c76a4b7008 100644 --- a/shared/nm-meta-setting.h +++ b/shared/nm-meta-setting.h @@ -118,6 +118,7 @@ typedef enum { NM_META_SETTING_TYPE_CONNECTION, NM_META_SETTING_TYPE_DCB, NM_META_SETTING_TYPE_DUMMY, + NM_META_SETTING_TYPE_ETHTOOL, NM_META_SETTING_TYPE_GENERIC, NM_META_SETTING_TYPE_GSM, NM_META_SETTING_TYPE_INFINIBAND, diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index ee9e28571d..804139e41d 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -41,6 +41,7 @@ #include "nm-setting-ip6-config.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" +#include "nm-setting-ethtool.h" #include "nm-setting-8021x.h" #include "nm-setting-bond.h" #include "nm-setting-team.h" @@ -53,6 +54,7 @@ #include "nm-setting-generic.h" #include "nm-core-internal.h" #include "nm-utils.h" +#include "nm-ethtool-utils.h" #include "platform/nm-platform.h" #include "NetworkManagerUtils.h" @@ -4051,15 +4053,66 @@ parse_ethtool_option (const char *value, char **out_password, gboolean *out_autoneg, guint32 *out_speed, - const char **out_duplex) + const char **out_duplex, + NMSettingEthtool **out_s_ethtool) { gs_free const char **words = NULL; guint i; - words = nm_utils_strsplit_set (value, "\t \n"); + words = nm_utils_strsplit_set (value, NULL); if (!words) return; + if (words[0] && words[0][0] == '-') { + /* /sbin/ethtool $opts */ + if (NM_IN_STRSET (words[0], "-K", "--features", "--offload")) { + if (!words[1]) { + /* first argument must be the interface name. This is invalid. */ + return; + } + + if (!*out_s_ethtool) + *out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); + + for (i = 2; words[i]; ) { + const char *opt = words[i]; + const char *opt_val = words[++i]; + const NMEthtoolData *d = NULL; + NMTernary onoff = NM_TERNARY_DEFAULT; + + if (nm_streq0 (opt_val, "on")) + onoff = NM_TERNARY_TRUE; + else if (nm_streq0 (opt_val, "off")) + onoff = NM_TERNARY_FALSE; + + d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt); + + if (!d) { + if (onoff != NM_TERNARY_DEFAULT) { + /* the next value is just the on/off argument. Skip it too. */ + i++; + } + + /* silently ignore unsupported offloading features. */ + continue; + } + + i++; + + if (onoff == NM_TERNARY_DEFAULT) { + PARSE_WARNING ("Expects on/off argument for feature '%s'", opt); + continue; + } + + nm_setting_ethtool_set_feature (*out_s_ethtool, + d->optname, + onoff); + } + } + return; + } + + /* /sbin/ethtool -s ${REALDEVICE} $opts */ for (i = 0; words[i]; ) { const char *opt = words[i]; const char *opt_val = words[++i]; @@ -4176,54 +4229,72 @@ parse_ethtool_option (const char *value, } static void -parse_ethtool_options (shvarFile *ifcfg, NMSettingWired *s_wired, const char *value) +parse_ethtool_options (shvarFile *ifcfg, NMConnection *connection) { + NMSettingWired *s_wired; + gs_unref_object NMSettingEthtool *s_ethtool = NULL; NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; + gs_free char *ethtool_opts_free = NULL; + const char *ethtool_opts; gs_free char *wol_password = NULL; - gs_free char *wol_value = NULL; - gboolean ignore_wol_password = FALSE; + gs_free char *wol_value_free = NULL; + const char *tmp; gboolean autoneg = FALSE; guint32 speed = 0; const char *duplex = NULL; - if (value) { - gs_free const char **opts = NULL; - const char *const *iter; - + ethtool_opts = svGetValue (ifcfg, "ETHTOOL_OPTS", ðtool_opts_free); + if (ethtool_opts) { /* WAKE_ON_LAN_IGNORE is inferred from a specified but empty ETHTOOL_OPTS */ - if (!value[0]) + if (!ethtool_opts[0]) wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; + else { + gs_free const char **opts = NULL; + const char *const *iter; - opts = nm_utils_strsplit_set (value, ";"); - for (iter = opts; iter && iter[0]; iter++) { - /* in case of repeated wol_passwords, parse_ethtool_option() - * will do the right thing and clear wol_password before resetting. */ - parse_ethtool_option (iter[0], &wol_flags, &wol_password, &autoneg, &speed, &duplex); + opts = nm_utils_strsplit_set (ethtool_opts, ";"); + for (iter = opts; iter && iter[0]; iter++) { + /* in case of repeated wol_passwords, parse_ethtool_option() + * will do the right thing and clear wol_password before resetting. */ + parse_ethtool_option (iter[0], + &wol_flags, + &wol_password, + &autoneg, + &speed, + &duplex, + &s_ethtool); + } } } /* ETHTOOL_WAKE_ON_LAN = ignore overrides WoL settings in ETHTOOL_OPTS */ - wol_value = svGetValueStr_cp (ifcfg, "ETHTOOL_WAKE_ON_LAN"); - if (wol_value) { - if (strcmp (wol_value, "ignore") == 0) - wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; - else - PARSE_WARNING ("invalid ETHTOOL_WAKE_ON_LAN value '%s'", wol_value); - } + tmp = svGetValueStr (ifcfg, "ETHTOOL_WAKE_ON_LAN", &wol_value_free); + if (nm_streq0 (tmp, "ignore")) + wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; + else if (tmp) + PARSE_WARNING ("invalid ETHTOOL_WAKE_ON_LAN value '%s'", tmp); if ( wol_password && !NM_FLAGS_HAS (wol_flags, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) { PARSE_WARNING ("Wake-on-LAN password not expected"); - ignore_wol_password = TRUE; + nm_clear_g_free (&wol_password); } - g_object_set (s_wired, - NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags, - NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, ignore_wol_password ? NULL : wol_password, - NM_SETTING_WIRED_AUTO_NEGOTIATE, autoneg, - NM_SETTING_WIRED_SPEED, speed, - NM_SETTING_WIRED_DUPLEX, duplex, - NULL); + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) { + g_object_set (s_wired, + NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags, + NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, wol_password, + NM_SETTING_WIRED_AUTO_NEGOTIATE, autoneg, + NM_SETTING_WIRED_SPEED, speed, + NM_SETTING_WIRED_DUPLEX, duplex, + NULL); + } + + if (s_ethtool) { + nm_connection_add_setting (connection, + NM_SETTING (g_steal_pointer (&s_ethtool))); + } } static NMSetting * @@ -4365,10 +4436,6 @@ make_wired_setting (shvarFile *ifcfg, nm_clear_g_free (&value); } - parse_ethtool_options (ifcfg, s_wired, - svGetValue (ifcfg, "ETHTOOL_OPTS", &value)); - nm_clear_g_free (&value); - return (NMSetting *) g_steal_pointer (&s_wired); } @@ -5595,6 +5662,8 @@ connection_from_file_full (const char *filename, if (!connection) return NULL; + parse_ethtool_options (parsed, connection); + has_complex_routes_v4 = utils_has_complex_routes (filename, AF_INET); has_complex_routes_v6 = utils_has_complex_routes (filename, AF_INET6); diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index 862e640e02..fecce50e29 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -470,3 +470,63 @@ nms_ifcfg_rh_utils_user_key_decode (const char *name, GString *str_buffer) return TRUE; } + +/*****************************************************************************/ + +const char *const _nm_ethtool_ifcfg_names[] = { +#define ETHT_NAME(eid, ename) \ +[eid - _NM_ETHTOOL_ID_FEATURE_FIRST] = ""ename"" + /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GRO, "gro"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GSO, "gso"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LRO, "lro"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX, "rx"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_SG, "sg"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TSO, "tso"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX, "tx"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"), +}; + +const NMEthtoolData * +nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name) +{ + static const struct { + NMEthtoolID ethtool_id; + const char *kernel_name; + } kernel_names[] = { + { NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro" }, + { NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation" }, + { NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro" }, + { NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter" }, + { NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum" }, + { NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing" }, + { NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse" }, + { NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert" }, + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (_nm_ethtool_ifcfg_names); i++) { + if (nm_streq (name, _nm_ethtool_ifcfg_names[i])) + return nm_ethtool_data[i]; + } + + /* Option not found. Note that ethtool utility has built-in features and + * NetworkManager's API follows the naming of these built-in features, whenever + * they exist. + * For example, NM's "ethtool.feature-ntuple" corresponds to ethtool utility's "ntuple" + * feature. However the underlying kernel feature is called "rx-ntuple-filter" (as reported + * for ETH_SS_FEATURES). + * + * With ethtool utility, whose command line we attempt to parse here, the user can also + * specify the name of the underlying kernel feature directly. So, check whether that is + * the case and if yes, map them to the corresponding NetworkManager's features. */ + for (i = 0; i < G_N_ELEMENTS (kernel_names); i++) { + if (nm_streq (name, kernel_names[i].kernel_name)) + return nm_ethtool_data[kernel_names[i].ethtool_id]; + } + + return NULL; +} diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index 3756af7cc6..d95b1f61cf 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -22,6 +22,7 @@ #define _UTILS_H_ #include "nm-connection.h" +#include "nm-ethtool-utils.h" #include "shvar.h" @@ -80,4 +81,20 @@ _nms_ifcfg_rh_utils_numbered_tag (char *buf, gsize buf_len, const char *tag_name _nms_ifcfg_rh_utils_numbered_tag (buf, sizeof (buf), ""tag_name"", (which)); \ }) +/*****************************************************************************/ + +extern const char *const _nm_ethtool_ifcfg_names[_NM_ETHTOOL_ID_FEATURE_NUM]; + +static inline const char * +nms_ifcfg_rh_utils_get_ethtool_name (NMEthtoolID ethtool_id) +{ + nm_assert (ethtool_id >= _NM_ETHTOOL_ID_FEATURE_FIRST && ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST); + nm_assert ((ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST) < G_N_ELEMENTS (_nm_ethtool_ifcfg_names)); + nm_assert (_nm_ethtool_ifcfg_names[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]); + + return _nm_ethtool_ifcfg_names[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]; +} + +const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name); + #endif /* _UTILS_H_ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 4fed68a254..a2abe995a8 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -37,6 +37,7 @@ #include "nm-setting-connection.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" +#include "nm-setting-ethtool.h" #include "nm-setting-8021x.h" #include "nm-setting-proxy.h" #include "nm-setting-ip4-config.h" @@ -50,6 +51,7 @@ #include "nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nm-meta-setting.h" +#include "nm-ethtool-utils.h" #include "nms-ifcfg-rh-common.h" #include "nms-ifcfg-rh-reader.h" @@ -1135,6 +1137,7 @@ static gboolean write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingWired *s_wired; + NMSettingEthtool *s_ethtool; const char *duplex; guint32 speed; GString *str = NULL; @@ -1143,65 +1146,112 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro const char *wol_password; s_wired = nm_connection_get_setting_wired (connection); + s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (connection, NM_TYPE_SETTING_ETHTOOL)); - if (!s_wired) + if (!s_wired && !s_ethtool) { + svUnsetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN"); + svUnsetValue (ifcfg, "ETHTOOL_OPTS"); return TRUE; - - auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired); - speed = nm_setting_wired_get_speed (s_wired); - duplex = nm_setting_wired_get_duplex (s_wired); - - /* autoneg off + speed 0 + duplex NULL, means we want NM - * to skip link configuration which is default. So write - * down link config only if we have auto-negotiate true or - * a valid value for one among speed and duplex. - */ - if (auto_negotiate) { - str = g_string_sized_new (64); - g_string_printf (str, "autoneg on"); - } else if (speed || duplex) { - str = g_string_sized_new (64); - g_string_printf (str, "autoneg off"); } - if (speed) - g_string_append_printf (str, " speed %u", speed); - if (duplex) - g_string_append_printf (str, " duplex %s", duplex); - wol = nm_setting_wired_get_wake_on_lan (s_wired); - wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired); + if (s_wired) { + auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired); + speed = nm_setting_wired_get_speed (s_wired); + duplex = nm_setting_wired_get_duplex (s_wired); + + /* autoneg off + speed 0 + duplex NULL, means we want NM + * to skip link configuration which is default. So write + * down link config only if we have auto-negotiate true or + * a valid value for one among speed and duplex. + */ + if (auto_negotiate) { + str = g_string_sized_new (64); + g_string_printf (str, "autoneg on"); + } else if (speed || duplex) { + str = g_string_sized_new (64); + g_string_printf (str, "autoneg off"); + } + if (speed) + g_string_append_printf (str, " speed %u", speed); + if (duplex) + g_string_append_printf (str, " duplex %s", duplex); + + wol = nm_setting_wired_get_wake_on_lan (s_wired); + wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired); + + svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", + wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE + ? "ignore" + : NULL); + if (!NM_IN_SET (wol, NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE, + NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)) { + if (!str) + str = g_string_sized_new (30); + else + g_string_append (str, " "); + + 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 (!NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ALL)) + g_string_append (str, "d"); + + if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) + g_string_append_printf (str, "s sopass %s", wol_password); + } + } else + svUnsetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN"); + + if (s_ethtool) { + NMEthtoolID ethtool_id; + NMSettingConnection *s_con; + const char *iface = NULL; + + s_con = nm_connection_get_setting_connection (connection); + if (s_con) { + iface = nm_setting_connection_get_interface_name (s_con); + if ( iface + && ( !iface[0] + || !NM_STRCHAR_ALL (iface, ch, (ch >= 'a' && ch <= 'z') + || (ch >= 'A' && ch <= 'Z') + || (ch >= '0' && ch <= '9') + || NM_IN_SET (ch, '_')))) + iface = NULL; + } - svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", - wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE - ? "ignore" - : NULL); - if (!NM_IN_SET (wol, NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE, - NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)) { if (!str) str = g_string_sized_new (30); else - g_string_append (str, " "); + g_string_append (str, " ; "); + g_string_append (str, "-K "); + g_string_append (str, iface ?: "net0"); - g_string_append (str, "wol "); + for (ethtool_id = _NM_ETHTOOL_ID_FEATURE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST; ethtool_id++) { + const NMEthtoolData *ed = nm_ethtool_data[ethtool_id]; + NMTernary val; - 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"); + nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - if (!NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ALL)) - g_string_append (str, "d"); + val = nm_setting_ethtool_get_feature (s_ethtool, ed->optname); + if (val == NM_TERNARY_DEFAULT) + continue; - if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) - g_string_append_printf (str, "s sopass %s", wol_password); + g_string_append_c (str, ' '); + g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); + g_string_append (str, val == NM_TERNARY_TRUE ? " on" : " off"); + } } if (str) { diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected new file mode 100644 index 0000000000..426085765c --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected @@ -0,0 +1,15 @@ +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +ETHTOOL_OPTS="autoneg on ; -K net0 rxvlan off tx on" +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +NAME="Test Write Wired Auto-Negotiate" +UUID=${UUID} +ONBOOT=yes 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 67431c18a4..fc42937d0e 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -43,12 +43,14 @@ #include "nm-setting-pppoe.h" #include "nm-setting-ppp.h" #include "nm-setting-vpn.h" +#include "nm-setting-ethtool.h" #include "nm-setting-gsm.h" #include "nm-setting-cdma.h" #include "nm-setting-serial.h" #include "nm-setting-vlan.h" #include "nm-setting-dcb.h" #include "nm-core-internal.h" +#include "nm-ethtool-utils.h" #include "NetworkManagerUtils.h" @@ -3726,6 +3728,7 @@ test_write_wired_auto_negotiate_on (void) gs_unref_object NMConnection *connection = NULL; gs_unref_object NMConnection *reread = NULL; NMSettingWired *s_wired; + NMSettingEthtool *s_ethtool; char *val; shvarFile *f; @@ -3735,8 +3738,14 @@ test_write_wired_auto_negotiate_on (void) NM_SETTING_WIRED_AUTO_NEGOTIATE, TRUE, NULL); - _writer_new_connection (connection, + s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); + nm_setting_ethtool_set_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX, NM_TERNARY_TRUE); + nm_setting_ethtool_set_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN, NM_TERNARY_FALSE); + nm_connection_add_setting (connection, NM_SETTING (s_ethtool)); + + _writer_new_connec_exp (connection, TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-test_write_wired_auto_negotiate_on.cexpected", &testfile); f = _svOpenFile (testfile); @@ -3750,7 +3759,15 @@ test_write_wired_auto_negotiate_on (void) reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + nmtst_assert_connection_verifies_without_normalization (reread); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + + s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (reread, NM_TYPE_SETTING_ETHTOOL)); + g_assert (s_ethtool); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX), ==, NM_TERNARY_TRUE); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN), ==, NM_TERNARY_FALSE); + g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN), ==, NM_TERNARY_DEFAULT); } static void From b7c8e3dbfa51017a40b0f7229a1e50074c0d9204 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 7 Aug 2018 09:21:45 +0200 Subject: [PATCH 24/32] shared: add NM_DIV_ROUND_UP() helper macro Inspired by ethtool's DIV_ROUND_UP() and systemd's DIV_ROUND_UP(). --- shared/nm-utils/nm-macros-internal.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index d1391073eb..3d2520d131 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -1137,6 +1137,14 @@ nm_clear_g_cancellable (GCancellable **cancellable) && ((__x & (__x - (((typeof(__x)) 1)))) == ((typeof(__x)) 0))); \ }) +#define NM_DIV_ROUND_UP(x, y) \ + ({ \ + const typeof(x) _x = (x); \ + const typeof(y) _y = (y); \ + \ + (_x / _y + !!(_x % _y)); \ + }) + /*****************************************************************************/ #define NM_UTILS_LOOKUP_DEFAULT(v) return (v) From 29266e0086fa1b0faa76da266cbce9fa6467e965 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 16 Jul 2018 10:43:28 +0200 Subject: [PATCH 25/32] platform/ethtool: split functions for ETHTOOL_GSTRINGS ethtool_get_stringset() will be used later, independently. Also, don't trust and ensure that the block of strings returned by ETHTOOL_GSTRINGS are NUL terminated. --- src/platform/nm-platform-utils.c | 106 +++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 35 deletions(-) diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 0d224443fa..2bcaa4d94e 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -39,9 +39,9 @@ #include "nm-core-utils.h" -/****************************************************************** +/****************************************************************************** * utils - ******************************************************************/ + *****************************************************************************/ extern char *if_indextoname (unsigned __ifindex, char *__ifname); unsigned if_nametoindex (const char *__ifname); @@ -63,9 +63,9 @@ nmp_utils_if_nametoindex (const char *ifname) return if_nametoindex (ifname); } -/****************************************************************** +/****************************************************************************** * ethtool - ******************************************************************/ + *****************************************************************************/ NM_UTILS_ENUM2STR_DEFINE_STATIC (_ethtool_cmd_to_string, guint32, NM_UTILS_ENUM2STR (ETHTOOL_GDRVINFO, "ETHTOOL_GDRVINFO"), @@ -157,39 +157,75 @@ ethtool_get (int ifindex, gpointer edata) } } -static int -ethtool_get_stringset_index (int ifindex, int stringset_id, const char *string) +/*****************************************************************************/ + +static struct ethtool_gstrings * +ethtool_get_stringset (int ifindex, int stringset_id) { - gs_free struct ethtool_sset_info *info = NULL; - gs_free struct ethtool_gstrings *strings = NULL; - guint32 len, i; + struct { + struct ethtool_sset_info info; + guint32 sentinel; + } sset_info = { }; + gs_free struct ethtool_gstrings *gstrings = NULL; + guint32 i, len; - g_return_val_if_fail (ifindex > 0, -1); + g_return_val_if_fail (ifindex > 0, NULL); - info = g_malloc0 (sizeof (*info) + sizeof (guint32)); - info->cmd = ETHTOOL_GSSET_INFO; - info->reserved = 0; - info->sset_mask = 1ULL << stringset_id; + sset_info.info.cmd = ETHTOOL_GSSET_INFO; + sset_info.info.reserved = 0; + sset_info.info.sset_mask = (1ULL << stringset_id); - if (!ethtool_get (ifindex, info)) - return -1; - if (!info->sset_mask) - return -1; + if (!ethtool_get (ifindex, &sset_info)) + return NULL; + if (!sset_info.info.sset_mask) + return NULL; - len = info->data[0]; + len = sset_info.info.data[0]; - strings = g_malloc0 (sizeof (*strings) + len * ETH_GSTRING_LEN); - strings->cmd = ETHTOOL_GSTRINGS; - strings->string_set = stringset_id; - strings->len = len; - if (!ethtool_get (ifindex, strings)) - return -1; - - for (i = 0; i < len; i++) { - if (!strcmp ((char *) &strings->data[i * ETH_GSTRING_LEN], string)) - return i; + gstrings = g_malloc0 (sizeof (*gstrings) + (len * ETH_GSTRING_LEN)); + gstrings->cmd = ETHTOOL_GSTRINGS; + gstrings->string_set = stringset_id; + gstrings->len = len; + if (gstrings->len > 0) { + if (!ethtool_get (ifindex, gstrings)) + return NULL; + for (i = 0; i < gstrings->len; i++) { + /* ensure NUL terminated */ + gstrings->data[i * ETH_GSTRING_LEN + (ETH_GSTRING_LEN - 1)] = '\0'; + } } + return g_steal_pointer (&gstrings); +} + +static int +ethtool_gstrings_find (const struct ethtool_gstrings *gstrings, const char *needle) +{ + guint32 i; + + /* ethtool_get_stringset() always ensures NUL terminated strings at ETH_GSTRING_LEN. + * that means, we cannot possibly request longer names. */ + nm_assert (needle && strlen (needle) < ETH_GSTRING_LEN); + + for (i = 0; i < gstrings->len; i++) { + if (nm_streq ((char *) &gstrings->data[i * ETH_GSTRING_LEN], needle)) + return i; + } + return -1; +} + +static int +ethtool_get_stringset_index (int ifindex, int stringset_id, const char *needle) +{ + gs_free struct ethtool_gstrings *gstrings = NULL; + + /* ethtool_get_stringset() always ensures NUL terminated strings at ETH_GSTRING_LEN. + * that means, we cannot possibly request longer names. */ + nm_assert (needle && strlen (needle) < ETH_GSTRING_LEN); + + gstrings = ethtool_get_stringset (ifindex, stringset_id); + if (gstrings) + return ethtool_gstrings_find (gstrings, needle); return -1; } @@ -282,7 +318,7 @@ nmp_utils_ethtool_supports_vlans (int ifindex) g_return_val_if_fail (ifindex > 0, FALSE); idx = ethtool_get_stringset_index (ifindex, ETH_SS_FEATURES, "vlan-challenged"); - if (idx == -1) { + if (idx < 0) { nm_log_dbg (LOGD_PLATFORM, "ethtool: vlan-challenged ethtool feature does not exist for %d?", ifindex); return FALSE; } @@ -310,7 +346,7 @@ nmp_utils_ethtool_get_peer_ifindex (int ifindex) g_return_val_if_fail (ifindex > 0, 0); peer_ifindex_stat = ethtool_get_stringset_index (ifindex, ETH_SS_STATS, "peer_ifindex"); - if (peer_ifindex_stat == -1) { + if (peer_ifindex_stat < 0) { nm_log_dbg (LOGD_PLATFORM, "ethtool: peer_ifindex stat for %d does not exist?", ifindex); return FALSE; } @@ -530,9 +566,9 @@ nmp_utils_ethtool_set_wake_on_lan (int ifindex, return ethtool_get (ifindex, &wol_info); } -/****************************************************************** +/****************************************************************************** * mii - ******************************************************************/ + *****************************************************************************/ gboolean nmp_utils_mii_supports_carrier_detect (int ifindex) @@ -576,9 +612,9 @@ nmp_utils_mii_supports_carrier_detect (int ifindex) return TRUE; } -/****************************************************************** +/****************************************************************************** * udev - ******************************************************************/ + *****************************************************************************/ const char * nmp_utils_udev_get_driver (struct udev_device *udevice) From bdd9f7482c50c6ce766aaf49e49c0fe23e8848ed Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 16 Jul 2018 13:08:38 +0200 Subject: [PATCH 26/32] platform/ethtool: add SocketHandle to reuse socket for ethtool requests Previously, each call to ethtool_get() would resolve the ifindex and create a new socket for the ethtool request. This is partly done, because ethtool only supports making requests by name. Since interfaces can be renamed, this is inherrently racy. So, we want to fetch the latest name shortly before making the request. Some functions like nmp_utils_ethtool_supports_vlans() require multiple ioctls. And next, we will introduce more ethtool functions, that make an even larger number of individual requests. Add a simple SocketHandle struct, to create the socket once and reuse it for multiple requests. This is still entirely internal API in "nm-platform-utils.c". --- src/platform/nm-platform-utils.c | 218 +++++++++++++++++++------------ 1 file changed, 133 insertions(+), 85 deletions(-) diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 2bcaa4d94e..b6dee1cdfe 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -63,6 +63,42 @@ nmp_utils_if_nametoindex (const char *ifname) return if_nametoindex (ifname); } +/*****************************************************************************/ + +typedef struct { + int fd; + int ifindex; + char ifname[IFNAMSIZ]; +} SocketHandle; + +static int +socket_handle_init (SocketHandle *shandle, int ifindex) +{ + if (!nmp_utils_if_indextoname (ifindex, shandle->ifname)) { + shandle->ifindex = 0; + return -ENODEV; + } + + shandle->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (shandle->fd < 0) { + shandle->ifindex = 0; + return -errno; + } + + shandle->ifindex = ifindex; + return 0; +} + +static void +socket_handle_destroy (SocketHandle *shandle) +{ + if (shandle->ifindex) { + shandle->ifindex = 0; + nm_close (shandle->fd); + } +} +#define nm_auto_socket_handle nm_auto(socket_handle_destroy) + /****************************************************************************** * ethtool *****************************************************************************/ @@ -87,6 +123,8 @@ _ethtool_data_to_string (gconstpointer edata, char *buf, gsize len) return _ethtool_cmd_to_string (*((guint32 *) edata), buf, len); } +/*****************************************************************************/ + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) #define ethtool_cmd_speed(pedata) ((pedata)->speed) @@ -94,73 +132,63 @@ _ethtool_data_to_string (gconstpointer edata, char *buf, gsize len) G_STMT_START { (pedata)->speed = (guint16) (speed); } G_STMT_END #endif -static gboolean -ethtool_get (int ifindex, gpointer edata) +static int +ethtool_call_handle (SocketHandle *shandle, gpointer edata) { - char ifname[IFNAMSIZ]; + struct ifreq ifr = { + .ifr_data = edata, + }; + char sbuf[50]; + int errsv; + + nm_assert (shandle); + nm_assert (shandle->ifindex); + nm_assert (shandle->ifname[0]); + nm_assert (strlen (shandle->ifname) < IFNAMSIZ); + nm_assert (edata); + + memcpy (ifr.ifr_name, shandle->ifname, IFNAMSIZ); + if (ioctl (shandle->fd, SIOCETHTOOL, &ifr) < 0) { + errsv = errno; + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed: %s", + shandle->ifindex, + _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), + shandle->ifname, + strerror (errsv)); + return -errsv; + } + + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: success", + shandle->ifindex, + _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), + shandle->ifname); + return 0; +} + +static int +ethtool_call_ifindex (int ifindex, gpointer edata) +{ + nm_auto_socket_handle SocketHandle shandle = { }; + int r; char sbuf[50]; - nm_assert (ifindex > 0); + nm_assert (edata); - /* ethtool ioctl API uses the ifname to refer to an interface. That is racy - * as interfaces can be renamed *sigh*. - * - * Note that we anyway have to verify whether the interface exists, before - * calling ioctl for a non-existing ifname. This is to prevent autoloading - * of kernel modules *sigh*. - * Thus, as we anyway verify the existence of ifname before doing the call, - * go one step further and lookup the ifname everytime anew. - * - * This does not solve the renaming race, but it minimizes the time for - * the race to happen as much as possible. */ - - if (!nmp_utils_if_indextoname (ifindex, ifname)) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: request fails resolving ifindex: %s", + if ((r = socket_handle_init (&shandle, ifindex)) < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", ifindex, _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - g_strerror (errno)); - return FALSE; + g_strerror (-r)); + return r; } - { - nm_auto_close int fd = -1; - struct ifreq ifr = { - .ifr_data = edata, - }; - - memcpy (ifr.ifr_name, ifname, sizeof (ifname)); - - fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed creating socket for ioctl: %s", - ifindex, - _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - ifname, - g_strerror (errno)); - return FALSE; - } - - if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed: %s", - ifindex, - _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - ifname, - strerror (errno)); - return FALSE; - } - - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: success", - ifindex, - _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - ifname); - return TRUE; - } + return ethtool_call_handle (&shandle, edata); } /*****************************************************************************/ static struct ethtool_gstrings * -ethtool_get_stringset (int ifindex, int stringset_id) +ethtool_get_stringset (SocketHandle *shandle, int stringset_id) { struct { struct ethtool_sset_info info; @@ -169,13 +197,11 @@ ethtool_get_stringset (int ifindex, int stringset_id) gs_free struct ethtool_gstrings *gstrings = NULL; guint32 i, len; - g_return_val_if_fail (ifindex > 0, NULL); - sset_info.info.cmd = ETHTOOL_GSSET_INFO; sset_info.info.reserved = 0; sset_info.info.sset_mask = (1ULL << stringset_id); - if (!ethtool_get (ifindex, &sset_info)) + if (ethtool_call_handle (shandle, &sset_info) < 0) return NULL; if (!sset_info.info.sset_mask) return NULL; @@ -187,7 +213,7 @@ ethtool_get_stringset (int ifindex, int stringset_id) gstrings->string_set = stringset_id; gstrings->len = len; if (gstrings->len > 0) { - if (!ethtool_get (ifindex, gstrings)) + if (ethtool_call_handle (shandle, gstrings) < 0) return NULL; for (i = 0; i < gstrings->len; i++) { /* ensure NUL terminated */ @@ -215,7 +241,7 @@ ethtool_gstrings_find (const struct ethtool_gstrings *gstrings, const char *need } static int -ethtool_get_stringset_index (int ifindex, int stringset_id, const char *needle) +ethtool_get_stringset_index (SocketHandle *shandle, int stringset_id, const char *needle) { gs_free struct ethtool_gstrings *gstrings = NULL; @@ -223,7 +249,7 @@ ethtool_get_stringset_index (int ifindex, int stringset_id, const char *needle) * that means, we cannot possibly request longer names. */ nm_assert (needle && strlen (needle) < ETH_GSTRING_LEN); - gstrings = ethtool_get_stringset (ifindex, stringset_id); + gstrings = ethtool_get_stringset (shandle, stringset_id); if (gstrings) return ethtool_gstrings_find (gstrings, needle); return -1; @@ -234,13 +260,14 @@ nmp_utils_ethtool_get_driver_info (int ifindex, NMPUtilsEthtoolDriverInfo *data) { struct ethtool_drvinfo *drvinfo; - G_STATIC_ASSERT (sizeof (*data) == sizeof (*drvinfo)); - G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, driver) == offsetof (struct ethtool_drvinfo, driver)); - G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, version) == offsetof (struct ethtool_drvinfo, version)); - G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, fw_version) == offsetof (struct ethtool_drvinfo, fw_version)); - G_STATIC_ASSERT (sizeof (data->driver) == sizeof (drvinfo->driver)); - G_STATIC_ASSERT (sizeof (data->version) == sizeof (drvinfo->version)); - G_STATIC_ASSERT (sizeof (data->fw_version) == sizeof (drvinfo->fw_version)); + + G_STATIC_ASSERT_EXPR (sizeof (*data) == sizeof (*drvinfo)); + G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, driver) == offsetof (struct ethtool_drvinfo, driver)); + G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, version) == offsetof (struct ethtool_drvinfo, version)); + G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, fw_version) == offsetof (struct ethtool_drvinfo, fw_version)); + G_STATIC_ASSERT_EXPR (sizeof (data->driver) == sizeof (drvinfo->driver)); + G_STATIC_ASSERT_EXPR (sizeof (data->version) == sizeof (drvinfo->version)); + G_STATIC_ASSERT_EXPR (sizeof (data->fw_version) == sizeof (drvinfo->fw_version)); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (data, FALSE); @@ -249,7 +276,7 @@ nmp_utils_ethtool_get_driver_info (int ifindex, memset (drvinfo, 0, sizeof (*drvinfo)); drvinfo->cmd = ETHTOOL_GDRVINFO; - return ethtool_get (ifindex, drvinfo); + return ethtool_call_ifindex (ifindex, drvinfo) >= 0; } gboolean @@ -269,7 +296,7 @@ nmp_utils_ethtool_get_permanent_address (int ifindex, edata.e.cmd = ETHTOOL_GPERMADDR; edata.e.size = NM_UTILS_HWADDR_LEN_MAX; - if (!ethtool_get (ifindex, &edata.e)) + if (ethtool_call_ifindex (ifindex, &edata.e) < 0) return FALSE; if (edata.e.size > NM_UTILS_HWADDR_LEN_MAX) @@ -288,8 +315,8 @@ nmp_utils_ethtool_get_permanent_address (int ifindex, } return FALSE; } -not_all_0or1: +not_all_0or1: memcpy (buf, edata.e.data, edata.e.size); *length = edata.e.size; return TRUE; @@ -306,20 +333,30 @@ nmp_utils_ethtool_supports_carrier_detect (int ifindex) * assume the device supports carrier-detect, otherwise we assume it * doesn't. */ - return ethtool_get (ifindex, &edata); + return ethtool_call_ifindex (ifindex, &edata) >= 0; } gboolean nmp_utils_ethtool_supports_vlans (int ifindex) { + nm_auto_socket_handle SocketHandle shandle = { }; + int r; gs_free struct ethtool_gfeatures *features = NULL; int idx, block, bit, size; g_return_val_if_fail (ifindex > 0, FALSE); - idx = ethtool_get_stringset_index (ifindex, ETH_SS_FEATURES, "vlan-challenged"); + if ((r = socket_handle_init (&shandle, ifindex)) < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", + ifindex, + "support-vlans", + g_strerror (-r)); + return FALSE; + } + + idx = ethtool_get_stringset_index (&shandle, ETH_SS_FEATURES, "vlan-challenged"); if (idx < 0) { - nm_log_dbg (LOGD_PLATFORM, "ethtool: vlan-challenged ethtool feature does not exist for %d?", ifindex); + nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: vlan-challenged ethtool feature does not exist?", ifindex); return FALSE; } @@ -331,7 +368,7 @@ nmp_utils_ethtool_supports_vlans (int ifindex) features->cmd = ETHTOOL_GFEATURES; features->size = size; - if (!ethtool_get (ifindex, features)) + if (ethtool_call_handle (&shandle, features) < 0) return FALSE; return !(features->features[block].active & (1 << bit)); @@ -340,21 +377,32 @@ nmp_utils_ethtool_supports_vlans (int ifindex) int nmp_utils_ethtool_get_peer_ifindex (int ifindex) { + nm_auto_socket_handle SocketHandle shandle = { }; + int r; + gs_free struct ethtool_stats *stats = NULL; int peer_ifindex_stat; g_return_val_if_fail (ifindex > 0, 0); - peer_ifindex_stat = ethtool_get_stringset_index (ifindex, ETH_SS_STATS, "peer_ifindex"); + if ((r = socket_handle_init (&shandle, ifindex)) < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", + ifindex, + "get-peer-ifindex", + g_strerror (-r)); + return FALSE; + } + + peer_ifindex_stat = ethtool_get_stringset_index (&shandle, ETH_SS_STATS, "peer_ifindex"); if (peer_ifindex_stat < 0) { - nm_log_dbg (LOGD_PLATFORM, "ethtool: peer_ifindex stat for %d does not exist?", ifindex); + nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: peer_ifindex stat does not exist?", ifindex); return FALSE; } stats = g_malloc0 (sizeof (*stats) + (peer_ifindex_stat + 1) * sizeof (guint64)); stats->cmd = ETHTOOL_GSTATS; stats->n_stats = peer_ifindex_stat + 1; - if (!ethtool_get (ifindex, stats)) + if (ethtool_call_ifindex (ifindex, stats) < 0) return 0; return stats->data[peer_ifindex_stat]; @@ -369,7 +417,7 @@ nmp_utils_ethtool_get_wake_on_lan (int ifindex) memset (&wol, 0, sizeof (wol)); wol.cmd = ETHTOOL_GWOL; - if (!ethtool_get (ifindex, &wol)) + if (ethtool_call_ifindex (ifindex, &wol) < 0) return FALSE; return wol.wolopts != 0; @@ -387,7 +435,7 @@ nmp_utils_ethtool_get_link_settings (int ifindex, g_return_val_if_fail (ifindex > 0, FALSE); - if (!ethtool_get (ifindex, &edata)) + if (ethtool_call_ifindex (ifindex, &edata) < 0) return FALSE; if (out_autoneg) @@ -469,7 +517,7 @@ nmp_utils_ethtool_set_link_settings (int ifindex, || (!speed && duplex == NM_PLATFORM_LINK_DUPLEX_UNKNOWN), FALSE); /* retrieve first current settings */ - if (!ethtool_get (ifindex, &edata)) + if (ethtool_call_ifindex (ifindex, &edata) < 0) return FALSE; /* then change the needed ones */ @@ -521,7 +569,7 @@ nmp_utils_ethtool_set_link_settings (int ifindex, } } - return ethtool_get (ifindex, &edata); + return ethtool_call_ifindex (ifindex, &edata) >= 0; } gboolean @@ -536,8 +584,8 @@ nmp_utils_ethtool_set_wake_on_lan (int ifindex, if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE) return TRUE; - nm_log_dbg (LOGD_PLATFORM, "setting Wake-on-LAN options 0x%x, password '%s'", - (unsigned) wol, wol_password); + nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: setting Wake-on-LAN options 0x%x, password '%s'", + ifindex, (unsigned) wol, wol_password); wol_info.cmd = ETHTOOL_SWOL; wol_info.wolopts = 0; @@ -557,13 +605,13 @@ nmp_utils_ethtool_set_wake_on_lan (int ifindex, if (wol_password) { if (!nm_utils_hwaddr_aton (wol_password, wol_info.sopass, ETH_ALEN)) { - nm_log_dbg (LOGD_PLATFORM, "couldn't parse Wake-on-LAN password '%s'", wol_password); + nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: couldn't parse Wake-on-LAN password '%s'", ifindex, wol_password); return FALSE; } wol_info.wolopts |= WAKE_MAGICSECURE; } - return ethtool_get (ifindex, &wol_info); + return ethtool_call_ifindex (ifindex, &wol_info) >= 0; } /****************************************************************************** From 14f963cde33591e8a25763322e034ddaf0124ee8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 16 Jul 2018 14:11:09 +0200 Subject: [PATCH 27/32] platform/mii: use SocketHandle also for nmp_utils_mii_supports_carrier_detect() There is little difference in practice because there is only one caller. Still re-use the SocketHandle also for mii. If only, to make it clear that SocketHandle is not only suitable for ethtool, but also mii. --- src/platform/nm-platform-utils.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index b6dee1cdfe..74f8b3a998 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -621,29 +621,25 @@ nmp_utils_ethtool_set_wake_on_lan (int ifindex, gboolean nmp_utils_mii_supports_carrier_detect (int ifindex) { - char ifname[IFNAMSIZ]; - nm_auto_close int fd = -1; + nm_auto_socket_handle SocketHandle shandle = { }; + int r; struct ifreq ifr; struct mii_ioctl_data *mii; g_return_val_if_fail (ifindex > 0, FALSE); - if (!nmp_utils_if_indextoname (ifindex, ifname)) { - nm_log_trace (LOGD_PLATFORM, "mii[%d]: carrier-detect no: request fails resolving ifindex: %s", ifindex, g_strerror (errno)); - return FALSE; - } - - fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: couldn't open control socket: %s", ifindex, ifname, g_strerror (errno)); + if ((r = socket_handle_init (&shandle, ifindex)) < 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d]: carrier-detect no: failed creating ethtool socket: %s", + ifindex, + g_strerror (-r)); return FALSE; } memset (&ifr, 0, sizeof (struct ifreq)); - memcpy (ifr.ifr_name, ifname, IFNAMSIZ); + memcpy (ifr.ifr_name, shandle.ifname, IFNAMSIZ); - if (ioctl (fd, SIOCGMIIPHY, &ifr) < 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIPHY failed: %s", ifindex, ifname, strerror (errno)); + if (ioctl (shandle.fd, SIOCGMIIPHY, &ifr) < 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIPHY failed: %s", ifindex, shandle.ifname, strerror (errno)); return FALSE; } @@ -651,12 +647,12 @@ nmp_utils_mii_supports_carrier_detect (int ifindex) mii = (struct mii_ioctl_data *) &ifr.ifr_ifru; mii->reg_num = MII_BMSR; - if (ioctl (fd, SIOCGMIIREG, &ifr) != 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIREG failed: %s", ifindex, ifname, strerror (errno)); + if (ioctl (shandle.fd, SIOCGMIIREG, &ifr) != 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIREG failed: %s", ifindex, shandle.ifname, strerror (errno)); return FALSE; } - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect yes: SIOCGMIIREG result 0x%X", ifindex, ifname, mii->val_out); + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect yes: SIOCGMIIREG result 0x%X", ifindex, shandle.ifname, mii->val_out); return TRUE; } From c085b6e3a7d0ab62857878394d8f4c94909bed79 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 16 Jul 2018 15:42:07 +0200 Subject: [PATCH 28/32] platform/ethtool: add code to get/set offload features via ethtool Also, add two more features "tx-tcp-segmentation" and "tx-tcp6-segmentation". There are two reasons for that: - systemd-networkd supports setting these two features, so lets support them too (apparently they are important enough for networkd). - these two features are already implicitly covered by "tso". Like for the "ethtool" program, "tso" is an alias for several actual features. By adding two features that are already also covered by an alias (which sets multiple kernel names at once), we showcase how aliases for the same feature can coexist. In particular, note how setting "tso on tx-tcp6-segmentation off" will behave as one would expect: all 4 tso features covered by the alias are enabled, except that particular one. --- clients/common/nm-meta-setting-desc.c | 2 + libnm-core/nm-setting-ethtool.h | 24 +- shared/nm-ethtool-utils.c | 4 + shared/nm-ethtool-utils.h | 4 +- src/platform/nm-platform-utils.c | 376 ++++++++++++++++++ src/platform/nm-platform-utils.h | 56 ++- src/platform/nm-platform.c | 26 ++ src/platform/nm-platform.h | 11 + src/platform/tests/test-link.c | 98 +++++ .../plugins/ifcfg-rh/nms-ifcfg-rh-utils.c | 24 +- 10 files changed, 599 insertions(+), 26 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index a2833be1d3..0595640ef2 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -5881,6 +5881,8 @@ static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = { PROPERTY_INFO_ETHTOOL (FEATURE_TSO), PROPERTY_INFO_ETHTOOL (FEATURE_TX), PROPERTY_INFO_ETHTOOL (FEATURE_TXVLAN), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP6_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP_SEGMENTATION), NULL, }; diff --git a/libnm-core/nm-setting-ethtool.h b/libnm-core/nm-setting-ethtool.h index 763d2691ee..10f5651b19 100644 --- a/libnm-core/nm-setting-ethtool.h +++ b/libnm-core/nm-setting-ethtool.h @@ -31,17 +31,19 @@ G_BEGIN_DECLS /*****************************************************************************/ -#define NM_ETHTOOL_OPTNAME_FEATURE_GRO "feature-gro" -#define NM_ETHTOOL_OPTNAME_FEATURE_GSO "feature-gso" -#define NM_ETHTOOL_OPTNAME_FEATURE_LRO "feature-lro" -#define NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE "feature-ntuple" -#define NM_ETHTOOL_OPTNAME_FEATURE_RX "feature-rx" -#define NM_ETHTOOL_OPTNAME_FEATURE_RXHASH "feature-rxhash" -#define NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN "feature-rxvlan" -#define NM_ETHTOOL_OPTNAME_FEATURE_SG "feature-sg" -#define NM_ETHTOOL_OPTNAME_FEATURE_TSO "feature-tso" -#define NM_ETHTOOL_OPTNAME_FEATURE_TX "feature-tx" -#define NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN "feature-txvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_GRO "feature-gro" +#define NM_ETHTOOL_OPTNAME_FEATURE_GSO "feature-gso" +#define NM_ETHTOOL_OPTNAME_FEATURE_LRO "feature-lro" +#define NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE "feature-ntuple" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX "feature-rx" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXHASH "feature-rxhash" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN "feature-rxvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_SG "feature-sg" +#define NM_ETHTOOL_OPTNAME_FEATURE_TSO "feature-tso" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX "feature-tx" +#define NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN "feature-txvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP6_SEGMENTATION "feature-tx-tcp6-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_SEGMENTATION "feature-tx-tcp-segmentation" gboolean nm_ethtool_optname_is_feature (const char *optname); diff --git a/shared/nm-ethtool-utils.c b/shared/nm-ethtool-utils.c index 1e6d405a88..a57228040c 100644 --- a/shared/nm-ethtool-utils.c +++ b/shared/nm-ethtool-utils.c @@ -46,6 +46,8 @@ const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = { ETHT_DATA (FEATURE_TSO), ETHT_DATA (FEATURE_TX), ETHT_DATA (FEATURE_TXVLAN), + ETHT_DATA (FEATURE_TX_TCP6_SEGMENTATION), + ETHT_DATA (FEATURE_TX_TCP_SEGMENTATION), [_NM_ETHTOOL_ID_NUM] = NULL, }; @@ -61,6 +63,8 @@ const guint8 const _by_name[_NM_ETHTOOL_ID_NUM] = { NM_ETHTOOL_ID_FEATURE_SG, NM_ETHTOOL_ID_FEATURE_TSO, NM_ETHTOOL_ID_FEATURE_TX, + NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, NM_ETHTOOL_ID_FEATURE_TXVLAN, }; diff --git a/shared/nm-ethtool-utils.h b/shared/nm-ethtool-utils.h index 06956d0462..3846450803 100644 --- a/shared/nm-ethtool-utils.h +++ b/shared/nm-ethtool-utils.h @@ -40,7 +40,9 @@ typedef enum { NM_ETHTOOL_ID_FEATURE_TSO, NM_ETHTOOL_ID_FEATURE_TX, NM_ETHTOOL_ID_FEATURE_TXVLAN, - _NM_ETHTOOL_ID_FEATURE_LAST = NM_ETHTOOL_ID_FEATURE_TXVLAN, + NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, + _NM_ETHTOOL_ID_FEATURE_LAST = NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, _NM_ETHTOOL_ID_FEATURE_NUM = (_NM_ETHTOOL_ID_FEATURE_LAST - _NM_ETHTOOL_ID_FEATURE_FIRST + 1), _NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_FEATURE_LAST, diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 74f8b3a998..24f8dfa8d3 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -36,9 +36,12 @@ #include "nm-utils.h" #include "nm-setting-wired.h" +#include "nm-ethtool-utils.h" #include "nm-core-utils.h" +#define ONOFF(bool_val) ((bool_val) ? "on" : "off") + /****************************************************************************** * utils *****************************************************************************/ @@ -113,6 +116,7 @@ NM_UTILS_ENUM2STR_DEFINE_STATIC (_ethtool_cmd_to_string, guint32, NM_UTILS_ENUM2STR (ETHTOOL_GSTATS, "ETHTOOL_GSTATS"), NM_UTILS_ENUM2STR (ETHTOOL_GSTRINGS, "ETHTOOL_GSTRINGS"), NM_UTILS_ENUM2STR (ETHTOOL_GWOL, "ETHTOOL_GWOL"), + NM_UTILS_ENUM2STR (ETHTOOL_SFEATURES, "ETHTOOL_SFEATURES"), NM_UTILS_ENUM2STR (ETHTOOL_SSET, "ETHTOOL_SSET"), NM_UTILS_ENUM2STR (ETHTOOL_SWOL, "ETHTOOL_SWOL"), ); @@ -255,6 +259,378 @@ ethtool_get_stringset_index (SocketHandle *shandle, int stringset_id, const char return -1; } +/*****************************************************************************/ + +static const NMEthtoolFeatureInfo _ethtool_feature_infos[_NM_ETHTOOL_ID_FEATURE_NUM] = { +#define ETHT_FEAT(eid, ...) \ + { \ + .ethtool_id = eid, \ + .n_kernel_names = NM_NARG (__VA_ARGS__), \ + .kernel_names = ((const char *const[]) { __VA_ARGS__ }), \ + } + + /* the order does only matter for one thing: if it happens that more than one NMEthtoolID + * reference the same kernel-name, then the one that is mentioned *later* will win in + * case these NMEthtoolIDs are set. That mostly only makes sense for ethtool-ids which + * refer to multiple features ("feature-tso"), while also having more specific ids + * ("feature-tx-tcp-segmentation"). */ + + /* names from ethtool utility, which are aliases for multiple features. */ + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_SG, "tx-scatter-gather", + "tx-scatter-gather-fraglist"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TSO, "tx-tcp-segmentation", + "tx-tcp-ecn-segmentation", + "tx-tcp-mangleid-segmentation", + "tx-tcp6-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX, "tx-checksum-ipv4", + "tx-checksum-ip-generic", + "tx-checksum-ipv6", + "tx-checksum-fcoe-crc", + "tx-checksum-sctp"), + + /* names from ethtool utility, which are aliases for one feature. */ + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert"), + + /* names of features, as known by kernel. */ + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), +}; + +/* the number of kernel features that we handle. It essentially is the sum of all + * kernel_names. So, all ethtool-ids that reference exactly one kernel-name + * (_NM_ETHTOOL_ID_FEATURE_NUM) + some extra, for ethtool-ids that are aliases + * for multiple kernel-names. */ +#define N_ETHTOOL_KERNEL_FEATURES (((guint) _NM_ETHTOOL_ID_FEATURE_NUM) + 8u) + +static void +_ASSERT_ethtool_feature_infos (void) +{ +#if NM_MORE_ASSERTS > 10 + guint i, k, n; + bool found[_NM_ETHTOOL_ID_FEATURE_NUM] = { }; + + G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (_ethtool_feature_infos) == _NM_ETHTOOL_ID_FEATURE_NUM); + + n = 0; + for (i = 0; i < G_N_ELEMENTS (_ethtool_feature_infos); i++) { + NMEthtoolFeatureState kstate; + const NMEthtoolFeatureInfo *inf = &_ethtool_feature_infos[i]; + + g_assert (inf->ethtool_id >= _NM_ETHTOOL_ID_FEATURE_FIRST); + g_assert (inf->ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST); + g_assert (inf->n_kernel_names > 0); + + for (k = 0; k < i; k++) + g_assert (inf->ethtool_id != _ethtool_feature_infos[k].ethtool_id); + + g_assert (!found[inf->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]); + found[inf->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST] = TRUE; + + kstate.idx_kernel_name = inf->n_kernel_names - 1; + g_assert ((guint) kstate.idx_kernel_name == (guint) (inf->n_kernel_names - 1)); + + n += inf->n_kernel_names; + for (k = 0; k < inf->n_kernel_names; k++) { + g_assert (nm_utils_strv_find_first ((char **) inf->kernel_names, + k, + inf->kernel_names[k]) < 0); + } + } + + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) + g_assert (found[i]); + + g_assert (n == N_ETHTOOL_KERNEL_FEATURES); +#endif +} + +static NMEthtoolFeatureStates * +ethtool_get_features (SocketHandle *shandle) +{ + gs_free NMEthtoolFeatureStates *states = NULL; + gs_free struct ethtool_gstrings *ss_features = NULL; + + _ASSERT_ethtool_feature_infos (); + + ss_features = ethtool_get_stringset (shandle, ETH_SS_FEATURES); + if (!ss_features) + return NULL; + + if (ss_features->len > 0) { + gs_free struct ethtool_gfeatures *gfeatures = NULL; + guint idx; + const NMEthtoolFeatureState *states_list0 = NULL; + const NMEthtoolFeatureState *const*states_plist0 = NULL; + guint states_plist_n = 0; + + gfeatures = g_malloc0 ( sizeof (struct ethtool_gfeatures) + + (NM_DIV_ROUND_UP (ss_features->len, 32u) * sizeof(gfeatures->features[0]))); + + gfeatures->cmd = ETHTOOL_GFEATURES; + gfeatures->size = NM_DIV_ROUND_UP (ss_features->len, 32u); + if (ethtool_call_handle (shandle, gfeatures) < 0) + return NULL; + + for (idx = 0; idx < G_N_ELEMENTS (_ethtool_feature_infos); idx++) { + const NMEthtoolFeatureInfo *info = &_ethtool_feature_infos[idx]; + guint idx_kernel_name; + + for (idx_kernel_name = 0; idx_kernel_name < info->n_kernel_names; idx_kernel_name++) { + NMEthtoolFeatureState *kstate; + const char *kernel_name = info->kernel_names[idx_kernel_name]; + int i_feature; + guint i_block; + guint32 i_flag; + + i_feature = ethtool_gstrings_find (ss_features, kernel_name); + if (i_feature < 0) + continue; + + i_block = ((guint) i_feature) / 32u; + i_flag = (guint32) (1u << (((guint) i_feature) % 32u)); + + if (!states) { + states = g_malloc0 (sizeof (NMEthtoolFeatureStates) + + (N_ETHTOOL_KERNEL_FEATURES * sizeof (NMEthtoolFeatureState)) + + ((N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)) * sizeof (NMEthtoolFeatureState *))); + states_list0 = &states->states_list[0]; + states_plist0 = (gpointer) &states_list0[N_ETHTOOL_KERNEL_FEATURES]; + states->n_ss_features = ss_features->len; + } + + nm_assert (states->n_states < N_ETHTOOL_KERNEL_FEATURES); + kstate = (NMEthtoolFeatureState *) &states_list0[states->n_states]; + states->n_states++; + + kstate->info = info; + kstate->idx_ss_features = i_feature; + kstate->idx_kernel_name = idx_kernel_name; + kstate->available = !!(gfeatures->features[i_block].available & i_flag); + kstate->requested = !!(gfeatures->features[i_block].requested & i_flag); + kstate->active = !!(gfeatures->features[i_block].active & i_flag); + kstate->never_changed = !!(gfeatures->features[i_block].never_changed & i_flag); + + nm_assert (states_plist_n < N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)); + + if (!states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]) + states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST] = &states_plist0[states_plist_n]; + ((const NMEthtoolFeatureState **) states_plist0)[states_plist_n] = kstate; + states_plist_n++; + } + + if (states && states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]) { + nm_assert (states_plist_n < N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)); + nm_assert (!states_plist0[states_plist_n]); + states_plist_n++; + } + } + } + + return g_steal_pointer (&states); +} + +NMEthtoolFeatureStates * +nmp_utils_ethtool_get_features (int ifindex) +{ + nm_auto_socket_handle SocketHandle shandle = { }; + NMEthtoolFeatureStates *features; + int r; + + g_return_val_if_fail (ifindex > 0, 0); + + if ((r = socket_handle_init (&shandle, ifindex)) < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", + ifindex, + "get-features", + g_strerror (-r)); + return FALSE; + } + + features = ethtool_get_features (&shandle); + + if (!features) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure getting features", + ifindex, + "get-features"); + return NULL; + } + + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: retrieved kernel features", + ifindex, + "get-features"); + return features; +} + +static const char * +_ethtool_feature_state_to_string (char *buf, gsize buf_size, const NMEthtoolFeatureState *s, const char *prefix) +{ + int l; + + l = g_snprintf (buf, buf_size, + "%s %s%s", + prefix ?: "", + ONOFF (s->active), + (!s->available || s->never_changed) + ? ", [fixed]" + : ((s->requested != s->active) + ? (s->requested ? ", [requested on]" : ", [requested off]") + : "")); + nm_assert (l < buf_size); + return buf; +} + +gboolean +nmp_utils_ethtool_set_features (int ifindex, + const NMEthtoolFeatureStates *features, + const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */) +{ + nm_auto_socket_handle SocketHandle shandle = { }; + gs_free struct ethtool_sfeatures *sfeatures = NULL; + int r; + guint i, j; + struct { + const NMEthtoolFeatureState *f_state; + NMTernary requested; + } set_states[N_ETHTOOL_KERNEL_FEATURES]; + guint set_states_n = 0; + gboolean success = TRUE; + + g_return_val_if_fail (ifindex > 0, 0); + g_return_val_if_fail (features, 0); + g_return_val_if_fail (requested, 0); + + nm_assert (features->n_states <= N_ETHTOOL_KERNEL_FEATURES); + + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { + const NMEthtoolFeatureState *const*states_indexed; + + if (requested[i] == NM_TERNARY_DEFAULT) + continue; + + if (!(states_indexed = features->states_indexed[i])) { + if (do_set) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: set feature %s: skip (not found)", + ifindex, + "set-features", + nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname); + success = FALSE; + } + continue; + } + + for (j = 0; states_indexed[j]; j++) { + const NMEthtoolFeatureState *s = states_indexed[j]; + char sbuf[255]; + + if (set_states_n >= G_N_ELEMENTS (set_states)) + g_return_val_if_reached (FALSE); + + if (s->never_changed) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s feature %s (%s): %s, %s (skip feature marked as never changed)", + ifindex, + "set-features", + do_set ? "set" : "reset", + nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, + s->info->kernel_names[s->idx_kernel_name], + ONOFF (do_set ? requested[i] == NM_TERNARY_TRUE : s->active), + _ethtool_feature_state_to_string (sbuf, sizeof (sbuf), s, do_set ? " currently:" : " before:")); + continue; + } + + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s feature %s (%s): %s, %s", + ifindex, + "set-features", + do_set ? "set" : "reset", + nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, + s->info->kernel_names[s->idx_kernel_name], + ONOFF (do_set ? requested[i] == NM_TERNARY_TRUE : s->active), + _ethtool_feature_state_to_string (sbuf, sizeof (sbuf), s, do_set ? " currently:" : " before:")); + + if ( do_set + && (!s->available || s->never_changed) + && (s->active != (requested[i] == NM_TERNARY_TRUE))) { + /* we request to change a flag which kernel reported as fixed. + * While the ethtool operation will silently succeed, mark the request + * as failure. */ + success = FALSE; + } + + set_states[set_states_n].f_state = s; + set_states[set_states_n].requested = requested[i]; + set_states_n++; + } + } + + if (set_states_n == 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: no feature requested", + ifindex, + "set-features"); + return TRUE; + } + + if ((r = socket_handle_init (&shandle, ifindex)) < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", + ifindex, + "set-features", + g_strerror (-r)); + return FALSE; + } + + sfeatures = g_malloc0 (sizeof (struct ethtool_sfeatures) + + (NM_DIV_ROUND_UP (features->n_ss_features, 32U) * sizeof(sfeatures->features[0]))); + sfeatures->cmd = ETHTOOL_SFEATURES; + sfeatures->size = NM_DIV_ROUND_UP (features->n_ss_features, 32U); + + for (i = 0; i < set_states_n; i++) { + const NMEthtoolFeatureState *s = set_states[i].f_state; + guint i_block; + guint32 i_flag; + gboolean is_requested; + + i_block = s->idx_ss_features / 32u; + i_flag = (guint32) (1u << (s->idx_ss_features % 32u)); + + sfeatures->features[i_block].valid |= i_flag; + + if (do_set) + is_requested = (set_states[i].requested == NM_TERNARY_TRUE); + else + is_requested = s->active; + + if (is_requested) + sfeatures->features[i_block].requested |= i_flag; + else + sfeatures->features[i_block].requested &= ~i_flag; + } + + if ((r = ethtool_call_handle (&shandle, sfeatures)) < 0) { + success = FALSE; + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure setting features (%s)", + ifindex, + "set-features", + g_strerror (-r)); + return FALSE; + } + + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s", + ifindex, + "set-features", + success + ? "successfully setting features" + : "at least some of the features were not successfuly set"); + return success; +} + +/*****************************************************************************/ + gboolean nmp_utils_ethtool_get_driver_info (int ifindex, NMPUtilsEthtoolDriverInfo *data) diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h index 97f5630a4d..bad77aee38 100644 --- a/src/platform/nm-platform-utils.h +++ b/src/platform/nm-platform-utils.h @@ -23,6 +23,9 @@ #include "nm-platform.h" #include "nm-setting-wired.h" +#include "nm-ethtool-utils.h" + +/*****************************************************************************/ const char *nmp_utils_ethtool_get_driver (int ifindex); gboolean nmp_utils_ethtool_supports_carrier_detect (int ifindex); @@ -35,6 +38,10 @@ gboolean nmp_utils_ethtool_set_wake_on_lan (int ifindex, NMSettingWiredWakeOnLan gboolean nmp_utils_ethtool_get_link_settings (int ifindex, gboolean *out_autoneg, guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex); gboolean nmp_utils_ethtool_set_link_settings (int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex); +gboolean nmp_utils_ethtool_get_permanent_address (int ifindex, + guint8 *buf, + size_t *length); + typedef struct { /* We don't want to include in header files, * thus create a ABI compatible version of struct ethtool_drvinfo.*/ @@ -55,9 +62,52 @@ typedef struct { gboolean nmp_utils_ethtool_get_driver_info (int ifindex, NMPUtilsEthtoolDriverInfo *data); -gboolean nmp_utils_ethtool_get_permanent_address (int ifindex, - guint8 *buf, - size_t *length); +typedef struct { + NMEthtoolID ethtool_id; + + guint8 n_kernel_names; + + /* one NMEthtoolID refers to one or more kernel_names. The reason for supporting this complexity + * (where one NMSettingEthtool option refers to multiple kernel features) is to follow what + * ethtool does, where "tx" is an alias for multiple features. */ + const char *const*kernel_names; +} NMEthtoolFeatureInfo; + +typedef struct { + const NMEthtoolFeatureInfo *info; + + guint idx_ss_features; + + /* one NMEthtoolFeatureInfo references one or more kernel_names. This is the index + * of the matching info->kernel_names */ + guint8 idx_kernel_name; + + bool available:1; + bool requested:1; + bool active:1; + bool never_changed:1; +} NMEthtoolFeatureState; + +struct _NMEthtoolFeatureStates { + guint n_states; + + guint n_ss_features; + + /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ + const NMEthtoolFeatureState *const*states_indexed[_NM_ETHTOOL_ID_FEATURE_NUM]; + + /* the same content, here as a list of n_states entries. */ + const NMEthtoolFeatureState states_list[]; +}; + +NMEthtoolFeatureStates *nmp_utils_ethtool_get_features (int ifindex); + +gboolean nmp_utils_ethtool_set_features (int ifindex, + const NMEthtoolFeatureStates *features, + const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */); + +/*****************************************************************************/ gboolean nmp_utils_mii_supports_carrier_detect (int ifindex); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 22af971505..0020acc924 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -3213,6 +3213,32 @@ NM_UTILS_LOOKUP_STR_DEFINE (nm_platform_link_duplex_type_to_string, NMPlatformLi /*****************************************************************************/ +NMEthtoolFeatureStates * +nm_platform_ethtool_get_link_features (NMPlatform *self, int ifindex) +{ + _CHECK_SELF_NETNS (self, klass, netns, NULL); + + g_return_val_if_fail (ifindex > 0, NULL); + + return nmp_utils_ethtool_get_features (ifindex); +} + +gboolean +nm_platform_ethtool_set_features (NMPlatform *self, + int ifindex, + const NMEthtoolFeatureStates *features, + const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */) +{ + _CHECK_SELF_NETNS (self, klass, netns, FALSE); + + g_return_val_if_fail (ifindex > 0, FALSE); + + return nmp_utils_ethtool_set_features (ifindex, features, requested, do_set); +} + +/*****************************************************************************/ + const NMDedupMultiHeadEntry * nm_platform_lookup_all (NMPlatform *platform, NMPCacheIdType cache_id_type, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index bbc9fccabc..994e041719 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -1534,6 +1534,17 @@ int nm_platform_ip_address_cmp_expiry (const NMPlatformIPAddress *a, const NMPla gboolean nm_platform_ethtool_set_wake_on_lan (NMPlatform *self, int ifindex, NMSettingWiredWakeOnLan wol, const char *wol_password); gboolean nm_platform_ethtool_set_link_settings (NMPlatform *self, int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex); gboolean nm_platform_ethtool_get_link_settings (NMPlatform *self, int ifindex, gboolean *out_autoneg, guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex); + +typedef struct _NMEthtoolFeatureStates NMEthtoolFeatureStates; + +NMEthtoolFeatureStates *nm_platform_ethtool_get_link_features (NMPlatform *self, + int ifindex); +gboolean nm_platform_ethtool_set_features (NMPlatform *self, + int ifindex, + const NMEthtoolFeatureStates *features, + const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */); + const char * nm_platform_link_duplex_type_to_string (NMPlatformLinkDuplexType duplex); void nm_platform_ip4_dev_route_blacklist_set (NMPlatform *self, diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 854285357a..20b3374b28 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -2713,6 +2713,102 @@ test_sysctl_netns_switch (void) /*****************************************************************************/ +static void +ethtool_features_dump (const NMEthtoolFeatureStates *features) +{ + guint i, j; + + g_assert (features); + + _LOGT (">>> %u features (%u ss-features)", features->n_states, features->n_ss_features); + + for (i = 0; i < features->n_states; i++) { + const NMEthtoolFeatureState *s = &features->states_list[i]; + + _LOGT (">>> feature-list[%3u]: %3d = %-32s (%3u) | %s %s %s %s", + i, + (int) s->info->ethtool_id, + s->info->kernel_names[s->idx_kernel_name], + s->idx_ss_features, + s->active ? "ACT" : "act", + s->available ? "AVA" : "ava", + s->never_changed ? "NCH" : "nch", + s->requested ? "REQ" : "req"); + } + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { + _LOGT (">>> feature-idx [%3u]: %-32s = %u features", + i + (guint) _NM_ETHTOOL_ID_FEATURE_FIRST, + nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, + (guint) NM_PTRARRAY_LEN (features->states_indexed[i])); + for (j = 0; features->states_indexed[i] && features->states_indexed[i][j]; j++) { + const NMEthtoolFeatureState *s = features->states_indexed[i][j]; + + _LOGT (">>> %3u: %-32s | %s %s %s %s", + j, + s->info->kernel_names[s->idx_kernel_name], + s->active ? "ACT" : "act", + s->available ? "AVA" : "ava", + s->never_changed ? "NCH" : "nch", + s->requested ? "REQ" : "req"); + } + } +} + +static void +test_ethtool_features_get (void) +{ + gs_unref_ptrarray GPtrArray *gfree_keeper = g_ptr_array_new_with_free_func (g_free); + const int IFINDEX = 1; + guint i; + guint i_run; + + for (i_run = 0; i_run < 5; i_run++) { + NMEthtoolFeatureStates *features; + NMTernary *requested; + gboolean do_set = TRUE; + + requested = g_new (NMTernary, _NM_ETHTOOL_ID_FEATURE_NUM); + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) + requested[i] = NM_TERNARY_DEFAULT; + g_ptr_array_add (gfree_keeper, requested); + + if (i_run == 0) { + requested[NM_ETHTOOL_ID_FEATURE_RX] = NM_TERNARY_FALSE; + requested[NM_ETHTOOL_ID_FEATURE_TSO] = NM_TERNARY_FALSE; + requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION] = NM_TERNARY_FALSE; + } else if (i_run == 1) + do_set = FALSE; + else if (i_run == 2) { + requested[NM_ETHTOOL_ID_FEATURE_TSO] = NM_TERNARY_FALSE; + requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION] = NM_TERNARY_TRUE; + } else if (i_run == 3) + do_set = FALSE; + + _LOGT (">>> ethtool-features-get RUN %u (do-set=%s", i_run, do_set ? "set" : "reset"); + + features = nmp_utils_ethtool_get_features (IFINDEX); + g_ptr_array_add (gfree_keeper, features); + + ethtool_features_dump (features); + + if (_LOGT_ENABLED ()) { + int ignore; + + ignore = system ("ethtool -k lo"); + (void) ignore; + } + + if (!do_set) { + requested = gfree_keeper->pdata[i_run * 2 - 2]; + features = gfree_keeper->pdata[i_run * 2 - 1]; + } + + nmp_utils_ethtool_set_features (IFINDEX, features, requested, do_set); + } +} + +/*****************************************************************************/ + NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP; void @@ -2774,5 +2870,7 @@ _nmtstp_setup_tests (void) g_test_add_func ("/general/sysctl/rename", test_sysctl_rename); g_test_add_func ("/general/sysctl/netns-switch", test_sysctl_netns_switch); + + g_test_add_func ("/link/ethtool/features/get", test_ethtool_features_get); } } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index fecce50e29..12da58cf40 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -477,17 +477,19 @@ const char *const _nm_ethtool_ifcfg_names[] = { #define ETHT_NAME(eid, ename) \ [eid - _NM_ETHTOOL_ID_FEATURE_FIRST] = ""ename"" /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GRO, "gro"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GSO, "gso"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LRO, "lro"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX, "rx"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_SG, "sg"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TSO, "tso"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX, "tx"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GRO, "gro"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GSO, "gso"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LRO, "lro"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX, "rx"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_SG, "sg"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TSO, "tso"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX, "tx"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), }; const NMEthtoolData * From 8c752076aab0cd8431be2d50c610d67d94a6ab74 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Aug 2018 11:48:34 +0200 Subject: [PATCH 29/32] device: implement setting ethtool offload features --- src/devices/nm-device.c | 87 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index d71005944b..908a0b5359 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -43,6 +43,7 @@ #include "nm-utils/nm-random-utils.h" #include "nm-utils/unaligned.h" +#include "nm-ethtool-utils.h" #include "nm-common-macros.h" #include "nm-device-private.h" #include "NetworkManagerUtils.h" @@ -65,6 +66,7 @@ #include "nm-firewall-manager.h" #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" +#include "nm-setting-ethtool.h" #include "nm-auth-utils.h" #include "nm-netns.h" #include "nm-dispatcher.h" @@ -172,6 +174,12 @@ struct _NMDeviceConnectivityHandle { bool is_periodic_bump_on_complete:1; }; +typedef struct { + int ifindex; + NMEthtoolFeatureStates *features; + NMTernary requested[_NM_ETHTOOL_ID_FEATURE_NUM]; +} EthtoolState; + /*****************************************************************************/ enum { @@ -508,6 +516,8 @@ typedef struct _NMDevicePrivate { GHashTable * ip6_saved_properties; + EthtoolState *ethtool_state; + struct { NMDhcpClient * client; NMNDiscDHCPLevel mode; @@ -740,6 +750,79 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (mtu_source_to_str, NMDeviceMtuSource, /*****************************************************************************/ +static void +_ethtool_state_reset (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->ethtool_state) { + gs_free NMEthtoolFeatureStates *features = priv->ethtool_state->features; + gs_free EthtoolState *ethtool_state = g_steal_pointer (&priv->ethtool_state); + + if (!nm_platform_ethtool_set_features (nm_device_get_platform (self), + ethtool_state->ifindex, + features, + ethtool_state->requested, + FALSE)) + _LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more offload features"); + else + _LOGD (LOGD_DEVICE, "ethtool: offload features successfully reset"); + } +} + +static void +_ethtool_state_set (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int ifindex; + NMConnection *connection; + NMSettingEthtool *s_ethtool; + NMPlatform *platform; + gs_free EthtoolState *ethtool_state = NULL; + gs_free NMEthtoolFeatureStates *features = NULL; + + _ethtool_state_reset (self); + + connection = nm_device_get_applied_connection (self); + if (!connection) + return; + + ifindex = nm_device_get_ip_ifindex (self); + if (ifindex <= 0) + return; + + s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (connection, NM_TYPE_SETTING_ETHTOOL)); + if (!s_ethtool) + return; + + ethtool_state = g_new (EthtoolState, 1); + if (nm_setting_ethtool_init_features (s_ethtool, ethtool_state->requested) == 0) + return; + + platform = nm_device_get_platform (self); + + features = nm_platform_ethtool_get_link_features (platform, ifindex); + if (!features) { + _LOGW (LOGD_DEVICE, "ethtool: failure setting offload features (cannot read features)"); + return; + } + + if (!nm_platform_ethtool_set_features (platform, + ifindex, + features, + ethtool_state->requested, + TRUE)) + _LOGW (LOGD_DEVICE, "ethtool: failure setting one or more offload features"); + else + _LOGD (LOGD_DEVICE, "ethtool: offload features successfully set"); + + ethtool_state->ifindex = ifindex; + ethtool_state->features = g_steal_pointer (&features); + priv->ethtool_state = g_steal_pointer (ðtool_state); +} + +/*****************************************************************************/ + NMSettings * nm_device_get_settings (NMDevice *self) { @@ -6228,6 +6311,8 @@ activate_stage2_device_config (NMDevice *self) if (!nm_device_sys_iface_state_is_external_or_assume (self)) { NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; + _ethtool_state_set (self); + if (!tc_commit (self)) { _LOGW (LOGD_IP6, "failed applying traffic control rules"); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED); @@ -14022,6 +14107,8 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean priv->ip6_mtu_initial = 0; } + _ethtool_state_reset (self); + _cleanup_generic_post (self, cleanup_type); } From 582ee91145a5369222b709fb8ee8d367dea85ed7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Aug 2018 20:43:22 +0200 Subject: [PATCH 30/32] cli: add functionality to hide properties from output Historically, nmcli printed all fields during operations like `nmcli connection show "$PROFILE"`. As we supported more and more options, this resulted in a verbose output, of most properties just being the default values. To counter that, we added the '-overview' option. When given, it would hide options that are set at their default. This option was not the default, to preserve established behavior. However, for new options, we can afford to hide them. Add a mechanism, that property getters can mark their value to be hidden. At the moment, there is no way to show these properties. However, we could add a '-verbose' option, with the opposite meaning of '-overview'. Anyway, that does not seem necessary at the moment. Hiding properties from output is only acceptable for new properties (otherwise we badly change behavior), and if the properties are set at their default values (otherwise, we hide important information). --- clients/cli/utils.c | 13 ++++++++++++- clients/common/nm-meta-setting-desc.h | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/clients/cli/utils.c b/clients/cli/utils.c index ea2c7de860..8cbfe9f2fa 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -1092,7 +1092,18 @@ _print_fill (const NmcConfig *nmc_config, nm_assert (!to_free || value == to_free); - if (!nmc_config->overview || !is_default) + if ( is_default + && ( nmc_config->overview + || NM_FLAGS_HAS (text_out_flags, NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE))) { + /* don't mark the entry for display. This is to shorten the output in case + * the property is the default value. But we only do that, if the user + * opts in to this behavior (-overview), or of the property marks itself + * elegible to be hidden. + * + * In general, only new API shall mark itself eligible to be hidden. + * Long established properties cannot, because it would be a change + * in behavior. */ + } else header_cell->to_print = TRUE; if (NM_FLAGS_HAS (text_out_flags, NM_META_ACCESSOR_GET_OUT_FLAGS_STRV)) { diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index acb0a223b1..31f1dd51bd 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -148,6 +148,11 @@ typedef enum { typedef enum { NM_META_ACCESSOR_GET_OUT_FLAGS_NONE = 0, NM_META_ACCESSOR_GET_OUT_FLAGS_STRV = (1LL << 0), + + /* the property allows to be hidden, if and only if, it's value is set to the + * default. This should only be set by new properties, to preserve behavior + * of old properties, which were always printed. */ + NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE = (1LL << 1), } NMMetaAccessorGetOutFlags; typedef enum { From 9e7c960fadfc166ea27fd17e42d590d1d5bc1b55 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Aug 2018 20:48:25 +0200 Subject: [PATCH 31/32] cli: hide ethtool options form `nmcli connection show "$PROFILE"` output We will add a large number of offload features. That means, the output of `nmcli connection show "$PROFILE"` would be very verbose, in case the profile has a [ethtool] option. Since this is newly added API, don't do that. Don't show ethtool properties that are left unset. A minor problem here is, that it becomes no longer obvious which properties exist. We should however counter that by documentation. Also, one could do: $ nmcli connection modify "$PROFILE" ethtool.xxx x Error: invalid property 'xxx': 'xxx' not among [feature-gro, feature-gso, feature-lro, feature-ntuple, feature-rx, feature-rxhash, feature-rxvlan, feature-sg, feature-tso, feature-tx, feature-txvlan, feature-tx-tcp6-segmentation, feature-tx-tcp-segmentation]. Likewise, bash completion still works as one would expect. $ nmcli --complete-args connection modify "$PROFILE" ethtool. ethtool.feature-gro ethtool.feature-gso ethtool.feature-lro [...] Note the output of $ nmcli -f ethtool.feature-gro connection show "$PROFILE" gives now nothing (if there is an ethtool section, but not this particular feature). Maybe this shouldn't be like that. On the other hand, specifying a connection setting that doesn't exist also gives no output: $ nmcli -f bond connection show "$PROFILE" So, maybe this behavior is fine. --- clients/common/nm-meta-setting-desc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 0595640ef2..505c764b6e 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -4842,6 +4842,7 @@ _get_fcn_ethtool (ARGS_GET_FCN) else { s = NULL; NM_SET_OUT (out_is_default, TRUE); + *out_flags |= NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE; } if (s && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) From da109a291c6d219a554578e32c4c0daae6def241 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 9 Aug 2018 20:17:02 +0200 Subject: [PATCH 32/32] all/ethtool: add support for all currently supported kernel features As of upstream kernel v4.18-rc8. Note that we name the features like they are called in ethtool's ioctl API ETH_SS_FEATURES. Except, for features like "tx-gro", which ethtool utility aliases as "gro". So, for those features where ethtool has a built-in, alternative name, we prefer the alias. And again, note that a few aliases of ethtool utility ("sg", "tso", "tx") actually affect more than one underlying kernel feature. Note that 3 kernel features which are announced via ETH_SS_FEATURES are explicitly exluded because kernel marks them as "never_changed": #define NETIF_F_NEVER_CHANGE (NETIF_F_VLAN_CHALLENGED | \ NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) --- clients/common/nm-meta-setting-desc.c | 39 +++++++++ libnm-core/nm-setting-ethtool.h | 65 ++++++++++++--- shared/nm-ethtool-utils.c | 78 ++++++++++++++++++ shared/nm-ethtool-utils.h | 43 +++++++++- src/platform/nm-platform-utils.c | 81 ++++++++++++++----- .../plugins/ifcfg-rh/nms-ifcfg-rh-utils.c | 65 ++++++++++++--- 6 files changed, 322 insertions(+), 49 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 505c764b6e..c4b0414575 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -5871,19 +5871,58 @@ static const NMMetaPropertyInfo *const property_infos_DCB[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_ETHTOOL static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = { + PROPERTY_INFO_ETHTOOL (FEATURE_ESP_HW_OFFLOAD), + PROPERTY_INFO_ETHTOOL (FEATURE_ESP_TX_CSUM_HW_OFFLOAD), + PROPERTY_INFO_ETHTOOL (FEATURE_FCOE_MTU), PROPERTY_INFO_ETHTOOL (FEATURE_GRO), PROPERTY_INFO_ETHTOOL (FEATURE_GSO), + PROPERTY_INFO_ETHTOOL (FEATURE_HIGHDMA), + PROPERTY_INFO_ETHTOOL (FEATURE_HW_TC_OFFLOAD), + PROPERTY_INFO_ETHTOOL (FEATURE_L2_FWD_OFFLOAD), + PROPERTY_INFO_ETHTOOL (FEATURE_LOOPBACK), PROPERTY_INFO_ETHTOOL (FEATURE_LRO), PROPERTY_INFO_ETHTOOL (FEATURE_NTUPLE), PROPERTY_INFO_ETHTOOL (FEATURE_RX), PROPERTY_INFO_ETHTOOL (FEATURE_RXHASH), PROPERTY_INFO_ETHTOOL (FEATURE_RXVLAN), + PROPERTY_INFO_ETHTOOL (FEATURE_RX_ALL), + PROPERTY_INFO_ETHTOOL (FEATURE_RX_FCS), + PROPERTY_INFO_ETHTOOL (FEATURE_RX_GRO_HW), + PROPERTY_INFO_ETHTOOL (FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD), + PROPERTY_INFO_ETHTOOL (FEATURE_RX_VLAN_FILTER), + PROPERTY_INFO_ETHTOOL (FEATURE_RX_VLAN_STAG_FILTER), + PROPERTY_INFO_ETHTOOL (FEATURE_RX_VLAN_STAG_HW_PARSE), PROPERTY_INFO_ETHTOOL (FEATURE_SG), + PROPERTY_INFO_ETHTOOL (FEATURE_TLS_HW_RECORD), + PROPERTY_INFO_ETHTOOL (FEATURE_TLS_HW_TX_OFFLOAD), PROPERTY_INFO_ETHTOOL (FEATURE_TSO), PROPERTY_INFO_ETHTOOL (FEATURE_TX), PROPERTY_INFO_ETHTOOL (FEATURE_TXVLAN), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_FCOE_CRC), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_IPV4), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_IPV6), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_IP_GENERIC), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_SCTP), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_ESP_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_FCOE_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_GRE_CSUM_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_GRE_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_GSO_PARTIAL), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_GSO_ROBUST), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_IPXIP4_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_IPXIP6_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_NOCACHE_COPY), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_SCATTER_GATHER), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_SCATTER_GATHER_FRAGLIST), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_SCTP_SEGMENTATION), PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP6_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP_ECN_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP_MANGLEID_SEGMENTATION), PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_UDP_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_UDP_TNL_SEGMENTATION), + PROPERTY_INFO_ETHTOOL (FEATURE_TX_VLAN_STAG_HW_INSERT), NULL, }; diff --git a/libnm-core/nm-setting-ethtool.h b/libnm-core/nm-setting-ethtool.h index 10f5651b19..6a0458a516 100644 --- a/libnm-core/nm-setting-ethtool.h +++ b/libnm-core/nm-setting-ethtool.h @@ -31,19 +31,58 @@ G_BEGIN_DECLS /*****************************************************************************/ -#define NM_ETHTOOL_OPTNAME_FEATURE_GRO "feature-gro" -#define NM_ETHTOOL_OPTNAME_FEATURE_GSO "feature-gso" -#define NM_ETHTOOL_OPTNAME_FEATURE_LRO "feature-lro" -#define NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE "feature-ntuple" -#define NM_ETHTOOL_OPTNAME_FEATURE_RX "feature-rx" -#define NM_ETHTOOL_OPTNAME_FEATURE_RXHASH "feature-rxhash" -#define NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN "feature-rxvlan" -#define NM_ETHTOOL_OPTNAME_FEATURE_SG "feature-sg" -#define NM_ETHTOOL_OPTNAME_FEATURE_TSO "feature-tso" -#define NM_ETHTOOL_OPTNAME_FEATURE_TX "feature-tx" -#define NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN "feature-txvlan" -#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP6_SEGMENTATION "feature-tx-tcp6-segmentation" -#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_SEGMENTATION "feature-tx-tcp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_ESP_HW_OFFLOAD "feature-esp-hw-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_ESP_TX_CSUM_HW_OFFLOAD "feature-esp-tx-csum-hw-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_FCOE_MTU "feature-fcoe-mtu" +#define NM_ETHTOOL_OPTNAME_FEATURE_GRO "feature-gro" +#define NM_ETHTOOL_OPTNAME_FEATURE_GSO "feature-gso" +#define NM_ETHTOOL_OPTNAME_FEATURE_HIGHDMA "feature-highdma" +#define NM_ETHTOOL_OPTNAME_FEATURE_HW_TC_OFFLOAD "feature-hw-tc-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_L2_FWD_OFFLOAD "feature-l2-fwd-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_LOOPBACK "feature-loopback" +#define NM_ETHTOOL_OPTNAME_FEATURE_LRO "feature-lro" +#define NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE "feature-ntuple" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX "feature-rx" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXHASH "feature-rxhash" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN "feature-rxvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_ALL "feature-rx-all" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_FCS "feature-rx-fcs" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_GRO_HW "feature-rx-gro-hw" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD "feature-rx-udp_tunnel-port-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_FILTER "feature-rx-vlan-filter" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_FILTER "feature-rx-vlan-stag-filter" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_HW_PARSE "feature-rx-vlan-stag-hw-parse" +#define NM_ETHTOOL_OPTNAME_FEATURE_SG "feature-sg" +#define NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_RECORD "feature-tls-hw-record" +#define NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_TX_OFFLOAD "feature-tls-hw-tx-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_TSO "feature-tso" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX "feature-tx" +#define NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN "feature-txvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_FCOE_CRC "feature-tx-checksum-fcoe-crc" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV4 "feature-tx-checksum-ipv4" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV6 "feature-tx-checksum-ipv6" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IP_GENERIC "feature-tx-checksum-ip-generic" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_SCTP "feature-tx-checksum-sctp" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_ESP_SEGMENTATION "feature-tx-esp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_FCOE_SEGMENTATION "feature-tx-fcoe-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_CSUM_SEGMENTATION "feature-tx-gre-csum-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_SEGMENTATION "feature-tx-gre-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_PARTIAL "feature-tx-gso-partial" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_ROBUST "feature-tx-gso-robust" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP4_SEGMENTATION "feature-tx-ipxip4-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP6_SEGMENTATION "feature-tx-ipxip6-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_NOCACHE_COPY "feature-tx-nocache-copy" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER "feature-tx-scatter-gather" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER_FRAGLIST "feature-tx-scatter-gather-fraglist" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCTP_SEGMENTATION "feature-tx-sctp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP6_SEGMENTATION "feature-tx-tcp6-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_ECN_SEGMENTATION "feature-tx-tcp-ecn-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_MANGLEID_SEGMENTATION "feature-tx-tcp-mangleid-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_SEGMENTATION "feature-tx-tcp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_SEGMENTATION "feature-tx-udp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION "feature-tx-udp_tnl-csum-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_SEGMENTATION "feature-tx-udp_tnl-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_VLAN_STAG_HW_INSERT "feature-tx-vlan-stag-hw-insert" gboolean nm_ethtool_optname_is_feature (const char *optname); diff --git a/shared/nm-ethtool-utils.c b/shared/nm-ethtool-utils.c index a57228040c..d50695ae0e 100644 --- a/shared/nm-ethtool-utils.c +++ b/shared/nm-ethtool-utils.c @@ -35,36 +35,114 @@ const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = { /* indexed by NMEthtoolID */ + ETHT_DATA (FEATURE_ESP_HW_OFFLOAD), + ETHT_DATA (FEATURE_ESP_TX_CSUM_HW_OFFLOAD), + ETHT_DATA (FEATURE_FCOE_MTU), ETHT_DATA (FEATURE_GRO), ETHT_DATA (FEATURE_GSO), + ETHT_DATA (FEATURE_HIGHDMA), + ETHT_DATA (FEATURE_HW_TC_OFFLOAD), + ETHT_DATA (FEATURE_L2_FWD_OFFLOAD), + ETHT_DATA (FEATURE_LOOPBACK), ETHT_DATA (FEATURE_LRO), ETHT_DATA (FEATURE_NTUPLE), ETHT_DATA (FEATURE_RX), ETHT_DATA (FEATURE_RXHASH), ETHT_DATA (FEATURE_RXVLAN), + ETHT_DATA (FEATURE_RX_ALL), + ETHT_DATA (FEATURE_RX_FCS), + ETHT_DATA (FEATURE_RX_GRO_HW), + ETHT_DATA (FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD), + ETHT_DATA (FEATURE_RX_VLAN_FILTER), + ETHT_DATA (FEATURE_RX_VLAN_STAG_FILTER), + ETHT_DATA (FEATURE_RX_VLAN_STAG_HW_PARSE), ETHT_DATA (FEATURE_SG), + ETHT_DATA (FEATURE_TLS_HW_RECORD), + ETHT_DATA (FEATURE_TLS_HW_TX_OFFLOAD), ETHT_DATA (FEATURE_TSO), ETHT_DATA (FEATURE_TX), ETHT_DATA (FEATURE_TXVLAN), + ETHT_DATA (FEATURE_TX_CHECKSUM_FCOE_CRC), + ETHT_DATA (FEATURE_TX_CHECKSUM_IPV4), + ETHT_DATA (FEATURE_TX_CHECKSUM_IPV6), + ETHT_DATA (FEATURE_TX_CHECKSUM_IP_GENERIC), + ETHT_DATA (FEATURE_TX_CHECKSUM_SCTP), + ETHT_DATA (FEATURE_TX_ESP_SEGMENTATION), + ETHT_DATA (FEATURE_TX_FCOE_SEGMENTATION), + ETHT_DATA (FEATURE_TX_GRE_CSUM_SEGMENTATION), + ETHT_DATA (FEATURE_TX_GRE_SEGMENTATION), + ETHT_DATA (FEATURE_TX_GSO_PARTIAL), + ETHT_DATA (FEATURE_TX_GSO_ROBUST), + ETHT_DATA (FEATURE_TX_IPXIP4_SEGMENTATION), + ETHT_DATA (FEATURE_TX_IPXIP6_SEGMENTATION), + ETHT_DATA (FEATURE_TX_NOCACHE_COPY), + ETHT_DATA (FEATURE_TX_SCATTER_GATHER), + ETHT_DATA (FEATURE_TX_SCATTER_GATHER_FRAGLIST), + ETHT_DATA (FEATURE_TX_SCTP_SEGMENTATION), ETHT_DATA (FEATURE_TX_TCP6_SEGMENTATION), + ETHT_DATA (FEATURE_TX_TCP_ECN_SEGMENTATION), + ETHT_DATA (FEATURE_TX_TCP_MANGLEID_SEGMENTATION), ETHT_DATA (FEATURE_TX_TCP_SEGMENTATION), + ETHT_DATA (FEATURE_TX_UDP_SEGMENTATION), + ETHT_DATA (FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION), + ETHT_DATA (FEATURE_TX_UDP_TNL_SEGMENTATION), + ETHT_DATA (FEATURE_TX_VLAN_STAG_HW_INSERT), [_NM_ETHTOOL_ID_NUM] = NULL, }; const guint8 const _by_name[_NM_ETHTOOL_ID_NUM] = { /* sorted by optname. */ + NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_FCOE_MTU, NM_ETHTOOL_ID_FEATURE_GRO, NM_ETHTOOL_ID_FEATURE_GSO, + NM_ETHTOOL_ID_FEATURE_HIGHDMA, + NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_LOOPBACK, NM_ETHTOOL_ID_FEATURE_LRO, NM_ETHTOOL_ID_FEATURE_NTUPLE, NM_ETHTOOL_ID_FEATURE_RX, + NM_ETHTOOL_ID_FEATURE_RX_ALL, + NM_ETHTOOL_ID_FEATURE_RX_FCS, + NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, + NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, NM_ETHTOOL_ID_FEATURE_RXHASH, NM_ETHTOOL_ID_FEATURE_RXVLAN, NM_ETHTOOL_ID_FEATURE_SG, + NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, + NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, NM_ETHTOOL_ID_FEATURE_TSO, NM_ETHTOOL_ID_FEATURE_TX, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, + NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, + NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, + NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, + NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, + NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, + NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, NM_ETHTOOL_ID_FEATURE_TXVLAN, }; diff --git a/shared/nm-ethtool-utils.h b/shared/nm-ethtool-utils.h index 3846450803..5f22a9a06e 100644 --- a/shared/nm-ethtool-utils.h +++ b/shared/nm-ethtool-utils.h @@ -29,20 +29,59 @@ typedef enum { _NM_ETHTOOL_ID_FIRST = 0, _NM_ETHTOOL_ID_FEATURE_FIRST = _NM_ETHTOOL_ID_FIRST, - NM_ETHTOOL_ID_FEATURE_GRO = _NM_ETHTOOL_ID_FEATURE_FIRST, + NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD = _NM_ETHTOOL_ID_FEATURE_FIRST, + NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_FCOE_MTU, + NM_ETHTOOL_ID_FEATURE_GRO, NM_ETHTOOL_ID_FEATURE_GSO, + NM_ETHTOOL_ID_FEATURE_HIGHDMA, + NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_LOOPBACK, NM_ETHTOOL_ID_FEATURE_LRO, NM_ETHTOOL_ID_FEATURE_NTUPLE, NM_ETHTOOL_ID_FEATURE_RX, NM_ETHTOOL_ID_FEATURE_RXHASH, NM_ETHTOOL_ID_FEATURE_RXVLAN, + NM_ETHTOOL_ID_FEATURE_RX_ALL, + NM_ETHTOOL_ID_FEATURE_RX_FCS, + NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, + NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, NM_ETHTOOL_ID_FEATURE_SG, + NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, + NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, NM_ETHTOOL_ID_FEATURE_TSO, NM_ETHTOOL_ID_FEATURE_TX, NM_ETHTOOL_ID_FEATURE_TXVLAN, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, + NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, + NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, + NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, + NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, + NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, + NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, - _NM_ETHTOOL_ID_FEATURE_LAST = NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, + _NM_ETHTOOL_ID_FEATURE_LAST = NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, _NM_ETHTOOL_ID_FEATURE_NUM = (_NM_ETHTOOL_ID_FEATURE_LAST - _NM_ETHTOOL_ID_FEATURE_FIRST + 1), _NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_FEATURE_LAST, diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 24f8dfa8d3..9459fbc993 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -276,31 +276,70 @@ static const NMEthtoolFeatureInfo _ethtool_feature_infos[_NM_ETHTOOL_ID_FEATURE_ * ("feature-tx-tcp-segmentation"). */ /* names from ethtool utility, which are aliases for multiple features. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_SG, "tx-scatter-gather", - "tx-scatter-gather-fraglist"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TSO, "tx-tcp-segmentation", - "tx-tcp-ecn-segmentation", - "tx-tcp-mangleid-segmentation", - "tx-tcp6-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX, "tx-checksum-ipv4", - "tx-checksum-ip-generic", - "tx-checksum-ipv6", - "tx-checksum-fcoe-crc", - "tx-checksum-sctp"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_SG, "tx-scatter-gather", + "tx-scatter-gather-fraglist"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TSO, "tx-tcp-segmentation", + "tx-tcp-ecn-segmentation", + "tx-tcp-mangleid-segmentation", + "tx-tcp6-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX, "tx-checksum-ipv4", + "tx-checksum-ip-generic", + "tx-checksum-ipv6", + "tx-checksum-fcoe-crc", + "tx-checksum-sctp"), /* names from ethtool utility, which are aliases for one feature. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert"), /* names of features, as known by kernel. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_HIGHDMA, "highdma"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, "hw-tc-offload"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, "l2-fwd-offload"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_LOOPBACK, "loopback"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_ALL, "rx-all"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_FCS, "rx-fcs"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, "rx-gro-hw"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, "rx-udp_tunnel-port-offload"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, "rx-vlan-filter"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, "rx-vlan-stag-filter"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, "rx-vlan-stag-hw-parse"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, "tls-hw-record"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, "tls-hw-tx-offload"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, "tx-checksum-fcoe-crc"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, "tx-checksum-ipv4"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, "tx-checksum-ipv6"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, "tx-checksum-ip-generic"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, "tx-checksum-sctp"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, "tx-esp-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, "tx-fcoe-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, "tx-gre-csum-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, "tx-gre-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, "tx-gso-partial"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, "tx-gso-robust"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, "tx-ipxip4-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, "tx-ipxip6-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, "tx-nocache-copy"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, "tx-scatter-gather"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, "tx-scatter-gather-fraglist"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, "tx-sctp-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, "tx-tcp-ecn-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, "tx-tcp-mangleid-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, "tx-udp-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), + ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), }; /* the number of kernel features that we handle. It essentially is the sum of all diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index 12da58cf40..49096d262f 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -477,19 +477,58 @@ const char *const _nm_ethtool_ifcfg_names[] = { #define ETHT_NAME(eid, ename) \ [eid - _NM_ETHTOOL_ID_FEATURE_FIRST] = ""ename"" /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GRO, "gro"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GSO, "gso"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LRO, "lro"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX, "rx"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_SG, "sg"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TSO, "tso"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX, "tx"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GRO, "gro"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GSO, "gso"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_HIGHDMA, "highdma"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, "hw-tc-offload"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, "l2-fwd-offload"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LOOPBACK, "loopback"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LRO, "lro"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX, "rx"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_ALL, "rx-all"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_FCS, "rx-fcs"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, "rx-gro-hw"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, "rx-udp_tunnel-port-offload"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, "rx-vlan-filter"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, "rx-vlan-stag-filter"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, "rx-vlan-stag-hw-parse"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_SG, "sg"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, "tls-hw-record"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, "tls-hw-tx-offload"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TSO, "tso"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX, "tx"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, "tx-checksum-fcoe-crc"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, "tx-checksum-ipv4"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, "tx-checksum-ipv6"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, "tx-checksum-ip-generic"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, "tx-checksum-sctp"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, "tx-esp-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, "tx-fcoe-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, "tx-gre-csum-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, "tx-gre-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, "tx-gso-partial"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, "tx-gso-robust"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, "tx-ipxip4-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, "tx-ipxip6-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, "tx-nocache-copy"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, "tx-scatter-gather"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, "tx-scatter-gather-fraglist"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, "tx-sctp-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, "tx-tcp-ecn-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, "tx-tcp-mangleid-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, "tx-udp-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), + ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), }; const NMEthtoolData *