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

Samuel Forms samuel_formulaires at numlog.fr
Tue Apr 28 17:43:41 EDT 2009


Hello,

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
#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) || defined(HAVE_UDP_ENCAP_CONVERT)
that failed, I manually applied it.

I had a simiar 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 the VPN IS behind NAT; my problem was :
- when nat_traversal is set to no, everything works (although I have
problems when tunnel is inactive for a while, I'll check that later)
- when nat_traversal is set to 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 ipsec_rcv.c, my
understanding of the symptom 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];
    break;
(...)
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 *)
&(prvdev->mystats);
                }

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;
before
                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.




More information about the Users mailing list