1
linux/net
Radu Rendec 543821c6f5 [PKT_SCHED] CLS_U32: Fix endianness problem with u32 classifier hash masks.
While trying to implement u32 hashes in my shaping machine I ran into
a possible bug in the u32 hash/bucket computing algorithm
(net/sched/cls_u32.c).

The problem occurs only with hash masks that extend over the octet
boundary, on little endian machines (where htonl() actually does
something).

Let's say that I would like to use 0x3fc0 as the hash mask. This means
8 contiguous "1" bits starting at b6. With such a mask, the expected
(and logical) behavior is to hash any address in, for instance,
192.168.0.0/26 in bucket 0, then any address in 192.168.0.64/26 in
bucket 1, then 192.168.0.128/26 in bucket 2 and so on.

This is exactly what would happen on a big endian machine, but on
little endian machines, what would actually happen with current
implementation is 0x3fc0 being reversed (into 0xc03f0000) by htonl()
in the userspace tool and then applied to 192.168.x.x in the u32
classifier. When shifting right by 16 bits (rank of first "1" bit in
the reversed mask) and applying the divisor mask (0xff for divisor
256), what would actually remain is 0x3f applied on the "168" octet of
the address.

One could say is this can be easily worked around by taking endianness
into account in userspace and supplying an appropriate mask (0xfc03)
that would be turned into contiguous "1" bits when reversed
(0x03fc0000). But the actual problem is the network address (inside
the packet) not being converted to host order, but used as a
host-order value when computing the bucket.

Let's say the network address is written as n31 n30 ... n0, with n0
being the least significant bit. When used directly (without any
conversion) on a little endian machine, it becomes n7 ... n0 n8 ..n15
etc in the machine's registers. Thus bits n7 and n8 would no longer be
adjacent and 192.168.64.0/26 and 192.168.128.0/26 would no longer be
consecutive.

The fix is to apply ntohl() on the hmask before computing fshift,
and in u32_hash_fold() convert the packet data to host order before
shifting down by fshift.

With helpful feedback from Jamal Hadi Salim and Jarek Poplawski.

Signed-off-by: David S. Miller <davem@davemloft.net>
2007-11-07 04:11:45 -08:00
..
9p 9p: add missing end-of-options record for trans_fd 2007-11-06 08:02:53 -06:00
802 [NET]: Move hardware header operations out of netdevice. 2007-10-10 16:52:52 -07:00
8021q [8021Q]: transfer dev_id from real device 2007-10-10 16:54:56 -07:00
appletalk [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
atm [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
ax25 [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
bluetooth [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
bridge [NETFILTER]: ebt_arp: fix --arp-gratuitous matching dependence on --arp-ip-{src,dst} 2007-11-07 04:08:25 -08:00
core [NET]: Removing duplicit #includes 2007-11-07 04:11:44 -08:00
dccp [DCCP]: Use DEFINE_PROTO_INUSE infrastructure. 2007-11-07 04:09:01 -08:00
decnet [DECNET]: "addr" module param can't be __initdata 2007-11-07 04:08:55 -08:00
econet [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
ethernet [NET]: Validate device addr prior to interface-up 2007-10-23 21:27:50 -07:00
ieee80211 [NET]: Removing duplicit #includes 2007-11-07 04:11:44 -08:00
ipv4 [IPV4]: Compact some ifdefs in the fib code. 2007-11-07 04:11:41 -08:00
ipv6 [IPV6]: Convert /proc/net/ipv6_route to seq_file interface 2007-11-07 04:09:18 -08:00
ipx [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
irda [IRDA] IRNET: Fix build when TCGETS2 is defined. 2007-11-01 02:26:38 -07:00
iucv [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
key [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
lapb
llc [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
mac80211 cleanup asm/scatterlist.h includes 2007-11-02 08:47:06 +01:00
netfilter [NETFILTER]: nf_sockopts list head cleanup 2007-11-07 04:08:24 -08:00
netlabel [NetLabel]: correct usage of RCU locking 2007-10-26 04:29:08 -07:00
netlink [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
netrom [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
packet [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
rfkill get rid of input BIT* duplicate defines 2007-10-19 11:53:42 -07:00
rose [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
rxrpc [SG] Get rid of __sg_mark_end() 2007-11-02 08:47:06 +01:00
sched [PKT_SCHED] CLS_U32: Fix endianness problem with u32 classifier hash masks. 2007-11-07 04:11:45 -08:00
sctp [SCTP]: Use the {DEFINE|REF}_PROTO_INUSE infrastructure 2007-11-07 04:09:00 -08:00
sunrpc [SG] Get rid of __sg_mark_end() 2007-11-02 08:47:06 +01:00
tipc [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
unix [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
wanrouter [NET]: Make /proc/net per network namespace 2007-10-10 16:49:06 -07:00
wireless Driver core: change add_uevent_var to use a struct 2007-10-12 14:51:01 -07:00
x25 [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
xfrm cleanup asm/scatterlist.h includes 2007-11-02 08:47:06 +01:00
compat.c O_CLOEXEC for SCM_RIGHTS 2007-07-16 09:05:45 -07:00
Kconfig [NET]: Add network namespace clone & unshare support. 2007-10-10 16:52:46 -07:00
Makefile 9p: Reorganization of 9p file system code 2007-07-14 15:13:40 -05:00
nonet.c
socket.c [NET]: Fix error reporting in sys_socketpair(). 2007-10-29 22:37:34 -07:00
sysctl_net.c
TUNABLE