Date: Sun, 1 Dec 2002 20:40:09 +0700 From: pirat <pirat@access.inet.co.th> To: Maxim Sobolev <sobomax@FreeBSD.org> Cc: FreeBSD-stable@FreeBSD.org Subject: Re: options GRE in 4.7-stable Message-ID: <20021201134009.GA86354@thai-aec.org> In-Reply-To: <20021201125900.GC7921@vega.vega.com> References: <20021201030950.GC11858@thai-aec.org> <20021201125900.GC7921@vega.vega.com>
index | next in thread | previous in thread | raw e-mail
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 <sobomax@FreeBSD.org>
> To: pirat <pirat@access.inet.co.th>
> 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 <never@nevermind.kiev.ua>
> > > To: pirat sriyotha <makhamus@yahoo.com>
> > > 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 <sobomax@FreeBSD.org> 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 <sys/cdefs.h>
> 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 <hwr@pilhuhn.de>
> + *
> + * 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 <sys/param.h>
> +#include <sys/kernel.h>
> +#include <sys/malloc.h>
> +#include <sys/mbuf.h>
> +#include <sys/proc.h>
> +#include <sys/protosw.h>
> +#include <machine/bus.h>
> +#include <sys/rman.h>
> +#include <sys/socket.h>
> +#include <sys/sockio.h>
> +#include <sys/sysctl.h>
> +#include <sys/systm.h>
> +
> +#include <net/ethernet.h>
> +#include <net/if.h>
> +#include <net/if_types.h>
> +#include <net/route.h>
> +
> +#ifdef INET
> +#include <netinet/in.h>
> +#include <netinet/in_systm.h>
> +#include <netinet/in_var.h>
> +#include <netinet/ip.h>
> +#include <netinet/ip_gre.h>
> +#include <netinet/ip_var.h>
> +#include <netinet/ip_encap.h>
> +#else
> +#error "Huh? if_gre without inet?"
> +#endif
> +
> +#include <net/bpf.h>
> +
> +#include <net/net_osdep.h>
> +#include <net/if_gre.h>
> +
> +/*
> + * 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 <hwr@pilhuhn.de>
> + *
> + * 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 <sys/ioccom.h>
> +#ifdef _KERNEL
> +#include <sys/queue.h>
> +
> +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 <hwr@pilhuhn.de>
> + *
> + * 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 <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/mbuf.h>
> +#include <sys/socket.h>
> +#include <sys/socketvar.h>
> +#include <sys/protosw.h>
> +#include <sys/errno.h>
> +#include <sys/time.h>
> +#include <sys/kernel.h>
> +#include <sys/syslog.h>
> +#include <net/bpf.h>
> +#include <net/ethernet.h>
> +#include <net/if.h>
> +#include <net/netisr.h>
> +#include <net/route.h>
> +#include <net/raw_cb.h>
> +
> +#ifdef INET
> +#include <netinet/in.h>
> +#include <netinet/in_var.h>
> +#include <netinet/in_systm.h>
> +#include <netinet/ip.h>
> +#include <netinet/ip_var.h>
> +#include <netinet/ip_gre.h>
> +#include <machine/in_cksum.h>
> +#else
> +#error ip_gre input without IP?
> +#endif
> +
> +#ifdef NS
> +#include <netns/ns.h>
> +#include <netns/ns_if.h>
> +#endif
> +
> +#ifdef NETATALK
> +#include <netatalk/at.h>
> +#include <netatalk/at_var.h>
> +#include <netatalk/at_extern.h>
> +#endif
> +
> +/* Needs IP headers. */
> +#include <net/if_gre.h>
> +
> +#include <machine/stdarg.h>
> +
> +#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 <hwr@pilhuhn.de>
> + *
> + * 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 <bsd.kmod.mk>
> 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 <hwr@pilhuhn.de>
> +.\"
> +.\" 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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021201134009.GA86354>
