about summary refs log tree commit diff
path: root/src/core/settings/plugins/ifcfg-rh
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/settings/plugins/ifcfg-rh')
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c16
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c28
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c1
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h2
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c26
-rw-r--r--src/core/settings/plugins/ifcfg-rh/shvar.c23
6 files changed, 74 insertions, 22 deletions
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
index eb0d733d..0a385247 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
@@ -52,7 +52,6 @@ typedef struct {
 
     GHashTable *unmanaged_specs;
     GHashTable *unrecognized_specs;
-
 } NMSIfcfgRHPluginPrivate;
 
 struct _NMSIfcfgRHPlugin {
@@ -177,6 +176,7 @@ nm_assert_self(NMSIfcfgRHPlugin *self, gboolean unhandled_specs_consistent)
 static NMSIfcfgRHStorage *
 _load_file(NMSIfcfgRHPlugin *self, const char *filename, GError **error)
 {
+    NMSIfcfgRHStorage            *ret            = NULL;
     gs_unref_object NMConnection *connection     = NULL;
     gs_free_error GError         *load_error     = NULL;
     gs_free char                 *unhandled_spec = NULL;
@@ -224,16 +224,16 @@ _load_file(NMSIfcfgRHPlugin *self, const char *filename, GError **error)
             nm_assert_not_reached();
             return NULL;
         }
-        return nms_ifcfg_rh_storage_new_unhandled(self,
+
+        ret = nms_ifcfg_rh_storage_new_unhandled(self, filename, unmanaged_spec, unrecognized_spec);
+    } else {
+        ret = nms_ifcfg_rh_storage_new_connection(self,
                                                   filename,
-                                                  unmanaged_spec,
-                                                  unrecognized_spec);
+                                                  g_steal_pointer(&connection),
+                                                  &st.st_mtim);
     }
 
-    return nms_ifcfg_rh_storage_new_connection(self,
-                                               filename,
-                                               g_steal_pointer(&connection),
-                                               &st.st_mtim);
+    return ret;
 }
 
 static void
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index 6cfb5705..84a9479d 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -917,7 +917,7 @@ enum {
  * @options_route: (in-out): when line is from the OPTIONS setting, this is a pre-created
  *   route object that is completed with the settings from options. Otherwise,
  *   it shall point to %NULL and a new route is created and returned.
- * @out_route: (out) (transfer-full) (allow-none): the parsed %NMIPRoute instance.
+ * @out_route: (out) (transfer full) (optional): the parsed %NMIPRoute instance.
  *   In case a @options_route is passed in, it returns the input route that was modified
  *   in-place. But the caller must unref the returned route in either case.
  * @error: the failure description.
@@ -2481,6 +2481,11 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea
         g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DHCP_IAID, v, NULL);
 
     nm_clear_g_free(&value);
+    v = svGetValueStr(ifcfg, "DHCPV6_PD_HINT", &value);
+    if (v)
+        g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_DHCP_PD_HINT, v, NULL);
+
+    nm_clear_g_free(&value);
     v = svGetValueStr(ifcfg, "DHCPV6_HOSTNAME", &value);
     /* Use DHCP_HOSTNAME as fallback if it is in FQDN format and ipv6.method is
      * auto or dhcp: this is required to support old ifcfg files
@@ -2591,7 +2596,7 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea
                         &local)) {
         PARSE_WARNING("%s", local->message);
         g_clear_error(&local);
-    } else if (errno == ENOENT) {
+    } else if (errno == ENOKEY) {
         /* The key is not specified. If "v" (IPV6_TOKEN) is set,
          * we default to EUI64. Otherwise, the connection would not verify. */
         if (v)
@@ -2683,16 +2688,25 @@ make_hostname_setting(shvarFile *ifcfg)
     NMTernary  from_dns_lookup;
     NMTernary  only_from_default;
     int        priority;
+    gboolean   has_setting = FALSE;
 
     priority = svGetValueInt64(ifcfg, "HOSTNAME_PRIORITY", 10, G_MININT32, G_MAXINT32, 0);
+    if (!has_setting && errno != ENOKEY)
+        has_setting = TRUE;
+
+    from_dhcp = svGetValueTernary(ifcfg, "HOSTNAME_FROM_DHCP");
+    if (!has_setting && errno != ENOKEY)
+        has_setting = TRUE;
+
+    from_dns_lookup = svGetValueTernary(ifcfg, "HOSTNAME_FROM_DNS_LOOKUP");
+    if (!has_setting && errno != ENOKEY)
+        has_setting = TRUE;
 
-    from_dhcp         = svGetValueTernary(ifcfg, "HOSTNAME_FROM_DHCP");
-    from_dns_lookup   = svGetValueTernary(ifcfg, "HOSTNAME_FROM_DNS_LOOKUP");
     only_from_default = svGetValueTernary(ifcfg, "HOSTNAME_ONLY_FROM_DEFAULT");
+    if (!has_setting && errno != ENOKEY)
+        has_setting = TRUE;
 
