Lines 165-170
Link Here
|
165 |
int mtu; |
165 |
int mtu; |
166 |
struct m_tag *fwd_tag = NULL; |
166 |
struct m_tag *fwd_tag = NULL; |
167 |
|
167 |
|
|
|
168 |
struct mbuf *mcopy; |
169 |
|
168 |
/* |
170 |
/* |
169 |
* Are we active and forwarding packets? |
171 |
* Are we active and forwarding packets? |
170 |
*/ |
172 |
*/ |
Lines 230-235
Link Here
|
230 |
IPSTAT_INC(ips_total); |
232 |
IPSTAT_INC(ips_total); |
231 |
|
233 |
|
232 |
/* |
234 |
/* |
|
|
235 |
* Save the IP header and at most 8 bytes of the payload, |
236 |
* in case we need to generate an ICMP message to the src. |
237 |
* |
238 |
* XXX this can be optimized a lot by saving the data in a local |
239 |
* buffer on the stack (72 bytes at most), and only allocating the |
240 |
* mbuf if really necessary. The vast majority of the packets |
241 |
* are forwarded without having to send an ICMP back (either |
242 |
* because unnecessary, or because rate limited), so we are |
243 |
* really we are wasting a lot of work here. |
244 |
* |
245 |
* We don't use m_copy() because it might return a reference |
246 |
* to a shared cluster. Both this function and ip_output() |
247 |
* assume exclusive access to the IP header in `m', so any |
248 |
* data in a cluster may change before we reach icmp_error(). |
249 |
*/ |
250 |
mcopy = m_gethdr(M_NOWAIT, m->m_type); |
251 |
if (mcopy != NULL && !m_dup_pkthdr(mcopy, m, M_NOWAIT)) { |
252 |
/* |
253 |
* It's probably ok if the pkthdr dup fails (because |
254 |
* the deep copy of the tag chain failed), but for now |
255 |
* be conservative and just discard the copy since |
256 |
* code below may some day want the tags. |
257 |
*/ |
258 |
m_free(mcopy); |
259 |
mcopy = NULL; |
260 |
} |
261 |
if (mcopy != NULL) { |
262 |
mcopy->m_len = min(ntohs(ip->ip_len), M_TRAILINGSPACE(mcopy)); |
263 |
mcopy->m_pkthdr.len = mcopy->m_len; |
264 |
m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t)); |
265 |
} |
266 |
/* |
233 |
* Step 3: incoming packet firewall processing |
267 |
* Step 3: incoming packet firewall processing |
234 |
*/ |
268 |
*/ |
235 |
|
269 |
|
Lines 285-291
Link Here
|
285 |
if (!V_ipstealth) { |
319 |
if (!V_ipstealth) { |
286 |
#endif |
320 |
#endif |
287 |
if (ip->ip_ttl <= IPTTLDEC) { |
321 |
if (ip->ip_ttl <= IPTTLDEC) { |
288 |
icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0); |
322 |
icmp_error(mcopy, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0); |
|
|
323 |
if (mcopy) |
324 |
m_freem(mcopy); |
289 |
return NULL; /* mbuf already free'd */ |
325 |
return NULL; /* mbuf already free'd */ |
290 |
} |
326 |
} |
291 |
|
327 |
|
Lines 306-313
Link Here
|
306 |
/* |
342 |
/* |
307 |
* Find route to destination. |
343 |
* Find route to destination. |
308 |
*/ |
344 |
*/ |
309 |
if ((dst = ip_findroute(&ro, dest, m)) == NULL) |
345 |
if ((dst = ip_findroute(&ro, dest, m)) == NULL) { |
|
|
346 |
if (mcopy) |
347 |
m_freem(mcopy); |
310 |
return NULL; /* icmp unreach already sent */ |
348 |
return NULL; /* icmp unreach already sent */ |
|
|
349 |
} |
311 |
ifp = ro.ro_rt->rt_ifp; |
350 |
ifp = ro.ro_rt->rt_ifp; |
312 |
|
351 |
|
313 |
/* |
352 |
/* |
Lines 355-360
Link Here
|
355 |
m->m_flags |= M_FASTFWD_OURS; |
394 |
m->m_flags |= M_FASTFWD_OURS; |
356 |
if (ro.ro_rt) |
395 |
if (ro.ro_rt) |
357 |
RTFREE(ro.ro_rt); |
396 |
RTFREE(ro.ro_rt); |
|
|
397 |
if (mcopy) |
398 |
m_freem(mcopy); |
358 |
return m; |
399 |
return m; |
359 |
} |
400 |
} |
360 |
/* |
401 |
/* |
Lines 367-374
Link Here
|
367 |
m->m_flags &= ~M_IP_NEXTHOP; |
408 |
m->m_flags &= ~M_IP_NEXTHOP; |
368 |
} |
409 |
} |
369 |
RTFREE(ro.ro_rt); |
410 |
RTFREE(ro.ro_rt); |
370 |
if ((dst = ip_findroute(&ro, dest, m)) == NULL) |
411 |
if ((dst = ip_findroute(&ro, dest, m)) == NULL) { |
|
|
412 |
if (mcopy) |
413 |
m_freem(mcopy); |
371 |
return NULL; /* icmp unreach already sent */ |
414 |
return NULL; /* icmp unreach already sent */ |
|
|
415 |
} |
372 |
ifp = ro.ro_rt->rt_ifp; |
416 |
ifp = ro.ro_rt->rt_ifp; |
373 |
} |
417 |
} |
374 |
|
418 |
|
Lines 384-390
Link Here
|
384 |
*/ |
428 |
*/ |
385 |
if ((ro.ro_rt->rt_flags & RTF_REJECT) && |
429 |
if ((ro.ro_rt->rt_flags & RTF_REJECT) && |
386 |
(ro.ro_rt->rt_expire == 0 || time_uptime < ro.ro_rt->rt_expire)) { |
430 |
(ro.ro_rt->rt_expire == 0 || time_uptime < ro.ro_rt->rt_expire)) { |
387 |
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); |
431 |
icmp_error(mcopy, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); |
388 |
goto consumed; |
432 |
goto consumed; |
389 |
} |
433 |
} |
390 |
|
434 |
|
Lines 392-398
Link Here
|
392 |
* Check if media link state of interface is not down |
436 |
* Check if media link state of interface is not down |
393 |
*/ |
437 |
*/ |
394 |
if (ifp->if_link_state == LINK_STATE_DOWN) { |
438 |
if (ifp->if_link_state == LINK_STATE_DOWN) { |
395 |
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); |
439 |
icmp_error(mcopy, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); |
396 |
goto consumed; |
440 |
goto consumed; |
397 |
} |
441 |
} |
398 |
|
442 |
|
Lines 421-427
Link Here
|
421 |
*/ |
465 |
*/ |
422 |
if (ip_off & IP_DF) { |
466 |
if (ip_off & IP_DF) { |
423 |
IPSTAT_INC(ips_cantfrag); |
467 |
IPSTAT_INC(ips_cantfrag); |
424 |
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, |
468 |
icmp_error(mcopy, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, |
425 |
0, mtu); |
469 |
0, mtu); |
426 |
goto consumed; |
470 |
goto consumed; |
427 |
} else { |
471 |
} else { |
Lines 469-479
Link Here
|
469 |
IPSTAT_INC(ips_fastforward); |
513 |
IPSTAT_INC(ips_fastforward); |
470 |
} |
514 |
} |
471 |
consumed: |
515 |
consumed: |
|
|
516 |
if (mcopy) |
517 |
m_freem(mcopy); |
472 |
RTFREE(ro.ro_rt); |
518 |
RTFREE(ro.ro_rt); |
473 |
return NULL; |
519 |
return NULL; |
474 |
drop: |
520 |
drop: |
475 |
if (m) |
521 |
if (m) |
476 |
m_freem(m); |
522 |
m_freem(m); |
|
|
523 |
if (mcopy) |
524 |
m_freem(mcopy); |
477 |
if (ro.ro_rt) |
525 |
if (ro.ro_rt) |
478 |
RTFREE(ro.ro_rt); |
526 |
RTFREE(ro.ro_rt); |
479 |
return NULL; |
527 |
return NULL; |