diff options
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | include/net/neighbour.h | 4 | ||||
-rw-r--r-- | net/core/neighbour.c | 25 | ||||
-rw-r--r-- | net/ipv4/route.c | 6 |
4 files changed, 7 insertions, 29 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f84dfd25c431..52c4e3835aa6 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -254,7 +254,6 @@ struct netdev_hw_addr_list { | |||
254 | struct hh_cache { | 254 | struct hh_cache { |
255 | u16 hh_len; | 255 | u16 hh_len; |
256 | u16 __pad; | 256 | u16 __pad; |
257 | int (*hh_output)(struct sk_buff *skb); | ||
258 | seqlock_t hh_lock; | 257 | seqlock_t hh_lock; |
259 | 258 | ||
260 | /* cached hardware header; allow for machine alignment needs. */ | 259 | /* cached hardware header; allow for machine alignment needs. */ |
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 97990ddca66c..60bac8112d86 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -340,13 +340,13 @@ static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb) | |||
340 | } while (read_seqretry(&hh->hh_lock, seq)); | 340 | } while (read_seqretry(&hh->hh_lock, seq)); |
341 | 341 | ||
342 | skb_push(skb, hh_len); | 342 | skb_push(skb, hh_len); |
343 | return hh->hh_output(skb); | 343 | return dev_queue_xmit(skb); |
344 | } | 344 | } |
345 | 345 | ||
346 | static inline int neigh_output(struct neighbour *n, struct sk_buff *skb) | 346 | static inline int neigh_output(struct neighbour *n, struct sk_buff *skb) |
347 | { | 347 | { |
348 | struct hh_cache *hh = &n->hh; | 348 | struct hh_cache *hh = &n->hh; |
349 | if (hh->hh_len) | 349 | if ((n->nud_state & NUD_CONNECTED) && hh->hh_len) |
350 | return neigh_hh_output(hh, skb); | 350 | return neigh_hh_output(hh, skb); |
351 | else | 351 | else |
352 | return n->output(skb); | 352 | return n->output(skb); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index c22def5ae486..2feda6e7a31d 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -720,15 +720,9 @@ EXPORT_SYMBOL(neigh_destroy); | |||
720 | */ | 720 | */ |
721 | static void neigh_suspect(struct neighbour *neigh) | 721 | static void neigh_suspect(struct neighbour *neigh) |
722 | { | 722 | { |
723 | struct hh_cache *hh; | ||
724 | |||
725 | NEIGH_PRINTK2("neigh %p is suspected.\n", neigh); | 723 | NEIGH_PRINTK2("neigh %p is suspected.\n", neigh); |
726 | 724 | ||
727 | neigh->output = neigh->ops->output; | 725 | neigh->output = neigh->ops->output; |
728 | |||
729 | hh = &neigh->hh; | ||
730 | if (hh->hh_len) | ||
731 | hh->hh_output = neigh->ops->output; | ||
732 | } | 726 | } |
733 | 727 | ||
734 | /* Neighbour state is OK; | 728 | /* Neighbour state is OK; |
@@ -738,15 +732,9 @@ static void neigh_suspect(struct neighbour *neigh) | |||
738 | */ | 732 | */ |
739 | static void neigh_connect(struct neighbour *neigh) | 733 | static void neigh_connect(struct neighbour *neigh) |
740 | { | 734 | { |
741 | struct hh_cache *hh; | ||
742 | |||
743 | NEIGH_PRINTK2("neigh %p is connected.\n", neigh); | 735 | NEIGH_PRINTK2("neigh %p is connected.\n", neigh); |
744 | 736 | ||
745 | neigh->output = neigh->ops->connected_output; | 737 | neigh->output = neigh->ops->connected_output; |
746 | |||
747 | hh = &neigh->hh; | ||
748 | if (hh->hh_len) | ||
749 | hh->hh_output = dev_queue_xmit; | ||
750 | } | 738 | } |
751 | 739 | ||
752 | static void neigh_periodic_work(struct work_struct *work) | 740 | static void neigh_periodic_work(struct work_struct *work) |
@@ -1215,18 +1203,9 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst) | |||
1215 | /* Only one thread can come in here and initialize the | 1203 | /* Only one thread can come in here and initialize the |
1216 | * hh_cache entry. | 1204 | * hh_cache entry. |
1217 | */ | 1205 | */ |
1218 | if (hh->hh_len) | 1206 | if (!hh->hh_len) |
1219 | goto end; | 1207 | dev->header_ops->cache(n, hh, prot); |
1220 | |||
1221 | if (dev->header_ops->cache(n, hh, prot)) | ||
1222 | goto end; | ||
1223 | |||
1224 | if (n->nud_state & NUD_CONNECTED) | ||
1225 | hh->hh_output = dev_queue_xmit; | ||
1226 | else | ||
1227 | hh->hh_output = n->ops->output; | ||
1228 | 1208 | ||
1229 | end: | ||
1230 | write_unlock_bh(&n->lock); | 1209 | write_unlock_bh(&n->lock); |
1231 | } | 1210 | } |
1232 | 1211 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a52bb74d2612..bcf9bb508200 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -427,9 +427,9 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) | |||
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 | -1, | 429 | -1, |
430 | (r->dst.neighbour ? | 430 | (r->dst.neighbour && |
431 | (r->dst.neighbour->hh.hh_output == | 431 | (r->dst.neighbour->nud_state & NUD_CONNECTED)) ? |
432 | dev_queue_xmit) : 0), | 432 | 1 : 0, |
433 | r->rt_spec_dst, &len); | 433 | r->rt_spec_dst, &len); |
434 | 434 | ||
435 | seq_printf(seq, "%*s\n", 127 - len, ""); | 435 | seq_printf(seq, "%*s\n", 127 - len, ""); |