From 0186330a4bd5fed46cde5814c263db97ad717afb Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 12 Mar 2013 13:14:54 -0400 Subject: [PATCH] settings: use NMConfig directly rather than reparsing NetworkManager.conf Add some new API to NMConfig so that NMSettings and its plugins can use NMConfig to look up values rather than reparsing the config file themselves. Also, move the no-auto-default cache from NetworkManager.conf to $NMSTATEDIR/no-auto-default.state, so NM isn't rewriting its own config file at runtime. --- src/config/Makefile.am | 3 +- src/config/nm-config.c | 130 +++++++++++++++- src/config/nm-config.h | 7 + src/config/tests/Makefile.am | 8 + src/config/tests/NetworkManager.conf | 1 + src/config/tests/nm-test-device.c | 101 ++++++++++++ src/config/tests/nm-test-device.h | 52 +++++++ src/config/tests/test-config.c | 82 +++++++++- src/settings/nm-settings.c | 153 +++---------------- src/settings/plugins/ifnet/net_parser.c | 28 ---- src/settings/plugins/ifnet/net_parser.h | 1 - src/settings/plugins/ifnet/net_utils.c | 3 +- src/settings/plugins/ifnet/plugin.c | 28 ++-- src/settings/plugins/ifnet/plugin.h | 2 - src/settings/plugins/ifnet/tests/Makefile.am | 1 + src/settings/plugins/ifnet/tests/test_all.c | 18 ++- src/settings/plugins/ifupdown/plugin.c | 39 ++--- 17 files changed, 433 insertions(+), 224 deletions(-) create mode 100644 src/config/tests/nm-test-device.c create mode 100644 src/config/tests/nm-test-device.h diff --git a/src/config/Makefile.am b/src/config/Makefile.am index 20e0ae1336..3aa0a3b4f1 100644 --- a/src/config/Makefile.am +++ b/src/config/Makefile.am @@ -14,7 +14,8 @@ libnm_config_la_CPPFLAGS = \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/src/logging \ - -DNMCONFDIR=\"$(nmconfdir)\" + -DNMCONFDIR=\"$(nmconfdir)\" \ + -DNMSTATEDIR=\"$(nmstatedir)\" libnm_config_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ diff --git a/src/config/nm-config.c b/src/config/nm-config.c index 2bc4676f45..2ec1aebea9 100644 --- a/src/config/nm-config.c +++ b/src/config/nm-config.c @@ -25,14 +25,19 @@ #include "nm-config.h" #include "nm-logging.h" +#include "nm-utils.h" #include -#define NM_DEFAULT_SYSTEM_CONF_FILE NMCONFDIR "/NetworkManager.conf" -#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf" +#define NM_DEFAULT_SYSTEM_CONF_FILE NMCONFDIR "/NetworkManager.conf" +#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf" +#define NM_NO_AUTO_DEFAULT_STATE_FILE NMSTATEDIR "/no-auto-default.state" typedef struct { char *path; + char *no_auto_default_file; + GKeyFile *keyfile; + char **plugins; char *dhcp_client; char **dns_plugins; @@ -41,6 +46,7 @@ typedef struct { char *connectivity_uri; gint connectivity_interval; char *connectivity_response; + char **no_auto_default; } NMConfigPrivate; static NMConfig *singleton = NULL; @@ -126,9 +132,101 @@ nm_config_get_connectivity_response (NMConfig *config) return NM_CONFIG_GET_PRIVATE (config)->connectivity_response; } +char * +nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + + return g_key_file_get_string (priv->keyfile, group, key, error); +} + +/************************************************************************/ + +static void +merge_no_auto_default_state (NMConfig *config) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + GPtrArray *updated; + char **list; + int i, j; + char *data; + + /* If the config already matches everything, we don't need to do anything else. */ + if (priv->no_auto_default && !g_strcmp0 (priv->no_auto_default[0], "*")) + return; + + updated = g_ptr_array_new (); + if (priv->no_auto_default) { + for (i = 0; priv->no_auto_default[i]; i++) + g_ptr_array_add (updated, priv->no_auto_default[i]); + g_free (priv->no_auto_default); + } + + if (g_file_get_contents (priv->no_auto_default_file, &data, NULL, NULL)) { + list = g_strsplit (data, "\n", -1); + for (i = 0; list[i]; i++) { + if (!*list[i]) + continue; + for (j = 0; j < updated->len; j++) { + if (!strcmp (list[i], updated->pdata[j])) + break; + } + if (j == updated->len) + g_ptr_array_add (updated, list[i]); + } + g_free (list); + g_free (data); + } + + g_ptr_array_add (updated, NULL); + priv->no_auto_default = (char **) g_ptr_array_free (updated, FALSE); +} + +gboolean +nm_config_get_ethernet_can_auto_default (NMConfig *config, NMConfigDevice *device) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + + return !nm_config_device_spec_match_list (device, (const char **) priv->no_auto_default); +} + +void +nm_config_set_ethernet_no_auto_default (NMConfig *config, NMConfigDevice *device) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + char *current; + GString *updated; + GError *error = NULL; + + if (!nm_config_get_ethernet_can_auto_default (config, device)) + return; + + updated = g_string_new (NULL); + if (g_file_get_contents (priv->no_auto_default_file, ¤t, NULL, NULL)) { + g_string_append (updated, current); + g_free (current); + if (updated->str[updated->len - 1] != '\n') + g_string_append_c (updated, '\n'); + } + + g_string_append (updated, nm_config_device_get_hwaddr (device)); + g_string_append_c (updated, '\n'); + + if (!g_file_set_contents (priv->no_auto_default_file, updated->str, updated->len, &error)) { + nm_log_warn (LOGD_SETTINGS, "Could not update no-auto-default.state file: %s", + error->message); + g_error_free (error); + } + + g_string_free (updated, TRUE); + + merge_no_auto_default_state (config); +} + /************************************************************************/ static char *cli_config_path; +static char *cli_no_auto_default_file; static char *cli_plugins; static char *cli_log_level; static char *cli_log_domains; @@ -138,6 +236,7 @@ static char *cli_connectivity_response; static GOptionEntry config_options[] = { { "config", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_path, N_("Config file location"), N_("/path/to/config.file") }, + { "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli_no_auto_default_file, "no-auto-default.state location", NULL }, { "plugins", 0, 0, G_OPTION_ARG_STRING, &cli_plugins, N_("List of plugins separated by ','"), N_("plugin1,plugin2") }, { "log-level", 0, 0, G_OPTION_ARG_STRING, &cli_log_level, N_("Log level: one of [%s]"), "INFO" }, { "log-domains", 0, 0, G_OPTION_ARG_STRING, &cli_log_domains, @@ -216,10 +315,14 @@ read_config (NMConfig *config, const char *path, GError **error) if (!priv->connectivity_response) priv->connectivity_response = g_key_file_get_value (kf, "connectivity", "response", NULL); - success = TRUE; - } + if (!priv->no_auto_default) + priv->no_auto_default = g_key_file_get_string_list (kf, "main", "no-auto-default", NULL, NULL); + + priv->keyfile = kf; + success = TRUE; + } else + g_key_file_free (kf); - g_key_file_free (kf); return success; } @@ -268,8 +371,9 @@ nm_config_new (GError **error) if (!read_config (singleton, cli_config_path, error)) { g_object_unref (singleton); singleton = NULL; + return NULL; } - return singleton; + goto got_config; } /* Even though we prefer NetworkManager.conf, we need to check the @@ -281,7 +385,7 @@ nm_config_new (GError **error) /* Try deprecated nm-system-settings.conf first */ if (read_config (singleton, NM_OLD_SYSTEM_CONF_FILE, &local)) - return singleton; + goto got_config; if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND) == FALSE) { fprintf (stderr, "Default config file %s invalid: (%d) %s\n", @@ -293,7 +397,7 @@ nm_config_new (GError **error) /* Try the standard config file location next */ if (read_config (singleton, NM_DEFAULT_SYSTEM_CONF_FILE, &local)) - return singleton; + goto got_config; if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND) == FALSE) { fprintf (stderr, "Default config file %s invalid: (%d) %s\n", @@ -316,6 +420,15 @@ nm_config_new (GError **error) /* ignore error if config file not found */ g_clear_error (&local); + + got_config: + /* Handle no-auto-default state file */ + if (cli_no_auto_default_file) + priv->no_auto_default_file = g_strdup (cli_no_auto_default_file); + else + priv->no_auto_default_file = g_strdup (NM_NO_AUTO_DEFAULT_STATE_FILE); + merge_no_auto_default_state (singleton); + return singleton; } @@ -331,6 +444,7 @@ finalize (GObject *gobject) NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject); g_free (priv->path); + g_clear_pointer (&priv->keyfile, g_key_file_unref); g_strfreev (priv->plugins); g_free (priv->dhcp_client); g_strfreev (priv->dns_plugins); diff --git a/src/config/nm-config.h b/src/config/nm-config.h index dbdc2f0ae4..e18018d106 100644 --- a/src/config/nm-config.h +++ b/src/config/nm-config.h @@ -25,6 +25,8 @@ #include #include +#include "nm-config-device.h" + G_BEGIN_DECLS #define NM_TYPE_CONFIG (nm_config_get_type ()) @@ -56,6 +58,11 @@ const char *nm_config_get_connectivity_uri (NMConfig *config); const guint nm_config_get_connectivity_interval (NMConfig *config); const char *nm_config_get_connectivity_response (NMConfig *config); +gboolean nm_config_get_ethernet_can_auto_default (NMConfig *config, NMConfigDevice *device); +void nm_config_set_ethernet_no_auto_default (NMConfig *config, NMConfigDevice *device); + +char *nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error); + /* for main.c only */ GOptionEntry *nm_config_get_options (void); NMConfig *nm_config_new (GError **error); diff --git a/src/config/tests/Makefile.am b/src/config/tests/Makefile.am index cf91697ef3..c99c3848ef 100644 --- a/src/config/tests/Makefile.am +++ b/src/config/tests/Makefile.am @@ -1,11 +1,19 @@ if ENABLE_TESTS INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/src/config noinst_PROGRAMS = \ test-config +test_config_SOURCES = \ + nm-test-device.c \ + nm-test-device.h \ + test-config.c + test_config_CPPFLAGS = \ -DSRCDIR=\""$(srcdir)"\" \ $(GLIB_CFLAGS) diff --git a/src/config/tests/NetworkManager.conf b/src/config/tests/NetworkManager.conf index 3261e40631..401ba48a72 100644 --- a/src/config/tests/NetworkManager.conf +++ b/src/config/tests/NetworkManager.conf @@ -1,6 +1,7 @@ [main] dhcp=dhclient plugins=foo,bar,baz +no-auto-default=11:11:11:11:11:11 [logging] level=INFO diff --git a/src/config/tests/nm-test-device.c b/src/config/tests/nm-test-device.c new file mode 100644 index 0000000000..b671f2558e --- /dev/null +++ b/src/config/tests/nm-test-device.c @@ -0,0 +1,101 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-test-device.h" +#include "nm-config-device.h" +#include "nm-utils.h" + +static void nm_test_device_config_device_interface_init (NMConfigDeviceInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (NMTestDevice, nm_test_device, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (NM_TYPE_CONFIG_DEVICE, nm_test_device_config_device_interface_init)) + +static void +nm_test_device_init (NMTestDevice *self) +{ +} + +static void +finalize (GObject *object) +{ + NMTestDevice *self = NM_TEST_DEVICE (object); + + g_free (self->hwaddr); + g_free (self->hwaddr_bytes); + + G_OBJECT_CLASS (nm_test_device_parent_class)->finalize (object); +} + +static void +nm_test_device_class_init (NMTestDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = finalize; +} + +static gboolean +spec_match_list (NMConfigDevice *device, const GSList *specs) +{ + NMTestDevice *self = NM_TEST_DEVICE (device); + const GSList *iter; + const char *spec; + + for (iter = specs; iter; iter = iter->next) { + spec = iter->data; + if (g_str_has_prefix (spec, "mac:") && !strcmp (spec + 4, self->hwaddr)) + return TRUE; + } + return FALSE; +} + +static const guint8 * +get_hw_address (NMConfigDevice *device, guint *out_len) +{ + NMTestDevice *self = NM_TEST_DEVICE (device); + + if (out_len) + *out_len = ETH_ALEN; + return self->hwaddr_bytes; +} + +static void +nm_test_device_config_device_interface_init (NMConfigDeviceInterface *iface) +{ + iface->spec_match_list = spec_match_list; + iface->get_hw_address = get_hw_address; +} + +NMTestDevice * +nm_test_device_new (const char *hwaddr) +{ + NMTestDevice *self = g_object_new (NM_TYPE_TEST_DEVICE, NULL); + + self->hwaddr = g_strdup (hwaddr); + self->hwaddr_bytes = g_malloc (ETH_ALEN); + nm_utils_hwaddr_aton (hwaddr, ARPHRD_ETHER, self->hwaddr_bytes); + + return self; +} diff --git a/src/config/tests/nm-test-device.h b/src/config/tests/nm-test-device.h new file mode 100644 index 0000000000..ad63bf5fd2 --- /dev/null +++ b/src/config/tests/nm-test-device.h @@ -0,0 +1,52 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef NM_TEST_DEVICE_H +#define NM_TEST_DEVICE_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_TEST_DEVICE (nm_test_device_get_type ()) +#define NM_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEST_DEVICE, NMTestDevice)) +#define NM_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) +#define NM_IS_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_TEST_DEVICE)) +#define NM_IS_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_TEST_DEVICE)) +#define NM_TEST_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) + +typedef struct { + GObject parent; + + char *hwaddr; + guint8 *hwaddr_bytes; +} NMTestDevice; + +typedef struct { + GObjectClass parent; +} NMTestDeviceClass; + +GType nm_test_device_get_type (void); + +NMTestDevice *nm_test_device_new (const char *hwaddr); + +G_END_DECLS + +#endif /* NM_DEVICE_H */ diff --git a/src/config/tests/test-config.c b/src/config/tests/test-config.c index e2da79ffd6..f8df2709c9 100644 --- a/src/config/tests/test-config.c +++ b/src/config/tests/test-config.c @@ -18,9 +18,14 @@ * */ +#include "config.h" + +#include + #include #include +#include "nm-test-device.h" static void setup_config (const char *config_file, ...) @@ -58,6 +63,7 @@ test_config_simple (void) NMConfig *config; GError *error = NULL; const char **plugins; + char *value; setup_config (SRCDIR "/NetworkManager.conf", NULL); config = nm_config_new (&error); @@ -74,6 +80,18 @@ test_config_simple (void) g_assert_cmpstr (plugins[1], ==, "bar"); g_assert_cmpstr (plugins[2], ==, "baz"); + value = nm_config_get_value (config, "extra-section", "extra-key", NULL); + g_assert_cmpstr (value, ==, "some value"); + g_free (value); + + value = nm_config_get_value (config, "extra-section", "no-key", &error); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); + g_clear_error (&error); + + value = nm_config_get_value (config, "no-section", "no-key", &error); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_clear_error (&error); + g_object_unref (config); } @@ -106,7 +124,7 @@ test_config_override (void) GError *error = NULL; const char **plugins; - setup_config (SRCDIR "/NetworkManager.conf", + setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", "--plugins", "alpha,beta,gamma,delta", "--connectivity-interval", "12", NULL); @@ -128,6 +146,67 @@ test_config_override (void) g_object_unref (config); } +static void +test_config_no_auto_default (void) +{ + NMConfig *config; + GError *error = NULL; + int fd, nwrote; + char *state_file; + NMTestDevice *dev1, *dev2, *dev3, *dev4; + + fd = g_file_open_tmp (NULL, &state_file, &error); + g_assert_no_error (error); + + nwrote = write (fd, "22:22:22:22:22:22\n", 18); + g_assert_cmpint (nwrote, ==, 18); + nwrote = write (fd, "44:44:44:44:44:44\n", 18); + g_assert_cmpint (nwrote, ==, 18); + close (fd); + + setup_config (SRCDIR "/NetworkManager.conf", + "--no-auto-default", state_file, + NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + dev1 = nm_test_device_new ("11:11:11:11:11:11"); + dev2 = nm_test_device_new ("22:22:22:22:22:22"); + dev3 = nm_test_device_new ("33:33:33:33:33:33"); + dev4 = nm_test_device_new ("44:44:44:44:44:44"); + + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev1))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev2))); + g_assert (nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev4))); + + nm_config_set_ethernet_no_auto_default (config, NM_CONFIG_DEVICE (dev3)); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); + + g_object_unref (config); + + setup_config (SRCDIR "/NetworkManager.conf", + "--no-auto-default", state_file, + NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev1))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev2))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev4))); + + g_object_unref (config); + + g_object_unref (dev1); + g_object_unref (dev2); + g_object_unref (dev3); + g_object_unref (dev4); + + unlink (state_file); + g_free (state_file); +} + int main (int argc, char **argv) { @@ -137,6 +216,7 @@ main (int argc, char **argv) g_test_add_func ("/config/simple", test_config_simple); g_test_add_func ("/config/non-existent", test_config_non_existent); g_test_add_func ("/config/parse-error", test_config_parse_error); + g_test_add_func ("/config/no-auto-default", test_config_no_auto_default); /* This one has to come last, because it leaves its values in * nm-config.c's global variables, and there's no way to reset diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 1c3a05b1b8..5d01c8444f 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -71,8 +70,6 @@ #include "nm-connection-provider.h" #include "nm-config.h" -#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" - /* LINKER CRACKROCK */ #define EXPORT(sym) void * __export_##sym = &sym; @@ -1305,7 +1302,7 @@ impl_settings_save_hostname (NMSettings *self, } static gboolean -have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) +have_connection_for_device (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; @@ -1313,10 +1310,13 @@ have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) NMSettingConnection *s_con; NMSettingWired *s_wired; const GByteArray *setting_mac; + const guint8 *hwaddr; + guint hwaddr_len = 0; gboolean ret = FALSE; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - g_return_val_if_fail (mac != NULL, FALSE); + + hwaddr = nm_device_get_hw_address (device, &hwaddr_len); /* Find a wired connection locked to the given MAC address, if any */ g_hash_table_iter_init (&iter, priv->connections); @@ -1353,8 +1353,8 @@ have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { /* A connection mac-locked to this device */ - if (mac->len == setting_mac->len && - !memcmp (setting_mac->data, mac->data, mac->len)) { + if (hwaddr_len == setting_mac->len && + !memcmp (setting_mac->data, hwaddr, hwaddr_len)) { ret = TRUE; break; } @@ -1368,54 +1368,6 @@ have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) return ret; } -/* Search through the list of blacklisted MAC addresses in the config file. */ -static gboolean -is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac) -{ - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - const char *config_file; - GKeyFile *config; - char **list, **iter; - gboolean found = FALSE; - int hwaddr_type; - - g_return_val_if_fail (mac != NULL, FALSE); - - config_file = nm_config_get_path (priv->config); - if (!config_file) - return FALSE; - - config = g_key_file_new (); - g_key_file_set_list_separator (config, ','); - if (!g_key_file_load_from_file (config, config_file, G_KEY_FILE_NONE, NULL)) - goto out; - - hwaddr_type = nm_utils_hwaddr_type (mac->len); - - list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL); - for (iter = list; iter && *iter; iter++) { - guint8 *candidate, buffer[NM_UTILS_HWADDR_LEN_MAX]; - - if (strcmp (g_strstrip (*iter), "*") == 0) { - found = TRUE; - break; - } - - candidate = nm_utils_hwaddr_aton (*iter, hwaddr_type, buffer); - if (candidate && !memcmp (mac->data, candidate, mac->len)) { - found = TRUE; - break; - } - } - - if (list) - g_strfreev (list); - -out: - g_key_file_free (config); - return found; -} - #define DEFAULT_WIRED_TAG "default-wired" static void @@ -1425,29 +1377,10 @@ default_wired_deleted (NMDefaultWiredConnection *wired, NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMDevice *device; NMSettingConnection *s_con; - const guint8 *hw_addr_bytes; - char *hw_addr; - const char *config_file; - GKeyFile *config; - char **list, **iter, **updated; - gboolean found = FALSE; - gsize len = 0, i; - char *data; device = nm_default_wired_connection_get_device (wired); g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, NULL); - /* If there was no config file specified, there's nothing to do */ - config_file = nm_config_get_path (priv->config); - if (!config_file) - return; - - /* When the default wired connection is removed (either deleted or saved - * to a new persistent connection by a plugin), write the MAC address of - * the wired device to the config file and don't create a new default wired - * connection for that device again. - */ - s_con = nm_connection_get_setting_connection (NM_CONNECTION (wired)); g_assert (s_con); @@ -1457,51 +1390,12 @@ default_wired_deleted (NMDefaultWiredConnection *wired, if (nm_setting_connection_get_read_only (s_con)) return; - hw_addr_bytes = nm_device_get_hw_address (device, NULL); - hw_addr = nm_utils_hwaddr_ntoa (hw_addr_bytes, ARPHRD_ETHER); - - config = g_key_file_new (); - - g_key_file_set_list_separator (config, ','); - g_key_file_load_from_file (config, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL); - - list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL); - for (iter = list; iter && *iter; iter++) { - if ( strcmp (*iter, "*") == 0 - || strcmp (*iter, hw_addr) == 0) { - found = TRUE; - break; - } - } - - /* Add this device's MAC to the list */ - if (!found) { - /* New list; size + 1 for the new element, + 1 again for ending NULL */ - updated = g_malloc0 (sizeof (char*) * (len + 2)); - - /* Copy original list and add new MAC */ - for (i = 0; list && list[i]; i++) - updated[i] = list[i]; - updated[i++] = hw_addr; - updated[i] = NULL; - - g_key_file_set_string_list (config, - "main", CONFIG_KEY_NO_AUTO_DEFAULT, - (const char **) updated, - len + 2); - /* g_free() not g_strfreev() since 'updated' isn't a deep-copy */ - g_free (updated); - - data = g_key_file_to_data (config, &len, NULL); - if (data) { - g_file_set_contents (config_file, data, len, NULL); - g_free (data); - } - } - - g_free (hw_addr); - g_strfreev (list); - g_key_file_free (config); + /* When the default wired connection is removed (either deleted or saved + * to a new persistent connection by a plugin), write the MAC address of + * the wired device to the config file and don't create a new default wired + * connection for that device again. + */ + nm_config_set_ethernet_no_auto_default (priv->config, NM_CONFIG_DEVICE (device)); } static void @@ -1557,9 +1451,6 @@ void nm_settings_device_added (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GByteArray *mac = NULL; - const guint8 *hwaddr; - guint hwaddr_len = 0; NMDefaultWiredConnection *wired; gboolean read_only = TRUE; const char *id; @@ -1572,18 +1463,11 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) * ignore it. */ if ( !nm_device_get_managed (device) - || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG)) + || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG) + || have_connection_for_device (self, device) + || !nm_config_get_ethernet_can_auto_default (priv->config, NM_CONFIG_DEVICE (device))) return; - hwaddr = nm_device_get_hw_address (device, &hwaddr_len); - - mac = g_byte_array_sized_new (hwaddr_len); - g_byte_array_append (mac, hwaddr, hwaddr_len); - - if ( have_connection_for_device (self, mac, device) - || is_mac_auto_wired_blacklisted (self, mac)) - goto ignore; - if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) read_only = FALSE; @@ -1591,7 +1475,7 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) wired = nm_default_wired_connection_new (device, defname, read_only); g_free (defname); if (!wired) - goto ignore; + return; id = nm_connection_get_id (NM_CONNECTION (wired)); g_assert (id); @@ -1605,9 +1489,6 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) g_object_unref (wired); g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired); - -ignore: - g_byte_array_free (mac, TRUE); } void diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c index f37366afe4..97b4874392 100644 --- a/src/settings/plugins/ifnet/net_parser.c +++ b/src/settings/plugins/ifnet/net_parser.c @@ -223,34 +223,6 @@ destroy_connection_config (GHashTable * conn) g_hash_table_destroy (conn); } -/* Read settings from NetworkManager's config file */ -const char * -ifnet_get_global_setting (const char *group, const char *key) -{ - GError *error = NULL; - GKeyFile *keyfile = g_key_file_new (); - gchar *result = NULL; - const char *conf_file; - - /* Get confing file name from plugin. */ - conf_file = ifnet_plugin_get_conf_file (); - - if (!g_key_file_load_from_file (keyfile, - conf_file, - G_KEY_FILE_NONE, &error)) { - PLUGIN_WARN (IFNET_PLUGIN_NAME, - "loading system config file (%s) caused error: (%d) %s", - conf_file, - error ? error->code : -1, error - && error->message ? error->message : "(unknown)"); - } else { - result = g_key_file_get_string (keyfile, group, key, &error); - } - g_key_file_free (keyfile); - - return result; -} - static void strip_function (GIOChannel * channel, gchar * line) { diff --git a/src/settings/plugins/ifnet/net_parser.h b/src/settings/plugins/ifnet/net_parser.h index 47086c762b..005207adfe 100644 --- a/src/settings/plugins/ifnet/net_parser.h +++ b/src/settings/plugins/ifnet/net_parser.h @@ -34,7 +34,6 @@ void ifnet_destroy (void); GList *ifnet_get_connection_names (void); const char *ifnet_get_data (const char *conn_name, const char *key); const char *ifnet_get_global_data (const char *key); -const char *ifnet_get_global_setting (const char *group, const char *key); gboolean ifnet_has_network (const char *conn_name); /* Writer functions */ diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c index c2e3a376aa..ae2307f913 100644 --- a/src/settings/plugins/ifnet/net_utils.c +++ b/src/settings/plugins/ifnet/net_utils.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "net_utils.h" #include "wpa_parser.h" @@ -800,7 +801,7 @@ get_dhcp_hostname_and_client_id (char **hostname, char **client_id) *hostname = NULL; *client_id = NULL; - dhcp_client = ifnet_get_global_setting ("main", "dhcp"); + dhcp_client = nm_config_get_dhcp_client (nm_config_get ()); if (dhcp_client) { if (!strcmp (dhcp_client, "dhclient")) g_file_get_contents (dhclient_conf, &contents, NULL, diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c index d0c9ccc726..89e1d42e40 100644 --- a/src/settings/plugins/ifnet/plugin.c +++ b/src/settings/plugins/ifnet/plugin.c @@ -119,13 +119,18 @@ write_system_hostname (NMSystemConfigInterface * config, } static gboolean -is_managed_plugin () +is_managed_plugin (void) { - const char *result = NULL; + char *result = NULL; - result = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED); - if (result) - return is_true (result); + result = nm_config_get_value (nm_config_get (), + IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED, + NULL); + if (result) { + gboolean ret = is_true (result); + g_free (result); + return ret; + } return IFNET_MANAGE_WELL_KNOWN_DEFAULT; } @@ -272,9 +277,11 @@ reload_connections (gpointer config) old = g_hash_table_lookup (priv->config_connections, conn_name); if (old && new) { - const char *auto_refresh; + char *auto_refresh; - auto_refresh = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, "auto_refresh"); + auto_refresh = nm_config_get_value (nm_config_get (), + IFNET_KEY_FILE_GROUP, "auto_refresh", + NULL); if (auto_refresh && is_true (auto_refresh)) { if (!nm_connection_compare (NM_CONNECTION (old), NM_CONNECTION (new), @@ -296,6 +303,7 @@ reload_connections (gpointer config) commit_cb, NULL); g_object_unref (new); } + g_free (auto_refresh); g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); } else if (new) { g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new); @@ -568,12 +576,6 @@ sc_plugin_ifnet_class_init (SCPluginIfnetClass * req_class) NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); } -const char * -ifnet_plugin_get_conf_file (void) -{ - return nm_config_get_path (nm_config_get ()); -} - G_MODULE_EXPORT GObject * nm_system_config_factory (void) { diff --git a/src/settings/plugins/ifnet/plugin.h b/src/settings/plugins/ifnet/plugin.h index 27e71eead7..6ac0f482f1 100644 --- a/src/settings/plugins/ifnet/plugin.h +++ b/src/settings/plugins/ifnet/plugin.h @@ -43,7 +43,5 @@ struct _SCPluginIfnetClass { GObjectClass parent; }; -const char * ifnet_plugin_get_conf_file (void); - GType sc_plugin_ifnet_get_type (void); #endif diff --git a/src/settings/plugins/ifnet/tests/Makefile.am b/src/settings/plugins/ifnet/tests/Makefile.am index 19ee13c866..0bfb5b3dab 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.am +++ b/src/settings/plugins/ifnet/tests/Makefile.am @@ -8,6 +8,7 @@ INCLUDES=-I$(srcdir)/../ \ -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/include \ -I$(top_builddir)/include \ + -I$(top_srcdir)/src/config \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/src/wifi diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c index 4c31260105..3e36b0fa7c 100644 --- a/src/settings/plugins/ifnet/tests/test_all.c +++ b/src/settings/plugins/ifnet/tests/test_all.c @@ -33,16 +33,22 @@ #include "net_utils.h" #include "wpa_parser.h" #include "connection_parser.h" +#include "nm-config.h" -/* Fake config file function to make the linker happy */ -const char *ifnet_plugin_get_conf_file (void); - -const char * -ifnet_plugin_get_conf_file (void) +/* Fake NMConfig handling; the values it returns don't matter, so this + * is easier than forcing it to read our own config file, etc. + */ +NMConfig * +nm_config_get (void) { - return "/etc/foo/barasdfasdfasdfasdf"; + return NULL; } +const char * +nm_config_get_dhcp_client (NMConfig *config) +{ + return "dhclient"; +} static void test_getdata () diff --git a/src/settings/plugins/ifupdown/plugin.c b/src/settings/plugins/ifupdown/plugin.c index 321440b0f6..9efbd51b00 100644 --- a/src/settings/plugins/ifupdown/plugin.c +++ b/src/settings/plugins/ifupdown/plugin.c @@ -80,7 +80,6 @@ typedef struct { GHashTable *well_known_interfaces; GHashTable *well_known_ifaces; gboolean unmanage_well_known; - const char *conf_file; gulong inotify_event_id; int inotify_system_hostname_wd; @@ -311,7 +310,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) GHashTable *auto_ifaces; if_block *block = NULL; NMInotifyHelper *inotify_helper; - GKeyFile* keyfile; + char *value; GError *error = NULL; GList *keys, *iter; const char *subsys[2] = { "net", NULL }; @@ -443,36 +442,23 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) g_list_free (keys); g_hash_table_destroy (auto_ifaces); - /* Read the config file to find out whether to manage interfaces */ - keyfile = g_key_file_new (); - if (!g_key_file_load_from_file (keyfile, - priv->conf_file, - G_KEY_FILE_NONE, - &error)) { - nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: (%d) %s", - priv->conf_file, - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + /* Check the config file to find out whether to manage interfaces */ + value = nm_config_get_value (nm_config_get (), + IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED, + &error); + if (error) { + nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: %s", + nm_config_get_path (nm_config_get ()), + error->message); } else { gboolean manage_well_known; error = NULL; - manage_well_known = g_key_file_get_boolean (keyfile, - IFUPDOWN_KEY_FILE_GROUP, - IFUPDOWN_KEY_FILE_KEY_MANAGED, - &error); - if (error) { - nm_log_info (LOGD_SETTINGS, "getting keyfile key '%s' in group '%s' failed: (%d) %s", - IFUPDOWN_KEY_FILE_GROUP, - IFUPDOWN_KEY_FILE_KEY_MANAGED, - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - } else - priv->unmanage_well_known = !manage_well_known; + manage_well_known = !g_strcmp0 (value, "true") || !g_strcmp0 (value, "1"); + priv->unmanage_well_known = !manage_well_known; + g_free (value); } PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); - if (keyfile) - g_key_file_free (keyfile); /* Add well-known interfaces */ keys = g_udev_client_query_by_subsystem (priv->client, "net"); @@ -715,7 +701,6 @@ nm_system_config_factory (void) if (!singleton) { singleton = SC_PLUGIN_IFUPDOWN (g_object_new (SC_TYPE_PLUGIN_IFUPDOWN, NULL)); priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (singleton); - priv->conf_file = nm_config_get_path (nm_config_get ()); } else g_object_ref (singleton);