ndisc: avoid calling start() multiple times

It hooks on ndp event callbacks and we'll end up in them being done
redundantly, leaking them on dispose and potentially even calling them.
This commit is contained in:
Lubomir Rintel
2016-10-14 19:53:53 +02:00
parent 679f8dfc7d
commit aed2106d3e
3 changed files with 8 additions and 7 deletions

View File

@@ -1897,10 +1897,8 @@ device_link_changed (NMDevice *self)
} }
if (priv->ndisc && info.inet6_token.id) { if (priv->ndisc && info.inet6_token.id) {
if (nm_ndisc_set_iid (priv->ndisc, info.inet6_token)) { if (nm_ndisc_set_iid (priv->ndisc, info.inet6_token))
_LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
nm_ndisc_start (priv->ndisc);
}
} }
if (klass->link_changed) if (klass->link_changed)

View File

@@ -323,6 +323,9 @@ start (NMNDisc *ndisc)
NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc); NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc);
int fd = ndp_get_eventfd (priv->ndp); int fd = ndp_get_eventfd (priv->ndp);
g_return_if_fail (!priv->event_channel);
g_return_if_fail (!priv->event_id);
priv->event_channel = g_io_channel_unix_new (fd); priv->event_channel = g_io_channel_unix_new (fd);
priv->event_id = g_io_add_watch (priv->event_channel, G_IO_IN, (GIOFunc) event_ready, ndisc); priv->event_id = g_io_add_watch (priv->event_channel, G_IO_IN, (GIOFunc) event_ready, ndisc);

View File

@@ -531,6 +531,7 @@ nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid)
_LOGD ("IPv6 interface identifier changed, flushing addresses"); _LOGD ("IPv6 interface identifier changed, flushing addresses");
g_array_remove_range (rdata->addresses, 0, rdata->addresses->len); g_array_remove_range (rdata->addresses, 0, rdata->addresses->len);
_emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES);
solicit (ndisc);
} }
return TRUE; return TRUE;
} }
@@ -556,21 +557,20 @@ nm_ndisc_start (NMNDisc *ndisc)
NMNDiscClass *klass = NM_NDISC_GET_CLASS (ndisc); NMNDiscClass *klass = NM_NDISC_GET_CLASS (ndisc);
gint64 ra_wait_secs; gint64 ra_wait_secs;
g_assert (klass->start); g_return_if_fail (klass->start);
g_return_if_fail (!priv->ra_timeout_id);
_LOGD ("starting neighbor discovery: %d", priv->ifindex); _LOGD ("starting neighbor discovery: %d", priv->ifindex);
if (!nm_ndisc_netns_push (ndisc, &netns)) if (!nm_ndisc_netns_push (ndisc, &netns))
return; return;
nm_clear_g_source (&priv->ra_timeout_id);
ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1; ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1;
ra_wait_secs = CLAMP (ra_wait_secs, 30, 120); ra_wait_secs = CLAMP (ra_wait_secs, 30, 120);
priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, ndisc_ra_timeout_cb, ndisc); priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, ndisc_ra_timeout_cb, ndisc);
_LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs); _LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs);
if (klass->start) klass->start (ndisc);
klass->start (ndisc);
solicit (ndisc); solicit (ndisc);
} }