mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 22:48:01 +02:00
rdisc: make NMRDisc namespace aware
This commit is contained in:
parent
a0c8f9c345
commit
3ba9444728
8 changed files with 121 additions and 13 deletions
|
|
@ -5849,7 +5849,8 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
|
|||
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
|
||||
g_assert (s_ip6);
|
||||
|
||||
priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self),
|
||||
priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
|
||||
nm_device_get_ip_ifindex (self),
|
||||
nm_device_get_ip_iface (self),
|
||||
nm_connection_get_uuid (connection),
|
||||
nm_setting_ip6_config_get_addr_gen_mode (s_ip6),
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ main (int argc, char *argv[])
|
|||
if (global_opt.slaac) {
|
||||
nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, TRUE);
|
||||
|
||||
rdisc = nm_lndp_rdisc_new (ifindex, global_opt.ifname, global_opt.uuid, global_opt.addr_gen_mode, NULL);
|
||||
rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, ifindex, global_opt.ifname, global_opt.uuid, global_opt.addr_gen_mode, NULL);
|
||||
g_assert (rdisc);
|
||||
|
||||
if (iid)
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ typedef enum {
|
|||
} NMIPConfigSource;
|
||||
|
||||
/* platform */
|
||||
typedef struct _NMPlatform NMPlatform;
|
||||
typedef struct _NMPlatformIP4Address NMPlatformIP4Address;
|
||||
typedef struct _NMPlatformIP4Route NMPlatformIP4Route;
|
||||
typedef struct _NMPlatformIP6Address NMPlatformIP6Address;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-platform.h"
|
||||
#include "nmp-netns.h"
|
||||
|
||||
#define _NMLOG_PREFIX_NAME "rdisc-lndp"
|
||||
|
||||
|
|
@ -273,9 +274,14 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
|||
static gboolean
|
||||
event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc)
|
||||
{
|
||||
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||
NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
|
||||
|
||||
_LOGD ("processing libndp events");
|
||||
|
||||
if (!nm_rdisc_netns_push (rdisc, &netns))
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
ndp_callall_eventfd_handler (priv->ndp);
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
|
@ -298,40 +304,50 @@ start (NMRDisc *rdisc)
|
|||
/******************************************************************/
|
||||
|
||||
static inline gint32
|
||||
ipv6_sysctl_get (const char *ifname, const char *property, gint32 defval)
|
||||
ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, gint32 defval)
|
||||
{
|
||||
return nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, nm_utils_ip6_property_path (ifname, property), defval);
|
||||
return nm_platform_sysctl_get_int32 (platform, nm_utils_ip6_property_path (ifname, property), defval);
|
||||
}
|
||||
|
||||
NMRDisc *
|
||||
nm_lndp_rdisc_new (int ifindex,
|
||||
nm_lndp_rdisc_new (NMPlatform *platform,
|
||||
int ifindex,
|
||||
const char *ifname,
|
||||
const char *uuid,
|
||||
NMSettingIP6ConfigAddrGenMode addr_gen_mode,
|
||||
GError **error)
|
||||
{
|
||||
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||
NMRDisc *rdisc;
|
||||
NMLNDPRDiscPrivate *priv;
|
||||
int errsv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_PLATFORM (platform), NULL);
|
||||
g_return_val_if_fail (!error || !*error, NULL);
|
||||
|
||||
rdisc = g_object_new (NM_TYPE_LNDP_RDISC, NULL);
|
||||
if (!nm_platform_netns_push (platform, &netns))
|
||||
return NULL;
|
||||
|
||||
rdisc = g_object_new (NM_TYPE_LNDP_RDISC,
|
||||
NM_RDISC_PLATFORM, platform,
|
||||
NULL);
|
||||
|
||||
rdisc->ifindex = ifindex;
|
||||
rdisc->ifname = g_strdup (ifname);
|
||||
rdisc->uuid = g_strdup (uuid);
|
||||
rdisc->addr_gen_mode = addr_gen_mode;
|
||||
|
||||
rdisc->max_addresses = ipv6_sysctl_get (ifname, "max_addresses",
|
||||
rdisc->max_addresses = ipv6_sysctl_get (platform, ifname, "max_addresses",
|
||||
NM_RDISC_MAX_ADDRESSES_DEFAULT);
|
||||
rdisc->rtr_solicitations = ipv6_sysctl_get (ifname, "router_solicitations",
|
||||
rdisc->rtr_solicitations = ipv6_sysctl_get (platform, ifname, "router_solicitations",
|
||||
NM_RDISC_RTR_SOLICITATIONS_DEFAULT);
|
||||
rdisc->rtr_solicitation_interval = ipv6_sysctl_get (ifname, "router_solicitation_interval",
|
||||
rdisc->rtr_solicitation_interval = ipv6_sysctl_get (platform, ifname, "router_solicitation_interval",
|
||||
NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT);
|
||||
|
||||
priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
|
||||
|
||||
errsv = ndp_open (&priv->ndp);
|
||||
|
||||
if (errsv != 0) {
|
||||
errsv = errsv > 0 ? errsv : -errsv;
|
||||
g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ typedef struct {
|
|||
|
||||
GType nm_lndp_rdisc_get_type (void);
|
||||
|
||||
NMRDisc *nm_lndp_rdisc_new (int ifindex,
|
||||
NMRDisc *nm_lndp_rdisc_new (NMPlatform *platform,
|
||||
int ifindex,
|
||||
const char *ifname,
|
||||
const char *uuid,
|
||||
NMSettingIP6ConfigAddrGenMode addr_gen_mode,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include "nm-rdisc-private.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-platform.h"
|
||||
#include "nmp-netns.h"
|
||||
|
||||
#include <nm-setting-ip6-config.h>
|
||||
|
||||
|
|
@ -46,6 +48,10 @@ typedef struct {
|
|||
|
||||
G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT)
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
||||
PROP_PLATFORM,
|
||||
);
|
||||
|
||||
enum {
|
||||
CONFIG_CHANGED,
|
||||
RA_TIMEOUT,
|
||||
|
|
@ -56,6 +62,31 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
|||
|
||||
/******************************************************************/
|
||||
|
||||
NMPNetns *
|
||||
nm_rdisc_netns_get (NMRDisc *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_RDISC (self), NULL);
|
||||
|
||||
return self->_netns;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_RDISC (self), FALSE);
|
||||
|
||||
if ( self->_netns
|
||||
&& !nmp_netns_push (self->_netns)) {
|
||||
NM_SET_OUT (netns, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NM_SET_OUT (netns, self->_netns);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new)
|
||||
{
|
||||
|
|
@ -317,10 +348,14 @@ nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid)
|
|||
static gboolean
|
||||
send_rs (NMRDisc *rdisc)
|
||||
{
|
||||
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||
NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc);
|
||||
NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!nm_rdisc_netns_push (rdisc, &netns))
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
if (klass->send_rs (rdisc, &error)) {
|
||||
_LOGD ("router solicitation sent");
|
||||
priv->solicitations_left--;
|
||||
|
|
@ -383,6 +418,7 @@ rdisc_ra_timeout_cb (gpointer user_data)
|
|||
void
|
||||
nm_rdisc_start (NMRDisc *rdisc)
|
||||
{
|
||||
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||
NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
|
||||
NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc);
|
||||
guint ra_wait_secs;
|
||||
|
|
@ -391,6 +427,9 @@ nm_rdisc_start (NMRDisc *rdisc)
|
|||
|
||||
_LOGD ("starting router discovery: %d", rdisc->ifindex);
|
||||
|
||||
if (!nm_rdisc_netns_push (rdisc, &netns))
|
||||
return;
|
||||
|
||||
nm_clear_g_source (&priv->ra_timeout_id);
|
||||
ra_wait_secs = CLAMP (rdisc->rtr_solicitations * rdisc->rtr_solicitation_interval, 30, 120);
|
||||
priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, rdisc_ra_timeout_cb, rdisc);
|
||||
|
|
@ -668,11 +707,42 @@ dns_domain_free (gpointer data)
|
|||
g_free (((NMRDiscDNSDomain *)(data))->domain);
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMRDisc *self = NM_RDISC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PLATFORM:
|
||||
/* construct-only */
|
||||
self->_platform = g_value_get_object (value) ? : NM_PLATFORM_GET;
|
||||
if (!self->_platform)
|
||||
g_return_if_reached ();
|
||||
|
||||
g_object_ref (self->_platform);
|
||||
|
||||
self->_netns = nm_platform_netns_get (self->_platform);
|
||||
if (self->_netns)
|
||||
g_object_ref (self->_netns);
|
||||
|
||||
g_return_if_fail (!self->_netns || self->_netns == nmp_netns_get_current ());
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_rdisc_init (NMRDisc *rdisc)
|
||||
{
|
||||
NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
|
||||
|
||||
rdisc->_netns = nmp_netns_get_current ();
|
||||
if (rdisc->_netns)
|
||||
g_object_ref (rdisc->_netns);
|
||||
|
||||
rdisc->gateways = g_array_new (FALSE, FALSE, sizeof (NMRDiscGateway));
|
||||
rdisc->addresses = g_array_new (FALSE, FALSE, sizeof (NMRDiscAddress));
|
||||
rdisc->routes = g_array_new (FALSE, FALSE, sizeof (NMRDiscRoute));
|
||||
|
|
@ -715,6 +785,9 @@ finalize (GObject *object)
|
|||
g_array_unref (rdisc->dns_servers);
|
||||
g_array_unref (rdisc->dns_domains);
|
||||
|
||||
g_clear_object (&rdisc->_netns);
|
||||
g_clear_object (&rdisc->_platform);
|
||||
|
||||
G_OBJECT_CLASS (nm_rdisc_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
|
@ -725,10 +798,19 @@ nm_rdisc_class_init (NMRDiscClass *klass)
|
|||
|
||||
g_type_class_add_private (klass, sizeof (NMRDiscPrivate));
|
||||
|
||||
object_class->set_property = set_property;
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
klass->config_changed = config_changed;
|
||||
|
||||
obj_properties[PROP_PLATFORM] =
|
||||
g_param_spec_object (NM_RDISC_PLATFORM, "", "",
|
||||
NM_TYPE_PLATFORM,
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
signals[CONFIG_CHANGED] =
|
||||
g_signal_new (NM_RDISC_CONFIG_CHANGED,
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
|
|
|
|||
|
|
@ -21,11 +21,9 @@
|
|||
#ifndef __NETWORKMANAGER_RDISC_H__
|
||||
#define __NETWORKMANAGER_RDISC_H__
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "nm-default.h"
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
|
|
@ -36,6 +34,7 @@
|
|||
#define NM_IS_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_RDISC))
|
||||
#define NM_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_RDISC, NMRDiscClass))
|
||||
|
||||
#define NM_RDISC_PLATFORM "platform"
|
||||
#define NM_RDISC_CONFIG_CHANGED "config-changed"
|
||||
#define NM_RDISC_RA_TIMEOUT "ra-timeout"
|
||||
|
||||
|
|
@ -114,6 +113,9 @@ typedef enum {
|
|||
typedef struct {
|
||||
GObject parent;
|
||||
|
||||
NMPlatform *_platform;
|
||||
NMPNetns *_netns;
|
||||
|
||||
int ifindex;
|
||||
char *ifname;
|
||||
char *uuid;
|
||||
|
|
@ -149,4 +151,8 @@ gboolean nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid);
|
|||
void nm_rdisc_start (NMRDisc *rdisc);
|
||||
void nm_rdisc_dad_failed (NMRDisc *rdisc, struct in6_addr *address);
|
||||
|
||||
NMPlatform *nm_rdisc_get_platform (NMRDisc *self);
|
||||
NMPNetns *nm_rdisc_netns_get (NMRDisc *self);
|
||||
gboolean nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns);
|
||||
|
||||
#endif /* __NETWORKMANAGER_RDISC_H__ */
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ main (int argc, char **argv)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
rdisc = nm_lndp_rdisc_new (ifindex,
|
||||
rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
ifname,
|
||||
"8ce666e8-d34d-4fb1-b858-f15a7al28086",
|
||||
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue