Deleted Added
sdiff udiff text old ( 103026 ) new ( 103032 )
full compact
1/* $NetBSD: if_gre.c,v 1.42 2002/08/14 00:23:27 itojun Exp $ */
2/* $FreeBSD: head/sys/net/if_gre.c 103032 2002-09-06 18:16:03Z sobomax $ */
3
4/*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Heiko W.Rupp <hwr@pilhuhn.de>
10 *

--- 31 unchanged lines hidden (view full) ---

42 * See RFC 1701 and 1702 for more details.
43 * If_gre is compatible with Cisco GRE tunnels, so you can
44 * have a NetBSD box as the other end of a tunnel interface of a Cisco
45 * router. See gre(4) for more details.
46 * Also supported: IP in IP encaps (proto 55) as of RFC 2004
47 */
48
49#include <sys/cdefs.h>
50__RCSID("@(#) $FreeBSD: head/sys/net/if_gre.c 103032 2002-09-06 18:16:03Z sobomax $");
51
52#include "opt_inet.h"
53#include "opt_ns.h"
54#include "bpf.h"
55
56#include <sys/param.h>
57#include <sys/kernel.h>
58#include <sys/malloc.h>

--- 51 unchanged lines hidden (view full) ---

110 */
111#define GREMTU 1476
112
113#define GRENAME "gre"
114
115static MALLOC_DEFINE(M_GRE, GRENAME, "Generic Routing Encapsulation");
116
117struct gre_softc_head gre_softc_list;
118
119static int gre_clone_create __P((struct if_clone *, int));
120static void gre_clone_destroy __P((struct ifnet *));
121static int gre_ioctl(struct ifnet *, u_long, caddr_t);
122static int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *,
123 struct rtentry *rt);
124
125static struct if_clone gre_cloner =
126 IF_CLONE_INITIALIZER("gre", gre_clone_create, gre_clone_destroy, 0, IF_MAXUNIT);
127
128static int gre_compute_route(struct gre_softc *sc);
129
130static void greattach __P((void));
131
132#ifdef INET
133extern struct domain inetdomain;
134static const struct protosw in_gre_protosw =
135{ SOCK_RAW, &inetdomain, IPPROTO_GRE, PR_ATOMIC|PR_ADDR,
136 (pr_input_t*)gre_input, (pr_output_t*)rip_output, rip_ctlinput, rip_ctloutput,
137 0,
138 0, 0, 0, 0,

--- 22 unchanged lines hidden (view full) ---

161 */
162#define MAX_GRE_NEST 1
163#endif
164static int max_gre_nesting = MAX_GRE_NEST;
165SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW,
166 &max_gre_nesting, 0, "Max nested tunnels");
167
168/* ARGSUSED */
169static void
170greattach(void)
171{
172
173 LIST_INIT(&gre_softc_list);
174 if_clone_attach(&gre_cloner);
175}
176
177static int
178gre_clone_create(ifc, unit)
179 struct if_clone *ifc;
180 int unit;
181{
182 struct gre_softc *sc;
183
184 sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK);
185 memset(sc, 0, sizeof(struct gre_softc));

--- 17 unchanged lines hidden (view full) ---

203 if_attach(&sc->sc_if);
204#if NBPF
205 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int32_t));
206#endif
207 LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list);
208 return (0);
209}
210
211static void
212gre_clone_destroy(ifp)
213 struct ifnet *ifp;
214{
215 struct gre_softc *sc = ifp->if_softc;
216
217#ifdef INET
218 if (sc->encap != NULL)
219 encap_detach(sc->encap);

--- 5 unchanged lines hidden (view full) ---

225 if_detach(ifp);
226 free(sc, M_GRE);
227}
228
229/*
230 * The output routine. Takes a packet and encapsulates it in the protocol
231 * given by sc->g_proto. See also RFC 1701 and RFC 2004
232 */
233static int
234gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
235 struct rtentry *rt)
236{
237 int error = 0;
238 struct gre_softc *sc = ifp->if_softc;
239 struct greip *gh;
240 struct ip *ip;
241 u_char osrc;

--- 155 unchanged lines hidden (view full) ---

397 gh->gi_ptype = htons(etype);
398 }
399
400 gh->gi_pr = sc->g_proto;
401 if (sc->g_proto != IPPROTO_MOBILE) {
402 gh->gi_src = sc->g_src;
403 gh->gi_dst = sc->g_dst;
404 ((struct ip*)gh)->ip_hl = (sizeof(struct ip)) >> 2;
405 ((struct ip*)gh)->ip_ttl = GRE_TTL;
406 ((struct ip*)gh)->ip_tos = ip->ip_tos;
407 ((struct ip*)gh)->ip_id = ip->ip_id;
408 gh->gi_len = m->m_pkthdr.len;
409 }
410
411 ifp->if_opackets++;
412 ifp->if_obytes += m->m_pkthdr.len;
413 /* send it off */
414 error = ip_output(m, NULL, &sc->route, 0, NULL);
415 end:
416 sc->called = 0;
417 if (error)
418 ifp->if_oerrors++;
419 return (error);
420}
421
422static int
423gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
424{
425 struct ifreq *ifr = (struct ifreq *)data;
426 struct if_laddrreq *lifr = (struct if_laddrreq *)data;
427 struct in_aliasreq *aifr = (struct in_aliasreq *)data;
428 struct gre_softc *sc = ifp->if_softc;
429 int s;
430 struct sockaddr_in si;

--- 224 unchanged lines hidden (view full) ---

655 * us. If the interface is p2p as a--->b, then a routing entry exists
656 * If we now send a packet to b (e.g. ping b), this will come down here
657 * gets src=a, dst=b tacked on and would from ip_ouput() sent back to
658 * if_gre.
659 * Goal here is to compute a route to b that is less specific than
660 * a-->b. We know that this one exists as in normal operation we have
661 * at least a default route which matches.
662 */
663static int
664gre_compute_route(struct gre_softc *sc)
665{
666 struct route *ro;
667 u_int32_t a, b, c;
668
669 ro = &sc->route;
670
671 memset(ro, 0, sizeof(struct route));

--- 112 unchanged lines hidden ---