Subject: Re: kern/22792 gif and routing
To: None <tech-net@netbsd.org>
From: Michael van Elst <mlelstv@serpens.de>
List: tech-net
Date: 09/21/2003 10:57:01
mlelstv@serpens.de (Michael van Elst) writes:

Here is a small patch to the gif driver. It now expires the
cached route after 10 seconds and also when the IP specific
code is detached.

Index: net/if_gif.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_gif.h,v
retrieving revision 1.8
diff -u -r1.8 if_gif.h
--- net/if_gif.h	2001/08/16 17:45:26	1.8
+++ net/if_gif.h	2003/09/21 10:50:33
@@ -65,7 +65,9 @@
 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
 	void	*gif_si;		/* softintr handle */
 #endif
+	long     gif_route_expire;
 };
+#define GIF_ROUTE_TTL   10
 
 #define gif_ro gifsc_gifscr.gifscr_ro
 #ifdef INET6
Index: netinet/in_gif.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in_gif.c,v
retrieving revision 1.26.10.1
diff -u -r1.26.10.1 in_gif.c
--- netinet/in_gif.c	2002/07/15 16:32:46	1.26.10.1
+++ netinet/in_gif.c	2003/09/21 10:50:33
@@ -48,6 +48,7 @@
 #include <sys/ioctl.h>
 #include <sys/syslog.h>
 #include <sys/protosw.h>
+#include <sys/kernel.h>
 
 #include <net/if.h>
 #include <net/route.h>
@@ -184,8 +185,9 @@
 		return ENOBUFS;
 	bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip));
 
-	if (dst->sin_family != sin_dst->sin_family ||
-	    dst->sin_addr.s_addr != sin_dst->sin_addr.s_addr) {
+	if (sc->gif_route_expire - time.tv_sec <= 0 ||
+	    dst->sin_family != sin_dst->sin_family ||
+	    !in_hosteq(dst->sin_addr, sin_dst->sin_addr)) {
 		/* cache route doesn't match */
 		bzero(dst, sizeof(*dst));
 		dst->sin_family = sin_dst->sin_family;
@@ -209,6 +211,8 @@
 			m_freem(m);
 			return ENETUNREACH;	/*XXX*/
 		}
+
+		sc->gif_route_expire = time.tv_sec + GIF_ROUTE_TTL;
 	}
 
 	error = ip_output(m, NULL, &sc->gif_ro, 0, NULL);
@@ -431,5 +435,11 @@
 	error = encap_detach(sc->encap_cookie4);
 	if (error == 0)
 		sc->encap_cookie4 = NULL;
+
+	if (sc->gif_ro.ro_rt) {
+		RTFREE(sc->gif_ro.ro_rt);
+		sc->gif_ro.ro_rt = NULL;
+	}
+
 	return error;
 }
Index: netinet6/in6_gif.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_gif.c,v
retrieving revision 1.27
diff -u -r1.27 in6_gif.c
--- netinet6/in6_gif.c	2001/12/21 06:30:44	1.27
+++ netinet6/in6_gif.c	2003/09/21 10:50:33
@@ -49,6 +49,7 @@
 #include <sys/queue.h>
 #include <sys/syslog.h>
 #include <sys/protosw.h>
+#include <sys/kernel.h>
 
 #include <net/if.h>
 #include <net/route.h>
@@ -184,7 +185,8 @@
 	ip6->ip6_flow &= ~ntohl(0xff00000);
 	ip6->ip6_flow |= htonl((u_int32_t)otos << 20);
 
-	if (dst->sin6_family != sin6_dst->sin6_family ||
+        if ( sc->gif_route_expire - time.tv_sec <= 0 ||
+	     dst->sin6_family != sin6_dst->sin6_family ||
 	     !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr)) {
 		/* cache route doesn't match */
 		bzero(dst, sizeof(*dst));
@@ -209,6 +211,8 @@
 			m_freem(m);
 			return ENETUNREACH;	/* XXX */
 		}
+
+		sc->gif_route_expire = time.tv_sec + GIF_ROUTE_TTL;
 	}
 	
 #ifdef IPV6_MINMTU
@@ -417,6 +421,12 @@
 	error = encap_detach(sc->encap_cookie6);
 	if (error == 0)
 		sc->encap_cookie6 = NULL;
+
+	if (sc->gif_ro6.ro_rt) {
+		RTFREE(sc->gif_ro6.ro_rt);
+		sc->gif_ro6.ro_rt = NULL;
+	}
+
 	return error;
 }
 

-- 
-- 
                                Michael van Elst
Internet: mlelstv@serpens.de
                                "A potential Snark may lurk in every tree."