diff options
author | David S. Miller <davem@davemloft.net> | 2011-07-13 03:51:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-13 05:29:59 -0400 |
commit | 5c25f686db352082eef8daa21b760192351a023a (patch) | |
tree | 20b1d6797b0d9d6757e2e367ceb6cc4fe866acbe /net/core | |
parent | e69dd336ee3a05a589629b505b18ba5e7a5b4c54 (diff) |
net: Kill support for multiple hh_cache entries per neighbour
This never, ever, happens.
Neighbour entries are always tied to one address family, and therefore
one set of dst_ops, and therefore one dst_ops->protocol "hh_type"
value.
This capability was blindly imported by Alexey Kuznetsov when he wrote
the neighbour layer.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/neighbour.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8f7e1d8d92a..f879bb55299 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -702,9 +702,9 @@ void neigh_destroy(struct neighbour *neigh) | |||
702 | if (neigh_del_timer(neigh)) | 702 | if (neigh_del_timer(neigh)) |
703 | printk(KERN_WARNING "Impossible event.\n"); | 703 | printk(KERN_WARNING "Impossible event.\n"); |
704 | 704 | ||
705 | while ((hh = neigh->hh) != NULL) { | 705 | hh = neigh->hh; |
706 | neigh->hh = hh->hh_next; | 706 | if (hh) { |
707 | hh->hh_next = NULL; | 707 | neigh->hh = NULL; |
708 | 708 | ||
709 | write_seqlock_bh(&hh->hh_lock); | 709 | write_seqlock_bh(&hh->hh_lock); |
710 | hh->hh_output = neigh_blackhole; | 710 | hh->hh_output = neigh_blackhole; |
@@ -737,7 +737,8 @@ static void neigh_suspect(struct neighbour *neigh) | |||
737 | 737 | ||
738 | neigh->output = neigh->ops->output; | 738 | neigh->output = neigh->ops->output; |
739 | 739 | ||
740 | for (hh = neigh->hh; hh; hh = hh->hh_next) | 740 | hh = neigh->hh; |
741 | if (hh) | ||
741 | hh->hh_output = neigh->ops->output; | 742 | hh->hh_output = neigh->ops->output; |
742 | } | 743 | } |
743 | 744 | ||
@@ -754,7 +755,8 @@ static void neigh_connect(struct neighbour *neigh) | |||
754 | 755 | ||
755 | neigh->output = neigh->ops->connected_output; | 756 | neigh->output = neigh->ops->connected_output; |
756 | 757 | ||
757 | for (hh = neigh->hh; hh; hh = hh->hh_next) | 758 | hh = neigh->hh; |
759 | if (hh) | ||
758 | hh->hh_output = neigh->ops->hh_output; | 760 | hh->hh_output = neigh->ops->hh_output; |
759 | } | 761 | } |
760 | 762 | ||
@@ -1025,7 +1027,8 @@ static void neigh_update_hhs(const struct neighbour *neigh) | |||
1025 | update = neigh->dev->header_ops->cache_update; | 1027 | update = neigh->dev->header_ops->cache_update; |
1026 | 1028 | ||
1027 | if (update) { | 1029 | if (update) { |
1028 | for (hh = neigh->hh; hh; hh = hh->hh_next) { | 1030 | hh = neigh->hh; |
1031 | if (hh) { | ||
1029 | write_seqlock_bh(&hh->hh_lock); | 1032 | write_seqlock_bh(&hh->hh_lock); |
1030 | update(hh, neigh->dev, neigh->ha); | 1033 | update(hh, neigh->dev, neigh->ha); |
1031 | write_sequnlock_bh(&hh->hh_lock); | 1034 | write_sequnlock_bh(&hh->hh_lock); |
@@ -1211,19 +1214,17 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl, | |||
1211 | } | 1214 | } |
1212 | EXPORT_SYMBOL(neigh_event_ns); | 1215 | EXPORT_SYMBOL(neigh_event_ns); |
1213 | 1216 | ||
1214 | static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst, | 1217 | static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst) |
1215 | __be16 protocol) | ||
1216 | { | 1218 | { |
1217 | struct hh_cache *hh; | 1219 | struct hh_cache *hh; |
1218 | 1220 | ||
1219 | smp_rmb(); /* paired with smp_wmb() in neigh_hh_init() */ | 1221 | smp_rmb(); /* paired with smp_wmb() in neigh_hh_init() */ |
1220 | for (hh = n->hh; hh; hh = hh->hh_next) { | 1222 | hh = n->hh; |
1221 | if (hh->hh_type == protocol) { | 1223 | if (hh) { |
1222 | atomic_inc(&hh->hh_refcnt); | 1224 | atomic_inc(&hh->hh_refcnt); |
1223 | if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) | 1225 | if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) |
1224 | hh_cache_put(hh); | 1226 | hh_cache_put(hh); |
1225 | return true; | 1227 | return true; |
1226 | } | ||
1227 | } | 1228 | } |
1228 | return false; | 1229 | return false; |
1229 | } | 1230 | } |
@@ -1235,7 +1236,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, | |||
1235 | struct hh_cache *hh; | 1236 | struct hh_cache *hh; |
1236 | struct net_device *dev = dst->dev; | 1237 | struct net_device *dev = dst->dev; |
1237 | 1238 | ||
1238 | if (likely(neigh_hh_lookup(n, dst, protocol))) | 1239 | if (likely(neigh_hh_lookup(n, dst))) |
1239 | return; | 1240 | return; |
1240 | 1241 | ||
1241 | /* slow path */ | 1242 | /* slow path */ |
@@ -1244,7 +1245,6 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, | |||
1244 | return; | 1245 | return; |
1245 | 1246 | ||
1246 | seqlock_init(&hh->hh_lock); | 1247 | seqlock_init(&hh->hh_lock); |
1247 | hh->hh_type = protocol; | ||
1248 | atomic_set(&hh->hh_refcnt, 2); | 1248 | atomic_set(&hh->hh_refcnt, 2); |
1249 | 1249 | ||
1250 | if (dev->header_ops->cache(n, hh, protocol)) { | 1250 | if (dev->header_ops->cache(n, hh, protocol)) { |
@@ -1255,7 +1255,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, | |||
1255 | write_lock_bh(&n->lock); | 1255 | write_lock_bh(&n->lock); |
1256 | 1256 | ||
1257 | /* must check if another thread already did the insert */ | 1257 | /* must check if another thread already did the insert */ |
1258 | if (neigh_hh_lookup(n, dst, protocol)) { | 1258 | if (neigh_hh_lookup(n, dst)) { |
1259 | kfree(hh); | 1259 | kfree(hh); |
1260 | goto end; | 1260 | goto end; |
1261 | } | 1261 | } |
@@ -1265,7 +1265,6 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, | |||
1265 | else | 1265 | else |
1266 | hh->hh_output = n->ops->output; | 1266 | hh->hh_output = n->ops->output; |
1267 | 1267 | ||
1268 | hh->hh_next = n->hh; | ||
1269 | smp_wmb(); /* paired with smp_rmb() in neigh_hh_lookup() */ | 1268 | smp_wmb(); /* paired with smp_rmb() in neigh_hh_lookup() */ |
1270 | n->hh = hh; | 1269 | n->hh = hh; |
1271 | 1270 | ||