Subject: kern/10993: [ipf] NAT uses wrong IPv4 source address on NEEDFRAG message
To: None <gnats-bugs@gnats.netbsd.org>
From: None <itojun@itojun.org>
List: netbsd-bugs
Date: 09/11/2000 16:46:13
>Number: 10993
>Category: kern
>Synopsis: [ipf] NAT uses wrong IPv4 source address on NEEDFRAG message
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Sep 11 16:47:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: Jun-ichiro itojun Hagino
>Release: NetBSD 1.4.2, possibly current too
>Organization:
itojun.org
>Environment:
System: NetBSD lychee.itojun.org 1.4.2 NetBSD 1.4.2 (LYCHEE.v6) #1138: Sun Sep 10 22:00:15 JST 2000 itojun@lychee.itojun.org:/export/home/itojun/k/kame/netbsd/sys/arch/i386/compile/LYCHEE.v6 i386
>Description:
If we set NAT box with difrerent interface MTU on two sides,
ipfilter will transmit wrong ICMPv6 "need fragment" message.
>How-To-Repeat:
setup the following configuration. NAT box has two IPv4 address
B and C, http server has A, http client has C.
C and D are private address.
also setup MTU(B) to be > MTU(C). setup A to perform path MTU
discovery, and make sure A to send TCP packets with DF bit raised.
(http server) A --- B (NAT box) C --- D (http client)
global address private address
try to transfer large amount of data from A to D. Eventually,
A will transmit a packet which fits MTU(B) but does not fit MTU(C).
NAT box.
orginal packet from A: A --> B
The packet will be rewritten in ip_nat.c:ip_natin(), and passed to
ip_fil.c:ipfr_fastroute().
after ip_natin(): A --> D
ipfr_fastroute() cannot forward the packet to interface C
(as MTU is too big), and NAT box will attempt to transmit an ICMPv4
"need fragment" error message, against the packet, via
ip_fil.c:send_icmp_err().
send_icmp_err() constructs ICMPv4 need fragment packet. The packet
will become like this:
IPv4 header: B --> A (correct)
ICMPv4 header: need fragment
old IPv4 packet: A --> D (wrong)
here, the destination address of the old IPv4 packet needs to be
translated back to "A --> B". otherwise, A will not recognize
smaller-than-normal path MTU between A and D, and tcp session will
choke (hang up).
>Fix:
improve send_icmp_err(). make a nat_outlookup() against IPv4
destination of the original packet (D), and rewrite it back to
global address of NAT box (B).
>Release-Note:
>Audit-Trail:
>Unformatted: