summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@redhat.com>2015-01-12 09:54:12 -0500
committerDan Winship <danw@redhat.com>2015-01-12 09:54:35 -0500
commit6d5e62a3877491299654de99809e156fd348c549 (patch)
tree7b8b40f65f576ec3c61b2cc5fa05aa2eec3c54fc
parent3b1c5ee0fde05f2d7d786d474591f4d23d64284a (diff)
parentf79d62692ec4fe5ba21bbeab26286b2a3b250fdd (diff)
dispatcher: merge branch 'danw/policy-based-routing-rh1160013'
-rw-r--r--callouts/nm-dispatcher-api.h1
-rw-r--r--callouts/nm-dispatcher-utils.c5
-rw-r--r--callouts/tests/dispatcher-old-down1
-rw-r--r--callouts/tests/dispatcher-old-up1
-rw-r--r--callouts/tests/dispatcher-old-vpn-down1
-rw-r--r--callouts/tests/dispatcher-old-vpn-up1
-rw-r--r--callouts/tests/test-dispatcher-envp.c7
-rw-r--r--contrib/fedora/rpm/NetworkManager.spec7
-rwxr-xr-xexamples/dispatcher/10-ifcfg-rh-routes.sh21
-rw-r--r--examples/dispatcher/Makefile.am1
-rw-r--r--man/NetworkManager.xml6
-rw-r--r--src/nm-dispatcher.c8
-rw-r--r--src/settings/nm-settings-connection.c81
-rw-r--r--src/settings/nm-settings-connection.h16
-rw-r--r--src/settings/plugins/ifcfg-rh/common.h2
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c87
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h5
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c14
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c27
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.c24
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.h1
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c6
-rw-r--r--src/settings/plugins/keyfile/nm-keyfile-connection.c63
-rw-r--r--src/settings/plugins/keyfile/nm-keyfile-connection.h3
-rw-r--r--src/settings/plugins/keyfile/plugin.c21
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);
}