[IPV4] UDP: Fix endianness bugs in hashing changes.
I accidently applied an earlier version of Eric Dumazet's patch, from March 21st. His version from March 30th didn't have these bugs, so this just interdiffs to the correct patch. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
40caf5ea5a
commit
b7b5f487ab
|
@ -270,10 +270,10 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
|
||||||
struct sock *sk, *result = NULL;
|
struct sock *sk, *result = NULL;
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
unsigned int hash, hashwild;
|
unsigned int hash, hashwild;
|
||||||
int score, best = -1;
|
int score, best = -1, hport = ntohs(dport);
|
||||||
|
|
||||||
hash = hash_port_and_addr(ntohs(dport), daddr);
|
hash = hash_port_and_addr(hport, daddr);
|
||||||
hashwild = hash_port_and_addr(ntohs(dport), 0);
|
hashwild = hash_port_and_addr(hport, 0);
|
||||||
|
|
||||||
read_lock(&udp_hash_lock);
|
read_lock(&udp_hash_lock);
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ lookup:
|
||||||
struct inet_sock *inet = inet_sk(sk);
|
struct inet_sock *inet = inet_sk(sk);
|
||||||
|
|
||||||
if (sk->sk_hash != hash || ipv6_only_sock(sk) ||
|
if (sk->sk_hash != hash || ipv6_only_sock(sk) ||
|
||||||
inet->num != dport)
|
inet->num != hport)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
score = (sk->sk_family == PF_INET ? 1 : 0);
|
score = (sk->sk_family == PF_INET ? 1 : 0);
|
||||||
|
@ -327,11 +327,10 @@ found:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct sock *udp_v4_mcast_next(
|
static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum,
|
||||||
struct sock *sk,
|
int hport, __be32 loc_addr,
|
||||||
unsigned int hnum, __be16 loc_port, __be32 loc_addr,
|
__be16 rmt_port, __be32 rmt_addr,
|
||||||
__be16 rmt_port, __be32 rmt_addr,
|
int dif)
|
||||||
int dif)
|
|
||||||
{
|
{
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
struct sock *s = sk;
|
struct sock *s = sk;
|
||||||
|
@ -340,7 +339,7 @@ static inline struct sock *udp_v4_mcast_next(
|
||||||
struct inet_sock *inet = inet_sk(s);
|
struct inet_sock *inet = inet_sk(s);
|
||||||
|
|
||||||
if (s->sk_hash != hnum ||
|
if (s->sk_hash != hnum ||
|
||||||
inet->num != loc_port ||
|
inet->num != hport ||
|
||||||
(inet->daddr && inet->daddr != rmt_addr) ||
|
(inet->daddr && inet->daddr != rmt_addr) ||
|
||||||
(inet->dport != rmt_port && inet->dport) ||
|
(inet->dport != rmt_port && inet->dport) ||
|
||||||
(inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
|
(inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
|
||||||
|
@ -1173,8 +1172,9 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
struct sock *sk, *skw, *sknext;
|
struct sock *sk, *skw, *sknext;
|
||||||
int dif;
|
int dif;
|
||||||
unsigned int hash = hash_port_and_addr(ntohs(uh->dest), daddr);
|
int hport = ntohs(uh->dest);
|
||||||
unsigned int hashwild = hash_port_and_addr(ntohs(uh->dest), 0);
|
unsigned int hash = hash_port_and_addr(hport, daddr);
|
||||||
|
unsigned int hashwild = hash_port_and_addr(hport, 0);
|
||||||
|
|
||||||
dif = skb->dev->ifindex;
|
dif = skb->dev->ifindex;
|
||||||
|
|
||||||
|
@ -1183,20 +1183,20 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
|
||||||
sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]);
|
sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]);
|
||||||
skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]);
|
skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]);
|
||||||
|
|
||||||
sk = udp_v4_mcast_next(sk, hash, uh->dest, daddr, uh->source, saddr, dif);
|
sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif);
|
||||||
if (!sk) {
|
if (!sk) {
|
||||||
hash = hashwild;
|
hash = hashwild;
|
||||||
sk = udp_v4_mcast_next(skw, hash, uh->dest, daddr, uh->source,
|
sk = udp_v4_mcast_next(skw, hash, hport, daddr, uh->source,
|
||||||
saddr, dif);
|
saddr, dif);
|
||||||
}
|
}
|
||||||
if (sk) {
|
if (sk) {
|
||||||
do {
|
do {
|
||||||
struct sk_buff *skb1 = skb;
|
struct sk_buff *skb1 = skb;
|
||||||
sknext = udp_v4_mcast_next(sk_next(sk), hash, uh->dest,
|
sknext = udp_v4_mcast_next(sk_next(sk), hash, hport,
|
||||||
daddr, uh->source, saddr, dif);
|
daddr, uh->source, saddr, dif);
|
||||||
if (!sknext && hash != hashwild) {
|
if (!sknext && hash != hashwild) {
|
||||||
hash = hashwild;
|
hash = hashwild;
|
||||||
sknext = udp_v4_mcast_next(skw, hash, uh->dest,
|
sknext = udp_v4_mcast_next(skw, hash, hport,
|
||||||
daddr, uh->source, saddr, dif);
|
daddr, uh->source, saddr, dif);
|
||||||
}
|
}
|
||||||
if (sknext)
|
if (sknext)
|
||||||
|
@ -1295,7 +1295,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
|
||||||
return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
|
return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
|
||||||
|
|
||||||
sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
|
sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
|
||||||
skb->dev->ifindex, udptable );
|
skb->dev->ifindex, udptable);
|
||||||
|
|
||||||
if (sk != NULL) {
|
if (sk != NULL) {
|
||||||
int ret = udp_queue_rcv_skb(sk, skb);
|
int ret = udp_queue_rcv_skb(sk, skb);
|
||||||
|
|
Loading…
Reference in New Issue