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

Commit 7539fadc authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller
Browse files

net: Add utility functions to clear rxhash



In several places 'skb->rxhash = 0' is being done to clear the
rxhash value in an skb.  This does not clear l4_rxhash which could
still be set so that the rxhash wouldn't be recalculated on subsequent
call to skb_get_rxhash.  This patch adds an explict function to clear
all the rxhash related information in the skb properly.

skb_clear_hash_if_not_l4 clears the rxhash only if it is not marked as
l4_rxhash.

Fixed up places where 'skb->rxhash = 0' was being called.

Signed-off-by: default avatarTom Herbert <therbert@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3958afa1
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -712,6 +712,18 @@ static inline __u32 skb_get_hash(struct sk_buff *skb)
	return skb->rxhash;
}

static inline void skb_clear_hash(struct sk_buff *skb)
{
	skb->rxhash = 0;
	skb->l4_rxhash = 0;
}

static inline void skb_clear_hash_if_not_l4(struct sk_buff *skb)
{
	if (!skb->l4_rxhash)
		skb_clear_hash(skb);
}

#ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
+2 −3
Original line number Diff line number Diff line
@@ -322,12 +322,11 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
	skb->dev = dev;

	/*
	 * Clear rxhash so that we can recalulate the hash for the
	 * Clear hash so that we can recalulate the hash for the
	 * encapsulated packet, unless we have already determine the hash
	 * over the L4 4-tuple.
	 */
	if (!skb->l4_rxhash)
		skb->rxhash = 0;
	skb_clear_hash_if_not_l4(skb);
	skb_set_queue_mapping(skb, 0);
	skb_scrub_packet(skb, !net_eq(net, dev_net(dev)));
}
+1 −1
Original line number Diff line number Diff line
@@ -704,7 +704,7 @@ struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
			memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
			if (ip_defrag(skb, user))
				return NULL;
			skb->rxhash = 0;
			skb_clear_hash(skb);
		}
	}
	return skb;
+2 −3
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,

	skb_scrub_packet(skb, xnet);

	skb->rxhash = 0;
	skb_clear_hash(skb);
	skb_dst_set(skb, &rt->dst);
	memset(IPCB(skb), 0, sizeof(*IPCB(skb)));

@@ -107,8 +107,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)

	nf_reset(skb);
	secpath_reset(skb);
	if (!skb->l4_rxhash)
		skb->rxhash = 0;
	skb_clear_hash_if_not_l4(skb);
	skb_dst_drop(skb);
	skb->vlan_tci = 0;
	skb_set_queue_mapping(skb, 0);
+5 −5
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
	}

	csum_replace4(&nh->check, *addr, new_addr);
	skb->rxhash = 0;
	skb_clear_hash(skb);
	*addr = new_addr;
}

@@ -199,7 +199,7 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto,
	if (recalculate_csum)
		update_ipv6_checksum(skb, l4_proto, addr, new_addr);

	skb->rxhash = 0;
	skb_clear_hash(skb);
	memcpy(addr, new_addr, sizeof(__be32[4]));
}

@@ -296,7 +296,7 @@ static void set_tp_port(struct sk_buff *skb, __be16 *port,
{
	inet_proto_csum_replace2(check, skb, *port, new_port, 0);
	*port = new_port;
	skb->rxhash = 0;
	skb_clear_hash(skb);
}

static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port)
@@ -310,7 +310,7 @@ static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port)
			uh->check = CSUM_MANGLED_0;
	} else {
		*port = new_port;
		skb->rxhash = 0;
		skb_clear_hash(skb);
	}
}

@@ -381,7 +381,7 @@ static int set_sctp(struct sk_buff *skb,
		/* Carry any checksum errors through. */
		sh->checksum = old_csum ^ old_correct_csum ^ new_csum;

		skb->rxhash = 0;
		skb_clear_hash(skb);
	}

	return 0;