-    /* Create the setting when at least one key is not default*/
-    if (priority == 0 && from_dhcp == NM_TERNARY_DEFAULT && from_dns_lookup == NM_TERNARY_DEFAULT
-        && only_from_default == NM_TERNARY_DEFAULT)
+    if (!has_setting)
         return NULL;
 
     setting = nm_setting_hostname_new();
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
index 207b8700..50e352d3 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
@@ -881,6 +881,7 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = {
     _KEY_TYPE("DHCPV6_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
     _KEY_TYPE("DHCPV6_HOSTNAME_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
     _KEY_TYPE("DHCPV6_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
+    _KEY_TYPE("DHCPV6_PD_HINT", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
     _KEY_TYPE("DHCPV6_SEND_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
     _KEY_TYPE("DHCP_CLIENT_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
     _KEY_TYPE("DHCP_FQDN", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
index 51b118e3..eb9e418a 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
@@ -33,7 +33,7 @@ typedef struct {
     NMSIfcfgKeyTypeFlags key_flags;
 } NMSIfcfgKeyTypeInfo;
 
-extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[263];
+extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[264];
 
 const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx);
 
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 97637063..08deaf5a 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -62,6 +62,24 @@
 /*****************************************************************************/
 
 static void
+set_error_unsupported(GError      **error,
+                      NMConnection *connection,
+                      const char   *name,
+                      gboolean      is_setting)
+{
+    g_set_error(error,
+                NM_SETTINGS_ERROR,
+                NM_SETTINGS_ERROR_NOT_SUPPORTED_BY_PLUGIN,
+                "The ifcfg-rh plugin doesn't support %s '%s'. If you are modifying an existing "
+                "connection profile saved in ifcfg-rh format, please migrate the connection to "
+                "keyfile using 'nmcli connection migrate %s' or via the Update2() D-Bus API "
+                "and try again.",
+                is_setting ? "setting" : "property",
+                name,
+                nm_connection_get_uuid(connection));
+};
+
+static void
 save_secret_flags(shvarFile *ifcfg, const char *key, NMSettingSecretFlags flags)
 {
     GString *str;
@@ -3100,6 +3118,9 @@ write_ip6_setting(NMConnection *connection, shvarFile *ifcfg, GString **out_rout
                   "DHCPV6_DUID",
                   nm_setting_ip6_config_get_dhcp_duid(NM_SETTING_IP6_CONFIG(s_ip6)));
     svSetValueStr(ifcfg, "DHCPV6_IAID", nm_setting_ip_config_get_dhcp_iaid(s_ip6));
+    svSetValueStr(ifcfg,
+                  "DHCPV6_PD_HINT",
+                  nm_setting_ip6_config_get_dhcp_pd_hint(NM_SETTING_IP6_CONFIG(s_ip6)));
 
     hostname = nm_setting_ip_config_get_dhcp_hostname(s_ip6);
     svSetValueStr(ifcfg, "DHCPV6_HOSTNAME", hostname);
@@ -3485,6 +3506,11 @@ do_write_construct(NMConnection                   *connection,
     write_sriov_setting(connection, ifcfg);
     write_tc_setting(connection, ifcfg);
 
+    if (_nm_connection_get_setting(connection, NM_TYPE_SETTING_LINK)) {
+        set_error_unsupported(error, connection, "link", TRUE);
+        return FALSE;
+    }
+
     route_path_is_svformat = utils_has_route_file_new_syntax(route_path);
 
     has_complex_routes_v4 = utils_has_complex_routes(ifcfg_name, AF_INET);
diff --git a/src/core/settings/plugins/ifcfg-rh/shvar.c b/src/core/settings/plugins/ifcfg-rh/shvar.c
index fe8187c3..1ca2ea60 100644
--- a/src/core/settings/plugins/ifcfg-rh/shvar.c
+++ b/src/core/settings/plugins/ifcfg-rh/shvar.c
@@ -97,23 +97,32 @@ static void _line_link_parse(shvarFile *s, const char *value, gsize len);
  * in case no valid value is found, the fallback value. Valid values
  * are: "yes", "true", "t", "y", "1" and "no", "false", "f", "n", "0".
  *
+ * Always sets errno. Either to zero on success, to ENOKEY for NULL
+ * or to EINVAL otherwise.
+ *
  * Returns: the parsed boolean value or @fallback.
  */
 int
 svParseBoolean(const char *value, int fallback)
 {
-    if (!value)
+    if (!value) {
+        errno = ENOKEY;
         return fallback;
+    }
 
     if (!g_ascii_strcasecmp("yes", value) || !g_ascii_strcasecmp("true", value)
         || !g_ascii_strcasecmp("t", value) || !g_ascii_strcasecmp("y", value)
-        || !g_ascii_strcasecmp("1", value))
+        || !g_ascii_strcasecmp("1", value)) {
+        errno = 0;
         return TRUE;
-    else if (!g_ascii_strcasecmp("no", value) || !g_ascii_strcasecmp("false", value)
-             || !g_ascii_strcasecmp("f", value) || !g_ascii_strcasecmp("n", value)
-             || !g_ascii_strcasecmp("0", value))
+    } else if (!g_ascii_strcasecmp("no", value) || !g_ascii_strcasecmp("false", value)
+               || !g_ascii_strcasecmp("f", value) || !g_ascii_strcasecmp("n", value)
+               || !g_ascii_strcasecmp("0", value)) {
+        errno = 0;
         return FALSE;
+    }
 
+    errno = EINVAL;
     return fallback;
 }
 
@@ -1253,6 +1262,7 @@ svGetValueStr_cp(shvarFile *s, const char *key)
  * @fallback: the fallback value in any error case
  *
  * Reads a value @key and converts it to a boolean using svParseBoolean().
+ * This always sets errno, see svParseBoolean().
  *
  * Returns: the parsed boolean value or @fallback.
  */
@@ -1271,6 +1281,7 @@ svGetValueBoolean(shvarFile *s, const char *key, int fallback)
  * @key: the name of the key to read
  *
  * Reads a value @key and converts it to a NMTernary value.
+ * This always sets errno, see svParseBoolean().
  *
  * Returns: the parsed NMTernary
  */
@@ -1328,7 +1339,7 @@ svGetValueEnum(shvarFile *s, const char *key, GType gtype, int *out_value, GErro
     if (!svalue) {
         /* don't touch out_value. The caller is supposed
          * to initialize it with the default value. */
-        errno = ENOENT;
+        errno = ENOKEY;
         return TRUE;
     }