diff options
Diffstat (limited to 'src')
38 files changed, 574 insertions, 1592 deletions
diff --git a/src/devices/adsl/nm-atm-manager.c b/src/devices/adsl/nm-atm-manager.c index 0830f85d..aeb5af6c 100644 --- a/src/devices/adsl/nm-atm-manager.c +++ b/src/devices/adsl/nm-atm-manager.c @@ -30,6 +30,8 @@ #include "nm-device-factory.h" #include "nm-logging.h" #include "nm-glib-compat.h" +#include "nm-platform.h" +#include "gsystem-local-alloc.h" typedef struct { GUdevClient *client; @@ -103,6 +105,8 @@ adsl_add (NMAtmManager *self, GUdevDevice *udev_device) NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); const char *ifname, *sysfs_path = NULL; char *driver = NULL; + gs_free char *atm_index_path = NULL; + int atm_index; NMDevice *device; g_return_if_fail (udev_device != NULL); @@ -115,20 +119,34 @@ adsl_add (NMAtmManager *self, GUdevDevice *udev_device) nm_log_dbg (LOGD_HW, "(%s): found ATM device", ifname); - if (dev_get_attrs (udev_device, &sysfs_path, &driver)) { - g_assert (sysfs_path); + atm_index_path = g_strdup_printf ("/sys/class/atm/%s/atmindex", + ASSERT_VALID_PATH_COMPONENT (ifname)); + atm_index = (int) nm_platform_sysctl_get_int_checked (NM_PLATFORM_GET, + atm_index_path, + 10, 0, G_MAXINT, + -1); + if (atm_index < 0) { + nm_log_warn (LOGD_HW, "(%s): failed to get ATM index", ifname); + return; + } - device = nm_device_adsl_new (sysfs_path, ifname, driver); - g_assert (device); + if (!dev_get_attrs (udev_device, &sysfs_path, &driver)) { + nm_log_warn (LOGD_HW, "(%s): failed to get ATM attributes", ifname); + return; + } - priv->devices = g_slist_prepend (priv->devices, device); - g_object_weak_ref (G_OBJECT (device), device_destroyed, self); + g_assert (sysfs_path); - g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); - g_object_unref (device); + device = nm_device_adsl_new (sysfs_path, ifname, driver, atm_index); + g_assert (device); - g_free (driver); - } + priv->devices = g_slist_prepend (priv->devices, device); + g_object_weak_ref (G_OBJECT (device), device_destroyed, self); + + g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); + g_object_unref (device); + + g_free (driver); } static void diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index 4d2cac5b..bcef39a2 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -55,10 +55,16 @@ G_DEFINE_TYPE (NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) #define NM_DEVICE_ADSL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ADSL, NMDeviceAdslPrivate)) +enum { + PROP_0, + PROP_ATM_INDEX, + + LAST_PROP +}; + /**********************************************/ typedef struct { - gboolean disposed; guint carrier_poll_id; int atm_index; @@ -69,6 +75,8 @@ typedef struct { int brfd; int nas_ifindex; char * nas_ifname; + guint nas_update_id; + guint nas_update_count; } NMDeviceAdslPrivate; /**************************************************************/ @@ -136,76 +144,6 @@ complete_connection (NMDevice *device, /**************************************************************/ -static void -set_nas_iface (NMDeviceAdsl *self, int idx, const char *name) -{ - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - - g_return_if_fail (name != NULL); - - g_warn_if_fail (priv->nas_ifindex <= 0); - priv->nas_ifindex = idx > 0 ? idx : nm_platform_link_get_ifindex (NM_PLATFORM_GET, name); - g_warn_if_fail (priv->nas_ifindex > 0); - - g_warn_if_fail (priv->nas_ifname == NULL); - priv->nas_ifname = g_strdup (name); -} - -static gboolean -br2684_create_iface (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) -{ - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - struct atm_newif_br2684 ni; - int err, fd, errsv; - gboolean success = FALSE; - guint num = 0; - - g_return_val_if_fail (s_adsl != NULL, FALSE); - - fd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); - if (fd < 0) { - errsv = errno; - _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); - return FALSE; - } - - memset (&ni, 0, sizeof (ni)); - ni.backend_num = ATM_BACKEND_BR2684; - ni.media = BR2684_MEDIA_ETHERNET; - ni.mtu = 1500; - - /* Loop attempting to create an interface that doesn't exist yet. The - * kernel can create one for us automatically, but due to API issues it - * cannot return that name to us. Since we want to know the name right - * away, just brute-force it. - */ - while (num < 10000) { - memset (&ni.ifname, 0, sizeof (ni.ifname)); - g_snprintf (ni.ifname, sizeof (ni.ifname), "nas%d", num); - - err = ioctl (fd, ATM_NEWBACKENDIF, &ni); - if (err == 0) { - set_nas_iface (self, -1, ni.ifname); - _LOGI (LOGD_ADSL, "using NAS interface %s (%d)", - priv->nas_ifname, priv->nas_ifindex); - success = TRUE; - break; - } else { - errsv = errno; - if (errsv == -EEXIST) { - /* Try again */ - num++; - } else { - _LOGW (LOGD_ADSL, "failed to create br2684 interface (%d)", errsv); - break; - } - } - } - - close (fd); - return success; -} - static gboolean br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) { @@ -295,7 +233,13 @@ error: } static void -link_changed_cb (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformLink *info, NMPlatformSignalChangeType change_type, NMPlatformReason reason, NMDeviceAdsl *self) +link_changed_cb (NMPlatform *platform, + NMPObjectType obj_type, + int ifindex, + NMPlatformLink *info, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDeviceAdsl *self) { if (change_type == NM_PLATFORM_SIGNAL_REMOVED) { NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); @@ -303,9 +247,9 @@ link_changed_cb (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPl /* This only gets called for PPPoE connections and "nas" interfaces */ - if (priv->nas_ifindex >= 0 && ifindex == priv->nas_ifindex) { + if (priv->nas_ifindex > 0 && ifindex == priv->nas_ifindex) { /* NAS device went away for some reason; kill the connection */ - _LOGD (LOGD_ADSL, "NAS interface disappeared"); + _LOGD (LOGD_ADSL, "br2684 interface disappeared"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BR2684_FAILED); @@ -313,11 +257,140 @@ link_changed_cb (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPl } } +static gboolean +pppoe_vcc_config (NMDeviceAdsl *self) +{ + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); + NMSettingAdsl *s_adsl; + + s_adsl = nm_connection_get_setting_adsl (nm_device_get_connection (device)); + g_assert (s_adsl); + + /* Set up the VCC */ + if (!br2684_assign_vcc (self, s_adsl)) + return FALSE; + + /* Watch for the 'nas' interface going away */ + g_signal_connect (nm_platform_get (), NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK (link_changed_cb), + self); + + _LOGD (LOGD_ADSL, "ATM setup successful"); + + /* otherwise we're good for stage3 */ + nm_platform_link_set_up (NM_PLATFORM_GET, priv->nas_ifindex, NULL); + + return TRUE; +} + +static gboolean +nas_update_cb (gpointer user_data) +{ + NMDeviceAdsl *self = NM_DEVICE_ADSL (user_data); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); + + g_assert (priv->nas_ifname); + + priv->nas_update_count++; + + if (priv->nas_update_count > 10) { + priv->nas_update_id = 0; + _LOGW (LOGD_ADSL, "failed to find br2684 interface %s ifindex after timeout", priv->nas_ifname); + nm_device_state_changed (device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BR2684_FAILED); + return G_SOURCE_REMOVE; + } + + g_warn_if_fail (priv->nas_ifindex < 0); + priv->nas_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->nas_ifname); + if (priv->nas_ifindex < 0) { + /* Keep waiting for it to appear */ + return G_SOURCE_CONTINUE; + } + + priv->nas_update_id = 0; + _LOGD (LOGD_ADSL, "using br2684 iface '%s' index %d", priv->nas_ifname, priv->nas_ifindex); + + if (pppoe_vcc_config (self)) { + nm_device_activate_schedule_stage3_ip_config_start (device); + } else { + nm_device_state_changed (device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BR2684_FAILED); + } + + return G_SOURCE_REMOVE; +} + +static NMActStageReturn +br2684_create_iface (NMDeviceAdsl *self, + NMSettingAdsl *s_adsl, + NMDeviceStateReason *out_reason) +{ + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); + struct atm_newif_br2684 ni; + int err, fd, errsv; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + guint num = 0; + + g_return_val_if_fail (s_adsl != NULL, FALSE); + + if (priv->nas_update_id) { + g_warn_if_fail (priv->nas_update_id == 0); + nm_clear_g_source (&priv->nas_update_id); + } + + fd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); + if (fd < 0) { + errsv = errno; + _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); + *out_reason = NM_DEVICE_STATE_REASON_BR2684_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + memset (&ni, 0, sizeof (ni)); + ni.backend_num = ATM_BACKEND_BR2684; + ni.media = BR2684_MEDIA_ETHERNET; + ni.mtu = 1500; + + /* Loop attempting to create an interface that doesn't exist yet. The + * kernel can create one for us automatically, but due to API issues it + * cannot return that name to us. Since we want to know the name right + * away, just brute-force it. + */ + while (num < 10000) { + memset (&ni.ifname, 0, sizeof (ni.ifname)); + g_snprintf (ni.ifname, sizeof (ni.ifname), "nas%d", num++); + + err = ioctl (fd, ATM_NEWBACKENDIF, &ni); + if (err == 0) { + g_free (priv->nas_ifname); + priv->nas_ifname = g_strdup (ni.ifname); + _LOGD (LOGD_ADSL, "waiting for br2684 iface '%s' to appear", priv->nas_ifname); + + priv->nas_update_count = 0; + priv->nas_update_id = g_timeout_add (100, nas_update_cb, self); + ret = NM_ACT_STAGE_RETURN_POSTPONE; + break; + } else if (errno != EEXIST) { + errsv = errno; + _LOGW (LOGD_ADSL, "failed to create br2684 interface (%d)", errsv); + *out_reason = NM_DEVICE_STATE_REASON_BR2684_FAILED; + break; + } + } + + close (fd); + return ret; +} + static NMActStageReturn act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) { NMDeviceAdsl *self = NM_DEVICE_ADSL (device); - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMSettingAdsl *s_adsl; const char *protocol; @@ -331,37 +404,14 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) _LOGD (LOGD_ADSL, "using ADSL protocol '%s'", protocol); if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) == 0) { - /* PPPoE needs RFC2684 bridging before we can do PPP over it */ - if (!br2684_create_iface (self, s_adsl)) { - *out_reason = NM_DEVICE_STATE_REASON_BR2684_FAILED; - goto done; - } - - /* Set up the VCC */ - if (!br2684_assign_vcc (self, s_adsl)) { - *out_reason = NM_DEVICE_STATE_REASON_BR2684_FAILED; - goto done; - } - - /* Watch for the 'nas' interface going away */ - g_signal_connect (nm_platform_get (), NM_PLATFORM_SIGNAL_LINK_CHANGED, - G_CALLBACK (link_changed_cb), - self); - - _LOGD (LOGD_ADSL, "ATM setup successful"); - - /* otherwise we're good for stage3 */ - nm_platform_link_set_up (NM_PLATFORM_GET, priv->nas_ifindex, NULL); - ret = NM_ACT_STAGE_RETURN_SUCCESS; - + ret = br2684_create_iface (self, s_adsl, out_reason); } else if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) == 0) { /* PPPoA doesn't need anything special */ ret = NM_ACT_STAGE_RETURN_SUCCESS; } else _LOGW (LOGD_ADSL, "unhandled ADSL protocol '%s'", protocol); -done: return ret; } @@ -425,7 +475,7 @@ act_stage3_ip4_config_start (NMDevice *device, g_assert (priv->nas_ifname); ppp_iface = priv->nas_ifname; - _LOGD (LOGD_ADSL, "starting PPPoE on NAS interface %s", priv->nas_ifname); + _LOGD (LOGD_ADSL, "starting PPPoE on br2684 interface %s", priv->nas_ifname); } else { ppp_iface = nm_device_get_iface (device); _LOGD (LOGD_ADSL, "starting PPPoA"); @@ -454,31 +504,37 @@ act_stage3_ip4_config_start (NMDevice *device, } static void -deactivate (NMDevice *device) +adsl_cleanup (NMDeviceAdsl *self) { - NMDeviceAdsl *self = NM_DEVICE_ADSL (device); NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); if (priv->ppp_manager) { - g_object_unref (priv->ppp_manager); - priv->ppp_manager = NULL; + g_signal_handlers_disconnect_by_func (priv->ppp_manager, G_CALLBACK (ppp_state_changed), self); + g_signal_handlers_disconnect_by_func (priv->ppp_manager, G_CALLBACK (ppp_ip4_config), self); + g_clear_object (&priv->ppp_manager); } - g_signal_handlers_disconnect_by_func (nm_platform_get (), G_CALLBACK (link_changed_cb), device); + g_signal_handlers_disconnect_by_func (nm_platform_get (), G_CALLBACK (link_changed_cb), self); if (priv->brfd >= 0) { close (priv->brfd); priv->brfd = -1; } + nm_clear_g_source (&priv->nas_update_id); + /* FIXME: kernel has no way of explicitly deleting the 'nasX' interface yet, * so it gets leaked. It does get destroyed when it's no longer in use, * but we have no control over that. */ - if (priv->nas_ifindex >= 0) - priv->nas_ifindex = -1; - g_free (priv->nas_ifname); - priv->nas_ifname = NULL; + priv->nas_ifindex = -1; + g_clear_pointer (&priv->nas_ifname, g_free); +} + +static void +deactivate (NMDevice *device) +{ + adsl_cleanup (NM_DEVICE_ADSL (device)); } /**************************************************************/ @@ -505,89 +561,74 @@ carrier_update_cb (gpointer user_data) NMDevice * nm_device_adsl_new (const char *udi, const char *iface, - const char *driver) + const char *driver, + int atm_index) { g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (atm_index >= 0, NULL); return (NMDevice *) g_object_new (NM_TYPE_DEVICE_ADSL, NM_DEVICE_UDI, udi, NM_DEVICE_IFACE, iface, NM_DEVICE_DRIVER, driver, + NM_DEVICE_ADSL_ATM_INDEX, atm_index, NM_DEVICE_TYPE_DESC, "ADSL", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ADSL, NULL); } -static int -get_atm_index (const char *iface) +static void +constructed (GObject *object) { - char *path; - int idx; - - path = g_strdup_printf ("/sys/class/atm/%s/atmindex", - ASSERT_VALID_PATH_COMPONENT (iface)); - idx = (int) nm_platform_sysctl_get_int_checked (NM_PLATFORM_GET, path, 10, 0, G_MAXINT, -1); - g_free (path); + NMDeviceAdsl *self = NM_DEVICE_ADSL (object); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - return idx; -} + G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructed (object); -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - NMDeviceAdsl *self; - NMDeviceAdslPrivate *priv; - - object = G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (!object) - return NULL; - - self = NM_DEVICE_ADSL (object); - priv = NM_DEVICE_ADSL_GET_PRIVATE (object); - - priv->atm_index = get_atm_index (nm_device_get_iface (NM_DEVICE (object))); - if (priv->atm_index < 0) { - _LOGE (LOGD_ADSL, "error reading ATM device index"); - g_object_unref (object); - return NULL; - } else - _LOGD (LOGD_ADSL, "ATM device index %d", priv->atm_index); + priv->carrier_poll_id = g_timeout_add_seconds (5, carrier_update_cb, self); - /* Poll the carrier */ - priv->carrier_poll_id = g_timeout_add_seconds (5, carrier_update_cb, object); + _LOGD (LOGD_ADSL, "ATM device index %d", priv->atm_index); - return object; + g_return_if_fail (priv->atm_index >= 0); } static void dispose (GObject *object) { - NMDeviceAdsl *self = NM_DEVICE_ADSL (object); - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); + adsl_cleanup (NM_DEVICE_ADSL (object)); - if (priv->disposed) { - G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object); - return; - } + nm_clear_g_source (&NM_DEVICE_ADSL_GET_PRIVATE (object)->carrier_poll_id); - priv->disposed = TRUE; + G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object); +} - if (priv->carrier_poll_id) { - g_source_remove (priv->carrier_poll_id); - priv->carrier_poll_id = 0; +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_ATM_INDEX: + g_value_set_int (value, NM_DEVICE_ADSL_GET_PRIVATE (object)->atm_index); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } +} - g_signal_handlers_disconnect_by_func (nm_platform_get (), G_CALLBACK (link_changed_cb), self); - - g_free (priv->nas_ifname); - priv->nas_ifname = NULL; - - G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object); +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_ATM_INDEX: + /* construct only */ + NM_DEVICE_ADSL_GET_PRIVATE (object)->atm_index = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void @@ -603,8 +644,10 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceAdslPrivate)); - object_class->constructor = constructor; + object_class->constructed = constructed; object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; parent_class->get_generic_capabilities = get_generic_capabilities; @@ -615,6 +658,14 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass) parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; parent_class->deactivate = deactivate; + /* properties */ + g_object_class_install_property + (object_class, PROP_ATM_INDEX, + g_param_spec_int (NM_DEVICE_ADSL_ATM_INDEX, "", "", + -1, G_MAXINT, -1, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_adsl_object_info); diff --git a/src/devices/adsl/nm-device-adsl.h b/src/devices/adsl/nm-device-adsl.h index f21381c2..bf41ed79 100644 --- a/src/devices/adsl/nm-device-adsl.h +++ b/src/devices/adsl/nm-device-adsl.h @@ -36,20 +36,22 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ADSL)) #define NM_DEVICE_ADSL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) +#define NM_DEVICE_ADSL_ATM_INDEX "atm-index" + typedef struct { NMDevice parent; } NMDeviceAdsl; typedef struct { NMDeviceClass parent; - } NMDeviceAdslClass; GType nm_device_adsl_get_type (void); NMDevice *nm_device_adsl_new (const char *udi, const char *iface, - const char *driver); + const char *driver, + int atm_index); G_END_DECLS diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 8a023843..2dda84b3 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -883,7 +883,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason) } if (!priv->supplicant.mgr) - priv->supplicant.mgr = nm_supplicant_manager_get (); + priv->supplicant.mgr = g_object_ref (nm_supplicant_manager_get ()); /* If we need secrets, get them */ setting_name = nm_connection_need_secrets (connection, NULL); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index b330397f..7cce6593 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -96,7 +96,7 @@ parent_hwaddr_changed (NMDevice *parent, NMDeviceVlan *self = NM_DEVICE_VLAN (user_data); NMConnection *connection; NMSettingWired *s_wired; - const char *cloned_mac = NULL; + const char *cloned_mac = NULL, *new_mac; /* Never touch assumed devices */ if (nm_device_uses_assumed_connection (self)) @@ -112,9 +112,13 @@ parent_hwaddr_changed (NMDevice *parent, cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); if (!cloned_mac) { - _LOGD (LOGD_VLAN, "parent hardware address changed"); - nm_device_set_hw_addr (self, nm_device_get_hw_address (parent), - "set", LOGD_VLAN); + new_mac = nm_device_get_hw_address (parent); + _LOGD (LOGD_VLAN, "parent hardware address changed to %s%s%s", + NM_PRINT_FMT_QUOTE_STRING (new_mac)); + if (new_mac) { + nm_device_set_hw_addr (self, nm_device_get_hw_address (parent), + "set", LOGD_VLAN); + } } } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 9b69d5ab..bb39ca55 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -7007,7 +7007,7 @@ nm_device_start_ip_check (NMDevice *self) if (priv->ip4_config && priv->ip4_state == IP_DONE) { guint gw = 0; - ping_binary = "/usr/bin/ping"; + ping_binary = nm_utils_find_helper ("ping", "/usr/bin/ping", NULL); log_domain = LOGD_IP4; gw = nm_ip4_config_get_gateway (priv->ip4_config); @@ -7016,7 +7016,7 @@ nm_device_start_ip_check (NMDevice *self) } else if (priv->ip6_config && priv->ip6_state == IP_DONE) { const struct in6_addr *gw = NULL; - ping_binary = "/usr/bin/ping6"; + ping_binary = nm_utils_find_helper ("ping6", "/usr/bin/ping6", NULL); log_domain = LOGD_IP6; gw = nm_ip6_config_get_gateway (priv->ip6_config); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 15d41206..1bf64bcc 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -136,6 +136,8 @@ struct _NMDeviceWifiPrivate { guint32 failed_link_count; guint periodic_source_id; guint link_timeout_id; + guint32 failed_iface_count; + guint reacquire_iface_id; NMDeviceWifiCapabilities capabilities; }; @@ -217,8 +219,7 @@ constructor (GType type, _LOGI (LOGD_HW | LOGD_WIFI, "driver supports Access Point (AP) mode"); /* Connect to the supplicant manager */ - priv->sup_mgr = nm_supplicant_manager_get (); - g_assert (priv->sup_mgr); + priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ()); return object; } @@ -1959,6 +1960,15 @@ cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect) } static void +cleanup_supplicant_failures (NMDeviceWifi *self) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + nm_clear_g_source (&priv->reacquire_iface_id); + priv->failed_iface_count = 0; +} + +static void wifi_secrets_cb (NMActRequest *req, guint32 call_id, NMConnection *connection, @@ -2158,6 +2168,24 @@ handle_8021x_or_psk_auth_fail (NMDeviceWifi *self, return handled; } +static gboolean +reacquire_interface_cb (gpointer user_data) +{ + NMDevice *device = NM_DEVICE (user_data); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + priv->reacquire_iface_id = 0; + priv->failed_iface_count++; + + _LOGW (LOGD_WIFI, "re-acquiring supplicant interface (#%d).", priv->failed_iface_count); + + if (!priv->sup_iface) + supplicant_interface_acquire (self); + + return G_SOURCE_REMOVE; +} + static void supplicant_iface_state_cb (NMSupplicantInterface *iface, guint32 new_state, @@ -2264,7 +2292,10 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, * ready if the supplicant comes back. */ supplicant_interface_release (self); - supplicant_interface_acquire (self); + if (priv->failed_iface_count < 5) + priv->reacquire_iface_id = g_timeout_add_seconds (10, reacquire_interface_cb, self); + else + _LOGI (LOGD_DEVICE | LOGD_WIFI, "supplicant interface keeps failing, giving up"); break; default: break; @@ -3061,6 +3092,7 @@ device_state_changed (NMDevice *device, } cleanup_association_attempt (self, TRUE); + cleanup_supplicant_failures (self); remove_all_aps (self); } @@ -3147,6 +3179,7 @@ set_enabled (NMDevice *device, gboolean enabled) } /* Re-initialize the supplicant interface and wait for it to be ready */ + cleanup_supplicant_failures (self); if (priv->sup_iface) supplicant_interface_release (self); supplicant_interface_acquire (self); @@ -3201,6 +3234,7 @@ dispose (GObject *object) cleanup_association_attempt (self, TRUE); supplicant_interface_release (self); + cleanup_supplicant_failures (self); g_clear_object (&priv->sup_mgr); diff --git a/src/dhcp-manager/nm-dhcp-helper.c b/src/dhcp-manager/nm-dhcp-helper.c index 7855f68c..5bcb0e27 100644 --- a/src/dhcp-manager/nm-dhcp-helper.c +++ b/src/dhcp-manager/nm-dhcp-helper.c @@ -160,6 +160,10 @@ main (int argc, char *argv[]) GDBusConnection *connection; GError *error = NULL; +#if !GLIB_CHECK_VERSION (2, 36, 0) + g_type_init (); +#endif + connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private-dhcp", G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error); diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 20ddefc3..af6ec087 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -373,16 +373,7 @@ nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, /***************************************************/ -NMDhcpManager * -nm_dhcp_manager_get (void) -{ - static NMDhcpManager *singleton = NULL; - - if (G_UNLIKELY (singleton == NULL)) - singleton = g_object_new (NM_TYPE_DHCP_MANAGER, NULL); - g_assert (singleton); - return singleton; -} +NM_DEFINE_SINGLETON_GETTER (NMDhcpManager, nm_dhcp_manager_get, NM_TYPE_DHCP_MANAGER); static void nm_dhcp_manager_init (NMDhcpManager *self) diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c index ab7f26d5..75809422 100644 --- a/src/dhcp-manager/nm-dhcp-utils.c +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -479,7 +479,7 @@ nm_dhcp_utils_ip4_config_from_options (const char *iface, str = g_hash_table_lookup (options, "dhcp_lease_time"); if (str) { address.lifetime = address.preferred = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP4, " lease time %d", address.lifetime); + nm_log_info (LOGD_DHCP4, " lease time %u", address.lifetime); } address.source = NM_IP_CONFIG_SOURCE_DHCP; @@ -623,13 +623,13 @@ nm_dhcp_utils_ip6_config_from_options (const char *iface, str = g_hash_table_lookup (options, "max_life"); if (str) { address.lifetime = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP6, " valid_lft %d", address.lifetime); + nm_log_info (LOGD_DHCP6, " valid_lft %u", address.lifetime); } str = g_hash_table_lookup (options, "preferred_life"); if (str) { address.preferred = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP6, " preferred_lft %d", address.preferred); + nm_log_info (LOGD_DHCP6, " preferred_lft %u", address.preferred); } str = g_hash_table_lookup (options, "ip6_address"); diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index f041c29e..c4be7df2 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -1074,18 +1074,7 @@ nm_dns_manager_end_updates (NMDnsManager *mgr, const char *func) /******************************************************************/ -NMDnsManager * -nm_dns_manager_get (void) -{ - static NMDnsManager * singleton = NULL; - - if (!singleton) { - singleton = NM_DNS_MANAGER (g_object_new (NM_TYPE_DNS_MANAGER, NULL)); - g_assert (singleton); - } - - return singleton; -} +NM_DEFINE_SINGLETON_GETTER (NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGER); static void init_resolv_conf_mode (NMDnsManager *self) diff --git a/src/main-utils.c b/src/main-utils.c index b0d8df3e..da327c40 100644 --- a/src/main-utils.c +++ b/src/main-utils.c @@ -84,8 +84,11 @@ nm_main_utils_setup_signals (GMainLoop *main_loop) signal (SIGPIPE, SIG_IGN); g_unix_signal_add (SIGHUP, sighup_handler, GINT_TO_POINTER (SIGHUP)); - g_unix_signal_add (SIGUSR1, sighup_handler, GINT_TO_POINTER (SIGUSR1)); - g_unix_signal_add (SIGUSR2, sighup_handler, GINT_TO_POINTER (SIGUSR2)); + if (nm_glib_check_version (2, 36, 0)) { + g_unix_signal_add (SIGUSR1, sighup_handler, GINT_TO_POINTER (SIGUSR1)); + g_unix_signal_add (SIGUSR2, sighup_handler, GINT_TO_POINTER (SIGUSR2)); + } else + nm_log_warn (LOGD_CORE, "glib-version: cannot handle SIGUSR1 and SIGUSR2 signals. Consider upgrading glib to 2.36.0 or newer"); g_unix_signal_add (SIGINT, sigint_handler, main_loop); g_unix_signal_add (SIGTERM, sigterm_handler, main_loop); } diff --git a/src/main.c b/src/main.c index 53d2cf64..2de36dc1 100644 --- a/src/main.c +++ b/src/main.c @@ -46,12 +46,9 @@ #include "main-utils.h" #include "nm-manager.h" #include "nm-linux-platform.h" -#include "nm-dns-manager.h" #include "nm-dbus-manager.h" -#include "nm-supplicant-manager.h" +#include "nm-device.h" #include "nm-dhcp-manager.h" -#include "nm-firewall-manager.h" -#include "nm-vpn-manager.h" #include "nm-logging.h" #include "nm-config.h" #include "nm-session-monitor.h" @@ -293,11 +290,6 @@ main (int argc, char *argv[]) gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE; gboolean success = FALSE; NMManager *manager = NULL; - gs_unref_object NMVpnManager *vpn_manager = NULL; - gs_unref_object NMDnsManager *dns_mgr = NULL; - gs_unref_object NMSupplicantManager *sup_mgr = NULL; - gs_unref_object NMDhcpManager *dhcp_mgr = NULL; - gs_unref_object NMFirewallManager *fw_mgr = NULL; gs_unref_object NMSettings *settings = NULL; gs_unref_object NMConfig *config = NULL; gs_unref_object NMSessionMonitor *session_monitor = NULL; @@ -483,16 +475,6 @@ main (int argc, char *argv[]) nm_auth_manager_setup (nm_config_get_auth_polkit (config)); - vpn_manager = nm_vpn_manager_get (); - g_assert (vpn_manager != NULL); - - dns_mgr = nm_dns_manager_get (); - g_assert (dns_mgr != NULL); - - /* Initialize DHCP manager */ - dhcp_mgr = nm_dhcp_manager_get (); - g_assert (dhcp_mgr != NULL); - nm_dispatcher_init (); settings = nm_settings_new (&error); @@ -509,14 +491,6 @@ main (int argc, char *argv[]) wwan_enabled, wimax_enabled); - /* Initialize the supplicant manager */ - sup_mgr = nm_supplicant_manager_get (); - g_assert (sup_mgr != NULL); - - /* Initialize Firewall manager */ - fw_mgr = nm_firewall_manager_get (); - g_assert (fw_mgr != NULL); - /* Initialize session monitor */ session_monitor = nm_session_monitor_get (); g_assert (session_monitor != NULL); diff --git a/src/nm-firewall-manager.c b/src/nm-firewall-manager.c index 59520b3b..4d302e9d 100644 --- a/src/nm-firewall-manager.c +++ b/src/nm-firewall-manager.c @@ -337,18 +337,7 @@ name_owner_changed (NMDBusManager *dbus_mgr, /*******************************************************************/ -NMFirewallManager * -nm_firewall_manager_get (void) -{ - static NMFirewallManager *singleton = NULL; - - if (G_UNLIKELY (!singleton)) { - singleton = NM_FIREWALL_MANAGER (g_object_new (NM_TYPE_FIREWALL_MANAGER, NULL)); - g_assert (singleton); - } - - return singleton; -} +NM_DEFINE_SINGLETON_GETTER (NMFirewallManager, nm_firewall_manager_get, NM_TYPE_FIREWALL_MANAGER); static void nm_firewall_manager_init (NMFirewallManager * self) diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 18966c57..25bde8ed 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -327,7 +327,6 @@ int main (int argc, char *argv[]) { char *bad_domains = NULL; - gs_unref_object NMDhcpManager *dhcp_mgr = NULL; GError *error = NULL; gboolean wrote_pidfile = FALSE; gs_free char *pidfile = NULL; @@ -437,11 +436,7 @@ main (int argc, char *argv[]) if (global_opt.dhcp4_address) { nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip4_property_path (global_opt.ifname, "promote_secondaries"), "1"); - /* Initialize DHCP manager */ - dhcp_mgr = nm_dhcp_manager_get (); - g_assert (dhcp_mgr != NULL); - - dhcp4_client = nm_dhcp_manager_start_ip4 (dhcp_mgr, + dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (), global_opt.ifname, ifindex, hwaddr, diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 5918f3dc..f625d350 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -876,8 +876,8 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src) /** * nm_ip4_config_replace: - * @dst: config from which to remove everything in @src - * @src: config to remove from @dst + * @dst: config to replace with @src content + * @src: source config to copy * @relevant_changes: return whether there are changes to the * destination object that are relevant. This is equal to * nm_ip4_config_equal() showing any difference. @@ -922,7 +922,10 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev /* default gateway */ if ( src_priv->gateway != dst_priv->gateway || src_priv->has_gateway != dst_priv->has_gateway) { - nm_ip4_config_set_gateway (dst, src_priv->gateway); + if (src_priv->has_gateway) + nm_ip4_config_set_gateway (dst, src_priv->gateway); + else + nm_ip4_config_unset_gateway (dst); has_relevant_changes = TRUE; } @@ -1629,16 +1632,31 @@ void nm_ip4_config_add_search (NMIP4Config *config, const char *new) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); - int i; + char *search; + size_t len; g_return_if_fail (new != NULL); g_return_if_fail (new[0] != '\0'); - for (i = 0; i < priv->searches->len; i++) - if (!g_strcmp0 (g_ptr_array_index (priv->searches, i), new)) - return; + search = g_strdup (new); + + /* Remove trailing dot as it has no effect */ + len = strlen (search); + if (search[len - 1] == '.') + search[len - 1] = 0; + + if (!search[0]) { + g_free (search); + return; + } + + if (_nm_utils_strv_find_first ((char **) priv->searches->pdata, + priv->searches->len, search) >= 0) { + g_free (search); + return; + } - g_ptr_array_add (priv->searches, g_strdup (new)); + g_ptr_array_add (priv->searches, search); _NOTIFY (config, PROP_SEARCHES); } diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index ef256231..f68c4339 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -35,6 +35,7 @@ #include "nm-route-manager.h" #include "NetworkManagerUtils.h" #include "nm-macros-internal.h" +#include "nm-core-internal.h" G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, G_TYPE_OBJECT) @@ -1553,16 +1554,31 @@ void nm_ip6_config_add_search (NMIP6Config *config, const char *new) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); - int i; + char *search; + size_t len; g_return_if_fail (new != NULL); g_return_if_fail (new[0] != '\0'); - for (i = 0; i < priv->searches->len; i++) - if (!g_strcmp0 (g_ptr_array_index (priv->searches, i), new)) - return; + search = g_strdup (new); + + /* Remove trailing dot as it has no effect */ + len = strlen (search); + if (search[len - 1] == '.') + search[len - 1] = 0; + + if (!search[0]) { + g_free (search); + return; + } + + if (_nm_utils_strv_find_first ((char **) priv->searches->pdata, + priv->searches->len, search) >= 0) { + g_free (search); + return; + } - g_ptr_array_add (priv->searches, g_strdup (new)); + g_ptr_array_add (priv->searches, search); _NOTIFY (config, PROP_SEARCHES); } diff --git a/src/nm-manager.c b/src/nm-manager.c index cc52ea78..a1e4fb4f 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -4880,7 +4880,7 @@ nm_manager_init (NMManager *manager) G_CALLBACK (dbus_connection_changed_cb), manager); - priv->vpn_manager = nm_vpn_manager_get (); + priv->vpn_manager = g_object_ref (nm_vpn_manager_get ()); g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); @@ -4908,10 +4908,10 @@ nm_manager_init (NMManager *manager) nm_log_warn (LOGD_AUTOIP4, "could not initialize avahi-autoipd D-Bus proxy"); /* sleep/wake handling */ - priv->sleep_monitor = nm_sleep_monitor_get (); - g_signal_connect (priv->sleep_monitor, "sleeping", + priv->sleep_monitor = g_object_ref (nm_sleep_monitor_get ()); + g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_SLEEPING, G_CALLBACK (sleeping_cb), manager); - g_signal_connect (priv->sleep_monitor, "resuming", + g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_RESUMING, G_CALLBACK (resuming_cb), manager); /* Listen for authorization changes */ @@ -5142,7 +5142,11 @@ dispose (GObject *object) } g_clear_object (&priv->aipd_proxy); - g_clear_object (&priv->sleep_monitor); + if (priv->sleep_monitor) { + g_signal_handlers_disconnect_by_func (priv->sleep_monitor, sleeping_cb, manager); + g_signal_handlers_disconnect_by_func (priv->sleep_monitor, resuming_cb, manager); + g_clear_object (&priv->sleep_monitor); + } if (priv->fw_monitor) { g_signal_handlers_disconnect_by_func (priv->fw_monitor, firmware_dir_changed, manager); diff --git a/src/nm-policy.c b/src/nm-policy.c index 1be5c4a3..fc2a9bf7 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1792,7 +1792,7 @@ nm_policy_new (NMManager *manager, NMSettings *settings) priv->fw_started_id = g_signal_connect (nm_firewall_manager_get (), "started", G_CALLBACK (firewall_started), policy); - priv->dns_manager = nm_dns_manager_get (); + priv->dns_manager = g_object_ref (nm_dns_manager_get ()); nm_dns_manager_set_initial_hostname (priv->dns_manager, priv->orig_hostname); priv->config_changed_id = g_signal_connect (priv->dns_manager, "config-changed", G_CALLBACK (dns_config_changed), policy); @@ -1903,7 +1903,7 @@ dispose (GObject *object) if (priv->dns_manager) { g_signal_handler_disconnect (priv->dns_manager, priv->config_changed_id); - priv->dns_manager = NULL; + g_clear_object (&priv->dns_manager); } for (iter = priv->manager_ids; iter; iter = g_slist_next (iter)) diff --git a/src/nm-sleep-monitor-systemd.c b/src/nm-sleep-monitor-systemd.c index c0bc65e4..44523a4a 100644 --- a/src/nm-sleep-monitor-systemd.c +++ b/src/nm-sleep-monitor-systemd.c @@ -243,16 +243,6 @@ nm_sleep_monitor_class_init (NMSleepMonitorClass *klass) G_TYPE_NONE, 0); } -NMSleepMonitor * -nm_sleep_monitor_get (void) -{ - static NMSleepMonitor *singleton = NULL; - - if (singleton) - return g_object_ref (singleton); - - singleton = NM_SLEEP_MONITOR (g_object_new (NM_TYPE_SLEEP_MONITOR, NULL)); - return singleton; -} +NM_DEFINE_SINGLETON_GETTER (NMSleepMonitor, nm_sleep_monitor_get, NM_TYPE_SLEEP_MONITOR); /* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/nm-sleep-monitor-upower.c b/src/nm-sleep-monitor-upower.c index 39cce595..0c46ae10 100644 --- a/src/nm-sleep-monitor-upower.c +++ b/src/nm-sleep-monitor-upower.c @@ -133,16 +133,6 @@ nm_sleep_monitor_class_init (NMSleepMonitorClass *klass) G_TYPE_NONE, 0); } -NMSleepMonitor * -nm_sleep_monitor_get (void) -{ - static NMSleepMonitor *singleton = NULL; - - if (singleton) - return g_object_ref (singleton); - - singleton = NM_SLEEP_MONITOR (g_object_new (NM_TYPE_SLEEP_MONITOR, NULL)); - return singleton; -} +NM_DEFINE_SINGLETON_GETTER (NMSleepMonitor, nm_sleep_monitor_get, NM_TYPE_SLEEP_MONITOR); /* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 2dd0b512..ee6ba421 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -384,6 +384,7 @@ _nl_link_parse_info_data (struct nl_sock *sk, int ifindex, NMNLInfoDataClosure data = { .parser = parser, .parser_data = parser_data }; struct nl_msg *msg = NULL; struct nl_cb *cb; + struct nl_cb *cb0; int err; err = rtnl_link_build_get_request (ifindex, NULL, &msg); @@ -395,7 +396,9 @@ _nl_link_parse_info_data (struct nl_sock *sk, int ifindex, if (err < 0) return err; - cb = nl_cb_clone (nl_socket_get_cb (sk)); + cb0 = nl_socket_get_cb (sk); + cb = nl_cb_clone (cb0); + nl_cb_put (cb0); if (cb == NULL) return -NLE_NOMEM; nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, _nl_link_parse_info_data_cb, &data); @@ -416,8 +419,11 @@ _nl_sock_flush_data (struct nl_sock *sk) { int nle; struct nl_cb *cb; + struct nl_cb *cb0; - cb = nl_cb_clone (nl_socket_get_cb (sk)); + cb0 = nl_socket_get_cb (sk); + cb = nl_cb_clone (cb0); + nl_cb_put (cb0); if (cb == NULL) return -NLE_NOMEM; @@ -747,7 +753,6 @@ struct _NMLinuxPlatformPrivate { } delayed_action; GHashTable *prune_candidates; - GHashTable *delayed_deletion; GHashTable *wifi_data; }; @@ -1658,33 +1663,6 @@ delayed_action_handle_idle (gpointer user_data) } static void -delayed_action_clear_REFRESH_LINK (NMPlatform *platform, int ifindex) -{ - NMLinuxPlatformPrivate *priv; - gssize idx; - gpointer user_data; - - if (ifindex <= 0) - return; - - priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); - if (!NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_REFRESH_LINK)) - return; - - user_data = GINT_TO_POINTER (ifindex); - - idx = _nm_utils_ptrarray_find_first (priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data); - if (idx < 0) - return; - - _LOGt_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, user_data, "clear"); - - g_ptr_array_remove_index_fast (priv->delayed_action.list_refresh_link, idx); - if (priv->delayed_action.list_refresh_link->len == 0) - priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK; -} - -static void delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gpointer user_data) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); @@ -1793,39 +1771,6 @@ cache_prune_candidates_prune (NMPlatform *platform) } static void -cache_delayed_deletion_prune (NMPlatform *platform) -{ - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); - GPtrArray *prune_list = NULL; - GHashTableIter iter; - guint i; - NMPObject *obj; - - if (g_hash_table_size (priv->delayed_deletion) == 0) - return; - - g_hash_table_iter_init (&iter, priv->delayed_deletion); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &obj)) { - if (obj) { - if (!prune_list) - prune_list = g_ptr_array_new_full (g_hash_table_size (priv->delayed_deletion), (GDestroyNotify) nmp_object_unref); - g_ptr_array_add (prune_list, nmp_object_ref (obj)); - } - } - - g_hash_table_remove_all (priv->delayed_deletion); - - if (prune_list) { - for (i = 0; i < prune_list->len; i++) { - obj = prune_list->pdata[i]; - _LOGt ("delayed-deletion: delete %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0)); - cache_remove_netlink (platform, obj, NULL, NULL, NM_PLATFORM_REASON_EXTERNAL); - } - g_ptr_array_unref (prune_list); - } -} - -static void cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMPCacheOpsType ops_type, gpointer user_data) { NMPlatform *platform = NM_PLATFORM (user_data); @@ -1945,6 +1890,20 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP NULL); } } + if ( NM_IN_SET (ops_type, NMP_CACHE_OPS_ADDED, NMP_CACHE_OPS_UPDATED) + && (new && new->_link.netlink.is_in_netlink) + && (!old || !old->_link.netlink.is_in_netlink)) + { + if ( new->link.type == NM_LINK_TYPE_VETH + && new->link.parent == 0) { + /* the initial notification when adding a veth pair can lack the parent/IFLA_LINK + * (https://bugzilla.redhat.com/show_bug.cgi?id=1285827). + * Request it again. */ + delayed_action_schedule (platform, + DELAYED_ACTION_TYPE_REFRESH_LINK, + GINT_TO_POINTER (new->link.ifindex)); + } + } { /* on enslave/release, we also refresh the master. */ int ifindex1 = 0, ifindex2 = 0; @@ -1964,7 +1923,22 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP if (ifindex2 > 0 && ifindex1 != ifindex2) delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_LINK, GINT_TO_POINTER (ifindex2)); } - + } + { + if ( ( (ops_type == NMP_CACHE_OPS_REMOVED) + || ( (ops_type == NMP_CACHE_OPS_UPDATED) + && new + && !new->_link.netlink.is_in_netlink)) + && old + && old->_link.netlink.is_in_netlink + && old->link.master) { + /* sometimes we receive a wrong RTM_DELLINK message when unslaving + * a device. Refetch the link again to check whether the device + * is really gone. + * + * https://bugzilla.redhat.com/show_bug.cgi?id=1285719#c2 */ + delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_LINK, GINT_TO_POINTER (old->link.ifindex)); + } } break; case NMP_OBJECT_TYPE_IP4_ADDRESS: @@ -2051,13 +2025,8 @@ do_request_link (NMPlatform *platform, int ifindex, const char *name, gboolean h _LOGt ("do_request_link (%d,%s)", ifindex, name ? name : ""); if (ifindex > 0) { - NMPObject *obj; - cache_prune_candidates_record_one (platform, (NMPObject *) nmp_cache_lookup_link (priv->cache, ifindex)); - obj = nmp_object_new_link (ifindex); - _LOGt ("delayed-deletion: protect object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0)); - g_hash_table_insert (priv->delayed_deletion, obj, NULL); } event_handler_read_netlink_all (platform, FALSE); @@ -2067,7 +2036,6 @@ do_request_link (NMPlatform *platform, int ifindex, const char *name, gboolean h event_handler_read_netlink_all (platform, TRUE); - cache_delayed_deletion_prune (platform); cache_prune_candidates_prune (platform); if (handle_delayed_action) @@ -2373,7 +2341,6 @@ static int event_notification (struct nl_msg *msg, gpointer user_data) { NMPlatform *platform = NM_PLATFORM (user_data); - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (user_data); auto_nl_object struct nl_object *nlo = NULL; auto_nmp_obj NMPObject *obj = NULL; struct nlmsghdr *msghdr; @@ -2416,31 +2383,12 @@ event_notification (struct nl_msg *msg, gpointer user_data) switch (msghdr->nlmsg_type) { case RTM_NEWLINK: - if (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK) { - if (g_hash_table_lookup (priv->delayed_deletion, obj) != NULL) { - /* the object is scheduled for delayed deletion. Replace that object - * by clearing the value from priv->delayed_deletion. */ - _LOGt ("delayed-deletion: clear delayed deletion of protected object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0)); - g_hash_table_insert (priv->delayed_deletion, nmp_object_ref (obj), NULL); - } - delayed_action_clear_REFRESH_LINK (platform, obj->link.ifindex); - } - /* fall-through */ case RTM_NEWADDR: case RTM_NEWROUTE: cache_update_netlink (platform, obj, &obj_cache, NULL, NM_PLATFORM_REASON_EXTERNAL); break; case RTM_DELLINK: - if ( NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK - && g_hash_table_contains (priv->delayed_deletion, obj)) { - /* We sometimes receive spurious RTM_DELLINK events. In this case, we want to delay - * the deletion of the object until later. */ - _LOGt ("delayed-deletion: delay deletion of protected object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0)); - g_hash_table_insert (priv->delayed_deletion, nmp_object_ref (obj), nmp_object_ref (obj)); - break; - } - /* fall-through */ case RTM_DELADDR: case RTM_DELROUTE: cache_remove_netlink (platform, obj, &obj_cache, NULL, NM_PLATFORM_REASON_EXTERNAL); @@ -4636,11 +4584,16 @@ event_handler_read_netlink_one (NMPlatform *platform) NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); int nle; + errno = 0; nle = nl_recvmsgs_default (priv->nlh_event); /* Work around a libnl bug fixed in 3.2.22 (375a6294) */ - if (nle == 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) + if (nle == 0 && errno == EAGAIN) { + /* EAGAIN is equal to EWOULDBLOCK. If it would not be, we'd have to + * workaround libnl3 mapping EWOULDBLOCK to -NLE_FAILURE. */ + G_STATIC_ASSERT (EAGAIN == EWOULDBLOCK); nle = -NLE_AGAIN; + } if (nle < 0) switch (nle) { @@ -4883,10 +4836,6 @@ nm_linux_platform_init (NMLinuxPlatform *self) self->priv = priv; - priv->delayed_deletion = g_hash_table_new_full ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal, - (GDestroyNotify) nmp_object_unref, - (GDestroyNotify) nmp_object_unref); priv->cache = nmp_cache_new (); priv->delayed_action.list_master_connected = g_ptr_array_new (); priv->delayed_action.list_refresh_link = g_ptr_array_new (); @@ -4989,7 +4938,6 @@ dispose (GObject *object) nm_clear_g_source (&priv->delayed_action.idle_id); g_clear_pointer (&priv->prune_candidates, g_hash_table_unref); - g_clear_pointer (&priv->delayed_deletion, g_hash_table_unref); G_OBJECT_CLASS (nm_linux_platform_parent_class)->dispose (object); } diff --git a/src/platform/tests/Makefile.am b/src/platform/tests/Makefile.am index 35aa098a..085f56ca 100644 --- a/src/platform/tests/Makefile.am +++ b/src/platform/tests/Makefile.am @@ -31,9 +31,7 @@ PLATFORM_LDADD = \ @GNOME_CODE_COVERAGE_RULES@ noinst_PROGRAMS = \ - dump \ monitor \ - platform \ test-link-fake \ test-link-linux \ test-address-fake \ @@ -50,12 +48,6 @@ EXTRA_DIST = test-common.h monitor_SOURCES = monitor.c $(PLATFORM_SOURCES) monitor_LDADD = $(PLATFORM_LDADD) -dump_SOURCES = dump.c $(PLATFORM_SOURCES) -dump_LDADD = $(PLATFORM_LDADD) - -platform_SOURCES = platform.c $(PLATFORM_SOURCES) -platform_LDADD = $(PLATFORM_LDADD) - test_link_fake_SOURCES = test-link.c $(TEST_SOURCES) test_link_fake_CPPFLAGS = \ $(AM_CPPFLAGS) \ diff --git a/src/platform/tests/Makefile.in b/src/platform/tests/Makefile.in index f45f3a9c..e21a3bb6 100644 --- a/src/platform/tests/Makefile.in +++ b/src/platform/tests/Makefile.in @@ -89,12 +89,12 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @REQUIRE_ROOT_TESTS_TRUE@am__append_1 = -DREQUIRE_ROOT_TESTS=1 -noinst_PROGRAMS = dump$(EXEEXT) monitor$(EXEEXT) platform$(EXEEXT) \ - test-link-fake$(EXEEXT) test-link-linux$(EXEEXT) \ - test-address-fake$(EXEEXT) test-address-linux$(EXEEXT) \ - test-general$(EXEEXT) test-nmp-object$(EXEEXT) \ - test-route-fake$(EXEEXT) test-route-linux$(EXEEXT) \ - test-cleanup-fake$(EXEEXT) test-cleanup-linux$(EXEEXT) +noinst_PROGRAMS = monitor$(EXEEXT) test-link-fake$(EXEEXT) \ + test-link-linux$(EXEEXT) test-address-fake$(EXEEXT) \ + test-address-linux$(EXEEXT) test-general$(EXEEXT) \ + test-nmp-object$(EXEEXT) test-route-fake$(EXEEXT) \ + test-route-linux$(EXEEXT) test-cleanup-fake$(EXEEXT) \ + test-cleanup-linux$(EXEEXT) TESTS = test-address-fake$(EXEEXT) test-address-linux$(EXEEXT) \ test-cleanup-fake$(EXEEXT) test-cleanup-linux$(EXEEXT) \ test-general$(EXEEXT) test-link-fake$(EXEEXT) \ @@ -125,19 +125,13 @@ CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am__objects_1 = nm-platform.$(OBJEXT) nm-fake-platform.$(OBJEXT) \ nm-linux-platform.$(OBJEXT) -am_dump_OBJECTS = dump.$(OBJEXT) $(am__objects_1) -dump_OBJECTS = $(am_dump_OBJECTS) -dump_DEPENDENCIES = $(PLATFORM_LDADD) +am_monitor_OBJECTS = monitor.$(OBJEXT) $(am__objects_1) +monitor_OBJECTS = $(am_monitor_OBJECTS) +monitor_DEPENDENCIES = $(PLATFORM_LDADD) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -am_monitor_OBJECTS = monitor.$(OBJEXT) $(am__objects_1) -monitor_OBJECTS = $(am_monitor_OBJECTS) -monitor_DEPENDENCIES = $(PLATFORM_LDADD) -am_platform_OBJECTS = platform.$(OBJEXT) $(am__objects_1) -platform_OBJECTS = $(am_platform_OBJECTS) -platform_DEPENDENCIES = $(PLATFORM_LDADD) am__objects_2 = test_address_fake-nm-platform.$(OBJEXT) \ test_address_fake-nm-fake-platform.$(OBJEXT) \ test_address_fake-nm-linux-platform.$(OBJEXT) @@ -251,18 +245,18 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(dump_SOURCES) $(monitor_SOURCES) $(platform_SOURCES) \ - $(test_address_fake_SOURCES) $(test_address_linux_SOURCES) \ - $(test_cleanup_fake_SOURCES) $(test_cleanup_linux_SOURCES) \ - $(test_general_SOURCES) $(test_link_fake_SOURCES) \ - $(test_link_linux_SOURCES) $(test_nmp_object_SOURCES) \ - $(test_route_fake_SOURCES) $(test_route_linux_SOURCES) -DIST_SOURCES = $(dump_SOURCES) $(monitor_SOURCES) $(platform_SOURCES) \ - $(test_address_fake_SOURCES) $(test_address_linux_SOURCES) \ - $(test_cleanup_fake_SOURCES) $(test_cleanup_linux_SOURCES) \ - $(test_general_SOURCES) $(test_link_fake_SOURCES) \ - $(test_link_linux_SOURCES) $(test_nmp_object_SOURCES) \ - $(test_route_fake_SOURCES) $(test_route_linux_SOURCES) +SOURCES = $(monitor_SOURCES) $(test_address_fake_SOURCES) \ + $(test_address_linux_SOURCES) $(test_cleanup_fake_SOURCES) \ + $(test_cleanup_linux_SOURCES) $(test_general_SOURCES) \ + $(test_link_fake_SOURCES) $(test_link_linux_SOURCES) \ + $(test_nmp_object_SOURCES) $(test_route_fake_SOURCES) \ + $(test_route_linux_SOURCES) +DIST_SOURCES = $(monitor_SOURCES) $(test_address_fake_SOURCES) \ + $(test_address_linux_SOURCES) $(test_cleanup_fake_SOURCES) \ + $(test_cleanup_linux_SOURCES) $(test_general_SOURCES) \ + $(test_link_fake_SOURCES) $(test_link_linux_SOURCES) \ + $(test_nmp_object_SOURCES) $(test_route_fake_SOURCES) \ + $(test_route_linux_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -779,10 +773,6 @@ PLATFORM_LDADD = \ EXTRA_DIST = test-common.h monitor_SOURCES = monitor.c $(PLATFORM_SOURCES) monitor_LDADD = $(PLATFORM_LDADD) -dump_SOURCES = dump.c $(PLATFORM_SOURCES) -dump_LDADD = $(PLATFORM_LDADD) -platform_SOURCES = platform.c $(PLATFORM_SOURCES) -platform_LDADD = $(PLATFORM_LDADD) test_link_fake_SOURCES = test-link.c $(TEST_SOURCES) test_link_fake_CPPFLAGS = \ $(AM_CPPFLAGS) \ @@ -894,18 +884,10 @@ clean-noinstPROGRAMS: echo " rm -f" $$list; \ rm -f $$list -dump$(EXEEXT): $(dump_OBJECTS) $(dump_DEPENDENCIES) $(EXTRA_dump_DEPENDENCIES) - @rm -f dump$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(dump_OBJECTS) $(dump_LDADD) $(LIBS) - monitor$(EXEEXT): $(monitor_OBJECTS) $(monitor_DEPENDENCIES) $(EXTRA_monitor_DEPENDENCIES) @rm -f monitor$(EXEEXT) $(AM_V_CCLD)$(LINK) $(monitor_OBJECTS) $(monitor_LDADD) $(LIBS) -platform$(EXEEXT): $(platform_OBJECTS) $(platform_DEPENDENCIES) $(EXTRA_platform_DEPENDENCIES) - @rm -f platform$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(platform_OBJECTS) $(platform_LDADD) $(LIBS) - test-address-fake$(EXEEXT): $(test_address_fake_OBJECTS) $(test_address_fake_DEPENDENCIES) $(EXTRA_test_address_fake_DEPENDENCIES) @rm -f test-address-fake$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_address_fake_OBJECTS) $(test_address_fake_LDADD) $(LIBS) @@ -952,12 +934,10 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-fake-platform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-linux-platform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-platform.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/platform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-general.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nmp-object.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_address_fake-nm-fake-platform.Po@am__quote@ diff --git a/src/platform/tests/dump.c b/src/platform/tests/dump.c deleted file mode 100644 index 54de1da7..00000000 --- a/src/platform/tests/dump.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <arpa/inet.h> - -#include "nm-platform.h" -#include "nm-linux-platform.h" -#include "nm-fake-platform.h" -#include "nm-macros-internal.h" - -static void -dump_interface (NMPlatformLink *link) -{ - GArray *ip6_addresses; - GArray *ip4_addresses; - const NMPlatformIP6Address *ip6_address; - const NMPlatformIP4Address *ip4_address; - GArray *ip6_routes; - GArray *ip4_routes; - const NMPlatformIP6Route *ip6_route; - const NMPlatformIP4Route *ip4_route; - char networkstr[INET6_ADDRSTRLEN]; - char gatewaystr[INET6_ADDRSTRLEN]; - int vlan_id, vlan_parent; - const char *address; - size_t addrlen; - int i; - - g_assert (NM_FLAGS_HAS (link->flags, IFF_UP) || !link->connected); - - printf ("%d: %s: %s", link->ifindex, link->name, nm_link_type_to_string (link->type)); - if (NM_FLAGS_HAS (link->flags, IFF_UP)) - printf (" %s", link->connected ? "CONNECTED" : "DISCONNECTED"); - else - printf (" DOWN"); - if (NM_FLAGS_HAS (link->flags, IFF_NOARP)) - printf (" noarp"); - if (link->master) - printf (" master %d", link->master); - if (link->parent) - printf (" parent %d", link->parent); - printf (" mtu %d", link->mtu); - printf ("\n"); - if (link->driver) - printf (" driver: %s\n", link->driver); - printf (" UDI: %s\n", nm_platform_link_get_udi (NM_PLATFORM_GET, link->ifindex)); - if (!nm_platform_vlan_get_info (NM_PLATFORM_GET, link->ifindex, &vlan_parent, &vlan_id)) - g_assert_not_reached (); - if (vlan_parent) - printf (" vlan parent %d id %d\n", vlan_parent, vlan_id); - - if (nm_platform_link_is_software (NM_PLATFORM_GET, link->ifindex)) - printf (" class software\n"); - if (nm_platform_link_supports_slaves (NM_PLATFORM_GET, link->ifindex)) - printf (" class supports-slaves\n"); - if (nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, link->ifindex)) - printf (" feature carrier-detect\n"); - if (nm_platform_link_supports_vlans (NM_PLATFORM_GET, link->ifindex)) - printf (" feature vlans\n"); - - address = nm_platform_link_get_address (NM_PLATFORM_GET, link->ifindex, &addrlen); - if (address) { - printf (" link-address "); - for (i = 0; i < addrlen; i++) - printf ("%s%02hhx", i ? ":" : "", address[i]); - printf ("\n"); - } - - ip4_addresses = nm_platform_ip4_address_get_all (NM_PLATFORM_GET, link->ifindex); - ip6_addresses = nm_platform_ip6_address_get_all (NM_PLATFORM_GET, link->ifindex); - - g_assert (ip4_addresses); - g_assert (ip6_addresses); - - for (i = 0; i < ip4_addresses->len; i++) { - ip4_address = &g_array_index (ip4_addresses, NMPlatformIP4Address, i); - printf (" ip4-address %s\n", nm_platform_ip4_address_to_string (ip4_address)); - } - - for (i = 0; i < ip6_addresses->len; i++) { - ip6_address = &g_array_index (ip6_addresses, NMPlatformIP6Address, i); - printf (" ip6-address %s\n", nm_platform_ip6_address_to_string (ip6_address)); - } - - g_array_unref (ip4_addresses); - g_array_unref (ip6_addresses); - - ip4_routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, link->ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); - ip6_routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, link->ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); - - g_assert (ip4_routes); - g_assert (ip6_routes); - - for (i = 0; i < ip4_routes->len; i++) { - ip4_route = &g_array_index (ip4_routes, NMPlatformIP4Route, i); - inet_ntop (AF_INET, &ip4_route->network, networkstr, sizeof (networkstr)); - inet_ntop (AF_INET, &ip4_route->gateway, gatewaystr, sizeof (gatewaystr)); - printf (" ip4-route %s/%d via %s\n", networkstr, ip4_route->plen, gatewaystr); - } - - for (i = 0; i < ip6_routes->len; i++) { - ip6_route = &g_array_index (ip6_routes, NMPlatformIP6Route, i); - inet_ntop (AF_INET6, &ip6_route->network, networkstr, sizeof (networkstr)); - inet_ntop (AF_INET6, &ip6_route->gateway, gatewaystr, sizeof (gatewaystr)); - printf (" ip6-route %s/%d via %s\n", networkstr, ip6_route->plen, gatewaystr); - } - - g_array_unref (ip4_routes); - g_array_unref (ip6_routes); -} - -static void -dump_all (void) -{ - GArray *links = nm_platform_link_get_all (NM_PLATFORM_GET); - int i; - - for (i = 0; i < links->len; i++) - dump_interface (&g_array_index (links, NMPlatformLink, i)); -} - -int -main (int argc, char **argv) -{ -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - - g_assert (argc <= 2); - if (argc > 1 && !g_strcmp0 (argv[1], "--fake")) - nm_fake_platform_setup (); - else - nm_linux_platform_setup (); - - dump_all (); - - return EXIT_SUCCESS; -} diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c index 9aff1047..f1058db8 100644 --- a/src/platform/tests/monitor.c +++ b/src/platform/tests/monitor.c @@ -3,10 +3,13 @@ #include <stdlib.h> #include <syslog.h> -#include "nm-fake-platform.h" #include "nm-linux-platform.h" #include "nm-logging.h" +#include "nm-test-utils.h" + +NMTST_DEFINE (); + int main (int argc, char **argv) { @@ -16,15 +19,16 @@ main (int argc, char **argv) g_type_init (); #endif + if (!g_getenv ("G_MESSAGES_DEBUG")) + g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); + + nmtst_init_with_logging (&argc, &argv, "DEBUG", "ALL"); + + nm_log_info (LOGD_PLATFORM, "platform monitor start"); + loop = g_main_loop_new (NULL, FALSE); - nm_logging_setup ("debug", NULL, NULL, NULL); - openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR, LOG_DAEMON); - - g_assert (argc <= 2); - if (argc > 1 && !g_strcmp0 (argv[1], "--fake")) - nm_fake_platform_setup (); - else - nm_linux_platform_setup (); + + nm_linux_platform_setup (); g_main_loop_run (loop); diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c deleted file mode 100644 index 24e828c1..00000000 --- a/src/platform/tests/platform.c +++ /dev/null @@ -1,902 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-platform.c - Handle runtime kernel networking configuration - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2013 Red Hat, Inc. - */ - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <arpa/inet.h> -#include <netlink/route/addr.h> - -#include "gsystem-local-alloc.h" -#include "nm-platform.h" -#include "nm-linux-platform.h" -#include "nm-fake-platform.h" - -#define error(...) fprintf (stderr, __VA_ARGS__) - -typedef gboolean boolean_t; -typedef int decimal_t; -typedef const char *string_t; - -#define print_boolean(value) printf ("%s\n", value ? "yes" : "no") -#define print_decimal(value) printf ("%d\n", value) -#define print_string(value) printf ("%s\n", value) - -static gboolean -do_sysctl_set (char **argv) -{ - return nm_platform_sysctl_set (NM_PLATFORM_GET, argv[0], argv[1]); -} - -static gboolean -do_sysctl_get (char **argv) -{ - gs_free char *value = nm_platform_sysctl_get (NM_PLATFORM_GET, argv[0]); - - printf ("%s\n", value); - - return !!value; -} - -static int -parse_ifindex (const char *str) -{ - char *endptr; - int ifindex = 0; - - ifindex = strtol (str, &endptr, 10); - - if (*endptr) { - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, str); - } - - return ifindex; -} - -static gboolean -do_link_get_all (char **argv) -{ - GArray *links; - NMPlatformLink *device; - int i; - - links = nm_platform_link_get_all (NM_PLATFORM_GET); - for (i = 0; i < links->len; i++) { - device = &g_array_index (links, NMPlatformLink, i); - - printf ("%d: %s type %d\n", device->ifindex, device->name, device->type); - } - g_array_unref (links); - - return TRUE; -} - -static gboolean -do_dummy_add (char **argv) -{ - return nm_platform_dummy_add (NM_PLATFORM_GET, argv[0], NULL) == NM_PLATFORM_ERROR_SUCCESS; -} - -static gboolean -do_bridge_add (char **argv) -{ - return nm_platform_bridge_add (NM_PLATFORM_GET, argv[0], NULL, 0, NULL) == NM_PLATFORM_ERROR_SUCCESS; -} - -static gboolean -do_bond_add (char **argv) -{ - return nm_platform_bond_add (NM_PLATFORM_GET, argv[0], NULL) == NM_PLATFORM_ERROR_SUCCESS; -} - -static gboolean -do_team_add (char **argv) -{ - return nm_platform_team_add (NM_PLATFORM_GET, argv[0], NULL) == NM_PLATFORM_ERROR_SUCCESS; -} - -static gboolean -do_vlan_add (char **argv) -{ - const char *name = *argv++; - int parent = parse_ifindex (*argv++); - int vlanid = strtol (*argv++, NULL, 10); - guint32 vlan_flags = strtol (*argv++, NULL, 10); - - return nm_platform_vlan_add (NM_PLATFORM_GET, name, parent, vlanid, vlan_flags, NULL) == NM_PLATFORM_ERROR_SUCCESS; -} - -static gboolean -do_link_exists (char **argv) -{ - gboolean value = !!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, argv[0]); - - print_boolean (value); - - return TRUE; -} - -#define LINK_CMD(cmdname) \ - static gboolean \ - do_link_##cmdname (char **argv) \ - { \ - int ifindex = parse_ifindex (argv[0]); \ - return ifindex ? nm_platform_link_##cmdname (NM_PLATFORM_GET, ifindex) : FALSE; \ - } - -#define LINK_CMD_GET_FULL(cmdname, type, cond) \ - static gboolean \ - do_link_##cmdname (char **argv) \ - { \ - int ifindex = parse_ifindex (argv[0]); \ - if (ifindex) { \ - type##_t value = nm_platform_link_##cmdname (NM_PLATFORM_GET, ifindex); \ - if (cond) { \ - print_##type (value); \ - return TRUE; \ - } \ - } \ - return FALSE; \ - } -#define LINK_CMD_GET(cmdname, type) LINK_CMD_GET_FULL (cmdname, type, TRUE); - -LINK_CMD (delete) - -/* do_link_delete_by_ifname: - * - * We don't need this as we allow ifname instead of ifindex anyway. - */ - -static gboolean -do_link_get_ifindex (char **argv) -{ - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, argv[0]); - - if (ifindex) - printf ("%d\n", ifindex); - - return !!ifindex; -} - -LINK_CMD_GET_FULL (get_name, string, value) -LINK_CMD_GET_FULL (get_type, decimal, value > 0) -LINK_CMD_GET (is_software, boolean) -LINK_CMD_GET (supports_slaves, boolean) - -static gboolean -do_link_set_up (char **argv) -{ - int ifindex = parse_ifindex (argv[0]); - - return ifindex ? nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL) : FALSE; -} - -LINK_CMD (set_down) -LINK_CMD (set_arp) -LINK_CMD (set_noarp) -LINK_CMD_GET (is_up, boolean) -LINK_CMD_GET (is_connected, boolean) -LINK_CMD_GET (uses_arp, boolean) - -static gboolean -do_link_set_address (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - char *hex = *argv++; - int hexlen = strlen (hex); - char address[hexlen/2]; - char *endptr; - int i; - - g_assert (!(hexlen % 2)); - - for (i = 0; i < sizeof (address); i++) { - char digit[3]; - - digit[0] = hex[2*i]; - digit[1] = hex[2*i+1]; - digit[2] = '\0'; - - address[i] = strtoul (digit, &endptr, 16); - g_assert (!*endptr); - } - - return nm_platform_link_set_address (NM_PLATFORM_GET, ifindex, address, sizeof (address)); -} - -static gboolean -do_link_get_address (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - const char *address; - size_t length; - int i; - - address = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &length); - - if (!address || length <= 0) - return FALSE; - - for (i = 0; i < length; i++) - printf ("%02x", address[i]); - printf ("\n"); - - return TRUE; -} - -static gboolean -do_link_set_mtu (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - int mtu = strtoul (*argv++, NULL, 10); - - return nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, mtu); -} - -LINK_CMD_GET (get_mtu, decimal); -LINK_CMD_GET (supports_carrier_detect, boolean) -LINK_CMD_GET (supports_vlans, boolean) - -static gboolean -do_link_enslave (char **argv) -{ - int master = parse_ifindex (*argv++); - int slave = parse_ifindex (*argv++); - - return nm_platform_link_enslave (NM_PLATFORM_GET, master, slave); -} - -static gboolean -do_link_release (char **argv) -{ - int master = parse_ifindex (*argv++); - int slave = parse_ifindex (*argv++); - - return nm_platform_link_release (NM_PLATFORM_GET, master, slave); -} - -LINK_CMD_GET (get_master, decimal) - -static gboolean -do_master_set_option (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - const char *option = *argv++; - const char *value = *argv++; - - return nm_platform_master_set_option (NM_PLATFORM_GET, ifindex, option, value); -} - -static gboolean -do_master_get_option (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - const char *option = *argv++; - gs_free char *value = nm_platform_master_get_option (NM_PLATFORM_GET, ifindex, option); - - printf ("%s\n", value); - - return !!value; -} - -static gboolean -do_slave_set_option (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - const char *option = *argv++; - const char *value = *argv++; - - return nm_platform_slave_set_option (NM_PLATFORM_GET, ifindex, option, value); -} - -static gboolean -do_slave_get_option (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - const char *option = *argv++; - gs_free char *value = nm_platform_slave_get_option (NM_PLATFORM_GET, ifindex, option); - - printf ("%s\n", value); - - return !!value; -} - -static gboolean -do_vlan_get_info (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - int parent; - int vlanid; - - if (!nm_platform_vlan_get_info (NM_PLATFORM_GET, ifindex, &parent, &vlanid)) - return FALSE; - - printf ("%d %d\n", parent, vlanid); - - return TRUE; -} - -static gboolean -do_vlan_set_ingress_map (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - int from = strtol (*argv++, NULL, 10); - int to = strtol (*argv++, NULL, 10); - - return nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, from, to); -} - -static gboolean -do_vlan_set_egress_map (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - int from = strtol (*argv++, NULL, 10); - int to = strtol (*argv++, NULL, 10); - - return nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, from, to); -} - -static gboolean -do_veth_get_properties (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - NMPlatformVethProperties props; - - if (!nm_platform_veth_get_properties (NM_PLATFORM_GET, ifindex, &props)) - return FALSE; - - printf ("peer: %d\n", props.peer); - - return TRUE; -} - -static gboolean -do_tun_get_properties (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - NMPlatformTunProperties props; - - if (!nm_platform_tun_get_properties (NM_PLATFORM_GET, ifindex, &props)) - return FALSE; - - printf ("mode: %s\n", props.mode); - if (props.owner == -1) - printf ("owner: none\n"); - else - printf ("owner: %lu\n", (gulong) props.owner); - if (props.group == -1) - printf ("group: none\n"); - else - printf ("group: %lu\n", (gulong) props.group); - printf ("no-pi: "); - print_boolean (props.no_pi); - printf ("vnet-hdr: "); - print_boolean (props.vnet_hdr); - printf ("multi-queue: "); - print_boolean (props.multi_queue); - - return TRUE; -} - -static gboolean -do_macvlan_get_properties (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - NMPlatformMacvlanProperties props; - - if (!nm_platform_macvlan_get_properties (NM_PLATFORM_GET, ifindex, &props)) - return FALSE; - - printf ("parent: %d\n", props.parent_ifindex); - printf ("mode: %s\n", props.mode); - printf ("no-promisc: "); - print_boolean (props.no_promisc); - return TRUE; -} - -static gboolean -do_vxlan_get_properties (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - NMPlatformVxlanProperties props; - char addrstr[INET6_ADDRSTRLEN]; - - if (!nm_platform_vxlan_get_properties (NM_PLATFORM_GET, ifindex, &props)) - return FALSE; - - printf ("parent-ifindex: %u\n", props.parent_ifindex); - printf ("id: %u\n", props.id); - if (props.group) - inet_ntop (AF_INET, &props.group, addrstr, sizeof (addrstr)); - else if (props.group6.s6_addr[0]) - inet_ntop (AF_INET6, &props.group6, addrstr, sizeof (addrstr)); - else - strcpy (addrstr, "-"); - printf ("group: %s\n", addrstr); - if (props.local) - inet_ntop (AF_INET, &props.local, addrstr, sizeof (addrstr)); - else if (props.local6.s6_addr[0]) - inet_ntop (AF_INET6, &props.local6, addrstr, sizeof (addrstr)); - else - strcpy (addrstr, "-"); - printf ("local: %s\n", addrstr); - printf ("tos: %u\n", props.tos); - printf ("ttl: %u\n", props.ttl); - printf ("learning: "); - print_boolean (props.learning); - printf ("ageing: %u\n", props.ageing); - printf ("limit: %u\n", props.limit); - printf ("dst-port: %u\n", props.dst_port); - printf ("src-port-min: %u\n", props.src_port_min); - printf ("src-port-max: %u\n", props.src_port_max); - printf ("proxy: "); - print_boolean (props.proxy); - printf ("rsc: "); - print_boolean (props.rsc); - printf ("l2miss: "); - print_boolean (props.l2miss); - printf ("l3miss: "); - print_boolean (props.l3miss); - - return TRUE; -} - -static gboolean -do_gre_get_properties (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - NMPlatformGreProperties props; - char addrstr[INET_ADDRSTRLEN]; - - if (!nm_platform_gre_get_properties (NM_PLATFORM_GET, ifindex, &props)) - return FALSE; - - printf ("parent-ifindex: %u\n", props.parent_ifindex); - printf ("input-flags: %u\n", props.input_flags); - printf ("output-flags: %u\n", props.input_flags); - printf ("input-key: %u\n", props.input_key); - printf ("output-key: %u\n", props.output_key); - if (props.local) - inet_ntop (AF_INET, &props.local, addrstr, sizeof (addrstr)); - else - strcpy (addrstr, "-"); - printf ("local: %s\n", addrstr); - if (props.remote) - inet_ntop (AF_INET, &props.remote, addrstr, sizeof (addrstr)); - else - strcpy (addrstr, "-"); - printf ("remote: %s\n", addrstr); - printf ("ttl: %u\n", props.ttl); - printf ("tos: %u\n", props.tos); - printf ("path-mtu-discovery: "); - print_boolean (props.path_mtu_discovery); - - return TRUE; -} - -static gboolean -do_ip4_address_get_all (char **argv) -{ - int ifindex = parse_ifindex (argv[0]); - GArray *addresses; - NMPlatformIP4Address *address; - char addrstr[INET_ADDRSTRLEN]; - int i; - - if (ifindex) { - addresses = nm_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex); - for (i = 0; i < addresses->len; i++) { - address = &g_array_index (addresses, NMPlatformIP4Address, i); - inet_ntop (AF_INET, &address->address, addrstr, sizeof (addrstr)); - printf ("%s/%d\n", addrstr, address->plen); - } - g_array_unref (addresses); - } - - return !!ifindex; -} - -static gboolean -do_ip6_address_get_all (char **argv) -{ - int ifindex = parse_ifindex (argv[0]); - GArray *addresses; - NMPlatformIP6Address *address; - char addrstr[INET6_ADDRSTRLEN]; - int i; - - if (ifindex) { - addresses = nm_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex); - for (i = 0; i < addresses->len; i++) { - address = &g_array_index (addresses, NMPlatformIP6Address, i); - inet_ntop (AF_INET6, &address->address, addrstr, sizeof (addrstr)); - printf ("%s/%d\n", addrstr, address->plen); - } - g_array_unref (addresses); - } - - return !!ifindex; -} - -static gboolean -parse_ip_address (int family, char *str, gpointer address, int *plen) -{ - char *endptr; - - if (plen) - *plen = 0; - - if (plen) { - char *ptr = strchr (str, '/'); - if (ptr) { - *ptr++ = '\0'; - *plen = strtol (ptr, &endptr, 10); - if (*endptr) - ptr = NULL; - } - if (!ptr) { - error ("Bad format of IP address, expected address/plen.\n"); - return FALSE; - } - } - - if (inet_pton (family, str, address)) - return TRUE; - - error ("Bad format of IP address, expected address%s.\n", plen ? "/plen" : ""); - return FALSE; -} - -typedef in_addr_t ip4_t; -typedef struct in6_addr ip6_t; - -#define parse_ip4_address(s, a, p) parse_ip_address (AF_INET, s, a, p) -#define parse_ip6_address(s, a, p) parse_ip_address (AF_INET6, s, a, p) - -static gboolean -do_ip4_address_add (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - ip4_t address; - int plen; - - if (ifindex && parse_ip4_address (*argv++, &address, &plen)) { - guint32 lifetime = strtol (*argv++, NULL, 10); - guint32 preferred = strtol (*argv++, NULL, 10); - - gboolean value = nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, address, 0, plen, lifetime, preferred, NULL); - return value; - } else - return FALSE; -} - -static gboolean -do_ip6_address_add (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - ip6_t address; - int plen; - - if (ifindex && parse_ip6_address (*argv++, &address, &plen)) { - guint32 lifetime = strtol (*argv++, NULL, 10); - guint32 preferred = strtol (*argv++, NULL, 10); - guint flags = (*argv) ? rtnl_addr_str2flags (*argv++) : 0; - - gboolean value = nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, address, in6addr_any, plen, lifetime, preferred, flags); - return value; - } else - return FALSE; -} - -#define ADDR_CMD_FULL(v, cmdname, print, ...) \ - static gboolean \ - do_##v##_address_##cmdname (char **argv) \ - { \ - int ifindex = parse_ifindex (*argv++); \ - v##_t address; \ - int plen; \ - if (ifindex && parse_##v##_address (*argv++, &address, &plen)) { \ - gboolean value = !!nm_platform_##v##_address_##cmdname (NM_PLATFORM_GET, ifindex, address, plen, ##__VA_ARGS__); \ - if (print) { \ - print_boolean (value); \ - return TRUE; \ - } else \ - return value; \ - } else \ - return FALSE; \ - } -#define ADDR_CMD(cmdname) ADDR_CMD_FULL (ip4, cmdname, FALSE, 0) ADDR_CMD_FULL (ip6, cmdname, FALSE) -#define ADDR_CMD_PRINT(cmdname) ADDR_CMD_FULL (ip4, cmdname, TRUE) ADDR_CMD_FULL (ip6, cmdname, TRUE) - -ADDR_CMD (delete) -ADDR_CMD_PRINT (get) - -static gboolean -do_ip4_route_get_all (char **argv) -{ - int ifindex = parse_ifindex (argv[0]); - GArray *routes; - NMPlatformIP4Route *route; - char networkstr[INET_ADDRSTRLEN], gatewaystr[INET_ADDRSTRLEN]; - int i; - - if (ifindex) { - routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); - for (i = 0; i < routes->len; i++) { - route = &g_array_index (routes, NMPlatformIP4Route, i); - inet_ntop (AF_INET, &route->network, networkstr, sizeof (networkstr)); - inet_ntop (AF_INET, &route->gateway, gatewaystr, sizeof (gatewaystr)); - printf ("%s/%d via %s metric %d\n", - networkstr, route->plen, gatewaystr, route->metric); - } - g_array_unref (routes); - } - - return !!ifindex; -} - -static gboolean -do_ip6_route_get_all (char **argv) -{ - int ifindex = parse_ifindex (argv[0]); - GArray *routes; - NMPlatformIP6Route *route; - char networkstr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN]; - int i; - - if (ifindex) { - routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); - for (i = 0; i < routes->len; i++) { - route = &g_array_index (routes, NMPlatformIP6Route, i); - inet_ntop (AF_INET6, &route->network, networkstr, sizeof (networkstr)); - inet_ntop (AF_INET6, &route->gateway, gatewaystr, sizeof (gatewaystr)); - printf ("%s/%d via %s metric %d\n", - networkstr, route->plen, gatewaystr, route->metric); - } - g_array_unref (routes); - } - - return !!ifindex; -} - -static gboolean -do_ip4_route_add (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - in_addr_t network, gateway; - int plen, metric, mss; - - parse_ip4_address (*argv++, &network, &plen); - parse_ip4_address (*argv++, &gateway, NULL); - metric = strtol (*argv++, NULL, 10); - mss = strtol (*argv++, NULL, 10); - - return nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, - network, plen, gateway, 0, - metric, mss); -} - -static gboolean -do_ip6_route_add (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - struct in6_addr network, gateway; - int plen, metric, mss; - - parse_ip6_address (*argv++, &network, &plen); - parse_ip6_address (*argv++, &gateway, NULL); - metric = strtol (*argv++, NULL, 10); - mss = strtol (*argv++, NULL, 10); - return nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, - network, plen, gateway, - metric, mss); -} - -static gboolean -do_ip4_route_delete (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - in_addr_t network; - int plen, metric; - - parse_ip4_address (*argv++, &network, &plen); - metric = strtol (*argv++, NULL, 10); - - return nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric); -} - -static gboolean -do_ip6_route_delete (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - struct in6_addr network; - int plen, metric; - - parse_ip6_address (*argv++, &network, &plen); - metric = strtol (*argv++, NULL, 10); - - return nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric); -} - -static gboolean -do_ip4_route_get (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - in_addr_t network; - int plen, metric; - - parse_ip4_address (*argv++, &network, &plen); - metric = strtol (*argv++, NULL, 10); - - print_boolean (!!nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric)); - return TRUE; -} - -static gboolean -do_ip6_route_get (char **argv) -{ - int ifindex = parse_ifindex (*argv++); - struct in6_addr network; - int plen, metric; - - parse_ip6_address (*argv++, &network, &plen); - metric = strtol (*argv++, NULL, 10); - - print_boolean (!!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric)); - return TRUE; -} - -typedef struct { - const char *name; - const char *help; - int (*handler) (char **argv); - int argc; - const char *arghelp; -} command_t; - -static const command_t commands[] = { - { "sysctl-set", "get /proc/sys or /sys value", do_sysctl_set, 2, "<path> <value>" }, - { "sysctl-get", "get /proc/sys or /sys value", do_sysctl_get, 1, "<value>" }, - { "link-get-all", "print all links", do_link_get_all, 0, "" }, - { "dummy-add", "add dummy interface", do_dummy_add, 1, "<ifname>" }, - { "bridge-add", "add bridge interface", do_bridge_add, 1, "<ifname>" }, - { "bond-add", "add bond interface", do_bond_add, 1, "<ifname>" }, - { "team-add", "add team interface", do_team_add, 1, "<ifname>" }, - { "vlan-add", "add vlan interface", do_vlan_add, 4, "<ifname> <parent> <vlanid> <vlanflags>" }, - { "link-exists", "check ifname for existance", do_link_exists, 1, "<ifname>" }, - { "link-delete", "delete interface", do_link_delete, 1, "<ifname/ifindex>" }, - { "link-get-ifindex>", "get interface index", do_link_get_ifindex, 1, "<ifname>" }, - { "link-get-name", "get interface name", do_link_get_name, 1, "<ifindex>" }, - { "link-get-type", "get interface type", do_link_get_type, 1, "<ifname/ifindex>" }, - { "link-is-software", "check if interface is a software one", do_link_is_software, 1, "<ifname/ifindex>" }, - { "link-supports-slaves", "check if interface supports slaves", do_link_supports_slaves, 1, "<ifname/ifindex>" }, - { "link-set-up", "set interface up", do_link_set_up, 1, "<ifname/ifindex>" }, - { "link-set-down", "set interface down", do_link_set_down, 1, "<ifname/ifindex>" }, - { "link-set-arp", "activate interface arp", do_link_set_arp, 1, "<ifname/ifindex>" }, - { "link-set-noarp", "deactivate interface arp", do_link_set_noarp, 1, "<ifname/ifindex>" }, - { "link-is-up", "check if interface is up", do_link_is_up, 1, "<ifname/ifindex>" }, - { "link-is-connected", "check interface carrier", do_link_is_connected, 1, "<ifname/ifindex>" }, - { "link-uses-arp", "check whether interface uses arp", do_link_uses_arp, 1, "<ifname/ifindex>" }, - { "link-get-address", "print link address", do_link_get_address, 1, "<ifname/ifindex>" }, - { "link-set-address", "set link address", do_link_set_address, 2, "<ifname/ifindex> <hex>" }, - { "link-get-mtu", "print link mtu", do_link_get_mtu, 1, "<ifname/ifindex>" }, - { "link-set-mtu", "set link mtu", do_link_set_mtu, 2, "<ifname/ifindex> <mtu>" }, - { "link-supports-carrier-detect", "check whether interface supports carrier detect", - do_link_supports_carrier_detect, 1, "<ifname/ifindex>" }, - { "link-supports-vlans", "check whether interface supports VLANs", - do_link_supports_vlans, 1, "<ifname/ifindex>" }, - { "link-enslave", "enslave slave interface with master", do_link_enslave, 2, "<master> <slave>" }, - { "link-release", "release save interface from master", do_link_release, 2, "<master> <slave>" }, - { "link-get-master", "print master interface of a slave", do_link_get_master, 1, "<ifname/ifindex>" }, - { "link-master-set-option", "set master option", do_master_set_option, 3, - "<ifname/ifindex> <option> <value>" }, - { "link-master-get-option", "get master option", do_master_get_option, 2, - "<ifname/ifindex> <option>" }, - { "link-slave-set-option", "set slave option", do_slave_set_option, 3, - "<ifname/ifindex> <option>" }, - { "link-slave-get-option", "get slave option", do_slave_get_option, 2, - "<ifname/ifindex> <option>" }, - { "vlan-get-info", "get vlan info", do_vlan_get_info, 1, "<ifname/ifindex>" }, - { "vlan-set-ingress-map", "set vlan ingress map", do_vlan_set_ingress_map, 3, - "<ifname/ifindex> <from> <to>" }, - { "vlan-set-egress-map", "set vlan egress map", do_vlan_set_egress_map, 3, - "<ifname/ifindex> <from> <to>" }, - { "veth-get-properties", "get veth properties", do_veth_get_properties, 1, - "<ifname/ifindex>" }, - { "tun-get-properties", "get tun/tap properties", do_tun_get_properties, 1, - "<ifname/ifindex>" }, - { "macvlan-get-properties", "get macvlan properties", do_macvlan_get_properties, 1, - "<ifname/ifindex>" }, - { "vxlan-get-properties", "get vxlan properties", do_vxlan_get_properties, 1, - "<ifname/ifindex>" }, - { "gre-get-properties", "get gre properties", do_gre_get_properties, 1, - "<ifname/ifindex>" }, - { "ip4-address-get-all", "print all IPv4 addresses", do_ip4_address_get_all, 1, "<ifname/ifindex>" }, - { "ip6-address-get-all", "print all IPv6 addresses", do_ip6_address_get_all, 1, "<ifname/ifindex>" }, - { "ip4-address-add", "add IPv4 address", do_ip4_address_add, 4, "<ifname/ifindex> <address>/<plen> <lifetime> <>" }, - { "ip6-address-add", "add IPv6 address", do_ip6_address_add, 4, "<ifname/ifindex> <address>/<plen> <lifetime> [<flags>] <>" }, - { "ip4-address-delete", "delete IPv4 address", do_ip4_address_delete, 2, - "<ifname/ifindex> <address>/<plen>" }, - { "ip6-address-delete", "delete IPv6 address", do_ip6_address_delete, 2, - "<ifname/ifindex> <address>/<plen>" }, - { "ip4-address-exists", "check for existence of IPv4 address", do_ip4_address_get, 2, - "<ifname/ifindex> <address>/<plen>" }, - { "ip6-address-exists", "check for existence of IPv6 address", do_ip6_address_get, 2, - "<ifname/ifindex> <address>/<plen>" }, - { "ip4-route-get-all", "print all IPv4 routes", do_ip4_route_get_all, 1, "<ifname/ifindex>" }, - { "ip6-route-get-all", "print all IPv6 routes", do_ip6_route_get_all, 1, "<ifname/ifindex>" }, - { "ip4-route-add", "add IPv4 route", do_ip4_route_add, 5, - "<ifname/ifindex> <network>/<plen> <gateway> <metric> <mss>" }, - { "ip6-route-add", "add IPv6 route", do_ip6_route_add, 5, - "<ifname/ifindex> <network>/<plen> <gateway> <metric> <mss>" }, - { "ip4-route-delete", "delete IPv4 route", do_ip4_route_delete, 3, - "<ifname/ifindex> <network>/<plen> <metric>" }, - { "ip6-route-delete", "delete IPv6 route", do_ip6_route_delete, 3, - "<ifname/ifindex> <network>/<plen> <metric>" }, - { "ip4-route-exists", "check for existence of IPv4 route", do_ip4_route_get, 3, - "<ifname/ifindex> <network>/<plen> <metric>" }, - { "ip6-route-exists", "check for existence of IPv6 route", do_ip6_route_get, 3, - "<ifname/ifindex> <network>/<plen> <metric>" }, - { NULL, NULL, NULL, 0, NULL }, -}; - -int -main (int argc, char **argv) -{ - const char *arg0 = *argv++; - const command_t *command = NULL; - gboolean status = TRUE; - -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - - if (*argv && !g_strcmp0 (argv[1], "--fake")) { - nm_fake_platform_setup (); - } else - nm_linux_platform_setup (); - - if (*argv) - for (command = commands; command->name; command++) - if (g_str_has_prefix (command->name, *argv)) - break; - - if (command && command->name) { - argv++; - if (g_strv_length (argv) == command->argc) - status = command->handler (argv); - else { - error ("Wrong number of arguments to '%s' (expected %d).\n\nUsage: %s %s %s\n-- %s\n", - command->name, command->argc, - arg0, command->name, command->arghelp, command->help); - return EXIT_FAILURE; - } - } else { - error ("Usage: %s COMMAND\n\n", arg0); - error ("COMMAND\n"); - for (command = commands; command->name; command++) - error (" %s %s\n -- %s\n", command->name, command->arghelp, command->help); - error ("\n"); - } - - return EXIT_SUCCESS; -} diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index f9645d85..47cbcec1 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -274,10 +274,14 @@ test_slave (int master, int type, SignalData *master_changed) } /* Release */ + ensure_no_signal (link_added); ensure_no_signal (link_changed); + ensure_no_signal (link_removed); g_assert (nm_platform_link_release (NM_PLATFORM_GET, master, ifindex)); g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, 0); + accept_signals (link_added, 0, 1); accept_signals (link_changed, 1, 3); + accept_signals (link_removed, 0, 1); accept_signals (master_changed, 1, 2); ensure_no_signal (master_changed); @@ -289,7 +293,9 @@ test_slave (int master, int type, SignalData *master_changed) ensure_no_signal (master_changed); /* Remove */ + ensure_no_signal (link_added); ensure_no_signal (link_changed); + ensure_no_signal (link_removed); g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex)); accept_signals (master_changed, 0, 1); accept_signals (link_changed, 0, 1); diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 73528aa9..d27b262e 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -865,7 +865,8 @@ create_pppd_cmd_line (NMPPPManager *self, return NULL; if ( pppoe - || (adsl && strcmp (nm_setting_adsl_get_protocol (adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE))) { + || ( adsl + && !strcmp (nm_setting_adsl_get_protocol (adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE))) { pppoe_binary = nm_utils_find_helper ("pppoe", NULL, err); if (!pppoe_binary) return NULL; diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index c694ad6f..8d9252a5 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -50,9 +50,8 @@ G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) NMAgentManagerPrivate)) typedef struct { - gboolean disposed; - NMDBusManager *dbus_mgr; + NMAuthManager *auth_mgr; /* Auth chains for checking agent permissions */ GSList *chains; @@ -1559,35 +1558,7 @@ authority_changed_cb (NMAuthManager *auth_manager, NMAgentManager *self) /*************************************************************/ -NMAgentManager * -nm_agent_manager_get (void) -{ - static NMAgentManager *singleton = NULL; - NMAgentManagerPrivate *priv; - - if (singleton) - return g_object_ref (singleton); - - singleton = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL); - g_assert (singleton); - - priv = NM_AGENT_MANAGER_GET_PRIVATE (singleton); - priv->dbus_mgr = nm_dbus_manager_get (); - - nm_dbus_manager_register_object (priv->dbus_mgr, NM_DBUS_PATH_AGENT_MANAGER, singleton); - - g_signal_connect (priv->dbus_mgr, - NM_DBUS_MANAGER_NAME_OWNER_CHANGED, - G_CALLBACK (name_owner_changed_cb), - singleton); - - g_signal_connect (nm_auth_manager_get (), - NM_AUTH_MANAGER_SIGNAL_CHANGED, - G_CALLBACK (authority_changed_cb), - singleton); - - return singleton; -} +NM_DEFINE_SINGLETON_GETTER (NMAgentManager, nm_agent_manager_get, NM_TYPE_AGENT_MANAGER); static void nm_agent_manager_init (NMAgentManager *self) @@ -1602,23 +1573,57 @@ nm_agent_manager_init (NMAgentManager *self) } static void -dispose (GObject *object) +constructed (GObject *object) { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (object); - if (!priv->disposed) { - priv->disposed = TRUE; + G_OBJECT_CLASS (nm_agent_manager_parent_class)->constructed (object); - g_signal_handlers_disconnect_by_func (nm_auth_manager_get (), - G_CALLBACK (authority_changed_cb), - object); + priv->dbus_mgr = g_object_ref (nm_dbus_manager_get ()); + priv->auth_mgr = g_object_ref (nm_auth_manager_get ()); + + nm_dbus_manager_register_object (priv->dbus_mgr, NM_DBUS_PATH_AGENT_MANAGER, object); - g_slist_free_full (priv->chains, (GDestroyNotify) nm_auth_chain_unref); + g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, + G_CALLBACK (name_owner_changed_cb), + object); + + g_signal_connect (priv->auth_mgr, + NM_AUTH_MANAGER_SIGNAL_CHANGED, + G_CALLBACK (authority_changed_cb), + object); +} +static void +dispose (GObject *object) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (object); + + g_slist_free_full (priv->chains, (GDestroyNotify) nm_auth_chain_unref); + priv->chains = NULL; + + if (priv->agents) { g_hash_table_destroy (priv->agents); + priv->agents = NULL; + } + if (priv->requests) { g_hash_table_destroy (priv->requests); + priv->requests = NULL; + } - priv->dbus_mgr = NULL; + if (priv->auth_mgr) { + g_signal_handlers_disconnect_by_func (priv->auth_mgr, + G_CALLBACK (authority_changed_cb), + object); + g_clear_object (&priv->auth_mgr); + } + if (priv->dbus_mgr) { + g_signal_handlers_disconnect_by_func (priv->dbus_mgr, + G_CALLBACK (name_owner_changed_cb), + object); + nm_dbus_manager_unregister_object (priv->dbus_mgr, object); + g_clear_object (&priv->dbus_mgr); } G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object); @@ -1632,6 +1637,7 @@ nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class) g_type_class_add_private (agent_manager_class, sizeof (NMAgentManagerPrivate)); /* virtual methods */ + object_class->constructed = constructed; object_class->dispose = dispose; /* Signals */ diff --git a/src/settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c index 41f0268d..3732e77a 100644 --- a/src/settings/nm-inotify-helper.c +++ b/src/settings/nm-inotify-helper.c @@ -24,6 +24,7 @@ #include <string.h> #include <sys/inotify.h> #include <glib.h> +#include <errno.h> #include "nm-inotify-helper.h" #include "nm-logging.h" @@ -55,9 +56,10 @@ nm_inotify_helper_add_watch (NMInotifyHelper *self, const char *path) { NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); int wd; - guint32 refcount; + guint refcount; - g_return_val_if_fail (priv->ifd >= 0, -1); + if (priv->ifd < 0) + return -1; /* We only care about modifications since we're just trying to get change * notifications on hardlinks. @@ -78,9 +80,10 @@ void nm_inotify_helper_remove_watch (NMInotifyHelper *self, int wd) { NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); - guint32 refcount; + guint refcount; - g_return_if_fail (priv->ifd >= 0); + if (priv->ifd < 0) + return; refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd))); if (!refcount) @@ -128,7 +131,9 @@ init_inotify (NMInotifyHelper *self) priv->ifd = inotify_init (); if (priv->ifd == -1) { - nm_log_warn (LOGD_SETTINGS, "couldn't initialize inotify"); + int errsv = errno; + + nm_log_warn (LOGD_SETTINGS, "couldn't initialize inotify: %s (%d)", strerror (errsv), errsv); return FALSE; } @@ -145,24 +150,7 @@ init_inotify (NMInotifyHelper *self) return TRUE; } -NMInotifyHelper * -nm_inotify_helper_get (void) -{ - static NMInotifyHelper *singleton_instance = NULL; - - if (!singleton_instance) { - singleton_instance = (NMInotifyHelper *) g_object_new (NM_TYPE_INOTIFY_HELPER, NULL); - - if (!init_inotify (singleton_instance)) { - g_clear_object (&singleton_instance); - return NULL; - } - } else - g_object_ref (singleton_instance); - - g_assert (singleton_instance); - return singleton_instance; -} +NM_DEFINE_SINGLETON_GETTER (NMInotifyHelper, nm_inotify_helper_get, NM_TYPE_INOTIFY_HELPER); static void nm_inotify_helper_init (NMInotifyHelper *self) @@ -173,6 +161,14 @@ nm_inotify_helper_init (NMInotifyHelper *self) } static void +constructed (GObject *object) +{ + G_OBJECT_CLASS (nm_inotify_helper_parent_class)->constructed (object); + + init_inotify (NM_INOTIFY_HELPER (object)); +} + +static void finalize (GObject *object) { NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (object); @@ -193,6 +189,7 @@ nm_inotify_helper_class_init (NMInotifyHelperClass *klass) g_type_class_add_private (klass, sizeof (NMInotifyHelperPrivate)); /* Virtual methods */ + object_class->constructed = constructed; object_class->finalize = finalize; /* Signals */ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index da5384c0..1fa19237 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -2282,7 +2282,7 @@ nm_settings_connection_init (NMSettingsConnection *self) G_CALLBACK (session_changed_cb), self); - priv->agent_mgr = nm_agent_manager_get (); + priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); priv->seen_bssids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 4d7d697d..f20bc71b 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1922,7 +1922,7 @@ nm_settings_init (NMSettings *self) * transient, and we don't want the agent manager to get destroyed and * recreated often. */ - priv->agent_mgr = nm_agent_manager_get (); + priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); g_signal_connect (priv->agent_mgr, "agent-registered", G_CALLBACK (secret_agent_registered), self); } diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c index 6358c180..083f2ebc 100644 --- a/src/supplicant-manager/nm-supplicant-manager.c +++ b/src/supplicant-manager/nm-supplicant-manager.c @@ -318,19 +318,7 @@ on_proxy_acquired (GObject *object, GAsyncResult *result, gpointer user_data) /*******************************************************************/ -NMSupplicantManager * -nm_supplicant_manager_get (void) -{ - static NMSupplicantManager *singleton = NULL; - - if (!singleton) - singleton = NM_SUPPLICANT_MANAGER (g_object_new (NM_TYPE_SUPPLICANT_MANAGER, NULL)); - else - g_object_ref (singleton); - - g_assert (singleton); - return singleton; -} +NM_DEFINE_SINGLETON_GETTER (NMSupplicantManager, nm_supplicant_manager_get, NM_TYPE_SUPPLICANT_MANAGER); static void nm_supplicant_manager_init (NMSupplicantManager *self) diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c index 235cfd42..404940d4 100644 --- a/src/tests/test-ip4-config.c +++ b/src/tests/test-ip4-config.c @@ -336,6 +336,27 @@ test_merge_subtract_mss_mtu (void) g_object_unref (cfg3); } +static void +test_strip_search_trailing_dot (void) +{ + NMIP4Config *config; + + config = nm_ip4_config_new (); + + nm_ip4_config_add_search (config, "."); + nm_ip4_config_add_search (config, "foo"); + nm_ip4_config_add_search (config, "bar."); + nm_ip4_config_add_search (config, "baz.com"); + nm_ip4_config_add_search (config, "baz.com."); + + g_assert_cmpuint (nm_ip4_config_get_num_searches (config), ==, 3); + g_assert_cmpstr (nm_ip4_config_get_search (config, 0), ==, "foo"); + g_assert_cmpstr (nm_ip4_config_get_search (config, 1), ==, "bar"); + g_assert_cmpstr (nm_ip4_config_get_search (config, 2), ==, "baz.com"); + + g_object_unref (config); +} + /*******************************************/ int @@ -352,6 +373,7 @@ main (int argc, char **argv) g_test_add_func ("/ip4-config/add-address-with-source", test_add_address_with_source); g_test_add_func ("/ip4-config/add-route-with-source", test_add_route_with_source); g_test_add_func ("/ip4-config/merge-subtract-mss-mtu", test_merge_subtract_mss_mtu); + g_test_add_func ("/ip4-config/strip-search-trailing-dot", test_strip_search_trailing_dot); return g_test_run (); } diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c index 9e1d5651..a5397b8a 100644 --- a/src/tests/test-ip6-config.c +++ b/src/tests/test-ip6-config.c @@ -321,6 +321,27 @@ test_nm_ip6_config_addresses_sort (void) g_object_unref (config); } +static void +test_strip_search_trailing_dot (void) +{ + NMIP6Config *config; + + config = nm_ip6_config_new (); + + nm_ip6_config_add_search (config, "."); + nm_ip6_config_add_search (config, "foo"); + nm_ip6_config_add_search (config, "bar."); + nm_ip6_config_add_search (config, "baz.com"); + nm_ip6_config_add_search (config, "baz.com."); + + g_assert_cmpuint (nm_ip6_config_get_num_searches (config), ==, 3); + g_assert_cmpstr (nm_ip6_config_get_search (config, 0), ==, "foo"); + g_assert_cmpstr (nm_ip6_config_get_search (config, 1), ==, "bar"); + g_assert_cmpstr (nm_ip6_config_get_search (config, 2), ==, "baz.com"); + + g_object_unref (config); +} + /*******************************************/ NMTST_DEFINE(); @@ -335,6 +356,7 @@ main (int argc, char **argv) g_test_add_func ("/ip6-config/add-address-with-source", test_add_address_with_source); g_test_add_func ("/ip6-config/add-route-with-source", test_add_route_with_source); g_test_add_func ("/ip6-config/test_nm_ip6_config_addresses_sort", test_nm_ip6_config_addresses_sort); + g_test_add_func ("/ip6-config/strip-search-trailing-dot", test_strip_search_trailing_dot); return g_test_run (); } diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index e2d3103b..64e5e2ab 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -1663,7 +1663,6 @@ static void really_activate (NMVpnConnection *connection, const char *username) { NMVpnConnectionPrivate *priv; - NMAgentManager *agent_mgr; GHashTable *details; g_return_if_fail (NM_IS_VPN_CONNECTION (connection)); @@ -1702,8 +1701,7 @@ really_activate (NMVpnConnection *connection, const char *username) * dialog and we won't get the secrets we need. In this case fall back to * the old Connect() call. */ - agent_mgr = nm_agent_manager_get (); - if (nm_agent_manager_all_agents_have_capability (agent_mgr, + if (nm_agent_manager_all_agents_have_capability (nm_agent_manager_get (), nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (connection)), NM_SECRET_AGENT_CAPABILITY_VPN_HINTS)) { nm_log_dbg (LOGD_VPN, "Allowing interactive secrets as all agents have that capability"); @@ -1719,7 +1717,6 @@ really_activate (NMVpnConnection *connection, const char *username) DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, priv->connect_hash, G_TYPE_INVALID); } - g_object_unref (agent_mgr); g_hash_table_destroy (details); _set_vpn_state (connection, STATE_CONNECT, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE); diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 1f3798c7..1de9b753 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -200,19 +200,7 @@ vpn_dir_changed (GFileMonitor *monitor, /******************************************************************************/ -NMVpnManager * -nm_vpn_manager_get (void) -{ - static NMVpnManager *singleton = NULL; - - if (!singleton) - singleton = NM_VPN_MANAGER (g_object_new (NM_TYPE_VPN_MANAGER, NULL)); - else - g_object_ref (singleton); - - g_assert (singleton); - return singleton; -} +NM_DEFINE_SINGLETON_GETTER (NMVpnManager, nm_vpn_manager_get, NM_TYPE_VPN_MANAGER); static void nm_vpn_manager_init (NMVpnManager *self) |