1/* $NetBSD: if_gre.c,v 1.42 2002/08/14 00:23:27 itojun Exp $ */
2/* $FreeBSD: head/sys/net/if_gre.c 103026 2002-09-06 17:12:50Z 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 103026 2002-09-06 17:12:50Z 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;
118int ip_gre_ttl = GRE_TTL;
119
120int gre_clone_create __P((struct if_clone *, int));
121void gre_clone_destroy __P((struct ifnet *));
122
123struct if_clone gre_cloner =
124 IF_CLONE_INITIALIZER("gre", gre_clone_create, gre_clone_destroy, 0, IF_MAXUNIT);
125
126int gre_compute_route(struct gre_softc *sc);
127
128void greattach __P((void));
129
130#ifdef INET
131extern struct domain inetdomain;
132static const struct protosw in_gre_protosw =
133{ SOCK_RAW, &inetdomain, IPPROTO_GRE, PR_ATOMIC|PR_ADDR,
134 (pr_input_t*)gre_input, (pr_output_t*)rip_output, rip_ctlinput, rip_ctloutput,
135 0,
136 0, 0, 0, 0,
--- 22 unchanged lines hidden (view full) ---
159 */
160#define MAX_GRE_NEST 1
161#endif
162static int max_gre_nesting = MAX_GRE_NEST;
163SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW,
164 &max_gre_nesting, 0, "Max nested tunnels");
165
166/* ARGSUSED */
167void
168greattach(void)
169{
170
171 LIST_INIT(&gre_softc_list);
172 if_clone_attach(&gre_cloner);
173}
174
175int
176gre_clone_create(ifc, unit)
177 struct if_clone *ifc;
178 int unit;
179{
180 struct gre_softc *sc;
181
182 sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK);
183 memset(sc, 0, sizeof(struct gre_softc));
--- 17 unchanged lines hidden (view full) ---
201 if_attach(&sc->sc_if);
202#if NBPF
203 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int32_t));
204#endif
205 LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list);
206 return (0);
207}
208
209void
210gre_clone_destroy(ifp)
211 struct ifnet *ifp;
212{
213 struct gre_softc *sc = ifp->if_softc;
214
215#ifdef INET
216 if (sc->encap != NULL)
217 encap_detach(sc->encap);
--- 5 unchanged lines hidden (view full) ---
223 if_detach(ifp);
224 free(sc, M_GRE);
225}
226
227/*
228 * The output routine. Takes a packet and encapsulates it in the protocol
229 * given by sc->g_proto. See also RFC 1701 and RFC 2004
230 */
231int
232gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
233 struct rtentry *rt)
234{
235 int error = 0;
236 struct gre_softc *sc = ifp->if_softc;
237 struct greip *gh;
238 struct ip *ip;
239 u_char osrc;
--- 155 unchanged lines hidden (view full) ---
395 gh->gi_ptype = htons(etype);
396 }
397
398 gh->gi_pr = sc->g_proto;
399 if (sc->g_proto != IPPROTO_MOBILE) {
400 gh->gi_src = sc->g_src;
401 gh->gi_dst = sc->g_dst;
402 ((struct ip*)gh)->ip_hl = (sizeof(struct ip)) >> 2;
403 ((struct ip*)gh)->ip_ttl = ip_gre_ttl;
404 ((struct ip*)gh)->ip_tos = ip->ip_tos;
405 ((struct ip*)gh)->ip_id = ip->ip_id;
406 gh->gi_len = m->m_pkthdr.len;
407 }
408
409 ifp->if_opackets++;
410 ifp->if_obytes += m->m_pkthdr.len;
411 /* send it off */
412 error = ip_output(m, NULL, &sc->route, 0, NULL);
413 end:
414 sc->called = 0;
415 if (error)
416 ifp->if_oerrors++;
417 return (error);
418}
419
420int
421gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
422{
423 struct ifreq *ifr = (struct ifreq *)data;
424 struct if_laddrreq *lifr = (struct if_laddrreq *)data;
425 struct in_aliasreq *aifr = (struct in_aliasreq *)data;
426 struct gre_softc *sc = ifp->if_softc;
427 int s;
428 struct sockaddr_in si;
--- 224 unchanged lines hidden (view full) ---
653 * us. If the interface is p2p as a--->b, then a routing entry exists
654 * If we now send a packet to b (e.g. ping b), this will come down here
655 * gets src=a, dst=b tacked on and would from ip_ouput() sent back to
656 * if_gre.
657 * Goal here is to compute a route to b that is less specific than
658 * a-->b. We know that this one exists as in normal operation we have
659 * at least a default route which matches.
660 */
661int
662gre_compute_route(struct gre_softc *sc)
663{
664 struct route *ro;
665 u_int32_t a, b, c;
666
667 ro = &sc->route;
668
669 memset(ro, 0, sizeof(struct route));
--- 112 unchanged lines hidden ---
2/* $FreeBSD: head/sys/net/if_gre.c 103026 2002-09-06 17:12:50Z 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 103026 2002-09-06 17:12:50Z 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;
118int ip_gre_ttl = GRE_TTL;
119
120int gre_clone_create __P((struct if_clone *, int));
121void gre_clone_destroy __P((struct ifnet *));
122
123struct if_clone gre_cloner =
124 IF_CLONE_INITIALIZER("gre", gre_clone_create, gre_clone_destroy, 0, IF_MAXUNIT);
125
126int gre_compute_route(struct gre_softc *sc);
127
128void greattach __P((void));
129
130#ifdef INET
131extern struct domain inetdomain;
132static const struct protosw in_gre_protosw =
133{ SOCK_RAW, &inetdomain, IPPROTO_GRE, PR_ATOMIC|PR_ADDR,
134 (pr_input_t*)gre_input, (pr_output_t*)rip_output, rip_ctlinput, rip_ctloutput,
135 0,
136 0, 0, 0, 0,
--- 22 unchanged lines hidden (view full) ---
159 */
160#define MAX_GRE_NEST 1
161#endif
162static int max_gre_nesting = MAX_GRE_NEST;
163SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW,
164 &max_gre_nesting, 0, "Max nested tunnels");
165
166/* ARGSUSED */
167void
168greattach(void)
169{
170
171 LIST_INIT(&gre_softc_list);
172 if_clone_attach(&gre_cloner);
173}
174
175int
176gre_clone_create(ifc, unit)
177 struct if_clone *ifc;
178 int unit;
179{
180 struct gre_softc *sc;
181
182 sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK);
183 memset(sc, 0, sizeof(struct gre_softc));
--- 17 unchanged lines hidden (view full) ---
201 if_attach(&sc->sc_if);
202#if NBPF
203 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int32_t));
204#endif
205 LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list);
206 return (0);
207}
208
209void
210gre_clone_destroy(ifp)
211 struct ifnet *ifp;
212{
213 struct gre_softc *sc = ifp->if_softc;
214
215#ifdef INET
216 if (sc->encap != NULL)
217 encap_detach(sc->encap);
--- 5 unchanged lines hidden (view full) ---
223 if_detach(ifp);
224 free(sc, M_GRE);
225}
226
227/*
228 * The output routine. Takes a packet and encapsulates it in the protocol
229 * given by sc->g_proto. See also RFC 1701 and RFC 2004
230 */
231int
232gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
233 struct rtentry *rt)
234{
235 int error = 0;
236 struct gre_softc *sc = ifp->if_softc;
237 struct greip *gh;
238 struct ip *ip;
239 u_char osrc;
--- 155 unchanged lines hidden (view full) ---
395 gh->gi_ptype = htons(etype);
396 }
397
398 gh->gi_pr = sc->g_proto;
399 if (sc->g_proto != IPPROTO_MOBILE) {
400 gh->gi_src = sc->g_src;
401 gh->gi_dst = sc->g_dst;
402 ((struct ip*)gh)->ip_hl = (sizeof(struct ip)) >> 2;
403 ((struct ip*)gh)->ip_ttl = ip_gre_ttl;
404 ((struct ip*)gh)->ip_tos = ip->ip_tos;
405 ((struct ip*)gh)->ip_id = ip->ip_id;
406 gh->gi_len = m->m_pkthdr.len;
407 }
408
409 ifp->if_opackets++;
410 ifp->if_obytes += m->m_pkthdr.len;
411 /* send it off */
412 error = ip_output(m, NULL, &sc->route, 0, NULL);
413 end:
414 sc->called = 0;
415 if (error)
416 ifp->if_oerrors++;
417 return (error);
418}
419
420int
421gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
422{
423 struct ifreq *ifr = (struct ifreq *)data;
424 struct if_laddrreq *lifr = (struct if_laddrreq *)data;
425 struct in_aliasreq *aifr = (struct in_aliasreq *)data;
426 struct gre_softc *sc = ifp->if_softc;
427 int s;
428 struct sockaddr_in si;
--- 224 unchanged lines hidden (view full) ---
653 * us. If the interface is p2p as a--->b, then a routing entry exists
654 * If we now send a packet to b (e.g. ping b), this will come down here
655 * gets src=a, dst=b tacked on and would from ip_ouput() sent back to
656 * if_gre.
657 * Goal here is to compute a route to b that is less specific than
658 * a-->b. We know that this one exists as in normal operation we have
659 * at least a default route which matches.
660 */
661int
662gre_compute_route(struct gre_softc *sc)
663{
664 struct route *ro;
665 u_int32_t a, b, c;
666
667 ro = &sc->route;
668
669 memset(ro, 0, sizeof(struct route));
--- 112 unchanged lines hidden ---