diff options
author | Dan Winship <danw@redhat.com> | 2014-12-17 08:50:05 -0500 |
---|---|---|
committer | Dan Winship <danw@redhat.com> | 2015-01-12 09:53:24 -0500 |
commit | f79d62692ec4fe5ba21bbeab26286b2a3b250fdd (patch) | |
tree | 7b8b40f65f576ec3c61b2cc5fa05aa2eec3c54fc | |
parent | 5a229741cc1e5c19341628445af80915155cd18e (diff) |
ifcfg-rh: allow handling complex routing rules via dispatcher (rh #1160013)
If a connection has an associated "rule-NAME" or "rule6-NAME" file,
don't try to read in the routes, since NetworkManager won't be able to
parse them correctly. Instead, log a warning that they will need to be
applied via a dispatcher script, and provide a script that would do
that in examples/dispatcher/.
-rw-r--r-- | contrib/fedora/rpm/NetworkManager.spec | 7 | ||||
-rwxr-xr-x | examples/dispatcher/10-ifcfg-rh-routes.sh | 21 | ||||
-rw-r--r-- | examples/dispatcher/Makefile.am | 1 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/common.h | 2 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c | 23 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/reader.c | 27 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/utils.c | 24 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/utils.h | 1 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/writer.c | 6 |
9 files changed, 95 insertions, 17 deletions
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/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 3281da945f..32ef72af79 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -332,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) @@ -493,6 +515,7 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) object_class->get_property = get_property; object_class->dispose = dispose; 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/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); } |