diff options
author | Thomas Haller <thaller@redhat.com> | 2016-03-08 13:11:36 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-03-15 12:56:58 +0100 |
commit | 3ba944472853d5221ed83c369a77f80ee7305648 (patch) | |
tree | 3b451437edd45a54a0f65de8c02769ce7b7507d5 | |
parent | a0c8f9c3452f50f284128b9a1f39b0db90442aa8 (diff) | |
download | NetworkManager-3ba944472853d5221ed83c369a77f80ee7305648.tar.gz |
rdisc: make NMRDisc namespace aware
-rw-r--r-- | src/devices/nm-device.c | 3 | ||||
-rw-r--r-- | src/nm-iface-helper.c | 2 | ||||
-rw-r--r-- | src/nm-types.h | 1 | ||||
-rw-r--r-- | src/rdisc/nm-lndp-rdisc.c | 30 | ||||
-rw-r--r-- | src/rdisc/nm-lndp-rdisc.h | 3 | ||||
-rw-r--r-- | src/rdisc/nm-rdisc.c | 82 | ||||
-rw-r--r-- | src/rdisc/nm-rdisc.h | 10 | ||||
-rw-r--r-- | src/rdisc/tests/test-rdisc-linux.c | 3 |
8 files changed, 121 insertions, 13 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index ec63147f81..51a84bfebb 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -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), diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index dab0ec5fec..5a697537c1 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -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) diff --git a/src/nm-types.h b/src/nm-types.h index 6722e39474..997723e607 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -74,6 +74,7 @@ typedef enum { } NMIPConfigSource; /* platform */ +typedef struct _NMPlatform NMPlatform; typedef struct _NMPlatformIP4Address NMPlatformIP4Address; typedef struct _NMPlatformIP4Route NMPlatformIP4Route; typedef struct _NMPlatformIP6Address NMPlatformIP6Address; diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c index 0686346215..27fd2f836c 100644 --- a/src/rdisc/nm-lndp-rdisc.c +++ b/src/rdisc/nm-lndp-rdisc.c @@ -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, diff --git a/src/rdisc/nm-lndp-rdisc.h b/src/rdisc/nm-lndp-rdisc.h index e6706e3c3f..4c7c4743e7 100644 --- a/src/rdisc/nm-lndp-rdisc.h +++ b/src/rdisc/nm-lndp-rdisc.h @@ -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, diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c index 7500d363e7..7abcb703bf 100644 --- a/src/rdisc/nm-rdisc.c +++ b/src/rdisc/nm-rdisc.c @@ -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); @@ -669,10 +708,41 @@ dns_domain_free (gpointer data) } 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), diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h index 51e2602f74..5b97bec563 100644 --- a/src/rdisc/nm-rdisc.h +++ b/src/rdisc/nm-rdisc.h @@ -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__ */ diff --git a/src/rdisc/tests/test-rdisc-linux.c b/src/rdisc/tests/test-rdisc-linux.c index bbdb5fb842..e22eb1ade1 100644 --- a/src/rdisc/tests/test-rdisc-linux.c +++ b/src/rdisc/tests/test-rdisc-linux.c @@ -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, |