# 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
%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
--- /dev/null
+#!/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
EXTRA_DIST = \
+ 10-ifcfg-rh-routes.sh \
70-wifi-wired-exclusive.sh
#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 "~"
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unrecognized_spec;
}
+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,
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 */
/* 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) {
/* 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:
return ret;
}
+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)
{
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);
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);
}