From 5266e25e2badd61048e403c93a39091d8382f7f1 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 8 Nov 2012 13:15:41 -0500 Subject: libnm-utils: add :carrier-detect properties For settings corresponding to devices that have a :carrier property (ie bond, bridge, infiniband, vlan, and wired), add a :carrier-detect property specifying how that affects the connection: yes: The connection can only be activated when the device has carrier, and will be deactivated if the device loses carrier (for more than 4 seconds). no: The connection ignores carrier on the device; it can be activated when there is no carrier, and stays activated when carrier is lost. on-activate: The connection can only be activated when the device has carrier, but it will not be deactivated if the device loses carrier. https://bugzilla.gnome.org/show_bug.cgi?id=688284 --- libnm-util/libnm-util.ver | 3 ++ libnm-util/nm-setting-infiniband.c | 50 +++++++++++++++++++++++++++++++++ libnm-util/nm-setting-infiniband.h | 3 ++ libnm-util/nm-setting-vlan.c | 51 ++++++++++++++++++++++++++++++++++ libnm-util/nm-setting-vlan.h | 3 ++ libnm-util/nm-setting-wired.c | 50 +++++++++++++++++++++++++++++++++ libnm-util/nm-setting-wired.h | 3 ++ libnm-util/nm-utils-private.h | 3 ++ libnm-util/nm-utils.c | 8 ++++++ src/settings/plugins/ifcfg-rh/reader.c | 24 ++++++++++++++++ src/settings/plugins/ifcfg-rh/writer.c | 6 ++++ 11 files changed, 204 insertions(+) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 04f2a91194..cd144a150e 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -286,6 +286,7 @@ global: nm_setting_hash_flags_get_type; nm_setting_infiniband_error_get_type; nm_setting_infiniband_error_quark; + nm_setting_infiniband_get_carrier_detect; nm_setting_infiniband_get_mac_address; nm_setting_infiniband_get_mtu; nm_setting_infiniband_get_transport_mode; @@ -414,6 +415,7 @@ global: nm_setting_vlan_clear_priorities; nm_setting_vlan_error_get_type; nm_setting_vlan_error_quark; + nm_setting_vlan_get_carrier_detect; nm_setting_vlan_get_flags; nm_setting_vlan_get_id; nm_setting_vlan_get_interface_name; @@ -449,6 +451,7 @@ global: nm_setting_wired_error_get_type; nm_setting_wired_error_quark; nm_setting_wired_get_auto_negotiate; + nm_setting_wired_get_carrier_detect; nm_setting_wired_get_cloned_mac_address; nm_setting_wired_get_duplex; nm_setting_wired_get_mac_address; diff --git a/libnm-util/nm-setting-infiniband.c b/libnm-util/nm-setting-infiniband.c index ee40aa0ec9..c23ab919bb 100644 --- a/libnm-util/nm-setting-infiniband.c +++ b/libnm-util/nm-setting-infiniband.c @@ -66,6 +66,7 @@ typedef struct { GByteArray *mac_address; char *transport_mode; guint32 mtu; + char *carrier_detect; } NMSettingInfinibandPrivate; enum { @@ -73,6 +74,7 @@ enum { PROP_MAC_ADDRESS, PROP_MTU, PROP_TRANSPORT_MODE, + PROP_CARRIER_DETECT, LAST_PROP }; @@ -135,6 +137,21 @@ nm_setting_infiniband_get_transport_mode (NMSettingInfiniband *setting) return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->transport_mode; } +/** + * nm_setting_infiniband_get_carrier_detect: + * @setting: the #NMSettingInfiniband + * + * Returns: the connection's carrier-detection behavior; + * See #NMSettingInfiniband:carrier-detect. + **/ +const char * +nm_setting_infiniband_get_carrier_detect (NMSettingInfiniband *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_INFINIBAND (setting), NULL); + + return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->carrier_detect; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) @@ -163,6 +180,14 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (priv->carrier_detect && !_nm_utils_carrier_detect_mode_valid (priv->carrier_detect)) { + g_set_error (error, + NM_SETTING_INFINIBAND_ERROR, + NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY, + NM_SETTING_INFINIBAND_CARRIER_DETECT); + return FALSE; + } + return TRUE; } @@ -203,6 +228,10 @@ set_property (GObject *object, guint prop_id, g_free (priv->transport_mode); priv->transport_mode = g_value_dup_string (value); break; + case PROP_CARRIER_DETECT: + g_free (priv->carrier_detect); + priv->carrier_detect = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -225,6 +254,9 @@ get_property (GObject *object, guint prop_id, case PROP_TRANSPORT_MODE: g_value_set_string (value, nm_setting_infiniband_get_transport_mode (setting)); break; + case PROP_CARRIER_DETECT: + g_value_set_string (value, nm_setting_infiniband_get_carrier_detect (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -293,5 +325,23 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) "The IPoIB transport mode. Either 'datagram' or 'connected'.", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingInfiniband:carrier-detect: + * + * Controls whether device carrier affects this connection. Possible values + * are 'no', meaning the connection completely ignores carrier; 'yes', + * meaning the connection can only be activated if carrier is present, + * and will be deactivated automatically if carrier is lost; and + * 'on-activate', meaning the connection can only be activated if carrier + * is present, but will not be deactivated if carrier is lost. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER_DETECT, + g_param_spec_string (NM_SETTING_INFINIBAND_CARRIER_DETECT, + "Carrier-detect", + "Controls whether device carrier affects this connection.", + "yes", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-infiniband.h b/libnm-util/nm-setting-infiniband.h index 98a3dd5e9c..a599093690 100644 --- a/libnm-util/nm-setting-infiniband.h +++ b/libnm-util/nm-setting-infiniband.h @@ -54,6 +54,7 @@ GQuark nm_setting_infiniband_error_quark (void); #define NM_SETTING_INFINIBAND_MAC_ADDRESS "mac-address" #define NM_SETTING_INFINIBAND_MTU "mtu" #define NM_SETTING_INFINIBAND_TRANSPORT_MODE "transport-mode" +#define NM_SETTING_INFINIBAND_CARRIER_DETECT "carrier-detect" typedef struct { NMSetting parent; @@ -76,6 +77,8 @@ const GByteArray *nm_setting_infiniband_get_mac_address (NMSettingInfiniband guint32 nm_setting_infiniband_get_mtu (NMSettingInfiniband *setting); const char * nm_setting_infiniband_get_transport_mode (NMSettingInfiniband *setting); +const char * nm_setting_infiniband_get_carrier_detect (NMSettingInfiniband *setting); + G_END_DECLS #endif /* NM_SETTING_INFINIBAND_H */ diff --git a/libnm-util/nm-setting-vlan.c b/libnm-util/nm-setting-vlan.c index df7f0702a4..92d5a3d23e 100644 --- a/libnm-util/nm-setting-vlan.c +++ b/libnm-util/nm-setting-vlan.c @@ -28,6 +28,7 @@ #include "nm-setting-vlan.h" #include "nm-param-spec-specialized.h" #include "nm-utils.h" +#include "nm-utils-private.h" #include "nm-dbus-glib-types.h" #include "nm-setting-connection.h" #include "nm-setting-private.h" @@ -74,6 +75,7 @@ typedef struct { guint32 flags; GSList *ingress_priority_map; GSList *egress_priority_map; + char *carrier_detect; } NMSettingVlanPrivate; enum { @@ -84,6 +86,7 @@ enum { PROP_FLAGS, PROP_INGRESS_PRIORITY_MAP, PROP_EGRESS_PRIORITY_MAP, + PROP_CARRIER_DETECT, LAST_PROP }; @@ -433,6 +436,21 @@ nm_setting_vlan_clear_priorities (NMSettingVlan *setting, NMVlanPriorityMap map) set_map (setting, map, NULL); } +/** + * nm_setting_vlan_get_carrier_detect: + * @setting: the #NMSettingVlan + * + * Returns: the connection's carrier-detection behavior; + * See #NMSettingVlan:carrier-detect. + **/ +const char * +nm_setting_vlan_get_carrier_detect (NMSettingVlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), NULL); + + return NM_SETTING_VLAN_GET_PRIVATE (setting)->carrier_detect; +} + /*********************************************************************/ static void @@ -519,6 +537,14 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (priv->carrier_detect && !_nm_utils_carrier_detect_mode_valid (priv->carrier_detect)) { + g_set_error (error, + NM_SETTING_VLAN_ERROR, + NM_SETTING_VLAN_ERROR_INVALID_PROPERTY, + NM_SETTING_VLAN_CARRIER_DETECT); + return FALSE; + } + return TRUE; } @@ -575,6 +601,10 @@ set_property (GObject *object, guint prop_id, priv->egress_priority_map = priority_stringlist_to_maplist (NM_VLAN_EGRESS_MAP, g_value_get_boxed (value)); break; + case PROP_CARRIER_DETECT: + g_free (priv->carrier_detect); + priv->carrier_detect = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -620,6 +650,9 @@ get_property (GObject *object, guint prop_id, case PROP_EGRESS_PRIORITY_MAP: g_value_take_boxed (value, priority_maplist_to_stringlist (priv->egress_priority_map)); break; + case PROP_CARRIER_DETECT: + g_value_set_string (value, nm_setting_vlan_get_carrier_detect (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -771,4 +804,22 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) "'to' are unsigned integers, ie '7:3'.", DBUS_TYPE_G_LIST_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingVlan:carrier-detect: + * + * Controls whether device carrier affects this connection. Possible values + * are 'no', meaning the connection completely ignores carrier; 'yes', + * meaning the connection can only be activated if carrier is present, + * and will be deactivated automatically if carrier is lost; and + * 'on-activate', meaning the connection can only be activated if carrier + * is present, but will not be deactivated if carrier is lost. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER_DETECT, + g_param_spec_string (NM_SETTING_VLAN_CARRIER_DETECT, + "Carrier-detect", + "Controls whether device carrier affects this connection.", + "yes", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-vlan.h b/libnm-util/nm-setting-vlan.h index 019c6da071..68d63cd953 100644 --- a/libnm-util/nm-setting-vlan.h +++ b/libnm-util/nm-setting-vlan.h @@ -63,6 +63,7 @@ GQuark nm_setting_vlan_error_quark (void); #define NM_SETTING_VLAN_FLAGS "flags" #define NM_SETTING_VLAN_INGRESS_PRIORITY_MAP "ingress-priority-map" #define NM_SETTING_VLAN_EGRESS_PRIORITY_MAP "egress-priority-map" +#define NM_SETTING_VLAN_CARRIER_DETECT "carrier-detect" typedef struct { NMSetting parent; @@ -142,6 +143,8 @@ gboolean nm_setting_vlan_add_priority_str (NMSettingVlan *setting, NMVlanPriorityMap map, const char *str); +const char * nm_setting_vlan_get_carrier_detect (NMSettingVlan *setting); + G_END_DECLS #endif /* NM_SETTING_VLAN_H */ diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index f44d6df618..0ab9f29817 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -83,6 +83,7 @@ typedef struct { GPtrArray *s390_subchannels; char *s390_nettype; GHashTable *s390_options; + char *carrier_detect; } NMSettingWiredPrivate; enum { @@ -98,6 +99,7 @@ enum { PROP_S390_SUBCHANNELS, PROP_S390_NETTYPE, PROP_S390_OPTIONS, + PROP_CARRIER_DETECT, LAST_PROP }; @@ -420,6 +422,21 @@ nm_setting_wired_remove_s390_option (NMSettingWired *setting, return g_hash_table_remove (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key); } +/** + * nm_setting_wired_get_carrier_detect: + * @setting: the #NMSettingWired + * + * Returns: the connection's carrier-detection behavior; + * See #NMSettingWired:carrier-detect. + **/ +const char * +nm_setting_wired_get_carrier_detect (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->carrier_detect; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -506,6 +523,14 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (priv->carrier_detect && !_nm_utils_carrier_detect_mode_valid (priv->carrier_detect)) { + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_CARRIER_DETECT); + return FALSE; + } + return TRUE; } @@ -603,6 +628,10 @@ set_property (GObject *object, guint prop_id, if (new_hash) g_hash_table_foreach (new_hash, copy_hash, priv->s390_options); break; + case PROP_CARRIER_DETECT: + g_free (priv->carrier_detect); + priv->carrier_detect = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -650,6 +679,9 @@ get_property (GObject *object, guint prop_id, case PROP_S390_OPTIONS: g_value_set_boxed (value, priv->s390_options); break; + case PROP_CARRIER_DETECT: + g_value_set_string (value, nm_setting_wired_get_carrier_detect (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -869,5 +901,23 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) "'layer2', 'portname', 'protocol', among others.", DBUS_TYPE_G_MAP_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingWired:carrier-detect: + * + * Controls whether device carrier affects this connection. Possible values + * are 'no', meaning the connection completely ignores carrier; 'yes', + * meaning the connection can only be activated if carrier is present, + * and will be deactivated automatically if carrier is lost; and + * 'on-activate', meaning the connection can only be activated if carrier + * is present, but will not be deactivated if carrier is lost. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER_DETECT, + g_param_spec_string (NM_SETTING_WIRED_CARRIER_DETECT, + "Carrier-detect", + "Controls whether device carrier affects this connection.", + "yes", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index e235d23cc4..473e22b5a9 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -66,6 +66,7 @@ GQuark nm_setting_wired_error_quark (void); #define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels" #define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype" #define NM_SETTING_WIRED_S390_OPTIONS "s390-options" +#define NM_SETTING_WIRED_CARRIER_DETECT "carrier-detect" typedef struct { NMSetting parent; @@ -109,6 +110,8 @@ gboolean nm_setting_wired_add_s390_option (NMSettingWired *setting gboolean nm_setting_wired_remove_s390_option (NMSettingWired *setting, const char *key); +const char * nm_setting_wired_get_carrier_detect (NMSettingWired *setting); + G_END_DECLS #endif /* NM_SETTING_WIRED_H */ diff --git a/libnm-util/nm-utils-private.h b/libnm-util/nm-utils-private.h index fa1e3a016d..bbafbbbfe9 100644 --- a/libnm-util/nm-utils-private.h +++ b/libnm-util/nm-utils-private.h @@ -34,4 +34,7 @@ gboolean _nm_utils_string_slist_validate (GSList *list, void _nm_utils_register_value_transformations (void); +gboolean _nm_utils_carrier_detect_mode_valid (const char *carrier_detect); + + #endif diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index f1f1114238..ca9f7f511b 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -1483,6 +1483,14 @@ nm_utils_wpa_psk_valid (const char *psk) return TRUE; } +gboolean +_nm_utils_carrier_detect_mode_valid (const char *carrier_detect) +{ + const char *valid_carrier_detect[] = { "no", "on-activate", "yes", NULL }; + + return _nm_utils_string_in_list (carrier_detect, valid_carrier_detect); +} + /** * nm_utils_ip4_addresses_from_gvalue: * @value: gvalue containing a GPtrArray of GArrays of guint32s diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 6205057b11..ada633acc5 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -3437,6 +3437,14 @@ make_wired_setting (shvarFile *ifcfg, g_free (value); } + value = svGetValue(ifcfg, "CARRIER_DETECT", FALSE); + if (!value || !strlen (value)) { + g_free (value); + value = g_strdup ("yes"); + } + g_object_set (s_wired, NM_SETTING_WIRED_CARRIER_DETECT, value, NULL); + g_free (value); + return (NMSetting *) s_wired; error: @@ -3546,6 +3554,14 @@ make_infiniband_setting (shvarFile *ifcfg, PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: NM_CONTROLLED was false but HWADDR was missing; device will be managed"); } + value = svGetValue(ifcfg, "CARRIER_DETECT", FALSE); + if (!value || !strlen (value)) { + g_free (value); + value = g_strdup ("yes"); + } + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_CARRIER_DETECT, value, NULL); + g_free (value); + return (NMSetting *) s_infiniband; } @@ -4079,6 +4095,14 @@ make_vlan_setting (shvarFile *ifcfg, parse_prio_map_list (s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP); parse_prio_map_list (s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP); + value = svGetValue(ifcfg, "CARRIER_DETECT", FALSE); + if (!value || !strlen (value)) { + g_free (value); + value = g_strdup ("yes"); + } + g_object_set (s_vlan, NM_SETTING_VLAN_CARRIER_DETECT, value, NULL); + g_free (value); + if (out_master) *out_master = svGetValue (ifcfg, "MASTER", FALSE); return (NMSetting *) s_vlan; diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 23a1b5f396..3b2a595502 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -988,6 +988,8 @@ write_infiniband_setting (NMConnection *connection, shvarFile *ifcfg, GError **e strcmp (transport_mode, "connected") == 0 ? "yes" : "no", FALSE); + svSetValue (ifcfg, "CARRIER_DETECT", nm_setting_infiniband_get_carrier_detect (s_infiniband), FALSE); + svSetValue (ifcfg, "TYPE", TYPE_INFINIBAND, FALSE); return TRUE; @@ -1110,6 +1112,8 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) g_string_free (str, TRUE); } + svSetValue (ifcfg, "CARRIER_DETECT", nm_setting_wired_get_carrier_detect (s_wired), FALSE); + svSetValue (ifcfg, "TYPE", TYPE_ETHERNET, FALSE); return TRUE; @@ -1227,6 +1231,8 @@ write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, } } + svSetValue (ifcfg, "CARRIER_DETECT", nm_setting_vlan_get_carrier_detect (s_vlan), FALSE); + return TRUE; } -- cgit v1.2.3