diff options
Diffstat (limited to 'src/platform/nm-linux-platform.c')
-rw-r--r-- | src/platform/nm-linux-platform.c | 162 |
1 files changed, 101 insertions, 61 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 2bdcb9bcd8..a089edef09 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -50,6 +50,7 @@ #include "nm-core-utils.h" #include "nmp-object.h" +#include "nmp-netns.h" #include "nm-platform-utils.h" #include "wifi/wifi-utils.h" #include "wifi/wifi-utils-wext.h" @@ -221,6 +222,7 @@ static void do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActi static void cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMPCacheOpsType ops_type, gpointer user_data); static void cache_prune_candidates_prune (NMPlatform *platform); static gboolean event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks); +static void _assert_netns_current (NMPlatform *platform); /*****************************************************************************/ @@ -647,6 +649,8 @@ _linktype_get_type (NMPlatform *platform, { guint i; + _assert_netns_current (platform); + if (completed_from_cache) { const NMPObject *obj; @@ -2410,6 +2414,7 @@ void nm_linux_platform_setup (void) { g_object_new (NM_TYPE_LINUX_PLATFORM, + NM_PLATFORM_NETNS_SUPPORT, FALSE, NM_PLATFORM_REGISTER_SINGLETON, TRUE, NULL); } @@ -2417,6 +2422,16 @@ nm_linux_platform_setup (void) /******************************************************************/ static void +_assert_netns_current (NMPlatform *platform) +{ +#if NM_MORE_ASSERTS + nm_assert (NM_IS_LINUX_PLATFORM (platform)); + + nm_assert (NM_IN_SET (nm_platform_netns_get (platform), NULL, nmp_netns_get_current ())); +#endif +} + +static void _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *path, const char *value) { GError *error = NULL; @@ -2449,6 +2464,7 @@ _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *path, const char *va static gboolean sysctl_set (NMPlatform *platform, const char *path, const char *value) { + nm_auto_pop_netns NMPNetns *netns = NULL; int fd, tries; gssize nwrote; gsize len; @@ -2464,6 +2480,9 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) /* Don't write to suspicious locations */ g_assert (!strstr (path, "/../")); + if (!nm_platform_netns_push (platform, &netns)) + return FALSE; + fd = open (path, O_WRONLY | O_TRUNC); if (fd == -1) { if (errno == ENOENT) { @@ -2578,6 +2597,7 @@ _log_dbg_sysctl_get_impl (NMPlatform *platform, const char *path, const char *co static char * sysctl_get (NMPlatform *platform, const char *path) { + nm_auto_pop_netns NMPNetns *netns = NULL; GError *error = NULL; char *contents; @@ -2587,6 +2607,9 @@ sysctl_get (NMPlatform *platform, const char *path) /* Don't write to suspicious locations */ g_assert (!strstr (path, "/../")); + if (!nm_platform_netns_push (platform, &netns)) + return NULL; + if (!g_file_get_contents (path, &contents, NULL, &error)) { /* We assume FAILED means EOPNOTSUP */ if ( g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) @@ -2651,6 +2674,9 @@ do_emit_signal (NMPlatform *platform, const NMPObject *obj, NMPCacheOpsType cach nm_assert (!obj || cache_op == NMP_CACHE_OPS_REMOVED || obj == nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, obj)); nm_assert (!obj || cache_op != NMP_CACHE_OPS_REMOVED || obj != nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, obj)); + /* we raise the signals inside the namespace of the NMPlatform instance. */ + _assert_netns_current (platform); + switch (cache_op) { case NMP_CACHE_OPS_ADDED: if (!nmp_object_is_visible (obj)) @@ -4135,11 +4161,15 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable static gboolean link_supports_carrier_detect (NMPlatform *platform, int ifindex) { + nm_auto_pop_netns NMPNetns *netns = NULL; const char *name = nm_platform_link_get_name (platform, ifindex); if (!name) return FALSE; + if (!nm_platform_netns_push (platform, &netns)) + return FALSE; + /* We use netlink for the actual carrier detection, but netlink can't tell * us whether the device actually supports carrier detection in the first * place. We assume any device that does implements one of these two APIs. @@ -4150,6 +4180,7 @@ link_supports_carrier_detect (NMPlatform *platform, int ifindex) static gboolean link_supports_vlans (NMPlatform *platform, int ifindex) { + nm_auto_pop_netns NMPNetns *netns = NULL; const NMPObject *obj; obj = cache_lookup_link (platform, ifindex); @@ -4158,6 +4189,9 @@ link_supports_vlans (NMPlatform *platform, int ifindex) if (!obj || obj->link.arptype != ARPHRD_ETHER) return FALSE; + if (!nm_platform_netns_push (platform, &netns)) + return FALSE; + return nmp_utils_ethtool_supports_vlans (obj->link.name); } @@ -4196,6 +4230,11 @@ link_get_permanent_address (NMPlatform *platform, guint8 *buf, size_t *length) { + nm_auto_pop_netns NMPNetns *netns = NULL; + + if (!nm_platform_netns_push (platform, &netns)) + return FALSE; + return nmp_utils_ethtool_get_permanent_address (nm_platform_link_get_name (platform, ifindex), buf, length); } @@ -4975,15 +5014,19 @@ wifi_get_wifi_data (NMPlatform *platform, int ifindex) return wifi_data; } +#define WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, retval) \ + nm_auto_pop_netns NMPNetns *netns = NULL; \ + WifiData *wifi_data; \ + if (!nm_platform_netns_push (platform, &netns)) \ + return retval; \ + wifi_data = wifi_get_wifi_data (platform, ifindex); \ + if (!wifi_data) \ + return retval; static gboolean wifi_get_capabilities (NMPlatform *platform, int ifindex, NMDeviceWifiCapabilities *caps) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return FALSE; - + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); if (caps) *caps = wifi_utils_get_caps (wifi_data); return TRUE; @@ -4992,90 +5035,64 @@ wifi_get_capabilities (NMPlatform *platform, int ifindex, NMDeviceWifiCapabiliti static gboolean wifi_get_bssid (NMPlatform *platform, int ifindex, guint8 *bssid) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return FALSE; + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); return wifi_utils_get_bssid (wifi_data, bssid); } static guint32 wifi_get_frequency (NMPlatform *platform, int ifindex) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return 0; + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); return wifi_utils_get_freq (wifi_data); } static gboolean wifi_get_quality (NMPlatform *platform, int ifindex) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return FALSE; + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); return wifi_utils_get_qual (wifi_data); } static guint32 wifi_get_rate (NMPlatform *platform, int ifindex) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return FALSE; + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); return wifi_utils_get_rate (wifi_data); } static NM80211Mode wifi_get_mode (NMPlatform *platform, int ifindex) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return NM_802_11_MODE_UNKNOWN; - + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, NM_802_11_MODE_UNKNOWN); return wifi_utils_get_mode (wifi_data); } static void wifi_set_mode (NMPlatform *platform, int ifindex, NM80211Mode mode) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (wifi_data) - wifi_utils_set_mode (wifi_data, mode); + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); + wifi_utils_set_mode (wifi_data, mode); } static void wifi_set_powersave (NMPlatform *platform, int ifindex, guint32 powersave) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (wifi_data) - wifi_utils_set_powersave (wifi_data, powersave); + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); + wifi_utils_set_powersave (wifi_data, powersave); } static guint32 wifi_find_frequency (NMPlatform *platform, int ifindex, const guint32 *freqs) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return 0; - + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); return wifi_utils_find_freq (wifi_data, freqs); } static void wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean running) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (wifi_data) - wifi_utils_indicate_addressing_running (wifi_data, running); + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); + wifi_utils_indicate_addressing_running (wifi_data, running); } /******************************************************************/ @@ -5083,33 +5100,21 @@ wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean ru static guint32 mesh_get_channel (NMPlatform *platform, int ifindex) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return 0; - + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); return wifi_utils_get_mesh_channel (wifi_data); } static gboolean mesh_set_channel (NMPlatform *platform, int ifindex, guint32 channel) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return FALSE; - + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); return wifi_utils_set_mesh_channel (wifi_data, channel); } static gboolean mesh_set_ssid (NMPlatform *platform, int ifindex, const guint8 *ssid, gsize len) { - WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); - - if (!wifi_data) - return FALSE; - + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); return wifi_utils_set_mesh_ssid (wifi_data, ssid, len); } @@ -5118,8 +5123,12 @@ mesh_set_ssid (NMPlatform *platform, int ifindex, const guint8 *ssid, gsize len) static gboolean link_get_wake_on_lan (NMPlatform *platform, int ifindex) { + nm_auto_pop_netns NMPNetns *netns = NULL; NMLinkType type = nm_platform_link_get_type (platform, ifindex); + if (!nm_platform_netns_push (platform, &netns)) + return FALSE; + if (type == NM_LINK_TYPE_ETHERNET) return nmp_utils_ethtool_get_wake_on_lan (nm_platform_link_get_name (platform, ifindex)); else if (type == NM_LINK_TYPE_WIFI) { @@ -5140,6 +5149,11 @@ link_get_driver_info (NMPlatform *platform, char **out_driver_version, char **out_fw_version) { + nm_auto_pop_netns NMPNetns *netns = NULL; + + if (!nm_platform_netns_push (platform, &netns)) + return FALSE; + return nmp_utils_ethtool_get_driver_info (nm_platform_link_get_name (platform, ifindex), out_driver_name, out_driver_version, @@ -5721,6 +5735,7 @@ out: static gboolean event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks) { + nm_auto_pop_netns NMPNetns *netns = NULL; NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); int r, nle; struct pollfd pfd; @@ -5733,6 +5748,9 @@ event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks) gint64 timeout_abs_ns; } data_next; + if (!nm_platform_netns_push (platform, &netns)) + return FALSE; + while (TRUE) { while (TRUE) { @@ -5837,7 +5855,14 @@ cache_update_link_udev (NMPlatform *platform, int ifindex, GUdevDevice *udev_dev NMPCacheOpsType cache_op; cache_op = nmp_cache_update_link_udev (priv->cache, ifindex, udev_device, &obj_cache, &was_visible, cache_pre_hook, platform); - do_emit_signal (platform, obj_cache, cache_op, was_visible); + + if (cache_op != NMP_CACHE_OPS_UNCHANGED) { + nm_auto_pop_netns NMPNetns *netns = NULL; + + if (!nm_platform_netns_push (platform, &netns)) + return; + do_emit_signal (platform, obj_cache, cache_op, was_visible); + } } static void @@ -5908,6 +5933,7 @@ handle_udev_event (GUdevClient *client, GUdevDevice *udev_device, gpointer user_data) { + nm_auto_pop_netns NMPNetns *netns = NULL; NMPlatform *platform = NM_PLATFORM (user_data); const char *subsys; const char *ifindex; @@ -5915,6 +5941,9 @@ handle_udev_event (GUdevClient *client, g_return_if_fail (action != NULL); + if (!nm_platform_netns_push (platform, &netns)) + return; + /* A bit paranoid */ subsys = g_udev_device_get_subsystem (udev_device); g_return_if_fail (!g_strcmp0 (subsys, "net")); @@ -5939,7 +5968,8 @@ nm_linux_platform_init (NMLinuxPlatform *self) NMLinuxPlatformPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_LINUX_PLATFORM, NMLinuxPlatformPrivate); gboolean use_udev; - use_udev = access ("/sys", W_OK) == 0; + use_udev = nmp_netns_is_initial () + && access ("/sys", W_OK) == 0; self->priv = priv; @@ -5963,7 +5993,17 @@ constructed (GObject *_object) gboolean status; int nle; - _LOGD ("create (%s udev)", + nm_assert (!platform->_netns || platform->_netns == nmp_netns_get_current ()); + + _LOGD ("create (%s netns, %s, %s udev)", + !platform->_netns ? "ignore" : "use", + !platform->_netns && nmp_netns_is_initial () + ? "initial netns" + : (!nmp_netns_get_current () + ? "no netns support" + : nm_sprintf_bufa (100, "in netns[%p]%s", + nmp_netns_get_current (), + nmp_netns_get_current () == nmp_netns_get_initial () ? "/main" : "")), nmp_cache_use_udev_get (priv->cache) ? "use" : "no"); priv->nlh = nl_socket_alloc (); |