[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

pf - icmp fragmentation needed packet broken with modulate state



Submitter-Id:  net
Originator:    Jan Krupa
Organization:
net
Synopsis: pf - icmp fragmentation needed packet broken with
modulate state
Severity:      non-critical
Priority:      low
Category:      kernel
Class:         sw-bug
Release:       3.4-stable
Environment:
        System      : OpenBSD 3.4
        Architecture: OpenBSD.i386
        Machine     : i386
Description:

The message bellow I sent to misc_(_at_)_openbsd_(_dot_)_org and two weeks later there is no response to it and I think it's a bug...

 The message follows:

 I have trouble with routing ICMP fragmentation needed (type 3, code 4)
 via OpenBSD (3.2-stable, 3.4-stable after upgrade) router.
 Scenario:

         xl0       ep1                   ep1       xl0
 [ PC1 ]---[ OBSD1 ]--- VPN by provider ---[ OBSD2 ]---[ PC2 ]
                          (mtu=1460)
 ...
 pass out on ep1 inet proto tcp all flags S/SA modulate state
 ...
 pass  in on xl0 inet proto tcp all flags S/SA keep state
 ...

 PC workstation (PC1) establishes TCP connection to the PC2.
 On the ep1 interface of the OpenBSD router (OBSD1) initial sequence
 number of packet generated by PC1 is replaced with OBSD1's sequence
 number. In opposite direction PC1's sequence numbers are returned
 back. This is how modulate state works on ep1.

 The problems starts with data packet with don't fragment flag set
 and with length greater than mtu on the route to the PC2.
 In my case it is VPN with mtu of 1460 bytes (mtu on OBSD is 1500).

 Such large packet arrives VPN entry (provider's router) and due
 to its length and DF set an ICMP error message (fragmentation needed)
 is generated by provider's router and it is send back to the OBSD1
 which should forward it to the PC1.

 ICMP error message contains IP header and 8 data bytes of IP packet
 to which it belongs. For ICMP error related to TCP packet there are
 also port numbers and sequence number within ICMP message.

 So, OBSD1 receives on ep1 ICMP error with modulated sequence number.
 It is forwarded to PC1: on xl0 ICMP error is transmitted with sequence
 number of the original large TCP packet generated by PC1. It is OK,
 sequence number is rewritten back. But, ICMP checksum of this
 ICMP error is not updated. On PC1 this error message is discarded due
 to bad checksum, next too large packet is send by PC1...
 ...connection freezes

How-To-Repeat:
 Route TCP packet via OBSD box with modulate state on on output
 network interface. This TCP packet must have DF set and it's length
 must be greater than mtu on the route to the packet destination.
 Watch ICMP comming back to this packet.

Fix:
 After discovering all these things described above,
 the simple workaround was to modify pf rules on ep1 to
 use keep state for vpn traffic:

 ...
 pass out on ep1 inet proto tcp all flags S/SA modulate state
 pass out on ep1 inet proto tcp from any to $vpn_dest \
   flags S/SA keep state
 ...