summaryrefslogtreecommitdiff
path: root/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c')
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c246
1 files changed, 130 insertions, 116 deletions
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index b1cf80ad91..50d0bc723a 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -77,18 +77,6 @@
/*****************************************************************************/
-static gboolean
-get_uint (const char *str, guint32 *value)
-{
- gint64 tmp;
-
- tmp = _nm_utils_ascii_str_to_int64 (str, 0, 0, G_MAXUINT32, -1);
- if (tmp == -1)
- return FALSE;
- *value = tmp;
- return TRUE;
-}
-
static void
check_if_bond_slave (shvarFile *ifcfg,
NMSettingConnection *s_con)
@@ -4650,66 +4638,114 @@ team_connection_from_ifcfg (const char *file,
return connection;
}
+typedef enum {
+ BRIDGE_OPT_TYPE_MAIN,
+ BRIDGE_OPT_TYPE_OPTION,
+ BRIDGE_OPT_TYPE_PORT_MAIN,
+ BRIDGE_OPT_TYPE_PORT_OPTION,
+} BridgeOptType;
+
typedef void (*BridgeOptFunc) (NMSetting *setting,
gboolean stp,
const char *key,
- const char *value);
+ const char *value,
+ BridgeOptType opt_type);
static void
handle_bridge_option (NMSetting *setting,
gboolean stp,
const char *key,
- const char *value)
+ const char *value,
+ BridgeOptType opt_type)
{
- guint32 u = 0;
+ static const struct {
+ const char *key;
+ const char *property_name;
+ BridgeOptType opt_type;
+ gboolean only_with_stp;
+ gboolean extended_bool;
+ } m/*etadata*/[] = {
+ { "DELAY", NM_SETTING_BRIDGE_FORWARD_DELAY, BRIDGE_OPT_TYPE_MAIN, .only_with_stp = TRUE },
+ { "priority", NM_SETTING_BRIDGE_PRIORITY, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE },
+ { "hello_time", NM_SETTING_BRIDGE_HELLO_TIME, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE },
+ { "max_age", NM_SETTING_BRIDGE_MAX_AGE, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE },
+ { "ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, BRIDGE_OPT_TYPE_OPTION },
+ { "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, BRIDGE_OPT_TYPE_OPTION },
+ { "group_fwd_mask", NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, BRIDGE_OPT_TYPE_OPTION },
+ { "priority", NM_SETTING_BRIDGE_PORT_PRIORITY, BRIDGE_OPT_TYPE_PORT_OPTION },
+ { "path_cost", NM_SETTING_BRIDGE_PORT_PATH_COST, BRIDGE_OPT_TYPE_PORT_OPTION },
+ { "hairpin_mode", NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, BRIDGE_OPT_TYPE_PORT_OPTION, .extended_bool = TRUE, },
+ };
+ const char *error_message = NULL;
+ int i;
+ gint64 v;
- if (!strcmp (key, "priority")) {
- if (stp == FALSE)
- PARSE_WARNING ("'priority' invalid when STP is disabled");
- else if (get_uint (value, &u))
- g_object_set (setting, NM_SETTING_BRIDGE_PRIORITY, u, NULL);
- else
- PARSE_WARNING ("invalid priority value '%s'", value);
- } else if (!strcmp (key, "hello_time")) {
- if (stp == FALSE)
- PARSE_WARNING ("'hello_time' invalid when STP is disabled");
- else if (get_uint (value, &u))
- g_object_set (setting, NM_SETTING_BRIDGE_HELLO_TIME, u, NULL);
- else
- PARSE_WARNING ("invalid hello_time value '%s'", value);
- } else if (!strcmp (key, "max_age")) {
- if (stp == FALSE)
- PARSE_WARNING ("'max_age' invalid when STP is disabled");
- else if (get_uint (value, &u))
- g_object_set (setting, NM_SETTING_BRIDGE_MAX_AGE, u, NULL);
- else
- PARSE_WARNING ("invalid max_age value '%s'", value);
- } else if (!strcmp (key, "ageing_time")) {
- if (get_uint (value, &u))
- g_object_set (setting, NM_SETTING_BRIDGE_AGEING_TIME, u, NULL);
- else
- PARSE_WARNING ("invalid ageing_time value '%s'", value);
- } 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);
- } else if (!strcmp (key, "group_fwd_mask")) {
- if (get_uint (value, &u) && u <= 0xFFFF && !NM_FLAGS_ANY (u, 7))
- g_object_set (setting, NM_SETTING_BRIDGE_GROUP_FORWARD_MASK,
- (gboolean) u, NULL);
- else
- PARSE_WARNING ("invalid group_fwd_mask value '%s'", value);
- } else
- PARSE_WARNING ("unhandled bridge option '%s'", key);
+ for (i = 0; i < G_N_ELEMENTS (m); i++) {
+ GParamSpec *param_spec;
+
+ if (opt_type != m[i].opt_type)
+ continue;
+ if (!nm_streq (key, m[i].key))
+ continue;
+ if (m[i].only_with_stp && !stp) {
+ PARSE_WARNING ("'%s' invalid when STP is disabled", key);
+ return;
+ }
+
+ param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), m[i].property_name);
+ switch (param_spec->value_type) {
+ case G_TYPE_BOOLEAN:
+ if (m[i].extended_bool) {
+ if (!strcasecmp (value, "on") || !strcasecmp (value, "yes") || !strcmp (value, "1"))
+ v = TRUE;
+ else if (!strcasecmp (value, "off") || !strcasecmp (value, "no"))
+ v = FALSE;
+ else {
+ error_message = "is not a boolean";
+ goto warn;
+ }
+ } else {
+ v = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
+ if (v == -1) {
+ error_message = g_strerror (errno);
+ goto warn;
+ }
+ }
+ if (!nm_g_object_set_property_boolean (G_OBJECT (setting), m[i].property_name, v, NULL)) {
+ error_message = "number is out of range";
+ goto warn;
+ }
+ return;
+ case G_TYPE_UINT:
+ v = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT, -1);
+ if (v == -1) {
+ error_message = g_strerror (errno);
+ goto warn;
+ }
+ if (!nm_g_object_set_property_uint (G_OBJECT (setting), m[i].property_name, v, NULL)) {
+ error_message = "number is out of range";
+ goto warn;
+ }
+ return;
+ default:
+ nm_assert_not_reached ();
+ continue;
+ }
+
+warn:
+ PARSE_WARNING ("invalid %s value '%s': %s", key, value, error_message);
+ return;
+ }
+
+ PARSE_WARNING ("unhandled bridge option '%s'", key);
}
static void
handle_bridging_opts (NMSetting *setting,
gboolean stp,
const char *value,
- BridgeOptFunc func)
+ BridgeOptFunc func,
+ BridgeOptType opt_type)
{
gs_free const char **items = NULL;
const char *const *iter;
@@ -4724,7 +4760,7 @@ handle_bridging_opts (NMSetting *setting,
key = *keys;
val = *(keys + 1);
if (val && key[0] && val[0])
- func (setting, stp, key, val);
+ func (setting, stp, key, val, opt_type);
}
}
}
@@ -4734,30 +4770,29 @@ make_bridge_setting (shvarFile *ifcfg,
const char *file,
GError **error)
{
- NMSettingBridge *s_bridge;
- char *value;
- guint32 u;
+ gs_unref_object NMSettingBridge *s_bridge = NULL;
+ gs_free char *value_to_free = NULL;
+ const char *value;
gboolean stp = FALSE;
gboolean stp_set = FALSE;
- value = svGetValueStr_cp (ifcfg, "DEVICE");
+ value = svGetValueStr (ifcfg, "DEVICE", &value_to_free);
if (!value) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"mandatory DEVICE keyword missing");
return NULL;
}
- g_free (value);
+ nm_clear_g_free (&value_to_free);
s_bridge = NM_SETTING_BRIDGE (nm_setting_bridge_new ());
- value = svGetValueStr_cp (ifcfg, "MACADDR");
+ value = svGetValueStr (ifcfg, "BRIDGE_MACADDR", &value_to_free);
if (value) {
- value = g_strstrip (value);
g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, value, NULL);
- g_free (value);
+ nm_clear_g_free (&value_to_free);
}
- value = svGetValueStr_cp (ifcfg, "STP");
+ value = svGetValueStr (ifcfg, "STP", &value_to_free);
if (value) {
if (!strcasecmp (value, "on") || !strcasecmp (value, "yes")) {
g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, TRUE, NULL);
@@ -4768,7 +4803,7 @@ make_bridge_setting (shvarFile *ifcfg,
stp_set = TRUE;
} else
PARSE_WARNING ("invalid STP value '%s'", value);
- g_free (value);
+ nm_clear_g_free (&value_to_free);
}
if (!stp_set) {
@@ -4776,25 +4811,19 @@ make_bridge_setting (shvarFile *ifcfg,
g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL);
}
- value = svGetValueStr_cp (ifcfg, "DELAY");
+ value = svGetValueStr (ifcfg, "DELAY", &value_to_free);
if (value) {
- if (stp) {
- if (get_uint (value, &u))
- g_object_set (s_bridge, NM_SETTING_BRIDGE_FORWARD_DELAY, u, NULL);
- else
- PARSE_WARNING ("invalid forward delay value '%s'", value);
- } else
- PARSE_WARNING ("DELAY invalid when STP is disabled");
- g_free (value);
+ handle_bridge_option (NM_SETTING (s_bridge), stp, "DELAY", value, BRIDGE_OPT_TYPE_MAIN);
+ nm_clear_g_free (&value_to_free);
}
- value = svGetValueStr_cp (ifcfg, "BRIDGING_OPTS");
+ value = svGetValueStr (ifcfg, "BRIDGING_OPTS", &value_to_free);
if (value) {
- handle_bridging_opts (NM_SETTING (s_bridge), stp, value, handle_bridge_option);
- g_free (value);
+ handle_bridging_opts (NM_SETTING (s_bridge), stp, value, handle_bridge_option, BRIDGE_OPT_TYPE_OPTION);
+ nm_clear_g_free (&value_to_free);
}
- return (NMSetting *) s_bridge;
+ return (NMSetting *) g_steal_pointer (&s_bridge);
}
static NMConnection *
@@ -4805,6 +4834,8 @@ bridge_connection_from_ifcfg (const char *file,
NMConnection *connection = NULL;
NMSetting *con_setting = NULL;
NMSetting *bridge_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);
@@ -4827,57 +4858,40 @@ bridge_connection_from_ifcfg (const char *file,
}
nm_connection_add_setting (connection, bridge_setting);
- return connection;
-}
+ wired_setting = make_wired_setting (ifcfg, file, &s_8021x, error);
+ if (!wired_setting) {
+ g_object_unref (connection);
+ return NULL;
+ }
+ nm_connection_add_setting (connection, wired_setting);
-static void
-handle_bridge_port_option (NMSetting *setting,
- gboolean stp,
- const char *key,
- const char *value)
-{
- guint32 u = 0;
+ if (s_8021x)
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
- if (!strcmp (key, "priority")) {
- if (get_uint (value, &u))
- g_object_set (setting, NM_SETTING_BRIDGE_PORT_PRIORITY, u, NULL);
- else
- PARSE_WARNING ("invalid priority value '%s'", value);
- } else if (!strcmp (key, "path_cost")) {
- if (get_uint (value, &u))
- g_object_set (setting, NM_SETTING_BRIDGE_PORT_PATH_COST, u, NULL);
- else
- PARSE_WARNING ("invalid path_cost value '%s'", value);
- } 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
- PARSE_WARNING ("invalid hairpin_mode value '%s'", value);
- } else
- PARSE_WARNING ("unhandled bridge port option '%s'", key);
+ return connection;
}
static NMSetting *
make_bridge_port_setting (shvarFile *ifcfg)
{
NMSetting *s_port = NULL;
- char *value;
+ gs_free char *value_to_free = NULL;
+ const char *value;
g_return_val_if_fail (ifcfg != NULL, FALSE);
- value = svGetValueStr_cp (ifcfg, "BRIDGE_UUID");
+ value = svGetValueStr (ifcfg, "BRIDGE_UUID", &value_to_free);
if (!value)
- value = svGetValueStr_cp (ifcfg, "BRIDGE");
+ value = svGetValueStr (ifcfg, "BRIDGE", &value_to_free);
if (value) {
- g_free (value);
+ nm_clear_g_free (&value_to_free);
s_port = nm_setting_bridge_port_new ();
- value = svGetValueStr_cp (ifcfg, "BRIDGING_OPTS");
- if (value)
- handle_bridging_opts (s_port, FALSE, value, handle_bridge_port_option);
- g_free (value);
+ value = svGetValueStr (ifcfg, "BRIDGING_OPTS", &value_to_free);
+ if (value) {
+ handle_bridging_opts (s_port, FALSE, value, handle_bridge_option, BRIDGE_OPT_TYPE_PORT_OPTION);
+ nm_clear_g_free (&value_to_free);
+ }
}
return s_port;