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: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Tom Herbert 2013-12-15 22:12:18 -08:00 committed by David S. Miller
parent 3958afa1b2
commit 7539fadcb8
5 changed files with 22 additions and 12 deletions

View File

@ -712,6 +712,18 @@ static inline __u32 skb_get_hash(struct sk_buff *skb)
return skb->rxhash; 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 #ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{ {

View File

@ -322,12 +322,11 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
skb->dev = 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 * encapsulated packet, unless we have already determine the hash
* over the L4 4-tuple. * over the L4 4-tuple.
*/ */
if (!skb->l4_rxhash) skb_clear_hash_if_not_l4(skb);
skb->rxhash = 0;
skb_set_queue_mapping(skb, 0); skb_set_queue_mapping(skb, 0);
skb_scrub_packet(skb, !net_eq(net, dev_net(dev))); skb_scrub_packet(skb, !net_eq(net, dev_net(dev)));
} }

View File

@ -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)); memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
if (ip_defrag(skb, user)) if (ip_defrag(skb, user))
return NULL; return NULL;
skb->rxhash = 0; skb_clear_hash(skb);
} }
} }
return skb; return skb;

View File

@ -56,7 +56,7 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
skb_scrub_packet(skb, xnet); skb_scrub_packet(skb, xnet);
skb->rxhash = 0; skb_clear_hash(skb);
skb_dst_set(skb, &rt->dst); skb_dst_set(skb, &rt->dst);
memset(IPCB(skb), 0, sizeof(*IPCB(skb))); 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); nf_reset(skb);
secpath_reset(skb); secpath_reset(skb);
if (!skb->l4_rxhash) skb_clear_hash_if_not_l4(skb);
skb->rxhash = 0;
skb_dst_drop(skb); skb_dst_drop(skb);
skb->vlan_tci = 0; skb->vlan_tci = 0;
skb_set_queue_mapping(skb, 0); skb_set_queue_mapping(skb, 0);

View File

@ -165,7 +165,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
} }
csum_replace4(&nh->check, *addr, new_addr); csum_replace4(&nh->check, *addr, new_addr);
skb->rxhash = 0; skb_clear_hash(skb);
*addr = new_addr; *addr = new_addr;
} }
@ -199,7 +199,7 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto,
if (recalculate_csum) if (recalculate_csum)
update_ipv6_checksum(skb, l4_proto, addr, new_addr); update_ipv6_checksum(skb, l4_proto, addr, new_addr);
skb->rxhash = 0; skb_clear_hash(skb);
memcpy(addr, new_addr, sizeof(__be32[4])); 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); inet_proto_csum_replace2(check, skb, *port, new_port, 0);
*port = new_port; *port = new_port;
skb->rxhash = 0; skb_clear_hash(skb);
} }
static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port) 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; uh->check = CSUM_MANGLED_0;
} else { } else {
*port = new_port; *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. */ /* Carry any checksum errors through. */
sh->checksum = old_csum ^ old_correct_csum ^ new_csum; sh->checksum = old_csum ^ old_correct_csum ^ new_csum;
skb->rxhash = 0; skb_clear_hash(skb);
} }
return 0; return 0;