[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: USAGI IPv6 patches



¡Hola!

[I'm Cc: ing debian-ipv6 and USAGI lists.]

> horape@tinuviel.compendium.net.ar writes:
>  > Could we solve it like the Apache/SGI problem? Breaking the USAGI
>  > differences in reasonably-sized patches and offering them to you?

>  > Would you accept -for instance- a patch for the DOUBLE_BIND feature?

> This is exactly what we are asking for.

Attached is a patch adapted from USAGI that let us to bind different sockets
to the same port but different IP versions.

The applying of this patch would let us in the "IPV6 Sockets Accept IPV4,
Specific IPV4 Address Bindings Succeed" class with -for example- DEC Unix
and old KAME, because we yet do IPv4 mapping.

KAME people seems to want to deprecate IPv6 mapped address, and newer
versions don't let IPv6 sockets accept IPv4 connections. That's the MS
way too (they have IPv4 and IPv6 as fully different protocols) IMHO that's
the right approach and in a future we should be able to compile linux
with IPv6 support but no IPv4, but i'll ask the ngtrans people what's their
opinion and maybe send you a patch to do that.

I hope this is the start of a more fluid feedback between mainstream linux
and USAGI developers.

> Later,
> David S. Miller
> davem@redhat.com

					HoraPe
---
Horacio J. Peña
horape@compendium.com.ar
horape@uninet.edu
bofh@puntoar.net.ar
horape@hcdn.gov.ar
diff -ruN linux-2.4.0-orig/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- linux-2.4.0-orig/net/ipv4/tcp_ipv4.c	Mon Jan  1 16:01:58 2001
+++ linux/net/ipv4/tcp_ipv4.c	Fri Mar 16 02:14:18 2001
@@ -222,6 +222,31 @@
 			for( ; sk2 != NULL; sk2 = sk2->bind_next) {
 				if (sk != sk2 &&
 				    sk->bound_dev_if == sk2->bound_dev_if) {
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+					int sk2_reuse = sk2->reuse;
+					struct in6_addr *sk2_rcv_saddr6p = (sk2->state != TCP_TIME_WAIT) ?
+									&sk2->net_pinfo.af_inet6.rcv_saddr :
+									&((struct tcp_tw_bucket*)sk2)->v6_rcv_saddr;
+					if (sk2->family != PF_INET6 ||
+					    ipv6_addr_type(sk2_rcv_saddr6p) == IPV6_ADDR_MAPPED) {
+					        if (sk->rcv_saddr &&
+					            sk2->rcv_saddr &&
+					            sk->rcv_saddr != sk2->rcv_saddr)
+					                continue;
+					        if (sk_reuse && sk2_reuse &&
+					            sk2->state != TCP_LISTEN &&
+					            (sk->rcv_saddr != sk2->rcv_saddr)) {
+					                continue;
+					        }
+					} else if (!ipv6_addr_type(sk2_rcv_saddr6p) == IPV6_ADDR_ANY)
+					        continue;       /* one6 -> wild4, one4 */
+					else if (!sk->rcv_saddr)
+					        continue;       /* wild6 -> wild4 */
+					else if (sk_reuse && sk2_reuse &&
+					         sk2->state != TCP_LISTEN) {
+					        continue;
+					}
+#else
 					if (!sk_reuse	||
 					    !sk2->reuse	||
 					    sk2->state == TCP_LISTEN) {
@@ -230,6 +255,7 @@
 						    (sk2->rcv_saddr == sk->rcv_saddr))
 							break;
 					}
+#endif
 				}
 			}
 			/* If we found a conflict, fail. */
diff -ruN linux-2.4.0-orig/net/ipv4/udp.c linux/net/ipv4/udp.c
--- linux-2.4.0-orig/net/ipv4/udp.c	Thu Mar 15 23:41:35 2001
+++ linux/net/ipv4/udp.c	Fri Mar 16 02:21:54 2001
@@ -93,6 +93,7 @@
 #include <net/route.h>
 #include <net/inet_common.h>
 #include <net/checksum.h>
+#include <net/ipv6.h>
 
 /*
  *	Snmp MIB for the UDP layer
@@ -159,12 +160,34 @@
 		     sk2 = sk2->next) {
 			if (sk2->num == snum &&
 			    sk2 != sk &&
-			    sk2->bound_dev_if == sk->bound_dev_if &&
-			    (!sk2->rcv_saddr ||
+			    sk2->bound_dev_if == sk->bound_dev_if) {
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+                                struct in6_addr *sk2_rcv_saddr6p = &sk2->net_pinfo.af_inet6.rcv_saddr;
+                                if (sk2->family != PF_INET6 ||
+                                    ipv6_addr_type(sk2_rcv_saddr6p) == IPV6_ADDR_MAPPED) {
+                                    if (sk->rcv_saddr &&
+                                        sk2->rcv_saddr &&
+                                        sk->rcv_saddr != sk2->rcv_saddr)
+                                            continue;
+                                    if (sk->reuse && sk2->reuse &&
+                                        (sk->rcv_saddr != sk2->rcv_saddr)) {
+                                            continue;
+                                    }
+                                } else if (!ipv6_addr_type(sk2_rcv_saddr6p) == IPV6_ADDR_ANY)
+                                        continue;       /* one6 -> wild4, one4 */
+                                else if (!sk->rcv_saddr)
+                                        continue;       /* wild6 -> wild4 */
+                                else if (sk->reuse && sk2->reuse) {
+                                        continue;
+                                }
+#else
+			    if ((!sk2->rcv_saddr ||
 			     !sk->rcv_saddr ||
 			     sk2->rcv_saddr == sk->rcv_saddr) &&
 			    (!sk2->reuse || !sk->reuse))
 				goto fail;
+#endif
+			}
 		}
 	}
 	sk->num = snum;
