Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7b5f487 authored by David S. Miller's avatar David S. Miller
Browse files

[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: default avatarDavid S. Miller <davem@davemloft.net>
parent 40caf5ea
Loading
Loading
Loading
Loading
+18 −18
Original line number Diff line number Diff line
@@ -270,10 +270,10 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
	struct sock *sk, *result = NULL;
	struct hlist_node *node;
	unsigned int hash, hashwild;
	int score, best = -1;
	int score, best = -1, hport = ntohs(dport);

	hash = hash_port_and_addr(ntohs(dport), daddr);
	hashwild = hash_port_and_addr(ntohs(dport), 0);
 	hash = hash_port_and_addr(hport, daddr);
 	hashwild = hash_port_and_addr(hport, 0);

	read_lock(&udp_hash_lock);

@@ -283,7 +283,7 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
		struct inet_sock *inet = inet_sk(sk);

		if (sk->sk_hash != hash || ipv6_only_sock(sk) ||
			inet->num != dport)
			inet->num != hport)
			continue;

		score = (sk->sk_family == PF_INET ? 1 : 0);
@@ -327,9 +327,8 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
	return result;
}

static inline struct sock *udp_v4_mcast_next(
			struct sock *sk,
			unsigned int hnum, __be16 loc_port, __be32 loc_addr,
static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum,
					     int hport, __be32 loc_addr,
					     __be16 rmt_port, __be32 rmt_addr,
					     int dif)
{
@@ -340,7 +339,7 @@ static inline struct sock *udp_v4_mcast_next(
		struct inet_sock *inet = inet_sk(s);

		if (s->sk_hash != hnum					||
		    inet->num != loc_port				||
		    inet->num != hport					||
		    (inet->daddr && inet->daddr != rmt_addr)		||
		    (inet->dport != rmt_port && inet->dport)		||
		    (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;
	int dif;
	unsigned int hash = hash_port_and_addr(ntohs(uh->dest), daddr);
	unsigned int hashwild = hash_port_and_addr(ntohs(uh->dest), 0);
	int hport = ntohs(uh->dest);
	unsigned int hash = hash_port_and_addr(hport, daddr);
	unsigned int hashwild = hash_port_and_addr(hport, 0);

	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)]);
	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) {
		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);
	}
	if (sk) {
		do {
			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);
			if (!sknext && 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);
			}
			if (sknext)