--- linux-2.6.22.14/drivers/net/pppoe.c 2008-01-22 14:03:03.000000000 +0200 +++ linux/drivers/net/pppoe.c 2008-01-15 11:04:02.000000000 +0200 @@ -77,12 +77,14 @@ #include #include #include +#include #include #include +#include -#define PPPOE_HASH_BITS 4 +#define PPPOE_HASH_BITS 12 #define PPPOE_HASH_SIZE (1<remote,addr,ETH_ALEN) == 0)); } -static int hash_item(unsigned long sid, unsigned char *addr) +static inline int hash_item(unsigned long sid, unsigned char *addr) { - char hash = 0; - int i, j; - - for (i = 0; i < ETH_ALEN ; ++i) { - for (j = 0; j < 8/PPPOE_HASH_BITS ; ++j) { - hash ^= addr[i] >> ( j * PPPOE_HASH_BITS ); - } - } - - for (i = 0; i < (sizeof(unsigned long)*8) / PPPOE_HASH_BITS ; ++i) - hash ^= sid >> (i*PPPOE_HASH_BITS); - - return hash & ( PPPOE_HASH_SIZE - 1 ); + return jhash_3words( + sid, get_unaligned((u32 *) addr), + get_unaligned((u16 *) addr + 2), 0) % PPPOE_HASH_SIZE; } /* zeroed because its in .bss */ @@ -861,6 +853,9 @@ static int __pppoe_xmit(struct sock *sk, if (!dev) goto abort; + nf_bridge_put(skb->nf_bridge); + skb->nf_bridge = NULL; + /* Copy the skb if there is no space for the header. */ if (headroom < (sizeof(struct pppoe_hdr) + dev->hard_header_len)) { skb2 = dev_alloc_skb(32+skb->len +