diff --git a/src/rdisc/nm-fake-rdisc.c b/src/rdisc/nm-fake-rdisc.c index b66f95803..4d2d034e9 100644 --- a/src/rdisc/nm-fake-rdisc.c +++ b/src/rdisc/nm-fake-rdisc.c @@ -223,7 +223,7 @@ nm_fake_rdisc_done (NMFakeRDisc *self) /******************************************************************/ static gboolean -send_rs (NMRDisc *rdisc) +send_rs (NMRDisc *rdisc, GError **error) { g_signal_emit (rdisc, signals[RS_SENT], 0); return TRUE; diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c index 413e1c93f..091b76b36 100644 --- a/src/rdisc/nm-lndp-rdisc.c +++ b/src/rdisc/nm-lndp-rdisc.c @@ -50,20 +50,28 @@ G_DEFINE_TYPE (NMLNDPRDisc, nm_lndp_rdisc, NM_TYPE_RDISC) /******************************************************************/ static gboolean -send_rs (NMRDisc *rdisc) +send_rs (NMRDisc *rdisc, GError **error) { NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); struct ndp_msg *msg; - int error; + int errsv; - error = ndp_msg_new (&msg, NDP_MSG_RS); - g_assert (!error); + errsv = ndp_msg_new (&msg, NDP_MSG_RS); + if (!errsv) { + errsv = errsv > 0 ? errsv : -errsv; + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + "cannot create router solicitation"); + return FALSE; + } ndp_msg_ifindex_set (msg, rdisc->ifindex); - error = ndp_msg_send (priv->ndp, msg); + errsv = ndp_msg_send (priv->ndp, msg); ndp_msg_destroy (msg); - if (error) { - _LOGE ("cannot send router solicitation: %d.", error); + if (errsv) { + errsv = errsv > 0 ? errsv : -errsv; + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + "%s (%d)", + g_strerror (errsv), errsv); return FALSE; } diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c index ec0c66e7b..6be8c69da 100644 --- a/src/rdisc/nm-rdisc.c +++ b/src/rdisc/nm-rdisc.c @@ -40,6 +40,7 @@ typedef struct { gint64 last_rs; guint ra_timeout_id; /* first RA timeout */ guint timeout_id; /* prefix/dns/etc lifetime timeout */ + char *last_send_rs_error; } NMRDiscPrivate; #define NM_RDISC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_RDISC, NMRDiscPrivate)) @@ -319,11 +320,24 @@ send_rs (NMRDisc *rdisc) { NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc); NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + GError *error = NULL; - _LOGD ("sending router solicitation"); - - if (klass->send_rs (rdisc)) + if (klass->send_rs (rdisc, &error)) { + _LOGD ("router solicitation sent"); priv->solicitations_left--; + g_clear_pointer (&priv->last_send_rs_error, g_free); + } else { + gboolean different_message; + + different_message = g_strcmp0 (priv->last_send_rs_error, error->message) != 0; + _NMLOG (different_message ? LOGL_WARN : LOGL_DEBUG, + "failure sending router solicitation: %s", error->message); + if (different_message) { + g_clear_pointer (&priv->last_send_rs_error, g_free); + priv->last_send_rs_error = g_strdup (error->message); + } + g_clear_error (&error); + } priv->last_rs = nm_utils_get_monotonic_timestamp_s (); if (priv->solicitations_left > 0) { @@ -646,6 +660,7 @@ nm_rdisc_ra_received (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) nm_clear_g_source (&priv->ra_timeout_id); nm_clear_g_source (&priv->send_rs_id); + g_clear_pointer (&priv->last_send_rs_error, g_free); check_timestamps (rdisc, now, changed); } @@ -684,6 +699,7 @@ dispose (GObject *object) nm_clear_g_source (&priv->ra_timeout_id); nm_clear_g_source (&priv->send_rs_id); + g_clear_pointer (&priv->last_send_rs_error, g_free); if (priv->timeout_id) { g_source_remove (priv->timeout_id); diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h index c150a7291..51e2602f7 100644 --- a/src/rdisc/nm-rdisc.h +++ b/src/rdisc/nm-rdisc.h @@ -137,7 +137,7 @@ typedef struct { GObjectClass parent; void (*start) (NMRDisc *rdisc); - gboolean (*send_rs) (NMRDisc *rdisc); + gboolean (*send_rs) (NMRDisc *rdisc, GError **error); void (*config_changed) (NMRDisc *rdisc, NMRDiscConfigMap changed); void (*ra_process) (NMRDisc *rdisc); void (*ra_timeout) (NMRDisc *rdisc);