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:09:04 +0900


> >Very unfortunately, 6to4 is not yet supported in FreeBSD/KAME.
> >So now available options will be,
> > -Use freenet6 (for one hosts).
> > -Get IPv6 address block and connect to 6bone using gif tunnel.
> 
> 	We hope to add 6to4 support for KAME/FreeBSD very soon (next week is a
> 	good guess).   We may need some more testing before real use,
> 	but it should work.  it is in KAME/NetBSD already, I just don't have
> 	time to make it work on othre *BSDs yet...


6to4 support seems to be very important for initial IPv6
deployment on FreeBSD4.0, so I tried small additinal patches
to make it available. And It seems to work.

Could some FreeBSD4.0 user with direct internet connectivity
please try this patches and try to ping6 to my host's 6to4
address?
The procedure is,

 (1)apply this patch and rebuild your kernel

 (2)configure 6to4 interface

     I suppose that your IPv4 address is 1.2.3.4

     -configure stf interface's outer addr, using gifconfig

       gifconfig stf0 1.2.3.4 255.255.255.255

       (The destination IPv4 addr can be anything.)

     -encode your IPv4 address to hex format per 2 byte, for
      later use

       If it is 1.2.3.4, then it will be, 0102:0304.

     -encode your IPv6 address on stf interface, for later
      configuration

       The format is, like below.

         2002: 4byte v4 addr : 2byte SLA ID : 8byte interface ID

       For simplicity, I choose 0 for SLA ID, and 1 for interface ID.
       Then, if your IPv4 addr is 1.2.3.4, then your IPv6 addr on stf is,

         2002:0102:0304::1

     -configure stf interface's IPv6 addr

        Please use ifconfig.

       ifconfig stf0 inet6 2002:0102:0304::1 prefixlen 16

 (3)try pinging to my host's 6to4 address

    My machine's 6to4 address is 2002:cbb2:8dd8::1.

    Please try,

     ping6 2002:cbb2:8dd8::1

   I hope there is reply from my machine.



And here is the 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 10:09:25
@@ -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 10:09:25
@@ -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,17 @@
 
 		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) {
+			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