2008-05-11 20:20:52 +00:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
2007-11-21 06:24:15 +00:00
|
|
|
/* NetworkManager system settings service
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
2008-06-26 18:31:52 +00:00
|
|
|
* 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.
|
2007-11-21 06:24:15 +00:00
|
|
|
*
|
2015-02-20 12:40:36 +01:00
|
|
|
* Copyright 2008 - 2015 Red Hat, Inc.
|
2007-11-21 06:24:15 +00:00
|
|
|
*/
|
|
|
|
|
|
2014-11-13 10:07:02 -05:00
|
|
|
#include "config.h"
|
|
|
|
|
|
2007-11-21 06:24:15 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <arpa/inet.h>
|
2009-08-07 12:13:54 -05:00
|
|
|
#include <sys/wait.h>
|
2007-12-01 16:00:17 +00:00
|
|
|
#include <sys/inotify.h>
|
2008-03-08 00:12:42 +00:00
|
|
|
#include <errno.h>
|
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
#include <unistd.h>
|
2007-11-21 06:24:15 +00:00
|
|
|
|
|
|
|
|
#include <nm-connection.h>
|
2014-07-05 16:23:30 -04:00
|
|
|
#include <nm-dbus-interface.h>
|
2007-11-21 06:24:15 +00:00
|
|
|
#include <nm-setting-connection.h>
|
|
|
|
|
#include <nm-setting-ip4-config.h>
|
2011-12-12 22:20:56 -05:00
|
|
|
#include <nm-setting-vlan.h>
|
2010-01-05 19:05:01 -06:00
|
|
|
#include <nm-setting-ip6-config.h>
|
2007-11-21 06:24:15 +00:00
|
|
|
#include <nm-setting-wired.h>
|
2007-11-27 19:25:46 +00:00
|
|
|
#include <nm-setting-wireless.h>
|
2009-02-27 13:28:20 -05:00
|
|
|
#include <nm-setting-8021x.h>
|
2011-10-18 13:48:42 +02:00
|
|
|
#include <nm-setting-bond.h>
|
2013-07-25 15:36:47 +02:00
|
|
|
#include <nm-setting-team.h>
|
|
|
|
|
#include <nm-setting-team-port.h>
|
2012-05-23 16:19:27 +02:00
|
|
|
#include <nm-setting-bridge.h>
|
2012-05-23 16:19:28 +02:00
|
|
|
#include <nm-setting-bridge-port.h>
|
2013-09-26 16:21:37 -05:00
|
|
|
#include <nm-setting-dcb.h>
|
2013-10-29 10:45:36 -04:00
|
|
|
#include <nm-setting-generic.h>
|
2015-07-17 14:38:54 +02:00
|
|
|
#include "nm-default.h"
|
2014-07-27 20:35:17 +02:00
|
|
|
#include "nm-core-internal.h"
|
2007-11-27 19:25:46 +00:00
|
|
|
#include <nm-utils.h>
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2014-02-04 14:27:03 +01:00
|
|
|
#include "nm-platform.h"
|
2013-09-26 17:34:23 -04:00
|
|
|
#include "NetworkManagerUtils.h"
|
2012-02-29 23:11:04 -06:00
|
|
|
|
2008-05-11 20:20:52 +00:00
|
|
|
#include "common.h"
|
2007-11-21 06:24:15 +00:00
|
|
|
#include "shvar.h"
|
2009-03-26 16:57:55 -04:00
|
|
|
#include "utils.h"
|
2008-02-07 Dan Williams <dcbw@redhat.com>
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (add_one_secret_to_hash): copy secrets out of the plugin-returned hash
table of secrets
- (connection_settings_get_secrets): consolidate error returns into
one place; use the new get_secrets() plugin interface function to
get secrets from the plugin itself rather than using GObject data
magic
* system-settings/src/main.c
- (connection_added_cb, connection_removed_cb, free_plugin_connections,
load_connections): keep a private list of the plugin-returned
connections, don't use the plugin's GSList
* system-settings/plugins/ifcfg-fedora/plugin.c
- (watch_path): watch the path, not the filename (duh)
- (reload_all_connections): use the direct hash/equal functions; the
ones for int aren't appropriate here
- (get_secrets, system_config_interface_init): implement the
get_secrets() function
- (build_one_connection, find_connection_by_path): ifcfg file path is
now in the connection's ConnectionData instead of being a GObject
data property
- (handle_profile_item_changed): ifcfg file path is now in the
connection's ConnectionData instead of being a GObject data property;
be sure to copy secrets over from the new connection to the existing
connection when updating the connection's settings
- (init): sc_plugin_inotify_init() returns success/fail, not the inotify
file descriptor
* system-settings/plugins/ifcfg-fedora/parser.c
system-settings/plugins/ifcfg-fedora/parser.h
- (connection_data_get, copy_one_cdata_secret, clear_one_cdata_secret,
connection_data_copy_secrets, connection_data_free,
connection_data_add): new functions; connection data manipulation
- (make_wireless_security_setting): stuff secrets into the
connection data, not as GObject data items; make sure to close
the keys ifcfg file
- (wireless_connection_from_ifcfg, wired_connection_from_ifcfg): add
connection data to the connection
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3299 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-02-07 20:11:31 +00:00
|
|
|
|
2008-05-11 20:20:52 +00:00
|
|
|
#include "reader.h"
|
2009-02-28 07:08:19 -05:00
|
|
|
|
2014-04-05 09:37:04 -04:00
|
|
|
#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg)
|
2008-02-07 Dan Williams <dcbw@redhat.com>
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (add_one_secret_to_hash): copy secrets out of the plugin-returned hash
table of secrets
- (connection_settings_get_secrets): consolidate error returns into
one place; use the new get_secrets() plugin interface function to
get secrets from the plugin itself rather than using GObject data
magic
* system-settings/src/main.c
- (connection_added_cb, connection_removed_cb, free_plugin_connections,
load_connections): keep a private list of the plugin-returned
connections, don't use the plugin's GSList
* system-settings/plugins/ifcfg-fedora/plugin.c
- (watch_path): watch the path, not the filename (duh)
- (reload_all_connections): use the direct hash/equal functions; the
ones for int aren't appropriate here
- (get_secrets, system_config_interface_init): implement the
get_secrets() function
- (build_one_connection, find_connection_by_path): ifcfg file path is
now in the connection's ConnectionData instead of being a GObject
data property
- (handle_profile_item_changed): ifcfg file path is now in the
connection's ConnectionData instead of being a GObject data property;
be sure to copy secrets over from the new connection to the existing
connection when updating the connection's settings
- (init): sc_plugin_inotify_init() returns success/fail, not the inotify
file descriptor
* system-settings/plugins/ifcfg-fedora/parser.c
system-settings/plugins/ifcfg-fedora/parser.h
- (connection_data_get, copy_one_cdata_secret, clear_one_cdata_secret,
connection_data_copy_secrets, connection_data_free,
connection_data_add): new functions; connection data manipulation
- (make_wireless_security_setting): stuff secrets into the
connection data, not as GObject data items; make sure to close
the keys ifcfg file
- (wireless_connection_from_ifcfg, wired_connection_from_ifcfg): add
connection data to the connection
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3299 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-02-07 20:11:31 +00:00
|
|
|
|
2007-11-21 06:24:15 +00:00
|
|
|
static gboolean
|
|
|
|
|
get_int (const char *str, int *value)
|
|
|
|
|
{
|
|
|
|
|
char *e;
|
2012-05-23 16:19:27 +02:00
|
|
|
long int tmp;
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2009-03-27 11:34:49 -04:00
|
|
|
errno = 0;
|
2012-05-23 16:19:27 +02:00
|
|
|
tmp = strtol (str, &e, 0);
|
2013-09-26 16:21:37 -05:00
|
|
|
if (errno || *e != '\0' || tmp > G_MAXINT || tmp < G_MININT)
|
2007-11-21 06:24:15 +00:00
|
|
|
return FALSE;
|
2012-05-23 16:19:27 +02:00
|
|
|
*value = (int) tmp;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2012-05-23 16:19:27 +02:00
|
|
|
static gboolean
|
|
|
|
|
get_uint (const char *str, guint32 *value)
|
|
|
|
|
{
|
|
|
|
|
char *e;
|
|
|
|
|
long unsigned int tmp;
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
tmp = strtoul (str, &e, 0);
|
|
|
|
|
if (errno || *e != '\0')
|
|
|
|
|
return FALSE;
|
|
|
|
|
*value = (guint32) tmp;
|
2007-11-21 06:24:15 +00:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-10 14:16:01 +01:00
|
|
|
static char *
|
2011-11-17 18:05:35 -06:00
|
|
|
make_connection_name (shvarFile *ifcfg,
|
|
|
|
|
const char *ifcfg_name,
|
|
|
|
|
const char *suggested,
|
|
|
|
|
const char *prefix)
|
2011-11-10 14:16:01 +01:00
|
|
|
{
|
2011-11-17 18:05:35 -06:00
|
|
|
char *full_name = NULL, *name;
|
2011-11-10 14:16:01 +01:00
|
|
|
|
|
|
|
|
/* If the ifcfg file already has a NAME, always use that */
|
|
|
|
|
name = svGetValue (ifcfg, "NAME", FALSE);
|
|
|
|
|
if (name && strlen (name))
|
|
|
|
|
return name;
|
|
|
|
|
|
|
|
|
|
/* Otherwise construct a new NAME */
|
|
|
|
|
g_free (name);
|
|
|
|
|
if (!prefix)
|
2011-11-17 18:05:35 -06:00
|
|
|
prefix = _("System");
|
2011-11-10 14:16:01 +01:00
|
|
|
|
|
|
|
|
/* For cosmetic reasons, if the suggested name is the same as
|
|
|
|
|
* the ifcfg files name, don't use it. Mainly for wifi so that
|
|
|
|
|
* the SSID is shown in the connection ID instead of just "wlan0".
|
|
|
|
|
*/
|
2011-11-17 18:05:35 -06:00
|
|
|
if (suggested && strcmp (ifcfg_name, suggested))
|
|
|
|
|
full_name = g_strdup_printf ("%s %s (%s)", prefix, suggested, ifcfg_name);
|
|
|
|
|
else
|
|
|
|
|
full_name = g_strdup_printf ("%s %s", prefix, ifcfg_name);
|
2011-11-10 14:16:01 +01:00
|
|
|
|
|
|
|
|
return full_name;
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-04 18:59:13 +00:00
|
|
|
static NMSetting *
|
|
|
|
|
make_connection_setting (const char *file,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
const char *type,
|
2011-11-10 14:16:01 +01:00
|
|
|
const char *suggested,
|
|
|
|
|
const char *prefix)
|
2008-02-04 18:59:13 +00:00
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
2015-10-08 18:26:45 +02:00
|
|
|
NMSettingConnectionLldp lldp;
|
2009-12-30 16:30:41 -06:00
|
|
|
const char *ifcfg_name = NULL;
|
2011-11-10 14:16:01 +01:00
|
|
|
char *new_id, *uuid = NULL, *zone = NULL, *value;
|
2008-02-04 18:59:13 +00:00
|
|
|
|
2009-12-30 16:30:41 -06:00
|
|
|
ifcfg_name = utils_get_ifcfg_name (file, TRUE);
|
2008-02-04 18:59:13 +00:00
|
|
|
if (!ifcfg_name)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2011-11-10 14:16:01 +01:00
|
|
|
new_id = make_connection_name (ifcfg, ifcfg_name, suggested, prefix);
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL);
|
2008-10-26 17:41:37 +00:00
|
|
|
g_free (new_id);
|
2008-01-18 16:52:09 +00:00
|
|
|
|
2009-02-27 13:28:20 -05:00
|
|
|
/* Try for a UUID key before falling back to hashing the file name */
|
2009-03-01 19:04:55 -05:00
|
|
|
uuid = svGetValue (ifcfg, "UUID", FALSE);
|
2009-02-27 13:28:20 -05:00
|
|
|
if (!uuid || !strlen (uuid)) {
|
|
|
|
|
g_free (uuid);
|
2014-11-27 18:40:18 +01:00
|
|
|
uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL);
|
2009-02-27 13:28:20 -05:00
|
|
|
}
|
2011-10-07 15:58:06 +02:00
|
|
|
|
2008-10-26 17:41:37 +00:00
|
|
|
g_object_set (s_con,
|
|
|
|
|
NM_SETTING_CONNECTION_TYPE, type,
|
|
|
|
|
NM_SETTING_CONNECTION_UUID, uuid,
|
|
|
|
|
NULL);
|
|
|
|
|
g_free (uuid);
|
2008-08-27 02:57:21 +00:00
|
|
|
|
2013-03-07 09:45:07 -05:00
|
|
|
value = svGetValue (ifcfg, "DEVICE", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
if (nm_utils_iface_valid_name (value)) {
|
|
|
|
|
g_object_set (s_con,
|
|
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME, value,
|
|
|
|
|
NULL);
|
|
|
|
|
} else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid DEVICE name '%s'", value);
|
2013-03-07 09:45:07 -05:00
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-08 18:26:45 +02:00
|
|
|
value = svGetValue (ifcfg, "LLDP", FALSE);
|
|
|
|
|
if (!g_strcmp0 (value, "rx"))
|
|
|
|
|
lldp = NM_SETTING_CONNECTION_LLDP_ENABLE_RX;
|
|
|
|
|
else
|
|
|
|
|
lldp = svParseBoolean (value, NM_SETTING_CONNECTION_LLDP_DEFAULT);
|
2015-10-21 13:49:27 +02:00
|
|
|
g_free (value);
|
2015-10-08 18:26:45 +02:00
|
|
|
|
2009-03-10 10:25:53 -04:00
|
|
|
/* Missing ONBOOT is treated as "ONBOOT=true" by the old network service */
|
2014-10-06 16:04:00 +02:00
|
|
|
g_object_set (s_con,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT,
|
2015-10-08 18:04:30 +02:00
|
|
|
svGetValueBoolean (ifcfg, "ONBOOT", TRUE),
|
2014-10-06 16:04:00 +02:00
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY,
|
|
|
|
|
(gint) svGetValueInt64 (ifcfg, "AUTOCONNECT_PRIORITY", 10,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT),
|
2015-05-06 10:59:11 +02:00
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES,
|
2015-10-08 18:04:30 +02:00
|
|
|
svGetValueBoolean (ifcfg, "AUTOCONNECT_SLAVES", NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT),
|
2015-10-08 18:26:45 +02:00
|
|
|
NM_SETTING_CONNECTION_LLDP, lldp,
|
2009-03-01 19:04:55 -05:00
|
|
|
NULL);
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2011-02-07 18:58:19 -06:00
|
|
|
value = svGetValue (ifcfg, "USERS", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
char **items, **iter;
|
|
|
|
|
|
|
|
|
|
items = g_strsplit_set (value, " ", -1);
|
|
|
|
|
for (iter = items; iter && *iter; iter++) {
|
|
|
|
|
if (strlen (*iter)) {
|
|
|
|
|
if (!nm_setting_connection_add_permission (s_con, "user", *iter, NULL))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid USERS item '%s'", *iter);
|
2011-02-07 18:58:19 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
2011-04-14 16:56:20 +02:00
|
|
|
g_strfreev (items);
|
2011-02-07 18:58:19 -06:00
|
|
|
}
|
|
|
|
|
|
2011-10-07 15:58:06 +02:00
|
|
|
|
|
|
|
|
zone = svGetValue(ifcfg, "ZONE", FALSE);
|
|
|
|
|
if (!zone || !strlen (zone)) {
|
|
|
|
|
g_free (zone);
|
|
|
|
|
zone = NULL;
|
|
|
|
|
}
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_ZONE, zone, NULL);
|
|
|
|
|
g_free (zone);
|
|
|
|
|
|
2012-08-22 10:17:15 +02:00
|
|
|
value = svGetValue (ifcfg, "SECONDARY_UUIDS", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
char **items, **iter;
|
|
|
|
|
|
|
|
|
|
items = g_strsplit_set (value, " \t", -1);
|
|
|
|
|
for (iter = items; iter && *iter; iter++) {
|
|
|
|
|
if (strlen (*iter)) {
|
|
|
|
|
if (!nm_setting_connection_add_secondary (s_con, *iter))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("secondary connection UUID '%s' already added", *iter);
|
2012-08-22 10:17:15 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
g_strfreev (items);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-23 16:19:28 +02:00
|
|
|
value = svGetValue (ifcfg, "BRIDGE", FALSE);
|
|
|
|
|
if (value) {
|
2014-04-15 19:32:48 +02:00
|
|
|
const char *old_value;
|
2012-05-23 16:19:28 +02:00
|
|
|
|
2014-04-15 19:32:48 +02:00
|
|
|
if ((old_value = nm_setting_connection_get_master (s_con))) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("Already configured as slave of %s. Ignoring BRIDGE=\"%s\"",
|
2014-04-15 19:32:48 +02:00
|
|
|
old_value, value);
|
|
|
|
|
} else {
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, value, NULL);
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE,
|
|
|
|
|
NM_SETTING_BRIDGE_SETTING_NAME, NULL);
|
2012-05-23 16:19:28 +02:00
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-12 22:32:06 -05:00
|
|
|
value = svGetValue (ifcfg, "GATEWAY_PING_TIMEOUT", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
long int tmp;
|
|
|
|
|
guint32 timeout;
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
tmp = strtol (value, NULL, 10);
|
|
|
|
|
if (errno == 0 && tmp >= 0 && tmp < G_MAXINT32) {
|
|
|
|
|
timeout = (guint32) tmp;
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, timeout, NULL);
|
|
|
|
|
} else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid GATEWAY_PING_TIMEOUT time");
|
2013-07-12 22:32:06 -05:00
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
switch (svGetValueBoolean (ifcfg, "CONNECTION_METERED", -1)) {
|
2015-05-29 17:41:21 +02:00
|
|
|
case TRUE:
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_METERED, NM_METERED_YES, NULL);
|
|
|
|
|
break;
|
|
|
|
|
case FALSE:
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_METERED, NM_METERED_NO, NULL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-26 17:41:37 +00:00
|
|
|
return NM_SETTING (s_con);
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
/* Returns TRUE on missing address or valid address */
|
2009-03-27 09:47:44 -04:00
|
|
|
static gboolean
|
|
|
|
|
read_ip4_address (shvarFile *ifcfg,
|
2008-03-19 03:08:32 +00:00
|
|
|
const char *tag,
|
2014-09-16 16:42:46 -04:00
|
|
|
char **out_addr,
|
2008-03-19 03:08:32 +00:00
|
|
|
GError **error)
|
2007-11-21 06:24:15 +00:00
|
|
|
{
|
2008-03-19 03:08:32 +00:00
|
|
|
char *value = NULL;
|
2009-03-27 09:47:44 -04:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (tag != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (out_addr != NULL, FALSE);
|
2014-12-31 00:08:12 +01:00
|
|
|
g_return_val_if_fail (!error || !*error, FALSE);
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
*out_addr = NULL;
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, tag, FALSE);
|
2008-03-19 03:08:32 +00:00
|
|
|
if (!value)
|
2009-03-27 09:47:44 -04:00
|
|
|
return TRUE;
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
if (nm_utils_ipaddr_valid (AF_INET, value)) {
|
|
|
|
|
*out_addr = value;
|
|
|
|
|
return TRUE;
|
2009-03-27 09:47:44 -04:00
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2008-03-19 03:08:32 +00:00
|
|
|
"Invalid %s IP4 address '%s'", tag, value);
|
2014-09-16 16:42:46 -04:00
|
|
|
g_free (value);
|
2013-07-26 14:25:05 -05:00
|
|
|
return FALSE;
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-22 08:57:07 -04:00
|
|
|
static char *
|
|
|
|
|
get_numbered_tag (char *tag_name, int which)
|
2013-08-22 14:17:46 +02:00
|
|
|
{
|
|
|
|
|
if (which == -1)
|
|
|
|
|
return g_strdup (tag_name);
|
|
|
|
|
return g_strdup_printf ("%s%u", tag_name, which);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2014-12-16 10:10:22 +01:00
|
|
|
is_any_ip4_address_defined (shvarFile *ifcfg, int *idx)
|
2013-08-22 14:17:46 +02:00
|
|
|
{
|
2014-12-16 10:10:22 +01:00
|
|
|
int i, ignore, *ret_idx;;
|
|
|
|
|
|
|
|
|
|
ret_idx = idx ? idx : &ignore;
|
2013-08-22 14:17:46 +02:00
|
|
|
|
|
|
|
|
for (i = -1; i <= 2; i++) {
|
2013-08-22 08:57:07 -04:00
|
|
|
char *tag;
|
2013-08-22 14:17:46 +02:00
|
|
|
char *value;
|
|
|
|
|
|
|
|
|
|
tag = get_numbered_tag ("IPADDR", i);
|
|
|
|
|
value = svGetValue (ifcfg, tag, FALSE);
|
|
|
|
|
g_free (tag);
|
|
|
|
|
if (value) {
|
|
|
|
|
g_free (value);
|
2014-12-16 10:10:22 +01:00
|
|
|
*ret_idx = i;
|
2013-08-22 14:17:46 +02:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tag = get_numbered_tag ("PREFIX", i);
|
|
|
|
|
value = svGetValue (ifcfg, tag, FALSE);
|
|
|
|
|
g_free(tag);
|
|
|
|
|
if (value) {
|
|
|
|
|
g_free (value);
|
2014-12-16 10:10:22 +01:00
|
|
|
*ret_idx = i;
|
2013-08-22 14:17:46 +02:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tag = get_numbered_tag ("NETMASK", i);
|
|
|
|
|
value = svGetValue (ifcfg, tag, FALSE);
|
|
|
|
|
g_free(tag);
|
|
|
|
|
if (value) {
|
|
|
|
|
g_free (value);
|
2014-12-16 10:10:22 +01:00
|
|
|
*ret_idx = i;
|
2013-08-22 14:17:46 +02:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
/* Returns TRUE on missing address or valid address */
|
|
|
|
|
static gboolean
|
2009-03-27 09:47:44 -04:00
|
|
|
read_full_ip4_address (shvarFile *ifcfg,
|
2011-04-14 10:30:51 +02:00
|
|
|
gint32 which,
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPAddress *base_addr,
|
|
|
|
|
NMIPAddress **out_address,
|
2014-10-20 21:30:56 -04:00
|
|
|
char **out_gateway,
|
2009-03-27 09:47:44 -04:00
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
char *ip_tag, *prefix_tag, *netmask_tag, *gw_tag;
|
2014-10-20 21:30:56 -04:00
|
|
|
char *ip = NULL;
|
2014-09-16 16:42:46 -04:00
|
|
|
long prefix = 0;
|
2009-03-27 09:47:44 -04:00
|
|
|
gboolean success = FALSE;
|
|
|
|
|
char *value;
|
2014-09-16 16:42:46 -04:00
|
|
|
guint32 tmp;
|
2009-03-27 09:47:44 -04:00
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
g_return_val_if_fail (which >= -1, FALSE);
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, FALSE);
|
2014-09-16 16:42:46 -04:00
|
|
|
g_return_val_if_fail (out_address != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (*out_address == NULL, FALSE);
|
2014-12-31 00:08:12 +01:00
|
|
|
g_return_val_if_fail (!error || !*error, FALSE);
|
2009-03-27 09:47:44 -04:00
|
|
|
|
2013-08-22 14:17:46 +02:00
|
|
|
ip_tag = get_numbered_tag ("IPADDR", which);
|
|
|
|
|
prefix_tag = get_numbered_tag ("PREFIX", which);
|
|
|
|
|
netmask_tag = get_numbered_tag ("NETMASK", which);
|
|
|
|
|
gw_tag = get_numbered_tag ("GATEWAY", which);
|
2009-03-27 09:47:44 -04:00
|
|
|
|
|
|
|
|
/* IP address */
|
2014-09-16 16:42:46 -04:00
|
|
|
if (!read_ip4_address (ifcfg, ip_tag, &ip, error))
|
2013-07-26 14:25:05 -05:00
|
|
|
goto done;
|
2014-09-16 16:42:46 -04:00
|
|
|
if (!ip) {
|
|
|
|
|
if (base_addr)
|
|
|
|
|
ip = g_strdup (nm_ip_address_get_address (base_addr));
|
|
|
|
|
else {
|
|
|
|
|
success = TRUE;
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
2008-04-07 22:57:29 +00:00
|
|
|
}
|
2009-03-27 09:47:44 -04:00
|
|
|
|
|
|
|
|
/* Gateway */
|
2014-10-20 21:30:56 -04:00
|
|
|
if (out_gateway && !*out_gateway) {
|
|
|
|
|
if (!read_ip4_address (ifcfg, gw_tag, out_gateway, error))
|
|
|
|
|
goto done;
|
2009-03-27 09:47:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Prefix */
|
|
|
|
|
value = svGetValue (ifcfg, prefix_tag, FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
errno = 0;
|
|
|
|
|
prefix = strtol (value, NULL, 10);
|
2014-09-16 16:42:46 -04:00
|
|
|
if (errno || prefix < 0) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-27 09:47:44 -04:00
|
|
|
"Invalid IP4 prefix '%s'", value);
|
|
|
|
|
g_free (value);
|
2013-07-26 14:25:05 -05:00
|
|
|
goto done;
|
2009-03-27 09:47:44 -04:00
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fall back to NETMASK if no PREFIX was specified */
|
2014-09-16 16:42:46 -04:00
|
|
|
if (prefix == 0) {
|
|
|
|
|
if (!read_ip4_address (ifcfg, netmask_tag, &value, error))
|
2013-07-26 14:25:05 -05:00
|
|
|
goto done;
|
2014-09-16 16:42:46 -04:00
|
|
|
if (value) {
|
|
|
|
|
inet_pton (AF_INET, value, &tmp);
|
|
|
|
|
prefix = nm_utils_ip4_netmask_to_prefix (tmp);
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
2009-03-27 09:47:44 -04:00
|
|
|
}
|
|
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
if (prefix == 0 && base_addr)
|
|
|
|
|
prefix = nm_ip_address_get_prefix (base_addr);
|
2010-01-20 16:34:23 -08:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
/* Try to autodetermine the prefix for the address' class */
|
|
|
|
|
if (prefix == 0) {
|
|
|
|
|
if (inet_pton (AF_INET, ip, &tmp) == 1) {
|
|
|
|
|
prefix = nm_utils_ip4_get_default_prefix (tmp);
|
2010-01-20 16:34:23 -08:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
PARSE_WARNING ("missing %s, assuming %s/%ld", prefix_tag, ip, prefix);
|
|
|
|
|
}
|
2010-01-20 16:34:23 -08:00
|
|
|
}
|
|
|
|
|
|
2009-03-27 09:47:44 -04:00
|
|
|
/* Validate the prefix */
|
2014-09-16 16:42:46 -04:00
|
|
|
if (prefix == 0) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2014-09-16 16:42:46 -04:00
|
|
|
"Missing IP4 prefix");
|
2013-07-26 14:25:05 -05:00
|
|
|
goto done;
|
2009-03-27 09:47:44 -04:00
|
|
|
}
|
|
|
|
|
|
2014-10-20 21:30:56 -04:00
|
|
|
*out_address = nm_ip_address_new (AF_INET, ip, prefix, error);
|
2014-09-16 16:42:46 -04:00
|
|
|
if (*out_address)
|
|
|
|
|
success = TRUE;
|
2009-03-27 09:47:44 -04:00
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
done:
|
2014-09-16 16:42:46 -04:00
|
|
|
g_free (ip);
|
2009-03-27 09:47:44 -04:00
|
|
|
g_free (ip_tag);
|
|
|
|
|
g_free (prefix_tag);
|
|
|
|
|
g_free (netmask_tag);
|
|
|
|
|
g_free (gw_tag);
|
2013-07-26 14:25:05 -05:00
|
|
|
|
|
|
|
|
return success;
|
2009-03-27 09:47:44 -04:00
|
|
|
}
|
2008-04-07 22:57:29 +00:00
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
/* Returns TRUE on missing route or valid route */
|
|
|
|
|
static gboolean
|
2009-12-07 14:23:26 -08:00
|
|
|
read_one_ip4_route (shvarFile *ifcfg,
|
|
|
|
|
guint32 which,
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPRoute **out_route,
|
2009-12-07 14:23:26 -08:00
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
char *ip_tag, *netmask_tag, *gw_tag, *metric_tag, *value;
|
2014-09-16 16:42:46 -04:00
|
|
|
char *dest = NULL, *next_hop = NULL;
|
2014-11-04 15:48:48 -05:00
|
|
|
gint64 prefix, metric;
|
2009-12-07 14:23:26 -08:00
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
g_return_val_if_fail (ifcfg != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (out_route != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (*out_route == NULL, FALSE);
|
2014-12-31 00:08:12 +01:00
|
|
|
g_return_val_if_fail (!error || !*error, FALSE);
|
2009-12-07 14:23:26 -08:00
|
|
|
|
|
|
|
|
ip_tag = g_strdup_printf ("ADDRESS%u", which);
|
|
|
|
|
netmask_tag = g_strdup_printf ("NETMASK%u", which);
|
|
|
|
|
gw_tag = g_strdup_printf ("GATEWAY%u", which);
|
|
|
|
|
metric_tag = g_strdup_printf ("METRIC%u", which);
|
|
|
|
|
|
|
|
|
|
/* Destination */
|
2014-09-16 16:42:46 -04:00
|
|
|
if (!read_ip4_address (ifcfg, ip_tag, &dest, error))
|
2009-12-07 14:23:26 -08:00
|
|
|
goto out;
|
2014-09-16 16:42:46 -04:00
|
|
|
if (!dest) {
|
2009-12-07 14:23:26 -08:00
|
|
|
/* Check whether IP is missing or 0.0.0.0 */
|
|
|
|
|
char *val;
|
|
|
|
|
val = svGetValue (ifcfg, ip_tag, FALSE);
|
|
|
|
|
if (!val) {
|
2014-09-16 16:42:46 -04:00
|
|
|
*out_route = NULL;
|
2013-07-26 14:25:05 -05:00
|
|
|
success = TRUE; /* missing route = success */
|
2009-12-07 14:23:26 -08:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
g_free (val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Next hop */
|
2014-09-16 16:42:46 -04:00
|
|
|
if (!read_ip4_address (ifcfg, gw_tag, &next_hop, error))
|
2009-12-07 14:23:26 -08:00
|
|
|
goto out;
|
2014-09-16 16:42:46 -04:00
|
|
|
/* We don't make distinction between missing GATEWAY IP and 0.0.0.0 */
|
2009-12-07 14:23:26 -08:00
|
|
|
|
|
|
|
|
/* Prefix */
|
2014-09-16 16:42:46 -04:00
|
|
|
if (!read_ip4_address (ifcfg, netmask_tag, &value, error))
|
2009-12-07 14:23:26 -08:00
|
|
|
goto out;
|
2014-09-16 16:42:46 -04:00
|
|
|
if (value) {
|
|
|
|
|
guint32 netmask;
|
2009-12-07 14:23:26 -08:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
inet_pton (AF_INET, value, &netmask);
|
|
|
|
|
prefix = nm_utils_ip4_netmask_to_prefix (netmask);
|
|
|
|
|
g_free (value);
|
2014-11-11 15:58:58 +01:00
|
|
|
if (prefix == 0 || netmask != nm_utils_ip4_prefix_to_netmask (prefix)) {
|
2014-09-16 16:42:46 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Invalid IP4 netmask '%s' \"%s\"", netmask_tag, nm_utils_inet4_ntop (netmask, NULL));
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2014-09-16 16:42:46 -04:00
|
|
|
"Missing IP4 route element '%s'", netmask_tag);
|
2009-12-07 14:23:26 -08:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Metric */
|
|
|
|
|
value = svGetValue (ifcfg, metric_tag, FALSE);
|
|
|
|
|
if (value) {
|
2015-02-22 11:55:31 +01:00
|
|
|
metric = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1);
|
2014-09-16 16:42:46 -04:00
|
|
|
if (metric < 0) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-12-07 14:23:26 -08:00
|
|
|
"Invalid IP4 route metric '%s'", value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
2014-09-16 16:42:46 -04:00
|
|
|
} else
|
2014-11-04 15:48:48 -05:00
|
|
|
metric = -1;
|
2009-12-07 14:23:26 -08:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
*out_route = nm_ip_route_new (AF_INET, dest, prefix, next_hop, metric, error);
|
|
|
|
|
if (*out_route)
|
|
|
|
|
success = TRUE;
|
2009-12-07 14:23:26 -08:00
|
|
|
|
|
|
|
|
out:
|
2014-09-16 16:42:46 -04:00
|
|
|
g_free (dest);
|
|
|
|
|
g_free (next_hop);
|
2009-12-07 14:23:26 -08:00
|
|
|
g_free (ip_tag);
|
|
|
|
|
g_free (netmask_tag);
|
|
|
|
|
g_free (gw_tag);
|
|
|
|
|
g_free (metric_tag);
|
2013-07-26 14:25:05 -05:00
|
|
|
return success;
|
2009-12-07 14:23:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2014-10-19 17:30:10 -04:00
|
|
|
read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError **error)
|
2009-12-07 14:23:26 -08:00
|
|
|
{
|
|
|
|
|
char *contents = NULL;
|
|
|
|
|
gsize len = 0;
|
|
|
|
|
char **lines = NULL, **iter;
|
|
|
|
|
GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric;
|
|
|
|
|
GMatchInfo *match_info;
|
2014-11-04 15:48:48 -05:00
|
|
|
gint64 prefix_int, metric_int;
|
2009-12-07 14:23:26 -08:00
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
|
|
|
|
const char *pattern_empty = "^\\s*(\\#.*)?$";
|
|
|
|
|
const char *pattern_to1 = "^\\s*(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|default)" /* IP or 'default' keyword */
|
|
|
|
|
"(?:/(\\d{1,2}))?"; /* optional prefix */
|
|
|
|
|
const char *pattern_to2 = "to\\s+(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|default)" /* IP or 'default' keyword */
|
|
|
|
|
"(?:/(\\d{1,2}))?"; /* optional prefix */
|
|
|
|
|
const char *pattern_via = "via\\s+(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"; /* IP of gateway */
|
|
|
|
|
const char *pattern_metric = "metric\\s+(\\d+)"; /* metric */
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (filename != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (s_ip4 != NULL, FALSE);
|
2014-12-31 00:08:12 +01:00
|
|
|
g_return_val_if_fail (!error || !*error, FALSE);
|
2009-12-07 14:23:26 -08:00
|
|
|
|
|
|
|
|
/* Read the route file */
|
2013-07-26 14:25:05 -05:00
|
|
|
if (!g_file_get_contents (filename, &contents, &len, NULL) || !len) {
|
2009-12-07 14:23:26 -08:00
|
|
|
g_free (contents);
|
2013-07-26 14:25:05 -05:00
|
|
|
return TRUE; /* missing/empty = success */
|
2009-12-07 14:23:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create regexes for pieces to be matched */
|
|
|
|
|
regex_to1 = g_regex_new (pattern_to1, 0, 0, NULL);
|
|
|
|
|
regex_to2 = g_regex_new (pattern_to2, 0, 0, NULL);
|
|
|
|
|
regex_via = g_regex_new (pattern_via, 0, 0, NULL);
|
|
|
|
|
regex_metric = g_regex_new (pattern_metric, 0, 0, NULL);
|
|
|
|
|
|
|
|
|
|
/* Iterate through file lines */
|
|
|
|
|
lines = g_strsplit_set (contents, "\n\r", -1);
|
|
|
|
|
for (iter = lines; iter && *iter; iter++) {
|
2015-02-07 16:54:01 +01:00
|
|
|
gs_free char *next_hop = NULL, *dest = NULL;
|
|
|
|
|
char *prefix, *metric;
|
|
|
|
|
NMIPRoute *route;
|
2009-12-07 14:23:26 -08:00
|
|
|
|
|
|
|
|
/* Skip empty lines */
|
|
|
|
|
if (g_regex_match_simple (pattern_empty, *iter, 0, 0))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Destination */
|
|
|
|
|
g_regex_match (regex_to1, *iter, 0, &match_info);
|
|
|
|
|
if (!g_match_info_matches (match_info)) {
|
|
|
|
|
g_match_info_free (match_info);
|
|
|
|
|
g_regex_match (regex_to2, *iter, 0, &match_info);
|
|
|
|
|
if (!g_match_info_matches (match_info)) {
|
|
|
|
|
g_match_info_free (match_info);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Missing IP4 route destination address in record: '%s'", *iter);
|
2009-12-07 14:23:26 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dest = g_match_info_fetch (match_info, 1);
|
|
|
|
|
if (!strcmp (dest, "default"))
|
2015-02-07 16:54:01 +01:00
|
|
|
strcpy (dest, "0.0.0.0");
|
2014-09-16 16:42:46 -04:00
|
|
|
if (!nm_utils_ipaddr_valid (AF_INET, dest)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Invalid IP4 route destination address '%s'", dest);
|
2014-09-16 16:42:46 -04:00
|
|
|
g_match_info_free (match_info);
|
2009-12-07 14:23:26 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Prefix - is optional; 32 if missing */
|
|
|
|
|
prefix = g_match_info_fetch (match_info, 2);
|
2011-04-14 11:41:55 +02:00
|
|
|
g_match_info_free (match_info);
|
2009-12-07 14:23:26 -08:00
|
|
|
prefix_int = 32;
|
|
|
|
|
if (prefix) {
|
|
|
|
|
errno = 0;
|
|
|
|
|
prefix_int = strtol (prefix, NULL, 10);
|
2011-07-05 23:17:14 -05:00
|
|
|
if (errno || prefix_int <= 0 || prefix_int > 32) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Invalid IP4 route destination prefix '%s'", prefix);
|
2009-12-07 14:23:26 -08:00
|
|
|
g_free (prefix);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_free (prefix);
|
|
|
|
|
|
|
|
|
|
/* Next hop */
|
|
|
|
|
g_regex_match (regex_via, *iter, 0, &match_info);
|
2013-08-19 19:39:17 +02:00
|
|
|
if (g_match_info_matches (match_info)) {
|
2014-09-16 16:42:46 -04:00
|
|
|
next_hop = g_match_info_fetch (match_info, 1);
|
|
|
|
|
if (!nm_utils_ipaddr_valid (AF_INET, next_hop)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2013-08-19 19:39:17 +02:00
|
|
|
"Invalid IP4 route gateway address '%s'",
|
|
|
|
|
next_hop);
|
|
|
|
|
g_match_info_free (match_info);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* we don't make distinction between missing GATEWAY IP and 0.0.0.0 */
|
2009-12-07 14:23:26 -08:00
|
|
|
}
|
2013-08-19 19:39:17 +02:00
|
|
|
g_match_info_free (match_info);
|
2009-12-07 14:23:26 -08:00
|
|
|
|
|
|
|
|
/* Metric */
|
|
|
|
|
g_regex_match (regex_metric, *iter, 0, &match_info);
|
2014-11-04 15:48:48 -05:00
|
|
|
metric_int = -1;
|
2009-12-07 14:23:26 -08:00
|
|
|
if (g_match_info_matches (match_info)) {
|
|
|
|
|
metric = g_match_info_fetch (match_info, 1);
|
|
|
|
|
errno = 0;
|
|
|
|
|
metric_int = strtol (metric, NULL, 10);
|
|
|
|
|
if (errno || metric_int < 0) {
|
|
|
|
|
g_match_info_free (match_info);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-12-07 14:23:26 -08:00
|
|
|
"Invalid IP4 route metric '%s'", metric);
|
|
|
|
|
g_free (metric);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (metric);
|
|
|
|
|
}
|
|
|
|
|
g_match_info_free (match_info);
|
|
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
route = nm_ip_route_new (AF_INET, dest, prefix_int, next_hop, metric_int, error);
|
2015-02-07 16:54:01 +01:00
|
|
|
if (!route)
|
2014-09-16 16:42:46 -04:00
|
|
|
goto error;
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_route (s_ip4, route))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate IP4 route");
|
2015-02-07 16:54:01 +01:00
|
|
|
nm_ip_route_unref (route);
|
2009-12-07 14:23:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_free (contents);
|
|
|
|
|
g_strfreev (lines);
|
|
|
|
|
g_regex_unref (regex_to1);
|
|
|
|
|
g_regex_unref (regex_to2);
|
|
|
|
|
g_regex_unref (regex_via);
|
|
|
|
|
g_regex_unref (regex_metric);
|
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 14:56:00 +01:00
|
|
|
static void
|
|
|
|
|
parse_dns_options (NMSettingIPConfig *ip_config, char *value)
|
|
|
|
|
{
|
|
|
|
|
char **options = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (ip_config);
|
|
|
|
|
|
|
|
|
|
if (!value)
|
|
|
|
|
return;
|
|
|
|
|
|
2015-05-20 14:29:49 +02:00
|
|
|
if (!nm_setting_ip_config_has_dns_options (ip_config))
|
|
|
|
|
nm_setting_ip_config_clear_dns_options (ip_config, TRUE);
|
|
|
|
|
|
2015-03-26 14:56:00 +01:00
|
|
|
options = g_strsplit (value, " ", 0);
|
|
|
|
|
if (options) {
|
|
|
|
|
char **item;
|
|
|
|
|
for (item = options; *item; item++) {
|
|
|
|
|
if (strlen (*item)) {
|
|
|
|
|
if (!nm_setting_ip_config_add_dns_option (ip_config, *item))
|
|
|
|
|
PARSE_WARNING ("can't add DNS option '%s'", *item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_strfreev (options);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
static gboolean
|
2011-01-26 16:27:32 +01:00
|
|
|
parse_full_ip6_address (shvarFile *ifcfg,
|
|
|
|
|
const char *addr_str,
|
|
|
|
|
int i,
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPAddress **out_address,
|
2011-01-26 16:27:32 +01:00
|
|
|
GError **error)
|
2010-01-05 19:05:01 -06:00
|
|
|
{
|
|
|
|
|
char **list;
|
2014-10-20 21:30:56 -04:00
|
|
|
char *ip_val, *prefix_val;
|
2014-09-16 16:42:46 -04:00
|
|
|
long prefix;
|
2010-01-05 19:05:01 -06:00
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
g_return_val_if_fail (addr_str != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (out_address != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (*out_address == NULL, FALSE);
|
2014-12-31 00:08:12 +01:00
|
|
|
g_return_val_if_fail (!error || !*error, FALSE);
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2013-07-26 14:25:05 -05:00
|
|
|
/* Split the address and prefix */
|
2010-01-05 19:05:01 -06:00
|
|
|
list = g_strsplit_set (addr_str, "/", 2);
|
|
|
|
|
if (g_strv_length (list) < 1) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2010-01-05 19:05:01 -06:00
|
|
|
"Invalid IP6 address '%s'", addr_str);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-26 16:27:32 +01:00
|
|
|
ip_val = list[0];
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
prefix_val = list[1];
|
2011-01-26 16:27:32 +01:00
|
|
|
if (prefix_val) {
|
2010-01-05 19:05:01 -06:00
|
|
|
errno = 0;
|
2011-01-26 16:27:32 +01:00
|
|
|
prefix = strtol (prefix_val, NULL, 10);
|
2010-01-05 19:05:01 -06:00
|
|
|
if (errno || prefix <= 0 || prefix > 128) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2011-01-26 16:27:32 +01:00
|
|
|
"Invalid IP6 prefix '%s'", prefix_val);
|
2010-01-05 19:05:01 -06:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* Missing prefix is treated as prefix of 64 */
|
2014-09-16 16:42:46 -04:00
|
|
|
prefix = 64;
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
|
|
|
|
|
2014-10-20 21:30:56 -04:00
|
|
|
*out_address = nm_ip_address_new (AF_INET6, ip_val, prefix, error);
|
2014-09-16 16:42:46 -04:00
|
|
|
if (*out_address)
|
|
|
|
|
success = TRUE;
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
error:
|
2010-01-05 19:05:01 -06:00
|
|
|
g_strfreev (list);
|
2013-07-26 14:25:05 -05:00
|
|
|
return success;
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* IPv6 address is very complex to describe completely by a regular expression,
|
|
|
|
|
* so don't try to, rather use looser syntax to comprise all possibilities
|
|
|
|
|
* NOTE: The regexes below don't describe all variants allowed by 'ip route add',
|
|
|
|
|
* namely destination IP without 'to' keyword is recognized just at line start.
|
|
|
|
|
*/
|
|
|
|
|
#define IPV6_ADDR_REGEX "[0-9A-Fa-f:.]+"
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2014-10-19 17:30:10 -04:00
|
|
|
read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error)
|
2010-01-05 19:05:01 -06:00
|
|
|
{
|
|
|
|
|
char *contents = NULL;
|
|
|
|
|
gsize len = 0;
|
|
|
|
|
char **lines = NULL, **iter;
|
|
|
|
|
GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric;
|
|
|
|
|
GMatchInfo *match_info;
|
2014-09-16 16:42:46 -04:00
|
|
|
char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL;
|
2014-11-04 15:48:48 -05:00
|
|
|
gint64 prefix_int, metric_int;
|
2010-01-05 19:05:01 -06:00
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
|
|
|
|
const char *pattern_empty = "^\\s*(\\#.*)?$";
|
2013-10-07 17:47:52 +02:00
|
|
|
const char *pattern_to1 = "^\\s*(default|" IPV6_ADDR_REGEX ")" /* IPv6 or 'default' keyword */
|
2011-07-05 23:27:50 -05:00
|
|
|
"(?:/(\\d{1,3}))?"; /* optional prefix */
|
2013-10-07 17:47:52 +02:00
|
|
|
const char *pattern_to2 = "to\\s+(default|" IPV6_ADDR_REGEX ")" /* IPv6 or 'default' keyword */
|
2011-07-05 23:27:50 -05:00
|
|
|
"(?:/(\\d{1,3}))?"; /* optional prefix */
|
2010-01-05 19:05:01 -06:00
|
|
|
const char *pattern_via = "via\\s+(" IPV6_ADDR_REGEX ")"; /* IPv6 of gateway */
|
|
|
|
|
const char *pattern_metric = "metric\\s+(\\d+)"; /* metric */
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (filename != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (s_ip6 != NULL, FALSE);
|
2014-12-31 00:08:12 +01:00
|
|
|
g_return_val_if_fail (!error || !*error, FALSE);
|
2010-01-05 19:05:01 -06:00
|
|
|
|
|
|
|
|
/* Read the route file */
|
2013-07-26 14:25:05 -05:00
|
|
|
if (!g_file_get_contents (filename, &contents, &len, NULL) || !len) {
|
2010-01-05 19:05:01 -06:00
|
|
|
g_free (contents);
|
2013-07-26 14:25:05 -05:00
|
|
|
return TRUE; /* missing/empty = success */
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create regexes for pieces to be matched */
|
|
|
|
|
regex_to1 = g_regex_new (pattern_to1, 0, 0, NULL);
|
|
|
|
|
regex_to2 = g_regex_new (pattern_to2, 0, 0, NULL);
|
|
|
|
|
regex_via = g_regex_new (pattern_via, 0, 0, NULL);
|
|
|
|
|
regex_metric = g_regex_new (pattern_metric, 0, 0, NULL);
|
|
|
|
|
|
|
|
|
|
/* Iterate through file lines */
|
|
|
|
|
lines = g_strsplit_set (contents, "\n\r", -1);
|
|
|
|
|
for (iter = lines; iter && *iter; iter++) {
|
2015-02-07 16:54:01 +01:00
|
|
|
NMIPRoute *route;
|
2010-01-05 19:05:01 -06:00
|
|
|
|
|
|
|
|
/* Skip empty lines */
|
|
|
|
|
if (g_regex_match_simple (pattern_empty, *iter, 0, 0))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Destination */
|
|
|
|
|
g_regex_match (regex_to1, *iter, 0, &match_info);
|
|
|
|
|
if (!g_match_info_matches (match_info)) {
|
|
|
|
|
g_match_info_free (match_info);
|
|
|
|
|
g_regex_match (regex_to2, *iter, 0, &match_info);
|
|
|
|
|
if (!g_match_info_matches (match_info)) {
|
|
|
|
|
g_match_info_free (match_info);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Missing IP6 route destination address in record: '%s'", *iter);
|
2010-01-05 19:05:01 -06:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dest = g_match_info_fetch (match_info, 1);
|
2013-10-07 17:47:52 +02:00
|
|
|
if (!g_strcmp0 (dest, "default")) {
|
|
|
|
|
/* Ignore default route - NM handles it internally */
|
2014-09-16 16:42:46 -04:00
|
|
|
g_clear_pointer (&dest, g_free);
|
2013-10-07 17:47:52 +02:00
|
|
|
g_match_info_free (match_info);
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring manual default route: '%s' (%s)", *iter, filename);
|
2013-10-07 17:47:52 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
2010-01-05 19:05:01 -06:00
|
|
|
|
|
|
|
|
/* Prefix - is optional; 128 if missing */
|
|
|
|
|
prefix = g_match_info_fetch (match_info, 2);
|
2011-04-14 11:41:55 +02:00
|
|
|
g_match_info_free (match_info);
|
2010-01-05 19:05:01 -06:00
|
|
|
prefix_int = 128;
|
|
|
|
|
if (prefix) {
|
|
|
|
|
errno = 0;
|
|
|
|
|
prefix_int = strtol (prefix, NULL, 10);
|
2011-07-05 23:17:14 -05:00
|
|
|
if (errno || prefix_int <= 0 || prefix_int > 128) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Invalid IP6 route destination prefix '%s'", prefix);
|
2014-09-16 16:42:46 -04:00
|
|
|
g_free (dest);
|
2010-01-05 19:05:01 -06:00
|
|
|
g_free (prefix);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_free (prefix);
|
|
|
|
|
|
|
|
|
|
/* Next hop */
|
|
|
|
|
g_regex_match (regex_via, *iter, 0, &match_info);
|
2014-06-09 18:46:34 +02:00
|
|
|
if (g_match_info_matches (match_info)) {
|
2014-09-16 16:42:46 -04:00
|
|
|
next_hop = g_match_info_fetch (match_info, 1);
|
|
|
|
|
if (!nm_utils_ipaddr_valid (AF_INET6, next_hop)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2014-06-09 18:46:34 +02:00
|
|
|
"Invalid IPv6 route nexthop address '%s'",
|
|
|
|
|
next_hop);
|
|
|
|
|
g_match_info_free (match_info);
|
2014-09-16 16:42:46 -04:00
|
|
|
g_free (dest);
|
2014-06-09 18:46:34 +02:00
|
|
|
g_free (next_hop);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* Missing "via" is taken as :: */
|
2014-09-16 16:42:46 -04:00
|
|
|
next_hop = NULL;
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
2014-06-09 18:46:34 +02:00
|
|
|
g_match_info_free (match_info);
|
2010-01-05 19:05:01 -06:00
|
|
|
|
|
|
|
|
/* Metric */
|
|
|
|
|
g_regex_match (regex_metric, *iter, 0, &match_info);
|
2014-11-04 15:48:48 -05:00
|
|
|
metric_int = -1;
|
2010-01-05 19:05:01 -06:00
|
|
|
if (g_match_info_matches (match_info)) {
|
|
|
|
|
metric = g_match_info_fetch (match_info, 1);
|
|
|
|
|
errno = 0;
|
|
|
|
|
metric_int = strtol (metric, NULL, 10);
|
|
|
|
|
if (errno || metric_int < 0 || metric_int > G_MAXUINT32) {
|
|
|
|
|
g_match_info_free (match_info);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2010-01-05 19:05:01 -06:00
|
|
|
"Invalid IP6 route metric '%s'", metric);
|
2014-09-16 16:42:46 -04:00
|
|
|
g_free (dest);
|
|
|
|
|
g_free (next_hop);
|
2010-01-05 19:05:01 -06:00
|
|
|
g_free (metric);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (metric);
|
|
|
|
|
}
|
|
|
|
|
g_match_info_free (match_info);
|
|
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
route = nm_ip_route_new (AF_INET6, dest, prefix_int, next_hop, metric_int, error);
|
|
|
|
|
g_free (dest);
|
|
|
|
|
g_free (next_hop);
|
|
|
|
|
if (!route)
|
|
|
|
|
goto error;
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_route (s_ip6, route))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate IP6 route");
|
2015-02-07 16:54:01 +01:00
|
|
|
nm_ip_route_unref (route);
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_free (contents);
|
|
|
|
|
g_strfreev (lines);
|
|
|
|
|
g_regex_unref (regex_to1);
|
|
|
|
|
g_regex_unref (regex_to2);
|
|
|
|
|
g_regex_unref (regex_via);
|
|
|
|
|
g_regex_unref (regex_metric);
|
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2009-12-07 14:23:26 -08:00
|
|
|
|
2007-11-21 06:24:15 +00:00
|
|
|
static NMSetting *
|
2009-08-07 12:13:54 -05:00
|
|
|
make_ip4_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *network_file,
|
|
|
|
|
GError **error)
|
2007-11-21 06:24:15 +00:00
|
|
|
{
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip4 = NULL;
|
2007-11-27 19:25:46 +00:00
|
|
|
char *value = NULL;
|
2009-12-07 14:23:26 -08:00
|
|
|
char *route_path = NULL;
|
2013-09-26 16:36:55 -04:00
|
|
|
char *method;
|
2015-03-26 14:56:00 +01:00
|
|
|
char *dns_options = NULL;
|
2015-01-28 23:02:29 +01:00
|
|
|
gs_free char *gateway = NULL;
|
2011-04-14 10:30:51 +02:00
|
|
|
gint32 i;
|
2008-12-09 20:01:49 +00:00
|
|
|
shvarFile *network_ifcfg;
|
2009-12-07 14:23:26 -08:00
|
|
|
shvarFile *route_ifcfg;
|
2013-07-26 14:25:05 -05:00
|
|
|
gboolean never_default = FALSE;
|
2009-03-27 09:47:44 -04:00
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
|
2008-12-09 20:01:49 +00:00
|
|
|
|
2009-11-13 14:40:13 -08:00
|
|
|
/* First check if DEFROUTE is set for this device; DEFROUTE has the
|
|
|
|
|
* opposite meaning from never-default. The default if DEFROUTE is not
|
|
|
|
|
* specified is DEFROUTE=yes which means that this connection can be used
|
|
|
|
|
* as a default route
|
|
|
|
|
*/
|
2015-10-08 18:04:30 +02:00
|
|
|
never_default = !svGetValueBoolean (ifcfg, "DEFROUTE", TRUE);
|
2009-11-13 14:40:13 -08:00
|
|
|
|
|
|
|
|
/* Then check if GATEWAYDEV; it's global and overrides DEFROUTE */
|
2014-03-18 13:13:12 -04:00
|
|
|
network_ifcfg = svOpenFile (network_file, NULL);
|
2008-12-09 20:01:49 +00:00
|
|
|
if (network_ifcfg) {
|
|
|
|
|
char *gatewaydev;
|
|
|
|
|
|
|
|
|
|
/* Get the connection ifcfg device name and the global gateway device */
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "DEVICE", FALSE);
|
|
|
|
|
gatewaydev = svGetValue (network_ifcfg, "GATEWAYDEV", FALSE);
|
2015-05-20 14:29:49 +02:00
|
|
|
dns_options = svGetValueFull (network_ifcfg, "RES_OPTIONS", FALSE);
|
2008-12-09 20:01:49 +00:00
|
|
|
|
|
|
|
|
/* If there was a global gateway device specified, then only connections
|
|
|
|
|
* for that device can be the default connection.
|
|
|
|
|
*/
|
2009-11-13 14:40:13 -08:00
|
|
|
if (gatewaydev && value)
|
|
|
|
|
never_default = !!strcmp (value, gatewaydev);
|
2008-12-09 20:01:49 +00:00
|
|
|
|
|
|
|
|
g_free (gatewaydev);
|
|
|
|
|
g_free (value);
|
|
|
|
|
svCloseFile (network_ifcfg);
|
|
|
|
|
}
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "BOOTPROTO", FALSE);
|
2013-09-26 16:36:55 -04:00
|
|
|
|
|
|
|
|
if (!value || !*value || !g_ascii_strcasecmp (value, "none")) {
|
2014-12-16 10:10:22 +01:00
|
|
|
if (is_any_ip4_address_defined (ifcfg, NULL))
|
2013-09-26 16:36:55 -04:00
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
|
|
|
|
|
else
|
|
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
|
|
|
|
|
} else if (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp")) {
|
|
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
|
|
|
|
|
} else if (!g_ascii_strcasecmp (value, "static")) {
|
2015-10-07 18:18:38 -07:00
|
|
|
if (is_any_ip4_address_defined (ifcfg, NULL))
|
|
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
|
|
|
|
|
else
|
|
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
|
2013-09-26 16:36:55 -04:00
|
|
|
} else if (!g_ascii_strcasecmp (value, "autoip")) {
|
|
|
|
|
g_free (value);
|
|
|
|
|
g_object_set (s_ip4,
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
|
|
|
|
|
NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default,
|
2013-09-26 16:36:55 -04:00
|
|
|
NULL);
|
|
|
|
|
return NM_SETTING (s_ip4);
|
|
|
|
|
} else if (!g_ascii_strcasecmp (value, "shared")) {
|
2014-12-16 10:10:22 +01:00
|
|
|
int idx;
|
|
|
|
|
|
2013-09-26 16:36:55 -04:00
|
|
|
g_free (value);
|
|
|
|
|
g_object_set (s_ip4,
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED,
|
|
|
|
|
NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default,
|
2013-09-26 16:36:55 -04:00
|
|
|
NULL);
|
2014-12-16 10:10:22 +01:00
|
|
|
/* 1 IP address is allowed for shared connections. Read it. */
|
|
|
|
|
if (is_any_ip4_address_defined (ifcfg, &idx)) {
|
|
|
|
|
NMIPAddress *addr = NULL;
|
|
|
|
|
|
2015-09-15 15:27:25 +02:00
|
|
|
if (!read_full_ip4_address (ifcfg, idx, NULL, &addr, NULL, error))
|
2014-12-16 10:10:22 +01:00
|
|
|
goto done;
|
|
|
|
|
if (!read_ip4_address (ifcfg, "GATEWAY", &gateway, error))
|
|
|
|
|
goto done;
|
|
|
|
|
(void) nm_setting_ip_config_add_address (s_ip4, addr);
|
|
|
|
|
nm_ip_address_unref (addr);
|
|
|
|
|
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL);
|
|
|
|
|
}
|
2013-09-26 16:36:55 -04:00
|
|
|
return NM_SETTING (s_ip4);
|
|
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2013-09-26 16:36:55 -04:00
|
|
|
"Unknown BOOTPROTO '%s'", value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto done;
|
2008-03-13 03:11:02 +00:00
|
|
|
}
|
2013-09-26 16:36:55 -04:00
|
|
|
g_free (value);
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2009-03-27 09:47:44 -04:00
|
|
|
g_object_set (s_ip4,
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, method,
|
2015-10-08 18:04:30 +02:00
|
|
|
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svGetValueBoolean (ifcfg, "PEERDNS", TRUE),
|
|
|
|
|
NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svGetValueBoolean (ifcfg, "PEERROUTES", TRUE),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default,
|
2015-10-08 18:04:30 +02:00
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, !svGetValueBoolean (ifcfg, "IPV4_FAILURE_FATAL", FALSE),
|
2014-12-22 15:10:22 +01:00
|
|
|
NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV4_ROUTE_METRIC", 10,
|
|
|
|
|
-1, G_MAXUINT32, -1),
|
2009-03-27 09:47:44 -04:00
|
|
|
NULL);
|
|
|
|
|
|
2011-06-16 12:30:38 +02:00
|
|
|
if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0)
|
|
|
|
|
return NM_SETTING (s_ip4);
|
|
|
|
|
|
2013-10-21 13:12:51 +02:00
|
|
|
/* Handle DHCP settings */
|
|
|
|
|
if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "DHCP_HOSTNAME", FALSE);
|
2008-07-07 19:30:53 +00:00
|
|
|
if (value && strlen (value))
|
2014-10-19 17:30:10 -04:00
|
|
|
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, value, NULL);
|
2008-07-07 19:30:53 +00:00
|
|
|
g_free (value);
|
|
|
|
|
|
2014-01-06 16:20:48 -06:00
|
|
|
g_object_set (s_ip4,
|
2015-10-08 18:04:30 +02:00
|
|
|
NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, svGetValueBoolean (ifcfg, "DHCP_SEND_HOSTNAME", TRUE),
|
2015-09-28 19:20:01 +02:00
|
|
|
NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT, svGetValueInt64 (ifcfg, "IPV4_DHCP_TIMEOUT", 10, 0, G_MAXUINT32, 0),
|
2014-01-06 16:20:48 -06:00
|
|
|
NULL);
|
|
|
|
|
|
2009-03-27 10:30:06 -04:00
|
|
|
value = svGetValue (ifcfg, "DHCP_CLIENT_ID", FALSE);
|
2009-03-27 09:47:44 -04:00
|
|
|
if (value && strlen (value))
|
|
|
|
|
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, value, NULL);
|
|
|
|
|
g_free (value);
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-21 13:12:51 +02:00
|
|
|
/* Read static IP addresses.
|
|
|
|
|
* Read them even for AUTO method - in this case the addresses are
|
|
|
|
|
* added to the automatic ones. Note that this is not currently supported by
|
|
|
|
|
* the legacy 'network' service (ifup-eth).
|
|
|
|
|
*/
|
|
|
|
|
for (i = -1; i < 256; i++) {
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPAddress *addr = NULL;
|
2013-10-21 13:12:51 +02:00
|
|
|
|
2015-01-28 23:02:29 +01:00
|
|
|
/* gateway will only be set if still unset. Hence, we don't leak gateway
|
|
|
|
|
* here by calling read_full_ip4_address() repeatedly */
|
2015-09-15 15:27:25 +02:00
|
|
|
if (!read_full_ip4_address (ifcfg, i, NULL, &addr, &gateway, error))
|
2013-10-21 13:12:51 +02:00
|
|
|
goto done;
|
2014-02-19 16:10:36 -05:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
if (!addr) {
|
2013-10-21 13:12:51 +02:00
|
|
|
/* The first mandatory variable is 2-indexed (IPADDR2)
|
|
|
|
|
* Variables IPADDR, IPADDR0 and IPADDR1 are optional */
|
|
|
|
|
if (i > 1)
|
|
|
|
|
break;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_address (s_ip4, addr))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate IP4 address");
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_address_unref (addr);
|
2013-10-21 13:12:51 +02:00
|
|
|
}
|
|
|
|
|
|
2014-10-20 21:30:56 -04:00
|
|
|
/* Gateway */
|
|
|
|
|
if (!gateway) {
|
|
|
|
|
network_ifcfg = svOpenFile (network_file, NULL);
|
|
|
|
|
if (network_ifcfg) {
|
|
|
|
|
gboolean read_success;
|
|
|
|
|
|
|
|
|
|
read_success = read_ip4_address (network_ifcfg, "GATEWAY", &gateway, error);
|
|
|
|
|
svCloseFile (network_ifcfg);
|
|
|
|
|
if (!read_success)
|
|
|
|
|
goto done;
|
2015-09-15 16:54:09 +02:00
|
|
|
|
|
|
|
|
if (gateway && nm_setting_ip_config_get_num_addresses (s_ip4) == 0) {
|
|
|
|
|
gs_free char *f = g_path_get_basename (ifcfg->fileName);
|
|
|
|
|
PARSE_WARNING ("ignoring GATEWAY (/etc/sysconfig/network) for %s "
|
|
|
|
|
"because the connection has no static addresses", f);
|
|
|
|
|
g_clear_pointer (&gateway, g_free);
|
|
|
|
|
}
|
2014-10-20 21:30:56 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL);
|
|
|
|
|
|
2010-01-05 19:05:01 -06:00
|
|
|
/* DNS servers
|
|
|
|
|
* Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting())
|
|
|
|
|
*/
|
2013-07-26 14:25:05 -05:00
|
|
|
for (i = 1; i <= 10; i++) {
|
2009-03-27 09:47:44 -04:00
|
|
|
char *tag;
|
|
|
|
|
|
|
|
|
|
tag = g_strdup_printf ("DNS%u", i);
|
2014-06-24 12:46:03 -04:00
|
|
|
value = svGetValue (ifcfg, tag, FALSE);
|
|
|
|
|
if (value) {
|
2014-09-16 16:42:46 -04:00
|
|
|
if (nm_utils_ipaddr_valid (AF_INET, value)) {
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_dns (s_ip4, value))
|
2014-09-16 16:42:46 -04:00
|
|
|
PARSE_WARNING ("duplicate DNS server %s", tag);
|
|
|
|
|
} else if (nm_utils_ipaddr_valid (AF_INET6, value)) {
|
2014-06-24 12:46:03 -04:00
|
|
|
/* Ignore IPv6 addresses */
|
2014-09-16 16:42:46 -04:00
|
|
|
} else {
|
|
|
|
|
PARSE_WARNING ("invalid DNS server address %s", value);
|
|
|
|
|
g_free (tag);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto done;
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
2014-06-24 12:46:03 -04:00
|
|
|
|
|
|
|
|
g_free (value);
|
2009-03-27 09:47:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_free (tag);
|
|
|
|
|
}
|
2008-03-19 03:08:32 +00:00
|
|
|
|
2008-07-07 19:30:53 +00:00
|
|
|
/* DNS searches */
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "DOMAIN", FALSE);
|
2008-07-07 19:30:53 +00:00
|
|
|
if (value) {
|
|
|
|
|
char **searches = NULL;
|
|
|
|
|
|
|
|
|
|
searches = g_strsplit (value, " ", 0);
|
|
|
|
|
if (searches) {
|
|
|
|
|
char **item;
|
2008-10-29 14:35:25 +00:00
|
|
|
for (item = searches; *item; item++) {
|
|
|
|
|
if (strlen (*item)) {
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_dns_search (s_ip4, *item))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate DNS domain '%s'", *item);
|
2008-10-29 14:35:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_strfreev (searches);
|
2008-03-13 03:11:02 +00:00
|
|
|
}
|
2008-07-07 19:30:53 +00:00
|
|
|
g_free (value);
|
2008-02-12 19:20:18 +00:00
|
|
|
}
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2015-03-26 14:56:00 +01:00
|
|
|
/* DNS options */
|
2015-05-20 14:29:49 +02:00
|
|
|
value = svGetValueFull (ifcfg, "RES_OPTIONS", FALSE);
|
2015-03-26 14:56:00 +01:00
|
|
|
parse_dns_options (s_ip4, value);
|
|
|
|
|
parse_dns_options (s_ip4, dns_options);
|
|
|
|
|
g_free (value);
|
|
|
|
|
g_free (dns_options);
|
|
|
|
|
dns_options = NULL;
|
|
|
|
|
|
2009-12-07 14:23:26 -08:00
|
|
|
/* Static routes - route-<name> file */
|
|
|
|
|
route_path = utils_get_route_path (ifcfg->fileName);
|
|
|
|
|
|
2014-12-17 08:50:05 -05:00
|
|
|
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)) {
|
2009-12-07 14:23:26 -08:00
|
|
|
/* Parse route file in new syntax */
|
|
|
|
|
route_ifcfg = utils_get_route_ifcfg (ifcfg->fileName, FALSE);
|
|
|
|
|
if (route_ifcfg) {
|
|
|
|
|
for (i = 0; i < 256; i++) {
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPRoute *route = NULL;
|
2013-07-26 14:25:05 -05:00
|
|
|
|
2015-09-15 15:27:25 +02:00
|
|
|
if (!read_one_ip4_route (route_ifcfg, i, &route, error)) {
|
2009-12-07 14:23:26 -08:00
|
|
|
svCloseFile (route_ifcfg);
|
2010-04-12 16:24:07 -07:00
|
|
|
goto done;
|
2009-12-07 14:23:26 -08:00
|
|
|
}
|
2013-07-26 14:25:05 -05:00
|
|
|
|
2009-12-07 14:23:26 -08:00
|
|
|
if (!route)
|
|
|
|
|
break;
|
|
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_route (s_ip4, route))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate IP4 route");
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_route_unref (route);
|
2009-12-07 14:23:26 -08:00
|
|
|
}
|
|
|
|
|
svCloseFile (route_ifcfg);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2013-07-26 14:25:05 -05:00
|
|
|
if (!read_route_file_legacy (route_path, s_ip4, error))
|
2010-04-12 16:24:07 -07:00
|
|
|
goto done;
|
2009-12-07 14:23:26 -08:00
|
|
|
}
|
2015-01-28 22:43:23 +01:00
|
|
|
g_free (route_path);
|
2009-12-07 14:23:26 -08:00
|
|
|
|
2008-08-27 19:43:15 +00:00
|
|
|
/* Legacy value NM used for a while but is incorrect (rh #459370) */
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_get_num_dns_searches (s_ip4)) {
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "SEARCH", FALSE);
|
2008-08-27 19:43:15 +00:00
|
|
|
if (value) {
|
|
|
|
|
char **searches = NULL;
|
|
|
|
|
|
|
|
|
|
searches = g_strsplit (value, " ", 0);
|
|
|
|
|
if (searches) {
|
|
|
|
|
char **item;
|
2008-10-29 14:35:25 +00:00
|
|
|
for (item = searches; *item; item++) {
|
|
|
|
|
if (strlen (*item)) {
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_dns_search (s_ip4, *item))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate DNS search '%s'", *item);
|
2008-10-29 14:35:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_strfreev (searches);
|
2008-08-27 19:43:15 +00:00
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
return NM_SETTING (s_ip4);
|
|
|
|
|
|
2010-04-12 16:24:07 -07:00
|
|
|
done:
|
2015-03-26 14:56:00 +01:00
|
|
|
g_free (dns_options);
|
2013-07-26 14:25:05 -05:00
|
|
|
g_free (route_path);
|
2009-03-27 09:47:44 -04:00
|
|
|
g_object_unref (s_ip4);
|
2007-11-27 19:25:46 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-19 16:10:36 -05:00
|
|
|
static void
|
2015-09-15 15:27:25 +02:00
|
|
|
read_aliases (NMSettingIPConfig *s_ip4, const char *filename)
|
2014-02-19 16:10:36 -05:00
|
|
|
{
|
|
|
|
|
GDir *dir;
|
|
|
|
|
char *dirname, *base;
|
|
|
|
|
shvarFile *parsed;
|
2015-06-01 15:28:43 +02:00
|
|
|
NMIPAddress *base_addr = NULL;
|
2014-02-19 16:10:36 -05:00
|
|
|
GError *err = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (s_ip4 != NULL);
|
|
|
|
|
g_return_if_fail (filename != NULL);
|
|
|
|
|
|
2015-06-01 15:28:43 +02:00
|
|
|
if (nm_setting_ip_config_get_num_addresses (s_ip4) > 0)
|
|
|
|
|
base_addr = nm_setting_ip_config_get_address (s_ip4, 0);
|
2014-06-24 12:46:03 -04:00
|
|
|
|
2014-02-19 16:10:36 -05:00
|
|
|
dirname = g_path_get_dirname (filename);
|
|
|
|
|
g_return_if_fail (dirname != NULL);
|
|
|
|
|
base = g_path_get_basename (filename);
|
|
|
|
|
g_return_if_fail (base != NULL);
|
|
|
|
|
|
|
|
|
|
dir = g_dir_open (dirname, 0, &err);
|
|
|
|
|
if (dir) {
|
|
|
|
|
const char *item;
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPAddress *addr;
|
2014-02-19 16:10:36 -05:00
|
|
|
gboolean ok;
|
|
|
|
|
|
|
|
|
|
while ((item = g_dir_read_name (dir))) {
|
|
|
|
|
char *full_path, *device;
|
|
|
|
|
const char *p;
|
|
|
|
|
|
|
|
|
|
if (!utils_is_ifcfg_alias_file (item, base))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
full_path = g_build_filename (dirname, item, NULL);
|
|
|
|
|
|
|
|
|
|
p = strchr (item, ':');
|
|
|
|
|
g_assert (p != NULL); /* we know this is true from utils_is_ifcfg_alias_file() */
|
|
|
|
|
for (p++; *p; p++) {
|
2014-04-01 15:05:29 -04:00
|
|
|
if (!g_ascii_isalnum (*p) && *p != '_')
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (*p) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring alias file '%s' with invalid name", full_path);
|
2014-04-01 15:05:29 -04:00
|
|
|
g_free (full_path);
|
|
|
|
|
continue;
|
2014-02-19 16:10:36 -05:00
|
|
|
}
|
|
|
|
|
|
2014-04-09 12:43:35 -04:00
|
|
|
parsed = svOpenFile (full_path, &err);
|
2014-02-19 16:10:36 -05:00
|
|
|
if (!parsed) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("couldn't parse alias file '%s': %s", full_path, err->message);
|
2014-02-19 16:10:36 -05:00
|
|
|
g_free (full_path);
|
2014-04-09 12:43:35 -04:00
|
|
|
g_clear_error (&err);
|
2014-02-19 16:10:36 -05:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device = svGetValue (parsed, "DEVICE", FALSE);
|
|
|
|
|
if (!device) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("alias file '%s' has no DEVICE", full_path);
|
2014-02-19 16:10:36 -05:00
|
|
|
svCloseFile (parsed);
|
|
|
|
|
g_free (full_path);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* We know that item starts with IFCFG_TAG from utils_is_ifcfg_alias_file() */
|
|
|
|
|
if (strcmp (device, item + strlen (IFCFG_TAG)) != 0) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("alias file '%s' has invalid DEVICE (%s) for filename",
|
|
|
|
|
full_path, device);
|
2014-02-19 16:10:36 -05:00
|
|
|
g_free (device);
|
|
|
|
|
svCloseFile (parsed);
|
|
|
|
|
g_free (full_path);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
addr = NULL;
|
2015-09-15 15:27:25 +02:00
|
|
|
ok = read_full_ip4_address (parsed, -1, base_addr, &addr, NULL, &err);
|
2014-02-19 16:10:36 -05:00
|
|
|
svCloseFile (parsed);
|
|
|
|
|
if (ok) {
|
2014-09-16 16:38:04 -04:00
|
|
|
nm_ip_address_set_attribute (addr, "label", g_variant_new_string (device));
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_address (s_ip4, addr))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate IP4 address in alias file %s", item);
|
2014-02-19 16:10:36 -05:00
|
|
|
} else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("error reading IP4 address from alias file '%s': %s",
|
|
|
|
|
full_path, err ? err->message : "no address");
|
|
|
|
|
g_clear_error (&err);
|
2014-02-19 16:10:36 -05:00
|
|
|
}
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_address_unref (addr);
|
2014-02-19 16:10:36 -05:00
|
|
|
|
|
|
|
|
g_free (device);
|
|
|
|
|
g_free (full_path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_dir_close (dir);
|
|
|
|
|
} else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("can not read directory '%s': %s", dirname, err->message);
|
2014-02-19 16:10:36 -05:00
|
|
|
g_error_free (err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_free (base);
|
|
|
|
|
g_free (dirname);
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-05 19:05:01 -06:00
|
|
|
static NMSetting *
|
|
|
|
|
make_ip6_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *network_file,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip6 = NULL;
|
2010-01-05 19:05:01 -06:00
|
|
|
char *value = NULL;
|
|
|
|
|
char *str_value;
|
|
|
|
|
char *route6_path = NULL;
|
2015-03-26 14:56:00 +01:00
|
|
|
char *dns_options = NULL;
|
2011-06-16 11:04:27 +02:00
|
|
|
gboolean ipv6init, ipv6forwarding, ipv6_autoconf, dhcp6 = FALSE;
|
2010-01-05 19:05:01 -06:00
|
|
|
char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
|
2013-10-21 13:12:51 +02:00
|
|
|
char *ipv6addr, *ipv6addr_secondaries;
|
|
|
|
|
char **list = NULL, **iter;
|
2010-01-05 19:05:01 -06:00
|
|
|
guint32 i;
|
|
|
|
|
shvarFile *network_ifcfg;
|
2013-07-26 14:25:05 -05:00
|
|
|
gboolean never_default = FALSE;
|
2012-10-04 13:26:03 -05:00
|
|
|
gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip;
|
2012-02-21 16:03:04 +01:00
|
|
|
NMSettingIP6ConfigPrivacy ip6_privacy_val;
|
2015-09-08 20:38:41 +02:00
|
|
|
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
|
|
|
|
|
char *tmp;
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
|
2010-01-05 19:05:01 -06:00
|
|
|
|
|
|
|
|
/* First check if IPV6_DEFROUTE is set for this device; IPV6_DEFROUTE has the
|
|
|
|
|
* opposite meaning from never-default. The default if IPV6_DEFROUTE is not
|
|
|
|
|
* specified is IPV6_DEFROUTE=yes which means that this connection can be used
|
|
|
|
|
* as a default route
|
|
|
|
|
*/
|
2015-10-08 18:04:30 +02:00
|
|
|
never_default = !svGetValueBoolean (ifcfg, "IPV6_DEFROUTE", TRUE);
|
2010-01-05 19:05:01 -06:00
|
|
|
|
|
|
|
|
/* Then check if IPV6_DEFAULTGW or IPV6_DEFAULTDEV is specified;
|
|
|
|
|
* they are global and override IPV6_DEFROUTE
|
|
|
|
|
* When both are set, the device specified in IPV6_DEFAULTGW takes preference.
|
|
|
|
|
*/
|
2014-03-18 13:13:12 -04:00
|
|
|
network_ifcfg = svOpenFile (network_file, NULL);
|
2010-01-05 19:05:01 -06:00
|
|
|
if (network_ifcfg) {
|
|
|
|
|
char *ipv6_defaultgw, *ipv6_defaultdev;
|
|
|
|
|
char *default_dev = NULL;
|
|
|
|
|
|
|
|
|
|
/* Get the connection ifcfg device name and the global default route device */
|
|
|
|
|
value = svGetValue (ifcfg, "DEVICE", FALSE);
|
|
|
|
|
ipv6_defaultgw = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE);
|
|
|
|
|
ipv6_defaultdev = svGetValue (network_ifcfg, "IPV6_DEFAULTDEV", FALSE);
|
2015-05-20 14:29:49 +02:00
|
|
|
dns_options = svGetValueFull (network_ifcfg, "RES_OPTIONS", FALSE);
|
2010-01-05 19:05:01 -06:00
|
|
|
|
|
|
|
|
if (ipv6_defaultgw) {
|
|
|
|
|
default_dev = strchr (ipv6_defaultgw, '%');
|
|
|
|
|
if (default_dev)
|
|
|
|
|
default_dev++;
|
|
|
|
|
}
|
|
|
|
|
if (!default_dev)
|
|
|
|
|
default_dev = ipv6_defaultdev;
|
|
|
|
|
|
|
|
|
|
/* If there was a global default route device specified, then only connections
|
|
|
|
|
* for that device can be the default connection.
|
|
|
|
|
*/
|
|
|
|
|
if (default_dev && value)
|
|
|
|
|
never_default = !!strcmp (value, default_dev);
|
|
|
|
|
|
|
|
|
|
g_free (ipv6_defaultgw);
|
|
|
|
|
g_free (ipv6_defaultdev);
|
|
|
|
|
g_free (value);
|
|
|
|
|
svCloseFile (network_ifcfg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find out method property */
|
2011-06-16 11:04:27 +02:00
|
|
|
/* Is IPV6 enabled? Set method to "ignored", when not enabled */
|
|
|
|
|
str_value = svGetValue (ifcfg, "IPV6INIT", FALSE);
|
2015-10-08 18:04:30 +02:00
|
|
|
ipv6init = svGetValueBoolean (ifcfg, "IPV6INIT", FALSE);
|
2011-06-16 11:04:27 +02:00
|
|
|
if (!str_value) {
|
2014-03-18 13:13:12 -04:00
|
|
|
network_ifcfg = svOpenFile (network_file, NULL);
|
2011-06-16 11:04:27 +02:00
|
|
|
if (network_ifcfg) {
|
2015-10-08 18:04:30 +02:00
|
|
|
ipv6init = svGetValueBoolean (network_ifcfg, "IPV6INIT", FALSE);
|
2011-06-16 11:04:27 +02:00
|
|
|
svCloseFile (network_ifcfg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_free (str_value);
|
|
|
|
|
|
|
|
|
|
if (!ipv6init)
|
|
|
|
|
method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; /* IPv6 is disabled */
|
2010-01-05 19:05:01 -06:00
|
|
|
else {
|
2015-10-08 18:04:30 +02:00
|
|
|
ipv6forwarding = svGetValueBoolean (ifcfg, "IPV6FORWARDING", FALSE);
|
|
|
|
|
ipv6_autoconf = svGetValueBoolean (ifcfg, "IPV6_AUTOCONF", !ipv6forwarding);
|
|
|
|
|
dhcp6 = svGetValueBoolean (ifcfg, "DHCPV6C", FALSE);
|
2011-06-16 11:04:27 +02:00
|
|
|
|
|
|
|
|
if (ipv6_autoconf)
|
|
|
|
|
method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
|
|
|
|
|
else if (dhcp6)
|
|
|
|
|
method = NM_SETTING_IP6_CONFIG_METHOD_DHCP;
|
|
|
|
|
else {
|
|
|
|
|
/* IPV6_AUTOCONF=no and no IPv6 address -> method 'link-local' */
|
|
|
|
|
str_value = svGetValue (ifcfg, "IPV6ADDR", FALSE);
|
|
|
|
|
if (!str_value)
|
|
|
|
|
str_value = svGetValue (ifcfg, "IPV6ADDR_SECONDARIES", FALSE);
|
|
|
|
|
|
|
|
|
|
if (!str_value)
|
|
|
|
|
method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
|
|
|
|
|
g_free (str_value);
|
|
|
|
|
}
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
|
|
|
|
/* TODO - handle other methods */
|
|
|
|
|
|
2012-02-21 16:03:04 +01:00
|
|
|
/* Read IPv6 Privacy Extensions configuration */
|
2015-09-08 20:38:41 +02:00
|
|
|
tmp = svGetValue (ifcfg, "IPV6_PRIVACY", FALSE);
|
|
|
|
|
if (tmp) {
|
2015-10-08 18:04:30 +02:00
|
|
|
ip6_privacy = svGetValueBoolean (ifcfg, "IPV6_PRIVACY", FALSE);
|
2012-02-21 16:03:04 +01:00
|
|
|
if (!ip6_privacy)
|
2015-09-08 20:38:41 +02:00
|
|
|
ip6_privacy = g_strcmp0 (tmp, "rfc4941") == 0 ||
|
|
|
|
|
g_strcmp0 (tmp, "rfc3041") == 0;
|
2012-02-21 16:03:04 +01:00
|
|
|
}
|
2015-10-08 18:04:30 +02:00
|
|
|
ip6_privacy_prefer_public_ip = svGetValueBoolean (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", FALSE);
|
2015-09-08 20:38:41 +02:00
|
|
|
ip6_privacy_val = tmp ?
|
2012-02-21 16:03:04 +01:00
|
|
|
(ip6_privacy ?
|
|
|
|
|
(ip6_privacy_prefer_public_ip ? NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR : NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR) :
|
|
|
|
|
NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED) :
|
|
|
|
|
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
2015-09-08 20:38:41 +02:00
|
|
|
g_free (tmp);
|
2012-02-21 16:03:04 +01:00
|
|
|
|
2010-01-05 19:05:01 -06:00
|
|
|
g_object_set (s_ip6,
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, method,
|
2015-10-08 18:04:30 +02:00
|
|
|
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svGetValueBoolean (ifcfg, "IPV6_PEERDNS", TRUE),
|
|
|
|
|
NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svGetValueBoolean (ifcfg, "IPV6_PEERROUTES", TRUE),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default,
|
2015-10-08 18:04:30 +02:00
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, !svGetValueBoolean (ifcfg, "IPV6_FAILURE_FATAL", FALSE),
|
2014-12-22 15:10:22 +01:00
|
|
|
NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV6_ROUTE_METRIC", 10,
|
|
|
|
|
-1, G_MAXUINT32, -1),
|
2012-02-21 16:03:04 +01:00
|
|
|
NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val,
|
2010-01-05 19:05:01 -06:00
|
|
|
NULL);
|
|
|
|
|
|
2011-06-16 11:04:27 +02:00
|
|
|
/* Don't bother to read IP, DNS and routes when IPv6 is disabled */
|
|
|
|
|
if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0)
|
|
|
|
|
return NM_SETTING (s_ip6);
|
|
|
|
|
|
2013-10-21 13:12:51 +02:00
|
|
|
if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)
|
|
|
|
|
|| !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
|
2012-10-19 14:07:41 +02:00
|
|
|
/* METHOD_AUTO may trigger DHCPv6, so save the hostname to send to DHCP */
|
|
|
|
|
value = svGetValue (ifcfg, "DHCP_HOSTNAME", FALSE);
|
|
|
|
|
if (value && value[0])
|
2014-10-19 17:30:10 -04:00
|
|
|
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, value, NULL);
|
2012-10-19 14:07:41 +02:00
|
|
|
g_free (value);
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
|
|
|
|
|
2013-10-21 13:12:51 +02:00
|
|
|
/* Read static IP addresses.
|
|
|
|
|
* Read them even for AUTO and DHCP methods - in this case the addresses are
|
|
|
|
|
* added to the automatic ones. Note that this is not currently supported by
|
|
|
|
|
* the legacy 'network' service (ifup-eth).
|
|
|
|
|
*/
|
|
|
|
|
ipv6addr = svGetValue (ifcfg, "IPV6ADDR", FALSE);
|
|
|
|
|
ipv6addr_secondaries = svGetValue (ifcfg, "IPV6ADDR_SECONDARIES", FALSE);
|
|
|
|
|
|
|
|
|
|
value = g_strjoin (ipv6addr && ipv6addr_secondaries ? " " : NULL,
|
|
|
|
|
ipv6addr ? ipv6addr : "",
|
|
|
|
|
ipv6addr_secondaries ? ipv6addr_secondaries : "",
|
|
|
|
|
NULL);
|
|
|
|
|
g_free (ipv6addr);
|
|
|
|
|
g_free (ipv6addr_secondaries);
|
|
|
|
|
|
|
|
|
|
list = g_strsplit_set (value, " ", 0);
|
|
|
|
|
g_free (value);
|
|
|
|
|
for (iter = list, i = 0; iter && *iter; iter++, i++) {
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPAddress *addr = NULL;
|
2013-10-21 13:12:51 +02:00
|
|
|
|
2015-09-15 15:27:25 +02:00
|
|
|
if (!parse_full_ip6_address (ifcfg, *iter, i, &addr, error)) {
|
2013-10-21 13:12:51 +02:00
|
|
|
g_strfreev (list);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_address (s_ip6, addr))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate IP6 address");
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_address_unref (addr);
|
2013-10-21 13:12:51 +02:00
|
|
|
}
|
|
|
|
|
g_strfreev (list);
|
|
|
|
|
|
2014-10-20 21:30:56 -04:00
|
|
|
/* Gateway */
|
|
|
|
|
if (nm_setting_ip_config_get_num_addresses (s_ip6)) {
|
|
|
|
|
value = svGetValue (ifcfg, "IPV6_DEFAULTGW", FALSE);
|
|
|
|
|
if (!value) {
|
|
|
|
|
/* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */
|
|
|
|
|
network_ifcfg = svOpenFile (network_file, NULL);
|
|
|
|
|
if (network_ifcfg) {
|
|
|
|
|
value = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE);
|
|
|
|
|
svCloseFile (network_ifcfg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (value) {
|
|
|
|
|
char *ptr;
|
|
|
|
|
if ((ptr = strchr (value, '%')) != NULL)
|
|
|
|
|
*ptr = '\0'; /* remove %interface prefix if present */
|
|
|
|
|
if (!nm_utils_ipaddr_valid (AF_INET6, value)) {
|
|
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Invalid IP6 address '%s'", value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, value, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-08 20:38:41 +02:00
|
|
|
/* IPv6 addressing mode configuration */
|
|
|
|
|
tmp = svGetValue (ifcfg, "IPV6_ADDR_GEN_MODE", FALSE);
|
|
|
|
|
if (tmp) {
|
|
|
|
|
if (nm_utils_enum_from_str (nm_setting_ip6_config_addr_gen_mode_get_type (), tmp,
|
|
|
|
|
(int *) &addr_gen_mode, NULL))
|
|
|
|
|
g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, addr_gen_mode, NULL);
|
|
|
|
|
else
|
|
|
|
|
PARSE_WARNING ("Invalid IPV6_ADDR_GEN_MODE");
|
|
|
|
|
g_free (tmp);
|
2015-10-26 18:21:18 +01:00
|
|
|
} else {
|
|
|
|
|
g_object_set (s_ip6,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
|
|
|
|
|
NULL);
|
2015-09-08 20:38:41 +02:00
|
|
|
}
|
|
|
|
|
|
2010-01-05 19:05:01 -06:00
|
|
|
/* DNS servers
|
|
|
|
|
* Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting())
|
|
|
|
|
*/
|
2013-07-26 14:25:05 -05:00
|
|
|
for (i = 1; i <= 10; i++) {
|
2010-01-05 19:05:01 -06:00
|
|
|
char *tag;
|
|
|
|
|
|
|
|
|
|
tag = g_strdup_printf ("DNS%u", i);
|
|
|
|
|
value = svGetValue (ifcfg, tag, FALSE);
|
2013-07-26 14:25:05 -05:00
|
|
|
if (!value) {
|
|
|
|
|
g_free (tag);
|
|
|
|
|
break; /* all done */
|
|
|
|
|
}
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2014-09-16 16:42:46 -04:00
|
|
|
if (nm_utils_ipaddr_valid (AF_INET6, value)) {
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_dns (s_ip6, value))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate DNS server %s", tag);
|
2014-09-16 16:42:46 -04:00
|
|
|
} else if (nm_utils_ipaddr_valid (AF_INET, value)) {
|
|
|
|
|
/* Ignore IPv4 addresses */
|
2013-07-26 14:25:05 -05:00
|
|
|
} else {
|
2014-09-16 16:42:46 -04:00
|
|
|
PARSE_WARNING ("invalid DNS server address %s", value);
|
|
|
|
|
g_free (tag);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
2010-01-05 19:05:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_free (tag);
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
/* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2014-12-17 08:50:05 -05:00
|
|
|
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;
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2014-12-17 08:50:05 -05:00
|
|
|
g_free (route6_path);
|
|
|
|
|
}
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2015-03-26 14:56:00 +01:00
|
|
|
/* DNS options */
|
2015-05-20 14:29:49 +02:00
|
|
|
value = svGetValueFull (ifcfg, "RES_OPTIONS", FALSE);
|
2015-03-26 14:56:00 +01:00
|
|
|
parse_dns_options (s_ip6, value);
|
|
|
|
|
parse_dns_options (s_ip6, dns_options);
|
|
|
|
|
g_free (value);
|
|
|
|
|
g_free (dns_options);
|
|
|
|
|
|
2010-01-05 19:05:01 -06:00
|
|
|
return NM_SETTING (s_ip6);
|
|
|
|
|
|
|
|
|
|
error:
|
2015-03-26 14:56:00 +01:00
|
|
|
g_free (dns_options);
|
2013-07-26 14:25:05 -05:00
|
|
|
g_free (route6_path);
|
2010-01-05 19:05:01 -06:00
|
|
|
g_object_unref (s_ip6);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 10:34:36 -04:00
|
|
|
static void
|
|
|
|
|
check_if_bond_slave (shvarFile *ifcfg,
|
|
|
|
|
NMSettingConnection *s_con)
|
|
|
|
|
{
|
|
|
|
|
char *value;
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "MASTER", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, value, NULL);
|
|
|
|
|
g_object_set (s_con,
|
|
|
|
|
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME,
|
|
|
|
|
NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
2014-01-28 09:25:59 -05:00
|
|
|
|
|
|
|
|
/* We should be checking for SLAVE=yes as well, but NM used to not set that,
|
|
|
|
|
* so for backward-compatibility, we don't check.
|
|
|
|
|
*/
|
2012-09-19 10:34:36 -04:00
|
|
|
}
|
|
|
|
|
|
2013-07-25 15:36:47 +02:00
|
|
|
static void
|
|
|
|
|
check_if_team_slave (shvarFile *ifcfg,
|
|
|
|
|
NMSettingConnection *s_con)
|
|
|
|
|
{
|
|
|
|
|
char *value;
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "DEVICETYPE", FALSE);
|
|
|
|
|
if (!value)
|
|
|
|
|
return;
|
|
|
|
|
if (strcasecmp (value, TYPE_TEAM_PORT)) {
|
|
|
|
|
g_free (value);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
value = svGetValue (ifcfg, "TEAM_MASTER", FALSE);
|
|
|
|
|
if (!value)
|
|
|
|
|
return;
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, value, NULL);
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-26 16:21:37 -05:00
|
|
|
typedef struct {
|
|
|
|
|
const char *enable_key;
|
|
|
|
|
const char *advertise_key;
|
|
|
|
|
const char *willing_key;
|
|
|
|
|
const char *flags_prop;
|
|
|
|
|
} DcbFlagsProperty;
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
DCB_APP_FCOE_FLAGS = 0,
|
|
|
|
|
DCB_APP_ISCSI_FLAGS = 1,
|
|
|
|
|
DCB_APP_FIP_FLAGS = 2,
|
|
|
|
|
DCB_PFC_FLAGS = 3,
|
|
|
|
|
DCB_PG_FLAGS = 4,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static DcbFlagsProperty dcb_flags_props[] = {
|
2013-11-05 14:11:04 -06:00
|
|
|
{ KEY_DCB_APP_FCOE_ENABLE, KEY_DCB_APP_FCOE_ADVERTISE, KEY_DCB_APP_FCOE_WILLING, NM_SETTING_DCB_APP_FCOE_FLAGS },
|
|
|
|
|
{ KEY_DCB_APP_ISCSI_ENABLE, KEY_DCB_APP_ISCSI_ADVERTISE, KEY_DCB_APP_ISCSI_WILLING, NM_SETTING_DCB_APP_ISCSI_FLAGS },
|
|
|
|
|
{ KEY_DCB_APP_FIP_ENABLE, KEY_DCB_APP_FIP_ADVERTISE, KEY_DCB_APP_FIP_WILLING, NM_SETTING_DCB_APP_FIP_FLAGS },
|
|
|
|
|
{ KEY_DCB_PFC_ENABLE, KEY_DCB_PFC_ADVERTISE, KEY_DCB_PFC_WILLING, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS },
|
|
|
|
|
{ KEY_DCB_PG_ENABLE, KEY_DCB_PG_ADVERTISE, KEY_DCB_PG_WILLING, NM_SETTING_DCB_PRIORITY_GROUP_FLAGS },
|
2013-09-26 16:21:37 -05:00
|
|
|
{ NULL },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static NMSettingDcbFlags
|
|
|
|
|
read_dcb_flags (shvarFile *ifcfg, DcbFlagsProperty *property)
|
|
|
|
|
{
|
|
|
|
|
NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (ifcfg, property->enable_key, FALSE))
|
2013-09-26 16:21:37 -05:00
|
|
|
flags |= NM_SETTING_DCB_FLAG_ENABLE;
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (ifcfg, property->advertise_key, FALSE))
|
2013-09-26 16:21:37 -05:00
|
|
|
flags |= NM_SETTING_DCB_FLAG_ADVERTISE;
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (ifcfg, property->willing_key, FALSE))
|
2013-09-26 16:21:37 -05:00
|
|
|
flags |= NM_SETTING_DCB_FLAG_WILLING;
|
|
|
|
|
|
|
|
|
|
return flags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
read_dcb_app (shvarFile *ifcfg,
|
|
|
|
|
NMSettingDcb *s_dcb,
|
|
|
|
|
const char *app,
|
|
|
|
|
DcbFlagsProperty *flags_prop,
|
|
|
|
|
const char *priority_prop,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
|
|
|
|
|
char *tmp, *val;
|
|
|
|
|
gboolean success = TRUE;
|
|
|
|
|
int priority = -1;
|
|
|
|
|
|
|
|
|
|
flags = read_dcb_flags (ifcfg, flags_prop);
|
|
|
|
|
|
|
|
|
|
/* Priority */
|
|
|
|
|
tmp = g_strdup_printf ("DCB_APP_%s_PRIORITY", app);
|
|
|
|
|
val = svGetValue (ifcfg, tmp, FALSE);
|
|
|
|
|
if (val) {
|
|
|
|
|
success = get_int (val, &priority);
|
|
|
|
|
if (success)
|
|
|
|
|
success = (priority >= 0 && priority <= 7);
|
|
|
|
|
if (!success) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2013-09-26 16:21:37 -05:00
|
|
|
"Invalid %s value '%s' (expected 0 - 7)",
|
|
|
|
|
tmp, val);
|
|
|
|
|
}
|
|
|
|
|
g_free (val);
|
|
|
|
|
|
|
|
|
|
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring DCB %s priority; app not enabled", app);
|
2013-09-26 16:21:37 -05:00
|
|
|
}
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
g_object_set (G_OBJECT (s_dcb),
|
|
|
|
|
flags_prop->flags_prop, flags,
|
|
|
|
|
priority_prop, (guint) priority,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef void (*DcbSetBoolFunc) (NMSettingDcb *, guint, gboolean);
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
read_dcb_bool_array (shvarFile *ifcfg,
|
|
|
|
|
NMSettingDcb *s_dcb,
|
|
|
|
|
NMSettingDcbFlags flags,
|
|
|
|
|
const char *prop,
|
|
|
|
|
const char *desc,
|
|
|
|
|
DcbSetBoolFunc set_func,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
char *val;
|
|
|
|
|
gboolean success = FALSE;
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
val = svGetValue (ifcfg, prop, FALSE);
|
|
|
|
|
if (!val)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring %s; %s is not enabled", prop, desc);
|
2013-09-26 16:21:37 -05:00
|
|
|
success = TRUE;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val = g_strstrip (val);
|
|
|
|
|
if (strlen (val) != 8) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("%s value '%s' must be 8 characters long", prop, val);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"boolean array must be 8 characters");
|
2013-09-26 16:21:37 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* All characters must be either 0 or 1 */
|
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
|
if (val[i] != '0' && val[i] != '1') {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid %s value '%s': not all 0s and 1s", prop, val);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"invalid boolean digit");
|
2013-09-26 16:21:37 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
set_func (s_dcb, i, (val[i] == '1'));
|
|
|
|
|
}
|
|
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
g_free (val);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef void (*DcbSetUintFunc) (NMSettingDcb *, guint, guint);
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
read_dcb_uint_array (shvarFile *ifcfg,
|
|
|
|
|
NMSettingDcb *s_dcb,
|
|
|
|
|
NMSettingDcbFlags flags,
|
|
|
|
|
const char *prop,
|
|
|
|
|
const char *desc,
|
|
|
|
|
gboolean f_allowed,
|
|
|
|
|
DcbSetUintFunc set_func,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
char *val;
|
|
|
|
|
gboolean success = FALSE;
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
val = svGetValue (ifcfg, prop, FALSE);
|
|
|
|
|
if (!val)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring %s; %s is not enabled", prop, desc);
|
2013-09-26 16:21:37 -05:00
|
|
|
success = TRUE;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val = g_strstrip (val);
|
|
|
|
|
if (strlen (val) != 8) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("%s value '%s' must be 8 characters long", prop, val);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"uint array must be 8 characters");
|
2013-09-26 16:21:37 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* All characters must be either 0 - 7 or (optionally) f */
|
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
|
if (val[i] >= '0' && val[i] <= '7')
|
|
|
|
|
set_func (s_dcb, i, val[i] - '0');
|
|
|
|
|
else if (f_allowed && (val[i] == 'f' || val[i] == 'F'))
|
|
|
|
|
set_func (s_dcb, i, 15);
|
|
|
|
|
else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid %s value '%s': not 0 - 7%s",
|
|
|
|
|
prop, val, f_allowed ? " or 'f'" : "");
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"invalid uint digit");
|
2013-09-26 16:21:37 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
g_free (val);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
read_dcb_percent_array (shvarFile *ifcfg,
|
|
|
|
|
NMSettingDcb *s_dcb,
|
|
|
|
|
NMSettingDcbFlags flags,
|
|
|
|
|
const char *prop,
|
|
|
|
|
const char *desc,
|
|
|
|
|
gboolean sum_pct,
|
|
|
|
|
DcbSetUintFunc set_func,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
char *val;
|
|
|
|
|
gboolean success = FALSE;
|
|
|
|
|
char **split = NULL, **iter;
|
|
|
|
|
int tmp;
|
|
|
|
|
guint i, sum = 0;
|
|
|
|
|
|
|
|
|
|
val = svGetValue (ifcfg, prop, FALSE);
|
|
|
|
|
if (!val)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring %s; %s is not enabled", prop, desc);
|
2013-09-26 16:21:37 -05:00
|
|
|
success = TRUE;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val = g_strstrip (val);
|
|
|
|
|
split = g_strsplit_set (val, ",", 0);
|
|
|
|
|
if (!split || (g_strv_length (split) != 8)) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid %s percentage list value '%s'", prop, val);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"percent array must be 8 elements");
|
2013-09-26 16:21:37 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (iter = split, i = 0; iter && *iter; iter++, i++) {
|
|
|
|
|
if (!get_int (*iter, &tmp) || tmp < 0 || tmp > 100) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid %s percentage value '%s'", prop, *iter);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"invalid percent element");
|
2013-09-26 16:21:37 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
set_func (s_dcb, i, (guint) tmp);
|
|
|
|
|
sum += (guint) tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sum_pct && (sum != 100)) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("%s percentages do not equal 100%%", prop);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"invalid percentage sum");
|
2013-09-26 16:21:37 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
if (split)
|
|
|
|
|
g_strfreev (split);
|
|
|
|
|
g_free (val);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
make_dcb_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *network_file,
|
|
|
|
|
NMSetting **out_setting,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingDcb *s_dcb = NULL;
|
|
|
|
|
gboolean dcb_on;
|
|
|
|
|
NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
|
|
|
|
|
char *val;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (out_setting != NULL, FALSE);
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
dcb_on = !!svGetValueBoolean (ifcfg, "DCB", FALSE);
|
2013-09-26 16:21:37 -05:00
|
|
|
if (!dcb_on)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
|
|
|
|
g_assert (s_dcb);
|
|
|
|
|
|
|
|
|
|
/* FCOE */
|
|
|
|
|
if (!read_dcb_app (ifcfg, s_dcb, "FCOE",
|
|
|
|
|
&dcb_flags_props[DCB_APP_FCOE_FLAGS],
|
|
|
|
|
NM_SETTING_DCB_APP_FCOE_PRIORITY,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
if (nm_setting_dcb_get_app_fcoe_flags (s_dcb) & NM_SETTING_DCB_FLAG_ENABLE) {
|
2013-11-05 14:11:04 -06:00
|
|
|
val = svGetValue (ifcfg, KEY_DCB_APP_FCOE_MODE, FALSE);
|
2013-09-26 16:21:37 -05:00
|
|
|
if (val) {
|
|
|
|
|
if (strcmp (val, NM_SETTING_DCB_FCOE_MODE_FABRIC) == 0 ||
|
|
|
|
|
strcmp (val, NM_SETTING_DCB_FCOE_MODE_VN2VN) == 0)
|
|
|
|
|
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_FCOE_MODE, val, NULL);
|
|
|
|
|
else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid FCoE mode '%s'", val);
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"invalid FCoE mode");
|
2013-09-26 16:21:37 -05:00
|
|
|
g_free (val);
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
g_free (val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* iSCSI */
|
|
|
|
|
if (!read_dcb_app (ifcfg, s_dcb, "ISCSI",
|
|
|
|
|
&dcb_flags_props[DCB_APP_ISCSI_FLAGS],
|
|
|
|
|
NM_SETTING_DCB_APP_ISCSI_PRIORITY,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIP */
|
|
|
|
|
if (!read_dcb_app (ifcfg, s_dcb, "FIP",
|
|
|
|
|
&dcb_flags_props[DCB_APP_FIP_FLAGS],
|
|
|
|
|
NM_SETTING_DCB_APP_FIP_PRIORITY,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Priority Flow Control */
|
|
|
|
|
flags = read_dcb_flags (ifcfg, &dcb_flags_props[DCB_PFC_FLAGS]);
|
|
|
|
|
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, flags, NULL);
|
|
|
|
|
|
|
|
|
|
if (!read_dcb_bool_array (ifcfg,
|
|
|
|
|
s_dcb,
|
|
|
|
|
flags,
|
2013-11-05 14:11:04 -06:00
|
|
|
KEY_DCB_PFC_UP,
|
2013-09-26 16:21:37 -05:00
|
|
|
"PFC",
|
|
|
|
|
nm_setting_dcb_set_priority_flow_control,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Priority Groups */
|
|
|
|
|
flags = read_dcb_flags (ifcfg, &dcb_flags_props[DCB_PG_FLAGS]);
|
|
|
|
|
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, flags, NULL);
|
|
|
|
|
|
|
|
|
|
if (!read_dcb_uint_array (ifcfg,
|
|
|
|
|
s_dcb,
|
|
|
|
|
flags,
|
2013-11-05 14:11:04 -06:00
|
|
|
KEY_DCB_PG_ID,
|
2013-09-26 16:21:37 -05:00
|
|
|
"PGID",
|
|
|
|
|
TRUE,
|
|
|
|
|
nm_setting_dcb_set_priority_group_id,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Group bandwidth */
|
|
|
|
|
if (!read_dcb_percent_array (ifcfg,
|
|
|
|
|
s_dcb,
|
|
|
|
|
flags,
|
2013-11-05 14:11:04 -06:00
|
|
|
KEY_DCB_PG_PCT,
|
2013-09-26 16:21:37 -05:00
|
|
|
"PGPCT",
|
|
|
|
|
TRUE,
|
|
|
|
|
nm_setting_dcb_set_priority_group_bandwidth,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Priority bandwidth */
|
|
|
|
|
if (!read_dcb_percent_array (ifcfg,
|
|
|
|
|
s_dcb,
|
|
|
|
|
flags,
|
2013-11-05 14:11:04 -06:00
|
|
|
KEY_DCB_PG_UPPCT,
|
2013-09-26 16:21:37 -05:00
|
|
|
"UPPCT",
|
|
|
|
|
FALSE,
|
|
|
|
|
nm_setting_dcb_set_priority_bandwidth,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Strict Bandwidth */
|
|
|
|
|
if (!read_dcb_bool_array (ifcfg,
|
|
|
|
|
s_dcb,
|
|
|
|
|
flags,
|
2013-11-05 14:11:04 -06:00
|
|
|
KEY_DCB_PG_STRICT,
|
2013-09-26 16:21:37 -05:00
|
|
|
"STRICT",
|
|
|
|
|
nm_setting_dcb_set_priority_strict_bandwidth,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!read_dcb_uint_array (ifcfg,
|
|
|
|
|
s_dcb,
|
|
|
|
|
flags,
|
2013-11-05 14:11:04 -06:00
|
|
|
KEY_DCB_PG_UP2TC,
|
2013-09-26 16:21:37 -05:00
|
|
|
"UP2TC",
|
|
|
|
|
FALSE,
|
|
|
|
|
nm_setting_dcb_set_priority_traffic_class,
|
|
|
|
|
error)) {
|
|
|
|
|
g_object_unref (s_dcb);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*out_setting = NM_SETTING (s_dcb);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-29 12:57:44 +00:00
|
|
|
static gboolean
|
|
|
|
|
add_one_wep_key (shvarFile *ifcfg,
|
|
|
|
|
const char *shvar_key,
|
|
|
|
|
guint8 key_idx,
|
2010-04-23 14:20:10 -07:00
|
|
|
gboolean passphrase,
|
2008-05-11 20:20:52 +00:00
|
|
|
NMSettingWirelessSecurity *s_wsec,
|
2008-03-29 12:57:44 +00:00
|
|
|
GError **error)
|
2007-11-27 19:25:46 +00:00
|
|
|
{
|
|
|
|
|
char *key = NULL;
|
|
|
|
|
char *value = NULL;
|
2008-03-29 12:57:44 +00:00
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (shvar_key != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (key_idx <= 3, FALSE);
|
2008-05-11 20:20:52 +00:00
|
|
|
g_return_val_if_fail (s_wsec != NULL, FALSE);
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, shvar_key, FALSE);
|
2008-03-29 12:57:44 +00:00
|
|
|
if (!value || !strlen (value)) {
|
|
|
|
|
g_free (value);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
|
|
|
|
|
/* Validate keys */
|
2010-04-23 14:20:10 -07:00
|
|
|
if (passphrase) {
|
|
|
|
|
if (strlen (value) && strlen (value) < 64) {
|
|
|
|
|
key = g_strdup (value);
|
|
|
|
|
g_object_set (G_OBJECT (s_wsec),
|
|
|
|
|
NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE,
|
|
|
|
|
NM_WEP_KEY_TYPE_PASSPHRASE,
|
|
|
|
|
NULL);
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
2010-04-23 14:20:10 -07:00
|
|
|
} else {
|
|
|
|
|
if (strlen (value) == 10 || strlen (value) == 26) {
|
|
|
|
|
/* Hexadecimal WEP key */
|
|
|
|
|
char *p = value;
|
|
|
|
|
|
|
|
|
|
while (*p) {
|
|
|
|
|
if (!g_ascii_isxdigit (*p)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2010-04-23 14:20:10 -07:00
|
|
|
"Invalid hexadecimal WEP key.");
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
key = g_strdup (value);
|
2010-06-17 14:57:25 +02:00
|
|
|
} else if ( !strncmp (value, "s:", 2)
|
2010-04-23 14:20:10 -07:00
|
|
|
&& (strlen (value) == 7 || strlen (value) == 15)) {
|
2010-06-17 14:57:25 +02:00
|
|
|
/* ASCII key */
|
2010-04-23 14:20:10 -07:00
|
|
|
char *p = value + 2;
|
|
|
|
|
|
|
|
|
|
while (*p) {
|
2012-09-25 10:44:23 -04:00
|
|
|
if (!g_ascii_isprint ((int) (*p))) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2010-06-17 14:57:25 +02:00
|
|
|
"Invalid ASCII WEP key.");
|
2010-04-23 14:20:10 -07:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
p++;
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
|
|
|
|
|
2010-06-17 14:57:25 +02:00
|
|
|
/* Remove 's:' prefix.
|
|
|
|
|
* Don't convert to hex string. wpa_supplicant takes 'wep_key0' option over D-Bus as byte array
|
|
|
|
|
* and converts it to hex string itself. Even though we convert hex string keys into a bin string
|
|
|
|
|
* before passing to wpa_supplicant, this prevents two unnecessary conversions. And mainly,
|
|
|
|
|
* ASCII WEP key doesn't change to HEX WEP key in UI, which could confuse users.
|
|
|
|
|
*/
|
|
|
|
|
key = g_strdup (value + 2);
|
2010-04-23 14:20:10 -07:00
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
|
|
|
|
|
2008-03-29 12:57:44 +00:00
|
|
|
if (key) {
|
2008-10-30 14:45:55 +00:00
|
|
|
nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, key);
|
2011-04-14 16:56:20 +02:00
|
|
|
g_free (key);
|
2008-03-29 12:57:44 +00:00
|
|
|
success = TRUE;
|
2010-04-23 14:20:10 -07:00
|
|
|
} else
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Invalid WEP key length.");
|
2008-03-29 12:57:44 +00:00
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
out:
|
|
|
|
|
g_free (value);
|
2008-03-29 12:57:44 +00:00
|
|
|
return success;
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
|
|
|
|
|
2008-03-29 12:57:44 +00:00
|
|
|
static gboolean
|
2008-05-11 20:20:52 +00:00
|
|
|
read_wep_keys (shvarFile *ifcfg,
|
|
|
|
|
guint8 def_idx,
|
|
|
|
|
NMSettingWirelessSecurity *s_wsec,
|
|
|
|
|
GError **error)
|
2008-03-29 12:57:44 +00:00
|
|
|
{
|
2010-04-23 14:20:10 -07:00
|
|
|
/* Try hex/ascii keys first */
|
|
|
|
|
if (!add_one_wep_key (ifcfg, "KEY1", 0, FALSE, s_wsec, error))
|
2008-03-29 12:57:44 +00:00
|
|
|
return FALSE;
|
2010-04-23 14:20:10 -07:00
|
|
|
if (!add_one_wep_key (ifcfg, "KEY2", 1, FALSE, s_wsec, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (!add_one_wep_key (ifcfg, "KEY3", 2, FALSE, s_wsec, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (!add_one_wep_key (ifcfg, "KEY4", 3, FALSE, s_wsec, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (!add_one_wep_key (ifcfg, "KEY", def_idx, FALSE, s_wsec, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* And then passphrases */
|
|
|
|
|
if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE1", 0, TRUE, s_wsec, error))
|
2008-03-29 12:57:44 +00:00
|
|
|
return FALSE;
|
2010-04-23 14:20:10 -07:00
|
|
|
if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE2", 1, TRUE, s_wsec, error))
|
2008-03-29 12:57:44 +00:00
|
|
|
return FALSE;
|
2010-04-23 14:20:10 -07:00
|
|
|
if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE3", 2, TRUE, s_wsec, error))
|
2008-03-29 12:57:44 +00:00
|
|
|
return FALSE;
|
2010-04-23 14:20:10 -07:00
|
|
|
if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE4", 3, TRUE, s_wsec, error))
|
2008-03-29 12:57:44 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
static NMSettingSecretFlags
|
|
|
|
|
read_secret_flags (shvarFile *ifcfg, const char *flags_key)
|
|
|
|
|
{
|
|
|
|
|
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
|
|
|
|
|
char *val;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (flags_key != NULL, NM_SETTING_SECRET_FLAG_NONE);
|
|
|
|
|
g_return_val_if_fail (flags_key[0] != '\0', NM_SETTING_SECRET_FLAG_NONE);
|
|
|
|
|
g_return_val_if_fail (g_str_has_suffix (flags_key, "_FLAGS"), NM_SETTING_SECRET_FLAG_NONE);
|
|
|
|
|
|
|
|
|
|
val = svGetValue (ifcfg, flags_key, FALSE);
|
|
|
|
|
if (val) {
|
|
|
|
|
if (strstr (val, SECRET_FLAG_AGENT))
|
|
|
|
|
flags |= NM_SETTING_SECRET_FLAG_AGENT_OWNED;
|
|
|
|
|
if (strstr (val, SECRET_FLAG_NOT_SAVED))
|
|
|
|
|
flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED;
|
|
|
|
|
if (strstr (val, SECRET_FLAG_NOT_REQUIRED))
|
|
|
|
|
flags |= NM_SETTING_SECRET_FLAG_NOT_REQUIRED;
|
|
|
|
|
|
|
|
|
|
g_free (val);
|
|
|
|
|
}
|
|
|
|
|
return flags;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
static NMSetting *
|
2009-02-27 13:28:20 -05:00
|
|
|
make_wep_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
GError **error)
|
2007-11-27 19:25:46 +00:00
|
|
|
{
|
2011-02-28 17:47:29 -06:00
|
|
|
NMSettingWirelessSecurity *s_wsec;
|
2007-11-27 19:25:46 +00:00
|
|
|
char *value;
|
2008-02-07 Dan Williams <dcbw@redhat.com>
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (add_one_secret_to_hash): copy secrets out of the plugin-returned hash
table of secrets
- (connection_settings_get_secrets): consolidate error returns into
one place; use the new get_secrets() plugin interface function to
get secrets from the plugin itself rather than using GObject data
magic
* system-settings/src/main.c
- (connection_added_cb, connection_removed_cb, free_plugin_connections,
load_connections): keep a private list of the plugin-returned
connections, don't use the plugin's GSList
* system-settings/plugins/ifcfg-fedora/plugin.c
- (watch_path): watch the path, not the filename (duh)
- (reload_all_connections): use the direct hash/equal functions; the
ones for int aren't appropriate here
- (get_secrets, system_config_interface_init): implement the
get_secrets() function
- (build_one_connection, find_connection_by_path): ifcfg file path is
now in the connection's ConnectionData instead of being a GObject
data property
- (handle_profile_item_changed): ifcfg file path is now in the
connection's ConnectionData instead of being a GObject data property;
be sure to copy secrets over from the new connection to the existing
connection when updating the connection's settings
- (init): sc_plugin_inotify_init() returns success/fail, not the inotify
file descriptor
* system-settings/plugins/ifcfg-fedora/parser.c
system-settings/plugins/ifcfg-fedora/parser.h
- (connection_data_get, copy_one_cdata_secret, clear_one_cdata_secret,
connection_data_copy_secrets, connection_data_free,
connection_data_add): new functions; connection data manipulation
- (make_wireless_security_setting): stuff secrets into the
connection data, not as GObject data items; make sure to close
the keys ifcfg file
- (wireless_connection_from_ifcfg, wired_connection_from_ifcfg): add
connection data to the connection
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3299 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-02-07 20:11:31 +00:00
|
|
|
shvarFile *keys_ifcfg = NULL;
|
2008-03-29 12:57:44 +00:00
|
|
|
int default_key_idx = 0;
|
2011-02-28 17:51:52 -06:00
|
|
|
gboolean has_default_key = FALSE, success;
|
2011-03-03 12:29:37 -06:00
|
|
|
NMSettingSecretFlags key_flags;
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2011-02-28 17:47:29 -06:00
|
|
|
s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
|
|
|
|
|
g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL);
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "DEFAULTKEY", FALSE);
|
2007-11-27 19:25:46 +00:00
|
|
|
if (value) {
|
2008-03-29 12:57:44 +00:00
|
|
|
success = get_int (value, &default_key_idx);
|
|
|
|
|
if (success && (default_key_idx >= 1) && (default_key_idx <= 4)) {
|
2011-02-02 16:50:58 -06:00
|
|
|
has_default_key = TRUE;
|
2008-03-29 12:57:44 +00:00
|
|
|
default_key_idx--; /* convert to [0...3] */
|
2011-02-28 17:47:29 -06:00
|
|
|
g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, default_key_idx, NULL);
|
2008-03-29 12:57:44 +00:00
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2008-02-04 23:18:16 +00:00
|
|
|
"Invalid default WEP key '%s'", value);
|
2007-11-27 19:25:46 +00:00
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
/* Read WEP key flags */
|
|
|
|
|
key_flags = read_secret_flags (ifcfg, "WEP_KEY_FLAGS");
|
|
|
|
|
g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, key_flags, NULL);
|
2008-03-29 12:57:44 +00:00
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
/* Read keys in the ifcfg file if they are system-owned */
|
|
|
|
|
if (key_flags == NM_SETTING_SECRET_FLAG_NONE) {
|
|
|
|
|
if (!read_wep_keys (ifcfg, default_key_idx, s_wsec, error))
|
2008-03-29 12:57:44 +00:00
|
|
|
goto error;
|
2011-03-03 12:29:37 -06:00
|
|
|
|
|
|
|
|
/* Try to get keys from the "shadow" key file */
|
|
|
|
|
keys_ifcfg = utils_get_keys_ifcfg (file, FALSE);
|
|
|
|
|
if (keys_ifcfg) {
|
|
|
|
|
if (!read_wep_keys (keys_ifcfg, default_key_idx, s_wsec, error)) {
|
|
|
|
|
svCloseFile (keys_ifcfg);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
svCloseFile (keys_ifcfg);
|
|
|
|
|
g_assert (error == NULL || *error == NULL);
|
2008-04-02 17:39:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "SECURITYMODE", FALSE);
|
2007-11-27 19:25:46 +00:00
|
|
|
if (value) {
|
|
|
|
|
char *lcase;
|
|
|
|
|
|
|
|
|
|
lcase = g_ascii_strdown (value, -1);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
if (!strcmp (lcase, "open")) {
|
2011-02-28 17:47:29 -06:00
|
|
|
g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL);
|
2007-11-27 19:25:46 +00:00
|
|
|
} else if (!strcmp (lcase, "restricted")) {
|
2011-02-28 17:47:29 -06:00
|
|
|
g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", NULL);
|
2007-11-27 19:25:46 +00:00
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-26 16:57:55 -04:00
|
|
|
"Invalid WEP authentication algorithm '%s'",
|
2007-11-27 19:25:46 +00:00
|
|
|
lcase);
|
|
|
|
|
g_free (lcase);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (lcase);
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
/* If no WEP keys were given, and the keys are not agent-owned, and no
|
|
|
|
|
* default WEP key index was given, then the connection is unencrypted.
|
|
|
|
|
*/
|
2011-02-28 17:47:29 -06:00
|
|
|
if ( !nm_setting_wireless_security_get_wep_key (s_wsec, 0)
|
|
|
|
|
&& !nm_setting_wireless_security_get_wep_key (s_wsec, 1)
|
|
|
|
|
&& !nm_setting_wireless_security_get_wep_key (s_wsec, 2)
|
|
|
|
|
&& !nm_setting_wireless_security_get_wep_key (s_wsec, 3)
|
2011-03-03 12:29:37 -06:00
|
|
|
&& (has_default_key == FALSE)
|
|
|
|
|
&& (key_flags == NM_SETTING_SECRET_FLAG_NONE)) {
|
2008-10-30 14:45:55 +00:00
|
|
|
const char *auth_alg;
|
|
|
|
|
|
2011-02-28 17:47:29 -06:00
|
|
|
auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
|
2008-10-30 14:45:55 +00:00
|
|
|
if (auth_alg && !strcmp (auth_alg, "shared")) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2008-04-02 17:39:35 +00:00
|
|
|
"WEP Shared Key authentication is invalid for "
|
|
|
|
|
"unencrypted connections.");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2008-04-02 17:39:35 +00:00
|
|
|
/* Unencrypted */
|
2011-02-28 17:47:29 -06:00
|
|
|
g_object_unref (s_wsec);
|
|
|
|
|
s_wsec = NULL;
|
2008-04-02 17:39:35 +00:00
|
|
|
}
|
2008-02-07 Dan Williams <dcbw@redhat.com>
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (add_one_secret_to_hash): copy secrets out of the plugin-returned hash
table of secrets
- (connection_settings_get_secrets): consolidate error returns into
one place; use the new get_secrets() plugin interface function to
get secrets from the plugin itself rather than using GObject data
magic
* system-settings/src/main.c
- (connection_added_cb, connection_removed_cb, free_plugin_connections,
load_connections): keep a private list of the plugin-returned
connections, don't use the plugin's GSList
* system-settings/plugins/ifcfg-fedora/plugin.c
- (watch_path): watch the path, not the filename (duh)
- (reload_all_connections): use the direct hash/equal functions; the
ones for int aren't appropriate here
- (get_secrets, system_config_interface_init): implement the
get_secrets() function
- (build_one_connection, find_connection_by_path): ifcfg file path is
now in the connection's ConnectionData instead of being a GObject
data property
- (handle_profile_item_changed): ifcfg file path is now in the
connection's ConnectionData instead of being a GObject data property;
be sure to copy secrets over from the new connection to the existing
connection when updating the connection's settings
- (init): sc_plugin_inotify_init() returns success/fail, not the inotify
file descriptor
* system-settings/plugins/ifcfg-fedora/parser.c
system-settings/plugins/ifcfg-fedora/parser.h
- (connection_data_get, copy_one_cdata_secret, clear_one_cdata_secret,
connection_data_copy_secrets, connection_data_free,
connection_data_add): new functions; connection data manipulation
- (make_wireless_security_setting): stuff secrets into the
connection data, not as GObject data items; make sure to close
the keys ifcfg file
- (wireless_connection_from_ifcfg, wired_connection_from_ifcfg): add
connection data to the connection
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3299 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-02-07 20:11:31 +00:00
|
|
|
|
2011-02-28 17:47:29 -06:00
|
|
|
return (NMSetting *) s_wsec;
|
2007-11-27 19:25:46 +00:00
|
|
|
|
|
|
|
|
error:
|
2011-02-28 17:47:29 -06:00
|
|
|
if (s_wsec)
|
|
|
|
|
g_object_unref (s_wsec);
|
2007-11-27 19:25:46 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-27 13:28:20 -05:00
|
|
|
static gboolean
|
|
|
|
|
fill_wpa_ciphers (shvarFile *ifcfg,
|
|
|
|
|
NMSettingWirelessSecurity *wsec,
|
2009-03-01 19:04:55 -05:00
|
|
|
gboolean group,
|
|
|
|
|
gboolean adhoc)
|
2009-02-27 13:28:20 -05:00
|
|
|
{
|
|
|
|
|
char *value = NULL, *p;
|
|
|
|
|
char **list = NULL, **iter;
|
2009-03-01 19:04:55 -05:00
|
|
|
int i = 0;
|
2009-02-27 13:28:20 -05:00
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
p = value = svGetValue (ifcfg, group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", TRUE);
|
2009-02-27 13:28:20 -05:00
|
|
|
if (!value)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
/* Strip quotes */
|
|
|
|
|
if (p[0] == '"')
|
|
|
|
|
p++;
|
|
|
|
|
if (p[strlen (p) - 1] == '"')
|
|
|
|
|
p[strlen (p) - 1] = '\0';
|
|
|
|
|
|
|
|
|
|
list = g_strsplit_set (p, " ", 0);
|
2009-03-01 19:04:55 -05:00
|
|
|
for (iter = list; iter && *iter; iter++, i++) {
|
|
|
|
|
/* Ad-Hoc configurations cannot have pairwise ciphers, and can only
|
|
|
|
|
* have one group cipher. Ignore any additional group ciphers and
|
|
|
|
|
* any pairwise ciphers specified.
|
|
|
|
|
*/
|
|
|
|
|
if (adhoc) {
|
|
|
|
|
if (group && (i > 0)) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring group cipher '%s' (only one group cipher allowed "
|
|
|
|
|
"in Ad-Hoc mode)", *iter);
|
2009-03-01 19:04:55 -05:00
|
|
|
continue;
|
|
|
|
|
} else if (!group) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring pairwise cipher '%s' (pairwise not used "
|
|
|
|
|
"in Ad-Hoc mode)", *iter);
|
2009-03-01 19:04:55 -05:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-27 13:28:20 -05:00
|
|
|
if (!strcmp (*iter, "CCMP")) {
|
|
|
|
|
if (group)
|
|
|
|
|
nm_setting_wireless_security_add_group (wsec, "ccmp");
|
|
|
|
|
else
|
|
|
|
|
nm_setting_wireless_security_add_pairwise (wsec, "ccmp");
|
|
|
|
|
} else if (!strcmp (*iter, "TKIP")) {
|
|
|
|
|
if (group)
|
|
|
|
|
nm_setting_wireless_security_add_group (wsec, "tkip");
|
|
|
|
|
else
|
|
|
|
|
nm_setting_wireless_security_add_pairwise (wsec, "tkip");
|
|
|
|
|
} else if (group && !strcmp (*iter, "WEP104"))
|
|
|
|
|
nm_setting_wireless_security_add_group (wsec, "wep104");
|
|
|
|
|
else if (group && !strcmp (*iter, "WEP40"))
|
|
|
|
|
nm_setting_wireless_security_add_group (wsec, "wep40");
|
|
|
|
|
else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignoring invalid %s cipher '%s'",
|
|
|
|
|
group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE",
|
|
|
|
|
*iter);
|
2009-02-27 13:28:20 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (list)
|
|
|
|
|
g_strfreev (list);
|
|
|
|
|
g_free (value);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define WPA_PMK_LEN 32
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
parse_wpa_psk (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
2014-06-26 10:42:11 -04:00
|
|
|
GBytes *ssid,
|
2009-02-27 13:28:20 -05:00
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
shvarFile *keys_ifcfg;
|
|
|
|
|
char *psk = NULL, *p, *hashed = NULL;
|
2012-03-07 14:05:47 +01:00
|
|
|
size_t plen;
|
2009-12-16 13:29:01 -08:00
|
|
|
gboolean quoted = FALSE;
|
2009-02-27 13:28:20 -05:00
|
|
|
|
2010-09-25 00:34:10 -05:00
|
|
|
/* Passphrase must be between 10 and 66 characters in length because WPA
|
2009-02-27 13:28:20 -05:00
|
|
|
* hex keys are exactly 64 characters (no quoting), and WPA passphrases
|
|
|
|
|
* are between 8 and 63 characters (inclusive), plus optional quoting if
|
|
|
|
|
* the passphrase contains spaces.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Try to get keys from the "shadow" key file */
|
2009-03-26 16:57:55 -04:00
|
|
|
keys_ifcfg = utils_get_keys_ifcfg (file, FALSE);
|
2009-02-27 13:28:20 -05:00
|
|
|
if (keys_ifcfg) {
|
2009-03-01 19:04:55 -05:00
|
|
|
psk = svGetValue (keys_ifcfg, "WPA_PSK", TRUE);
|
2009-02-27 13:28:20 -05:00
|
|
|
svCloseFile (keys_ifcfg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fall back to the original ifcfg */
|
|
|
|
|
if (!psk)
|
2009-03-01 19:04:55 -05:00
|
|
|
psk = svGetValue (ifcfg, "WPA_PSK", TRUE);
|
2009-02-27 13:28:20 -05:00
|
|
|
|
2010-12-14 15:26:40 -06:00
|
|
|
if (!psk)
|
2009-02-27 13:28:20 -05:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
p = psk;
|
2012-03-07 14:05:47 +01:00
|
|
|
plen = strlen (p);
|
2009-02-27 13:28:20 -05:00
|
|
|
|
2012-03-07 14:05:47 +01:00
|
|
|
if ( (plen >= 2 && (p[0] == '"' || p[0] == '\'') && p[0] == p[plen - 1])
|
|
|
|
|
|| (plen >= 3 && p[0] == '$' && p[1] == '\'' && p[1] == p[plen - 1]))
|
2009-12-16 13:29:01 -08:00
|
|
|
quoted = TRUE;
|
2009-02-27 13:28:20 -05:00
|
|
|
|
2009-12-16 13:29:01 -08:00
|
|
|
if (!quoted && (strlen (psk) == 64)) {
|
2009-02-27 13:28:20 -05:00
|
|
|
/* Verify the hex PSK; 64 digits */
|
|
|
|
|
while (*p) {
|
2012-09-25 10:44:23 -04:00
|
|
|
if (!g_ascii_isxdigit (*p++)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-02-27 13:28:20 -05:00
|
|
|
"Invalid WPA_PSK (contains non-hexadecimal characters)");
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
hashed = g_strdup (psk);
|
|
|
|
|
} else {
|
2009-12-16 13:29:01 -08:00
|
|
|
/* Prior to 4f6eef9e77265484555663cf666cde4fa8323469 and
|
|
|
|
|
* 28e2e446868b94b92edc4a82aa0bf1e3eda8ec54 the writer may not have
|
|
|
|
|
* properly quoted passphrases, so just handle anything that's unquoted
|
|
|
|
|
* and between 8 and 63 characters as a passphrase.
|
|
|
|
|
*/
|
|
|
|
|
|
2012-03-07 14:05:47 +01:00
|
|
|
/* Get rid of the quotes */
|
|
|
|
|
hashed = utils_single_unquote_string (p);
|
2009-12-16 13:29:01 -08:00
|
|
|
|
|
|
|
|
/* Length check */
|
2012-03-07 14:05:47 +01:00
|
|
|
if (strlen (hashed) < 8 || strlen (hashed) > 63) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-12-16 13:29:01 -08:00
|
|
|
"Invalid WPA_PSK (passphrases must be between "
|
|
|
|
|
"8 and 63 characters long (inclusive))");
|
2012-03-07 14:05:47 +01:00
|
|
|
g_free (hashed);
|
|
|
|
|
hashed = NULL;
|
2009-12-16 13:29:01 -08:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!hashed) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-02-27 13:28:20 -05:00
|
|
|
"Invalid WPA_PSK (doesn't look like a passphrase or hex key)");
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
g_free (psk);
|
|
|
|
|
return hashed;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-09 10:51:07 -04:00
|
|
|
static gboolean
|
2009-03-10 09:04:15 -04:00
|
|
|
eap_simple_reader (const char *eap_method,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
shvarFile *keys,
|
|
|
|
|
NMSetting8021x *s_8021x,
|
|
|
|
|
gboolean phase2,
|
|
|
|
|
GError **error)
|
2009-03-09 10:51:07 -04:00
|
|
|
{
|
2011-03-03 12:29:37 -06:00
|
|
|
NMSettingSecretFlags flags;
|
2009-03-10 09:04:15 -04:00
|
|
|
char *value;
|
2009-03-09 10:51:07 -04:00
|
|
|
|
2009-03-10 09:04:15 -04:00
|
|
|
value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE);
|
|
|
|
|
if (!value) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:04:15 -04:00
|
|
|
"Missing IEEE_8021X_IDENTITY for EAP method '%s'.",
|
|
|
|
|
eap_method);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS");
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_FLAGS, flags, NULL);
|
2009-03-09 10:51:07 -04:00
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
/* Only read the password if it's system-owned */
|
|
|
|
|
if (flags == NM_SETTING_SECRET_FLAG_NONE) {
|
|
|
|
|
value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE);
|
|
|
|
|
if (!value && keys) {
|
|
|
|
|
/* Try the lookaside keys file */
|
|
|
|
|
value = svGetValue (keys, "IEEE_8021X_PASSWORD", FALSE);
|
|
|
|
|
}
|
2009-03-10 09:04:15 -04:00
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
if (!value) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2011-03-03 12:29:37 -06:00
|
|
|
"Missing IEEE_8021X_PASSWORD for EAP method '%s'.",
|
|
|
|
|
eap_method);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
2009-03-10 09:04:15 -04:00
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-10 18:23:13 -04:00
|
|
|
static char *
|
2012-01-23 13:53:08 +01:00
|
|
|
get_full_file_path (const char *ifcfg_path, const char *file_path)
|
2009-03-10 18:23:13 -04:00
|
|
|
{
|
2012-01-23 13:53:08 +01:00
|
|
|
const char *base = file_path;
|
2009-03-10 18:23:13 -04:00
|
|
|
char *p, *ret, *dirname;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (ifcfg_path != NULL, NULL);
|
2012-01-23 13:53:08 +01:00
|
|
|
g_return_val_if_fail (file_path != NULL, NULL);
|
2009-03-10 18:23:13 -04:00
|
|
|
|
2012-01-23 13:53:08 +01:00
|
|
|
if (file_path[0] == '/')
|
|
|
|
|
return g_strdup (file_path);
|
2009-03-10 18:23:13 -04:00
|
|
|
|
2012-01-23 13:53:08 +01:00
|
|
|
p = strrchr (file_path, '/');
|
2009-03-10 18:23:13 -04:00
|
|
|
if (p)
|
2009-04-21 18:12:41 -04:00
|
|
|
base = p + 1;
|
2009-03-10 18:23:13 -04:00
|
|
|
|
|
|
|
|
dirname = g_path_get_dirname (ifcfg_path);
|
2009-04-21 18:12:41 -04:00
|
|
|
ret = g_build_path ("/", dirname, base, NULL);
|
2009-03-10 18:23:13 -04:00
|
|
|
g_free (dirname);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-10 09:04:15 -04:00
|
|
|
static gboolean
|
|
|
|
|
eap_tls_reader (const char *eap_method,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
shvarFile *keys,
|
|
|
|
|
NMSetting8021x *s_8021x,
|
|
|
|
|
gboolean phase2,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2009-03-31 07:29:31 -04:00
|
|
|
char *value;
|
2009-03-10 09:04:15 -04:00
|
|
|
char *ca_cert = NULL;
|
2009-03-11 14:49:27 -04:00
|
|
|
char *real_path = NULL;
|
2009-03-10 09:04:15 -04:00
|
|
|
char *client_cert = NULL;
|
|
|
|
|
char *privkey = NULL;
|
|
|
|
|
char *privkey_password = NULL;
|
|
|
|
|
gboolean success = FALSE;
|
2009-09-04 09:07:00 -05:00
|
|
|
NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
|
2011-02-28 17:50:32 -06:00
|
|
|
const char *ca_cert_key = phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT";
|
|
|
|
|
const char *pk_pw_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD": "IEEE_8021X_PRIVATE_KEY_PASSWORD";
|
|
|
|
|
const char *pk_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY";
|
|
|
|
|
const char *cli_cert_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT";
|
2011-03-03 12:29:37 -06:00
|
|
|
const char *pk_pw_flags_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS": "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS";
|
2011-03-03 17:32:29 -06:00
|
|
|
const char *pk_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS;
|
2011-03-03 12:29:37 -06:00
|
|
|
NMSettingSecretFlags flags;
|
2009-03-10 09:04:15 -04:00
|
|
|
|
2009-03-31 07:29:31 -04:00
|
|
|
value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE);
|
|
|
|
|
if (!value) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-31 07:29:31 -04:00
|
|
|
"Missing IEEE_8021X_IDENTITY for EAP method '%s'.",
|
|
|
|
|
eap_method);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2011-02-28 17:50:32 -06:00
|
|
|
ca_cert = svGetValue (ifcfg, ca_cert_key, FALSE);
|
2009-03-10 09:04:15 -04:00
|
|
|
if (ca_cert) {
|
2012-01-23 13:53:08 +01:00
|
|
|
real_path = get_full_file_path (ifcfg->fileName, ca_cert);
|
2009-03-10 09:04:15 -04:00
|
|
|
if (phase2) {
|
2009-09-04 09:07:00 -05:00
|
|
|
if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x,
|
|
|
|
|
real_path,
|
|
|
|
|
NM_SETTING_802_1X_CK_SCHEME_PATH,
|
|
|
|
|
NULL,
|
|
|
|
|
error))
|
2009-03-10 09:04:15 -04:00
|
|
|
goto done;
|
|
|
|
|
} else {
|
2009-09-04 09:07:00 -05:00
|
|
|
if (!nm_setting_802_1x_set_ca_cert (s_8021x,
|
|
|
|
|
real_path,
|
|
|
|
|
NM_SETTING_802_1X_CK_SCHEME_PATH,
|
|
|
|
|
NULL,
|
|
|
|
|
error))
|
2009-03-10 09:04:15 -04:00
|
|
|
goto done;
|
|
|
|
|
}
|
2011-03-03 12:29:37 -06:00
|
|
|
g_free (real_path);
|
|
|
|
|
real_path = NULL;
|
2009-03-10 09:04:15 -04:00
|
|
|
} else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("missing %s for EAP method '%s'; this is insecure!",
|
|
|
|
|
ca_cert_key, eap_method);
|
2009-03-10 09:04:15 -04:00
|
|
|
}
|
|
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
/* Read and set private key password flags */
|
|
|
|
|
flags = read_secret_flags (ifcfg, pk_pw_flags_key);
|
2011-03-03 17:32:29 -06:00
|
|
|
g_object_set (s_8021x, pk_pw_flags_prop, flags, NULL);
|
2009-03-10 09:04:15 -04:00
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
/* Read the private key password if it's system-owned */
|
|
|
|
|
if (flags == NM_SETTING_SECRET_FLAG_NONE) {
|
|
|
|
|
/* Private key password */
|
|
|
|
|
privkey_password = svGetValue (ifcfg, pk_pw_key, FALSE);
|
|
|
|
|
if (!privkey_password && keys) {
|
|
|
|
|
/* Try the lookaside keys file */
|
|
|
|
|
privkey_password = svGetValue (keys, pk_pw_key, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!privkey_password) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2011-03-03 12:29:37 -06:00
|
|
|
"Missing %s for EAP method '%s'.",
|
|
|
|
|
pk_pw_key,
|
|
|
|
|
eap_method);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
2009-03-10 09:04:15 -04:00
|
|
|
}
|
|
|
|
|
|
2009-03-11 14:49:27 -04:00
|
|
|
/* The private key itself */
|
2011-02-28 17:50:32 -06:00
|
|
|
privkey = svGetValue (ifcfg, pk_key, FALSE);
|
2009-03-10 09:04:15 -04:00
|
|
|
if (!privkey) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:04:15 -04:00
|
|
|
"Missing %s for EAP method '%s'.",
|
2011-02-28 17:50:32 -06:00
|
|
|
pk_key,
|
2009-03-10 09:04:15 -04:00
|
|
|
eap_method);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-23 13:53:08 +01:00
|
|
|
real_path = get_full_file_path (ifcfg->fileName, privkey);
|
2009-03-10 09:04:15 -04:00
|
|
|
if (phase2) {
|
2009-09-04 09:07:00 -05:00
|
|
|
if (!nm_setting_802_1x_set_phase2_private_key (s_8021x,
|
|
|
|
|
real_path,
|
|
|
|
|
privkey_password,
|
2011-03-03 12:29:37 -06:00
|
|
|
NM_SETTING_802_1X_CK_SCHEME_PATH,
|
2009-09-04 09:07:00 -05:00
|
|
|
&privkey_format,
|
|
|
|
|
error))
|
2009-03-10 09:04:15 -04:00
|
|
|
goto done;
|
|
|
|
|
} else {
|
2009-09-04 09:07:00 -05:00
|
|
|
if (!nm_setting_802_1x_set_private_key (s_8021x,
|
|
|
|
|
real_path,
|
|
|
|
|
privkey_password,
|
2011-03-03 12:29:37 -06:00
|
|
|
NM_SETTING_802_1X_CK_SCHEME_PATH,
|
2009-09-04 09:07:00 -05:00
|
|
|
&privkey_format,
|
|
|
|
|
error))
|
2009-03-10 09:04:15 -04:00
|
|
|
goto done;
|
|
|
|
|
}
|
2011-03-03 12:29:37 -06:00
|
|
|
g_free (real_path);
|
|
|
|
|
real_path = NULL;
|
2009-03-10 09:04:15 -04:00
|
|
|
|
2009-09-04 09:07:00 -05:00
|
|
|
/* Only set the client certificate if the private key is not PKCS#12 format,
|
|
|
|
|
* as NM (due to supplicant restrictions) requires. If the key was PKCS#12,
|
|
|
|
|
* then nm_setting_802_1x_set_private_key() already set the client certificate
|
|
|
|
|
* to the same value as the private key.
|
2009-03-10 09:04:15 -04:00
|
|
|
*/
|
2009-09-04 09:07:00 -05:00
|
|
|
if ( privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY
|
|
|
|
|
|| privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) {
|
2011-02-28 17:50:32 -06:00
|
|
|
client_cert = svGetValue (ifcfg, cli_cert_key, FALSE);
|
2009-03-10 09:04:15 -04:00
|
|
|
if (!client_cert) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:04:15 -04:00
|
|
|
"Missing %s for EAP method '%s'.",
|
2011-02-28 17:50:32 -06:00
|
|
|
cli_cert_key,
|
2009-03-10 09:04:15 -04:00
|
|
|
eap_method);
|
|
|
|
|
goto done;
|
2009-03-09 10:51:07 -04:00
|
|
|
}
|
|
|
|
|
|
2012-01-23 13:53:08 +01:00
|
|
|
real_path = get_full_file_path (ifcfg->fileName, client_cert);
|
2009-03-10 09:04:15 -04:00
|
|
|
if (phase2) {
|
2009-09-04 09:07:00 -05:00
|
|
|
if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x,
|
|
|
|
|
real_path,
|
|
|
|
|
NM_SETTING_802_1X_CK_SCHEME_PATH,
|
|
|
|
|
NULL,
|
|
|
|
|
error))
|
2009-03-10 09:04:15 -04:00
|
|
|
goto done;
|
|
|
|
|
} else {
|
2009-09-04 09:07:00 -05:00
|
|
|
if (!nm_setting_802_1x_set_client_cert (s_8021x,
|
|
|
|
|
real_path,
|
|
|
|
|
NM_SETTING_802_1X_CK_SCHEME_PATH,
|
|
|
|
|
NULL,
|
|
|
|
|
error))
|
2009-03-10 09:04:15 -04:00
|
|
|
goto done;
|
2009-03-09 10:51:07 -04:00
|
|
|
}
|
2011-03-03 12:29:37 -06:00
|
|
|
g_free (real_path);
|
|
|
|
|
real_path = NULL;
|
2009-03-10 09:04:15 -04:00
|
|
|
}
|
2009-03-09 10:51:07 -04:00
|
|
|
|
2009-03-10 09:04:15 -04:00
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
done:
|
2009-03-11 14:49:27 -04:00
|
|
|
g_free (real_path);
|
2009-03-10 09:04:15 -04:00
|
|
|
g_free (ca_cert);
|
|
|
|
|
g_free (client_cert);
|
|
|
|
|
g_free (privkey);
|
|
|
|
|
g_free (privkey_password);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
eap_peap_reader (const char *eap_method,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
shvarFile *keys,
|
|
|
|
|
NMSetting8021x *s_8021x,
|
|
|
|
|
gboolean phase2,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2011-07-15 11:28:27 +02:00
|
|
|
char *anon_ident = NULL;
|
2009-03-10 09:04:15 -04:00
|
|
|
char *ca_cert = NULL;
|
2009-03-10 18:23:13 -04:00
|
|
|
char *real_cert_path = NULL;
|
2009-03-10 09:04:15 -04:00
|
|
|
char *inner_auth = NULL;
|
|
|
|
|
char *peapver = NULL;
|
2009-03-10 18:23:13 -04:00
|
|
|
char *lower;
|
2009-03-10 09:04:15 -04:00
|
|
|
char **list = NULL, **iter;
|
|
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
|
|
|
|
ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE);
|
|
|
|
|
if (ca_cert) {
|
2012-01-23 13:53:08 +01:00
|
|
|
real_cert_path = get_full_file_path (ifcfg->fileName, ca_cert);
|
2009-09-04 09:07:00 -05:00
|
|
|
if (!nm_setting_802_1x_set_ca_cert (s_8021x,
|
|
|
|
|
real_cert_path,
|
|
|
|
|
NM_SETTING_802_1X_CK_SCHEME_PATH,
|
|
|
|
|
NULL,
|
|
|
|
|
error))
|
2009-03-10 09:04:15 -04:00
|
|
|
goto done;
|
|
|
|
|
} else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("missing IEEE_8021X_CA_CERT for EAP method '%s'; this is insecure!",
|
|
|
|
|
eap_method);
|
2009-03-10 09:04:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
peapver = svGetValue (ifcfg, "IEEE_8021X_PEAP_VERSION", FALSE);
|
|
|
|
|
if (peapver) {
|
|
|
|
|
if (!strcmp (peapver, "0"))
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "0", NULL);
|
|
|
|
|
else if (!strcmp (peapver, "1"))
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL);
|
|
|
|
|
else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:04:15 -04:00
|
|
|
"Unknown IEEE_8021X_PEAP_VERSION value '%s'",
|
|
|
|
|
peapver);
|
|
|
|
|
goto done;
|
2009-03-09 10:51:07 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", FALSE))
|
2009-03-10 09:04:15 -04:00
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", NULL);
|
|
|
|
|
|
2011-07-15 11:28:27 +02:00
|
|
|
anon_ident = svGetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY", FALSE);
|
|
|
|
|
if (anon_ident && strlen (anon_ident))
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL);
|
|
|
|
|
|
2009-03-10 09:04:15 -04:00
|
|
|
inner_auth = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE);
|
|
|
|
|
if (!inner_auth) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:04:15 -04:00
|
|
|
"Missing IEEE_8021X_INNER_AUTH_METHODS.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Handle options for the inner auth method */
|
|
|
|
|
list = g_strsplit (inner_auth, " ", 0);
|
|
|
|
|
for (iter = list; iter && *iter; iter++) {
|
|
|
|
|
if (!strlen (*iter))
|
|
|
|
|
continue;
|
|
|
|
|
|
2009-07-29 14:08:54 -04:00
|
|
|
if ( !strcmp (*iter, "MSCHAPV2")
|
|
|
|
|
|| !strcmp (*iter, "MD5")
|
|
|
|
|
|| !strcmp (*iter, "GTC")) {
|
2009-03-10 09:04:15 -04:00
|
|
|
if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
|
|
|
|
|
goto done;
|
|
|
|
|
} else if (!strcmp (*iter, "TLS")) {
|
|
|
|
|
if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
|
|
|
|
|
goto done;
|
2009-03-10 09:46:40 -04:00
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:46:40 -04:00
|
|
|
"Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
|
|
|
|
|
*iter);
|
|
|
|
|
goto done;
|
2009-03-10 09:04:15 -04:00
|
|
|
}
|
2009-03-10 09:46:40 -04:00
|
|
|
|
2009-03-10 18:23:13 -04:00
|
|
|
lower = g_ascii_strdown (*iter, -1);
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, NULL);
|
|
|
|
|
g_free (lower);
|
2009-03-10 09:04:15 -04:00
|
|
|
break;
|
2009-03-09 10:51:07 -04:00
|
|
|
}
|
|
|
|
|
|
2009-03-10 18:23:13 -04:00
|
|
|
if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 18:23:13 -04:00
|
|
|
"No valid IEEE_8021X_INNER_AUTH_METHODS found.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-10 09:04:15 -04:00
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
if (list)
|
|
|
|
|
g_strfreev (list);
|
|
|
|
|
g_free (inner_auth);
|
|
|
|
|
g_free (peapver);
|
2009-03-10 18:23:13 -04:00
|
|
|
g_free (real_cert_path);
|
2009-03-10 09:04:15 -04:00
|
|
|
g_free (ca_cert);
|
2011-07-15 11:28:27 +02:00
|
|
|
g_free (anon_ident);
|
2009-03-10 09:04:15 -04:00
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
eap_ttls_reader (const char *eap_method,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
shvarFile *keys,
|
|
|
|
|
NMSetting8021x *s_8021x,
|
|
|
|
|
gboolean phase2,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2009-03-10 09:46:40 -04:00
|
|
|
gboolean success = FALSE;
|
|
|
|
|
char *anon_ident = NULL;
|
|
|
|
|
char *ca_cert = NULL;
|
2009-03-10 18:23:13 -04:00
|
|
|
char *real_cert_path = NULL;
|
2009-03-10 09:46:40 -04:00
|
|
|
char *inner_auth = NULL;
|
2009-03-16 12:06:59 -04:00
|
|
|
char *tmp;
|
2009-03-10 09:46:40 -04:00
|
|
|
char **list = NULL, **iter;
|
|
|
|
|
|
|
|
|
|
ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE);
|
|
|
|
|
if (ca_cert) {
|
2012-01-23 13:53:08 +01:00
|
|
|
real_cert_path = get_full_file_path (ifcfg->fileName, ca_cert);
|
2009-09-04 09:07:00 -05:00
|
|
|
if (!nm_setting_802_1x_set_ca_cert (s_8021x,
|
|
|
|
|
real_cert_path,
|
|
|
|
|
NM_SETTING_802_1X_CK_SCHEME_PATH,
|
|
|
|
|
NULL,
|
|
|
|
|
error))
|
2009-03-10 09:46:40 -04:00
|
|
|
goto done;
|
|
|
|
|
} else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("missing IEEE_8021X_CA_CERT for EAP method '%s'; this is insecure!",
|
|
|
|
|
eap_method);
|
2009-03-10 09:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
anon_ident = svGetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY", FALSE);
|
|
|
|
|
if (anon_ident && strlen (anon_ident))
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL);
|
|
|
|
|
|
2009-03-16 12:06:59 -04:00
|
|
|
tmp = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE);
|
|
|
|
|
if (!tmp) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:46:40 -04:00
|
|
|
"Missing IEEE_8021X_INNER_AUTH_METHODS.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-16 12:06:59 -04:00
|
|
|
inner_auth = g_ascii_strdown (tmp, -1);
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
|
2009-03-10 09:46:40 -04:00
|
|
|
/* Handle options for the inner auth method */
|
|
|
|
|
list = g_strsplit (inner_auth, " ", 0);
|
|
|
|
|
for (iter = list; iter && *iter; iter++) {
|
|
|
|
|
if (!strlen (*iter))
|
|
|
|
|
continue;
|
|
|
|
|
|
2009-03-16 12:06:59 -04:00
|
|
|
if ( !strcmp (*iter, "mschapv2")
|
|
|
|
|
|| !strcmp (*iter, "mschap")
|
|
|
|
|
|| !strcmp (*iter, "pap")
|
|
|
|
|
|| !strcmp (*iter, "chap")) {
|
2009-03-10 09:46:40 -04:00
|
|
|
if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
|
|
|
|
|
goto done;
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, *iter, NULL);
|
2009-03-16 12:06:59 -04:00
|
|
|
} else if (!strcmp (*iter, "eap-tls")) {
|
2009-03-10 09:46:40 -04:00
|
|
|
if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
|
|
|
|
|
goto done;
|
2009-03-16 12:06:59 -04:00
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", NULL);
|
2014-07-03 13:49:14 -05:00
|
|
|
} else if ( !strcmp (*iter, "eap-mschapv2")
|
|
|
|
|
|| !strcmp (*iter, "eap-md5")
|
|
|
|
|
|| !strcmp (*iter, "eap-gtc")) {
|
2009-03-10 09:46:40 -04:00
|
|
|
if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
|
|
|
|
|
goto done;
|
2014-07-03 13:49:14 -05:00
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, (*iter + STRLEN ("eap-")), NULL);
|
2009-03-10 09:46:40 -04:00
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:46:40 -04:00
|
|
|
"Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
|
|
|
|
|
*iter);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
if (list)
|
|
|
|
|
g_strfreev (list);
|
|
|
|
|
g_free (inner_auth);
|
2009-03-10 18:23:13 -04:00
|
|
|
g_free (real_cert_path);
|
2009-03-10 09:46:40 -04:00
|
|
|
g_free (ca_cert);
|
|
|
|
|
g_free (anon_ident);
|
|
|
|
|
return success;
|
2009-03-09 10:51:07 -04:00
|
|
|
}
|
|
|
|
|
|
2012-01-23 13:53:08 +01:00
|
|
|
static gboolean
|
|
|
|
|
eap_fast_reader (const char *eap_method,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
shvarFile *keys,
|
|
|
|
|
NMSetting8021x *s_8021x,
|
|
|
|
|
gboolean phase2,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
char *anon_ident = NULL;
|
|
|
|
|
char *pac_file = NULL;
|
|
|
|
|
char *real_pac_path = NULL;
|
|
|
|
|
char *inner_auth = NULL;
|
|
|
|
|
char *fast_provisioning = NULL;
|
|
|
|
|
char *lower;
|
|
|
|
|
char **list = NULL, **iter;
|
|
|
|
|
const char* pac_prov_str;
|
|
|
|
|
gboolean allow_unauth = FALSE, allow_auth = FALSE;
|
|
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
|
|
|
|
pac_file = svGetValue (ifcfg, "IEEE_8021X_PAC_FILE", FALSE);
|
|
|
|
|
if (pac_file) {
|
|
|
|
|
real_pac_path = get_full_file_path (ifcfg->fileName, pac_file);
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PAC_FILE, real_pac_path, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fast_provisioning = svGetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", FALSE);
|
|
|
|
|
if (fast_provisioning) {
|
|
|
|
|
list = g_strsplit_set (fast_provisioning, " \t", 0);
|
|
|
|
|
for (iter = list; iter && *iter; iter++) {
|
|
|
|
|
if (**iter == '\0')
|
|
|
|
|
continue;
|
|
|
|
|
if (strcmp (*iter, "allow-unauth") == 0)
|
|
|
|
|
allow_unauth = TRUE;
|
|
|
|
|
else if (strcmp (*iter, "allow-auth") == 0)
|
|
|
|
|
allow_auth = TRUE;
|
|
|
|
|
else {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid IEEE_8021X_FAST_PROVISIONING '%s' "
|
|
|
|
|
"(space-separated list of these values [allow-auth, allow-unauth] expected)",
|
|
|
|
|
*iter);
|
2012-01-23 13:53:08 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_strfreev (list);
|
|
|
|
|
list = NULL;
|
|
|
|
|
}
|
|
|
|
|
pac_prov_str = allow_unauth ? (allow_auth ? "3" : "1") : (allow_auth ? "2" : "0");
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, pac_prov_str, NULL);
|
|
|
|
|
|
|
|
|
|
if (!pac_file && !(allow_unauth || allow_auth)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2012-01-23 13:53:08 +01:00
|
|
|
"IEEE_8021X_PAC_FILE not provided and EAP-FAST automatic PAC provisioning disabled.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
anon_ident = svGetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY", FALSE);
|
|
|
|
|
if (anon_ident && strlen (anon_ident))
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL);
|
|
|
|
|
|
|
|
|
|
inner_auth = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE);
|
|
|
|
|
if (!inner_auth) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2012-01-23 13:53:08 +01:00
|
|
|
"Missing IEEE_8021X_INNER_AUTH_METHODS.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Handle options for the inner auth method */
|
|
|
|
|
list = g_strsplit (inner_auth, " ", 0);
|
|
|
|
|
for (iter = list; iter && *iter; iter++) {
|
|
|
|
|
if (!strlen (*iter))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if ( !strcmp (*iter, "MSCHAPV2")
|
|
|
|
|
|| !strcmp (*iter, "GTC")) {
|
|
|
|
|
if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
|
|
|
|
|
goto done;
|
|
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2012-01-23 13:53:08 +01:00
|
|
|
"Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
|
|
|
|
|
*iter);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lower = g_ascii_strdown (*iter, -1);
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, NULL);
|
|
|
|
|
g_free (lower);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2012-01-23 13:53:08 +01:00
|
|
|
"No valid IEEE_8021X_INNER_AUTH_METHODS found.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
g_strfreev (list);
|
|
|
|
|
g_free (inner_auth);
|
|
|
|
|
g_free (fast_provisioning);
|
|
|
|
|
g_free (real_pac_path);
|
|
|
|
|
g_free (pac_file);
|
|
|
|
|
g_free (anon_ident);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-28 16:07:36 -06:00
|
|
|
typedef struct {
|
|
|
|
|
const char *method;
|
|
|
|
|
gboolean (*reader)(const char *eap_method,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
shvarFile *keys,
|
|
|
|
|
NMSetting8021x *s_8021x,
|
|
|
|
|
gboolean phase2,
|
|
|
|
|
GError **error);
|
|
|
|
|
gboolean wifi_phase2_only;
|
|
|
|
|
} EAPReader;
|
|
|
|
|
|
|
|
|
|
static EAPReader eap_readers[] = {
|
|
|
|
|
{ "md5", eap_simple_reader, TRUE },
|
|
|
|
|
{ "pap", eap_simple_reader, TRUE },
|
|
|
|
|
{ "chap", eap_simple_reader, TRUE },
|
|
|
|
|
{ "mschap", eap_simple_reader, TRUE },
|
|
|
|
|
{ "mschapv2", eap_simple_reader, TRUE },
|
2011-03-14 00:25:14 -05:00
|
|
|
{ "leap", eap_simple_reader, FALSE },
|
2013-09-18 19:17:34 +01:00
|
|
|
{ "pwd", eap_simple_reader, FALSE },
|
2011-02-28 16:07:36 -06:00
|
|
|
{ "tls", eap_tls_reader, FALSE },
|
|
|
|
|
{ "peap", eap_peap_reader, FALSE },
|
|
|
|
|
{ "ttls", eap_ttls_reader, FALSE },
|
2012-01-23 13:53:08 +01:00
|
|
|
{ "fast", eap_fast_reader, FALSE },
|
2011-02-28 16:07:36 -06:00
|
|
|
{ NULL, NULL }
|
|
|
|
|
};
|
|
|
|
|
|
2014-02-25 15:27:20 +01:00
|
|
|
static void
|
|
|
|
|
read_8021x_list_value (shvarFile *ifcfg,
|
|
|
|
|
const char *ifcfg_var_name,
|
|
|
|
|
NMSetting8021x *setting,
|
|
|
|
|
const char *prop_name)
|
|
|
|
|
{
|
|
|
|
|
char *value;
|
2014-08-21 13:19:53 -04:00
|
|
|
char **strv;
|
2014-02-25 15:27:20 +01:00
|
|
|
|
|
|
|
|
g_return_if_fail (ifcfg != NULL);
|
|
|
|
|
g_return_if_fail (ifcfg_var_name != NULL);
|
|
|
|
|
g_return_if_fail (prop_name != NULL);
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, ifcfg_var_name, FALSE);
|
|
|
|
|
if (!value)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
strv = g_strsplit_set (value, " \t", 0);
|
2014-08-21 13:19:53 -04:00
|
|
|
if (strv && strv[0])
|
|
|
|
|
g_object_set (setting, prop_name, strv, NULL);
|
2014-02-25 15:27:20 +01:00
|
|
|
g_strfreev (strv);
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-27 13:28:20 -05:00
|
|
|
static NMSetting8021x *
|
|
|
|
|
fill_8021x (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
const char *key_mgmt,
|
2009-03-09 10:51:07 -04:00
|
|
|
gboolean wifi,
|
2009-02-27 13:28:20 -05:00
|
|
|
GError **error)
|
|
|
|
|
{
|
2009-03-09 10:51:07 -04:00
|
|
|
NMSetting8021x *s_8021x;
|
2009-03-10 09:04:15 -04:00
|
|
|
shvarFile *keys = NULL;
|
2009-03-09 10:51:07 -04:00
|
|
|
char *value;
|
2013-02-24 18:08:38 +01:00
|
|
|
char **list = NULL, **iter;
|
2009-03-09 10:51:07 -04:00
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE);
|
|
|
|
|
if (!value) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-09 10:51:07 -04:00
|
|
|
"Missing IEEE_8021X_EAP_METHODS for key management '%s'",
|
|
|
|
|
key_mgmt);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list = g_strsplit (value, " ", 0);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
|
|
|
|
|
|
2009-03-10 09:04:15 -04:00
|
|
|
/* Read in the lookaside keys file, if present */
|
2009-03-26 16:57:55 -04:00
|
|
|
keys = utils_get_keys_ifcfg (file, FALSE);
|
2009-03-10 09:04:15 -04:00
|
|
|
|
|
|
|
|
/* Validate and handle each EAP method */
|
|
|
|
|
for (iter = list; iter && *iter; iter++) {
|
|
|
|
|
EAPReader *eap = &eap_readers[0];
|
|
|
|
|
gboolean found = FALSE;
|
|
|
|
|
char *lower = NULL;
|
|
|
|
|
|
|
|
|
|
lower = g_ascii_strdown (*iter, -1);
|
2014-07-27 02:20:00 +02:00
|
|
|
while (eap->method) {
|
2009-03-10 18:23:13 -04:00
|
|
|
if (strcmp (eap->method, lower))
|
|
|
|
|
goto next;
|
2009-03-10 09:04:15 -04:00
|
|
|
|
|
|
|
|
/* Some EAP methods don't provide keying material, thus they
|
|
|
|
|
* cannot be used with WiFi unless they are an inner method
|
|
|
|
|
* used with TTLS or PEAP or whatever.
|
|
|
|
|
*/
|
|
|
|
|
if (wifi && eap->wifi_phase2_only) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("ignored invalid IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi.",
|
|
|
|
|
lower);
|
2009-03-10 18:23:13 -04:00
|
|
|
goto next;
|
2009-03-10 09:04:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Parse EAP method specific options */
|
|
|
|
|
if (!(*eap->reader)(lower, ifcfg, keys, s_8021x, FALSE, error)) {
|
|
|
|
|
g_free (lower);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
nm_setting_802_1x_add_eap_method (s_8021x, lower);
|
|
|
|
|
found = TRUE;
|
2014-07-27 02:20:00 +02:00
|
|
|
break;
|
2009-03-10 18:23:13 -04:00
|
|
|
|
|
|
|
|
next:
|
|
|
|
|
eap++;
|
2009-03-10 09:04:15 -04:00
|
|
|
}
|
|
|
|
|
|
2014-04-05 09:37:04 -04:00
|
|
|
if (!found)
|
|
|
|
|
PARSE_WARNING ("ignored unknown IEEE_8021X_EAP_METHOD '%s'.", lower);
|
2009-03-10 09:04:15 -04:00
|
|
|
g_free (lower);
|
2009-03-09 10:51:07 -04:00
|
|
|
}
|
|
|
|
|
|
2009-03-10 09:04:15 -04:00
|
|
|
if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 09:04:15 -04:00
|
|
|
"No valid EAP methods found in IEEE_8021X_EAP_METHODS.");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
2009-03-09 10:51:07 -04:00
|
|
|
|
2014-02-25 15:27:20 +01:00
|
|
|
value = svGetValue (ifcfg, "IEEE_8021X_SUBJECT_MATCH", FALSE);
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_SUBJECT_MATCH, value, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "IEEE_8021X_PHASE2_SUBJECT_MATCH", FALSE);
|
|
|
|
|
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, value, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
read_8021x_list_value (ifcfg, "IEEE_8021X_ALTSUBJECT_MATCHES",
|
|
|
|
|
s_8021x, NM_SETTING_802_1X_ALTSUBJECT_MATCHES);
|
|
|
|
|
read_8021x_list_value (ifcfg, "IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES",
|
|
|
|
|
s_8021x, NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES);
|
|
|
|
|
|
2013-02-24 18:08:38 +01:00
|
|
|
if (list)
|
|
|
|
|
g_strfreev (list);
|
2009-03-10 09:04:15 -04:00
|
|
|
if (keys)
|
|
|
|
|
svCloseFile (keys);
|
2009-03-09 10:51:07 -04:00
|
|
|
return s_8021x;
|
|
|
|
|
|
|
|
|
|
error:
|
2013-02-24 18:08:38 +01:00
|
|
|
if (list)
|
|
|
|
|
g_strfreev (list);
|
2009-03-10 09:04:15 -04:00
|
|
|
if (keys)
|
|
|
|
|
svCloseFile (keys);
|
2009-03-09 10:51:07 -04:00
|
|
|
g_object_unref (s_8021x);
|
2009-02-27 13:28:20 -05:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMSetting *
|
|
|
|
|
make_wpa_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
2014-06-26 10:42:11 -04:00
|
|
|
GBytes *ssid,
|
2009-02-27 13:28:20 -05:00
|
|
|
gboolean adhoc,
|
|
|
|
|
NMSetting8021x **s_8021x,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingWirelessSecurity *wsec;
|
2009-03-11 14:49:27 -04:00
|
|
|
char *value, *psk, *lower;
|
2011-03-14 00:25:14 -05:00
|
|
|
gboolean wpa_psk = FALSE, wpa_eap = FALSE, ieee8021x = FALSE;
|
2009-02-27 13:28:20 -05:00
|
|
|
|
|
|
|
|
wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
|
|
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "KEY_MGMT", FALSE);
|
2011-03-14 00:25:14 -05:00
|
|
|
wpa_psk = !g_strcmp0 (value, "WPA-PSK");
|
|
|
|
|
wpa_eap = !g_strcmp0 (value, "WPA-EAP");
|
|
|
|
|
ieee8021x = !g_strcmp0 (value, "IEEE8021X");
|
|
|
|
|
if (!wpa_psk && !wpa_eap && !ieee8021x)
|
2009-02-27 13:28:20 -05:00
|
|
|
goto error; /* Not WPA or Dynamic WEP */
|
|
|
|
|
|
2011-03-14 00:25:14 -05:00
|
|
|
/* Pairwise and Group ciphers (only relevant for WPA/RSN) */
|
|
|
|
|
if (wpa_psk || wpa_eap) {
|
|
|
|
|
fill_wpa_ciphers (ifcfg, wsec, FALSE, adhoc);
|
|
|
|
|
fill_wpa_ciphers (ifcfg, wsec, TRUE, adhoc);
|
|
|
|
|
}
|
2009-02-27 13:28:20 -05:00
|
|
|
|
|
|
|
|
/* WPA and/or RSN */
|
2009-03-01 19:04:55 -05:00
|
|
|
if (adhoc) {
|
|
|
|
|
/* Ad-Hoc mode only supports WPA proto for now */
|
2009-02-27 13:28:20 -05:00
|
|
|
nm_setting_wireless_security_add_proto (wsec, "wpa");
|
2009-03-01 19:04:55 -05:00
|
|
|
} else {
|
2009-03-27 14:15:06 -04:00
|
|
|
char *allow_wpa, *allow_rsn;
|
|
|
|
|
|
|
|
|
|
allow_wpa = svGetValue (ifcfg, "WPA_ALLOW_WPA", FALSE);
|
|
|
|
|
allow_rsn = svGetValue (ifcfg, "WPA_ALLOW_WPA2", FALSE);
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (allow_wpa && svGetValueBoolean (ifcfg, "WPA_ALLOW_WPA", TRUE))
|
2009-03-27 14:15:06 -04:00
|
|
|
nm_setting_wireless_security_add_proto (wsec, "wpa");
|
2015-10-08 18:04:30 +02:00
|
|
|
if (allow_rsn && svGetValueBoolean (ifcfg, "WPA_ALLOW_WPA2", TRUE))
|
2009-03-27 14:15:06 -04:00
|
|
|
nm_setting_wireless_security_add_proto (wsec, "rsn");
|
|
|
|
|
|
|
|
|
|
/* If neither WPA_ALLOW_WPA or WPA_ALLOW_WPA2 were present, default
|
|
|
|
|
* to both WPA and RSN allowed.
|
|
|
|
|
*/
|
2011-03-14 00:25:14 -05:00
|
|
|
if (!allow_wpa && !allow_rsn && !ieee8021x) {
|
2009-03-01 19:04:55 -05:00
|
|
|
nm_setting_wireless_security_add_proto (wsec, "wpa");
|
|
|
|
|
nm_setting_wireless_security_add_proto (wsec, "rsn");
|
2009-03-27 14:15:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_free (allow_wpa);
|
|
|
|
|
g_free (allow_rsn);
|
2009-03-01 19:04:55 -05:00
|
|
|
}
|
2009-02-27 13:28:20 -05:00
|
|
|
|
2013-10-31 14:13:33 +01:00
|
|
|
/* coverity[dereference] */
|
2009-02-27 13:28:20 -05:00
|
|
|
if (!strcmp (value, "WPA-PSK")) {
|
2011-03-03 12:29:37 -06:00
|
|
|
NMSettingSecretFlags psk_flags;
|
|
|
|
|
|
|
|
|
|
psk_flags = read_secret_flags (ifcfg, "WPA_PSK_FLAGS");
|
|
|
|
|
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, psk_flags, NULL);
|
|
|
|
|
|
|
|
|
|
/* Read PSK if it's system-owned */
|
|
|
|
|
if (psk_flags == NM_SETTING_SECRET_FLAG_NONE) {
|
|
|
|
|
psk = parse_wpa_psk (ifcfg, file, ssid, error);
|
|
|
|
|
if (psk) {
|
|
|
|
|
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL);
|
|
|
|
|
g_free (psk);
|
2015-02-07 17:59:28 +01:00
|
|
|
} else if (error)
|
|
|
|
|
goto error;
|
2010-12-14 15:26:40 -06:00
|
|
|
}
|
2009-03-01 19:04:55 -05:00
|
|
|
|
|
|
|
|
if (adhoc)
|
|
|
|
|
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL);
|
|
|
|
|
else
|
|
|
|
|
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
|
2009-02-27 13:28:20 -05:00
|
|
|
} else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) {
|
|
|
|
|
/* Adhoc mode is mutually exclusive with any 802.1x-based authentication */
|
|
|
|
|
if (adhoc) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-02-27 13:28:20 -05:00
|
|
|
"Ad-Hoc mode cannot be used with KEY_MGMT type '%s'", value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-09 10:51:07 -04:00
|
|
|
*s_8021x = fill_8021x (ifcfg, file, value, TRUE, error);
|
2009-02-27 13:28:20 -05:00
|
|
|
if (!*s_8021x)
|
|
|
|
|
goto error;
|
2009-03-11 14:49:27 -04:00
|
|
|
|
|
|
|
|
lower = g_ascii_strdown (value, -1);
|
|
|
|
|
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, lower, NULL);
|
|
|
|
|
g_free (lower);
|
2009-02-27 13:28:20 -05:00
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-02-27 13:28:20 -05:00
|
|
|
"Unknown wireless KEY_MGMT type '%s'", value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_free (value);
|
|
|
|
|
return (NMSetting *) wsec;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_free (value);
|
|
|
|
|
if (wsec)
|
|
|
|
|
g_object_unref (wsec);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-26 16:57:55 -04:00
|
|
|
static NMSetting *
|
|
|
|
|
make_leap_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingWirelessSecurity *wsec;
|
|
|
|
|
shvarFile *keys_ifcfg;
|
|
|
|
|
char *value;
|
2011-03-03 12:29:37 -06:00
|
|
|
NMSettingSecretFlags flags;
|
2009-03-26 16:57:55 -04:00
|
|
|
|
|
|
|
|
wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "KEY_MGMT", FALSE);
|
|
|
|
|
if (!value || strcmp (value, "IEEE8021X"))
|
|
|
|
|
goto error; /* Not LEAP */
|
|
|
|
|
|
|
|
|
|
g_free (value);
|
|
|
|
|
value = svGetValue (ifcfg, "SECURITYMODE", FALSE);
|
|
|
|
|
if (!value || strcasecmp (value, "leap"))
|
|
|
|
|
goto error; /* Not LEAP */
|
|
|
|
|
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2011-03-03 12:29:37 -06:00
|
|
|
flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS");
|
|
|
|
|
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, NULL);
|
|
|
|
|
|
|
|
|
|
/* Read LEAP password if it's system-owned */
|
|
|
|
|
if (flags == NM_SETTING_SECRET_FLAG_NONE) {
|
|
|
|
|
value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE);
|
|
|
|
|
if (!value) {
|
|
|
|
|
/* Try to get keys from the "shadow" key file */
|
|
|
|
|
keys_ifcfg = utils_get_keys_ifcfg (file, FALSE);
|
|
|
|
|
if (keys_ifcfg) {
|
|
|
|
|
value = svGetValue (keys_ifcfg, "IEEE_8021X_PASSWORD", FALSE);
|
|
|
|
|
svCloseFile (keys_ifcfg);
|
|
|
|
|
}
|
2009-03-26 16:57:55 -04:00
|
|
|
}
|
2011-03-03 12:29:37 -06:00
|
|
|
if (value && strlen (value))
|
|
|
|
|
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, value, NULL);
|
|
|
|
|
g_free (value);
|
2009-03-26 16:57:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE);
|
|
|
|
|
if (!value || !strlen (value)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-26 16:57:55 -04:00
|
|
|
"Missing LEAP identity");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
g_object_set (wsec,
|
|
|
|
|
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
|
|
|
|
|
NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap",
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
return (NMSetting *) wsec;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_free (value);
|
|
|
|
|
if (wsec)
|
|
|
|
|
g_object_unref (wsec);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-27 13:28:20 -05:00
|
|
|
static NMSetting *
|
|
|
|
|
make_wireless_security_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
2014-06-26 10:42:11 -04:00
|
|
|
GBytes *ssid,
|
2009-02-27 13:28:20 -05:00
|
|
|
gboolean adhoc,
|
|
|
|
|
NMSetting8021x **s_8021x,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSetting *wsec;
|
|
|
|
|
|
ifcfg-rh: fix wireless_connection_from_ifcfg() to accept missing @error argument
wireless_connection_from_ifcfg() did not support being called without
error argument.
#0 0x00007fe4fa2204e9 in g_logv (log_domain=0x7fe4f0597060 "NetworkManager-ifcfg-rh", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fff1c7aaf00) at gmessages.c:989
#1 0x00007fe4fa22063f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1025
#2 0x00007fe4f057eec3 in wireless_connection_from_ifcfg (file=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", ifcfg=0x7fe4fec6f730, error=0x0) at reader.c:3431
#3 0x00007fe4f057e2b6 in connection_from_file_full (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", network_file=0x7fe4f05976aa "/etc/sysconfig/network", test_type=0x0, out_unhandled=0x7fff1c7ab1f8,
error=0x0, out_ignore_error=0x7fff1c7ab174) at reader.c:4750
#4 0x00007fe4f057db80 in connection_from_file (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", out_unhandled=0x7fff1c7ab1f8, error=0x0) at reader.c:4834
#5 0x00007fe4f057b4a6 in nm_ifcfg_connection_new (source=0x0, full_path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", error=0x0) at nm-ifcfg-connection.c:119
#6 0x00007fe4f0579c1d in _internal_new_connection (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", source=0x0, error=0x0) at plugin.c:136
#7 0x00007fe4f0579256 in connection_new_or_changed (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", existing=0x0, out_old_path=0x7fff1c7ab458) at plugin.c:265
#8 0x00007fe4f0578f61 in read_connections (plugin=0x7fe4fec6cd00) at plugin.c:462
#9 0x00007fe4f0578839 in get_connections (config=0x7fe4fec6cd00) at plugin.c:497
#10 0x00007fe4fdc9affb in nm_system_config_interface_get_connections (config=0x7fe4fec6cd00) at settings/nm-system-config-interface.c:143
#11 0x00007fe4fdc9764f in load_connections (self=0x7fe4fec6ca40) at settings/nm-settings.c:201
#12 0x00007fe4fdc96d74 in nm_settings_new (error=0x7fff1c7abb18) at settings/nm-settings.c:1802
#13 0x00007fe4fdc37146 in main (argc=1, argv=0x7fff1c7abcd8) at main.c:415
Fixes: 356849f70c72f920d1600ab98611f9f7ed10214c
Fixes: 12bfaf5a8da788ae5ed50c0c93c203250a6ecf8b
2014-12-30 21:43:10 +01:00
|
|
|
g_return_val_if_fail (error && !*error, NULL);
|
|
|
|
|
|
2009-03-26 16:57:55 -04:00
|
|
|
if (!adhoc) {
|
|
|
|
|
wsec = make_leap_setting (ifcfg, file, error);
|
|
|
|
|
if (wsec)
|
|
|
|
|
return wsec;
|
|
|
|
|
else if (*error)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-27 13:28:20 -05:00
|
|
|
wsec = make_wpa_setting (ifcfg, file, ssid, adhoc, s_8021x, error);
|
|
|
|
|
if (wsec)
|
|
|
|
|
return wsec;
|
|
|
|
|
else if (*error)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
wsec = make_wep_setting (ifcfg, file, error);
|
|
|
|
|
if (wsec)
|
|
|
|
|
return wsec;
|
|
|
|
|
else if (*error)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return NULL; /* unencrypted */
|
|
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2014-09-10 10:26:11 +02:00
|
|
|
static char **
|
2014-09-19 21:12:51 +02:00
|
|
|
transform_hwaddr_blacklist (const char *blacklist)
|
2014-09-10 10:26:11 +02:00
|
|
|
{
|
|
|
|
|
char **strv, **iter;
|
|
|
|
|
int shift = 0;
|
|
|
|
|
|
|
|
|
|
strv = _nm_utils_strsplit_set (blacklist, " \t", 0);
|
|
|
|
|
for (iter = strv; iter && *iter; iter++) {
|
|
|
|
|
if (shift) {
|
2014-09-19 21:12:51 +02:00
|
|
|
*(iter - shift) = *iter;
|
2014-09-10 10:26:11 +02:00
|
|
|
*iter = NULL;
|
|
|
|
|
}
|
2014-09-19 21:12:51 +02:00
|
|
|
if (!nm_utils_hwaddr_valid (*(iter - shift), ETH_ALEN)) {
|
|
|
|
|
PARSE_WARNING ("invalid MAC in HWADDR_BLACKLIST '%s'", *(iter - shift));
|
|
|
|
|
g_free (*(iter - shift));
|
|
|
|
|
*(iter - shift) = NULL;
|
2014-09-10 10:26:11 +02:00
|
|
|
shift++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return strv;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
static NMSetting *
|
|
|
|
|
make_wireless_setting (shvarFile *ifcfg,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingWireless *s_wireless;
|
2014-07-30 10:57:45 -04:00
|
|
|
char *value = NULL;
|
2014-10-02 12:25:18 -05:00
|
|
|
gint64 chan = 0;
|
2007-11-27 19:25:46 +00:00
|
|
|
|
|
|
|
|
s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
|
|
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
value = svGetValue (ifcfg, "HWADDR", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
value = g_strstrip (value);
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, value, NULL);
|
|
|
|
|
g_free (value);
|
2008-07-31 16:19:28 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
value = svGetValue (ifcfg, "MACADDR", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
value = g_strstrip (value);
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, value, NULL);
|
|
|
|
|
g_free (value);
|
2010-06-22 14:21:25 +02:00
|
|
|
}
|
|
|
|
|
|
2011-06-30 17:58:31 +02:00
|
|
|
value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE);
|
2011-06-30 13:23:28 +02:00
|
|
|
if (value) {
|
2014-09-10 10:26:11 +02:00
|
|
|
char **strv;
|
2011-06-30 13:23:28 +02:00
|
|
|
|
2014-09-19 21:12:51 +02:00
|
|
|
strv = transform_hwaddr_blacklist (value);
|
2014-09-10 10:26:11 +02:00
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, strv, NULL);
|
|
|
|
|
g_strfreev (strv);
|
2014-08-21 13:19:53 -04:00
|
|
|
g_free (value);
|
2011-06-30 13:23:28 +02:00
|
|
|
}
|
|
|
|
|
|
2009-03-26 16:57:55 -04:00
|
|
|
value = svGetValue (ifcfg, "ESSID", TRUE);
|
2007-11-27 19:25:46 +00:00
|
|
|
if (value) {
|
2014-11-06 17:51:09 -06:00
|
|
|
GBytes *bytes = NULL;
|
|
|
|
|
gsize ssid_len = 0;
|
|
|
|
|
gsize value_len = strlen (value);
|
2009-03-26 16:57:55 -04:00
|
|
|
|
|
|
|
|
if ( (value_len >= 2)
|
|
|
|
|
&& (value[0] == '"')
|
|
|
|
|
&& (value[value_len - 1] == '"')) {
|
|
|
|
|
/* Strip the quotes and unescape */
|
2014-11-06 17:51:09 -06:00
|
|
|
char *p = value + 1;
|
|
|
|
|
|
2009-03-26 16:57:55 -04:00
|
|
|
value[value_len - 1] = '\0';
|
|
|
|
|
svUnescape (p);
|
2014-11-06 17:51:09 -06:00
|
|
|
bytes = g_bytes_new (p, strlen (p));
|
2009-03-26 16:57:55 -04:00
|
|
|
} else if ((value_len > 2) && (strncmp (value, "0x", 2) == 0)) {
|
|
|
|
|
/* Hex representation */
|
|
|
|
|
if (value_len % 2) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-26 16:57:55 -04:00
|
|
|
"Invalid SSID '%s' size (looks like hex but length not multiple of 2)",
|
|
|
|
|
value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-06 17:51:09 -06:00
|
|
|
bytes = nm_utils_hexstr2bin (value);
|
|
|
|
|
if (!bytes) {
|
|
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Invalid SSID '%s' (looks like hex SSID but isn't)",
|
|
|
|
|
value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
2009-03-26 16:57:55 -04:00
|
|
|
}
|
2014-11-06 17:51:09 -06:00
|
|
|
} else
|
|
|
|
|
bytes = g_bytes_new (value, value_len);
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2014-11-06 17:51:09 -06:00
|
|
|
ssid_len = g_bytes_get_size (bytes);
|
2009-03-26 16:57:55 -04:00
|
|
|
if (ssid_len > 32 || ssid_len == 0) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2007-12-04 21:44:40 +00:00
|
|
|
"Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)",
|
2009-03-26 16:57:55 -04:00
|
|
|
value, ssid_len);
|
2014-11-06 17:51:09 -06:00
|
|
|
g_bytes_unref (bytes);
|
2008-07-07 19:30:53 +00:00
|
|
|
g_free (value);
|
2007-11-27 19:25:46 +00:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-26 10:42:11 -04:00
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, bytes, NULL);
|
|
|
|
|
g_bytes_unref (bytes);
|
2009-03-26 16:57:55 -04:00
|
|
|
g_free (value);
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
|
|
|
|
|
2009-03-26 16:57:55 -04:00
|
|
|
value = svGetValue (ifcfg, "MODE", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
char *lcase;
|
|
|
|
|
const char *mode = NULL;
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2009-03-26 16:57:55 -04:00
|
|
|
lcase = g_ascii_strdown (value, -1);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
if (!strcmp (lcase, "ad-hoc")) {
|
|
|
|
|
mode = "adhoc";
|
2014-10-20 17:33:00 +02:00
|
|
|
} else if (!strcmp (lcase, "ap")) {
|
|
|
|
|
mode = "ap";
|
2009-12-04 11:10:22 -08:00
|
|
|
} else if (!strcmp (lcase, "managed") || !strcmp (lcase, "auto")) {
|
2009-03-26 16:57:55 -04:00
|
|
|
mode = "infrastructure";
|
|
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2014-10-20 17:33:00 +02:00
|
|
|
"Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')",
|
2009-03-26 16:57:55 -04:00
|
|
|
lcase);
|
2007-11-27 19:25:46 +00:00
|
|
|
g_free (lcase);
|
2009-03-26 16:57:55 -04:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (lcase);
|
|
|
|
|
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, mode, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "BSSID", FALSE);
|
|
|
|
|
if (value) {
|
2014-07-30 10:57:45 -04:00
|
|
|
value = g_strstrip (value);
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, value, NULL);
|
2011-04-14 16:56:20 +02:00
|
|
|
g_free (value);
|
2008-04-02 17:39:35 +00:00
|
|
|
}
|
2009-03-27 11:34:49 -04:00
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "CHANNEL", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
errno = 0;
|
2015-02-22 11:55:31 +01:00
|
|
|
chan = _nm_utils_ascii_str_to_int64 (value, 10, 1, 196, 0);
|
2014-10-02 12:25:18 -05:00
|
|
|
if (errno || (chan == 0)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-27 11:34:49 -04:00
|
|
|
"Invalid wireless channel '%s'", value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_CHANNEL, (guint32) chan, NULL);
|
2014-10-02 12:25:18 -05:00
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "BAND", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
if (!strcmp (value, "a")) {
|
|
|
|
|
if (chan && chan <= 14) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2014-10-09 13:20:06 -05:00
|
|
|
"Band '%s' invalid for channel %u", value, (guint32) chan);
|
2014-10-02 12:25:18 -05:00
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} else if (!strcmp (value, "bg")) {
|
|
|
|
|
if (chan && chan > 14) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2014-10-09 13:20:06 -05:00
|
|
|
"Band '%s' invalid for channel %u", value, (guint32) chan);
|
2014-10-02 12:25:18 -05:00
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2014-10-02 12:25:18 -05:00
|
|
|
"Invalid wireless band '%s'", value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, value, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
} else if (chan > 0) {
|
2009-03-27 11:34:49 -04:00
|
|
|
if (chan > 14)
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL);
|
|
|
|
|
else
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "MTU", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
long int mtu;
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
mtu = strtol (value, NULL, 10);
|
|
|
|
|
if (errno || mtu < 0 || mtu > 50000) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-27 11:34:49 -04:00
|
|
|
"Invalid wireless MTU '%s'", value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint32) mtu, NULL);
|
2011-04-14 16:56:20 +02:00
|
|
|
g_free (value);
|
2009-03-27 11:34:49 -04:00
|
|
|
}
|
2008-04-02 17:39:35 +00:00
|
|
|
|
2014-02-28 16:34:20 -06:00
|
|
|
g_object_set (s_wireless,
|
|
|
|
|
NM_SETTING_WIRELESS_HIDDEN,
|
2015-10-08 18:04:30 +02:00
|
|
|
svGetValueBoolean (ifcfg, "SSID_HIDDEN", FALSE),
|
2014-02-28 16:34:20 -06:00
|
|
|
NULL);
|
|
|
|
|
|
2015-01-21 14:29:42 -06:00
|
|
|
g_object_set (s_wireless,
|
|
|
|
|
NM_SETTING_WIRELESS_POWERSAVE,
|
2015-10-08 18:04:30 +02:00
|
|
|
svGetValueBoolean (ifcfg, "POWERSAVE", FALSE) ? 1 : 0,
|
2015-01-21 14:29:42 -06:00
|
|
|
NULL);
|
|
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
return NM_SETTING (s_wireless);
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
if (s_wireless)
|
|
|
|
|
g_object_unref (s_wireless);
|
|
|
|
|
return NULL;
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
static NMConnection *
|
2008-07-31 16:19:28 +00:00
|
|
|
wireless_connection_from_ifcfg (const char *file,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
GError **error)
|
2007-11-27 19:25:46 +00:00
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSetting *con_setting = NULL;
|
|
|
|
|
NMSetting *wireless_setting = NULL;
|
2009-02-27 13:28:20 -05:00
|
|
|
NMSetting8021x *s_8021x = NULL;
|
2014-06-26 10:42:11 -04:00
|
|
|
GBytes *ssid;
|
2007-11-27 19:25:46 +00:00
|
|
|
NMSetting *security_setting = NULL;
|
|
|
|
|
char *printable_ssid = NULL;
|
2009-02-27 13:28:20 -05:00
|
|
|
const char *mode;
|
|
|
|
|
gboolean adhoc = FALSE;
|
ifcfg-rh: fix wireless_connection_from_ifcfg() to accept missing @error argument
wireless_connection_from_ifcfg() did not support being called without
error argument.
#0 0x00007fe4fa2204e9 in g_logv (log_domain=0x7fe4f0597060 "NetworkManager-ifcfg-rh", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fff1c7aaf00) at gmessages.c:989
#1 0x00007fe4fa22063f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1025
#2 0x00007fe4f057eec3 in wireless_connection_from_ifcfg (file=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", ifcfg=0x7fe4fec6f730, error=0x0) at reader.c:3431
#3 0x00007fe4f057e2b6 in connection_from_file_full (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", network_file=0x7fe4f05976aa "/etc/sysconfig/network", test_type=0x0, out_unhandled=0x7fff1c7ab1f8,
error=0x0, out_ignore_error=0x7fff1c7ab174) at reader.c:4750
#4 0x00007fe4f057db80 in connection_from_file (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", out_unhandled=0x7fff1c7ab1f8, error=0x0) at reader.c:4834
#5 0x00007fe4f057b4a6 in nm_ifcfg_connection_new (source=0x0, full_path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", error=0x0) at nm-ifcfg-connection.c:119
#6 0x00007fe4f0579c1d in _internal_new_connection (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", source=0x0, error=0x0) at plugin.c:136
#7 0x00007fe4f0579256 in connection_new_or_changed (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", existing=0x0, out_old_path=0x7fff1c7ab458) at plugin.c:265
#8 0x00007fe4f0578f61 in read_connections (plugin=0x7fe4fec6cd00) at plugin.c:462
#9 0x00007fe4f0578839 in get_connections (config=0x7fe4fec6cd00) at plugin.c:497
#10 0x00007fe4fdc9affb in nm_system_config_interface_get_connections (config=0x7fe4fec6cd00) at settings/nm-system-config-interface.c:143
#11 0x00007fe4fdc9764f in load_connections (self=0x7fe4fec6ca40) at settings/nm-settings.c:201
#12 0x00007fe4fdc96d74 in nm_settings_new (error=0x7fff1c7abb18) at settings/nm-settings.c:1802
#13 0x00007fe4fdc37146 in main (argc=1, argv=0x7fff1c7abcd8) at main.c:415
Fixes: 356849f70c72f920d1600ab98611f9f7ed10214c
Fixes: 12bfaf5a8da788ae5ed50c0c93c203250a6ecf8b
2014-12-30 21:43:10 +01:00
|
|
|
GError *local = NULL;
|
2007-11-27 19:25:46 +00:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (file != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, NULL);
|
ifcfg-rh: fix wireless_connection_from_ifcfg() to accept missing @error argument
wireless_connection_from_ifcfg() did not support being called without
error argument.
#0 0x00007fe4fa2204e9 in g_logv (log_domain=0x7fe4f0597060 "NetworkManager-ifcfg-rh", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fff1c7aaf00) at gmessages.c:989
#1 0x00007fe4fa22063f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1025
#2 0x00007fe4f057eec3 in wireless_connection_from_ifcfg (file=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", ifcfg=0x7fe4fec6f730, error=0x0) at reader.c:3431
#3 0x00007fe4f057e2b6 in connection_from_file_full (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", network_file=0x7fe4f05976aa "/etc/sysconfig/network", test_type=0x0, out_unhandled=0x7fff1c7ab1f8,
error=0x0, out_ignore_error=0x7fff1c7ab174) at reader.c:4750
#4 0x00007fe4f057db80 in connection_from_file (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", out_unhandled=0x7fff1c7ab1f8, error=0x0) at reader.c:4834
#5 0x00007fe4f057b4a6 in nm_ifcfg_connection_new (source=0x0, full_path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", error=0x0) at nm-ifcfg-connection.c:119
#6 0x00007fe4f0579c1d in _internal_new_connection (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", source=0x0, error=0x0) at plugin.c:136
#7 0x00007fe4f0579256 in connection_new_or_changed (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", existing=0x0, out_old_path=0x7fff1c7ab458) at plugin.c:265
#8 0x00007fe4f0578f61 in read_connections (plugin=0x7fe4fec6cd00) at plugin.c:462
#9 0x00007fe4f0578839 in get_connections (config=0x7fe4fec6cd00) at plugin.c:497
#10 0x00007fe4fdc9affb in nm_system_config_interface_get_connections (config=0x7fe4fec6cd00) at settings/nm-system-config-interface.c:143
#11 0x00007fe4fdc9764f in load_connections (self=0x7fe4fec6ca40) at settings/nm-settings.c:201
#12 0x00007fe4fdc96d74 in nm_settings_new (error=0x7fff1c7abb18) at settings/nm-settings.c:1802
#13 0x00007fe4fdc37146 in main (argc=1, argv=0x7fff1c7abcd8) at main.c:415
Fixes: 356849f70c72f920d1600ab98611f9f7ed10214c
Fixes: 12bfaf5a8da788ae5ed50c0c93c203250a6ecf8b
2014-12-30 21:43:10 +01:00
|
|
|
g_return_val_if_fail (!error || !*error, NULL);
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2007-11-27 19:25:46 +00:00
|
|
|
|
|
|
|
|
/* Wireless */
|
2013-10-29 10:45:36 -04:00
|
|
|
wireless_setting = make_wireless_setting (ifcfg, error);
|
2008-07-31 16:19:28 +00:00
|
|
|
if (!wireless_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
nm_connection_add_setting (connection, wireless_setting);
|
|
|
|
|
|
2008-10-28 19:26:00 +00:00
|
|
|
ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (wireless_setting));
|
2014-06-26 10:42:11 -04:00
|
|
|
if (ssid) {
|
|
|
|
|
printable_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL),
|
|
|
|
|
g_bytes_get_size (ssid));
|
|
|
|
|
} else
|
2008-07-31 16:19:28 +00:00
|
|
|
printable_ssid = g_strdup_printf ("unmanaged");
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting));
|
|
|
|
|
if (mode && !strcmp (mode, "adhoc"))
|
|
|
|
|
adhoc = TRUE;
|
2009-02-27 13:28:20 -05:00
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
/* Wireless security */
|
ifcfg-rh: fix wireless_connection_from_ifcfg() to accept missing @error argument
wireless_connection_from_ifcfg() did not support being called without
error argument.
#0 0x00007fe4fa2204e9 in g_logv (log_domain=0x7fe4f0597060 "NetworkManager-ifcfg-rh", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fff1c7aaf00) at gmessages.c:989
#1 0x00007fe4fa22063f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1025
#2 0x00007fe4f057eec3 in wireless_connection_from_ifcfg (file=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", ifcfg=0x7fe4fec6f730, error=0x0) at reader.c:3431
#3 0x00007fe4f057e2b6 in connection_from_file_full (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", network_file=0x7fe4f05976aa "/etc/sysconfig/network", test_type=0x0, out_unhandled=0x7fff1c7ab1f8,
error=0x0, out_ignore_error=0x7fff1c7ab174) at reader.c:4750
#4 0x00007fe4f057db80 in connection_from_file (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", out_unhandled=0x7fff1c7ab1f8, error=0x0) at reader.c:4834
#5 0x00007fe4f057b4a6 in nm_ifcfg_connection_new (source=0x0, full_path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", error=0x0) at nm-ifcfg-connection.c:119
#6 0x00007fe4f0579c1d in _internal_new_connection (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", source=0x0, error=0x0) at plugin.c:136
#7 0x00007fe4f0579256 in connection_new_or_changed (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", existing=0x0, out_old_path=0x7fff1c7ab458) at plugin.c:265
#8 0x00007fe4f0578f61 in read_connections (plugin=0x7fe4fec6cd00) at plugin.c:462
#9 0x00007fe4f0578839 in get_connections (config=0x7fe4fec6cd00) at plugin.c:497
#10 0x00007fe4fdc9affb in nm_system_config_interface_get_connections (config=0x7fe4fec6cd00) at settings/nm-system-config-interface.c:143
#11 0x00007fe4fdc9764f in load_connections (self=0x7fe4fec6ca40) at settings/nm-settings.c:201
#12 0x00007fe4fdc96d74 in nm_settings_new (error=0x7fff1c7abb18) at settings/nm-settings.c:1802
#13 0x00007fe4fdc37146 in main (argc=1, argv=0x7fff1c7abcd8) at main.c:415
Fixes: 356849f70c72f920d1600ab98611f9f7ed10214c
Fixes: 12bfaf5a8da788ae5ed50c0c93c203250a6ecf8b
2014-12-30 21:43:10 +01:00
|
|
|
security_setting = make_wireless_security_setting (ifcfg, file, ssid, adhoc, &s_8021x, &local);
|
|
|
|
|
if (local) {
|
2013-10-29 10:45:36 -04:00
|
|
|
g_free (printable_ssid);
|
|
|
|
|
g_object_unref (connection);
|
ifcfg-rh: fix wireless_connection_from_ifcfg() to accept missing @error argument
wireless_connection_from_ifcfg() did not support being called without
error argument.
#0 0x00007fe4fa2204e9 in g_logv (log_domain=0x7fe4f0597060 "NetworkManager-ifcfg-rh", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fff1c7aaf00) at gmessages.c:989
#1 0x00007fe4fa22063f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1025
#2 0x00007fe4f057eec3 in wireless_connection_from_ifcfg (file=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", ifcfg=0x7fe4fec6f730, error=0x0) at reader.c:3431
#3 0x00007fe4f057e2b6 in connection_from_file_full (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", network_file=0x7fe4f05976aa "/etc/sysconfig/network", test_type=0x0, out_unhandled=0x7fff1c7ab1f8,
error=0x0, out_ignore_error=0x7fff1c7ab174) at reader.c:4750
#4 0x00007fe4f057db80 in connection_from_file (filename=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", out_unhandled=0x7fff1c7ab1f8, error=0x0) at reader.c:4834
#5 0x00007fe4f057b4a6 in nm_ifcfg_connection_new (source=0x0, full_path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", error=0x0) at nm-ifcfg-connection.c:119
#6 0x00007fe4f0579c1d in _internal_new_connection (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", source=0x0, error=0x0) at plugin.c:136
#7 0x00007fe4f0579256 in connection_new_or_changed (self=0x7fe4fec6cd00, path=0x7fe4fec7c800 "/etc/sysconfig/network-scripts/ifcfg-Wi-Fi-1", existing=0x0, out_old_path=0x7fff1c7ab458) at plugin.c:265
#8 0x00007fe4f0578f61 in read_connections (plugin=0x7fe4fec6cd00) at plugin.c:462
#9 0x00007fe4f0578839 in get_connections (config=0x7fe4fec6cd00) at plugin.c:497
#10 0x00007fe4fdc9affb in nm_system_config_interface_get_connections (config=0x7fe4fec6cd00) at settings/nm-system-config-interface.c:143
#11 0x00007fe4fdc9764f in load_connections (self=0x7fe4fec6ca40) at settings/nm-settings.c:201
#12 0x00007fe4fdc96d74 in nm_settings_new (error=0x7fff1c7abb18) at settings/nm-settings.c:1802
#13 0x00007fe4fdc37146 in main (argc=1, argv=0x7fff1c7abcd8) at main.c:415
Fixes: 356849f70c72f920d1600ab98611f9f7ed10214c
Fixes: 12bfaf5a8da788ae5ed50c0c93c203250a6ecf8b
2014-12-30 21:43:10 +01:00
|
|
|
g_propagate_error (error, local);
|
2013-10-29 10:45:36 -04:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if (security_setting) {
|
|
|
|
|
nm_connection_add_setting (connection, security_setting);
|
|
|
|
|
if (s_8021x)
|
|
|
|
|
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
|
2009-02-27 13:28:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Connection */
|
2007-11-27 19:25:46 +00:00
|
|
|
con_setting = make_connection_setting (file, ifcfg,
|
|
|
|
|
NM_SETTING_WIRELESS_SETTING_NAME,
|
2011-11-10 14:16:01 +01:00
|
|
|
printable_ssid, NULL);
|
2008-07-31 16:19:28 +00:00
|
|
|
g_free (printable_ssid);
|
2007-11-27 19:25:46 +00:00
|
|
|
if (!con_setting) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2007-11-27 19:25:46 +00:00
|
|
|
"Failed to create connection setting.");
|
2008-07-31 16:19:28 +00:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, con_setting);
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2015-05-12 11:55:52 +02:00
|
|
|
static void
|
2015-09-24 17:31:19 +02:00
|
|
|
parse_ethtool_option (const char *value, NMSettingWiredWakeOnLan *out_flags, char **out_password)
|
2015-05-12 11:55:52 +02:00
|
|
|
{
|
2015-09-24 17:31:19 +02:00
|
|
|
gs_strfreev char **words = NULL;
|
|
|
|
|
const char **iter = NULL, *flag;
|
2015-05-12 11:55:52 +02:00
|
|
|
|
2015-09-24 17:31:19 +02:00
|
|
|
if (!value || !value[0])
|
2015-05-12 11:55:52 +02:00
|
|
|
return;
|
|
|
|
|
|
2015-09-24 17:31:19 +02:00
|
|
|
words = g_strsplit_set (value, "\t ", 0);
|
|
|
|
|
iter = (const char **) words;
|
|
|
|
|
|
|
|
|
|
while (iter[0]) {
|
|
|
|
|
gboolean is_wol;
|
|
|
|
|
|
|
|
|
|
if (g_str_equal (iter[0], "wol"))
|
|
|
|
|
is_wol = TRUE;
|
|
|
|
|
else if (g_str_equal (iter[0], "sopass"))
|
|
|
|
|
is_wol = FALSE;
|
|
|
|
|
else {
|
|
|
|
|
/* Silently skip unknown options */
|
|
|
|
|
iter++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iter++;
|
2015-05-12 11:55:52 +02:00
|
|
|
|
2015-09-24 17:31:19 +02:00
|
|
|
/* g_strsplit_set() returns empty tokens, meaning that we must skip over repeated
|
|
|
|
|
* space characters like to parse "wol d". */
|
|
|
|
|
while (iter[0] && !*iter[0])
|
|
|
|
|
iter++;
|
2015-09-21 18:24:07 +02:00
|
|
|
|
2015-09-24 17:31:19 +02:00
|
|
|
if (is_wol) {
|
|
|
|
|
NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE;
|
2015-09-21 18:24:07 +02:00
|
|
|
|
2015-09-24 17:31:19 +02:00
|
|
|
if (!iter[0]) {
|
|
|
|
|
PARSE_WARNING ("Wake-on-LAN options missing");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (flag = iter[0]; *flag; flag++) {
|
2015-05-12 11:55:52 +02:00
|
|
|
switch (*flag) {
|
|
|
|
|
case 'p':
|
|
|
|
|
wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_PHY;
|
|
|
|
|
break;
|
|
|
|
|
case 'u':
|
|
|
|
|
wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST;
|
|
|
|
|
break;
|
|
|
|
|
case 'm':
|
|
|
|
|
wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST;
|
|
|
|
|
break;
|
|
|
|
|
case 'b':
|
|
|
|
|
wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST;
|
|
|
|
|
break;
|
|
|
|
|
case 'a':
|
|
|
|
|
wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_ARP;
|
|
|
|
|
break;
|
|
|
|
|
case 'g':
|
|
|
|
|
wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC;
|
|
|
|
|
break;
|
|
|
|
|
case 's':
|
|
|
|
|
break;
|
|
|
|
|
case 'd':
|
|
|
|
|
wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
PARSE_WARNING ("unrecognized Wake-on-LAN option '%c'", *flag);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-24 17:31:19 +02:00
|
|
|
*out_flags = wol_flags;
|
|
|
|
|
} else {
|
|
|
|
|
if (!iter[0]) {
|
|
|
|
|
PARSE_WARNING ("Wake-on-LAN password missing");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-05-12 11:55:52 +02:00
|
|
|
|
2015-09-24 17:31:19 +02:00
|
|
|
g_clear_pointer (out_password, g_free);
|
|
|
|
|
if (nm_utils_hwaddr_valid (iter[0], ETH_ALEN))
|
|
|
|
|
*out_password = g_strdup (iter[0]);
|
|
|
|
|
else
|
|
|
|
|
PARSE_WARNING ("Wake-on-LAN password '%s' is invalid", iter[0]);
|
|
|
|
|
}
|
2015-05-12 11:55:52 +02:00
|
|
|
iter++;
|
|
|
|
|
}
|
2015-09-24 17:31:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
parse_ethtool_options (shvarFile *ifcfg, NMSettingWired *s_wired, const char *value)
|
|
|
|
|
{
|
|
|
|
|
NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT;
|
|
|
|
|
gs_free char *wol_password = NULL;
|
|
|
|
|
gboolean ignore_wol_password = FALSE;
|
|
|
|
|
|
|
|
|
|
if (value) {
|
|
|
|
|
gs_strfreev char **opts = NULL;
|
|
|
|
|
const char **iter;
|
|
|
|
|
|
|
|
|
|
wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE;
|
|
|
|
|
|
|
|
|
|
opts = g_strsplit_set (value, ";", 0);
|
|
|
|
|
for (iter = (const char **) opts; iter[0]; iter++) {
|
|
|
|
|
/* in case of repeated wol_passwords, parse_ethtool_option()
|
|
|
|
|
* will do the right thing and clear wol_password before resetting. */
|
|
|
|
|
parse_ethtool_option (iter[0], &wol_flags, &wol_password);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-05-12 11:55:52 +02:00
|
|
|
|
2015-09-24 17:31:19 +02:00
|
|
|
if ( wol_password
|
|
|
|
|
&& !NM_FLAGS_HAS (wol_flags, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) {
|
|
|
|
|
PARSE_WARNING ("Wake-on-LAN password not expected");
|
|
|
|
|
ignore_wol_password = TRUE;
|
|
|
|
|
}
|
|
|
|
|
g_object_set (s_wired,
|
|
|
|
|
NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags,
|
|
|
|
|
NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, ignore_wol_password ? NULL : wol_password,
|
|
|
|
|
NULL);
|
2015-05-12 11:55:52 +02:00
|
|
|
}
|
|
|
|
|
|
2007-11-21 06:24:15 +00:00
|
|
|
static NMSetting *
|
2009-03-10 10:44:32 -04:00
|
|
|
make_wired_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
NMSetting8021x **s_8021x,
|
|
|
|
|
GError **error)
|
2007-11-21 06:24:15 +00:00
|
|
|
{
|
|
|
|
|
NMSettingWired *s_wired;
|
2009-03-10 10:44:32 -04:00
|
|
|
char *value = NULL;
|
2010-06-29 00:37:14 -07:00
|
|
|
int mtu;
|
2010-06-25 23:46:47 -07:00
|
|
|
char *nettype;
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
value = svGetValue (ifcfg, "MTU", FALSE);
|
2007-11-21 06:24:15 +00:00
|
|
|
if (value) {
|
|
|
|
|
if (get_int (value, &mtu)) {
|
|
|
|
|
if (mtu >= 0 && mtu < 65536)
|
2008-10-26 17:07:13 +00:00
|
|
|
g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu, NULL);
|
2007-11-21 06:24:15 +00:00
|
|
|
} else {
|
2008-07-31 16:19:28 +00:00
|
|
|
/* Shouldn't be fatal... */
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid MTU '%s'", value);
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
value = svGetValue (ifcfg, "HWADDR", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
value = g_strstrip (value);
|
|
|
|
|
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, value, NULL);
|
|
|
|
|
g_free (value);
|
2010-05-26 17:35:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "SUBCHANNELS", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
const char *p = value;
|
|
|
|
|
gboolean success = TRUE;
|
|
|
|
|
char **chans = NULL;
|
|
|
|
|
|
|
|
|
|
/* basic sanity checks */
|
|
|
|
|
while (*p) {
|
2012-09-25 10:44:23 -04:00
|
|
|
if (!g_ascii_isxdigit (*p) && (*p != ',') && (*p != '.')) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid SUBCHANNELS '%s'", value);
|
2010-05-26 17:35:57 -07:00
|
|
|
success = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
guint32 num_chans;
|
|
|
|
|
|
|
|
|
|
chans = g_strsplit_set (value, ",", 0);
|
|
|
|
|
num_chans = g_strv_length (chans);
|
|
|
|
|
if (num_chans < 2 || num_chans > 3) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid SUBCHANNELS '%s' (%d channels, 2 or 3 expected)",
|
|
|
|
|
value, g_strv_length (chans));
|
2014-08-21 13:19:53 -04:00
|
|
|
} else
|
|
|
|
|
g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, chans, NULL);
|
2010-05-26 17:35:57 -07:00
|
|
|
g_strfreev (chans);
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-25 23:46:47 -07:00
|
|
|
value = svGetValue (ifcfg, "PORTNAME", FALSE);
|
2010-06-29 00:37:14 -07:00
|
|
|
if (value && strlen (value)) {
|
|
|
|
|
nm_setting_wired_add_s390_option (s_wired, "portname", value);
|
|
|
|
|
}
|
2010-06-25 23:46:47 -07:00
|
|
|
g_free (value);
|
|
|
|
|
|
2011-04-12 15:38:47 -05:00
|
|
|
value = svGetValue (ifcfg, "CTCPROT", FALSE);
|
|
|
|
|
if (value && strlen (value))
|
|
|
|
|
nm_setting_wired_add_s390_option (s_wired, "ctcprot", value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2010-06-25 23:46:47 -07:00
|
|
|
nettype = svGetValue (ifcfg, "NETTYPE", FALSE);
|
|
|
|
|
if (nettype && strlen (nettype)) {
|
|
|
|
|
if (!strcmp (nettype, "qeth") || !strcmp (nettype, "lcs") || !strcmp (nettype, "ctc"))
|
|
|
|
|
g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, nettype, NULL);
|
|
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("unknown s390 NETTYPE '%s'", nettype);
|
2010-06-25 23:46:47 -07:00
|
|
|
}
|
2011-04-12 15:38:47 -05:00
|
|
|
g_free (nettype);
|
2010-06-25 23:46:47 -07:00
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "OPTIONS", FALSE);
|
|
|
|
|
if (value && strlen (value)) {
|
|
|
|
|
char **options, **iter;
|
|
|
|
|
|
|
|
|
|
iter = options = g_strsplit_set (value, " ", 0);
|
|
|
|
|
while (iter && *iter) {
|
2010-06-29 00:37:14 -07:00
|
|
|
char *equals = strchr (*iter, '=');
|
|
|
|
|
gboolean valid = FALSE;
|
|
|
|
|
|
|
|
|
|
if (equals) {
|
|
|
|
|
*equals = '\0';
|
|
|
|
|
valid = nm_setting_wired_add_s390_option (s_wired, *iter, equals + 1);
|
|
|
|
|
}
|
|
|
|
|
if (!valid)
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid s390 OPTION '%s'", *iter);
|
2010-06-25 23:46:47 -07:00
|
|
|
iter++;
|
|
|
|
|
}
|
|
|
|
|
g_strfreev (options);
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
value = svGetValue (ifcfg, "MACADDR", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
value = g_strstrip (value);
|
|
|
|
|
g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, value, NULL);
|
|
|
|
|
g_free (value);
|
2010-06-22 14:21:25 +02:00
|
|
|
}
|
|
|
|
|
|
2011-06-30 17:58:31 +02:00
|
|
|
value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE);
|
2011-06-30 13:23:28 +02:00
|
|
|
if (value) {
|
2014-09-10 10:26:11 +02:00
|
|
|
char **strv;
|
2011-06-30 13:23:28 +02:00
|
|
|
|
2014-09-19 21:12:51 +02:00
|
|
|
strv = transform_hwaddr_blacklist (value);
|
2014-09-10 10:26:11 +02:00
|
|
|
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, strv, NULL);
|
|
|
|
|
g_strfreev (strv);
|
2011-06-30 13:23:28 +02:00
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-10 10:44:32 -04:00
|
|
|
value = svGetValue (ifcfg, "KEY_MGMT", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
if (!strcmp (value, "IEEE8021X")) {
|
2009-03-10 18:23:13 -04:00
|
|
|
*s_8021x = fill_8021x (ifcfg, file, value, FALSE, error);
|
2009-03-10 10:44:32 -04:00
|
|
|
if (!*s_8021x)
|
|
|
|
|
goto error;
|
|
|
|
|
} else {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2009-03-10 10:44:32 -04:00
|
|
|
"Unknown wired KEY_MGMT type '%s'", value);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-21 18:24:07 +02:00
|
|
|
value = svGetValueFull (ifcfg, "ETHTOOL_OPTS", FALSE);
|
2015-05-12 11:55:52 +02:00
|
|
|
parse_ethtool_options (ifcfg, s_wired, value);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2007-11-21 06:24:15 +00:00
|
|
|
return (NMSetting *) s_wired;
|
2009-03-10 10:44:32 -04:00
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_free (value);
|
|
|
|
|
g_object_unref (s_wired);
|
|
|
|
|
return NULL;
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMConnection *
|
2008-07-31 16:19:28 +00:00
|
|
|
wired_connection_from_ifcfg (const char *file,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
GError **error)
|
2007-11-21 06:24:15 +00:00
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSetting *con_setting = NULL;
|
|
|
|
|
NMSetting *wired_setting = NULL;
|
2009-03-10 10:44:32 -04:00
|
|
|
NMSetting8021x *s_8021x = NULL;
|
2007-11-21 06:24:15 +00:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (file != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, NULL);
|
|
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2011-11-10 14:16:01 +01:00
|
|
|
con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL, NULL);
|
2007-11-21 06:24:15 +00:00
|
|
|
if (!con_setting) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2007-11-27 19:25:46 +00:00
|
|
|
"Failed to create connection setting.");
|
2008-07-31 16:19:28 +00:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
2012-09-19 10:34:36 -04:00
|
|
|
check_if_bond_slave (ifcfg, NM_SETTING_CONNECTION (con_setting));
|
2013-07-25 15:36:47 +02:00
|
|
|
check_if_team_slave (ifcfg, NM_SETTING_CONNECTION (con_setting));
|
2007-11-21 06:24:15 +00:00
|
|
|
nm_connection_add_setting (connection, con_setting);
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
wired_setting = make_wired_setting (ifcfg, file, &s_8021x, error);
|
2008-07-31 16:19:28 +00:00
|
|
|
if (!wired_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2007-11-21 06:24:15 +00:00
|
|
|
nm_connection_add_setting (connection, wired_setting);
|
|
|
|
|
|
2009-03-10 10:44:32 -04:00
|
|
|
if (s_8021x)
|
|
|
|
|
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
|
|
|
|
|
|
2007-11-21 06:24:15 +00:00
|
|
|
return connection;
|
|
|
|
|
}
|
2008-03-08 00:12:42 +00:00
|
|
|
|
2013-06-10 16:18:48 -03:00
|
|
|
static gboolean
|
|
|
|
|
parse_infiniband_p_key (shvarFile *ifcfg,
|
|
|
|
|
int *out_p_key,
|
|
|
|
|
char **out_parent,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2013-08-02 13:46:16 -04:00
|
|
|
char *device = NULL, *physdev = NULL, *pkey_id = NULL, *end;
|
2013-06-10 16:18:48 -03:00
|
|
|
char *ifname = NULL;
|
2014-02-27 18:24:14 +01:00
|
|
|
guint32 id = G_MAXUINT32;
|
2013-06-10 16:18:48 -03:00
|
|
|
gboolean ret = FALSE;
|
|
|
|
|
|
|
|
|
|
device = svGetValue (ifcfg, "DEVICE", FALSE);
|
|
|
|
|
if (!device) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("InfiniBand connection specified PKEY but not DEVICE");
|
2013-06-10 16:18:48 -03:00
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
physdev = svGetValue (ifcfg, "PHYSDEV", FALSE);
|
|
|
|
|
if (!physdev) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("InfiniBand connection specified PKEY but not PHYSDEV");
|
2013-06-10 16:18:48 -03:00
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-02 13:46:16 -04:00
|
|
|
pkey_id = svGetValue (ifcfg, "PKEY_ID", FALSE);
|
|
|
|
|
if (!pkey_id) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("InfiniBand connection specified PKEY but not PKEY_ID");
|
2013-06-10 16:18:48 -03:00
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-02 13:46:16 -04:00
|
|
|
if (g_str_has_prefix (pkey_id, "0x"))
|
|
|
|
|
id = strtoul (pkey_id, &end, 16);
|
|
|
|
|
else if (!g_str_has_prefix (pkey_id, "0"))
|
|
|
|
|
id = strtoul (pkey_id, &end, 10);
|
2013-06-10 16:18:48 -03:00
|
|
|
else
|
2013-08-02 13:46:16 -04:00
|
|
|
end = pkey_id;
|
|
|
|
|
if (end == pkey_id || *end || id > 0xFFFF) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid InfiniBand PKEY_ID '%s'", pkey_id);
|
2013-06-10 16:18:48 -03:00
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
id = (id | 0x8000);
|
|
|
|
|
|
|
|
|
|
ifname = g_strdup_printf ("%s.%04x", physdev, id);
|
|
|
|
|
if (strcmp (device, ifname) != 0) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("InfiniBand DEVICE (%s) does not match PHYSDEV+PKEY_ID (%s)",
|
|
|
|
|
device, ifname);
|
2013-06-10 16:18:48 -03:00
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*out_p_key = id;
|
|
|
|
|
*out_parent = g_strdup (physdev);
|
|
|
|
|
ret = TRUE;
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
g_free (device);
|
|
|
|
|
g_free (physdev);
|
2013-08-02 13:46:16 -04:00
|
|
|
g_free (pkey_id);
|
2013-06-10 16:18:48 -03:00
|
|
|
g_free (ifname);
|
|
|
|
|
|
|
|
|
|
if (!ret) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2013-06-10 16:18:48 -03:00
|
|
|
"Failed to create InfiniBand setting.");
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-10-21 09:34:30 -04:00
|
|
|
static NMSetting *
|
|
|
|
|
make_infiniband_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingInfiniband *s_infiniband;
|
|
|
|
|
char *value = NULL;
|
|
|
|
|
int mtu;
|
|
|
|
|
|
|
|
|
|
s_infiniband = NM_SETTING_INFINIBAND (nm_setting_infiniband_new ());
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "MTU", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
if (get_int (value, &mtu)) {
|
|
|
|
|
if (mtu >= 0 && mtu < 65536)
|
|
|
|
|
g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, mtu, NULL);
|
|
|
|
|
} else {
|
|
|
|
|
/* Shouldn't be fatal... */
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid MTU '%s'", value);
|
2011-10-21 09:34:30 -04:00
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
value = svGetValue (ifcfg, "HWADDR", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
value = g_strstrip (value);
|
|
|
|
|
g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, value, NULL);
|
|
|
|
|
g_free (value);
|
2011-10-21 09:34:30 -04:00
|
|
|
}
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (ifcfg, "CONNECTED_MODE", FALSE))
|
2011-11-14 14:52:40 -05:00
|
|
|
g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL);
|
2012-03-16 13:48:11 -04:00
|
|
|
else
|
|
|
|
|
g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL);
|
2011-11-14 14:52:40 -05:00
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (ifcfg, "PKEY", FALSE)) {
|
2013-06-10 16:18:48 -03:00
|
|
|
int p_key;
|
|
|
|
|
char *parent;
|
|
|
|
|
|
|
|
|
|
if (!parse_infiniband_p_key (ifcfg, &p_key, &parent, error)) {
|
|
|
|
|
g_object_unref (s_infiniband);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_object_set (s_infiniband,
|
|
|
|
|
NM_SETTING_INFINIBAND_P_KEY, p_key,
|
|
|
|
|
NM_SETTING_INFINIBAND_PARENT, parent,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-21 09:34:30 -04:00
|
|
|
return (NMSetting *) s_infiniband;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMConnection *
|
|
|
|
|
infiniband_connection_from_ifcfg (const char *file,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSetting *con_setting = NULL;
|
|
|
|
|
NMSetting *infiniband_setting = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (file != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, NULL);
|
|
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2011-10-21 09:34:30 -04:00
|
|
|
|
|
|
|
|
con_setting = make_connection_setting (file, ifcfg, NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL);
|
|
|
|
|
if (!con_setting) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2011-10-21 09:34:30 -04:00
|
|
|
"Failed to create connection setting.");
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2012-09-19 10:34:36 -04:00
|
|
|
check_if_bond_slave (ifcfg, NM_SETTING_CONNECTION (con_setting));
|
2013-07-25 15:36:47 +02:00
|
|
|
check_if_team_slave (ifcfg, NM_SETTING_CONNECTION (con_setting));
|
2011-10-21 09:34:30 -04:00
|
|
|
nm_connection_add_setting (connection, con_setting);
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
infiniband_setting = make_infiniband_setting (ifcfg, file, error);
|
2011-10-21 09:34:30 -04:00
|
|
|
if (!infiniband_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, infiniband_setting);
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-18 13:48:42 +02:00
|
|
|
static void
|
|
|
|
|
handle_bond_option (NMSettingBond *s_bond,
|
|
|
|
|
const char *key,
|
|
|
|
|
const char *value)
|
|
|
|
|
{
|
2013-10-01 18:27:25 +02:00
|
|
|
char *sanitized = NULL, *j;
|
|
|
|
|
const char *p = value;
|
|
|
|
|
|
|
|
|
|
/* Remove any quotes or +/- from arp_ip_target */
|
|
|
|
|
if (!g_strcmp0 (key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET) && value && value[0]) {
|
|
|
|
|
if (*p == '\'' || *p == '"')
|
|
|
|
|
p++;
|
|
|
|
|
j = sanitized = g_malloc0 (strlen (p) + 1);
|
|
|
|
|
while (*p) {
|
|
|
|
|
if (*p != '+' && *p != '-' && *p != '\'' && *p != '"')
|
|
|
|
|
*j++ = *p;
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!nm_setting_bond_add_option (s_bond, key, sanitized ? sanitized : value))
|
2014-12-17 10:31:12 +01:00
|
|
|
PARSE_WARNING ("invalid bonding option '%s' = %s",
|
|
|
|
|
key, sanitized ? sanitized : value);
|
2013-10-01 18:27:25 +02:00
|
|
|
g_free (sanitized);
|
2011-10-18 13:48:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMSetting *
|
|
|
|
|
make_bond_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingBond *s_bond;
|
|
|
|
|
char *value;
|
|
|
|
|
|
|
|
|
|
s_bond = NM_SETTING_BOND (nm_setting_bond_new ());
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "DEVICE", FALSE);
|
|
|
|
|
if (!value || !strlen (value)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"mandatory DEVICE keyword missing");
|
2011-10-18 13:48:42 +02:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "BONDING_OPTS", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
char **items, **iter;
|
|
|
|
|
|
|
|
|
|
items = g_strsplit_set (value, " ", -1);
|
|
|
|
|
for (iter = items; iter && *iter; iter++) {
|
|
|
|
|
if (strlen (*iter)) {
|
|
|
|
|
char **keys, *key, *val;
|
|
|
|
|
|
|
|
|
|
keys = g_strsplit_set (*iter, "=", 2);
|
|
|
|
|
if (keys && *keys) {
|
|
|
|
|
key = *keys;
|
|
|
|
|
val = *(keys + 1);
|
|
|
|
|
if (val && strlen(key) && strlen(val))
|
|
|
|
|
handle_bond_option (s_bond, key, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_strfreev (keys);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
g_strfreev (items);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (NMSetting *) s_bond;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_object_unref (s_bond);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMConnection *
|
|
|
|
|
bond_connection_from_ifcfg (const char *file,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSetting *con_setting = NULL;
|
|
|
|
|
NMSetting *bond_setting = NULL;
|
|
|
|
|
NMSetting *wired_setting = NULL;
|
|
|
|
|
NMSetting8021x *s_8021x = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (file != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, NULL);
|
|
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2011-10-18 13:48:42 +02:00
|
|
|
|
2011-11-10 14:16:01 +01:00
|
|
|
con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BOND_SETTING_NAME, NULL, _("Bond"));
|
2011-10-18 13:48:42 +02:00
|
|
|
if (!con_setting) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2011-10-18 13:48:42 +02:00
|
|
|
"Failed to create connection setting.");
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, con_setting);
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
bond_setting = make_bond_setting (ifcfg, file, error);
|
2011-10-18 13:48:42 +02:00
|
|
|
if (!bond_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, bond_setting);
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
wired_setting = make_wired_setting (ifcfg, file, &s_8021x, error);
|
2011-10-18 13:48:42 +02:00
|
|
|
if (!wired_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, wired_setting);
|
|
|
|
|
|
|
|
|
|
if (s_8021x)
|
|
|
|
|
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-14 10:05:42 +01:00
|
|
|
/* Check 'error' for errors. Missing config (NULL return value) is a valid case. */
|
2014-01-22 16:34:41 -06:00
|
|
|
static char *
|
|
|
|
|
read_team_config (shvarFile *ifcfg, const char *key, GError **error)
|
|
|
|
|
{
|
|
|
|
|
char *value;
|
|
|
|
|
size_t l;
|
|
|
|
|
|
|
|
|
|
/* FIXME: validate the JSON at some point */
|
|
|
|
|
value = svGetValue (ifcfg, key, TRUE);
|
|
|
|
|
if (!value)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* No reason Team config should be over 20k. The config is read
|
|
|
|
|
* verbatim, length-checked, then unescaped. svUnescape() does not
|
|
|
|
|
* deal well with extremely long strings.
|
|
|
|
|
*/
|
|
|
|
|
l = strlen (value);
|
|
|
|
|
if (l > 20000) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"%s too long (size %zd)", key, l);
|
2014-01-22 16:34:41 -06:00
|
|
|
g_free (value);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
svUnescape (value);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-25 15:36:47 +02:00
|
|
|
static NMSetting *
|
|
|
|
|
make_team_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingTeam *s_team;
|
|
|
|
|
char *value;
|
2014-02-14 10:05:42 +01:00
|
|
|
GError *local_err = NULL;
|
2013-07-25 15:36:47 +02:00
|
|
|
|
|
|
|
|
s_team = NM_SETTING_TEAM (nm_setting_team_new ());
|
|
|
|
|
|
2014-01-22 16:34:41 -06:00
|
|
|
value = svGetValue (ifcfg, "DEVICE", FALSE);
|
2013-07-25 15:36:47 +02:00
|
|
|
if (!value || !strlen (value)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"mandatory DEVICE keyword missing");
|
2013-07-25 15:36:47 +02:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2014-02-14 10:05:42 +01:00
|
|
|
value = read_team_config (ifcfg, "TEAM_CONFIG", &local_err);
|
|
|
|
|
if (local_err) {
|
|
|
|
|
g_propagate_error (error, local_err);
|
2014-01-22 16:34:41 -06:00
|
|
|
goto error;
|
2014-02-14 10:05:42 +01:00
|
|
|
}
|
2014-01-22 16:34:41 -06:00
|
|
|
g_object_set (s_team, NM_SETTING_TEAM_CONFIG, value, NULL);
|
|
|
|
|
g_free (value);
|
2013-07-25 15:36:47 +02:00
|
|
|
|
|
|
|
|
return (NMSetting *) s_team;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_object_unref (s_team);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMConnection *
|
|
|
|
|
team_connection_from_ifcfg (const char *file,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSetting *con_setting = NULL;
|
|
|
|
|
NMSetting *team_setting = NULL;
|
|
|
|
|
NMSetting *wired_setting = NULL;
|
|
|
|
|
NMSetting8021x *s_8021x = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (file != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, NULL);
|
|
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2013-07-25 15:36:47 +02:00
|
|
|
|
|
|
|
|
con_setting = make_connection_setting (file, ifcfg, NM_SETTING_TEAM_SETTING_NAME, NULL, _("Team"));
|
|
|
|
|
if (!con_setting) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2013-07-25 15:36:47 +02:00
|
|
|
"Failed to create connection setting.");
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, con_setting);
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
team_setting = make_team_setting (ifcfg, file, error);
|
2013-07-25 15:36:47 +02:00
|
|
|
if (!team_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, team_setting);
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
wired_setting = make_wired_setting (ifcfg, file, &s_8021x, error);
|
2013-07-25 15:36:47 +02:00
|
|
|
if (!wired_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, wired_setting);
|
|
|
|
|
|
|
|
|
|
if (s_8021x)
|
|
|
|
|
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-23 16:19:28 +02:00
|
|
|
typedef void (*BridgeOptFunc) (NMSetting *setting,
|
|
|
|
|
gboolean stp,
|
|
|
|
|
const char *key,
|
|
|
|
|
const char *value);
|
|
|
|
|
|
2012-05-23 16:19:27 +02:00
|
|
|
static void
|
2012-05-23 16:19:28 +02:00
|
|
|
handle_bridge_option (NMSetting *setting,
|
2012-05-23 16:19:27 +02:00
|
|
|
gboolean stp,
|
|
|
|
|
const char *key,
|
|
|
|
|
const char *value)
|
|
|
|
|
{
|
|
|
|
|
guint32 u = 0;
|
|
|
|
|
|
|
|
|
|
if (!strcmp (key, "priority")) {
|
|
|
|
|
if (stp == FALSE) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("'priority' invalid when STP is disabled");
|
2012-05-23 16:19:27 +02:00
|
|
|
} else if (get_uint (value, &u))
|
2012-05-23 16:19:28 +02:00
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_PRIORITY, u, NULL);
|
2012-05-23 16:19:27 +02:00
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid priority value '%s'", value);
|
2012-05-23 16:19:27 +02:00
|
|
|
} else if (!strcmp (key, "hello_time")) {
|
|
|
|
|
if (stp == FALSE) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("'hello_time' invalid when STP is disabled");
|
2012-05-23 16:19:27 +02:00
|
|
|
} else if (get_uint (value, &u))
|
2012-05-23 16:19:28 +02:00
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_HELLO_TIME, u, NULL);
|
2012-05-23 16:19:27 +02:00
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid hello_time value '%s'", value);
|
2012-05-23 16:19:27 +02:00
|
|
|
} else if (!strcmp (key, "max_age")) {
|
|
|
|
|
if (stp == FALSE) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("'max_age' invalid when STP is disabled");
|
2012-05-23 16:19:27 +02:00
|
|
|
} else if (get_uint (value, &u))
|
2012-05-23 16:19:28 +02:00
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_MAX_AGE, u, NULL);
|
2012-05-23 16:19:27 +02:00
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid max_age value '%s'", value);
|
2012-05-23 16:19:27 +02:00
|
|
|
} else if (!strcmp (key, "ageing_time")) {
|
|
|
|
|
if (get_uint (value, &u))
|
2012-05-23 16:19:28 +02:00
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_AGEING_TIME, u, NULL);
|
2012-05-23 16:19:27 +02:00
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid ageing_time value '%s'", value);
|
2015-02-20 12:40:36 +01:00
|
|
|
} else if (!strcmp (key, "multicast_snooping")) {
|
|
|
|
|
if (get_uint (value, &u))
|
|
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_MULTICAST_SNOOPING,
|
|
|
|
|
(gboolean) u, NULL);
|
|
|
|
|
else
|
|
|
|
|
PARSE_WARNING ("invalid multicast_snooping value '%s'", value);
|
2012-05-23 16:19:27 +02:00
|
|
|
} else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("unhandled bridge option '%s'", key);
|
2012-05-23 16:19:27 +02:00
|
|
|
}
|
|
|
|
|
|
2012-05-23 16:19:28 +02:00
|
|
|
static void
|
|
|
|
|
handle_bridging_opts (NMSetting *setting,
|
|
|
|
|
gboolean stp,
|
|
|
|
|
const char *value,
|
|
|
|
|
BridgeOptFunc func)
|
|
|
|
|
{
|
|
|
|
|
char **items, **iter;
|
|
|
|
|
|
|
|
|
|
items = g_strsplit_set (value, " ", -1);
|
|
|
|
|
for (iter = items; iter && *iter; iter++) {
|
|
|
|
|
if (strlen (*iter)) {
|
|
|
|
|
char **keys, *key, *val;
|
|
|
|
|
|
|
|
|
|
keys = g_strsplit_set (*iter, "=", 2);
|
|
|
|
|
if (keys && *keys) {
|
|
|
|
|
key = *keys;
|
|
|
|
|
val = *(keys + 1);
|
|
|
|
|
if (val && strlen(key) && strlen(val))
|
|
|
|
|
func (setting, stp, key, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_strfreev (keys);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_strfreev (items);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-23 16:19:27 +02:00
|
|
|
static NMSetting *
|
|
|
|
|
make_bridge_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingBridge *s_bridge;
|
|
|
|
|
char *value;
|
|
|
|
|
guint32 u;
|
|
|
|
|
gboolean stp = FALSE;
|
2013-03-22 09:13:12 -05:00
|
|
|
gboolean stp_set = FALSE;
|
2012-05-23 16:19:27 +02:00
|
|
|
|
|
|
|
|
s_bridge = NM_SETTING_BRIDGE (nm_setting_bridge_new ());
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "DEVICE", FALSE);
|
|
|
|
|
if (!value || !strlen (value)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"mandatory DEVICE keyword missing");
|
2012-05-23 16:19:27 +02:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
value = svGetValue (ifcfg, "MACADDR", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
value = g_strstrip (value);
|
|
|
|
|
g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, value, NULL);
|
|
|
|
|
g_free (value);
|
2014-05-21 09:13:33 +02:00
|
|
|
}
|
|
|
|
|
|
2012-05-23 16:19:27 +02:00
|
|
|
value = svGetValue (ifcfg, "STP", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
if (!strcasecmp (value, "on") || !strcasecmp (value, "yes")) {
|
|
|
|
|
g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, TRUE, NULL);
|
|
|
|
|
stp = TRUE;
|
2013-03-22 09:13:12 -05:00
|
|
|
stp_set = TRUE;
|
|
|
|
|
} else if (!strcasecmp (value, "off") || !strcasecmp (value, "no")) {
|
2012-05-23 16:19:27 +02:00
|
|
|
g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL);
|
2013-03-22 09:13:12 -05:00
|
|
|
stp_set = TRUE;
|
|
|
|
|
} else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid STP value '%s'", value);
|
2012-05-23 16:19:27 +02:00
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-22 09:13:12 -05:00
|
|
|
if (!stp_set) {
|
|
|
|
|
/* Missing or invalid STP property means "no" */
|
|
|
|
|
g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-23 16:19:27 +02:00
|
|
|
value = svGetValue (ifcfg, "DELAY", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
if (stp) {
|
|
|
|
|
if (get_uint (value, &u))
|
|
|
|
|
g_object_set (s_bridge, NM_SETTING_BRIDGE_FORWARD_DELAY, u, NULL);
|
|
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid forward delay value '%s'", value);
|
2012-05-23 16:19:27 +02:00
|
|
|
} else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("DELAY invalid when STP is disabled");
|
2012-05-23 16:19:27 +02:00
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "BRIDGING_OPTS", FALSE);
|
|
|
|
|
if (value) {
|
2012-05-23 16:19:28 +02:00
|
|
|
handle_bridging_opts (NM_SETTING (s_bridge), stp, value, handle_bridge_option);
|
2012-05-23 16:19:27 +02:00
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (NMSetting *) s_bridge;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_object_unref (s_bridge);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMConnection *
|
|
|
|
|
bridge_connection_from_ifcfg (const char *file,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSetting *con_setting = NULL;
|
|
|
|
|
NMSetting *bridge_setting = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (file != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, NULL);
|
|
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2012-05-23 16:19:27 +02:00
|
|
|
|
|
|
|
|
con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BRIDGE_SETTING_NAME, NULL, _("Bridge"));
|
|
|
|
|
if (!con_setting) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2012-05-23 16:19:27 +02:00
|
|
|
"Failed to create connection setting.");
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, con_setting);
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
bridge_setting = make_bridge_setting (ifcfg, file, error);
|
2012-05-23 16:19:27 +02:00
|
|
|
if (!bridge_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, bridge_setting);
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-23 16:19:28 +02:00
|
|
|
static void
|
|
|
|
|
handle_bridge_port_option (NMSetting *setting,
|
|
|
|
|
gboolean stp,
|
|
|
|
|
const char *key,
|
|
|
|
|
const char *value)
|
|
|
|
|
{
|
|
|
|
|
guint32 u = 0;
|
|
|
|
|
|
|
|
|
|
if (!strcmp (key, "priority")) {
|
|
|
|
|
if (get_uint (value, &u))
|
|
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_PORT_PRIORITY, u, NULL);
|
|
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid priority value '%s'", value);
|
2012-05-23 16:19:28 +02:00
|
|
|
} else if (!strcmp (key, "path_cost")) {
|
|
|
|
|
if (get_uint (value, &u))
|
|
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_PORT_PATH_COST, u, NULL);
|
|
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid path_cost value '%s'", value);
|
2012-05-23 16:19:28 +02:00
|
|
|
} else if (!strcmp (key, "hairpin_mode")) {
|
|
|
|
|
if (!strcasecmp (value, "on") || !strcasecmp (value, "yes") || !strcmp (value, "1"))
|
|
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, TRUE, NULL);
|
|
|
|
|
else if (!strcasecmp (value, "off") || !strcasecmp (value, "no"))
|
|
|
|
|
g_object_set (setting, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, FALSE, NULL);
|
|
|
|
|
else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("invalid hairpin_mode value '%s'", value);
|
2012-05-23 16:19:28 +02:00
|
|
|
} else
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("unhandled bridge port option '%s'", key);
|
2012-05-23 16:19:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMSetting *
|
2013-03-22 09:25:58 -05:00
|
|
|
make_bridge_port_setting (shvarFile *ifcfg)
|
2012-05-23 16:19:28 +02:00
|
|
|
{
|
2013-03-22 09:25:58 -05:00
|
|
|
NMSetting *s_port = NULL;
|
2012-05-23 16:19:28 +02:00
|
|
|
char *value;
|
|
|
|
|
|
2013-03-22 09:25:58 -05:00
|
|
|
g_return_val_if_fail (ifcfg != NULL, FALSE);
|
2012-05-23 16:19:28 +02:00
|
|
|
|
2013-03-22 09:25:58 -05:00
|
|
|
value = svGetValue (ifcfg, "BRIDGE", FALSE);
|
2012-05-23 16:19:28 +02:00
|
|
|
if (value) {
|
2013-03-22 09:25:58 -05:00
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
s_port = nm_setting_bridge_port_new ();
|
|
|
|
|
value = svGetValue (ifcfg, "BRIDGING_OPTS", FALSE);
|
|
|
|
|
if (value)
|
|
|
|
|
handle_bridging_opts (s_port, FALSE, value, handle_bridge_port_option);
|
2012-05-23 16:19:28 +02:00
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s_port;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-25 15:36:47 +02:00
|
|
|
static NMSetting *
|
|
|
|
|
make_team_port_setting (shvarFile *ifcfg)
|
|
|
|
|
{
|
|
|
|
|
NMSetting *s_port = NULL;
|
|
|
|
|
char *value;
|
2014-01-22 16:34:41 -06:00
|
|
|
GError *error = NULL;
|
2013-07-25 15:36:47 +02:00
|
|
|
|
2014-01-22 16:34:41 -06:00
|
|
|
value = read_team_config (ifcfg, "TEAM_PORT_CONFIG", &error);
|
2013-07-25 15:36:47 +02:00
|
|
|
if (value) {
|
|
|
|
|
s_port = nm_setting_team_port_new ();
|
|
|
|
|
g_object_set (s_port, NM_SETTING_TEAM_PORT_CONFIG, value, NULL);
|
|
|
|
|
g_free (value);
|
2014-01-22 16:34:41 -06:00
|
|
|
} else if (error) {
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("%s", error->message);
|
2014-01-22 16:34:41 -06:00
|
|
|
g_error_free (error);
|
2013-07-25 15:36:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s_port;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-18 13:48:42 +02:00
|
|
|
static gboolean
|
|
|
|
|
is_bond_device (const char *name, shvarFile *parsed)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (name != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (parsed != NULL, FALSE);
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (parsed, "BONDING_MASTER", FALSE))
|
2011-10-18 13:48:42 +02:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
/* XXX: Check for "bond[\d]+"? */
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-16 22:08:42 +08:00
|
|
|
static gboolean
|
|
|
|
|
is_vlan_device (const char *name, shvarFile *parsed)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (name != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (parsed != NULL, FALSE);
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (parsed, "VLAN", FALSE))
|
2012-02-16 22:08:42 +08:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-04 14:27:03 +01:00
|
|
|
static gboolean
|
|
|
|
|
is_wifi_device (const char *name, shvarFile *parsed)
|
|
|
|
|
{
|
|
|
|
|
int ifindex;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (name != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (parsed != NULL, FALSE);
|
|
|
|
|
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, name);
|
2014-02-04 14:27:03 +01:00
|
|
|
if (ifindex == 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
return nm_platform_link_get_type (NM_PLATFORM_GET, ifindex) == NM_LINK_TYPE_WIFI;
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
2011-12-21 18:03:28 -06:00
|
|
|
static void
|
|
|
|
|
parse_prio_map_list (NMSettingVlan *s_vlan,
|
|
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
const char *key,
|
|
|
|
|
NMVlanPriorityMap map)
|
|
|
|
|
{
|
|
|
|
|
char *value;
|
|
|
|
|
gchar **list = NULL, **iter;
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, key, FALSE);
|
|
|
|
|
if (!value)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
list = g_strsplit_set (value, ",", -1);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
|
|
for (iter = list; iter && *iter; iter++) {
|
|
|
|
|
if (!*iter || !strchr (*iter, ':'))
|
|
|
|
|
continue;
|
|
|
|
|
|
2014-04-05 09:37:04 -04:00
|
|
|
if (!nm_setting_vlan_add_priority_str (s_vlan, map, *iter))
|
|
|
|
|
PARSE_WARNING ("invalid %s priority map item '%s'", key, *iter);
|
2011-12-21 18:03:28 -06:00
|
|
|
}
|
|
|
|
|
g_strfreev (list);
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-12 22:20:56 -05:00
|
|
|
static NMSetting *
|
|
|
|
|
make_vlan_setting (shvarFile *ifcfg,
|
|
|
|
|
const char *file,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingVlan *s_vlan = NULL;
|
|
|
|
|
char *value = NULL;
|
2011-12-21 18:03:28 -06:00
|
|
|
char *iface_name = NULL;
|
2012-02-21 12:17:28 -06:00
|
|
|
char *parent = NULL;
|
2012-04-25 14:40:04 -04:00
|
|
|
const char *p = NULL;
|
|
|
|
|
char *end = NULL;
|
2012-02-21 12:17:28 -06:00
|
|
|
gint vlan_id = -1;
|
2011-12-12 22:20:56 -05:00
|
|
|
guint32 vlan_flags = 0;
|
2015-09-01 17:34:26 +02:00
|
|
|
gint gvrp;
|
2011-12-12 22:20:56 -05:00
|
|
|
|
2012-02-21 12:17:28 -06:00
|
|
|
value = svGetValue (ifcfg, "VLAN_ID", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
errno = 0;
|
|
|
|
|
vlan_id = (gint) g_ascii_strtoll (value, NULL, 10);
|
|
|
|
|
if (vlan_id < 0 || vlan_id > 4096 || errno) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Invalid VLAN_ID '%s'", value);
|
2012-02-21 12:17:28 -06:00
|
|
|
g_free (value);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Need DEVICE if we don't have a separate VLAN_ID property */
|
2011-12-21 18:03:28 -06:00
|
|
|
iface_name = svGetValue (ifcfg, "DEVICE", FALSE);
|
2012-02-21 12:17:28 -06:00
|
|
|
if (!iface_name && vlan_id < 0) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2011-12-21 18:03:28 -06:00
|
|
|
"Missing DEVICE property; cannot determine VLAN ID.");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-12 22:20:56 -05:00
|
|
|
s_vlan = NM_SETTING_VLAN (nm_setting_vlan_new ());
|
|
|
|
|
|
2013-08-04 22:32:35 -05:00
|
|
|
/* Parent interface from PHYSDEV takes precedence if it exists */
|
|
|
|
|
parent = svGetValue (ifcfg, "PHYSDEV", FALSE);
|
|
|
|
|
|
2012-02-21 12:17:28 -06:00
|
|
|
if (iface_name) {
|
|
|
|
|
p = strchr (iface_name, '.');
|
|
|
|
|
if (p) {
|
2013-08-04 22:32:35 -05:00
|
|
|
/* eth0.43; PHYSDEV is assumed from it if unknown */
|
|
|
|
|
if (!parent) {
|
|
|
|
|
parent = g_strndup (iface_name, p - iface_name);
|
|
|
|
|
if (g_str_has_prefix (parent, "vlan")) {
|
|
|
|
|
/* Like initscripts, if no PHYSDEV and we get an obviously
|
|
|
|
|
* invalid parent interface from DEVICE, fail.
|
|
|
|
|
*/
|
|
|
|
|
g_free (parent);
|
|
|
|
|
parent = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-02-21 12:17:28 -06:00
|
|
|
p++;
|
|
|
|
|
} else {
|
2014-09-25 18:07:56 +02:00
|
|
|
/* format like vlan43; PHYSDEV must be set */
|
2012-02-21 12:17:28 -06:00
|
|
|
if (g_str_has_prefix (iface_name, "vlan"))
|
|
|
|
|
p = iface_name + 4;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-25 14:40:04 -04:00
|
|
|
if (p) {
|
|
|
|
|
/* Grab VLAN ID from interface name; this takes precedence over the
|
|
|
|
|
* separate VLAN_ID property for backwards compat.
|
|
|
|
|
*/
|
2015-06-23 21:08:29 +02:00
|
|
|
|
|
|
|
|
gint device_vlan_id = (gint) g_ascii_strtoll (p, &end, 10);
|
|
|
|
|
if (device_vlan_id >= 0 && device_vlan_id <= 4095 && end != p && !*end)
|
|
|
|
|
vlan_id = device_vlan_id;
|
2012-02-21 12:17:28 -06:00
|
|
|
}
|
2011-12-21 18:03:28 -06:00
|
|
|
}
|
|
|
|
|
|
2012-02-21 12:17:28 -06:00
|
|
|
if (vlan_id < 0) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2012-02-21 12:17:28 -06:00
|
|
|
"Failed to determine VLAN ID from DEVICE or VLAN_ID.");
|
2011-12-21 18:03:28 -06:00
|
|
|
goto error;
|
2011-12-12 22:20:56 -05:00
|
|
|
}
|
2012-02-21 12:17:28 -06:00
|
|
|
g_object_set (s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL);
|
2011-12-12 22:20:56 -05:00
|
|
|
|
2012-02-21 12:17:28 -06:00
|
|
|
if (parent == NULL) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2012-02-21 12:17:28 -06:00
|
|
|
"Failed to determine VLAN parent from DEVICE or PHYSDEV");
|
2011-12-21 18:03:28 -06:00
|
|
|
goto error;
|
2011-12-12 22:20:56 -05:00
|
|
|
}
|
2012-02-21 12:17:28 -06:00
|
|
|
g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, parent, NULL);
|
2015-02-07 16:54:01 +01:00
|
|
|
g_clear_pointer (&parent, g_free);
|
2011-12-12 22:20:56 -05:00
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (ifcfg, "REORDER_HDR", FALSE))
|
2011-12-21 18:03:28 -06:00
|
|
|
vlan_flags |= NM_VLAN_FLAG_REORDER_HEADERS;
|
2011-12-12 22:20:56 -05:00
|
|
|
|
2015-09-01 17:34:26 +02:00
|
|
|
gvrp = svGetValueBoolean (ifcfg, "GVRP", -1);
|
|
|
|
|
if (gvrp > 0)
|
|
|
|
|
vlan_flags |= NM_VLAN_FLAG_GVRP;
|
|
|
|
|
|
2011-12-12 22:20:56 -05:00
|
|
|
value = svGetValue (ifcfg, "VLAN_FLAGS", FALSE);
|
2012-02-21 12:17:28 -06:00
|
|
|
if (value) {
|
2015-09-01 17:34:26 +02:00
|
|
|
/* Prefer GVRP variable; only take VLAN_FLAG=GVRP when GVRP is not specified */
|
|
|
|
|
if (g_strstr_len (value, -1, "GVRP") && gvrp == -1)
|
2012-02-21 12:17:28 -06:00
|
|
|
vlan_flags |= NM_VLAN_FLAG_GVRP;
|
|
|
|
|
if (g_strstr_len (value, -1, "LOOSE_BINDING"))
|
|
|
|
|
vlan_flags |= NM_VLAN_FLAG_LOOSE_BINDING;
|
|
|
|
|
}
|
2011-12-12 22:20:56 -05:00
|
|
|
|
2015-10-13 10:05:19 +02:00
|
|
|
if (svGetValueBoolean (ifcfg, "MVRP", FALSE))
|
|
|
|
|
vlan_flags |= NM_VLAN_FLAG_MVRP;
|
|
|
|
|
|
2011-12-12 22:20:56 -05:00
|
|
|
g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, vlan_flags, NULL);
|
|
|
|
|
g_free (value);
|
|
|
|
|
|
2011-12-21 18:03:28 -06:00
|
|
|
parse_prio_map_list (s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP);
|
|
|
|
|
parse_prio_map_list (s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP);
|
2011-12-12 22:20:56 -05:00
|
|
|
|
2015-02-07 16:54:01 +01:00
|
|
|
g_free (iface_name);
|
|
|
|
|
|
2011-12-12 22:20:56 -05:00
|
|
|
return (NMSetting *) s_vlan;
|
|
|
|
|
|
2011-12-21 18:03:28 -06:00
|
|
|
error:
|
2012-02-21 12:17:28 -06:00
|
|
|
g_free (parent);
|
2011-12-21 18:03:28 -06:00
|
|
|
g_free (iface_name);
|
2011-12-12 22:20:56 -05:00
|
|
|
g_object_unref (s_vlan);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMConnection *
|
|
|
|
|
vlan_connection_from_ifcfg (const char *file,
|
2011-12-21 18:03:28 -06:00
|
|
|
shvarFile *ifcfg,
|
|
|
|
|
GError **error)
|
2011-12-12 22:20:56 -05:00
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSetting *con_setting = NULL;
|
|
|
|
|
NMSetting *wired_setting = NULL;
|
|
|
|
|
NMSetting *vlan_setting = NULL;
|
|
|
|
|
NMSetting8021x *s_8021x = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (file != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (ifcfg != NULL, NULL);
|
|
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2011-12-12 22:20:56 -05:00
|
|
|
|
|
|
|
|
con_setting = make_connection_setting (file, ifcfg, NM_SETTING_VLAN_SETTING_NAME, NULL, "Vlan");
|
|
|
|
|
if (!con_setting) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"Failed to create connection setting.");
|
2011-12-12 22:20:56 -05:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2014-09-25 18:07:56 +02:00
|
|
|
check_if_bond_slave (ifcfg, NM_SETTING_CONNECTION (con_setting));
|
|
|
|
|
check_if_team_slave (ifcfg, NM_SETTING_CONNECTION (con_setting));
|
2011-12-12 22:20:56 -05:00
|
|
|
nm_connection_add_setting (connection, con_setting);
|
|
|
|
|
|
2014-09-25 18:07:56 +02:00
|
|
|
vlan_setting = make_vlan_setting (ifcfg, file, error);
|
2011-12-12 22:20:56 -05:00
|
|
|
if (!vlan_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, vlan_setting);
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
wired_setting = make_wired_setting (ifcfg, file, &s_8021x, error);
|
2011-12-12 22:20:56 -05:00
|
|
|
if (!wired_setting) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_connection_add_setting (connection, wired_setting);
|
|
|
|
|
|
|
|
|
|
if (s_8021x)
|
|
|
|
|
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
static NMConnection *
|
|
|
|
|
create_unhandled_connection (const char *filename, shvarFile *ifcfg,
|
|
|
|
|
const char *type, char **out_spec)
|
2013-02-12 18:00:48 -05:00
|
|
|
{
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSetting *s_con;
|
|
|
|
|
char *value;
|
|
|
|
|
|
|
|
|
|
g_assert (out_spec != NULL);
|
|
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
|
|
|
|
|
/* Get NAME, UUID, etc. We need to set a connection type (generic) and add
|
|
|
|
|
* an empty type-specific setting as well, to make sure it passes
|
|
|
|
|
* nm_connection_verify() later.
|
|
|
|
|
*/
|
|
|
|
|
s_con = make_connection_setting (filename, ifcfg, NM_SETTING_GENERIC_SETTING_NAME,
|
|
|
|
|
NULL, NULL);
|
|
|
|
|
nm_connection_add_setting (connection, s_con);
|
2013-02-12 18:00:48 -05:00
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
nm_connection_add_setting (connection, nm_setting_generic_new ());
|
|
|
|
|
|
|
|
|
|
/* Get a spec */
|
2013-10-29 10:45:36 -04:00
|
|
|
value = svGetValue (ifcfg, "HWADDR", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
char *lower = g_ascii_strdown (value, -1);
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
*out_spec = g_strdup_printf ("%s:mac:%s", type, lower);
|
2013-10-29 10:45:36 -04:00
|
|
|
g_free (lower);
|
|
|
|
|
g_free (value);
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
return connection;
|
2013-10-29 10:45:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "SUBCHANNELS", FALSE);
|
|
|
|
|
if (value) {
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
*out_spec = g_strdup_printf ("%s:s390-subchannels:%s", type, value);
|
2013-10-29 10:45:36 -04:00
|
|
|
g_free (value);
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
return connection;
|
2013-10-29 10:45:36 -04:00
|
|
|
}
|
2013-02-12 18:00:48 -05:00
|
|
|
|
|
|
|
|
value = svGetValue (ifcfg, "DEVICE", FALSE);
|
|
|
|
|
if (value) {
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
*out_spec = g_strdup_printf ("%s:interface-name:%s", type, value);
|
2013-02-12 18:00:48 -05:00
|
|
|
g_free (value);
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
return connection;
|
2013-02-12 18:00:48 -05:00
|
|
|
}
|
|
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
g_object_unref (connection);
|
2013-10-29 10:45:36 -04:00
|
|
|
return NULL;
|
2013-02-12 18:00:48 -05:00
|
|
|
}
|
|
|
|
|
|
2013-05-23 19:05:40 -03:00
|
|
|
char *
|
|
|
|
|
uuid_from_file (const char *filename)
|
|
|
|
|
{
|
|
|
|
|
const char *ifcfg_name = NULL;
|
|
|
|
|
shvarFile *ifcfg;
|
|
|
|
|
char *uuid;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (filename != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
ifcfg_name = utils_get_ifcfg_name (filename, TRUE);
|
|
|
|
|
if (!ifcfg_name)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2014-03-18 13:13:12 -04:00
|
|
|
ifcfg = svOpenFile (filename, NULL);
|
2013-05-23 19:05:40 -03:00
|
|
|
if (!ifcfg)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* Try for a UUID key before falling back to hashing the file name */
|
|
|
|
|
uuid = svGetValue (ifcfg, "UUID", FALSE);
|
|
|
|
|
if (!uuid || !strlen (uuid)) {
|
|
|
|
|
g_free (uuid);
|
2014-11-27 18:40:18 +01:00
|
|
|
uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL);
|
2013-05-23 19:05:40 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
svCloseFile (ifcfg);
|
|
|
|
|
return uuid;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 13:54:47 +02:00
|
|
|
static void
|
|
|
|
|
check_dns_search_domains (shvarFile *ifcfg, NMSetting *s_ip4, NMSetting *s_ip6)
|
|
|
|
|
{
|
|
|
|
|
if (!s_ip6)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* If there is no IPv4 config or it doesn't contain DNS searches,
|
|
|
|
|
* read DOMAIN and put the domains into IPv6.
|
|
|
|
|
*/
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!s_ip4 || nm_setting_ip_config_get_num_dns_searches (NM_SETTING_IP_CONFIG (s_ip4)) == 0) {
|
2013-09-20 13:54:47 +02:00
|
|
|
/* DNS searches */
|
|
|
|
|
char *value = svGetValue (ifcfg, "DOMAIN", FALSE);
|
|
|
|
|
if (value) {
|
|
|
|
|
char **searches = g_strsplit (value, " ", 0);
|
|
|
|
|
if (searches) {
|
|
|
|
|
char **item;
|
|
|
|
|
for (item = searches; *item; item++) {
|
|
|
|
|
if (strlen (*item)) {
|
2014-10-19 17:30:10 -04:00
|
|
|
if (!nm_setting_ip_config_add_dns_search (NM_SETTING_IP_CONFIG (s_ip6), *item))
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("duplicate DNS domain '%s'", *item);
|
2013-09-20 13:54:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_strfreev (searches);
|
|
|
|
|
}
|
|
|
|
|
g_free (value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-16 09:57:36 -05:00
|
|
|
static NMConnection *
|
|
|
|
|
connection_from_file_full (const char *filename,
|
|
|
|
|
const char *network_file, /* for unit tests only */
|
|
|
|
|
const char *test_type, /* for unit tests only */
|
|
|
|
|
char **out_unhandled,
|
|
|
|
|
GError **error,
|
|
|
|
|
gboolean *out_ignore_error)
|
2007-11-21 06:24:15 +00:00
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
shvarFile *parsed;
|
2015-02-07 16:54:01 +01:00
|
|
|
gs_free char *type = NULL;
|
|
|
|
|
char *devtype, *bootproto;
|
2013-09-26 16:21:37 -05:00
|
|
|
NMSetting *s_ip4, *s_ip6, *s_port, *s_dcb = NULL;
|
2009-12-30 16:30:41 -06:00
|
|
|
const char *ifcfg_name = NULL;
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2008-05-11 20:20:52 +00:00
|
|
|
g_return_val_if_fail (filename != NULL, NULL);
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
if (out_unhandled)
|
|
|
|
|
g_return_val_if_fail (*out_unhandled == NULL, NULL);
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
/* Non-NULL only for unit tests; normally use /etc/sysconfig/network */
|
|
|
|
|
if (!network_file)
|
|
|
|
|
network_file = SYSCONFDIR "/sysconfig/network";
|
|
|
|
|
|
2009-12-30 16:30:41 -06:00
|
|
|
ifcfg_name = utils_get_ifcfg_name (filename, TRUE);
|
2008-02-04 23:18:16 +00:00
|
|
|
if (!ifcfg_name) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2008-05-11 20:20:52 +00:00
|
|
|
"Ignoring connection '%s' because it's not an ifcfg file.", filename);
|
2008-02-04 23:18:16 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-18 13:13:12 -04:00
|
|
|
parsed = svOpenFile (filename, error);
|
|
|
|
|
if (!parsed)
|
2007-11-21 06:24:15 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (!svGetValueBoolean (parsed, "NM_CONTROLLED", TRUE)) {
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
g_assert (out_unhandled != NULL);
|
2013-10-29 10:45:36 -04:00
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
connection = create_unhandled_connection (filename, parsed, "unmanaged", out_unhandled);
|
|
|
|
|
if (!connection)
|
2015-07-02 14:46:58 +02:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
|
|
|
|
|
"NM_CONTROLLED was false but device was not uniquely identified; device will be managed");
|
2013-10-29 10:45:36 -04:00
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:25:58 -05:00
|
|
|
/* iBFT is handled by the iBFT settings plugin */
|
|
|
|
|
bootproto = svGetValue (parsed, "BOOTPROTO", FALSE);
|
|
|
|
|
if (bootproto && !g_ascii_strcasecmp (bootproto, "ibft")) {
|
|
|
|
|
if (out_ignore_error)
|
|
|
|
|
*out_ignore_error = TRUE;
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2014-07-30 16:25:58 -05:00
|
|
|
"Ignoring iBFT configuration");
|
|
|
|
|
g_free (bootproto);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
2015-01-28 22:29:32 +01:00
|
|
|
g_free (bootproto);
|
2014-07-30 16:25:58 -05:00
|
|
|
|
2013-05-28 16:26:00 +02:00
|
|
|
devtype = svGetValue (parsed, "DEVICETYPE", FALSE);
|
|
|
|
|
if (devtype) {
|
2013-07-25 15:36:47 +02:00
|
|
|
if (!strcasecmp (devtype, TYPE_TEAM))
|
|
|
|
|
type = g_strdup (TYPE_TEAM);
|
2014-03-10 10:45:14 +01:00
|
|
|
else if (!strcasecmp (devtype, TYPE_TEAM_PORT))
|
|
|
|
|
type = g_strdup (TYPE_ETHERNET);
|
2013-05-28 16:26:00 +02:00
|
|
|
g_free (devtype);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-25 15:36:47 +02:00
|
|
|
if (!type)
|
|
|
|
|
type = svGetValue (parsed, "TYPE", FALSE);
|
|
|
|
|
|
2007-11-21 06:24:15 +00:00
|
|
|
if (!type) {
|
2008-03-08 00:12:42 +00:00
|
|
|
char *device;
|
|
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
device = svGetValue (parsed, "DEVICE", FALSE);
|
2008-03-08 00:12:42 +00:00
|
|
|
if (!device) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2008-05-11 20:20:52 +00:00
|
|
|
"File '%s' had neither TYPE nor DEVICE keys.", filename);
|
2008-03-08 00:12:42 +00:00
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-19 03:08:32 +00:00
|
|
|
if (!strcmp (device, "lo")) {
|
2013-03-22 11:22:42 -05:00
|
|
|
if (out_ignore_error)
|
|
|
|
|
*out_ignore_error = TRUE;
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2008-03-19 03:08:32 +00:00
|
|
|
"Ignoring loopback device config.");
|
|
|
|
|
g_free (device);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-01 19:04:55 -05:00
|
|
|
if (!test_type) {
|
2011-10-18 13:48:42 +02:00
|
|
|
if (is_bond_device (device, parsed))
|
|
|
|
|
type = g_strdup (TYPE_BOND);
|
2012-02-16 22:08:42 +08:00
|
|
|
else if (is_vlan_device (device, parsed))
|
|
|
|
|
type = g_strdup (TYPE_VLAN);
|
2014-02-04 14:27:03 +01:00
|
|
|
else if (is_wifi_device (device, parsed))
|
2009-03-01 19:04:55 -05:00
|
|
|
type = g_strdup (TYPE_WIRELESS);
|
|
|
|
|
else
|
|
|
|
|
type = g_strdup (TYPE_ETHERNET);
|
|
|
|
|
} else {
|
|
|
|
|
/* For the unit tests, there won't necessarily be any
|
|
|
|
|
* adapters of the connection's type in the system so the
|
|
|
|
|
* type can't be tested with ioctls.
|
|
|
|
|
*/
|
|
|
|
|
type = g_strdup (test_type);
|
|
|
|
|
}
|
2008-03-08 00:12:42 +00:00
|
|
|
|
|
|
|
|
g_free (device);
|
2011-04-12 15:38:47 -05:00
|
|
|
} else {
|
|
|
|
|
/* Check for IBM s390 CTC devices and call them Ethernet */
|
|
|
|
|
if (g_strcmp0 (type, "CTC") == 0) {
|
|
|
|
|
g_free (type);
|
|
|
|
|
type = g_strdup (TYPE_ETHERNET);
|
|
|
|
|
}
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-08 18:04:30 +02:00
|
|
|
if (svGetValueBoolean (parsed, "BONDING_MASTER", FALSE) &&
|
2011-10-18 13:48:42 +02:00
|
|
|
strcasecmp (type, TYPE_BOND)) {
|
2014-10-15 11:14:00 -04:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
2011-10-18 13:48:42 +02:00
|
|
|
"BONDING_MASTER=yes key only allowed in TYPE=bond connections");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-03 16:17:45 -07:00
|
|
|
/* Construct the connection */
|
2008-11-03 19:36:40 +00:00
|
|
|
if (!strcasecmp (type, TYPE_ETHERNET))
|
2013-10-29 10:45:36 -04:00
|
|
|
connection = wired_connection_from_ifcfg (filename, parsed, error);
|
2008-11-03 19:36:40 +00:00
|
|
|
else if (!strcasecmp (type, TYPE_WIRELESS))
|
2013-10-29 10:45:36 -04:00
|
|
|
connection = wireless_connection_from_ifcfg (filename, parsed, error);
|
2011-10-21 09:34:30 -04:00
|
|
|
else if (!strcasecmp (type, TYPE_INFINIBAND))
|
2013-10-29 10:45:36 -04:00
|
|
|
connection = infiniband_connection_from_ifcfg (filename, parsed, error);
|
2011-12-12 22:20:56 -05:00
|
|
|
else if (!strcasecmp (type, TYPE_BOND))
|
2013-10-29 10:45:36 -04:00
|
|
|
connection = bond_connection_from_ifcfg (filename, parsed, error);
|
2013-07-25 15:36:47 +02:00
|
|
|
else if (!strcasecmp (type, TYPE_TEAM))
|
2013-10-29 10:45:36 -04:00
|
|
|
connection = team_connection_from_ifcfg (filename, parsed, error);
|
2011-12-12 22:20:56 -05:00
|
|
|
else if (!strcasecmp (type, TYPE_VLAN))
|
2013-10-29 10:45:36 -04:00
|
|
|
connection = vlan_connection_from_ifcfg (filename, parsed, error);
|
2011-12-12 22:20:56 -05:00
|
|
|
else if (!strcasecmp (type, TYPE_BRIDGE))
|
2013-10-29 10:45:36 -04:00
|
|
|
connection = bridge_connection_from_ifcfg (filename, parsed, error);
|
2011-10-18 13:48:42 +02:00
|
|
|
else {
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
g_assert (out_unhandled != NULL);
|
|
|
|
|
|
|
|
|
|
connection = create_unhandled_connection (filename, parsed, "unrecognized", out_unhandled);
|
|
|
|
|
if (!connection)
|
2014-04-05 09:37:04 -04:00
|
|
|
PARSE_WARNING ("connection type was unrecognized but device was not uniquely identified; device may be managed");
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
goto done;
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-29 10:45:36 -04:00
|
|
|
if (!connection)
|
2007-12-01 17:24:57 +00:00
|
|
|
goto done;
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2014-07-30 16:25:58 -05:00
|
|
|
s_ip6 = make_ip6_setting (parsed, network_file, error);
|
2013-07-26 14:25:05 -05:00
|
|
|
if (!s_ip6) {
|
2007-12-01 17:24:57 +00:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
connection = NULL;
|
|
|
|
|
goto done;
|
2013-09-26 16:36:55 -04:00
|
|
|
} else
|
2010-04-12 16:24:07 -07:00
|
|
|
nm_connection_add_setting (connection, s_ip6);
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2014-07-30 16:25:58 -05:00
|
|
|
s_ip4 = make_ip4_setting (parsed, network_file, error);
|
2013-07-26 14:25:05 -05:00
|
|
|
if (!s_ip4) {
|
2010-01-05 19:05:01 -06:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
connection = NULL;
|
|
|
|
|
goto done;
|
2014-02-19 16:10:36 -05:00
|
|
|
} else {
|
2015-09-15 15:27:25 +02:00
|
|
|
read_aliases (NM_SETTING_IP_CONFIG (s_ip4), filename);
|
2010-04-12 16:24:07 -07:00
|
|
|
nm_connection_add_setting (connection, s_ip4);
|
2014-02-19 16:10:36 -05:00
|
|
|
}
|
2010-01-05 19:05:01 -06:00
|
|
|
|
2013-09-20 13:54:47 +02:00
|
|
|
/* There is only one DOMAIN variable and it is read and put to IPv4 config
|
|
|
|
|
* But if IPv4 is disabled or the config fails for some reason, we read
|
|
|
|
|
* DOMAIN and put the values into IPv6 config instead.
|
|
|
|
|
*/
|
|
|
|
|
check_dns_search_domains (parsed, s_ip4, s_ip6);
|
|
|
|
|
|
2012-05-23 16:19:28 +02:00
|
|
|
/* Bridge port? */
|
2013-03-22 09:25:58 -05:00
|
|
|
s_port = make_bridge_port_setting (parsed);
|
2013-07-25 15:36:47 +02:00
|
|
|
if (s_port)
|
|
|
|
|
nm_connection_add_setting (connection, s_port);
|
|
|
|
|
|
|
|
|
|
/* Team port? */
|
|
|
|
|
s_port = make_team_port_setting (parsed);
|
2013-03-22 09:25:58 -05:00
|
|
|
if (s_port)
|
2012-05-23 16:19:28 +02:00
|
|
|
nm_connection_add_setting (connection, s_port);
|
|
|
|
|
|
2013-09-26 16:21:37 -05:00
|
|
|
if (!make_dcb_setting (parsed, network_file, &s_dcb, error)) {
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
connection = NULL;
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
if (s_dcb)
|
|
|
|
|
nm_connection_add_setting (connection, s_dcb);
|
|
|
|
|
|
2013-12-01 23:43:14 +01:00
|
|
|
if (!nm_connection_normalize (connection, NULL, NULL, error)) {
|
2007-12-01 16:00:17 +00:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
connection = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-21 06:24:15 +00:00
|
|
|
done:
|
|
|
|
|
svCloseFile (parsed);
|
2007-11-26 03:47:30 +00:00
|
|
|
return connection;
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
2014-12-16 09:57:36 -05:00
|
|
|
NMConnection *
|
|
|
|
|
connection_from_file (const char *filename,
|
|
|
|
|
char **out_unhandled,
|
2015-06-01 16:34:16 +02:00
|
|
|
GError **error,
|
|
|
|
|
gboolean *out_ignore_error)
|
2014-12-16 09:57:36 -05:00
|
|
|
{
|
2015-06-01 16:34:16 +02:00
|
|
|
return connection_from_file_full (filename, NULL, NULL,
|
2014-12-16 09:57:36 -05:00
|
|
|
out_unhandled,
|
2015-01-06 15:50:35 +01:00
|
|
|
error,
|
2015-06-01 16:34:16 +02:00
|
|
|
out_ignore_error);
|
2014-12-16 09:57:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMConnection *
|
|
|
|
|
connection_from_file_test (const char *filename,
|
|
|
|
|
const char *network_file,
|
|
|
|
|
const char *test_type,
|
|
|
|
|
char **out_unhandled,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
return connection_from_file_full (filename,
|
|
|
|
|
network_file,
|
|
|
|
|
test_type,
|
|
|
|
|
out_unhandled,
|
|
|
|
|
error,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-19 10:34:19 -05:00
|
|
|
guint
|
|
|
|
|
devtimeout_from_file (const char *filename)
|
|
|
|
|
{
|
|
|
|
|
shvarFile *ifcfg;
|
|
|
|
|
char *devtimeout_str;
|
|
|
|
|
guint devtimeout;
|
|
|
|
|
|
2015-01-10 14:21:18 +01:00
|
|
|
g_return_val_if_fail (filename != NULL, 0);
|
2014-12-19 10:34:19 -05:00
|
|
|
|
|
|
|
|
ifcfg = svOpenFile (filename, NULL);
|
|
|
|
|
if (!ifcfg)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
devtimeout_str = svGetValue (ifcfg, "DEVTIMEOUT", FALSE);
|
|
|
|
|
if (devtimeout_str) {
|
2015-02-22 11:55:31 +01:00
|
|
|
devtimeout = _nm_utils_ascii_str_to_int64 (devtimeout_str, 10, 0, G_MAXUINT, 0);
|
2014-12-19 10:34:19 -05:00
|
|
|
g_free (devtimeout_str);
|
|
|
|
|
} else
|
|
|
|
|
devtimeout = 0;
|
|
|
|
|
|
2015-01-28 22:53:34 +01:00
|
|
|
svCloseFile (ifcfg);
|
|
|
|
|
|
2014-12-19 10:34:19 -05:00
|
|
|
return devtimeout;
|
|
|
|
|
}
|