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>
This commit is contained in:
@@ -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);
|
||||
|
@@ -426,9 +426,10 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
|
||||
(int)((dst_metric(&r->dst, RTAX_RTT) >> 3) +
|
||||
dst_metric(&r->dst, RTAX_RTTVAR)),
|
||||
r->rt_key_tos,
|
||||
r->dst.hh ? atomic_read(&r->dst.hh->hh_refcnt) : -1,
|
||||
r->dst.hh ? (r->dst.hh->hh_output ==
|
||||
dev_queue_xmit) : 0,
|
||||
-1,
|
||||
(r->dst.neighbour ?
|
||||
(r->dst.neighbour->hh.hh_output ==
|
||||
dev_queue_xmit) : 0),
|
||||
r->rt_spec_dst, &len);
|
||||
|
||||
seq_printf(seq, "%*s\n", 127 - len, "");
|
||||
|
Reference in New Issue
Block a user