diff options
author | shin <shin@FreeBSD.org> | 2000-03-11 11:17:24 +0000 |
---|---|---|
committer | shin <shin@FreeBSD.org> | 2000-03-11 11:17:24 +0000 |
commit | 4897d4b884a45fa62be25d44438c46c8b795c36c (patch) | |
tree | 62045144ea41cdf658b5188ff11cd090c84f819d /sys/netinet | |
parent | 843cb7cecfa2978f81dbd98715c6cd6f8bc90bcf (diff) | |
download | FreeBSD-src-4897d4b884a45fa62be25d44438c46c8b795c36c.zip FreeBSD-src-4897d4b884a45fa62be25d44438c46c8b795c36c.tar.gz |
IPv6 6to4 support.
Now most big problem of IPv6 is getting IPv6 address
assignment.
6to4 solve the problem. 6to4 addr is defined like below,
2002: 4byte v4 addr : 2byte SLA ID : 8byte interface ID
The most important point of the address format is that an IPv4 addr
is embeded in it. So any user who has IPv4 addr can get IPv6 address
block with 2byte subnet space. Also, the IPv4 addr is used for
semi-automatic IPv6 over IPv4 tunneling.
With 6to4, getting IPv6 addr become dramatically easy.
The attached patch enable 6to4 extension, and confirmed to work,
between "Richard Seaman, Jr." <dick@tar.com> and me.
Approved by: jkh
Reviewed by: itojun
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in_gif.c | 43 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 2 | ||||
-rw-r--r-- | sys/netinet/tcp_reass.c | 2 |
3 files changed, 44 insertions, 3 deletions
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index 021c800..9348a53 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -84,6 +84,9 @@ SYSCTL_DECL(_net_inet_ip); 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 @@ in_gif_output(ifp, family, m, rt) 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 @@ in_gif_output(ifp, family, m, rt) #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,28 @@ in_gif_output(ifp, family, m, rt) 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 { + 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) @@ -233,6 +260,20 @@ in_gif_input(struct mbuf *m, int off, int proto) 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 || + IN_MULTICAST(ntohl(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 && satosin(sc->gif_pdst)->sin_addr.s_addr == INADDR_ANY) { diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index b802880..1d2d8c3 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -643,7 +643,7 @@ findpcb: #ifdef INET6 /* save packet options if user wanted */ - if (inp->in6p_flags & INP_CONTROLOPTS) { + if (isipv6 && inp->in6p_flags & INP_CONTROLOPTS) { if (inp->in6p_options) { m_freem(inp->in6p_options); inp->in6p_options = 0; diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index b802880..1d2d8c3 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -643,7 +643,7 @@ findpcb: #ifdef INET6 /* save packet options if user wanted */ - if (inp->in6p_flags & INP_CONTROLOPTS) { + if (isipv6 && inp->in6p_flags & INP_CONTROLOPTS) { if (inp->in6p_options) { m_freem(inp->in6p_options); inp->in6p_options = 0; |