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