aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-07-14 10:53:20 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-14 10:53:20 -0400
commitf6b72b6217f8c24f2a54988e58af858b4e66024d (patch)
treec59d5adcf9bb226db6f602c5078106052524cfea /net/ipv4
parent390fd0b388e4f85549e5d60bdeb21364b344d9b9 (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.c14
-rw-r--r--net/ipv4/route.c7
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, "");