View | Details | Raw Unified | Return to bug 207087 | Differences between
and this patch

Collapse All | Expand All

(-)sys/netinet/ip_fastfwd.c (-6 / +54 lines)
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;

Return to bug 207087