1/* $NetBSD: if_gre.c,v 1.49 2003/12/11 00:22:29 itojun Exp $ */ 2/* $FreeBSD: head/sys/net/if_gre.c 123992 2003-12-30 11:41:43Z 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 * --- 196 unchanged lines hidden (view full) --- 207static int 208gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 209 struct rtentry *rt) 210{ 211 int error = 0; 212 struct gre_softc *sc = ifp->if_softc; 213 struct greip *gh; 214 struct ip *ip; |
215 u_int16_t etype = 0; |
216 struct mobile_h mob_h; 217 218 /* 219 * gre may cause infinite recursion calls when misconfigured. 220 * We'll prevent this by introducing upper limit. 221 */ 222 if (++(sc->called) > max_gre_nesting) { 223 printf("%s: gre_output: recursively called too many " --- 7 unchanged lines hidden (view full) --- 231 sc->g_src.s_addr == INADDR_ANY || sc->g_dst.s_addr == INADDR_ANY) { 232 m_freem(m); 233 error = ENETDOWN; 234 goto end; 235 } 236 237 gh = NULL; 238 ip = NULL; |
239 240 if (ifp->if_bpf) { 241 u_int32_t af = dst->sa_family; 242 bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m); 243 } 244 245 m->m_flags &= ~(M_BCAST|M_MCAST); 246 --- 28 unchanged lines hidden (view full) --- 275 msiz = MOB_H_SIZ_S; 276 } else { 277 mob_h.proto |= MOB_H_SBIT; 278 mob_h.osrc = ip->ip_src.s_addr; 279 ip->ip_src.s_addr = sc->g_src.s_addr; 280 msiz = MOB_H_SIZ_L; 281 } 282 mob_h.proto = htons(mob_h.proto); |
283 mob_h.hcrc = gre_in_cksum((u_int16_t *)&mob_h, msiz); |
284 285 if ((m->m_data - msiz) < m->m_pktdat) { 286 /* need new mbuf */ 287 MGETHDR(m0, M_DONTWAIT, MT_HEADER); 288 if (m0 == NULL) { 289 _IF_DROP(&ifp->if_snd); 290 m_freem(m); 291 error = ENOBUFS; --- 66 unchanged lines hidden (view full) --- 358 gh->gi_pr = sc->g_proto; 359 if (sc->g_proto != IPPROTO_MOBILE) { 360 gh->gi_src = sc->g_src; 361 gh->gi_dst = sc->g_dst; 362 ((struct ip*)gh)->ip_hl = (sizeof(struct ip)) >> 2; 363 ((struct ip*)gh)->ip_ttl = GRE_TTL; 364 ((struct ip*)gh)->ip_tos = ip->ip_tos; 365 ((struct ip*)gh)->ip_id = ip->ip_id; |
366 gh->gi_len = htons(m->m_pkthdr.len); |
367 } 368 369 ifp->if_opackets++; 370 ifp->if_obytes += m->m_pkthdr.len; 371 /* send it off */ |
372 error = ip_output(m, NULL, &sc->route, 0, 373 (struct ip_moptions *)NULL, (struct inpcb *)NULL); |
374 end: 375 sc->called = 0; 376 if (error) 377 ifp->if_oerrors++; 378 return (error); 379} 380 381static int --- 232 unchanged lines hidden (view full) --- 614 return (error); 615} 616 617/* 618 * computes a route to our destination that is not the one 619 * which would be taken by ip_output(), as this one will loop back to 620 * us. If the interface is p2p as a--->b, then a routing entry exists 621 * If we now send a packet to b (e.g. ping b), this will come down here |
622 * gets src=a, dst=b tacked on and would from ip_output() sent back to |
623 * if_gre. 624 * Goal here is to compute a route to b that is less specific than 625 * a-->b. We know that this one exists as in normal operation we have 626 * at least a default route which matches. 627 */ 628static int 629gre_compute_route(struct gre_softc *sc) 630{ --- 19 unchanged lines hidden (view full) --- 650 c = a & 0xfffffffe; 651 b = b ^ 0x01; 652 a = b | c; 653 ((struct sockaddr_in *)&ro->ro_dst)->sin_addr.s_addr 654 = htonl(a); 655 } 656 657#ifdef DIAGNOSTIC |
658 printf("%s: searching for a route to %s", if_name(&sc->sc_if), |
659 inet_ntoa(((struct sockaddr_in *)&ro->ro_dst)->sin_addr)); 660#endif 661 662 rtalloc(ro); 663 664 /* 665 * check if this returned a route at all and this route is no 666 * recursion to ourself --- 23 unchanged lines hidden (view full) --- 690 691 return 0; 692} 693 694/* 695 * do a checksum of a buffer - much like in_cksum, which operates on 696 * mbufs. 697 */ |
698u_int16_t 699gre_in_cksum(u_int16_t *p, u_int len) |
700{ |
701 u_int32_t sum = 0; |
702 int nwords = len >> 1; 703 704 while (nwords-- != 0) 705 sum += *p++; 706 707 if (len & 1) { 708 union { 709 u_short w; --- 39 unchanged lines hidden --- |