Index: udev-147/udev/udev-watch.c
===================================================================
--- udev-147.orig/udev/udev-watch.c
+++ udev-147/udev/udev-watch.c
@@ -79,13 +79,15 @@ void udev_watch_restore(struct udev *ude
 			s = device;
 			l = util_strpcpy(&s, sizeof(device), udev_get_sys_path(udev));
 			len = readlinkat(dirfd(dir), ent->d_name, s, l);
-			if (len <= 0 || len >= (ssize_t)l) {
+			if (len <= 0 || len == (ssize_t)l) {
 				unlinkat(dirfd(dir), ent->d_name, 0);
 				continue;
 			}
 			s[len] = '\0';
+
 			dbg(udev, "old watch to '%s' found\n", device);
-			dev = udev_device_new_from_syspath(udev, device);
+			dev = udev_device_new_from_id_filename(udev, s);
+
 			if (dev == NULL) {
 				unlinkat(dirfd(dir), ent->d_name, 0);
 				continue;
@@ -166,8 +168,10 @@ struct udev_device *udev_watch_lookup(st
 	s = syspath;
 	l = util_strpcpy(&s, sizeof(syspath), udev_get_sys_path(udev));
 	len = readlink(filename, s, l);
-	if (len < 0 || (size_t)len >= l)
+	if (len <= 0 || (size_t)len == l)
 		return NULL;
 	s[len] = '\0';
-	return udev_device_new_from_syspath(udev, syspath);
+
+	return udev_device_new_from_id_filename(udev, s);
+
 }
Index: udev-147/libudev/libudev-device.c
===================================================================
--- udev-147.orig/libudev/libudev-device.c
+++ udev-147/libudev/libudev-device.c
@@ -19,6 +19,7 @@
 #include <fcntl.h>
 #include <ctype.h>
 #include <sys/stat.h>
+#include <sys/ioctl.h>
 #include <net/if.h>
 
 #include "libudev.h"
@@ -422,6 +423,61 @@ struct udev_device *udev_device_new_from
 	return device;
 }
 
+struct udev_device *udev_device_new_from_id_filename(struct udev *udev, char *id)
+{
+	char type;
+	int maj, min;
+	char subsys[UTIL_PATH_SIZE];
+	char *sysname;
+
+	switch(id[0]) {
+	case 'b':
+	case 'c':
+		if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3)
+			return NULL;
+		return udev_device_new_from_devnum(udev, type, makedev(maj, min));
+	case 'n': {
+		int sk;
+		struct ifreq ifr;
+		struct udev_device *dev;
+		int ifindex;
+
+		ifindex = strtoul(&id[1], NULL, 10);
+		if (ifindex <= 0)
+			return NULL;
+
+		sk = socket(PF_INET, SOCK_DGRAM, 0);
+		if (sk < 0)
+			return NULL;
+		memset(&ifr, 0x00, sizeof(struct ifreq));
+		ifr.ifr_ifindex = ifindex;
+		if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) {
+			close(sk);
+			return NULL;
+		}
+		close(sk);
+
+		dev = udev_device_new_from_subsystem_sysname(udev, "net", ifr.ifr_name);
+		if (dev == NULL)
+			return NULL;
+		if (udev_device_get_ifindex(dev) == ifindex)
+			return dev;
+		udev_device_unref(dev);
+		return NULL;
+	}
+        case '+':
+		util_strscpy(subsys, sizeof(subsys), &id[1]);
+		sysname = strchr(subsys, ':');
+		if (sysname == NULL)
+			return NULL;
+		sysname[0] = '\0';
+		sysname = &sysname[1];
+		return udev_device_new_from_subsystem_sysname(udev, subsys, sysname);
+	default:
+		return NULL;
+	}
+}
+
 /**
  * udev_device_new_from_subsystem_sysname:
  * @udev: udev library context
Index: udev-147/libudev/libudev-private.h
===================================================================
--- udev-147.orig/libudev/libudev-private.h
+++ udev-147/libudev/libudev-private.h
@@ -65,6 +65,7 @@ struct udev_list_entry *udev_get_propert
 
 /* libudev-device.c */
 struct udev_device *udev_device_new(struct udev *udev);
+struct udev_device *udev_device_new_from_id_filename(struct udev *udev, char *id);
 int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath);
 int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem);
 int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype);
Index: udev-147/udev/udev-node.c
===================================================================
--- udev-147.orig/udev/udev-node.c
+++ udev-147/udev/udev-node.c
@@ -239,28 +239,20 @@ static const char *link_find_prioritized
 	for (;;) {
 		struct udev_device *dev_db;
 		struct dirent *dent;
-		char devpath[UTIL_PATH_SIZE];
-		char syspath[UTIL_PATH_SIZE];
-		ssize_t len;
 
 		dent = readdir(dir);
 		if (dent == NULL || dent->d_name[0] == '\0')
 			break;
 		if (dent->d_name[0] == '.')
 			continue;
-		dbg(udev, "found '%s/%s'\n", stackdir, dent->d_name);
-		len = readlinkat(dirfd(dir), dent->d_name, devpath, sizeof(devpath));
-		if (len <= 0 || len == (ssize_t)sizeof(devpath))
-			continue;
-		devpath[len] = '\0';
-		util_strscpyl(syspath, sizeof(syspath), udev_get_sys_path(udev), devpath, NULL);
-		info(udev, "found '%s' claiming '%s'\n", syspath, stackdir);
+
+		info(udev, "found '%s' claiming '%s'\n", dent->d_name, stackdir);
 
 		/* did we find ourself? */
-		if (strcmp(udev_device_get_syspath(dev), syspath) == 0)
+		if (strcmp(dent->d_name, udev_device_get_id_filename(dev)) == 0)
 			continue;
 
-		dev_db = udev_device_new_from_syspath(udev, syspath);
+		dev_db = udev_device_new_from_id_filename(udev, dent->d_name);
 		if (dev_db != NULL) {
 			const char *devnode;
 
@@ -270,7 +262,7 @@ static const char *link_find_prioritized
 				    udev_device_get_devnode(dev_db), udev_device_get_devlink_priority(dev_db));
 				if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) {
 					info(udev, "'%s' claims priority %i for '%s'\n",
-					     syspath, udev_device_get_devlink_priority(dev_db), stackdir);
+					     udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir);
 					priority = udev_device_get_devlink_priority(dev_db);
 					util_strscpy(buf, bufsize, devnode);
 					target = buf;
