about summary refs log tree commit diff
path: root/shared/nm-udev-aux
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2019-05-10 15:07:08 +0200
committerSebastien Bacher <seb128@ubuntu.com>2019-05-22 13:41:30 +0200
commitd57a1dd26f8e9859252b0983c2d2ec3b95eb5714 (patch)
tree46f1146e87af8cc7b58b751f7e575bd0abb2f59d /shared/nm-udev-aux
parentad9ed8bfb963266b4eea524131845f406cfc55d7 (diff)
parent85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (diff)
Import Debian changes 1.18.0-1ubuntu1
network-manager (1.18.0-1ubuntu1) eoan; urgency=medium

  * Update to 1.18, merge on Debian, new version includes nwe support for
    policy routing rules and for VLAN filtering for Linux bridge.
  * Remaining Ubuntu changes
    - Use systemd-resolved instead of dnsmasq
    - debian/control:
      + Depend on isc-dhcp-client instead of recommends
      + Recommend network-manager-pptp
      + Suggest avahi-autoipd for IPv4LL support
    - debian/rules, debian/network-manager.postinst:
      + Don't restart NetworkManager on upgrade but recommend restarting
        the computer
    - debian/rules, debian/network-manager.postinst:
      + Don't install sysvinit scripts or migrate from sysvinit
    - debian/network-manager.postinst:
      + Don't add the netdev group.
      + drop in an empty override file for NetworkManager to manage all
        devices for upgrade from any version, as long as there is no
        netplan configuration yet.
    - debian/default-wifi-powersave-on.conf, debian/rules:
      + Install a config file to enable WiFi powersave
    - Enable build tests
    - Add autopkgtests
    - debian/source_network-manager.py, debian/network-manager.install,
      debian/network-manager.links: Add apport hook
    - Add network-manager-config-connectivity-ubuntu package
    - NetworkManager.conf: disable MAC randomization feature. There is no
      easy way for desktop users to disable this feature yet. And there are
      reports that it doesn't work well with some systems.
    - Update Vcs links to point to Ubuntu branch
    - Add patches. See patch descriptions for more details:
      + Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
      + Update-dnsmasq-parameters.patch
      + Disable-general-with-expect.patch
      + libnm-Check-self-still-NMManager-or-not.patch
      + dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
      + Read-system-connections-from-run.patch
    - debian/tests/urfkill-integration - don't stop/start network manager
    - Revert "Add Conflicts to network-manager-dev against deprecated libraries"
      This reverts commit b4acc5e03e2b821e1cccc69529bb70826c741942.  We're still
      building libnm-glib for now, so these packages have a use in Ubuntu.
  * Removed delta, not needed anymore
    - debian/network-manager.maintscript
      + Remove /etc/dbus-1/system.d/nm-ofono.conf
