mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 11:50:14 +01: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);
|
||||
}
|
||||
|
||||
static void
|
||||
stop (NMNDisc *ndisc)
|
||||
{
|
||||
NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (ndisc);
|
||||
|
||||
nm_clear_g_source (&priv->receive_ra_id);
|
||||
}
|
||||
|
||||
void
|
||||
nm_fake_ndisc_emit_new_ras (NMFakeNDisc *self)
|
||||
{
|
||||
|
|
@ -388,7 +396,8 @@ nm_fake_ndisc_class_init (NMFakeNDiscClass *klass)
|
|||
|
||||
object_class->dispose = dispose;
|
||||
|
||||
ndisc_class->start = start;
|
||||
ndisc_class->start = start;
|
||||
ndisc_class->stop = stop;
|
||||
ndisc_class->send_rs = send_rs;
|
||||
|
||||
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
|
||||
|
|
@ -659,24 +689,8 @@ static void
|
|||
dispose (GObject *object)
|
||||
{
|
||||
NMNDisc *ndisc = NM_NDISC (object);
|
||||
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:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
ndp_close (priv->ndp);
|
||||
priv->ndp = NULL;
|
||||
}
|
||||
_cleanup (ndisc);
|
||||
|
||||
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);
|
||||
|
||||
object_class->dispose = dispose;
|
||||
ndisc_class->start = start;
|
||||
ndisc_class->send_rs = send_rs;
|
||||
ndisc_class->send_ra = send_ra;
|
||||
ndisc_class->start = start;
|
||||
ndisc_class->stop = stop;
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address, gboolean emit_changed_signal)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ typedef struct {
|
|||
GObjectClass parent;
|
||||
|
||||
void (*start) (NMNDisc *ndisc);
|
||||
void (*stop) (NMNDisc *ndisc);
|
||||
gboolean (*send_rs) (NMNDisc *ndisc, GError **error);
|
||||
gboolean (*send_ra) (NMNDisc *ndisc, GError **error);
|
||||
} NMNDiscClass;
|
||||
|
|
@ -177,6 +178,7 @@ NMNDiscNodeType nm_ndisc_get_node_type (NMNDisc *self);
|
|||
|
||||
gboolean nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid);
|
||||
void nm_ndisc_start (NMNDisc *ndisc);
|
||||
void nm_ndisc_stop (NMNDisc *ndisc);
|
||||
NMNDiscConfigMap nm_ndisc_dad_failed (NMNDisc *ndisc,
|
||||
const struct in6_addr *address,
|
||||
gboolean emit_changed_signal);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue