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 --- |