diff options
| author | David S. Miller <davem@davemloft.net> | 2011-07-14 10:53:20 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-07-14 10:53:20 -0400 |
| commit | f6b72b6217f8c24f2a54988e58af858b4e66024d (patch) | |
| tree | c59d5adcf9bb226db6f602c5078106052524cfea /net/ipv4 | |
| 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')
| -rw-r--r-- | net/ipv4/ip_output.c | 14 | ||||
| -rw-r--r-- | net/ipv4/route.c | 7 |
2 files changed, 13 insertions, 8 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) | |||
| 182 | struct rtable *rt = (struct rtable *)dst; | 182 | struct rtable *rt = (struct rtable *)dst; |
| 183 | struct net_device *dev = dst->dev; | 183 | struct net_device *dev = dst->dev; |
| 184 | unsigned int hh_len = LL_RESERVED_SPACE(dev); | 184 | unsigned int hh_len = LL_RESERVED_SPACE(dev); |
| 185 | struct neighbour *neigh; | ||
| 185 | 186 | ||
| 186 | if (rt->rt_type == RTN_MULTICAST) { | 187 | if (rt->rt_type == RTN_MULTICAST) { |
| 187 | IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len); | 188 | 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) | |||
| 203 | skb = skb2; | 204 | skb = skb2; |
| 204 | } | 205 | } |
| 205 | 206 | ||
| 206 | if (dst->hh) | 207 | neigh = dst->neighbour; |
| 207 | return neigh_hh_output(dst->hh, skb); | 208 | if (neigh) { |
| 208 | else if (dst->neighbour) | 209 | struct hh_cache *hh = &neigh->hh; |
| 209 | return dst->neighbour->output(skb); | 210 | if (hh->hh_len) |
| 210 | 211 | return neigh_hh_output(hh, skb); | |
| 212 | else | ||
| 213 | return dst->neighbour->output(skb); | ||
| 214 | } | ||
| 211 | if (net_ratelimit()) | 215 | if (net_ratelimit()) |
| 212 | printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); | 216 | printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); |
| 213 | kfree_skb(skb); | 217 | kfree_skb(skb); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index c6388e825ed3..a52bb74d2612 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -426,9 +426,10 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) | |||
| 426 | (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) + | 426 | (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) + |
| 427 | dst_metric(&r->dst, RTAX_RTTVAR)), | 427 | dst_metric(&r->dst, RTAX_RTTVAR)), |
| 428 | r->rt_key_tos, | 428 | r->rt_key_tos, |
| 429 | r->dst.hh ? atomic_read(&r->dst.hh->hh_refcnt) : -1, | 429 | -1, |
| 430 | r->dst.hh ? (r->dst.hh->hh_output == | 430 | (r->dst.neighbour ? |
| 431 | dev_queue_xmit) : 0, | 431 | (r->dst.neighbour->hh.hh_output == |
| 432 | dev_queue_xmit) : 0), | ||
| 432 | r->rt_spec_dst, &len); | 433 | r->rt_spec_dst, &len); |
| 433 | 434 | ||
| 434 | seq_printf(seq, "%*s\n", 127 - len, ""); | 435 | seq_printf(seq, "%*s\n", 127 - len, ""); |