diff -ruN linux-2.4.0-orig/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- linux-2.4.0-orig/net/ipv6/tcp_ipv6.c	Mon Jan  1 16:01:58 2001
+++ linux/net/ipv6/tcp_ipv6.c	Fri Mar 16 00:50:35 2001
@@ -144,16 +144,21 @@
 			for( ; sk2 != NULL; sk2 = sk2->bind_next) {
 				if (sk != sk2 &&
 				    sk->bound_dev_if == sk2->bound_dev_if) {
+				        struct in6_addr *sk2_rcv_saddr6p = sk2->state != TCP_TIME_WAIT ?
+			        				&sk2->net_pinfo.af_inet6.rcv_saddr :
+			        				&((struct tcp_tw_bucket*)sk2)->v6_rcv_saddr;
 					if (!sk_reuse	||
 					    !sk2->reuse	||
 					    sk2->state == TCP_LISTEN) {
+					        if ((sk2->family != PF_INET6 ||
+						    ipv6_addr_type(sk2_rcv_saddr6p) == IPV6_ADDR_MAPPED) &&
+						    addr_type != IPV6_ADDR_MAPPED)
+						        continue;
 						/* NOTE: IPv6 tw bucket have different format */
 						if (!sk2->rcv_saddr	||
 						    addr_type == IPV6_ADDR_ANY ||
 						    !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,
-								   sk2->state != TCP_TIME_WAIT ?
-								   &sk2->net_pinfo.af_inet6.rcv_saddr :
-								   &((struct tcp_tw_bucket*)sk)->v6_rcv_saddr) ||
+								   sk2_rcv_saddr6p) ||
 						    (addr_type==IPV6_ADDR_MAPPED && sk2->family==AF_INET &&
 						     sk->rcv_saddr==sk2->rcv_saddr))
 							break;
diff -ruN linux-2.4.0-orig/net/ipv6/udp.c linux/net/ipv6/udp.c
--- linux-2.4.0-orig/net/ipv6/udp.c	Mon Jan  1 16:01:58 2001
+++ linux/net/ipv6/udp.c	Fri Mar 16 00:54:20 2001
@@ -105,16 +105,21 @@
 		     sk2 = sk2->next) {
 			if (sk2->num == snum &&
 			    sk2 != sk &&
-			    sk2->bound_dev_if == sk->bound_dev_if &&
-			    (!sk2->rcv_saddr ||
-			     addr_type == IPV6_ADDR_ANY ||
-			     !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,
+			    sk2->bound_dev_if == sk->bound_dev_if) {
+				if ((sk2->family != PF_INET6 ||
+				    ipv6_addr_type(&sk2->net_pinfo.af_inet6.rcv_saddr) == IPV6_ADDR_MAPPED) &&
+				    addr_type != IPV6_ADDR_MAPPED)
+					continue;
+				if ((!sk2->rcv_saddr ||
+			     	     addr_type == IPV6_ADDR_ANY ||
+			             !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,
 					    &sk2->net_pinfo.af_inet6.rcv_saddr) ||
-			     (addr_type == IPV6_ADDR_MAPPED &&
-			      sk2->family == AF_INET &&
-			      sk->rcv_saddr == sk2->rcv_saddr)) &&
-			    (!sk2->reuse || !sk->reuse))
-				goto fail;
+			            (addr_type == IPV6_ADDR_MAPPED &&
+				     sk2->family == AF_INET &&
+				     sk->rcv_saddr == sk2->rcv_saddr)) &&
+				    (!sk2->reuse || !sk->reuse))
+					goto fail;
+			}
 		}
 	}

Reply to: