Skip to content

Commit 1bcb5a7

Browse files
committed
In IPIP input rename the variable ipo to ip as it is used for inner
and outer header. Reset values depending on the the mbuf when the mbuf is adjusted. Check the length of the inner IP header with the correct size in case of IPv6. Check the IPv4 header size including IP options. For the IPIP statistics the inner header length has to be subtracted from the packet size as the outer header has already been stripped off. OK mpi@
1 parent db9fad6 commit 1bcb5a7

File tree

1 file changed

+33
-34
lines changed

1 file changed

+33
-34
lines changed

sys/netinet/ip_ipip.c

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: ip_ipip.c,v 1.79 2017/05/26 15:56:51 bluhm Exp $ */
1+
/* $OpenBSD: ip_ipip.c,v 1.80 2017/05/26 16:27:25 bluhm Exp $ */
22
/*
33
* The authors of this code are John Ioannidis ([email protected]),
44
* Angelos D. Keromytis ([email protected]) and
@@ -120,11 +120,10 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
120120
struct ifnet *gifp)
121121
{
122122
struct mbuf *m = *mp;
123-
int iphlen = *offp;
124123
struct sockaddr_in *sin;
125124
struct ifnet *ifp;
126125
struct niqueue *ifq = NULL;
127-
struct ip *ipo;
126+
struct ip *ip;
128127
#ifdef INET6
129128
struct sockaddr_in6 *sin6;
130129
struct ip6_hdr *ip6;
@@ -160,8 +159,8 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
160159
/* Keep outer ecn field. */
161160
switch (oaf) {
162161
case AF_INET:
163-
ipo = mtod(m, struct ip *);
164-
otos = ipo->ip_tos;
162+
ip = mtod(m, struct ip *);
163+
otos = ip->ip_tos;
165164
break;
166165
#ifdef INET6
167166
case AF_INET6:
@@ -172,14 +171,13 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
172171
}
173172

174173
/* Remove outer IP header */
175-
m_adj(m, iphlen);
176-
177-
/* Sanity check */
178-
if (m->m_pkthdr.len < sizeof(struct ip)) {
179-
ipipstat_inc(ipips_hdrops);
180-
m_freem(m);
181-
return IPPROTO_DONE;
182-
}
174+
KASSERT(*offp > 0);
175+
m_adj(m, *offp);
176+
*offp = 0;
177+
ip = NULL;
178+
#ifdef INET6
179+
ip6 = NULL;
180+
#endif
183181

184182
switch (proto) {
185183
case IPPROTO_IPV4:
@@ -197,6 +195,13 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
197195
return IPPROTO_DONE;
198196
}
199197

198+
/* Sanity check */
199+
if (m->m_pkthdr.len < hlen) {
200+
ipipstat_inc(ipips_hdrops);
201+
m_freem(m);
202+
return IPPROTO_DONE;
203+
}
204+
200205
/*
201206
* Bring the inner header into the first mbuf, if not there already.
202207
*/
@@ -217,31 +222,30 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
217222
/* Some sanity checks in the inner IP header */
218223
switch (proto) {
219224
case IPPROTO_IPV4:
220-
ipo = mtod(m, struct ip *);
221-
#ifdef INET6
222-
ip6 = NULL;
223-
#endif
224-
itos = ipo->ip_tos;
225+
ip = mtod(m, struct ip *);
226+
hlen = ip->ip_hl << 2;
227+
if (m->m_pkthdr.len < hlen) {
228+
ipipstat_inc(ipips_hdrops);
229+
m_freem(m);
230+
return IPPROTO_DONE;
231+
}
232+
itos = ip->ip_tos;
225233
mode = m->m_flags & (M_AUTH|M_CONF) ?
226234
ECN_ALLOWED_IPSEC : ECN_ALLOWED;
227-
if (!ip_ecn_egress(mode, &otos, &ipo->ip_tos)) {
235+
if (!ip_ecn_egress(mode, &otos, &ip->ip_tos)) {
228236
DPRINTF(("%s: ip_ecn_egress() failed\n", __func__));
229237
ipipstat_inc(ipips_pdrops);
230238
m_freem(m);
231239
return IPPROTO_DONE;
232240
}
233241
/* re-calculate the checksum if ip_tos was changed */
234-
if (itos != ipo->ip_tos) {
235-
hlen = ipo->ip_hl << 2;
236-
if (m->m_pkthdr.len >= hlen) {
237-
ipo->ip_sum = 0;
238-
ipo->ip_sum = in_cksum(m, hlen);
239-
}
242+
if (itos != ip->ip_tos) {
243+
ip->ip_sum = 0;
244+
ip->ip_sum = in_cksum(m, hlen);
240245
}
241246
break;
242247
#ifdef INET6
243248
case IPPROTO_IPV6:
244-
ipo = NULL;
245249
ip6 = mtod(m, struct ip6_hdr *);
246250
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
247251
if (!ip_ecn_egress(ECN_ALLOWED, &otos, &itos)) {
@@ -253,11 +257,6 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
253257
ip6->ip6_flow &= ~htonl(0xff << 20);
254258
ip6->ip6_flow |= htonl((u_int32_t) itos << 20);
255259
break;
256-
#endif
257-
default:
258-
ipo = NULL;
259-
#ifdef INET6
260-
ip6 = NULL;
261260
#endif
262261
}
263262

@@ -272,11 +271,11 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
272271

273272
memset(&ss, 0, sizeof(ss));
274273

275-
if (ipo) {
274+
if (ip) {
276275
sin = (struct sockaddr_in *)&ss;
277276
sin->sin_family = AF_INET;
278277
sin->sin_len = sizeof(*sin);
279-
sin->sin_addr = ipo->ip_src;
278+
sin->sin_addr = ip->ip_src;
280279
#ifdef INET6
281280
} else if (ip6) {
282281
sin6 = (struct sockaddr_in6 *)&ss;
@@ -298,7 +297,7 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
298297
}
299298

300299
/* Statistics */
301-
ipipstat_add(ipips_ibytes, m->m_pkthdr.len - iphlen);
300+
ipipstat_add(ipips_ibytes, m->m_pkthdr.len - hlen);
302301

303302
/*
304303
* Interface pointer stays the same; if no IPsec processing has

0 commit comments

Comments
 (0)