1/* $NetBSD: if_gre.c,v 1.49 2003/12/11 00:22:29 itojun Exp $ */ |
2/* $FreeBSD: head/sys/net/if_gre.c 223223 2011-06-18 09:34:03Z bz $ */ |
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 * --- 32 unchanged lines hidden (view full) --- 43 44#include "opt_atalk.h" 45#include "opt_inet.h" 46#include "opt_inet6.h" 47 48#include <sys/param.h> 49#include <sys/jail.h> 50#include <sys/kernel.h> |
51#include <sys/libkern.h> |
52#include <sys/malloc.h> 53#include <sys/module.h> 54#include <sys/mbuf.h> 55#include <sys/priv.h> 56#include <sys/proc.h> 57#include <sys/protosw.h> 58#include <sys/socket.h> 59#include <sys/sockio.h> --- 27 unchanged lines hidden (view full) --- 87 * It is not easy to calculate the right value for a GRE MTU. 88 * We leave this task to the admin and use the same default that 89 * other vendors use. 90 */ 91#define GREMTU 1476 92 93#define GRENAME "gre" 94 |
95#define MTAG_COOKIE_GRE 1307983903 96#define MTAG_GRE_NESTING 1 97struct mtag_gre_nesting { 98 uint16_t count; 99 uint16_t max; 100 struct ifnet *ifp[]; 101}; 102 |
103/* 104 * gre_mtx protects all global variables in if_gre.c. 105 * XXX: gre_softc data not protected yet. 106 */ 107struct mtx gre_mtx; 108static MALLOC_DEFINE(M_GRE, GRENAME, "Generic Routing Encapsulation"); 109 110struct gre_softc_head gre_softc_list; --- 89 unchanged lines hidden (view full) --- 200 GRE2IFP(sc)->if_mtu = GREMTU; 201 GRE2IFP(sc)->if_flags = IFF_POINTOPOINT|IFF_MULTICAST; 202 GRE2IFP(sc)->if_output = gre_output; 203 GRE2IFP(sc)->if_ioctl = gre_ioctl; 204 sc->g_dst.s_addr = sc->g_src.s_addr = INADDR_ANY; 205 sc->g_proto = IPPROTO_GRE; 206 GRE2IFP(sc)->if_flags |= IFF_LINK0; 207 sc->encap = NULL; |
208 sc->gre_fibnum = curthread->td_proc->p_fibnum; 209 sc->wccp_ver = WCCP_V1; 210 sc->key = 0; 211 if_attach(GRE2IFP(sc)); 212 bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t)); 213 mtx_lock(&gre_mtx); 214 LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list); 215 mtx_unlock(&gre_mtx); --- 27 unchanged lines hidden (view full) --- 243static int 244gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 245 struct route *ro) 246{ 247 int error = 0; 248 struct gre_softc *sc = ifp->if_softc; 249 struct greip *gh; 250 struct ip *ip; |
251 struct m_tag *mtag; 252 struct mtag_gre_nesting *gt; 253 size_t len; |
254 u_short gre_ip_id = 0; 255 uint8_t gre_ip_tos = 0; 256 u_int16_t etype = 0; 257 struct mobile_h mob_h; 258 u_int32_t af; |
259 int extra = 0, max; |
260 261 /* |
262 * gre may cause infinite recursion calls when misconfigured. High 263 * nesting level may cause stack exhaustion. We'll prevent this by 264 * detecting loops and by introducing upper limit. |
265 */ |
266 mtag = m_tag_locate(m, MTAG_COOKIE_GRE, MTAG_GRE_NESTING, NULL); 267 if (mtag != NULL) { 268 struct ifnet **ifp2; 269 270 gt = (struct mtag_gre_nesting *)(mtag + 1); 271 gt->count++; 272 if (gt->count > min(gt->max,max_gre_nesting)) { 273 printf("%s: hit maximum recursion limit %u on %s\n", 274 __func__, gt->count - 1, ifp->if_xname); 275 m_freem(m); 276 error = EIO; /* is there better errno? */ 277 goto end; 278 } 279 280 ifp2 = gt->ifp; 281 for (max = gt->count - 1; max > 0; max--) { 282 if (*ifp2 == ifp) 283 break; 284 ifp2++; 285 } 286 if (*ifp2 == ifp) { 287 printf("%s: detected loop with nexting %u on %s\n", 288 __func__, gt->count-1, ifp->if_xname); 289 m_freem(m); 290 error = EIO; /* is there better errno? */ 291 goto end; 292 } 293 *ifp2 = ifp; 294 295 } else { 296 /* 297 * Given that people should NOT increase max_gre_nesting beyond 298 * their real needs, we allocate once per packet rather than 299 * allocating an mtag once per passing through gre. 300 * 301 * Note: the sysctl does not actually check for saneness, so we 302 * limit the maximum numbers of possible recursions here. 303 */ 304 max = imin(max_gre_nesting, 256); 305 /* If someone sets the sysctl <= 0, we want at least 1. */ 306 max = imax(max, 1); 307 len = sizeof(struct mtag_gre_nesting) + 308 max * sizeof(struct ifnet *); 309 mtag = m_tag_alloc(MTAG_COOKIE_GRE, MTAG_GRE_NESTING, len, 310 M_NOWAIT); 311 if (mtag == NULL) { 312 m_freem(m); 313 error = ENOMEM; 314 goto end; 315 } 316 gt = (struct mtag_gre_nesting *)(mtag + 1); 317 bzero(gt, len); 318 gt->count = 1; 319 gt->max = max; 320 *gt->ifp = ifp; 321 m_tag_prepend(m, mtag); |
322 } 323 324 if (!((ifp->if_flags & IFF_UP) && 325 (ifp->if_drv_flags & IFF_DRV_RUNNING)) || 326 sc->g_src.s_addr == INADDR_ANY || sc->g_dst.s_addr == INADDR_ANY) { 327 m_freem(m); 328 error = ENETDOWN; 329 goto end; --- 171 unchanged lines hidden (view full) --- 501 /* 502 * Send it off and with IP_FORWARD flag to prevent it from 503 * overwriting the ip_id again. ip_id is already set to the 504 * ip_id of the encapsulated packet. 505 */ 506 error = ip_output(m, NULL, &sc->route, IP_FORWARDING, 507 (struct ip_moptions *)NULL, (struct inpcb *)NULL); 508 end: |
509 if (error) 510 ifp->if_oerrors++; 511 return (error); 512} 513 514static int 515gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 516{ --- 464 unchanged lines hidden --- |