Deleted Added
full compact
ip_gre.c (154665) ip_gre.c (158645)
1/* $NetBSD: ip_gre.c,v 1.29 2003/09/05 23:02:43 itojun Exp $ */
1/* $NetBSD: ip_gre.c,v 1.29 2003/09/05 23:02:43 itojun Exp $ */
2/* $FreeBSD: head/sys/netinet/ip_gre.c 154665 2006-01-22 01:08:30Z rwatson $ */
2/* $FreeBSD: head/sys/netinet/ip_gre.c 158645 2006-05-16 11:15:22Z glebius $ */
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 *

--- 79 unchanged lines hidden (view full) ---

90#include <machine/stdarg.h>
91
92#if 1
93void gre_inet_ntoa(struct in_addr in); /* XXX */
94#endif
95
96static struct gre_softc *gre_lookup(struct mbuf *, u_int8_t);
97
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 *

--- 79 unchanged lines hidden (view full) ---

90#include <machine/stdarg.h>
91
92#if 1
93void gre_inet_ntoa(struct in_addr in); /* XXX */
94#endif
95
96static struct gre_softc *gre_lookup(struct mbuf *, u_int8_t);
97
98static int gre_input2(struct mbuf *, int, u_char);
98static struct mbuf *gre_input2(struct mbuf *, int, u_char);
99
100/*
101 * De-encapsulate a packet and feed it back through ip input (this
102 * routine is called whenever IP gets a packet with proto type
103 * IPPROTO_GRE and a local destination address).
104 * This really is simple
105 */
106void
107gre_input(struct mbuf *m, int off)
108{
99
100/*
101 * De-encapsulate a packet and feed it back through ip input (this
102 * routine is called whenever IP gets a packet with proto type
103 * IPPROTO_GRE and a local destination address).
104 * This really is simple
105 */
106void
107gre_input(struct mbuf *m, int off)
108{
109 int ret, proto;
109 int proto;
110
111 proto = (mtod(m, struct ip *))->ip_p;
112
110
111 proto = (mtod(m, struct ip *))->ip_p;
112
113 ret = gre_input2(m, off, proto);
113 m = gre_input2(m, off, proto);
114
114 /*
115 /*
115 * ret == 0 : packet not processed, meaning that
116 * no matching tunnel that is up is found.
117 * we inject it to raw ip socket to see if anyone picks it up.
116 * If no matching tunnel that is up is found. We inject
117 * the mbuf to raw ip socket to see if anyone picks it up.
118 */
118 */
119 if (ret == 0)
119 if (m != NULL)
120 rip_input(m, off);
121}
122
123/*
120 rip_input(m, off);
121}
122
123/*
124 * decapsulate.
125 * Does the real work and is called from gre_input() (above)
126 * returns 0 if packet is not yet processed
127 * and 1 if it needs no further processing
128 * proto is the protocol number of the "calling" foo_input()
129 * routine.
124 * Decapsulate. Does the real work and is called from gre_input()
125 * (above). Returns an mbuf back if packet is not yet processed,
126 * and NULL if it needs no further processing. proto is the protocol
127 * number of the "calling" foo_input() routine.
130 */
128 */
131static int
129static struct mbuf *
132gre_input2(struct mbuf *m ,int hlen, u_char proto)
133{
134 struct greip *gip;
135 int isr;
136 struct gre_softc *sc;
137 u_int16_t flags;
138 u_int32_t af;
139
140 if ((sc = gre_lookup(m, proto)) == NULL) {
141 /* No matching tunnel or tunnel is down. */
130gre_input2(struct mbuf *m ,int hlen, u_char proto)
131{
132 struct greip *gip;
133 int isr;
134 struct gre_softc *sc;
135 u_int16_t flags;
136 u_int32_t af;
137
138 if ((sc = gre_lookup(m, proto)) == NULL) {
139 /* No matching tunnel or tunnel is down. */
142 return (0);
140 return (m);
143 }
144
145 if (m->m_len < sizeof(*gip)) {
146 m = m_pullup(m, sizeof(*gip));
147 if (m == NULL)
141 }
142
143 if (m->m_len < sizeof(*gip)) {
144 m = m_pullup(m, sizeof(*gip));
145 if (m == NULL)
148 return (ENOBUFS);
146 return (NULL);
149 }
150 gip = mtod(m, struct greip *);
151
152 GRE2IFP(sc)->if_ipackets++;
153 GRE2IFP(sc)->if_ibytes += m->m_pkthdr.len;
154
155 switch (proto) {
156 case IPPROTO_GRE:
157 hlen += sizeof(struct gre_h);
158
159 /* process GRE flags as packet can be of variable len */
160 flags = ntohs(gip->gi_flags);
161
162 /* Checksum & Offset are present */
163 if ((flags & GRE_CP) | (flags & GRE_RP))
164 hlen += 4;
165 /* We don't support routing fields (variable length) */
166 if (flags & GRE_RP)
147 }
148 gip = mtod(m, struct greip *);
149
150 GRE2IFP(sc)->if_ipackets++;
151 GRE2IFP(sc)->if_ibytes += m->m_pkthdr.len;
152
153 switch (proto) {
154 case IPPROTO_GRE:
155 hlen += sizeof(struct gre_h);
156
157 /* process GRE flags as packet can be of variable len */
158 flags = ntohs(gip->gi_flags);
159
160 /* Checksum & Offset are present */
161 if ((flags & GRE_CP) | (flags & GRE_RP))
162 hlen += 4;
163 /* We don't support routing fields (variable length) */
164 if (flags & GRE_RP)
167 return (0);
165 return (m);
168 if (flags & GRE_KP)
169 hlen += 4;
170 if (flags & GRE_SP)
171 hlen += 4;
172
173 switch (ntohs(gip->gi_ptype)) { /* ethertypes */
174 case WCCP_PROTOCOL_TYPE:
175 if (sc->wccp_ver == WCCP_V2)

--- 10 unchanged lines hidden (view full) ---

186 break;
187#endif
188#ifdef NETATALK
189 case ETHERTYPE_ATALK:
190 isr = NETISR_ATALK1;
191 af = AF_APPLETALK;
192 break;
193#endif
166 if (flags & GRE_KP)
167 hlen += 4;
168 if (flags & GRE_SP)
169 hlen += 4;
170
171 switch (ntohs(gip->gi_ptype)) { /* ethertypes */
172 case WCCP_PROTOCOL_TYPE:
173 if (sc->wccp_ver == WCCP_V2)

--- 10 unchanged lines hidden (view full) ---

184 break;
185#endif
186#ifdef NETATALK
187 case ETHERTYPE_ATALK:
188 isr = NETISR_ATALK1;
189 af = AF_APPLETALK;
190 break;
191#endif
194 default: /* others not yet supported */
195 return (0);
192 default:
193 /* Others not yet supported. */
194 return (m);
196 }
197 break;
198 default:
195 }
196 break;
197 default:
199 /* others not yet supported */
200 return (0);
198 /* Others not yet supported. */
199 return (m);
201 }
202
203 if (hlen > m->m_pkthdr.len) {
204 m_freem(m);
200 }
201
202 if (hlen > m->m_pkthdr.len) {
203 m_freem(m);
205 return (EINVAL);
204 return (NULL);
206 }
207 /* Unlike NetBSD, in FreeBSD m_adj() adjusts m->m_pkthdr.len as well */
208 m_adj(m, hlen);
209
210 if (GRE2IFP(sc)->if_bpf) {
211 bpf_mtap2(GRE2IFP(sc)->if_bpf, &af, sizeof(af), m);
212 }
213
214 m->m_pkthdr.rcvif = GRE2IFP(sc);
215
216 netisr_dispatch(isr, m);
217
205 }
206 /* Unlike NetBSD, in FreeBSD m_adj() adjusts m->m_pkthdr.len as well */
207 m_adj(m, hlen);
208
209 if (GRE2IFP(sc)->if_bpf) {
210 bpf_mtap2(GRE2IFP(sc)->if_bpf, &af, sizeof(af), m);
211 }
212
213 m->m_pkthdr.rcvif = GRE2IFP(sc);
214
215 netisr_dispatch(isr, m);
216
218 return (1); /* packet is done, no further processing needed */
217 /* Packet is done, no further processing needed. */
218 return (NULL);
219}
220
221/*
222 * input routine for IPPRPOTO_MOBILE
223 * This is a little bit diffrent from the other modes, as the
224 * encapsulating header was not prepended, but instead inserted
225 * between IP header and payload
226 */

--- 106 unchanged lines hidden ---
219}
220
221/*
222 * input routine for IPPRPOTO_MOBILE
223 * This is a little bit diffrent from the other modes, as the
224 * encapsulating header was not prepended, but instead inserted
225 * between IP header and payload
226 */

--- 106 unchanged lines hidden ---