mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF* for 2.4.10
@ 2001-10-01 10:19 Matthias Andree
  2001-10-01 19:30 ` David S. Miller
  2001-10-02  3:06 ` 2.2.19 backport of devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF* Matthias Andree
  0 siblings, 2 replies; 3+ messages in thread
From: Matthias Andree @ 2001-10-01 10:19 UTC (permalink / raw)
  To: Linus Torvalds, David S. Miller, netdev
  Cc: Linux-Kernel mailing list, Alexey Kuznetsov

Linus,

Please apply this patch to 2.4.11-preX. It's been in -ac for
some revisions now, and no-one has screamed or claimed it broke
anything. It's unchanged from my 2.4.9 version, it applies cleanly
against 2.4.10, so I'm resubmitting.

The patch is also available from
http://home.pages.de/~mandree/linux/kernel/2.4/

Best regards,
Matthias Andree

------------------------------------------------------------------------------

This is the second edition of my SIOCGIF* compatibility patch, against
Linux 2.4.9. In contrast to the first edition, it only does the "search
passed-in address" logic for SIOCGIFADDR, DSTADDR, BRDADDR and NETMASK
ioctls as suggested by Alexey Kuznetsov. It keeps the "only do this if
we got AF_INET" property.

This patch allows the aforementioned ioctls to return the proper values
for an interface that has multiple addresses with the same label, as
configured by:

ip addr 192.168.0.1/24 dev eth0
ip addr 172.16.15.14/16 dev eth0

Note that SIOCGIFCONF returns all these IP aliases, which confuses
applications that feed the data obtained from SIOCGIFCONF back into
SIOCGIFNETMASK, but do not validate the address via SIOCGIFADDR.

4.4BSD applications pass in the interface address alongside the
interface name to select the alias.

Remember, this patch falls back to interface-only match (return the
"primary" address) if at least one of these conditions is true:

- the address family is not AF_INET
- no interface alias has the address passed in

--- linux-2.4.9-f/net/ipv4/devinet.c.orig	Wed May 16 19:21:45 2001
+++ linux-2.4.9-f/net/ipv4/devinet.c	Mon Sep 17 00:39:41 2001
@@ -20,6 +20,10 @@
  *	Changes:
  *	        Alexey Kuznetsov:	pa_* fields are replaced with ifaddr lists.
  *		Cyrus Durgin:		updated for kmod
+ *		Matthias Andree:	in devinet_ioctl, compare label and 
+ *					address (4.4BSD alias style support),
+ *					fall back to comparing just the label
+ *					if no match found.
  */
 
 #include <linux/config.h>
