From owner-freebsd-stable Sun Dec 1 5:36:47 2002 Delivered-To: freebsd-stable@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4E1CA37B401; Sun, 1 Dec 2002 05:35:56 -0800 (PST) Received: from access.inet.co.th (access.inet.co.th [203.151.127.252]) by mx1.FreeBSD.org (Postfix) with ESMTP id B75A843EB2; Sun, 1 Dec 2002 05:35:51 -0800 (PST) (envelope-from pirat@access.inet.co.th) Received: from radwaste.thai-aec.org (TruPPP0A136.inet.co.th [203.151.124.136]) by access.inet.co.th (8.8.8/8.8.8) with ESMTP id UAA10601; Sun, 1 Dec 2002 20:35:31 +0700 (ICT) (envelope-from pirat@access.inet.co.th) Received: from firak.thai-aec.org (firak.thai-aec.org. [192.168.1.55]) by radwaste.thai-aec.org (8.12.6/8.12.5) with ESMTP id gB1DetIS000884; Sun, 1 Dec 2002 20:40:56 +0700 (ICT) (envelope-from pirat@access.inet.co.th) Received: from firak.thai-aec.org (localhost [127.0.0.1]) by firak.thai-aec.org (8.12.6/8.12.6) with ESMTP id gB1DeB6j090433; Sun, 1 Dec 2002 20:40:11 +0700 (ICT) (envelope-from pirat@access.inet.co.th) Received: (from pirat@localhost) by firak.thai-aec.org (8.12.6/8.12.6/Submit) id gB1De9mQ090432; Sun, 1 Dec 2002 20:40:09 +0700 (ICT) X-Authentication-Warning: firak.thai-aec.org: pirat set sender to pirat@access.inet.co.th using -f Date: Sun, 1 Dec 2002 20:40:09 +0700 From: pirat To: Maxim Sobolev Cc: FreeBSD-stable@FreeBSD.org Subject: Re: options GRE in 4.7-stable Message-ID: <20021201134009.GA86354@thai-aec.org> References: <20021201030950.GC11858@thai-aec.org> <20021201125900.GC7921@vega.vega.com> Mime-Version: 1.0 Content-Type: text/plain; charset=tis-620 Content-Disposition: inline In-Reply-To: <20021201125900.GC7921@vega.vega.com> User-Agent: Mutt/1.4i X-Operating-System: FreeBSD firak.thai-aec.org 4.7-STABLE FreeBSD 4.7-STABLE Sender: owner-freebsd-stable@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG hi sirs, your kindness is highly appreciated. with best regards, psr On Sun, Dec 01, 2002 at 02:59:00PM +0200, Maxim Sobolev wrote: > Date: Sun, 1 Dec 2002 14:59:00 +0200 > From: Maxim Sobolev > To: pirat > Subject: Re: options GRE in 4.7-stable > > See attached. Apply it as follows, and don't forget to recompile > your kernel after that: > > # cd /usr/src > # patch -p1 -s < /tmp/if_gre.diff > > -Maxim > > On Sun, Dec 01, 2002 at 10:09:50AM +0700, pirat wrote: > > hi sirs, > > > > i have heard from Alexandr Kovalenko that you have patch for GRE. > > may i have that patch for GRE ? > > my machine is > > > > uname -a > > FreeBSD firak.thai-aec.org 4.7-STABLE FreeBSD 4.7-STABLE #4: Fri Nov 29 04:28:21 > > ICT 2002 firak@firak.thai-aec.org:/var/obj/var/src/sys/Firak i386 > > > > thank you very much in advance. > > > > with best regards, > > pirat sriyotha > > > > On Fri, Nov 29, 2002 at 02:21:40PM +0200, Alexandr Kovalenko wrote: > > > Date: Fri, 29 Nov 2002 14:21:40 +0200 > > > From: Alexandr Kovalenko > > > To: pirat sriyotha > > > Cc: FreeBSD-stable@FreeBSD.ORG > > > Subject: Re: options GRE in 4.7-stable > > > > > > Hello, pirat sriyotha! > > > > > > On Wed, Nov 27, 2002 at 07:45:27PM -0800, you wrote: > > > > > > > i would like to ask that if options GRE is now in > > > > 4.7-stable ? > > > > > > > > if not then what options can be substituted for? > > > > > > > > thanks in advance for any hints and helps. > > > Maxim Sobolev developed patch for GRE, you can ask > > > him about that. > Index: src.gre/sys/netns/ns_if.h > =================================================================== > RCS file: /home/ncvs/src/sys/netns/ns_if.h,v > retrieving revision 1.12 > diff -d -u -r1.12 ns_if.h > --- src.gre/sys/netns/ns_if.h 29 Dec 1999 04:46:19 -0000 1.12 > +++ src.gre/sys/netns/ns_if.h 1 Dec 2002 12:44:45 -0000 > @@ -80,10 +80,10 @@ > #endif > > #ifdef _KERNEL > -struct ns_ifaddr *ns_ifaddr; > -struct ns_ifaddr *ns_iaonnetof(); > -void nsintr __P((void)); > -struct ifqueue nsintrq; /* XNS input packet queue */ > +extern struct ns_ifaddr *ns_ifaddr; > +struct ns_ifaddr *ns_iaonnetof(void); > +void nsintr(void); > +extern struct ifqueue nsintrq; /* XNS input packet queue */ > #endif > > #endif > Index: src.gre/sys/netns/ns.h > =================================================================== > RCS file: /home/ncvs/src/sys/netns/ns.h,v > retrieving revision 1.13 > diff -d -u -r1.13 ns.h > --- src.gre/sys/netns/ns.h 29 Dec 1999 04:46:19 -0000 1.13 > +++ src.gre/sys/netns/ns.h 1 Dec 2002 12:44:45 -0000 > @@ -137,12 +137,12 @@ > > #ifdef _KERNEL > extern struct domain nsdomain; > -union ns_host ns_thishost; > -union ns_host ns_zerohost; > -union ns_host ns_broadhost; > -union ns_net ns_zeronet; > -union ns_net ns_broadnet; > -u_short ns_cksum(); > +extern union ns_host ns_thishost; > +extern union ns_host ns_zerohost; > +extern union ns_host ns_broadhost; > +extern union ns_net ns_zeronet; > +extern union ns_net ns_broadnet; > +u_short ns_cksum(void); > #else > > #include > Index: src.gre/sys/net/if_gre.c > =================================================================== > RCS file: src.gre/sys/net/if_gre.c > diff -N src.gre/sys/net/if_gre.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ src.gre/sys/net/if_gre.c 1 Dec 2002 12:44:45 -0000 > @@ -0,0 +1,802 @@ > +/* $NetBSD: if_gre.c,v 1.42 2002/08/14 00:23:27 itojun Exp $ */ > +/* $FreeBSD$ */ > + > +/* > + * Copyright (c) 1998 The NetBSD Foundation, Inc. > + * All rights reserved. > + * > + * This code is derived from software contributed to The NetBSD Foundation > + * by Heiko W.Rupp > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the NetBSD > + * Foundation, Inc. and its contributors. > + * 4. Neither the name of The NetBSD Foundation nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS > + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * Encapsulate L3 protocols into IP > + * See RFC 1701 and 1702 for more details. > + * If_gre is compatible with Cisco GRE tunnels, so you can > + * have a NetBSD box as the other end of a tunnel interface of a Cisco > + * router. See gre(4) for more details. > + * Also supported: IP in IP encaps (proto 55) as of RFC 2004 > + */ > + > +#include "opt_atalk.h" > +#include "opt_inet.h" > +#include "opt_ns.h" > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#ifdef INET > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#else > +#error "Huh? if_gre without inet?" > +#endif > + > +#include > + > +#include > +#include > + > +/* > + * It is not easy to calculate the right value for a GRE MTU. > + * We leave this task to the admin and use the same default that > + * other vendors use. > + */ > +#define GREMTU 1476 > + > +#define GRENAME "gre" > +#define GRE_MAXUNIT 0x7fff > + > +static MALLOC_DEFINE(M_GRE, GRENAME, "Generic Routing Encapsulation"); > +static struct rman greunits[1]; > + > +struct gre_softc_head gre_softc_list; > + > +static int gre_clone_create(struct if_clone *, int *); > +static void gre_clone_destroy(struct ifnet *); > +static int gre_ioctl(struct ifnet *, u_long, caddr_t); > +static int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *, > + struct rtentry *rt); > + > +static struct if_clone gre_cloner = > + IF_CLONE_INITIALIZER("gre", gre_clone_create, gre_clone_destroy); > + > +static int gre_compute_route(struct gre_softc *sc); > + > +static void greattach(void); > + > +#ifdef INET > +extern struct domain inetdomain; > +static const struct protosw in_gre_protosw = > +{ SOCK_RAW, &inetdomain, IPPROTO_GRE, PR_ATOMIC|PR_ADDR, > + gre_input, rip_output, rip_ctlinput, rip_ctloutput, > + 0, > + 0, 0, 0, 0, > + &rip_usrreqs > +}; > +static const struct protosw in_mobile_protosw = > +{ SOCK_RAW, &inetdomain, IPPROTO_MOBILE, PR_ATOMIC|PR_ADDR, > + gre_mobile_input, rip_output, rip_ctlinput, rip_ctloutput, > + 0, > + 0, 0, 0, 0, > + &rip_usrreqs > +}; > +#endif > + > +SYSCTL_DECL(_net_link); > +SYSCTL_NODE(_net_link, IFT_OTHER, gre, CTLFLAG_RW, 0, > + "Generic Routing Encapsulation"); > +#ifndef MAX_GRE_NEST > +/* > + * This macro controls the default upper limitation on nesting of gre tunnels. > + * Since, setting a large value to this macro with a careless configuration > + * may introduce system crash, we don't allow any nestings by default. > + * If you need to configure nested gre tunnels, you can define this macro > + * in your kernel configuration file. However, if you do so, please be > + * careful to configure the tunnels so that it won't make a loop. > + */ > +#define MAX_GRE_NEST 1 > +#endif > +static int max_gre_nesting = MAX_GRE_NEST; > +SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW, > + &max_gre_nesting, 0, "Max nested tunnels"); > + > +/* ARGSUSED */ > +static void > +greattach(void) > +{ > + > + LIST_INIT(&gre_softc_list); > + if_clone_attach(&gre_cloner); > +} > + > +static int > +gre_clone_create(ifc, unit) > + struct if_clone *ifc; > + int *unit; > +{ > + struct resource *r; > + struct gre_softc *sc; > + > + if (*unit > GRE_MAXUNIT) > + return (ENXIO); > + > + if (*unit < 0) { > + r = rman_reserve_resource(greunits, 0, GRE_MAXUNIT, 1, > + RF_ALLOCATED | RF_ACTIVE, NULL); > + if (r == NULL) > + return (ENOSPC); > + *unit = rman_get_start(r); > + } else { > + r = rman_reserve_resource(greunits, *unit, *unit, 1, > + RF_ALLOCATED | RF_ACTIVE, NULL); > + if (r == NULL) > + return (EEXIST); > + } > + > + sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK); > + memset(sc, 0, sizeof(struct gre_softc)); > + > + sc->sc_if.if_name = GRENAME; > + sc->sc_if.if_softc = sc; > + sc->sc_if.if_unit = *unit; > + sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; > + sc->sc_if.if_type = IFT_OTHER; > + sc->sc_if.if_addrlen = 0; > + sc->sc_if.if_hdrlen = 24; /* IP + GRE */ > + sc->sc_if.if_mtu = GREMTU; > + sc->sc_if.if_flags = IFF_POINTOPOINT|IFF_MULTICAST; > + sc->sc_if.if_output = gre_output; > + sc->sc_if.if_ioctl = gre_ioctl; > + sc->g_dst.s_addr = sc->g_src.s_addr = INADDR_ANY; > + sc->g_proto = IPPROTO_GRE; > + sc->sc_if.if_flags |= IFF_LINK0; > + sc->encap = NULL; > + sc->called = 0; > + sc->r_unit = r; > + if_attach(&sc->sc_if); > + bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int32_t)); > + LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list); > + return (0); > +} > + > +static void > +gre_clone_destroy(ifp) > + struct ifnet *ifp; > +{ > + int err; > + struct gre_softc *sc = ifp->if_softc; > + > +#ifdef INET > + if (sc->encap != NULL) > + encap_detach(sc->encap); > +#endif > + LIST_REMOVE(sc, sc_list); > + bpfdetach(ifp); > + if_detach(ifp); > + > + err = rman_release_resource(sc->r_unit); > + KASSERT(err == 0, ("Unexpected error freeing resource")); > + > + free(sc, M_GRE); > +} > + > +/* > + * The output routine. Takes a packet and encapsulates it in the protocol > + * given by sc->g_proto. See also RFC 1701 and RFC 2004 > + */ > +static int > +gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, > + struct rtentry *rt) > +{ > + int error = 0; > + struct gre_softc *sc = ifp->if_softc; > + struct greip *gh; > + struct ip *ip; > + u_char osrc; > + u_short etype = 0; > + struct mobile_h mob_h; > + > + /* > + * gre may cause infinite recursion calls when misconfigured. > + * We'll prevent this by introducing upper limit. > + */ > + if (++(sc->called) > max_gre_nesting) { > + printf("%s: gre_output: recursively called too many " > + "times(%d)\n", if_name(&sc->sc_if), sc->called); > + m_freem(m); > + error = EIO; /* is there better errno? */ > + goto end; > + } > + > + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 0 || > + sc->g_src.s_addr == INADDR_ANY || sc->g_dst.s_addr == INADDR_ANY) { > + m_freem(m); > + error = ENETDOWN; > + goto end; > + } > + > + gh = NULL; > + ip = NULL; > + osrc = 0; > + > + if (ifp->if_bpf) { > + /* see comment of other if_foo.c files */ > + struct mbuf m0; > + u_int32_t af = dst->sa_family; > + > + m0.m_next = m; > + m0.m_len = 4; > + m0.m_data = (char *)⁡ > + > + bpf_mtap(ifp, &m0); > + } > + > + m->m_flags &= ~(M_BCAST|M_MCAST); > + > + if (sc->g_proto == IPPROTO_MOBILE) { > + if (dst->sa_family == AF_INET) { > + struct mbuf *m0; > + int msiz; > + > + ip = mtod(m, struct ip *); > + > + /* > + * RFC2004 specifies that fragmented diagrams shouldn't > + * be encapsulated. > + */ > + if ((ip->ip_off & IP_MF) != 0) { > + IF_DROP(&ifp->if_snd); > + m_freem(m); > + error = EINVAL; /* is there better errno? */ > + goto end; > + } > + memset(&mob_h, 0, MOB_H_SIZ_L); > + mob_h.proto = (ip->ip_p) << 8; > + mob_h.odst = ip->ip_dst.s_addr; > + ip->ip_dst.s_addr = sc->g_dst.s_addr; > + > + /* > + * If the packet comes from our host, we only change > + * the destination address in the IP header. > + * Else we also need to save and change the source > + */ > + if (in_hosteq(ip->ip_src, sc->g_src)) { > + msiz = MOB_H_SIZ_S; > + } else { > + mob_h.proto |= MOB_H_SBIT; > + mob_h.osrc = ip->ip_src.s_addr; > + ip->ip_src.s_addr = sc->g_src.s_addr; > + msiz = MOB_H_SIZ_L; > + } > + mob_h.proto = htons(mob_h.proto); > + mob_h.hcrc = gre_in_cksum((u_short *)&mob_h, msiz); > + > + if ((m->m_data - msiz) < m->m_pktdat) { > + /* need new mbuf */ > + MGETHDR(m0, M_DONTWAIT, MT_HEADER); > + if (m0 == NULL) { > + IF_DROP(&ifp->if_snd); > + m_freem(m); > + error = ENOBUFS; > + goto end; > + } > + m0->m_next = m; > + m->m_data += sizeof(struct ip); > + m->m_len -= sizeof(struct ip); > + m0->m_pkthdr.len = m->m_pkthdr.len + msiz; > + m0->m_len = msiz + sizeof(struct ip); > + m0->m_data += max_linkhdr; > + memcpy(mtod(m0, caddr_t), (caddr_t)ip, > + sizeof(struct ip)); > + m = m0; > + } else { /* we have some space left in the old one */ > + m->m_data -= msiz; > + m->m_len += msiz; > + m->m_pkthdr.len += msiz; > + bcopy(ip, mtod(m, caddr_t), > + sizeof(struct ip)); > + } > + ip = mtod(m, struct ip *); > + memcpy((caddr_t)(ip + 1), &mob_h, (unsigned)msiz); > + ip->ip_len = ntohs(ip->ip_len) + msiz; > + } else { /* AF_INET */ > + IF_DROP(&ifp->if_snd); > + m_freem(m); > + error = EINVAL; > + goto end; > + } > + } else if (sc->g_proto == IPPROTO_GRE) { > + switch (dst->sa_family) { > + case AF_INET: > + ip = mtod(m, struct ip *); > + etype = ETHERTYPE_IP; > + break; > +#ifdef NETATALK > + case AF_APPLETALK: > + etype = ETHERTYPE_ATALK; > + break; > +#endif > +#ifdef NS > + case AF_NS: > + etype = ETHERTYPE_NS; > + break; > +#endif > + default: > + IF_DROP(&ifp->if_snd); > + m_freem(m); > + error = EAFNOSUPPORT; > + goto end; > + } > + M_PREPEND(m, sizeof(struct greip), M_DONTWAIT); > + } else { > + IF_DROP(&ifp->if_snd); > + m_freem(m); > + error = EINVAL; > + goto end; > + } > + > + if (m == NULL) { /* impossible */ > + IF_DROP(&ifp->if_snd); > + error = ENOBUFS; > + goto end; > + } > + > + gh = mtod(m, struct greip *); > + if (sc->g_proto == IPPROTO_GRE) { > + /* we don't have any GRE flags for now */ > + > + memset((void *)&gh->gi_g, 0, sizeof(struct gre_h)); > + gh->gi_ptype = htons(etype); > + } > + > + gh->gi_pr = sc->g_proto; > + if (sc->g_proto != IPPROTO_MOBILE) { > + gh->gi_src = sc->g_src; > + gh->gi_dst = sc->g_dst; > + ((struct ip*)gh)->ip_hl = (sizeof(struct ip)) >> 2; > + ((struct ip*)gh)->ip_ttl = GRE_TTL; > + ((struct ip*)gh)->ip_tos = ip->ip_tos; > + ((struct ip*)gh)->ip_id = ip->ip_id; > + gh->gi_len = m->m_pkthdr.len; > + } > + > + ifp->if_opackets++; > + ifp->if_obytes += m->m_pkthdr.len; > + /* send it off */ > + error = ip_output(m, NULL, &sc->route, 0, NULL); > + end: > + sc->called = 0; > + if (error) > + ifp->if_oerrors++; > + return (error); > +} > + > +static int > +gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) > +{ > + struct ifreq *ifr = (struct ifreq *)data; > + struct if_laddrreq *lifr = (struct if_laddrreq *)data; > + struct in_aliasreq *aifr = (struct in_aliasreq *)data; > + struct gre_softc *sc = ifp->if_softc; > + int s; > + struct sockaddr_in si; > + struct sockaddr *sa = NULL; > + int error; > + struct sockaddr_in sp, sm, dp, dm; > + > + error = 0; > + > + s = splnet(); > + switch (cmd) { > + case SIOCSIFADDR: > + ifp->if_flags |= IFF_UP; > + break; > + case SIOCSIFDSTADDR: > + break; > + case SIOCSIFFLAGS: > + if ((error = suser(curproc)) != 0) > + break; > + if ((ifr->ifr_flags & IFF_LINK0) != 0) > + sc->g_proto = IPPROTO_GRE; > + else > + sc->g_proto = IPPROTO_MOBILE; > + goto recompute; > + case SIOCSIFMTU: > + if ((error = suser(curproc)) != 0) > + break; > + if (ifr->ifr_mtu < 576) { > + error = EINVAL; > + break; > + } > + ifp->if_mtu = ifr->ifr_mtu; > + break; > + case SIOCGIFMTU: > + ifr->ifr_mtu = sc->sc_if.if_mtu; > + break; > + case SIOCADDMULTI: > + case SIOCDELMULTI: > + if ((error = suser(curproc)) != 0) > + break; > + if (ifr == 0) { > + error = EAFNOSUPPORT; > + break; > + } > + switch (ifr->ifr_addr.sa_family) { > +#ifdef INET > + case AF_INET: > + break; > +#endif > + default: > + error = EAFNOSUPPORT; > + break; > + } > + break; > + case GRESPROTO: > + if ((error = suser(curproc)) != 0) > + break; > + sc->g_proto = ifr->ifr_flags; > + switch (sc->g_proto) { > + case IPPROTO_GRE: > + ifp->if_flags |= IFF_LINK0; > + break; > + case IPPROTO_MOBILE: > + ifp->if_flags &= ~IFF_LINK0; > + break; > + default: > + error = EPROTONOSUPPORT; > + break; > + } > + goto recompute; > + case GREGPROTO: > + ifr->ifr_flags = sc->g_proto; > + break; > + case GRESADDRS: > + case GRESADDRD: > + if ((error = suser(curproc)) != 0) > + break; > + /* > + * set tunnel endpoints, compute a less specific route > + * to the remote end and mark if as up > + */ > + sa = &ifr->ifr_addr; > + if (cmd == GRESADDRS) > + sc->g_src = (satosin(sa))->sin_addr; > + if (cmd == GRESADDRD) > + sc->g_dst = (satosin(sa))->sin_addr; > + recompute: > +#ifdef INET > + if (sc->encap != NULL) { > + encap_detach(sc->encap); > + sc->encap = NULL; > + } > +#endif > + if ((sc->g_src.s_addr != INADDR_ANY) && > + (sc->g_dst.s_addr != INADDR_ANY)) { > + bzero(&sp, sizeof(sp)); > + bzero(&sm, sizeof(sm)); > + bzero(&dp, sizeof(dp)); > + bzero(&dm, sizeof(dm)); > + sp.sin_len = sm.sin_len = dp.sin_len = dm.sin_len = > + sizeof(struct sockaddr_in); > + sp.sin_family = sm.sin_family = dp.sin_family = > + dm.sin_family = AF_INET; > + sp.sin_addr = sc->g_src; > + dp.sin_addr = sc->g_dst; > + sm.sin_addr.s_addr = dm.sin_addr.s_addr = > + INADDR_BROADCAST; > +#ifdef INET > + sc->encap = encap_attach(AF_INET, sc->g_proto, > + sintosa(&sp), sintosa(&sm), sintosa(&dp), > + sintosa(&dm), (sc->g_proto == IPPROTO_GRE) ? > + &in_gre_protosw : &in_mobile_protosw, sc); > + if (sc->encap == NULL) > + printf("%s: unable to attach encap\n", > + if_name(&sc->sc_if)); > +#endif > + if (sc->route.ro_rt != 0) /* free old route */ > + RTFREE(sc->route.ro_rt); > + if (gre_compute_route(sc) == 0) > + ifp->if_flags |= IFF_RUNNING; > + else > + ifp->if_flags &= ~IFF_RUNNING; > + } > + break; > + case GREGADDRS: > + memset(&si, 0, sizeof(si)); > + si.sin_family = AF_INET; > + si.sin_len = sizeof(struct sockaddr_in); > + si.sin_addr.s_addr = sc->g_src.s_addr; > + sa = sintosa(&si); > + ifr->ifr_addr = *sa; > + break; > + case GREGADDRD: > + memset(&si, 0, sizeof(si)); > + si.sin_family = AF_INET; > + si.sin_len = sizeof(struct sockaddr_in); > + si.sin_addr.s_addr = sc->g_dst.s_addr; > + sa = sintosa(&si); > + ifr->ifr_addr = *sa; > + break; > + case SIOCSIFPHYADDR: > + if ((error = suser(curproc)) != 0) > + break; > + if (aifr->ifra_addr.sin_family != AF_INET || > + aifr->ifra_dstaddr.sin_family != AF_INET) { > + error = EAFNOSUPPORT; > + break; > + } > + if (aifr->ifra_addr.sin_len != sizeof(si) || > + aifr->ifra_dstaddr.sin_len != sizeof(si)) { > + error = EINVAL; > + break; > + } > + sc->g_src = aifr->ifra_addr.sin_addr; > + sc->g_dst = aifr->ifra_dstaddr.sin_addr; > + goto recompute; > + case SIOCSLIFPHYADDR: > + if ((error = suser(curproc)) != 0) > + break; > + if (lifr->addr.ss_family != AF_INET || > + lifr->dstaddr.ss_family != AF_INET) { > + error = EAFNOSUPPORT; > + break; > + } > + if (lifr->addr.ss_len != sizeof(si) || > + lifr->dstaddr.ss_len != sizeof(si)) { > + error = EINVAL; > + break; > + } > + sc->g_src = (satosin((struct sockadrr *)&lifr->addr))->sin_addr; > + sc->g_dst = > + (satosin((struct sockadrr *)&lifr->dstaddr))->sin_addr; > + goto recompute; > + case SIOCDIFPHYADDR: > + if ((error = suser(curproc)) != 0) > + break; > + sc->g_src.s_addr = INADDR_ANY; > + sc->g_dst.s_addr = INADDR_ANY; > + goto recompute; > + case SIOCGLIFPHYADDR: > + if (sc->g_src.s_addr == INADDR_ANY || > + sc->g_dst.s_addr == INADDR_ANY) { > + error = EADDRNOTAVAIL; > + break; > + } > + memset(&si, 0, sizeof(si)); > + si.sin_family = AF_INET; > + si.sin_len = sizeof(struct sockaddr_in); > + si.sin_addr.s_addr = sc->g_src.s_addr; > + memcpy(&lifr->addr, &si, sizeof(si)); > + si.sin_addr.s_addr = sc->g_dst.s_addr; > + memcpy(&lifr->dstaddr, &si, sizeof(si)); > + break; > + case SIOCGIFPSRCADDR: > + if (sc->g_src.s_addr == INADDR_ANY) { > + error = EADDRNOTAVAIL; > + break; > + } > + memset(&si, 0, sizeof(si)); > + si.sin_family = AF_INET; > + si.sin_len = sizeof(struct sockaddr_in); > + si.sin_addr.s_addr = sc->g_src.s_addr; > + bcopy(&si, &ifr->ifr_addr, sizeof(ifr->ifr_addr)); > + break; > + case SIOCGIFPDSTADDR: > + if (sc->g_dst.s_addr == INADDR_ANY) { > + error = EADDRNOTAVAIL; > + break; > + } > + memset(&si, 0, sizeof(si)); > + si.sin_family = AF_INET; > + si.sin_len = sizeof(struct sockaddr_in); > + si.sin_addr.s_addr = sc->g_dst.s_addr; > + bcopy(&si, &ifr->ifr_addr, sizeof(ifr->ifr_addr)); > + break; > + default: > + error = EINVAL; > + break; > + } > + > + splx(s); > + return (error); > +} > + > +/* > + * computes a route to our destination that is not the one > + * which would be taken by ip_output(), as this one will loop back to > + * us. If the interface is p2p as a--->b, then a routing entry exists > + * If we now send a packet to b (e.g. ping b), this will come down here > + * gets src=a, dst=b tacked on and would from ip_ouput() sent back to > + * if_gre. > + * Goal here is to compute a route to b that is less specific than > + * a-->b. We know that this one exists as in normal operation we have > + * at least a default route which matches. > + */ > +static int > +gre_compute_route(struct gre_softc *sc) > +{ > + struct route *ro; > + u_int32_t a, b, c; > + > + ro = &sc->route; > + > + memset(ro, 0, sizeof(struct route)); > + ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = sc->g_dst; > + ro->ro_dst.sa_family = AF_INET; > + ro->ro_dst.sa_len = sizeof(ro->ro_dst); > + > + /* > + * toggle last bit, so our interface is not found, but a less > + * specific route. I'd rather like to specify a shorter mask, > + * but this is not possible. Should work though. XXX > + * there is a simpler way ... > + */ > + if ((sc->sc_if.if_flags & IFF_LINK1) == 0) { > + a = ntohl(sc->g_dst.s_addr); > + b = a & 0x01; > + c = a & 0xfffffffe; > + b = b ^ 0x01; > + a = b | c; > + ((struct sockaddr_in *)&ro->ro_dst)->sin_addr.s_addr > + = htonl(a); > + } > + > +#ifdef DIAGNOSTIC > + printf("%s: searching a route to %s", if_name(&sc->sc_if), > + inet_ntoa(((struct sockaddr_in *)&ro->ro_dst)->sin_addr)); > +#endif > + > + rtalloc(ro); > + > + /* > + * check if this returned a route at all and this route is no > + * recursion to ourself > + */ > + if (ro->ro_rt == NULL || ro->ro_rt->rt_ifp->if_softc == sc) { > +#ifdef DIAGNOSTIC > + if (ro->ro_rt == NULL) > + printf(" - no route found!\n"); > + else > + printf(" - route loops back to ourself!\n"); > +#endif > + return EADDRNOTAVAIL; > + } > + > + /* > + * now change it back - else ip_output will just drop > + * the route and search one to this interface ... > + */ > + if ((sc->sc_if.if_flags & IFF_LINK1) == 0) > + ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = sc->g_dst; > + > +#ifdef DIAGNOSTIC > + printf(", choosing %s with gateway %s", if_name(ro->ro_rt->rt_ifp), > + inet_ntoa(((struct sockaddr_in *)(ro->ro_rt->rt_gateway))->sin_addr)); > + printf("\n"); > +#endif > + > + return 0; > +} > + > +/* > + * do a checksum of a buffer - much like in_cksum, which operates on > + * mbufs. > + */ > +u_short > +gre_in_cksum(u_short *p, u_int len) > +{ > + u_int sum = 0; > + int nwords = len >> 1; > + > + while (nwords-- != 0) > + sum += *p++; > + > + if (len & 1) { > + union { > + u_short w; > + u_char c[2]; > + } u; > + u.c[0] = *(u_char *)p; > + u.c[1] = 0; > + sum += u.w; > + } > + > + /* end-around-carry */ > + sum = (sum >> 16) + (sum & 0xffff); > + sum += (sum >> 16); > + return (~sum); > +} > + > +static int > +gremodevent(module_t mod, int type, void *data) > +{ > + int err; > + > + switch (type) { > + case MOD_LOAD: > + greunits->rm_type = RMAN_ARRAY; > + greunits->rm_descr = "configurable if_gre units"; > + err = rman_init(greunits); > + if (err != 0) > + return (err); > + err = rman_manage_region(greunits, 0, GRE_MAXUNIT); > + if (err != 0) { > + printf("%s: greunits: rman_manage_region: Failed %d\n", > + GRENAME, err); > + rman_fini(greunits); > + return (err); > + } > + greattach(); > + break; > + case MOD_UNLOAD: > + if_clone_detach(&gre_cloner); > + > + while (!LIST_EMPTY(&gre_softc_list)) > + gre_clone_destroy(&LIST_FIRST(&gre_softc_list)->sc_if); > + > + err = rman_fini(greunits); > + if (err != 0) > + return (err); > + > + break; > + } > + return 0; > +} > + > +static moduledata_t gre_mod = { > + "if_gre", > + gremodevent, > + 0 > +}; > + > +DECLARE_MODULE(if_gre, gre_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); > +MODULE_VERSION(if_gre, 1); > Index: src.gre/sys/net/ethernet.h > =================================================================== > RCS file: /home/ncvs/src/sys/net/ethernet.h,v > retrieving revision 1.12.2.7 > diff -d -u -r1.12.2.7 ethernet.h > --- src.gre/sys/net/ethernet.h 4 Apr 2002 05:51:55 -0000 1.12.2.7 > +++ src.gre/sys/net/ethernet.h 1 Dec 2002 12:44:45 -0000 > @@ -60,14 +60,264 @@ > u_char octet[ETHER_ADDR_LEN]; > }; > > -#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ > +/* > + * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields. > + * However, there are some conflicts. > + */ > + > +#define ETHERTYPE_8023 0x0004 /* IEEE 802.3 packet */ > + /* 0x0101 .. 0x1FF Experimental */ > +#define ETHERTYPE_PUP 0x0200 /* Xerox PUP protocol - see 0A00 */ > +#define ETHERTYPE_PUPAT 0x0200 /* PUP Address Translation - see 0A01 */ > +#define ETHERTYPE_SPRITE 0x0500 /* ??? */ > + /* 0x0400 Nixdorf */ > +#define ETHERTYPE_NS 0x0600 /* XNS */ > +#define ETHERTYPE_NSAT 0x0601 /* XNS Address Translation (3Mb only) */ > +#define ETHERTYPE_DLOG1 0x0660 /* DLOG (?) */ > +#define ETHERTYPE_DLOG2 0x0661 /* DLOG (?) */ > #define ETHERTYPE_IP 0x0800 /* IP protocol */ > -#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ > -#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ > -#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging */ > -#define ETHERTYPE_IPV6 0x86dd /* IPv6 */ > -#define ETHERTYPE_LOOPBACK 0x9000 /* used to test interfaces */ > -/* XXX - add more useful types here */ > +#define ETHERTYPE_X75 0x0801 /* X.75 Internet */ > +#define ETHERTYPE_NBS 0x0802 /* NBS Internet */ > +#define ETHERTYPE_ECMA 0x0803 /* ECMA Internet */ > +#define ETHERTYPE_CHAOS 0x0804 /* CHAOSnet */ > +#define ETHERTYPE_X25 0x0805 /* X.25 Level 3 */ > +#define ETHERTYPE_ARP 0x0806 /* Address resolution protocol */ > +#define ETHERTYPE_NSCOMPAT 0x0807 /* XNS Compatibility */ > +#define ETHERTYPE_FRARP 0x0808 /* Frame Relay ARP (RFC1701) */ > + /* 0x081C Symbolics Private */ > + /* 0x0888 - 0x088A Xyplex */ > +#define ETHERTYPE_UBDEBUG 0x0900 /* Ungermann-Bass network debugger */ > +#define ETHERTYPE_IEEEPUP 0x0A00 /* Xerox IEEE802.3 PUP */ > +#define ETHERTYPE_IEEEPUPAT 0x0A01 /* Xerox IEEE802.3 PUP Address Translation */ > +#define ETHERTYPE_VINES 0x0BAD /* Banyan VINES */ > +#define ETHERTYPE_VINESLOOP 0x0BAE /* Banyan VINES Loopback */ > +#define ETHERTYPE_VINESECHO 0x0BAF /* Banyan VINES Echo */ > + > +/* 0x1000 - 0x100F Berkeley Trailer */ > +/* > + * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have > + * (type-ETHERTYPE_TRAIL)*512 bytes of data followed > + * by an ETHER type (as given above) and then the (variable-length) header. > + */ > +#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ > +#define ETHERTYPE_NTRAILER 16 > + > +#define ETHERTYPE_DCA 0x1234 /* DCA - Multicast */ > +#define ETHERTYPE_VALID 0x1600 /* VALID system protocol */ > +#define ETHERTYPE_DOGFIGHT 0x1989 /* Artificial Horizons ("Aviator" dogfight simulator [on Sun]) */ > +#define ETHERTYPE_RCL 0x1995 /* Datapoint Corporation (RCL lan protocol) */ > + > + /* The following 3C0x types > + are unregistered: */ > +#define ETHERTYPE_NBPVCD 0x3C00 /* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */ > +#define ETHERTYPE_NBPSCD 0x3C01 /* 3Com NBP System control datagram not registered */ > +#define ETHERTYPE_NBPCREQ 0x3C02 /* 3Com NBP Connect request (virtual cct) not registered */ > +#define ETHERTYPE_NBPCRSP 0x3C03 /* 3Com NBP Connect repsonse not registered */ > +#define ETHERTYPE_NBPCC 0x3C04 /* 3Com NBP Connect complete not registered */ > +#define ETHERTYPE_NBPCLREQ 0x3C05 /* 3Com NBP Close request (virtual cct) not registered */ > +#define ETHERTYPE_NBPCLRSP 0x3C06 /* 3Com NBP Close response not registered */ > +#define ETHERTYPE_NBPDG 0x3C07 /* 3Com NBP Datagram (like XNS IDP) not registered */ > +#define ETHERTYPE_NBPDGB 0x3C08 /* 3Com NBP Datagram broadcast not registered */ > +#define ETHERTYPE_NBPCLAIM 0x3C09 /* 3Com NBP Claim NetBIOS name not registered */ > +#define ETHERTYPE_NBPDLTE 0x3C0A /* 3Com NBP Delete Netbios name not registered */ > +#define ETHERTYPE_NBPRAS 0x3C0B /* 3Com NBP Remote adaptor status request not registered */ > +#define ETHERTYPE_NBPRAR 0x3C0C /* 3Com NBP Remote adaptor response not registered */ > +#define ETHERTYPE_NBPRST 0x3C0D /* 3Com NBP Reset not registered */ > + > +#define ETHERTYPE_PCS 0x4242 /* PCS Basic Block Protocol */ > +#define ETHERTYPE_IMLBLDIAG 0x424C /* Information Modes Little Big LAN diagnostic */ > +#define ETHERTYPE_DIDDLE 0x4321 /* THD - Diddle */ > +#define ETHERTYPE_IMLBL 0x4C42 /* Information Modes Little Big LAN */ > +#define ETHERTYPE_SIMNET 0x5208 /* BBN Simnet Private */ > +#define ETHERTYPE_DECEXPER 0x6000 /* DEC Unassigned, experimental */ > +#define ETHERTYPE_MOPDL 0x6001 /* DEC MOP dump/load */ > +#define ETHERTYPE_MOPRC 0x6002 /* DEC MOP remote console */ > +#define ETHERTYPE_DECnet 0x6003 /* DEC DECNET Phase IV route */ > +#define ETHERTYPE_DN ETHERTYPE_DECnet /* libpcap, tcpdump */ > +#define ETHERTYPE_LAT 0x6004 /* DEC LAT */ > +#define ETHERTYPE_DECDIAG 0x6005 /* DEC diagnostic protocol (at interface initialization?) */ > +#define ETHERTYPE_DECCUST 0x6006 /* DEC customer protocol */ > +#define ETHERTYPE_SCA 0x6007 /* DEC LAVC, SCA */ > +#define ETHERTYPE_AMBER 0x6008 /* DEC AMBER */ > +#define ETHERTYPE_DECMUMPS 0x6009 /* DEC MUMPS */ > + /* 0x6010 - 0x6014 3Com Corporation */ > +#define ETHERTYPE_TRANSETHER 0x6558 /* Trans Ether Bridging (RFC1701)*/ > +#define ETHERTYPE_RAWFR 0x6559 /* Raw Frame Relay (RFC1701) */ > +#define ETHERTYPE_UBDL 0x7000 /* Ungermann-Bass download */ > +#define ETHERTYPE_UBNIU 0x7001 /* Ungermann-Bass NIUs */ > +#define ETHERTYPE_UBDIAGLOOP 0x7002 /* Ungermann-Bass diagnostic/loopback */ > +#define ETHERTYPE_UBNMC 0x7003 /* Ungermann-Bass ??? (NMC to/from UB Bridge) */ > +#define ETHERTYPE_UBBST 0x7005 /* Ungermann-Bass Bridge Spanning Tree */ > +#define ETHERTYPE_OS9 0x7007 /* OS/9 Microware */ > +#define ETHERTYPE_OS9NET 0x7009 /* OS/9 Net? */ > + /* 0x7020 - 0x7029 LRT (England) (now Sintrom) */ > +#define ETHERTYPE_RACAL 0x7030 /* Racal-Interlan */ > +#define ETHERTYPE_PRIMENTS 0x7031 /* Prime NTS (Network Terminal Service) */ > +#define ETHERTYPE_CABLETRON 0x7034 /* Cabletron */ > +#define ETHERTYPE_CRONUSVLN 0x8003 /* Cronus VLN */ > +#define ETHERTYPE_CRONUS 0x8004 /* Cronus Direct */ > +#define ETHERTYPE_HP 0x8005 /* HP Probe */ > +#define ETHERTYPE_NESTAR 0x8006 /* Nestar */ > +#define ETHERTYPE_ATTSTANFORD 0x8008 /* AT&T/Stanford (local use) */ > +#define ETHERTYPE_EXCELAN 0x8010 /* Excelan */ > +#define ETHERTYPE_SG_DIAG 0x8013 /* SGI diagnostic type */ > +#define ETHERTYPE_SG_NETGAMES 0x8014 /* SGI network games */ > +#define ETHERTYPE_SG_RESV 0x8015 /* SGI reserved type */ > +#define ETHERTYPE_SG_BOUNCE 0x8016 /* SGI bounce server */ > +#define ETHERTYPE_APOLLODOMAIN 0x8019 /* Apollo DOMAIN */ > +#define ETHERTYPE_TYMSHARE 0x802E /* Tymeshare */ > +#define ETHERTYPE_TIGAN 0x802F /* Tigan, Inc. */ > +#define ETHERTYPE_REVARP 0x8035 /* Reverse addr resolution protocol */ > +#define ETHERTYPE_AEONIC 0x8036 /* Aeonic Systems */ > +#define ETHERTYPE_IPXNEW 0x8037 /* IPX (Novell Netware?) */ > +#define ETHERTYPE_LANBRIDGE 0x8038 /* DEC LANBridge */ > +#define ETHERTYPE_DSMD 0x8039 /* DEC DSM/DDP */ > +#define ETHERTYPE_ARGONAUT 0x803A /* DEC Argonaut Console */ > +#define ETHERTYPE_VAXELN 0x803B /* DEC VAXELN */ > +#define ETHERTYPE_DECDNS 0x803C /* DEC DNS Naming Service */ > +#define ETHERTYPE_ENCRYPT 0x803D /* DEC Ethernet Encryption */ > +#define ETHERTYPE_DECDTS 0x803E /* DEC Distributed Time Service */ > +#define ETHERTYPE_DECLTM 0x803F /* DEC LAN Traffic Monitor */ > +#define ETHERTYPE_DECNETBIOS 0x8040 /* DEC PATHWORKS DECnet NETBIOS Emulation */ > +#define ETHERTYPE_DECLAST 0x8041 /* DEC Local Area System Transport */ > + /* 0x8042 DEC Unassigned */ > +#define ETHERTYPE_PLANNING 0x8044 /* Planning Research Corp. */ > + /* 0x8046 - 0x8047 AT&T */ > +#define ETHERTYPE_DECAM 0x8048 /* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */ > +#define ETHERTYPE_EXPERDATA 0x8049 /* ExperData */ > +#define ETHERTYPE_VEXP 0x805B /* Stanford V Kernel exp. */ > +#define ETHERTYPE_VPROD 0x805C /* Stanford V Kernel prod. */ > +#define ETHERTYPE_ES 0x805D /* Evans & Sutherland */ > +#define ETHERTYPE_LITTLE 0x8060 /* Little Machines */ > +#define ETHERTYPE_COUNTERPOINT 0x8062 /* Counterpoint Computers */ > + /* 0x8065 - 0x8066 Univ. of Mass @ Amherst */ > +#define ETHERTYPE_VEECO 0x8067 /* Veeco Integrated Auto. */ > +#define ETHERTYPE_GENDYN 0x8068 /* General Dynamics */ > +#define ETHERTYPE_ATT 0x8069 /* AT&T */ > +#define ETHERTYPE_AUTOPHON 0x806A /* Autophon */ > +#define ETHERTYPE_COMDESIGN 0x806C /* ComDesign */ > +#define ETHERTYPE_COMPUGRAPHIC 0x806D /* Compugraphic Corporation */ > + /* 0x806E - 0x8077 Landmark Graphics Corp. */ > +#define ETHERTYPE_MATRA 0x807A /* Matra */ > +#define ETHERTYPE_DDE 0x807B /* Dansk Data Elektronik */ > +#define ETHERTYPE_MERIT 0x807C /* Merit Internodal (or Univ of Michigan?) */ > + /* 0x807D - 0x807F Vitalink Communications */ > +#define ETHERTYPE_VLTLMAN 0x8080 /* Vitalink TransLAN III Management */ > + /* 0x8081 - 0x8083 Counterpoint Computers */ > + /* 0x8088 - 0x808A Xyplex */ > +#define ETHERTYPE_ATALK 0x809B /* AppleTalk */ > +#define ETHERTYPE_AT ETHERTYPE_ATALK /* old NetBSD */ > +#define ETHERTYPE_APPLETALK ETHERTYPE_ATALK /* HP-UX */ > + /* 0x809C - 0x809E Datability */ > +#define ETHERTYPE_SPIDER 0x809F /* Spider Systems Ltd. */ > + /* 0x80A3 Nixdorf */ > + /* 0x80A4 - 0x80B3 Siemens Gammasonics Inc. */ > + /* 0x80C0 - 0x80C3 DCA (Digital Comm. Assoc.) Data Exchange Cluster */ > + /* 0x80C4 - 0x80C5 Banyan Systems */ > +#define ETHERTYPE_PACER 0x80C6 /* Pacer Software */ > +#define ETHERTYPE_APPLITEK 0x80C7 /* Applitek Corporation */ > + /* 0x80C8 - 0x80CC Intergraph Corporation */ > + /* 0x80CD - 0x80CE Harris Corporation */ > + /* 0x80CF - 0x80D2 Taylor Instrument */ > + /* 0x80D3 - 0x80D4 Rosemount Corporation */ > +#define ETHERTYPE_SNA 0x80D5 /* IBM SNA Services over Ethernet */ > +#define ETHERTYPE_VARIAN 0x80DD /* Varian Associates */ > + /* 0x80DE - 0x80DF TRFS (Integrated Solutions Transparent Remote File System) */ > + /* 0x80E0 - 0x80E3 Allen-Bradley */ > + /* 0x80E4 - 0x80F0 Datability */ > +#define ETHERTYPE_RETIX 0x80F2 /* Retix */ > +#define ETHERTYPE_AARP 0x80F3 /* AppleTalk AARP */ > + /* 0x80F4 - 0x80F5 Kinetics */ > +#define ETHERTYPE_APOLLO 0x80F7 /* Apollo Computer */ > +#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging (XXX conflicts) */ > + /* 0x80FF - 0x8101 Wellfleet Communications (XXX conflicts) */ > +#define ETHERTYPE_BOFL 0x8102 /* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */ > +#define ETHERTYPE_WELLFLEET 0x8103 /* Wellfleet Communications */ > + /* 0x8107 - 0x8109 Symbolics Private */ > +#define ETHERTYPE_TALARIS 0x812B /* Talaris */ > +#define ETHERTYPE_WATERLOO 0x8130 /* Waterloo Microsystems Inc. (XXX which?) */ > +#define ETHERTYPE_HAYES 0x8130 /* Hayes Microcomputers (XXX which?) */ > +#define ETHERTYPE_VGLAB 0x8131 /* VG Laboratory Systems */ > + /* 0x8132 - 0x8137 Bridge Communications */ > +#define ETHERTYPE_IPX 0x8137 /* Novell (old) NetWare IPX (ECONFIG E option) */ > +#define ETHERTYPE_NOVELL 0x8138 /* Novell, Inc. */ > + /* 0x8139 - 0x813D KTI */ > +#define ETHERTYPE_MUMPS 0x813F /* M/MUMPS data sharing */ > +#define ETHERTYPE_AMOEBA 0x8145 /* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */ > +#define ETHERTYPE_FLIP 0x8146 /* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */ > +#define ETHERTYPE_VURESERVED 0x8147 /* Vrije Universiteit (NL) [reserved] */ > +#define ETHERTYPE_LOGICRAFT 0x8148 /* Logicraft */ > +#define ETHERTYPE_NCD 0x8149 /* Network Computing Devices */ > +#define ETHERTYPE_ALPHA 0x814A /* Alpha Micro */ > +#define ETHERTYPE_SNMP 0x814C /* SNMP over Ethernet (see RFC1089) */ > + /* 0x814D - 0x814E BIIN */ > +#define ETHERTYPE_TEC 0x814F /* Technically Elite Concepts */ > +#define ETHERTYPE_RATIONAL 0x8150 /* Rational Corp */ > + /* 0x8151 - 0x8153 Qualcomm */ > + /* 0x815C - 0x815E Computer Protocol Pty Ltd */ > + /* 0x8164 - 0x8166 Charles River Data Systems */ > +#define ETHERTYPE_XTP 0x817D /* Protocol Engines XTP */ > +#define ETHERTYPE_SGITW 0x817E /* SGI/Time Warner prop. */ > +#define ETHERTYPE_HIPPI_FP 0x8180 /* HIPPI-FP encapsulation */ > +#define ETHERTYPE_STP 0x8181 /* Scheduled Transfer STP, HIPPI-ST */ > + /* 0x8182 - 0x8183 Reserved for HIPPI-6400 */ > + /* 0x8184 - 0x818C SGI prop. */ > +#define ETHERTYPE_MOTOROLA 0x818D /* Motorola */ > +#define ETHERTYPE_NETBEUI 0x8191 /* PowerLAN NetBIOS/NetBEUI (PC) */ > + /* 0x819A - 0x81A3 RAD Network Devices */ > + /* 0x81B7 - 0x81B9 Xyplex */ > + /* 0x81CC - 0x81D5 Apricot Computers */ > + /* 0x81D6 - 0x81DD Artisoft Lantastic */ > + /* 0x81E6 - 0x81EF Polygon */ > + /* 0x81F0 - 0x81F2 Comsat Labs */ > + /* 0x81F3 - 0x81F5 SAIC */ > + /* 0x81F6 - 0x81F8 VG Analytical */ > + /* 0x8203 - 0x8205 QNX Software Systems Ltd. */ > + /* 0x8221 - 0x8222 Ascom Banking Systems */ > + /* 0x823E - 0x8240 Advanced Encryption Systems */ > + /* 0x8263 - 0x826A Charles River Data Systems */ > + /* 0x827F - 0x8282 Athena Programming */ > + /* 0x829A - 0x829B Inst Ind Info Tech */ > + /* 0x829C - 0x82AB Taurus Controls */ > + /* 0x82AC - 0x8693 Walker Richer & Quinn */ > +#define ETHERTYPE_ACCTON 0x8390 /* Accton Technologies (unregistered) */ > +#define ETHERTYPE_TALARISMC 0x852B /* Talaris multicast */ > +#define ETHERTYPE_KALPANA 0x8582 /* Kalpana */ > + /* 0x8694 - 0x869D Idea Courier */ > + /* 0x869E - 0x86A1 Computer Network Tech */ > + /* 0x86A3 - 0x86AC Gateway Communications */ > +#define ETHERTYPE_SECTRA 0x86DB /* SECTRA */ > +#define ETHERTYPE_IPV6 0x86DD /* IP protocol version 6 */ > +#define ETHERTYPE_DELTACON 0x86DE /* Delta Controls */ > +#define ETHERTYPE_ATOMIC 0x86DF /* ATOMIC */ > + /* 0x86E0 - 0x86EF Landis & Gyr Powers */ > + /* 0x8700 - 0x8710 Motorola */ > +#define ETHERTYPE_RDP 0x8739 /* Control Technology Inc. RDP Without IP */ > +#define ETHERTYPE_MICP 0x873A /* Control Technology Inc. Mcast Industrial Ctrl Proto. */ > + /* 0x873B - 0x873C Control Technology Inc. Proprietary */ > +#define ETHERTYPE_TCPCOMP 0x876B /* TCP/IP Compression (RFC1701) */ > +#define ETHERTYPE_IPAS 0x876C /* IP Autonomous Systems (RFC1701) */ > +#define ETHERTYPE_SECUREDATA 0x876D /* Secure Data (RFC1701) */ > +#define ETHERTYPE_FLOWCONTROL 0x8808 /* 802.3x flow control packet */ > +#define ETHERTYPE_PPP 0x880B /* PPP (obsolete by PPPOE) */ > +#define ETHERTYPE_HITACHI 0x8820 /* Hitachi Cable (Optoelectronic Systems Laboratory) */ > +#define ETHERTYPE_MPLS 0x8847 /* MPLS Unicast */ > +#define ETHERTYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */ > +#define ETHERTYPE_AXIS 0x8856 /* Axis Communications AB proprietary bootstrap/config */ > +#define ETHERTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */ > +#define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */ > +#define ETHERTYPE_LANPROBE 0x8888 /* HP LanProbe test? */ > +#define ETHERTYPE_LOOPBACK 0x9000 /* Loopback: used to test interfaces */ > +#define ETHERTYPE_LBACK ETHERTYPE_LOOPBACK /* DEC MOP loopback */ > +#define ETHERTYPE_XNSSM 0x9001 /* 3Com (Formerly Bridge Communications), XNS Systems Management */ > +#define ETHERTYPE_TCPSM 0x9002 /* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */ > +#define ETHERTYPE_BCLOOP 0x9003 /* 3Com (Formerly Bridge Communications), loopback detection */ > +#define ETHERTYPE_DEBNI 0xAAAA /* DECNET? Used by VAX 6220 DEBNI */ > +#define ETHERTYPE_SONIX 0xFAF5 /* Sonix Arpeggio */ > +#define ETHERTYPE_VITAL 0xFF00 /* BBN VITAL-LanBridge cache wakeups */ > + /* 0xFF00 - 0xFFOF ISC Bunker Ramo */ > + > +#define ETHERTYPE_MAX 0xFFFF /* Maximum valid ethernet type, reserved */ > > /* > * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have > Index: src.gre/sys/net/if_gre.h > =================================================================== > RCS file: src.gre/sys/net/if_gre.h > diff -N src.gre/sys/net/if_gre.h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ src.gre/sys/net/if_gre.h 1 Dec 2002 12:44:46 -0000 > @@ -0,0 +1,174 @@ > +/* $NetBSD: if_gre.h,v 1.10 2002/02/24 17:22:20 martin Exp $ */ > +/* $FreeBSD$ */ > + > +/* > + * Copyright (c) 1998 The NetBSD Foundation, Inc. > + * All rights reserved > + * > + * This code is derived from software contributed to The NetBSD Foundation > + * by Heiko W.Rupp > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the NetBSD > + * Foundation, Inc. and its contributors. > + * 4. Neither the name of The NetBSD Foundation nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS > + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef _NET_IF_GRE_H > +#define _NET_IF_GRE_H > + > +#include > +#ifdef _KERNEL > +#include > + > +struct gre_softc { > + struct ifnet sc_if; > + LIST_ENTRY(gre_softc) sc_list; > + int gre_unit; > + int gre_flags; > + struct in_addr g_src; /* source address of gre packets */ > + struct in_addr g_dst; /* destination address of gre packets */ > + struct route route; /* routing entry that determines, where a > + encapsulated packet should go */ > + u_char g_proto; /* protocol of encapsulator */ > + > + const struct encaptab *encap; /* encapsulation cookie */ > + > + int called; /* infinite recursion preventer */ > + > + struct resource *r_unit;/* resource allocated for this unit */ > +}; > + > + > +struct gre_h { > + u_int16_t flags; /* GRE flags */ > + u_int16_t ptype; /* protocol type of payload typically > + Ether protocol type*/ > +/* > + * from here on: fields are optional, presence indicated by flags > + * > + u_int_16 checksum checksum (one-complements of GRE header > + and payload > + Present if (ck_pres | rt_pres == 1). > + Valid if (ck_pres == 1). > + u_int_16 offset offset from start of routing filed to > + first octet of active SRE (see below). > + Present if (ck_pres | rt_pres == 1). > + Valid if (rt_pres == 1). > + u_int_32 key inserted by encapsulator e.g. for > + authentication > + Present if (key_pres ==1 ). > + u_int_32 seq_num Sequence number to allow for packet order > + Present if (seq_pres ==1 ). > + struct gre_sre[] routing Routing fileds (see below) > + Present if (rt_pres == 1) > + */ > +} __attribute__((__packed__)); > + > +struct greip { > + struct ip gi_i; > + struct gre_h gi_g; > +} __attribute__((__packed__)); > + > +#define gi_pr gi_i.ip_p > +#define gi_len gi_i.ip_len > +#define gi_src gi_i.ip_src > +#define gi_dst gi_i.ip_dst > +#define gi_ptype gi_g.ptype > +#define gi_flags gi_g.flags > + > +#define GRE_CP 0x8000 /* Checksum Present */ > +#define GRE_RP 0x4000 /* Routing Present */ > +#define GRE_KP 0x2000 /* Key Present */ > +#define GRE_SP 0x1000 /* Sequence Present */ > +#define GRE_SS 0x0800 /* Strict Source Route */ > + > +/* > + * CISCO uses special type for GRE tunnel created as part of WCCP > + * connection, while in fact those packets are just IPv4 encapsulated > + * into GRE. > + */ > +#define WCCP_PROTOCOL_TYPE 0x883E > + > +/* > + * gre_sre defines a Source route Entry. These are needed if packets > + * should be routed over more than one tunnel hop by hop > + */ > +struct gre_sre { > + u_int16_t sre_family; /* adress family */ > + u_char sre_offset; /* offset to first octet of active entry */ > + u_char sre_length; /* number of octets in the SRE. > + sre_lengthl==0 -> last entry. */ > + u_char *sre_rtinfo; /* the routing information */ > +}; > + > +struct greioctl { > + int unit; > + struct in_addr addr; > +}; > + > +/* for mobile encaps */ > + > +struct mobile_h { > + u_int16_t proto; /* protocol and S-bit */ > + u_int16_t hcrc; /* header checksum */ > + u_int32_t odst; /* original destination address */ > + u_int32_t osrc; /* original source addr, if S-bit set */ > +} __attribute__((__packed__)); > + > +struct mobip_h { > + struct ip mi; > + struct mobile_h mh; > +} __attribute__((__packed__)); > + > + > +#define MOB_H_SIZ_S (sizeof(struct mobile_h) - sizeof(u_int32_t)) > +#define MOB_H_SIZ_L (sizeof(struct mobile_h)) > +#define MOB_H_SBIT 0x0080 > + > +#define GRE_TTL 30 > + > +#endif /* _KERNEL */ > + > +/* > + * ioctls needed to manipulate the interface > + */ > + > +#define GRESADDRS _IOW('i', 101, struct ifreq) > +#define GRESADDRD _IOW('i', 102, struct ifreq) > +#define GREGADDRS _IOWR('i', 103, struct ifreq) > +#define GREGADDRD _IOWR('i', 104, struct ifreq) > +#define GRESPROTO _IOW('i' , 105, struct ifreq) > +#define GREGPROTO _IOWR('i', 106, struct ifreq) > + > +#ifdef _KERNEL > +LIST_HEAD(gre_softc_head, gre_softc); > +extern struct gre_softc_head gre_softc_list; > + > +u_short gre_in_cksum(u_short *p, u_int len); > +#endif /* _KERNEL */ > + > +#endif > Index: src.gre/sys/netatalk/at.h > =================================================================== > RCS file: /home/ncvs/src/sys/netatalk/at.h,v > retrieving revision 1.5 > diff -d -u -r1.5 at.h > --- src.gre/sys/netatalk/at.h 3 Feb 1998 21:56:42 -0000 1.5 > +++ src.gre/sys/netatalk/at.h 1 Dec 2002 12:44:46 -0000 > @@ -19,6 +19,8 @@ > * Ann Arbor, Michigan > * +1-313-763-0525 > * netatalk@itd.umich.edu > + * > + * $FreeBSD$ > */ > > #ifndef __AT_HEADER__ > @@ -28,14 +30,6 @@ > */ > #define ATPROTO_DDP 0 > #define ATPROTO_AARP 254 > - > -/* > - * Ethernet types, for DIX. > - * These should really be in some global header file, but we can't > - * count on them being there, and it's annoying to patch system files. > - */ > -#define ETHERTYPE_AT 0x809B /* AppleTalk protocol */ > -#define ETHERTYPE_AARP 0x80F3 /* AppleTalk ARP */ > > #define DDP_MAXSZ 587 > > Index: src.gre/sys/conf/options > =================================================================== > RCS file: /home/ncvs/src/sys/conf/options,v > retrieving revision 1.191.2.44 > diff -d -u -r1.191.2.44 options > --- src.gre/sys/conf/options 1 Sep 2002 07:18:21 -0000 1.191.2.44 > +++ src.gre/sys/conf/options 1 Dec 2002 12:44:46 -0000 > @@ -284,6 +284,7 @@ > LIBMCHAIN > NCP opt_ncp.h > NETATALK opt_atalk.h > +NS opt_ns.h > PPP_BSDCOMP opt_ppp.h > PPP_DEFLATE opt_ppp.h > PPP_FILTER opt_ppp.h > Index: src.gre/sys/conf/files > =================================================================== > RCS file: /home/ncvs/src/sys/conf/files,v > retrieving revision 1.340.2.124 > diff -d -u -r1.340.2.124 files > --- src.gre/sys/conf/files 21 Nov 2002 23:45:37 -0000 1.340.2.124 > +++ src.gre/sys/conf/files 1 Dec 2002 12:44:46 -0000 > @@ -738,6 +738,7 @@ > net/if_faith.c optional faith > net/if_fddisubr.c optional fddi > net/if_gif.c optional gif > +net/if_gre.c optional gre > net/if_loop.c optional loop > net/if_media.c standard > net/if_mib.c standard > @@ -894,6 +895,7 @@ > netinet/igmp.c optional inet > netinet/in.c optional inet > #netinet/in_hostcache.c optional inet > +netinet/ip_gre.c optional gre inet > netinet/ip_id.c optional inet > netinet/in_pcb.c optional inet > netinet/in_proto.c optional inet > Index: src.gre/sys/netinet/ip_gre.c > =================================================================== > RCS file: src.gre/sys/netinet/ip_gre.c > diff -N src.gre/sys/netinet/ip_gre.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ src.gre/sys/netinet/ip_gre.c 1 Dec 2002 12:44:48 -0000 > @@ -0,0 +1,352 @@ > +/* $NetBSD: ip_gre.c,v 1.21 2002/08/14 00:23:30 itojun Exp $ */ > +/* $FreeBSD$ */ > + > +/* > + * Copyright (c) 1998 The NetBSD Foundation, Inc. > + * All rights reserved. > + * > + * This code is derived from software contributed to The NetBSD Foundation > + * by Heiko W.Rupp > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the NetBSD > + * Foundation, Inc. and its contributors. > + * 4. Neither the name of The NetBSD Foundation nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS > + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * deencapsulate tunneled packets and send them on > + * output half is in net/if_gre.[ch] > + * This currently handles IPPROTO_GRE, IPPROTO_MOBILE > + */ > + > +#include "opt_inet.h" > +#include "opt_ns.h" > +#include "opt_atalk.h" > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#ifdef INET > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#else > +#error ip_gre input without IP? > +#endif > + > +#ifdef NS > +#include > +#include > +#endif > + > +#ifdef NETATALK > +#include > +#include > +#include > +#endif > + > +/* Needs IP headers. */ > +#include > + > +#include > + > +#if 1 > +void gre_inet_ntoa(struct in_addr in); /* XXX */ > +#endif > + > +static struct gre_softc *gre_lookup(struct mbuf *, u_int8_t); > + > +static int gre_input2(struct mbuf *, int, u_char); > + > +/* > + * De-encapsulate a packet and feed it back through ip input (this > + * routine is called whenever IP gets a packet with proto type > + * IPPROTO_GRE and a local destination address). > + * This really is simple > + */ > +void > +#if __STDC__ > +gre_input(struct mbuf *m, ...) > +#else > +gre_input(m, va_alist) > + struct mbuf *m; > + va_dcl > +#endif > +{ > + int off, ret, proto; > + va_list ap; > + > + va_start(ap, m); > + off = va_arg(ap, int); > + va_end(ap); > + proto = (mtod(m, struct ip *))->ip_p; > + > + ret = gre_input2(m, off, proto); > + /* > + * ret == 0 : packet not processed, meaning that > + * no matching tunnel that is up is found. > + * we inject it to raw ip socket to see if anyone picks it up. > + */ > + if (ret == 0) > + rip_input(m, off, proto); > +} > + > +/* > + * decapsulate. > + * Does the real work and is called from gre_input() (above) > + * returns 0 if packet is not yet processed > + * and 1 if it needs no further processing > + * proto is the protocol number of the "calling" foo_input() > + * routine. > + */ > + > +static int > +gre_input2(struct mbuf *m ,int hlen, u_char proto) > +{ > + struct greip *gip = mtod(m, struct greip *); > + int s; > + struct ifqueue *ifq; > + struct gre_softc *sc; > + u_short flags; > + > + if ((sc = gre_lookup(m, proto)) == NULL) { > + /* No matching tunnel or tunnel is down. */ > + return (0); > + } > + > + sc->sc_if.if_ipackets++; > + sc->sc_if.if_ibytes += m->m_pkthdr.len; > + > + switch (proto) { > + case IPPROTO_GRE: > + hlen += sizeof (struct gre_h); > + > + /* process GRE flags as packet can be of variable len */ > + flags = ntohs(gip->gi_flags); > + > + /* Checksum & Offset are present */ > + if ((flags & GRE_CP) | (flags & GRE_RP)) > + hlen += 4; > + /* We don't support routing fields (variable length) */ > + if (flags & GRE_RP) > + return(0); > + if (flags & GRE_KP) > + hlen += 4; > + if (flags & GRE_SP) > + hlen +=4; > + > + switch (ntohs(gip->gi_ptype)) { /* ethertypes */ > + case ETHERTYPE_IP: /* shouldn't need a schednetisr(), as */ > + case WCCP_PROTOCOL_TYPE: /* we are in ip_input */ > + ifq = &ipintrq; > + break; > +#ifdef NS > + case ETHERTYPE_NS: > + ifq = &nsintrq; > + schednetisr(NETISR_NS); > + break; > +#endif > +#ifdef NETATALK > + case ETHERTYPE_ATALK: > + ifq = &atintrq1; > + schednetisr(NETISR_ATALK); > + break; > +#endif > + case ETHERTYPE_IPV6: > + /* FALLTHROUGH */ > + default: /* others not yet supported */ > + return(0); > + } > + break; > + default: > + /* others not yet supported */ > + return(0); > + } > + > + m->m_data += hlen; > + m->m_len -= hlen; > + m->m_pkthdr.len -= hlen; > + > + if (sc->sc_if.if_bpf) { > + struct mbuf m0; > + u_int32_t af = AF_INET; > + > + m0.m_next = m; > + m0.m_len = 4; > + m0.m_data = (char *)⁡ > + > + bpf_mtap(&(sc->sc_if), &m0); > + } > + > + m->m_pkthdr.rcvif = &sc->sc_if; > + > + s = splnet(); /* possible */ > + if (_IF_QFULL(ifq)) { > + IF_DROP(ifq); > + m_freem(m); > + } else { > + IF_ENQUEUE(ifq,m); > + } > + splx(s); > + > + return(1); /* packet is done, no further processing needed */ > +} > + > +/* > + * input routine for IPPRPOTO_MOBILE > + * This is a little bit diffrent from the other modes, as the > + * encapsulating header was not prepended, but instead inserted > + * between IP header and payload > + */ > + > +void > +#if __STDC__ > +gre_mobile_input(struct mbuf *m, ...) > +#else > +gre_mobile_input(m, va_alist) > + struct mbuf *m; > + va_dcl > +#endif > +{ > + struct ip *ip = mtod(m, struct ip *); > + struct mobip_h *mip = mtod(m, struct mobip_h *); > + struct ifqueue *ifq; > + struct gre_softc *sc; > + int hlen,s; > + va_list ap; > + u_char osrc = 0; > + int msiz; > + > + va_start(ap,m); > + hlen = va_arg(ap, int); > + va_end(ap); > + > + if ((sc = gre_lookup(m, IPPROTO_MOBILE)) == NULL) { > + /* No matching tunnel or tunnel is down. */ > + m_freem(m); > + return; > + } > + > + sc->sc_if.if_ipackets++; > + sc->sc_if.if_ibytes += m->m_pkthdr.len; > + > + if(ntohs(mip->mh.proto) & MOB_H_SBIT) { > + osrc = 1; > + msiz = MOB_H_SIZ_L; > + mip->mi.ip_src.s_addr = mip->mh.osrc; > + } else { > + msiz = MOB_H_SIZ_S; > + } > + mip->mi.ip_dst.s_addr = mip->mh.odst; > + mip->mi.ip_p = (ntohs(mip->mh.proto) >> 8); > + > + if (gre_in_cksum((u_short*)&mip->mh,msiz) != 0) { > + m_freem(m); > + return; > + } > + > + bcopy((caddr_t)(ip) + (ip->ip_hl << 2) + msiz, (caddr_t)(ip) + > + (ip->ip_hl << 2), m->m_len - msiz - (ip->ip_hl << 2)); > + m->m_len -= msiz; > + m->m_pkthdr.len -= msiz; > + > + /* > + * On FreeBSD, rip_input() supplies us with ip->ip_len > + * already converted into host byteorder and also decreases > + * it by the lengh of IP header, however, ip_input() expects > + * that this field is in the original format (network byteorder > + * and full size of IP packet), so that adjust accordingly. > + */ > + ip->ip_len = htons(ip->ip_len + sizeof(struct ip) - msiz); > + > + ip->ip_sum = 0; > + ip->ip_sum = in_cksum(m, (ip->ip_hl << 2)); > + > + if (sc->sc_if.if_bpf) { > + struct mbuf m0; > + u_int af = AF_INET; > + > + m0.m_next = m; > + m0.m_len = 4; > + m0.m_data = (char *)⁡ > + > + bpf_mtap(&(sc->sc_if), &m0); > + } > + > + m->m_pkthdr.rcvif = &sc->sc_if; > + > + ifq = &ipintrq; > + s = splnet(); /* possible */ > + if (_IF_QFULL(ifq)) { > + IF_DROP(ifq); > + m_freem(m); > + } else { > + IF_ENQUEUE(ifq,m); > + } > + splx(s); > +} > + > +/* > + * Find the gre interface associated with our src/dst/proto set. > + */ > +static struct gre_softc * > +gre_lookup(m, proto) > + struct mbuf *m; > + u_int8_t proto; > +{ > + struct ip *ip = mtod(m, struct ip *); > + struct gre_softc *sc; > + > + for (sc = LIST_FIRST(&gre_softc_list); sc != NULL; > + sc = LIST_NEXT(sc, sc_list)) { > + if ((sc->g_dst.s_addr == ip->ip_src.s_addr) && > + (sc->g_src.s_addr == ip->ip_dst.s_addr) && > + (sc->g_proto == proto) && > + ((sc->sc_if.if_flags & IFF_UP) != 0)) > + return (sc); > + } > + > + return (NULL); > +} > Index: src.gre/sys/netinet/in_proto.c > =================================================================== > RCS file: /home/ncvs/src/sys/netinet/in_proto.c,v > retrieving revision 1.53.2.4 > diff -d -u -r1.53.2.4 in_proto.c > --- src.gre/sys/netinet/in_proto.c 24 Jul 2001 19:10:18 -0000 1.53.2.4 > +++ src.gre/sys/netinet/in_proto.c 1 Dec 2002 12:44:48 -0000 > @@ -162,6 +162,18 @@ > encap_init, 0, 0, 0, > &rip_usrreqs > }, > +{ SOCK_RAW, &inetdomain, IPPROTO_MOBILE, PR_ATOMIC|PR_ADDR|PR_LASTHDR, > + encap4_input, 0, 0, rip_ctloutput, > + 0, > + encap_init, 0, 0, 0, > + &rip_usrreqs > +}, > +{ SOCK_RAW, &inetdomain, IPPROTO_GRE, PR_ATOMIC|PR_ADDR|PR_LASTHDR, > + encap4_input, 0, 0, rip_ctloutput, > + 0, > + encap_init, 0, 0, 0, > + &rip_usrreqs > +}, > # ifdef INET6 > { SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR|PR_LASTHDR, > encap4_input, 0, 0, rip_ctloutput, > Index: src.gre/sys/netinet/ip_gre.h > =================================================================== > RCS file: src.gre/sys/netinet/ip_gre.h > diff -N src.gre/sys/netinet/ip_gre.h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ src.gre/sys/netinet/ip_gre.h 1 Dec 2002 12:44:48 -0000 > @@ -0,0 +1,43 @@ > +/* $NetBSD: ip_gre.h,v 1.5 2002/06/09 16:33:40 itojun Exp $ */ > +/* $FreeBSD$ */ > + > +/* > + * Copyright (c) 1998 The NetBSD Foundation, Inc. > + * All rights reserved. > + * > + * This code is derived from software contributed to The NetBSD Foundation > + * by Heiko W.Rupp > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the NetBSD > + * Foundation, Inc. and its contributors. > + * 4. Neither the name of The NetBSD Foundation nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS > + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifdef _KERNEL > +void gre_input(struct mbuf *, ...); > +void gre_mobile_input(struct mbuf *, ...); > +#endif /* _KERNEL */ > Index: src.gre/sys/netinet/in.h > =================================================================== > RCS file: /home/ncvs/src/sys/netinet/in.h,v > retrieving revision 1.48.2.8 > diff -d -u -r1.48.2.8 in.h > --- src.gre/sys/netinet/in.h 2 May 2002 02:36:50 -0000 1.48.2.8 > +++ src.gre/sys/netinet/in.h 1 Dec 2002 12:44:48 -0000 > @@ -101,7 +101,9 @@ > #define IPPROTO_INLSP 52 /* Integ. Net Layer Security */ > #define IPPROTO_SWIPE 53 /* IP with encryption */ > #define IPPROTO_NHRP 54 /* Next Hop Resolution */ > -/* 55-57: Unassigned */ > +#define IPPROTO_MOBILE 55 /* IP Mobility */ > +#define IPPROTO_TLSP 56 /* Transport Layer Security */ > +#define IPPROTO_SKIP 57 /* SKIP */ > #define IPPROTO_ICMPV6 58 /* ICMP6 */ > #define IPPROTO_NONE 59 /* IP6 no next header */ > #define IPPROTO_DSTOPTS 60 /* IP6 destination option */ > @@ -477,6 +479,9 @@ > > int prison_ip __P((struct proc *p, int flag, u_int32_t *ip)); > void prison_remote_ip __P((struct proc *p, int flag, u_int32_t *ip)); > + > +#define in_hosteq(s, t) ((s).s_addr == (t).s_addr) > +#define in_nullhost(x) ((x).s_addr == INADDR_ANY) > > #define satosin(sa) ((struct sockaddr_in *)(sa)) > #define sintosa(sin) ((struct sockaddr *)(sin)) > Index: src.gre/sys/modules/if_gre/Makefile > =================================================================== > RCS file: src.gre/sys/modules/if_gre/Makefile > diff -N src.gre/sys/modules/if_gre/Makefile > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ src.gre/sys/modules/if_gre/Makefile 1 Dec 2002 12:44:48 -0000 > @@ -0,0 +1,17 @@ > +# $FreeBSD$ > + > +.PATH: ${.CURDIR}/../../net ${.CURDIR}/../../netinet > + > +KMOD= if_gre > +SRCS= if_gre.c ip_gre.c opt_inet.h opt_ns.h opt_atalk.h > + > +opt_inet.h: > + echo "#define INET 1" > ${.TARGET} > + > +opt_ns.h: > + echo "#define NS 1" > ${.TARGET} > + > +opt_atalk.h: > + echo "#define NETATALK 1" > ${.TARGET} > + > +.include > Index: src.gre/sys/modules/Makefile > =================================================================== > RCS file: /home/ncvs/src/sys/modules/Makefile,v > retrieving revision 1.110.2.62 > diff -d -u -r1.110.2.62 Makefile > --- src.gre/sys/modules/Makefile 21 Nov 2002 23:42:20 -0000 1.110.2.62 > +++ src.gre/sys/modules/Makefile 1 Dec 2002 12:44:48 -0000 > @@ -27,6 +27,7 @@ > if_ef \ > if_faith \ > if_gif \ > + if_gre \ > if_ppp \ > if_sl \ > if_stf \ > Index: src.gre/sys/i386/conf/LINT > =================================================================== > RCS file: /home/ncvs/src/sys/i386/conf/Attic/LINT,v > retrieving revision 1.749.2.133 > diff -d -u -r1.749.2.133 LINT > --- src.gre/sys/i386/conf/LINT 22 Nov 2002 01:34:57 -0000 1.749.2.133 > +++ src.gre/sys/i386/conf/LINT 1 Dec 2002 12:44:51 -0000 > @@ -495,6 +495,8 @@ > # The `gif' pseudo-device implements IPv6 over IP4 tunneling, > # IPv4 over IPv6 tunneling, IPv4 over IPv4 tunneling and > # IPv6 over IPv6 tunneling. > +# The `gre' device implements two types of IP4 over IP4 tunneling: > +# GRE and MOBILE, as specified in the RFC1701 and RFC2004. > # The `faith' pseudo-device captures packets sent to it and diverts them > # to the IPv4/IPv6 translation daemon. > # The `stf' device implements 6to4 encapsulation. > @@ -518,6 +520,7 @@ > pseudo-device disc #Discard device (ds0, ds1, etc) > pseudo-device tun #Tunnel driver (ppp(8), nos-tun(8)) > pseudo-device sl 2 #Serial Line IP > +pseudo-device gre #IP over IP tunneling > pseudo-device ppp 2 #Point-to-point protocol > options PPP_BSDCOMP #PPP BSD-compress support > options PPP_DEFLATE #PPP zlib/deflate/gzip support > Index: src.gre/share/man/man4/Makefile > =================================================================== > RCS file: /home/ncvs/src/share/man/man4/Makefile,v > retrieving revision 1.83.2.52 > diff -d -u -r1.83.2.52 Makefile > --- src.gre/share/man/man4/Makefile 21 Nov 2002 01:28:16 -0000 1.83.2.52 > +++ src.gre/share/man/man4/Makefile 1 Dec 2002 12:44:51 -0000 > @@ -46,6 +46,7 @@ > fwohci.4 \ > fxp.4 \ > gif.4 \ > + gre.4 \ > gusc.4 \ > gx.4 \ > ichsmb.4 \ > Index: src.gre/share/man/man4/gre.4 > =================================================================== > RCS file: src.gre/share/man/man4/gre.4 > diff -N src.gre/share/man/man4/gre.4 > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ src.gre/share/man/man4/gre.4 1 Dec 2002 12:44:51 -0000 > @@ -0,0 +1,279 @@ > +.\" $NetBSD: gre.4,v 1.28 2002/06/10 02:49:35 itojun Exp $ > +.\" $FreeBSD$ > +.\" > +.\" Copyright 1998 (c) The NetBSD Foundation, Inc. > +.\" All rights reserved. > +.\" > +.\" This code is derived from software contributed to The NetBSD Foundation > +.\" by Heiko W.Rupp > +.\" > +.\" Redistribution and use in source and binary forms, with or without > +.\" modification, are permitted provided that the following conditions > +.\" are met: > +.\" 1. Redistributions of source code must retain the above copyright > +.\" notice, this list of conditions and the following disclaimer. > +.\" 2. Redistributions in binary form must reproduce the above copyright > +.\" notice, this list of conditions and the following disclaimer in the > +.\" documentation and/or other materials provided with the distribution. > +.\" 3. All advertising materials mentioning features or use of this software > +.\" must display the following acknowledgement: > +.\" This product includes software developed by the NetBSD > +.\" Foundation, Inc. and its contributors. > +.\" 4. Neither the name of the The NetBSD Foundation nor the names of its > +.\" contributors may be used to endorse or promote products derived > +.\" from this software without specific prior written permission. > +.\" > +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS > +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS > +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > +.\" POSSIBILITY OF SUCH DAMAGE. > +.\" > +.Dd June 9, 2002 > +.Dt GRE 4 > +.Os > +.Sh NAME > +.Nm gre > +.Nd encapsulating network device > +.Sh SYNOPSIS > +.Cd pseudo-device gre > +.Sh DESCRIPTION > +The > +.Nm gre > +network interface pseudo device encapsulates datagrams > +into IP. These encapsulated datagrams are routed to a destination host, > +where they are decapsulated and further routed to their final destination. > +The > +.Dq tunnel > +appears to the inner datagrams as one hop. > +.Pp > +.Nm > +interfaces are dynamically created and destroyed with the > +.Xr ifconfig 8 > +.Cm create > +and > +.Cm destroy > +subcommands. > +.Pp > +This driver currently supports the following modes of operation: > +.Bl -tag -width abc > +.It GRE encapsulation (IP protocol number 47) > +Encapsulated datagrams are > +prepended an outer datagram and a GRE header. The GRE header specifies > +the type of the encapsulated datagram and thus allows for tunneling other > +protocols than IP like e.g. AppleTalk. GRE mode is also the default tunnel > +mode on Cisco routers. This is also the default mode of operation of the > +.Sy gre Ns Ar X > +interfaces. > +.It MOBILE encapsulation (IP protocol number 55) > +Datagrams are > +encapsulated into IP, but with a shorter encapsulation. The original > +IP header is modified and the modifications are inserted between the > +so modified header and the original payload. Like > +.Xr gif 4 , > +only for IP in IP encapsulation. > +.El > +.Pp > +The > +.Sy gre Ns Ar X > +interfaces support a number of > +.Xr ioctl 2 Ns s , > +such as: > +.Bl -tag -width aaa > +.It GRESADDRS : > +Set the IP address of the local tunnel end. This is the source address > +set by or displayed by ifconfig for the > +.Sy gre Ns Ar X > +interface. > +.It GRESADDRD : > +Set the IP address of the remote tunnel end. This is the destination address > +set by or displayed by ifconfig for the > +.Sy gre Ns Ar X > +interface. > +.It GREGADDRS : > +Query the IP address that is set for the local tunnel end. This is the > +address the encapsulation header carries as local address (i.e. the real > +address of the tunnel start point.) > +.It GREGADDRD : > +Query the IP address that is set for the remote tunnel end. This is the > +address the encapsulated packets are sent to (i.e. the real address of > +the remote tunnel endpoint.) > +.It GRESPROTO : > +Set the operation mode to the specified IP protocol value. The > +protocol is passed to the interface in (struct ifreq)-\*[Gt]ifr_flags. > +The operation mode can also be given as > +.Bl -tag -width link0xxx > +.It link0 > +IPPROTO_GRE > +.It -link0 > +IPPROTO_MOBILE > +.El > +.Pp > +to > +.Xr ifconfig 8 . > +.Pp > +The link1 flag is not used to choose encapsulation, but to modify the > +internal route search for the remote tunnel endpoint, see the > +.Sx BUGS > +section below. > +.It GREGPROTO : > +Query operation mode. > +.El > +.Pp > +Note that the IP addresses of the tunnel endpoints may be the same as the > +ones defined with > +.Xr ifconfig 8 > +for the interface (as if IP is encapsulated), but need not be, as e.g. when > +encapsulating AppleTalk. > +.Sh EXAMPLES > +Configuration example: > +.Bd -literal > +Host X-- Host A ----------------tunnel---------- cisco D------Host E > + \\ | > + \\ / > + +------Host B----------Host C----------+ > +.Ed > +On host A > +.Ns ( Nx ) : > +.Bd -literal > + # route add default B > + # ifconfig greN create > + # ifconfig greN A D netmask 0xffffffff linkX up > + # ifconfig greN tunnel A D > + # route add E D > +.Ed > +On Host D (Cisco): > +.Bd -literal > + Interface TunnelX > + ip unnumbered D ! e.g. address from Ethernet interface > + tunnel source D ! e.g. address from Ethernet interface > + tunnel destination A > + ip route C \*[Lt]some interface and mask\*[Gt] > + ip route A mask C > + ip route X mask tunnelX > +.Ed > +OR > +On Host D > +.Ns ( Nx ) : > +.Bd -literal > + # route add default C > + # ifconfig greN create > + # ifconfig greN D A > + # ifconfig tunnel greN D A > +.Ed > +.Pp > +If all goes well, you should see packets flowing ;-) > +.Pp > +If you want to reach Host A over the tunnel (from Host D (Cisco)), then > +you have to have an alias on Host A for e.g. the Ethernet interface like: > +.Bd -literal > + ifconfig \*[Lt]etherif\*[Gt] alias Y > +.Ed > +and on the cisco > +.Bd -literal > + ip route Y mask tunnelX > +.Ed > +.Pp > +A similar setup can be used to create a link between two private networks > +(for example in the 192.168 subnet) over the Internet: > +.Bd -literal > +192.168.1.* --- Router A -------tunnel-------- Router B --- 192.168.2.* > + \\ / > + \\ / > + +----- the Internet ------+ > +.Ed > +Assuming router A has the (external) IP address A and the internal address > +192.168.1.1, while router B has external address B and internal address > +192.168.2.1, the following commands will configure the tunnel: > +.Pp > +On router A: > +.Bd -literal > + # ifconfig greN create > + # ifconfig greN 192.168.1.1 192.168.2.1 link1 > + # ifconfig greN tunnel A B > + # route add -net 192.168.2 -netmask 255.255.255.0 192.168.2.1 > +.Ed > +.Pp > +On router B: > +.Bd -literal > + # ifconfig greN create > + # ifconfig greN 192.168.2.1 192.168.1.1 link1 > + # ifconfig greN tunnel B A > + # route add -net 192.168.1 -netmask 255.255.255.0 192.168.1.1 > +.Ed > +.Pp > +Note that this is a safe situation where the link1 flag (as discussed in the > +.Sx BUGS > +section below) may (and probably should) be set. > +.Sh NOTES > +The MTU of > +.Sy gre Ns Ar X > +interfaces is set to 1476 by default to match the value used by Cisco routers. > +This may not be an optimal value, depending on the link between the two tunnel > +endpoints. It can be adjusted via > +.Xr ifconfig 8 . > +.Pp > +For correct operation, the > +.Nm > +device needs a route to the destination that is less specific than the > +one over the tunnel. > +(Basically, there needs to be a route to the decapsulating host that > +does not run over the tunnel, as this would be a loop.) > +If the addresses are ambiguous, doing the > +.Xr ifconfig 8 > +.Li tunnel > +step before the > +.Xr ifconfig 8 > +call to set the > +.Sy gre Ns Ar X > +IP addresses will help to find a route outside the tunnel. > +.Pp > +In order to tell > +.Xr ifconfig 8 > +to actually mark the interface as up, the keyword > +.Dq up > +must be given last on its command line. > +.Pp > +The kernel must be set to forward datagrams by either option > +.Em GATEWAY > +in the kernel config file or by issuing the appropriate option to > +.Xr sysctl 8 . > +.Sh SEE ALSO > +.Xr atalk 4 , > +.Xr gif 4 , > +.Xr inet 4 , > +.Xr ip 4 , > +.Xr netintro 4 , > +.Xr options 4 , > +.Xr protocols 5 , > +.Xr ifconfig 8 , > +.Xr sysctl 8 > +.Pp > +A description of GRE encapsulation can be found in RFC 1701 and RFC 1702. > +.Pp > +A description of MOBILE encapsulation can be found in RFC 2004. > +.Sh AUTHORS > +.An Heiko W.Rupp Aq hwr@pilhuhn.de > +.Sh BUGS > +The compute_route() code in if_gre.c toggles the last bit of the > +IP-address to provoke the search for a less specific route than the > +one directly over the tunnel to prevent loops. This is possibly not > +the best solution. > +.Pp > +To avoid the address munging described above, turn on the link1 flag > +on the > +.Xr ifconfig 8 > +command line. > +This implies that the GRE packet destination and the ifconfig remote host > +are not the same IP addresses, and that the GRE destination does not route > +over the > +.Sy gre Ns Ar X > +interface itself. > +.Pp > +The GRE RFCs are not yet fully implemented (no GRE options). To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message