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

Collapse All | Expand All

(-)sys/netinet/ip_fastfwd.c (-9 / +24 lines)
Lines 275-362 passin: Link Here
275
	if (ip->ip_ttl <= IPTTLDEC) {
275
	if (ip->ip_ttl <= IPTTLDEC) {
276
		icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0);
276
		icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0);
277
		return NULL;	/* mbuf already free'd */
277
		return NULL;	/* mbuf already free'd */
278
	}
278
	}
279
279
280
	/*
280
	/*
281
	 * Decrement the TTL and incrementally change the IP header checksum.
281
	 * Decrement the TTL and incrementally change the IP header checksum.
282
	 * Don't bother doing this with hw checksum offloading, it's faster
282
	 * Don't bother doing this with hw checksum offloading, it's faster
283
	 * doing it right here.
283
	 * doing it right here.
284
	 */
284
	 */
285
	ip->ip_ttl -= IPTTLDEC;
285
	ip->ip_ttl -= IPTTLDEC;
286
	if (ip->ip_sum >= (u_int16_t) ~htons(IPTTLDEC << 8))
286
	if (ip->ip_sum >= (u_int16_t) ~htons(IPTTLDEC << 8))
287
		ip->ip_sum -= ~htons(IPTTLDEC << 8);
287
		ip->ip_sum -= ~htons(IPTTLDEC << 8);
288
	else
288
	else
289
		ip->ip_sum += htons(IPTTLDEC << 8);
289
		ip->ip_sum += htons(IPTTLDEC << 8);
290
#ifdef IPSTEALTH
290
#ifdef IPSTEALTH
291
	}
291
	}
292
#endif
292
#endif
293
293
294
	/*
294
	/*
295
	 * Next hop forced by ipfilter hook?
296
	 */
297
	if (m->m_flags & M_IP_NEXTHOP) {
298
		fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
299
		/*
300
		 * Skip outgoing filtering.
301
		 */
302
		if (fwd_tag)
303
			goto reroute;
304
	}
305
	/*
295
	 * Find route to destination.
306
	 * Find route to destination.
296
	 */
307
	 */
297
	if (ip_findroute(&nh, dest, m) != 0)
308
	if (ip_findroute(&nh, dest, m) != 0)
298
		return (NULL);	/* icmp unreach already sent */
309
		return (NULL);	/* icmp unreach already sent */
299
310
300
	/*
311
	/*
301
	 * Step 5: outgoing firewall packet processing
312
	 * Step 5: outgoing firewall packet processing
302
	 */
313
	 */
303
	if (!PFIL_HOOKED(&V_inet_pfil_hook))
314
	if (!PFIL_HOOKED(&V_inet_pfil_hook))
304
		goto passout;
315
		goto passout;
305
316
306
	if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, PFIL_FWD,
317
	if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, PFIL_FWD,
307
	    NULL) || m == NULL) {
318
	    NULL) || m == NULL) {
308
		goto drop;
319
		goto drop;
309
	}
320
	}
310
321
311
	M_ASSERTVALID(m);
322
	M_ASSERTVALID(m);
312
	M_ASSERTPKTHDR(m);
323
	M_ASSERTPKTHDR(m);
313
324
314
	ip = mtod(m, struct ip *);
325
	ip = mtod(m, struct ip *);
315
	dest.s_addr = ip->ip_dst.s_addr;
326
	dest.s_addr = ip->ip_dst.s_addr;
316
327
317
	/*
328
	/*
318
	 * Destination address changed?
329
	 * Destination address changed?
319
	 */
330
	 */
320
	if (m->m_flags & M_IP_NEXTHOP)
331
	if (m->m_flags & M_IP_NEXTHOP)
321
		fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
332
		fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
322
	if (odest.s_addr != dest.s_addr || fwd_tag != NULL) {
333
	if (odest.s_addr != dest.s_addr || fwd_tag != NULL) {
323
		/*
334
		/*
324
		 * Is it now for a local address on this host?
335
		 * Is it now for a local address on this host?
325
		 */
336
		 */
326
		if (m->m_flags & M_FASTFWD_OURS || in_localip(dest)) {
337
		if (m->m_flags & M_FASTFWD_OURS || in_localip(dest)) {
327
forwardlocal:
338
forwardlocal:
328
			/*
339
			/*
329
			 * Return packet for processing by ip_input().
340
			 * Return packet for processing by ip_input().
330
			 */
341
			 */
331
			m->m_flags |= M_FASTFWD_OURS;
342
			m->m_flags |= M_FASTFWD_OURS;
332
			return (m);
343
			return (m);
333
		}
344
		}
334
		/*
345
	}
335
		 * Redo route lookup with new destination address
346
336
		 */
347
reroute:
337
		if (fwd_tag) {
348
	if (fwd_tag != NULL) {
338
			dest.s_addr = ((struct sockaddr_in *)
349
		dest.s_addr = ((struct sockaddr_in *)
339
				    (fwd_tag + 1))->sin_addr.s_addr;
350
			    (fwd_tag + 1))->sin_addr.s_addr;
340
			m_tag_delete(m, fwd_tag);
351
		m_tag_delete(m, fwd_tag);
341
			m->m_flags &= ~M_IP_NEXTHOP;
352
		m->m_flags &= ~M_IP_NEXTHOP;
342
		}
353
	}
354
	/*
355
	 * Redo route lookup with new destination address
356
	 */
357
	if (odest.s_addr != dest.s_addr || fwd_tag != NULL) {
343
		if (ip_findroute(&nh, dest, m) != 0)
358
		if (ip_findroute(&nh, dest, m) != 0)
344
			return (NULL);	/* icmp unreach already sent */
359
			return (NULL);	/* icmp unreach already sent */
345
	}
360
	}
346
361
347
passout:
362
passout:
348
	/*
363
	/*
349
	 * Step 6: send off the packet
364
	 * Step 6: send off the packet
350
	 */
365
	 */
351
	ip_len = ntohs(ip->ip_len);
366
	ip_len = ntohs(ip->ip_len);
352
	ip_off = ntohs(ip->ip_off);
367
	ip_off = ntohs(ip->ip_off);
353
368
354
	bzero(&dst, sizeof(dst));
369
	bzero(&dst, sizeof(dst));
355
	dst.sin_family = AF_INET;
370
	dst.sin_family = AF_INET;
356
	dst.sin_len = sizeof(dst);
371
	dst.sin_len = sizeof(dst);
357
	dst.sin_addr = nh.nh_addr;
372
	dst.sin_addr = nh.nh_addr;
358
373
359
	/*
374
	/*
360
	 * Check if packet fits MTU or if hardware will fragment for us
375
	 * Check if packet fits MTU or if hardware will fragment for us
361
	 */
376
	 */
362
	if (ip_len <= nh.nh_mtu) {
377
	if (ip_len <= nh.nh_mtu) {

Return to bug 231143