[Openswan Users] Bug 1021 Workaround ? O2.6.21+K2.6.25+NAT-T

Samuel Forms samuel_formulaires at numlog.fr
Thu May 7 12:32:17 EDT 2009


This may be more related to DEV list, but if it helps a user...

I compiled KLIPS (ipsec.ko module) + programs on
- Debian Sarge
- Openswan 2.6.21
- with patches from ftp://ftp.openswan.org/openswan/testing/nat-t/
- vanilla Kernel 2.6.25 (User Mode Linux, not a real machine)
There was just a little problem with linux/net/ipsec_rcv.c, a line
that failed, I manually applied it.

I had a similar problem to the one described in bug 1021, but even though
mine is different, the functions invovled may be the same.

My system is behind an ADSL modem, so Openswan IS behind NAT; my problem
was :
- when nat_traversal=no, everything works (although I have problems when
tunnel is inactive for a while, I'll check that later)
- when nat_traversal=yes, my ping to remote network gets a reply in an
UDP/4500 packet, but I don't get the ICMP echo-reply => on ipsec0 I see
only ICMP echo-request (wihle for bug 1021 only the reply !?)

After a whole week-end of printk'ing everywhere in linux/net/ipsec_rcv.c,
my understanding of this is :
In ipsec_rcv.c, function ipsec_rcv_init(), there is a loop (line 844), and
within this loop, a test :
for(i = 0; i <= ipsecdevices_max; i++) {
if(prvdev->dev == skb->dev) {
    ipsecdev = ipsecdevices[i];
And after this loop :
               if(ipsecdev) {
                        skb->dev = ipsecdev;
                } else {
                        skb->dev = ipsec_mast_get_device(0);
                        /* ipsec_mast_get takes the device */
                        if(skb->dev) dev_put(skb->dev);
                if(prvdev) {
                        stats = (struct net_device_stats *)

The problem is that
- when nat_traversal is OFF,  skb->dev (skb previously set to irs->skb),
is set to eth1 (outgoing intf, to which ipsec0 is attached), so that
     if(prvdev->dev == skb->dev) {
matches, we leave the for(), ipsec0 gets its RX++, and everything is fine

- when nat_traversal is enabled, when the UDP packet is received, skb->dev
(skb previously set to irs->skb), is set to ipsec0 by klips26_rcv_encap()
: <<"assigning packet ownership to virtual device %s from physical device
%s.\n",>> at line 2110, so nothing matches within the loop, and we leave
the loop with skb->dev set to mast0, so mast0 gets its RX incremented, but
it doesn't work

For our special need, only one ipsec0 intf is fine, so a "workaround" for
me is to [comment the loop and] simply add
                ipsecdev = ipsecdevices[0];
                prvdev = ipsecdevices[0]->priv;
                if(ipsecdev) {

Of course this is very ugly, but it just works for me. Maybe it can help
developpers or the one who reported bug#1021...

Someone may say "you don't need to enable nat_trav when /you/ are NATed,
but when /the remote end/ is"; sure, but /both/ VPN gateway /and/ client
may be behind NAT, it is the case when you don't manage the WAN link :
there is a router in front.

NOTE : I finally realized that programs had been compiled with
USE_NAT_T=false in Makefile.in. I rebuilt programs, but same symptoms...


More information about the Users mailing list