IPv6: can a link-site (or global) address be configured in rc.conf?

Yoshinobu Inoue shin@nd.net.fujitsu.co.jp
Fri, 10 Mar 2000 20:39:22 +0900


> And here is the patches.

The last patches should work but I found a improvement related
to coexistence with gif, so this is the updated patches.

Thanks,
Yoshinobu Inoue

Index: net/if_gif.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_gif.c,v
retrieving revision 1.3
diff -u -r1.3 if_gif.c
--- net/if_gif.c	2000/02/27 18:36:30	1.3
+++ net/if_gif.c	2000/03/10 11:32:38
@@ -83,7 +83,7 @@
 /*
  * gif global variable definitions
  */
-int ngif = NGIF;		/* number of interfaces */
+int ngif = NGIF + 1;		/* number of interfaces. +1 for stf. */
 struct gif_softc *gif = 0;
 
 void
@@ -95,7 +95,7 @@
 
 	gif = sc = malloc (ngif * sizeof(struct gif_softc), M_DEVBUF, M_WAIT);
 	bzero(sc, ngif * sizeof(struct gif_softc));
-	for (i = 0; i < ngif; sc++, i++) {
+	for (i = 0; i < ngif - 1; sc++, i++) {  /* leave last one for stf */
 		sc->gif_if.if_name = "gif";
 		sc->gif_if.if_unit = i;
 		sc->gif_if.if_mtu    = GIF_MTU;
@@ -107,6 +107,16 @@
 		if_attach(&sc->gif_if);
 		bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int));
 	}
+	sc->gif_if.if_name = "stf";
+	sc->gif_if.if_unit = 0;
+	sc->gif_if.if_mtu    = GIF_MTU;
+	sc->gif_if.if_flags  = IFF_MULTICAST;
+	sc->gif_if.if_ioctl  = gif_ioctl;
+	sc->gif_if.if_output = gif_output;
+	sc->gif_if.if_type   = IFT_GIF;
+	sc->gif_if.if_snd.ifq_maxlen = ifqmaxlen;
+	if_attach(&sc->gif_if);
+	bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int));
 }
 
 PSEUDO_SET(gifattach, if_gif);
@@ -322,6 +332,11 @@
 
 			/* only one gif can have dst = INADDR_ANY */
 #define	satosaddr(sa) (((struct sockaddr_in *)(sa))->sin_addr.s_addr)
+
+#ifdef INET6
+			if (bcmp(ifp->if_name, "stf", 3) == 0)
+				satosaddr(dst) = INADDR_BROADCAST;
+#endif
 
 			if (satosaddr(dst) == INADDR_ANY) {
 				int i;
Index: netinet/in_gif.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_gif.c,v
retrieving revision 1.3
diff -u -r1.3 in_gif.c
--- netinet/in_gif.c	1999/12/22 19:13:18	1.3
+++ netinet/in_gif.c	2000/03/10 11:32:38
@@ -84,6 +84,9 @@
 SYSCTL_INT(_net_inet_ip, IPCTL_GIF_TTL, gifttl, CTLFLAG_RW,
 	&ip_gif_ttl,	0, "");
 
+#define IN6_IS_ADDR_6TO4(x)	(ntohs((x)->s6_addr16[0]) == 0x2002)
+#define GET_V4(x)	((struct in_addr *)(&(x)->s6_addr16[1]))
+
 int
 in_gif_output(ifp, family, m, rt)
 	struct ifnet	*ifp;
@@ -98,6 +101,9 @@
 	struct ip iphdr;	/* capsule IP header, host byte ordered */
 	int proto, error;
 	u_int8_t tos;
+#ifdef INET6
+	struct ip6_hdr *ip6 = NULL;
+#endif
 
 	if (sin_src == NULL || sin_dst == NULL ||
 	    sin_src->sin_family != AF_INET ||
@@ -124,7 +130,6 @@
 #ifdef INET6
 	case AF_INET6:
 	    {
-		struct ip6_hdr *ip6;
 		proto = IPPROTO_IPV6;
 		if (m->m_len < sizeof(*ip6)) {
 			m = m_pullup(m, sizeof(*ip6));
@@ -147,6 +152,24 @@
 
 	bzero(&iphdr, sizeof(iphdr));
 	iphdr.ip_src = sin_src->sin_addr;
+#ifdef INET6
+	/* XXX: temporal stf support hack */
+	if (bcmp(ifp->if_name, "stf", 3) == 0 && ip6 != NULL) {
+		if (IN6_IS_ADDR_6TO4(&ip6->ip6_dst))
+			iphdr.ip_dst = *GET_V4(&ip6->ip6_dst);
+		else if (rt && rt->rt_gateway->sa_family == AF_INET6) {
+			struct in6_addr *dst6;
+
+			dst6 = &((struct sockaddr_in6 *)
+				 (rt->rt_gateway))->sin6_addr;
+			if (IN6_IS_ADDR_6TO4(dst6))
+				iphdr.ip_dst = *GET_V4(dst6);
+		} else {
+			m_freem(m);
+			return ENETUNREACH;
+		}
+	} else
+#endif
 	if (ifp->if_flags & IFF_LINK0) {
 		/* multi-destination mode */
 		if (sin_dst->sin_addr.s_addr != INADDR_ANY)
@@ -232,6 +255,19 @@
 
 		if ((sc->gif_if.if_flags & IFF_UP) == 0)
 			continue;
+
+#ifdef INET6
+		/* XXX: temporal stf support hack */
+		if (proto == IPPROTO_IPV6 &&
+		    bcmp(sc->gif_if.if_name, "stf", 3) == 0 &&
+		    satosin(sc->gif_psrc)->sin_addr.s_addr ==
+		    ip->ip_dst.s_addr &&
+		    satosin(sc->gif_pdst)->sin_addr.s_addr ==
+		    INADDR_BROADCAST) {
+			gifp = &sc->gif_if;
+			break;
+		}
+#endif
 
 		if ((sc->gif_if.if_flags & IFF_LINK0)
 		 && satosin(sc->gif_psrc)->sin_addr.s_addr == ip->ip_dst.s_addr