> 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


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to