diff options
| author | David S. Miller <davem@davemloft.net> | 2011-07-14 07:53:20 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-07-14 07:53:20 -0700 | 
| commit | f6b72b6217f8c24f2a54988e58af858b4e66024d (patch) | |
| tree | c59d5adcf9bb226db6f602c5078106052524cfea /net/ipv4/ip_output.c | |
| parent | 390fd0b388e4f85549e5d60bdeb21364b344d9b9 (diff) | |
net: Embed hh_cache inside of struct neighbour.
Now that there is a one-to-one correspondance between neighbour
and hh_cache entries, we no longer need:
1) dynamic allocation
2) attachment to dst->hh
3) refcounting
Initialization of the hh_cache entry is indicated by hh_len
being non-zero, and such initialization is always done with
the neighbour's lock held as a writer.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_output.c')
| -rw-r--r-- | net/ipv4/ip_output.c | 14 | 
1 files changed, 9 insertions, 5 deletions
| diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 54119d5aae8f..a621b96aed15 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -182,6 +182,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)  	struct rtable *rt = (struct rtable *)dst;  	struct net_device *dev = dst->dev;  	unsigned int hh_len = LL_RESERVED_SPACE(dev); +	struct neighbour *neigh;  	if (rt->rt_type == RTN_MULTICAST) {  		IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len); @@ -203,11 +204,14 @@ static inline int ip_finish_output2(struct sk_buff *skb)  		skb = skb2;  	} -	if (dst->hh) -		return neigh_hh_output(dst->hh, skb); -	else if (dst->neighbour) -		return dst->neighbour->output(skb); - +	neigh = dst->neighbour; +	if (neigh) { +		struct hh_cache *hh = &neigh->hh; +		if (hh->hh_len) +			return neigh_hh_output(hh, skb); +		else +			return dst->neighbour->output(skb); +	}  	if (net_ratelimit())  		printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");  	kfree_skb(skb); | 
