diff options
Diffstat (limited to 'sys/netinet6/in6_gif.c')
-rw-r--r-- | sys/netinet6/in6_gif.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c index 632ff8f..41c34f2 100644 --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -93,6 +93,7 @@ in6_gif_output(ifp, family, m) struct sockaddr_in6 *sin6_src = (struct sockaddr_in6 *)sc->gif_psrc; struct sockaddr_in6 *sin6_dst = (struct sockaddr_in6 *)sc->gif_pdst; struct ip6_hdr *ip6; + struct etherip_header eiphdr; int proto, error; u_int8_t itos, otos; @@ -135,6 +136,20 @@ in6_gif_output(ifp, family, m) break; } #endif + case AF_LINK: + proto = IPPROTO_ETHERIP; + eiphdr.eip_ver = ETHERIP_VERSION & ETHERIP_VER_VERS_MASK; + eiphdr.eip_pad = 0; + /* prepend Ethernet-in-IP header */ + M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT); + if (m && m->m_len < sizeof(struct etherip_header)) + m = m_pullup(m, sizeof(struct etherip_header)); + if (m == NULL) + return ENOBUFS; + bcopy(&eiphdr, mtod(m, struct etherip_header *), + sizeof(struct etherip_header)); + break; + default: #ifdef DEBUG printf("in6_gif_output: warning: unknown family %d passed\n", @@ -301,6 +316,10 @@ in6_gif_input(mp, offp, proto) break; } #endif + case IPPROTO_ETHERIP: + af = AF_LINK; + break; + default: ip6stat.ip6s_nogif++; m_freem(m); |