Hello, I just want to report an endiannes issue found with 2.4.18+newnat running on a PPC architecture.
The problem comes from a change in the definition of both ip_conntrack_manip and ip_conntrack_tuple structures. (kernel/include/linux/netfilter_ipv4/ip_conntrack_tuple.h) In old nat they both contained an union "u" of 16bits width. With newnat this union "u" is now 32bits width. This breaks code where the union is still initialized with 16bits values as if the whole union size was still equal to its "port" element. Exemple: In FTP conntrack's helper defined in kernel/net/ipv4/netfilter/ip_conntrack_ftp.c we have the following code: exp->tuple = ((struct ip_conntrack_tuple) { { ct->tuplehash[!dir].tuple.src.ip, { 0 } }, { htonl((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]), { htons(array[4] << 8 | array[5]) }, IPPROTO_TCP }}); exp->mask = ((struct ip_conntrack_tuple) { { 0xFFFFFFFF, { 0 } }, { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); This code assumes "u" unions are 16bits. On little-endian arch this init code will correctly init the union's "port" element. But on big-endian arch the value will be written in the upper part of the 32bits and thus the "port" element is no longer initialized. One possible fix for this chunck of code could be: exp->tuple = ((struct ip_conntrack_tuple) { { ct->tuplehash[!dir].tuple.src.ip, { 0 } }, { htonl((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]), { tcp: { port: htons(array[4] << 8 | array[5]) } }, IPPROTO_TCP }}); exp->mask = ((struct ip_conntrack_tuple) { { 0xFFFFFFFF, { 0 } }, { 0xFFFFFFFF, { tcp: { port: 0xFFFF } }, 0xFFFF }}); This way we explicitely initialize the right union's elements. There is multiple places in newnat code having this issue. Anybody else tried newnat on a big-endian arch ? Regards, Rob -- Roberto Romano Software Engineer LIGHTNING SA http://www.lightning.ch/