ifcfg-rh: merge branch 'th/ifcfg-unset-well-known-keys'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/367
This commit is contained in:
Thomas Haller 2019-12-21 12:57:42 +01:00
commit 6404a363bd
13 changed files with 814 additions and 420 deletions

View file

@ -601,4 +601,32 @@ _g_atomic_pointer_compare_and_exchange (volatile void *atomic,
/*****************************************************************************/
#if !GLIB_CHECK_VERSION (2, 58, 0)
static inline gboolean
g_hash_table_steal_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *stolen_key,
gpointer *stolen_value)
{
if (g_hash_table_lookup_extended (hash_table, lookup_key, stolen_key, stolen_value)) {
g_hash_table_steal (hash_table, lookup_key);
return TRUE;
}
if (stolen_key)
*stolen_key = NULL;
if (stolen_value)
*stolen_value = NULL;
return FALSE;
}
#else
#define g_hash_table_steal_extended(hash_table, lookup_key, stolen_key, stolen_value) \
({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_hash_table_steal_extended (hash_table, lookup_key, stolen_key, stolen_value); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#endif
/*****************************************************************************/
#endif /* __NM_GLIB_H__ */

View file

@ -206,9 +206,9 @@ _load_file (NMSIfcfgRHPlugin *self,
const char *unmanaged_spec;
const char *unrecognized_spec;
if (!nms_ifcfg_rh_util_parse_unhandled_spec (unhandled_spec,
&unmanaged_spec,
&unrecognized_spec)) {
if (!nms_ifcfg_rh_utils_parse_unhandled_spec (unhandled_spec,
&unmanaged_spec,
&unrecognized_spec)) {
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
"invalid unhandled spec \"%s\"",
unhandled_spec);

View file

@ -17,9 +17,9 @@
/*****************************************************************************/
gboolean
nms_ifcfg_rh_util_parse_unhandled_spec (const char *unhandled_spec,
const char **out_unmanaged_spec,
const char **out_unrecognized_spec)
nms_ifcfg_rh_utils_parse_unhandled_spec (const char *unhandled_spec,
const char **out_unmanaged_spec,
const char **out_unrecognized_spec)
{
if (unhandled_spec) {
if (NM_STR_HAS_PREFIX (unhandled_spec, "unmanaged:")) {
@ -586,3 +586,336 @@ nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name)
return NULL;
}
/*****************************************************************************/
gboolean
nms_ifcfg_rh_utils_is_numbered_tag_impl (const char *key,
const char *tag,
gsize tag_len,
gint64 *out_idx)
{
gint64 idx;
nm_assert (key);
nm_assert (tag);
nm_assert (tag_len == strlen (tag));
nm_assert (tag_len > 0);
if (strncmp (key, tag, tag_len) != 0)
return FALSE;
key += tag_len;
if (key[0] == '\0')
return FALSE;
if (!NM_STRCHAR_ALL (key, ch, g_ascii_isdigit (ch)))
return FALSE;
idx = _nm_utils_ascii_str_to_int64 (key, 10, 0, G_MAXINT64, -1);
if (idx == -1)
return FALSE;
NM_SET_OUT (out_idx, idx);
return TRUE;
}
/*****************************************************************************/
#define _KEY_TYPE(key, flags) { .key_name = ""key"", .key_flags = ((NMS_IFCFG_KEY_TYPE_WELL_KNOWN) | (flags)), }
const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = {
_KEY_TYPE ("ACD_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ADDRESS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("ARPING_WAIT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("AUTH_RETRIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("AUTOCONNECT_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("AUTOCONNECT_RETRIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("AUTOCONNECT_SLAVES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BAND", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BONDING_MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BONDING_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BOOTPROTO", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BRIDGE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BRIDGE_MACADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BRIDGE_PORT_VLANS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BRIDGE_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BRIDGE_VLANS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BRIDGING_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BROWSER_ONLY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("BSSID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("CHANNEL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("CIPHER_GROUP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("CIPHER_PAIRWISE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("CONNECTED_MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("CONNECTION_METERED", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("CTCPROT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DCB", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_FCOE_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_FCOE_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_FCOE_MODE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DCB_APP_FCOE_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_FCOE_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_FIP_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_FIP_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DCB_APP_FIP_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_FIP_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_ISCSI_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_ISCSI_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DCB_APP_ISCSI_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_APP_ISCSI_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PFC_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PFC_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PFC_UP, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PFC_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PG_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PG_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PG_ID, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PG_PCT, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PG_STRICT, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PG_UP2TC, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PG_UPPCT, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE (KEY_DCB_PG_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DEFAULTKEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DEFROUTE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DELAY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DEVICE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DEVICETYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DEVTIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DHCPV6C", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DHCPV6_DUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_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_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 ),
_KEY_TYPE ("DHCP_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DHCP_HOSTNAME_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DHCP_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DHCP_SEND_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DHCPv6_DUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DHCPv6_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("DNS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("DOMAIN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ESSID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ETHTOOL_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ETHTOOL_WAKE_ON_LAN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("FILS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("FILTER", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("GATEWAY", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("GATEWAYDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("GATEWAY_PING_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("GENERATE_MAC_ADDRESS_MASK", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("GVRP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("HWADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("HWADDR_BLACKLIST", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_ALTSUBJECT_MATCHES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_ANON_IDENTITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_AUTH_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_CA_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_CA_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_CA_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_CLIENT_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_CLIENT_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_CLIENT_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_DOMAIN_SUFFIX_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_EAP_METHODS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_FAST_PROVISIONING", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_IDENTITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_AUTH_METHODS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_CA_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_CA_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_CA_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_CLIENT_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_CLIENT_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_CLIENT_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_PRIVATE_KEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_OPTIONAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PAC_FILE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PASSWORD_RAW", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PASSWORD_RAW_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PEAP_FORCE_NEW_LABEL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PEAP_VERSION", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PHASE1_AUTH_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PHASE2_SUBJECT_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PRIVATE_KEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PRIVATE_KEY_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_SUBJECT_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IEEE_8021X_SYSTEM_CA_CERTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPADDR", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("IPV4_DHCP_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV4_DNS_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV4_FAILURE_FATAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV4_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV4_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6ADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6ADDR_SECONDARIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6FORWARDING", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6INIT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6TUNNELIPV4", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_ADDR_GEN_MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_AUTOCONF", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_DEFAULTDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_DEFAULTGW", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_DEFROUTE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_DISABLED", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_DNS_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_DOMAIN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_FAILURE_FATAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_PEERDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_PEERROUTES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_PRIVACY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_PRIVACY_PREFER_PUBLIC_IP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_RES_OPTIONS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("IPV6_TOKEN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("KEY", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("KEY_MGMT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("KEY_PASSPHRASE", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("KEY_TYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("LLDP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("LLMNR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MACADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MAC_ADDRESS_RANDOMIZATION", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MASTER_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MATCH_INTERFACE_NAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("METRIC", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MTU", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MULTI_CONNECT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("MVRP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("NAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("NETMASK", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("NETTYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("NM_CONTROLLED", NMS_IFCFG_KEY_TYPE_IS_PLAIN | NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY ),
_KEY_TYPE ("NM_USER_", NMS_IFCFG_KEY_TYPE_IS_PREFIX ),
_KEY_TYPE ("ONBOOT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("OPTIONS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("OVS_PORT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("OVS_PORT_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PAC_SCRIPT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PAC_URL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PEERDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PEERROUTES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PHYSDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PKEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PMF", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PORTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("POWERSAVE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("PREFIX", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("PROXY_METHOD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("QDISC", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("REORDER_HDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("RES_OPTIONS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ROUTING_RULE6_", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("ROUTING_RULE_", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("SEARCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("SECONDARY_UUIDS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("SECURITYMODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("SLAVE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("SRIOV_AUTOPROBE_DRIVERS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("SRIOV_TOTAL_VFS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("SRIOV_VF", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("SSID_HIDDEN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("STABLE_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("STP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("SUBCHANNELS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("TEAM_CONFIG", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("TEAM_MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("TEAM_MASTER_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("TEAM_PORT_CONFIG", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("TYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("USERS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("VLAN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("VLAN_EGRESS_PRIORITY_MAP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("VLAN_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("VLAN_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("VLAN_INGRESS_PRIORITY_MAP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("WEP_KEY_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("WPA_ALLOW_WPA", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("WPA_ALLOW_WPA2", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("WPA_PSK", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("WPA_PSK_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("WPS_METHOD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ZONE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
};
const NMSIfcfgKeyTypeInfo *
nms_ifcfg_well_known_key_find_info (const char *key, gssize *out_idx)
{
gssize idx;
G_STATIC_ASSERT (G_STRUCT_OFFSET (NMSIfcfgKeyTypeInfo, key_name) == 0);
idx = nm_utils_array_find_binary_search (nms_ifcfg_well_known_keys,
sizeof (nms_ifcfg_well_known_keys[0]),
G_N_ELEMENTS (nms_ifcfg_well_known_keys),
&key,
nm_strcmp_p_with_data,
NULL);
NM_SET_OUT (out_idx, idx);
if (idx < 0)
return NULL;
return &nms_ifcfg_well_known_keys[idx];
}
const NMSIfcfgKeyTypeInfo *
nms_ifcfg_rh_utils_is_well_known_key (const char *key)
{
const NMSIfcfgKeyTypeInfo *ti;
gssize idx;
nm_assert (key);
ti = nms_ifcfg_well_known_key_find_info (key, &idx);
if (ti) {
if (NM_FLAGS_ANY (ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_PLAIN
| NMS_IFCFG_KEY_TYPE_IS_NUMBERED)) {
/* these tags are valid on full match. */
return ti;
}
nm_assert (NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_PREFIX));
/* a prefix tag needs some extra words afterwards. */
return NULL;
}
/* Not found. Maybe it's a numbered/prefixed key? With idx we got the index where
* we should insert the key. Since the numbered/prefixed keys share a prefix, we can
* find the possible prefix at the index before the insert position. */
idx = ~idx;
if (idx == 0)
return NULL;
ti = &nms_ifcfg_well_known_keys[idx - 1];
if (NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_NUMBERED)) {
if (nms_ifcfg_rh_utils_is_numbered_tag (key, ti->key_name, NULL))
return ti;
return NULL;
}
if (NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_PREFIX)) {
gsize l = strlen (ti->key_name);
if ( strncmp (key, ti->key_name, l) == 0
&& key[l] != '\0')
return ti;
return NULL;
}
return NULL;
}

View file

@ -11,9 +11,48 @@
#include "shvar.h"
gboolean nms_ifcfg_rh_util_parse_unhandled_spec (const char *unhandled_spec,
const char **out_unmanaged_spec,
const char **out_unrecognized_spec);
/*****************************************************************************/
typedef enum {
NMS_IFCFG_KEY_TYPE_UNKNOWN = 0,
NMS_IFCFG_KEY_TYPE_WELL_KNOWN = (1u << 0),
NMS_IFCFG_KEY_TYPE_IS_PLAIN = (1u << 1),
NMS_IFCFG_KEY_TYPE_IS_NUMBERED = (1u << 2),
NMS_IFCFG_KEY_TYPE_IS_PREFIX = (1u << 3),
/* by default, well knowns keys that are not explicitly set
* by the writer (the unvisited, dirty ones) are removed.
* With this flag, such keys are kept if they are present. */
NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY = (1u << 4),
} NMSIfcfgKeyTypeFlags;
typedef struct {
const char *key_name;
NMSIfcfgKeyTypeFlags key_flags;
} NMSIfcfgKeyTypeInfo;
const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[225];
const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info (const char *key, gssize *out_idx);
static inline NMSIfcfgKeyTypeFlags
nms_ifcfg_well_known_key_find_info_flags (const char *key)
{
const NMSIfcfgKeyTypeInfo *ti;
ti = nms_ifcfg_well_known_key_find_info (key, NULL);
if (!ti)
return NMS_IFCFG_KEY_TYPE_UNKNOWN;
return ti->key_flags;
}
/*****************************************************************************/
gboolean nms_ifcfg_rh_utils_parse_unhandled_spec (const char *unhandled_spec,
const char **out_unmanaged_spec,
const char **out_unrecognized_spec);
#define NM_IFCFG_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory")
#define NM_IFCFG_CONNECTION_LOG_FMT "%s (%s,\"%s\")"
@ -51,6 +90,12 @@ _nms_ifcfg_rh_utils_numbered_tag (char *buf, gsize buf_len, const char *tag_name
{
gsize l;
#if NM_MORE_ASSERTS > 5
nm_assert (NM_FLAGS_ALL (nms_ifcfg_well_known_key_find_info_flags (tag_name),
NMS_IFCFG_KEY_TYPE_WELL_KNOWN
| NMS_IFCFG_KEY_TYPE_IS_NUMBERED));
#endif
l = g_strlcpy (buf, tag_name, buf_len);
nm_assert (l < buf_len);
if (which != -1) {
@ -70,6 +115,28 @@ _nms_ifcfg_rh_utils_numbered_tag (char *buf, gsize buf_len, const char *tag_name
_nms_ifcfg_rh_utils_numbered_tag (buf, sizeof (buf), ""tag_name"", (which)); \
})
gboolean nms_ifcfg_rh_utils_is_numbered_tag_impl (const char *key,
const char *tag,
gsize tag_len,
gint64 *out_idx);
static inline gboolean
nms_ifcfg_rh_utils_is_numbered_tag (const char *key,
const char *tag,
gint64 *out_idx)
{
nm_assert (tag);
return nms_ifcfg_rh_utils_is_numbered_tag_impl (key, tag, strlen (tag), out_idx);
}
#define NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG(key, tag, out_idx) \
nms_ifcfg_rh_utils_is_numbered_tag_impl (key, tag, NM_STRLEN (tag), out_idx)
/*****************************************************************************/
const NMSIfcfgKeyTypeInfo *nms_ifcfg_rh_utils_is_well_known_key (const char *key);
/*****************************************************************************/
extern const char *const _nm_ethtool_ifcfg_names[_NM_ETHTOOL_ID_FEATURE_NUM];

View file

@ -66,10 +66,8 @@ save_secret_flags (shvarFile *ifcfg,
g_return_if_fail (ifcfg != NULL);
g_return_if_fail (key != NULL);
if (flags == NM_SETTING_SECRET_FLAG_NONE) {
svUnsetValue (ifcfg, key);
if (flags == NM_SETTING_SECRET_FLAG_NONE)
return;
}
/* Convert flags bitfield into string representation */
str = g_string_sized_new (20);
@ -100,9 +98,6 @@ set_secret (shvarFile *ifcfg,
const char *flags_key,
NMSettingSecretFlags flags)
{
/* Clear the secret from the ifcfg and the associated "keys" file */
svUnsetValue (ifcfg, key);
/* Save secret flags */
save_secret_flags (ifcfg, flags_key, flags);
@ -147,7 +142,7 @@ write_secrets (shvarFile *ifcfg,
if (!any_secrets)
(void) unlink (svFileGetName (keyfile));
else if (!svWriteFile (keyfile, 0600, &local)) {
else if (!svWriteFileWithoutDirtyWellknown (keyfile, 0600, &local)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
"Failure to write secrets to '%s': %s", svFileGetName (keyfile), local->message);
return FALSE;
@ -372,12 +367,8 @@ write_8021x_setting (NMConnection *connection,
int vint;
s_8021x = nm_connection_get_setting_802_1x (connection);
if (!s_8021x) {
/* If wired, clear KEY_MGMT */
if (wired)
svUnsetValue (ifcfg, "KEY_MGMT");
if (!s_8021x)
return TRUE;
}
/* If wired, write KEY_MGMT */
if (wired)
@ -424,10 +415,7 @@ write_8021x_setting (NMConnection *connection,
nm_setting_802_1x_get_system_ca_certs (s_8021x));
value = nm_setting_802_1x_get_phase1_peapver (s_8021x);
if (NM_IN_STRSET (value, "0", "1"))
svSetValueStr (ifcfg, "IEEE_8021X_PEAP_VERSION", value);
else
svUnsetValue (ifcfg, "IEEE_8021X_PEAP_VERSION");
svSetValueStr (ifcfg, "IEEE_8021X_PEAP_VERSION", value);
svSetValueBoolean_cond_true (ifcfg,
"IEEE_8021X_PEAP_FORCE_NEW_LABEL",
@ -452,7 +440,6 @@ write_8021x_setting (NMConnection *connection,
svSetValueStr (ifcfg, "IEEE_8021X_FAST_PROVISIONING", value);
/* Phase2 auth methods */
svUnsetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS");
phase2_auth = g_string_new (NULL);
value = nm_setting_802_1x_get_phase2_auth (s_8021x);
@ -473,9 +460,7 @@ write_8021x_setting (NMConnection *connection,
}
auth_flags = nm_setting_802_1x_get_phase1_auth_flags (s_8021x);
if (auth_flags == NM_SETTING_802_1X_AUTH_FLAGS_NONE) {
svUnsetValue (ifcfg, "IEEE_8021X_PHASE1_AUTH_FLAGS");
} else {
if (auth_flags != NM_SETTING_802_1X_AUTH_FLAGS_NONE) {
svSetValueEnum (ifcfg, "IEEE_8021X_PHASE1_AUTH_FLAGS",
nm_setting_802_1x_auth_flags_get_type(),
auth_flags);
@ -492,7 +477,6 @@ write_8021x_setting (NMConnection *connection,
svSetValueStr (ifcfg, "IEEE_8021X_PHASE2_SUBJECT_MATCH",
nm_setting_802_1x_get_phase2_subject_match (s_8021x));
svUnsetValue (ifcfg, "IEEE_8021X_ALTSUBJECT_MATCHES");
str = g_string_new (NULL);
num = nm_setting_802_1x_get_num_altsubject_matches (s_8021x);
for (i = 0; i < num; i++) {
@ -505,7 +489,6 @@ write_8021x_setting (NMConnection *connection,
svSetValueStr (ifcfg, "IEEE_8021X_ALTSUBJECT_MATCHES", str->str);
g_string_free (str, TRUE);
svUnsetValue (ifcfg, "IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES");
str = g_string_new (NULL);
num = nm_setting_802_1x_get_num_phase2_altsubject_matches (s_8021x);
for (i = 0; i < num; i++) {
@ -565,14 +548,11 @@ write_wireless_security_setting (NMConnection *connection,
}
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
g_assert (key_mgmt);
nm_assert (key_mgmt);
auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
svUnsetValue (ifcfg, "DEFAULTKEY");
if (!strcmp (key_mgmt, "none")) {
svUnsetValue (ifcfg, "KEY_MGMT");
wep = TRUE;
*no_8021x = TRUE;
} else if (!strcmp (key_mgmt, "wpa-psk")) {
@ -595,7 +575,6 @@ write_wireless_security_setting (NMConnection *connection,
wpa = TRUE;
}
svUnsetValue (ifcfg, "SECURITYMODE");
if (auth_alg) {
if (!strcmp (auth_alg, "shared"))
svSetValueStr (ifcfg, "SECURITYMODE", "restricted");
@ -615,11 +594,8 @@ write_wireless_security_setting (NMConnection *connection,
}
}
/* WPS */
wps_method = nm_setting_wireless_security_get_wps_method (s_wsec);
if (wps_method == NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT)
svUnsetValue (ifcfg, "WPS_METHOD");
else
if (wps_method != NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT)
svSetValueEnum (ifcfg, "WPS_METHOD", nm_setting_wireless_security_wps_method_get_type (), wps_method);
/* WEP keys */
@ -705,8 +681,6 @@ write_wireless_security_setting (NMConnection *connection,
}
/* WPA protos */
svUnsetValue (ifcfg, "WPA_ALLOW_WPA");
svUnsetValue (ifcfg, "WPA_ALLOW_WPA2");
num = nm_setting_wireless_security_get_num_protos (s_wsec);
for (i = 0; i < num; i++) {
proto = nm_setting_wireless_security_get_proto (s_wsec, i);
@ -717,7 +691,6 @@ write_wireless_security_setting (NMConnection *connection,
}
/* WPA Pairwise ciphers */
svUnsetValue (ifcfg, "CIPHER_PAIRWISE");
str = g_string_new (NULL);
num = nm_setting_wireless_security_get_num_pairwise (s_wsec);
for (i = 0; i < num; i++) {
@ -739,7 +712,6 @@ write_wireless_security_setting (NMConnection *connection,
g_string_free (str, TRUE);
/* WPA Group ciphers */
svUnsetValue (ifcfg, "CIPHER_GROUP");
str = g_string_new (NULL);
num = nm_setting_wireless_security_get_num_groups (s_wsec);
for (i = 0; i < num; i++) {
@ -764,16 +736,12 @@ write_wireless_security_setting (NMConnection *connection,
"WPA_PSK_FLAGS",
wpa ? nm_setting_wireless_security_get_psk_flags (s_wsec) : NM_SETTING_SECRET_FLAG_NONE);
if (nm_setting_wireless_security_get_pmf (s_wsec) == NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT)
svUnsetValue (ifcfg, "PMF");
else {
if (nm_setting_wireless_security_get_pmf (s_wsec) != NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT) {
svSetValueEnum (ifcfg, "PMF", nm_setting_wireless_security_pmf_get_type (),
nm_setting_wireless_security_get_pmf (s_wsec));
}
if (nm_setting_wireless_security_get_fils (s_wsec) == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT)
svUnsetValue (ifcfg, "FILS");
else {
if (nm_setting_wireless_security_get_fils (s_wsec) != NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) {
svSetValueEnum (ifcfg, "FILS", nm_setting_wireless_security_fils_get_type (),
nm_setting_wireless_security_get_fils (s_wsec));
}
@ -814,14 +782,12 @@ write_wireless_setting (NMConnection *connection,
svSetValueStr (ifcfg, "GENERATE_MAC_ADDRESS_MASK",
nm_setting_wireless_get_generate_mac_address_mask (s_wireless));
svUnsetValue (ifcfg, "HWADDR_BLACKLIST");
macaddr_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless);
if (macaddr_blacklist[0]) {
char *blacklist_str;
gs_free char *blacklist_str = NULL;
blacklist_str = g_strjoinv (" ", (char **) macaddr_blacklist);
svSetValueStr (ifcfg, "HWADDR_BLACKLIST", blacklist_str);
g_free (blacklist_str);
}
mtu = nm_setting_wireless_get_mtu (s_wireless);
@ -883,9 +849,9 @@ write_wireless_setting (NMConnection *connection,
}
mode = nm_setting_wireless_get_mode (s_wireless);
if (!mode)
svUnsetValue(ifcfg, "MODE");
else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_INFRA))
if (!mode) {
/* pass */
} else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_INFRA))
svSetValueStr (ifcfg, "MODE", "Managed");
else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) {
svSetValueStr (ifcfg, "MODE", "Ad-Hoc");
@ -899,8 +865,6 @@ write_wireless_setting (NMConnection *connection,
return FALSE;
}
svUnsetValue (ifcfg, "CHANNEL");
svUnsetValue (ifcfg, "BAND");
chan = nm_setting_wireless_get_channel (s_wireless);
if (chan) {
svSetValueInt64 (ifcfg, "CHANNEL", chan);
@ -916,18 +880,13 @@ write_wireless_setting (NMConnection *connection,
* otherwise there's no way to detect WEP vs. open when WEP keys aren't
* saved.
*/
svUnsetValue (ifcfg, "DEFAULTKEY");
svUnsetValue (ifcfg, "SECURITYMODE");
if (nm_connection_get_setting_wireless_security (connection)) {
if (!write_wireless_security_setting (connection, ifcfg, secrets, adhoc, no_8021x, error))
return FALSE;
} else {
/* Clear out wifi security keys */
svUnsetValue (ifcfg, "KEY_MGMT");
svUnsetValue (ifcfg, "IEEE_8021X_IDENTITY");
set_secret (ifcfg, secrets, "IEEE_8021X_PASSWORD", NULL, "IEEE_8021X_PASSWORD_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
svUnsetValue (ifcfg, "SECURITYMODE");
/* Clear existing keys */
set_secret (ifcfg, secrets, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
@ -941,11 +900,6 @@ write_wireless_setting (NMConnection *connection,
set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
}
svUnsetValue (ifcfg, "DEFAULTKEY");
svUnsetValue (ifcfg, "WPA_ALLOW_WPA");
svUnsetValue (ifcfg, "WPA_ALLOW_WPA2");
svUnsetValue (ifcfg, "CIPHER_PAIRWISE");
svUnsetValue (ifcfg, "CIPHER_GROUP");
set_secret (ifcfg, secrets, "WPA_PSK", NULL, "WPA_PSK_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
}
@ -963,7 +917,6 @@ write_wireless_setting (NMConnection *connection,
break;
default:
case NM_SETTING_WIRELESS_POWERSAVE_DEFAULT:
svUnsetValue (ifcfg, "POWERSAVE");
break;
}
@ -1054,8 +1007,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
blacklist_str = g_strjoinv (" ", (char **) macaddr_blacklist);
svSetValueStr (ifcfg, "HWADDR_BLACKLIST", blacklist_str);
} else
svUnsetValue (ifcfg, "HWADDR_BLACKLIST");
}
mtu = nm_setting_wired_get_mtu (s_wired);
svSetValueInt64_cond (ifcfg, "MTU", mtu != 0, mtu);
@ -1089,7 +1041,6 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
svSetValueStr (ifcfg, "CTCPROT",
nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot"));
svUnsetValue (ifcfg, "OPTIONS");
num_opts = nm_setting_wired_get_num_s390_options (s_wired);
if (s390_subchannels && num_opts) {
nm_auto_free_gstring GString *tmp = NULL;
@ -1141,11 +1092,9 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro
s_wired = nm_connection_get_setting_wired (connection);
s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (connection, NM_TYPE_SETTING_ETHTOOL));
if (!s_wired && !s_ethtool) {
svUnsetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN");
svUnsetValue (ifcfg, "ETHTOOL_OPTS");
if ( !s_wired
&& !s_ethtool)
return TRUE;
}
if (s_wired) {
auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired);
@ -1204,8 +1153,7 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro
if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC))
g_string_append_printf (str, "s sopass %s", wol_password);
}
} else
svUnsetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN");
}
if (s_ethtool) {
NMEthtoolID ethtool_id;
@ -1250,8 +1198,7 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro
if (str) {
svSetValueStr (ifcfg, "ETHTOOL_OPTS", str->str);
g_string_free (str, TRUE);
} else
svUnsetValue (ifcfg, "ETHTOOL_OPTS");
}
return TRUE;
}
@ -1350,10 +1297,6 @@ write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired,
svSetValueStr (ifcfg, "VLAN_EGRESS_PRIORITY_MAP", tmp);
g_free (tmp);
svUnsetValue (ifcfg, "HWADDR");
svUnsetValue (ifcfg, "MACADDR");
svUnsetValue (ifcfg, "MTU");
*wired = write_wired_for_virtual (connection, ifcfg);
return TRUE;
@ -1372,8 +1315,6 @@ write_bond_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired,
return FALSE;
}
svUnsetValue (ifcfg, "BONDING_OPTS");
num_opts = nm_setting_bond_get_num_options (s_bond);
if (num_opts) {
nm_auto_free_gstring GString *str = NULL;
@ -1467,10 +1408,9 @@ write_bridge_vlans (NMSetting *setting,
g_object_get (setting, property_name, &vlans, NULL);
if (!vlans || !vlans->len) {
svUnsetValue (ifcfg, key);
if ( !vlans
|| !vlans->len)
return TRUE;
}
string = g_string_new ("");
for (i = 0; i < vlans->len; i++) {
@ -1506,9 +1446,7 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire
return FALSE;
}
svUnsetValue (ifcfg, "BRIDGING_OPTS");
svSetValueBoolean (ifcfg, "STP", FALSE);
svUnsetValue (ifcfg, "DELAY");
mac = nm_setting_bridge_get_mac_address (s_bridge);
svSetValueStr (ifcfg, "BRIDGE_MACADDR", mac);
@ -1604,8 +1542,6 @@ write_bridge_port_setting (NMConnection *connection, shvarFile *ifcfg, GError **
if (!s_port)
return TRUE;
svUnsetValue (ifcfg, "BRIDGING_OPTS");
/* Bridge options */
string = g_string_sized_new (32);
@ -1681,11 +1617,11 @@ write_dcb_app (shvarFile *ifcfg,
write_dcb_flags (ifcfg, tag, flags);
nm_sprintf_buf (prop, "DCB_%s_PRIORITY", tag);
if ((flags & NM_SETTING_DCB_FLAG_ENABLE) && (priority >= 0))
if ( (flags & NM_SETTING_DCB_FLAG_ENABLE)
&& (priority >= 0)) {
nm_sprintf_buf (prop, "DCB_%s_PRIORITY", tag);
svSetValueInt64 (ifcfg, prop, priority);
else
svUnsetValue (ifcfg, prop);
}
}
typedef gboolean (*DcbGetBoolFunc) (NMSettingDcb *, guint);
@ -1700,10 +1636,8 @@ write_dcb_bool_array (shvarFile *ifcfg,
char str[9];
guint i;
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
svUnsetValue (ifcfg, key);
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE))
return;
}
str[8] = 0;
for (i = 0; i < 8; i++)
@ -1723,10 +1657,8 @@ write_dcb_uint_array (shvarFile *ifcfg,
char str[9];
guint i, num;
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
svUnsetValue (ifcfg, key);
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE))
return;
}
str[8] = 0;
for (i = 0; i < 8; i++) {
@ -1751,10 +1683,8 @@ write_dcb_percent_array (shvarFile *ifcfg,
GString *str;
guint i;
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
svUnsetValue (ifcfg, key);
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE))
return;
}
str = g_string_sized_new (30);
for (i = 0; i < 8; i++) {
@ -1773,38 +1703,8 @@ write_dcb_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
NMSettingDcbFlags flags;
s_dcb = nm_connection_get_setting_dcb (connection);
if (!s_dcb) {
static const char *clear_keys[] = {
"DCB",
KEY_DCB_APP_FCOE_ENABLE,
KEY_DCB_APP_FCOE_ADVERTISE,
KEY_DCB_APP_FCOE_WILLING,
KEY_DCB_APP_FCOE_MODE,
KEY_DCB_APP_ISCSI_ENABLE,
KEY_DCB_APP_ISCSI_ADVERTISE,
KEY_DCB_APP_ISCSI_WILLING,
KEY_DCB_APP_FIP_ENABLE,
KEY_DCB_APP_FIP_ADVERTISE,
KEY_DCB_APP_FIP_WILLING,
KEY_DCB_PFC_ENABLE,
KEY_DCB_PFC_ADVERTISE,
KEY_DCB_PFC_WILLING,
KEY_DCB_PFC_UP,
KEY_DCB_PG_ENABLE,
KEY_DCB_PG_ADVERTISE,
KEY_DCB_PG_WILLING,
KEY_DCB_PG_ID,
KEY_DCB_PG_PCT,
KEY_DCB_PG_UPPCT,
KEY_DCB_PG_STRICT,
KEY_DCB_PG_UP2TC,
NULL };
const char **iter;
for (iter = clear_keys; *iter; iter++)
svUnsetValue (ifcfg, *iter);
if (!s_dcb)
return TRUE;
}
svSetValueStr (ifcfg, "DCB", "yes");
@ -1813,8 +1713,6 @@ write_dcb_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
nm_setting_dcb_get_app_fcoe_priority (s_dcb));
if (nm_setting_dcb_get_app_fcoe_flags (s_dcb) & NM_SETTING_DCB_FLAG_ENABLE)
svSetValueStr (ifcfg, KEY_DCB_APP_FCOE_MODE, nm_setting_dcb_get_app_fcoe_mode (s_dcb));
else
svUnsetValue (ifcfg, KEY_DCB_APP_FCOE_MODE);
write_dcb_app (ifcfg, "APP_ISCSI",
nm_setting_dcb_get_app_iscsi_flags (s_dcb),
@ -1881,9 +1779,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
svSetValueStr (ifcfg, "AUTOCONNECT_SLAVES",
autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES ? "yes" :
autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO ? "no" : NULL);
} else
svUnsetValue (ifcfg, "AUTOCONNECT_SLAVES");
}
switch (nm_setting_connection_get_lldp (s_con)) {
case NM_SETTING_CONNECTION_LLDP_ENABLE_RX:
tmp = "rx";
@ -1897,7 +1793,6 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
svSetValueStr (ifcfg, "LLDP", tmp);
/* Permissions */
svUnsetValue (ifcfg, "USERS");
n = nm_setting_connection_get_num_permissions (s_con);
if (n > 0) {
str = g_string_sized_new (n * 20);
@ -1969,11 +1864,8 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
svSetValueStr (ifcfg, "DEVICETYPE", TYPE_TEAM);
else if (master_iface && nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME))
svSetValueStr (ifcfg, "DEVICETYPE", TYPE_TEAM_PORT);
else
svUnsetValue (ifcfg, "DEVICETYPE");
/* secondary connection UUIDs */
svUnsetValue (ifcfg, "SECONDARY_UUIDS");
n = nm_setting_connection_get_num_secondaries (s_con);
if (n > 0) {
str = g_string_sized_new (n * 37);
@ -2006,17 +1898,19 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
case NM_METERED_NO:
svSetValueStr (ifcfg, "CONNECTION_METERED", "no");
break;
default:
svUnsetValue (ifcfg, "CONNECTION_METERED");
case NM_METERED_UNKNOWN:
case NM_METERED_GUESS_YES:
case NM_METERED_GUESS_NO:
break;
}
vint = nm_setting_connection_get_auth_retries (s_con);
svSetValueInt64_cond (ifcfg, "AUTH_RETRIES", vint >= 0, vint);
vint32 = nm_setting_connection_get_wait_device_timeout (s_con);
if (vint32 == -1)
svUnsetValue (ifcfg, "DEVTIMEOUT");
else if ((vint32 % 1000) == 0)
if (vint32 == -1) {
/* pass */
} else if ((vint32 % 1000) == 0)
svSetValueInt64 (ifcfg, "DEVTIMEOUT", vint32 / 1000);
else {
char b[100];
@ -2030,15 +1924,13 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) {
svSetValueEnum (ifcfg, "MDNS", nm_setting_connection_mdns_get_type (),
mdns);
} else
svUnsetValue (ifcfg, "MDNS");
}
llmnr = nm_setting_connection_get_llmnr (s_con);
if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT) {
svSetValueEnum (ifcfg, "LLMNR", nm_setting_connection_llmnr_get_type (),
llmnr);
} else
svUnsetValue (ifcfg, "LLMNR");
}
}
static char *
@ -2223,10 +2115,6 @@ write_proxy_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
if (!s_proxy)
return TRUE;
svUnsetValue (ifcfg, "BROWSER_ONLY");
svUnsetValue (ifcfg, "PAC_URL");
svUnsetValue (ifcfg, "PAC_SCRIPT");
method = nm_setting_proxy_get_method (s_proxy);
switch (method) {
case NM_SETTING_PROXY_METHOD_AUTO:
@ -2299,8 +2187,6 @@ write_sriov_setting (NMConnection *connection, shvarFile *ifcfg)
s_sriov = NM_SETTING_SRIOV (nm_connection_get_setting (connection,
NM_TYPE_SETTING_SRIOV));
if (!s_sriov) {
svUnsetValue (ifcfg, "SRIOV_TOTAL_VFS");
svUnsetValue (ifcfg, "SRIOV_AUTOPROBE_DRIVERS");
return;
}
@ -2309,8 +2195,6 @@ write_sriov_setting (NMConnection *connection, shvarFile *ifcfg)
b = nm_setting_sriov_get_autoprobe_drivers (s_sriov);
if (b != NM_TERNARY_DEFAULT)
svSetValueInt64 (ifcfg, "SRIOV_AUTOPROBE_DRIVERS", b);
else
svUnsetValue (ifcfg, "SRIOV_AUTOPROBE_DRIVERS");
num = nm_setting_sriov_get_num_vfs (s_sriov);
for (i = 0; i < num; i++) {
@ -2373,8 +2257,6 @@ write_match_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
nm_auto_free_gstring GString *str = NULL;
guint i, num;
svUnsetValue (ifcfg, "MATCH_INTERFACE_NAME");
s_match = (NMSettingMatch *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MATCH);
if (!s_match)
return TRUE;
@ -2406,10 +2288,8 @@ write_res_options (shvarFile *ifcfg, NMSettingIPConfig *s_ip, const char *var)
nm_auto_free_gstring GString *value = NULL;
guint i, num_options;
if (!nm_setting_ip_config_has_dns_options (s_ip)) {
svUnsetValue (ifcfg, var);
if (!nm_setting_ip_config_has_dns_options (s_ip))
return;
}
value = g_string_new (NULL);
num_options = nm_setting_ip_config_get_num_dns_options (s_ip);
@ -2422,6 +2302,47 @@ write_res_options (shvarFile *ifcfg, NMSettingIPConfig *s_ip, const char *var)
svSetValue (ifcfg, var, value->str);
}
static void
write_dns_setting (shvarFile *ifcfg,
NMConnection *connection,
int addr_family)
{
NMSettingIPConfig *s_ip;
NMSettingIPConfig *s_ip4;
NMSettingIPConfig *s_ip6 = NULL;
guint num4;
guint num6 = 0;
guint num;
guint i;
guint offset;
if (addr_family == AF_INET6) {
s_ip6 = nm_connection_get_setting_ip6_config (connection);
num6 = s_ip6 ? nm_setting_ip_config_get_num_dns (s_ip6) : 0u;
}
s_ip4 = nm_connection_get_setting_ip4_config (connection);
num4 = s_ip4 ? nm_setting_ip_config_get_num_dns (s_ip4) : 0u;
if (addr_family == AF_INET6) {
num = num6;
offset = num4;
s_ip = s_ip6;
} else {
num = num4;
offset = 0;
s_ip = s_ip4;
}
for (i = 0; i < num; i++) {
char tag[64];
svSetValueStr (ifcfg,
numbered_tag (tag, "DNS", offset + i + 1u),
nm_setting_ip_config_get_dns (s_ip, i));
}
}
static gboolean
write_ip4_setting (NMConnection *connection,
shvarFile *ifcfg,
@ -2453,8 +2374,6 @@ write_ip4_setting (NMConnection *connection,
*
* Some IPv4 setting related options are not cleared,
* for no strong reason. */
svUnsetValue (ifcfg, "BOOTPROTO");
svUnsetValue (ifcfg, "RES_OPTIONS");
svUnsetAll (ifcfg, SV_KEY_TYPE_IP4_ADDRESS);
return TRUE;
}
@ -2465,17 +2384,8 @@ write_ip4_setting (NMConnection *connection,
if (!method)
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
/* IPv4 disabled, clear IPv4 related parameters */
svUnsetValue (ifcfg, "BOOTPROTO");
for (j = -1; j < 256; j++) {
svUnsetValue (ifcfg, numbered_tag (tag, "IPADDR", j));
svUnsetValue (ifcfg, numbered_tag (tag, "PREFIX", j));
svUnsetValue (ifcfg, numbered_tag (tag, "NETMASK", j));
svUnsetValue (ifcfg, numbered_tag (tag, "GATEWAY", j));
}
if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED))
return TRUE;
}
num = nm_setting_ip_config_get_num_addresses (s_ip4);
@ -2492,7 +2402,7 @@ write_ip4_setting (NMConnection *connection,
else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED))
svSetValueStr (ifcfg, "BOOTPROTO", "shared");
has_netmask = !!svFindFirstKeyWithPrefix (ifcfg, "NETMASK");
has_netmask = !!svFindFirstNumberedKey (ifcfg, "NETMASK");
/* Write out IPADDR<n>, PREFIX<n>, GATEWAY<n> for current IP addresses
* without labels. Unset obsolete NETMASK<n>.
@ -2535,44 +2445,14 @@ write_ip4_setting (NMConnection *connection,
svSetValueStr (ifcfg, tag,
nm_utils_inet4_ntop (_nm_utils_ip4_prefix_to_netmask (prefix), buf));
} else
svUnsetValue (ifcfg, tag);
}
n++;
}
svUnsetValue (ifcfg, numbered_tag (tag, "IPADDR", 0));
svUnsetValue (ifcfg, numbered_tag (tag, "PREFIX", 0));
svUnsetValue (ifcfg, numbered_tag (tag, "NETMASK", 0));
if (n == 0) {
svUnsetValue (ifcfg, "IPADDR");
svUnsetValue (ifcfg, "PREFIX");
svUnsetValue (ifcfg, "NETMASK");
}
for (j = n; j < 256; j++) {
svUnsetValue (ifcfg, numbered_tag (tag, "IPADDR", j));
svUnsetValue (ifcfg, numbered_tag (tag, "PREFIX", j));
svUnsetValue (ifcfg, numbered_tag (tag, "NETMASK", j));
}
for (j = -1; j < 256; j++) {
if (j != 0)
svUnsetValue (ifcfg, numbered_tag (tag, "GATEWAY", j));
}
svSetValueStr (ifcfg, "GATEWAY", nm_setting_ip_config_get_gateway (s_ip4));
num = nm_setting_ip_config_get_num_dns (s_ip4);
for (i = 0; i < 254; i++) {
const char *dns;
numbered_tag (tag, "DNS", i + 1);
if (i >= num)
svUnsetValue (ifcfg, tag);
else {
dns = nm_setting_ip_config_get_dns (s_ip4, i);
svSetValueStr (ifcfg, tag, dns);
}
}
write_dns_setting (ifcfg, connection, AF_INET);
num = nm_setting_ip_config_get_num_dns_searches (s_ip4);
if (num > 0) {
@ -2584,8 +2464,7 @@ write_ip4_setting (NMConnection *connection,
}
svSetValueStr (ifcfg, "DOMAIN", searches->str);
g_string_free (searches, TRUE);
} else
svUnsetValue (ifcfg, "DOMAIN");
}
/* DEFROUTE; remember that it has the opposite meaning from never-default */
svSetValueBoolean (ifcfg, "DEFROUTE", !nm_setting_ip_config_get_never_default (s_ip4));
@ -2646,8 +2525,7 @@ write_ip4_setting (NMConnection *connection,
timeout = nm_setting_ip_config_get_dad_timeout (s_ip4);
if (timeout < 0) {
svUnsetValue (ifcfg, "ACD_TIMEOUT");
svUnsetValue (ifcfg, "ARPING_WAIT");
/* pass */
} else if (timeout == 0) {
svSetValueStr (ifcfg, "ACD_TIMEOUT", "0");
svSetValueStr (ifcfg, "ARPING_WAIT", "0");
@ -2660,8 +2538,6 @@ write_ip4_setting (NMConnection *connection,
priority = nm_setting_ip_config_get_dns_priority (s_ip4);
if (priority)
svSetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", priority);
else
svUnsetValue (ifcfg, "IPV4_DNS_PRIORITY");
write_res_options (ifcfg, s_ip4, "RES_OPTIONS");
@ -2747,7 +2623,7 @@ write_ip4_aliases (NMConnection *connection, const char *base_ifcfg_path)
svSetValueInt64 (ifcfg, "PREFIX", nm_ip_address_get_prefix(addr));
svWriteFile (ifcfg, 0644, NULL);
svWriteFileWithoutDirtyWellknown (ifcfg, 0644, NULL);
svCloseFile (ifcfg);
}
}
@ -2764,9 +2640,7 @@ write_ip6_setting_dhcp_hostname (NMSettingIPConfig *s_ip6, shvarFile *ifcfg)
/* Missing DHCPV6_SEND_HOSTNAME means TRUE, and we prefer not write it
* explicitly in that case, because it is NM-specific variable
*/
if (nm_setting_ip_config_get_dhcp_send_hostname (s_ip6))
svUnsetValue (ifcfg, "DHCPV6_SEND_HOSTNAME");
else
if (!nm_setting_ip_config_get_dhcp_send_hostname (s_ip6))
svSetValueStr (ifcfg, "DHCPV6_SEND_HOSTNAME", "no");
flags = nm_setting_ip_config_get_dhcp_hostname_flags (s_ip6);
@ -2783,12 +2657,10 @@ write_ip6_setting (NMConnection *connection,
GError **error)
{
NMSettingIPConfig *s_ip6;
NMSettingIPConfig *s_ip4;
const char *value;
guint i, num, num4;
guint i, num;
int priority;
NMIPAddress *addr;
const char *dns;
gint64 route_metric;
NMIPRouteTableSyncMode route_table;
GString *ip_str1, *ip_str2, *ip_ptr;
@ -2802,40 +2674,21 @@ write_ip6_setting (NMConnection *connection,
*
* Some IPv6 setting related options are not cleared,
* for no strong reason. */
svUnsetValue (ifcfg, "IPV6INIT");
svUnsetValue (ifcfg, "IPV6_AUTOCONF");
svUnsetValue (ifcfg, "DHCPV6C");
svUnsetValue (ifcfg, "DHCPv6_DUID");
svUnsetValue (ifcfg, "DHCPv6_IAID");
svUnsetValue (ifcfg, "DHCPV6_HOSTNAME");
svUnsetValue (ifcfg, "DHCPV6_SEND_HOSTNAME");
svUnsetValue (ifcfg, "IPV6_DEFROUTE");
svUnsetValue (ifcfg, "IPV6_PEERDNS");
svUnsetValue (ifcfg, "IPV6_PEERROUTES");
svUnsetValue (ifcfg, "IPV6_FAILURE_FATAL");
svUnsetValue (ifcfg, "IPV6_ROUTE_METRIC");
svUnsetValue (ifcfg, "IPV6_ADDR_GEN_MODE");
svUnsetValue (ifcfg, "IPV6_RES_OPTIONS");
return TRUE;
}
value = nm_setting_ip_config_get_method (s_ip6);
g_assert (value);
svUnsetValue (ifcfg, "IPV6_DISABLED");
if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
svSetValueStr (ifcfg, "IPV6INIT", "no");
svUnsetValue (ifcfg, "DHCPV6C");
return TRUE;
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) {
svSetValueStr (ifcfg, "IPV6_DISABLED", "yes");
svSetValueStr (ifcfg, "IPV6INIT", "no");
svUnsetValue (ifcfg, "DHCPV6C");
svUnsetValue (ifcfg, "IPV6_AUTOCONF");
return TRUE;
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
svSetValueStr (ifcfg, "IPV6INIT", "yes");
svSetValueStr (ifcfg, "IPV6_AUTOCONF", "yes");
svUnsetValue (ifcfg, "DHCPV6C");
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
svSetValueStr (ifcfg, "IPV6INIT", "yes");
svSetValueStr (ifcfg, "IPV6_AUTOCONF", "no");
@ -2843,15 +2696,12 @@ write_ip6_setting (NMConnection *connection,
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
svSetValueStr (ifcfg, "IPV6INIT", "yes");
svSetValueStr (ifcfg, "IPV6_AUTOCONF", "no");
svUnsetValue (ifcfg, "DHCPV6C");
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
svSetValueStr (ifcfg, "IPV6INIT", "yes");
svSetValueStr (ifcfg, "IPV6_AUTOCONF", "no");
svUnsetValue (ifcfg, "DHCPV6C");
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
svSetValueStr (ifcfg, "IPV6INIT", "yes");
svSetValueStr (ifcfg, "IPV6_AUTOCONF", "shared");
svUnsetValue (ifcfg, "DHCPV6C");
}
svSetValueStr (ifcfg, "DHCPV6_DUID",
@ -2885,22 +2735,7 @@ write_ip6_setting (NMConnection *connection,
g_string_free (ip_str1, TRUE);
g_string_free (ip_str2, TRUE);
/* Write out DNS - 'DNS' key is used both for IPv4 and IPv6 */
s_ip4 = nm_connection_get_setting_ip4_config (connection);
num4 = s_ip4 ? nm_setting_ip_config_get_num_dns (s_ip4) : 0; /* from where to start with IPv6 entries */
num = nm_setting_ip_config_get_num_dns (s_ip6);
for (i = 0; i < 254; i++) {
char tag[64];
numbered_tag (tag, "DNS", i + num4 + 1);
if (i >= num)
svUnsetValue (ifcfg, tag);
else {
dns = nm_setting_ip_config_get_dns (s_ip6, i);
svSetValueStr (ifcfg, tag, dns);
}
}
write_dns_setting (ifcfg, connection, AF_INET6);
/* Write out DNS domains */
num = nm_setting_ip_config_get_num_dns_searches (s_ip6);
@ -2914,15 +2749,11 @@ write_ip6_setting (NMConnection *connection,
g_string_append (searches, nm_setting_ip_config_get_dns_search (s_ip6, i));
}
svSetValueStr (ifcfg, "IPV6_DOMAIN", searches->str);
} else
svUnsetValue (ifcfg, "IPV6_DOMAIN");
}
/* handle IPV6_DEFROUTE */
/* IPV6_DEFROUTE has the opposite meaning from 'never-default' */
if (nm_setting_ip_config_get_never_default (s_ip6))
svSetValueStr (ifcfg, "IPV6_DEFROUTE", "no");
else
svSetValueStr (ifcfg, "IPV6_DEFROUTE", "yes");
svSetValueBoolean (ifcfg, "IPV6_DEFROUTE", !nm_setting_ip_config_get_never_default (s_ip6));
svSetValueStr (ifcfg, "IPV6_PEERDNS",
nm_setting_ip_config_get_ignore_auto_dns (s_ip6) ? "no" : NULL);
@ -2946,8 +2777,6 @@ write_ip6_setting (NMConnection *connection,
route_table);
/* IPv6 Privacy Extensions */
svUnsetValue (ifcfg, "IPV6_PRIVACY");
svUnsetValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP");
switch (nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6))) {
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
svSetValueStr (ifcfg, "IPV6_PRIVACY", "no");
@ -2968,8 +2797,6 @@ write_ip6_setting (NMConnection *connection,
if (addr_gen_mode != NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) {
svSetValueEnum (ifcfg, "IPV6_ADDR_GEN_MODE", nm_setting_ip6_config_addr_gen_mode_get_type (),
addr_gen_mode);
} else {
svUnsetValue (ifcfg, "IPV6_ADDR_GEN_MODE");
}
/* IPv6 tokenized interface identifier */
@ -2979,8 +2806,6 @@ write_ip6_setting (NMConnection *connection,
priority = nm_setting_ip_config_get_dns_priority (s_ip6);
if (priority)
svSetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", priority);
else
svUnsetValue (ifcfg, "IPV6_DNS_PRIORITY");
write_res_options (ifcfg, s_ip6, "IPV6_RES_OPTIONS");
@ -3229,8 +3054,6 @@ do_write_construct (NMConnection *connection,
if (!write_tc_setting (connection, ifcfg, error))
return FALSE;
svUnsetValue (ifcfg, "DHCP_HOSTNAME");
svUnsetValue (ifcfg, "DHCP_FQDN");
route_path_is_svformat = utils_has_route_file_new_syntax (route_path);
@ -3317,7 +3140,7 @@ do_write_to_disk (NMConnection *connection,
* only. But we loaded the ifcfg files from disk, and managled our
* new settings (in-memory). */
if (!svWriteFile (ifcfg, 0644, error))
if (!svWriteFileWithoutDirtyWellknown (ifcfg, 0644, error))
return FALSE;
write_ip4_aliases (connection, svFileGetName (ifcfg));
@ -3336,7 +3159,7 @@ do_write_to_disk (NMConnection *connection,
else {
nm_assert (route_content_svformat || route_content);
if (route_content_svformat) {
if (!svWriteFile (route_content_svformat, 0644, error))
if (!svWriteFileWithoutDirtyWellknown (route_content_svformat, 0644, error))
return FALSE;
} else {
if (!g_file_set_contents (route_path, route_content->str, route_content->len, NULL)) {

View file

@ -19,13 +19,23 @@
#include "nm-glib-aux/nm-enum-utils.h"
#include "nm-glib-aux/nm-io-utils.h"
#include "c-list/src/c-list.h"
#include "nms-ifcfg-rh-utils.h"
/*****************************************************************************/
struct _shvarLine {
const char *key;
CList lst;
/* We index variables by their key in shvarFile.lst_idx. One shell variable might
* occur multiple times in a file (in which case the last occurrence wins).
* Hence, we need to keep a list of all the same keys.
*
* This is a pointer to the next shadowed line. */
struct _shvarLine *prev_shadowed;
/* There are three cases:
*
* 1) the line is not a valid variable assignment (that is, it doesn't
@ -43,21 +53,37 @@ struct _shvarLine {
* @key/@key_with_prefix.
* */
char *line;
const char *key;
char *key_with_prefix;
/* svSetValue() will clear the dirty flag. */
bool dirty:1;
};
typedef struct _shvarLine shvarLine;
struct _shvarFile {
char *fileName;
int fd;
CList lst_head;
gboolean modified;
char *fileName;
CList lst_head;
GHashTable *lst_idx;
int fd;
bool modified:1;
};
/*****************************************************************************/
#define ASSERT_key_is_well_known(key) \
nm_assert ( ({ \
const char *_key = (key); \
gboolean _is_wellknown = TRUE; \
\
if (!nms_ifcfg_rh_utils_is_well_known_key (_key)) { \
_is_wellknown = FALSE; \
g_critical ("ifcfg-rh key \"%s\" is not well-known", _key); \
} \
\
_is_wellknown; \
}) )
/**
* svParseBoolean:
* @value: the input string
@ -612,6 +638,7 @@ svFile_new (const char *name)
s->fd = -1;
s->fileName = g_strdup (name);
c_list_init (&s->lst_head);
s->lst_idx = g_hash_table_new (nm_pstr_hash, nm_pstr_equal);
return s;
}
@ -671,8 +698,11 @@ line_new_parse (const char *value, gsize len)
nm_assert (value);
line = g_slice_new0 (shvarLine);
c_list_init (&line->lst);
line = g_slice_new (shvarLine);
*line = (shvarLine) {
.lst = C_LIST_INIT (line->lst),
.dirty = TRUE,
};
for (k = 0; k < len; k++) {
if (g_ascii_isspace (value[k]))
@ -706,14 +736,19 @@ line_new_build (const char *key, const char *value)
{
char *value_escaped = NULL;
shvarLine *line;
char *new_key;
value = svEscape (value, &value_escaped);
line = g_slice_new (shvarLine);
c_list_init (&line->lst);
line->line = value_escaped ?: g_strdup (value);
line->key_with_prefix = g_strdup (key);
line->key = line->key_with_prefix;
new_key = g_strdup (key),
*line = (shvarLine) {
.lst = C_LIST_INIT (line->lst),
.line = value_escaped ?: g_strdup (value),
.key_with_prefix = new_key,
.key = new_key,
.dirty = FALSE,
};
ASSERT_shvarLine (line);
return line;
}
@ -727,6 +762,8 @@ line_set (shvarLine *line, const char *value)
ASSERT_shvarLine (line);
nm_assert (line->key);
line->dirty = FALSE;
if (line->key != line->key_with_prefix) {
memmove (line->key_with_prefix, line->key, strlen (line->key) + 1);
line->key = line->key_with_prefix;
@ -753,14 +790,48 @@ static void
line_free (shvarLine *line)
{
ASSERT_shvarLine (line);
c_list_unlink_stale (&line->lst);
g_free (line->line);
g_free (line->key_with_prefix);
c_list_unlink_stale (&line->lst);
g_slice_free (shvarLine, line);
}
/*****************************************************************************/
static void
_line_link_parse (shvarFile *s, const char *value, gsize len)
{
shvarLine *line;
line = line_new_parse (value, len);
if (!line->key)
goto do_link;
if (G_UNLIKELY (!g_hash_table_insert (s->lst_idx, line, line))) {
shvarLine *existing_key;
shvarLine *existing_val;
/* Slow-path: we have duplicate keys. Fix the mess we created.
* Unfortunately, g_hash_table_insert() now had to allocate an extra
* array to track the keys/values differently. I wish there was an
* GHashTable API to add a key only if it does not exist yet. */
if (!g_hash_table_lookup_extended (s->lst_idx, line, (gpointer *) &existing_key, (gpointer *) &existing_val))
nm_assert_not_reached ();
nm_assert (existing_val == line);
nm_assert (existing_key != line);
line->prev_shadowed = existing_key;
g_hash_table_replace (s->lst_idx, line, line);
}
do_link:
c_list_link_tail (&s->lst_head, &line->lst);
}
/*****************************************************************************/
/* Open the file <name>, returning a shvarFile on success and NULL on failure.
* Add a wrinkle to let the caller specify whether or not to create the file
* (actually, return a structure anyway) if it doesn't exist.
@ -818,9 +889,9 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
s = svFile_new (name);
for (p = arena; (q = strchr (p, '\n')) != NULL; p = q + 1)
c_list_link_tail (&s->lst_head, &line_new_parse (p, q - p)->lst);
_line_link_parse (s, p, q - p);
if (p[0])
c_list_link_tail (&s->lst_head, &line_new_parse (p, strlen (p))->lst);
_line_link_parse (s, p, strlen (p));
/* closefd is set if we opened the file read-only, so go ahead and
* close it, because we can't write to it anyway */
@ -850,36 +921,6 @@ svCreateFile (const char *name)
/*****************************************************************************/
static gboolean
_is_all_digits (const char *str)
{
return str[0]
&& NM_STRCHAR_ALL (str, ch, g_ascii_isdigit (ch));
}
#define IS_NUMBERED_TAG(key, tab_name) \
({ \
const char *_key2 = (key); \
\
( (strncmp (_key2, tab_name, NM_STRLEN (tab_name)) == 0) \
&& _is_all_digits (&_key2[NM_STRLEN (tab_name)])); \
})
#define IS_NUMBERED_TAG_PARSE(key, tab_name, out_idx) \
({ \
const char *_key = (key); \
gint64 _idx; \
gboolean _good = FALSE; \
gint64 *_out_idx = (out_idx); \
\
if ( IS_NUMBERED_TAG (_key, ""tab_name"") \
&& (_idx = _nm_utils_ascii_str_to_int64 (&_key[NM_STRLEN (tab_name)], 10, 0, G_MAXINT64, -1)) != -1) { \
NM_SET_OUT (_out_idx, _idx); \
_good = TRUE; \
} \
_good; \
})
static gboolean
_svKeyMatchesType (const char *key, SvKeyType match_key_type)
{
@ -887,18 +928,18 @@ _svKeyMatchesType (const char *key, SvKeyType match_key_type)
return TRUE;
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTE_SVFORMAT)) {
if ( IS_NUMBERED_TAG (key, "ADDRESS")
|| IS_NUMBERED_TAG (key, "NETMASK")
|| IS_NUMBERED_TAG (key, "GATEWAY")
|| IS_NUMBERED_TAG (key, "METRIC")
|| IS_NUMBERED_TAG (key, "OPTIONS"))
if ( NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "ADDRESS", NULL)
|| NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "NETMASK", NULL)
|| NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "GATEWAY", NULL)
|| NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "METRIC", NULL)
|| NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "OPTIONS", NULL))
return TRUE;
}
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_IP4_ADDRESS)) {
if ( IS_NUMBERED_TAG (key, "IPADDR")
|| IS_NUMBERED_TAG (key, "PREFIX")
|| IS_NUMBERED_TAG (key, "NETMASK")
|| IS_NUMBERED_TAG (key, "GATEWAY"))
if ( NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "IPADDR", NULL)
|| NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "PREFIX", NULL)
|| NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "NETMASK", NULL)
|| NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "GATEWAY", NULL))
return TRUE;
}
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_USER)) {
@ -906,20 +947,20 @@ _svKeyMatchesType (const char *key, SvKeyType match_key_type)
return TRUE;
}
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_TC)) {
if ( IS_NUMBERED_TAG (key, "QDISC")
|| IS_NUMBERED_TAG (key, "FILTER"))
if ( NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "QDISC", NULL)
|| NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "FILTER", NULL))
return TRUE;
}
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_SRIOV_VF)) {
if (IS_NUMBERED_TAG (key, "SRIOV_VF"))
if (NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "SRIOV_VF", NULL))
return TRUE;
}
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTING_RULE4)) {
if (IS_NUMBERED_TAG_PARSE (key, "ROUTING_RULE_", NULL))
if (NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "ROUTING_RULE_", NULL))
return TRUE;
}
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTING_RULE6)) {
if (IS_NUMBERED_TAG_PARSE (key, "ROUTING_RULE6_", NULL))
if (NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "ROUTING_RULE6_", NULL))
return TRUE;
}
@ -931,9 +972,9 @@ svNumberedParseKey (const char *key)
{
gint64 idx;
if (IS_NUMBERED_TAG_PARSE (key, "ROUTING_RULE_", &idx))
if (NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "ROUTING_RULE_", &idx))
return idx;
if (IS_NUMBERED_TAG_PARSE (key, "ROUTING_RULE6_", &idx))
if (NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "ROUTING_RULE6_", &idx))
return idx;
return -1;
}
@ -1001,20 +1042,18 @@ svGetKeysSorted (shvarFile *s,
/*****************************************************************************/
const char *
svFindFirstKeyWithPrefix (shvarFile *s, const char *key_prefix)
svFindFirstNumberedKey (shvarFile *s, const char *key_prefix)
{
CList *current;
const shvarLine *l;
const shvarLine *line;
g_return_val_if_fail (s, NULL);
g_return_val_if_fail (key_prefix, NULL);
c_list_for_each (current, &s->lst_head) {
l = c_list_entry (current, shvarLine, lst);
if ( l->key
&& l->line
&& g_str_has_prefix (l->key, key_prefix))
return l->key;
c_list_for_each_entry (line, &s->lst_head, lst) {
if ( line->key
&& line->line
&& nms_ifcfg_rh_utils_is_numbered_tag (line->key, key_prefix, NULL))
return line->key;
}
return NULL;
@ -1025,20 +1064,16 @@ svFindFirstKeyWithPrefix (shvarFile *s, const char *key_prefix)
static const char *
_svGetValue (shvarFile *s, const char *key, char **to_free)
{
CList *current;
const shvarLine *line, *l;
const shvarLine *line;
const char *v;
nm_assert (s);
nm_assert (_shell_is_name (key, -1));
nm_assert (to_free);
line = NULL;
c_list_for_each (current, &s->lst_head) {
l = c_list_entry (current, shvarLine, lst);
if (l->key && nm_streq (l->key, key))
line = l;
}
ASSERT_key_is_well_known (key);
line = g_hash_table_lookup (s->lst_idx, &key);
if (line && line->line) {
v = svUnescape (line->line, to_free);
@ -1229,19 +1264,15 @@ svGetValueEnum (shvarFile *s, const char *key,
gboolean
svUnsetAll (shvarFile *s, SvKeyType match_key_type)
{
CList *current;
shvarLine *line;
gboolean changed = FALSE;
g_return_val_if_fail (s, FALSE);
c_list_for_each (current, &s->lst_head) {
line = c_list_entry (current, shvarLine, lst);
c_list_for_each_entry (line, &s->lst_head, lst) {
ASSERT_shvarLine (line);
if (!line->key)
continue;
if (_svKeyMatchesType (line->key, match_key_type)) {
if ( line->key
&& _svKeyMatchesType (line->key, match_key_type)) {
if (nm_clear_g_free (&line->line)) {
ASSERT_shvarLine (line);
changed = TRUE;
@ -1254,13 +1285,46 @@ svUnsetAll (shvarFile *s, SvKeyType match_key_type)
return changed;
}
gboolean
svUnsetDirtyWellknown (shvarFile *s, NMTernary new_dirty_value)
{
shvarLine *line;
gboolean changed = FALSE;
g_return_val_if_fail (s, FALSE);
c_list_for_each_entry (line, &s->lst_head, lst) {
const NMSIfcfgKeyTypeInfo *ti;
ASSERT_shvarLine (line);
if ( line->dirty
&& line->key
&& line->line
&& (ti = nms_ifcfg_rh_utils_is_well_known_key (line->key))
&& !NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY)) {
if (nm_clear_g_free (&line->line)) {
ASSERT_shvarLine (line);
changed = TRUE;
}
}
if (new_dirty_value != NM_TERNARY_DEFAULT)
line->dirty = (new_dirty_value != NM_TERNARY_FALSE);
}
if (changed)
s->modified = TRUE;
return changed;
}
/* Same as svSetValueStr() but it preserves empty @value -- contrary to
* svSetValueStr() for which "" effectively means to remove the value. */
gboolean
svSetValue (shvarFile *s, const char *key, const char *value)
{
CList *current;
shvarLine *line, *l;
shvarLine *line;
shvarLine *l_shadowed;
gboolean changed = FALSE;
g_return_val_if_fail (s, FALSE);
@ -1268,29 +1332,37 @@ svSetValue (shvarFile *s, const char *key, const char *value)
nm_assert (_shell_is_name (key, -1));
line = NULL;
c_list_for_each (current, &s->lst_head) {
l = c_list_entry (current, shvarLine, lst);
if (l->key && nm_streq (l->key, key)) {
if (line) {
/* if we find multiple entries for the same key, we can
* delete all but the last. */
line_free (line);
changed = TRUE;
}
line = l;
}
ASSERT_key_is_well_known (key);
line = g_hash_table_lookup (s->lst_idx, &key);
if ( line
&& (l_shadowed = line->prev_shadowed)) {
/* if we find multiple entries for the same key, we can
* delete the shadowed ones. */
line->prev_shadowed = NULL;
changed = TRUE;
do {
shvarLine *l = l_shadowed;
l_shadowed = l_shadowed->prev_shadowed;
line_free (l);
} while (l_shadowed);
}
if (!value) {
if (line) {
/* We only clear the value, but leave the line entry. This way, if we
* happen to re-add the value, we write it to the same line again. */
if (nm_clear_g_free (&line->line)) {
changed = TRUE;
}
}
} else {
if (!line) {
c_list_link_tail (&s->lst_head, &line_new_build (key, value)->lst);
line = line_new_build (key, value);
if (!g_hash_table_add (s->lst_idx, line))
nm_assert_not_reached ();
c_list_link_tail (&s->lst_head, &line->lst);
changed = TRUE;
} else {
if (line_set (line, value))
@ -1442,14 +1514,15 @@ svWriteFile (shvarFile *s, int mode, GError **error)
void
svCloseFile (shvarFile *s)
{
CList *current, *safe;
shvarLine *line;
g_return_if_fail (s != NULL);
if (s->fd >= 0)
nm_close (s->fd);
g_free (s->fileName);
c_list_for_each_safe (current, safe, &s->lst_head)
line_free (c_list_entry (current, shvarLine, lst));
g_hash_table_destroy (s->lst_idx);
while ((line = c_list_first_entry (&s->lst_head, shvarLine, lst)))
line_free (line);
g_slice_free (shvarFile, s);
}

View file

@ -30,7 +30,7 @@ shvarFile *svCreateFile (const char *name);
/* Open the file <name>, return shvarFile on success, NULL on failure */
shvarFile *svOpenFile (const char *name, GError **error);
const char *svFindFirstKeyWithPrefix (shvarFile *s, const char *key_prefix);
const char *svFindFirstNumberedKey (shvarFile *s, const char *key_prefix);
/* Get the value associated with the key, and leave the current pointer
* pointing at the line containing the value. The char* returned MUST
@ -79,6 +79,7 @@ gboolean svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value);
gboolean svUnsetValue (shvarFile *s, const char *key);
gboolean svUnsetAll (shvarFile *s, SvKeyType match_key_type);
gboolean svUnsetDirtyWellknown (shvarFile *s, NMTernary new_dirty_value);
/* Write the current contents iff modified. Returns FALSE on error
* and TRUE on success. Do not write if no values have been modified.
@ -88,6 +89,13 @@ gboolean svUnsetAll (shvarFile *s, SvKeyType match_key_type);
*/
gboolean svWriteFile (shvarFile *s, int mode, GError **error);
static inline gboolean
svWriteFileWithoutDirtyWellknown (shvarFile *s, int mode, GError **error)
{
svUnsetDirtyWellknown (s, NM_TERNARY_FALSE);
return svWriteFile (s, mode, error);
}
/* Close the file descriptor (if open) and free the shvarFile. */
void svCloseFile (shvarFile *s);

View file

@ -1,6 +1,5 @@
HWADDR=00:22:15:59:62:97
TYPE=Ethernet
BRIDGING_OPTS="priority=28 hairpin_mode=1"
NAME="System test-bridge-component"
UUID=${UUID}
DEVICE=eth0

View file

@ -2,7 +2,6 @@ DNS1=192.0.2.1
IPADDR=102.0.2.2
GATEWAY=192.0.2.1
NETMASK=255.254.0.0
BOOTPROTO="static"
DEVICE=eth1
ONBOOT=yes
IPV6INIT=yes

View file

@ -16,4 +16,4 @@ CIPHER_GROUP="TKIP CCMP WEP40 WEP104"
KEY_MGMT=WPA-PSK
WPA_ALLOW_WPA=yes
WPA_ALLOW_WPA2=yes
LAST_ENTRY=no-newline
CTCPROT=no-newline

View file

@ -5,32 +5,32 @@
# don't consider only line-by-line, thus this is
# expected.
#
# Also note that setting NAME will replace the last
# Also note that setting IPADDR will replace the last
# occurrence, and delete all previous once.
#L1
NAME=l2
IPADDR=l2
#L2
NAME=l3
IPADDR=l3
some_key1=''
some_key2=$'\U0x'
some_key3=$'x\U0'
METRIC1=''
METRIC2=$'\U0x'
METRIC3=$'x\U0'
#L4
NAME='
NAME=l4x
IPADDR='
IPADDR=l4x
'
#Lx-1
NAME2=not-visible
IPADDR2=not-visible
#Lx-2
NAME2='invalid
IPADDR2='invalid
#Lx-3
#Ly-1
NAME3='invalid
IPADDR3='invalid
#Ly-2
NAME3=name3-value
IPADDR3=name3-value
#Ly-3

View file

@ -5,27 +5,27 @@
# don't consider only line-by-line, thus this is
# expected.
#
# Also note that setting NAME will replace the last
# Also note that setting IPADDR will replace the last
# occurrence, and delete all previous once.
#L1
#L2
some_key1=''
some_key2=$'\U0x'
some_key3=$'x\U0'
METRIC1=''
METRIC2=$'\U0x'
METRIC3=$'x\U0'
#L4
NAME=set-by-test1
IPADDR=set-by-test1
#NM: '
#Lx-1
#Lx-2
NAME2=set-by-test2
IPADDR2=set-by-test2
#Lx-3
#Ly-1
#Ly-2
NAME3=set-by-test3
IPADDR3=set-by-test3
#Ly-3

View file

@ -2868,7 +2868,7 @@ test_ifcfg_no_trailing_newline (void)
shvarFile *sv;
sv = _svOpenFile (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk");
_svGetValue_check (sv, "LAST_ENTRY", "no-newline");
_svGetValue_check (sv, "CTCPROT", "no-newline");
svCloseFile (sv);
}
@ -9781,23 +9781,23 @@ test_write_unknown (gconstpointer test_data)
_nmtst_svFileSetModified (sv);
if (g_str_has_suffix (testfile, "ifcfg-test-write-unknown-4")) {
_svGetValue_check (sv, "NAME", "l4x");
_svGetValue_check (sv, "NAME2", "");
_svGetValue_check (sv, "NAME3", "name3-value");
_svGetValue_check (sv, "IPADDR", "l4x");
_svGetValue_check (sv, "IPADDR2", "");
_svGetValue_check (sv, "IPADDR3", "name3-value");
svSetValue (sv, "NAME", "set-by-test1");
svSetValue (sv, "NAME2", NULL);
svSetValue (sv, "NAME2", "set-by-test2");
svSetValue (sv, "NAME3", "set-by-test3");
svSetValue (sv, "IPADDR", "set-by-test1");
svSetValue (sv, "IPADDR2", NULL);
svSetValue (sv, "IPADDR2", "set-by-test2");
svSetValue (sv, "IPADDR3", "set-by-test3");
_svGetValue_check (sv, "some_key", NULL);
_svGetValue_check (sv, "some_key1", "");
_svGetValue_check (sv, "some_key2", "");
_svGetValue_check (sv, "some_key3", "x");
_svGetValue_check (sv, "METRIC", NULL);
_svGetValue_check (sv, "METRIC1", "");
_svGetValue_check (sv, "METRIC2", "");
_svGetValue_check (sv, "METRIC3", "x");
_svGetValue_check (sv, "NAME", "set-by-test1");
_svGetValue_check (sv, "NAME2", "set-by-test2");
_svGetValue_check (sv, "NAME3", "set-by-test3");
_svGetValue_check (sv, "IPADDR", "set-by-test1");
_svGetValue_check (sv, "IPADDR2", "set-by-test2");
_svGetValue_check (sv, "IPADDR3", "set-by-test3");
}
success = svWriteFile (sv, 0644, &error);
@ -10242,6 +10242,69 @@ test_tc_write (void)
/*****************************************************************************/
static void
test_well_known_keys (void)
{
gsize i;
for (i = 0; i < G_N_ELEMENTS (nms_ifcfg_well_known_keys); i++) {
const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i];
g_assert (ti->key_name);
g_assert (ti->key_name[0]);
g_assert (NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_WELL_KNOWN));
g_assert (nm_utils_is_power_of_two (ti->key_flags & ( NMS_IFCFG_KEY_TYPE_IS_PLAIN
| NMS_IFCFG_KEY_TYPE_IS_NUMBERED
| NMS_IFCFG_KEY_TYPE_IS_PREFIX)));
}
for (i = 1; i < G_N_ELEMENTS (nms_ifcfg_well_known_keys); i++) {
const NMSIfcfgKeyTypeInfo *ti_prev = &nms_ifcfg_well_known_keys[i - 1];
const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i];
g_assert_cmpstr (ti_prev->key_name, <, ti->key_name);
}
for (i = 0; i < G_N_ELEMENTS (nms_ifcfg_well_known_keys); i++) {
const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i];
gs_free char *key_name = NULL;
gssize idx;
g_assert (ti == nms_ifcfg_well_known_key_find_info (ti->key_name, &idx));
g_assert_cmpint (i, ==, idx);
key_name = g_strdup (ti->key_name);
g_assert (ti == nms_ifcfg_well_known_key_find_info (key_name, &idx));
g_assert_cmpint (i, ==, idx);
}
#define _test_well_known(key, expected) \
G_STMT_START { \
const NMSIfcfgKeyTypeInfo *_ti; \
const char *_expected = (expected); \
\
_ti = nms_ifcfg_rh_utils_is_well_known_key (""key""); \
if (!_expected) { \
g_assert (!_ti); \
} else { \
g_assert (_ti); \
g_assert_cmpstr (_ti->key_name, ==, _expected); \
} \
} G_STMT_END
#define _test_well_known_plain(key) \
_test_well_known (""key"", ""key"")
_test_well_known_plain ("ONBOOT");
_test_well_known ("NM_USER_", NULL);
_test_well_known ("NM_USER_x", "NM_USER_");
_test_well_known ("IPADDR", "IPADDR");
_test_well_known ("IPADDR1", "IPADDR");
_test_well_known ("IPADDRx", NULL);
}
/*****************************************************************************/
#define TPATH "/settings/plugins/ifcfg-rh/"
#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED TEST_IFCFG_DIR"/ifcfg-test-wifi-open-ssid-long-quoted"
@ -10538,6 +10601,7 @@ int main (int argc, char **argv)
g_test_add_func (TPATH "tc/read", test_tc_read);
g_test_add_func (TPATH "tc/write", test_tc_write);
g_test_add_func (TPATH "utils/test_well_known_keys", test_well_known_keys);
return g_test_run ();
}