ip_gre.c (263152) | ip_gre.c (269699) |
---|---|
1/* $NetBSD: ip_gre.c,v 1.29 2003/09/05 23:02:43 itojun Exp $ */ 2 3/*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Heiko W.Rupp <hwr@pilhuhn.de> --- 24 unchanged lines hidden (view full) --- 33 34/* 35 * deencapsulate tunneled packets and send them on 36 * output half is in net/if_gre.[ch] 37 * This currently handles IPPROTO_GRE, IPPROTO_MOBILE 38 */ 39 40#include <sys/cdefs.h> | 1/* $NetBSD: ip_gre.c,v 1.29 2003/09/05 23:02:43 itojun Exp $ */ 2 3/*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Heiko W.Rupp <hwr@pilhuhn.de> --- 24 unchanged lines hidden (view full) --- 33 34/* 35 * deencapsulate tunneled packets and send them on 36 * output half is in net/if_gre.[ch] 37 * This currently handles IPPROTO_GRE, IPPROTO_MOBILE 38 */ 39 40#include <sys/cdefs.h> |
41__FBSDID("$FreeBSD: head/sys/netinet/ip_gre.c 263152 2014-03-14 06:29:43Z glebius $"); | 41__FBSDID("$FreeBSD: head/sys/netinet/ip_gre.c 269699 2014-08-08 01:57:15Z kevlo $"); |
42 43#include "opt_inet.h" 44#include "opt_inet6.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/mbuf.h> 49#include <sys/socket.h> --- 37 unchanged lines hidden (view full) --- 87static struct mbuf *gre_input2(struct mbuf *, int, u_char); 88 89/* 90 * De-encapsulate a packet and feed it back through ip input (this 91 * routine is called whenever IP gets a packet with proto type 92 * IPPROTO_GRE and a local destination address). 93 * This really is simple 94 */ | 42 43#include "opt_inet.h" 44#include "opt_inet6.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/mbuf.h> 49#include <sys/socket.h> --- 37 unchanged lines hidden (view full) --- 87static struct mbuf *gre_input2(struct mbuf *, int, u_char); 88 89/* 90 * De-encapsulate a packet and feed it back through ip input (this 91 * routine is called whenever IP gets a packet with proto type 92 * IPPROTO_GRE and a local destination address). 93 * This really is simple 94 */ |
95void 96gre_input(struct mbuf *m, int off) | 95int 96gre_input(struct mbuf **mp, int *offp, int proto) |
97{ | 97{ |
98 int proto; | 98 struct mbuf *m; 99 int off; |
99 | 100 |
100 proto = (mtod(m, struct ip *))->ip_p; | 101 m = *mp; 102 off = *offp; 103 *mp = NULL; |
101 102 m = gre_input2(m, off, proto); 103 104 /* 105 * If no matching tunnel that is up is found. We inject 106 * the mbuf to raw ip socket to see if anyone picks it up. 107 */ | 104 105 m = gre_input2(m, off, proto); 106 107 /* 108 * If no matching tunnel that is up is found. We inject 109 * the mbuf to raw ip socket to see if anyone picks it up. 110 */ |
108 if (m != NULL) 109 rip_input(m, off); | 111 if (m != NULL) { 112 *mp = m; 113 rip_input(mp, offp, proto); 114 } 115 return (IPPROTO_DONE); |
110} 111 112/* 113 * Decapsulate. Does the real work and is called from gre_input() 114 * (above). Returns an mbuf back if packet is not yet processed, 115 * and NULL if it needs no further processing. proto is the protocol 116 * number of the "calling" foo_input() routine. 117 */ --- 90 unchanged lines hidden (view full) --- 208 209/* 210 * input routine for IPPRPOTO_MOBILE 211 * This is a little bit diffrent from the other modes, as the 212 * encapsulating header was not prepended, but instead inserted 213 * between IP header and payload 214 */ 215 | 116} 117 118/* 119 * Decapsulate. Does the real work and is called from gre_input() 120 * (above). Returns an mbuf back if packet is not yet processed, 121 * and NULL if it needs no further processing. proto is the protocol 122 * number of the "calling" foo_input() routine. 123 */ --- 90 unchanged lines hidden (view full) --- 214 215/* 216 * input routine for IPPRPOTO_MOBILE 217 * This is a little bit diffrent from the other modes, as the 218 * encapsulating header was not prepended, but instead inserted 219 * between IP header and payload 220 */ 221 |
216void 217gre_mobile_input(struct mbuf *m, int hlen) | 222int 223gre_mobile_input(struct mbuf **mp, int *offp, int proto) |
218{ 219 struct ip *ip; 220 struct mobip_h *mip; | 224{ 225 struct ip *ip; 226 struct mobip_h *mip; |
227 struct mbuf *m; |
|
221 struct gre_softc *sc; 222 int msiz; 223 | 228 struct gre_softc *sc; 229 int msiz; 230 |
231 m = *mp; |
|
224 if ((sc = gre_lookup(m, IPPROTO_MOBILE)) == NULL) { 225 /* No matching tunnel or tunnel is down. */ 226 m_freem(m); | 232 if ((sc = gre_lookup(m, IPPROTO_MOBILE)) == NULL) { 233 /* No matching tunnel or tunnel is down. */ 234 m_freem(m); |
227 return; | 235 return (IPPROTO_DONE); |
228 } 229 230 if (m->m_len < sizeof(*mip)) { 231 m = m_pullup(m, sizeof(*mip)); 232 if (m == NULL) | 236 } 237 238 if (m->m_len < sizeof(*mip)) { 239 m = m_pullup(m, sizeof(*mip)); 240 if (m == NULL) |
233 return; | 241 return (IPPROTO_DONE); |
234 } 235 ip = mtod(m, struct ip *); 236 mip = mtod(m, struct mobip_h *); 237 238 GRE2IFP(sc)->if_ipackets++; 239 GRE2IFP(sc)->if_ibytes += m->m_pkthdr.len; 240 241 if (ntohs(mip->mh.proto) & MOB_H_SBIT) { 242 msiz = MOB_H_SIZ_L; 243 mip->mi.ip_src.s_addr = mip->mh.osrc; 244 } else 245 msiz = MOB_H_SIZ_S; 246 247 if (m->m_len < (ip->ip_hl << 2) + msiz) { 248 m = m_pullup(m, (ip->ip_hl << 2) + msiz); 249 if (m == NULL) | 242 } 243 ip = mtod(m, struct ip *); 244 mip = mtod(m, struct mobip_h *); 245 246 GRE2IFP(sc)->if_ipackets++; 247 GRE2IFP(sc)->if_ibytes += m->m_pkthdr.len; 248 249 if (ntohs(mip->mh.proto) & MOB_H_SBIT) { 250 msiz = MOB_H_SIZ_L; 251 mip->mi.ip_src.s_addr = mip->mh.osrc; 252 } else 253 msiz = MOB_H_SIZ_S; 254 255 if (m->m_len < (ip->ip_hl << 2) + msiz) { 256 m = m_pullup(m, (ip->ip_hl << 2) + msiz); 257 if (m == NULL) |
250 return; | 258 return (IPPROTO_DONE); |
251 ip = mtod(m, struct ip *); 252 mip = mtod(m, struct mobip_h *); 253 } 254 255 mip->mi.ip_dst.s_addr = mip->mh.odst; 256 mip->mi.ip_p = (ntohs(mip->mh.proto) >> 8); 257 258 if (gre_in_cksum((u_int16_t *)&mip->mh, msiz) != 0) { 259 m_freem(m); | 259 ip = mtod(m, struct ip *); 260 mip = mtod(m, struct mobip_h *); 261 } 262 263 mip->mi.ip_dst.s_addr = mip->mh.odst; 264 mip->mi.ip_p = (ntohs(mip->mh.proto) >> 8); 265 266 if (gre_in_cksum((u_int16_t *)&mip->mh, msiz) != 0) { 267 m_freem(m); |
260 return; | 268 return (IPPROTO_DONE); |
261 } 262 263 bcopy((caddr_t)(ip) + (ip->ip_hl << 2) + msiz, (caddr_t)(ip) + 264 (ip->ip_hl << 2), m->m_len - msiz - (ip->ip_hl << 2)); 265 m->m_len -= msiz; 266 m->m_pkthdr.len -= msiz; 267 268 /* --- 8 unchanged lines hidden (view full) --- 277 278 if (bpf_peers_present(GRE2IFP(sc)->if_bpf)) { 279 u_int32_t af = AF_INET; 280 bpf_mtap2(GRE2IFP(sc)->if_bpf, &af, sizeof(af), m); 281 } 282 283 if ((GRE2IFP(sc)->if_flags & IFF_MONITOR) != 0) { 284 m_freem(m); | 269 } 270 271 bcopy((caddr_t)(ip) + (ip->ip_hl << 2) + msiz, (caddr_t)(ip) + 272 (ip->ip_hl << 2), m->m_len - msiz - (ip->ip_hl << 2)); 273 m->m_len -= msiz; 274 m->m_pkthdr.len -= msiz; 275 276 /* --- 8 unchanged lines hidden (view full) --- 285 286 if (bpf_peers_present(GRE2IFP(sc)->if_bpf)) { 287 u_int32_t af = AF_INET; 288 bpf_mtap2(GRE2IFP(sc)->if_bpf, &af, sizeof(af), m); 289 } 290 291 if ((GRE2IFP(sc)->if_flags & IFF_MONITOR) != 0) { 292 m_freem(m); |
285 return; | 293 return (IPPROTO_DONE); |
286 } 287 288 m->m_pkthdr.rcvif = GRE2IFP(sc); 289 290 netisr_queue(NETISR_IP, m); | 294 } 295 296 m->m_pkthdr.rcvif = GRE2IFP(sc); 297 298 netisr_queue(NETISR_IP, m); |
299 return (IPPROTO_DONE); |
|
291} 292 293/* 294 * Find the gre interface associated with our src/dst/proto set. 295 * 296 * XXXRW: Need some sort of drain/refcount mechanism so that the softc 297 * reference remains valid after it's returned from gre_lookup(). Right 298 * now, I'm thinking it should be reference-counted with a gre_dropref() --- 25 unchanged lines hidden --- | 300} 301 302/* 303 * Find the gre interface associated with our src/dst/proto set. 304 * 305 * XXXRW: Need some sort of drain/refcount mechanism so that the softc 306 * reference remains valid after it's returned from gre_lookup(). Right 307 * now, I'm thinking it should be reference-counted with a gre_dropref() --- 25 unchanged lines hidden --- |