Name: Don't Spin For Ages if Out of Memory in NAT Expect Code Signed-off-by: Rusty Russell We spin trying for a free port, but ip_conntrack_add_expect() can fail for OOM as well, in which case we shouldn't spin. Found by nfsim --failtest. Index: linux-2.6.10-bk6-Netfilter/net/ipv4/netfilter/ip_nat_ftp.c =================================================================== --- linux-2.6.10-bk6-Netfilter.orig/net/ipv4/netfilter/ip_nat_ftp.c 2005-01-05 11:36:51.447230016 +1100 +++ linux-2.6.10-bk6-Netfilter/net/ipv4/netfilter/ip_nat_ftp.c 2005-01-05 11:36:59.000081808 +1100 @@ -119,7 +119,7 @@ { u_int32_t newip; u_int16_t port; - int dir = CTINFO2DIR(ctinfo); + int err, dir = CTINFO2DIR(ctinfo); struct ip_conntrack *ct = exp->master; DEBUGP("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen); @@ -136,8 +136,12 @@ /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { exp->tuple.dst.u.tcp.port = htons(port); - if (ip_conntrack_add_expect(exp) == 0) + err = ip_conntrack_add_expect(exp); + if (err == 0) break; + /* Don't spin forever if out of memory etc. */ + if (err != -EBUSY) + return NF_DROP; } if (port == 0) Index: linux-2.6.10-bk6-Netfilter/net/ipv4/netfilter/ip_nat_amanda.c =================================================================== --- linux-2.6.10-bk6-Netfilter.orig/net/ipv4/netfilter/ip_nat_amanda.c 2005-01-05 11:36:55.737577784 +1100 +++ linux-2.6.10-bk6-Netfilter/net/ipv4/netfilter/ip_nat_amanda.c 2005-01-05 11:36:59.000081808 +1100 @@ -52,10 +52,13 @@ /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { exp->tuple.dst.u.tcp.port = htons(port); - if (ip_conntrack_add_expect(exp) == 0) + ret = ip_conntrack_add_expect(exp); + if (ret == 0) break; + /* Don't spin forever if out of memory etc. */ + if (ret != -EBUSY) + return NF_DROP; } - if (port == 0) return NF_DROP; Index: linux-2.6.10-bk6-Netfilter/net/ipv4/netfilter/ip_nat_irc.c =================================================================== --- linux-2.6.10-bk6-Netfilter.orig/net/ipv4/netfilter/ip_nat_irc.c 2005-01-05 11:36:55.747576264 +1100 +++ linux-2.6.10-bk6-Netfilter/net/ipv4/netfilter/ip_nat_irc.c 2005-01-05 11:36:59.000081808 +1100 @@ -62,9 +62,16 @@ /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { + int err; + exp->tuple.dst.u.tcp.port = htons(port); - if (ip_conntrack_add_expect(exp) == 0) + + err = ip_conntrack_add_expect(exp); + if (err == 0) break; + /* Don't spin forever if out of memory etc. */ + if (err != -EBUSY) + return NF_DROP; } if (port == 0)