mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-06 05:38:15 +02:00
device/ndisc: add nm_ndisc_stop() method
It is bad style to rely on the last unref of an object for stopping the operation. With a ref-counted object you should never rely on anybody else still having (or not having) a reference. Hence, you should not rely on stopping the ND during the last unref. Add an explicit nm_ndisc_stop() function.
This commit is contained in:
parent
e8eaaa78d1
commit
6ce482c526
4 changed files with 94 additions and 21 deletions
|
|
@ -337,6 +337,14 @@ start (NMNDisc *ndisc)
|
||||||
priv->receive_ra_id = g_timeout_add_seconds (ra->when, receive_ra, ndisc);
|
priv->receive_ra_id = g_timeout_add_seconds (ra->when, receive_ra, ndisc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop (NMNDisc *ndisc)
|
||||||
|
{
|
||||||
|
NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (ndisc);
|
||||||
|
|
||||||
|
nm_clear_g_source (&priv->receive_ra_id);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_fake_ndisc_emit_new_ras (NMFakeNDisc *self)
|
nm_fake_ndisc_emit_new_ras (NMFakeNDisc *self)
|
||||||
{
|
{
|
||||||
|
|
@ -388,7 +396,8 @@ nm_fake_ndisc_class_init (NMFakeNDiscClass *klass)
|
||||||
|
|
||||||
object_class->dispose = dispose;
|
object_class->dispose = dispose;
|
||||||
|
|
||||||
ndisc_class->start = start;
|
ndisc_class->start = start;
|
||||||
|
ndisc_class->stop = stop;
|
||||||
ndisc_class->send_rs = send_rs;
|
ndisc_class->send_rs = send_rs;
|
||||||
|
|
||||||
signals[RS_SENT] =
|
signals[RS_SENT] =
|
||||||
|
|
|
||||||
|
|
@ -535,6 +535,36 @@ start (NMNDisc *ndisc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cleanup (NMNDisc *ndisc)
|
||||||
|
{
|
||||||
|
NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE (ndisc);
|
||||||
|
|
||||||
|
nm_clear_g_source_inst (&priv->event_source);
|
||||||
|
|
||||||
|
if (priv->ndp) {
|
||||||
|
switch (nm_ndisc_get_node_type (ndisc)) {
|
||||||
|
case NM_NDISC_NODE_TYPE_HOST:
|
||||||
|
ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc);
|
||||||
|
break;
|
||||||
|
case NM_NDISC_NODE_TYPE_ROUTER:
|
||||||
|
ndp_msgrcv_handler_unregister (priv->ndp, receive_rs, NDP_MSG_RS, nm_ndisc_get_ifindex (ndisc), ndisc);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nm_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ndp_close (priv->ndp);
|
||||||
|
priv->ndp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop (NMNDisc *ndisc)
|
||||||
|
{
|
||||||
|
_cleanup (ndisc);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -659,24 +689,8 @@ static void
|
||||||
dispose (GObject *object)
|
dispose (GObject *object)
|
||||||
{
|
{
|
||||||
NMNDisc *ndisc = NM_NDISC (object);
|
NMNDisc *ndisc = NM_NDISC (object);
|
||||||
NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE (ndisc);
|
|
||||||
|
|
||||||
nm_clear_g_source_inst (&priv->event_source);
|
_cleanup (ndisc);
|
||||||
|
|
||||||
if (priv->ndp) {
|
|
||||||
switch (nm_ndisc_get_node_type (ndisc)) {
|
|
||||||
case NM_NDISC_NODE_TYPE_HOST:
|
|
||||||
ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc);
|
|
||||||
break;
|
|
||||||
case NM_NDISC_NODE_TYPE_ROUTER:
|
|
||||||
ndp_msgrcv_handler_unregister (priv->ndp, receive_rs, NDP_MSG_RS, nm_ndisc_get_ifindex (ndisc), ndisc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
ndp_close (priv->ndp);
|
|
||||||
priv->ndp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (nm_lndp_ndisc_parent_class)->dispose (object);
|
G_OBJECT_CLASS (nm_lndp_ndisc_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
@ -688,7 +702,8 @@ nm_lndp_ndisc_class_init (NMLndpNDiscClass *klass)
|
||||||
NMNDiscClass *ndisc_class = NM_NDISC_CLASS (klass);
|
NMNDiscClass *ndisc_class = NM_NDISC_CLASS (klass);
|
||||||
|
|
||||||
object_class->dispose = dispose;
|
object_class->dispose = dispose;
|
||||||
ndisc_class->start = start;
|
ndisc_class->start = start;
|
||||||
ndisc_class->send_rs = send_rs;
|
ndisc_class->stop = stop;
|
||||||
ndisc_class->send_ra = send_ra;
|
ndisc_class->send_rs = send_rs;
|
||||||
|
ndisc_class->send_ra = send_ra;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -960,6 +960,53 @@ nm_ndisc_start (NMNDisc *ndisc)
|
||||||
announce_router_initial (ndisc);
|
announce_router_initial (ndisc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nm_ndisc_stop (NMNDisc *ndisc)
|
||||||
|
{
|
||||||
|
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||||
|
NMNDiscDataInternal *rdata;
|
||||||
|
NMNDiscPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_NDISC (ndisc));
|
||||||
|
|
||||||
|
priv = NM_NDISC_GET_PRIVATE (ndisc);
|
||||||
|
|
||||||
|
nm_assert (NM_NDISC_GET_CLASS (ndisc)->stop);
|
||||||
|
|
||||||
|
_LOGD ("stopping neighbor discovery for ifindex %d",
|
||||||
|
priv->ifindex);
|
||||||
|
|
||||||
|
if (!nm_ndisc_netns_push (ndisc, &netns))
|
||||||
|
return;
|
||||||
|
|
||||||
|
NM_NDISC_GET_CLASS (ndisc)->stop (ndisc);
|
||||||
|
|
||||||
|
rdata = &priv->rdata;
|
||||||
|
|
||||||
|
g_array_set_size (rdata->gateways, 0);
|
||||||
|
g_array_set_size (rdata->addresses, 0);
|
||||||
|
g_array_set_size (rdata->routes, 0);
|
||||||
|
g_array_set_size (rdata->dns_servers, 0);
|
||||||
|
g_array_set_size (rdata->dns_domains, 0);
|
||||||
|
priv->rdata.public.hop_limit = 64;
|
||||||
|
|
||||||
|
/* Start at very low number so that last_rs - router_solicitation_interval
|
||||||
|
* is much lower than nm_utils_get_monotonic_timestamp_sec() at startup.
|
||||||
|
*/
|
||||||
|
priv->last_rs = G_MININT32;
|
||||||
|
nm_clear_g_source_inst (&priv->ra_timeout_source);
|
||||||
|
nm_clear_g_source (&priv->send_rs_id);
|
||||||
|
nm_clear_g_source (&priv->send_ra_id);
|
||||||
|
nm_clear_g_free (&priv->last_error);
|
||||||
|
nm_clear_g_source (&priv->timeout_id);
|
||||||
|
|
||||||
|
priv->solicitations_left = 0;
|
||||||
|
priv->announcements_left = 0;
|
||||||
|
|
||||||
|
priv->last_rs = G_MININT32;
|
||||||
|
priv->last_ra = G_MININT32;
|
||||||
|
}
|
||||||
|
|
||||||
NMNDiscConfigMap
|
NMNDiscConfigMap
|
||||||
nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address, gboolean emit_changed_signal)
|
nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address, gboolean emit_changed_signal)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,7 @@ typedef struct {
|
||||||
GObjectClass parent;
|
GObjectClass parent;
|
||||||
|
|
||||||
void (*start) (NMNDisc *ndisc);
|
void (*start) (NMNDisc *ndisc);
|
||||||
|
void (*stop) (NMNDisc *ndisc);
|
||||||
gboolean (*send_rs) (NMNDisc *ndisc, GError **error);
|
gboolean (*send_rs) (NMNDisc *ndisc, GError **error);
|
||||||
gboolean (*send_ra) (NMNDisc *ndisc, GError **error);
|
gboolean (*send_ra) (NMNDisc *ndisc, GError **error);
|
||||||
} NMNDiscClass;
|
} NMNDiscClass;
|
||||||
|
|
@ -177,6 +178,7 @@ NMNDiscNodeType nm_ndisc_get_node_type (NMNDisc *self);
|
||||||
|
|
||||||
gboolean nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid);
|
gboolean nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid);
|
||||||
void nm_ndisc_start (NMNDisc *ndisc);
|
void nm_ndisc_start (NMNDisc *ndisc);
|
||||||
|
void nm_ndisc_stop (NMNDisc *ndisc);
|
||||||
NMNDiscConfigMap nm_ndisc_dad_failed (NMNDisc *ndisc,
|
NMNDiscConfigMap nm_ndisc_dad_failed (NMNDisc *ndisc,
|
||||||
const struct in6_addr *address,
|
const struct in6_addr *address,
|
||||||
gboolean emit_changed_signal);
|
gboolean emit_changed_signal);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue