diff options
author | Dan Winship <danw@redhat.com> | 2015-01-12 09:54:12 -0500 |
---|---|---|
committer | Dan Winship <danw@redhat.com> | 2015-01-12 09:54:35 -0500 |
commit | 6d5e62a3877491299654de99809e156fd348c549 (patch) | |
tree | 7b8b40f65f576ec3c61b2cc5fa05aa2eec3c54fc | |
parent | 3b1c5ee0fde05f2d7d786d474591f4d23d64284a (diff) | |
parent | f79d62692ec4fe5ba21bbeab26286b2a3b250fdd (diff) |
dispatcher: merge branch 'danw/policy-based-routing-rh1160013'
25 files changed, 269 insertions, 141 deletions
diff --git a/callouts/nm-dispatcher-api.h b/callouts/nm-dispatcher-api.h index df1bced456..9b2c3b32cb 100644 --- a/callouts/nm-dispatcher-api.h +++ b/callouts/nm-dispatcher-api.h @@ -31,6 +31,7 @@ #define NM_DISPATCHER_DBUS_PATH "/org/freedesktop/nm_dispatcher" #define NMD_CONNECTION_PROPS_PATH "path" +#define NMD_CONNECTION_PROPS_FILENAME "filename" #define NMD_DEVICE_PROPS_INTERFACE "interface" #define NMD_DEVICE_PROPS_IP_INTERFACE "ip-interface" diff --git a/callouts/nm-dispatcher-utils.c b/callouts/nm-dispatcher-utils.c index 99616c1a12..e84b5669cd 100644 --- a/callouts/nm-dispatcher-utils.c +++ b/callouts/nm-dispatcher-utils.c @@ -334,6 +334,7 @@ nm_dispatcher_utils_construct_envp (const char *action, { const char *iface = NULL, *ip_iface = NULL; const char *uuid = NULL, *id = NULL, *path; + const char *filename = NULL; NMDeviceState dev_state = NM_DEVICE_STATE_UNKNOWN; GVariant *value; char **envp = NULL, *path_item; @@ -349,6 +350,10 @@ nm_dispatcher_utils_construct_envp (const char *action, if (!strcmp (action, "hostname")) goto done; + /* config filename */ + if (g_variant_lookup (connection_props, NMD_CONNECTION_PROPS_FILENAME, "&s", &filename)) + items = g_slist_prepend (items, g_strdup_printf ("CONNECTION_FILENAME=%s", filename)); + /* Canonicalize the VPN interface name; "" is used when passing it through * D-Bus so make sure that's fixed up here. */ diff --git a/callouts/tests/dispatcher-old-down b/callouts/tests/dispatcher-old-down index 836f353289..80980856c4 100644 --- a/callouts/tests/dispatcher-old-down +++ b/callouts/tests/dispatcher-old-down @@ -15,6 +15,7 @@ path=/org/freedesktop/NetworkManager/Devices/0 PATH= CONNECTION_UUID=3fd2a33a-d81b-423f-ae99-e6baba742311 CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/callouts/tests/dispatcher-old-down DEVICE_IFACE=wlan0 DEVICE_IP_IFACE=wlan0 diff --git a/callouts/tests/dispatcher-old-up b/callouts/tests/dispatcher-old-up index 53f35ace6c..e4eb8e6c7b 100644 --- a/callouts/tests/dispatcher-old-up +++ b/callouts/tests/dispatcher-old-up @@ -34,6 +34,7 @@ domains=hsd1.mn.comcast.net. PATH= CONNECTION_UUID=3fd2a33a-d81b-423f-ae99-e6baba742311 CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/callouts/tests/dispatcher-old-up DEVICE_IFACE=wlan0 DEVICE_IP_IFACE=wlan0 IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 diff --git a/callouts/tests/dispatcher-old-vpn-down b/callouts/tests/dispatcher-old-vpn-down index 1f1cf2b64d..e702445011 100644 --- a/callouts/tests/dispatcher-old-vpn-down +++ b/callouts/tests/dispatcher-old-vpn-down @@ -34,6 +34,7 @@ domains=hsd1.mn.comcast.net. PATH= CONNECTION_UUID=355653c0-34d3-4777-ad25-f9a498b7ef8e CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/callouts/tests/dispatcher-old-vpn-down DEVICE_IFACE=wlan0 DEVICE_IP_IFACE=tun0 IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 diff --git a/callouts/tests/dispatcher-old-vpn-up b/callouts/tests/dispatcher-old-vpn-up index 7cda8a69a2..619c6fec6b 100644 --- a/callouts/tests/dispatcher-old-vpn-up +++ b/callouts/tests/dispatcher-old-vpn-up @@ -34,6 +34,7 @@ domains=hsd1.mn.comcast.net. PATH= CONNECTION_UUID=355653c0-34d3-4777-ad25-f9a498b7ef8e CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/callouts/tests/dispatcher-old-vpn-up DEVICE_IFACE=wlan0 DEVICE_IP_IFACE=tun0 IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 diff --git a/callouts/tests/test-dispatcher-envp.c b/callouts/tests/test-dispatcher-envp.c index 460174b230..a715b62c26 100644 --- a/callouts/tests/test-dispatcher-envp.c +++ b/callouts/tests/test-dispatcher-envp.c @@ -34,6 +34,7 @@ static gboolean parse_main (GKeyFile *kf, + const char *filename, GVariant **out_con_dict, GVariant **out_con_props, char **out_expected_iface, @@ -82,6 +83,11 @@ parse_main (GKeyFile *kf, g_variant_builder_add (&props, "{sv}", "connection-path", g_variant_new_object_path ("/org/freedesktop/NetworkManager/Connections/5")); + /* Strip out the non-fixed portion of the filename */ + filename = strstr (filename, "/callouts"); + g_variant_builder_add (&props, "{sv}", + "filename", + g_variant_new_string (filename)); *out_con_props = g_variant_builder_end (&props); return TRUE; @@ -358,6 +364,7 @@ get_dispatcher_file (const char *file, return FALSE; if (!parse_main (kf, + file, out_con_dict, out_con_props, out_expected_iface, diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec index 241ab4a961..70884ffa0d 100644 --- a/contrib/fedora/rpm/NetworkManager.spec +++ b/contrib/fedora/rpm/NetworkManager.spec @@ -450,6 +450,12 @@ mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/conf.d # create a dnsmasq.d directory %{__mkdir_p} $RPM_BUILD_ROOT%{_sysconfdir}/NetworkManager/dnsmasq.d +# create dispatcher directories +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/dispatcher.d +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/dispatcher.d/pre-up.d +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/dispatcher.d/pre-down.d +%{__cp} examples/dispatcher/10-ifcfg-rh-routes.sh $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/dispatcher.d/pre-up.d + %{__mkdir_p} $RPM_BUILD_ROOT%{_datadir}/gnome-vpn-properties %{__mkdir_p} $RPM_BUILD_ROOT%{_localstatedir}/lib/NetworkManager @@ -509,6 +515,7 @@ fi %dir %{_sysconfdir}/%{name}/dispatcher.d %dir %{_sysconfdir}/%{name}/dispatcher.d/pre-down.d %dir %{_sysconfdir}/%{name}/dispatcher.d/pre-up.d +%{_sysconfdir}/%{name}/dispatcher.d/pre-up.d/10-ifcfg-rh-routes.sh %dir %{_sysconfdir}/%{name}/dnsmasq.d %dir %{_sysconfdir}/%{name}/VPN %config(noreplace) %{_sysconfdir}/%{name}/NetworkManager.conf diff --git a/examples/dispatcher/10-ifcfg-rh-routes.sh b/examples/dispatcher/10-ifcfg-rh-routes.sh new file mode 100755 index 0000000000..78f009ef67 --- /dev/null +++ b/examples/dispatcher/10-ifcfg-rh-routes.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# This ifcfg-rh-specific script runs +# /etc/sysconfig/network-scripts/ifup-routes when bringing up +# interfaces that have routing rules associated with them that can't +# be expressed by NMSettingIPConfig. (Eg, policy-based routing.) + +# This should be installed in dispatcher.d/pre-up.d/ + +dir=$(dirname "$CONNECTION_FILENAME") +if [ "$dir" != "/etc/sysconfig/network-scripts" ]; then + exit 0 +fi +profile=$(basename "$CONNECTION_FILENAME" | sed -ne 's/^ifcfg-//p') +if [ -z "$profile" ]; then + exit 0 +fi + +if [ -f "$dir/rule-$profile" -o -f "$dir/rule6-$profile" ]; then + /etc/sysconfig/network-scripts/ifup-routes "$DEVICE_IP_IFACE" "$profile" +fi diff --git a/examples/dispatcher/Makefile.am b/examples/dispatcher/Makefile.am index 0db71a0d4f..0089d5fe7b 100644 --- a/examples/dispatcher/Makefile.am +++ b/examples/dispatcher/Makefile.am @@ -1,3 +1,4 @@ EXTRA_DIST = \ + 10-ifcfg-rh-routes.sh \ 70-wifi-wired-exclusive.sh diff --git a/man/NetworkManager.xml b/man/NetworkManager.xml index d1a807fcd9..26f84e5e21 100644 --- a/man/NetworkManager.xml +++ b/man/NetworkManager.xml @@ -167,6 +167,12 @@ </para></listitem> </varlistentry> <varlistentry> + <term><varname>CONNECTION_FILENAME</varname></term> + <listitem><para> + The backing file name of the connection profile (if any). + </para></listitem> + </varlistentry> + <varlistentry> <term><varname>DEVICE_IFACE</varname></term> <listitem><para> The interface name of the device. diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index ae451768da..4e2002660c 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -37,6 +37,7 @@ #include "nm-dhcp6-config.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" +#include "nm-settings-connection.h" #define CALL_TIMEOUT (1000 * 60 * 10) /* 10 minutes for all scripts */ @@ -474,6 +475,7 @@ _dispatcher_call (DispatcherAction action, if (connection) { GVariant *connection_dict; + const char *filename; connection_dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); connection_hash = nm_utils_connection_dict_to_hash (connection_dict); @@ -483,6 +485,12 @@ _dispatcher_call (DispatcherAction action, value_hash_add_object_path (connection_props, NMD_CONNECTION_PROPS_PATH, nm_connection_get_path (connection)); + filename = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection)); + if (filename) { + value_hash_add_str (connection_props, + NMD_CONNECTION_PROPS_FILENAME, + filename); + } } else { connection_hash = value_hash_create (); connection_props = value_hash_create (); diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 44a45bb472..321cb12bf4 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -84,6 +84,7 @@ enum { PROP_UNSAVED, PROP_READY, PROP_FLAGS, + PROP_FILENAME, }; enum { @@ -130,6 +131,8 @@ typedef struct { gint32 autoconnect_retry_time; NMDeviceStateReason autoconnect_blocked_reason; + char *filename; + } NMSettingsConnectionPrivate; /**************************************************************/ @@ -524,17 +527,14 @@ ignore_cb (NMSettingsConnection *connection, * subsystems watching this connection. Before returning, 'callback' is run * with the given 'user_data' along with any errors encountered. */ -void -nm_settings_connection_replace_and_commit (NMSettingsConnection *self, - NMConnection *new_connection, - NMSettingsConnectionCommitFunc callback, - gpointer user_data) +static void +replace_and_commit (NMSettingsConnection *self, + NMConnection *new_connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) { GError *error = NULL; - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); - g_return_if_fail (NM_IS_CONNECTION (new_connection)); - if (nm_settings_connection_replace_settings (self, new_connection, TRUE, &error)) { nm_settings_connection_commit_changes (self, callback, user_data); } else { @@ -544,6 +544,18 @@ nm_settings_connection_replace_and_commit (NMSettingsConnection *self, } } +void +nm_settings_connection_replace_and_commit (NMSettingsConnection *self, + NMConnection *new_connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); + g_return_if_fail (NM_IS_CONNECTION (new_connection)); + + NM_SETTINGS_CONNECTION_GET_CLASS (self)->replace_and_commit (self, new_connection, callback, user_data); +} + static void commit_changes (NMSettingsConnection *self, NMSettingsConnectionCommitFunc callback, @@ -2188,6 +2200,45 @@ nm_settings_connection_set_ready (NMSettingsConnection *connection, } } +/** + * nm_settings_connection_set_filename: + * @connection: an #NMSettingsConnection + * @filename: @connection's filename + * + * Called by a backend to sets the filename that @connection is read + * from/written to. + */ +void +nm_settings_connection_set_filename (NMSettingsConnection *connection, + const char *filename) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + + if (g_strcmp0 (filename, priv->filename) != 0) { + g_free (priv->filename); + priv->filename = g_strdup (filename); + g_object_notify (G_OBJECT (connection), NM_SETTINGS_CONNECTION_FILENAME); + } +} + +/** + * nm_settings_connection_get_filename: + * @connection: an #NMSettingsConnection + * + * Gets the filename that @connection was read from/written to. This may be + * %NULL if @connection is unsaved, or if it is associated with a backend that + * does not store each connection in a separate file. + * + * Returns: @connection's filename. + */ +const char * +nm_settings_connection_get_filename (NMSettingsConnection *connection) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + + return priv->filename; +} + /**************************************************************/ static void @@ -2277,6 +2328,9 @@ get_property (GObject *object, guint prop_id, case PROP_FLAGS: g_value_set_uint (value, nm_settings_connection_get_flags (self)); break; + case PROP_FILENAME: + g_value_set_string (value, nm_settings_connection_get_filename (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2296,6 +2350,9 @@ set_property (GObject *object, guint prop_id, case PROP_FLAGS: nm_settings_connection_set_flags_all (self, g_value_get_uint (value)); break; + case PROP_FILENAME: + nm_settings_connection_set_filename (self, g_value_get_string (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2314,6 +2371,7 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) object_class->get_property = get_property; object_class->set_property = set_property; + class->replace_and_commit = replace_and_commit; class->commit_changes = commit_changes; class->delete = do_delete; class->supports_secrets = supports_secrets; @@ -2349,6 +2407,13 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_FILENAME, + g_param_spec_string (NM_SETTINGS_CONNECTION_FILENAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /* Signals */ /* Emitted when the connection is changed for any reason */ diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index cd41c1d5f6..b54fbbe7a8 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -46,10 +46,17 @@ G_BEGIN_DECLS #define NM_SETTINGS_CONNECTION_UPDATED_BY_USER "updated-by-user" /* Properties */ +<<<<<<< HEAD #define NM_SETTINGS_CONNECTION_VISIBLE "visible" #define NM_SETTINGS_CONNECTION_UNSAVED "unsaved" #define NM_SETTINGS_CONNECTION_READY "ready" #define NM_SETTINGS_CONNECTION_FLAGS "flags" +======= +#define NM_SETTINGS_CONNECTION_VISIBLE "visible" +#define NM_SETTINGS_CONNECTION_UNSAVED "unsaved" +#define NM_SETTINGS_CONNECTION_FLAGS "flags" +#define NM_SETTINGS_CONNECTION_FILENAME "filename" +>>>>>>> settings: add NMSettingsConnection:filename /** @@ -96,6 +103,11 @@ struct _NMSettingsConnectionClass { GObjectClass parent; /* virtual methods */ + void (*replace_and_commit) (NMSettingsConnection *connection, + NMConnection *new_connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data); + void (*commit_changes) (NMSettingsConnection *connection, NMSettingsConnectionCommitFunc callback, gpointer user_data); @@ -201,6 +213,10 @@ gboolean nm_settings_connection_get_ready (NMSettingsConnection *connection); void nm_settings_connection_set_ready (NMSettingsConnection *connection, gboolean ready); +void nm_settings_connection_set_filename (NMSettingsConnection *connection, + const char *filename); +const char *nm_settings_connection_get_filename (NMSettingsConnection *connection); + G_END_DECLS #endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h index d78f375250..7736d2632e 100644 --- a/src/settings/plugins/ifcfg-rh/common.h +++ b/src/settings/plugins/ifcfg-rh/common.h @@ -26,7 +26,9 @@ #define IFCFG_TAG "ifcfg-" #define KEYS_TAG "keys-" #define ROUTE_TAG "route-" +#define RULE_TAG "rule-" #define ROUTE6_TAG "route6-" +#define RULE6_TAG "rule6-" #define BAK_TAG ".bak" #define TILDE_TAG "~" diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index b044fe01c4..32ef72af79 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -51,7 +51,6 @@ G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SETTINGS_CONNECTI typedef struct { gulong ih_event_id; - char *path; int file_wd; char *keyfile; @@ -228,6 +227,7 @@ nm_ifcfg_connection_new (NMConnection *source, unrecognized_spec = unhandled_spec + strlen ("unrecognized:"); object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION, + NM_SETTINGS_CONNECTION_FILENAME, full_path, NM_IFCFG_CONNECTION_UNMANAGED_SPEC, unmanaged_spec, NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, unrecognized_spec, NULL); @@ -235,13 +235,9 @@ nm_ifcfg_connection_new (NMConnection *source, if (nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, update_unsaved, - error)) { - /* Set the path and start monitoring */ - if (full_path) { - nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (object), full_path); - nm_ifcfg_connection_check_devtimeout (NM_IFCFG_CONNECTION (object)); - } - } else + error)) + nm_ifcfg_connection_check_devtimeout (NM_IFCFG_CONNECTION (object)); + else g_clear_object (&object); g_object_unref (tmp); @@ -249,14 +245,6 @@ nm_ifcfg_connection_new (NMConnection *source, return (NMIfcfgConnection *) object; } -const char * -nm_ifcfg_connection_get_path (NMIfcfgConnection *self) -{ - g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL); - - return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->path; -} - static void path_watch_stop (NMIfcfgConnection *self) { @@ -297,17 +285,21 @@ path_watch_stop (NMIfcfgConnection *self) } } -void -nm_ifcfg_connection_set_path (NMIfcfgConnection *self, const char *ifcfg_path) +static void +filename_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) { + NMIfcfgConnection *self = NM_IFCFG_CONNECTION (object); NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); - - g_return_if_fail (ifcfg_path != NULL); + const char *ifcfg_path; path_watch_stop (self); - g_free (priv->path); - priv->path = g_strdup (ifcfg_path); + ifcfg_path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (self)); + if (!ifcfg_path) + return; + priv->keyfile = utils_get_keys_path (ifcfg_path); priv->routefile = utils_get_route_path (ifcfg_path); priv->route6file = utils_get_route6_path (ifcfg_path); @@ -340,6 +332,28 @@ nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self) } static void +replace_and_commit (NMSettingsConnection *connection, + NMConnection *new_connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + const char *filename; + GError *error = NULL; + + filename = nm_settings_connection_get_filename (connection); + if (filename && utils_has_complex_routes (filename)) { + if (callback) { + error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Cannot modify a connection that has an associated 'rule-' or 'rule6-' file"); + callback (connection, error, user_data); + g_clear_error (&error); + } + } + + NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->replace_and_commit (connection, new_connection, callback, user_data); +} + +static void commit_changes (NMSettingsConnection *connection, NMSettingsConnectionCommitFunc callback, gpointer user_data) @@ -349,13 +363,15 @@ commit_changes (NMSettingsConnection *connection, NMConnection *reread; gboolean same = FALSE, success = FALSE; char *ifcfg_path = NULL; + const char *filename; /* To ensure we don't rewrite files that are only changed from other * processes on-disk, read the existing connection back in and only rewrite * it if it's really changed. */ - if (priv->path) { - reread = connection_from_file (priv->path, NULL, NULL); + filename = nm_settings_connection_get_filename (connection); + if (filename) { + reread = connection_from_file (filename, NULL, NULL); if (reread) { same = nm_connection_compare (NM_CONNECTION (connection), reread, @@ -373,7 +389,7 @@ commit_changes (NMSettingsConnection *connection, success = writer_update_connection (NM_CONNECTION (connection), IFCFG_DIR, - priv->path, + filename, priv->keyfile, &error); } else { @@ -382,7 +398,7 @@ commit_changes (NMSettingsConnection *connection, &ifcfg_path, &error); if (success) { - nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (connection), ifcfg_path); + nm_settings_connection_set_filename (connection, ifcfg_path); g_free (ifcfg_path); } } @@ -403,14 +419,15 @@ do_delete (NMSettingsConnection *connection, gpointer user_data) { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); + const char *filename; - if (priv->path) { - g_unlink (priv->path); + filename = nm_settings_connection_get_filename (connection); + if (filename) { + g_unlink (filename); if (priv->keyfile) g_unlink (priv->keyfile); if (priv->routefile) g_unlink (priv->routefile); - if (priv->route6file) g_unlink (priv->route6file); } @@ -423,6 +440,8 @@ do_delete (NMSettingsConnection *connection, static void nm_ifcfg_connection_init (NMIfcfgConnection *connection) { + g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_FILENAME, + G_CALLBACK (filename_changed), NULL); } static void @@ -484,14 +503,6 @@ dispose (GObject *object) } static void -finalize (GObject *object) -{ - g_free (NM_IFCFG_CONNECTION_GET_PRIVATE (object)->path); - - G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object); -} - -static void nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifcfg_connection_class); @@ -503,8 +514,8 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; - object_class->finalize = finalize; settings_class->delete = do_delete; + settings_class->replace_and_commit = replace_and_commit; settings_class->commit_changes = commit_changes; /* Properties */ diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h index 58576d9d15..328e58f5f2 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -50,11 +50,6 @@ NMIfcfgConnection *nm_ifcfg_connection_new (NMConnection *source, const char *full_path, GError **error); -const char *nm_ifcfg_connection_get_path (NMIfcfgConnection *self); - -void nm_ifcfg_connection_set_path (NMIfcfgConnection *self, - const char *ifcfg_path); - const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self); const char *nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self); diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c index 60ffcc7f84..3594399fb7 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.c +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -107,7 +107,7 @@ connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data) SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data); const char *path; - path = nm_ifcfg_connection_get_path (connection); + path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection)); g_return_if_fail (path != NULL); connection_new_or_changed (plugin, path, connection, NULL); @@ -202,14 +202,14 @@ find_by_path (SCPluginIfcfg *self, const char *path) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); GHashTableIter iter; - NMIfcfgConnection *candidate = NULL; + NMSettingsConnection *candidate = NULL; g_return_val_if_fail (path != NULL, NULL); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { - if (g_strcmp0 (path, nm_ifcfg_connection_get_path (candidate)) == 0) - return candidate; + if (g_strcmp0 (path, nm_settings_connection_get_filename (candidate)) == 0) + return NM_IFCFG_CONNECTION (candidate); } return NULL; } @@ -252,11 +252,11 @@ connection_new_or_changed (SCPluginIfcfg *self, /* See if it's a rename */ existing = find_by_uuid_from_path (self, path); if (existing) { - const char *old_path = nm_ifcfg_connection_get_path (existing); + const char *old_path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (existing)); nm_log_info (LOGD_SETTINGS, "renaming %s -> %s", old_path, path); if (out_old_path) *out_old_path = g_strdup (old_path); - nm_ifcfg_connection_set_path (existing, path); + nm_settings_connection_set_filename (NM_SETTINGS_CONNECTION (existing), path); } } @@ -440,7 +440,7 @@ read_connections (SCPluginIfcfg *plugin) oldconns = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, &value)) { - const char *ifcfg_path = nm_ifcfg_connection_get_path (value); + const char *ifcfg_path = nm_settings_connection_get_filename (value); if (ifcfg_path) g_hash_table_insert (oldconns, g_strdup (ifcfg_path), value); } diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index e892394dcf..f2da5416c0 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -1071,14 +1071,10 @@ make_ip4_setting (shvarFile *ifcfg, /* Static routes - route-<name> file */ route_path = utils_get_route_path (ifcfg->fileName); - if (!route_path) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Could not get route file path for '%s'", ifcfg->fileName); - goto done; - } - /* First test new/legacy syntax */ - if (utils_has_route_file_new_syntax (route_path)) { + if (utils_has_complex_routes (route_path)) { + PARSE_WARNING ("'rule-' or 'rule6-' file is present; you will need to use a dispatcher script to apply these routes"); + } else if (utils_has_route_file_new_syntax (route_path)) { /* Parse route file in new syntax */ route_ifcfg = utils_get_route_ifcfg (ifcfg->fileName, FALSE); if (route_ifcfg) { @@ -1465,18 +1461,15 @@ make_ip6_setting (shvarFile *ifcfg, /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */ - /* Read static routes from route6-<interface> file */ - route6_path = utils_get_route6_path (ifcfg->fileName); - if (!route6_path) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Could not get route6 file path for '%s'", ifcfg->fileName); - goto error; - } + if (!utils_has_complex_routes (ifcfg->fileName)) { + /* Read static routes from route6-<interface> file */ + route6_path = utils_get_route6_path (ifcfg->fileName); + if (!read_route6_file (route6_path, s_ip6, error)) + goto error; - if (!read_route6_file (route6_path, s_ip6, error)) - goto error; + g_free (route6_path); + } - g_free (route6_path); return NM_SETTING (s_ip6); error: diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c index 4378c6ebd8..c57f2cfedf 100644 --- a/src/settings/plugins/ifcfg-rh/utils.c +++ b/src/settings/plugins/ifcfg-rh/utils.c @@ -361,6 +361,30 @@ gone: } gboolean +utils_has_complex_routes (const char *filename) +{ + char *rules; + + g_return_val_if_fail (filename != NULL, TRUE); + + rules = utils_get_extra_path (filename, RULE_TAG); + if (g_file_test (rules, G_FILE_TEST_EXISTS)) { + g_free (rules); + return TRUE; + } + g_free (rules); + + rules = utils_get_extra_path (filename, RULE6_TAG); + if (g_file_test (rules, G_FILE_TEST_EXISTS)) { + g_free (rules); + return TRUE; + } + g_free (rules); + + return FALSE; +} + +gboolean utils_ignore_ip_config (NMConnection *connection) { NMSettingConnection *s_con; diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h index 95af828bb1..27c5e46104 100644 --- a/src/settings/plugins/ifcfg-rh/utils.h +++ b/src/settings/plugins/ifcfg-rh/utils.h @@ -47,6 +47,7 @@ shvarFile *utils_get_route_ifcfg (const char *parent, gboolean should_create); shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create); gboolean utils_has_route_file_new_syntax (const char *filename); +gboolean utils_has_complex_routes (const char *filename); gboolean utils_ignore_ip_config (NMConnection *connection); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 300b0c1665..86b56cce47 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -2638,6 +2638,12 @@ writer_update_connection (NMConnection *connection, const char *keyfile, GError **error) { + if (utils_has_complex_routes (filename)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Cannot modify a connection that has an associated 'rule-' or 'rule6-' file"); + return FALSE; + } + return write_connection (connection, ifcfg_dir, filename, keyfile, NULL, error); } diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.c b/src/settings/plugins/keyfile/nm-keyfile-connection.c index c852f02806..9ff65a20aa 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.c +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.c @@ -36,19 +36,12 @@ G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SETTINGS_CONNECTION) -#define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate)) - -typedef struct { - char *path; -} NMKeyfileConnectionPrivate; - NMKeyfileConnection * nm_keyfile_connection_new (NMConnection *source, const char *full_path, GError **error) { GObject *object; - NMKeyfileConnectionPrivate *priv; NMConnection *tmp; const char *uuid; gboolean update_unsaved = TRUE; @@ -75,10 +68,9 @@ nm_keyfile_connection_new (NMConnection *source, update_unsaved = FALSE; } - object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, NULL); - - priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); - priv->path = g_strdup (full_path); + object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, + NM_SETTINGS_CONNECTION_FILENAME, full_path, + NULL); /* Update our settings with what was read from the file */ if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), @@ -93,38 +85,16 @@ nm_keyfile_connection_new (NMConnection *source, return (NMKeyfileConnection *) object; } -const char * -nm_keyfile_connection_get_path (NMKeyfileConnection *self) -{ - g_return_val_if_fail (NM_IS_KEYFILE_CONNECTION (self), NULL); - - return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->path; -} - -void -nm_keyfile_connection_set_path (NMKeyfileConnection *self, const char *path) -{ - NMKeyfileConnectionPrivate *priv; - - g_return_if_fail (NM_IS_KEYFILE_CONNECTION (self)); - g_return_if_fail (path != NULL); - - priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (self); - g_free (priv->path); - priv->path = g_strdup (path); -} - static void commit_changes (NMSettingsConnection *connection, NMSettingsConnectionCommitFunc callback, gpointer user_data) { - NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); char *path = NULL; GError *error = NULL; if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (connection), - priv->path, + nm_settings_connection_get_filename (connection), &path, &error)) { callback (connection, error, user_data); @@ -133,10 +103,8 @@ commit_changes (NMSettingsConnection *connection, } /* Update the filename if it changed */ - if (path) { - g_free (priv->path); - priv->path = path; - } + if (path) + nm_settings_connection_set_filename (connection, path); NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection, callback, @@ -148,10 +116,11 @@ do_delete (NMSettingsConnection *connection, NMSettingsConnectionDeleteFunc callback, gpointer user_data) { - NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); + const char *path; - if (priv->path) - g_unlink (priv->path); + path = nm_settings_connection_get_filename (connection); + if (path) + g_unlink (path); NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection, callback, @@ -166,23 +135,11 @@ nm_keyfile_connection_init (NMKeyfileConnection *connection) } static void -finalize (GObject *object) -{ - g_free (NM_KEYFILE_CONNECTION_GET_PRIVATE (object)->path); - - G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->finalize (object); -} - -static void nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class) { - GObjectClass *object_class = G_OBJECT_CLASS (keyfile_connection_class); NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (keyfile_connection_class); - g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate)); - /* Virtual methods */ - object_class->finalize = finalize; settings_class->commit_changes = commit_changes; settings_class->delete = do_delete; } diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.h b/src/settings/plugins/keyfile/nm-keyfile-connection.h index 135bb49f73..f6fa432b65 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.h +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.h @@ -47,9 +47,6 @@ NMKeyfileConnection *nm_keyfile_connection_new (NMConnection *source, const char *filename, GError **error); -const char *nm_keyfile_connection_get_path (NMKeyfileConnection *self); -void nm_keyfile_connection_set_path (NMKeyfileConnection *self, const char *path); - G_END_DECLS #endif /* __NETWORKMANAGER_KEYFILE_CONNECTION_H__ */ diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c index 371fa47a7d..ead074362e 100644 --- a/src/settings/plugins/keyfile/plugin.c +++ b/src/settings/plugins/keyfile/plugin.c @@ -87,7 +87,7 @@ remove_connection (SCPluginKeyfile *self, NMKeyfileConnection *connection) g_return_if_fail (connection != NULL); - nm_log_info (LOGD_SETTINGS, "removed %s.", nm_keyfile_connection_get_path (connection)); + nm_log_info (LOGD_SETTINGS, "removed %s.", nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection))); /* Removing from the hash table should drop the last reference */ g_object_ref (connection); @@ -139,14 +139,14 @@ find_by_path (SCPluginKeyfile *self, const char *path) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); GHashTableIter iter; - NMKeyfileConnection *candidate = NULL; + NMSettingsConnection *candidate = NULL; g_return_val_if_fail (path != NULL, NULL); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { - if (g_strcmp0 (path, nm_keyfile_connection_get_path (candidate)) == 0) - return candidate; + if (g_strcmp0 (path, nm_settings_connection_get_filename (candidate)) == 0) + return NM_KEYFILE_CONNECTION (candidate); } return NULL; } @@ -157,7 +157,8 @@ new_connection (SCPluginKeyfile *self, char **out_old_path) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); - NMKeyfileConnection *tmp, *connection; + NMKeyfileConnection *tmp; + NMSettingsConnection *connection; GError *error = NULL; const char *uuid; @@ -176,8 +177,8 @@ new_connection (SCPluginKeyfile *self, uuid = nm_connection_get_uuid (NM_CONNECTION (tmp)); connection = g_hash_table_lookup (priv->connections, uuid); if (connection) { - nm_log_info (LOGD_SETTINGS, "rename %s -> %s", nm_keyfile_connection_get_path (connection), name); - if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection), + nm_log_info (LOGD_SETTINGS, "rename %s -> %s", nm_settings_connection_get_filename (connection), name); + if (!nm_settings_connection_replace_settings (connection, NM_CONNECTION (tmp), FALSE, /* don't set Unsaved */ &error)) { @@ -186,8 +187,8 @@ new_connection (SCPluginKeyfile *self, } g_object_unref (tmp); if (out_old_path) - *out_old_path = g_strdup (nm_keyfile_connection_get_path (connection)); - nm_keyfile_connection_set_path (connection, name); + *out_old_path = g_strdup (nm_settings_connection_get_filename (connection)); + nm_settings_connection_set_filename (connection, name); } else { nm_log_info (LOGD_SETTINGS, "new connection %s", name); g_hash_table_insert (priv->connections, g_strdup (uuid), tmp); @@ -330,7 +331,7 @@ read_connections (NMSystemConfigInterface *config) oldconns = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, &data)) { - const char *con_path = nm_keyfile_connection_get_path (data); + const char *con_path = nm_settings_connection_get_filename (data); if (con_path) g_hash_table_insert (oldconns, g_strdup (con_path), data); } |