Diffstat (limited to 'shared/nm-udev-aux')
-rw-r--r--shared/nm-udev-aux/nm-udev-utils.c291
-rw-r--r--shared/nm-udev-aux/nm-udev-utils.h48
2 files changed, 339 insertions, 0 deletions
diff --git a/shared/nm-udev-aux/nm-udev-utils.c b/shared/nm-udev-aux/nm-udev-utils.c
new file mode 100644
index 00000000..5d0919b3
--- /dev/null
+++ b/shared/nm-udev-aux/nm-udev-utils.c
@@ -0,0 +1,291 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* nm-udev-utils.c - udev utils functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include "nm-udev-utils.h"
+
+#include <libudev.h>
+
+struct _NMPUdevClient {
+	char **subsystems;
+	GSource *watch_source;
+	struct udev *udev;
+	struct udev_monitor *monitor;
+	NMUdevClientEvent event_handler;
+	gpointer event_user_data;
+};
+
+/*****************************************************************************/
+
+gboolean
+nm_udev_utils_property_as_boolean (const char *uproperty)
+{
+	/* taken from g_udev_device_get_property_as_boolean() */
+
+	if (uproperty) {
+		if (   strcmp (uproperty, "1") == 0
+		    || g_ascii_strcasecmp (uproperty, "true") == 0)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+const char *
+nm_udev_utils_property_decode (const char *uproperty, char **to_free)
+{
+	const char *p;
+	char *unescaped = NULL;
+	char *n = NULL;
+
+	if (!uproperty) {
+		*to_free = NULL;
+		return NULL;
+	}
+
+	p = uproperty;
+	while (*p) {
+		int a, b;
+
+		if (   p[0] == '\\'
+		    && p[1] == 'x'
+		    && (a = g_ascii_xdigit_value (p[2])) >= 0
+		    && (b = g_ascii_xdigit_value (p[3])) >= 0
+		    && (a || b)) {
+			if (!n) {
+				gssize l = p - uproperty;
+
+				unescaped = g_malloc (l + strlen (p) + 1 - 3);
+				memcpy (unescaped, uproperty, l);
+				n = &unescaped[l];
+			}
+			*n++ = (a << 4) | b;
+			p += 4;
+		} else {
+			if (n)
+				*n++ = *p;
+			p++;
+		}
+	}
+
+	if (!n) {
+		*to_free = NULL;
+		return uproperty;
+	}
+
+	*n++ = '\0';
+	return (*to_free = unescaped);
+}
+
+char *
+nm_udev_utils_property_decode_cp (const char *uproperty)
+{
+	char *cpy;
+
+	uproperty = nm_udev_utils_property_decode (uproperty, &cpy);
+	return cpy ?: g_strdup (uproperty);
+}
+
+/*****************************************************************************/
+
+static void
+_subsystem_split (const char *subsystem_full,
+                  const char **out_subsystem,
+                  const char **out_devtype,
+                  char **to_free)
+{
+	char *tmp, *s;
+
+	nm_assert (subsystem_full);
+	nm_assert (out_subsystem);
+	nm_assert (out_devtype);
+	nm_assert (to_free);
+
+	s = strstr (subsystem_full, "/");
+	if (s) {
+		tmp = g_strdup (subsystem_full);
+		s = &tmp[s - subsystem_full];
+		*s = '\0';
+		*out_subsystem = tmp;
+		*out_devtype = &s[1];
+		*to_free = tmp;
+	} else {
+		*out_subsystem = subsystem_full;
+		*out_devtype = NULL;
+		*to_free = NULL;
+	}
+}
+
+static struct udev_enumerate *
+nm_udev_utils_enumerate (struct udev *uclient,
+                         const char *const*subsystems)
+{
+	struct udev_enumerate *enumerate;
+	guint n;
+
+	enumerate = udev_enumerate_new (uclient);
+
+	if (subsystems) {
+		for (n = 0; subsystems[n]; n++) {
+			const char *subsystem;
+			const char *devtype;
+			gs_free char *to_free = NULL;
+
+			_subsystem_split (subsystems[n], &subsystem, &devtype, &to_free);
+
+			udev_enumerate_add_match_subsystem (enumerate, subsystem);
+
+			if (devtype != NULL)
+				udev_enumerate_add_match_property (enumerate, "DEVTYPE", devtype);
+		}
+	}
+
+	return enumerate;
+}
+
+struct udev *
+nm_udev_client_get_udev (NMUdevClient *self)
+{
+	g_return_val_if_fail (self, NULL);
+
+	return self->udev;
+}
+
+struct udev_enumerate *
+nm_udev_client_enumerate_new (NMUdevClient *self)
+{
+	g_return_val_if_fail (self, NULL);
+
+	return nm_udev_utils_enumerate (self->udev, (const char *const*) self->subsystems);
+}
+
+/*****************************************************************************/
+
+static gboolean
+monitor_event (GIOChannel *source,
+               GIOCondition condition,
+               gpointer user_data)
+{
+	NMUdevClient *self = user_data;
+	struct udev_device *udevice;
+
+	if (!self->monitor)
+		goto out;
+
+	udevice = udev_monitor_receive_device (self->monitor);
+	if (udevice == NULL)
+		goto out;
+
+	self->event_handler (self,
+	                     udevice,
+	                     self->event_user_data);
+	udev_device_unref (udevice);
+
+out:
+	return TRUE;
+}
+
+/**
+ * nm_udev_client_new:
+ * @subsystems: the subsystems
+ * @event_handler: callback for events
+ * @event_user_data: user-data for @event_handler
+ *
+ * Basically, it is g_udev_client_new(), and most notably
+ * g_udev_client_constructed().
+ *
+ * Returns: a new NMUdevClient instance.
+ */
+NMUdevClient *
+nm_udev_client_new (const char *const*subsystems,
+                    NMUdevClientEvent event_handler,
+                    gpointer event_user_data)
+{
+	NMUdevClient *self;
+	GIOChannel *channel;
+	guint n;
+
+	self = g_slice_new0 (NMUdevClient);
+
+	self->event_handler = event_handler;
+	self->event_user_data = event_user_data;
+	self->subsystems = subsystems && subsystems[0] ? g_strdupv ((char **) subsystems) : NULL;
+
+	self->udev = udev_new ();
+	if (!self->udev)
+		goto fail;
+
+	/* connect to event source */
+	if (self->event_handler) {
+		self->monitor = udev_monitor_new_from_netlink (self->udev, "udev");
+		if (!self->monitor)
+			goto fail;
+
+		if (self->subsystems) {
+			/* install subsystem filters to only wake up for certain events */
+			for (n = 0; self->subsystems[n]; n++) {
+				gs_free char *to_free = NULL;
+				const char *subsystem;
+				const char *devtype;
+
+				_subsystem_split (self->subsystems[n], &subsystem, &devtype, &to_free);
+				udev_monitor_filter_add_match_subsystem_devtype (self->monitor, subsystem, devtype);
+			}
+
+			/* listen to events, and buffer them */
+			udev_monitor_set_receive_buffer_size (self->monitor, 4*1024*1024);
+			udev_monitor_enable_receiving (self->monitor);
+			channel = g_io_channel_unix_new (udev_monitor_get_fd (self->monitor));
+			self->watch_source = g_io_create_watch (channel, G_IO_IN);
+			g_io_channel_unref (channel);
+			g_source_set_callback (self->watch_source, (GSourceFunc)(void (*) (void)) monitor_event, self, NULL);
+			g_source_attach (self->watch_source, g_main_context_get_thread_default ());
+			g_source_unref (self->watch_source);
+		}
+	}
+
+	return self;
+
+fail:
+	return nm_udev_client_unref (self);
+}
+
+NMUdevClient *
+nm_udev_client_unref (NMUdevClient *self)
+{
+	if (!self)
+		return NULL;
+
+	if (self->watch_source) {
+		g_source_destroy (self->watch_source);
+		self->watch_source = NULL;
+	}
+
+	udev_monitor_unref (self->monitor);
+	self->monitor = NULL;
+	udev_unref (self->udev);
+	self->udev = NULL;
+
+	g_strfreev (self->subsystems);
+
+	g_slice_free (NMUdevClient, self);
+
+	return NULL;
+}
diff --git a/shared/nm-udev-aux/nm-udev-utils.h b/shared/nm-udev-aux/nm-udev-utils.h
new file mode 100644
index 00000000..911e8a27
--- /dev/null
+++ b/shared/nm-udev-aux/nm-udev-utils.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* nm-udev-utils.h - udev utils functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ */
+
+#ifndef __NM_UDEV_UTILS_H__
+#define __NM_UDEV_UTILS_H__
+
+struct udev;
+struct udev_device;
+struct udev_enumerate;
+
+gboolean nm_udev_utils_property_as_boolean (const char *uproperty);
+const char *nm_udev_utils_property_decode    (const char *uproperty, char **to_free);
+char       *nm_udev_utils_property_decode_cp (const char *uproperty);
+
+typedef struct _NMPUdevClient NMUdevClient;
+
+typedef void (*NMUdevClientEvent) (NMUdevClient *udev_client,
+                                   struct udev_device *udevice,
+                                   gpointer event_user_data);
+
+NMUdevClient *nm_udev_client_new (const char *const*subsystems,
+                                  NMUdevClientEvent event_handler,
+                                  gpointer event_user_data);
+
+NMUdevClient *nm_udev_client_unref (NMUdevClient *self);
+
+struct udev *nm_udev_client_get_udev (NMUdevClient *self);
+
+struct udev_enumerate *nm_udev_client_enumerate_new (NMUdevClient *self);
+
+#endif /* __NM_UDEV_UTILS_H__ */