@@ -463,6 +467,7 @@
 int devinet_ioctl(unsigned int cmd, void *arg)
 {
 	struct ifreq ifr;
+	struct sockaddr_in sin_orig;
 	struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
 	struct in_device *in_dev;
 	struct in_ifaddr **ifap = NULL;
@@ -470,6 +475,7 @@
 	struct net_device *dev;
 	char *colon;
 	int ret = 0;
+	int tryaddrmatch = 0;
 
 	/*
 	 *	Fetch the caller's info block into kernel space
@@ -479,6 +485,9 @@
 		return -EFAULT;
 	ifr.ifr_name[IFNAMSIZ-1] = 0;
 
+	/* save original address for comparison */
+	memcpy(&sin_orig, sin, sizeof(*sin));
+
 	colon = strchr(ifr.ifr_name, ':');
 	if (colon)
 		*colon = 0;
@@ -496,6 +505,7 @@
 		   so that we do not impose a lock.
 		   One day we will be forced to put shlock here (I mean SMP)
 		 */
+		tryaddrmatch = (sin_orig.sin_family == AF_INET);
 		memset(sin, 0, sizeof(*sin));
 		sin->sin_family = AF_INET;
 		break;
@@ -529,9 +539,29 @@
 		*colon = ':';
 
 	if ((in_dev=__in_dev_get(dev)) != NULL) {
-		for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
-			if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
-				break;
+		if (tryaddrmatch) {
+			/* Matthias Andree */
+			/* compare label and address (4.4BSD style) */
+			/* note: we only do this for a limited set of ioctls
+			   and only if the original address family was AF_INET.
+			   This is checked above. */
+			for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next) {
+				if ((strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
+				    && (sin_orig.sin_addr.s_addr == ifa->ifa_address)) {
+					break; /* found */
+				} /* if */
+			} /* for */
+		} else { /* tryaddrmatch */
+			ifa = NULL;
+		} /* if (tryaddrmatch) */
+		/* we didn't get a match, maybe the application is
+		   4.3BSD-style and passed in junk so we fall back to 
+		   comparing just the label */
+		if (ifa == NULL) {
+			for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
+				if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
+					break;
+		}
 	}
 
 	if (ifa == NULL && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) {

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF* for 2.4.10
  2001-10-01 10:19 devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF* for 2.4.10 Matthias Andree
@ 2001-10-01 19:30 ` David S. Miller
  2001-10-02  3:06 ` 2.2.19 backport of devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF* Matthias Andree
  1 sibling, 0 replies; 3+ messages in thread
From: David S. Miller @ 2001-10-01 19:30 UTC (permalink / raw)
  To: matthias.andree; +Cc: Torvalds, netdev, linux-kernel, kuznet

   From: Matthias Andree <matthias.andree@stud.uni-dortmund.de>
   Date: Mon, 1 Oct 2001 12:19:31 +0200

   Please apply this patch to 2.4.11-preX. It's been in -ac for
   some revisions now, and no-one has screamed or claimed it broke
   anything. It's unchanged from my 2.4.9 version, it applies cleanly
   against 2.4.10, so I'm resubmitting.

I've already submitted these changes to Linus with some cleanups
from Alexey...

Franks a lot,
David S. Miller
davem@redhat.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

* 2.2.19 backport of devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF*
  2001-10-01 10:19 devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF* for 2.4.10 Matthias Andree
  2001-10-01 19:30 ` David S. Miller
@ 2001-10-02  3:06 ` Matthias Andree
  1 sibling, 0 replies; 3+ messages in thread
From: Matthias Andree @ 2001-10-02  3:06 UTC (permalink / raw)
  To: Linux-Kernel mailing list
  Cc: Alan Cox, David S. Miller, netdev, Alexey Kuznetsov, ak

Here's that 2.4.9 patch to devinet.c backported to 2.2.19. Same
functionality, but caters for CONFIG_IP_ALIAS:

The patch is also available at
http://mandree.home.pages.de/linux/kernel/2.2/

Alan, please consider this for inclusion into your current 2.2.20pre*
series.

--- devinet.c.orig	Fri Dec 22 12:36:33 2000
+++ devinet.c	Tue Oct  2 04:29:03 2001
@@ -20,6 +20,10 @@
  *	Changes:
  *	        Alexey Kuznetsov:	pa_* fields are replaced with ifaddr lists.
  *		Cyrus Durgin:		updated for kmod
+ *		Matthias Andree:	in devinet_ioctl, compare label and 
+ *					address (4.4BSD alias style support),
+ *					fall back to comparing just the label
+ *					if no match found.
  */
 
 #include <linux/config.h>
@@ -405,6 +409,8 @@
 	struct device *dev;
 #ifdef CONFIG_IP_ALIAS
 	char *colon;
+	struct sockaddr_in sin_orig;
+	int tryaddrmatch = 0;
 #endif
 	int exclusive = 0;
 	int ret = 0;
@@ -418,6 +424,9 @@
 	ifr.ifr_name[IFNAMSIZ-1] = 0;
 
 #ifdef CONFIG_IP_ALIAS
+        /* save original address for comparison */
+ 	memcpy(&sin_orig, sin, sizeof(*sin));
+	
 	colon = strchr(ifr.ifr_name, ':');
 	if (colon)
 		*colon = 0;
@@ -436,6 +445,9 @@
 		   so that we do not impose a lock.
 		   One day we will be forced to put shlock here (I mean SMP)
 		 */
+#ifdef CONFIG_IP_ALIAS
+		tryaddrmatch = (sin_orig.sin_family == AF_INET);
+#endif
 		memset(sin, 0, sizeof(*sin));
 		sin->sin_family = AF_INET;
 		break;
@@ -473,6 +485,25 @@
 #endif
 
 	if ((in_dev=dev->ip_ptr) != NULL) {
+#ifdef CONFIG_IP_ALIAS
+		if (tryaddrmatch) {
+			/* Matthias Andree */
+			/* compare label and address (4.4BSD style) */
+			/* note: we only do this for a limited set of ioctls
+			   and only if the original address family was AF_INET.
+			   This is checked above. */
+			for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next) {
+				if ((strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
+				    && (sin_orig.sin_addr.s_addr == ifa->ifa_address)) {
+					break; /* found */
+				} /* if */
+			} /* for */
+		}
+		/* we didn't get a match, maybe the application is
+		   4.3BSD-style and passed in junk so we fall back to 
+		   comparing just the label */
+		if (ifa == NULL) 
+#endif
 		for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
 			if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
 				break;

-- 
Matthias Andree

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2001-10-02 10:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-01 10:19 devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF* for 2.4.10 Matthias Andree
2001-10-01 19:30 ` David S. Miller
2001-10-02  3:06 ` 2.2.19 backport of devinet.c 4.4BSD compatibility patch to ioctl SIOCGIF* Matthias Andree

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®